From 49a6c3cce86e366681bed0d9970af3f10a3e5e1c Mon Sep 17 00:00:00 2001 From: meza Date: Sat, 8 Jul 2023 18:17:59 +0100 Subject: [PATCH] fix: propagated the error query string solution to the remaining locations it was missing --- src/__snapshots__/index.test.ts.snap | 6 ++++++ src/index.test.ts | 16 ++++++++++++++-- src/index.ts | 11 ++++++++--- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/__snapshots__/index.test.ts.snap b/src/__snapshots__/index.test.ts.snap index adfe7ea2..28618bf8 100644 --- a/src/__snapshots__/index.test.ts.snap +++ b/src/__snapshots__/index.test.ts.snap @@ -1,5 +1,11 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`Auth0 Remix Server > getting the user > when the access token is valid > and the user profile fetch fails > redirects to the failed url 1`] = `"/logout?error=test-error"`; + +exports[`Auth0 Remix Server > getting the user > when the token is expired > and there is no other loader refreshing the token > and there is a refresh token > redirects to the failed login url when the refresh fails 1`] = `"/logout?error=test-error2"`; + +exports[`Auth0 Remix Server > getting the user > when there are no credentials returned > redirects to the failed login url 1`] = `"/logout?error=no_credentials"`; + exports[`Auth0 Remix Server > handling the callback token exchange > when there is a code in the exchange as a GET > redirects to the failed login url if the token exchange fails 2`] = ` { "body": "grant_type=authorization_code&client_id=clientId&client_secret=clientSecret&code=test-code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth0%2Fcallback", diff --git a/src/index.test.ts b/src/index.test.ts index 2835ef6c..70c1963c 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -724,6 +724,8 @@ describe('Auth0 Remix Server', () => { const authorizer = new Auth0RemixServer(authOptions); await expect(authorizer.getUser(request, context)).rejects.toThrowError(redirectError); // a redirect happened + const redirectUrl = vi.mocked(redirect).mock.calls[0][0]; + expect(redirectUrl).toMatchSnapshot(); expect(consoleSpy).toHaveBeenCalledWith('No credentials found'); }); }); @@ -796,7 +798,9 @@ describe('Auth0 Remix Server', () => { } as never; vi.mocked(fetch).mockResolvedValue({ - ok: false + ok: false, + status: 400, + json: () => Promise.resolve({ error: 'test-error' }) } as never); const consoleSpy = vi.spyOn(console, 'error').mockImplementation(noop); @@ -806,6 +810,9 @@ describe('Auth0 Remix Server', () => { const authorizer = new Auth0RemixServer(authOptions); await expect(authorizer.getUser(request, {})).rejects.toThrowError(redirectError); // a redirect happened expect(consoleSpy).toHaveBeenCalledWith('Failed to get user profile from Auth0'); + const redirectUrl = vi.mocked(redirect).mock.calls[0][0]; + expect(redirectUrl).toMatchSnapshot(); + expect(redirectUrl).toContain('error=test-error'); }); }); }); @@ -859,7 +866,9 @@ describe('Auth0 Remix Server', () => { it('redirects to the failed login url when the refresh fails', async ({ authOptions, appLoadContext }) => { vi.mocked(fetch).mockResolvedValue({ - ok: false + ok: false, + status: 400, + json: () => Promise.resolve({ error: 'test-error2' }) } as never); const consoleSpy = vi.spyOn(console, 'error').mockImplementation(noop); const request = new Request('https://it-doesnt-matter.com'); @@ -867,6 +876,9 @@ describe('Auth0 Remix Server', () => { const authorizer = new Auth0RemixServer(authOptions); await expect(authorizer.getUser(request, appLoadContext)).rejects.toThrowError(redirectError); // a redirect happened expect(consoleSpy).toHaveBeenCalledWith('Failed to refresh token from Auth0'); + const redirectUrl = vi.mocked(redirect).mock.calls[0][0]; + expect(redirectUrl).toMatchSnapshot(); + expect(redirectUrl).toContain('error=test-error2'); }); it('returns the correct credentials with the rotation off', async ({ authOptions, appLoadContext }) => { diff --git a/src/index.ts b/src/index.ts index 7a772292..7b32b266 100644 --- a/src/index.ts +++ b/src/index.ts @@ -244,7 +244,7 @@ export class Auth0RemixServer { credentials = await getCredentials(request, this.session); } catch (err) { console.error('No credentials found'); - throw redirect(this.failedLoginRedirect); + throw redirect(this.failedLoginRedirect + '?error=no_credentials'); } try { @@ -288,10 +288,12 @@ export class Auth0RemixServer { method: 'POST', body: body.toString() }); + const searchParams = new URLSearchParams(); if (!response.ok) { console.error('Failed to refresh token from Auth0'); - throw redirect(this.failedLoginRedirect); + searchParams.set('error', await this.getErrorReason(response)); + throw redirect(this.failedLoginRedirect.concat('?', searchParams.toString())); } const data = (await response.json()) as Auth0Credentials; const userData: UserCredentials = { @@ -317,9 +319,12 @@ export class Auth0RemixServer { } }); + const searchParams = new URLSearchParams(); + if (!response.ok) { console.error('Failed to get user profile from Auth0'); - throw redirect(this.failedLoginRedirect); + searchParams.set('error', await this.getErrorReason(response)); + throw redirect(this.failedLoginRedirect.concat('?', searchParams.toString())); } const data = (await response.json()) as Auth0UserProfile;