-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathauthenticationMiddleware.ts
More file actions
75 lines (68 loc) · 2.64 KB
/
authenticationMiddleware.ts
File metadata and controls
75 lines (68 loc) · 2.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import {MiddlewareObj} from "@middy/core"
import {APIGatewayProxyEventBase, APIGatewayProxyResult} from "aws-lambda"
import {getUsernameFromEvent, getSessionIdFromEvent} from "./event"
import {
authenticateRequest,
AuthDependencies,
AuthResult,
AuthTimeoutResult
} from "./authenticateRequest"
import {getTokenMapping, TokenMappingItem} from "@cpt-ui-common/dynamoFunctions"
export const authenticationMiddleware = ({
axiosInstance,
ddbClient,
authOptions,
logger
}: AuthDependencies) => ({
before: async (request) => {
const {event} = request
logger.info("Using standard authentication middleware")
let invalidSessionCause: string | undefined = undefined
let authenticatedResult: AuthResult | AuthTimeoutResult | null = null
try {
const username = getUsernameFromEvent(event)
const sessionId = getSessionIdFromEvent(event)
// Fetch the token mapping item for the user
const tokenMappingItem: TokenMappingItem = await getTokenMapping(
ddbClient,
authOptions.tokenMappingTableName,
username,
logger
)
const tokenMappingSessionId = tokenMappingItem?.sessionId
if (tokenMappingItem !== undefined && tokenMappingSessionId === sessionId) {
// Feed the token mapping item to authenticateRequest
logger.info("Session ID matches the token mapping item, proceeding with authentication")
authenticatedResult = await authenticateRequest(
username,
{axiosInstance, ddbClient, logger, authOptions},
tokenMappingItem,
authOptions.tokenMappingTableName,
false
)
if (authenticatedResult && "isTimeout" in authenticatedResult) {
invalidSessionCause = "Timeout"
authenticatedResult = null
}
} else {
logger.info("A session is active but does not match the requestors sessionId", {username, sessionId})
invalidSessionCause = "ConcurrentSession"
}
} catch (error) {
logger.error("Authentication failed returning restart login prompt", {error})
invalidSessionCause = "InvalidSession"
}
if (!authenticatedResult || "isTimeout" in authenticatedResult) {
request.earlyResponse = {
statusCode: 401,
body: JSON.stringify({
message: "Session expired or invalid. Please log in again.",
restartLogin: true,
...(invalidSessionCause && {invalidSessionCause})
})
}
return request.earlyResponse
}
event.requestContext.authorizer = authenticatedResult as AuthResult
}
} satisfies MiddlewareObj<APIGatewayProxyEventBase<AuthResult>, APIGatewayProxyResult, Error>)