-
Notifications
You must be signed in to change notification settings - Fork 283
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(express): Make
requireAuth
middleware flexible (#4159)
- Loading branch information
1 parent
d0960c4
commit d895494
Showing
6 changed files
with
139 additions
and
28 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,5 @@ | ||
--- | ||
"@clerk/express": minor | ||
--- | ||
|
||
Make `requireAuth` middleware more flexible |
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
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
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 |
---|---|---|
@@ -1,31 +1,55 @@ | ||
import { requireAuth } from '../requireAuth'; | ||
import type { NextFunction, Request as ExpressRequest, Response as ExpressResponse } from 'express'; | ||
|
||
import { requireAuth, UnauthorizedError } from '../requireAuth'; | ||
import { mockRequest, mockRequestWithAuth, mockResponse } from './helpers'; | ||
|
||
// This middleware is used to handle the UnauthorizedError thrown by requireAuth | ||
// See https://expressjs.com/en/guide/error-handling.html for handling errors in Express | ||
const errorHandler = (err: Error, _req: ExpressRequest, res: ExpressResponse, next: NextFunction) => { | ||
if (err instanceof UnauthorizedError) { | ||
return res.status(401).send('Unauthorized'); | ||
} | ||
|
||
return next(err); | ||
}; | ||
|
||
describe('requireAuth', () => { | ||
it('throws error if clerkMiddleware is not executed before this middleware', async () => { | ||
expect(() => requireAuth(mockRequest(), mockResponse(), () => undefined)).toThrow( | ||
/The "clerkMiddleware" should be registered before using "requireAuth"/, | ||
); | ||
}); | ||
|
||
it('make application require auth - returns 401 Unauthorized for signed-out', async () => { | ||
it('passes UnauthorizedError to next for unauthenticated requests', () => { | ||
const request = mockRequestWithAuth(); | ||
const response = mockResponse(); | ||
const nextFn = jest.fn(); | ||
const next = jest.fn(); | ||
|
||
requireAuth(request, response, next); | ||
|
||
requireAuth(mockRequestWithAuth(), response, nextFn); | ||
// Simulate how Express would call the error middleware | ||
const error = next.mock.calls[0][0]; | ||
errorHandler(error, request, response, next); | ||
|
||
expect(response.status).toHaveBeenCalledWith(401); | ||
expect(nextFn).not.toHaveBeenCalled(); | ||
expect(response.send).toHaveBeenCalledWith('Unauthorized'); | ||
}); | ||
|
||
it('make application require auth - proceed with next middlewares for signed-in', async () => { | ||
const response = mockResponse(); | ||
const nextFn = jest.fn(); | ||
it('allows access for authenticated requests', async () => { | ||
const request = mockRequestWithAuth({ userId: 'user_1234' }); | ||
const response = mockResponse(); | ||
const next = jest.fn(); | ||
|
||
requireAuth(request, response, next); | ||
|
||
// Simulate a protected route | ||
const protectedRoute = (_req: ExpressRequest, res: ExpressResponse) => { | ||
res.status(200).send('Welcome, user_1234'); | ||
}; | ||
|
||
requireAuth(request, response, nextFn); | ||
protectedRoute(request, response); | ||
|
||
expect(response.status).not.toHaveBeenCalled(); | ||
expect(nextFn).toHaveBeenCalled(); | ||
expect(response.status).toHaveBeenCalledWith(200); | ||
expect(response.send).toHaveBeenCalledWith('Welcome, user_1234'); | ||
}); | ||
}); |
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
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