-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathCognitoGithubOidcApiHandler.ts
More file actions
102 lines (80 loc) · 2.8 KB
/
Copy pathCognitoGithubOidcApiHandler.ts
File metadata and controls
102 lines (80 loc) · 2.8 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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import { AuthError, forceError } from "Util/Error";
import {
DANGERouslyLogEvent,
formatErrorResponse,
formatRedirectResponse,
formatSuccessResponse,
LambdaFunctionUrlEvent,
LambdaResponse
} from "Util/LambdaEvent";
import {
createIdTokenJwt,
formatTokenResponse,
parseTokenRequest,
parseUserInfoAccessToken,
} from "AuthnApi/Cognito";
import {
getAuthorizeUrlRedirect,
GithubApi
} from "AuthnApi/Downstream/GithubApi";
import { parseAuthorizeCodeGrantRequest } from "AuthnApi/OAuth";
const name = "CognitoGithubOidcApi";
/* This has no config at all because Cognito passes all necessary info
in the endpoint calls. */
export async function handler(
event: LambdaFunctionUrlEvent,
): Promise<LambdaResponse>{
console.log(name + " exec");
try {
const oidcApiResult = await dispatchOidcApiCall(event);
if( oidcApiResult ){
return oidcApiResult;
}
console.error("failed to dispatch", event);
return formatErrorResponse(404, "invalid API call");
}
catch( err ){
if( err instanceof AuthError ){
console.error("auth error", err.message, err.privateMsg);
return formatErrorResponse(400, err.message);
}
console.error("error", err);
return formatErrorResponse(500, forceError(err).message);
}
}
async function dispatchOidcApiCall(
event: LambdaFunctionUrlEvent
):Promise<LambdaResponse|undefined>{
DANGERouslyLogEvent(name, event);
const {method, path} = event.requestContext.http;
const query = event.queryStringParameters;
if( method === "GET" && path === "/authorize" ){
const params = parseAuthorizeCodeGrantRequest(query);
const githubAuthUrl = getAuthorizeUrlRedirect(params);
return formatRedirectResponse(githubAuthUrl);
}
if( method === "POST" && path === "/token" ){
// do not log the tokenRequest without protecting the secrets it contains
const tokenRequest = parseTokenRequest(event.body);
const githubApi = new GithubApi();
const githubToken = await githubApi.getToken(tokenRequest)
console.log("githubToken", githubToken);
const attributes = await githubApi.mapOidcAttributes(
githubToken.access_token );
const idToken = createIdTokenJwt({
secret: tokenRequest.client_secret,
issuer: `https://${event.headers.host}`,
audience: tokenRequest.client_id,
attributes });
const tokenResponse = formatTokenResponse({idToken, githubToken});
console.log("token response", tokenResponse);
return formatSuccessResponse(tokenResponse);
}
if( method === "GET" && path === "/userinfo" ){
const accessToken = parseUserInfoAccessToken(event.headers);
const githubApi = new GithubApi();
const attributes = await githubApi.mapOidcAttributes(accessToken);
return formatSuccessResponse(attributes);
}
return undefined;
}