From 9fafcf8b116701ecfb8d432ecd42ec76785ccfd0 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Thu, 2 Nov 2023 23:50:43 +0700 Subject: [PATCH] SHIP IT --- packages/api/src/auth/index.ts | 1 - .../dbAuth/api/src/DbAuthHandler.ts | 16 +++++++--------- .../auth-providers/dbAuth/api/src/decoder.ts | 17 +++-------------- .../auth-providers/dbAuth/api/src/shared.ts | 9 +++++---- packages/auth/src/AuthProvider/AuthProvider.tsx | 7 ++----- .../src/AuthProvider/ServerAuthProvider.tsx | 4 ++-- .../streaming/createReactStreamingHandler.ts | 6 +++++- packages/web/src/apollo/links.tsx | 1 - 8 files changed, 24 insertions(+), 37 deletions(-) diff --git a/packages/api/src/auth/index.ts b/packages/api/src/auth/index.ts index 9e843c56118f..ecb189696aa7 100644 --- a/packages/api/src/auth/index.ts +++ b/packages/api/src/auth/index.ts @@ -76,7 +76,6 @@ export const getAuthenticationContext = async ({ } const { schema, token } = parseAuthorizationHeader(event) - console.log(`👉 \n ~ file: index.ts:79 ~ token:`, token) let authDecoders: Array = [] diff --git a/packages/auth-providers/dbAuth/api/src/DbAuthHandler.ts b/packages/auth-providers/dbAuth/api/src/DbAuthHandler.ts index c48ecc8586d1..bdc650dc85c1 100644 --- a/packages/auth-providers/dbAuth/api/src/DbAuthHandler.ts +++ b/packages/auth-providers/dbAuth/api/src/DbAuthHandler.ts @@ -292,6 +292,7 @@ export class DbAuthHandler< corsContext: CorsContext | undefined sessionExpiresDate: string webAuthnExpiresDate: string + encryptedSession: string | null = null // class constant: list of auth methods that are supported static get METHODS(): AuthMethodNames[] { @@ -402,9 +403,9 @@ export class DbAuthHandler< } try { - const [session, csrfToken] = decryptSession( - getSession(this.cookie, this.options.cookie?.name) - ) + this.encryptedSession = getSession(this.cookie, this.options.cookie?.name) + + const [session, csrfToken] = decryptSession(this.encryptedSession) this.session = session this.sessionCsrfToken = csrfToken } catch (e) { @@ -568,12 +569,8 @@ export class DbAuthHandler< async getToken() { try { - const user = await this._getCurrentUser() - - // need to return *something* for our existing Authorization header stuff - // to work, so return the user's ID in case we can use it for something - // in the future - return [user[this.options.authFields.id]] + // Just return the encrypted session cookie, to be passed back in the Authorization header + return [this.encryptedSession || ''] } catch (e: any) { if (e instanceof DbAuthError.NotLoggedInError) { return this._logoutResponse() @@ -1435,6 +1432,7 @@ export class DbAuthHandler< _ok(body: string, headers = {}, options = { statusCode: 200 }) { return { statusCode: options.statusCode, + // @TODO should we do a null check in body?! body: typeof body === 'string' ? body : JSON.stringify(body), headers: { 'Content-Type': 'application/json', ...headers }, } diff --git a/packages/auth-providers/dbAuth/api/src/decoder.ts b/packages/auth-providers/dbAuth/api/src/decoder.ts index 58b12c962bb4..173ed929a406 100644 --- a/packages/auth-providers/dbAuth/api/src/decoder.ts +++ b/packages/auth-providers/dbAuth/api/src/decoder.ts @@ -10,22 +10,17 @@ export const createAuthDecoder = (cookieNameOption: string): Decoder => { return null } - // @TODO for SSR we need to make sure we are passing the cookie from the FE to the BE const session = dbAuthSession(req.event, cookieNameOption) - const authHeaderUserId = token - - if (session.id.toString() !== authHeaderUserId) { - console.error('Authorization header does not match decrypted user ID') - throw new Error('Authorization header does not match decrypted user ID') - } + // We no longer compare the session id with the bearer token + // Because we only pass around the encrypted session (in both cookie and header) return session } } /** @deprecated use `createAuthDecoder` */ export const authDecoder: Decoder = async ( - authHeaderValue: string, + _authHeaderValue: string, // Browser: 4, FEServer: encryptedSession type: string, req: { event: APIGatewayProxyEvent } ) => { @@ -37,12 +32,6 @@ export const authDecoder: Decoder = async ( // it fall back to the default cookie name `session`, making it backwards // compatible with existing RW apps. const session = dbAuthSession(req.event, undefined) - const authHeaderUserId = authHeaderValue - - if (session.id.toString() !== authHeaderUserId) { - console.error('Authorization header does not match decrypted user ID') - throw new Error('Authorization header does not match decrypted user ID') - } return session } diff --git a/packages/auth-providers/dbAuth/api/src/shared.ts b/packages/auth-providers/dbAuth/api/src/shared.ts index 8d2febc04c70..7883bc10d5e5 100644 --- a/packages/auth-providers/dbAuth/api/src/shared.ts +++ b/packages/auth-providers/dbAuth/api/src/shared.ts @@ -35,7 +35,7 @@ export const extractCookie = (event: APIGatewayProxyEvent) => { return eventGraphiQLHeadersCookie(event) || eventHeadersCookie(event) } -function extractSessionFromHeader(event: APIGatewayProxyEvent) { +function extractEncryptedSessionFromHeader(event: APIGatewayProxyEvent) { return event.headers.authorization?.split(' ')[1] } @@ -88,17 +88,18 @@ export const dbAuthSession = ( cookieNameOption: string | undefined ) => { const cookieHeader = extractCookie(event) - const sessionInAuthHeader = extractSessionFromHeader(event) + const sessionInAuthHeader = extractEncryptedSessionFromHeader(event) - if (cookieHeader && !sessionInAuthHeader) { + if (cookieHeader) { + // i.e. Browser making a request const [session, _csrfToken] = decryptSession( getSession(cookieHeader, cookieNameOption) ) return session } else if (sessionInAuthHeader) { + // i.e. FE Sever makes the request, and adds encrypted session to the Authorization header const [session, _csrfToken] = decryptSession(sessionInAuthHeader) - console.log(`👉 \n ~ file: shared.ts:103 ~ session:`, session) return session } else { return null diff --git a/packages/auth/src/AuthProvider/AuthProvider.tsx b/packages/auth/src/AuthProvider/AuthProvider.tsx index aeddfc05c795..1606319f220f 100644 --- a/packages/auth/src/AuthProvider/AuthProvider.tsx +++ b/packages/auth/src/AuthProvider/AuthProvider.tsx @@ -148,13 +148,10 @@ export function createAuthProvider< logIn, logOut, getToken: + // When its rendering on the server, just get the token from the serverAuthState typeof window === 'undefined' ? async () => { - console.log( - 'xxxxx definitely calling this function', - serverAuthState - ) - return serverAuthState.token || null + return serverAuthState.encryptedSession || null } : getToken, getCurrentUser, diff --git a/packages/auth/src/AuthProvider/ServerAuthProvider.tsx b/packages/auth/src/AuthProvider/ServerAuthProvider.tsx index f470e5cb851c..f8bad563347f 100644 --- a/packages/auth/src/AuthProvider/ServerAuthProvider.tsx +++ b/packages/auth/src/AuthProvider/ServerAuthProvider.tsx @@ -4,7 +4,7 @@ import type { AuthProviderState } from './AuthProviderState' import { defaultAuthProviderState } from './AuthProviderState' export const ServerAuthContext = React.createContext< - AuthProviderState & { token: string | null } ->({ ...defaultAuthProviderState, token: null }) + AuthProviderState & { encryptedSession: string | null } +>({ ...defaultAuthProviderState, encryptedSession: null }) export const ServerAuthProvider = ServerAuthContext.Provider diff --git a/packages/vite/src/streaming/createReactStreamingHandler.ts b/packages/vite/src/streaming/createReactStreamingHandler.ts index 47400c6555a4..ac441fa461de 100644 --- a/packages/vite/src/streaming/createReactStreamingHandler.ts +++ b/packages/vite/src/streaming/createReactStreamingHandler.ts @@ -65,7 +65,11 @@ export const createReactStreamingHandler = async ( const middleware = entryServerImport.middleware if (middleware) { - decodedAuthState = await middleware(req) + try { + decodedAuthState = (await middleware(req)).context + } catch (e) { + console.error('Whooopsie, error in middleware', e) + } } } diff --git a/packages/web/src/apollo/links.tsx b/packages/web/src/apollo/links.tsx index 04721652d896..48ccc83d5dbd 100644 --- a/packages/web/src/apollo/links.tsx +++ b/packages/web/src/apollo/links.tsx @@ -44,7 +44,6 @@ export function createAuthApolloLink( ) { return new ApolloLink((operation, forward) => { const { token } = operation.getContext() - // Only add auth headers when there's a token. `token` is `null` when `!isAuthenticated`. const authHeaders = token ? {