@shware/security 0.4.9 → 1.1.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 (105) hide show
  1. package/dist/auth/index.cjs +103 -23
  2. package/dist/auth/index.cjs.map +1 -1
  3. package/dist/auth/index.d.cts +10 -3
  4. package/dist/auth/index.d.ts +10 -3
  5. package/dist/auth/index.mjs +104 -24
  6. package/dist/auth/index.mjs.map +1 -1
  7. package/dist/auth/types.cjs.map +1 -1
  8. package/dist/auth/types.d.cts +11 -3
  9. package/dist/auth/types.d.ts +11 -3
  10. package/dist/index.cjs +4 -4
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.d.cts +2 -2
  13. package/dist/index.d.ts +2 -2
  14. package/dist/index.mjs +2 -2
  15. package/dist/index.mjs.map +1 -1
  16. package/dist/oauth2/client.cjs +40 -6
  17. package/dist/oauth2/client.cjs.map +1 -1
  18. package/dist/oauth2/client.d.cts +29 -6
  19. package/dist/oauth2/client.d.ts +29 -6
  20. package/dist/oauth2/client.mjs +40 -6
  21. package/dist/oauth2/client.mjs.map +1 -1
  22. package/dist/oauth2/error.cjs.map +1 -1
  23. package/dist/oauth2/error.d.cts +1 -1
  24. package/dist/oauth2/error.d.ts +1 -1
  25. package/dist/oauth2/error.mjs.map +1 -1
  26. package/dist/oauth2/provider/apple.cjs +21 -5
  27. package/dist/oauth2/provider/apple.cjs.map +1 -1
  28. package/dist/oauth2/provider/apple.d.cts +12 -4
  29. package/dist/oauth2/provider/apple.d.ts +12 -4
  30. package/dist/oauth2/provider/apple.mjs +19 -4
  31. package/dist/oauth2/provider/apple.mjs.map +1 -1
  32. package/dist/oauth2/provider/common.cjs +5 -13
  33. package/dist/oauth2/provider/common.cjs.map +1 -1
  34. package/dist/oauth2/provider/common.d.cts +6 -11
  35. package/dist/oauth2/provider/common.d.ts +6 -11
  36. package/dist/oauth2/provider/common.mjs +5 -13
  37. package/dist/oauth2/provider/common.mjs.map +1 -1
  38. package/dist/oauth2/provider/facebook.cjs +19 -3
  39. package/dist/oauth2/provider/facebook.cjs.map +1 -1
  40. package/dist/oauth2/provider/facebook.d.cts +17 -3
  41. package/dist/oauth2/provider/facebook.d.ts +17 -3
  42. package/dist/oauth2/provider/facebook.mjs +18 -3
  43. package/dist/oauth2/provider/facebook.mjs.map +1 -1
  44. package/dist/oauth2/provider/github.cjs +6 -3
  45. package/dist/oauth2/provider/github.cjs.map +1 -1
  46. package/dist/oauth2/provider/github.d.cts +11 -3
  47. package/dist/oauth2/provider/github.d.ts +11 -3
  48. package/dist/oauth2/provider/github.mjs +5 -3
  49. package/dist/oauth2/provider/github.mjs.map +1 -1
  50. package/dist/oauth2/provider/google.cjs +17 -1
  51. package/dist/oauth2/provider/google.cjs.map +1 -1
  52. package/dist/oauth2/provider/google.d.cts +11 -4
  53. package/dist/oauth2/provider/google.d.ts +11 -4
  54. package/dist/oauth2/provider/google.mjs +16 -1
  55. package/dist/oauth2/provider/google.mjs.map +1 -1
  56. package/dist/oauth2/provider/x.cjs +16 -4
  57. package/dist/oauth2/provider/x.cjs.map +1 -1
  58. package/dist/oauth2/provider/x.d.cts +11 -3
  59. package/dist/oauth2/provider/x.d.ts +11 -3
  60. package/dist/oauth2/provider/x.mjs +15 -4
  61. package/dist/oauth2/provider/x.mjs.map +1 -1
  62. package/dist/oauth2/types.cjs +20 -0
  63. package/dist/oauth2/types.cjs.map +1 -1
  64. package/dist/oauth2/types.d.cts +73 -12
  65. package/dist/oauth2/types.d.ts +73 -12
  66. package/dist/oauth2/types.mjs +13 -0
  67. package/dist/oauth2/types.mjs.map +1 -1
  68. package/dist/session/__test__/{redis-session.test.cjs → redis.test.cjs} +7 -7
  69. package/dist/session/__test__/redis.test.cjs.map +1 -0
  70. package/dist/session/__test__/{redis-session.test.mjs → redis.test.mjs} +4 -4
  71. package/dist/session/__test__/redis.test.mjs.map +1 -0
  72. package/dist/session/index.cjs +3 -3
  73. package/dist/session/index.cjs.map +1 -1
  74. package/dist/session/index.d.cts +1 -1
  75. package/dist/session/index.d.ts +1 -1
  76. package/dist/session/index.mjs +5 -2
  77. package/dist/session/index.mjs.map +1 -1
  78. package/dist/session/{redis-session.cjs → redis.cjs} +29 -8
  79. package/dist/session/redis.cjs.map +1 -0
  80. package/dist/session/{redis-session.d.cts → redis.d.cts} +6 -2
  81. package/dist/session/{redis-session.d.ts → redis.d.ts} +6 -2
  82. package/dist/session/{redis-session.mjs → redis.mjs} +25 -4
  83. package/dist/session/redis.mjs.map +1 -0
  84. package/dist/session/types.cjs.map +1 -1
  85. package/dist/session/types.d.cts +3 -0
  86. package/dist/session/types.d.ts +3 -0
  87. package/dist/utils/timing.cjs +73 -0
  88. package/dist/utils/timing.cjs.map +1 -0
  89. package/dist/utils/timing.d.cts +13 -0
  90. package/dist/utils/timing.d.ts +13 -0
  91. package/dist/utils/timing.mjs +48 -0
  92. package/dist/utils/timing.mjs.map +1 -0
  93. package/package.json +1 -1
  94. package/dist/oidc/index.cjs +0 -39
  95. package/dist/oidc/index.cjs.map +0 -1
  96. package/dist/oidc/index.d.cts +0 -10
  97. package/dist/oidc/index.d.ts +0 -10
  98. package/dist/oidc/index.mjs +0 -14
  99. package/dist/oidc/index.mjs.map +0 -1
  100. package/dist/session/__test__/redis-session.test.cjs.map +0 -1
  101. package/dist/session/__test__/redis-session.test.mjs.map +0 -1
  102. package/dist/session/redis-session.cjs.map +0 -1
  103. package/dist/session/redis-session.mjs.map +0 -1
  104. /package/dist/session/__test__/{redis-session.test.d.cts → redis.test.d.cts} +0 -0
  105. /package/dist/session/__test__/{redis-session.test.d.ts → redis.test.d.ts} +0 -0
@@ -16,7 +16,7 @@ var defaultUserFields = [
16
16
  "location",
17
17
  "verified"
18
18
  ];
19
- function x(options) {
19
+ function createXProvider(options) {
20
20
  return {
21
21
  authorizationUri: "https://x.com/i/oauth2/authorize",
22
22
  tokenUri: "https://api.x.com/2/oauth2/token",
@@ -25,7 +25,7 @@ function x(options) {
25
25
  userInfoUri: "https://api.x.com/2/users/me",
26
26
  defaultScope: ["users.read", "tweet.read", "offline.access"],
27
27
  createAuthorizationUri(params) {
28
- if (!params.codeVerifier) throw new Error("codeVerifier is required for x");
28
+ if (!params.pkce) throw new Error("pkce is required for x");
29
29
  return createAuthorizationUri({
30
30
  ...params,
31
31
  scope: params.scope ?? this.defaultScope,
@@ -33,7 +33,7 @@ function x(options) {
33
33
  });
34
34
  },
35
35
  async exchangeAuthorizationCode(params) {
36
- if (!params.codeVerifier) throw new Error("codeVerifier is required for x");
36
+ if (!params.pkce) throw new Error("pkce is required for x");
37
37
  const response = await exchangeAuthorizationCode({
38
38
  ...params,
39
39
  tokenUri: this.tokenUri,
@@ -77,7 +77,16 @@ function x(options) {
77
77
  };
78
78
  },
79
79
  async refreshAccessToken(params) {
80
- return refreshAccessToken({ ...params, tokenUri: this.tokenUri, authentication: "basic" });
80
+ const response = await refreshAccessToken({
81
+ ...params,
82
+ tokenUri: this.tokenUri,
83
+ authentication: "basic"
84
+ });
85
+ if (!response.ok) {
86
+ const { error, error_description } = await response.json();
87
+ throw new OAuth2Error(response.status, error, error_description);
88
+ }
89
+ return await response.json();
81
90
  },
82
91
  async revokeToken(params) {
83
92
  invariant(this.tokenRevokeUri, "tokenRevokeUri is required");
@@ -89,7 +98,9 @@ function x(options) {
89
98
  }
90
99
  };
91
100
  }
101
+ var x = createXProvider();
92
102
  export {
103
+ createXProvider,
93
104
  x
94
105
  };
95
106
  //# sourceMappingURL=x.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/oauth2/provider/x.ts"],"sourcesContent":["import invariant from 'tiny-invariant';\nimport { Provider } from '../types';\nimport { OAuth2Error } from '../error';\nimport {\n createAuthorizationUri,\n exchangeAuthorizationCode,\n refreshAccessToken,\n revokeToken,\n} from './common';\n\nexport interface XOptions {\n userFields?: UserField[];\n}\n\nconst defaultUserFields = [\n 'id',\n 'name',\n 'profile_image_url',\n 'url',\n 'username',\n 'location',\n 'verified',\n];\n\nexport function x(options?: XOptions): Provider<XUserInfo> {\n return {\n authorizationUri: 'https://x.com/i/oauth2/authorize',\n tokenUri: 'https://api.x.com/2/oauth2/token',\n tokenRevokeUri: 'https://api.x.com/2/oauth2/revoke',\n // https://docs.x.com/x-api/users/user-lookup-me\n userInfoUri: 'https://api.x.com/2/users/me',\n defaultScope: ['users.read', 'tweet.read', 'offline.access'],\n createAuthorizationUri(params) {\n if (!params.codeVerifier) throw new Error('codeVerifier is required for x');\n return createAuthorizationUri({\n ...params,\n scope: params.scope ?? this.defaultScope,\n authorizationUri: this.authorizationUri,\n });\n },\n async exchangeAuthorizationCode(params) {\n if (!params.codeVerifier) throw new Error('codeVerifier is required for x');\n const response = await exchangeAuthorizationCode({\n ...params,\n tokenUri: this.tokenUri,\n authentication: 'basic',\n });\n if (!response.ok) {\n const { error, error_description } = (await response.json()) as XErrorResponse;\n throw new OAuth2Error(response.status, error, error_description);\n }\n return (await response.json()) as XOAuth2Token;\n },\n async getUserInfo({ access_token }) {\n invariant(access_token, 'access_token is required');\n invariant(this.userInfoUri, 'userInfoUri is required');\n\n const userFields = options?.userFields ?? defaultUserFields;\n const headers = { Accept: 'application/json', Authorization: `Bearer ${access_token}` };\n\n const url = new URL(this.userInfoUri);\n userFields.forEach((field) => url.searchParams.append('user.fields', field));\n\n const response = await fetch(this.userInfoUri, { headers });\n if (!response.ok) {\n const { errors } = (await response.json()) as XAPIErrorResponse;\n throw new OAuth2Error(\n response.status,\n 'invalid_request',\n 'Failed to fetch user info: ' + (errors.at(0)?.detail ?? errors.at(0)?.title)\n );\n }\n const profile = (await response.json()) as XUserInfo;\n return {\n data: profile,\n claims: {\n sub: profile.data.id,\n name: profile.data.name,\n picture: profile.data.profile_image_url,\n email: profile.data.email,\n email_verified: profile.data.verified || false,\n preferred_username: profile.data.username,\n profile: `https://x.com/${profile.data.username}`,\n website: profile.data.url,\n },\n };\n },\n async refreshAccessToken(params) {\n return refreshAccessToken({ ...params, tokenUri: this.tokenUri, authentication: 'basic' });\n },\n async revokeToken(params) {\n invariant(this.tokenRevokeUri, 'tokenRevokeUri is required');\n return revokeToken({\n ...params,\n tokenRevokeUri: this.tokenRevokeUri,\n authentication: 'basic',\n });\n },\n };\n}\n\ntype UserField =\n | 'affiliation'\n | 'connection_status'\n | 'created_at'\n | 'description'\n | 'entities'\n | 'id'\n | 'is_identity_verified'\n | 'location'\n | 'most_recent_tweet_id'\n | 'name'\n | 'parody'\n | 'pinned_tweet_id'\n | 'profile_banner_url'\n | 'profile_image_url'\n | 'protected'\n | 'public_metrics'\n | 'receives_your_dm'\n | 'subscription'\n | 'subscription_type'\n | 'url'\n | 'username'\n | 'verified'\n | 'verified_followers_count'\n | 'verified_type'\n | 'withheld';\n\nexport interface XUser {\n id: string;\n name: string;\n email?: string;\n username: string;\n location?: string;\n entities?: {\n url: { urls: UrlEntity[] };\n description: {\n hashtags: HashtagEntity[];\n cashtags: HashtagEntity[];\n mentions: MentionEntity[];\n };\n };\n verified?: boolean;\n description?: string;\n url?: string;\n profile_image_url?: string;\n protected?: boolean;\n pinned_tweet_id?: string;\n created_at?: string;\n}\n\nexport interface XUserInfo {\n data: XUser;\n includes?: { tweets?: { id: string; text: string }[]; users?: XUser[] };\n}\n\n// prettier-ignore\ntype UrlEntity = { start: number; end: number; url: string; display_url: string; expanded_url: string; }\ntype HashtagEntity = { start: number; end: number; tag: string };\ntype MentionEntity = { start: number; end: string; username: string };\n\ntype XOAuth2Token = {\n token_type: string;\n expires_in: number;\n access_token: string;\n scope: string;\n refresh_token: string;\n};\n\ntype XErrorResponse = { error: string; error_description: string };\ntype XAPIErrorResponse = {\n errors: { title: string; type: string; detail?: string; status?: number }[];\n};\n"],"mappings":";AAAA,OAAO,eAAe;AAEtB,SAAS,mBAAmB;AAC5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAMP,IAAM,oBAAoB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,EAAE,SAAyC;AACzD,SAAO;AAAA,IACL,kBAAkB;AAAA,IAClB,UAAU;AAAA,IACV,gBAAgB;AAAA;AAAA,IAEhB,aAAa;AAAA,IACb,cAAc,CAAC,cAAc,cAAc,gBAAgB;AAAA,IAC3D,uBAAuB,QAAQ;AAC7B,UAAI,CAAC,OAAO,aAAc,OAAM,IAAI,MAAM,gCAAgC;AAC1E,aAAO,uBAAuB;AAAA,QAC5B,GAAG;AAAA,QACH,OAAO,OAAO,SAAS,KAAK;AAAA,QAC5B,kBAAkB,KAAK;AAAA,MACzB,CAAC;AAAA,IACH;AAAA,IACA,MAAM,0BAA0B,QAAQ;AACtC,UAAI,CAAC,OAAO,aAAc,OAAM,IAAI,MAAM,gCAAgC;AAC1E,YAAM,WAAW,MAAM,0BAA0B;AAAA,QAC/C,GAAG;AAAA,QACH,UAAU,KAAK;AAAA,QACf,gBAAgB;AAAA,MAClB,CAAC;AACD,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,EAAE,OAAO,kBAAkB,IAAK,MAAM,SAAS,KAAK;AAC1D,cAAM,IAAI,YAAY,SAAS,QAAQ,OAAO,iBAAiB;AAAA,MACjE;AACA,aAAQ,MAAM,SAAS,KAAK;AAAA,IAC9B;AAAA,IACA,MAAM,YAAY,EAAE,aAAa,GAAG;AAClC,gBAAU,cAAc,0BAA0B;AAClD,gBAAU,KAAK,aAAa,yBAAyB;AAErD,YAAM,aAAa,SAAS,cAAc;AAC1C,YAAM,UAAU,EAAE,QAAQ,oBAAoB,eAAe,UAAU,YAAY,GAAG;AAEtF,YAAM,MAAM,IAAI,IAAI,KAAK,WAAW;AACpC,iBAAW,QAAQ,CAAC,UAAU,IAAI,aAAa,OAAO,eAAe,KAAK,CAAC;AAE3E,YAAM,WAAW,MAAM,MAAM,KAAK,aAAa,EAAE,QAAQ,CAAC;AAC1D,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,EAAE,OAAO,IAAK,MAAM,SAAS,KAAK;AACxC,cAAM,IAAI;AAAA,UACR,SAAS;AAAA,UACT;AAAA,UACA,iCAAiC,OAAO,GAAG,CAAC,GAAG,UAAU,OAAO,GAAG,CAAC,GAAG;AAAA,QACzE;AAAA,MACF;AACA,YAAM,UAAW,MAAM,SAAS,KAAK;AACrC,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ;AAAA,UACN,KAAK,QAAQ,KAAK;AAAA,UAClB,MAAM,QAAQ,KAAK;AAAA,UACnB,SAAS,QAAQ,KAAK;AAAA,UACtB,OAAO,QAAQ,KAAK;AAAA,UACpB,gBAAgB,QAAQ,KAAK,YAAY;AAAA,UACzC,oBAAoB,QAAQ,KAAK;AAAA,UACjC,SAAS,iBAAiB,QAAQ,KAAK,QAAQ;AAAA,UAC/C,SAAS,QAAQ,KAAK;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAAA,IACA,MAAM,mBAAmB,QAAQ;AAC/B,aAAO,mBAAmB,EAAE,GAAG,QAAQ,UAAU,KAAK,UAAU,gBAAgB,QAAQ,CAAC;AAAA,IAC3F;AAAA,IACA,MAAM,YAAY,QAAQ;AACxB,gBAAU,KAAK,gBAAgB,4BAA4B;AAC3D,aAAO,YAAY;AAAA,QACjB,GAAG;AAAA,QACH,gBAAgB,KAAK;AAAA,QACrB,gBAAgB;AAAA,MAClB,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/oauth2/provider/x.ts"],"sourcesContent":["import invariant from 'tiny-invariant';\nimport { OAuth2Token, Provider } from '../types';\nimport { OAuth2Error } from '../error';\nimport {\n createAuthorizationUri,\n exchangeAuthorizationCode,\n refreshAccessToken,\n revokeToken,\n} from './common';\n\nexport interface XOptions {\n userFields?: UserField[];\n}\n\nconst defaultUserFields = [\n 'id',\n 'name',\n 'profile_image_url',\n 'url',\n 'username',\n 'location',\n 'verified',\n];\n\nexport function createXProvider(options?: XOptions): Provider {\n return {\n authorizationUri: 'https://x.com/i/oauth2/authorize',\n tokenUri: 'https://api.x.com/2/oauth2/token',\n tokenRevokeUri: 'https://api.x.com/2/oauth2/revoke',\n // https://docs.x.com/x-api/users/user-lookup-me\n userInfoUri: 'https://api.x.com/2/users/me',\n defaultScope: ['users.read', 'tweet.read', 'offline.access'],\n createAuthorizationUri(params) {\n if (!params.pkce) throw new Error('pkce is required for x');\n return createAuthorizationUri({\n ...params,\n scope: params.scope ?? this.defaultScope,\n authorizationUri: this.authorizationUri,\n });\n },\n async exchangeAuthorizationCode(params) {\n if (!params.pkce) throw new Error('pkce is required for x');\n const response = await exchangeAuthorizationCode({\n ...params,\n tokenUri: this.tokenUri,\n authentication: 'basic',\n });\n if (!response.ok) {\n const { error, error_description } = (await response.json()) as XErrorResponse;\n throw new OAuth2Error(response.status, error, error_description);\n }\n return (await response.json()) as XToken;\n },\n async getUserInfo({ access_token }) {\n invariant(access_token, 'access_token is required');\n invariant(this.userInfoUri, 'userInfoUri is required');\n\n const userFields = options?.userFields ?? defaultUserFields;\n const headers = { Accept: 'application/json', Authorization: `Bearer ${access_token}` };\n\n const url = new URL(this.userInfoUri);\n userFields.forEach((field) => url.searchParams.append('user.fields', field));\n\n const response = await fetch(this.userInfoUri, { headers });\n if (!response.ok) {\n const { errors } = (await response.json()) as XAPIErrorResponse;\n throw new OAuth2Error(\n response.status,\n 'invalid_request',\n 'Failed to fetch user info: ' + (errors.at(0)?.detail ?? errors.at(0)?.title)\n );\n }\n const profile = (await response.json()) as XUserInfo;\n return {\n data: profile,\n claims: {\n sub: profile.data.id,\n name: profile.data.name,\n picture: profile.data.profile_image_url,\n email: profile.data.email,\n email_verified: profile.data.verified || false,\n preferred_username: profile.data.username,\n profile: `https://x.com/${profile.data.username}`,\n website: profile.data.url,\n },\n };\n },\n async refreshAccessToken(params) {\n const response = await refreshAccessToken({\n ...params,\n tokenUri: this.tokenUri,\n authentication: 'basic',\n });\n if (!response.ok) {\n const { error, error_description } = (await response.json()) as XErrorResponse;\n throw new OAuth2Error(response.status, error, error_description);\n }\n return (await response.json()) as XToken;\n },\n async revokeToken(params) {\n invariant(this.tokenRevokeUri, 'tokenRevokeUri is required');\n return revokeToken({\n ...params,\n tokenRevokeUri: this.tokenRevokeUri,\n authentication: 'basic',\n });\n },\n };\n}\n\nexport const x = createXProvider();\n\ntype UserField =\n | 'affiliation'\n | 'connection_status'\n | 'created_at'\n | 'description'\n | 'entities'\n | 'id'\n | 'is_identity_verified'\n | 'location'\n | 'most_recent_tweet_id'\n | 'name'\n | 'parody'\n | 'pinned_tweet_id'\n | 'profile_banner_url'\n | 'profile_image_url'\n | 'protected'\n | 'public_metrics'\n | 'receives_your_dm'\n | 'subscription'\n | 'subscription_type'\n | 'url'\n | 'username'\n | 'verified'\n | 'verified_followers_count'\n | 'verified_type'\n | 'withheld';\n\nexport interface XUser {\n id: string;\n name: string;\n email?: string;\n username: string;\n location?: string;\n entities?: {\n url: { urls: UrlEntity[] };\n description: {\n hashtags: HashtagEntity[];\n cashtags: HashtagEntity[];\n mentions: MentionEntity[];\n };\n };\n verified?: boolean;\n description?: string;\n url?: string;\n profile_image_url?: string;\n protected?: boolean;\n pinned_tweet_id?: string;\n created_at?: string;\n}\n\nexport interface XUserInfo {\n data: XUser;\n includes?: { tweets?: { id: string; text: string }[]; users?: XUser[] };\n}\n\n// prettier-ignore\ntype UrlEntity = { start: number; end: number; url: string; display_url: string; expanded_url: string; }\ntype HashtagEntity = { start: number; end: number; tag: string };\ntype MentionEntity = { start: number; end: string; username: string };\n\nexport interface XToken extends OAuth2Token {\n token_type: string;\n expires_in: number;\n access_token: string;\n scope: string;\n refresh_token: string;\n}\n\ntype XErrorResponse = { error: string; error_description: string };\ntype XAPIErrorResponse = {\n errors: { title: string; type: string; detail?: string; status?: number }[];\n};\n"],"mappings":";AAAA,OAAO,eAAe;AAEtB,SAAS,mBAAmB;AAC5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAMP,IAAM,oBAAoB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,gBAAgB,SAA8B;AAC5D,SAAO;AAAA,IACL,kBAAkB;AAAA,IAClB,UAAU;AAAA,IACV,gBAAgB;AAAA;AAAA,IAEhB,aAAa;AAAA,IACb,cAAc,CAAC,cAAc,cAAc,gBAAgB;AAAA,IAC3D,uBAAuB,QAAQ;AAC7B,UAAI,CAAC,OAAO,KAAM,OAAM,IAAI,MAAM,wBAAwB;AAC1D,aAAO,uBAAuB;AAAA,QAC5B,GAAG;AAAA,QACH,OAAO,OAAO,SAAS,KAAK;AAAA,QAC5B,kBAAkB,KAAK;AAAA,MACzB,CAAC;AAAA,IACH;AAAA,IACA,MAAM,0BAA0B,QAAQ;AACtC,UAAI,CAAC,OAAO,KAAM,OAAM,IAAI,MAAM,wBAAwB;AAC1D,YAAM,WAAW,MAAM,0BAA0B;AAAA,QAC/C,GAAG;AAAA,QACH,UAAU,KAAK;AAAA,QACf,gBAAgB;AAAA,MAClB,CAAC;AACD,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,EAAE,OAAO,kBAAkB,IAAK,MAAM,SAAS,KAAK;AAC1D,cAAM,IAAI,YAAY,SAAS,QAAQ,OAAO,iBAAiB;AAAA,MACjE;AACA,aAAQ,MAAM,SAAS,KAAK;AAAA,IAC9B;AAAA,IACA,MAAM,YAAY,EAAE,aAAa,GAAG;AAClC,gBAAU,cAAc,0BAA0B;AAClD,gBAAU,KAAK,aAAa,yBAAyB;AAErD,YAAM,aAAa,SAAS,cAAc;AAC1C,YAAM,UAAU,EAAE,QAAQ,oBAAoB,eAAe,UAAU,YAAY,GAAG;AAEtF,YAAM,MAAM,IAAI,IAAI,KAAK,WAAW;AACpC,iBAAW,QAAQ,CAAC,UAAU,IAAI,aAAa,OAAO,eAAe,KAAK,CAAC;AAE3E,YAAM,WAAW,MAAM,MAAM,KAAK,aAAa,EAAE,QAAQ,CAAC;AAC1D,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,EAAE,OAAO,IAAK,MAAM,SAAS,KAAK;AACxC,cAAM,IAAI;AAAA,UACR,SAAS;AAAA,UACT;AAAA,UACA,iCAAiC,OAAO,GAAG,CAAC,GAAG,UAAU,OAAO,GAAG,CAAC,GAAG;AAAA,QACzE;AAAA,MACF;AACA,YAAM,UAAW,MAAM,SAAS,KAAK;AACrC,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ;AAAA,UACN,KAAK,QAAQ,KAAK;AAAA,UAClB,MAAM,QAAQ,KAAK;AAAA,UACnB,SAAS,QAAQ,KAAK;AAAA,UACtB,OAAO,QAAQ,KAAK;AAAA,UACpB,gBAAgB,QAAQ,KAAK,YAAY;AAAA,UACzC,oBAAoB,QAAQ,KAAK;AAAA,UACjC,SAAS,iBAAiB,QAAQ,KAAK,QAAQ;AAAA,UAC/C,SAAS,QAAQ,KAAK;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAAA,IACA,MAAM,mBAAmB,QAAQ;AAC/B,YAAM,WAAW,MAAM,mBAAmB;AAAA,QACxC,GAAG;AAAA,QACH,UAAU,KAAK;AAAA,QACf,gBAAgB;AAAA,MAClB,CAAC;AACD,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,EAAE,OAAO,kBAAkB,IAAK,MAAM,SAAS,KAAK;AAC1D,cAAM,IAAI,YAAY,SAAS,QAAQ,OAAO,iBAAiB;AAAA,MACjE;AACA,aAAQ,MAAM,SAAS,KAAK;AAAA,IAC9B;AAAA,IACA,MAAM,YAAY,QAAQ;AACxB,gBAAU,KAAK,gBAAgB,4BAA4B;AAC3D,aAAO,YAAY;AAAA,QACjB,GAAG;AAAA,QACH,gBAAgB,KAAK;AAAA,QACrB,gBAAgB;AAAA,MAClB,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEO,IAAM,IAAI,gBAAgB;","names":[]}
@@ -3,6 +3,10 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
6
10
  var __copyProps = (to, from, except, desc) => {
7
11
  if (from && typeof from === "object" || typeof from === "function") {
8
12
  for (let key of __getOwnPropNames(from))
@@ -15,5 +19,21 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
15
19
 
16
20
  // src/oauth2/types.ts
17
21
  var types_exports = {};
22
+ __export(types_exports, {
23
+ OidcScopes: () => OidcScopes
24
+ });
18
25
  module.exports = __toCommonJS(types_exports);
26
+ var OidcScopes = /* @__PURE__ */ ((OidcScopes2) => {
27
+ OidcScopes2["openid"] = "openid";
28
+ OidcScopes2["profile"] = "profile";
29
+ OidcScopes2["email"] = "email";
30
+ OidcScopes2["phone"] = "phone";
31
+ OidcScopes2["address"] = "address";
32
+ OidcScopes2["offline_access"] = "offline_access";
33
+ return OidcScopes2;
34
+ })(OidcScopes || {});
35
+ // Annotate the CommonJS export names for ESM import in node:
36
+ 0 && (module.exports = {
37
+ OidcScopes
38
+ });
19
39
  //# sourceMappingURL=types.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/oauth2/types.ts"],"sourcesContent":["export interface OAuth2AuthorizationRequest {\n state: string;\n codeVerifier: string;\n registrationId: string;\n authorizationRequestUri: string;\n}\n\ninterface CreateAuthorizationUriParams {\n state: string;\n clientId: string;\n redirectUri: string;\n scope: string[] | undefined;\n codeVerifier?: string;\n}\n\nexport interface CodeExchangeParams {\n code: string;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n codeVerifier?: string;\n}\n\nexport interface RefreshTokenParams {\n clientId: string;\n clientSecret: string;\n refreshToken: string;\n}\n\nexport interface RevokeTokenParams {\n token: string;\n clientId: string;\n clientSecret: string;\n}\n\nexport interface OAuth2Token {\n access_token?: string;\n token_type?: 'Bearer' | 'bearer' | string;\n expires_in?: number;\n refresh_token?: string;\n id_token?: string;\n scope?: string;\n}\n\n// https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims\nexport interface StandardClaims {\n sub: string;\n name?: string;\n given_name?: string;\n family_name?: string;\n middle_name?: string;\n nickname?: string;\n preferred_username?: string;\n profile?: string;\n picture?: string;\n website?: string;\n email?: string;\n email_verified?: boolean;\n gender?: 'female' | 'male' | string;\n birthdate?: string; // ISO 8601-1 [ISO8601‑1] YYYY-MM-DD format.\n zoneinfo?: string; // IANA Time Zone Database [IANA.time‑zones]\n locale?: string; // BCP47 [RFC5646] language tag.\n phone_number?: string; // E.164\n phone_number_verified?: boolean;\n address?: {\n formatted: string;\n street_address: string;\n locality: string;\n region: string;\n postal_code: string;\n country: string;\n }; // [RFC8259] JSON object\n updated_at?: number;\n}\n\nexport interface UserInfo<T extends Record<string, any> = Record<string, any>> {\n claims: StandardClaims;\n data: T;\n}\n\nexport interface Provider<T extends Record<string, any> = Record<string, any>> {\n /** Authorization URI for the provider. */\n authorizationUri: string;\n\n /** Token URI for the provider. */\n tokenUri: string;\n\n tokenRevokeUri?: string;\n\n /** User info URI for the provider. */\n userInfoUri?: string;\n\n /** User info authentication method for the provider. */\n userInfoAuthenticationMethod?: string;\n\n /**\n * Name of the attribute that will be used to extract the username from the call to 'userInfoUri'.\n * */\n userNameAttribute?: string;\n\n /** JWK set URI for the provider */\n jwkSetUri?: string;\n\n /**\n * URI that can either be an OpenID Connect discovery endpoint or an OAuth 2.0 Authorization\n * Server Metadata endpoint defined by RFC 8414.\n * */\n issuerUri?: string;\n\n /** Default scopes for the provider. */\n defaultScope: string[];\n\n /** step 1: generate authorization uri and redirect user to it */\n createAuthorizationUri: (params: CreateAuthorizationUriParams) => URL;\n\n /** step 2: exchange code for token */\n exchangeAuthorizationCode: (params: CodeExchangeParams) => Promise<OAuth2Token>;\n\n /** step 3: get user info */\n getUserInfo: (token: OAuth2Token) => Promise<UserInfo<T>>;\n\n /** others: refresh access token */\n refreshAccessToken?: (params: RefreshTokenParams) => Promise<OAuth2Token>;\n\n /** others: revoke token */\n revokeToken?: (params: RevokeTokenParams) => Promise<void>;\n}\n\nexport interface Registration {\n /**\n * Reference to the OAuth 2.0 provider to use. May reference an element from the 'provider'\n * property or used one of the commonly used providers (google, github, facebook, okta).\n * */\n provider?: string;\n\n /** Client ID for the registration. */\n clientId: string;\n\n /** Client secret of the registration. */\n clientSecret: string;\n\n /** Client authentication method. May be left blank when using a pre-defined provider. */\n clientAuthenticationMethod?: string;\n\n /** Authorization grant type. May be left blank when using a pre-defined provider. */\n authorizationGrantType?:\n | 'authorization_code' // default\n | 'client_credentials'\n | 'device_code'\n | 'jwt_bearer'\n // Deprecated. The latest OAuth 2.0 Security Best Current Practice disallows the use of the\n // Resource Owner Password Credentials grant.\n | 'password'\n | 'refresh_token'\n | 'token_exchange';\n\n /** Redirect URI. May be left blank when using a pre-defined provider. */\n redirectUri?: string;\n\n /** Authorization scopes. When left blank the provider's default scopes, if any, will be used. */\n scope?: string[];\n\n /** Client name. May be left blank when using a pre-defined provider. */\n clientName?: string;\n}\n\nexport interface OAuth2ClientConfig {\n baseUri: string;\n errorUri: string;\n provider: { [name: string]: Provider | undefined };\n registration: { [name: string]: Registration | undefined };\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../src/oauth2/types.ts"],"sourcesContent":["// reference: https://datatracker.ietf.org/doc/html/rfc7636\nexport interface PkceParameters {\n code_verifier: string;\n code_challenge: string;\n code_challenge_method: 'S256' | 'plain';\n}\n\nexport interface OAuth2AuthorizationRequest {\n state: string;\n registrationId: string;\n authorizationRequestUri: string;\n additionalParameters: PkceParameters;\n}\n\ninterface CreateAuthorizationUriParams {\n state: string;\n clientId: string;\n redirectUri: string;\n scope: string[] | undefined;\n pkce?: Omit<PkceParameters, 'code_verifier'>;\n}\n\nexport interface ExchangeCodeParams {\n code: string;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n pkce?: Omit<PkceParameters, 'code_challenge' | 'code_challenge_method'>;\n}\n\nexport interface RefreshTokenParams {\n clientId: string;\n clientSecret: string;\n refreshToken: string;\n}\n\nexport interface RevokeTokenParams {\n token: string;\n clientId: string;\n clientSecret: string;\n}\n\nexport interface LoginOAuth2NativeParams {\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n pkce?: PkceParameters;\n credentials: NativeCredentials;\n}\n\n// reference: https://datatracker.ietf.org/doc/html/rfc6749#section-5.1\nexport interface OAuth2Token {\n /**\n * REQUIRED.\n * The access token issued by the authorization server.\n */\n access_token: string;\n\n /**\n * REQUIRED.\n * The type of the token issued as described in Section 7.1. Value is case insensitive.\n */\n token_type: 'Bearer' | 'bearer' | 'mac' | (string & {});\n\n /**\n * RECOMMENDED.\n * The lifetime in seconds of the access token. For example, the value \"3600\" denotes that the\n * access token will expire in one hour from the time the response was generated. If omitted, the\n * authorization server SHOULD provide the expiration time via other means or document the default\n * value.\n */\n expires_in?: number;\n\n /**\n * OPTIONAL.\n * The refresh token, which can be used to obtain new access tokens using the same authorization\n * grant as described in Section 6.\n */\n refresh_token?: string;\n\n /**\n * OPTIONAL.\n * If identical to the scope requested by the client; otherwise, REQUIRED. The scope of the\n * access token as described by Section 3.3.\n */\n scope?: string;\n\n id_token?: string;\n}\n\nexport interface OidcToken extends OAuth2Token {\n id_token: string;\n}\n\nexport type NativeCredentials = {\n state: string;\n code?: string;\n client_id?: string;\n redirect_uri?: string;\n id_token?: string;\n access_token?: string;\n};\n\nexport enum OidcScopes {\n openid = 'openid',\n profile = 'profile',\n email = 'email',\n phone = 'phone',\n address = 'address',\n offline_access = 'offline_access',\n}\n\n// https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims\nexport interface StandardClaims {\n sub: string;\n name?: string;\n given_name?: string;\n family_name?: string;\n middle_name?: string;\n nickname?: string;\n preferred_username?: string;\n profile?: string;\n picture?: string;\n website?: string;\n email?: string;\n email_verified?: boolean;\n gender?: 'female' | 'male' | string;\n birthdate?: string; // ISO 8601-1 [ISO8601‑1] YYYY-MM-DD format.\n zoneinfo?: string; // IANA Time Zone Database [IANA.time‑zones]\n locale?: string; // BCP47 [RFC5646] language tag.\n phone_number?: string; // E.164\n phone_number_verified?: boolean;\n address?: {\n formatted: string;\n street_address: string;\n locality: string;\n region: string;\n postal_code: string;\n country: string;\n }; // [RFC8259] JSON object\n updated_at?: number;\n}\n\nexport interface UserInfo<T = unknown> {\n claims: StandardClaims;\n data: T;\n}\n\nexport interface Provider {\n /** Authorization URI for the provider. */\n authorizationUri: string;\n\n /** Token URI for the provider. */\n tokenUri: string;\n\n tokenRevokeUri?: string;\n\n /** User info URI for the provider. */\n userInfoUri?: string;\n\n /** User info authentication method for the provider. */\n userInfoAuthenticationMethod?: string;\n\n /**\n * Name of the attribute that will be used to extract the username from the call to 'userInfoUri'.\n * */\n userNameAttribute?: string;\n\n /** JWK set URI for the provider */\n jwkSetUri?: string;\n\n /**\n * URI that can either be an OpenID Connect discovery endpoint or an OAuth 2.0 Authorization\n * Server Metadata endpoint defined by RFC 8414.\n * */\n issuerUri?: string;\n\n /** Default scopes for the provider. */\n defaultScope: string[];\n\n /** step 1: generate authorization uri and redirect user to it */\n createAuthorizationUri: (params: CreateAuthorizationUriParams) => URL;\n\n /** step 2: exchange code for token */\n exchangeAuthorizationCode: (params: ExchangeCodeParams) => Promise<OAuth2Token>;\n\n /** step 3: get user info */\n getUserInfo: (token: OAuth2Token) => Promise<UserInfo>;\n\n /** others: refresh access token */\n refreshAccessToken?: (params: RefreshTokenParams) => Promise<OAuth2Token>;\n\n /** others: revoke token */\n revokeToken?: (params: RevokeTokenParams) => Promise<void>;\n\n loginOAuth2Native?: (\n params: LoginOAuth2NativeParams\n ) => Promise<{ token: OAuth2Token; userInfo: UserInfo }>;\n}\n\nexport interface Registration {\n /**\n * Reference to the OAuth 2.0 provider to use. May reference an element from the 'provider'\n * property or used one of the commonly used providers (google, github, facebook, okta).\n * */\n provider?: string;\n\n /** Client ID for the registration. */\n clientId: string;\n\n /** Client secret of the registration. */\n clientSecret: string;\n\n /** Client authentication method. May be left blank when using a pre-defined provider. */\n clientAuthenticationMethod?: string;\n\n /** Authorization grant type. May be left blank when using a pre-defined provider. */\n authorizationGrantType?:\n | 'authorization_code' // default\n | 'client_credentials'\n | 'device_code'\n | 'jwt_bearer'\n // Deprecated. The latest OAuth 2.0 Security Best Current Practice disallows the use of the\n // Resource Owner Password Credentials grant.\n | 'password'\n | 'refresh_token'\n | 'token_exchange';\n\n /** Redirect URI. May be left blank when using a pre-defined provider. */\n redirectUri?: string;\n\n /** Authorization scopes. When left blank the provider's default scopes, if any, will be used. */\n scope?: string[];\n\n /** Client name. May be left blank when using a pre-defined provider. */\n clientName?: string;\n}\n\nexport interface OAuth2ClientConfig {\n baseUri: string;\n errorUri: string;\n successUri: string;\n provider: { [name: string]: Provider | undefined };\n registration: { [name: string]: Registration | undefined };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAuGO,IAAK,aAAL,kBAAKA,gBAAL;AACL,EAAAA,YAAA,YAAS;AACT,EAAAA,YAAA,aAAU;AACV,EAAAA,YAAA,WAAQ;AACR,EAAAA,YAAA,WAAQ;AACR,EAAAA,YAAA,aAAU;AACV,EAAAA,YAAA,oBAAiB;AANP,SAAAA;AAAA,GAAA;","names":["OidcScopes"]}
@@ -1,22 +1,27 @@
1
+ interface PkceParameters {
2
+ code_verifier: string;
3
+ code_challenge: string;
4
+ code_challenge_method: 'S256' | 'plain';
5
+ }
1
6
  interface OAuth2AuthorizationRequest {
2
7
  state: string;
3
- codeVerifier: string;
4
8
  registrationId: string;
5
9
  authorizationRequestUri: string;
10
+ additionalParameters: PkceParameters;
6
11
  }
7
12
  interface CreateAuthorizationUriParams {
8
13
  state: string;
9
14
  clientId: string;
10
15
  redirectUri: string;
11
16
  scope: string[] | undefined;
12
- codeVerifier?: string;
17
+ pkce?: Omit<PkceParameters, 'code_verifier'>;
13
18
  }
14
- interface CodeExchangeParams {
19
+ interface ExchangeCodeParams {
15
20
  code: string;
16
21
  clientId: string;
17
22
  clientSecret: string;
18
23
  redirectUri: string;
19
- codeVerifier?: string;
24
+ pkce?: Omit<PkceParameters, 'code_challenge' | 'code_challenge_method'>;
20
25
  }
21
26
  interface RefreshTokenParams {
22
27
  clientId: string;
@@ -28,13 +33,64 @@ interface RevokeTokenParams {
28
33
  clientId: string;
29
34
  clientSecret: string;
30
35
  }
36
+ interface LoginOAuth2NativeParams {
37
+ clientId: string;
38
+ clientSecret: string;
39
+ redirectUri: string;
40
+ pkce?: PkceParameters;
41
+ credentials: NativeCredentials;
42
+ }
31
43
  interface OAuth2Token {
32
- access_token?: string;
33
- token_type?: 'Bearer' | 'bearer' | string;
44
+ /**
45
+ * REQUIRED.
46
+ * The access token issued by the authorization server.
47
+ */
48
+ access_token: string;
49
+ /**
50
+ * REQUIRED.
51
+ * The type of the token issued as described in Section 7.1. Value is case insensitive.
52
+ */
53
+ token_type: 'Bearer' | 'bearer' | 'mac' | (string & {});
54
+ /**
55
+ * RECOMMENDED.
56
+ * The lifetime in seconds of the access token. For example, the value "3600" denotes that the
57
+ * access token will expire in one hour from the time the response was generated. If omitted, the
58
+ * authorization server SHOULD provide the expiration time via other means or document the default
59
+ * value.
60
+ */
34
61
  expires_in?: number;
62
+ /**
63
+ * OPTIONAL.
64
+ * The refresh token, which can be used to obtain new access tokens using the same authorization
65
+ * grant as described in Section 6.
66
+ */
35
67
  refresh_token?: string;
36
- id_token?: string;
68
+ /**
69
+ * OPTIONAL.
70
+ * If identical to the scope requested by the client; otherwise, REQUIRED. The scope of the
71
+ * access token as described by Section 3.3.
72
+ */
37
73
  scope?: string;
74
+ id_token?: string;
75
+ }
76
+ interface OidcToken extends OAuth2Token {
77
+ id_token: string;
78
+ }
79
+ type NativeCredentials = {
80
+ state: string;
81
+ code?: string;
82
+ client_id?: string;
83
+ redirect_uri?: string;
84
+ id_token?: string;
85
+ access_token?: string;
86
+ };
87
+ declare enum OidcScopes {
88
+ openid = "openid",
89
+ profile = "profile",
90
+ email = "email",
91
+ phone = "phone",
92
+ address = "address",
93
+ offline_access = "offline_access"
38
94
  }
39
95
  interface StandardClaims {
40
96
  sub: string;
@@ -65,11 +121,11 @@ interface StandardClaims {
65
121
  };
66
122
  updated_at?: number;
67
123
  }
68
- interface UserInfo<T extends Record<string, any> = Record<string, any>> {
124
+ interface UserInfo<T = unknown> {
69
125
  claims: StandardClaims;
70
126
  data: T;
71
127
  }
72
- interface Provider<T extends Record<string, any> = Record<string, any>> {
128
+ interface Provider {
73
129
  /** Authorization URI for the provider. */
74
130
  authorizationUri: string;
75
131
  /** Token URI for the provider. */
@@ -95,13 +151,17 @@ interface Provider<T extends Record<string, any> = Record<string, any>> {
95
151
  /** step 1: generate authorization uri and redirect user to it */
96
152
  createAuthorizationUri: (params: CreateAuthorizationUriParams) => URL;
97
153
  /** step 2: exchange code for token */
98
- exchangeAuthorizationCode: (params: CodeExchangeParams) => Promise<OAuth2Token>;
154
+ exchangeAuthorizationCode: (params: ExchangeCodeParams) => Promise<OAuth2Token>;
99
155
  /** step 3: get user info */
100
- getUserInfo: (token: OAuth2Token) => Promise<UserInfo<T>>;
156
+ getUserInfo: (token: OAuth2Token) => Promise<UserInfo>;
101
157
  /** others: refresh access token */
102
158
  refreshAccessToken?: (params: RefreshTokenParams) => Promise<OAuth2Token>;
103
159
  /** others: revoke token */
104
160
  revokeToken?: (params: RevokeTokenParams) => Promise<void>;
161
+ loginOAuth2Native?: (params: LoginOAuth2NativeParams) => Promise<{
162
+ token: OAuth2Token;
163
+ userInfo: UserInfo;
164
+ }>;
105
165
  }
106
166
  interface Registration {
107
167
  /**
@@ -127,6 +187,7 @@ interface Registration {
127
187
  interface OAuth2ClientConfig {
128
188
  baseUri: string;
129
189
  errorUri: string;
190
+ successUri: string;
130
191
  provider: {
131
192
  [name: string]: Provider | undefined;
132
193
  };
@@ -135,4 +196,4 @@ interface OAuth2ClientConfig {
135
196
  };
136
197
  }
137
198
 
138
- export type { CodeExchangeParams, OAuth2AuthorizationRequest, OAuth2ClientConfig, OAuth2Token, Provider, RefreshTokenParams, Registration, RevokeTokenParams, StandardClaims, UserInfo };
199
+ export { type ExchangeCodeParams, type LoginOAuth2NativeParams, type NativeCredentials, type OAuth2AuthorizationRequest, type OAuth2ClientConfig, type OAuth2Token, OidcScopes, type OidcToken, type PkceParameters, type Provider, type RefreshTokenParams, type Registration, type RevokeTokenParams, type StandardClaims, type UserInfo };
@@ -1,22 +1,27 @@
1
+ interface PkceParameters {
2
+ code_verifier: string;
3
+ code_challenge: string;
4
+ code_challenge_method: 'S256' | 'plain';
5
+ }
1
6
  interface OAuth2AuthorizationRequest {
2
7
  state: string;
3
- codeVerifier: string;
4
8
  registrationId: string;
5
9
  authorizationRequestUri: string;
10
+ additionalParameters: PkceParameters;
6
11
  }
7
12
  interface CreateAuthorizationUriParams {
8
13
  state: string;
9
14
  clientId: string;
10
15
  redirectUri: string;
11
16
  scope: string[] | undefined;
12
- codeVerifier?: string;
17
+ pkce?: Omit<PkceParameters, 'code_verifier'>;
13
18
  }
14
- interface CodeExchangeParams {
19
+ interface ExchangeCodeParams {
15
20
  code: string;
16
21
  clientId: string;
17
22
  clientSecret: string;
18
23
  redirectUri: string;
19
- codeVerifier?: string;
24
+ pkce?: Omit<PkceParameters, 'code_challenge' | 'code_challenge_method'>;
20
25
  }
21
26
  interface RefreshTokenParams {
22
27
  clientId: string;
@@ -28,13 +33,64 @@ interface RevokeTokenParams {
28
33
  clientId: string;
29
34
  clientSecret: string;
30
35
  }
36
+ interface LoginOAuth2NativeParams {
37
+ clientId: string;
38
+ clientSecret: string;
39
+ redirectUri: string;
40
+ pkce?: PkceParameters;
41
+ credentials: NativeCredentials;
42
+ }
31
43
  interface OAuth2Token {
32
- access_token?: string;
33
- token_type?: 'Bearer' | 'bearer' | string;
44
+ /**
45
+ * REQUIRED.
46
+ * The access token issued by the authorization server.
47
+ */
48
+ access_token: string;
49
+ /**
50
+ * REQUIRED.
51
+ * The type of the token issued as described in Section 7.1. Value is case insensitive.
52
+ */
53
+ token_type: 'Bearer' | 'bearer' | 'mac' | (string & {});
54
+ /**
55
+ * RECOMMENDED.
56
+ * The lifetime in seconds of the access token. For example, the value "3600" denotes that the
57
+ * access token will expire in one hour from the time the response was generated. If omitted, the
58
+ * authorization server SHOULD provide the expiration time via other means or document the default
59
+ * value.
60
+ */
34
61
  expires_in?: number;
62
+ /**
63
+ * OPTIONAL.
64
+ * The refresh token, which can be used to obtain new access tokens using the same authorization
65
+ * grant as described in Section 6.
66
+ */
35
67
  refresh_token?: string;
36
- id_token?: string;
68
+ /**
69
+ * OPTIONAL.
70
+ * If identical to the scope requested by the client; otherwise, REQUIRED. The scope of the
71
+ * access token as described by Section 3.3.
72
+ */
37
73
  scope?: string;
74
+ id_token?: string;
75
+ }
76
+ interface OidcToken extends OAuth2Token {
77
+ id_token: string;
78
+ }
79
+ type NativeCredentials = {
80
+ state: string;
81
+ code?: string;
82
+ client_id?: string;
83
+ redirect_uri?: string;
84
+ id_token?: string;
85
+ access_token?: string;
86
+ };
87
+ declare enum OidcScopes {
88
+ openid = "openid",
89
+ profile = "profile",
90
+ email = "email",
91
+ phone = "phone",
92
+ address = "address",
93
+ offline_access = "offline_access"
38
94
  }
39
95
  interface StandardClaims {
40
96
  sub: string;
@@ -65,11 +121,11 @@ interface StandardClaims {
65
121
  };
66
122
  updated_at?: number;
67
123
  }
68
- interface UserInfo<T extends Record<string, any> = Record<string, any>> {
124
+ interface UserInfo<T = unknown> {
69
125
  claims: StandardClaims;
70
126
  data: T;
71
127
  }
72
- interface Provider<T extends Record<string, any> = Record<string, any>> {
128
+ interface Provider {
73
129
  /** Authorization URI for the provider. */
74
130
  authorizationUri: string;
75
131
  /** Token URI for the provider. */
@@ -95,13 +151,17 @@ interface Provider<T extends Record<string, any> = Record<string, any>> {
95
151
  /** step 1: generate authorization uri and redirect user to it */
96
152
  createAuthorizationUri: (params: CreateAuthorizationUriParams) => URL;
97
153
  /** step 2: exchange code for token */
98
- exchangeAuthorizationCode: (params: CodeExchangeParams) => Promise<OAuth2Token>;
154
+ exchangeAuthorizationCode: (params: ExchangeCodeParams) => Promise<OAuth2Token>;
99
155
  /** step 3: get user info */
100
- getUserInfo: (token: OAuth2Token) => Promise<UserInfo<T>>;
156
+ getUserInfo: (token: OAuth2Token) => Promise<UserInfo>;
101
157
  /** others: refresh access token */
102
158
  refreshAccessToken?: (params: RefreshTokenParams) => Promise<OAuth2Token>;
103
159
  /** others: revoke token */
104
160
  revokeToken?: (params: RevokeTokenParams) => Promise<void>;
161
+ loginOAuth2Native?: (params: LoginOAuth2NativeParams) => Promise<{
162
+ token: OAuth2Token;
163
+ userInfo: UserInfo;
164
+ }>;
105
165
  }
106
166
  interface Registration {
107
167
  /**
@@ -127,6 +187,7 @@ interface Registration {
127
187
  interface OAuth2ClientConfig {
128
188
  baseUri: string;
129
189
  errorUri: string;
190
+ successUri: string;
130
191
  provider: {
131
192
  [name: string]: Provider | undefined;
132
193
  };
@@ -135,4 +196,4 @@ interface OAuth2ClientConfig {
135
196
  };
136
197
  }
137
198
 
138
- export type { CodeExchangeParams, OAuth2AuthorizationRequest, OAuth2ClientConfig, OAuth2Token, Provider, RefreshTokenParams, Registration, RevokeTokenParams, StandardClaims, UserInfo };
199
+ export { type ExchangeCodeParams, type LoginOAuth2NativeParams, type NativeCredentials, type OAuth2AuthorizationRequest, type OAuth2ClientConfig, type OAuth2Token, OidcScopes, type OidcToken, type PkceParameters, type Provider, type RefreshTokenParams, type Registration, type RevokeTokenParams, type StandardClaims, type UserInfo };
@@ -1 +1,14 @@
1
+ // src/oauth2/types.ts
2
+ var OidcScopes = /* @__PURE__ */ ((OidcScopes2) => {
3
+ OidcScopes2["openid"] = "openid";
4
+ OidcScopes2["profile"] = "profile";
5
+ OidcScopes2["email"] = "email";
6
+ OidcScopes2["phone"] = "phone";
7
+ OidcScopes2["address"] = "address";
8
+ OidcScopes2["offline_access"] = "offline_access";
9
+ return OidcScopes2;
10
+ })(OidcScopes || {});
11
+ export {
12
+ OidcScopes
13
+ };
1
14
  //# sourceMappingURL=types.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"sources":["../../src/oauth2/types.ts"],"sourcesContent":["// reference: https://datatracker.ietf.org/doc/html/rfc7636\nexport interface PkceParameters {\n code_verifier: string;\n code_challenge: string;\n code_challenge_method: 'S256' | 'plain';\n}\n\nexport interface OAuth2AuthorizationRequest {\n state: string;\n registrationId: string;\n authorizationRequestUri: string;\n additionalParameters: PkceParameters;\n}\n\ninterface CreateAuthorizationUriParams {\n state: string;\n clientId: string;\n redirectUri: string;\n scope: string[] | undefined;\n pkce?: Omit<PkceParameters, 'code_verifier'>;\n}\n\nexport interface ExchangeCodeParams {\n code: string;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n pkce?: Omit<PkceParameters, 'code_challenge' | 'code_challenge_method'>;\n}\n\nexport interface RefreshTokenParams {\n clientId: string;\n clientSecret: string;\n refreshToken: string;\n}\n\nexport interface RevokeTokenParams {\n token: string;\n clientId: string;\n clientSecret: string;\n}\n\nexport interface LoginOAuth2NativeParams {\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n pkce?: PkceParameters;\n credentials: NativeCredentials;\n}\n\n// reference: https://datatracker.ietf.org/doc/html/rfc6749#section-5.1\nexport interface OAuth2Token {\n /**\n * REQUIRED.\n * The access token issued by the authorization server.\n */\n access_token: string;\n\n /**\n * REQUIRED.\n * The type of the token issued as described in Section 7.1. Value is case insensitive.\n */\n token_type: 'Bearer' | 'bearer' | 'mac' | (string & {});\n\n /**\n * RECOMMENDED.\n * The lifetime in seconds of the access token. For example, the value \"3600\" denotes that the\n * access token will expire in one hour from the time the response was generated. If omitted, the\n * authorization server SHOULD provide the expiration time via other means or document the default\n * value.\n */\n expires_in?: number;\n\n /**\n * OPTIONAL.\n * The refresh token, which can be used to obtain new access tokens using the same authorization\n * grant as described in Section 6.\n */\n refresh_token?: string;\n\n /**\n * OPTIONAL.\n * If identical to the scope requested by the client; otherwise, REQUIRED. The scope of the\n * access token as described by Section 3.3.\n */\n scope?: string;\n\n id_token?: string;\n}\n\nexport interface OidcToken extends OAuth2Token {\n id_token: string;\n}\n\nexport type NativeCredentials = {\n state: string;\n code?: string;\n client_id?: string;\n redirect_uri?: string;\n id_token?: string;\n access_token?: string;\n};\n\nexport enum OidcScopes {\n openid = 'openid',\n profile = 'profile',\n email = 'email',\n phone = 'phone',\n address = 'address',\n offline_access = 'offline_access',\n}\n\n// https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims\nexport interface StandardClaims {\n sub: string;\n name?: string;\n given_name?: string;\n family_name?: string;\n middle_name?: string;\n nickname?: string;\n preferred_username?: string;\n profile?: string;\n picture?: string;\n website?: string;\n email?: string;\n email_verified?: boolean;\n gender?: 'female' | 'male' | string;\n birthdate?: string; // ISO 8601-1 [ISO8601‑1] YYYY-MM-DD format.\n zoneinfo?: string; // IANA Time Zone Database [IANA.time‑zones]\n locale?: string; // BCP47 [RFC5646] language tag.\n phone_number?: string; // E.164\n phone_number_verified?: boolean;\n address?: {\n formatted: string;\n street_address: string;\n locality: string;\n region: string;\n postal_code: string;\n country: string;\n }; // [RFC8259] JSON object\n updated_at?: number;\n}\n\nexport interface UserInfo<T = unknown> {\n claims: StandardClaims;\n data: T;\n}\n\nexport interface Provider {\n /** Authorization URI for the provider. */\n authorizationUri: string;\n\n /** Token URI for the provider. */\n tokenUri: string;\n\n tokenRevokeUri?: string;\n\n /** User info URI for the provider. */\n userInfoUri?: string;\n\n /** User info authentication method for the provider. */\n userInfoAuthenticationMethod?: string;\n\n /**\n * Name of the attribute that will be used to extract the username from the call to 'userInfoUri'.\n * */\n userNameAttribute?: string;\n\n /** JWK set URI for the provider */\n jwkSetUri?: string;\n\n /**\n * URI that can either be an OpenID Connect discovery endpoint or an OAuth 2.0 Authorization\n * Server Metadata endpoint defined by RFC 8414.\n * */\n issuerUri?: string;\n\n /** Default scopes for the provider. */\n defaultScope: string[];\n\n /** step 1: generate authorization uri and redirect user to it */\n createAuthorizationUri: (params: CreateAuthorizationUriParams) => URL;\n\n /** step 2: exchange code for token */\n exchangeAuthorizationCode: (params: ExchangeCodeParams) => Promise<OAuth2Token>;\n\n /** step 3: get user info */\n getUserInfo: (token: OAuth2Token) => Promise<UserInfo>;\n\n /** others: refresh access token */\n refreshAccessToken?: (params: RefreshTokenParams) => Promise<OAuth2Token>;\n\n /** others: revoke token */\n revokeToken?: (params: RevokeTokenParams) => Promise<void>;\n\n loginOAuth2Native?: (\n params: LoginOAuth2NativeParams\n ) => Promise<{ token: OAuth2Token; userInfo: UserInfo }>;\n}\n\nexport interface Registration {\n /**\n * Reference to the OAuth 2.0 provider to use. May reference an element from the 'provider'\n * property or used one of the commonly used providers (google, github, facebook, okta).\n * */\n provider?: string;\n\n /** Client ID for the registration. */\n clientId: string;\n\n /** Client secret of the registration. */\n clientSecret: string;\n\n /** Client authentication method. May be left blank when using a pre-defined provider. */\n clientAuthenticationMethod?: string;\n\n /** Authorization grant type. May be left blank when using a pre-defined provider. */\n authorizationGrantType?:\n | 'authorization_code' // default\n | 'client_credentials'\n | 'device_code'\n | 'jwt_bearer'\n // Deprecated. The latest OAuth 2.0 Security Best Current Practice disallows the use of the\n // Resource Owner Password Credentials grant.\n | 'password'\n | 'refresh_token'\n | 'token_exchange';\n\n /** Redirect URI. May be left blank when using a pre-defined provider. */\n redirectUri?: string;\n\n /** Authorization scopes. When left blank the provider's default scopes, if any, will be used. */\n scope?: string[];\n\n /** Client name. May be left blank when using a pre-defined provider. */\n clientName?: string;\n}\n\nexport interface OAuth2ClientConfig {\n baseUri: string;\n errorUri: string;\n successUri: string;\n provider: { [name: string]: Provider | undefined };\n registration: { [name: string]: Registration | undefined };\n}\n"],"mappings":";AAuGO,IAAK,aAAL,kBAAKA,gBAAL;AACL,EAAAA,YAAA,YAAS;AACT,EAAAA,YAAA,aAAU;AACV,EAAAA,YAAA,WAAQ;AACR,EAAAA,YAAA,WAAQ;AACR,EAAAA,YAAA,aAAU;AACV,EAAAA,YAAA,oBAAiB;AANP,SAAAA;AAAA,GAAA;","names":["OidcScopes"]}
@@ -22,20 +22,20 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  mod
23
23
  ));
24
24
 
25
- // src/session/__test__/redis-session.test.ts
25
+ // src/session/__test__/redis.test.ts
26
26
  var import_ioredis = __toESM(require("ioredis"), 1);
27
- var import_redis_session = require("../redis-session.cjs");
27
+ var import_redis = require("../redis.cjs");
28
28
  var redis = new import_ioredis.default("redis://default:123456@localhost:6379");
29
- var repository = new import_redis_session.RedisIndexedSessionRepository(redis, "myapp:session");
29
+ var repository = new import_redis.RedisSessionRepository(redis, "myapp:session");
30
30
  describe("redis session crud", () => {
31
31
  const principalName = "user_123456";
32
32
  test("should create a session", async () => {
33
33
  const session = repository.createSession();
34
34
  const sessionId = session.getId();
35
- session.setAttribute(import_redis_session.PRINCIPAL_NAME_INDEX_NAME, principalName);
35
+ session.setAttribute(import_redis.PRINCIPAL_NAME_INDEX_NAME, principalName);
36
36
  await repository.save(session);
37
37
  const foundSession = await repository.findById(sessionId);
38
- expect(foundSession?.getAttribute(import_redis_session.PRINCIPAL_NAME_INDEX_NAME)).toBe(principalName);
38
+ expect(foundSession?.getAttribute(import_redis.PRINCIPAL_NAME_INDEX_NAME)).toBe(principalName);
39
39
  });
40
40
  test("should find a session by principal name", async () => {
41
41
  const sessions = await repository.findByPrincipalName(principalName);
@@ -68,7 +68,7 @@ describe("redis session attributes", () => {
68
68
  test("should change session id", async () => {
69
69
  const session = repository.createSession();
70
70
  session.setAttribute("test_key", "test_value");
71
- session.setAttribute(import_redis_session.PRINCIPAL_NAME_INDEX_NAME, "user_123");
71
+ session.setAttribute(import_redis.PRINCIPAL_NAME_INDEX_NAME, "user_123");
72
72
  const oldSessionId = session.getId();
73
73
  await repository.save(session);
74
74
  const oldSession = await repository.findById(oldSessionId);
@@ -91,4 +91,4 @@ describe("redis session config", () => {
91
91
  expect(session.getMaxInactiveInterval()).toBe(maxInactiveInterval);
92
92
  });
93
93
  });
94
- //# sourceMappingURL=redis-session.test.cjs.map
94
+ //# sourceMappingURL=redis.test.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/session/__test__/redis.test.ts"],"sourcesContent":["import Redis from 'ioredis';\nimport { PRINCIPAL_NAME_INDEX_NAME, RedisSessionRepository } from '../redis';\n\n// docker run -d -p 6379:6379 --name my-redis -e REDIS_PASSWORD=123456 redis\nconst redis = new Redis('redis://default:123456@localhost:6379');\nconst repository = new RedisSessionRepository(redis, 'myapp:session');\n\ndescribe('redis session crud', () => {\n const principalName = 'user_123456';\n\n test('should create a session', async () => {\n const session = repository.createSession();\n const sessionId = session.getId();\n session.setAttribute(PRINCIPAL_NAME_INDEX_NAME, principalName);\n await repository.save(session);\n const foundSession = await repository.findById(sessionId);\n expect(foundSession?.getAttribute(PRINCIPAL_NAME_INDEX_NAME)).toBe(principalName);\n });\n\n test('should find a session by principal name', async () => {\n const sessions = await repository.findByPrincipalName(principalName);\n expect(sessions.size).toBeGreaterThan(0);\n });\n\n test('should delete a session by id', async () => {\n const sessions = await repository.findByPrincipalName(principalName);\n for (const session of sessions.values()) {\n const sessionId = session.getId();\n await repository.deleteById(sessionId);\n const foundSession = await repository.findById(sessionId);\n expect(foundSession).toBeNull();\n }\n });\n});\n\ndescribe('redis session attributes', () => {\n test('should set and get attributes', async () => {\n const session = repository.createSession();\n session.setAttribute('test_key', 'test_value');\n const sessionId = session.getId();\n await repository.save(session);\n\n const foundSession = await repository.findById(sessionId);\n expect(foundSession).not.toBeNull();\n expect(foundSession?.getAttribute('test_key')).toBe('test_value');\n\n foundSession?.removeAttribute('test_key');\n await repository.save(foundSession!);\n\n const foundSession2 = await repository.findById(sessionId);\n expect(foundSession2?.getAttribute('test_key')).toBeNull();\n });\n\n test('should change session id', async () => {\n const session = repository.createSession();\n session.setAttribute('test_key', 'test_value');\n session.setAttribute(PRINCIPAL_NAME_INDEX_NAME, 'user_123');\n const oldSessionId = session.getId();\n await repository.save(session);\n\n const oldSession = await repository.findById(oldSessionId);\n expect(oldSession).not.toBeNull();\n if (!oldSession) throw new Error('Not found session id');\n\n const newSessionId = oldSession.changeSessionId();\n await repository.save(oldSession);\n\n const foundSession1 = await repository.findById(oldSessionId);\n expect(foundSession1).toBeNull();\n\n const foundSession2 = await repository.findById(newSessionId);\n expect(foundSession2).not.toBeNull();\n });\n});\n\ndescribe('redis session config', () => {\n const maxInactiveInterval = 24 * 60 * 60;\n repository.setDefaultMaxInactiveInterval(maxInactiveInterval);\n\n test('should set default max inactive interval', () => {\n const session = repository.createSession();\n expect(session.isExpired()).toBe(false);\n expect(session.getMaxInactiveInterval()).toBe(maxInactiveInterval);\n });\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qBAAkB;AAClB,mBAAkE;AAGlE,IAAM,QAAQ,IAAI,eAAAA,QAAM,uCAAuC;AAC/D,IAAM,aAAa,IAAI,oCAAuB,OAAO,eAAe;AAEpE,SAAS,sBAAsB,MAAM;AACnC,QAAM,gBAAgB;AAEtB,OAAK,2BAA2B,YAAY;AAC1C,UAAM,UAAU,WAAW,cAAc;AACzC,UAAM,YAAY,QAAQ,MAAM;AAChC,YAAQ,aAAa,wCAA2B,aAAa;AAC7D,UAAM,WAAW,KAAK,OAAO;AAC7B,UAAM,eAAe,MAAM,WAAW,SAAS,SAAS;AACxD,WAAO,cAAc,aAAa,sCAAyB,CAAC,EAAE,KAAK,aAAa;AAAA,EAClF,CAAC;AAED,OAAK,2CAA2C,YAAY;AAC1D,UAAM,WAAW,MAAM,WAAW,oBAAoB,aAAa;AACnE,WAAO,SAAS,IAAI,EAAE,gBAAgB,CAAC;AAAA,EACzC,CAAC;AAED,OAAK,iCAAiC,YAAY;AAChD,UAAM,WAAW,MAAM,WAAW,oBAAoB,aAAa;AACnE,eAAW,WAAW,SAAS,OAAO,GAAG;AACvC,YAAM,YAAY,QAAQ,MAAM;AAChC,YAAM,WAAW,WAAW,SAAS;AACrC,YAAM,eAAe,MAAM,WAAW,SAAS,SAAS;AACxD,aAAO,YAAY,EAAE,SAAS;AAAA,IAChC;AAAA,EACF,CAAC;AACH,CAAC;AAED,SAAS,4BAA4B,MAAM;AACzC,OAAK,iCAAiC,YAAY;AAChD,UAAM,UAAU,WAAW,cAAc;AACzC,YAAQ,aAAa,YAAY,YAAY;AAC7C,UAAM,YAAY,QAAQ,MAAM;AAChC,UAAM,WAAW,KAAK,OAAO;AAE7B,UAAM,eAAe,MAAM,WAAW,SAAS,SAAS;AACxD,WAAO,YAAY,EAAE,IAAI,SAAS;AAClC,WAAO,cAAc,aAAa,UAAU,CAAC,EAAE,KAAK,YAAY;AAEhE,kBAAc,gBAAgB,UAAU;AACxC,UAAM,WAAW,KAAK,YAAa;AAEnC,UAAM,gBAAgB,MAAM,WAAW,SAAS,SAAS;AACzD,WAAO,eAAe,aAAa,UAAU,CAAC,EAAE,SAAS;AAAA,EAC3D,CAAC;AAED,OAAK,4BAA4B,YAAY;AAC3C,UAAM,UAAU,WAAW,cAAc;AACzC,YAAQ,aAAa,YAAY,YAAY;AAC7C,YAAQ,aAAa,wCAA2B,UAAU;AAC1D,UAAM,eAAe,QAAQ,MAAM;AACnC,UAAM,WAAW,KAAK,OAAO;AAE7B,UAAM,aAAa,MAAM,WAAW,SAAS,YAAY;AACzD,WAAO,UAAU,EAAE,IAAI,SAAS;AAChC,QAAI,CAAC,WAAY,OAAM,IAAI,MAAM,sBAAsB;AAEvD,UAAM,eAAe,WAAW,gBAAgB;AAChD,UAAM,WAAW,KAAK,UAAU;AAEhC,UAAM,gBAAgB,MAAM,WAAW,SAAS,YAAY;AAC5D,WAAO,aAAa,EAAE,SAAS;AAE/B,UAAM,gBAAgB,MAAM,WAAW,SAAS,YAAY;AAC5D,WAAO,aAAa,EAAE,IAAI,SAAS;AAAA,EACrC,CAAC;AACH,CAAC;AAED,SAAS,wBAAwB,MAAM;AACrC,QAAM,sBAAsB,KAAK,KAAK;AACtC,aAAW,8BAA8B,mBAAmB;AAE5D,OAAK,4CAA4C,MAAM;AACrD,UAAM,UAAU,WAAW,cAAc;AACzC,WAAO,QAAQ,UAAU,CAAC,EAAE,KAAK,KAAK;AACtC,WAAO,QAAQ,uBAAuB,CAAC,EAAE,KAAK,mBAAmB;AAAA,EACnE,CAAC;AACH,CAAC;","names":["Redis"]}
@@ -1,8 +1,8 @@
1
- // src/session/__test__/redis-session.test.ts
1
+ // src/session/__test__/redis.test.ts
2
2
  import Redis from "ioredis";
3
- import { PRINCIPAL_NAME_INDEX_NAME, RedisIndexedSessionRepository } from "../redis-session.mjs";
3
+ import { PRINCIPAL_NAME_INDEX_NAME, RedisSessionRepository } from "../redis.mjs";
4
4
  var redis = new Redis("redis://default:123456@localhost:6379");
5
- var repository = new RedisIndexedSessionRepository(redis, "myapp:session");
5
+ var repository = new RedisSessionRepository(redis, "myapp:session");
6
6
  describe("redis session crud", () => {
7
7
  const principalName = "user_123456";
8
8
  test("should create a session", async () => {
@@ -67,4 +67,4 @@ describe("redis session config", () => {
67
67
  expect(session.getMaxInactiveInterval()).toBe(maxInactiveInterval);
68
68
  });
69
69
  });
70
- //# sourceMappingURL=redis-session.test.mjs.map
70
+ //# sourceMappingURL=redis.test.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/session/__test__/redis.test.ts"],"sourcesContent":["import Redis from 'ioredis';\nimport { PRINCIPAL_NAME_INDEX_NAME, RedisSessionRepository } from '../redis';\n\n// docker run -d -p 6379:6379 --name my-redis -e REDIS_PASSWORD=123456 redis\nconst redis = new Redis('redis://default:123456@localhost:6379');\nconst repository = new RedisSessionRepository(redis, 'myapp:session');\n\ndescribe('redis session crud', () => {\n const principalName = 'user_123456';\n\n test('should create a session', async () => {\n const session = repository.createSession();\n const sessionId = session.getId();\n session.setAttribute(PRINCIPAL_NAME_INDEX_NAME, principalName);\n await repository.save(session);\n const foundSession = await repository.findById(sessionId);\n expect(foundSession?.getAttribute(PRINCIPAL_NAME_INDEX_NAME)).toBe(principalName);\n });\n\n test('should find a session by principal name', async () => {\n const sessions = await repository.findByPrincipalName(principalName);\n expect(sessions.size).toBeGreaterThan(0);\n });\n\n test('should delete a session by id', async () => {\n const sessions = await repository.findByPrincipalName(principalName);\n for (const session of sessions.values()) {\n const sessionId = session.getId();\n await repository.deleteById(sessionId);\n const foundSession = await repository.findById(sessionId);\n expect(foundSession).toBeNull();\n }\n });\n});\n\ndescribe('redis session attributes', () => {\n test('should set and get attributes', async () => {\n const session = repository.createSession();\n session.setAttribute('test_key', 'test_value');\n const sessionId = session.getId();\n await repository.save(session);\n\n const foundSession = await repository.findById(sessionId);\n expect(foundSession).not.toBeNull();\n expect(foundSession?.getAttribute('test_key')).toBe('test_value');\n\n foundSession?.removeAttribute('test_key');\n await repository.save(foundSession!);\n\n const foundSession2 = await repository.findById(sessionId);\n expect(foundSession2?.getAttribute('test_key')).toBeNull();\n });\n\n test('should change session id', async () => {\n const session = repository.createSession();\n session.setAttribute('test_key', 'test_value');\n session.setAttribute(PRINCIPAL_NAME_INDEX_NAME, 'user_123');\n const oldSessionId = session.getId();\n await repository.save(session);\n\n const oldSession = await repository.findById(oldSessionId);\n expect(oldSession).not.toBeNull();\n if (!oldSession) throw new Error('Not found session id');\n\n const newSessionId = oldSession.changeSessionId();\n await repository.save(oldSession);\n\n const foundSession1 = await repository.findById(oldSessionId);\n expect(foundSession1).toBeNull();\n\n const foundSession2 = await repository.findById(newSessionId);\n expect(foundSession2).not.toBeNull();\n });\n});\n\ndescribe('redis session config', () => {\n const maxInactiveInterval = 24 * 60 * 60;\n repository.setDefaultMaxInactiveInterval(maxInactiveInterval);\n\n test('should set default max inactive interval', () => {\n const session = repository.createSession();\n expect(session.isExpired()).toBe(false);\n expect(session.getMaxInactiveInterval()).toBe(maxInactiveInterval);\n });\n});\n"],"mappings":";AAAA,OAAO,WAAW;AAClB,SAAS,2BAA2B,8BAA8B;AAGlE,IAAM,QAAQ,IAAI,MAAM,uCAAuC;AAC/D,IAAM,aAAa,IAAI,uBAAuB,OAAO,eAAe;AAEpE,SAAS,sBAAsB,MAAM;AACnC,QAAM,gBAAgB;AAEtB,OAAK,2BAA2B,YAAY;AAC1C,UAAM,UAAU,WAAW,cAAc;AACzC,UAAM,YAAY,QAAQ,MAAM;AAChC,YAAQ,aAAa,2BAA2B,aAAa;AAC7D,UAAM,WAAW,KAAK,OAAO;AAC7B,UAAM,eAAe,MAAM,WAAW,SAAS,SAAS;AACxD,WAAO,cAAc,aAAa,yBAAyB,CAAC,EAAE,KAAK,aAAa;AAAA,EAClF,CAAC;AAED,OAAK,2CAA2C,YAAY;AAC1D,UAAM,WAAW,MAAM,WAAW,oBAAoB,aAAa;AACnE,WAAO,SAAS,IAAI,EAAE,gBAAgB,CAAC;AAAA,EACzC,CAAC;AAED,OAAK,iCAAiC,YAAY;AAChD,UAAM,WAAW,MAAM,WAAW,oBAAoB,aAAa;AACnE,eAAW,WAAW,SAAS,OAAO,GAAG;AACvC,YAAM,YAAY,QAAQ,MAAM;AAChC,YAAM,WAAW,WAAW,SAAS;AACrC,YAAM,eAAe,MAAM,WAAW,SAAS,SAAS;AACxD,aAAO,YAAY,EAAE,SAAS;AAAA,IAChC;AAAA,EACF,CAAC;AACH,CAAC;AAED,SAAS,4BAA4B,MAAM;AACzC,OAAK,iCAAiC,YAAY;AAChD,UAAM,UAAU,WAAW,cAAc;AACzC,YAAQ,aAAa,YAAY,YAAY;AAC7C,UAAM,YAAY,QAAQ,MAAM;AAChC,UAAM,WAAW,KAAK,OAAO;AAE7B,UAAM,eAAe,MAAM,WAAW,SAAS,SAAS;AACxD,WAAO,YAAY,EAAE,IAAI,SAAS;AAClC,WAAO,cAAc,aAAa,UAAU,CAAC,EAAE,KAAK,YAAY;AAEhE,kBAAc,gBAAgB,UAAU;AACxC,UAAM,WAAW,KAAK,YAAa;AAEnC,UAAM,gBAAgB,MAAM,WAAW,SAAS,SAAS;AACzD,WAAO,eAAe,aAAa,UAAU,CAAC,EAAE,SAAS;AAAA,EAC3D,CAAC;AAED,OAAK,4BAA4B,YAAY;AAC3C,UAAM,UAAU,WAAW,cAAc;AACzC,YAAQ,aAAa,YAAY,YAAY;AAC7C,YAAQ,aAAa,2BAA2B,UAAU;AAC1D,UAAM,eAAe,QAAQ,MAAM;AACnC,UAAM,WAAW,KAAK,OAAO;AAE7B,UAAM,aAAa,MAAM,WAAW,SAAS,YAAY;AACzD,WAAO,UAAU,EAAE,IAAI,SAAS;AAChC,QAAI,CAAC,WAAY,OAAM,IAAI,MAAM,sBAAsB;AAEvD,UAAM,eAAe,WAAW,gBAAgB;AAChD,UAAM,WAAW,KAAK,UAAU;AAEhC,UAAM,gBAAgB,MAAM,WAAW,SAAS,YAAY;AAC5D,WAAO,aAAa,EAAE,SAAS;AAE/B,UAAM,gBAAgB,MAAM,WAAW,SAAS,YAAY;AAC5D,WAAO,aAAa,EAAE,IAAI,SAAS;AAAA,EACrC,CAAC;AACH,CAAC;AAED,SAAS,wBAAwB,MAAM;AACrC,QAAM,sBAAsB,KAAK,KAAK;AACtC,aAAW,8BAA8B,mBAAmB;AAE5D,OAAK,4CAA4C,MAAM;AACrD,UAAM,UAAU,WAAW,cAAc;AACzC,WAAO,QAAQ,UAAU,CAAC,EAAE,KAAK,KAAK;AACtC,WAAO,QAAQ,uBAAuB,CAAC,EAAE,KAAK,mBAAmB;AAAA,EACnE,CAAC;AACH,CAAC;","names":[]}
@@ -20,11 +20,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/session/index.ts
21
21
  var session_exports = {};
22
22
  __export(session_exports, {
23
- PRINCIPAL_NAME_INDEX_NAME: () => import_redis_session.PRINCIPAL_NAME_INDEX_NAME,
24
- RedisIndexedSessionRepository: () => import_redis_session.RedisIndexedSessionRepository
23
+ PRINCIPAL_NAME_INDEX_NAME: () => import_redis.PRINCIPAL_NAME_INDEX_NAME,
24
+ RedisIndexedSessionRepository: () => import_redis.RedisSessionRepository
25
25
  });
26
26
  module.exports = __toCommonJS(session_exports);
27
- var import_redis_session = require("./redis-session.cjs");
27
+ var import_redis = require("./redis.cjs");
28
28
  // Annotate the CommonJS export names for ESM import in node:
29
29
  0 && (module.exports = {
30
30
  PRINCIPAL_NAME_INDEX_NAME,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/session/index.ts"],"sourcesContent":["export type { Namespace, SessionRepository } from './types';\nexport { RedisIndexedSessionRepository, PRINCIPAL_NAME_INDEX_NAME } from './redis-session';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,2BAAyE;","names":[]}
1
+ {"version":3,"sources":["../../src/session/index.ts"],"sourcesContent":["export type { Namespace, SessionRepository } from './types';\nexport {\n RedisSessionRepository as RedisIndexedSessionRepository,\n PRINCIPAL_NAME_INDEX_NAME,\n} from './redis';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAGO;","names":[]}
@@ -1,4 +1,4 @@
1
1
  export { Namespace, SessionRepository } from './types.cjs';
2
- export { PRINCIPAL_NAME_INDEX_NAME, RedisIndexedSessionRepository } from './redis-session.cjs';
2
+ export { PRINCIPAL_NAME_INDEX_NAME, RedisSessionRepository as RedisIndexedSessionRepository } from './redis.cjs';
3
3
  import '../core/index.cjs';
4
4
  import 'ioredis';
@@ -1,4 +1,4 @@
1
1
  export { Namespace, SessionRepository } from './types.js';
2
- export { PRINCIPAL_NAME_INDEX_NAME, RedisIndexedSessionRepository } from './redis-session.js';
2
+ export { PRINCIPAL_NAME_INDEX_NAME, RedisSessionRepository as RedisIndexedSessionRepository } from './redis.js';
3
3
  import '../core/index.js';
4
4
  import 'ioredis';
@@ -1,7 +1,10 @@
1
1
  // src/session/index.ts
2
- import { RedisIndexedSessionRepository, PRINCIPAL_NAME_INDEX_NAME } from "./redis-session.mjs";
2
+ import {
3
+ RedisSessionRepository,
4
+ PRINCIPAL_NAME_INDEX_NAME
5
+ } from "./redis.mjs";
3
6
  export {
4
7
  PRINCIPAL_NAME_INDEX_NAME,
5
- RedisIndexedSessionRepository
8
+ RedisSessionRepository as RedisIndexedSessionRepository
6
9
  };
7
10
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/session/index.ts"],"sourcesContent":["export type { Namespace, SessionRepository } from './types';\nexport { RedisIndexedSessionRepository, PRINCIPAL_NAME_INDEX_NAME } from './redis-session';\n"],"mappings":";AACA,SAAS,+BAA+B,iCAAiC;","names":[]}
1
+ {"version":3,"sources":["../../src/session/index.ts"],"sourcesContent":["export type { Namespace, SessionRepository } from './types';\nexport {\n RedisSessionRepository as RedisIndexedSessionRepository,\n PRINCIPAL_NAME_INDEX_NAME,\n} from './redis';\n"],"mappings":";AACA;AAAA,EAC4B;AAAA,EAC1B;AAAA,OACK;","names":[]}