-
Notifications
You must be signed in to change notification settings - Fork 982
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(server-auth): Part 1/3: dbAuth middleware support (web side chan…
…ges) (#10444) Closes #10445 **Part 1/3: dbAuth middleware support** ~1. Updates dbAuthHandler to handle POST requests for login, logout, signup via the middleware~ taking this out of this PR, and going to PR separately. 2. Updates the dbAuth web client to speak to middleware instead of graphql 3. Implements fetching current user from middleware **What it does not have:** - actual middleware - when SSR/RSC is enabled AND you're logged in, graphql requests will fail with 500, because auth context hasn't been updated yet to support cookies (https://github.com/orgs/redwoodjs/projects/18/views/1?query=is%3Aopen+sort%3Aupdated-desc&pane=issue&itemId=59446357) **Before merging this:** - [x] Validate graphql auth is not broken ~- [ ] Validate webAuthN + graphql is not broken~ ~-[ ] Merge dbAuthHandler and tests again!~ Moved to separate PR
- Loading branch information
Showing
7 changed files
with
296 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
- feat(server-auth): Part 1/3: dbAuth middleware support (web side changes) (#10444) by @dac09 | ||
Adds ability to `createMiddlewareAuth` in dbAuth client which: | ||
1. Updates the dbAuth web client to speak to middleware instead of graphql | ||
2. Implements fetching current user from middleware |
150 changes: 150 additions & 0 deletions
150
packages/auth-providers/dbAuth/web/src/__tests__/dbAuth.middleware.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import { act, renderHook } from '@testing-library/react' | ||
|
||
import type { CustomProviderHooks, DbAuthClientArgs } from '../dbAuth' | ||
import { createDbAuthClient, createMiddlewareAuth } from '../dbAuth' | ||
|
||
import { fetchMock } from './dbAuth.test' | ||
|
||
const defaultArgs = { | ||
fetchConfig: { | ||
credentials: 'include' as const, | ||
}, | ||
} | ||
|
||
export function getMwDbAuth( | ||
args: DbAuthClientArgs & CustomProviderHooks = defaultArgs, | ||
) { | ||
// We have to create a special createDbAuthClient with middleware = true | ||
const dbAuthClient = createDbAuthClient({ ...args, middleware: true }) | ||
const { useAuth, AuthProvider } = createMiddlewareAuth(dbAuthClient, { | ||
useCurrentUser: args.useCurrentUser, | ||
useHasRole: args.useHasRole, | ||
}) | ||
const { result } = renderHook(() => useAuth(), { | ||
wrapper: AuthProvider, | ||
}) | ||
|
||
return result | ||
} | ||
|
||
// These tests are on top of the other tests in dbAuth.test.ts | ||
// They test the middleware specific things about the dbAuth client | ||
|
||
describe('dbAuth web ~ cookie/middleware auth', () => { | ||
it('will create a middleware version of the auth client', async () => { | ||
const { current: dbAuthInstance } = getMwDbAuth() | ||
|
||
// Middleware auth clients should not return tokens | ||
expect(await dbAuthInstance.getToken()).toBeNull() | ||
|
||
let currentUser | ||
await act(async () => { | ||
currentUser = await dbAuthInstance.getCurrentUser() | ||
}) | ||
|
||
expect(globalThis.fetch).toHaveBeenCalledWith( | ||
// Doesn't speak to graphql! | ||
'/middleware/dbauth/currentUser', | ||
expect.objectContaining({ | ||
credentials: 'include', | ||
method: 'GET', // in mw auth, we use GET for currentUser | ||
}), | ||
) | ||
|
||
expect(currentUser).toEqual({ | ||
id: 'middleware-user-555', | ||
username: 'user@middleware.auth', | ||
}) | ||
}) | ||
|
||
it('can still override getCurrentUser', async () => { | ||
const mockedCustomCurrentUser = jest.fn() | ||
const { current: dbAuthInstance } = getMwDbAuth({ | ||
useCurrentUser: mockedCustomCurrentUser, | ||
}) | ||
await act(async () => { | ||
await dbAuthInstance.getCurrentUser() | ||
}) | ||
|
||
expect(mockedCustomCurrentUser).toHaveBeenCalled() | ||
}) | ||
|
||
it('allows you to override the middleware endpoint', async () => { | ||
const auth = getMwDbAuth({ | ||
dbAuthUrl: '/hello/handsome', | ||
}).current | ||
|
||
await act(async () => await auth.forgotPassword('username')) | ||
|
||
expect(fetchMock).toHaveBeenCalledWith( | ||
'/hello/handsome', | ||
expect.any(Object), | ||
) | ||
}) | ||
|
||
it('calls login at the middleware endpoint', async () => { | ||
const auth = getMwDbAuth().current | ||
|
||
await act( | ||
async () => | ||
await auth.logIn({ username: 'username', password: 'password' }), | ||
) | ||
|
||
expect(globalThis.fetch).toHaveBeenCalledWith( | ||
'/middleware/dbauth', | ||
expect.any(Object), | ||
) | ||
}) | ||
|
||
it('calls middleware endpoint for logout', async () => { | ||
const auth = getMwDbAuth().current | ||
await act(async () => { | ||
await auth.logOut() | ||
}) | ||
|
||
expect(globalThis.fetch).toHaveBeenCalledWith('/middleware/dbauth', { | ||
body: '{"method":"logout"}', | ||
credentials: 'include', | ||
method: 'POST', | ||
}) | ||
}) | ||
|
||
it('calls reset password at the correct endpoint', async () => { | ||
const auth = getMwDbAuth().current | ||
|
||
await act( | ||
async () => | ||
await auth.resetPassword({ | ||
resetToken: 'reset-token', | ||
password: 'password', | ||
}), | ||
) | ||
|
||
expect(globalThis.fetch).toHaveBeenCalledWith( | ||
'/middleware/dbauth', | ||
expect.objectContaining({ | ||
body: '{"resetToken":"reset-token","password":"password","method":"resetPassword"}', | ||
}), | ||
) | ||
}) | ||
|
||
it('passes through fetchOptions to signup calls', async () => { | ||
const auth = getMwDbAuth().current | ||
|
||
await act( | ||
async () => | ||
await auth.signUp({ | ||
username: 'username', | ||
password: 'password', | ||
}), | ||
) | ||
|
||
expect(globalThis.fetch).toHaveBeenCalledWith( | ||
'/middleware/dbauth', | ||
expect.objectContaining({ | ||
method: 'POST', | ||
body: '{"username":"username","password":"password","method":"signup"}', | ||
}), | ||
) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.