@shware/security 0.4.6 → 0.4.7

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.
@@ -32,7 +32,6 @@ var common_exports = {};
32
32
  __export(common_exports, {
33
33
  createAuthorizationUri: () => createAuthorizationUri,
34
34
  exchangeAuthorizationCode: () => exchangeAuthorizationCode,
35
- proxyAgent: () => proxyAgent,
36
35
  refreshAccessToken: () => refreshAccessToken,
37
36
  revokeToken: () => revokeToken,
38
37
  verifyIdToken: () => verifyIdToken
@@ -40,7 +39,6 @@ __export(common_exports, {
40
39
  module.exports = __toCommonJS(common_exports);
41
40
  var import_crypto = require("crypto");
42
41
  var import_jsonwebtoken = __toESM(require("jsonwebtoken"), 1);
43
- var import_undici = require("undici");
44
42
  var import_error = require("../error.cjs");
45
43
  function createAuthorizationUri(options) {
46
44
  const url = new URL(options.authorizationUri);
@@ -56,7 +54,6 @@ function createAuthorizationUri(options) {
56
54
  }
57
55
  return url;
58
56
  }
59
- var proxyAgent = new import_undici.ProxyAgent("http://localhost:7890");
60
57
  async function exchangeAuthorizationCode(params) {
61
58
  const body = new URLSearchParams();
62
59
  body.append("code", params.code);
@@ -74,7 +71,7 @@ async function exchangeAuthorizationCode(params) {
74
71
  body.append("client_id", params.clientId);
75
72
  body.append("client_secret", params.clientSecret);
76
73
  }
77
- return (0, import_undici.fetch)(params.tokenUri, { method: "POST", headers, body, dispatcher: proxyAgent });
74
+ return fetch(params.tokenUri, { method: "POST", headers, body });
78
75
  }
79
76
  async function refreshAccessToken(params) {
80
77
  const body = new URLSearchParams();
@@ -91,7 +88,7 @@ async function refreshAccessToken(params) {
91
88
  body.append("client_id", params.clientId);
92
89
  body.append("client_secret", params.clientSecret);
93
90
  }
94
- const response = await (0, import_undici.fetch)(params.tokenUri, { method: "POST", headers, body });
91
+ const response = await fetch(params.tokenUri, { method: "POST", headers, body });
95
92
  if (!response.ok) {
96
93
  const error = await response.json();
97
94
  console.error("Refresh token error:", error);
@@ -113,7 +110,7 @@ async function revokeToken(params) {
113
110
  body.append("client_id", params.clientId);
114
111
  body.append("client_secret", params.clientSecret);
115
112
  }
116
- const response = await (0, import_undici.fetch)(params.tokenRevokeUri, { method: "POST", headers, body });
113
+ const response = await fetch(params.tokenRevokeUri, { method: "POST", headers, body });
117
114
  if (!response.ok) {
118
115
  const error = await response.json();
119
116
  console.error("Refresh token error:", error);
@@ -126,7 +123,7 @@ async function getJWK(kid, jwkSetUri) {
126
123
  if (cache.has(jwkSetUri)) {
127
124
  jwkSet = cache.get(jwkSetUri);
128
125
  } else {
129
- const response = await (0, import_undici.fetch)(jwkSetUri);
126
+ const response = await fetch(jwkSetUri);
130
127
  if (!response.ok) throw new import_error.OAuth2Error(response.status, "server_error", "Failed to fetch JWK");
131
128
  jwkSet = await response.json();
132
129
  cache.set(jwkSetUri, jwkSet);
@@ -151,7 +148,6 @@ async function verifyIdToken(idToken, jwkSetUri) {
151
148
  0 && (module.exports = {
152
149
  createAuthorizationUri,
153
150
  exchangeAuthorizationCode,
154
- proxyAgent,
155
151
  refreshAccessToken,
156
152
  revokeToken,
157
153
  verifyIdToken
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/oauth2/provider/common.ts"],"sourcesContent":["import { createHash } from 'crypto';\nimport jwt from 'jsonwebtoken';\nimport { fetch, ProxyAgent } from 'undici';\nimport { OAuth2Error } from '../error';\nimport { CodeExchangeParams, OAuth2Token } from '../types';\n\nexport function createAuthorizationUri(options: {\n state: string;\n scope: string[];\n clientId: string;\n redirectUri: string;\n authorizationUri: string;\n codeVerifier?: string;\n}) {\n const url = new URL(options.authorizationUri);\n url.searchParams.append('response_type', 'code');\n url.searchParams.append('client_id', options.clientId);\n url.searchParams.append('state', options.state);\n url.searchParams.append('scope', options.scope.join(' '));\n url.searchParams.append('redirect_uri', options.redirectUri);\n if (options.codeVerifier) {\n const codeChallenge = createHash('sha256')\n .update(options.codeVerifier)\n .digest()\n .toString('base64url');\n url.searchParams.append('code_challenge_method', 'S256');\n url.searchParams.append('code_challenge', codeChallenge);\n }\n return url;\n}\n\ninterface Params extends CodeExchangeParams {\n tokenUri: string;\n authentication?: 'basic' | 'post';\n}\n\nexport const proxyAgent = new ProxyAgent('http://localhost:7890');\nexport async function exchangeAuthorizationCode(params: Params) {\n const body = new URLSearchParams();\n body.append('code', params.code);\n body.append('redirect_uri', params.redirectUri);\n body.append('grant_type', 'authorization_code');\n if (params.codeVerifier) body.append('code_verifier', params.codeVerifier);\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'Content-Type': 'application/x-www-form-urlencoded',\n };\n if (params.authentication === 'basic') {\n const token = Buffer.from(`${params.clientId}:${params.clientSecret}`).toString('base64');\n headers.Authorization = `Basic ${token}`;\n } else {\n body.append('client_id', params.clientId);\n body.append('client_secret', params.clientSecret);\n }\n\n return fetch(params.tokenUri, { method: 'POST', headers, body, dispatcher: proxyAgent });\n}\n\ninterface RefreshTokenParams {\n tokenUri: string;\n clientId: string;\n clientSecret: string;\n refreshToken: string;\n authentication?: 'basic' | 'post';\n}\n\nexport async function refreshAccessToken(params: RefreshTokenParams) {\n const body = new URLSearchParams();\n body.append('grant_type', 'refresh_token');\n body.append('refresh_token', params.refreshToken);\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'Content-Type': 'application/x-www-form-urlencoded',\n };\n\n if (params.authentication === 'basic') {\n const token = Buffer.from(`${params.clientId}:${params.clientSecret}`).toString('base64');\n headers.Authorization = `Basic ${token}`;\n } else {\n body.append('client_id', params.clientId);\n body.append('client_secret', params.clientSecret);\n }\n\n const response = await fetch(params.tokenUri, { method: 'POST', headers, body });\n if (!response.ok) {\n const error = await response.json();\n console.error('Refresh token error:', error);\n throw new OAuth2Error(response.status, 'invalid_request', 'Failed to refresh token');\n }\n return (await response.json()) as OAuth2Token;\n}\n\ninterface RevokeTokenParams {\n token: string;\n clientId: string;\n clientSecret: string;\n tokenRevokeUri: string;\n authentication?: 'basic' | 'post';\n}\n\nexport async function revokeToken(params: RevokeTokenParams) {\n const body = new URLSearchParams();\n body.append('token', params.token);\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'Content-Type': 'application/x-www-form-urlencoded',\n };\n\n if (params.authentication === 'basic') {\n const token = Buffer.from(`${params.clientId}:${params.clientSecret}`).toString('base64');\n headers.Authorization = `Basic ${token}`;\n } else {\n body.append('client_id', params.clientId);\n body.append('client_secret', params.clientSecret);\n }\n\n const response = await fetch(params.tokenRevokeUri, { method: 'POST', headers, body });\n if (!response.ok) {\n const error = await response.json();\n console.error('Refresh token error:', error);\n throw new OAuth2Error(response.status, 'invalid_request', 'Failed to revoke token');\n }\n}\n\ninterface JWKSet {\n keys: { kty: string; kid: string; use: string; alg: string; n: string; e: string }[];\n}\n\nconst cache = new Map<string, JWKSet>();\n\nasync function getJWK(kid: string, jwkSetUri: string) {\n let jwkSet: JWKSet;\n if (cache.has(jwkSetUri)) {\n jwkSet = cache.get(jwkSetUri)!;\n } else {\n const response = await fetch(jwkSetUri);\n if (!response.ok) throw new OAuth2Error(response.status, 'server_error', 'Failed to fetch JWK');\n jwkSet = (await response.json()) as JWKSet;\n cache.set(jwkSetUri, jwkSet);\n }\n\n const jwk = jwkSet.keys.find((key) => key.kid === kid);\n if (!jwk) throw new OAuth2Error(400, 'invalid_request', `JWK not found for kid: ${kid}`);\n return jwk;\n}\n\nexport async function verifyIdToken<T>(idToken: string, jwkSetUri: string) {\n const header = jwt.decode(idToken, { complete: true });\n if (!header?.header.kid) {\n throw new OAuth2Error(400, 'invalid_request', 'kid not found in id_token header');\n }\n try {\n const key = await getJWK(header.header.kid, jwkSetUri);\n return jwt.verify(idToken, { key, format: 'jwk' }) as T;\n } catch (e) {\n throw new OAuth2Error(400, 'invalid_request', 'Failed to verify id_token');\n }\n}\n"],"mappings":"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","names":["jwt"]}
1
+ {"version":3,"sources":["../../../src/oauth2/provider/common.ts"],"sourcesContent":["import { createHash } from 'crypto';\nimport jwt from 'jsonwebtoken';\nimport { OAuth2Error } from '../error';\nimport { CodeExchangeParams, OAuth2Token } from '../types';\n\nexport function createAuthorizationUri(options: {\n state: string;\n scope: string[];\n clientId: string;\n redirectUri: string;\n authorizationUri: string;\n codeVerifier?: string;\n}) {\n const url = new URL(options.authorizationUri);\n url.searchParams.append('response_type', 'code');\n url.searchParams.append('client_id', options.clientId);\n url.searchParams.append('state', options.state);\n url.searchParams.append('scope', options.scope.join(' '));\n url.searchParams.append('redirect_uri', options.redirectUri);\n if (options.codeVerifier) {\n const codeChallenge = createHash('sha256')\n .update(options.codeVerifier)\n .digest()\n .toString('base64url');\n url.searchParams.append('code_challenge_method', 'S256');\n url.searchParams.append('code_challenge', codeChallenge);\n }\n return url;\n}\n\ninterface Params extends CodeExchangeParams {\n tokenUri: string;\n authentication?: 'basic' | 'post';\n}\n\nexport async function exchangeAuthorizationCode(params: Params) {\n const body = new URLSearchParams();\n body.append('code', params.code);\n body.append('redirect_uri', params.redirectUri);\n body.append('grant_type', 'authorization_code');\n if (params.codeVerifier) body.append('code_verifier', params.codeVerifier);\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'Content-Type': 'application/x-www-form-urlencoded',\n };\n if (params.authentication === 'basic') {\n const token = Buffer.from(`${params.clientId}:${params.clientSecret}`).toString('base64');\n headers.Authorization = `Basic ${token}`;\n } else {\n body.append('client_id', params.clientId);\n body.append('client_secret', params.clientSecret);\n }\n\n return fetch(params.tokenUri, { method: 'POST', headers, body });\n}\n\ninterface RefreshTokenParams {\n tokenUri: string;\n clientId: string;\n clientSecret: string;\n refreshToken: string;\n authentication?: 'basic' | 'post';\n}\n\nexport async function refreshAccessToken(params: RefreshTokenParams) {\n const body = new URLSearchParams();\n body.append('grant_type', 'refresh_token');\n body.append('refresh_token', params.refreshToken);\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'Content-Type': 'application/x-www-form-urlencoded',\n };\n\n if (params.authentication === 'basic') {\n const token = Buffer.from(`${params.clientId}:${params.clientSecret}`).toString('base64');\n headers.Authorization = `Basic ${token}`;\n } else {\n body.append('client_id', params.clientId);\n body.append('client_secret', params.clientSecret);\n }\n\n const response = await fetch(params.tokenUri, { method: 'POST', headers, body });\n if (!response.ok) {\n const error = await response.json();\n console.error('Refresh token error:', error);\n throw new OAuth2Error(response.status, 'invalid_request', 'Failed to refresh token');\n }\n return (await response.json()) as OAuth2Token;\n}\n\ninterface RevokeTokenParams {\n token: string;\n clientId: string;\n clientSecret: string;\n tokenRevokeUri: string;\n authentication?: 'basic' | 'post';\n}\n\nexport async function revokeToken(params: RevokeTokenParams) {\n const body = new URLSearchParams();\n body.append('token', params.token);\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'Content-Type': 'application/x-www-form-urlencoded',\n };\n\n if (params.authentication === 'basic') {\n const token = Buffer.from(`${params.clientId}:${params.clientSecret}`).toString('base64');\n headers.Authorization = `Basic ${token}`;\n } else {\n body.append('client_id', params.clientId);\n body.append('client_secret', params.clientSecret);\n }\n\n const response = await fetch(params.tokenRevokeUri, { method: 'POST', headers, body });\n if (!response.ok) {\n const error = await response.json();\n console.error('Refresh token error:', error);\n throw new OAuth2Error(response.status, 'invalid_request', 'Failed to revoke token');\n }\n}\n\ninterface JWKSet {\n keys: { kty: string; kid: string; use: string; alg: string; n: string; e: string }[];\n}\n\nconst cache = new Map<string, JWKSet>();\n\nasync function getJWK(kid: string, jwkSetUri: string) {\n let jwkSet: JWKSet;\n if (cache.has(jwkSetUri)) {\n jwkSet = cache.get(jwkSetUri)!;\n } else {\n const response = await fetch(jwkSetUri);\n if (!response.ok) throw new OAuth2Error(response.status, 'server_error', 'Failed to fetch JWK');\n jwkSet = (await response.json()) as JWKSet;\n cache.set(jwkSetUri, jwkSet);\n }\n\n const jwk = jwkSet.keys.find((key) => key.kid === kid);\n if (!jwk) throw new OAuth2Error(400, 'invalid_request', `JWK not found for kid: ${kid}`);\n return jwk;\n}\n\nexport async function verifyIdToken<T>(idToken: string, jwkSetUri: string) {\n const header = jwt.decode(idToken, { complete: true });\n if (!header?.header.kid) {\n throw new OAuth2Error(400, 'invalid_request', 'kid not found in id_token header');\n }\n try {\n const key = await getJWK(header.header.kid, jwkSetUri);\n return jwt.verify(idToken, { key, format: 'jwk' }) as T;\n } catch (e) {\n throw new OAuth2Error(400, 'invalid_request', 'Failed to verify id_token');\n }\n}\n"],"mappings":"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","names":["jwt"]}
@@ -1,5 +1,3 @@
1
- import * as undici from 'undici';
2
- import { ProxyAgent } from 'undici';
3
1
  import * as url from 'url';
4
2
  import { CodeExchangeParams, OAuth2Token } from '../types.cjs';
5
3
 
@@ -15,8 +13,7 @@ interface Params extends CodeExchangeParams {
15
13
  tokenUri: string;
16
14
  authentication?: 'basic' | 'post';
17
15
  }
18
- declare const proxyAgent: ProxyAgent;
19
- declare function exchangeAuthorizationCode(params: Params): Promise<undici.Response>;
16
+ declare function exchangeAuthorizationCode(params: Params): Promise<Response>;
20
17
  interface RefreshTokenParams {
21
18
  tokenUri: string;
22
19
  clientId: string;
@@ -35,4 +32,4 @@ interface RevokeTokenParams {
35
32
  declare function revokeToken(params: RevokeTokenParams): Promise<void>;
36
33
  declare function verifyIdToken<T>(idToken: string, jwkSetUri: string): Promise<T>;
37
34
 
38
- export { createAuthorizationUri, exchangeAuthorizationCode, proxyAgent, refreshAccessToken, revokeToken, verifyIdToken };
35
+ export { createAuthorizationUri, exchangeAuthorizationCode, refreshAccessToken, revokeToken, verifyIdToken };
@@ -1,5 +1,3 @@
1
- import * as undici from 'undici';
2
- import { ProxyAgent } from 'undici';
3
1
  import * as url from 'url';
4
2
  import { CodeExchangeParams, OAuth2Token } from '../types.js';
5
3
 
@@ -15,8 +13,7 @@ interface Params extends CodeExchangeParams {
15
13
  tokenUri: string;
16
14
  authentication?: 'basic' | 'post';
17
15
  }
18
- declare const proxyAgent: ProxyAgent;
19
- declare function exchangeAuthorizationCode(params: Params): Promise<undici.Response>;
16
+ declare function exchangeAuthorizationCode(params: Params): Promise<Response>;
20
17
  interface RefreshTokenParams {
21
18
  tokenUri: string;
22
19
  clientId: string;
@@ -35,4 +32,4 @@ interface RevokeTokenParams {
35
32
  declare function revokeToken(params: RevokeTokenParams): Promise<void>;
36
33
  declare function verifyIdToken<T>(idToken: string, jwkSetUri: string): Promise<T>;
37
34
 
38
- export { createAuthorizationUri, exchangeAuthorizationCode, proxyAgent, refreshAccessToken, revokeToken, verifyIdToken };
35
+ export { createAuthorizationUri, exchangeAuthorizationCode, refreshAccessToken, revokeToken, verifyIdToken };
@@ -1,7 +1,6 @@
1
1
  // src/oauth2/provider/common.ts
2
2
  import { createHash } from "crypto";
3
3
  import jwt from "jsonwebtoken";
4
- import { fetch, ProxyAgent } from "undici";
5
4
  import { OAuth2Error } from "../error.mjs";
6
5
  function createAuthorizationUri(options) {
7
6
  const url = new URL(options.authorizationUri);
@@ -17,7 +16,6 @@ function createAuthorizationUri(options) {
17
16
  }
18
17
  return url;
19
18
  }
20
- var proxyAgent = new ProxyAgent("http://localhost:7890");
21
19
  async function exchangeAuthorizationCode(params) {
22
20
  const body = new URLSearchParams();
23
21
  body.append("code", params.code);
@@ -35,7 +33,7 @@ async function exchangeAuthorizationCode(params) {
35
33
  body.append("client_id", params.clientId);
36
34
  body.append("client_secret", params.clientSecret);
37
35
  }
38
- return fetch(params.tokenUri, { method: "POST", headers, body, dispatcher: proxyAgent });
36
+ return fetch(params.tokenUri, { method: "POST", headers, body });
39
37
  }
40
38
  async function refreshAccessToken(params) {
41
39
  const body = new URLSearchParams();
@@ -111,7 +109,6 @@ async function verifyIdToken(idToken, jwkSetUri) {
111
109
  export {
112
110
  createAuthorizationUri,
113
111
  exchangeAuthorizationCode,
114
- proxyAgent,
115
112
  refreshAccessToken,
116
113
  revokeToken,
117
114
  verifyIdToken
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/oauth2/provider/common.ts"],"sourcesContent":["import { createHash } from 'crypto';\nimport jwt from 'jsonwebtoken';\nimport { fetch, ProxyAgent } from 'undici';\nimport { OAuth2Error } from '../error';\nimport { CodeExchangeParams, OAuth2Token } from '../types';\n\nexport function createAuthorizationUri(options: {\n state: string;\n scope: string[];\n clientId: string;\n redirectUri: string;\n authorizationUri: string;\n codeVerifier?: string;\n}) {\n const url = new URL(options.authorizationUri);\n url.searchParams.append('response_type', 'code');\n url.searchParams.append('client_id', options.clientId);\n url.searchParams.append('state', options.state);\n url.searchParams.append('scope', options.scope.join(' '));\n url.searchParams.append('redirect_uri', options.redirectUri);\n if (options.codeVerifier) {\n const codeChallenge = createHash('sha256')\n .update(options.codeVerifier)\n .digest()\n .toString('base64url');\n url.searchParams.append('code_challenge_method', 'S256');\n url.searchParams.append('code_challenge', codeChallenge);\n }\n return url;\n}\n\ninterface Params extends CodeExchangeParams {\n tokenUri: string;\n authentication?: 'basic' | 'post';\n}\n\nexport const proxyAgent = new ProxyAgent('http://localhost:7890');\nexport async function exchangeAuthorizationCode(params: Params) {\n const body = new URLSearchParams();\n body.append('code', params.code);\n body.append('redirect_uri', params.redirectUri);\n body.append('grant_type', 'authorization_code');\n if (params.codeVerifier) body.append('code_verifier', params.codeVerifier);\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'Content-Type': 'application/x-www-form-urlencoded',\n };\n if (params.authentication === 'basic') {\n const token = Buffer.from(`${params.clientId}:${params.clientSecret}`).toString('base64');\n headers.Authorization = `Basic ${token}`;\n } else {\n body.append('client_id', params.clientId);\n body.append('client_secret', params.clientSecret);\n }\n\n return fetch(params.tokenUri, { method: 'POST', headers, body, dispatcher: proxyAgent });\n}\n\ninterface RefreshTokenParams {\n tokenUri: string;\n clientId: string;\n clientSecret: string;\n refreshToken: string;\n authentication?: 'basic' | 'post';\n}\n\nexport async function refreshAccessToken(params: RefreshTokenParams) {\n const body = new URLSearchParams();\n body.append('grant_type', 'refresh_token');\n body.append('refresh_token', params.refreshToken);\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'Content-Type': 'application/x-www-form-urlencoded',\n };\n\n if (params.authentication === 'basic') {\n const token = Buffer.from(`${params.clientId}:${params.clientSecret}`).toString('base64');\n headers.Authorization = `Basic ${token}`;\n } else {\n body.append('client_id', params.clientId);\n body.append('client_secret', params.clientSecret);\n }\n\n const response = await fetch(params.tokenUri, { method: 'POST', headers, body });\n if (!response.ok) {\n const error = await response.json();\n console.error('Refresh token error:', error);\n throw new OAuth2Error(response.status, 'invalid_request', 'Failed to refresh token');\n }\n return (await response.json()) as OAuth2Token;\n}\n\ninterface RevokeTokenParams {\n token: string;\n clientId: string;\n clientSecret: string;\n tokenRevokeUri: string;\n authentication?: 'basic' | 'post';\n}\n\nexport async function revokeToken(params: RevokeTokenParams) {\n const body = new URLSearchParams();\n body.append('token', params.token);\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'Content-Type': 'application/x-www-form-urlencoded',\n };\n\n if (params.authentication === 'basic') {\n const token = Buffer.from(`${params.clientId}:${params.clientSecret}`).toString('base64');\n headers.Authorization = `Basic ${token}`;\n } else {\n body.append('client_id', params.clientId);\n body.append('client_secret', params.clientSecret);\n }\n\n const response = await fetch(params.tokenRevokeUri, { method: 'POST', headers, body });\n if (!response.ok) {\n const error = await response.json();\n console.error('Refresh token error:', error);\n throw new OAuth2Error(response.status, 'invalid_request', 'Failed to revoke token');\n }\n}\n\ninterface JWKSet {\n keys: { kty: string; kid: string; use: string; alg: string; n: string; e: string }[];\n}\n\nconst cache = new Map<string, JWKSet>();\n\nasync function getJWK(kid: string, jwkSetUri: string) {\n let jwkSet: JWKSet;\n if (cache.has(jwkSetUri)) {\n jwkSet = cache.get(jwkSetUri)!;\n } else {\n const response = await fetch(jwkSetUri);\n if (!response.ok) throw new OAuth2Error(response.status, 'server_error', 'Failed to fetch JWK');\n jwkSet = (await response.json()) as JWKSet;\n cache.set(jwkSetUri, jwkSet);\n }\n\n const jwk = jwkSet.keys.find((key) => key.kid === kid);\n if (!jwk) throw new OAuth2Error(400, 'invalid_request', `JWK not found for kid: ${kid}`);\n return jwk;\n}\n\nexport async function verifyIdToken<T>(idToken: string, jwkSetUri: string) {\n const header = jwt.decode(idToken, { complete: true });\n if (!header?.header.kid) {\n throw new OAuth2Error(400, 'invalid_request', 'kid not found in id_token header');\n }\n try {\n const key = await getJWK(header.header.kid, jwkSetUri);\n return jwt.verify(idToken, { key, format: 'jwk' }) as T;\n } catch (e) {\n throw new OAuth2Error(400, 'invalid_request', 'Failed to verify id_token');\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/oauth2/provider/common.ts"],"sourcesContent":["import { createHash } from 'crypto';\nimport jwt from 'jsonwebtoken';\nimport { OAuth2Error } from '../error';\nimport { CodeExchangeParams, OAuth2Token } from '../types';\n\nexport function createAuthorizationUri(options: {\n state: string;\n scope: string[];\n clientId: string;\n redirectUri: string;\n authorizationUri: string;\n codeVerifier?: string;\n}) {\n const url = new URL(options.authorizationUri);\n url.searchParams.append('response_type', 'code');\n url.searchParams.append('client_id', options.clientId);\n url.searchParams.append('state', options.state);\n url.searchParams.append('scope', options.scope.join(' '));\n url.searchParams.append('redirect_uri', options.redirectUri);\n if (options.codeVerifier) {\n const codeChallenge = createHash('sha256')\n .update(options.codeVerifier)\n .digest()\n .toString('base64url');\n url.searchParams.append('code_challenge_method', 'S256');\n url.searchParams.append('code_challenge', codeChallenge);\n }\n return url;\n}\n\ninterface Params extends CodeExchangeParams {\n tokenUri: string;\n authentication?: 'basic' | 'post';\n}\n\nexport async function exchangeAuthorizationCode(params: Params) {\n const body = new URLSearchParams();\n body.append('code', params.code);\n body.append('redirect_uri', params.redirectUri);\n body.append('grant_type', 'authorization_code');\n if (params.codeVerifier) body.append('code_verifier', params.codeVerifier);\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'Content-Type': 'application/x-www-form-urlencoded',\n };\n if (params.authentication === 'basic') {\n const token = Buffer.from(`${params.clientId}:${params.clientSecret}`).toString('base64');\n headers.Authorization = `Basic ${token}`;\n } else {\n body.append('client_id', params.clientId);\n body.append('client_secret', params.clientSecret);\n }\n\n return fetch(params.tokenUri, { method: 'POST', headers, body });\n}\n\ninterface RefreshTokenParams {\n tokenUri: string;\n clientId: string;\n clientSecret: string;\n refreshToken: string;\n authentication?: 'basic' | 'post';\n}\n\nexport async function refreshAccessToken(params: RefreshTokenParams) {\n const body = new URLSearchParams();\n body.append('grant_type', 'refresh_token');\n body.append('refresh_token', params.refreshToken);\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'Content-Type': 'application/x-www-form-urlencoded',\n };\n\n if (params.authentication === 'basic') {\n const token = Buffer.from(`${params.clientId}:${params.clientSecret}`).toString('base64');\n headers.Authorization = `Basic ${token}`;\n } else {\n body.append('client_id', params.clientId);\n body.append('client_secret', params.clientSecret);\n }\n\n const response = await fetch(params.tokenUri, { method: 'POST', headers, body });\n if (!response.ok) {\n const error = await response.json();\n console.error('Refresh token error:', error);\n throw new OAuth2Error(response.status, 'invalid_request', 'Failed to refresh token');\n }\n return (await response.json()) as OAuth2Token;\n}\n\ninterface RevokeTokenParams {\n token: string;\n clientId: string;\n clientSecret: string;\n tokenRevokeUri: string;\n authentication?: 'basic' | 'post';\n}\n\nexport async function revokeToken(params: RevokeTokenParams) {\n const body = new URLSearchParams();\n body.append('token', params.token);\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'Content-Type': 'application/x-www-form-urlencoded',\n };\n\n if (params.authentication === 'basic') {\n const token = Buffer.from(`${params.clientId}:${params.clientSecret}`).toString('base64');\n headers.Authorization = `Basic ${token}`;\n } else {\n body.append('client_id', params.clientId);\n body.append('client_secret', params.clientSecret);\n }\n\n const response = await fetch(params.tokenRevokeUri, { method: 'POST', headers, body });\n if (!response.ok) {\n const error = await response.json();\n console.error('Refresh token error:', error);\n throw new OAuth2Error(response.status, 'invalid_request', 'Failed to revoke token');\n }\n}\n\ninterface JWKSet {\n keys: { kty: string; kid: string; use: string; alg: string; n: string; e: string }[];\n}\n\nconst cache = new Map<string, JWKSet>();\n\nasync function getJWK(kid: string, jwkSetUri: string) {\n let jwkSet: JWKSet;\n if (cache.has(jwkSetUri)) {\n jwkSet = cache.get(jwkSetUri)!;\n } else {\n const response = await fetch(jwkSetUri);\n if (!response.ok) throw new OAuth2Error(response.status, 'server_error', 'Failed to fetch JWK');\n jwkSet = (await response.json()) as JWKSet;\n cache.set(jwkSetUri, jwkSet);\n }\n\n const jwk = jwkSet.keys.find((key) => key.kid === kid);\n if (!jwk) throw new OAuth2Error(400, 'invalid_request', `JWK not found for kid: ${kid}`);\n return jwk;\n}\n\nexport async function verifyIdToken<T>(idToken: string, jwkSetUri: string) {\n const header = jwt.decode(idToken, { complete: true });\n if (!header?.header.kid) {\n throw new OAuth2Error(400, 'invalid_request', 'kid not found in id_token header');\n }\n try {\n const key = await getJWK(header.header.kid, jwkSetUri);\n return jwt.verify(idToken, { key, format: 'jwk' }) as T;\n } catch (e) {\n throw new OAuth2Error(400, 'invalid_request', 'Failed to verify id_token');\n }\n}\n"],"mappings":"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","names":[]}
@@ -34,7 +34,6 @@ __export(x_exports, {
34
34
  });
35
35
  module.exports = __toCommonJS(x_exports);
36
36
  var import_tiny_invariant = __toESM(require("tiny-invariant"), 1);
37
- var import_undici = require("undici");
38
37
  var import_error = require("../error.cjs");
39
38
  var import_common = require("./common.cjs");
40
39
  var defaultUserFields = [
@@ -82,7 +81,7 @@ function x(options) {
82
81
  const headers = { Accept: "application/json", Authorization: `Bearer ${access_token}` };
83
82
  const url = new URL(this.userInfoUri);
84
83
  userFields.forEach((field) => url.searchParams.append("user.fields", field));
85
- const response = await (0, import_undici.fetch)(this.userInfoUri, { headers, dispatcher: import_common.proxyAgent });
84
+ const response = await fetch(this.userInfoUri, { headers });
86
85
  if (!response.ok) {
87
86
  const { errors } = await response.json();
88
87
  throw new import_error.OAuth2Error(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/oauth2/provider/x.ts"],"sourcesContent":["import invariant from 'tiny-invariant';\nimport { fetch } from 'undici';\nimport { Provider } from '../types';\nimport { OAuth2Error } from '../error';\nimport {\n createAuthorizationUri,\n exchangeAuthorizationCode,\n proxyAgent,\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, dispatcher: proxyAgent });\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;AAAA;AAAA;AAAA;AAAA;AAAA,4BAAsB;AACtB,oBAAsB;AAEtB,mBAA4B;AAC5B,oBAMO;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,iBAAO,sCAAuB;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,UAAM,yCAA0B;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,yBAAY,SAAS,QAAQ,OAAO,iBAAiB;AAAA,MACjE;AACA,aAAQ,MAAM,SAAS,KAAK;AAAA,IAC9B;AAAA,IACA,MAAM,YAAY,EAAE,aAAa,GAAG;AAClC,gCAAAA,SAAU,cAAc,0BAA0B;AAClD,gCAAAA,SAAU,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,UAAM,qBAAM,KAAK,aAAa,EAAE,SAAS,YAAY,yBAAW,CAAC;AAClF,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,iBAAO,kCAAmB,EAAE,GAAG,QAAQ,UAAU,KAAK,UAAU,gBAAgB,QAAQ,CAAC;AAAA,IAC3F;AAAA,IACA,MAAM,YAAY,QAAQ;AACxB,gCAAAA,SAAU,KAAK,gBAAgB,4BAA4B;AAC3D,iBAAO,2BAAY;AAAA,QACjB,GAAG;AAAA,QACH,gBAAgB,KAAK;AAAA,QACrB,gBAAgB;AAAA,MAClB,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":["invariant"]}
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;AAAA;AAAA;AAAA;AAAA;AAAA,4BAAsB;AAEtB,mBAA4B;AAC5B,oBAKO;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,iBAAO,sCAAuB;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,UAAM,yCAA0B;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,yBAAY,SAAS,QAAQ,OAAO,iBAAiB;AAAA,MACjE;AACA,aAAQ,MAAM,SAAS,KAAK;AAAA,IAC9B;AAAA,IACA,MAAM,YAAY,EAAE,aAAa,GAAG;AAClC,gCAAAA,SAAU,cAAc,0BAA0B;AAClD,gCAAAA,SAAU,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,iBAAO,kCAAmB,EAAE,GAAG,QAAQ,UAAU,KAAK,UAAU,gBAAgB,QAAQ,CAAC;AAAA,IAC3F;AAAA,IACA,MAAM,YAAY,QAAQ;AACxB,gCAAAA,SAAU,KAAK,gBAAgB,4BAA4B;AAC3D,iBAAO,2BAAY;AAAA,QACjB,GAAG;AAAA,QACH,gBAAgB,KAAK;AAAA,QACrB,gBAAgB;AAAA,MAClB,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":["invariant"]}
@@ -1,11 +1,9 @@
1
1
  // src/oauth2/provider/x.ts
2
2
  import invariant from "tiny-invariant";
3
- import { fetch } from "undici";
4
3
  import { OAuth2Error } from "../error.mjs";
5
4
  import {
6
5
  createAuthorizationUri,
7
6
  exchangeAuthorizationCode,
8
- proxyAgent,
9
7
  refreshAccessToken,
10
8
  revokeToken
11
9
  } from "./common.mjs";
@@ -54,7 +52,7 @@ function x(options) {
54
52
  const headers = { Accept: "application/json", Authorization: `Bearer ${access_token}` };
55
53
  const url = new URL(this.userInfoUri);
56
54
  userFields.forEach((field) => url.searchParams.append("user.fields", field));
57
- const response = await fetch(this.userInfoUri, { headers, dispatcher: proxyAgent });
55
+ const response = await fetch(this.userInfoUri, { headers });
58
56
  if (!response.ok) {
59
57
  const { errors } = await response.json();
60
58
  throw new OAuth2Error(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/oauth2/provider/x.ts"],"sourcesContent":["import invariant from 'tiny-invariant';\nimport { fetch } from 'undici';\nimport { Provider } from '../types';\nimport { OAuth2Error } from '../error';\nimport {\n createAuthorizationUri,\n exchangeAuthorizationCode,\n proxyAgent,\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, dispatcher: proxyAgent });\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;AACtB,SAAS,aAAa;AAEtB,SAAS,mBAAmB;AAC5B;AAAA,EACE;AAAA,EACA;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,SAAS,YAAY,WAAW,CAAC;AAClF,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 { 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":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shware/security",
3
- "version": "0.4.6",
3
+ "version": "0.4.7",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -38,7 +38,6 @@
38
38
  "jsonwebtoken": "^9.0.2",
39
39
  "path-to-regexp": "^8.2.0",
40
40
  "tiny-invariant": "^1.3.3",
41
- "undici": "^7.5.0",
42
41
  "zod": "^3.24.2"
43
42
  }
44
43
  }