Skip to content

Commit 37adfa5

Browse files
committed
Make it forward cookies from authState
1 parent a8f0e33 commit 37adfa5

6 files changed

Lines changed: 66 additions & 43 deletions

File tree

packages/api/src/auth/index.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ export interface AuthorizationHeader {
2929
export const parseAuthorizationHeader = (
3030
event: APIGatewayProxyEvent
3131
): AuthorizationHeader => {
32+
console.log(`👉 \n ~ file: index.ts:33 ~ event.headers:`, event.headers)
33+
if (event.headers.cookie) {
34+
return {
35+
schema: 'cookie',
36+
token: event.headers.cookie,
37+
}
38+
}
3239
const parts = (
3340
event.headers?.authorization || event.headers?.Authorization
3441
)?.split(' ')
@@ -44,13 +51,13 @@ export const parseAuthorizationHeader = (
4451

4552
export type AuthContextPayload = [
4653
Decoded,
47-
{ type: string } & AuthorizationHeader,
54+
{ type: string | null } & AuthorizationHeader,
4855
{ event: APIGatewayProxyEvent; context: LambdaContext }
4956
]
5057

5158
export type Decoder = (
5259
token: string,
53-
type: string,
60+
type: string | null,
5461
req: { event: APIGatewayProxyEvent; context: LambdaContext }
5562
) => Promise<Decoded>
5663

@@ -67,14 +74,6 @@ export const getAuthenticationContext = async ({
6774
event: APIGatewayProxyEvent
6875
context: LambdaContext
6976
}): Promise<undefined | AuthContextPayload> => {
70-
const type = getAuthProviderHeader(event)
71-
72-
// No `auth-provider` header means that the user is logged out,
73-
// and none of this auth malarky is required.
74-
if (!type) {
75-
return undefined
76-
}
77-
7877
const { schema, token } = parseAuthorizationHeader(event)
7978

8079
let authDecoders: Array<Decoder> = []
@@ -89,9 +88,9 @@ export const getAuthenticationContext = async ({
8988

9089
let i = 0
9190
while (!decoded && i < authDecoders.length) {
92-
decoded = await authDecoders[i](token, type, { event, context })
91+
decoded = await authDecoders[i](token, null, { event, context })
9392
i++
9493
}
9594

96-
return [decoded, { type, schema, token }, { event, context }]
95+
return [decoded, { type: null, schema, token }, { event, context }]
9796
}

packages/auth-providers/dbAuth/api/src/decoder.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import type { Decoder } from '@redwoodjs/api'
55
import { dbAuthSession } from './shared'
66

77
export const createAuthDecoder = (cookieNameOption: string): Decoder => {
8-
return async (_token, type, req) => {
9-
if (type !== 'dbAuth') {
10-
return null
11-
}
8+
return async (_token, _type, req) => {
9+
// if (type !== 'dbAuth') {
10+
// return null
11+
// }
1212

1313
const session = dbAuthSession(req.event, cookieNameOption)
1414

@@ -21,12 +21,13 @@ export const createAuthDecoder = (cookieNameOption: string): Decoder => {
2121
/** @deprecated use `createAuthDecoder` */
2222
export const authDecoder: Decoder = async (
2323
_authHeaderValue: string, // Browser: 4, FEServer: encryptedSession
24-
type: string,
24+
type: string | null,
2525
req: { event: APIGatewayProxyEvent }
2626
) => {
27-
if (type !== 'dbAuth') {
28-
return null
29-
}
27+
console.log(`👉 \n ~ file: decoder.ts:27 ~ type:`, type)
28+
// if (type !== 'dbAuth') {
29+
// return null
30+
// }
3031

3132
// Passing `undefined` as the second argument to `dbAuthSession` will make
3233
// it fall back to the default cookie name `session`, making it backwards

packages/auth-providers/dbAuth/api/src/shared.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ export const dbAuthSession = (
186186
const [session, _csrfToken] = decryptSession(
187187
getSession(cookieHeader, cookieNameOption)
188188
)
189+
console.log(`👉 \n ~ file: shared.ts:190 ~ session:`, session)
189190
return session
190191
} else if (sessionInAuthHeader) {
191192
// i.e. FE Sever makes the request, and adds encrypted session to the Authorization header

packages/auth/src/AuthProvider/ServerAuthProvider.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import type { AuthProviderState } from './AuthProviderState'
44
import { defaultAuthProviderState } from './AuthProviderState'
55

66
export const ServerAuthContext = React.createContext<
7-
AuthProviderState<never> & { encryptedSession: string | null }
7+
AuthProviderState<never> & {
8+
encryptedSession: string | null
9+
cookieHeader?: string
10+
}
811
>({ ...defaultAuthProviderState, encryptedSession: null })
912

1013
export const ServerAuthProvider = ServerAuthContext.Provider

packages/web/src/apollo/links.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,24 @@ import { print } from 'graphql/language/printer'
55

66
export function createHttpLink(
77
uri: string,
8-
httpLinkConfig: HttpOptions | undefined
8+
httpLinkConfig: HttpOptions | undefined,
9+
cookieHeader?: string
910
) {
11+
const headers: Record<string, string> = {}
12+
13+
if (cookieHeader) {
14+
headers.cookie = cookieHeader
15+
}
16+
1017
return new HttpLink({
1118
// @MARK: we have to construct the absoltue url for SSR
1219
uri,
1320
...httpLinkConfig,
1421
// you can disable result caching here if you want to
1522
// (this does not work if you are rendering your page with `export const dynamic = "force-static"`)
1623
fetchOptions: { cache: 'no-store' },
24+
credentials: 'include',
25+
headers,
1726
})
1827
}
1928
export function createUpdateDataLink(data: any) {
@@ -107,8 +116,8 @@ export type RedwoodApolloLink<
107116
}
108117

109118
export type RedwoodApolloLinks = [
110-
RedwoodApolloLink<'withToken'>,
111-
RedwoodApolloLink<'authMiddleware'>,
119+
// RedwoodApolloLink<'withToken'>,
120+
// RedwoodApolloLink<'authMiddleware'>,
112121
RedwoodApolloLink<'updateDataApolloLink'>,
113122
RedwoodApolloLink<'httpLink', HttpLink>
114123
]

packages/web/src/apollo/suspense.tsx

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
* Eventually we will have one ApolloProvider, not multiple.
88
*/
99

10+
import { useContext } from 'react'
11+
1012
import type {
1113
ApolloCache,
1214
ApolloClientOptions,
15+
ApolloLink,
1316
HttpOptions,
1417
InMemoryCacheConfig,
1518
setLogVerbosity,
16-
ApolloLink,
1719
} from '@apollo/client'
1820
import {
1921
setLogVerbosity as apolloSetLogVerbosity,
@@ -24,14 +26,14 @@ import {
2426
ApolloNextAppProvider,
2527
NextSSRApolloClient,
2628
NextSSRInMemoryCache,
27-
useSuspenseQuery,
2829
useBackgroundQuery,
29-
useReadQuery,
3030
useQuery,
31+
useReadQuery,
32+
useSuspenseQuery,
3133
} from '@apollo/experimental-nextjs-app-support/ssr'
3234

3335
import type { UseAuth } from '@redwoodjs/auth'
34-
import { useNoAuth } from '@redwoodjs/auth'
36+
import { ServerAuthContext, useNoAuth } from '@redwoodjs/auth'
3537
import './typeOverride'
3638

3739
import {
@@ -46,13 +48,7 @@ import type {
4648
RedwoodApolloLinkName,
4749
RedwoodApolloLinks,
4850
} from './links'
49-
import {
50-
createAuthApolloLink,
51-
createFinalLink,
52-
createHttpLink,
53-
createTokenLink,
54-
createUpdateDataLink,
55-
} from './links'
51+
import { createFinalLink, createHttpLink, createUpdateDataLink } from './links'
5652

5753
export type ApolloClientCacheConfig = InMemoryCacheConfig
5854

@@ -120,12 +116,13 @@ const ApolloProviderWithFetchConfig: React.FunctionComponent<{
120116
logLevel: ReturnType<typeof setLogVerbosity>
121117
children: React.ReactNode
122118
}> = ({ config, children, useAuth = useNoAuth, logLevel }) => {
119+
console.log(`👉 \n ~ file: suspense.tsx:119 ~ useAuth:`, useAuth)
123120
// Should they run into it, this helps users with the "Cannot render cell; GraphQL success but data is null" error.
124121
// See https://github.com/redwoodjs/redwood/issues/2473.
125122
apolloSetLogVerbosity(logLevel)
126123

127124
// See https://www.apollographql.com/docs/react/api/link/introduction.
128-
const { getToken, type: authProviderType } = useAuth()
125+
// const { getToken, type: authProviderType } = useAuth()
129126

130127
// `updateDataApolloLink` keeps track of the most recent req/res data so they can be passed to
131128
// any errors passed up to an error boundary.
@@ -134,7 +131,13 @@ const ApolloProviderWithFetchConfig: React.FunctionComponent<{
134131
mostRecentResponse: undefined,
135132
} as any
136133

137-
const { headers, uri } = useFetchConfig()
134+
const { uri } = useFetchConfig()
135+
136+
const serverAuthState = useContext(ServerAuthContext)
137+
console.log(
138+
`👉 \n ~ file: suspense.tsx:142 ~ serverAuthState:`,
139+
serverAuthState
140+
)
138141

139142
const getGraphqlUrl = () => {
140143
// @NOTE: This comes from packages/vite/src/streaming/registerGlobals.ts
@@ -152,14 +155,21 @@ const ApolloProviderWithFetchConfig: React.FunctionComponent<{
152155

153156
// We use this object, because that's the shape of what we pass to the config.link factory
154157
const redwoodApolloLinks: RedwoodApolloLinks = [
155-
{ name: 'withToken', link: createTokenLink(getToken) },
156-
{
157-
name: 'authMiddleware',
158-
link: createAuthApolloLink(authProviderType, headers),
159-
},
158+
// { name: 'withToken', link: createTokenLink(getToken) },
159+
// {
160+
// name: 'authMiddleware',
161+
// link: createAuthApolloLink(authProviderType, headers),
162+
// },
160163
// @TODO: do we need this in prod? I think it's only for dev errors
161164
{ name: 'updateDataApolloLink', link: createUpdateDataLink(data) },
162-
{ name: 'httpLink', link: createHttpLink(getGraphqlUrl(), httpLinkConfig) },
165+
{
166+
name: 'httpLink',
167+
link: createHttpLink(
168+
getGraphqlUrl(),
169+
httpLinkConfig,
170+
serverAuthState.cookieHeader
171+
),
172+
},
163173
]
164174

165175
const extendErrorAndRethrow = (error: any, _errorInfo: React.ErrorInfo) => {

0 commit comments

Comments
 (0)