@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
@@ -0,0 +1,66 @@
1
+ import jwt from "jsonwebtoken";
2
+
3
+ //#region src/tokenManager.ts
4
+ var TokenManager = class {
5
+ accessTokenSecret;
6
+ refreshTokenSecret;
7
+ accessTokenExpiresIn;
8
+ refreshTokenExpiresIn;
9
+ constructor(options) {
10
+ this.accessTokenSecret = options.accessTokenSecret;
11
+ this.refreshTokenSecret = options.refreshTokenSecret;
12
+ this.accessTokenExpiresIn = options.accessTokenExpiresIn || "15m";
13
+ this.refreshTokenExpiresIn = options.refreshTokenExpiresIn || "7d";
14
+ }
15
+ generateTokenPair(payload) {
16
+ const accessToken = jwt.sign(payload, this.accessTokenSecret, { expiresIn: this.accessTokenExpiresIn });
17
+ const refreshToken = jwt.sign(payload, this.refreshTokenSecret, { expiresIn: this.refreshTokenExpiresIn });
18
+ return {
19
+ accessToken,
20
+ refreshToken
21
+ };
22
+ }
23
+ verifyAccessToken(token) {
24
+ try {
25
+ return jwt.verify(token, this.accessTokenSecret);
26
+ } catch (error) {
27
+ const message = error instanceof Error ? error.message : String(error);
28
+ throw new Error(`Invalid access token: ${message}`);
29
+ }
30
+ }
31
+ verifyRefreshToken(token) {
32
+ try {
33
+ return jwt.verify(token, this.refreshTokenSecret);
34
+ } catch (error) {
35
+ const message = error instanceof Error ? error.message : String(error);
36
+ throw new Error(`Invalid refresh token: ${message}`);
37
+ }
38
+ }
39
+ refreshAccessToken(refreshToken) {
40
+ const decoded = this.verifyRefreshToken(refreshToken);
41
+ const { iat, exp,...payload } = decoded;
42
+ return jwt.sign(payload, this.accessTokenSecret, { expiresIn: this.accessTokenExpiresIn });
43
+ }
44
+ decodeToken(token) {
45
+ try {
46
+ return jwt.decode(token);
47
+ } catch {
48
+ return null;
49
+ }
50
+ }
51
+ isTokenExpired(token) {
52
+ const decoded = this.decodeToken(token);
53
+ if (!decoded) return true;
54
+ const now = Math.floor(Date.now() / 1e3);
55
+ return decoded.exp < now;
56
+ }
57
+ getTokenExpiration(token) {
58
+ const decoded = this.decodeToken(token);
59
+ if (!decoded) return null;
60
+ return new Date(decoded.exp * 1e3);
61
+ }
62
+ };
63
+
64
+ //#endregion
65
+ export { TokenManager };
66
+ //# sourceMappingURL=tokenManager-Ci2Tgxp8.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenManager-Ci2Tgxp8.mjs","names":["options: TokenManagerOptions","payload: TokenPayload","token: string","refreshToken: string"],"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,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAQ;CAER,YAAYA,SAA8B;AACzC,OAAK,oBAAoB,QAAQ;AACjC,OAAK,qBAAqB,QAAQ;AAClC,OAAK,uBAAuB,QAAQ,wBAAwB;AAC5D,OAAK,wBAAwB,QAAQ,yBAAyB;CAC9D;CAED,kBAAkBC,SAAkC;EACnD,MAAM,cAAc,IAAI,KAAK,SAAS,KAAK,mBAAmB,EAC7D,WAAW,KAAK,qBAChB,EAAC;EAEF,MAAM,eAAe,IAAI,KAAK,SAAS,KAAK,oBAAoB,EAC/D,WAAW,KAAK,sBAChB,EAAC;AAEF,SAAO;GACN;GACA;EACA;CACD;CAED,kBAAkBC,OAA6B;AAC9C,MAAI;AACH,UAAO,IAAI,OAAO,OAAO,KAAK,kBAAkB;EAChD,SAAQ,OAAO;GACf,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,SAAM,IAAI,OAAO,wBAAwB,QAAQ;EACjD;CACD;CAED,mBAAmBA,OAA6B;AAC/C,MAAI;AACH,UAAO,IAAI,OAAO,OAAO,KAAK,mBAAmB;EACjD,SAAQ,OAAO;GACf,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,SAAM,IAAI,OAAO,yBAAyB,QAAQ;EAClD;CACD;CAED,mBAAmBC,cAA8B;EAChD,MAAM,UAAU,KAAK,mBAAmB,aAAa;EAGrD,MAAM,EAAE,KAAK,IAAK,GAAG,SAAS,GAAG;AAEjC,SAAO,IAAI,KAAK,SAAS,KAAK,mBAAmB,EAChD,WAAW,KAAK,qBAChB,EAAC;CACF;CAED,YAAYD,OAAoC;AAC/C,MAAI;AACH,UAAO,IAAI,OAAO,MAAM;EACxB,QAAO;AACP,UAAO;EACP;CACD;CAED,eAAeA,OAAwB;EACtC,MAAM,UAAU,KAAK,YAAY,MAAM;AACvC,OAAK,QAAS,QAAO;EAErB,MAAM,MAAM,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK;AACzC,SAAO,QAAQ,MAAM;CACrB;CAED,mBAAmBA,OAA4B;EAC9C,MAAM,UAAU,KAAK,YAAY,MAAM;AACvC,OAAK,QAAS,QAAO;AAErB,SAAO,IAAI,KAAK,QAAQ,MAAM;CAC9B;AACD"}
@@ -0,0 +1,72 @@
1
+ const require_chunk = require('./chunk-CUT6urMc.cjs');
2
+ const jsonwebtoken = require_chunk.__toESM(require("jsonwebtoken"));
3
+
4
+ //#region src/tokenManager.ts
5
+ var TokenManager = class {
6
+ accessTokenSecret;
7
+ refreshTokenSecret;
8
+ accessTokenExpiresIn;
9
+ refreshTokenExpiresIn;
10
+ constructor(options) {
11
+ this.accessTokenSecret = options.accessTokenSecret;
12
+ this.refreshTokenSecret = options.refreshTokenSecret;
13
+ this.accessTokenExpiresIn = options.accessTokenExpiresIn || "15m";
14
+ this.refreshTokenExpiresIn = options.refreshTokenExpiresIn || "7d";
15
+ }
16
+ generateTokenPair(payload) {
17
+ const accessToken = jsonwebtoken.default.sign(payload, this.accessTokenSecret, { expiresIn: this.accessTokenExpiresIn });
18
+ const refreshToken = jsonwebtoken.default.sign(payload, this.refreshTokenSecret, { expiresIn: this.refreshTokenExpiresIn });
19
+ return {
20
+ accessToken,
21
+ refreshToken
22
+ };
23
+ }
24
+ verifyAccessToken(token) {
25
+ try {
26
+ return jsonwebtoken.default.verify(token, this.accessTokenSecret);
27
+ } catch (error) {
28
+ const message = error instanceof Error ? error.message : String(error);
29
+ throw new Error(`Invalid access token: ${message}`);
30
+ }
31
+ }
32
+ verifyRefreshToken(token) {
33
+ try {
34
+ return jsonwebtoken.default.verify(token, this.refreshTokenSecret);
35
+ } catch (error) {
36
+ const message = error instanceof Error ? error.message : String(error);
37
+ throw new Error(`Invalid refresh token: ${message}`);
38
+ }
39
+ }
40
+ refreshAccessToken(refreshToken) {
41
+ const decoded = this.verifyRefreshToken(refreshToken);
42
+ const { iat, exp,...payload } = decoded;
43
+ return jsonwebtoken.default.sign(payload, this.accessTokenSecret, { expiresIn: this.accessTokenExpiresIn });
44
+ }
45
+ decodeToken(token) {
46
+ try {
47
+ return jsonwebtoken.default.decode(token);
48
+ } catch {
49
+ return null;
50
+ }
51
+ }
52
+ isTokenExpired(token) {
53
+ const decoded = this.decodeToken(token);
54
+ if (!decoded) return true;
55
+ const now = Math.floor(Date.now() / 1e3);
56
+ return decoded.exp < now;
57
+ }
58
+ getTokenExpiration(token) {
59
+ const decoded = this.decodeToken(token);
60
+ if (!decoded) return null;
61
+ return new Date(decoded.exp * 1e3);
62
+ }
63
+ };
64
+
65
+ //#endregion
66
+ Object.defineProperty(exports, 'TokenManager', {
67
+ enumerable: true,
68
+ get: function () {
69
+ return TokenManager;
70
+ }
71
+ });
72
+ //# sourceMappingURL=tokenManager-CvEMgxOp.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenManager-CvEMgxOp.cjs","names":["options: TokenManagerOptions","payload: TokenPayload","token: string","refreshToken: string"],"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,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAQ;CAER,YAAYA,SAA8B;AACzC,OAAK,oBAAoB,QAAQ;AACjC,OAAK,qBAAqB,QAAQ;AAClC,OAAK,uBAAuB,QAAQ,wBAAwB;AAC5D,OAAK,wBAAwB,QAAQ,yBAAyB;CAC9D;CAED,kBAAkBC,SAAkC;EACnD,MAAM,cAAc,qBAAI,KAAK,SAAS,KAAK,mBAAmB,EAC7D,WAAW,KAAK,qBAChB,EAAC;EAEF,MAAM,eAAe,qBAAI,KAAK,SAAS,KAAK,oBAAoB,EAC/D,WAAW,KAAK,sBAChB,EAAC;AAEF,SAAO;GACN;GACA;EACA;CACD;CAED,kBAAkBC,OAA6B;AAC9C,MAAI;AACH,UAAO,qBAAI,OAAO,OAAO,KAAK,kBAAkB;EAChD,SAAQ,OAAO;GACf,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,SAAM,IAAI,OAAO,wBAAwB,QAAQ;EACjD;CACD;CAED,mBAAmBA,OAA6B;AAC/C,MAAI;AACH,UAAO,qBAAI,OAAO,OAAO,KAAK,mBAAmB;EACjD,SAAQ,OAAO;GACf,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,SAAM,IAAI,OAAO,yBAAyB,QAAQ;EAClD;CACD;CAED,mBAAmBC,cAA8B;EAChD,MAAM,UAAU,KAAK,mBAAmB,aAAa;EAGrD,MAAM,EAAE,KAAK,IAAK,GAAG,SAAS,GAAG;AAEjC,SAAO,qBAAI,KAAK,SAAS,KAAK,mBAAmB,EAChD,WAAW,KAAK,qBAChB,EAAC;CACF;CAED,YAAYD,OAAoC;AAC/C,MAAI;AACH,UAAO,qBAAI,OAAO,MAAM;EACxB,QAAO;AACP,UAAO;EACP;CACD;CAED,eAAeA,OAAwB;EACtC,MAAM,UAAU,KAAK,YAAY,MAAM;AACvC,OAAK,QAAS,QAAO;EAErB,MAAM,MAAM,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK;AACzC,SAAO,QAAQ,MAAM;CACrB;CAED,mBAAmBA,OAA4B;EAC9C,MAAM,UAAU,KAAK,YAAY,MAAM;AACvC,OAAK,QAAS,QAAO;AAErB,SAAO,IAAI,KAAK,QAAQ,MAAM;CAC9B;AACD"}
@@ -0,0 +1,40 @@
1
+ import ms from "ms";
2
+
3
+ //#region src/tokenManager.d.ts
4
+ interface TokenPayload {
5
+ userId: string;
6
+ email?: string;
7
+ [key: string]: any;
8
+ }
9
+ interface TokenPair {
10
+ accessToken: string;
11
+ refreshToken: string;
12
+ }
13
+ interface TokenManagerOptions {
14
+ accessTokenSecret: string;
15
+ refreshTokenSecret: string;
16
+ accessTokenExpiresIn?: ms.StringValue;
17
+ refreshTokenExpiresIn?: ms.StringValue;
18
+ }
19
+ interface DecodedToken extends TokenPayload {
20
+ iat: number;
21
+ exp: number;
22
+ }
23
+ declare class TokenManager {
24
+ private accessTokenSecret;
25
+ private refreshTokenSecret;
26
+ private accessTokenExpiresIn;
27
+ private refreshTokenExpiresIn;
28
+ constructor(options: TokenManagerOptions);
29
+ generateTokenPair(payload: TokenPayload): TokenPair;
30
+ verifyAccessToken(token: string): DecodedToken;
31
+ verifyRefreshToken(token: string): DecodedToken;
32
+ refreshAccessToken(refreshToken: string): string;
33
+ decodeToken(token: string): DecodedToken | null;
34
+ isTokenExpired(token: string): boolean;
35
+ getTokenExpiration(token: string): Date | null;
36
+ }
37
+ //# sourceMappingURL=tokenManager.d.ts.map
38
+ //#endregion
39
+ export { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload };
40
+ //# sourceMappingURL=tokenManager-RrwjL0y-.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenManager-RrwjL0y-.d.mts","names":[],"sources":["../src/tokenManager.ts"],"sourcesContent":[],"mappings":";;;UAGiB,YAAA;;EAAA,KAAA,CAAA,EAAA,MAAA;EAMA,CAAA,GAAA,EAAA,MAAS,CAAA,EAAA,GAAA;AAK1B;AAAoC,UALnB,SAAA,CAKmB;EAAA,WAGT,EAAA,MAAA;EAAW,YACV,EAAA,MAAA;AAAW;AAGtB,UAPA,mBAAA,CAOqB;EAKzB,iBAAY,EAAA,MAAA;EAAA,kBAAA,EAAA,MAAA;EAAA,oBAMH,CAAA,EAfE,EAAA,CAAG,WAeL;EAAmB,qBAOb,CAAA,EArBH,EAAA,CAAG,WAqBA;;AAeO,UAjClB,YAAA,SAAqB,YAiCH,CAAA;EAAY,GASX,EAAA,MAAA;EAAY,GAoBnB,EAAA,MAAA;;AAgBW,cAzE3B,YAAA,CAyE2B;;;;;uBAnElB;6BAOM,eAAe;oCAeR;qCASC;;8BAoBP;;qCAgBO"}
@@ -1,65 +1,3 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
3
- let jsonwebtoken = require("jsonwebtoken");
4
- jsonwebtoken = require_rolldown_runtime.__toESM(jsonwebtoken, 1);
5
- //#region src/tokenManager.ts
6
- var TokenManager = class {
7
- accessTokenSecret;
8
- refreshTokenSecret;
9
- accessTokenExpiresIn;
10
- refreshTokenExpiresIn;
11
- constructor(options) {
12
- this.accessTokenSecret = options.accessTokenSecret;
13
- this.refreshTokenSecret = options.refreshTokenSecret;
14
- this.accessTokenExpiresIn = options.accessTokenExpiresIn || "15m";
15
- this.refreshTokenExpiresIn = options.refreshTokenExpiresIn || "7d";
16
- }
17
- generateTokenPair(payload) {
18
- return {
19
- accessToken: jsonwebtoken.default.sign(payload, this.accessTokenSecret, { expiresIn: this.accessTokenExpiresIn }),
20
- refreshToken: jsonwebtoken.default.sign(payload, this.refreshTokenSecret, { expiresIn: this.refreshTokenExpiresIn })
21
- };
22
- }
23
- verifyAccessToken(token) {
24
- try {
25
- return jsonwebtoken.default.verify(token, this.accessTokenSecret);
26
- } catch (error) {
27
- const message = error instanceof Error ? error.message : String(error);
28
- throw new Error(`Invalid access token: ${message}`);
29
- }
30
- }
31
- verifyRefreshToken(token) {
32
- try {
33
- return jsonwebtoken.default.verify(token, this.refreshTokenSecret);
34
- } catch (error) {
35
- const message = error instanceof Error ? error.message : String(error);
36
- throw new Error(`Invalid refresh token: ${message}`);
37
- }
38
- }
39
- refreshAccessToken(refreshToken) {
40
- const { iat, exp, ...payload } = this.verifyRefreshToken(refreshToken);
41
- return jsonwebtoken.default.sign(payload, this.accessTokenSecret, { expiresIn: this.accessTokenExpiresIn });
42
- }
43
- decodeToken(token) {
44
- try {
45
- return jsonwebtoken.default.decode(token);
46
- } catch {
47
- return null;
48
- }
49
- }
50
- isTokenExpired(token) {
51
- const decoded = this.decodeToken(token);
52
- if (!decoded) return true;
53
- const now = Math.floor(Date.now() / 1e3);
54
- return decoded.exp < now;
55
- }
56
- getTokenExpiration(token) {
57
- const decoded = this.decodeToken(token);
58
- if (!decoded) return null;
59
- return /* @__PURE__ */ new Date(decoded.exp * 1e3);
60
- }
61
- };
62
- //#endregion
63
- exports.TokenManager = TokenManager;
1
+ const require_tokenManager = require('./tokenManager-CvEMgxOp.cjs');
64
2
 
65
- //# sourceMappingURL=tokenManager.cjs.map
3
+ exports.TokenManager = require_tokenManager.TokenManager;
@@ -1,37 +1,2 @@
1
- import ms from "ms";
2
- //#region src/tokenManager.d.ts
3
- export interface TokenPayload {
4
- userId: string;
5
- email?: string;
6
- [key: string]: any;
7
- }
8
- export interface TokenPair {
9
- accessToken: string;
10
- refreshToken: string;
11
- }
12
- export interface TokenManagerOptions {
13
- accessTokenSecret: string;
14
- refreshTokenSecret: string;
15
- accessTokenExpiresIn?: ms.StringValue;
16
- refreshTokenExpiresIn?: ms.StringValue;
17
- }
18
- export interface DecodedToken extends TokenPayload {
19
- iat: number;
20
- exp: number;
21
- }
22
- export declare class TokenManager {
23
- private accessTokenSecret;
24
- private refreshTokenSecret;
25
- private accessTokenExpiresIn;
26
- private refreshTokenExpiresIn;
27
- constructor(options: TokenManagerOptions);
28
- generateTokenPair(payload: TokenPayload): TokenPair;
29
- verifyAccessToken(token: string): DecodedToken;
30
- verifyRefreshToken(token: string): DecodedToken;
31
- refreshAccessToken(refreshToken: string): string;
32
- decodeToken(token: string): DecodedToken | null;
33
- isTokenExpired(token: string): boolean;
34
- getTokenExpiration(token: string): Date | null;
35
- }
36
- //#endregion
37
- //# sourceMappingURL=tokenManager.d.cts.map
1
+ import { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload } from "./tokenManager-CL3yE06D.cjs";
2
+ export { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload };
@@ -1,37 +1,2 @@
1
- import ms from "ms";
2
- //#region src/tokenManager.d.ts
3
- export interface TokenPayload {
4
- userId: string;
5
- email?: string;
6
- [key: string]: any;
7
- }
8
- export interface TokenPair {
9
- accessToken: string;
10
- refreshToken: string;
11
- }
12
- export interface TokenManagerOptions {
13
- accessTokenSecret: string;
14
- refreshTokenSecret: string;
15
- accessTokenExpiresIn?: ms.StringValue;
16
- refreshTokenExpiresIn?: ms.StringValue;
17
- }
18
- export interface DecodedToken extends TokenPayload {
19
- iat: number;
20
- exp: number;
21
- }
22
- export declare class TokenManager {
23
- private accessTokenSecret;
24
- private refreshTokenSecret;
25
- private accessTokenExpiresIn;
26
- private refreshTokenExpiresIn;
27
- constructor(options: TokenManagerOptions);
28
- generateTokenPair(payload: TokenPayload): TokenPair;
29
- verifyAccessToken(token: string): DecodedToken;
30
- verifyRefreshToken(token: string): DecodedToken;
31
- refreshAccessToken(refreshToken: string): string;
32
- decodeToken(token: string): DecodedToken | null;
33
- isTokenExpired(token: string): boolean;
34
- getTokenExpiration(token: string): Date | null;
35
- }
36
- //#endregion
37
- //# sourceMappingURL=tokenManager.d.mts.map
1
+ import { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload } from "./tokenManager-RrwjL0y-.mjs";
2
+ export { DecodedToken, TokenManager, TokenManagerOptions, TokenPair, TokenPayload };
@@ -1,62 +1,3 @@
1
- import jwt from "jsonwebtoken";
2
- //#region src/tokenManager.ts
3
- var TokenManager = class {
4
- accessTokenSecret;
5
- refreshTokenSecret;
6
- accessTokenExpiresIn;
7
- refreshTokenExpiresIn;
8
- constructor(options) {
9
- this.accessTokenSecret = options.accessTokenSecret;
10
- this.refreshTokenSecret = options.refreshTokenSecret;
11
- this.accessTokenExpiresIn = options.accessTokenExpiresIn || "15m";
12
- this.refreshTokenExpiresIn = options.refreshTokenExpiresIn || "7d";
13
- }
14
- generateTokenPair(payload) {
15
- return {
16
- accessToken: jwt.sign(payload, this.accessTokenSecret, { expiresIn: this.accessTokenExpiresIn }),
17
- refreshToken: jwt.sign(payload, this.refreshTokenSecret, { expiresIn: this.refreshTokenExpiresIn })
18
- };
19
- }
20
- verifyAccessToken(token) {
21
- try {
22
- return jwt.verify(token, this.accessTokenSecret);
23
- } catch (error) {
24
- const message = error instanceof Error ? error.message : String(error);
25
- throw new Error(`Invalid access token: ${message}`);
26
- }
27
- }
28
- verifyRefreshToken(token) {
29
- try {
30
- return jwt.verify(token, this.refreshTokenSecret);
31
- } catch (error) {
32
- const message = error instanceof Error ? error.message : String(error);
33
- throw new Error(`Invalid refresh token: ${message}`);
34
- }
35
- }
36
- refreshAccessToken(refreshToken) {
37
- const { iat, exp, ...payload } = this.verifyRefreshToken(refreshToken);
38
- return jwt.sign(payload, this.accessTokenSecret, { expiresIn: this.accessTokenExpiresIn });
39
- }
40
- decodeToken(token) {
41
- try {
42
- return jwt.decode(token);
43
- } catch {
44
- return null;
45
- }
46
- }
47
- isTokenExpired(token) {
48
- const decoded = this.decodeToken(token);
49
- if (!decoded) return true;
50
- const now = Math.floor(Date.now() / 1e3);
51
- return decoded.exp < now;
52
- }
53
- getTokenExpiration(token) {
54
- const decoded = this.decodeToken(token);
55
- if (!decoded) return null;
56
- return /* @__PURE__ */ new Date(decoded.exp * 1e3);
57
- }
58
- };
59
- //#endregion
60
- export { TokenManager };
1
+ import { TokenManager } from "./tokenManager-Ci2Tgxp8.mjs";
61
2
 
62
- //# sourceMappingURL=tokenManager.mjs.map
3
+ export { TokenManager };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geekmidas/auth",
3
- "version": "10.0.0-alpha.99",
3
+ "version": "10.0.0",
4
4
  "description": "JWT and OIDC authentication with token verification, Hono middleware, and Lambda authorizers",
5
5
  "type": "module",
6
6
  "exports": {
@@ -95,9 +95,6 @@
95
95
  }
96
96
  }
97
97
  },
98
- "files": [
99
- "dist"
100
- ],
101
98
  "repository": {
102
99
  "type": "git",
103
100
  "url": "https://github.com/geekmidas/toolbox"
@@ -108,18 +105,18 @@
108
105
  },
109
106
  "dependencies": {
110
107
  "@openauthjs/openauth": "~0.4.3",
111
- "jose": "~6.2.12",
112
- "jsonwebtoken": "~9.0.3",
108
+ "jose": "~5.10.0",
109
+ "jsonwebtoken": "^9.0.2",
113
110
  "@types/ms": "~2.1.0"
114
111
  },
115
112
  "devDependencies": {
116
- "@types/jsonwebtoken": "~9.0.10",
117
- "@geekmidas/cache": "^10.0.0-alpha.99"
113
+ "@types/jsonwebtoken": "^9.0.5",
114
+ "@geekmidas/cache": "^10.0.0"
118
115
  },
119
116
  "peerDependencies": {
120
- "@types/aws-lambda": ">=8.10.163",
121
- "hono": ">=4.13.8",
122
- "@geekmidas/cache": "^10.0.0-alpha.99"
117
+ "@types/aws-lambda": ">=8.10.92",
118
+ "hono": ">=4.0.0",
119
+ "@geekmidas/cache": "^10.0.0"
123
120
  },
124
121
  "peerDependenciesMeta": {
125
122
  "@geekmidas/cache": {
@@ -133,7 +130,6 @@
133
130
  }
134
131
  },
135
132
  "scripts": {
136
- "play": "tsx src/playground.ts",
137
- "build": "tsdown --config ../../tsdown.config.ts --filter ."
133
+ "play": "tsx src/playground.ts"
138
134
  }
139
135
  }
@@ -0,0 +1,213 @@
1
+ import type { Cache } from '@geekmidas/cache';
2
+ import { InMemoryCache } from '@geekmidas/cache/memory';
3
+ import { beforeEach, describe, expect, it } from 'vitest';
4
+ import { CacheTokenStorage } from '../cacheTokenStorage.ts';
5
+
6
+ describe('CacheTokenStorage', () => {
7
+ let storage: CacheTokenStorage;
8
+ let cache: Cache<string>;
9
+
10
+ beforeEach(() => {
11
+ cache = new InMemoryCache<string>();
12
+ storage = new CacheTokenStorage(cache);
13
+ });
14
+
15
+ describe('access token operations', () => {
16
+ it('should store and retrieve access token', async () => {
17
+ await storage.setAccessToken('test-access-token');
18
+
19
+ const token = await storage.getAccessToken();
20
+
21
+ expect(token).toBe('test-access-token');
22
+ });
23
+
24
+ it('should return null when no access token exists', async () => {
25
+ const token = await storage.getAccessToken();
26
+
27
+ expect(token).toBeNull();
28
+ });
29
+
30
+ it('should store access token with TTL', async () => {
31
+ await storage.setAccessToken('test-access-token', 3600);
32
+
33
+ const token = await storage.getAccessToken();
34
+
35
+ expect(token).toBe('test-access-token');
36
+ });
37
+
38
+ it('should overwrite existing access token', async () => {
39
+ await storage.setAccessToken('first-token');
40
+ await storage.setAccessToken('second-token');
41
+
42
+ const token = await storage.getAccessToken();
43
+
44
+ expect(token).toBe('second-token');
45
+ });
46
+ });
47
+
48
+ describe('refresh token operations', () => {
49
+ it('should store and retrieve refresh token', async () => {
50
+ await storage.setRefreshToken('test-refresh-token');
51
+
52
+ const token = await storage.getRefreshToken();
53
+
54
+ expect(token).toBe('test-refresh-token');
55
+ });
56
+
57
+ it('should return null when no refresh token exists', async () => {
58
+ const token = await storage.getRefreshToken();
59
+
60
+ expect(token).toBeNull();
61
+ });
62
+
63
+ it('should store refresh token with TTL', async () => {
64
+ await storage.setRefreshToken('test-refresh-token', 7200);
65
+
66
+ const token = await storage.getRefreshToken();
67
+
68
+ expect(token).toBe('test-refresh-token');
69
+ });
70
+
71
+ it('should overwrite existing refresh token', async () => {
72
+ await storage.setRefreshToken('first-refresh-token');
73
+ await storage.setRefreshToken('second-refresh-token');
74
+
75
+ const token = await storage.getRefreshToken();
76
+
77
+ expect(token).toBe('second-refresh-token');
78
+ });
79
+ });
80
+
81
+ describe('token lifecycle', () => {
82
+ it('should store both tokens independently', async () => {
83
+ await storage.setAccessToken('access-token');
84
+ await storage.setRefreshToken('refresh-token');
85
+
86
+ const accessToken = await storage.getAccessToken();
87
+ const refreshToken = await storage.getRefreshToken();
88
+
89
+ expect(accessToken).toBe('access-token');
90
+ expect(refreshToken).toBe('refresh-token');
91
+ });
92
+
93
+ it('should clear both tokens', async () => {
94
+ await storage.setAccessToken('access-token');
95
+ await storage.setRefreshToken('refresh-token');
96
+
97
+ await storage.clearTokens();
98
+
99
+ const accessToken = await storage.getAccessToken();
100
+ const refreshToken = await storage.getRefreshToken();
101
+
102
+ expect(accessToken).toBeNull();
103
+ expect(refreshToken).toBeNull();
104
+ });
105
+
106
+ it('should clear tokens when some are missing', async () => {
107
+ await storage.setAccessToken('access-token');
108
+
109
+ await storage.clearTokens();
110
+
111
+ const accessToken = await storage.getAccessToken();
112
+ const refreshToken = await storage.getRefreshToken();
113
+
114
+ expect(accessToken).toBeNull();
115
+ expect(refreshToken).toBeNull();
116
+ });
117
+ });
118
+
119
+ describe('custom storage keys', () => {
120
+ it('should use custom keys for token storage', async () => {
121
+ const customStorage = new CacheTokenStorage(
122
+ cache,
123
+ 'custom_access_key',
124
+ 'custom_refresh_key',
125
+ );
126
+
127
+ await customStorage.setAccessToken('access-token');
128
+ await customStorage.setRefreshToken('refresh-token');
129
+
130
+ const accessToken = await customStorage.getAccessToken();
131
+ const refreshToken = await customStorage.getRefreshToken();
132
+
133
+ expect(accessToken).toBe('access-token');
134
+ expect(refreshToken).toBe('refresh-token');
135
+ });
136
+
137
+ it('should isolate tokens between different storage instances', async () => {
138
+ const defaultStorage = new CacheTokenStorage(cache);
139
+ const customStorage = new CacheTokenStorage(
140
+ cache,
141
+ 'custom_access',
142
+ 'custom_refresh',
143
+ );
144
+
145
+ await defaultStorage.setAccessToken('default-access');
146
+ await customStorage.setAccessToken('custom-access');
147
+
148
+ const defaultToken = await defaultStorage.getAccessToken();
149
+ const customToken = await customStorage.getAccessToken();
150
+
151
+ expect(defaultToken).toBe('default-access');
152
+ expect(customToken).toBe('custom-access');
153
+ });
154
+
155
+ it('should clear tokens independently with custom keys', async () => {
156
+ const defaultStorage = new CacheTokenStorage(cache);
157
+ const customStorage = new CacheTokenStorage(
158
+ cache,
159
+ 'custom_access',
160
+ 'custom_refresh',
161
+ );
162
+
163
+ await defaultStorage.setAccessToken('default-access');
164
+ await customStorage.setAccessToken('custom-access');
165
+
166
+ await defaultStorage.clearTokens();
167
+
168
+ const defaultToken = await defaultStorage.getAccessToken();
169
+ const customToken = await customStorage.getAccessToken();
170
+
171
+ expect(defaultToken).toBeNull();
172
+ expect(customToken).toBe('custom-access');
173
+ });
174
+ });
175
+
176
+ describe('integration with real cache', () => {
177
+ it('should work with multiple cache instances', async () => {
178
+ const cache1 = new InMemoryCache<string>();
179
+ const cache2 = new InMemoryCache<string>();
180
+
181
+ const storage1 = new CacheTokenStorage(cache1);
182
+ const storage2 = new CacheTokenStorage(cache2);
183
+
184
+ await storage1.setAccessToken('token-1');
185
+ await storage2.setAccessToken('token-2');
186
+
187
+ const token1 = await storage1.getAccessToken();
188
+ const token2 = await storage2.getAccessToken();
189
+
190
+ expect(token1).toBe('token-1');
191
+ expect(token2).toBe('token-2');
192
+ });
193
+
194
+ it('should maintain token state across operations', async () => {
195
+ await storage.setAccessToken('initial-access');
196
+ await storage.setRefreshToken('initial-refresh');
197
+
198
+ let accessToken = await storage.getAccessToken();
199
+ let refreshToken = await storage.getRefreshToken();
200
+
201
+ expect(accessToken).toBe('initial-access');
202
+ expect(refreshToken).toBe('initial-refresh');
203
+
204
+ await storage.setAccessToken('updated-access');
205
+
206
+ accessToken = await storage.getAccessToken();
207
+ refreshToken = await storage.getRefreshToken();
208
+
209
+ expect(accessToken).toBe('updated-access');
210
+ expect(refreshToken).toBe('initial-refresh');
211
+ });
212
+ });
213
+ });