Skip to content

Commit

Permalink
chore(supabase-mw): Return tuple from initSupabaseMw to prevent accid…
Browse files Browse the repository at this point in the history
…ental misconfiguration (redwoodjs#10687)

Supabase equivalent of this:
redwoodjs#10642

Instead of returning middleware we now return `[middleware, '*']`. This
reduces the chance of the user accidentally not configuring the
middleware for certain routes
  • Loading branch information
dac09 committed May 28, 2024
1 parent 95a91ce commit f1eb271
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 21 deletions.
4 changes: 2 additions & 2 deletions packages/auth-providers/supabase/middleware/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ NOTE: This README needs to be updated when the Supabase Web Auth will create a c
import type { TagDescriptor } from '@redwoodjs/web'

import App from './App'
import createSupabaseAuthMiddleware from '@redwoodjs/auth-supabase-middleware'
import initSupabaseMiddleware from '@redwoodjs/auth-supabase-middleware'
import { Document } from './Document'

import { getCurrentUser } from '$api/src/lib/auth'
Expand All @@ -21,7 +21,7 @@ interface Props {
}

export const registerMiddleware = () => {
const supabaseAuthMiddleware = createSupabaseAuthMiddleware({
const supabaseAuthMiddleware = initSupabaseMiddleware({
// Optional. If not set, Supabase will use its own `currentUser` function
// instead of your app's
getCurrentUser,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
MiddlewareResponse,
} from '@redwoodjs/vite/middleware'

import createSupabaseAuthMiddleware from '../index'
import initSupabaseAuthMiddleware from '../index'
import type { SupabaseAuthMiddlewareOptions } from '../index'
const FIXTURE_PATH = path.resolve(
__dirname,
Expand All @@ -33,8 +33,6 @@ vi.mock('jsonwebtoken', () => {
}
})

// })

vi.mock('@redwoodjs/auth-supabase-api', () => {
return {
authDecoder: vi.fn(() => {
Expand Down Expand Up @@ -75,7 +73,7 @@ const options: SupabaseAuthMiddlewareOptions = {

describe('createSupabaseAuthMiddleware()', () => {
it('creates middleware for Supabase SSR auth', async () => {
const middleware = createSupabaseAuthMiddleware(options)
const [middleware] = initSupabaseAuthMiddleware(options)
const request = new Request('http://localhost:8911', {
method: 'GET',
headers: new Headers(),
Expand All @@ -94,7 +92,7 @@ describe('createSupabaseAuthMiddleware()', () => {
})

it('passes through non-authenticated requests', async () => {
const middleware = createSupabaseAuthMiddleware(options)
const [middleware] = initSupabaseAuthMiddleware(options)
const request = new Request('http://localhost:8911', {
method: 'GET',
headers: new Headers(),
Expand All @@ -104,13 +102,13 @@ describe('createSupabaseAuthMiddleware()', () => {

const result = await middleware(req, res)
expect(result).toEqual(res)
expect(result.body).toEqual('original response body')
expect(result?.body).toEqual('original response body')

const serverAuthState = req.serverAuthState.get()
expect(serverAuthState).toEqual(middlewareDefaultAuthProviderState)
})
it('passes through when no auth-provider cookie', async () => {
const middleware = createSupabaseAuthMiddleware(options)
const [middleware] = initSupabaseAuthMiddleware(options)
const request = new Request('http://localhost:8911', {
method: 'GET',
headers: new Headers({
Expand All @@ -124,14 +122,14 @@ describe('createSupabaseAuthMiddleware()', () => {

const result = await middleware(req, res)
expect(result).toEqual(res)
expect(result.body).toEqual('original response body when no auth provider')
expect(result?.body).toEqual('original response body when no auth provider')

const serverAuthState = req.serverAuthState.get()
expect(serverAuthState).toEqual(middlewareDefaultAuthProviderState)
})

it('passes through when unsupported auth-provider', async () => {
const middleware = createSupabaseAuthMiddleware(options)
const [middleware] = initSupabaseAuthMiddleware(options)
const request = new Request('http://localhost:8911', {
method: 'GET',
headers: new Headers({ cookie: 'auth-provider=unsupported' }),
Expand All @@ -143,15 +141,15 @@ describe('createSupabaseAuthMiddleware()', () => {

const result = await middleware(req, res)
expect(result).toEqual(res)
expect(result.body).toEqual(
expect(result?.body).toEqual(
'original response body for unsupported provider',
)
const serverAuthState = req.serverAuthState.get()
expect(serverAuthState).toEqual(middlewareDefaultAuthProviderState)
})

it('handles current user GETs', async () => {
const middleware = createSupabaseAuthMiddleware(options)
const [middleware] = initSupabaseAuthMiddleware(options)
const request = new Request(
'http://localhost:8911/middleware/supabase/currentUser',
{
Expand All @@ -163,7 +161,7 @@ describe('createSupabaseAuthMiddleware()', () => {
const res = new MiddlewareResponse()

const result = await middleware(req, res)
expect(result.body).toEqual(
expect(result?.body).toEqual(
JSON.stringify({
currentUser: { id: 1, email: 'user-1@example.com' },
}),
Expand All @@ -175,7 +173,7 @@ describe('createSupabaseAuthMiddleware()', () => {
})

it('authenticated request sets currentUser', async () => {
const middleware = createSupabaseAuthMiddleware(options)
const [middleware] = initSupabaseAuthMiddleware(options)
const request = new Request('http://localhost:8911/authenticated-request', {
method: 'GET',
headers: new Headers({
Expand Down Expand Up @@ -210,7 +208,7 @@ describe('createSupabaseAuthMiddleware()', () => {
},
}

const middleware = createSupabaseAuthMiddleware(optionsWithUserMetadata)
const [middleware] = initSupabaseAuthMiddleware(optionsWithUserMetadata)
const request = new Request('http://localhost:8911/authenticated-request', {
method: 'GET',
headers: new Headers({
Expand Down Expand Up @@ -240,6 +238,7 @@ describe('createSupabaseAuthMiddleware()', () => {
})

it('an exception when getting the currentUser clears out serverAuthState and cookies', async () => {
vi.spyOn(console, 'error').mockImplementation(() => {})
const optionsWithUserMetadata: SupabaseAuthMiddlewareOptions = {
getCurrentUser: async () => {
// this simulates a decoding error or some other issue like tampering with the cookie so the Supabase session is invalid
Expand All @@ -248,7 +247,7 @@ describe('createSupabaseAuthMiddleware()', () => {
},
}

const middleware = createSupabaseAuthMiddleware(optionsWithUserMetadata)
const [middleware] = initSupabaseAuthMiddleware(optionsWithUserMetadata)

// the default cookie name will always be sb-<project_ref>-auth-token (e.g. sb-example-auth-token )
const request = new Request('http://localhost:8911/authenticated-request', {
Expand Down Expand Up @@ -292,5 +291,7 @@ describe('createSupabaseAuthMiddleware()', () => {
'expires',
new Date(0),
)

vi.resetAllMocks()
})
})
14 changes: 10 additions & 4 deletions packages/auth-providers/supabase/middleware/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { AUTH_PROVIDER_HEADER } from '@redwoodjs/api'
import { authDecoder } from '@redwoodjs/auth-supabase-api'
import type { GetCurrentUser } from '@redwoodjs/graphql-server'
import type {
Middleware,
MiddlewareRequest,
MiddlewareResponse,
} from '@redwoodjs/vite/middleware'
Expand All @@ -15,10 +16,13 @@ export interface SupabaseAuthMiddlewareOptions {
/**
* Create Supabase Auth Middleware that sets the `serverAuthState` based on the Supabase cookie.
*/
const createSupabaseAuthMiddleware = ({
const initSupabaseAuthMiddleware = ({
getCurrentUser,
}: SupabaseAuthMiddlewareOptions) => {
return async (req: MiddlewareRequest, res: MiddlewareResponse) => {
}: SupabaseAuthMiddlewareOptions): [Middleware, '*'] => {
const middleware = async (
req: MiddlewareRequest,
res: MiddlewareResponse,
) => {
const type = 'supabase'
const cookieHeader = req.headers.get('cookie')

Expand Down Expand Up @@ -77,5 +81,7 @@ const createSupabaseAuthMiddleware = ({

return res
}

return [middleware, '*']
}
export default createSupabaseAuthMiddleware
export default initSupabaseAuthMiddleware

0 comments on commit f1eb271

Please sign in to comment.