Merge pull request #25823 from stephenglass/fix-redirect-error-handling

Fix error handling using auth redirect flow
This commit is contained in:
Patrik Oldsberg
2024-10-14 16:26:23 +02:00
committed by GitHub
5 changed files with 80 additions and 8 deletions
@@ -742,5 +742,33 @@ describe('createOAuthRouteHandlers', () => {
},
});
});
it('should set error search param and redirect on caught error', async () => {
const app = wrapInApp(createOAuthRouteHandlers(baseConfig));
const res = await request(app)
.get('/my-provider/handler/frame')
.query({
state: encodeOAuthState({
env: 'development',
nonce: '123',
flow: 'redirect',
redirectUrl: 'http://localhost:3000',
}),
});
// Check if it redirects on error
expect(res.status).toBe(302);
// Extract the redirect URL from the location header
const redirectLocation = res.header.location;
expect(redirectLocation).toBeDefined();
// Create a URL object from the redirect location
const redirectUrl = new URL(redirectLocation);
// Verify that the 'error' search param is set with the encoded error message
const errorMessage = redirectUrl.searchParams.get('error');
expect(errorMessage).toBe('Auth response is missing cookie nonce');
});
});
});
@@ -164,9 +164,10 @@ export function createOAuthRouteHandlers<TProfile>(
res: express.Response,
): Promise<void> {
let origin = defaultAppOrigin;
let state;
try {
const state = decodeOAuthState(req.query.state?.toString() ?? '');
state = decodeOAuthState(req.query.state?.toString() ?? '');
if (state.origin) {
try {
@@ -248,11 +249,20 @@ export function createOAuthRouteHandlers<TProfile>(
const { name, message } = isError(error)
? error
: new Error('Encountered invalid error'); // Being a bit safe and not forwarding the bad value
// post error message back to popup if failure
sendWebMessageResponse(res, origin, {
type: 'authorization_response',
error: { name, message },
});
if (state?.flow === 'redirect' && state?.redirectUrl) {
const redirectUrl = new URL(state.redirectUrl);
redirectUrl.searchParams.set('error', message);
// set the error in a cookie and redirect user back to sign in where the error can be rendered
res.redirect(redirectUrl.toString());
} else {
// post error message back to popup if failure
sendWebMessageResponse(res, origin, {
type: 'authorization_response',
error: { name, message },
});
}
}
},