Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
18b1a1e
Kick off env
connoravo-nhs Feb 24, 2026
0d0ef11
Psuedo representation
connoravo-nhs Feb 24, 2026
d015274
Redirection reconfigured
connoravo-nhs Feb 24, 2026
ab3329d
Formatting
connoravo-nhs Feb 25, 2026
a86c653
Add todo clean ups
connoravo-nhs Feb 25, 2026
2728205
Clean access provider
connoravo-nhs Feb 25, 2026
2d748ff
Extend token mapping
connoravo-nhs Feb 25, 2026
2762816
Clean up matrix changes, make them more human readable. Extend childr…
connoravo-nhs Feb 25, 2026
41ccaf9
Fix access provider test for logged in root test
connoravo-nhs Feb 25, 2026
2e98af8
Fix logoutpage tests
connoravo-nhs Feb 25, 2026
c3bde22
Introduce new requirements on mock object
connoravo-nhs Feb 26, 2026
de35f7c
Merge branch 'main' into AEA-6292
connoravo-nhs Feb 26, 2026
93e23f4
run release #skip-qc
connoravo-nhs Feb 26, 2026
c9989f7
Merge branch 'main' into AEA-6292
connoravo-nhs Feb 26, 2026
d22c032
Further ironing out. If sign out fails, redirect to logout. Check for…
connoravo-nhs Feb 26, 2026
e7197eb
Fix concurrent sessions on multi-role continous loop conflict
connoravo-nhs Feb 27, 2026
e2a1b5c
Merge branch 'main' into AEA-6292
connoravo-nhs Mar 2, 2026
9000f2f
Alter existing tests to work with adjustments
connoravo-nhs Mar 2, 2026
91038df
WIP: Scenario run through for ensureRoleSelected - pages need waited …
connoravo-nhs Mar 2, 2026
b490100
Spplit blocking tests
connoravo-nhs Mar 4, 2026
82c1f7a
Merge branch 'main' into AEA-6292
connoravo-nhs Mar 5, 2026
c3ce09e
Merge branch 'AEA-6292' of github.com-nhs:NHSDigital/eps-prescription…
connoravo-nhs Mar 5, 2026
a36e201
Fix frontend paths for ensureRoleSelected tests
connoravo-nhs Mar 5, 2026
cb69adf
should block children tests
connoravo-nhs Mar 5, 2026
8ce83ca
Ensure tests match, cover missing scenarios. Ensure negative scenario…
connoravo-nhs Mar 5, 2026
108b6f6
Merge branch 'main' into AEA-6292
connoravo-nhs Mar 5, 2026
4568d0c
Fire actions
connoravo-nhs Mar 5, 2026
39d777e
PR cleanup
connoravo-nhs Mar 5, 2026
b44f268
Merge branch 'main' into AEA-6292
connoravo-nhs Mar 9, 2026
125d316
Handle new session isSignedIn on select your role, but deal with logg…
connoravo-nhs Mar 9, 2026
b521759
Merge branch 'main' into AEA-6292
connoravo-nhs Mar 9, 2026
490ad05
Re-run but #skip-qc
connoravo-nhs Mar 11, 2026
a871bae
Introduce logout marker to detect logout on other tabs
connoravo-nhs Mar 11, 2026
806e50b
Resolve test mock issues
connoravo-nhs Mar 11, 2026
c027753
trigger build
jonathanwelch1-nhs Mar 11, 2026
6d19d7c
trigger build
jonathanwelch1-nhs Mar 11, 2026
209dff3
Memory router wrapping
connoravo-nhs Mar 11, 2026
ac989c6
Reduce recent logout marker time
connoravo-nhs Mar 11, 2026
146877b
fixed Buttons & ESC key can be spam clicked, leading to multiple sele…
jonathanwelch1-nhs Mar 11, 2026
493405c
Tab awareness and logout marker
connoravo-nhs Mar 12, 2026
4429929
fixed toms comments
jonathanwelch1-nhs Mar 12, 2026
8097180
Fixes
connoravo-nhs Mar 12, 2026
75c7cc9
improved test coverage
jonathanwelch1-nhs Mar 12, 2026
11a88b5
Merge branch 'main' into aea-5884-comments-on-modal
jonathanwelch1-nhs Mar 12, 2026
29944c7
Shuffle login to a helper func. Correct timing on signout process. WI…
connoravo-nhs Mar 12, 2026
7df5151
sonarcloud refactoring
jonathanwelch1-nhs Mar 12, 2026
96e1195
Merge remote-tracking branch 'origin' into aea-5884-comments-on-modal
jonathanwelch1-nhs Mar 12, 2026
fc3524b
Merge remote-tracking branch 'origin/aea-5884-comments-on-modal' into…
jonathanwelch1-nhs Mar 12, 2026
713f1ea
updated text
jonathanwelch1-nhs Mar 12, 2026
40a2e6c
Merge branch 'main' into aea-5884-comments-on-modal
connoravo-nhs Mar 13, 2026
1d89176
Axios label
connoravo-nhs Mar 13, 2026
916488a
Ensure RBAC isn't shown on duplicated tab logout page
connoravo-nhs Mar 13, 2026
be93e10
Fix require #skip-qc
connoravo-nhs Mar 13, 2026
cb83598
PR cleanup
connoravo-nhs Mar 16, 2026
27476dd
Apply suggestion from @connoravo-nhs
connoravo-nhs Mar 16, 2026
271bee8
TESTS REQ - Initial fixes to prevent both modals showing. Disable dup…
connoravo-nhs Mar 16, 2026
0ff74b3
Linting and test adjustments
connoravo-nhs Mar 17, 2026
4dbba97
Restore original test files - Changes not needed as access provider p…
connoravo-nhs Mar 17, 2026
145bcac
Reset auth context in tests from prior
connoravo-nhs Mar 17, 2026
c619eac
Forgotten one
connoravo-nhs Mar 17, 2026
51cb99b
Merge branch 'main' into aea-5884-comments-on-modal
connoravo-nhs Mar 17, 2026
6a085ae
Update packages/cpt-ui/src/components/SessionTimeoutModal.tsx
connoravo-nhs Mar 17, 2026
bff556e
Update packages/cpt-ui/src/components/SessionTimeoutModal.tsx
connoravo-nhs Mar 17, 2026
1e9f832
Environment var fixes
connoravo-nhs Mar 17, 2026
4b81d9d
Log function name change & tab helper mocks
connoravo-nhs Mar 17, 2026
cedb257
Remove unneeded import
connoravo-nhs Mar 17, 2026
80f26f4
Merge branch 'main' into AEA-6210
connoravo-nhs Mar 17, 2026
501fb1b
Adjust initial timeLeft setting to be seconds
connoravo-nhs Mar 18, 2026
c4c8682
Reset time the modal pops up
connoravo-nhs Mar 18, 2026
e9cfb49
Potential fix for pull request finding
connoravo-nhs Mar 18, 2026
d7d7a51
Potential fix for pull request finding
connoravo-nhs Mar 18, 2026
f1693f4
Potential fix for pull request finding
connoravo-nhs Mar 18, 2026
2871767
Potential fix for pull request finding
connoravo-nhs Mar 18, 2026
2b2360b
Fix timeleft for all setters
connoravo-nhs Mar 18, 2026
4524e75
Merge branch 'aea-5884-comments-on-modal' of github.com-nhs:NHSDigita…
connoravo-nhs Mar 18, 2026
a2f7a1f
Copilot suggestions refined and revert the useEffect changes as they …
connoravo-nhs Mar 18, 2026
24194a2
Fix: [AEA-0000] - Trivy ignore currently recognised risk for fast-xml…
connoravo-nhs Mar 18, 2026
11be413
Merge branch 'trivyignore180326' into aea-5884-comments-on-modal
connoravo-nhs Mar 18, 2026
92cf471
Merge branch 'main' into aea-5884-comments-on-modal
connoravo-nhs Mar 18, 2026
9457e62
Merge branch 'main' into AEA-6292
connoravo-nhs Mar 18, 2026
a262153
Fix user initiated logout modal not hiding on click
connoravo-nhs Mar 18, 2026
7ec81cc
Removals
connoravo-nhs Mar 19, 2026
be990e8
Protect rum logs. Remove logout marker appropriately for new clicking…
connoravo-nhs Mar 19, 2026
94c4d08
Fix concurrent sessions
connoravo-nhs Mar 19, 2026
804705f
Fix some tests #skip-qc
connoravo-nhs Mar 19, 2026
7b8b6f6
Test fixes
connoravo-nhs Mar 19, 2026
a11da04
Merge branch 'main' into AEA-6292
connoravo-nhs Mar 19, 2026
43c21f6
Log out marker fixes #skip-qc
connoravo-nhs Mar 20, 2026
0a5e846
Merge branch 'main' into AEA-6292
anthony-nhs Mar 20, 2026
f198907
Removing loading screens on select role and logout
connoravo-nhs Mar 20, 2026
5a57d41
Merge branch 'AEA-6292' of github.com-nhs:NHSDigital/eps-prescription…
connoravo-nhs Mar 20, 2026
45976e5
Fix logout marker timing and auto-delete if it's expired
connoravo-nhs Mar 20, 2026
e522e87
Merge branch 'main' into AEA-6292
connoravo-nhs Mar 23, 2026
ca9ce2f
Update regression test version
connoravo-nhs Mar 23, 2026
eaf885e
Merge branch 'AEA-6292' of github.com-nhs:NHSDigital/eps-prescription…
connoravo-nhs Mar 23, 2026
b068a42
Merge branch 'main' into AEA-6292
connoravo-nhs Mar 24, 2026
9c17701
Modify session timed out invalid session cause reason
connoravo-nhs Mar 24, 2026
d219966
Test resolves
connoravo-nhs Mar 24, 2026
7334a30
Merge branch 'main' into AEA-6292
connoravo-nhs Mar 30, 2026
631852d
PR review cleanup
connoravo-nhs Mar 30, 2026
c768a8a
Resolve linting issues
connoravo-nhs Mar 30, 2026
0e15cf2
Logging to debugs. Test repairs. Add new tests for logout path condit…
connoravo-nhs Mar 30, 2026
06546d1
Merge branch 'main' into AEA-6292
connoravo-nhs Mar 31, 2026
f4b6b30
Ensure session logged out is also ignored from redirections to login
connoravo-nhs Mar 31, 2026
3b87196
Merge branch 'main' into AEA-6292
connoravo-nhs Mar 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/run_regression_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ jobs:
GITHUB-TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
if [[ "$TARGET_ENVIRONMENT" != "prod" && "$TARGET_ENVIRONMENT" != "ref" ]]; then
REGRESSION_TEST_REPO_TAG="v3.9.10" # This is the tag or branch of the regression test code to run, usually a version tag like v3.1.0 or a branch name
REGRESSION_TEST_WORKFLOW_TAG="v3.9.10" # This is the tag of the github workflow to run, usually the same as REGRESSION_TEST_REPO_TAG
REGRESSION_TEST_REPO_TAG="v3.10.9" # This is the tag or branch of the regression test code to run, usually a version tag like v3.1.0 or a branch name
REGRESSION_TEST_WORKFLOW_TAG="v3.10.9" # This is the tag of the github workflow to run, usually the same as REGRESSION_TEST_REPO_TAG


if [[ -z "$REGRESSION_TEST_REPO_TAG" || -z "$REGRESSION_TEST_WORKFLOW_TAG" ]]; then
Expand Down
23 changes: 17 additions & 6 deletions packages/cognito/src/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {MiddyErrorHandler} from "@cpt-ui-common/middyErrorHandler"
import {headers} from "@cpt-ui-common/lambdaUtils"

import {rewriteRequestBody} from "./helpers"
import {insertTokenMapping, tryGetTokenMapping} from "@cpt-ui-common/dynamoFunctions"
import {insertTokenMapping, tryGetTokenMapping, TokenMappingItem} from "@cpt-ui-common/dynamoFunctions"

/*
This is the lambda code that is used to intercept calls to token endpoint as part of the cognito login flow
Expand Down Expand Up @@ -71,6 +71,18 @@ const errorResponseBody = {

const middyErrorHandler = new MiddyErrorHandler(errorResponseBody)

function checkIfValidTokenMapping(tokenMapping: TokenMappingItem | undefined): boolean {
const fifteenMinutes = 15 * 60 * 1000

return tokenMapping !== undefined &&
tokenMapping.sessionId !== undefined &&
tokenMapping.cis2AccessToken !== undefined &&
tokenMapping.cis2IdToken !== undefined &&
tokenMapping.cis2ExpiresIn !== undefined &&
tokenMapping.lastActivityTime !== undefined &&
tokenMapping.lastActivityTime > Date.now() - fifteenMinutes
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A strange case where a token wasn't fully "cleaned" from the database, it existed as a user entry but no further information. This was presenting as a concurrent session to users who weren't logged in elsewhere.

}

const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
logger.appendKeys({
"apigw-request-id": event.requestContext?.requestId
Expand Down Expand Up @@ -131,13 +143,13 @@ const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayPro
throw new Error("Can not get expiry time from decoded token")
}

const tokenMappingItem = {
const tokenMappingItem: TokenMappingItem = {
username: username,
sessionId: decodedIdToken.at_hash,
cis2AccessToken: accessToken,
cis2IdToken: idToken,
cis2ExpiresIn: decodedIdToken.exp.toString(),
selectedRoleId: decodedIdToken.selected_roleid,
currentlySelectedRole: decodedIdToken.selected_roleid,
lastActivityTime: Date.now()
}

Expand All @@ -147,10 +159,9 @@ const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayPro
logger
)

const fifteenMinutes = 15 * 60 * 1000
const sessionManagementTableName = cis2OidcConfig.sessionManagementTableName

if (existingTokenMapping !== undefined && existingTokenMapping.lastActivityTime > Date.now() - fifteenMinutes) {
const validToken = checkIfValidTokenMapping(existingTokenMapping)
if (validToken) {
logger.info("User already exists in token mapping table, creating draft session",
{username}, {sessionManagementTableName})
await insertTokenMapping(documentClient, sessionManagementTableName, tokenMappingItem, logger)
Expand Down
21 changes: 15 additions & 6 deletions packages/cognito/src/tokenMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import inputOutputLogger from "@middy/input-output-logger"
import {parse} from "querystring"
import {PrivateKey} from "jsonwebtoken"
import {exchangeTokenForApigeeAccessToken, fetchUserInfo, initializeOidcConfig} from "@cpt-ui-common/authFunctions"
import {insertTokenMapping, tryGetTokenMapping} from "@cpt-ui-common/dynamoFunctions"
import {insertTokenMapping, tryGetTokenMapping, TokenMappingItem} from "@cpt-ui-common/dynamoFunctions"
import {MiddyErrorHandler} from "@cpt-ui-common/middyErrorHandler"
import jwt from "jsonwebtoken"
import axios from "axios"
Expand Down Expand Up @@ -72,6 +72,17 @@ async function createSignedJwt(claims: Record<string, unknown>) {
})
}

function checkIfValidTokenMapping(tokenMapping: TokenMappingItem | undefined): boolean {
const fifteenMinutes = 15 * 60 * 1000

return tokenMapping !== undefined &&
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A strange case where a token wasn't fully "cleaned" from the database, it existed as a user entry but no further information. This was presenting as a concurrent session to users who weren't logged in elsewhere.

tokenMapping.sessionId !== undefined &&
tokenMapping.apigeeAccessToken !== undefined &&
tokenMapping.apigeeExpiresIn !== undefined &&
tokenMapping.lastActivityTime !== undefined &&
tokenMapping.lastActivityTime > Date.now() - fifteenMinutes
}

const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
const apigeeApiKey = await getSecret(apigeeApiKeyArn)
const apigeeApiSecret = await getSecret(apigeeApiSecretArn)
Expand Down Expand Up @@ -154,7 +165,7 @@ const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayPro
)
logger.info("Existing token mapping for user", {existingTokenMapping})

let tokenMappingItem = {
let tokenMappingItem: TokenMappingItem = {
username: `Mock_${baseUsername}`,
sessionId: sessionId,
apigeeAccessToken: exchangeResult.accessToken,
Expand All @@ -167,11 +178,9 @@ const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayPro
lastActivityTime: Date.now()
}

const fifteenMinutes = 15 * 60 * 1000

const sessionManagementTableName = mockOidcConfig.sessionManagementTableName

if (existingTokenMapping !== undefined && existingTokenMapping.lastActivityTime > Date.now() - fifteenMinutes) {
const validToken = checkIfValidTokenMapping(existingTokenMapping)
if (validToken) {
const username = tokenMappingItem.username
logger.info("User already exists in token mapping table, creating draft session",
{username}, {sessionManagementTableName})
Expand Down
14 changes: 11 additions & 3 deletions packages/cognito/tests/test_token.cis2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,11 @@ describe("cis2 token handler", () => {
mockTryGetTokenMapping.mockImplementationOnce(() => {
return Promise.resolve({
username: `${CIS2_USER_POOL_IDP}_foo`,
lastActivityTime: Date.now() - (10 * 60 * 1000) // 10 minutes ago (less than 15)
lastActivityTime: Date.now() - (10 * 60 * 1000), // 10 minutes ago (less than 15)
sessionId: "session-id",
cis2AccessToken: "foo",
cis2IdToken: "bar",
cis2ExpiresIn: Date.now() - - (10 * 60 * 1000)
})
})

Expand Down Expand Up @@ -353,14 +357,18 @@ describe("cis2 token handler", () => {

it("creates concurrent session when user exists and last activity exactly at 15 minute boundary", async () => {
// Mock Date.now() to ensure consistent timing for boundary test
const fixedTime = 1000000000000 // Fixed timestamp
const fixedTime = 1000000 // Fixed timestamp
const dateNowSpy = vi.spyOn(Date, "now").mockReturnValue(fixedTime)

const fifteenMinutes = 15 * 60 * 1000
mockTryGetTokenMapping.mockImplementationOnce(() => {
return Promise.resolve({
username: `${CIS2_USER_POOL_IDP}_foo`,
lastActivityTime: fixedTime - fifteenMinutes + 1 // Just barely within 15 minute window
lastActivityTime: fixedTime - fifteenMinutes + 1, // Just barely within 15 minute window
sessionId: "session-id",
cis2AccessToken: "foo",
cis2IdToken: "bar",
cis2ExpiresIn: fixedTime - fifteenMinutes + 1
})
})

Expand Down
14 changes: 9 additions & 5 deletions packages/cognito/tests/test_token.mock.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,10 @@ describe("token mock handler", () => {
mockTryGetTokenMapping.mockImplementation(() => {
return Promise.resolve({
username: "Mock_user_details_sub",
lastActivityTime: Date.now()
lastActivityTime: Date.now(),
sessionId: "session-id",
apigeeAccessToken: "foo",
apigeeExpiresIn: "3600"
})
})

Expand Down Expand Up @@ -259,10 +262,11 @@ describe("token mock handler", () => {
}, dummyContext)

// check call
expect(mockInsertTokenMapping).toHaveBeenCalledOnce()
expect(mockInsertTokenMapping).toHaveBeenCalledWith(
expect.anything(), // documentClient
"test-session-management-table", // tableName
{
({
username: "Mock_user_details_sub",
apigeeAccessToken: "new-access-token",
apigeeRefreshToken: "new-refresh-token",
Expand All @@ -279,7 +283,7 @@ describe("token mock handler", () => {
},
lastActivityTime: expect.any(Number),
sessionId: expect.any(String)
}, // item
}), // item
expect.anything() // logger
)
// Check response structure
Expand Down Expand Up @@ -342,7 +346,7 @@ describe("token mock handler", () => {
expect(mockInsertTokenMapping).toHaveBeenCalledWith(
expect.anything(), // documentClient
"dummyTable", // tableName
{
({
username: "Mock_user_details_sub",
apigeeAccessToken: "new-access-token",
apigeeRefreshToken: "new-refresh-token",
Expand All @@ -359,7 +363,7 @@ describe("token mock handler", () => {
},
lastActivityTime: expect.any(Number),
sessionId: expect.any(String)
}, // item
}), // item
expect.anything() // logger
)
// Check response structure
Expand Down
Loading
Loading