@shware/security 2.5.3 → 2.6.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 (225) hide show
  1. package/dist/auth/index.cjs +520 -561
  2. package/dist/auth/index.cjs.map +1 -1
  3. package/dist/auth/index.d.cts +104 -106
  4. package/dist/auth/index.d.cts.map +1 -0
  5. package/dist/auth/index.d.mts +109 -0
  6. package/dist/auth/index.d.mts.map +1 -0
  7. package/dist/auth/index.mjs +513 -536
  8. package/dist/auth/index.mjs.map +1 -1
  9. package/dist/auth/types.cjs +0 -19
  10. package/dist/auth/types.d.cts +44 -44
  11. package/dist/auth/types.d.cts.map +1 -0
  12. package/dist/auth/types.d.mts +50 -0
  13. package/dist/auth/types.d.mts.map +1 -0
  14. package/dist/auth/types.mjs +1 -1
  15. package/dist/core/index.cjs +34 -59
  16. package/dist/core/index.cjs.map +1 -1
  17. package/dist/core/index.d.cts +23 -21
  18. package/dist/core/index.d.cts.map +1 -0
  19. package/dist/core/index.d.mts +34 -0
  20. package/dist/core/index.d.mts.map +1 -0
  21. package/dist/core/index.mjs +32 -33
  22. package/dist/core/index.mjs.map +1 -1
  23. package/dist/email/schema.cjs +13 -38
  24. package/dist/email/schema.cjs.map +1 -1
  25. package/dist/email/schema.d.cts +11 -12
  26. package/dist/email/schema.d.cts.map +1 -0
  27. package/dist/email/schema.d.mts +12 -0
  28. package/dist/email/schema.d.mts.map +1 -0
  29. package/dist/email/schema.mjs +10 -11
  30. package/dist/email/schema.mjs.map +1 -1
  31. package/dist/index.cjs +17 -54
  32. package/dist/index.d.cts +10 -15
  33. package/dist/index.d.mts +10 -0
  34. package/dist/index.mjs +4 -17
  35. package/dist/oauth2/client.cjs +109 -145
  36. package/dist/oauth2/client.cjs.map +1 -1
  37. package/dist/oauth2/client.d.cts +55 -56
  38. package/dist/oauth2/client.d.cts.map +1 -0
  39. package/dist/oauth2/client.d.mts +58 -0
  40. package/dist/oauth2/client.d.mts.map +1 -0
  41. package/dist/oauth2/client.mjs +104 -116
  42. package/dist/oauth2/client.mjs.map +1 -1
  43. package/dist/oauth2/error.cjs +19 -44
  44. package/dist/oauth2/error.cjs.map +1 -1
  45. package/dist/oauth2/error.d.cts +8 -6
  46. package/dist/oauth2/error.d.cts.map +1 -0
  47. package/dist/oauth2/{error.d.ts → error.d.mts} +8 -6
  48. package/dist/oauth2/error.d.mts.map +1 -0
  49. package/dist/oauth2/error.mjs +18 -19
  50. package/dist/oauth2/error.mjs.map +1 -1
  51. package/dist/oauth2/provider/apple.cjs +75 -88
  52. package/dist/oauth2/provider/apple.cjs.map +1 -1
  53. package/dist/oauth2/provider/apple.d.cts +31 -30
  54. package/dist/oauth2/provider/apple.d.cts.map +1 -0
  55. package/dist/oauth2/provider/apple.d.mts +42 -0
  56. package/dist/oauth2/provider/apple.d.mts.map +1 -0
  57. package/dist/oauth2/provider/apple.mjs +71 -60
  58. package/dist/oauth2/provider/apple.mjs.map +1 -1
  59. package/dist/oauth2/provider/common.cjs +86 -109
  60. package/dist/oauth2/provider/common.cjs.map +1 -1
  61. package/dist/oauth2/provider/common.d.cts +19 -18
  62. package/dist/oauth2/provider/common.d.cts.map +1 -0
  63. package/dist/oauth2/provider/common.d.mts +30 -0
  64. package/dist/oauth2/provider/common.d.mts.map +1 -0
  65. package/dist/oauth2/provider/common.mjs +80 -79
  66. package/dist/oauth2/provider/common.mjs.map +1 -1
  67. package/dist/oauth2/provider/facebook.cjs +93 -109
  68. package/dist/oauth2/provider/facebook.cjs.map +1 -1
  69. package/dist/oauth2/provider/facebook.d.cts +29 -28
  70. package/dist/oauth2/provider/facebook.d.cts.map +1 -0
  71. package/dist/oauth2/provider/facebook.d.mts +45 -0
  72. package/dist/oauth2/provider/facebook.d.mts.map +1 -0
  73. package/dist/oauth2/provider/facebook.mjs +89 -81
  74. package/dist/oauth2/provider/facebook.mjs.map +1 -1
  75. package/dist/oauth2/provider/github.cjs +64 -91
  76. package/dist/oauth2/provider/github.cjs.map +1 -1
  77. package/dist/oauth2/provider/github.d.cts +52 -51
  78. package/dist/oauth2/provider/github.d.cts.map +1 -0
  79. package/dist/oauth2/provider/github.d.mts +60 -0
  80. package/dist/oauth2/provider/github.d.mts.map +1 -0
  81. package/dist/oauth2/provider/github.mjs +60 -63
  82. package/dist/oauth2/provider/github.mjs.map +1 -1
  83. package/dist/oauth2/provider/google.cjs +105 -122
  84. package/dist/oauth2/provider/google.cjs.map +1 -1
  85. package/dist/oauth2/provider/google.d.cts +34 -33
  86. package/dist/oauth2/provider/google.d.cts.map +1 -0
  87. package/dist/oauth2/provider/google.d.mts +44 -0
  88. package/dist/oauth2/provider/google.d.mts.map +1 -0
  89. package/dist/oauth2/provider/google.mjs +101 -94
  90. package/dist/oauth2/provider/google.mjs.map +1 -1
  91. package/dist/oauth2/provider/index.cjs +13 -46
  92. package/dist/oauth2/provider/index.d.cts +7 -7
  93. package/dist/oauth2/provider/index.d.mts +7 -0
  94. package/dist/oauth2/provider/index.mjs +1 -10
  95. package/dist/oauth2/provider/wechat.cjs +77 -99
  96. package/dist/oauth2/provider/wechat.cjs.map +1 -1
  97. package/dist/oauth2/provider/wechat.d.cts +28 -27
  98. package/dist/oauth2/provider/wechat.d.cts.map +1 -0
  99. package/dist/oauth2/provider/wechat.d.mts +39 -0
  100. package/dist/oauth2/provider/wechat.d.mts.map +1 -0
  101. package/dist/oauth2/provider/wechat.mjs +74 -72
  102. package/dist/oauth2/provider/wechat.mjs.map +1 -1
  103. package/dist/oauth2/provider/x.cjs +102 -125
  104. package/dist/oauth2/provider/x.cjs.map +1 -1
  105. package/dist/oauth2/provider/x.d.cts +51 -50
  106. package/dist/oauth2/provider/x.d.cts.map +1 -0
  107. package/dist/oauth2/provider/x.d.mts +69 -0
  108. package/dist/oauth2/provider/x.d.mts.map +1 -0
  109. package/dist/oauth2/provider/x.mjs +99 -103
  110. package/dist/oauth2/provider/x.mjs.map +1 -1
  111. package/dist/oauth2/types.cjs +13 -37
  112. package/dist/oauth2/types.cjs.map +1 -1
  113. package/dist/oauth2/types.d.cts +180 -178
  114. package/dist/oauth2/types.d.cts.map +1 -0
  115. package/dist/oauth2/types.d.mts +213 -0
  116. package/dist/oauth2/types.d.mts.map +1 -0
  117. package/dist/oauth2/types.mjs +13 -13
  118. package/dist/oauth2/types.mjs.map +1 -1
  119. package/dist/session/common.cjs +17 -43
  120. package/dist/session/common.cjs.map +1 -1
  121. package/dist/session/common.d.cts +4 -4
  122. package/dist/session/common.d.cts.map +1 -0
  123. package/dist/session/{common.d.ts → common.d.mts} +4 -4
  124. package/dist/session/common.d.mts.map +1 -0
  125. package/dist/session/common.mjs +14 -16
  126. package/dist/session/common.mjs.map +1 -1
  127. package/dist/session/db.cjs +88 -123
  128. package/dist/session/db.cjs.map +1 -1
  129. package/dist/session/db.d.cts +36 -36
  130. package/dist/session/db.d.cts.map +1 -0
  131. package/dist/session/db.d.mts +44 -0
  132. package/dist/session/db.d.mts.map +1 -0
  133. package/dist/session/db.mjs +84 -95
  134. package/dist/session/db.mjs.map +1 -1
  135. package/dist/session/map-session.cjs +71 -103
  136. package/dist/session/map-session.cjs.map +1 -1
  137. package/dist/session/map-session.d.cts +24 -24
  138. package/dist/session/map-session.d.cts.map +1 -0
  139. package/dist/session/map-session.d.mts +27 -0
  140. package/dist/session/map-session.d.mts.map +1 -0
  141. package/dist/session/map-session.mjs +70 -78
  142. package/dist/session/map-session.mjs.map +1 -1
  143. package/dist/session/redis.cjs +270 -319
  144. package/dist/session/redis.cjs.map +1 -1
  145. package/dist/session/redis.d.cts +51 -51
  146. package/dist/session/redis.d.cts.map +1 -0
  147. package/dist/session/redis.d.mts +58 -0
  148. package/dist/session/redis.d.mts.map +1 -0
  149. package/dist/session/redis.mjs +266 -291
  150. package/dist/session/redis.mjs.map +1 -1
  151. package/dist/session/types.cjs +0 -19
  152. package/dist/session/types.d.cts +34 -33
  153. package/dist/session/types.d.cts.map +1 -0
  154. package/dist/session/types.d.mts +45 -0
  155. package/dist/session/types.d.mts.map +1 -0
  156. package/dist/session/types.mjs +1 -1
  157. package/dist/utils/http.cjs +31 -55
  158. package/dist/utils/http.cjs.map +1 -1
  159. package/dist/utils/http.d.cts +7 -10
  160. package/dist/utils/http.d.cts.map +1 -0
  161. package/dist/utils/{http.d.ts → http.d.mts} +7 -10
  162. package/dist/utils/http.d.mts.map +1 -0
  163. package/dist/utils/http.mjs +24 -24
  164. package/dist/utils/http.mjs.map +1 -1
  165. package/dist/utils/oauth2.cjs +6 -30
  166. package/dist/utils/oauth2.cjs.map +1 -1
  167. package/dist/utils/oauth2.d.cts +3 -1
  168. package/dist/utils/oauth2.d.cts.map +1 -0
  169. package/dist/utils/oauth2.d.mts +5 -0
  170. package/dist/utils/oauth2.d.mts.map +1 -0
  171. package/dist/utils/oauth2.mjs +5 -5
  172. package/dist/utils/oauth2.mjs.map +1 -1
  173. package/dist/utils/timing.cjs +49 -70
  174. package/dist/utils/timing.cjs.map +1 -1
  175. package/dist/utils/timing.d.cts +10 -8
  176. package/dist/utils/timing.d.cts.map +1 -0
  177. package/dist/utils/timing.d.mts +15 -0
  178. package/dist/utils/timing.d.mts.map +1 -0
  179. package/dist/utils/timing.mjs +48 -45
  180. package/dist/utils/timing.mjs.map +1 -1
  181. package/dist/utils/valid.cjs +50 -71
  182. package/dist/utils/valid.cjs.map +1 -1
  183. package/dist/utils/valid.d.cts +17 -16
  184. package/dist/utils/valid.d.cts.map +1 -0
  185. package/dist/utils/valid.d.mts +28 -0
  186. package/dist/utils/valid.d.mts.map +1 -0
  187. package/dist/utils/valid.mjs +47 -44
  188. package/dist/utils/valid.mjs.map +1 -1
  189. package/package.json +22 -12
  190. package/dist/auth/index.d.ts +0 -111
  191. package/dist/auth/types.cjs.map +0 -1
  192. package/dist/auth/types.d.ts +0 -50
  193. package/dist/auth/types.mjs.map +0 -1
  194. package/dist/core/index.d.ts +0 -32
  195. package/dist/email/schema.d.ts +0 -13
  196. package/dist/index.cjs.map +0 -1
  197. package/dist/index.d.ts +0 -15
  198. package/dist/index.mjs.map +0 -1
  199. package/dist/oauth2/client.d.ts +0 -59
  200. package/dist/oauth2/provider/apple.d.ts +0 -41
  201. package/dist/oauth2/provider/common.d.ts +0 -29
  202. package/dist/oauth2/provider/facebook.d.ts +0 -44
  203. package/dist/oauth2/provider/github.d.ts +0 -59
  204. package/dist/oauth2/provider/google.d.ts +0 -43
  205. package/dist/oauth2/provider/index.cjs.map +0 -1
  206. package/dist/oauth2/provider/index.d.ts +0 -7
  207. package/dist/oauth2/provider/index.mjs.map +0 -1
  208. package/dist/oauth2/provider/wechat.d.ts +0 -38
  209. package/dist/oauth2/provider/x.d.ts +0 -68
  210. package/dist/oauth2/types.d.ts +0 -211
  211. package/dist/session/__tests__/redis.test.cjs +0 -247
  212. package/dist/session/__tests__/redis.test.cjs.map +0 -1
  213. package/dist/session/__tests__/redis.test.d.cts +0 -2
  214. package/dist/session/__tests__/redis.test.d.ts +0 -2
  215. package/dist/session/__tests__/redis.test.mjs +0 -252
  216. package/dist/session/__tests__/redis.test.mjs.map +0 -1
  217. package/dist/session/db.d.ts +0 -44
  218. package/dist/session/map-session.d.ts +0 -27
  219. package/dist/session/redis.d.ts +0 -58
  220. package/dist/session/types.cjs.map +0 -1
  221. package/dist/session/types.d.ts +0 -44
  222. package/dist/session/types.mjs.map +0 -1
  223. package/dist/utils/oauth2.d.ts +0 -3
  224. package/dist/utils/timing.d.ts +0 -13
  225. package/dist/utils/valid.d.ts +0 -27
@@ -1,7 +1,7 @@
1
- import { Provider, OAuth2Token } from '../types.cjs';
2
-
1
+ import { OAuth2Token, Provider } from "../types.cjs";
2
+ //#region src/oauth2/provider/wechat.d.ts
3
3
  type Options = {
4
- isWechatBrowser: boolean;
4
+ isWechatBrowser: boolean;
5
5
  };
6
6
  /**
7
7
  * reference: https://developers.weixin.qq.com/doc/offiaccount/en/OA_Web_Apps/Wechat_webpage_authorization.html
@@ -9,30 +9,31 @@ type Options = {
9
9
  declare function createWechatProvider(options?: Options): Provider;
10
10
  declare const wechat: Provider;
11
11
  interface WechatUserInfo {
12
- openid: string;
13
- nickname: string;
14
- sex: 0 | 1 | 2;
15
- province: string;
16
- city: string;
17
- country: string;
18
- /**
19
- * User's profile photo. The last numeric value represents the size of a square profile photo
20
- * (The value can be 0, 46, 64, 96, or 132. The value 0 represents a 640*640 square profile
21
- * photo). This parameter is left blank if a user has no profile photo. If the user changes the
22
- * profile photo, the URL of the original profile photo will expire.
23
- * e.g. http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46
24
- */
25
- headimgurl: string;
26
- privilege: string[];
27
- unionid?: string;
12
+ openid: string;
13
+ nickname: string;
14
+ sex: 0 | 1 | 2;
15
+ province: string;
16
+ city: string;
17
+ country: string;
18
+ /**
19
+ * User's profile photo. The last numeric value represents the size of a square profile photo
20
+ * (The value can be 0, 46, 64, 96, or 132. The value 0 represents a 640*640 square profile
21
+ * photo). This parameter is left blank if a user has no profile photo. If the user changes the
22
+ * profile photo, the URL of the original profile photo will expire.
23
+ * e.g. http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46
24
+ */
25
+ headimgurl: string;
26
+ privilege: string[];
27
+ unionid?: string;
28
28
  }
29
29
  interface WechatToken extends OAuth2Token {
30
- access_token: string;
31
- expires_in: number;
32
- refresh_token: string;
33
- openid: string;
34
- scope: string;
35
- unionid?: string;
30
+ access_token: string;
31
+ expires_in: number;
32
+ refresh_token: string;
33
+ openid: string;
34
+ scope: string;
35
+ unionid?: string;
36
36
  }
37
-
38
- export { type Options, type WechatToken, type WechatUserInfo, createWechatProvider, wechat };
37
+ //#endregion
38
+ export { Options, WechatToken, WechatUserInfo, createWechatProvider, wechat };
39
+ //# sourceMappingURL=wechat.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wechat.d.cts","names":[],"sources":["../../../src/oauth2/provider/wechat.ts"],"mappings":";;KAIY;EAAY;;;;;iBAKR,qBAAqB,UAAS,UAAuC;cAuExE,QAAM;UAEF;EACf;EACA;EACA;EACA;EACA;EACA;;;;;;;;EAQA;EACA;EACA;;UAGe,oBAAoB;EACnC;EACA;EACA;EACA;EACA;EACA"}
@@ -0,0 +1,39 @@
1
+ import { OAuth2Token, Provider } from "../types.mjs";
2
+ //#region src/oauth2/provider/wechat.d.ts
3
+ type Options = {
4
+ isWechatBrowser: boolean;
5
+ };
6
+ /**
7
+ * reference: https://developers.weixin.qq.com/doc/offiaccount/en/OA_Web_Apps/Wechat_webpage_authorization.html
8
+ */
9
+ declare function createWechatProvider(options?: Options): Provider;
10
+ declare const wechat: Provider;
11
+ interface WechatUserInfo {
12
+ openid: string;
13
+ nickname: string;
14
+ sex: 0 | 1 | 2;
15
+ province: string;
16
+ city: string;
17
+ country: string;
18
+ /**
19
+ * User's profile photo. The last numeric value represents the size of a square profile photo
20
+ * (The value can be 0, 46, 64, 96, or 132. The value 0 represents a 640*640 square profile
21
+ * photo). This parameter is left blank if a user has no profile photo. If the user changes the
22
+ * profile photo, the URL of the original profile photo will expire.
23
+ * e.g. http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46
24
+ */
25
+ headimgurl: string;
26
+ privilege: string[];
27
+ unionid?: string;
28
+ }
29
+ interface WechatToken extends OAuth2Token {
30
+ access_token: string;
31
+ expires_in: number;
32
+ refresh_token: string;
33
+ openid: string;
34
+ scope: string;
35
+ unionid?: string;
36
+ }
37
+ //#endregion
38
+ export { Options, WechatToken, WechatUserInfo, createWechatProvider, wechat };
39
+ //# sourceMappingURL=wechat.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wechat.d.mts","names":[],"sources":["../../../src/oauth2/provider/wechat.ts"],"mappings":";;KAIY;EAAY;;;;;iBAKR,qBAAqB,UAAS,UAAuC;cAuExE,QAAM;UAEF;EACf;EACA;EACA;EACA;EACA;EACA;;;;;;;;EAQA;EACA;EACA;;UAGe,oBAAoB;EACnC;EACA;EACA;EACA;EACA;EACA"}
@@ -1,76 +1,78 @@
1
- // src/oauth2/provider/wechat.ts
2
- import { invariant } from "@shware/utils";
3
1
  import { OAuth2Error } from "../error.mjs";
2
+ import { invariant } from "@shware/utils";
3
+ //#region src/oauth2/provider/wechat.ts
4
+ /**
5
+ * reference: https://developers.weixin.qq.com/doc/offiaccount/en/OA_Web_Apps/Wechat_webpage_authorization.html
6
+ */
4
7
  function createWechatProvider(options = { isWechatBrowser: false }) {
5
- const { isWechatBrowser } = options;
6
- return {
7
- authorizationUri: isWechatBrowser ? "https://open.weixin.qq.com/connect/oauth2/authorize" : "https://open.weixin.qq.com/connect/qrconnect",
8
- tokenUri: "https://api.weixin.qq.com/sns/oauth2/access_token",
9
- tokenRefreshUri: "https://api.weixin.qq.com/sns/oauth2/refresh_token",
10
- userInfoUri: "https://api.weixin.qq.com/sns/userinfo",
11
- defaultScope: [isWechatBrowser ? "snsapi_userinfo" : "snsapi_login"],
12
- createAuthorizationUri(params) {
13
- const url = new URL(this.authorizationUri);
14
- url.searchParams.set("appid", params.clientId);
15
- url.searchParams.set("scope", (params.scope ?? this.defaultScope).join(","));
16
- url.searchParams.set("redirect_uri", params.redirectUri);
17
- url.searchParams.set("response_type", "code");
18
- url.searchParams.set("state", params.state);
19
- return url;
20
- },
21
- async exchangeAuthorizationCode(params) {
22
- const url = new URL(this.tokenUri);
23
- url.searchParams.set("appid", params.clientId);
24
- url.searchParams.set("secret", params.clientSecret);
25
- url.searchParams.set("code", params.code);
26
- url.searchParams.set("grant_type", "authorization_code");
27
- const response = await fetch(url.href);
28
- if (!response.ok) {
29
- const { errcode, errmsg } = await response.json();
30
- throw new OAuth2Error(response.status, errmsg, `errcode: ${errcode}`);
31
- }
32
- return await response.json();
33
- },
34
- async getUserInfo({ access_token, openid }) {
35
- invariant(this.userInfoUri, "userInfoUri is required");
36
- invariant(openid && typeof openid === "string", "openid is required");
37
- const url = new URL(this.userInfoUri);
38
- url.searchParams.set("access_token", access_token);
39
- url.searchParams.set("openid", openid);
40
- const response = await fetch(url.href);
41
- if (!response.ok) {
42
- const { errcode, errmsg } = await response.json();
43
- throw new OAuth2Error(response.status, errmsg, `errcode: ${errcode}`);
44
- }
45
- const data = await response.json();
46
- return {
47
- data,
48
- claims: {
49
- sub: data.unionid ?? data.openid,
50
- name: data.nickname,
51
- picture: `${data.headimgurl.split("/").slice(0, -1).join("/")}/0`,
52
- gender: data.sex === 1 ? "male" : data.sex === 2 ? "female" : void 0
53
- }
54
- };
55
- },
56
- async refreshAccessToken(params) {
57
- invariant(this.tokenRefreshUri, "tokenRefreshUri is required");
58
- const url = new URL(this.tokenRefreshUri);
59
- url.searchParams.set("appid", params.clientId);
60
- url.searchParams.set("grant_type", "refresh_token");
61
- url.searchParams.set("refresh_token", params.refreshToken);
62
- const response = await fetch(url.href);
63
- if (!response.ok) {
64
- const { errcode, errmsg } = await response.json();
65
- throw new OAuth2Error(response.status, errmsg, `errcode: ${errcode}`);
66
- }
67
- return await response.json();
68
- }
69
- };
8
+ const { isWechatBrowser } = options;
9
+ return {
10
+ authorizationUri: isWechatBrowser ? "https://open.weixin.qq.com/connect/oauth2/authorize" : "https://open.weixin.qq.com/connect/qrconnect",
11
+ tokenUri: "https://api.weixin.qq.com/sns/oauth2/access_token",
12
+ tokenRefreshUri: "https://api.weixin.qq.com/sns/oauth2/refresh_token",
13
+ userInfoUri: "https://api.weixin.qq.com/sns/userinfo",
14
+ defaultScope: [isWechatBrowser ? "snsapi_userinfo" : "snsapi_login"],
15
+ createAuthorizationUri(params) {
16
+ const url = new URL(this.authorizationUri);
17
+ url.searchParams.set("appid", params.clientId);
18
+ url.searchParams.set("scope", (params.scope ?? this.defaultScope).join(","));
19
+ url.searchParams.set("redirect_uri", params.redirectUri);
20
+ url.searchParams.set("response_type", "code");
21
+ url.searchParams.set("state", params.state);
22
+ return url;
23
+ },
24
+ async exchangeAuthorizationCode(params) {
25
+ const url = new URL(this.tokenUri);
26
+ url.searchParams.set("appid", params.clientId);
27
+ url.searchParams.set("secret", params.clientSecret);
28
+ url.searchParams.set("code", params.code);
29
+ url.searchParams.set("grant_type", "authorization_code");
30
+ const response = await fetch(url.href);
31
+ if (!response.ok) {
32
+ const { errcode, errmsg } = await response.json();
33
+ throw new OAuth2Error(response.status, errmsg, `errcode: ${errcode}`);
34
+ }
35
+ return await response.json();
36
+ },
37
+ async getUserInfo({ access_token, openid }) {
38
+ invariant(this.userInfoUri, "userInfoUri is required");
39
+ invariant(openid && typeof openid === "string", "openid is required");
40
+ const url = new URL(this.userInfoUri);
41
+ url.searchParams.set("access_token", access_token);
42
+ url.searchParams.set("openid", openid);
43
+ const response = await fetch(url.href);
44
+ if (!response.ok) {
45
+ const { errcode, errmsg } = await response.json();
46
+ throw new OAuth2Error(response.status, errmsg, `errcode: ${errcode}`);
47
+ }
48
+ const data = await response.json();
49
+ return {
50
+ data,
51
+ claims: {
52
+ sub: data.unionid ?? data.openid,
53
+ name: data.nickname,
54
+ picture: `${data.headimgurl.split("/").slice(0, -1).join("/")}/0`,
55
+ gender: data.sex === 1 ? "male" : data.sex === 2 ? "female" : void 0
56
+ }
57
+ };
58
+ },
59
+ async refreshAccessToken(params) {
60
+ invariant(this.tokenRefreshUri, "tokenRefreshUri is required");
61
+ const url = new URL(this.tokenRefreshUri);
62
+ url.searchParams.set("appid", params.clientId);
63
+ url.searchParams.set("grant_type", "refresh_token");
64
+ url.searchParams.set("refresh_token", params.refreshToken);
65
+ const response = await fetch(url.href);
66
+ if (!response.ok) {
67
+ const { errcode, errmsg } = await response.json();
68
+ throw new OAuth2Error(response.status, errmsg, `errcode: ${errcode}`);
69
+ }
70
+ return await response.json();
71
+ }
72
+ };
70
73
  }
71
- var wechat = createWechatProvider();
72
- export {
73
- createWechatProvider,
74
- wechat
75
- };
74
+ const wechat = createWechatProvider();
75
+ //#endregion
76
+ export { createWechatProvider, wechat };
77
+
76
78
  //# sourceMappingURL=wechat.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/oauth2/provider/wechat.ts"],"sourcesContent":["import { invariant } from '@shware/utils';\nimport { OAuth2Error } from '../error';\nimport type { OAuth2Token, Provider } from '../types';\n\nexport type Options = { isWechatBrowser: boolean };\n\n/**\n * reference: https://developers.weixin.qq.com/doc/offiaccount/en/OA_Web_Apps/Wechat_webpage_authorization.html\n */\nexport function createWechatProvider(options: Options = { isWechatBrowser: false }): Provider {\n const { isWechatBrowser } = options;\n return {\n authorizationUri: isWechatBrowser\n ? 'https://open.weixin.qq.com/connect/oauth2/authorize'\n : 'https://open.weixin.qq.com/connect/qrconnect',\n tokenUri: 'https://api.weixin.qq.com/sns/oauth2/access_token',\n tokenRefreshUri: 'https://api.weixin.qq.com/sns/oauth2/refresh_token',\n userInfoUri: 'https://api.weixin.qq.com/sns/userinfo',\n defaultScope: [isWechatBrowser ? 'snsapi_userinfo' : 'snsapi_login'],\n createAuthorizationUri(params) {\n const url = new URL(this.authorizationUri);\n url.searchParams.set('appid', params.clientId);\n url.searchParams.set('scope', (params.scope ?? this.defaultScope).join(','));\n url.searchParams.set('redirect_uri', params.redirectUri);\n url.searchParams.set('response_type', 'code');\n url.searchParams.set('state', params.state);\n return url;\n },\n async exchangeAuthorizationCode(params) {\n const url = new URL(this.tokenUri);\n url.searchParams.set('appid', params.clientId);\n url.searchParams.set('secret', params.clientSecret);\n url.searchParams.set('code', params.code);\n url.searchParams.set('grant_type', 'authorization_code');\n const response = await fetch(url.href);\n if (!response.ok) {\n const { errcode, errmsg } = (await response.json()) as WechatErrorResponse;\n throw new OAuth2Error(response.status, errmsg, `errcode: ${errcode}`);\n }\n return (await response.json()) as WechatToken;\n },\n async getUserInfo({ access_token, openid }) {\n invariant(this.userInfoUri, 'userInfoUri is required');\n invariant(openid && typeof openid === 'string', 'openid is required');\n const url = new URL(this.userInfoUri);\n url.searchParams.set('access_token', access_token);\n url.searchParams.set('openid', openid);\n const response = await fetch(url.href);\n if (!response.ok) {\n const { errcode, errmsg } = (await response.json()) as WechatErrorResponse;\n throw new OAuth2Error(response.status, errmsg, `errcode: ${errcode}`);\n }\n const data = (await response.json()) as WechatUserInfo;\n\n return {\n data,\n claims: {\n sub: data.unionid ?? data.openid,\n name: data.nickname,\n picture: `${data.headimgurl.split('/').slice(0, -1).join('/')}/0`,\n gender: data.sex === 1 ? 'male' : data.sex === 2 ? 'female' : undefined,\n },\n };\n },\n async refreshAccessToken(params) {\n invariant(this.tokenRefreshUri, 'tokenRefreshUri is required');\n const url = new URL(this.tokenRefreshUri);\n url.searchParams.set('appid', params.clientId);\n url.searchParams.set('grant_type', 'refresh_token');\n url.searchParams.set('refresh_token', params.refreshToken);\n const response = await fetch(url.href);\n if (!response.ok) {\n const { errcode, errmsg } = (await response.json()) as WechatErrorResponse;\n throw new OAuth2Error(response.status, errmsg, `errcode: ${errcode}`);\n }\n return (await response.json()) as WechatToken;\n },\n };\n}\n\nexport const wechat = createWechatProvider();\n\nexport interface WechatUserInfo {\n openid: string;\n nickname: string;\n sex: 0 | 1 | 2; // 0: unknown, 1: male, 2: female\n province: string;\n city: string;\n country: string;\n /**\n * User's profile photo. The last numeric value represents the size of a square profile photo\n * (The value can be 0, 46, 64, 96, or 132. The value 0 represents a 640*640 square profile\n * photo). This parameter is left blank if a user has no profile photo. If the user changes the\n * profile photo, the URL of the original profile photo will expire.\n * e.g. http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46\n */\n headimgurl: string;\n privilege: string[];\n unionid?: string;\n}\n\nexport interface WechatToken extends OAuth2Token {\n access_token: string;\n expires_in: number;\n refresh_token: string;\n openid: string;\n scope: string;\n unionid?: string;\n}\n\ninterface WechatErrorResponse {\n errcode: number;\n errmsg: string;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"file":"wechat.mjs","names":[],"sources":["../../../src/oauth2/provider/wechat.ts"],"sourcesContent":["import { invariant } from '@shware/utils';\nimport { OAuth2Error } from '../error';\nimport type { OAuth2Token, Provider } from '../types';\n\nexport type Options = { isWechatBrowser: boolean };\n\n/**\n * reference: https://developers.weixin.qq.com/doc/offiaccount/en/OA_Web_Apps/Wechat_webpage_authorization.html\n */\nexport function createWechatProvider(options: Options = { isWechatBrowser: false }): Provider {\n const { isWechatBrowser } = options;\n return {\n authorizationUri: isWechatBrowser\n ? 'https://open.weixin.qq.com/connect/oauth2/authorize'\n : 'https://open.weixin.qq.com/connect/qrconnect',\n tokenUri: 'https://api.weixin.qq.com/sns/oauth2/access_token',\n tokenRefreshUri: 'https://api.weixin.qq.com/sns/oauth2/refresh_token',\n userInfoUri: 'https://api.weixin.qq.com/sns/userinfo',\n defaultScope: [isWechatBrowser ? 'snsapi_userinfo' : 'snsapi_login'],\n createAuthorizationUri(params) {\n const url = new URL(this.authorizationUri);\n url.searchParams.set('appid', params.clientId);\n url.searchParams.set('scope', (params.scope ?? this.defaultScope).join(','));\n url.searchParams.set('redirect_uri', params.redirectUri);\n url.searchParams.set('response_type', 'code');\n url.searchParams.set('state', params.state);\n return url;\n },\n async exchangeAuthorizationCode(params) {\n const url = new URL(this.tokenUri);\n url.searchParams.set('appid', params.clientId);\n url.searchParams.set('secret', params.clientSecret);\n url.searchParams.set('code', params.code);\n url.searchParams.set('grant_type', 'authorization_code');\n const response = await fetch(url.href);\n if (!response.ok) {\n const { errcode, errmsg } = (await response.json()) as WechatErrorResponse;\n throw new OAuth2Error(response.status, errmsg, `errcode: ${errcode}`);\n }\n return (await response.json()) as WechatToken;\n },\n async getUserInfo({ access_token, openid }) {\n invariant(this.userInfoUri, 'userInfoUri is required');\n invariant(openid && typeof openid === 'string', 'openid is required');\n const url = new URL(this.userInfoUri);\n url.searchParams.set('access_token', access_token);\n url.searchParams.set('openid', openid);\n const response = await fetch(url.href);\n if (!response.ok) {\n const { errcode, errmsg } = (await response.json()) as WechatErrorResponse;\n throw new OAuth2Error(response.status, errmsg, `errcode: ${errcode}`);\n }\n const data = (await response.json()) as WechatUserInfo;\n\n return {\n data,\n claims: {\n sub: data.unionid ?? data.openid,\n name: data.nickname,\n picture: `${data.headimgurl.split('/').slice(0, -1).join('/')}/0`,\n gender: data.sex === 1 ? 'male' : data.sex === 2 ? 'female' : undefined,\n },\n };\n },\n async refreshAccessToken(params) {\n invariant(this.tokenRefreshUri, 'tokenRefreshUri is required');\n const url = new URL(this.tokenRefreshUri);\n url.searchParams.set('appid', params.clientId);\n url.searchParams.set('grant_type', 'refresh_token');\n url.searchParams.set('refresh_token', params.refreshToken);\n const response = await fetch(url.href);\n if (!response.ok) {\n const { errcode, errmsg } = (await response.json()) as WechatErrorResponse;\n throw new OAuth2Error(response.status, errmsg, `errcode: ${errcode}`);\n }\n return (await response.json()) as WechatToken;\n },\n };\n}\n\nexport const wechat = createWechatProvider();\n\nexport interface WechatUserInfo {\n openid: string;\n nickname: string;\n sex: 0 | 1 | 2; // 0: unknown, 1: male, 2: female\n province: string;\n city: string;\n country: string;\n /**\n * User's profile photo. The last numeric value represents the size of a square profile photo\n * (The value can be 0, 46, 64, 96, or 132. The value 0 represents a 640*640 square profile\n * photo). This parameter is left blank if a user has no profile photo. If the user changes the\n * profile photo, the URL of the original profile photo will expire.\n * e.g. http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46\n */\n headimgurl: string;\n privilege: string[];\n unionid?: string;\n}\n\nexport interface WechatToken extends OAuth2Token {\n access_token: string;\n expires_in: number;\n refresh_token: string;\n openid: string;\n scope: string;\n unionid?: string;\n}\n\ninterface WechatErrorResponse {\n errcode: number;\n errmsg: string;\n}\n"],"mappings":";;;;;;AASA,SAAgB,qBAAqB,UAAmB,EAAE,iBAAiB,MAAM,GAAa;CAC5F,MAAM,EAAE,oBAAoB;CAC5B,OAAO;EACL,kBAAkB,kBACd,wDACA;EACJ,UAAU;EACV,iBAAiB;EACjB,aAAa;EACb,cAAc,CAAC,kBAAkB,oBAAoB,cAAc;EACnE,uBAAuB,QAAQ;GAC7B,MAAM,MAAM,IAAI,IAAI,KAAK,gBAAgB;GACzC,IAAI,aAAa,IAAI,SAAS,OAAO,QAAQ;GAC7C,IAAI,aAAa,IAAI,UAAU,OAAO,SAAS,KAAK,aAAA,CAAc,KAAK,GAAG,CAAC;GAC3E,IAAI,aAAa,IAAI,gBAAgB,OAAO,WAAW;GACvD,IAAI,aAAa,IAAI,iBAAiB,MAAM;GAC5C,IAAI,aAAa,IAAI,SAAS,OAAO,KAAK;GAC1C,OAAO;EACT;EACA,MAAM,0BAA0B,QAAQ;GACtC,MAAM,MAAM,IAAI,IAAI,KAAK,QAAQ;GACjC,IAAI,aAAa,IAAI,SAAS,OAAO,QAAQ;GAC7C,IAAI,aAAa,IAAI,UAAU,OAAO,YAAY;GAClD,IAAI,aAAa,IAAI,QAAQ,OAAO,IAAI;GACxC,IAAI,aAAa,IAAI,cAAc,oBAAoB;GACvD,MAAM,WAAW,MAAM,MAAM,IAAI,IAAI;GACrC,IAAI,CAAC,SAAS,IAAI;IAChB,MAAM,EAAE,SAAS,WAAY,MAAM,SAAS,KAAK;IACjD,MAAM,IAAI,YAAY,SAAS,QAAQ,QAAQ,YAAY,SAAS;GACtE;GACA,OAAQ,MAAM,SAAS,KAAK;EAC9B;EACA,MAAM,YAAY,EAAE,cAAc,UAAU;GAC1C,UAAU,KAAK,aAAa,yBAAyB;GACrD,UAAU,UAAU,OAAO,WAAW,UAAU,oBAAoB;GACpE,MAAM,MAAM,IAAI,IAAI,KAAK,WAAW;GACpC,IAAI,aAAa,IAAI,gBAAgB,YAAY;GACjD,IAAI,aAAa,IAAI,UAAU,MAAM;GACrC,MAAM,WAAW,MAAM,MAAM,IAAI,IAAI;GACrC,IAAI,CAAC,SAAS,IAAI;IAChB,MAAM,EAAE,SAAS,WAAY,MAAM,SAAS,KAAK;IACjD,MAAM,IAAI,YAAY,SAAS,QAAQ,QAAQ,YAAY,SAAS;GACtE;GACA,MAAM,OAAQ,MAAM,SAAS,KAAK;GAElC,OAAO;IACL;IACA,QAAQ;KACN,KAAK,KAAK,WAAW,KAAK;KAC1B,MAAM,KAAK;KACX,SAAS,GAAG,KAAK,WAAW,MAAM,GAAG,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,GAAG,EAAE;KAC9D,QAAQ,KAAK,QAAQ,IAAI,SAAS,KAAK,QAAQ,IAAI,WAAW,KAAA;IAChE;GACF;EACF;EACA,MAAM,mBAAmB,QAAQ;GAC/B,UAAU,KAAK,iBAAiB,6BAA6B;GAC7D,MAAM,MAAM,IAAI,IAAI,KAAK,eAAe;GACxC,IAAI,aAAa,IAAI,SAAS,OAAO,QAAQ;GAC7C,IAAI,aAAa,IAAI,cAAc,eAAe;GAClD,IAAI,aAAa,IAAI,iBAAiB,OAAO,YAAY;GACzD,MAAM,WAAW,MAAM,MAAM,IAAI,IAAI;GACrC,IAAI,CAAC,SAAS,IAAI;IAChB,MAAM,EAAE,SAAS,WAAY,MAAM,SAAS,KAAK;IACjD,MAAM,IAAI,YAAY,SAAS,QAAQ,QAAQ,YAAY,SAAS;GACtE;GACA,OAAQ,MAAM,SAAS,KAAK;EAC9B;CACF;AACF;AAEA,MAAa,SAAS,qBAAqB"}
@@ -1,129 +1,106 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
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
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/oauth2/provider/x.ts
21
- var x_exports = {};
22
- __export(x_exports, {
23
- createXProvider: () => createXProvider,
24
- x: () => x
25
- });
26
- module.exports = __toCommonJS(x_exports);
27
- var import_utils = require("@shware/utils");
28
- var import_error = require("../error.cjs");
29
- var import_common = require("./common.cjs");
30
- var defaultUserFields = [
31
- "id",
32
- "name",
33
- "profile_image_url",
34
- "url",
35
- "username",
36
- "location",
37
- "verified"
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_oauth2_error = require("../error.cjs");
3
+ const require_oauth2_provider_common = require("./common.cjs");
4
+ let _shware_utils = require("@shware/utils");
5
+ //#region src/oauth2/provider/x.ts
6
+ const defaultUserFields = [
7
+ "id",
8
+ "name",
9
+ "profile_image_url",
10
+ "url",
11
+ "username",
12
+ "location",
13
+ "verified"
38
14
  ];
39
15
  function createXProvider(options) {
40
- return {
41
- authorizationUri: "https://x.com/i/oauth2/authorize",
42
- tokenUri: "https://api.x.com/2/oauth2/token",
43
- tokenRefreshUri: "https://api.x.com/2/oauth2/token",
44
- tokenRevokeUri: "https://api.x.com/2/oauth2/revoke",
45
- // https://docs.x.com/x-api/users/user-lookup-me
46
- userInfoUri: "https://api.x.com/2/users/me",
47
- defaultScope: ["users.read", "tweet.read", "offline.access"],
48
- createAuthorizationUri(params) {
49
- if (!params.pkce) throw new Error("pkce is required for x");
50
- return (0, import_common.createAuthorizationUri)({
51
- ...params,
52
- scope: params.scope ?? this.defaultScope,
53
- authorizationUri: this.authorizationUri
54
- });
55
- },
56
- async exchangeAuthorizationCode(params) {
57
- if (!params.pkce) throw new Error("pkce is required for x");
58
- const response = await (0, import_common.exchangeAuthorizationCode)({
59
- ...params,
60
- tokenUri: this.tokenUri,
61
- authentication: "basic"
62
- });
63
- if (!response.ok) {
64
- const { error, error_description } = await response.json();
65
- throw new import_error.OAuth2Error(response.status, error, error_description);
66
- }
67
- return await response.json();
68
- },
69
- async getUserInfo({ access_token }) {
70
- (0, import_utils.invariant)(access_token, "access_token is required");
71
- (0, import_utils.invariant)(this.userInfoUri, "userInfoUri is required");
72
- const userFields = options?.userFields ?? defaultUserFields;
73
- const headers = { Accept: "application/json", Authorization: `Bearer ${access_token}` };
74
- const url = new URL(this.userInfoUri);
75
- userFields.forEach((field) => url.searchParams.append("user.fields", field));
76
- const response = await fetch(this.userInfoUri, { headers });
77
- if (!response.ok) {
78
- const { errors } = await response.json();
79
- throw new import_error.OAuth2Error(
80
- response.status,
81
- "invalid_request",
82
- `Failed to fetch user info: ${errors.at(0)?.detail ?? errors.at(0)?.title}`
83
- );
84
- }
85
- const profile = await response.json();
86
- return {
87
- data: profile,
88
- claims: {
89
- sub: profile.data.id,
90
- name: profile.data.name,
91
- picture: profile.data.profile_image_url,
92
- email: profile.data.email,
93
- email_verified: profile.data.verified || false,
94
- preferred_username: profile.data.username,
95
- profile: `https://x.com/${profile.data.username}`,
96
- website: profile.data.url
97
- }
98
- };
99
- },
100
- async refreshAccessToken(params) {
101
- (0, import_utils.invariant)(this.tokenRefreshUri, "tokenRefreshUri is required");
102
- const response = await (0, import_common.refreshAccessToken)({
103
- ...params,
104
- tokenUri: this.tokenRefreshUri,
105
- authentication: "basic"
106
- });
107
- if (!response.ok) {
108
- const { error, error_description } = await response.json();
109
- throw new import_error.OAuth2Error(response.status, error, error_description);
110
- }
111
- return await response.json();
112
- },
113
- async revokeToken(params) {
114
- (0, import_utils.invariant)(this.tokenRevokeUri, "tokenRevokeUri is required");
115
- return (0, import_common.revokeToken)({
116
- ...params,
117
- tokenRevokeUri: this.tokenRevokeUri,
118
- authentication: "basic"
119
- });
120
- }
121
- };
16
+ return {
17
+ authorizationUri: "https://x.com/i/oauth2/authorize",
18
+ tokenUri: "https://api.x.com/2/oauth2/token",
19
+ tokenRefreshUri: "https://api.x.com/2/oauth2/token",
20
+ tokenRevokeUri: "https://api.x.com/2/oauth2/revoke",
21
+ userInfoUri: "https://api.x.com/2/users/me",
22
+ defaultScope: [
23
+ "users.read",
24
+ "tweet.read",
25
+ "offline.access"
26
+ ],
27
+ createAuthorizationUri(params) {
28
+ if (!params.pkce) throw new Error("pkce is required for x");
29
+ return require_oauth2_provider_common.createAuthorizationUri({
30
+ ...params,
31
+ scope: params.scope ?? this.defaultScope,
32
+ authorizationUri: this.authorizationUri
33
+ });
34
+ },
35
+ async exchangeAuthorizationCode(params) {
36
+ if (!params.pkce) throw new Error("pkce is required for x");
37
+ const response = await require_oauth2_provider_common.exchangeAuthorizationCode({
38
+ ...params,
39
+ tokenUri: this.tokenUri,
40
+ authentication: "basic"
41
+ });
42
+ if (!response.ok) {
43
+ const { error, error_description } = await response.json();
44
+ throw new require_oauth2_error.OAuth2Error(response.status, error, error_description);
45
+ }
46
+ return await response.json();
47
+ },
48
+ async getUserInfo({ access_token }) {
49
+ (0, _shware_utils.invariant)(access_token, "access_token is required");
50
+ (0, _shware_utils.invariant)(this.userInfoUri, "userInfoUri is required");
51
+ const userFields = options?.userFields ?? defaultUserFields;
52
+ const headers = {
53
+ Accept: "application/json",
54
+ Authorization: `Bearer ${access_token}`
55
+ };
56
+ const url = new URL(this.userInfoUri);
57
+ userFields.forEach((field) => url.searchParams.append("user.fields", field));
58
+ const response = await fetch(this.userInfoUri, { headers });
59
+ if (!response.ok) {
60
+ const { errors } = await response.json();
61
+ throw new require_oauth2_error.OAuth2Error(response.status, "invalid_request", `Failed to fetch user info: ${errors.at(0)?.detail ?? errors.at(0)?.title}`);
62
+ }
63
+ const profile = await response.json();
64
+ return {
65
+ data: profile,
66
+ claims: {
67
+ sub: profile.data.id,
68
+ name: profile.data.name,
69
+ picture: profile.data.profile_image_url,
70
+ email: profile.data.email,
71
+ email_verified: profile.data.verified || false,
72
+ preferred_username: profile.data.username,
73
+ profile: `https://x.com/${profile.data.username}`,
74
+ website: profile.data.url
75
+ }
76
+ };
77
+ },
78
+ async refreshAccessToken(params) {
79
+ (0, _shware_utils.invariant)(this.tokenRefreshUri, "tokenRefreshUri is required");
80
+ const response = await require_oauth2_provider_common.refreshAccessToken({
81
+ ...params,
82
+ tokenUri: this.tokenRefreshUri,
83
+ authentication: "basic"
84
+ });
85
+ if (!response.ok) {
86
+ const { error, error_description } = await response.json();
87
+ throw new require_oauth2_error.OAuth2Error(response.status, error, error_description);
88
+ }
89
+ return await response.json();
90
+ },
91
+ async revokeToken(params) {
92
+ (0, _shware_utils.invariant)(this.tokenRevokeUri, "tokenRevokeUri is required");
93
+ return require_oauth2_provider_common.revokeToken({
94
+ ...params,
95
+ tokenRevokeUri: this.tokenRevokeUri,
96
+ authentication: "basic"
97
+ });
98
+ }
99
+ };
122
100
  }
123
- var x = createXProvider();
124
- // Annotate the CommonJS export names for ESM import in node:
125
- 0 && (module.exports = {
126
- createXProvider,
127
- x
128
- });
101
+ const x = createXProvider();
102
+ //#endregion
103
+ exports.createXProvider = createXProvider;
104
+ exports.x = x;
105
+
129
106
  //# sourceMappingURL=x.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/oauth2/provider/x.ts"],"sourcesContent":["import { invariant } from '@shware/utils';\nimport { OAuth2Error } from '../error';\nimport type { OAuth2Token, Provider } from '../types';\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 tokenRefreshUri: '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 invariant(this.tokenRefreshUri, 'tokenRefreshUri is required');\n const response = await refreshAccessToken({\n ...params,\n tokenUri: this.tokenRefreshUri,\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\ntype UrlEntity = {\n start: number;\n end: number;\n url: string;\n display_url: string;\n expanded_url: string;\n};\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":"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","names":[]}
1
+ {"version":3,"file":"x.cjs","names":["createAuthorizationUri","exchangeAuthorizationCode","OAuth2Error","refreshAccessToken","revokeToken"],"sources":["../../../src/oauth2/provider/x.ts"],"sourcesContent":["import { invariant } from '@shware/utils';\nimport { OAuth2Error } from '../error';\nimport type { OAuth2Token, Provider } from '../types';\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 tokenRefreshUri: '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 invariant(this.tokenRefreshUri, 'tokenRefreshUri is required');\n const response = await refreshAccessToken({\n ...params,\n tokenUri: this.tokenRefreshUri,\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\ntype UrlEntity = {\n start: number;\n end: number;\n url: string;\n display_url: string;\n expanded_url: string;\n};\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":";;;;;AAcA,MAAM,oBAAoB;CACxB;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAgB,gBAAgB,SAA8B;CAC5D,OAAO;EACL,kBAAkB;EAClB,UAAU;EACV,iBAAiB;EACjB,gBAAgB;EAEhB,aAAa;EACb,cAAc;GAAC;GAAc;GAAc;EAAgB;EAC3D,uBAAuB,QAAQ;GAC7B,IAAI,CAAC,OAAO,MAAM,MAAM,IAAI,MAAM,wBAAwB;GAC1D,OAAOA,+BAAAA,uBAAuB;IAC5B,GAAG;IACH,OAAO,OAAO,SAAS,KAAK;IAC5B,kBAAkB,KAAK;GACzB,CAAC;EACH;EACA,MAAM,0BAA0B,QAAQ;GACtC,IAAI,CAAC,OAAO,MAAM,MAAM,IAAI,MAAM,wBAAwB;GAC1D,MAAM,WAAW,MAAMC,+BAAAA,0BAA0B;IAC/C,GAAG;IACH,UAAU,KAAK;IACf,gBAAgB;GAClB,CAAC;GACD,IAAI,CAAC,SAAS,IAAI;IAChB,MAAM,EAAE,OAAO,sBAAuB,MAAM,SAAS,KAAK;IAC1D,MAAM,IAAIC,qBAAAA,YAAY,SAAS,QAAQ,OAAO,iBAAiB;GACjE;GACA,OAAQ,MAAM,SAAS,KAAK;EAC9B;EACA,MAAM,YAAY,EAAE,gBAAgB;GAClC,CAAA,GAAA,cAAA,UAAA,CAAU,cAAc,0BAA0B;GAClD,CAAA,GAAA,cAAA,UAAA,CAAU,KAAK,aAAa,yBAAyB;GAErD,MAAM,aAAa,SAAS,cAAc;GAC1C,MAAM,UAAU;IAAE,QAAQ;IAAoB,eAAe,UAAU;GAAe;GAEtF,MAAM,MAAM,IAAI,IAAI,KAAK,WAAW;GACpC,WAAW,SAAS,UAAU,IAAI,aAAa,OAAO,eAAe,KAAK,CAAC;GAE3E,MAAM,WAAW,MAAM,MAAM,KAAK,aAAa,EAAE,QAAQ,CAAC;GAC1D,IAAI,CAAC,SAAS,IAAI;IAChB,MAAM,EAAE,WAAY,MAAM,SAAS,KAAK;IACxC,MAAM,IAAIA,qBAAAA,YACR,SAAS,QACT,mBACA,8BAA8B,OAAO,GAAG,CAAC,CAAC,EAAE,UAAU,OAAO,GAAG,CAAC,CAAC,EAAE,OACtE;GACF;GACA,MAAM,UAAW,MAAM,SAAS,KAAK;GACrC,OAAO;IACL,MAAM;IACN,QAAQ;KACN,KAAK,QAAQ,KAAK;KAClB,MAAM,QAAQ,KAAK;KACnB,SAAS,QAAQ,KAAK;KACtB,OAAO,QAAQ,KAAK;KACpB,gBAAgB,QAAQ,KAAK,YAAY;KACzC,oBAAoB,QAAQ,KAAK;KACjC,SAAS,iBAAiB,QAAQ,KAAK;KACvC,SAAS,QAAQ,KAAK;IACxB;GACF;EACF;EACA,MAAM,mBAAmB,QAAQ;GAC/B,CAAA,GAAA,cAAA,UAAA,CAAU,KAAK,iBAAiB,6BAA6B;GAC7D,MAAM,WAAW,MAAMC,+BAAAA,mBAAmB;IACxC,GAAG;IACH,UAAU,KAAK;IACf,gBAAgB;GAClB,CAAC;GACD,IAAI,CAAC,SAAS,IAAI;IAChB,MAAM,EAAE,OAAO,sBAAuB,MAAM,SAAS,KAAK;IAC1D,MAAM,IAAID,qBAAAA,YAAY,SAAS,QAAQ,OAAO,iBAAiB;GACjE;GACA,OAAQ,MAAM,SAAS,KAAK;EAC9B;EACA,MAAM,YAAY,QAAQ;GACxB,CAAA,GAAA,cAAA,UAAA,CAAU,KAAK,gBAAgB,4BAA4B;GAC3D,OAAOE,+BAAAA,YAAY;IACjB,GAAG;IACH,gBAAgB,KAAK;IACrB,gBAAgB;GAClB,CAAC;EACH;CACF;AACF;AAEA,MAAa,IAAI,gBAAgB"}