@geekmidas/auth 0.0.4 → 0.0.5

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.
Files changed (102) hide show
  1. package/dist/{cacheTokenStorage-BlpcZwef.d.mts → cacheTokenStorage-BzBRJfd-.d.mts} +2 -1
  2. package/dist/cacheTokenStorage-Ca05vf3T.mjs +2 -1
  3. package/dist/cacheTokenStorage-Ca05vf3T.mjs.map +1 -0
  4. package/dist/cacheTokenStorage-CvptztkW.cjs +2 -1
  5. package/dist/cacheTokenStorage-CvptztkW.cjs.map +1 -0
  6. package/dist/cacheTokenStorage-yNUpDD8W.d.cts +2 -1
  7. package/dist/cacheTokenStorage.d.mts +1 -1
  8. package/dist/{chunk-DWy1uDak.cjs → chunk-CUT6urMc.cjs} +0 -9
  9. package/dist/client-DaiUm0UZ.cjs +2 -1
  10. package/dist/client-DaiUm0UZ.cjs.map +1 -0
  11. package/dist/client-DjNZS6vZ.mjs +2 -1
  12. package/dist/client-DjNZS6vZ.mjs.map +1 -0
  13. package/dist/client.d.mts +1 -1
  14. package/dist/hono/jwt.cjs +92 -0
  15. package/dist/hono/jwt.cjs.map +1 -0
  16. package/dist/hono/jwt.d.cts +45 -0
  17. package/dist/hono/jwt.d.mts +45 -0
  18. package/dist/hono/jwt.mjs +91 -0
  19. package/dist/hono/jwt.mjs.map +1 -0
  20. package/dist/hono/oidc.cjs +104 -0
  21. package/dist/hono/oidc.cjs.map +1 -0
  22. package/dist/hono/oidc.d.cts +48 -0
  23. package/dist/hono/oidc.d.mts +48 -0
  24. package/dist/hono/oidc.mjs +103 -0
  25. package/dist/hono/oidc.mjs.map +1 -0
  26. package/dist/index.cjs +1 -1
  27. package/dist/index.d.cts +1 -1
  28. package/dist/index.d.mts +2 -2
  29. package/dist/jwt-Bo_eACEi.cjs +70 -0
  30. package/dist/jwt-Bo_eACEi.cjs.map +1 -0
  31. package/dist/jwt-D88cPJyT.mjs +52 -0
  32. package/dist/jwt-D88cPJyT.mjs.map +1 -0
  33. package/dist/jwt-DF9kFbmh.d.cts +61 -0
  34. package/dist/jwt-DH8CJ2xC.d.mts +61 -0
  35. package/dist/jwt.cjs +5 -0
  36. package/dist/jwt.d.cts +2 -0
  37. package/dist/jwt.d.mts +2 -0
  38. package/dist/jwt.mjs +3 -0
  39. package/dist/lambda/jwt.cjs +126 -0
  40. package/dist/lambda/jwt.cjs.map +1 -0
  41. package/dist/lambda/jwt.d.cts +52 -0
  42. package/dist/lambda/jwt.d.mts +52 -0
  43. package/dist/lambda/jwt.mjs +125 -0
  44. package/dist/lambda/jwt.mjs.map +1 -0
  45. package/dist/lambda/oidc.cjs +117 -0
  46. package/dist/lambda/oidc.cjs.map +1 -0
  47. package/dist/lambda/oidc.d.cts +44 -0
  48. package/dist/lambda/oidc.d.mts +44 -0
  49. package/dist/lambda/oidc.mjs +116 -0
  50. package/dist/lambda/oidc.mjs.map +1 -0
  51. package/dist/oidc-C0KyYaAK.cjs +68 -0
  52. package/dist/oidc-C0KyYaAK.cjs.map +1 -0
  53. package/dist/oidc-CKOGLxjV.d.mts +86 -0
  54. package/dist/oidc-DDLIB5gb.d.cts +86 -0
  55. package/dist/oidc-KA30gMlx.mjs +62 -0
  56. package/dist/oidc-KA30gMlx.mjs.map +1 -0
  57. package/dist/oidc.cjs +3 -0
  58. package/dist/oidc.d.cts +3 -0
  59. package/dist/oidc.d.mts +3 -0
  60. package/dist/oidc.mjs +3 -0
  61. package/dist/server.cjs +1 -1
  62. package/dist/server.d.cts +1 -1
  63. package/dist/server.d.mts +2 -2
  64. package/dist/{tokenManager-CCcFk2Py.d.mts → tokenManager--Q93eNYr.d.mts} +2 -1
  65. package/dist/tokenManager-BVXxfHRa.mjs +2 -1
  66. package/dist/tokenManager-BVXxfHRa.mjs.map +1 -0
  67. package/dist/{tokenManager-B60gFnEF.cjs → tokenManager-EPmwgai2.cjs} +3 -2
  68. package/dist/tokenManager-EPmwgai2.cjs.map +1 -0
  69. package/dist/{tokenManager-mpzJKLvX.d.cts → tokenManager-H6-lWEah.d.cts} +2 -1
  70. package/dist/tokenManager.cjs +1 -1
  71. package/dist/tokenManager.d.cts +1 -1
  72. package/dist/tokenManager.d.mts +1 -1
  73. package/package.json +48 -1
  74. package/src/__tests__/hono-jwt.spec.ts +232 -0
  75. package/src/__tests__/hono-oidc.spec.ts +605 -0
  76. package/src/__tests__/jwt.spec.ts +174 -0
  77. package/src/__tests__/lambda-jwt.spec.ts +278 -0
  78. package/src/__tests__/lambda-oidc.spec.ts +623 -0
  79. package/src/__tests__/oidc.spec.ts +405 -0
  80. package/src/hono/jwt.ts +142 -0
  81. package/src/hono/oidc.ts +170 -0
  82. package/src/jwt.ts +106 -0
  83. package/src/lambda/jwt.ts +210 -0
  84. package/src/lambda/oidc.ts +203 -0
  85. package/src/oidc.ts +156 -0
  86. package/dist/__tests__/cacheTokenStorage.spec.cjs +0 -146
  87. package/dist/__tests__/cacheTokenStorage.spec.d.cts +0 -1
  88. package/dist/__tests__/cacheTokenStorage.spec.d.mts +0 -1
  89. package/dist/__tests__/cacheTokenStorage.spec.mjs +0 -145
  90. package/dist/__tests__/client.spec.cjs +0 -17281
  91. package/dist/__tests__/client.spec.d.cts +0 -1
  92. package/dist/__tests__/client.spec.d.mts +0 -1
  93. package/dist/__tests__/client.spec.mjs +0 -17308
  94. package/dist/__tests__/tokenManager.spec.cjs +0 -197
  95. package/dist/__tests__/tokenManager.spec.d.cts +0 -1
  96. package/dist/__tests__/tokenManager.spec.d.mts +0 -1
  97. package/dist/__tests__/tokenManager.spec.mjs +0 -196
  98. package/dist/playground.cjs +0 -0
  99. package/dist/playground.d.cts +0 -1
  100. package/dist/playground.d.mts +0 -1
  101. package/dist/playground.mjs +0 -0
  102. package/src/playground.ts +0 -0
@@ -0,0 +1,48 @@
1
+ import { TokenExtractionOptions } from "../jwt-DH8CJ2xC.mjs";
2
+ import { OidcClaims, OidcConfig, OidcUserInfo, OidcVerifier } from "../oidc-CKOGLxjV.mjs";
3
+ import { Context, MiddlewareHandler } from "hono";
4
+
5
+ //#region src/hono/oidc.d.ts
6
+ interface OidcMiddlewareOptions<TClaims extends OidcClaims = OidcClaims, TUserInfo extends OidcUserInfo = OidcUserInfo> {
7
+ config: OidcConfig;
8
+ extraction?: TokenExtractionOptions;
9
+ contextKey?: string;
10
+ fetchUserInfo?: boolean;
11
+ onError?: (c: Context, error: Error) => Response | Promise<Response>;
12
+ transformClaims?: (claims: OidcClaims, userInfo?: TUserInfo) => TClaims;
13
+ }
14
+ /**
15
+ * OIDC Middleware for Hono
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const oidc = new OidcMiddleware({
20
+ * config: {
21
+ * issuer: 'https://auth.example.com',
22
+ * audience: 'my-client-id',
23
+ * },
24
+ * });
25
+ *
26
+ * app.use('/api/*', oidc.handler());
27
+ *
28
+ * // With user info
29
+ * const oidcWithUserInfo = new OidcMiddleware({
30
+ * config: { issuer: '...', audience: '...' },
31
+ * fetchUserInfo: true,
32
+ * });
33
+ * ```
34
+ */
35
+ declare class OidcMiddleware<TClaims extends OidcClaims = OidcClaims, TUserInfo extends OidcUserInfo = OidcUserInfo> {
36
+ private readonly verifier;
37
+ private readonly extraction;
38
+ private readonly contextKey;
39
+ private readonly fetchUserInfo;
40
+ private readonly onError?;
41
+ private readonly transformClaims?;
42
+ constructor(options: OidcMiddlewareOptions<TClaims, TUserInfo>);
43
+ handler(): MiddlewareHandler;
44
+ optional(): MiddlewareHandler;
45
+ }
46
+ //#endregion
47
+ export { OidcClaims, OidcConfig, OidcMiddleware, OidcMiddlewareOptions, OidcUserInfo, OidcVerifier, TokenExtractionOptions };
48
+ //# sourceMappingURL=oidc.d.mts.map
@@ -0,0 +1,103 @@
1
+ import { OidcVerifier } from "../oidc-KA30gMlx.mjs";
2
+
3
+ //#region src/hono/oidc.ts
4
+ function extractToken(c, options = {}) {
5
+ const { headerName = "authorization", cookieName, tokenPrefix = "Bearer " } = options;
6
+ const headerValue = c.req.header(headerName);
7
+ if (headerValue) {
8
+ if (tokenPrefix && headerValue.startsWith(tokenPrefix)) return headerValue.slice(tokenPrefix.length);
9
+ return headerValue;
10
+ }
11
+ if (cookieName) {
12
+ const cookieHeader = c.req.header("cookie");
13
+ if (cookieHeader) {
14
+ const match = cookieHeader.match(new RegExp(`${cookieName}=([^;]+)`));
15
+ if (match) return match[1];
16
+ }
17
+ }
18
+ return null;
19
+ }
20
+ /**
21
+ * OIDC Middleware for Hono
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const oidc = new OidcMiddleware({
26
+ * config: {
27
+ * issuer: 'https://auth.example.com',
28
+ * audience: 'my-client-id',
29
+ * },
30
+ * });
31
+ *
32
+ * app.use('/api/*', oidc.handler());
33
+ *
34
+ * // With user info
35
+ * const oidcWithUserInfo = new OidcMiddleware({
36
+ * config: { issuer: '...', audience: '...' },
37
+ * fetchUserInfo: true,
38
+ * });
39
+ * ```
40
+ */
41
+ var OidcMiddleware = class {
42
+ verifier;
43
+ extraction;
44
+ contextKey;
45
+ fetchUserInfo;
46
+ onError;
47
+ transformClaims;
48
+ constructor(options) {
49
+ this.verifier = new OidcVerifier(options.config);
50
+ this.extraction = options.extraction ?? {};
51
+ this.contextKey = options.contextKey ?? "oidcClaims";
52
+ this.fetchUserInfo = options.fetchUserInfo ?? false;
53
+ this.onError = options.onError;
54
+ this.transformClaims = options.transformClaims;
55
+ }
56
+ handler() {
57
+ return async (c, next) => {
58
+ const token = extractToken(c, this.extraction);
59
+ if (!token) {
60
+ if (this.onError) return this.onError(c, new Error("No token provided"));
61
+ return c.json({ error: "Unauthorized" }, 401);
62
+ }
63
+ try {
64
+ const payload = await this.verifier.verify(token);
65
+ let userInfo;
66
+ if (this.fetchUserInfo) {
67
+ userInfo = await this.verifier.fetchUserInfo(token) ?? void 0;
68
+ c.set("oidcUserInfo", userInfo);
69
+ }
70
+ const claims = this.transformClaims ? this.transformClaims(payload, userInfo) : payload;
71
+ c.set(this.contextKey, claims);
72
+ c.set("oidcToken", token);
73
+ await next();
74
+ } catch (error) {
75
+ if (this.onError) return this.onError(c, error);
76
+ return c.json({ error: "Invalid token" }, 401);
77
+ }
78
+ };
79
+ }
80
+ optional() {
81
+ return async (c, next) => {
82
+ const token = extractToken(c, this.extraction);
83
+ if (token) {
84
+ const payload = await this.verifier.verifyOrNull(token);
85
+ if (payload) {
86
+ let userInfo;
87
+ if (this.fetchUserInfo) {
88
+ userInfo = await this.verifier.fetchUserInfo(token) ?? void 0;
89
+ c.set("oidcUserInfo", userInfo);
90
+ }
91
+ const claims = this.transformClaims ? this.transformClaims(payload, userInfo) : payload;
92
+ c.set(this.contextKey, claims);
93
+ c.set("oidcToken", token);
94
+ }
95
+ }
96
+ await next();
97
+ };
98
+ }
99
+ };
100
+
101
+ //#endregion
102
+ export { OidcMiddleware, OidcVerifier };
103
+ //# sourceMappingURL=oidc.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oidc.mjs","names":["c: Context","options: TokenExtractionOptions","options: OidcMiddlewareOptions<TClaims, TUserInfo>","next: Next","userInfo: TUserInfo | undefined"],"sources":["../../src/hono/oidc.ts"],"sourcesContent":["import type { Context, MiddlewareHandler, Next } from 'hono';\nimport {\n type OidcClaims,\n type OidcConfig,\n type OidcUserInfo,\n OidcVerifier,\n type TokenExtractionOptions,\n} from '../oidc';\n\nexport {\n OidcVerifier,\n type OidcClaims,\n type OidcConfig,\n type OidcUserInfo,\n type TokenExtractionOptions,\n};\n\nfunction extractToken(\n c: Context,\n options: TokenExtractionOptions = {},\n): string | null {\n const {\n headerName = 'authorization',\n cookieName,\n tokenPrefix = 'Bearer ',\n } = options;\n\n const headerValue = c.req.header(headerName);\n if (headerValue) {\n if (tokenPrefix && headerValue.startsWith(tokenPrefix)) {\n return headerValue.slice(tokenPrefix.length);\n }\n return headerValue;\n }\n\n if (cookieName) {\n const cookieHeader = c.req.header('cookie');\n if (cookieHeader) {\n const match = cookieHeader.match(new RegExp(`${cookieName}=([^;]+)`));\n if (match) {\n return match[1];\n }\n }\n }\n\n return null;\n}\n\nexport interface OidcMiddlewareOptions<\n TClaims extends OidcClaims = OidcClaims,\n TUserInfo extends OidcUserInfo = OidcUserInfo,\n> {\n config: OidcConfig;\n extraction?: TokenExtractionOptions;\n contextKey?: string;\n fetchUserInfo?: boolean;\n onError?: (c: Context, error: Error) => Response | Promise<Response>;\n transformClaims?: (claims: OidcClaims, userInfo?: TUserInfo) => TClaims;\n}\n\n/**\n * OIDC Middleware for Hono\n *\n * @example\n * ```typescript\n * const oidc = new OidcMiddleware({\n * config: {\n * issuer: 'https://auth.example.com',\n * audience: 'my-client-id',\n * },\n * });\n *\n * app.use('/api/*', oidc.handler());\n *\n * // With user info\n * const oidcWithUserInfo = new OidcMiddleware({\n * config: { issuer: '...', audience: '...' },\n * fetchUserInfo: true,\n * });\n * ```\n */\nexport class OidcMiddleware<\n TClaims extends OidcClaims = OidcClaims,\n TUserInfo extends OidcUserInfo = OidcUserInfo,\n> {\n private readonly verifier: OidcVerifier<TClaims, TUserInfo>;\n private readonly extraction: TokenExtractionOptions;\n private readonly contextKey: string;\n private readonly fetchUserInfo: boolean;\n private readonly onError?: (\n c: Context,\n error: Error,\n ) => Response | Promise<Response>;\n private readonly transformClaims?: (\n claims: OidcClaims,\n userInfo?: TUserInfo,\n ) => TClaims;\n\n constructor(options: OidcMiddlewareOptions<TClaims, TUserInfo>) {\n this.verifier = new OidcVerifier(options.config);\n this.extraction = options.extraction ?? {};\n this.contextKey = options.contextKey ?? 'oidcClaims';\n this.fetchUserInfo = options.fetchUserInfo ?? false;\n this.onError = options.onError;\n this.transformClaims = options.transformClaims;\n }\n\n handler(): MiddlewareHandler {\n return async (c: Context, next: Next) => {\n const token = extractToken(c, this.extraction);\n\n if (!token) {\n if (this.onError) {\n return this.onError(c, new Error('No token provided'));\n }\n return c.json({ error: 'Unauthorized' }, 401);\n }\n\n try {\n const payload = await this.verifier.verify(token);\n\n let userInfo: TUserInfo | undefined;\n if (this.fetchUserInfo) {\n userInfo = (await this.verifier.fetchUserInfo(token)) ?? undefined;\n c.set('oidcUserInfo', userInfo);\n }\n\n const claims = this.transformClaims\n ? this.transformClaims(payload, userInfo)\n : payload;\n\n c.set(this.contextKey, claims);\n c.set('oidcToken', token);\n\n await next();\n } catch (error) {\n if (this.onError) {\n return this.onError(c, error as Error);\n }\n return c.json({ error: 'Invalid token' }, 401);\n }\n };\n }\n\n optional(): MiddlewareHandler {\n return async (c: Context, next: Next) => {\n const token = extractToken(c, this.extraction);\n\n if (token) {\n const payload = await this.verifier.verifyOrNull(token);\n if (payload) {\n let userInfo: TUserInfo | undefined;\n if (this.fetchUserInfo) {\n userInfo = (await this.verifier.fetchUserInfo(token)) ?? undefined;\n c.set('oidcUserInfo', userInfo);\n }\n\n const claims = this.transformClaims\n ? this.transformClaims(payload, userInfo)\n : payload;\n\n c.set(this.contextKey, claims);\n c.set('oidcToken', token);\n }\n }\n\n await next();\n };\n }\n}\n"],"mappings":";;;AAiBA,SAAS,aACPA,GACAC,UAAkC,CAAE,GACrB;CACf,MAAM,EACJ,aAAa,iBACb,YACA,cAAc,WACf,GAAG;CAEJ,MAAM,cAAc,EAAE,IAAI,OAAO,WAAW;AAC5C,KAAI,aAAa;AACf,MAAI,eAAe,YAAY,WAAW,YAAY,CACpD,QAAO,YAAY,MAAM,YAAY,OAAO;AAE9C,SAAO;CACR;AAED,KAAI,YAAY;EACd,MAAM,eAAe,EAAE,IAAI,OAAO,SAAS;AAC3C,MAAI,cAAc;GAChB,MAAM,QAAQ,aAAa,MAAM,IAAI,QAAQ,EAAE,WAAW,WAAW;AACrE,OAAI,MACF,QAAO,MAAM;EAEhB;CACF;AAED,QAAO;AACR;;;;;;;;;;;;;;;;;;;;;;AAmCD,IAAa,iBAAb,MAGE;CACA,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CAIjB,AAAiB;CAKjB,YAAYC,SAAoD;AAC9D,OAAK,WAAW,IAAI,aAAa,QAAQ;AACzC,OAAK,aAAa,QAAQ,cAAc,CAAE;AAC1C,OAAK,aAAa,QAAQ,cAAc;AACxC,OAAK,gBAAgB,QAAQ,iBAAiB;AAC9C,OAAK,UAAU,QAAQ;AACvB,OAAK,kBAAkB,QAAQ;CAChC;CAED,UAA6B;AAC3B,SAAO,OAAOF,GAAYG,SAAe;GACvC,MAAM,QAAQ,aAAa,GAAG,KAAK,WAAW;AAE9C,QAAK,OAAO;AACV,QAAI,KAAK,QACP,QAAO,KAAK,QAAQ,GAAG,IAAI,MAAM,qBAAqB;AAExD,WAAO,EAAE,KAAK,EAAE,OAAO,eAAgB,GAAE,IAAI;GAC9C;AAED,OAAI;IACF,MAAM,UAAU,MAAM,KAAK,SAAS,OAAO,MAAM;IAEjD,IAAIC;AACJ,QAAI,KAAK,eAAe;AACtB,gBAAY,MAAM,KAAK,SAAS,cAAc,MAAM;AACpD,OAAE,IAAI,gBAAgB,SAAS;IAChC;IAED,MAAM,SAAS,KAAK,kBAChB,KAAK,gBAAgB,SAAS,SAAS,GACvC;AAEJ,MAAE,IAAI,KAAK,YAAY,OAAO;AAC9B,MAAE,IAAI,aAAa,MAAM;AAEzB,UAAM,MAAM;GACb,SAAQ,OAAO;AACd,QAAI,KAAK,QACP,QAAO,KAAK,QAAQ,GAAG,MAAe;AAExC,WAAO,EAAE,KAAK,EAAE,OAAO,gBAAiB,GAAE,IAAI;GAC/C;EACF;CACF;CAED,WAA8B;AAC5B,SAAO,OAAOJ,GAAYG,SAAe;GACvC,MAAM,QAAQ,aAAa,GAAG,KAAK,WAAW;AAE9C,OAAI,OAAO;IACT,MAAM,UAAU,MAAM,KAAK,SAAS,aAAa,MAAM;AACvD,QAAI,SAAS;KACX,IAAIC;AACJ,SAAI,KAAK,eAAe;AACtB,iBAAY,MAAM,KAAK,SAAS,cAAc,MAAM;AACpD,QAAE,IAAI,gBAAgB,SAAS;KAChC;KAED,MAAM,SAAS,KAAK,kBAChB,KAAK,gBAAgB,SAAS,SAAS,GACvC;AAEJ,OAAE,IAAI,KAAK,YAAY,OAAO;AAC9B,OAAE,IAAI,aAAa,MAAM;IAC1B;GACF;AAED,SAAM,MAAM;EACb;CACF;AACF"}
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  const require_cacheTokenStorage = require('./cacheTokenStorage-CvptztkW.cjs');
2
2
  const require_client = require('./client-DaiUm0UZ.cjs');
3
- const require_tokenManager = require('./tokenManager-B60gFnEF.cjs');
3
+ const require_tokenManager = require('./tokenManager-EPmwgai2.cjs');
4
4
 
5
5
  exports.CacheTokenStorage = require_cacheTokenStorage.CacheTokenStorage;
6
6
  exports.LocalStorageTokenStorage = require_client.LocalStorageTokenStorage;
package/dist/index.d.cts CHANGED
@@ -1,3 +1,3 @@
1
1
  import { CacheTokenStorage, LocalStorageTokenStorage, MemoryTokenStorage, TokenClient, TokenClientOptions, TokenStorage } from "./cacheTokenStorage-yNUpDD8W.cjs";
2
- import { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload } from "./tokenManager-mpzJKLvX.cjs";
2
+ import { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload } from "./tokenManager-H6-lWEah.cjs";
3
3
  export { CacheTokenStorage, DecodedToken, LocalStorageTokenStorage, MemoryTokenStorage, TokenClient, TokenClientOptions, TokenManager, TokenManagerOptions, TokenPair, TokenPayload, TokenStorage };
package/dist/index.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { CacheTokenStorage, LocalStorageTokenStorage, MemoryTokenStorage, TokenClient, TokenClientOptions, TokenStorage } from "./cacheTokenStorage-BlpcZwef.mjs";
2
- import { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload } from "./tokenManager-CCcFk2Py.mjs";
1
+ import { CacheTokenStorage, LocalStorageTokenStorage, MemoryTokenStorage, TokenClient, TokenClientOptions, TokenStorage } from "./cacheTokenStorage-BzBRJfd-.mjs";
2
+ import { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload } from "./tokenManager--Q93eNYr.mjs";
3
3
  export { CacheTokenStorage, DecodedToken, LocalStorageTokenStorage, MemoryTokenStorage, TokenClient, TokenClientOptions, TokenManager, TokenManagerOptions, TokenPair, TokenPayload, TokenStorage };
@@ -0,0 +1,70 @@
1
+ const require_chunk = require('./chunk-CUT6urMc.cjs');
2
+ const jose = require_chunk.__toESM(require("jose"));
3
+
4
+ //#region src/jwt.ts
5
+ function isJwksConfig(config) {
6
+ return "jwksUri" in config;
7
+ }
8
+ /**
9
+ * JWT Verifier with JWKS caching
10
+ */
11
+ var JwtVerifier = class {
12
+ jwks = null;
13
+ verifyOptions;
14
+ constructor(config) {
15
+ this.config = config;
16
+ this.verifyOptions = {
17
+ issuer: config.issuer,
18
+ audience: config.audience,
19
+ algorithms: config.algorithms ?? (isJwksConfig(config) ? void 0 : ["HS256"])
20
+ };
21
+ }
22
+ async verify(token) {
23
+ if (isJwksConfig(this.config)) {
24
+ if (!this.jwks) this.jwks = jose.createRemoteJWKSet(new URL(this.config.jwksUri));
25
+ const { payload: payload$1 } = await jose.jwtVerify(token, this.jwks, this.verifyOptions);
26
+ return payload$1;
27
+ }
28
+ const secret = new TextEncoder().encode(this.config.secret);
29
+ const { payload } = await jose.jwtVerify(token, secret, this.verifyOptions);
30
+ return payload;
31
+ }
32
+ async verifyOrNull(token) {
33
+ try {
34
+ return await this.verify(token);
35
+ } catch {
36
+ return null;
37
+ }
38
+ }
39
+ clearCache() {
40
+ this.jwks = null;
41
+ }
42
+ };
43
+ /**
44
+ * Decode a JWT without verification
45
+ * WARNING: This does NOT verify the token signature!
46
+ */
47
+ function decodeJwt(token) {
48
+ return jose.decodeJwt(token);
49
+ }
50
+
51
+ //#endregion
52
+ Object.defineProperty(exports, 'JwtVerifier', {
53
+ enumerable: true,
54
+ get: function () {
55
+ return JwtVerifier;
56
+ }
57
+ });
58
+ Object.defineProperty(exports, 'decodeJwt', {
59
+ enumerable: true,
60
+ get: function () {
61
+ return decodeJwt;
62
+ }
63
+ });
64
+ Object.defineProperty(exports, 'isJwksConfig', {
65
+ enumerable: true,
66
+ get: function () {
67
+ return isJwksConfig;
68
+ }
69
+ });
70
+ //# sourceMappingURL=jwt-Bo_eACEi.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt-Bo_eACEi.cjs","names":["config: JwtConfig","token: string","payload"],"sources":["../src/jwt.ts"],"sourcesContent":["import * as jose from 'jose';\n\n/**\n * Standard JWT claims\n */\nexport interface JwtClaims {\n sub?: string;\n iss?: string;\n aud?: string | string[];\n exp?: number;\n iat?: number;\n nbf?: number;\n jti?: string;\n}\n\n/**\n * Configuration for JWT verification with a symmetric secret\n */\nexport interface JwtSecretConfig {\n secret: string;\n issuer?: string;\n audience?: string | string[];\n algorithms?: string[];\n}\n\n/**\n * Configuration for JWT verification with JWKS\n */\nexport interface JwtJwksConfig {\n jwksUri: string;\n issuer?: string;\n audience?: string | string[];\n algorithms?: string[];\n}\n\nexport type JwtConfig = JwtSecretConfig | JwtJwksConfig;\n\n/**\n * Options for token extraction from requests\n */\nexport interface TokenExtractionOptions {\n headerName?: string;\n cookieName?: string;\n tokenPrefix?: string;\n}\n\nexport function isJwksConfig(config: JwtConfig): config is JwtJwksConfig {\n return 'jwksUri' in config;\n}\n\n/**\n * JWT Verifier with JWKS caching\n */\nexport class JwtVerifier<TClaims extends JwtClaims = JwtClaims> {\n private jwks: jose.JWTVerifyGetKey | null = null;\n private readonly verifyOptions: jose.JWTVerifyOptions;\n\n constructor(private readonly config: JwtConfig) {\n this.verifyOptions = {\n issuer: config.issuer,\n audience: config.audience,\n algorithms:\n config.algorithms ?? (isJwksConfig(config) ? undefined : ['HS256']),\n };\n }\n\n async verify(token: string): Promise<TClaims> {\n if (isJwksConfig(this.config)) {\n if (!this.jwks) {\n this.jwks = jose.createRemoteJWKSet(new URL(this.config.jwksUri));\n }\n const { payload } = await jose.jwtVerify(\n token,\n this.jwks,\n this.verifyOptions,\n );\n return payload as unknown as TClaims;\n }\n\n const secret = new TextEncoder().encode(this.config.secret);\n const { payload } = await jose.jwtVerify(token, secret, this.verifyOptions);\n return payload as unknown as TClaims;\n }\n\n async verifyOrNull(token: string): Promise<TClaims | null> {\n try {\n return await this.verify(token);\n } catch {\n return null;\n }\n }\n\n clearCache(): void {\n this.jwks = null;\n }\n}\n\n/**\n * Decode a JWT without verification\n * WARNING: This does NOT verify the token signature!\n */\nexport function decodeJwt<TClaims extends JwtClaims = JwtClaims>(\n token: string,\n): TClaims {\n return jose.decodeJwt(token) as unknown as TClaims;\n}\n"],"mappings":";;;;AA8CA,SAAgB,aAAaA,QAA4C;AACvE,QAAO,aAAa;AACrB;;;;AAKD,IAAa,cAAb,MAAgE;CAC9D,AAAQ,OAAoC;CAC5C,AAAiB;CAEjB,YAA6BA,QAAmB;EAAnB;AAC3B,OAAK,gBAAgB;GACnB,QAAQ,OAAO;GACf,UAAU,OAAO;GACjB,YACE,OAAO,eAAe,aAAa,OAAO,YAAe,CAAC,OAAQ;EACrE;CACF;CAED,MAAM,OAAOC,OAAiC;AAC5C,MAAI,aAAa,KAAK,OAAO,EAAE;AAC7B,QAAK,KAAK,KACR,MAAK,OAAO,KAAK,mBAAmB,IAAI,IAAI,KAAK,OAAO,SAAS;GAEnE,MAAM,EAAE,oBAAS,GAAG,MAAM,KAAK,UAC7B,OACA,KAAK,MACL,KAAK,cACN;AACD,UAAOC;EACR;EAED,MAAM,SAAS,IAAI,cAAc,OAAO,KAAK,OAAO,OAAO;EAC3D,MAAM,EAAE,SAAS,GAAG,MAAM,KAAK,UAAU,OAAO,QAAQ,KAAK,cAAc;AAC3E,SAAO;CACR;CAED,MAAM,aAAaD,OAAwC;AACzD,MAAI;AACF,UAAO,MAAM,KAAK,OAAO,MAAM;EAChC,QAAO;AACN,UAAO;EACR;CACF;CAED,aAAmB;AACjB,OAAK,OAAO;CACb;AACF;;;;;AAMD,SAAgB,UACdA,OACS;AACT,QAAO,KAAK,UAAU,MAAM;AAC7B"}
@@ -0,0 +1,52 @@
1
+ import * as jose from "jose";
2
+
3
+ //#region src/jwt.ts
4
+ function isJwksConfig(config) {
5
+ return "jwksUri" in config;
6
+ }
7
+ /**
8
+ * JWT Verifier with JWKS caching
9
+ */
10
+ var JwtVerifier = class {
11
+ jwks = null;
12
+ verifyOptions;
13
+ constructor(config) {
14
+ this.config = config;
15
+ this.verifyOptions = {
16
+ issuer: config.issuer,
17
+ audience: config.audience,
18
+ algorithms: config.algorithms ?? (isJwksConfig(config) ? void 0 : ["HS256"])
19
+ };
20
+ }
21
+ async verify(token) {
22
+ if (isJwksConfig(this.config)) {
23
+ if (!this.jwks) this.jwks = jose.createRemoteJWKSet(new URL(this.config.jwksUri));
24
+ const { payload: payload$1 } = await jose.jwtVerify(token, this.jwks, this.verifyOptions);
25
+ return payload$1;
26
+ }
27
+ const secret = new TextEncoder().encode(this.config.secret);
28
+ const { payload } = await jose.jwtVerify(token, secret, this.verifyOptions);
29
+ return payload;
30
+ }
31
+ async verifyOrNull(token) {
32
+ try {
33
+ return await this.verify(token);
34
+ } catch {
35
+ return null;
36
+ }
37
+ }
38
+ clearCache() {
39
+ this.jwks = null;
40
+ }
41
+ };
42
+ /**
43
+ * Decode a JWT without verification
44
+ * WARNING: This does NOT verify the token signature!
45
+ */
46
+ function decodeJwt(token) {
47
+ return jose.decodeJwt(token);
48
+ }
49
+
50
+ //#endregion
51
+ export { JwtVerifier, decodeJwt, isJwksConfig };
52
+ //# sourceMappingURL=jwt-D88cPJyT.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt-D88cPJyT.mjs","names":["config: JwtConfig","token: string","payload"],"sources":["../src/jwt.ts"],"sourcesContent":["import * as jose from 'jose';\n\n/**\n * Standard JWT claims\n */\nexport interface JwtClaims {\n sub?: string;\n iss?: string;\n aud?: string | string[];\n exp?: number;\n iat?: number;\n nbf?: number;\n jti?: string;\n}\n\n/**\n * Configuration for JWT verification with a symmetric secret\n */\nexport interface JwtSecretConfig {\n secret: string;\n issuer?: string;\n audience?: string | string[];\n algorithms?: string[];\n}\n\n/**\n * Configuration for JWT verification with JWKS\n */\nexport interface JwtJwksConfig {\n jwksUri: string;\n issuer?: string;\n audience?: string | string[];\n algorithms?: string[];\n}\n\nexport type JwtConfig = JwtSecretConfig | JwtJwksConfig;\n\n/**\n * Options for token extraction from requests\n */\nexport interface TokenExtractionOptions {\n headerName?: string;\n cookieName?: string;\n tokenPrefix?: string;\n}\n\nexport function isJwksConfig(config: JwtConfig): config is JwtJwksConfig {\n return 'jwksUri' in config;\n}\n\n/**\n * JWT Verifier with JWKS caching\n */\nexport class JwtVerifier<TClaims extends JwtClaims = JwtClaims> {\n private jwks: jose.JWTVerifyGetKey | null = null;\n private readonly verifyOptions: jose.JWTVerifyOptions;\n\n constructor(private readonly config: JwtConfig) {\n this.verifyOptions = {\n issuer: config.issuer,\n audience: config.audience,\n algorithms:\n config.algorithms ?? (isJwksConfig(config) ? undefined : ['HS256']),\n };\n }\n\n async verify(token: string): Promise<TClaims> {\n if (isJwksConfig(this.config)) {\n if (!this.jwks) {\n this.jwks = jose.createRemoteJWKSet(new URL(this.config.jwksUri));\n }\n const { payload } = await jose.jwtVerify(\n token,\n this.jwks,\n this.verifyOptions,\n );\n return payload as unknown as TClaims;\n }\n\n const secret = new TextEncoder().encode(this.config.secret);\n const { payload } = await jose.jwtVerify(token, secret, this.verifyOptions);\n return payload as unknown as TClaims;\n }\n\n async verifyOrNull(token: string): Promise<TClaims | null> {\n try {\n return await this.verify(token);\n } catch {\n return null;\n }\n }\n\n clearCache(): void {\n this.jwks = null;\n }\n}\n\n/**\n * Decode a JWT without verification\n * WARNING: This does NOT verify the token signature!\n */\nexport function decodeJwt<TClaims extends JwtClaims = JwtClaims>(\n token: string,\n): TClaims {\n return jose.decodeJwt(token) as unknown as TClaims;\n}\n"],"mappings":";;;AA8CA,SAAgB,aAAaA,QAA4C;AACvE,QAAO,aAAa;AACrB;;;;AAKD,IAAa,cAAb,MAAgE;CAC9D,AAAQ,OAAoC;CAC5C,AAAiB;CAEjB,YAA6BA,QAAmB;EAAnB;AAC3B,OAAK,gBAAgB;GACnB,QAAQ,OAAO;GACf,UAAU,OAAO;GACjB,YACE,OAAO,eAAe,aAAa,OAAO,YAAe,CAAC,OAAQ;EACrE;CACF;CAED,MAAM,OAAOC,OAAiC;AAC5C,MAAI,aAAa,KAAK,OAAO,EAAE;AAC7B,QAAK,KAAK,KACR,MAAK,OAAO,KAAK,mBAAmB,IAAI,IAAI,KAAK,OAAO,SAAS;GAEnE,MAAM,EAAE,oBAAS,GAAG,MAAM,KAAK,UAC7B,OACA,KAAK,MACL,KAAK,cACN;AACD,UAAOC;EACR;EAED,MAAM,SAAS,IAAI,cAAc,OAAO,KAAK,OAAO,OAAO;EAC3D,MAAM,EAAE,SAAS,GAAG,MAAM,KAAK,UAAU,OAAO,QAAQ,KAAK,cAAc;AAC3E,SAAO;CACR;CAED,MAAM,aAAaD,OAAwC;AACzD,MAAI;AACF,UAAO,MAAM,KAAK,OAAO,MAAM;EAChC,QAAO;AACN,UAAO;EACR;CACF;CAED,aAAmB;AACjB,OAAK,OAAO;CACb;AACF;;;;;AAMD,SAAgB,UACdA,OACS;AACT,QAAO,KAAK,UAAU,MAAM;AAC7B"}
@@ -0,0 +1,61 @@
1
+ //#region src/jwt.d.ts
2
+ /**
3
+ * Standard JWT claims
4
+ */
5
+ interface JwtClaims {
6
+ sub?: string;
7
+ iss?: string;
8
+ aud?: string | string[];
9
+ exp?: number;
10
+ iat?: number;
11
+ nbf?: number;
12
+ jti?: string;
13
+ }
14
+ /**
15
+ * Configuration for JWT verification with a symmetric secret
16
+ */
17
+ interface JwtSecretConfig {
18
+ secret: string;
19
+ issuer?: string;
20
+ audience?: string | string[];
21
+ algorithms?: string[];
22
+ }
23
+ /**
24
+ * Configuration for JWT verification with JWKS
25
+ */
26
+ interface JwtJwksConfig {
27
+ jwksUri: string;
28
+ issuer?: string;
29
+ audience?: string | string[];
30
+ algorithms?: string[];
31
+ }
32
+ type JwtConfig = JwtSecretConfig | JwtJwksConfig;
33
+ /**
34
+ * Options for token extraction from requests
35
+ */
36
+ interface TokenExtractionOptions {
37
+ headerName?: string;
38
+ cookieName?: string;
39
+ tokenPrefix?: string;
40
+ }
41
+ declare function isJwksConfig(config: JwtConfig): config is JwtJwksConfig;
42
+ /**
43
+ * JWT Verifier with JWKS caching
44
+ */
45
+ declare class JwtVerifier<TClaims extends JwtClaims = JwtClaims> {
46
+ private readonly config;
47
+ private jwks;
48
+ private readonly verifyOptions;
49
+ constructor(config: JwtConfig);
50
+ verify(token: string): Promise<TClaims>;
51
+ verifyOrNull(token: string): Promise<TClaims | null>;
52
+ clearCache(): void;
53
+ }
54
+ /**
55
+ * Decode a JWT without verification
56
+ * WARNING: This does NOT verify the token signature!
57
+ */
58
+ declare function decodeJwt<TClaims extends JwtClaims = JwtClaims>(token: string): TClaims;
59
+ //#endregion
60
+ export { JwtClaims, JwtConfig, JwtJwksConfig, JwtSecretConfig, JwtVerifier, TokenExtractionOptions, decodeJwt, isJwksConfig };
61
+ //# sourceMappingURL=jwt-DF9kFbmh.d.cts.map
@@ -0,0 +1,61 @@
1
+ //#region src/jwt.d.ts
2
+ /**
3
+ * Standard JWT claims
4
+ */
5
+ interface JwtClaims {
6
+ sub?: string;
7
+ iss?: string;
8
+ aud?: string | string[];
9
+ exp?: number;
10
+ iat?: number;
11
+ nbf?: number;
12
+ jti?: string;
13
+ }
14
+ /**
15
+ * Configuration for JWT verification with a symmetric secret
16
+ */
17
+ interface JwtSecretConfig {
18
+ secret: string;
19
+ issuer?: string;
20
+ audience?: string | string[];
21
+ algorithms?: string[];
22
+ }
23
+ /**
24
+ * Configuration for JWT verification with JWKS
25
+ */
26
+ interface JwtJwksConfig {
27
+ jwksUri: string;
28
+ issuer?: string;
29
+ audience?: string | string[];
30
+ algorithms?: string[];
31
+ }
32
+ type JwtConfig = JwtSecretConfig | JwtJwksConfig;
33
+ /**
34
+ * Options for token extraction from requests
35
+ */
36
+ interface TokenExtractionOptions {
37
+ headerName?: string;
38
+ cookieName?: string;
39
+ tokenPrefix?: string;
40
+ }
41
+ declare function isJwksConfig(config: JwtConfig): config is JwtJwksConfig;
42
+ /**
43
+ * JWT Verifier with JWKS caching
44
+ */
45
+ declare class JwtVerifier<TClaims extends JwtClaims = JwtClaims> {
46
+ private readonly config;
47
+ private jwks;
48
+ private readonly verifyOptions;
49
+ constructor(config: JwtConfig);
50
+ verify(token: string): Promise<TClaims>;
51
+ verifyOrNull(token: string): Promise<TClaims | null>;
52
+ clearCache(): void;
53
+ }
54
+ /**
55
+ * Decode a JWT without verification
56
+ * WARNING: This does NOT verify the token signature!
57
+ */
58
+ declare function decodeJwt<TClaims extends JwtClaims = JwtClaims>(token: string): TClaims;
59
+ //#endregion
60
+ export { JwtClaims, JwtConfig, JwtJwksConfig, JwtSecretConfig, JwtVerifier, TokenExtractionOptions, decodeJwt, isJwksConfig };
61
+ //# sourceMappingURL=jwt-DH8CJ2xC.d.mts.map
package/dist/jwt.cjs ADDED
@@ -0,0 +1,5 @@
1
+ const require_jwt = require('./jwt-Bo_eACEi.cjs');
2
+
3
+ exports.JwtVerifier = require_jwt.JwtVerifier;
4
+ exports.decodeJwt = require_jwt.decodeJwt;
5
+ exports.isJwksConfig = require_jwt.isJwksConfig;
package/dist/jwt.d.cts ADDED
@@ -0,0 +1,2 @@
1
+ import { JwtClaims, JwtConfig, JwtJwksConfig, JwtSecretConfig, JwtVerifier, TokenExtractionOptions, decodeJwt, isJwksConfig } from "./jwt-DF9kFbmh.cjs";
2
+ export { JwtClaims, JwtConfig, JwtJwksConfig, JwtSecretConfig, JwtVerifier, TokenExtractionOptions, decodeJwt, isJwksConfig };
package/dist/jwt.d.mts ADDED
@@ -0,0 +1,2 @@
1
+ import { JwtClaims, JwtConfig, JwtJwksConfig, JwtSecretConfig, JwtVerifier, TokenExtractionOptions, decodeJwt, isJwksConfig } from "./jwt-DH8CJ2xC.mjs";
2
+ export { JwtClaims, JwtConfig, JwtJwksConfig, JwtSecretConfig, JwtVerifier, TokenExtractionOptions, decodeJwt, isJwksConfig };
package/dist/jwt.mjs ADDED
@@ -0,0 +1,3 @@
1
+ import { JwtVerifier, decodeJwt, isJwksConfig } from "./jwt-D88cPJyT.mjs";
2
+
3
+ export { JwtVerifier, decodeJwt, isJwksConfig };
@@ -0,0 +1,126 @@
1
+ const require_jwt = require('../jwt-Bo_eACEi.cjs');
2
+
3
+ //#region src/lambda/jwt.ts
4
+ function generatePolicy(principalId, effect, resource, context) {
5
+ const policyDocument = {
6
+ Version: "2012-10-17",
7
+ Statement: [{
8
+ Action: "execute-api:Invoke",
9
+ Effect: effect,
10
+ Resource: resource
11
+ }]
12
+ };
13
+ return {
14
+ principalId,
15
+ policyDocument,
16
+ context
17
+ };
18
+ }
19
+ function getWildcardResource(methodArn) {
20
+ const parts = methodArn.split("/");
21
+ return `${parts[0]}/${parts[1]}/*`;
22
+ }
23
+ /**
24
+ * JWT Lambda Authorizer
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const authorizer = new JwtAuthorizer({
29
+ * config: {
30
+ * jwksUri: 'https://auth.example.com/.well-known/jwks.json',
31
+ * issuer: 'https://auth.example.com',
32
+ * },
33
+ * getContext: (claims) => ({ userId: claims.sub! }),
34
+ * });
35
+ *
36
+ * // TOKEN authorizer
37
+ * export const tokenHandler = authorizer.tokenHandler();
38
+ *
39
+ * // REQUEST authorizer
40
+ * export const requestHandler = authorizer.requestHandler();
41
+ * ```
42
+ */
43
+ var JwtAuthorizer = class {
44
+ verifier;
45
+ extraction;
46
+ wildcardResource;
47
+ getPrincipalId;
48
+ getContext;
49
+ authorize;
50
+ constructor(options) {
51
+ this.verifier = new require_jwt.JwtVerifier(options.config);
52
+ this.extraction = options.extraction ?? {};
53
+ this.wildcardResource = options.wildcardResource ?? true;
54
+ this.getPrincipalId = options.getPrincipalId ?? ((c) => c.sub ?? "unknown");
55
+ this.getContext = options.getContext;
56
+ this.authorize = options.authorize;
57
+ }
58
+ /**
59
+ * Returns a TOKEN authorizer handler
60
+ */
61
+ tokenHandler() {
62
+ return async (event, _context) => {
63
+ const { authorizationToken, methodArn } = event;
64
+ const resource = this.wildcardResource ? getWildcardResource(methodArn) : methodArn;
65
+ const token = authorizationToken.startsWith("Bearer ") ? authorizationToken.slice(7) : authorizationToken;
66
+ try {
67
+ const claims = await this.verifier.verify(token);
68
+ if (this.authorize) {
69
+ const isAuthorized = await this.authorize(claims);
70
+ if (!isAuthorized) return generatePolicy("unauthorized", "Deny", resource);
71
+ }
72
+ const principalId = this.getPrincipalId(claims);
73
+ const context = this.getContext?.(claims);
74
+ return generatePolicy(principalId, "Allow", resource, context);
75
+ } catch {
76
+ return generatePolicy("unauthorized", "Deny", resource);
77
+ }
78
+ };
79
+ }
80
+ /**
81
+ * Returns a REQUEST authorizer handler
82
+ */
83
+ requestHandler() {
84
+ const { headerName = "authorization", cookieName, tokenPrefix = "Bearer " } = this.extraction;
85
+ const extractToken = (event) => {
86
+ const headers = event.headers ?? {};
87
+ const headerKey = Object.keys(headers).find((k) => k.toLowerCase() === headerName.toLowerCase());
88
+ if (headerKey) {
89
+ const headerValue = headers[headerKey];
90
+ if (headerValue) {
91
+ if (tokenPrefix && headerValue.startsWith(tokenPrefix)) return headerValue.slice(tokenPrefix.length);
92
+ return headerValue;
93
+ }
94
+ }
95
+ if (cookieName) {
96
+ const cookieHeader = headers["cookie"] ?? headers["Cookie"] ?? "";
97
+ const match = cookieHeader.match(new RegExp(`${cookieName}=([^;]+)`));
98
+ if (match) return match[1];
99
+ }
100
+ return null;
101
+ };
102
+ return async (event, _context) => {
103
+ const methodArn = event.methodArn;
104
+ const resource = this.wildcardResource ? getWildcardResource(methodArn) : methodArn;
105
+ const token = extractToken(event);
106
+ if (!token) return generatePolicy("unauthorized", "Deny", resource);
107
+ try {
108
+ const claims = await this.verifier.verify(token);
109
+ if (this.authorize) {
110
+ const isAuthorized = await this.authorize(claims);
111
+ if (!isAuthorized) return generatePolicy("unauthorized", "Deny", resource);
112
+ }
113
+ const principalId = this.getPrincipalId(claims);
114
+ const context = this.getContext?.(claims);
115
+ return generatePolicy(principalId, "Allow", resource, context);
116
+ } catch {
117
+ return generatePolicy("unauthorized", "Deny", resource);
118
+ }
119
+ };
120
+ }
121
+ };
122
+
123
+ //#endregion
124
+ exports.JwtAuthorizer = JwtAuthorizer;
125
+ exports.JwtVerifier = require_jwt.JwtVerifier;
126
+ //# sourceMappingURL=jwt.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.cjs","names":["principalId: string","effect: 'Allow' | 'Deny'","resource: string","context?: Record<string, string | number | boolean>","policyDocument: PolicyDocument","methodArn: string","options: JwtAuthorizerOptions<TClaims>","JwtVerifier","event: APIGatewayTokenAuthorizerEvent","_context: LambdaContext","event: APIGatewayRequestAuthorizerEvent"],"sources":["../../src/lambda/jwt.ts"],"sourcesContent":["import type {\n APIGatewayAuthorizerResult,\n APIGatewayRequestAuthorizerEvent,\n APIGatewayTokenAuthorizerEvent,\n Context as LambdaContext,\n PolicyDocument,\n} from 'aws-lambda';\nimport {\n type JwtClaims,\n type JwtConfig,\n JwtVerifier,\n type TokenExtractionOptions,\n} from '../jwt';\n\nexport {\n JwtVerifier,\n type JwtClaims,\n type JwtConfig,\n type TokenExtractionOptions,\n};\n\nfunction generatePolicy(\n principalId: string,\n effect: 'Allow' | 'Deny',\n resource: string,\n context?: Record<string, string | number | boolean>,\n): APIGatewayAuthorizerResult {\n const policyDocument: PolicyDocument = {\n Version: '2012-10-17',\n Statement: [\n {\n Action: 'execute-api:Invoke',\n Effect: effect,\n Resource: resource,\n },\n ],\n };\n\n return {\n principalId,\n policyDocument,\n context,\n };\n}\n\nfunction getWildcardResource(methodArn: string): string {\n const parts = methodArn.split('/');\n return `${parts[0]}/${parts[1]}/*`;\n}\n\nexport interface JwtAuthorizerOptions<TClaims extends JwtClaims = JwtClaims> {\n config: JwtConfig;\n extraction?: TokenExtractionOptions;\n wildcardResource?: boolean;\n getPrincipalId?: (claims: TClaims) => string;\n getContext?: (\n claims: TClaims,\n ) => Record<string, string | number | boolean> | undefined;\n authorize?: (claims: TClaims) => boolean | Promise<boolean>;\n}\n\n/**\n * JWT Lambda Authorizer\n *\n * @example\n * ```typescript\n * const authorizer = new JwtAuthorizer({\n * config: {\n * jwksUri: 'https://auth.example.com/.well-known/jwks.json',\n * issuer: 'https://auth.example.com',\n * },\n * getContext: (claims) => ({ userId: claims.sub! }),\n * });\n *\n * // TOKEN authorizer\n * export const tokenHandler = authorizer.tokenHandler();\n *\n * // REQUEST authorizer\n * export const requestHandler = authorizer.requestHandler();\n * ```\n */\nexport class JwtAuthorizer<TClaims extends JwtClaims = JwtClaims> {\n private readonly verifier: JwtVerifier<TClaims>;\n private readonly extraction: TokenExtractionOptions;\n private readonly wildcardResource: boolean;\n private readonly getPrincipalId: (claims: TClaims) => string;\n private readonly getContext?: (\n claims: TClaims,\n ) => Record<string, string | number | boolean> | undefined;\n private readonly authorize?: (claims: TClaims) => boolean | Promise<boolean>;\n\n constructor(options: JwtAuthorizerOptions<TClaims>) {\n this.verifier = new JwtVerifier(options.config);\n this.extraction = options.extraction ?? {};\n this.wildcardResource = options.wildcardResource ?? true;\n this.getPrincipalId = options.getPrincipalId ?? ((c) => c.sub ?? 'unknown');\n this.getContext = options.getContext;\n this.authorize = options.authorize;\n }\n\n /**\n * Returns a TOKEN authorizer handler\n */\n tokenHandler() {\n return async (\n event: APIGatewayTokenAuthorizerEvent,\n _context: LambdaContext,\n ): Promise<APIGatewayAuthorizerResult> => {\n const { authorizationToken, methodArn } = event;\n const resource = this.wildcardResource\n ? getWildcardResource(methodArn)\n : methodArn;\n\n const token = authorizationToken.startsWith('Bearer ')\n ? authorizationToken.slice(7)\n : authorizationToken;\n\n try {\n const claims = await this.verifier.verify(token);\n\n if (this.authorize) {\n const isAuthorized = await this.authorize(claims);\n if (!isAuthorized) {\n return generatePolicy('unauthorized', 'Deny', resource);\n }\n }\n\n const principalId = this.getPrincipalId(claims);\n const context = this.getContext?.(claims);\n\n return generatePolicy(principalId, 'Allow', resource, context);\n } catch {\n return generatePolicy('unauthorized', 'Deny', resource);\n }\n };\n }\n\n /**\n * Returns a REQUEST authorizer handler\n */\n requestHandler() {\n const {\n headerName = 'authorization',\n cookieName,\n tokenPrefix = 'Bearer ',\n } = this.extraction;\n\n const extractToken = (\n event: APIGatewayRequestAuthorizerEvent,\n ): string | null => {\n const headers = event.headers ?? {};\n const headerKey = Object.keys(headers).find(\n (k) => k.toLowerCase() === headerName.toLowerCase(),\n );\n if (headerKey) {\n const headerValue = headers[headerKey];\n if (headerValue) {\n if (tokenPrefix && headerValue.startsWith(tokenPrefix)) {\n return headerValue.slice(tokenPrefix.length);\n }\n return headerValue;\n }\n }\n\n if (cookieName) {\n const cookieHeader = headers['cookie'] ?? headers['Cookie'] ?? '';\n const match = cookieHeader.match(new RegExp(`${cookieName}=([^;]+)`));\n if (match) {\n return match[1];\n }\n }\n\n return null;\n };\n\n return async (\n event: APIGatewayRequestAuthorizerEvent,\n _context: LambdaContext,\n ): Promise<APIGatewayAuthorizerResult> => {\n const methodArn = event.methodArn;\n const resource = this.wildcardResource\n ? getWildcardResource(methodArn)\n : methodArn;\n\n const token = extractToken(event);\n\n if (!token) {\n return generatePolicy('unauthorized', 'Deny', resource);\n }\n\n try {\n const claims = await this.verifier.verify(token);\n\n if (this.authorize) {\n const isAuthorized = await this.authorize(claims);\n if (!isAuthorized) {\n return generatePolicy('unauthorized', 'Deny', resource);\n }\n }\n\n const principalId = this.getPrincipalId(claims);\n const context = this.getContext?.(claims);\n\n return generatePolicy(principalId, 'Allow', resource, context);\n } catch {\n return generatePolicy('unauthorized', 'Deny', resource);\n }\n };\n }\n}\n"],"mappings":"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"}