Skip to content

Commit cccd8df

Browse files
VIA-529 SB Check vot (Vectors of Trust) value from NHS Login.
1 parent 39e83c1 commit cccd8df

File tree

3 files changed

+53
-3
lines changed

3 files changed

+53
-3
lines changed

src/utils/auth/callbacks/is-valid-signin.test.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,63 @@ describe("isValidSignIn", () => {
3636
iss: mockConfig.NHS_LOGIN_URL,
3737
aud: mockConfig.NHS_LOGIN_CLIENT_ID,
3838
identity_proofing_level: "P9",
39+
vot: "P9.Cp.Ck",
3940
});
4041

4142
const result = isValidSignIn(mockAccount, mockConfig);
4243
expect(result).toBe(true);
4344
});
4445

45-
it("should return false and logs if token is invalid", () => {
46+
it("should return false and logs if iss is invalid", () => {
4647
const mockAccount = { id_token: "invalid-token" } as Account;
4748

4849
(jwtDecode as jest.Mock).mockReturnValue({
4950
iss: "incorrect-issuer",
51+
aud: mockConfig.NHS_LOGIN_CLIENT_ID,
52+
identity_proofing_level: "P9",
53+
vot: "P9.Cp.Ck",
54+
});
55+
56+
const result = isValidSignIn(mockAccount, mockConfig);
57+
expect(result).toBe(false);
58+
});
59+
60+
it("should return false and logs if aud is invalid", () => {
61+
const mockAccount = { id_token: "invalid-token" } as Account;
62+
63+
(jwtDecode as jest.Mock).mockReturnValue({
64+
iss: mockConfig.NHS_LOGIN_URL,
5065
aud: "incorrect-audience",
66+
identity_proofing_level: "P9",
67+
vot: "P9.Cp.Ck",
68+
});
69+
70+
const result = isValidSignIn(mockAccount, mockConfig);
71+
expect(result).toBe(false);
72+
});
73+
74+
it("should return false and logs if identity_proofing_level is invalid", () => {
75+
const mockAccount = { id_token: "invalid-token" } as Account;
76+
77+
(jwtDecode as jest.Mock).mockReturnValue({
78+
iss: mockConfig.NHS_LOGIN_URL,
79+
aud: mockConfig.NHS_LOGIN_CLIENT_ID,
5180
identity_proofing_level: "P0",
81+
vot: "P9.Cp.Ck",
82+
});
83+
84+
const result = isValidSignIn(mockAccount, mockConfig);
85+
expect(result).toBe(false);
86+
});
87+
88+
it("should return false and logs if vot is invalid", () => {
89+
const mockAccount = { id_token: "invalid-token" } as Account;
90+
91+
(jwtDecode as jest.Mock).mockReturnValue({
92+
iss: mockConfig.NHS_LOGIN_URL,
93+
aud: mockConfig.NHS_LOGIN_CLIENT_ID,
94+
identity_proofing_level: "P9",
95+
vot: "P9.Sausages",
5296
});
5397

5498
const result = isValidSignIn(mockAccount, mockConfig);

src/utils/auth/callbacks/is-valid-signin.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,22 @@ const log: Logger = logger.child({
99
module: "utils-auth-callbacks-is-valid-signin",
1010
});
1111

12+
const ACCEPTED_VOTS = ["P9.Cp.Cd", "P9.Cp.Ck", "P9.Cm"];
13+
1214
const isValidSignIn = (account: Account | null | undefined, config: AppConfig) => {
1315
if (!account || typeof account.id_token !== "string") {
1416
log.info("Access denied from signIn callback. Account or id_token missing.");
1517
return false;
1618
}
1719

1820
const decodedToken = jwtDecode<DecodedIdToken>(account.id_token);
19-
const { iss, aud, identity_proofing_level } = decodedToken;
21+
const { iss, aud, identity_proofing_level, vot } = decodedToken;
2022

2123
const isValidToken =
22-
iss === config.NHS_LOGIN_URL && aud === config.NHS_LOGIN_CLIENT_ID && identity_proofing_level === "P9";
24+
iss === config.NHS_LOGIN_URL &&
25+
aud === config.NHS_LOGIN_CLIENT_ID &&
26+
identity_proofing_level === "P9" &&
27+
ACCEPTED_VOTS.includes(vot);
2328

2429
if (!isValidToken) {
2530
log.info({ context: decodedToken }, "Access denied from signIn callback.");

src/utils/auth/types.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export interface DecodedIdToken {
1515
aud: string;
1616
identity_proofing_level: string;
1717
jti: string;
18+
vot: string;
1819
}
1920

2021
export type APIMClientAssertionPayload = {

0 commit comments

Comments
 (0)