@shware/security 0.4.3
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.
- package/README.md +1 -0
- package/dist/auth/index.cjs +158 -0
- package/dist/auth/index.cjs.map +1 -0
- package/dist/auth/index.d.cts +27 -0
- package/dist/auth/index.d.ts +27 -0
- package/dist/auth/index.mjs +129 -0
- package/dist/auth/index.mjs.map +1 -0
- package/dist/auth/types.cjs +19 -0
- package/dist/auth/types.cjs.map +1 -0
- package/dist/auth/types.d.cts +25 -0
- package/dist/auth/types.d.ts +25 -0
- package/dist/auth/types.mjs +1 -0
- package/dist/auth/types.mjs.map +1 -0
- package/dist/core/index.cjs +19 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +17 -0
- package/dist/core/index.d.ts +17 -0
- package/dist/core/index.mjs +1 -0
- package/dist/core/index.mjs.map +1 -0
- package/dist/index.cjs +41 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.mjs +12 -0
- package/dist/index.mjs.map +1 -0
- package/dist/oauth2/client.cjs +110 -0
- package/dist/oauth2/client.cjs.map +1 -0
- package/dist/oauth2/client.d.cts +39 -0
- package/dist/oauth2/client.d.ts +39 -0
- package/dist/oauth2/client.mjs +74 -0
- package/dist/oauth2/client.mjs.map +1 -0
- package/dist/oauth2/error.cjs +54 -0
- package/dist/oauth2/error.cjs.map +1 -0
- package/dist/oauth2/error.d.cts +11 -0
- package/dist/oauth2/error.d.ts +11 -0
- package/dist/oauth2/error.mjs +28 -0
- package/dist/oauth2/error.mjs.map +1 -0
- package/dist/oauth2/provider/apple.cjs +85 -0
- package/dist/oauth2/provider/apple.cjs.map +1 -0
- package/dist/oauth2/provider/apple.d.cts +31 -0
- package/dist/oauth2/provider/apple.d.ts +31 -0
- package/dist/oauth2/provider/apple.mjs +50 -0
- package/dist/oauth2/provider/apple.mjs.map +1 -0
- package/dist/oauth2/provider/common.cjs +159 -0
- package/dist/oauth2/provider/common.cjs.map +1 -0
- package/dist/oauth2/provider/common.d.cts +38 -0
- package/dist/oauth2/provider/common.d.ts +38 -0
- package/dist/oauth2/provider/common.mjs +119 -0
- package/dist/oauth2/provider/common.mjs.map +1 -0
- package/dist/oauth2/provider/facebook.cjs +106 -0
- package/dist/oauth2/provider/facebook.cjs.map +1 -0
- package/dist/oauth2/provider/facebook.d.cts +29 -0
- package/dist/oauth2/provider/facebook.d.ts +29 -0
- package/dist/oauth2/provider/facebook.mjs +71 -0
- package/dist/oauth2/provider/facebook.mjs.map +1 -0
- package/dist/oauth2/provider/github.cjs +101 -0
- package/dist/oauth2/provider/github.cjs.map +1 -0
- package/dist/oauth2/provider/github.d.cts +51 -0
- package/dist/oauth2/provider/github.d.ts +51 -0
- package/dist/oauth2/provider/github.mjs +66 -0
- package/dist/oauth2/provider/github.mjs.map +1 -0
- package/dist/oauth2/provider/google.cjs +91 -0
- package/dist/oauth2/provider/google.cjs.map +1 -0
- package/dist/oauth2/provider/google.d.cts +35 -0
- package/dist/oauth2/provider/google.d.ts +35 -0
- package/dist/oauth2/provider/google.mjs +56 -0
- package/dist/oauth2/provider/google.mjs.map +1 -0
- package/dist/oauth2/provider/index.cjs +43 -0
- package/dist/oauth2/provider/index.cjs.map +1 -0
- package/dist/oauth2/provider/index.d.cts +6 -0
- package/dist/oauth2/provider/index.d.ts +6 -0
- package/dist/oauth2/provider/index.mjs +14 -0
- package/dist/oauth2/provider/index.mjs.map +1 -0
- package/dist/oauth2/provider/x.cjs +126 -0
- package/dist/oauth2/provider/x.cjs.map +1 -0
- package/dist/oauth2/provider/x.d.cts +60 -0
- package/dist/oauth2/provider/x.d.ts +60 -0
- package/dist/oauth2/provider/x.mjs +97 -0
- package/dist/oauth2/provider/x.mjs.map +1 -0
- package/dist/oauth2/schema.cjs +2 -0
- package/dist/oauth2/schema.cjs.map +1 -0
- package/dist/oauth2/schema.d.cts +2 -0
- package/dist/oauth2/schema.d.ts +2 -0
- package/dist/oauth2/schema.mjs +1 -0
- package/dist/oauth2/schema.mjs.map +1 -0
- package/dist/oauth2/types.cjs +19 -0
- package/dist/oauth2/types.cjs.map +1 -0
- package/dist/oauth2/types.d.cts +138 -0
- package/dist/oauth2/types.d.ts +138 -0
- package/dist/oauth2/types.mjs +1 -0
- package/dist/oauth2/types.mjs.map +1 -0
- package/dist/oidc/index.cjs +39 -0
- package/dist/oidc/index.cjs.map +1 -0
- package/dist/oidc/index.d.cts +10 -0
- package/dist/oidc/index.d.ts +10 -0
- package/dist/oidc/index.mjs +14 -0
- package/dist/oidc/index.mjs.map +1 -0
- package/dist/session/__test__/redis-session.test.cjs +94 -0
- package/dist/session/__test__/redis-session.test.cjs.map +1 -0
- package/dist/session/__test__/redis-session.test.d.cts +2 -0
- package/dist/session/__test__/redis-session.test.d.ts +2 -0
- package/dist/session/__test__/redis-session.test.mjs +70 -0
- package/dist/session/__test__/redis-session.test.mjs.map +1 -0
- package/dist/session/index.cjs +33 -0
- package/dist/session/index.cjs.map +1 -0
- package/dist/session/index.d.cts +4 -0
- package/dist/session/index.d.ts +4 -0
- package/dist/session/index.mjs +7 -0
- package/dist/session/index.mjs.map +1 -0
- package/dist/session/redis-session.cjs +403 -0
- package/dist/session/redis-session.cjs.map +1 -0
- package/dist/session/redis-session.d.cts +73 -0
- package/dist/session/redis-session.d.ts +73 -0
- package/dist/session/redis-session.mjs +377 -0
- package/dist/session/redis-session.mjs.map +1 -0
- package/dist/session/types.cjs +19 -0
- package/dist/session/types.cjs.map +1 -0
- package/dist/session/types.d.cts +39 -0
- package/dist/session/types.d.ts +39 -0
- package/dist/session/types.mjs +1 -0
- package/dist/session/types.mjs.map +1 -0
- package/dist/utils/http.cjs +63 -0
- package/dist/utils/http.cjs.map +1 -0
- package/dist/utils/http.d.cts +17 -0
- package/dist/utils/http.d.ts +17 -0
- package/dist/utils/http.mjs +34 -0
- package/dist/utils/http.mjs.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/oauth2/provider/x.ts
|
|
31
|
+
var x_exports = {};
|
|
32
|
+
__export(x_exports, {
|
|
33
|
+
x: () => x
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(x_exports);
|
|
36
|
+
var import_tiny_invariant = __toESM(require("tiny-invariant"), 1);
|
|
37
|
+
var import_undici = require("undici");
|
|
38
|
+
var import_error = require("../error.cjs");
|
|
39
|
+
var import_common = require("./common.cjs");
|
|
40
|
+
var defaultUserFields = [
|
|
41
|
+
"id",
|
|
42
|
+
"name",
|
|
43
|
+
"profile_image_url",
|
|
44
|
+
"url",
|
|
45
|
+
"username",
|
|
46
|
+
"location",
|
|
47
|
+
"verified"
|
|
48
|
+
];
|
|
49
|
+
function x(options) {
|
|
50
|
+
return {
|
|
51
|
+
authorizationUri: "https://x.com/i/oauth2/authorize",
|
|
52
|
+
tokenUri: "https://api.x.com/2/oauth2/token",
|
|
53
|
+
tokenRevokeUri: "https://api.x.com/2/oauth2/revoke",
|
|
54
|
+
// https://docs.x.com/x-api/users/user-lookup-me
|
|
55
|
+
userInfoUri: "https://api.x.com/2/users/me",
|
|
56
|
+
defaultScope: ["users.read", "tweet.read", "offline.access"],
|
|
57
|
+
createAuthorizationUri(params) {
|
|
58
|
+
if (!params.codeVerifier) throw new Error("codeVerifier is required for x");
|
|
59
|
+
return (0, import_common.createAuthorizationUri)({
|
|
60
|
+
...params,
|
|
61
|
+
scope: params.scope ?? this.defaultScope,
|
|
62
|
+
authorizationUri: this.authorizationUri
|
|
63
|
+
});
|
|
64
|
+
},
|
|
65
|
+
async exchangeAuthorizationCode(params) {
|
|
66
|
+
if (!params.codeVerifier) throw new Error("codeVerifier is required for x");
|
|
67
|
+
const response = await (0, import_common.exchangeAuthorizationCode)({
|
|
68
|
+
...params,
|
|
69
|
+
tokenUri: this.tokenUri,
|
|
70
|
+
authentication: "basic"
|
|
71
|
+
});
|
|
72
|
+
if (!response.ok) {
|
|
73
|
+
const { error, error_description } = await response.json();
|
|
74
|
+
throw new import_error.OAuth2Error(response.status, error, error_description);
|
|
75
|
+
}
|
|
76
|
+
return await response.json();
|
|
77
|
+
},
|
|
78
|
+
async getUserInfo({ access_token }) {
|
|
79
|
+
(0, import_tiny_invariant.default)(access_token, "access_token is required");
|
|
80
|
+
(0, import_tiny_invariant.default)(this.userInfoUri, "userInfoUri is required");
|
|
81
|
+
const userFields = options?.userFields ?? defaultUserFields;
|
|
82
|
+
const headers = { Accept: "application/json", Authorization: `Bearer ${access_token}` };
|
|
83
|
+
const url = new URL(this.userInfoUri);
|
|
84
|
+
userFields.forEach((field) => url.searchParams.append("user.fields", field));
|
|
85
|
+
const response = await (0, import_undici.fetch)(this.userInfoUri, { headers, dispatcher: import_common.proxyAgent });
|
|
86
|
+
if (!response.ok) {
|
|
87
|
+
const { errors } = await response.json();
|
|
88
|
+
throw new import_error.OAuth2Error(
|
|
89
|
+
response.status,
|
|
90
|
+
"invalid_request",
|
|
91
|
+
"Failed to fetch user info: " + (errors.at(0)?.detail ?? errors.at(0)?.title)
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
const profile = await response.json();
|
|
95
|
+
return {
|
|
96
|
+
data: profile,
|
|
97
|
+
claims: {
|
|
98
|
+
sub: profile.data.id,
|
|
99
|
+
name: profile.data.name,
|
|
100
|
+
picture: profile.data.profile_image_url,
|
|
101
|
+
email: profile.data.email,
|
|
102
|
+
email_verified: profile.data.verified || false,
|
|
103
|
+
preferred_username: profile.data.username,
|
|
104
|
+
profile: `https://x.com/${profile.data.username}`,
|
|
105
|
+
website: profile.data.url
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
},
|
|
109
|
+
async refreshAccessToken(params) {
|
|
110
|
+
return (0, import_common.refreshAccessToken)({ ...params, tokenUri: this.tokenUri, authentication: "basic" });
|
|
111
|
+
},
|
|
112
|
+
async revokeToken(params) {
|
|
113
|
+
(0, import_tiny_invariant.default)(this.tokenRevokeUri, "tokenRevokeUri is required");
|
|
114
|
+
return (0, import_common.revokeToken)({
|
|
115
|
+
...params,
|
|
116
|
+
tokenRevokeUri: this.tokenRevokeUri,
|
|
117
|
+
authentication: "basic"
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
123
|
+
0 && (module.exports = {
|
|
124
|
+
x
|
|
125
|
+
});
|
|
126
|
+
//# sourceMappingURL=x.cjs.map
|
|
@@ -0,0 +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"]}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Provider } from '../types.cjs';
|
|
2
|
+
|
|
3
|
+
interface XOptions {
|
|
4
|
+
userFields?: UserField[];
|
|
5
|
+
}
|
|
6
|
+
declare function x(options?: XOptions): Provider<XUserInfo>;
|
|
7
|
+
type UserField = 'affiliation' | 'connection_status' | 'created_at' | 'description' | 'entities' | 'id' | 'is_identity_verified' | 'location' | 'most_recent_tweet_id' | 'name' | 'parody' | 'pinned_tweet_id' | 'profile_banner_url' | 'profile_image_url' | 'protected' | 'public_metrics' | 'receives_your_dm' | 'subscription' | 'subscription_type' | 'url' | 'username' | 'verified' | 'verified_followers_count' | 'verified_type' | 'withheld';
|
|
8
|
+
interface XUser {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
email?: string;
|
|
12
|
+
username: string;
|
|
13
|
+
location?: string;
|
|
14
|
+
entities?: {
|
|
15
|
+
url: {
|
|
16
|
+
urls: UrlEntity[];
|
|
17
|
+
};
|
|
18
|
+
description: {
|
|
19
|
+
hashtags: HashtagEntity[];
|
|
20
|
+
cashtags: HashtagEntity[];
|
|
21
|
+
mentions: MentionEntity[];
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
verified?: boolean;
|
|
25
|
+
description?: string;
|
|
26
|
+
url?: string;
|
|
27
|
+
profile_image_url?: string;
|
|
28
|
+
protected?: boolean;
|
|
29
|
+
pinned_tweet_id?: string;
|
|
30
|
+
created_at?: string;
|
|
31
|
+
}
|
|
32
|
+
interface XUserInfo {
|
|
33
|
+
data: XUser;
|
|
34
|
+
includes?: {
|
|
35
|
+
tweets?: {
|
|
36
|
+
id: string;
|
|
37
|
+
text: string;
|
|
38
|
+
}[];
|
|
39
|
+
users?: XUser[];
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
type UrlEntity = {
|
|
43
|
+
start: number;
|
|
44
|
+
end: number;
|
|
45
|
+
url: string;
|
|
46
|
+
display_url: string;
|
|
47
|
+
expanded_url: string;
|
|
48
|
+
};
|
|
49
|
+
type HashtagEntity = {
|
|
50
|
+
start: number;
|
|
51
|
+
end: number;
|
|
52
|
+
tag: string;
|
|
53
|
+
};
|
|
54
|
+
type MentionEntity = {
|
|
55
|
+
start: number;
|
|
56
|
+
end: string;
|
|
57
|
+
username: string;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export { type XOptions, type XUser, type XUserInfo, x };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Provider } from '../types.js';
|
|
2
|
+
|
|
3
|
+
interface XOptions {
|
|
4
|
+
userFields?: UserField[];
|
|
5
|
+
}
|
|
6
|
+
declare function x(options?: XOptions): Provider<XUserInfo>;
|
|
7
|
+
type UserField = 'affiliation' | 'connection_status' | 'created_at' | 'description' | 'entities' | 'id' | 'is_identity_verified' | 'location' | 'most_recent_tweet_id' | 'name' | 'parody' | 'pinned_tweet_id' | 'profile_banner_url' | 'profile_image_url' | 'protected' | 'public_metrics' | 'receives_your_dm' | 'subscription' | 'subscription_type' | 'url' | 'username' | 'verified' | 'verified_followers_count' | 'verified_type' | 'withheld';
|
|
8
|
+
interface XUser {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
email?: string;
|
|
12
|
+
username: string;
|
|
13
|
+
location?: string;
|
|
14
|
+
entities?: {
|
|
15
|
+
url: {
|
|
16
|
+
urls: UrlEntity[];
|
|
17
|
+
};
|
|
18
|
+
description: {
|
|
19
|
+
hashtags: HashtagEntity[];
|
|
20
|
+
cashtags: HashtagEntity[];
|
|
21
|
+
mentions: MentionEntity[];
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
verified?: boolean;
|
|
25
|
+
description?: string;
|
|
26
|
+
url?: string;
|
|
27
|
+
profile_image_url?: string;
|
|
28
|
+
protected?: boolean;
|
|
29
|
+
pinned_tweet_id?: string;
|
|
30
|
+
created_at?: string;
|
|
31
|
+
}
|
|
32
|
+
interface XUserInfo {
|
|
33
|
+
data: XUser;
|
|
34
|
+
includes?: {
|
|
35
|
+
tweets?: {
|
|
36
|
+
id: string;
|
|
37
|
+
text: string;
|
|
38
|
+
}[];
|
|
39
|
+
users?: XUser[];
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
type UrlEntity = {
|
|
43
|
+
start: number;
|
|
44
|
+
end: number;
|
|
45
|
+
url: string;
|
|
46
|
+
display_url: string;
|
|
47
|
+
expanded_url: string;
|
|
48
|
+
};
|
|
49
|
+
type HashtagEntity = {
|
|
50
|
+
start: number;
|
|
51
|
+
end: number;
|
|
52
|
+
tag: string;
|
|
53
|
+
};
|
|
54
|
+
type MentionEntity = {
|
|
55
|
+
start: number;
|
|
56
|
+
end: string;
|
|
57
|
+
username: string;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export { type XOptions, type XUser, type XUserInfo, x };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// src/oauth2/provider/x.ts
|
|
2
|
+
import invariant from "tiny-invariant";
|
|
3
|
+
import { fetch } from "undici";
|
|
4
|
+
import { OAuth2Error } from "../error.mjs";
|
|
5
|
+
import {
|
|
6
|
+
createAuthorizationUri,
|
|
7
|
+
exchangeAuthorizationCode,
|
|
8
|
+
proxyAgent,
|
|
9
|
+
refreshAccessToken,
|
|
10
|
+
revokeToken
|
|
11
|
+
} from "./common.mjs";
|
|
12
|
+
var defaultUserFields = [
|
|
13
|
+
"id",
|
|
14
|
+
"name",
|
|
15
|
+
"profile_image_url",
|
|
16
|
+
"url",
|
|
17
|
+
"username",
|
|
18
|
+
"location",
|
|
19
|
+
"verified"
|
|
20
|
+
];
|
|
21
|
+
function x(options) {
|
|
22
|
+
return {
|
|
23
|
+
authorizationUri: "https://x.com/i/oauth2/authorize",
|
|
24
|
+
tokenUri: "https://api.x.com/2/oauth2/token",
|
|
25
|
+
tokenRevokeUri: "https://api.x.com/2/oauth2/revoke",
|
|
26
|
+
// https://docs.x.com/x-api/users/user-lookup-me
|
|
27
|
+
userInfoUri: "https://api.x.com/2/users/me",
|
|
28
|
+
defaultScope: ["users.read", "tweet.read", "offline.access"],
|
|
29
|
+
createAuthorizationUri(params) {
|
|
30
|
+
if (!params.codeVerifier) throw new Error("codeVerifier is required for x");
|
|
31
|
+
return createAuthorizationUri({
|
|
32
|
+
...params,
|
|
33
|
+
scope: params.scope ?? this.defaultScope,
|
|
34
|
+
authorizationUri: this.authorizationUri
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
async exchangeAuthorizationCode(params) {
|
|
38
|
+
if (!params.codeVerifier) throw new Error("codeVerifier is required for x");
|
|
39
|
+
const response = await exchangeAuthorizationCode({
|
|
40
|
+
...params,
|
|
41
|
+
tokenUri: this.tokenUri,
|
|
42
|
+
authentication: "basic"
|
|
43
|
+
});
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
const { error, error_description } = await response.json();
|
|
46
|
+
throw new OAuth2Error(response.status, error, error_description);
|
|
47
|
+
}
|
|
48
|
+
return await response.json();
|
|
49
|
+
},
|
|
50
|
+
async getUserInfo({ access_token }) {
|
|
51
|
+
invariant(access_token, "access_token is required");
|
|
52
|
+
invariant(this.userInfoUri, "userInfoUri is required");
|
|
53
|
+
const userFields = options?.userFields ?? defaultUserFields;
|
|
54
|
+
const headers = { Accept: "application/json", Authorization: `Bearer ${access_token}` };
|
|
55
|
+
const url = new URL(this.userInfoUri);
|
|
56
|
+
userFields.forEach((field) => url.searchParams.append("user.fields", field));
|
|
57
|
+
const response = await fetch(this.userInfoUri, { headers, dispatcher: proxyAgent });
|
|
58
|
+
if (!response.ok) {
|
|
59
|
+
const { errors } = await response.json();
|
|
60
|
+
throw new OAuth2Error(
|
|
61
|
+
response.status,
|
|
62
|
+
"invalid_request",
|
|
63
|
+
"Failed to fetch user info: " + (errors.at(0)?.detail ?? errors.at(0)?.title)
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
const profile = await response.json();
|
|
67
|
+
return {
|
|
68
|
+
data: profile,
|
|
69
|
+
claims: {
|
|
70
|
+
sub: profile.data.id,
|
|
71
|
+
name: profile.data.name,
|
|
72
|
+
picture: profile.data.profile_image_url,
|
|
73
|
+
email: profile.data.email,
|
|
74
|
+
email_verified: profile.data.verified || false,
|
|
75
|
+
preferred_username: profile.data.username,
|
|
76
|
+
profile: `https://x.com/${profile.data.username}`,
|
|
77
|
+
website: profile.data.url
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
async refreshAccessToken(params) {
|
|
82
|
+
return refreshAccessToken({ ...params, tokenUri: this.tokenUri, authentication: "basic" });
|
|
83
|
+
},
|
|
84
|
+
async revokeToken(params) {
|
|
85
|
+
invariant(this.tokenRevokeUri, "tokenRevokeUri is required");
|
|
86
|
+
return revokeToken({
|
|
87
|
+
...params,
|
|
88
|
+
tokenRevokeUri: this.tokenRevokeUri,
|
|
89
|
+
authentication: "basic"
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
export {
|
|
95
|
+
x
|
|
96
|
+
};
|
|
97
|
+
//# sourceMappingURL=x.mjs.map
|
|
@@ -0,0 +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":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=schema.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,19 @@
|
|
|
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 __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
|
|
16
|
+
// src/oauth2/types.ts
|
|
17
|
+
var types_exports = {};
|
|
18
|
+
module.exports = __toCommonJS(types_exports);
|
|
19
|
+
//# sourceMappingURL=types.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/oauth2/types.ts"],"sourcesContent":["export interface OAuth2AuthorizationRequest {\n state: string;\n codeVerifier: string;\n registrationId: string;\n authorizationRequestUri: string;\n}\n\ninterface CreateAuthorizationUriParams {\n state: string;\n clientId: string;\n redirectUri: string;\n scope: string[] | undefined;\n codeVerifier?: string;\n}\n\nexport interface CodeExchangeParams {\n code: string;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n codeVerifier?: string;\n}\n\nexport interface RefreshTokenParams {\n clientId: string;\n clientSecret: string;\n refreshToken: string;\n}\n\nexport interface RevokeTokenParams {\n token: string;\n clientId: string;\n clientSecret: string;\n}\n\nexport interface OAuth2Token {\n access_token?: string;\n token_type?: 'Bearer' | 'bearer' | string;\n expires_in?: number;\n refresh_token?: string;\n id_token?: string;\n scope?: string;\n}\n\n// https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims\nexport interface StandardClaims {\n sub: string;\n name?: string;\n given_name?: string;\n family_name?: string;\n middle_name?: string;\n nickname?: string;\n preferred_username?: string;\n profile?: string;\n picture?: string;\n website?: string;\n email?: string;\n email_verified?: boolean;\n gender?: 'female' | 'male' | string;\n birthdate?: string; // ISO 8601-1 [ISO8601‑1] YYYY-MM-DD format.\n zoneinfo?: string; // IANA Time Zone Database [IANA.time‑zones]\n locale?: string; // BCP47 [RFC5646] language tag.\n phone_number?: string; // E.164\n phone_number_verified?: boolean;\n address?: {\n formatted: string;\n street_address: string;\n locality: string;\n region: string;\n postal_code: string;\n country: string;\n }; // [RFC8259] JSON object\n updated_at?: number;\n}\n\nexport interface UserInfo<T extends Record<string, any> = Record<string, any>> {\n claims: StandardClaims;\n data: T;\n}\n\nexport interface Provider<T extends Record<string, any> = Record<string, any>> {\n /** Authorization URI for the provider. */\n authorizationUri: string;\n\n /** Token URI for the provider. */\n tokenUri: string;\n\n tokenRevokeUri?: string;\n\n /** User info URI for the provider. */\n userInfoUri?: string;\n\n /** User info authentication method for the provider. */\n userInfoAuthenticationMethod?: string;\n\n /**\n * Name of the attribute that will be used to extract the username from the call to 'userInfoUri'.\n * */\n userNameAttribute?: string;\n\n /** JWK set URI for the provider */\n jwkSetUri?: string;\n\n /**\n * URI that can either be an OpenID Connect discovery endpoint or an OAuth 2.0 Authorization\n * Server Metadata endpoint defined by RFC 8414.\n * */\n issuerUri?: string;\n\n /** Default scopes for the provider. */\n defaultScope: string[];\n\n /** step 1: generate authorization uri and redirect user to it */\n createAuthorizationUri: (params: CreateAuthorizationUriParams) => URL;\n\n /** step 2: exchange code for token */\n exchangeAuthorizationCode: (params: CodeExchangeParams) => Promise<OAuth2Token>;\n\n /** step 3: get user info */\n getUserInfo: (token: OAuth2Token) => Promise<UserInfo<T>>;\n\n /** others: refresh access token */\n refreshAccessToken?: (params: RefreshTokenParams) => Promise<OAuth2Token>;\n\n /** others: revoke token */\n revokeToken?: (params: RevokeTokenParams) => Promise<void>;\n}\n\nexport interface Registration {\n /**\n * Reference to the OAuth 2.0 provider to use. May reference an element from the 'provider'\n * property or used one of the commonly used providers (google, github, facebook, okta).\n * */\n provider?: string;\n\n /** Client ID for the registration. */\n clientId: string;\n\n /** Client secret of the registration. */\n clientSecret: string;\n\n /** Client authentication method. May be left blank when using a pre-defined provider. */\n clientAuthenticationMethod?: string;\n\n /** Authorization grant type. May be left blank when using a pre-defined provider. */\n authorizationGrantType?:\n | 'authorization_code' // default\n | 'client_credentials'\n | 'device_code'\n | 'jwt_bearer'\n // Deprecated. The latest OAuth 2.0 Security Best Current Practice disallows the use of the\n // Resource Owner Password Credentials grant.\n | 'password'\n | 'refresh_token'\n | 'token_exchange';\n\n /** Redirect URI. May be left blank when using a pre-defined provider. */\n redirectUri?: string;\n\n /** Authorization scopes. When left blank the provider's default scopes, if any, will be used. */\n scope?: string[];\n\n /** Client name. May be left blank when using a pre-defined provider. */\n clientName?: string;\n}\n\nexport interface OAuth2ClientConfig {\n baseUri: string;\n errorUri: string;\n provider: { [name: string]: Provider | undefined };\n registration: { [name: string]: Registration | undefined };\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
interface OAuth2AuthorizationRequest {
|
|
2
|
+
state: string;
|
|
3
|
+
codeVerifier: string;
|
|
4
|
+
registrationId: string;
|
|
5
|
+
authorizationRequestUri: string;
|
|
6
|
+
}
|
|
7
|
+
interface CreateAuthorizationUriParams {
|
|
8
|
+
state: string;
|
|
9
|
+
clientId: string;
|
|
10
|
+
redirectUri: string;
|
|
11
|
+
scope: string[] | undefined;
|
|
12
|
+
codeVerifier?: string;
|
|
13
|
+
}
|
|
14
|
+
interface CodeExchangeParams {
|
|
15
|
+
code: string;
|
|
16
|
+
clientId: string;
|
|
17
|
+
clientSecret: string;
|
|
18
|
+
redirectUri: string;
|
|
19
|
+
codeVerifier?: string;
|
|
20
|
+
}
|
|
21
|
+
interface RefreshTokenParams {
|
|
22
|
+
clientId: string;
|
|
23
|
+
clientSecret: string;
|
|
24
|
+
refreshToken: string;
|
|
25
|
+
}
|
|
26
|
+
interface RevokeTokenParams {
|
|
27
|
+
token: string;
|
|
28
|
+
clientId: string;
|
|
29
|
+
clientSecret: string;
|
|
30
|
+
}
|
|
31
|
+
interface OAuth2Token {
|
|
32
|
+
access_token?: string;
|
|
33
|
+
token_type?: 'Bearer' | 'bearer' | string;
|
|
34
|
+
expires_in?: number;
|
|
35
|
+
refresh_token?: string;
|
|
36
|
+
id_token?: string;
|
|
37
|
+
scope?: string;
|
|
38
|
+
}
|
|
39
|
+
interface StandardClaims {
|
|
40
|
+
sub: string;
|
|
41
|
+
name?: string;
|
|
42
|
+
given_name?: string;
|
|
43
|
+
family_name?: string;
|
|
44
|
+
middle_name?: string;
|
|
45
|
+
nickname?: string;
|
|
46
|
+
preferred_username?: string;
|
|
47
|
+
profile?: string;
|
|
48
|
+
picture?: string;
|
|
49
|
+
website?: string;
|
|
50
|
+
email?: string;
|
|
51
|
+
email_verified?: boolean;
|
|
52
|
+
gender?: 'female' | 'male' | string;
|
|
53
|
+
birthdate?: string;
|
|
54
|
+
zoneinfo?: string;
|
|
55
|
+
locale?: string;
|
|
56
|
+
phone_number?: string;
|
|
57
|
+
phone_number_verified?: boolean;
|
|
58
|
+
address?: {
|
|
59
|
+
formatted: string;
|
|
60
|
+
street_address: string;
|
|
61
|
+
locality: string;
|
|
62
|
+
region: string;
|
|
63
|
+
postal_code: string;
|
|
64
|
+
country: string;
|
|
65
|
+
};
|
|
66
|
+
updated_at?: number;
|
|
67
|
+
}
|
|
68
|
+
interface UserInfo<T extends Record<string, any> = Record<string, any>> {
|
|
69
|
+
claims: StandardClaims;
|
|
70
|
+
data: T;
|
|
71
|
+
}
|
|
72
|
+
interface Provider<T extends Record<string, any> = Record<string, any>> {
|
|
73
|
+
/** Authorization URI for the provider. */
|
|
74
|
+
authorizationUri: string;
|
|
75
|
+
/** Token URI for the provider. */
|
|
76
|
+
tokenUri: string;
|
|
77
|
+
tokenRevokeUri?: string;
|
|
78
|
+
/** User info URI for the provider. */
|
|
79
|
+
userInfoUri?: string;
|
|
80
|
+
/** User info authentication method for the provider. */
|
|
81
|
+
userInfoAuthenticationMethod?: string;
|
|
82
|
+
/**
|
|
83
|
+
* Name of the attribute that will be used to extract the username from the call to 'userInfoUri'.
|
|
84
|
+
* */
|
|
85
|
+
userNameAttribute?: string;
|
|
86
|
+
/** JWK set URI for the provider */
|
|
87
|
+
jwkSetUri?: string;
|
|
88
|
+
/**
|
|
89
|
+
* URI that can either be an OpenID Connect discovery endpoint or an OAuth 2.0 Authorization
|
|
90
|
+
* Server Metadata endpoint defined by RFC 8414.
|
|
91
|
+
* */
|
|
92
|
+
issuerUri?: string;
|
|
93
|
+
/** Default scopes for the provider. */
|
|
94
|
+
defaultScope: string[];
|
|
95
|
+
/** step 1: generate authorization uri and redirect user to it */
|
|
96
|
+
createAuthorizationUri: (params: CreateAuthorizationUriParams) => URL;
|
|
97
|
+
/** step 2: exchange code for token */
|
|
98
|
+
exchangeAuthorizationCode: (params: CodeExchangeParams) => Promise<OAuth2Token>;
|
|
99
|
+
/** step 3: get user info */
|
|
100
|
+
getUserInfo: (token: OAuth2Token) => Promise<UserInfo<T>>;
|
|
101
|
+
/** others: refresh access token */
|
|
102
|
+
refreshAccessToken?: (params: RefreshTokenParams) => Promise<OAuth2Token>;
|
|
103
|
+
/** others: revoke token */
|
|
104
|
+
revokeToken?: (params: RevokeTokenParams) => Promise<void>;
|
|
105
|
+
}
|
|
106
|
+
interface Registration {
|
|
107
|
+
/**
|
|
108
|
+
* Reference to the OAuth 2.0 provider to use. May reference an element from the 'provider'
|
|
109
|
+
* property or used one of the commonly used providers (google, github, facebook, okta).
|
|
110
|
+
* */
|
|
111
|
+
provider?: string;
|
|
112
|
+
/** Client ID for the registration. */
|
|
113
|
+
clientId: string;
|
|
114
|
+
/** Client secret of the registration. */
|
|
115
|
+
clientSecret: string;
|
|
116
|
+
/** Client authentication method. May be left blank when using a pre-defined provider. */
|
|
117
|
+
clientAuthenticationMethod?: string;
|
|
118
|
+
/** Authorization grant type. May be left blank when using a pre-defined provider. */
|
|
119
|
+
authorizationGrantType?: 'authorization_code' | 'client_credentials' | 'device_code' | 'jwt_bearer' | 'password' | 'refresh_token' | 'token_exchange';
|
|
120
|
+
/** Redirect URI. May be left blank when using a pre-defined provider. */
|
|
121
|
+
redirectUri?: string;
|
|
122
|
+
/** Authorization scopes. When left blank the provider's default scopes, if any, will be used. */
|
|
123
|
+
scope?: string[];
|
|
124
|
+
/** Client name. May be left blank when using a pre-defined provider. */
|
|
125
|
+
clientName?: string;
|
|
126
|
+
}
|
|
127
|
+
interface OAuth2ClientConfig {
|
|
128
|
+
baseUri: string;
|
|
129
|
+
errorUri: string;
|
|
130
|
+
provider: {
|
|
131
|
+
[name: string]: Provider | undefined;
|
|
132
|
+
};
|
|
133
|
+
registration: {
|
|
134
|
+
[name: string]: Registration | undefined;
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export type { CodeExchangeParams, OAuth2AuthorizationRequest, OAuth2ClientConfig, OAuth2Token, Provider, RefreshTokenParams, Registration, RevokeTokenParams, StandardClaims, UserInfo };
|