From c8d5f825fc9843eeee2d039c2903f1c83403487e Mon Sep 17 00:00:00 2001 From: Scott Cazan Date: Thu, 2 May 2024 12:18:02 +0200 Subject: [PATCH 1/4] Update GitBook trademark (#2305) --- src/components/TableOfContents/TableOfContents.tsx | 2 +- src/components/TableOfContents/Trademark.tsx | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/TableOfContents/TableOfContents.tsx b/src/components/TableOfContents/TableOfContents.tsx index 673daae13..aff93bbb7 100644 --- a/src/components/TableOfContents/TableOfContents.tsx +++ b/src/components/TableOfContents/TableOfContents.tsx @@ -75,7 +75,7 @@ export function TableOfContents(props: { 'dark:group-hover:[&::-webkit-scrollbar-thumb]:bg-light/3', 'navigation-open:flex', // can be auto height animated as such https://stackoverflow.com/a/76944290 'lg:-ml-5', - customization.trademark.enabled ? 'lg:pb-16' : 'lg:pb-4', + customization.trademark.enabled ? 'lg:pb-20' : 'lg:pb-4', )} > From 9a86965ba139329e2061e0396f1bd2ef34e200c1 Mon Sep 17 00:00:00 2001 From: Taran Vohra Date: Mon, 6 May 2024 21:02:48 +0530 Subject: [PATCH 2/4] Fix VA cookie to be only set if basePaths match (#2300) --- src/lib/visitor-auth.test.ts | 25 +++++++++++++++--- src/lib/visitor-auth.ts | 31 ++++++++++++++-------- src/middleware.ts | 51 ++++++++++++++++++++++++++---------- 3 files changed, 78 insertions(+), 29 deletions(-) diff --git a/src/lib/visitor-auth.test.ts b/src/lib/visitor-auth.test.ts index d62cc40a6..80e25e08b 100644 --- a/src/lib/visitor-auth.test.ts +++ b/src/lib/visitor-auth.test.ts @@ -2,6 +2,7 @@ import { it, describe, expect } from 'bun:test'; import { NextRequest } from 'next/server'; import { + VisitorAuthCookieValue, getVisitorAuthCookieName, getVisitorAuthCookieValue, getVisitorAuthToken, @@ -17,14 +18,18 @@ describe('getVisitorAuthToken', () => { const request = nextRequest('https://example.com', { [getVisitorAuthCookieName('/')]: { value: getVisitorAuthCookieValue('/', '123') }, }); - expect(getVisitorAuthToken(request, request.nextUrl)).toEqual('123'); + const visitorAuth = getVisitorAuthToken(request, request.nextUrl); + assertVisitorAuthCookieValue(visitorAuth); + expect(visitorAuth.token).toEqual('123'); }); it('should return the token from the cookie root basepath for a sub-path', () => { const request = nextRequest('https://example.com/hello/world', { [getVisitorAuthCookieName('/')]: { value: getVisitorAuthCookieValue('/', '123') }, }); - expect(getVisitorAuthToken(request, request.nextUrl)).toEqual('123'); + const visitorAuth = getVisitorAuthToken(request, request.nextUrl); + assertVisitorAuthCookieValue(visitorAuth); + expect(visitorAuth.token).toEqual('123'); }); it('should return the closest token from the path', () => { @@ -34,7 +39,9 @@ describe('getVisitorAuthToken', () => { value: getVisitorAuthCookieValue('/hello/', '123'), }, }); - expect(getVisitorAuthToken(request, request.nextUrl)).toEqual('123'); + const visitorAuth = getVisitorAuthToken(request, request.nextUrl); + assertVisitorAuthCookieValue(visitorAuth); + expect(visitorAuth.token).toEqual('123'); }); it('should return the token from the cookie in a collection type url', () => { @@ -43,7 +50,9 @@ describe('getVisitorAuthToken', () => { value: getVisitorAuthCookieValue('/hello/v/space1/', '123'), }, }); - expect(getVisitorAuthToken(request, request.nextUrl)).toEqual('123'); + const visitorAuth = getVisitorAuthToken(request, request.nextUrl); + assertVisitorAuthCookieValue(visitorAuth); + expect(visitorAuth.token).toEqual('123'); }); it('should return undefined if no cookie and no query param', () => { @@ -52,6 +61,14 @@ describe('getVisitorAuthToken', () => { }); }); +function assertVisitorAuthCookieValue(value: unknown): asserts value is VisitorAuthCookieValue { + if (value && typeof value === 'object' && 'token' in value) { + return; + } + + throw new Error('Expected a VisitorAuthCookieValue'); +} + function nextRequest(url: string, cookies: Record = {}) { const nextUrl = new URL(url); // @ts-ignore diff --git a/src/lib/visitor-auth.ts b/src/lib/visitor-auth.ts index 659cfd5cf..5adcd0178 100644 --- a/src/lib/visitor-auth.ts +++ b/src/lib/visitor-auth.ts @@ -16,7 +16,10 @@ export type VisitorAuthCookieValue = { * Get the visitor authentication token for the request. This token can either be in the * query parameters or stored as a cookie. */ -export function getVisitorAuthToken(request: NextRequest, url: URL): string | undefined { +export function getVisitorAuthToken( + request: NextRequest, + url: URL, +): string | VisitorAuthCookieValue | undefined { return url.searchParams.get(VISITOR_AUTH_PARAM) ?? getVisitorAuthTokenFromCookies(request, url); } @@ -68,7 +71,10 @@ function getUrlBasePathCombinations(url: URL): string[] { * checking all cookies for a matching "visitor authentication cookie" and returning the * best possible match for the current URL. */ -function getVisitorAuthTokenFromCookies(request: NextRequest, url: URL): string | undefined { +function getVisitorAuthTokenFromCookies( + request: NextRequest, + url: URL, +): VisitorAuthCookieValue | undefined { const urlBasePaths = getUrlBasePathCombinations(url); // Try to find a visitor authentication token for the current URL. The request // for the content could be hosted on a base path like `/foo/v/bar` or `/foo` or just `/` @@ -90,14 +96,17 @@ function getVisitorAuthTokenFromCookies(request: NextRequest, url: URL): string function findVisitorAuthCookieForBasePath( request: NextRequest, basePath: string, -): string | undefined { - return Array.from(request.cookies).reduce((acc, [name, cookie]) => { - if (name === getVisitorAuthCookieName(basePath)) { - const value = JSON.parse(cookie.value) as VisitorAuthCookieValue; - if (value.basePath === basePath) { - acc = value.token; +): VisitorAuthCookieValue | undefined { + return Array.from(request.cookies).reduce( + (acc, [name, cookie]) => { + if (name === getVisitorAuthCookieName(basePath)) { + const value = JSON.parse(cookie.value) as VisitorAuthCookieValue; + if (value.basePath === basePath) { + acc = value; + } } - } - return acc; - }, undefined); + return acc; + }, + undefined, + ); } diff --git a/src/middleware.ts b/src/middleware.ts index 9de61c27b..b2e926fe9 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -22,6 +22,7 @@ import { buildVersion } from '@/lib/build'; import { createContentSecurityPolicyNonce, getContentSecurityPolicy } from '@/lib/csp'; import { getURLLookupAlternatives, normalizeURL } from '@/lib/middleware'; import { + VisitorAuthCookieValue, getVisitorAuthCookieName, getVisitorAuthCookieValue, getVisitorAuthToken, @@ -588,7 +589,7 @@ async function lookupSpaceInMultiPathMode(request: NextRequest, url: URL): Promi */ async function lookupSpaceByAPI( lookupURL: URL, - visitorAuthToken: string | undefined, + visitorAuthToken: ReturnType, ): Promise { const url = stripURLSearch(lookupURL); const lookup = getURLLookupAlternatives(url); @@ -598,9 +599,17 @@ async function lookupSpaceByAPI( ); const result = await race(lookup.urls, async (alternative, { signal }) => { - const data = await getPublishedContentByUrl(alternative.url, visitorAuthToken, { - signal, - }); + const data = await getPublishedContentByUrl( + alternative.url, + typeof visitorAuthToken === 'undefined' + ? undefined + : typeof visitorAuthToken === 'string' + ? visitorAuthToken + : visitorAuthToken.token, + { + signal, + }, + ); if ('error' in data) { if (alternative.primary) { @@ -672,22 +681,36 @@ async function lookupSpaceByAPI( */ function getLookupResultForVisitorAuth( basePath: string, - visitorAuthToken: string, + visitorAuthToken: string | VisitorAuthCookieValue, ): Partial { return { // No caching for content served with visitor auth cacheMaxAge: undefined, cacheTags: [], cookies: { - [getVisitorAuthCookieName(basePath)]: { - value: getVisitorAuthCookieValue(basePath, visitorAuthToken), - options: { - httpOnly: true, - sameSite: 'none', - secure: process.env.NODE_ENV === 'production', - maxAge: 7 * 24 * 60 * 60, - }, - }, + /** + * If the visitorAuthToken has been retrieved from a cookie, we set it back only + * if the basePath matches the current one. This is to avoid setting cookie for + * different base paths. + */ + ...(typeof visitorAuthToken === 'string' || visitorAuthToken.basePath === basePath + ? { + [getVisitorAuthCookieName(basePath)]: { + value: getVisitorAuthCookieValue( + basePath, + typeof visitorAuthToken === 'string' + ? visitorAuthToken + : visitorAuthToken.token, + ), + options: { + httpOnly: true, + sameSite: 'none', + secure: process.env.NODE_ENV === 'production', + maxAge: 7 * 24 * 60 * 60, + }, + }, + } + : {}), }, }; } From 8f5f6c61f81f96a3075a8bbe23df1f85acefef63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Mon, 13 May 2024 16:10:15 +0200 Subject: [PATCH 3/4] Setup the pull_request workflow on actions (#2311) --- .github/workflows/ci.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f02719242..ec6def228 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,5 +1,9 @@ -on: [push] name: CI +on: + pull_request: + push: + branches: + - main jobs: deploy: From 5d73a0f062b0655f4f3713790ea2101be17dcbd3 Mon Sep 17 00:00:00 2001 From: fuyangpengqi <167312867+fuyangpengqi@users.noreply.github.com> Date: Mon, 13 May 2024 22:22:07 +0800 Subject: [PATCH 4/4] chore: fix some typos in README.md (#2290) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fuyangpengqi <995764973@qq.com> Co-authored-by: Samy Pessé --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f011225fa..482e67f65 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ GitBook's rendering engine is fully open-source and built on top of [Next.js](ht ### Types of contributions -We encourage you to contribute to GitBook to help us build the best tool for doucmenting techincal knowledge. If you're looking for some quick ways to contribute, continue reading to learn more about popular contributions. +We encourage you to contribute to GitBook to help us build the best tool for documenting technical knowledge. If you're looking for some quick ways to contribute, continue reading to learn more about popular contributions. #### Translations @@ -92,7 +92,7 @@ Encounter a bug or find an issue you'd like to fix? Helping us fix issues relate > > _Looking to add a specific feature in GitBook? Head to our [contributing guide](/.github/CONTRIBUTING.md) to get started._ > -> Self-hosting this project puts the responsibility of maintaining and merging future updates on **you**. We cannot guarantee support, maintainance, or updates to forked and self-hosted instances of this project. +> Self-hosting this project puts the responsibility of maintaining and merging future updates on **you**. We cannot guarantee support, maintenance, or updates to forked and self-hosted instances of this project. > > We want to make it as easy as possible for our community to collaborate and push the future of GitBook, which is why we encourage you to contribute to our product directly instead of creating your own version.