@infoxchange/make-it-so 2.11.0-internal-testing-vdt-199-add-ix-oidc-auth.1 → 2.11.0-internal-testing-vdt-199-add-auth-token-verify-function.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -304,7 +304,7 @@ const auth = new CloudFrontOidcAuth(stack, "CloudFrontOidcAuth", {
304
304
  });
305
305
 
306
306
  // Then you apply it to the a CloudFront backed site when it's created
307
- new IxStaticSite(stack, "IxStaticSite", {
307
+ const site = new IxStaticSite(stack, "IxStaticSite", {
308
308
  path: "path/to/site/files",
309
309
  cdk: {
310
310
  distribution: auth.addToDistributionDefinition(stack, {
@@ -314,29 +314,6 @@ new IxStaticSite(stack, "IxStaticSite", {
314
314
  });
315
315
  ```
316
316
 
317
- <details>
318
- <summary><strong>ApiGatewayOidcAuth</strong> - Adds OIDC authentication to a API Gateway instance.</summary>
319
-
320
- This is an instance of SST v2's [Auth construct](https://v2.sst.dev/auth) that is preconfigured for OIDC.
321
-
322
- ```typescript
323
- import { ApiGatewayOidcAuth } from "@infoxchange/make-it-so/cdk-constructs";
324
-
325
- // You first create an instance of ApiGatewayOidcAuth
326
- const auth = new ApiGatewayOidcAuth(stack, "ApiGatewayOidcAuth", {
327
- oidcIssuerUrl: "https://your-oidc-server.com/path/",
328
- oidcClientId: "your-client-id",
329
- oidcScope: "email",
330
- });
331
-
332
- // Then you attach it to an API instance
333
- const api = new Api(stack, "api", {});
334
- auth.attach(stack, {
335
- api,
336
- prefix: "/auth", // optional
337
- });
338
- ```
339
-
340
317
  ## Full Example
341
318
 
342
319
  To deploy a Next.js based site you would include a `sst.config.ts` file at the root of repo with contents like this:
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cdk-constructs/CloudFrontOidcAuth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AASvC,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAI1E,KAAK,cAAc,GAAG,qBAAqB,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACjE,KAAK,WAAW,GAAG,qBAAqB,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9D,KAAK,OAAO,CAAC,CAAC,IAAI;IAChB,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAC/B,CAAC;AAEF,KAAK,KAAK,GAAG;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,SAAS;IAC/C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;gBAER,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK;IAQhE,2BAA2B,CACzB,iBAAiB,SAAS,4BAA4B,EAEtD,KAAK,EAAE,cAAc,EACrB,EACE,sBAAsB,EACtB,MAAgB,GACjB,EAAE;QAAE,sBAAsB,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAwC5E,OAAO,CAAC,sBAAsB;IAgI9B,OAAO,CAAC,sBAAsB;CA8E/B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cdk-constructs/CloudFrontOidcAuth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AASvC,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAI1E,KAAK,cAAc,GAAG,qBAAqB,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACjE,KAAK,WAAW,GAAG,qBAAqB,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9D,KAAK,OAAO,CAAC,CAAC,IAAI;IAChB,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAC/B,CAAC;AAEF,KAAK,KAAK,GAAG;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,SAAS;IAC/C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;gBAER,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK;IAQhE,2BAA2B,CACzB,iBAAiB,SAAS,4BAA4B,EAEtD,KAAK,EAAE,cAAc,EACrB,EACE,sBAAsB,EACtB,MAAgB,GACjB,EAAE;QAAE,sBAAsB,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAuC5E,OAAO,CAAC,sBAAsB;IA8H9B,OAAO,CAAC,sBAAsB;CA8E/B"}
@@ -54,7 +54,6 @@ export class CloudFrontOidcAuth extends Construct {
54
54
  this.getAuthBehaviorOptions(scope, jwtSecret, prefix);
55
55
  return updatedDistributionDefinition;
56
56
  }
57
- // This deals with the infra required for checking if requests are authenticated and redirecting to the auth route if not
58
57
  getFunctionAssociation(scope, jwtSecret) {
59
58
  const cfKeyValueStore = new CloudFront.KeyValueStore(scope, `${this.id}CFKeyValueStore`);
60
59
  const kvStoreId = cfKeyValueStore.keyValueStoreId; // Your KV store ID
@@ -138,8 +137,6 @@ export class CloudFrontOidcAuth extends Construct {
138
137
  eventType: CloudFront.FunctionEventType.VIEWER_REQUEST,
139
138
  };
140
139
  }
141
- // This deals with the infra required for handling the OIDC authorisation process for requests that aren't yet
142
- // authenticated but want to become authenticated.
143
140
  getAuthBehaviorOptions(scope, jwtSecret, prefix) {
144
141
  const authRouteFunction = new SST.Function(scope, `${this.id}AuthRouteFunction`, {
145
142
  runtime: "nodejs20.x",
@@ -7,5 +7,4 @@ export * from "./IxElasticache.js";
7
7
  export * from "./IxApi.js";
8
8
  export * from "./IxQuicksightWorkspace.js";
9
9
  export * from "./CloudFrontOidcAuth/index.js";
10
- export * from "./ApiGatewayOidcAuth/index.js";
11
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cdk-constructs/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cdk-constructs/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC"}
@@ -7,4 +7,3 @@ export * from "./IxElasticache.js";
7
7
  export * from "./IxApi.js";
8
8
  export * from "./IxQuicksightWorkspace.js";
9
9
  export * from "./CloudFrontOidcAuth/index.js";
10
- export * from "./ApiGatewayOidcAuth/index.js";
@@ -0,0 +1,2 @@
1
+ export * from "./oidc.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC"}
@@ -0,0 +1 @@
1
+ export * from "./oidc.js";
@@ -0,0 +1,26 @@
1
+ import { JWTPayload } from "jose";
2
+ type VerifyAccessTokenParams<SafeVerify extends boolean = false> = {
3
+ token: string;
4
+ issuerUrl: string;
5
+ audience: string;
6
+ safeVerify?: SafeVerify;
7
+ };
8
+ /**
9
+ * Checks an OIDC access token against the issuer's details to determine if it's valid.
10
+ *
11
+ * @param params - The parameters for verifying the access token.
12
+ * @param params.token - The JWT access token to verify.
13
+ * @param params.issuerUrl - The OIDC issuer URL to discover JWKS and metadata.
14
+ * @param params.audience - The expected audience value to match against the token's claims.
15
+ * @param params.safeVerify - If true, returns a result object with error and payload fields instead of throwing on error.
16
+ * @returns If `safeVerify` is true, returns an object with either the verified payload or an error. Otherwise, returns the verified JWT payload or throws an error.
17
+ */
18
+ export declare function verifyAccessToken<SafeVerify extends boolean = false>({ token, issuerUrl, audience, safeVerify, }: VerifyAccessTokenParams<SafeVerify>): Promise<SafeVerify extends true ? {
19
+ error: Error | unknown;
20
+ payload: null;
21
+ } | {
22
+ error: null;
23
+ payload: JWTPayload;
24
+ } : JWTPayload>;
25
+ export {};
26
+ //# sourceMappingURL=oidc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oidc.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/oidc.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,UAAU,EAAa,MAAM,MAAM,CAAC;AAEjE,KAAK,uBAAuB,CAAC,UAAU,SAAS,OAAO,GAAG,KAAK,IAAI;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,SAAS,OAAO,GAAG,KAAK,EAAE,EAC1E,KAAK,EACL,SAAS,EACT,QAAQ,EACR,UAAU,GACX,EAAE,uBAAuB,CAAC,UAAU,CAAC,GAAG,OAAO,CAC9C,UAAU,SAAS,IAAI,GAEf;IAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GACzC;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAE,GACxC,UAAU,CACf,CAyCA"}
@@ -0,0 +1,48 @@
1
+ import { Issuer } from "openid-client";
2
+ import { createRemoteJWKSet, jwtVerify } from "jose";
3
+ /**
4
+ * Checks an OIDC access token against the issuer's details to determine if it's valid.
5
+ *
6
+ * @param params - The parameters for verifying the access token.
7
+ * @param params.token - The JWT access token to verify.
8
+ * @param params.issuerUrl - The OIDC issuer URL to discover JWKS and metadata.
9
+ * @param params.audience - The expected audience value to match against the token's claims.
10
+ * @param params.safeVerify - If true, returns a result object with error and payload fields instead of throwing on error.
11
+ * @returns If `safeVerify` is true, returns an object with either the verified payload or an error. Otherwise, returns the verified JWT payload or throws an error.
12
+ */
13
+ export async function verifyAccessToken({ token, issuerUrl, audience, safeVerify, }) {
14
+ try {
15
+ const issuer = await Issuer.discover(issuerUrl);
16
+ const jwksUri = issuer.metadata.jwks_uri;
17
+ if (!jwksUri) {
18
+ throw new Error("JWKS URI not found in issuer metadata");
19
+ }
20
+ const JWKS = createRemoteJWKSet(new URL(jwksUri));
21
+ // Verify the signature and basic claims
22
+ const { payload } = await jwtVerify(token, JWKS, {
23
+ issuer: issuer.metadata.issuer,
24
+ });
25
+ const tokenAud = payload.aud ?? payload.client_id;
26
+ let audienceMatches = false;
27
+ for (const aud of Array.isArray(tokenAud) ? tokenAud : [tokenAud]) {
28
+ if (aud === audience) {
29
+ audienceMatches = true;
30
+ break;
31
+ }
32
+ }
33
+ if (!audienceMatches) {
34
+ console.info("Token data:", payload);
35
+ throw new Error(`Token audience does not match expected audience ${audience}`);
36
+ }
37
+ if (safeVerify) {
38
+ return { payload, error: null };
39
+ }
40
+ return payload;
41
+ }
42
+ catch (err) {
43
+ if (safeVerify) {
44
+ return { error: err, payload: null };
45
+ }
46
+ throw err;
47
+ }
48
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@infoxchange/make-it-so",
3
- "version": "2.11.0-internal-testing-vdt-199-add-ix-oidc-auth.1",
3
+ "version": "2.11.0-internal-testing-vdt-199-add-auth-token-verify-function.2",
4
4
  "description": "Makes deploying services to IX infra easy",
5
5
  "repository": "github:infoxchange/make-it-so",
6
6
  "type": "module",
@@ -16,7 +16,8 @@
16
16
  "license": "MIT",
17
17
  "exports": {
18
18
  "./cdk-constructs": "./dist/cdk-constructs/index.js",
19
- "./deployConfig": "./dist/deployConfig.js"
19
+ "./deployConfig": "./dist/deployConfig.js",
20
+ "./auth": "./dist/lib/auth.js"
20
21
  },
21
22
  "lint-staged": {
22
23
  "**/*": [
@@ -84,7 +84,6 @@ export class CloudFrontOidcAuth extends Construct {
84
84
  return updatedDistributionDefinition;
85
85
  }
86
86
 
87
- // This deals with the infra required for checking if requests are authenticated and redirecting to the auth route if not
88
87
  private getFunctionAssociation(
89
88
  scope: ConstructScope,
90
89
  jwtSecret: SecretsManager.Secret,
@@ -211,8 +210,6 @@ export class CloudFrontOidcAuth extends Construct {
211
210
  };
212
211
  }
213
212
 
214
- // This deals with the infra required for handling the OIDC authorisation process for requests that aren't yet
215
- // authenticated but want to become authenticated.
216
213
  private getAuthBehaviorOptions(
217
214
  scope: ConstructScope,
218
215
  jwtSecret: SecretsManager.Secret,
@@ -7,4 +7,3 @@ export * from "./IxElasticache.js";
7
7
  export * from "./IxApi.js";
8
8
  export * from "./IxQuicksightWorkspace.js";
9
9
  export * from "./CloudFrontOidcAuth/index.js";
10
- export * from "./ApiGatewayOidcAuth/index.js";
@@ -0,0 +1 @@
1
+ export * from "./oidc.js";
@@ -0,0 +1,73 @@
1
+ import { Issuer } from "openid-client";
2
+ import { createRemoteJWKSet, JWTPayload, jwtVerify } from "jose";
3
+
4
+ type VerifyAccessTokenParams<SafeVerify extends boolean = false> = {
5
+ token: string;
6
+ issuerUrl: string;
7
+ audience: string;
8
+ safeVerify?: SafeVerify;
9
+ };
10
+
11
+ /**
12
+ * Checks an OIDC access token against the issuer's details to determine if it's valid.
13
+ *
14
+ * @param params - The parameters for verifying the access token.
15
+ * @param params.token - The JWT access token to verify.
16
+ * @param params.issuerUrl - The OIDC issuer URL to discover JWKS and metadata.
17
+ * @param params.audience - The expected audience value to match against the token's claims.
18
+ * @param params.safeVerify - If true, returns a result object with error and payload fields instead of throwing on error.
19
+ * @returns If `safeVerify` is true, returns an object with either the verified payload or an error. Otherwise, returns the verified JWT payload or throws an error.
20
+ */
21
+ export async function verifyAccessToken<SafeVerify extends boolean = false>({
22
+ token,
23
+ issuerUrl,
24
+ audience,
25
+ safeVerify,
26
+ }: VerifyAccessTokenParams<SafeVerify>): Promise<
27
+ SafeVerify extends true
28
+ ?
29
+ | { error: Error | unknown; payload: null }
30
+ | { error: null; payload: JWTPayload }
31
+ : JWTPayload
32
+ > {
33
+ try {
34
+ const issuer = await Issuer.discover(issuerUrl);
35
+ const jwksUri = issuer.metadata.jwks_uri;
36
+ if (!jwksUri) {
37
+ throw new Error("JWKS URI not found in issuer metadata");
38
+ }
39
+ const JWKS = createRemoteJWKSet(new URL(jwksUri));
40
+
41
+ // Verify the signature and basic claims
42
+ const { payload } = await jwtVerify(token, JWKS, {
43
+ issuer: issuer.metadata.issuer,
44
+ });
45
+
46
+ const tokenAud = payload.aud ?? payload.client_id;
47
+ let audienceMatches = false;
48
+ for (const aud of Array.isArray(tokenAud) ? tokenAud : [tokenAud]) {
49
+ if (aud === audience) {
50
+ audienceMatches = true;
51
+ break;
52
+ }
53
+ }
54
+ if (!audienceMatches) {
55
+ console.info("Token data:", payload);
56
+ throw new Error(
57
+ `Token audience does not match expected audience ${audience}`,
58
+ );
59
+ }
60
+
61
+ if (safeVerify) {
62
+ return { payload, error: null };
63
+ }
64
+ return payload as SafeVerify extends true
65
+ ? { error: null; payload: JWTPayload }
66
+ : JWTPayload;
67
+ } catch (err) {
68
+ if (safeVerify) {
69
+ return { error: err, payload: null };
70
+ }
71
+ throw err;
72
+ }
73
+ }
@@ -1,9 +0,0 @@
1
- declare module "sst/node/auth" {
2
- interface SessionTypes {
3
- user: {
4
- userID: string;
5
- };
6
- }
7
- }
8
- export declare const handler: (event: any, context: any) => Promise<any>;
9
- //# sourceMappingURL=auth-route.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth-route.d.ts","sourceRoot":"","sources":["../../../src/cdk-constructs/ApiGatewayOidcAuth/auth-route.ts"],"names":[],"mappings":"AAoBA,OAAO,QAAQ,eAAe,CAAC;IAC7B,UAAiB,YAAY;QAC3B,IAAI,EAAE;YACJ,MAAM,EAAE,MAAM,CAAC;SAChB,CAAC;KACH;CACF;AAED,eAAO,MAAM,OAAO,4CAiBlB,CAAC"}
@@ -1,33 +0,0 @@
1
- import { AuthHandler, OidcAdapter, Session } from "sst/node/auth";
2
- import { Issuer } from "openid-client";
3
- const oidcClientId = process.env.OIDC_CLIENT_ID;
4
- if (!oidcClientId) {
5
- throw new Error("OIDC_CLIENT_ID not set");
6
- }
7
- const oidcIssuerUrl = process.env.OIDC_ISSUER_URL;
8
- if (!oidcIssuerUrl) {
9
- throw new Error("OIDC_ISSUER_URL not set");
10
- }
11
- const oidcScope = process.env.OIDC_SCOPE;
12
- if (!oidcScope) {
13
- throw new Error("OIDC_SCOPE not set");
14
- }
15
- const oidcIssuerConfigUrl = new URL(`${process.env.OIDC_ISSUER_URL?.replace(/\/$/, "")}/.well-known/openid-configuration`);
16
- export const handler = AuthHandler({
17
- providers: {
18
- oidc: OidcAdapter({
19
- issuer: await Issuer.discover(oidcIssuerConfigUrl.href),
20
- clientID: oidcClientId,
21
- scope: oidcScope,
22
- onSuccess: async (tokenset) => {
23
- return Session.cookie({
24
- redirect: "/",
25
- type: "user",
26
- properties: {
27
- userID: tokenset.claims().sub,
28
- },
29
- });
30
- },
31
- }),
32
- },
33
- });
@@ -1,13 +0,0 @@
1
- import * as SST from "sst/constructs";
2
- type ConstructScope = ConstructorParameters<typeof SST.Auth>[0];
3
- type ConstructId = ConstructorParameters<typeof SST.Auth>[1];
4
- type Props = Omit<SST.AuthProps, "authenticator"> & {
5
- oidcIssuerUrl: string;
6
- oidcClientId: string;
7
- oidcScope: string;
8
- };
9
- export declare class ApiGatewayOidcAuth extends SST.Auth {
10
- constructor(scope: ConstructScope, id: ConstructId, props: Props);
11
- }
12
- export {};
13
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cdk-constructs/ApiGatewayOidcAuth/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AAGtC,KAAK,cAAc,GAAG,qBAAqB,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAChE,KAAK,WAAW,GAAG,qBAAqB,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAE7D,KAAK,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,eAAe,CAAC,GAAG;IAClD,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,GAAG,CAAC,IAAI;gBAClC,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK;CAajE"}
@@ -1,17 +0,0 @@
1
- import * as SST from "sst/constructs";
2
- import path from "node:path";
3
- export class ApiGatewayOidcAuth extends SST.Auth {
4
- constructor(scope, id, props) {
5
- super(scope, id, {
6
- ...props,
7
- authenticator: {
8
- handler: path.join(import.meta.dirname, "auth-route.handler"),
9
- environment: {
10
- OIDC_ISSUER_URL: props.oidcIssuerUrl,
11
- OIDC_CLIENT_ID: props.oidcClientId,
12
- OIDC_SCOPE: props.oidcScope,
13
- },
14
- },
15
- });
16
- }
17
- }
@@ -1,46 +0,0 @@
1
- import { AuthHandler, OidcAdapter, Session } from "sst/node/auth";
2
- import { Issuer } from "openid-client";
3
-
4
- const oidcClientId = process.env.OIDC_CLIENT_ID;
5
- if (!oidcClientId) {
6
- throw new Error("OIDC_CLIENT_ID not set");
7
- }
8
- const oidcIssuerUrl = process.env.OIDC_ISSUER_URL;
9
- if (!oidcIssuerUrl) {
10
- throw new Error("OIDC_ISSUER_URL not set");
11
- }
12
- const oidcScope = process.env.OIDC_SCOPE;
13
- if (!oidcScope) {
14
- throw new Error("OIDC_SCOPE not set");
15
- }
16
-
17
- const oidcIssuerConfigUrl = new URL(
18
- `${process.env.OIDC_ISSUER_URL?.replace(/\/$/, "")}/.well-known/openid-configuration`,
19
- );
20
-
21
- declare module "sst/node/auth" {
22
- export interface SessionTypes {
23
- user: {
24
- userID: string;
25
- };
26
- }
27
- }
28
-
29
- export const handler = AuthHandler({
30
- providers: {
31
- oidc: OidcAdapter({
32
- issuer: await Issuer.discover(oidcIssuerConfigUrl.href),
33
- clientID: oidcClientId,
34
- scope: oidcScope,
35
- onSuccess: async (tokenset) => {
36
- return Session.cookie({
37
- redirect: "/",
38
- type: "user",
39
- properties: {
40
- userID: tokenset.claims().sub,
41
- },
42
- });
43
- },
44
- }),
45
- },
46
- });
@@ -1,27 +0,0 @@
1
- import * as SST from "sst/constructs";
2
- import path from "node:path";
3
-
4
- type ConstructScope = ConstructorParameters<typeof SST.Auth>[0];
5
- type ConstructId = ConstructorParameters<typeof SST.Auth>[1];
6
-
7
- type Props = Omit<SST.AuthProps, "authenticator"> & {
8
- oidcIssuerUrl: string;
9
- oidcClientId: string;
10
- oidcScope: string;
11
- };
12
-
13
- export class ApiGatewayOidcAuth extends SST.Auth {
14
- constructor(scope: ConstructScope, id: ConstructId, props: Props) {
15
- super(scope, id, {
16
- ...props,
17
- authenticator: {
18
- handler: path.join(import.meta.dirname, "auth-route.handler"),
19
- environment: {
20
- OIDC_ISSUER_URL: props.oidcIssuerUrl,
21
- OIDC_CLIENT_ID: props.oidcClientId,
22
- OIDC_SCOPE: props.oidcScope,
23
- },
24
- },
25
- });
26
- }
27
- }