@geekmidas/auth 10.0.0-alpha.99 → 10.0.0

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 (147) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/dist/cacheTokenStorage-16NE8Cd9.mjs +32 -0
  3. package/dist/cacheTokenStorage-16NE8Cd9.mjs.map +1 -0
  4. package/dist/{cacheTokenStorage-B3u8Sf-6.d.cts → cacheTokenStorage-B7sOoysu.d.cts} +5 -2
  5. package/dist/cacheTokenStorage-B7sOoysu.d.cts.map +1 -0
  6. package/dist/cacheTokenStorage-CEpMniTi.cjs +38 -0
  7. package/dist/cacheTokenStorage-CEpMniTi.cjs.map +1 -0
  8. package/dist/{cacheTokenStorage-B3u8Sf-6.d.mts → cacheTokenStorage-_tq4Kmhc.d.mts} +5 -2
  9. package/dist/cacheTokenStorage-_tq4Kmhc.d.mts.map +1 -0
  10. package/dist/cacheTokenStorage.cjs +2 -30
  11. package/dist/cacheTokenStorage.d.cts +1 -1
  12. package/dist/cacheTokenStorage.d.mts +1 -1
  13. package/dist/cacheTokenStorage.mjs +2 -29
  14. package/dist/{rolldown-runtime-VH7oDXx4.cjs → chunk-CUT6urMc.cjs} +10 -8
  15. package/dist/client-BPl_mMvb.cjs +162 -0
  16. package/dist/client-BPl_mMvb.cjs.map +1 -0
  17. package/dist/client-eidYNJSH.mjs +144 -0
  18. package/dist/client-eidYNJSH.mjs.map +1 -0
  19. package/dist/client.cjs +6 -144
  20. package/dist/client.d.cts +1 -1
  21. package/dist/client.d.mts +1 -1
  22. package/dist/client.mjs +3 -140
  23. package/dist/hono/jwt.cjs +10 -7
  24. package/dist/hono/jwt.cjs.map +1 -1
  25. package/dist/hono/jwt.d.cts +6 -4
  26. package/dist/hono/jwt.d.cts.map +1 -1
  27. package/dist/hono/jwt.d.mts +6 -4
  28. package/dist/hono/jwt.d.mts.map +1 -1
  29. package/dist/hono/jwt.mjs +10 -7
  30. package/dist/hono/jwt.mjs.map +1 -1
  31. package/dist/hono/oidc.cjs +10 -7
  32. package/dist/hono/oidc.cjs.map +1 -1
  33. package/dist/hono/oidc.d.cts +7 -5
  34. package/dist/hono/oidc.d.cts.map +1 -1
  35. package/dist/hono/oidc.d.mts +7 -5
  36. package/dist/hono/oidc.d.mts.map +1 -1
  37. package/dist/hono/oidc.mjs +10 -7
  38. package/dist/hono/oidc.mjs.map +1 -1
  39. package/dist/index.cjs +5 -5
  40. package/dist/index.d.cts +2 -2
  41. package/dist/index.d.mts +2 -2
  42. package/dist/index.mjs +5 -4
  43. package/dist/{jwt-CoKrpeMB.d.mts → jwt-3eIuY2dg.d.cts} +3 -2
  44. package/dist/jwt-3eIuY2dg.d.cts.map +1 -0
  45. package/dist/jwt-Bo_eACEi.cjs +70 -0
  46. package/dist/jwt-Bo_eACEi.cjs.map +1 -0
  47. package/dist/{jwt-CoKrpeMB.d.cts → jwt-BqLlRkw-.d.mts} +3 -2
  48. package/dist/jwt-BqLlRkw-.d.mts.map +1 -0
  49. package/dist/jwt-D88cPJyT.mjs +52 -0
  50. package/dist/jwt-D88cPJyT.mjs.map +1 -0
  51. package/dist/jwt.cjs +4 -56
  52. package/dist/jwt.d.cts +1 -1
  53. package/dist/jwt.d.mts +1 -1
  54. package/dist/jwt.mjs +2 -51
  55. package/dist/lambda/jwt.cjs +20 -16
  56. package/dist/lambda/jwt.cjs.map +1 -1
  57. package/dist/lambda/jwt.d.cts +6 -4
  58. package/dist/lambda/jwt.d.cts.map +1 -1
  59. package/dist/lambda/jwt.d.mts +6 -4
  60. package/dist/lambda/jwt.d.mts.map +1 -1
  61. package/dist/lambda/jwt.mjs +20 -16
  62. package/dist/lambda/jwt.mjs.map +1 -1
  63. package/dist/lambda/oidc.cjs +20 -16
  64. package/dist/lambda/oidc.cjs.map +1 -1
  65. package/dist/lambda/oidc.d.cts +7 -5
  66. package/dist/lambda/oidc.d.cts.map +1 -1
  67. package/dist/lambda/oidc.d.mts +7 -5
  68. package/dist/lambda/oidc.d.mts.map +1 -1
  69. package/dist/lambda/oidc.mjs +20 -16
  70. package/dist/lambda/oidc.mjs.map +1 -1
  71. package/dist/oidc-C0KyYaAK.cjs +68 -0
  72. package/dist/oidc-C0KyYaAK.cjs.map +1 -0
  73. package/dist/oidc-ChA17wLB.d.cts +87 -0
  74. package/dist/oidc-ChA17wLB.d.cts.map +1 -0
  75. package/dist/oidc-DTRgBBl6.d.mts +87 -0
  76. package/dist/oidc-DTRgBBl6.d.mts.map +1 -0
  77. package/dist/oidc-KA30gMlx.mjs +62 -0
  78. package/dist/oidc-KA30gMlx.mjs.map +1 -0
  79. package/dist/oidc.cjs +2 -64
  80. package/dist/oidc.d.cts +3 -84
  81. package/dist/oidc.d.mts +3 -84
  82. package/dist/oidc.mjs +2 -61
  83. package/dist/server.cjs +4 -4
  84. package/dist/server.d.cts +3 -3
  85. package/dist/server.d.mts +3 -3
  86. package/dist/server.mjs +4 -3
  87. package/dist/tokenManager-CL3yE06D.d.cts +40 -0
  88. package/dist/tokenManager-CL3yE06D.d.cts.map +1 -0
  89. package/dist/tokenManager-Ci2Tgxp8.mjs +66 -0
  90. package/dist/tokenManager-Ci2Tgxp8.mjs.map +1 -0
  91. package/dist/tokenManager-CvEMgxOp.cjs +72 -0
  92. package/dist/tokenManager-CvEMgxOp.cjs.map +1 -0
  93. package/dist/tokenManager-RrwjL0y-.d.mts +40 -0
  94. package/dist/tokenManager-RrwjL0y-.d.mts.map +1 -0
  95. package/dist/tokenManager.cjs +2 -64
  96. package/dist/tokenManager.d.cts +2 -37
  97. package/dist/tokenManager.d.mts +2 -37
  98. package/dist/tokenManager.mjs +2 -61
  99. package/package.json +9 -13
  100. package/src/__tests__/cacheTokenStorage.spec.ts +213 -0
  101. package/src/__tests__/client.spec.ts +465 -0
  102. package/src/__tests__/hono-jwt.spec.ts +232 -0
  103. package/src/__tests__/hono-oidc.spec.ts +605 -0
  104. package/src/__tests__/jwt.spec.ts +197 -0
  105. package/src/__tests__/lambda-jwt.spec.ts +278 -0
  106. package/src/__tests__/lambda-oidc.spec.ts +624 -0
  107. package/src/__tests__/oidc.spec.ts +405 -0
  108. package/src/__tests__/tokenManager.spec.ts +259 -0
  109. package/src/cacheTokenStorage.ts +43 -0
  110. package/src/client.ts +220 -0
  111. package/src/hono/jwt.ts +142 -0
  112. package/src/hono/oidc.ts +170 -0
  113. package/src/index.ts +3 -0
  114. package/src/jwt.ts +106 -0
  115. package/src/lambda/jwt.ts +210 -0
  116. package/src/lambda/oidc.ts +203 -0
  117. package/src/oidc.ts +156 -0
  118. package/src/server.ts +8 -0
  119. package/src/tokenManager.ts +106 -0
  120. package/tsconfig.json +10 -0
  121. package/tsdown.config.ts +3 -0
  122. package/dist/cacheTokenStorage-B3u8Sf-6.d.cts.map +0 -1
  123. package/dist/cacheTokenStorage-B3u8Sf-6.d.mts.map +0 -1
  124. package/dist/cacheTokenStorage.cjs.map +0 -1
  125. package/dist/cacheTokenStorage.mjs.map +0 -1
  126. package/dist/client.cjs.map +0 -1
  127. package/dist/client.mjs.map +0 -1
  128. package/dist/cookies.cjs +0 -25
  129. package/dist/cookies.cjs.map +0 -1
  130. package/dist/cookies.d.cts +0 -12
  131. package/dist/cookies.d.cts.map +0 -1
  132. package/dist/cookies.d.mts +0 -12
  133. package/dist/cookies.d.mts.map +0 -1
  134. package/dist/cookies.mjs +0 -24
  135. package/dist/cookies.mjs.map +0 -1
  136. package/dist/jwt-CoKrpeMB.d.cts.map +0 -1
  137. package/dist/jwt-CoKrpeMB.d.mts.map +0 -1
  138. package/dist/jwt.cjs.map +0 -1
  139. package/dist/jwt.mjs.map +0 -1
  140. package/dist/oidc.cjs.map +0 -1
  141. package/dist/oidc.d.cts.map +0 -1
  142. package/dist/oidc.d.mts.map +0 -1
  143. package/dist/oidc.mjs.map +0 -1
  144. package/dist/tokenManager.cjs.map +0 -1
  145. package/dist/tokenManager.d.cts.map +0 -1
  146. package/dist/tokenManager.d.mts.map +0 -1
  147. package/dist/tokenManager.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"cacheTokenStorage.cjs","names":[],"sources":["../src/cacheTokenStorage.ts"],"sourcesContent":["import type { Cache } from '@geekmidas/cache';\nimport type { TokenStorage } from './client.js';\n\nexport class CacheTokenStorage implements TokenStorage {\n\tprivate cache: Cache;\n\tprivate accessTokenKey: string;\n\tprivate refreshTokenKey: string;\n\n\tconstructor(\n\t\tcache: Cache,\n\t\taccessTokenKey: string = 'access_token',\n\t\trefreshTokenKey: string = 'refresh_token',\n\t) {\n\t\tthis.cache = cache;\n\t\tthis.accessTokenKey = accessTokenKey;\n\t\tthis.refreshTokenKey = refreshTokenKey;\n\t}\n\n\tasync getAccessToken(): Promise<string | null> {\n\t\tconst token = await this.cache.get<string>(this.accessTokenKey);\n\t\treturn token ?? null;\n\t}\n\n\tasync setAccessToken(token: string, ttl?: number): Promise<void> {\n\t\tawait this.cache.set(this.accessTokenKey, token, ttl);\n\t}\n\n\tasync getRefreshToken(): Promise<string | null> {\n\t\tconst token = await this.cache.get<string>(this.refreshTokenKey);\n\t\treturn token ?? null;\n\t}\n\n\tasync setRefreshToken(token: string, ttl?: number): Promise<void> {\n\t\tawait this.cache.set(this.refreshTokenKey, token, ttl);\n\t}\n\n\tasync clearTokens(): Promise<void> {\n\t\tawait Promise.all([\n\t\t\tthis.cache.delete(this.accessTokenKey),\n\t\t\tthis.cache.delete(this.refreshTokenKey),\n\t\t]);\n\t}\n}\n"],"mappings":";;AAGA,IAAa,oBAAb,MAAuD;CACtD;CACA;CACA;CAEA,YACC,OACA,iBAAyB,gBACzB,kBAA0B,iBACzB;EACD,KAAK,QAAQ;EACb,KAAK,iBAAiB;EACtB,KAAK,kBAAkB;CACxB;CAEA,MAAM,iBAAyC;EAE9C,OAAO,MADa,KAAK,MAAM,IAAY,KAAK,cAAc,KAC9C;CACjB;CAEA,MAAM,eAAe,OAAe,KAA6B;EAChE,MAAM,KAAK,MAAM,IAAI,KAAK,gBAAgB,OAAO,GAAG;CACrD;CAEA,MAAM,kBAA0C;EAE/C,OAAO,MADa,KAAK,MAAM,IAAY,KAAK,eAAe,KAC/C;CACjB;CAEA,MAAM,gBAAgB,OAAe,KAA6B;EACjE,MAAM,KAAK,MAAM,IAAI,KAAK,iBAAiB,OAAO,GAAG;CACtD;CAEA,MAAM,cAA6B;EAClC,MAAM,QAAQ,IAAI,CACjB,KAAK,MAAM,OAAO,KAAK,cAAc,GACrC,KAAK,MAAM,OAAO,KAAK,eAAe,CACvC,CAAC;CACF;AACD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"cacheTokenStorage.mjs","names":[],"sources":["../src/cacheTokenStorage.ts"],"sourcesContent":["import type { Cache } from '@geekmidas/cache';\nimport type { TokenStorage } from './client.js';\n\nexport class CacheTokenStorage implements TokenStorage {\n\tprivate cache: Cache;\n\tprivate accessTokenKey: string;\n\tprivate refreshTokenKey: string;\n\n\tconstructor(\n\t\tcache: Cache,\n\t\taccessTokenKey: string = 'access_token',\n\t\trefreshTokenKey: string = 'refresh_token',\n\t) {\n\t\tthis.cache = cache;\n\t\tthis.accessTokenKey = accessTokenKey;\n\t\tthis.refreshTokenKey = refreshTokenKey;\n\t}\n\n\tasync getAccessToken(): Promise<string | null> {\n\t\tconst token = await this.cache.get<string>(this.accessTokenKey);\n\t\treturn token ?? null;\n\t}\n\n\tasync setAccessToken(token: string, ttl?: number): Promise<void> {\n\t\tawait this.cache.set(this.accessTokenKey, token, ttl);\n\t}\n\n\tasync getRefreshToken(): Promise<string | null> {\n\t\tconst token = await this.cache.get<string>(this.refreshTokenKey);\n\t\treturn token ?? null;\n\t}\n\n\tasync setRefreshToken(token: string, ttl?: number): Promise<void> {\n\t\tawait this.cache.set(this.refreshTokenKey, token, ttl);\n\t}\n\n\tasync clearTokens(): Promise<void> {\n\t\tawait Promise.all([\n\t\t\tthis.cache.delete(this.accessTokenKey),\n\t\t\tthis.cache.delete(this.refreshTokenKey),\n\t\t]);\n\t}\n}\n"],"mappings":";AAGA,IAAa,oBAAb,MAAuD;CACtD;CACA;CACA;CAEA,YACC,OACA,iBAAyB,gBACzB,kBAA0B,iBACzB;EACD,KAAK,QAAQ;EACb,KAAK,iBAAiB;EACtB,KAAK,kBAAkB;CACxB;CAEA,MAAM,iBAAyC;EAE9C,OAAO,MADa,KAAK,MAAM,IAAY,KAAK,cAAc,KAC9C;CACjB;CAEA,MAAM,eAAe,OAAe,KAA6B;EAChE,MAAM,KAAK,MAAM,IAAI,KAAK,gBAAgB,OAAO,GAAG;CACrD;CAEA,MAAM,kBAA0C;EAE/C,OAAO,MADa,KAAK,MAAM,IAAY,KAAK,eAAe,KAC/C;CACjB;CAEA,MAAM,gBAAgB,OAAe,KAA6B;EACjE,MAAM,KAAK,MAAM,IAAI,KAAK,iBAAiB,OAAO,GAAG;CACtD;CAEA,MAAM,cAA6B;EAClC,MAAM,QAAQ,IAAI,CACjB,KAAK,MAAM,OAAO,KAAK,cAAc,GACrC,KAAK,MAAM,OAAO,KAAK,eAAe,CACvC,CAAC;CACF;AACD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.cjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["export interface TokenStorage {\n\tgetAccessToken(): Promise<string | null> | string | null;\n\tsetAccessToken(token: string, ttl?: number): Promise<void> | void;\n\tgetRefreshToken(): Promise<string | null> | string | null;\n\tsetRefreshToken(token: string, ttl?: number): Promise<void> | void;\n\tclearTokens(): Promise<void> | void;\n}\n\nexport class LocalStorageTokenStorage implements TokenStorage {\n\tprivate accessTokenKey: string;\n\tprivate refreshTokenKey: string;\n\n\tconstructor(\n\t\taccessTokenKey: string = 'access_token',\n\t\trefreshTokenKey: string = 'refresh_token',\n\t) {\n\t\tthis.accessTokenKey = accessTokenKey;\n\t\tthis.refreshTokenKey = refreshTokenKey;\n\t}\n\n\tgetAccessToken(): string | null {\n\t\tif (typeof window === 'undefined') return null;\n\t\treturn localStorage.getItem(this.accessTokenKey);\n\t}\n\n\tsetAccessToken(token: string, _ttl?: number): void {\n\t\tif (typeof window === 'undefined') return;\n\t\tlocalStorage.setItem(this.accessTokenKey, token);\n\t}\n\n\tgetRefreshToken(): string | null {\n\t\tif (typeof window === 'undefined') return null;\n\t\treturn localStorage.getItem(this.refreshTokenKey);\n\t}\n\n\tsetRefreshToken(token: string, _ttl?: number): void {\n\t\tif (typeof window === 'undefined') return;\n\t\tlocalStorage.setItem(this.refreshTokenKey, token);\n\t}\n\n\tclearTokens(): void {\n\t\tif (typeof window === 'undefined') return;\n\t\tlocalStorage.removeItem(this.accessTokenKey);\n\t\tlocalStorage.removeItem(this.refreshTokenKey);\n\t}\n}\n\nexport class MemoryTokenStorage implements TokenStorage {\n\tprivate accessToken: string | null = null;\n\tprivate refreshToken: string | null = null;\n\n\tgetAccessToken(): string | null {\n\t\treturn this.accessToken;\n\t}\n\n\tsetAccessToken(token: string, _ttl?: number): void {\n\t\tthis.accessToken = token;\n\t}\n\n\tgetRefreshToken(): string | null {\n\t\treturn this.refreshToken;\n\t}\n\n\tsetRefreshToken(token: string, _ttl?: number): void {\n\t\tthis.refreshToken = token;\n\t}\n\n\tclearTokens(): void {\n\t\tthis.accessToken = null;\n\t\tthis.refreshToken = null;\n\t}\n}\n\nexport interface TokenClientOptions {\n\tstorage?: TokenStorage;\n\trefreshEndpoint?: string;\n\tonTokenRefresh?: (tokens: {\n\t\taccessToken: string;\n\t\trefreshToken?: string;\n\t}) => void;\n\tonTokenExpired?: () => void;\n}\n\nexport class TokenClient {\n\tprivate storage: TokenStorage;\n\tprivate refreshEndpoint?: string;\n\tprivate onTokenRefresh?: (tokens: {\n\t\taccessToken: string;\n\t\trefreshToken?: string;\n\t}) => void;\n\tprivate onTokenExpired?: () => void;\n\n\tconstructor(options: TokenClientOptions = {}) {\n\t\tthis.storage = options.storage || new LocalStorageTokenStorage();\n\t\tthis.refreshEndpoint = options.refreshEndpoint;\n\t\tthis.onTokenRefresh = options.onTokenRefresh;\n\t\tthis.onTokenExpired = options.onTokenExpired;\n\t}\n\n\tasync getAccessToken(): Promise<string | null> {\n\t\treturn await this.storage.getAccessToken();\n\t}\n\n\tasync getRefreshToken(): Promise<string | null> {\n\t\treturn await this.storage.getRefreshToken();\n\t}\n\n\tasync setTokens(\n\t\taccessToken: string,\n\t\trefreshToken?: string,\n\t\taccessTtl?: number,\n\t\trefreshTtl?: number,\n\t): Promise<void> {\n\t\tawait this.storage.setAccessToken(accessToken, accessTtl);\n\t\tif (refreshToken) {\n\t\t\tawait this.storage.setRefreshToken(refreshToken, refreshTtl);\n\t\t}\n\t}\n\n\tasync clearTokens(): Promise<void> {\n\t\tawait this.storage.clearTokens();\n\t}\n\n\tisTokenExpired(token: string): boolean {\n\t\ttry {\n\t\t\tconst parts = token.split('.');\n\t\t\tconst payloadPart = parts[1];\n\t\t\tif (!payloadPart) return true;\n\t\t\tconst payload = JSON.parse(atob(payloadPart));\n\t\t\tconst now = Math.floor(Date.now() / 1000);\n\t\t\treturn payload.exp < now;\n\t\t} catch {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tgetTokenExpiration(token: string): Date | null {\n\t\ttry {\n\t\t\tconst parts = token.split('.');\n\t\t\tconst payloadPart = parts[1];\n\t\t\tif (!payloadPart) return null;\n\t\t\tconst payload = JSON.parse(atob(payloadPart));\n\t\t\treturn new Date(payload.exp * 1000);\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync refreshTokens(): Promise<boolean> {\n\t\tconst refreshToken = await this.getRefreshToken();\n\n\t\tif (!refreshToken || !this.refreshEndpoint) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await fetch(this.refreshEndpoint, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({ refreshToken }),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error('Failed to refresh token');\n\t\t\t}\n\n\t\t\tconst data = (await response.json()) as {\n\t\t\t\taccessToken: string;\n\t\t\t\trefreshToken: string;\n\t\t\t};\n\t\t\tconst { accessToken, refreshToken: newRefreshToken } = data;\n\n\t\t\tawait this.setTokens(accessToken, newRefreshToken);\n\n\t\t\tif (this.onTokenRefresh) {\n\t\t\t\tthis.onTokenRefresh({ accessToken, refreshToken: newRefreshToken });\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} catch (_error) {\n\t\t\tawait this.clearTokens();\n\t\t\tif (this.onTokenExpired) {\n\t\t\t\tthis.onTokenExpired();\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tasync getValidAccessToken(): Promise<string | null> {\n\t\tconst accessToken = await this.getAccessToken();\n\n\t\tif (!accessToken) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (this.isTokenExpired(accessToken)) {\n\t\t\tconst refreshed = await this.refreshTokens();\n\t\t\tif (!refreshed) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn await this.getAccessToken();\n\t\t}\n\n\t\treturn accessToken;\n\t}\n\n\tasync createAuthHeaders(): Promise<Record<string, string>> {\n\t\tconst token = await this.getAccessToken();\n\t\treturn token ? { Authorization: `Bearer ${token}` } : {};\n\t}\n\n\tasync createValidAuthHeaders(): Promise<Record<string, string>> {\n\t\tconst token = await this.getValidAccessToken();\n\t\treturn token ? { Authorization: `Bearer ${token}` } : {};\n\t}\n}\n\nexport { CacheTokenStorage } from './cacheTokenStorage.js';\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.mjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["export interface TokenStorage {\n\tgetAccessToken(): Promise<string | null> | string | null;\n\tsetAccessToken(token: string, ttl?: number): Promise<void> | void;\n\tgetRefreshToken(): Promise<string | null> | string | null;\n\tsetRefreshToken(token: string, ttl?: number): Promise<void> | void;\n\tclearTokens(): Promise<void> | void;\n}\n\nexport class LocalStorageTokenStorage implements TokenStorage {\n\tprivate accessTokenKey: string;\n\tprivate refreshTokenKey: string;\n\n\tconstructor(\n\t\taccessTokenKey: string = 'access_token',\n\t\trefreshTokenKey: string = 'refresh_token',\n\t) {\n\t\tthis.accessTokenKey = accessTokenKey;\n\t\tthis.refreshTokenKey = refreshTokenKey;\n\t}\n\n\tgetAccessToken(): string | null {\n\t\tif (typeof window === 'undefined') return null;\n\t\treturn localStorage.getItem(this.accessTokenKey);\n\t}\n\n\tsetAccessToken(token: string, _ttl?: number): void {\n\t\tif (typeof window === 'undefined') return;\n\t\tlocalStorage.setItem(this.accessTokenKey, token);\n\t}\n\n\tgetRefreshToken(): string | null {\n\t\tif (typeof window === 'undefined') return null;\n\t\treturn localStorage.getItem(this.refreshTokenKey);\n\t}\n\n\tsetRefreshToken(token: string, _ttl?: number): void {\n\t\tif (typeof window === 'undefined') return;\n\t\tlocalStorage.setItem(this.refreshTokenKey, token);\n\t}\n\n\tclearTokens(): void {\n\t\tif (typeof window === 'undefined') return;\n\t\tlocalStorage.removeItem(this.accessTokenKey);\n\t\tlocalStorage.removeItem(this.refreshTokenKey);\n\t}\n}\n\nexport class MemoryTokenStorage implements TokenStorage {\n\tprivate accessToken: string | null = null;\n\tprivate refreshToken: string | null = null;\n\n\tgetAccessToken(): string | null {\n\t\treturn this.accessToken;\n\t}\n\n\tsetAccessToken(token: string, _ttl?: number): void {\n\t\tthis.accessToken = token;\n\t}\n\n\tgetRefreshToken(): string | null {\n\t\treturn this.refreshToken;\n\t}\n\n\tsetRefreshToken(token: string, _ttl?: number): void {\n\t\tthis.refreshToken = token;\n\t}\n\n\tclearTokens(): void {\n\t\tthis.accessToken = null;\n\t\tthis.refreshToken = null;\n\t}\n}\n\nexport interface TokenClientOptions {\n\tstorage?: TokenStorage;\n\trefreshEndpoint?: string;\n\tonTokenRefresh?: (tokens: {\n\t\taccessToken: string;\n\t\trefreshToken?: string;\n\t}) => void;\n\tonTokenExpired?: () => void;\n}\n\nexport class TokenClient {\n\tprivate storage: TokenStorage;\n\tprivate refreshEndpoint?: string;\n\tprivate onTokenRefresh?: (tokens: {\n\t\taccessToken: string;\n\t\trefreshToken?: string;\n\t}) => void;\n\tprivate onTokenExpired?: () => void;\n\n\tconstructor(options: TokenClientOptions = {}) {\n\t\tthis.storage = options.storage || new LocalStorageTokenStorage();\n\t\tthis.refreshEndpoint = options.refreshEndpoint;\n\t\tthis.onTokenRefresh = options.onTokenRefresh;\n\t\tthis.onTokenExpired = options.onTokenExpired;\n\t}\n\n\tasync getAccessToken(): Promise<string | null> {\n\t\treturn await this.storage.getAccessToken();\n\t}\n\n\tasync getRefreshToken(): Promise<string | null> {\n\t\treturn await this.storage.getRefreshToken();\n\t}\n\n\tasync setTokens(\n\t\taccessToken: string,\n\t\trefreshToken?: string,\n\t\taccessTtl?: number,\n\t\trefreshTtl?: number,\n\t): Promise<void> {\n\t\tawait this.storage.setAccessToken(accessToken, accessTtl);\n\t\tif (refreshToken) {\n\t\t\tawait this.storage.setRefreshToken(refreshToken, refreshTtl);\n\t\t}\n\t}\n\n\tasync clearTokens(): Promise<void> {\n\t\tawait this.storage.clearTokens();\n\t}\n\n\tisTokenExpired(token: string): boolean {\n\t\ttry {\n\t\t\tconst parts = token.split('.');\n\t\t\tconst payloadPart = parts[1];\n\t\t\tif (!payloadPart) return true;\n\t\t\tconst payload = JSON.parse(atob(payloadPart));\n\t\t\tconst now = Math.floor(Date.now() / 1000);\n\t\t\treturn payload.exp < now;\n\t\t} catch {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tgetTokenExpiration(token: string): Date | null {\n\t\ttry {\n\t\t\tconst parts = token.split('.');\n\t\t\tconst payloadPart = parts[1];\n\t\t\tif (!payloadPart) return null;\n\t\t\tconst payload = JSON.parse(atob(payloadPart));\n\t\t\treturn new Date(payload.exp * 1000);\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync refreshTokens(): Promise<boolean> {\n\t\tconst refreshToken = await this.getRefreshToken();\n\n\t\tif (!refreshToken || !this.refreshEndpoint) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await fetch(this.refreshEndpoint, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({ refreshToken }),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error('Failed to refresh token');\n\t\t\t}\n\n\t\t\tconst data = (await response.json()) as {\n\t\t\t\taccessToken: string;\n\t\t\t\trefreshToken: string;\n\t\t\t};\n\t\t\tconst { accessToken, refreshToken: newRefreshToken } = data;\n\n\t\t\tawait this.setTokens(accessToken, newRefreshToken);\n\n\t\t\tif (this.onTokenRefresh) {\n\t\t\t\tthis.onTokenRefresh({ accessToken, refreshToken: newRefreshToken });\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} catch (_error) {\n\t\t\tawait this.clearTokens();\n\t\t\tif (this.onTokenExpired) {\n\t\t\t\tthis.onTokenExpired();\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tasync getValidAccessToken(): Promise<string | null> {\n\t\tconst accessToken = await this.getAccessToken();\n\n\t\tif (!accessToken) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (this.isTokenExpired(accessToken)) {\n\t\t\tconst refreshed = await this.refreshTokens();\n\t\t\tif (!refreshed) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn await this.getAccessToken();\n\t\t}\n\n\t\treturn accessToken;\n\t}\n\n\tasync createAuthHeaders(): Promise<Record<string, string>> {\n\t\tconst token = await this.getAccessToken();\n\t\treturn token ? { Authorization: `Bearer ${token}` } : {};\n\t}\n\n\tasync createValidAuthHeaders(): Promise<Record<string, string>> {\n\t\tconst token = await this.getValidAccessToken();\n\t\treturn token ? { Authorization: `Bearer ${token}` } : {};\n\t}\n}\n\nexport { CacheTokenStorage } from './cacheTokenStorage.js';\n"],"mappings":"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"}
package/dist/cookies.cjs DELETED
@@ -1,25 +0,0 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- //#region src/cookies.ts
3
- /**
4
- * Reads one cookie out of a `Cookie` header.
5
- *
6
- * The header is a list of `name=value` pairs, so the name has to be matched
7
- * against a whole pair. Searching the raw header for `name=` instead lets an
8
- * attacker prefix their own cookie — `evil_session=ATTACKER; session=REAL`
9
- * contains `session=ATTACKER` — and the first match wins.
10
- */
11
- function readCookie(cookieHeader, name) {
12
- if (!cookieHeader) return null;
13
- for (const pair of cookieHeader.split(";")) {
14
- const separator = pair.indexOf("=");
15
- if (separator === -1) continue;
16
- if (pair.slice(0, separator).trim() !== name) continue;
17
- const value = pair.slice(separator + 1).trim();
18
- return value === "" ? null : value;
19
- }
20
- return null;
21
- }
22
- //#endregion
23
- exports.readCookie = readCookie;
24
-
25
- //# sourceMappingURL=cookies.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cookies.cjs","names":[],"sources":["../src/cookies.ts"],"sourcesContent":["/**\n * Reads one cookie out of a `Cookie` header.\n *\n * The header is a list of `name=value` pairs, so the name has to be matched\n * against a whole pair. Searching the raw header for `name=` instead lets an\n * attacker prefix their own cookie — `evil_session=ATTACKER; session=REAL`\n * contains `session=ATTACKER` — and the first match wins.\n */\nexport function readCookie(\n\tcookieHeader: string | undefined,\n\tname: string,\n): string | null {\n\tif (!cookieHeader) {\n\t\treturn null;\n\t}\n\n\tfor (const pair of cookieHeader.split(';')) {\n\t\tconst separator = pair.indexOf('=');\n\t\tif (separator === -1) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (pair.slice(0, separator).trim() !== name) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst value = pair.slice(separator + 1).trim();\n\t\treturn value === '' ? null : value;\n\t}\n\n\treturn null;\n}\n"],"mappings":";;;;;;;;;;AAQA,SAAgB,WACf,cACA,MACgB;CAChB,IAAI,CAAC,cACJ,OAAO;CAGR,KAAK,MAAM,QAAQ,aAAa,MAAM,GAAG,GAAG;EAC3C,MAAM,YAAY,KAAK,QAAQ,GAAG;EAClC,IAAI,cAAc,IACjB;EAGD,IAAI,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC,KAAK,MAAM,MACvC;EAGD,MAAM,QAAQ,KAAK,MAAM,YAAY,CAAC,CAAC,CAAC,KAAK;EAC7C,OAAO,UAAU,KAAK,OAAO;CAC9B;CAEA,OAAO;AACR"}
@@ -1,12 +0,0 @@
1
- //#region src/cookies.d.ts
2
- /**
3
- * Reads one cookie out of a `Cookie` header.
4
- *
5
- * The header is a list of `name=value` pairs, so the name has to be matched
6
- * against a whole pair. Searching the raw header for `name=` instead lets an
7
- * attacker prefix their own cookie — `evil_session=ATTACKER; session=REAL`
8
- * contains `session=ATTACKER` — and the first match wins.
9
- */
10
- export declare function readCookie(cookieHeader: string | undefined, name: string): string | null;
11
- //#endregion
12
- //# sourceMappingURL=cookies.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cookies.d.cts","names":[],"sources":["../src/cookies.ts"],"mappings":";;;;;;;;;wBAQgB,WACf,kCACA"}
@@ -1,12 +0,0 @@
1
- //#region src/cookies.d.ts
2
- /**
3
- * Reads one cookie out of a `Cookie` header.
4
- *
5
- * The header is a list of `name=value` pairs, so the name has to be matched
6
- * against a whole pair. Searching the raw header for `name=` instead lets an
7
- * attacker prefix their own cookie — `evil_session=ATTACKER; session=REAL`
8
- * contains `session=ATTACKER` — and the first match wins.
9
- */
10
- export declare function readCookie(cookieHeader: string | undefined, name: string): string | null;
11
- //#endregion
12
- //# sourceMappingURL=cookies.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cookies.d.mts","names":[],"sources":["../src/cookies.ts"],"mappings":";;;;;;;;;wBAQgB,WACf,kCACA"}
package/dist/cookies.mjs DELETED
@@ -1,24 +0,0 @@
1
- //#region src/cookies.ts
2
- /**
3
- * Reads one cookie out of a `Cookie` header.
4
- *
5
- * The header is a list of `name=value` pairs, so the name has to be matched
6
- * against a whole pair. Searching the raw header for `name=` instead lets an
7
- * attacker prefix their own cookie — `evil_session=ATTACKER; session=REAL`
8
- * contains `session=ATTACKER` — and the first match wins.
9
- */
10
- function readCookie(cookieHeader, name) {
11
- if (!cookieHeader) return null;
12
- for (const pair of cookieHeader.split(";")) {
13
- const separator = pair.indexOf("=");
14
- if (separator === -1) continue;
15
- if (pair.slice(0, separator).trim() !== name) continue;
16
- const value = pair.slice(separator + 1).trim();
17
- return value === "" ? null : value;
18
- }
19
- return null;
20
- }
21
- //#endregion
22
- export { readCookie };
23
-
24
- //# sourceMappingURL=cookies.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cookies.mjs","names":[],"sources":["../src/cookies.ts"],"sourcesContent":["/**\n * Reads one cookie out of a `Cookie` header.\n *\n * The header is a list of `name=value` pairs, so the name has to be matched\n * against a whole pair. Searching the raw header for `name=` instead lets an\n * attacker prefix their own cookie — `evil_session=ATTACKER; session=REAL`\n * contains `session=ATTACKER` — and the first match wins.\n */\nexport function readCookie(\n\tcookieHeader: string | undefined,\n\tname: string,\n): string | null {\n\tif (!cookieHeader) {\n\t\treturn null;\n\t}\n\n\tfor (const pair of cookieHeader.split(';')) {\n\t\tconst separator = pair.indexOf('=');\n\t\tif (separator === -1) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (pair.slice(0, separator).trim() !== name) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst value = pair.slice(separator + 1).trim();\n\t\treturn value === '' ? null : value;\n\t}\n\n\treturn null;\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,WACf,cACA,MACgB;CAChB,IAAI,CAAC,cACJ,OAAO;CAGR,KAAK,MAAM,QAAQ,aAAa,MAAM,GAAG,GAAG;EAC3C,MAAM,YAAY,KAAK,QAAQ,GAAG;EAClC,IAAI,cAAc,IACjB;EAGD,IAAI,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC,KAAK,MAAM,MACvC;EAGD,MAAM,QAAQ,KAAK,MAAM,YAAY,CAAC,CAAC,CAAC,KAAK;EAC7C,OAAO,UAAU,KAAK,OAAO;CAC9B;CAEA,OAAO;AACR"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"jwt-CoKrpeMB.d.cts","names":[],"sources":["../src/jwt.ts"],"mappings":";;;;UAKiB;EAChB;EACA;EACA;EACA;EACA;EACA;EACA;;;;;UAMgB;EAChB;EACA;EACA;EACA;;;;;UAMgB;EAChB;EACA;EACA;EACA;;KAGW,YAAY,kBAAkB;;;;UAKzB;EAChB;EACA;EACA;;iBAGe,aAAa,QAAQ,YAAY,UAAU;;;;cAO9C,YAAY,gBAAgB,YAAY;mBAIvB;UAHrB;mBACS;EAEjB,YAA6B,QAAQ;EAS/B,OAAO,gBAAgB,QAAQ;EAkB/B,aAAa,gBAAgB,QAAQ;EAQ3C;;;;;;iBASe,UAAU,gBAAgB,YAAY,WACrD,gBACE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"jwt-CoKrpeMB.d.mts","names":[],"sources":["../src/jwt.ts"],"mappings":";;;;UAKiB;EAChB;EACA;EACA;EACA;EACA;EACA;EACA;;;;;UAMgB;EAChB;EACA;EACA;EACA;;;;;UAMgB;EAChB;EACA;EACA;EACA;;KAGW,YAAY,kBAAkB;;;;UAKzB;EAChB;EACA;EACA;;iBAGe,aAAa,QAAQ,YAAY,UAAU;;;;cAO9C,YAAY,gBAAgB,YAAY;mBAIvB;UAHrB;mBACS;EAEjB,YAA6B,QAAQ;EAS/B,OAAO,gBAAgB,QAAQ;EAkB/B,aAAa,gBAAgB,QAAQ;EAQ3C;;;;;;iBASe,UAAU,gBAAgB,YAAY,WACrD,gBACE"}
package/dist/jwt.cjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"jwt.cjs","names":[],"sources":["../src/jwt.ts"],"sourcesContent":["import * as jose from 'jose';\n\n/**\n * Standard JWT claims\n */\nexport interface JwtClaims {\n\tsub?: string;\n\tiss?: string;\n\taud?: string | string[];\n\texp?: number;\n\tiat?: number;\n\tnbf?: number;\n\tjti?: string;\n}\n\n/**\n * Configuration for JWT verification with a symmetric secret\n */\nexport interface JwtSecretConfig {\n\tsecret: string;\n\tissuer?: string;\n\taudience?: string | string[];\n\talgorithms?: string[];\n}\n\n/**\n * Configuration for JWT verification with JWKS\n */\nexport interface JwtJwksConfig {\n\tjwksUri: string;\n\tissuer?: string;\n\taudience?: string | string[];\n\talgorithms?: string[];\n}\n\nexport type JwtConfig = JwtSecretConfig | JwtJwksConfig;\n\n/**\n * Options for token extraction from requests\n */\nexport interface TokenExtractionOptions {\n\theaderName?: string;\n\tcookieName?: string;\n\ttokenPrefix?: string;\n}\n\nexport function isJwksConfig(config: JwtConfig): config is JwtJwksConfig {\n\treturn 'jwksUri' in config;\n}\n\n/**\n * JWT Verifier with JWKS caching\n */\nexport class JwtVerifier<TClaims extends JwtClaims = JwtClaims> {\n\tprivate jwks: jose.JWTVerifyGetKey | null = null;\n\tprivate readonly verifyOptions: jose.JWTVerifyOptions;\n\n\tconstructor(private readonly config: JwtConfig) {\n\t\tthis.verifyOptions = {\n\t\t\tissuer: config.issuer,\n\t\t\taudience: config.audience,\n\t\t\talgorithms:\n\t\t\t\tconfig.algorithms ?? (isJwksConfig(config) ? undefined : ['HS256']),\n\t\t};\n\t}\n\n\tasync verify(token: string): Promise<TClaims> {\n\t\tif (isJwksConfig(this.config)) {\n\t\t\tif (!this.jwks) {\n\t\t\t\tthis.jwks = jose.createRemoteJWKSet(new URL(this.config.jwksUri));\n\t\t\t}\n\t\t\tconst { payload } = await jose.jwtVerify(\n\t\t\t\ttoken,\n\t\t\t\tthis.jwks,\n\t\t\t\tthis.verifyOptions,\n\t\t\t);\n\t\t\treturn payload as unknown as TClaims;\n\t\t}\n\n\t\tconst secret = new TextEncoder().encode(this.config.secret);\n\t\tconst { payload } = await jose.jwtVerify(token, secret, this.verifyOptions);\n\t\treturn payload as unknown as TClaims;\n\t}\n\n\tasync verifyOrNull(token: string): Promise<TClaims | null> {\n\t\ttry {\n\t\t\treturn await this.verify(token);\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tclearCache(): void {\n\t\tthis.jwks = null;\n\t}\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\ttoken: string,\n): TClaims {\n\treturn jose.decodeJwt(token) as unknown as TClaims;\n}\n"],"mappings":";;;;;AA8CA,SAAgB,aAAa,QAA4C;CACxE,OAAO,aAAa;AACrB;;;;AAKA,IAAa,cAAb,MAAgE;CAIlC;CAH7B,OAA4C;CAC5C;CAEA,YAAY,QAAoC;EAAnB,KAAA,SAAA;EAC5B,KAAK,gBAAgB;GACpB,QAAQ,OAAO;GACf,UAAU,OAAO;GACjB,YACC,OAAO,eAAe,aAAa,MAAM,IAAI,KAAA,IAAY,CAAC,OAAO;EACnE;CACD;CAEA,MAAM,OAAO,OAAiC;EAC7C,IAAI,aAAa,KAAK,MAAM,GAAG;GAC9B,IAAI,CAAC,KAAK,MACT,KAAK,OAAO,KAAK,mBAAmB,IAAI,IAAI,KAAK,OAAO,OAAO,CAAC;GAEjE,MAAM,EAAE,YAAY,MAAM,KAAK,UAC9B,OACA,KAAK,MACL,KAAK,aACN;GACA,OAAO;EACR;EAEA,MAAM,SAAS,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK,OAAO,MAAM;EAC1D,MAAM,EAAE,YAAY,MAAM,KAAK,UAAU,OAAO,QAAQ,KAAK,aAAa;EAC1E,OAAO;CACR;CAEA,MAAM,aAAa,OAAwC;EAC1D,IAAI;GACH,OAAO,MAAM,KAAK,OAAO,KAAK;EAC/B,QAAQ;GACP,OAAO;EACR;CACD;CAEA,aAAmB;EAClB,KAAK,OAAO;CACb;AACD;;;;;AAMA,SAAgB,UACf,OACU;CACV,OAAO,KAAK,UAAU,KAAK;AAC5B"}
package/dist/jwt.mjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"jwt.mjs","names":[],"sources":["../src/jwt.ts"],"sourcesContent":["import * as jose from 'jose';\n\n/**\n * Standard JWT claims\n */\nexport interface JwtClaims {\n\tsub?: string;\n\tiss?: string;\n\taud?: string | string[];\n\texp?: number;\n\tiat?: number;\n\tnbf?: number;\n\tjti?: string;\n}\n\n/**\n * Configuration for JWT verification with a symmetric secret\n */\nexport interface JwtSecretConfig {\n\tsecret: string;\n\tissuer?: string;\n\taudience?: string | string[];\n\talgorithms?: string[];\n}\n\n/**\n * Configuration for JWT verification with JWKS\n */\nexport interface JwtJwksConfig {\n\tjwksUri: string;\n\tissuer?: string;\n\taudience?: string | string[];\n\talgorithms?: string[];\n}\n\nexport type JwtConfig = JwtSecretConfig | JwtJwksConfig;\n\n/**\n * Options for token extraction from requests\n */\nexport interface TokenExtractionOptions {\n\theaderName?: string;\n\tcookieName?: string;\n\ttokenPrefix?: string;\n}\n\nexport function isJwksConfig(config: JwtConfig): config is JwtJwksConfig {\n\treturn 'jwksUri' in config;\n}\n\n/**\n * JWT Verifier with JWKS caching\n */\nexport class JwtVerifier<TClaims extends JwtClaims = JwtClaims> {\n\tprivate jwks: jose.JWTVerifyGetKey | null = null;\n\tprivate readonly verifyOptions: jose.JWTVerifyOptions;\n\n\tconstructor(private readonly config: JwtConfig) {\n\t\tthis.verifyOptions = {\n\t\t\tissuer: config.issuer,\n\t\t\taudience: config.audience,\n\t\t\talgorithms:\n\t\t\t\tconfig.algorithms ?? (isJwksConfig(config) ? undefined : ['HS256']),\n\t\t};\n\t}\n\n\tasync verify(token: string): Promise<TClaims> {\n\t\tif (isJwksConfig(this.config)) {\n\t\t\tif (!this.jwks) {\n\t\t\t\tthis.jwks = jose.createRemoteJWKSet(new URL(this.config.jwksUri));\n\t\t\t}\n\t\t\tconst { payload } = await jose.jwtVerify(\n\t\t\t\ttoken,\n\t\t\t\tthis.jwks,\n\t\t\t\tthis.verifyOptions,\n\t\t\t);\n\t\t\treturn payload as unknown as TClaims;\n\t\t}\n\n\t\tconst secret = new TextEncoder().encode(this.config.secret);\n\t\tconst { payload } = await jose.jwtVerify(token, secret, this.verifyOptions);\n\t\treturn payload as unknown as TClaims;\n\t}\n\n\tasync verifyOrNull(token: string): Promise<TClaims | null> {\n\t\ttry {\n\t\t\treturn await this.verify(token);\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tclearCache(): void {\n\t\tthis.jwks = null;\n\t}\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\ttoken: string,\n): TClaims {\n\treturn jose.decodeJwt(token) as unknown as TClaims;\n}\n"],"mappings":";;AA8CA,SAAgB,aAAa,QAA4C;CACxE,OAAO,aAAa;AACrB;;;;AAKA,IAAa,cAAb,MAAgE;CAIlC;CAH7B,OAA4C;CAC5C;CAEA,YAAY,QAAoC;EAAnB,KAAA,SAAA;EAC5B,KAAK,gBAAgB;GACpB,QAAQ,OAAO;GACf,UAAU,OAAO;GACjB,YACC,OAAO,eAAe,aAAa,MAAM,IAAI,KAAA,IAAY,CAAC,OAAO;EACnE;CACD;CAEA,MAAM,OAAO,OAAiC;EAC7C,IAAI,aAAa,KAAK,MAAM,GAAG;GAC9B,IAAI,CAAC,KAAK,MACT,KAAK,OAAO,KAAK,mBAAmB,IAAI,IAAI,KAAK,OAAO,OAAO,CAAC;GAEjE,MAAM,EAAE,YAAY,MAAM,KAAK,UAC9B,OACA,KAAK,MACL,KAAK,aACN;GACA,OAAO;EACR;EAEA,MAAM,SAAS,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK,OAAO,MAAM;EAC1D,MAAM,EAAE,YAAY,MAAM,KAAK,UAAU,OAAO,QAAQ,KAAK,aAAa;EAC1E,OAAO;CACR;CAEA,MAAM,aAAa,OAAwC;EAC1D,IAAI;GACH,OAAO,MAAM,KAAK,OAAO,KAAK;EAC/B,QAAQ;GACP,OAAO;EACR;CACD;CAEA,aAAmB;EAClB,KAAK,OAAO;CACb;AACD;;;;;AAMA,SAAgB,UACf,OACU;CACV,OAAO,KAAK,UAAU,KAAK;AAC5B"}
package/dist/oidc.cjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"oidc.cjs","names":[],"sources":["../src/oidc.ts"],"sourcesContent":["import * as jose from 'jose';\nimport type { JwtClaims, TokenExtractionOptions } from './jwt';\n\nexport type { TokenExtractionOptions };\n\n/**\n * Standard OIDC claims (extends JWT claims)\n */\nexport interface OidcClaims extends JwtClaims {\n\tnonce?: string;\n\tauth_time?: number;\n\tat_hash?: string;\n\tc_hash?: string;\n\tazp?: string;\n}\n\n/**\n * Standard OIDC user info claims\n */\nexport interface OidcUserInfo {\n\tsub: string;\n\tname?: string;\n\tgiven_name?: string;\n\tfamily_name?: string;\n\tmiddle_name?: string;\n\tnickname?: string;\n\tpreferred_username?: string;\n\tprofile?: string;\n\tpicture?: string;\n\twebsite?: string;\n\temail?: string;\n\temail_verified?: boolean;\n\tgender?: string;\n\tbirthdate?: string;\n\tzoneinfo?: string;\n\tlocale?: string;\n\tphone_number?: string;\n\tphone_number_verified?: boolean;\n\taddress?: {\n\t\tformatted?: string;\n\t\tstreet_address?: string;\n\t\tlocality?: string;\n\t\tregion?: string;\n\t\tpostal_code?: string;\n\t\tcountry?: string;\n\t};\n\tupdated_at?: number;\n}\n\n/**\n * OIDC Discovery document\n */\nexport interface OidcDiscovery {\n\tissuer: string;\n\tauthorization_endpoint: string;\n\ttoken_endpoint: string;\n\tuserinfo_endpoint?: string;\n\tjwks_uri: string;\n\tscopes_supported?: string[];\n\tresponse_types_supported: string[];\n\tclaims_supported?: string[];\n}\n\n/**\n * Configuration for OIDC verification\n */\nexport interface OidcConfig {\n\tissuer: string;\n\taudience: string | string[];\n\tcacheDiscovery?: boolean;\n}\n\n/**\n * OIDC Verifier with auto-discovery and caching\n */\nexport class OidcVerifier<\n\tTClaims extends OidcClaims = OidcClaims,\n\tTUserInfo extends OidcUserInfo = OidcUserInfo,\n> {\n\tprivate discovery: OidcDiscovery | null = null;\n\tprivate jwks: jose.JWTVerifyGetKey | null = null;\n\tprivate readonly discoveryUrl: string;\n\n\tconstructor(private readonly config: OidcConfig) {\n\t\tthis.discoveryUrl = config.issuer.endsWith('/')\n\t\t\t? `${config.issuer}.well-known/openid-configuration`\n\t\t\t: `${config.issuer}/.well-known/openid-configuration`;\n\t}\n\n\tasync getDiscovery(): Promise<OidcDiscovery> {\n\t\tif (this.discovery && this.config.cacheDiscovery !== false) {\n\t\t\treturn this.discovery;\n\t\t}\n\n\t\tconst response = await fetch(this.discoveryUrl);\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to fetch OIDC discovery: ${response.statusText}`);\n\t\t}\n\n\t\tthis.discovery = (await response.json()) as OidcDiscovery;\n\t\treturn this.discovery;\n\t}\n\n\tprivate async getJwks(): Promise<jose.JWTVerifyGetKey> {\n\t\tif (this.jwks && this.config.cacheDiscovery !== false) {\n\t\t\treturn this.jwks;\n\t\t}\n\n\t\tconst disc = await this.getDiscovery();\n\t\tthis.jwks = jose.createRemoteJWKSet(new URL(disc.jwks_uri));\n\t\treturn this.jwks;\n\t}\n\n\tasync verify(token: string): Promise<TClaims> {\n\t\tconst key = await this.getJwks();\n\t\tconst { payload } = await jose.jwtVerify(token, key, {\n\t\t\tissuer: this.config.issuer,\n\t\t\taudience: this.config.audience,\n\t\t});\n\t\treturn payload as unknown as TClaims;\n\t}\n\n\tasync verifyOrNull(token: string): Promise<TClaims | null> {\n\t\ttry {\n\t\t\treturn await this.verify(token);\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync fetchUserInfo(token: string): Promise<TUserInfo | null> {\n\t\ttry {\n\t\t\tconst disc = await this.getDiscovery();\n\t\t\tif (!disc.userinfo_endpoint) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst response = await fetch(disc.userinfo_endpoint, {\n\t\t\t\theaders: { Authorization: `Bearer ${token}` },\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn (await response.json()) as TUserInfo;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tclearCache(): void {\n\t\tthis.discovery = null;\n\t\tthis.jwks = null;\n\t}\n}\n"],"mappings":";;;;;;;;AA2EA,IAAa,eAAb,MAGE;CAK4B;CAJ7B,YAA0C;CAC1C,OAA4C;CAC5C;CAEA,YAAY,QAAqC;EAApB,KAAA,SAAA;EAC5B,KAAK,eAAe,OAAO,OAAO,SAAS,GAAG,IAC3C,GAAG,OAAO,OAAO,oCACjB,GAAG,OAAO,OAAO;CACrB;CAEA,MAAM,eAAuC;EAC5C,IAAI,KAAK,aAAa,KAAK,OAAO,mBAAmB,OACpD,OAAO,KAAK;EAGb,MAAM,WAAW,MAAM,MAAM,KAAK,YAAY;EAC9C,IAAI,CAAC,SAAS,IACb,MAAM,IAAI,MAAM,mCAAmC,SAAS,YAAY;EAGzE,KAAK,YAAa,MAAM,SAAS,KAAK;EACtC,OAAO,KAAK;CACb;CAEA,MAAc,UAAyC;EACtD,IAAI,KAAK,QAAQ,KAAK,OAAO,mBAAmB,OAC/C,OAAO,KAAK;EAGb,MAAM,OAAO,MAAM,KAAK,aAAa;EACrC,KAAK,OAAO,KAAK,mBAAmB,IAAI,IAAI,KAAK,QAAQ,CAAC;EAC1D,OAAO,KAAK;CACb;CAEA,MAAM,OAAO,OAAiC;EAC7C,MAAM,MAAM,MAAM,KAAK,QAAQ;EAC/B,MAAM,EAAE,YAAY,MAAM,KAAK,UAAU,OAAO,KAAK;GACpD,QAAQ,KAAK,OAAO;GACpB,UAAU,KAAK,OAAO;EACvB,CAAC;EACD,OAAO;CACR;CAEA,MAAM,aAAa,OAAwC;EAC1D,IAAI;GACH,OAAO,MAAM,KAAK,OAAO,KAAK;EAC/B,QAAQ;GACP,OAAO;EACR;CACD;CAEA,MAAM,cAAc,OAA0C;EAC7D,IAAI;GACH,MAAM,OAAO,MAAM,KAAK,aAAa;GACrC,IAAI,CAAC,KAAK,mBACT,OAAO;GAGR,MAAM,WAAW,MAAM,MAAM,KAAK,mBAAmB,EACpD,SAAS,EAAE,eAAe,UAAU,QAAQ,EAC7C,CAAC;GAED,IAAI,CAAC,SAAS,IACb,OAAO;GAGR,OAAQ,MAAM,SAAS,KAAK;EAC7B,QAAQ;GACP,OAAO;EACR;CACD;CAEA,aAAmB;EAClB,KAAK,YAAY;EACjB,KAAK,OAAO;CACb;AACD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"oidc.d.cts","names":[],"sources":["../src/oidc.ts"],"mappings":";;;;;iBAQiB,mBAAmB;EACnC;EACA;EACA;EACA;EACA;;;;;iBAMgB;EAChB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;IACC;IACA;IACA;IACA;IACA;IACA;;EAED;;;;;iBAMgB;EAChB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;;;iBAMgB;EAChB;EACA;EACA;;;;;qBAMY,aACZ,gBAAgB,aAAa,YAC7B,kBAAkB,eAAe;mBAMJ;UAJrB;UACA;mBACS;EAEjB,YAA6B,QAAQ;EAM/B,gBAAgB,QAAQ;UAchB;EAUR,OAAO,gBAAgB,QAAQ;EAS/B,aAAa,gBAAgB,QAAQ;EAQrC,cAAc,gBAAgB,QAAQ;EAqB5C"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"oidc.d.mts","names":[],"sources":["../src/oidc.ts"],"mappings":";;;;;iBAQiB,mBAAmB;EACnC;EACA;EACA;EACA;EACA;;;;;iBAMgB;EAChB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;IACC;IACA;IACA;IACA;IACA;IACA;;EAED;;;;;iBAMgB;EAChB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;;;iBAMgB;EAChB;EACA;EACA;;;;;qBAMY,aACZ,gBAAgB,aAAa,YAC7B,kBAAkB,eAAe;mBAMJ;UAJrB;UACA;mBACS;EAEjB,YAA6B,QAAQ;EAM/B,gBAAgB,QAAQ;UAchB;EAUR,OAAO,gBAAgB,QAAQ;EAS/B,aAAa,gBAAgB,QAAQ;EAQrC,cAAc,gBAAgB,QAAQ;EAqB5C"}
package/dist/oidc.mjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"oidc.mjs","names":[],"sources":["../src/oidc.ts"],"sourcesContent":["import * as jose from 'jose';\nimport type { JwtClaims, TokenExtractionOptions } from './jwt';\n\nexport type { TokenExtractionOptions };\n\n/**\n * Standard OIDC claims (extends JWT claims)\n */\nexport interface OidcClaims extends JwtClaims {\n\tnonce?: string;\n\tauth_time?: number;\n\tat_hash?: string;\n\tc_hash?: string;\n\tazp?: string;\n}\n\n/**\n * Standard OIDC user info claims\n */\nexport interface OidcUserInfo {\n\tsub: string;\n\tname?: string;\n\tgiven_name?: string;\n\tfamily_name?: string;\n\tmiddle_name?: string;\n\tnickname?: string;\n\tpreferred_username?: string;\n\tprofile?: string;\n\tpicture?: string;\n\twebsite?: string;\n\temail?: string;\n\temail_verified?: boolean;\n\tgender?: string;\n\tbirthdate?: string;\n\tzoneinfo?: string;\n\tlocale?: string;\n\tphone_number?: string;\n\tphone_number_verified?: boolean;\n\taddress?: {\n\t\tformatted?: string;\n\t\tstreet_address?: string;\n\t\tlocality?: string;\n\t\tregion?: string;\n\t\tpostal_code?: string;\n\t\tcountry?: string;\n\t};\n\tupdated_at?: number;\n}\n\n/**\n * OIDC Discovery document\n */\nexport interface OidcDiscovery {\n\tissuer: string;\n\tauthorization_endpoint: string;\n\ttoken_endpoint: string;\n\tuserinfo_endpoint?: string;\n\tjwks_uri: string;\n\tscopes_supported?: string[];\n\tresponse_types_supported: string[];\n\tclaims_supported?: string[];\n}\n\n/**\n * Configuration for OIDC verification\n */\nexport interface OidcConfig {\n\tissuer: string;\n\taudience: string | string[];\n\tcacheDiscovery?: boolean;\n}\n\n/**\n * OIDC Verifier with auto-discovery and caching\n */\nexport class OidcVerifier<\n\tTClaims extends OidcClaims = OidcClaims,\n\tTUserInfo extends OidcUserInfo = OidcUserInfo,\n> {\n\tprivate discovery: OidcDiscovery | null = null;\n\tprivate jwks: jose.JWTVerifyGetKey | null = null;\n\tprivate readonly discoveryUrl: string;\n\n\tconstructor(private readonly config: OidcConfig) {\n\t\tthis.discoveryUrl = config.issuer.endsWith('/')\n\t\t\t? `${config.issuer}.well-known/openid-configuration`\n\t\t\t: `${config.issuer}/.well-known/openid-configuration`;\n\t}\n\n\tasync getDiscovery(): Promise<OidcDiscovery> {\n\t\tif (this.discovery && this.config.cacheDiscovery !== false) {\n\t\t\treturn this.discovery;\n\t\t}\n\n\t\tconst response = await fetch(this.discoveryUrl);\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to fetch OIDC discovery: ${response.statusText}`);\n\t\t}\n\n\t\tthis.discovery = (await response.json()) as OidcDiscovery;\n\t\treturn this.discovery;\n\t}\n\n\tprivate async getJwks(): Promise<jose.JWTVerifyGetKey> {\n\t\tif (this.jwks && this.config.cacheDiscovery !== false) {\n\t\t\treturn this.jwks;\n\t\t}\n\n\t\tconst disc = await this.getDiscovery();\n\t\tthis.jwks = jose.createRemoteJWKSet(new URL(disc.jwks_uri));\n\t\treturn this.jwks;\n\t}\n\n\tasync verify(token: string): Promise<TClaims> {\n\t\tconst key = await this.getJwks();\n\t\tconst { payload } = await jose.jwtVerify(token, key, {\n\t\t\tissuer: this.config.issuer,\n\t\t\taudience: this.config.audience,\n\t\t});\n\t\treturn payload as unknown as TClaims;\n\t}\n\n\tasync verifyOrNull(token: string): Promise<TClaims | null> {\n\t\ttry {\n\t\t\treturn await this.verify(token);\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync fetchUserInfo(token: string): Promise<TUserInfo | null> {\n\t\ttry {\n\t\t\tconst disc = await this.getDiscovery();\n\t\t\tif (!disc.userinfo_endpoint) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst response = await fetch(disc.userinfo_endpoint, {\n\t\t\t\theaders: { Authorization: `Bearer ${token}` },\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn (await response.json()) as TUserInfo;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tclearCache(): void {\n\t\tthis.discovery = null;\n\t\tthis.jwks = null;\n\t}\n}\n"],"mappings":";;;;;AA2EA,IAAa,eAAb,MAGE;CAK4B;CAJ7B,YAA0C;CAC1C,OAA4C;CAC5C;CAEA,YAAY,QAAqC;EAApB,KAAA,SAAA;EAC5B,KAAK,eAAe,OAAO,OAAO,SAAS,GAAG,IAC3C,GAAG,OAAO,OAAO,oCACjB,GAAG,OAAO,OAAO;CACrB;CAEA,MAAM,eAAuC;EAC5C,IAAI,KAAK,aAAa,KAAK,OAAO,mBAAmB,OACpD,OAAO,KAAK;EAGb,MAAM,WAAW,MAAM,MAAM,KAAK,YAAY;EAC9C,IAAI,CAAC,SAAS,IACb,MAAM,IAAI,MAAM,mCAAmC,SAAS,YAAY;EAGzE,KAAK,YAAa,MAAM,SAAS,KAAK;EACtC,OAAO,KAAK;CACb;CAEA,MAAc,UAAyC;EACtD,IAAI,KAAK,QAAQ,KAAK,OAAO,mBAAmB,OAC/C,OAAO,KAAK;EAGb,MAAM,OAAO,MAAM,KAAK,aAAa;EACrC,KAAK,OAAO,KAAK,mBAAmB,IAAI,IAAI,KAAK,QAAQ,CAAC;EAC1D,OAAO,KAAK;CACb;CAEA,MAAM,OAAO,OAAiC;EAC7C,MAAM,MAAM,MAAM,KAAK,QAAQ;EAC/B,MAAM,EAAE,YAAY,MAAM,KAAK,UAAU,OAAO,KAAK;GACpD,QAAQ,KAAK,OAAO;GACpB,UAAU,KAAK,OAAO;EACvB,CAAC;EACD,OAAO;CACR;CAEA,MAAM,aAAa,OAAwC;EAC1D,IAAI;GACH,OAAO,MAAM,KAAK,OAAO,KAAK;EAC/B,QAAQ;GACP,OAAO;EACR;CACD;CAEA,MAAM,cAAc,OAA0C;EAC7D,IAAI;GACH,MAAM,OAAO,MAAM,KAAK,aAAa;GACrC,IAAI,CAAC,KAAK,mBACT,OAAO;GAGR,MAAM,WAAW,MAAM,MAAM,KAAK,mBAAmB,EACpD,SAAS,EAAE,eAAe,UAAU,QAAQ,EAC7C,CAAC;GAED,IAAI,CAAC,SAAS,IACb,OAAO;GAGR,OAAQ,MAAM,SAAS,KAAK;EAC7B,QAAQ;GACP,OAAO;EACR;CACD;CAEA,aAAmB;EAClB,KAAK,YAAY;EACjB,KAAK,OAAO;CACb;AACD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"tokenManager.cjs","names":["jwt"],"sources":["../src/tokenManager.ts"],"sourcesContent":["import jwt from 'jsonwebtoken';\nimport type ms from 'ms';\n\nexport interface TokenPayload {\n\tuserId: string;\n\temail?: string;\n\t[key: string]: any;\n}\n\nexport interface TokenPair {\n\taccessToken: string;\n\trefreshToken: string;\n}\n\nexport interface TokenManagerOptions {\n\taccessTokenSecret: string;\n\trefreshTokenSecret: string;\n\taccessTokenExpiresIn?: ms.StringValue;\n\trefreshTokenExpiresIn?: ms.StringValue;\n}\n\nexport interface DecodedToken extends TokenPayload {\n\tiat: number;\n\texp: number;\n}\n\nexport class TokenManager {\n\tprivate accessTokenSecret: string;\n\tprivate refreshTokenSecret: string;\n\tprivate accessTokenExpiresIn: ms.StringValue;\n\tprivate refreshTokenExpiresIn: ms.StringValue;\n\n\tconstructor(options: TokenManagerOptions) {\n\t\tthis.accessTokenSecret = options.accessTokenSecret;\n\t\tthis.refreshTokenSecret = options.refreshTokenSecret;\n\t\tthis.accessTokenExpiresIn = options.accessTokenExpiresIn || '15m';\n\t\tthis.refreshTokenExpiresIn = options.refreshTokenExpiresIn || '7d';\n\t}\n\n\tgenerateTokenPair(payload: TokenPayload): TokenPair {\n\t\tconst accessToken = jwt.sign(payload, this.accessTokenSecret, {\n\t\t\texpiresIn: this.accessTokenExpiresIn,\n\t\t});\n\n\t\tconst refreshToken = jwt.sign(payload, this.refreshTokenSecret, {\n\t\t\texpiresIn: this.refreshTokenExpiresIn,\n\t\t});\n\n\t\treturn {\n\t\t\taccessToken,\n\t\t\trefreshToken,\n\t\t};\n\t}\n\n\tverifyAccessToken(token: string): DecodedToken {\n\t\ttry {\n\t\t\treturn jwt.verify(token, this.accessTokenSecret) as DecodedToken;\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tthrow new Error(`Invalid access token: ${message}`);\n\t\t}\n\t}\n\n\tverifyRefreshToken(token: string): DecodedToken {\n\t\ttry {\n\t\t\treturn jwt.verify(token, this.refreshTokenSecret) as DecodedToken;\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tthrow new Error(`Invalid refresh token: ${message}`);\n\t\t}\n\t}\n\n\trefreshAccessToken(refreshToken: string): string {\n\t\tconst decoded = this.verifyRefreshToken(refreshToken);\n\n\t\t// Remove JWT specific fields before creating new token\n\t\tconst { iat, exp, ...payload } = decoded;\n\n\t\treturn jwt.sign(payload, this.accessTokenSecret, {\n\t\t\texpiresIn: this.accessTokenExpiresIn,\n\t\t});\n\t}\n\n\tdecodeToken(token: string): DecodedToken | null {\n\t\ttry {\n\t\t\treturn jwt.decode(token) as DecodedToken;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tisTokenExpired(token: string): boolean {\n\t\tconst decoded = this.decodeToken(token);\n\t\tif (!decoded) return true;\n\n\t\tconst now = Math.floor(Date.now() / 1000);\n\t\treturn decoded.exp < now;\n\t}\n\n\tgetTokenExpiration(token: string): Date | null {\n\t\tconst decoded = this.decodeToken(token);\n\t\tif (!decoded) return null;\n\n\t\treturn new Date(decoded.exp * 1000);\n\t}\n}\n"],"mappings":";;;;;AA0BA,IAAa,eAAb,MAA0B;CACzB;CACA;CACA;CACA;CAEA,YAAY,SAA8B;EACzC,KAAK,oBAAoB,QAAQ;EACjC,KAAK,qBAAqB,QAAQ;EAClC,KAAK,uBAAuB,QAAQ,wBAAwB;EAC5D,KAAK,wBAAwB,QAAQ,yBAAyB;CAC/D;CAEA,kBAAkB,SAAkC;EASnD,OAAO;GACN,aATmBA,aAAAA,QAAI,KAAK,SAAS,KAAK,mBAAmB,EAC7D,WAAW,KAAK,qBACjB,CAOW;GACV,cANoBA,aAAAA,QAAI,KAAK,SAAS,KAAK,oBAAoB,EAC/D,WAAW,KAAK,sBACjB,CAIY;EACZ;CACD;CAEA,kBAAkB,OAA6B;EAC9C,IAAI;GACH,OAAOA,aAAAA,QAAI,OAAO,OAAO,KAAK,iBAAiB;EAChD,SAAS,OAAO;GACf,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;GACrE,MAAM,IAAI,MAAM,yBAAyB,SAAS;EACnD;CACD;CAEA,mBAAmB,OAA6B;EAC/C,IAAI;GACH,OAAOA,aAAAA,QAAI,OAAO,OAAO,KAAK,kBAAkB;EACjD,SAAS,OAAO;GACf,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;GACrE,MAAM,IAAI,MAAM,0BAA0B,SAAS;EACpD;CACD;CAEA,mBAAmB,cAA8B;EAIhD,MAAM,EAAE,KAAK,KAAK,GAAG,YAHL,KAAK,mBAAmB,YAGD;EAEvC,OAAOA,aAAAA,QAAI,KAAK,SAAS,KAAK,mBAAmB,EAChD,WAAW,KAAK,qBACjB,CAAC;CACF;CAEA,YAAY,OAAoC;EAC/C,IAAI;GACH,OAAOA,aAAAA,QAAI,OAAO,KAAK;EACxB,QAAQ;GACP,OAAO;EACR;CACD;CAEA,eAAe,OAAwB;EACtC,MAAM,UAAU,KAAK,YAAY,KAAK;EACtC,IAAI,CAAC,SAAS,OAAO;EAErB,MAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;EACxC,OAAO,QAAQ,MAAM;CACtB;CAEA,mBAAmB,OAA4B;EAC9C,MAAM,UAAU,KAAK,YAAY,KAAK;EACtC,IAAI,CAAC,SAAS,OAAO;EAErB,uBAAO,IAAI,KAAK,QAAQ,MAAM,GAAI;CACnC;AACD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"tokenManager.d.cts","names":[],"sources":["../src/tokenManager.ts"],"mappings":";;iBAGiB;EAChB;EACA;GACC;;iBAGe;EAChB;EACA;;iBAGgB;EAChB;EACA;EACA,uBAAuB,GAAG;EAC1B,wBAAwB,GAAG;;iBAGX,qBAAqB;EACrC;EACA;;qBAGY;UACJ;UACA;UACA;UACA;EAER,YAAY,SAAS;EAOrB,kBAAkB,SAAS,eAAe;EAe1C,kBAAkB,gBAAgB;EASlC,mBAAmB,gBAAgB;EASnC,mBAAmB;EAWnB,YAAY,gBAAgB;EAQ5B,eAAe;EAQf,mBAAmB,gBAAgB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"tokenManager.d.mts","names":[],"sources":["../src/tokenManager.ts"],"mappings":";;iBAGiB;EAChB;EACA;GACC;;iBAGe;EAChB;EACA;;iBAGgB;EAChB;EACA;EACA,uBAAuB,GAAG;EAC1B,wBAAwB,GAAG;;iBAGX,qBAAqB;EACrC;EACA;;qBAGY;UACJ;UACA;UACA;UACA;EAER,YAAY,SAAS;EAOrB,kBAAkB,SAAS,eAAe;EAe1C,kBAAkB,gBAAgB;EASlC,mBAAmB,gBAAgB;EASnC,mBAAmB;EAWnB,YAAY,gBAAgB;EAQ5B,eAAe;EAQf,mBAAmB,gBAAgB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"tokenManager.mjs","names":[],"sources":["../src/tokenManager.ts"],"sourcesContent":["import jwt from 'jsonwebtoken';\nimport type ms from 'ms';\n\nexport interface TokenPayload {\n\tuserId: string;\n\temail?: string;\n\t[key: string]: any;\n}\n\nexport interface TokenPair {\n\taccessToken: string;\n\trefreshToken: string;\n}\n\nexport interface TokenManagerOptions {\n\taccessTokenSecret: string;\n\trefreshTokenSecret: string;\n\taccessTokenExpiresIn?: ms.StringValue;\n\trefreshTokenExpiresIn?: ms.StringValue;\n}\n\nexport interface DecodedToken extends TokenPayload {\n\tiat: number;\n\texp: number;\n}\n\nexport class TokenManager {\n\tprivate accessTokenSecret: string;\n\tprivate refreshTokenSecret: string;\n\tprivate accessTokenExpiresIn: ms.StringValue;\n\tprivate refreshTokenExpiresIn: ms.StringValue;\n\n\tconstructor(options: TokenManagerOptions) {\n\t\tthis.accessTokenSecret = options.accessTokenSecret;\n\t\tthis.refreshTokenSecret = options.refreshTokenSecret;\n\t\tthis.accessTokenExpiresIn = options.accessTokenExpiresIn || '15m';\n\t\tthis.refreshTokenExpiresIn = options.refreshTokenExpiresIn || '7d';\n\t}\n\n\tgenerateTokenPair(payload: TokenPayload): TokenPair {\n\t\tconst accessToken = jwt.sign(payload, this.accessTokenSecret, {\n\t\t\texpiresIn: this.accessTokenExpiresIn,\n\t\t});\n\n\t\tconst refreshToken = jwt.sign(payload, this.refreshTokenSecret, {\n\t\t\texpiresIn: this.refreshTokenExpiresIn,\n\t\t});\n\n\t\treturn {\n\t\t\taccessToken,\n\t\t\trefreshToken,\n\t\t};\n\t}\n\n\tverifyAccessToken(token: string): DecodedToken {\n\t\ttry {\n\t\t\treturn jwt.verify(token, this.accessTokenSecret) as DecodedToken;\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tthrow new Error(`Invalid access token: ${message}`);\n\t\t}\n\t}\n\n\tverifyRefreshToken(token: string): DecodedToken {\n\t\ttry {\n\t\t\treturn jwt.verify(token, this.refreshTokenSecret) as DecodedToken;\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tthrow new Error(`Invalid refresh token: ${message}`);\n\t\t}\n\t}\n\n\trefreshAccessToken(refreshToken: string): string {\n\t\tconst decoded = this.verifyRefreshToken(refreshToken);\n\n\t\t// Remove JWT specific fields before creating new token\n\t\tconst { iat, exp, ...payload } = decoded;\n\n\t\treturn jwt.sign(payload, this.accessTokenSecret, {\n\t\t\texpiresIn: this.accessTokenExpiresIn,\n\t\t});\n\t}\n\n\tdecodeToken(token: string): DecodedToken | null {\n\t\ttry {\n\t\t\treturn jwt.decode(token) as DecodedToken;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tisTokenExpired(token: string): boolean {\n\t\tconst decoded = this.decodeToken(token);\n\t\tif (!decoded) return true;\n\n\t\tconst now = Math.floor(Date.now() / 1000);\n\t\treturn decoded.exp < now;\n\t}\n\n\tgetTokenExpiration(token: string): Date | null {\n\t\tconst decoded = this.decodeToken(token);\n\t\tif (!decoded) return null;\n\n\t\treturn new Date(decoded.exp * 1000);\n\t}\n}\n"],"mappings":";;AA0BA,IAAa,eAAb,MAA0B;CACzB;CACA;CACA;CACA;CAEA,YAAY,SAA8B;EACzC,KAAK,oBAAoB,QAAQ;EACjC,KAAK,qBAAqB,QAAQ;EAClC,KAAK,uBAAuB,QAAQ,wBAAwB;EAC5D,KAAK,wBAAwB,QAAQ,yBAAyB;CAC/D;CAEA,kBAAkB,SAAkC;EASnD,OAAO;GACN,aATmB,IAAI,KAAK,SAAS,KAAK,mBAAmB,EAC7D,WAAW,KAAK,qBACjB,CAOW;GACV,cANoB,IAAI,KAAK,SAAS,KAAK,oBAAoB,EAC/D,WAAW,KAAK,sBACjB,CAIY;EACZ;CACD;CAEA,kBAAkB,OAA6B;EAC9C,IAAI;GACH,OAAO,IAAI,OAAO,OAAO,KAAK,iBAAiB;EAChD,SAAS,OAAO;GACf,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;GACrE,MAAM,IAAI,MAAM,yBAAyB,SAAS;EACnD;CACD;CAEA,mBAAmB,OAA6B;EAC/C,IAAI;GACH,OAAO,IAAI,OAAO,OAAO,KAAK,kBAAkB;EACjD,SAAS,OAAO;GACf,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;GACrE,MAAM,IAAI,MAAM,0BAA0B,SAAS;EACpD;CACD;CAEA,mBAAmB,cAA8B;EAIhD,MAAM,EAAE,KAAK,KAAK,GAAG,YAHL,KAAK,mBAAmB,YAGD;EAEvC,OAAO,IAAI,KAAK,SAAS,KAAK,mBAAmB,EAChD,WAAW,KAAK,qBACjB,CAAC;CACF;CAEA,YAAY,OAAoC;EAC/C,IAAI;GACH,OAAO,IAAI,OAAO,KAAK;EACxB,QAAQ;GACP,OAAO;EACR;CACD;CAEA,eAAe,OAAwB;EACtC,MAAM,UAAU,KAAK,YAAY,KAAK;EACtC,IAAI,CAAC,SAAS,OAAO;EAErB,MAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;EACxC,OAAO,QAAQ,MAAM;CACtB;CAEA,mBAAmB,OAA4B;EAC9C,MAAM,UAAU,KAAK,YAAY,KAAK;EACtC,IAAI,CAAC,SAAS,OAAO;EAErB,uBAAO,IAAI,KAAK,QAAQ,MAAM,GAAI;CACnC;AACD"}