Skip to content

Commit 0979725

Browse files
committed
Get it working with middleware!
1 parent 3f0a32b commit 0979725

File tree

6 files changed

+92
-15
lines changed

6 files changed

+92
-15
lines changed

packages/api/src/auth/__tests__/getAuthenticationContext.test.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,47 @@ describe('getAuthenticationContext with bearer tokens', () => {
212212
})
213213

214214
// @TODO add tests for requests with Cookie headers
215-
describe('getAuthenticationContext with cookies', () => {})
215+
describe('getAuthenticationContext with cookies', () => {
216+
it('Can take a single auth decoder for the given provider', async () => {
217+
const authDecoderOne = async (_token: string, type: string) => {
218+
if (type !== 'one') {
219+
return null
220+
}
221+
222+
return {
223+
iss: 'one',
224+
sub: 'user-id',
225+
}
226+
}
227+
228+
const fetchRequest = new Request('http://localhost:3000', {
229+
method: 'POST',
230+
body: '',
231+
headers: {
232+
cookie: 'auth-provider=one; session=xx/yy/zz',
233+
},
234+
})
235+
236+
const result = await getAuthenticationContext({
237+
authDecoder: authDecoderOne,
238+
event: fetchRequest,
239+
context: {} as Context,
240+
})
241+
242+
if (!result) {
243+
fail('Result is undefined')
244+
}
245+
246+
const [decoded, { type, schema, token }] = result
247+
248+
expect(decoded).toMatchObject({
249+
iss: 'one',
250+
sub: 'user-id',
251+
})
252+
expect(type).toEqual('one')
253+
expect(schema).toEqual('cookie')
254+
// @TODO we need to rename this. It's not actually the token, because
255+
// some auth providers will have a cookie where we don't know the key
256+
expect(token).toEqual('auth-provider=one; session=xx/yy/zz')
257+
})
258+
})

packages/api/src/auth/index.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,16 @@ export type { Decoded }
1212
// This is shared by `@redwoodjs/web`
1313
const AUTH_PROVIDER_HEADER = 'auth-provider'
1414

15-
export const getAuthProviderHeader = (event: APIGatewayProxyEvent) => {
15+
export const getAuthProviderHeader = (
16+
event: APIGatewayProxyEvent | Request
17+
) => {
1618
const authProviderKey = Object.keys(event?.headers ?? {}).find(
1719
(key) => key.toLowerCase() === AUTH_PROVIDER_HEADER
1820
)
1921
if (authProviderKey) {
20-
return event?.headers[authProviderKey]
22+
return isFetchApiRequest(event)
23+
? event?.headers.get(authProviderKey)
24+
: event?.headers[authProviderKey]
2125
}
2226
return undefined
2327
}
@@ -44,7 +48,7 @@ export const parseAuthorizationCookie = (
4448
return {
4549
parsedCookie,
4650
rawCookie: cookie,
47-
type: parsedCookie.authProvider,
51+
type: parsedCookie['auth-provider'],
4852
}
4953
}
5054

@@ -89,11 +93,11 @@ export const getAuthenticationContext = async ({
8993
context,
9094
}: {
9195
authDecoder?: Decoder | Decoder[]
92-
event: APIGatewayProxyEvent
96+
event: APIGatewayProxyEvent | Request
9397
context: LambdaContext
9498
}): Promise<undefined | AuthContextPayload> => {
9599
const typeFromHeader = getAuthProviderHeader(event)
96-
const cookieHeader = parseAuthorizationCookie(event)
100+
const cookieHeader = parseAuthorizationCookie(event) //?
97101

98102
// Shortcircuit - if no auth-provider or cookie header, its
99103
// an unauthenticated request
@@ -107,7 +111,7 @@ export const getAuthenticationContext = async ({
107111

108112
// If type is set in the header, use Bearer token auth
109113
if (typeFromHeader) {
110-
const parsedAuthHeader = parseAuthorizationHeader(event)
114+
const parsedAuthHeader = parseAuthorizationHeader(event as any)
111115
token = parsedAuthHeader.token
112116
type = typeFromHeader
113117
schema = parsedAuthHeader.schema
@@ -136,9 +140,15 @@ export const getAuthenticationContext = async ({
136140

137141
let i = 0
138142
while (!decoded && i < authDecoders.length) {
139-
decoded = await authDecoders[i](token, type, { event, context })
143+
decoded = await authDecoders[i](token, type, {
144+
// @TODO We will need to make a breaking change to auth decoders maybe
145+
event: event as any,
146+
context,
147+
})
140148
i++
141149
}
142150

143-
return [decoded, { type, schema, token }, { event, context }]
151+
// @TODO we need to rename this. It's not actually the token, because
152+
// some auth providers will have a cookie where we don't know the key
153+
return [decoded, { type, schema, token }, { event: event as any, context }]
144154
}

packages/api/src/transforms.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,21 @@ export const parseFetchEventBody = async (event: Request) => {
4747
return body ? JSON.parse(body) : undefined
4848
}
4949

50+
// @TODO
51+
// @TODO
52+
// @TODO
53+
// THis is in a hacked state. Need to figure out why instanceof isn't working in middleware
5054
export const isFetchApiRequest = (event: any): event is Request => {
51-
return event instanceof Request || event instanceof PonyFillRequest
55+
if (event instanceof Request || event instanceof PonyFillRequest) {
56+
return true
57+
}
58+
59+
if (event.httpMethod || event.queryStringParameters) {
60+
return false
61+
}
62+
63+
// @TODO I dont know why instance of Request is not working in middleware
64+
return true
5265
}
5366

5467
function getQueryStringParams(reqUrl: string) {

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,10 @@ export class DbAuthHandler<
393393
this.options = options
394394
this.event = event
395395
this.httpMethod = isFetchApiRequest(event) ? event.method : event.httpMethod
396+
console.log(
397+
`👉 \n ~ file: DbAuthHandler.ts:396 ~ isFetchApiRequest(event):`,
398+
isFetchApiRequest(event)
399+
)
396400

397401
this.cookie = extractCookie(event) || ''
398402

packages/auth-providers/dbAuth/web/src/dbAuth.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ export function createDbAuthClient({
121121
body: JSON.stringify({ username, password, method: 'login' }),
122122
})
123123

124+
if (typeof window !== undefined) {
125+
document.cookie = 'auth-provider=dbAuth'
126+
}
127+
124128
return response.json()
125129
}
126130

packages/vite/src/devFeServer.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Response, createServerAdapter } from '@whatwg-node/server'
1+
import { createServerAdapter } from '@whatwg-node/server'
22
import express from 'express'
33
import type { ViteDevServer } from 'vite'
44
import { createServer as createViteServer } from 'vite'
@@ -82,7 +82,9 @@ async function createServer() {
8282
app.get(expressPathDef, createServerAdapter(routeHandler))
8383
}
8484

85-
app.post(
85+
// @TODO: DbAuth still sends a GET request for getToken
86+
// Do we still need getToken if gets updated by middleware anyway?
87+
app.all(
8688
'/_rw_mw',
8789
createServerAdapter(async (req: Request) => {
8890
const entryServerImport = await vite.ssrLoadModule(
@@ -95,13 +97,14 @@ async function createServer() {
9597
if (middleware) {
9698
try {
9799
out = await middleware(req)
98-
console.log(`👉 \n ~ file: devFeServer.ts:97 ~ out:`, out)
99100
} catch (e) {
100-
console.error('Whooopsie, error in middleware', e)
101+
console.error('Whooopsie, error in middleware POST handler')
102+
console.error(e)
101103
}
102104
}
103105

104-
return new Response(out)
106+
// @TODO: We should check the type of resposne here I guess
107+
return out
105108
})
106109
)
107110

0 commit comments

Comments
 (0)