Skip to content

Commit 16ddf58

Browse files
committed
1 parent 6f73958 commit 16ddf58

File tree

10 files changed

+394
-161
lines changed

10 files changed

+394
-161
lines changed

infrastructure/terraform/components/sandbox/aws_cognito_user_pool_sandbox.tf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,12 @@ resource "aws_cognito_user_pool" "sandbox" {
1515
required = false
1616
string_attribute_constraints {}
1717
}
18+
19+
schema {
20+
name = "sbx_client_name"
21+
attribute_data_type = "String"
22+
mutable = true
23+
required = false
24+
string_attribute_constraints {}
25+
}
1826
}

lambdas/cognito-triggers/src/__tests__/pre-token-generation.test.ts

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ const eventWithCustomAttr = (): PreTokenGenerationV2Event => ({
6060
email_verified: 'True',
6161
sub: '76c25234-b041-70f2-8ba4-caf538363b35',
6262
'custom:sbx_client_id': 'f58d4b65-870c-42c0-8bb6-2941c5be2bec',
63+
'custom:sbx_client_name': 'NHS Trust',
6364
},
6465
},
6566
response: {
@@ -71,8 +72,8 @@ const eventWithCustomAttr = (): PreTokenGenerationV2Event => ({
7172
version: '2',
7273
});
7374

74-
describe('when user has custom:sbx_client_id attribute', () => {
75-
test('adds nhs-notify:client-id claim from custom attribute in event', async () => {
75+
describe('when user has custom attributes set', () => {
76+
test(`adds nhs-notify:client-id claim from 'custom:sbx_client_id' attribute in event`, async () => {
7677
const result = await new PreTokenGenerationLambda().handler(
7778
eventWithCustomAttr()
7879
);
@@ -90,4 +91,84 @@ describe('when user has custom:sbx_client_id attribute', () => {
9091
},
9192
});
9293
});
94+
95+
test(`adds nhs-notify:client-name to ID token from 'custom:sbx_client_name' attribute`, async () => {
96+
const result = await new PreTokenGenerationLambda().handler(
97+
eventWithCustomAttr()
98+
);
99+
100+
expect(
101+
result.response.claimsAndScopeOverrideDetails?.idTokenGeneration
102+
?.claimsToAddOrOverride
103+
).toMatchObject({
104+
'nhs-notify:client-id': 'f58d4b65-870c-42c0-8bb6-2941c5be2bec',
105+
'nhs-notify:client-name': 'NHS Trust',
106+
});
107+
108+
expect(
109+
result.response.claimsAndScopeOverrideDetails?.accessTokenGeneration
110+
?.claimsToAddOrOverride
111+
).toMatchObject({
112+
'nhs-notify:client-id': 'f58d4b65-870c-42c0-8bb6-2941c5be2bec',
113+
});
114+
});
115+
});
116+
117+
describe('when client ID and name are set but identity attributes are not', () => {
118+
test('does not include any name-related claims', async () => {
119+
const result = await new PreTokenGenerationLambda().handler(
120+
eventWithCustomAttr()
121+
);
122+
123+
const claims =
124+
result.response.claimsAndScopeOverrideDetails?.idTokenGeneration
125+
?.claimsToAddOrOverride ?? {};
126+
127+
expect(claims).toMatchObject({
128+
'nhs-notify:client-id': 'f58d4b65-870c-42c0-8bb6-2941c5be2bec',
129+
'nhs-notify:client-name': 'NHS Trust',
130+
});
131+
132+
expect(claims).not.toHaveProperty('preferred_username');
133+
expect(claims).not.toHaveProperty('given_name');
134+
expect(claims).not.toHaveProperty('family_name');
135+
});
136+
});
137+
138+
describe('when user has identity user attributes set', () => {
139+
test('adds name-related claims', async () => {
140+
const event = eventWithCustomAttr();
141+
142+
Object.assign(event.request.userAttributes, {
143+
preferred_username: 'Dr Test User',
144+
given_name: 'Test',
145+
family_name: 'User',
146+
});
147+
148+
const result = await new PreTokenGenerationLambda().handler(event);
149+
150+
expect(
151+
result.response.claimsAndScopeOverrideDetails?.idTokenGeneration
152+
?.claimsToAddOrOverride
153+
).toMatchObject({
154+
'nhs-notify:client-id': 'f58d4b65-870c-42c0-8bb6-2941c5be2bec',
155+
preferred_username: 'Dr Test User',
156+
given_name: 'Test',
157+
family_name: 'User',
158+
});
159+
});
160+
161+
test(`adds only 'preferred_username' if only that is set`, async () => {
162+
const event = eventNoCustomAttrs();
163+
event.request.userAttributes.preferred_username = 'Test User';
164+
165+
const result = await new PreTokenGenerationLambda().handler(event);
166+
167+
expect(
168+
result.response.claimsAndScopeOverrideDetails?.idTokenGeneration
169+
?.claimsToAddOrOverride
170+
).toMatchObject({
171+
preferred_username: 'Test User',
172+
});
173+
});
93174
});

lambdas/cognito-triggers/src/pre-token-generation.ts

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,63 @@ export type PreTokenGenerationV2Event = Omit<
1313
'claimsAndScopeOverrideDetails'
1414
> & {
1515
claimsAndScopeOverrideDetails:
16-
| PreTokenGenerationV2TriggerEvent['response']['claimsAndScopeOverrideDetails']
17-
| null;
16+
| PreTokenGenerationV2TriggerEvent['response']['claimsAndScopeOverrideDetails']
17+
| null;
1818
};
1919
};
2020

2121
export class PreTokenGenerationLambda {
2222
handler = async (event: PreTokenGenerationV2Event) => {
2323
let response = { ...event };
24-
const clientId = event.request.userAttributes['custom:sbx_client_id'];
24+
const { userAttributes } = event.request;
25+
26+
const clientId = userAttributes['custom:sbx_client_id'];
27+
const clientName = userAttributes['custom:sbx_client_name'];
2528

2629
if (clientId) {
2730
response = PreTokenGenerationLambda.setTokenClaims(
28-
event,
31+
response,
2932
'accessTokenGeneration',
30-
{
31-
'nhs-notify:client-id': clientId,
32-
}
33+
{ 'nhs-notify:client-id': clientId }
34+
);
35+
36+
response = PreTokenGenerationLambda.setTokenClaims(
37+
response,
38+
'idTokenGeneration',
39+
{ 'nhs-notify:client-id': clientId }
40+
);
41+
}
42+
43+
if (clientName) {
44+
response = PreTokenGenerationLambda.setTokenClaims(
45+
response,
46+
'idTokenGeneration',
47+
{ 'nhs-notify:client-name': clientName }
3348
);
49+
}
50+
51+
const preferred =
52+
userAttributes.preferred_username || userAttributes.display_name;
3453

54+
if (preferred) {
55+
response = PreTokenGenerationLambda.setTokenClaims(
56+
response,
57+
'idTokenGeneration',
58+
{ preferred_username: preferred }
59+
);
60+
}
61+
if (userAttributes.given_name) {
62+
response = PreTokenGenerationLambda.setTokenClaims(
63+
response,
64+
'idTokenGeneration',
65+
{ given_name: userAttributes.given_name }
66+
);
67+
}
68+
if (userAttributes.family_name) {
3569
response = PreTokenGenerationLambda.setTokenClaims(
36-
event,
70+
response,
3771
'idTokenGeneration',
38-
{
39-
'nhs-notify:client-id': clientId,
40-
}
72+
{ family_name: userAttributes.family_name }
4173
);
4274
}
4375

0 commit comments

Comments
 (0)