diff --git a/src/app/api/auth/salt/route.js b/src/app/api/auth/salt/route.js index 540fc37f..613d75c4 100644 --- a/src/app/api/auth/salt/route.js +++ b/src/app/api/auth/salt/route.js @@ -12,6 +12,15 @@ const supabaseClient = createClient( process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY ); +function getBearerToken(authHeader) { + if (typeof authHeader !== 'string') return null; + + const match = authHeader.match(/^Bearer\s+(.+)$/i); + const token = match?.[1]?.trim(); + + return token || null; +} + /** * Authenticate caller and return their auth user. * Accepts either a Bearer token (Authorization header) or Supabase cookies. @@ -19,8 +28,8 @@ const supabaseClient = createClient( async function authenticateUser(request) { try { const authHeader = request.headers.get('authorization'); - if (authHeader?.startsWith('Bearer ')) { - const token = authHeader.substring(7); + const token = getBearerToken(authHeader); + if (token) { const { data: { user }, error } = await supabaseClient.auth.getUser(token); if (!error && user) return { user }; } diff --git a/src/app/api/auth/salt/route.test.js b/src/app/api/auth/salt/route.test.js index 4495508a..15278e78 100644 --- a/src/app/api/auth/salt/route.test.js +++ b/src/app/api/auth/salt/route.test.js @@ -69,4 +69,35 @@ describe('salt cookie authentication', () => { expect(body).toEqual({ salt: 'stored-salt' }); expect(mocks.authGetUser).toHaveBeenCalledWith('access-token'); }); + + it('normalizes bearer scheme casing and extra spaces', async () => { + const { GET } = await import('./route.js'); + const response = await GET( + new Request('https://qrypt.chat/api/auth/salt', { + headers: { + authorization: 'bearer access-token ' + } + }) + ); + const body = await response.json(); + + expect(response.status).toBe(200); + expect(body).toEqual({ salt: 'stored-salt' }); + expect(mocks.authGetUser).toHaveBeenCalledWith('access-token'); + }); + + it('ignores an empty bearer header and falls back to cookies', async () => { + const { GET } = await import('./route.js'); + const response = await GET( + new Request('https://qrypt.chat/api/auth/salt', { + headers: { + authorization: 'Bearer ', + cookie: `sb-xydzwxwsbgmznthiiscl-auth-token=${cookieValue('cookie-token')}` + } + }) + ); + + expect(response.status).toBe(200); + expect(mocks.authGetUser).toHaveBeenCalledWith('cookie-token'); + }); });