Skip to content

Commit ac2b1e3

Browse files
gecBurtonclaude
andcommitted
Fix email parsing and remove roles check
- Fixed bug in auth.ts where email was discarded when realm_access was missing - Simplified parseAuthToken to only return email (removed roles) - Removed roles authorization check in middleware (redundant with ALB auth) - Added debug logging for token parsing in post-message.ts - Fixed TypeScript types in middleware This fixes the "null value in column useremail" error by ensuring tokens with just email field (no realm_access) are properly handled. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 25f25c4 commit ac2b1e3

File tree

3 files changed

+10
-24
lines changed

3 files changed

+10
-24
lines changed

frontend/src/auth.ts

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { decodeJwt } from 'jose';
55
export async function parseAuthToken(header: string) {
66
if (!header) {
77
console.error('No auth token provided to parse');
8-
return { email: null, roles: [] };
8+
return { email: null };
99
}
1010

1111
// Decode without verification since we're using auth-at-the-edge and can trust all traffic
@@ -14,27 +14,16 @@ export async function parseAuthToken(header: string) {
1414
tokenContent = decodeJwt(header);
1515
} catch(error) {
1616
console.error('Malformed JWT during decoding: ' + header, error);
17-
return { email: null, roles: [] };
17+
return { email: null };
1818
}
1919

2020
const email = tokenContent.email as string | undefined;
2121
if (!email) {
2222
console.error('No email found in token');
23-
return null;
23+
return { email: null };
2424
}
2525

26-
const realmAccess = tokenContent.realm_access as { roles?: string[] } | undefined;
27-
if (!realmAccess) {
28-
console.error('No realm access information found in token');
29-
return { email: null, roles: [] };
30-
}
31-
32-
const roles = realmAccess.roles || [];
33-
// console.debug(`Roles found for user ${email}: ${roles}`);
34-
return {
35-
email,
36-
roles,
37-
};
26+
return { email };
3827
}
3928

4029

frontend/src/middleware.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'dotenv/config';
2+
import type { MiddlewareNext } from 'astro';
23
import { parseAuthToken } from './auth.ts';
34

45
// Define paths that should be public (no authorisation required)
@@ -11,7 +12,7 @@ const PUBLIC_PATHS = [
1112
];
1213
const TEST_AUTHORISATION_JWT = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxNzM5ODk2MTk5IiwiaWF0IjoiMTczOTg5NTg5OSIsImF1dGhfdGltZSI6IjE3Mzk4OTM1MjkiLCJqdGkiOiIyYmVmOGI1ZS0yOGY0LTQ2OWQtYWQ2My1lZjJlNDgxNzliODYiLCJpc3MiOiJodHRwczovL2xvY2FsLXRlc3Rpbmcub2JmdXNjYXRlZC50ZXN0LmRvbWFpbi5nb3YudWsvcmVhbG1zL29iZnVzY2F0ZWQiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiYmMzNzNkZTQtNDAyMi00NmIyLTgxNTEtZjA0NjEzNzhlOWNiIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoibWludXRlIiwic2lkIjoiYzM2NmE5ZmUtMDNiNC00MjIxLWI0ZWItOTE0MzMzNWFhNjUyIiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6WyJodHRwczovL2xvY2FsLXRlc3Rpbmcub2JmdXNjYXRlZC50ZXN0LmRvbWFpbi5nb3YudWsiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbImxvY2FsLXRlc3RpbmciXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIiwiZW1haWxfdmVyaWZpZWQiOiJ0cnVlIiwicHJlZmVycmVkX3VzZXJuYW1lIjoidGVzdEB0ZXN0LmNvLnVrIiwiZW1haWwiOiJ0ZXN0QHRlc3QuY28udWsifQ.Pmlltl1M0Q9EAkU96J_zkPJUjjh2TGhQGzfi0v2J-IrxUt1KTnGEcnEk09TUJjdCuyIgO9YEH-uGj5MihnGj6PqCQjq17lWP5YUjYyjgrULfgM6jZ_659RK31wZdRg_72yiy-BeVd-c-v7UzRtdTXIMkwn_aWEIp7own__jfZV_E_32KfelgtwzljVGHjGXdz_Irg6_2B4lbRn8ipWAn3SDlM9Cj8aJw7q5qq7XPk9KkXclivi4bMQJ9RNgMxtgitFtdINRF1A9_pkbERM1LliAgvW-FTLwmVECAGDQyoE8xDQuti8JgixvM22WfpdznSLd2gWAWMiyYZJwRxzFSVw'; // pragma: allowlist secret
1314

14-
export async function onRequest(context, next) {
15+
export async function onRequest(context: any, next: MiddlewareNext) {
1516
const pathname = new URL(context.request.url).pathname;
1617

1718
// Check if the requested path is public
@@ -33,7 +34,7 @@ export async function onRequest(context, next) {
3334
return redirectToUnauthorised(context);
3435
}
3536

36-
const { email, roles } = await parseAuthToken(token);
37+
const { email } = await parseAuthToken(token);
3738

3839
// If the current user doesn't match the user for the session, destroy existing session data - it may be a shared device
3940
const storedUserEmail = await context.session.get('user-email');
@@ -42,18 +43,13 @@ export async function onRequest(context, next) {
4243
context.session.set('user-email', email);
4344
}
4445

45-
// allow any role (rather than the specific role for gov-ai-client)
46-
if (!roles) {
47-
return redirectToUnauthorised(context);
48-
}
49-
5046
return next();
5147
} catch(error) {
5248
console.error('Error authorising token:', error);
5349
return redirectToUnauthorised(context);
5450
}
5551
}
5652

57-
function redirectToUnauthorised(context) {
53+
function redirectToUnauthorised(context: any) { // eslint-disable-line @typescript-eslint/no-explicit-any
5854
return context.redirect('/unauthorised');
5955
}

frontend/src/pages/post-message.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ export async function POST(context: APIContext) {
3131
// get user email from JWT
3232
const oidcDataToken = context.request.headers.get('x-amzn-oidc-data') || '';
3333
console.log('OIDC data token present:', !!oidcDataToken, 'length:', oidcDataToken.length);
34-
const { email: userEmail } = await parseAuthToken(oidcDataToken);
34+
const authResult = await parseAuthToken(oidcDataToken);
35+
const userEmail = authResult.email;
3536
console.log('Parsed email from token:', userEmail);
3637

3738
if (!userEmail) {

0 commit comments

Comments
 (0)