@shware/security 7.1.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +108 -30
- package/dist/auth/attributes.cjs +5 -5
- package/dist/auth/attributes.cjs.map +1 -1
- package/dist/auth/attributes.d.cts +3 -5
- package/dist/auth/attributes.d.cts.map +1 -1
- package/dist/auth/attributes.d.mts +3 -5
- package/dist/auth/attributes.d.mts.map +1 -1
- package/dist/auth/attributes.mjs +5 -5
- package/dist/auth/attributes.mjs.map +1 -1
- package/dist/auth/desktop-codes.cjs +57 -0
- package/dist/auth/desktop-codes.cjs.map +1 -0
- package/dist/auth/desktop-codes.d.cts +24 -0
- package/dist/auth/desktop-codes.d.cts.map +1 -0
- package/dist/auth/desktop-codes.d.mts +24 -0
- package/dist/auth/desktop-codes.d.mts.map +1 -0
- package/dist/auth/desktop-codes.mjs +55 -0
- package/dist/auth/desktop-codes.mjs.map +1 -0
- package/dist/auth/email-codes.cjs +77 -0
- package/dist/auth/email-codes.cjs.map +1 -0
- package/dist/auth/email-codes.d.cts +39 -0
- package/dist/auth/email-codes.d.cts.map +1 -0
- package/dist/auth/email-codes.d.mts +39 -0
- package/dist/auth/email-codes.d.mts.map +1 -0
- package/dist/auth/email-codes.mjs +75 -0
- package/dist/auth/email-codes.mjs.map +1 -0
- package/dist/auth/error.cjs +47 -0
- package/dist/auth/error.cjs.map +1 -0
- package/dist/auth/error.d.cts +88 -0
- package/dist/auth/error.d.cts.map +1 -0
- package/dist/auth/error.d.mts +88 -0
- package/dist/auth/error.d.mts.map +1 -0
- package/dist/auth/error.mjs +45 -0
- package/dist/auth/error.mjs.map +1 -0
- package/dist/auth/index.cjs +245 -385
- package/dist/auth/index.cjs.map +1 -1
- package/dist/auth/index.d.cts +66 -57
- package/dist/auth/index.d.cts.map +1 -1
- package/dist/auth/index.d.mts +66 -57
- package/dist/auth/index.d.mts.map +1 -1
- package/dist/auth/index.mjs +248 -388
- package/dist/auth/index.mjs.map +1 -1
- package/dist/auth/respond.cjs +99 -0
- package/dist/auth/respond.cjs.map +1 -0
- package/dist/auth/respond.d.cts +39 -0
- package/dist/auth/respond.d.cts.map +1 -0
- package/dist/auth/respond.d.mts +39 -0
- package/dist/auth/respond.d.mts.map +1 -0
- package/dist/auth/respond.mjs +92 -0
- package/dist/auth/respond.mjs.map +1 -0
- package/dist/auth/types.d.cts +27 -13
- package/dist/auth/types.d.cts.map +1 -1
- package/dist/auth/types.d.mts +27 -13
- package/dist/auth/types.d.mts.map +1 -1
- package/dist/core/index.cjs +1 -2
- package/dist/core/index.d.cts +0 -2
- package/dist/core/index.d.cts.map +1 -1
- package/dist/core/index.d.mts +0 -2
- package/dist/core/index.d.mts.map +1 -1
- package/dist/core/index.mjs +1 -2
- package/dist/email/schema.cjs +1 -2
- package/dist/email/schema.d.cts +0 -2
- package/dist/email/schema.d.cts.map +1 -1
- package/dist/email/schema.d.mts +0 -2
- package/dist/email/schema.d.mts.map +1 -1
- package/dist/email/schema.mjs +1 -2
- package/dist/index.cjs +5 -0
- package/dist/index.d.cts +4 -1
- package/dist/index.d.mts +4 -1
- package/dist/index.mjs +3 -1
- package/dist/oauth2/client.cjs +1 -2
- package/dist/oauth2/client.d.cts +0 -2
- package/dist/oauth2/client.d.cts.map +1 -1
- package/dist/oauth2/client.d.mts +0 -2
- package/dist/oauth2/client.d.mts.map +1 -1
- package/dist/oauth2/client.mjs +1 -2
- package/dist/oauth2/error.cjs +1 -9
- package/dist/oauth2/error.cjs.map +1 -1
- package/dist/oauth2/error.d.cts +0 -5
- package/dist/oauth2/error.d.cts.map +1 -1
- package/dist/oauth2/error.d.mts +0 -5
- package/dist/oauth2/error.d.mts.map +1 -1
- package/dist/oauth2/error.mjs +2 -9
- package/dist/oauth2/error.mjs.map +1 -1
- package/dist/oauth2/name.cjs +1 -2
- package/dist/oauth2/name.d.cts +0 -2
- package/dist/oauth2/name.d.cts.map +1 -1
- package/dist/oauth2/name.d.mts +0 -2
- package/dist/oauth2/name.d.mts.map +1 -1
- package/dist/oauth2/name.mjs +1 -2
- package/dist/oauth2/provider/apple-client-secret.cjs +1 -2
- package/dist/oauth2/provider/apple-client-secret.d.cts +0 -2
- package/dist/oauth2/provider/apple-client-secret.d.cts.map +1 -1
- package/dist/oauth2/provider/apple-client-secret.d.mts +0 -2
- package/dist/oauth2/provider/apple-client-secret.d.mts.map +1 -1
- package/dist/oauth2/provider/apple-client-secret.mjs +1 -2
- package/dist/oauth2/provider/apple.cjs +1 -2
- package/dist/oauth2/provider/apple.d.cts +0 -2
- package/dist/oauth2/provider/apple.d.cts.map +1 -1
- package/dist/oauth2/provider/apple.d.mts +0 -2
- package/dist/oauth2/provider/apple.d.mts.map +1 -1
- package/dist/oauth2/provider/apple.mjs +1 -2
- package/dist/oauth2/provider/common.cjs +2 -3
- package/dist/oauth2/provider/common.cjs.map +1 -1
- package/dist/oauth2/provider/common.d.cts +0 -2
- package/dist/oauth2/provider/common.d.cts.map +1 -1
- package/dist/oauth2/provider/common.d.mts +0 -2
- package/dist/oauth2/provider/common.d.mts.map +1 -1
- package/dist/oauth2/provider/common.mjs +2 -3
- package/dist/oauth2/provider/common.mjs.map +1 -1
- package/dist/oauth2/provider/facebook.cjs +3 -6
- package/dist/oauth2/provider/facebook.cjs.map +1 -1
- package/dist/oauth2/provider/facebook.d.cts +0 -3
- package/dist/oauth2/provider/facebook.d.cts.map +1 -1
- package/dist/oauth2/provider/facebook.d.mts +0 -3
- package/dist/oauth2/provider/facebook.d.mts.map +1 -1
- package/dist/oauth2/provider/facebook.mjs +3 -6
- package/dist/oauth2/provider/facebook.mjs.map +1 -1
- package/dist/oauth2/provider/github.cjs +1 -2
- package/dist/oauth2/provider/github.d.cts +0 -2
- package/dist/oauth2/provider/github.d.cts.map +1 -1
- package/dist/oauth2/provider/github.d.mts +0 -2
- package/dist/oauth2/provider/github.d.mts.map +1 -1
- package/dist/oauth2/provider/github.mjs +1 -2
- package/dist/oauth2/provider/google.cjs +1 -2
- package/dist/oauth2/provider/google.d.cts +0 -2
- package/dist/oauth2/provider/google.d.cts.map +1 -1
- package/dist/oauth2/provider/google.d.mts +0 -2
- package/dist/oauth2/provider/google.d.mts.map +1 -1
- package/dist/oauth2/provider/google.mjs +1 -2
- package/dist/oauth2/provider/wechat.cjs +1 -2
- package/dist/oauth2/provider/wechat.d.cts +0 -2
- package/dist/oauth2/provider/wechat.d.cts.map +1 -1
- package/dist/oauth2/provider/wechat.d.mts +0 -2
- package/dist/oauth2/provider/wechat.d.mts.map +1 -1
- package/dist/oauth2/provider/wechat.mjs +1 -2
- package/dist/oauth2/provider/x.cjs +7 -6
- package/dist/oauth2/provider/x.cjs.map +1 -1
- package/dist/oauth2/provider/x.d.cts +3 -4
- package/dist/oauth2/provider/x.d.cts.map +1 -1
- package/dist/oauth2/provider/x.d.mts +3 -4
- package/dist/oauth2/provider/x.d.mts.map +1 -1
- package/dist/oauth2/provider/x.mjs +7 -6
- package/dist/oauth2/provider/x.mjs.map +1 -1
- package/dist/oauth2/types.cjs +1 -2
- package/dist/oauth2/types.cjs.map +1 -1
- package/dist/oauth2/types.d.cts +5 -2
- package/dist/oauth2/types.d.cts.map +1 -1
- package/dist/oauth2/types.d.mts +5 -2
- package/dist/oauth2/types.d.mts.map +1 -1
- package/dist/oauth2/types.mjs +1 -2
- package/dist/oauth2/types.mjs.map +1 -1
- package/dist/session/common.cjs +11 -15
- package/dist/session/common.cjs.map +1 -1
- package/dist/session/common.d.cts +7 -5
- package/dist/session/common.d.cts.map +1 -1
- package/dist/session/common.d.mts +7 -5
- package/dist/session/common.d.mts.map +1 -1
- package/dist/session/common.mjs +11 -14
- package/dist/session/common.mjs.map +1 -1
- package/dist/session/db.cjs +3 -4
- package/dist/session/db.cjs.map +1 -1
- package/dist/session/db.d.cts +0 -2
- package/dist/session/db.d.cts.map +1 -1
- package/dist/session/db.d.mts +0 -2
- package/dist/session/db.d.mts.map +1 -1
- package/dist/session/db.mjs +4 -5
- package/dist/session/db.mjs.map +1 -1
- package/dist/session/map-session.cjs +1 -2
- package/dist/session/map-session.d.cts +0 -2
- package/dist/session/map-session.d.cts.map +1 -1
- package/dist/session/map-session.d.mts +0 -2
- package/dist/session/map-session.d.mts.map +1 -1
- package/dist/session/map-session.mjs +1 -2
- package/dist/session/redis.cjs +7 -10
- package/dist/session/redis.cjs.map +1 -1
- package/dist/session/redis.d.cts +0 -2
- package/dist/session/redis.d.cts.map +1 -1
- package/dist/session/redis.d.mts +0 -2
- package/dist/session/redis.d.mts.map +1 -1
- package/dist/session/redis.mjs +8 -11
- package/dist/session/redis.mjs.map +1 -1
- package/dist/session/types.d.cts +0 -14
- package/dist/session/types.d.cts.map +1 -1
- package/dist/session/types.d.mts +0 -14
- package/dist/session/types.d.mts.map +1 -1
- package/dist/utils/http.cjs +1 -2
- package/dist/utils/http.d.cts +0 -2
- package/dist/utils/http.d.cts.map +1 -1
- package/dist/utils/http.d.mts +0 -2
- package/dist/utils/http.d.mts.map +1 -1
- package/dist/utils/http.mjs +1 -2
- package/dist/utils/oauth2.cjs +1 -2
- package/dist/utils/oauth2.d.cts +0 -2
- package/dist/utils/oauth2.d.cts.map +1 -1
- package/dist/utils/oauth2.d.mts +0 -2
- package/dist/utils/oauth2.d.mts.map +1 -1
- package/dist/utils/oauth2.mjs +1 -2
- package/dist/utils/timing.cjs +1 -2
- package/dist/utils/timing.d.cts +0 -2
- package/dist/utils/timing.d.cts.map +1 -1
- package/dist/utils/timing.d.mts +0 -2
- package/dist/utils/timing.d.mts.map +1 -1
- package/dist/utils/timing.mjs +1 -2
- package/dist/utils/valid.cjs +35 -54
- package/dist/utils/valid.cjs.map +1 -1
- package/dist/utils/valid.d.cts +8 -25
- package/dist/utils/valid.d.cts.map +1 -1
- package/dist/utils/valid.d.mts +8 -25
- package/dist/utils/valid.d.mts.map +1 -1
- package/dist/utils/valid.mjs +33 -52
- package/dist/utils/valid.mjs.map +1 -1
- package/package.json +4 -4
package/dist/oauth2/name.d.mts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { PersonNameComponents, StandardClaims } from "./types.mjs";
|
|
2
|
-
//#region src/oauth2/name.d.ts
|
|
3
2
|
/**
|
|
4
3
|
* Upper bound, in characters, on each name part taken from the client. Names that reach us outside
|
|
5
4
|
* a signed token (Apple's form_post `user`, a native login body) are plain client input, so they
|
|
@@ -44,6 +43,5 @@ type NameClaims = Pick<StandardClaims, 'name' | 'given_name' | 'family_name' | '
|
|
|
44
43
|
* Undefined parts are left out, so spreading the result never overwrites a claim with `undefined`.
|
|
45
44
|
*/
|
|
46
45
|
export declare function nameClaims(parts: Omit<NameClaims, 'name'>): NameClaims;
|
|
47
|
-
//#endregion
|
|
48
46
|
export {};
|
|
49
47
|
//# sourceMappingURL=name.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"name.d.mts","names":[],"sources":["../../src/oauth2/name.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"name.d.mts","names":[],"sources":["../../src/oauth2/name.ts"],"mappings":";;;;;;qBAOa;;;;;;;wBAaG,cACd,YACA,eACC,KAAK;;;;;;wBAcQ,cAAc;;iBAQb;EACf;IAAS;IAAoB;;EAC7B;;;;;;;wBAQc,eAAe,0BAA0B;;;;;wBAkCzC,gBAAgB,iBAAiB;KAU5C,aAAa,KAChB;;;;;wBAQc,WAAW,OAAO,KAAK,sBAAsB"}
|
package/dist/oauth2/name.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/oauth2/name.ts
|
|
2
2
|
/**
|
|
3
3
|
* Upper bound, in characters, on each name part taken from the client. Names that reach us outside
|
|
4
4
|
* a signed token (Apple's form_post `user`, a native login body) are plain client input, so they
|
|
@@ -95,7 +95,6 @@ function isObject(value) {
|
|
|
95
95
|
function withoutUndefined(value) {
|
|
96
96
|
return Object.fromEntries(Object.entries(value).filter(([, v]) => v !== void 0));
|
|
97
97
|
}
|
|
98
|
-
//#endregion
|
|
99
98
|
export { MAX_NAME_PART_LENGTH, cleanNamePart, cleanPersonName, composeName, nameClaims, parseAppleUser };
|
|
100
99
|
|
|
101
100
|
//# sourceMappingURL=name.mjs.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
let jose = require("jose");
|
|
3
|
-
|
|
3
|
+
// src/oauth2/provider/apple-client-secret.ts
|
|
4
4
|
/**
|
|
5
5
|
* Sign in with Apple has no static client secret: the secret is a JWT the server signs with its
|
|
6
6
|
* Sign in with Apple key (ES256, `iss` = team, `sub` = client id, `aud` = appleid.apple.com), and
|
|
@@ -40,7 +40,6 @@ function createAppleClientSecret(options) {
|
|
|
40
40
|
return secret;
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
-
//#endregion
|
|
44
43
|
exports.createAppleClientSecret = createAppleClientSecret;
|
|
45
44
|
|
|
46
45
|
//# sourceMappingURL=apple-client-secret.cjs.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
//#region src/oauth2/provider/apple-client-secret.d.ts
|
|
2
1
|
export interface AppleClientSecretOptions {
|
|
3
2
|
/** Apple Developer Team ID (Membership details). */
|
|
4
3
|
teamId: string;
|
|
@@ -23,5 +22,4 @@ export interface AppleClientSecretOptions {
|
|
|
23
22
|
* instead of generating, storing and rotating static ones by hand.
|
|
24
23
|
*/
|
|
25
24
|
export declare function createAppleClientSecret(options: AppleClientSecretOptions): (clientId: string) => Promise<string>;
|
|
26
|
-
//#endregion
|
|
27
25
|
//# sourceMappingURL=apple-client-secret.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apple-client-secret.d.cts","names":[],"sources":["../../../src/oauth2/provider/apple-client-secret.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"apple-client-secret.d.cts","names":[],"sources":["../../../src/oauth2/provider/apple-client-secret.ts"],"mappings":"A,iBAEiB;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;;;;;;;wBAcc,wBAAwB,SAAS,4BAAwB,qBAmBZ"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
//#region src/oauth2/provider/apple-client-secret.d.ts
|
|
2
1
|
export interface AppleClientSecretOptions {
|
|
3
2
|
/** Apple Developer Team ID (Membership details). */
|
|
4
3
|
teamId: string;
|
|
@@ -23,5 +22,4 @@ export interface AppleClientSecretOptions {
|
|
|
23
22
|
* instead of generating, storing and rotating static ones by hand.
|
|
24
23
|
*/
|
|
25
24
|
export declare function createAppleClientSecret(options: AppleClientSecretOptions): (clientId: string) => Promise<string>;
|
|
26
|
-
//#endregion
|
|
27
25
|
//# sourceMappingURL=apple-client-secret.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apple-client-secret.d.mts","names":[],"sources":["../../../src/oauth2/provider/apple-client-secret.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"apple-client-secret.d.mts","names":[],"sources":["../../../src/oauth2/provider/apple-client-secret.ts"],"mappings":"A,iBAEiB;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;;;;;;;wBAcc,wBAAwB,SAAS,4BAAwB,qBAmBZ"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SignJWT, importPKCS8 } from "jose";
|
|
2
|
-
|
|
2
|
+
// src/oauth2/provider/apple-client-secret.ts
|
|
3
3
|
/**
|
|
4
4
|
* Sign in with Apple has no static client secret: the secret is a JWT the server signs with its
|
|
5
5
|
* Sign in with Apple key (ES256, `iss` = team, `sub` = client id, `aud` = appleid.apple.com), and
|
|
@@ -39,7 +39,6 @@ function createAppleClientSecret(options) {
|
|
|
39
39
|
return secret;
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
-
//#endregion
|
|
43
42
|
export { createAppleClientSecret };
|
|
44
43
|
|
|
45
44
|
//# sourceMappingURL=apple-client-secret.mjs.map
|
|
@@ -3,7 +3,7 @@ const require_oauth2_error = require("../error.cjs");
|
|
|
3
3
|
const require_oauth2_name = require("../name.cjs");
|
|
4
4
|
const require_oauth2_provider_common = require("./common.cjs");
|
|
5
5
|
let _shware_utils = require("@shware/utils");
|
|
6
|
-
|
|
6
|
+
// src/oauth2/provider/apple.ts
|
|
7
7
|
/** `iss` of every Apple id token (https://appleid.apple.com/.well-known/openid-configuration). */
|
|
8
8
|
const APPLE_ISSUER = "https://appleid.apple.com";
|
|
9
9
|
function createAppleProvider() {
|
|
@@ -99,7 +99,6 @@ function createAppleProvider() {
|
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
101
|
const apple = createAppleProvider();
|
|
102
|
-
//#endregion
|
|
103
102
|
exports.apple = apple;
|
|
104
103
|
exports.createAppleProvider = createAppleProvider;
|
|
105
104
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { NativeCredential, OAuth2Token, PersonNameComponents, Provider } from "../types.cjs";
|
|
2
2
|
import { AppleUser } from "../name.cjs";
|
|
3
|
-
//#region src/oauth2/provider/apple.d.ts
|
|
4
3
|
export declare function createAppleProvider(): Provider;
|
|
5
4
|
export declare const apple: Provider;
|
|
6
5
|
export interface AppleIdToken {
|
|
@@ -42,5 +41,4 @@ export interface AppleNativeCredential extends NativeCredential {
|
|
|
42
41
|
export interface AppleErrorResponse {
|
|
43
42
|
error: 'invalid_request' | 'invalid_client' | 'invalid_grant' | 'unauthorized_client' | 'unsupported_grant_type' | 'invalid_scope';
|
|
44
43
|
}
|
|
45
|
-
//#endregion
|
|
46
44
|
//# sourceMappingURL=apple.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apple.d.cts","names":[],"sources":["../../../src/oauth2/provider/apple.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"apple.d.cts","names":[],"sources":["../../../src/oauth2/provider/apple.ts"],"mappings":";;wBAiBgB,uBAAuB;qBAgF1B,OAAK;iBAID;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;;;;;;iBAOe,sBAAsB;;EAErC,OAAO;;EAEP,WAAW;;iBAKI,mBAAmB;EAClC;EACA;EACA;EACA;EACA;;iBAGe,8BAA8B;EAC7C;EACA;EACA;;iBAIe;EACf"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { NativeCredential, OAuth2Token, PersonNameComponents, Provider } from "../types.mjs";
|
|
2
2
|
import { AppleUser } from "../name.mjs";
|
|
3
|
-
//#region src/oauth2/provider/apple.d.ts
|
|
4
3
|
export declare function createAppleProvider(): Provider;
|
|
5
4
|
export declare const apple: Provider;
|
|
6
5
|
export interface AppleIdToken {
|
|
@@ -42,5 +41,4 @@ export interface AppleNativeCredential extends NativeCredential {
|
|
|
42
41
|
export interface AppleErrorResponse {
|
|
43
42
|
error: 'invalid_request' | 'invalid_client' | 'invalid_grant' | 'unauthorized_client' | 'unsupported_grant_type' | 'invalid_scope';
|
|
44
43
|
}
|
|
45
|
-
//#endregion
|
|
46
44
|
//# sourceMappingURL=apple.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apple.d.mts","names":[],"sources":["../../../src/oauth2/provider/apple.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"apple.d.mts","names":[],"sources":["../../../src/oauth2/provider/apple.ts"],"mappings":";;wBAiBgB,uBAAuB;qBAgF1B,OAAK;iBAID;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;;;;;;iBAOe,sBAAsB;;EAErC,OAAO;;EAEP,WAAW;;iBAKI,mBAAmB;EAClC;EACA;EACA;EACA;EACA;;iBAGe,8BAA8B;EAC7C;EACA;EACA;;iBAIe;EACf"}
|
|
@@ -2,7 +2,7 @@ import { OAuth2Error } from "../error.mjs";
|
|
|
2
2
|
import { cleanPersonName, nameClaims, parseAppleUser } from "../name.mjs";
|
|
3
3
|
import { createAuthorizationUri, exchangeAuthorizationCode, verifyIdToken } from "./common.mjs";
|
|
4
4
|
import { invariant } from "@shware/utils";
|
|
5
|
-
|
|
5
|
+
// src/oauth2/provider/apple.ts
|
|
6
6
|
/** `iss` of every Apple id token (https://appleid.apple.com/.well-known/openid-configuration). */
|
|
7
7
|
const APPLE_ISSUER = "https://appleid.apple.com";
|
|
8
8
|
function createAppleProvider() {
|
|
@@ -98,7 +98,6 @@ function createAppleProvider() {
|
|
|
98
98
|
};
|
|
99
99
|
}
|
|
100
100
|
const apple = createAppleProvider();
|
|
101
|
-
//#endregion
|
|
102
101
|
export { apple, createAppleProvider };
|
|
103
102
|
|
|
104
103
|
//# sourceMappingURL=apple.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_oauth2_error = require("../error.cjs");
|
|
3
3
|
let jose = require("jose");
|
|
4
|
-
|
|
4
|
+
// src/oauth2/provider/common.ts
|
|
5
5
|
function createAuthorizationUri(options) {
|
|
6
6
|
const url = new URL(options.authorizationUri);
|
|
7
7
|
url.searchParams.append("response_type", "code");
|
|
@@ -90,10 +90,9 @@ async function verifyIdToken(idToken, options) {
|
|
|
90
90
|
return payload;
|
|
91
91
|
} catch (error) {
|
|
92
92
|
console.error("Failed to verify id_token", error);
|
|
93
|
-
throw new require_oauth2_error.OAuth2Error(400, "
|
|
93
|
+
throw new require_oauth2_error.OAuth2Error(400, "invalid_grant", "Failed to verify id_token");
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
|
-
//#endregion
|
|
97
96
|
exports.createAuthorizationUri = createAuthorizationUri;
|
|
98
97
|
exports.exchangeAuthorizationCode = exchangeAuthorizationCode;
|
|
99
98
|
exports.refreshAccessToken = refreshAccessToken;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.cjs","names":["OAuth2Error","createRemoteJWKSet","jwtVerify"],"sources":["../../../src/oauth2/provider/common.ts"],"sourcesContent":["import { createRemoteJWKSet, jwtVerify } from 'jose';\nimport { OAuth2Error } from '../error';\nimport type { ExchangeCodeParams, PkceParameters, RefreshTokenParams } from '../types';\n\nexport function createAuthorizationUri(options: {\n state: string;\n scope: string[];\n clientId: string;\n redirectUri: string;\n authorizationUri: string;\n pkce?: Omit<PkceParameters, 'code_verifier'>;\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.pkce) {\n url.searchParams.append('code_challenge_method', options.pkce.code_challenge_method);\n url.searchParams.append('code_challenge', options.pkce.code_challenge);\n }\n return url;\n}\n\nexport async function exchangeAuthorizationCode(\n params: ExchangeCodeParams & {\n tokenUri: string;\n authentication?: 'basic' | 'post';\n /** Extra request headers some providers require, e.g. GitHub's `User-Agent`. */\n headers?: Record<string, string>;\n }\n) {\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.pkce) body.append('code_verifier', params.pkce.code_verifier);\n\n const headers: Record<string, string> = {\n ...params.headers,\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 // Public clients (Google's installed-app clients, PKCE-only clients) have no secret.\n if (params.clientSecret) body.append('client_secret', params.clientSecret);\n }\n\n return fetch(params.tokenUri, { method: 'POST', headers, body });\n}\n\nexport async function refreshAccessToken(\n params: RefreshTokenParams & {\n tokenUri: string;\n authentication?: 'basic' | 'post';\n }\n) {\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 if (params.clientSecret) body.append('client_secret', params.clientSecret);\n }\n\n return fetch(params.tokenUri, { method: 'POST', headers, body });\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 if (params.clientSecret) 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\nexport interface VerifyIdTokenOptions {\n jwkSetUri: string;\n /** The `iss` values the provider signs with; anything else is refused. */\n issuer: string | string[];\n /**\n * The client the token must be issued to. An id token proves who the user is only to the client\n * it names in `aud`: any other app on the same identity provider can obtain a validly signed one\n * for the same user, so a token for a foreign client must never sign anyone in here.\n */\n audience: string;\n}\n\nexport async function verifyIdToken<T>(idToken: string, options: VerifyIdTokenOptions) {\n const { jwkSetUri, issuer, audience } = options;\n try {\n const jwks = createRemoteJWKSet(new URL(jwkSetUri));\n const { payload } = await jwtVerify(idToken, jwks, { issuer, audience });\n return payload as T;\n } catch (error) {\n console.error('Failed to verify id_token', error);\n throw new OAuth2Error(400, '
|
|
1
|
+
{"version":3,"file":"common.cjs","names":["OAuth2Error","createRemoteJWKSet","jwtVerify"],"sources":["../../../src/oauth2/provider/common.ts"],"sourcesContent":["import { createRemoteJWKSet, jwtVerify } from 'jose';\nimport { OAuth2Error } from '../error';\nimport type { ExchangeCodeParams, PkceParameters, RefreshTokenParams } from '../types';\n\nexport function createAuthorizationUri(options: {\n state: string;\n scope: string[];\n clientId: string;\n redirectUri: string;\n authorizationUri: string;\n pkce?: Omit<PkceParameters, 'code_verifier'>;\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.pkce) {\n url.searchParams.append('code_challenge_method', options.pkce.code_challenge_method);\n url.searchParams.append('code_challenge', options.pkce.code_challenge);\n }\n return url;\n}\n\nexport async function exchangeAuthorizationCode(\n params: ExchangeCodeParams & {\n tokenUri: string;\n authentication?: 'basic' | 'post';\n /** Extra request headers some providers require, e.g. GitHub's `User-Agent`. */\n headers?: Record<string, string>;\n }\n) {\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.pkce) body.append('code_verifier', params.pkce.code_verifier);\n\n const headers: Record<string, string> = {\n ...params.headers,\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 // Public clients (Google's installed-app clients, PKCE-only clients) have no secret.\n if (params.clientSecret) body.append('client_secret', params.clientSecret);\n }\n\n return fetch(params.tokenUri, { method: 'POST', headers, body });\n}\n\nexport async function refreshAccessToken(\n params: RefreshTokenParams & {\n tokenUri: string;\n authentication?: 'basic' | 'post';\n }\n) {\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 if (params.clientSecret) body.append('client_secret', params.clientSecret);\n }\n\n return fetch(params.tokenUri, { method: 'POST', headers, body });\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 if (params.clientSecret) 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\nexport interface VerifyIdTokenOptions {\n jwkSetUri: string;\n /** The `iss` values the provider signs with; anything else is refused. */\n issuer: string | string[];\n /**\n * The client the token must be issued to. An id token proves who the user is only to the client\n * it names in `aud`: any other app on the same identity provider can obtain a validly signed one\n * for the same user, so a token for a foreign client must never sign anyone in here.\n */\n audience: string;\n}\n\nexport async function verifyIdToken<T>(idToken: string, options: VerifyIdTokenOptions) {\n const { jwkSetUri, issuer, audience } = options;\n try {\n const jwks = createRemoteJWKSet(new URL(jwkSetUri));\n const { payload } = await jwtVerify(idToken, jwks, { issuer, audience });\n return payload as T;\n } catch (error) {\n console.error('Failed to verify id_token', error);\n // The token is the grant here: one for another audience or issuer is an invalid grant, not a\n // malformed request.\n throw new OAuth2Error(400, 'invalid_grant', 'Failed to verify id_token');\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ExchangeCodeParams, PkceParameters, RefreshTokenParams } from "../types.cjs";
|
|
2
|
-
//#region src/oauth2/provider/common.d.ts
|
|
3
2
|
export declare function createAuthorizationUri(options: {
|
|
4
3
|
state: string;
|
|
5
4
|
scope: string[];
|
|
@@ -38,6 +37,5 @@ export interface VerifyIdTokenOptions {
|
|
|
38
37
|
audience: string;
|
|
39
38
|
}
|
|
40
39
|
export declare function verifyIdToken<T>(idToken: string, options: VerifyIdTokenOptions): Promise<T>;
|
|
41
|
-
//#endregion
|
|
42
40
|
export {};
|
|
43
41
|
//# sourceMappingURL=common.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.cts","names":[],"sources":["../../../src/oauth2/provider/common.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"common.d.cts","names":[],"sources":["../../../src/oauth2/provider/common.ts"],"mappings":";wBAIgB,uBAAuB;EACrC;EACA;EACA;EACA;EACA;EACA,OAAO,KAAK;IACb;wBAcqB,0BACpB,QAAQ;EACN;EACA;;EAEA,UAAU;IACX,QAAA;wBAyBmB,mBACpB,QAAQ;EACN;EACA;IACD,QAAA;UAsBO;EACR;EACA;EACA;EACA;EACA;;wBAGoB,YAAY,QAAQ,oBAAiB;iBAwB1C;EACf;;EAEA;;;;;;EAMA;;wBAGoB,cAAc,GAAG,iBAAiB,SAAS,uBAAoB,QAAA"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ExchangeCodeParams, PkceParameters, RefreshTokenParams } from "../types.mjs";
|
|
2
|
-
//#region src/oauth2/provider/common.d.ts
|
|
3
2
|
export declare function createAuthorizationUri(options: {
|
|
4
3
|
state: string;
|
|
5
4
|
scope: string[];
|
|
@@ -38,6 +37,5 @@ export interface VerifyIdTokenOptions {
|
|
|
38
37
|
audience: string;
|
|
39
38
|
}
|
|
40
39
|
export declare function verifyIdToken<T>(idToken: string, options: VerifyIdTokenOptions): Promise<T>;
|
|
41
|
-
//#endregion
|
|
42
40
|
export {};
|
|
43
41
|
//# sourceMappingURL=common.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.mts","names":[],"sources":["../../../src/oauth2/provider/common.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"common.d.mts","names":[],"sources":["../../../src/oauth2/provider/common.ts"],"mappings":";wBAIgB,uBAAuB;EACrC;EACA;EACA;EACA;EACA;EACA,OAAO,KAAK;IACb;wBAcqB,0BACpB,QAAQ;EACN;EACA;;EAEA,UAAU;IACX,QAAA;wBAyBmB,mBACpB,QAAQ;EACN;EACA;IACD,QAAA;UAsBO;EACR;EACA;EACA;EACA;EACA;;wBAGoB,YAAY,QAAQ,oBAAiB;iBAwB1C;EACf;;EAEA;;;;;;EAMA;;wBAGoB,cAAc,GAAG,iBAAiB,SAAS,uBAAoB,QAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { OAuth2Error } from "../error.mjs";
|
|
2
2
|
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
3
|
-
|
|
3
|
+
// src/oauth2/provider/common.ts
|
|
4
4
|
function createAuthorizationUri(options) {
|
|
5
5
|
const url = new URL(options.authorizationUri);
|
|
6
6
|
url.searchParams.append("response_type", "code");
|
|
@@ -89,10 +89,9 @@ async function verifyIdToken(idToken, options) {
|
|
|
89
89
|
return payload;
|
|
90
90
|
} catch (error) {
|
|
91
91
|
console.error("Failed to verify id_token", error);
|
|
92
|
-
throw new OAuth2Error(400, "
|
|
92
|
+
throw new OAuth2Error(400, "invalid_grant", "Failed to verify id_token");
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
-
//#endregion
|
|
96
95
|
export { createAuthorizationUri, exchangeAuthorizationCode, refreshAccessToken, revokeToken, verifyIdToken };
|
|
97
96
|
|
|
98
97
|
//# sourceMappingURL=common.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.mjs","names":[],"sources":["../../../src/oauth2/provider/common.ts"],"sourcesContent":["import { createRemoteJWKSet, jwtVerify } from 'jose';\nimport { OAuth2Error } from '../error';\nimport type { ExchangeCodeParams, PkceParameters, RefreshTokenParams } from '../types';\n\nexport function createAuthorizationUri(options: {\n state: string;\n scope: string[];\n clientId: string;\n redirectUri: string;\n authorizationUri: string;\n pkce?: Omit<PkceParameters, 'code_verifier'>;\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.pkce) {\n url.searchParams.append('code_challenge_method', options.pkce.code_challenge_method);\n url.searchParams.append('code_challenge', options.pkce.code_challenge);\n }\n return url;\n}\n\nexport async function exchangeAuthorizationCode(\n params: ExchangeCodeParams & {\n tokenUri: string;\n authentication?: 'basic' | 'post';\n /** Extra request headers some providers require, e.g. GitHub's `User-Agent`. */\n headers?: Record<string, string>;\n }\n) {\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.pkce) body.append('code_verifier', params.pkce.code_verifier);\n\n const headers: Record<string, string> = {\n ...params.headers,\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 // Public clients (Google's installed-app clients, PKCE-only clients) have no secret.\n if (params.clientSecret) body.append('client_secret', params.clientSecret);\n }\n\n return fetch(params.tokenUri, { method: 'POST', headers, body });\n}\n\nexport async function refreshAccessToken(\n params: RefreshTokenParams & {\n tokenUri: string;\n authentication?: 'basic' | 'post';\n }\n) {\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 if (params.clientSecret) body.append('client_secret', params.clientSecret);\n }\n\n return fetch(params.tokenUri, { method: 'POST', headers, body });\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 if (params.clientSecret) 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\nexport interface VerifyIdTokenOptions {\n jwkSetUri: string;\n /** The `iss` values the provider signs with; anything else is refused. */\n issuer: string | string[];\n /**\n * The client the token must be issued to. An id token proves who the user is only to the client\n * it names in `aud`: any other app on the same identity provider can obtain a validly signed one\n * for the same user, so a token for a foreign client must never sign anyone in here.\n */\n audience: string;\n}\n\nexport async function verifyIdToken<T>(idToken: string, options: VerifyIdTokenOptions) {\n const { jwkSetUri, issuer, audience } = options;\n try {\n const jwks = createRemoteJWKSet(new URL(jwkSetUri));\n const { payload } = await jwtVerify(idToken, jwks, { issuer, audience });\n return payload as T;\n } catch (error) {\n console.error('Failed to verify id_token', error);\n throw new OAuth2Error(400, '
|
|
1
|
+
{"version":3,"file":"common.mjs","names":[],"sources":["../../../src/oauth2/provider/common.ts"],"sourcesContent":["import { createRemoteJWKSet, jwtVerify } from 'jose';\nimport { OAuth2Error } from '../error';\nimport type { ExchangeCodeParams, PkceParameters, RefreshTokenParams } from '../types';\n\nexport function createAuthorizationUri(options: {\n state: string;\n scope: string[];\n clientId: string;\n redirectUri: string;\n authorizationUri: string;\n pkce?: Omit<PkceParameters, 'code_verifier'>;\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.pkce) {\n url.searchParams.append('code_challenge_method', options.pkce.code_challenge_method);\n url.searchParams.append('code_challenge', options.pkce.code_challenge);\n }\n return url;\n}\n\nexport async function exchangeAuthorizationCode(\n params: ExchangeCodeParams & {\n tokenUri: string;\n authentication?: 'basic' | 'post';\n /** Extra request headers some providers require, e.g. GitHub's `User-Agent`. */\n headers?: Record<string, string>;\n }\n) {\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.pkce) body.append('code_verifier', params.pkce.code_verifier);\n\n const headers: Record<string, string> = {\n ...params.headers,\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 // Public clients (Google's installed-app clients, PKCE-only clients) have no secret.\n if (params.clientSecret) body.append('client_secret', params.clientSecret);\n }\n\n return fetch(params.tokenUri, { method: 'POST', headers, body });\n}\n\nexport async function refreshAccessToken(\n params: RefreshTokenParams & {\n tokenUri: string;\n authentication?: 'basic' | 'post';\n }\n) {\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 if (params.clientSecret) body.append('client_secret', params.clientSecret);\n }\n\n return fetch(params.tokenUri, { method: 'POST', headers, body });\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 if (params.clientSecret) 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\nexport interface VerifyIdTokenOptions {\n jwkSetUri: string;\n /** The `iss` values the provider signs with; anything else is refused. */\n issuer: string | string[];\n /**\n * The client the token must be issued to. An id token proves who the user is only to the client\n * it names in `aud`: any other app on the same identity provider can obtain a validly signed one\n * for the same user, so a token for a foreign client must never sign anyone in here.\n */\n audience: string;\n}\n\nexport async function verifyIdToken<T>(idToken: string, options: VerifyIdTokenOptions) {\n const { jwkSetUri, issuer, audience } = options;\n try {\n const jwks = createRemoteJWKSet(new URL(jwkSetUri));\n const { payload } = await jwtVerify(idToken, jwks, { issuer, audience });\n return payload as T;\n } catch (error) {\n console.error('Failed to verify id_token', error);\n // The token is the grant here: one for another audience or issuer is an invalid grant, not a\n // malformed request.\n throw new OAuth2Error(400, 'invalid_grant', 'Failed to verify id_token');\n }\n}\n"],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ const require_oauth2_error = require("../error.cjs");
|
|
|
3
3
|
const require_oauth2_provider_common = require("./common.cjs");
|
|
4
4
|
let node_crypto = require("node:crypto");
|
|
5
5
|
let _shware_utils = require("@shware/utils");
|
|
6
|
-
|
|
6
|
+
// src/oauth2/provider/facebook.ts
|
|
7
7
|
/**
|
|
8
8
|
* `iss` of Limited Login id tokens, per https://limited.facebook.com/.well-known/openid-configuration/
|
|
9
9
|
* (their `aud` is the app id).
|
|
@@ -53,8 +53,7 @@ function createFacebookProvider() {
|
|
|
53
53
|
sub: data.sub,
|
|
54
54
|
name: data.name,
|
|
55
55
|
picture: data.picture,
|
|
56
|
-
email: data.email
|
|
57
|
-
email_verified: true
|
|
56
|
+
email: data.email
|
|
58
57
|
}
|
|
59
58
|
};
|
|
60
59
|
}
|
|
@@ -108,12 +107,10 @@ async function fetchUserInfo(userInfoUri, accessToken, appSecretProof) {
|
|
|
108
107
|
sub: data.id,
|
|
109
108
|
name: data.name,
|
|
110
109
|
email: data.email,
|
|
111
|
-
picture: data.picture.data.url
|
|
112
|
-
email_verified: data.email_verified
|
|
110
|
+
picture: data.picture.data.url
|
|
113
111
|
}
|
|
114
112
|
};
|
|
115
113
|
}
|
|
116
|
-
//#endregion
|
|
117
114
|
exports.createFacebookProvider = createFacebookProvider;
|
|
118
115
|
exports.facebook = facebook;
|
|
119
116
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facebook.cjs","names":["createAuthorizationUri","exchangeAuthorizationCode","OAuth2Error","verifyIdToken","createHmac"],"sources":["../../../src/oauth2/provider/facebook.ts"],"sourcesContent":["import { createHmac } from 'node:crypto';\nimport { invariant } from '@shware/utils';\nimport { OAuth2Error } from '../error';\nimport type { LoginOAuth2NativeParams, OAuth2Token, Provider, UserInfo } from '../types';\nimport { createAuthorizationUri, exchangeAuthorizationCode, verifyIdToken } from './common';\n\n/**\n * `iss` of Limited Login id tokens, per https://limited.facebook.com/.well-known/openid-configuration/\n * (their `aud` is the app id).\n */\nconst FACEBOOK_ISSUER = 'https://www.facebook.com';\n\n/**\n * ref: https://developers.facebook.com/docs/facebook-login/guides/advanced/manual-flow/\n * ref: https://developers.facebook.com/tools/explorer\n * */\nexport function createFacebookProvider(): Provider {\n return {\n authorizationUri: 'https://www.facebook.com/v21.0/dialog/oauth',\n tokenUri: 'https://graph.facebook.com/v19.0/oauth/access_token',\n userInfoUri: 'https://graph.facebook.com/me',\n jwkSetUri: 'https://limited.facebook.com/.well-known/oauth/openid/jwks/',\n userNameAttribute: 'id',\n defaultScope: ['profile', 'email'],\n createAuthorizationUri({ pkce: _, ...params }) {\n return createAuthorizationUri({\n ...params,\n scope: params.scope ?? this.defaultScope,\n authorizationUri: this.authorizationUri,\n });\n },\n async exchangeAuthorizationCode({ pkce: _, ...params }) {\n const response = await exchangeAuthorizationCode({ ...params, tokenUri: this.tokenUri });\n if (!response.ok) {\n const { error } = (await response.json()) as FacebookErrorResponse;\n throw new OAuth2Error(response.status, 'invalid_request', error.message);\n }\n return (await response.json()) as FacebookToken;\n },\n async getUserInfo({ id_token, access_token }, { clientId }) {\n invariant(this.jwkSetUri, 'jwkSetUri is required');\n if (id_token) {\n const data = await verifyIdToken<FacebookDecodedIdToken>(id_token, {\n jwkSetUri: this.jwkSetUri,\n issuer: FACEBOOK_ISSUER,\n audience: clientId,\n });\n return {\n data,\n claims: {\n sub: data.sub,\n name: data.name,\n picture: data.picture,\n email: data.email,\n
|
|
1
|
+
{"version":3,"file":"facebook.cjs","names":["createAuthorizationUri","exchangeAuthorizationCode","OAuth2Error","verifyIdToken","createHmac"],"sources":["../../../src/oauth2/provider/facebook.ts"],"sourcesContent":["import { createHmac } from 'node:crypto';\nimport { invariant } from '@shware/utils';\nimport { OAuth2Error } from '../error';\nimport type { LoginOAuth2NativeParams, OAuth2Token, Provider, UserInfo } from '../types';\nimport { createAuthorizationUri, exchangeAuthorizationCode, verifyIdToken } from './common';\n\n/**\n * `iss` of Limited Login id tokens, per https://limited.facebook.com/.well-known/openid-configuration/\n * (their `aud` is the app id).\n */\nconst FACEBOOK_ISSUER = 'https://www.facebook.com';\n\n/**\n * ref: https://developers.facebook.com/docs/facebook-login/guides/advanced/manual-flow/\n * ref: https://developers.facebook.com/tools/explorer\n * */\nexport function createFacebookProvider(): Provider {\n return {\n authorizationUri: 'https://www.facebook.com/v21.0/dialog/oauth',\n tokenUri: 'https://graph.facebook.com/v19.0/oauth/access_token',\n userInfoUri: 'https://graph.facebook.com/me',\n jwkSetUri: 'https://limited.facebook.com/.well-known/oauth/openid/jwks/',\n userNameAttribute: 'id',\n defaultScope: ['profile', 'email'],\n createAuthorizationUri({ pkce: _, ...params }) {\n return createAuthorizationUri({\n ...params,\n scope: params.scope ?? this.defaultScope,\n authorizationUri: this.authorizationUri,\n });\n },\n async exchangeAuthorizationCode({ pkce: _, ...params }) {\n const response = await exchangeAuthorizationCode({ ...params, tokenUri: this.tokenUri });\n if (!response.ok) {\n const { error } = (await response.json()) as FacebookErrorResponse;\n throw new OAuth2Error(response.status, 'invalid_request', error.message);\n }\n return (await response.json()) as FacebookToken;\n },\n async getUserInfo({ id_token, access_token }, { clientId }) {\n invariant(this.jwkSetUri, 'jwkSetUri is required');\n if (id_token) {\n const data = await verifyIdToken<FacebookDecodedIdToken>(id_token, {\n jwkSetUri: this.jwkSetUri,\n issuer: FACEBOOK_ISSUER,\n audience: clientId,\n });\n return {\n data,\n claims: {\n sub: data.sub,\n name: data.name,\n picture: data.picture,\n email: data.email,\n // Facebook does not say whether the address is verified: left unset, so a host that\n // trusts only `email_verified === true` treats it as unverified.\n },\n };\n }\n invariant(access_token, 'access_token is required');\n invariant(this.userInfoUri, 'userInfoUri is required');\n return fetchUserInfo(this.userInfoUri, access_token);\n },\n async loginOAuth2Native({ clientId, clientSecret, credentials }: LoginOAuth2NativeParams) {\n const { id_token, access_token } = credentials;\n let userInfo: UserInfo;\n if (id_token) {\n // Limited Login: the id token's `aud` must be this app.\n userInfo = await this.getUserInfo(\n { token_type: 'bearer', access_token: '', id_token },\n {\n clientId,\n }\n );\n } else if (access_token) {\n // The Graph API serves any app's user access token, so `/me` alone would accept a token a\n // foreign app obtained for the same user. With `appsecret_proof` Facebook refuses tokens\n // not issued to the app whose secret signed the proof, binding the token to this client.\n if (!clientSecret) {\n throw new OAuth2Error(400, 'invalid_client', 'access_token login needs the app secret');\n }\n invariant(this.userInfoUri, 'userInfoUri is required');\n const proof = createHmac('sha256', clientSecret).update(access_token).digest('hex');\n userInfo = await fetchUserInfo(this.userInfoUri, access_token, proof);\n } else {\n throw new OAuth2Error(400, 'invalid_request', 'id_token or access_token is required');\n }\n const token: OAuth2Token = {\n token_type: 'bearer',\n access_token: access_token ?? '',\n id_token,\n };\n return { token, userInfo };\n },\n };\n}\n\nexport const facebook = createFacebookProvider();\n\nasync function fetchUserInfo(\n userInfoUri: string,\n accessToken: string,\n appSecretProof?: string\n): Promise<UserInfo<FacebookUserInfo>> {\n const url = new URL(userInfoUri);\n const fields = ['id', 'name', 'email', 'picture.width(320).height(320)'];\n url.searchParams.append('access_token', accessToken);\n url.searchParams.append('fields', fields.join(','));\n if (appSecretProof) url.searchParams.append('appsecret_proof', appSecretProof);\n const headers = { Accept: 'application/json' };\n const response = await fetch(url.href, { headers });\n if (!response.ok) {\n throw new OAuth2Error(response.status, 'invalid_request', 'Failed to fetch user info');\n }\n const data = (await response.json()) as FacebookUserInfo;\n return {\n data,\n claims: {\n sub: data.id,\n name: data.name,\n email: data.email,\n picture: data.picture.data.url,\n // Not stated by the Graph API either; see the Limited Login path above.\n },\n };\n}\n\nexport interface FacebookDecodedIdToken {\n sub: string;\n name: string;\n email: string;\n picture: string;\n nonce?: string;\n}\n\nexport interface FacebookUserInfo {\n id: string;\n name: string;\n email: string;\n picture: {\n data: {\n url: string;\n width: number;\n height: number;\n is_silhouette: boolean;\n };\n };\n}\n\nexport interface FacebookToken extends OAuth2Token {\n access_token: string;\n token_type: 'bearer';\n expires_in: number;\n id_token?: string;\n}\n\nexport type FacebookAppCredential =\n | { state: string; id_token: string } // platform=ios and tracking=limited\n | { state: string; access_token: string }; // tracking=enabled\n\ninterface FacebookErrorResponse {\n error: {\n message: string;\n type: 'OAuthException';\n code: number;\n error_subcode: number;\n fbtrace_id: string;\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { OAuth2Token, Provider } from "../types.cjs";
|
|
2
|
-
//#region src/oauth2/provider/facebook.d.ts
|
|
3
2
|
/**
|
|
4
3
|
* ref: https://developers.facebook.com/docs/facebook-login/guides/advanced/manual-flow/
|
|
5
4
|
* ref: https://developers.facebook.com/tools/explorer
|
|
@@ -17,7 +16,6 @@ export interface FacebookUserInfo {
|
|
|
17
16
|
id: string;
|
|
18
17
|
name: string;
|
|
19
18
|
email: string;
|
|
20
|
-
email_verified: boolean;
|
|
21
19
|
picture: {
|
|
22
20
|
data: {
|
|
23
21
|
url: string;
|
|
@@ -40,5 +38,4 @@ export type FacebookAppCredential = {
|
|
|
40
38
|
state: string;
|
|
41
39
|
access_token: string;
|
|
42
40
|
};
|
|
43
|
-
//#endregion
|
|
44
41
|
//# sourceMappingURL=facebook.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facebook.d.cts","names":[],"sources":["../../../src/oauth2/provider/facebook.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"facebook.d.cts","names":[],"sources":["../../../src/oauth2/provider/facebook.ts"],"mappings":";;;;;wBAgBgB,0BAA0B;qBAiF7B,UAAQ;iBA8BJ;EACf;EACA;EACA;EACA;EACA;;iBAGe;EACf;EACA;EACA;EACA;IACE;MACE;MACA;MACA;MACA;;;;iBAKW,sBAAsB;EACrC;EACA;EACA;EACA;;YAGU;EACN;EAAe;;EACf;EAAe"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { OAuth2Token, Provider } from "../types.mjs";
|
|
2
|
-
//#region src/oauth2/provider/facebook.d.ts
|
|
3
2
|
/**
|
|
4
3
|
* ref: https://developers.facebook.com/docs/facebook-login/guides/advanced/manual-flow/
|
|
5
4
|
* ref: https://developers.facebook.com/tools/explorer
|
|
@@ -17,7 +16,6 @@ export interface FacebookUserInfo {
|
|
|
17
16
|
id: string;
|
|
18
17
|
name: string;
|
|
19
18
|
email: string;
|
|
20
|
-
email_verified: boolean;
|
|
21
19
|
picture: {
|
|
22
20
|
data: {
|
|
23
21
|
url: string;
|
|
@@ -40,5 +38,4 @@ export type FacebookAppCredential = {
|
|
|
40
38
|
state: string;
|
|
41
39
|
access_token: string;
|
|
42
40
|
};
|
|
43
|
-
//#endregion
|
|
44
41
|
//# sourceMappingURL=facebook.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facebook.d.mts","names":[],"sources":["../../../src/oauth2/provider/facebook.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"facebook.d.mts","names":[],"sources":["../../../src/oauth2/provider/facebook.ts"],"mappings":";;;;;wBAgBgB,0BAA0B;qBAiF7B,UAAQ;iBA8BJ;EACf;EACA;EACA;EACA;EACA;;iBAGe;EACf;EACA;EACA;EACA;IACE;MACE;MACA;MACA;MACA;;;;iBAKW,sBAAsB;EACrC;EACA;EACA;EACA;;YAGU;EACN;EAAe;;EACf;EAAe"}
|
|
@@ -2,7 +2,7 @@ import { OAuth2Error } from "../error.mjs";
|
|
|
2
2
|
import { createAuthorizationUri, exchangeAuthorizationCode, verifyIdToken } from "./common.mjs";
|
|
3
3
|
import { createHmac } from "node:crypto";
|
|
4
4
|
import { invariant } from "@shware/utils";
|
|
5
|
-
|
|
5
|
+
// src/oauth2/provider/facebook.ts
|
|
6
6
|
/**
|
|
7
7
|
* `iss` of Limited Login id tokens, per https://limited.facebook.com/.well-known/openid-configuration/
|
|
8
8
|
* (their `aud` is the app id).
|
|
@@ -52,8 +52,7 @@ function createFacebookProvider() {
|
|
|
52
52
|
sub: data.sub,
|
|
53
53
|
name: data.name,
|
|
54
54
|
picture: data.picture,
|
|
55
|
-
email: data.email
|
|
56
|
-
email_verified: true
|
|
55
|
+
email: data.email
|
|
57
56
|
}
|
|
58
57
|
};
|
|
59
58
|
}
|
|
@@ -107,12 +106,10 @@ async function fetchUserInfo(userInfoUri, accessToken, appSecretProof) {
|
|
|
107
106
|
sub: data.id,
|
|
108
107
|
name: data.name,
|
|
109
108
|
email: data.email,
|
|
110
|
-
picture: data.picture.data.url
|
|
111
|
-
email_verified: data.email_verified
|
|
109
|
+
picture: data.picture.data.url
|
|
112
110
|
}
|
|
113
111
|
};
|
|
114
112
|
}
|
|
115
|
-
//#endregion
|
|
116
113
|
export { createFacebookProvider, facebook };
|
|
117
114
|
|
|
118
115
|
//# sourceMappingURL=facebook.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facebook.mjs","names":[],"sources":["../../../src/oauth2/provider/facebook.ts"],"sourcesContent":["import { createHmac } from 'node:crypto';\nimport { invariant } from '@shware/utils';\nimport { OAuth2Error } from '../error';\nimport type { LoginOAuth2NativeParams, OAuth2Token, Provider, UserInfo } from '../types';\nimport { createAuthorizationUri, exchangeAuthorizationCode, verifyIdToken } from './common';\n\n/**\n * `iss` of Limited Login id tokens, per https://limited.facebook.com/.well-known/openid-configuration/\n * (their `aud` is the app id).\n */\nconst FACEBOOK_ISSUER = 'https://www.facebook.com';\n\n/**\n * ref: https://developers.facebook.com/docs/facebook-login/guides/advanced/manual-flow/\n * ref: https://developers.facebook.com/tools/explorer\n * */\nexport function createFacebookProvider(): Provider {\n return {\n authorizationUri: 'https://www.facebook.com/v21.0/dialog/oauth',\n tokenUri: 'https://graph.facebook.com/v19.0/oauth/access_token',\n userInfoUri: 'https://graph.facebook.com/me',\n jwkSetUri: 'https://limited.facebook.com/.well-known/oauth/openid/jwks/',\n userNameAttribute: 'id',\n defaultScope: ['profile', 'email'],\n createAuthorizationUri({ pkce: _, ...params }) {\n return createAuthorizationUri({\n ...params,\n scope: params.scope ?? this.defaultScope,\n authorizationUri: this.authorizationUri,\n });\n },\n async exchangeAuthorizationCode({ pkce: _, ...params }) {\n const response = await exchangeAuthorizationCode({ ...params, tokenUri: this.tokenUri });\n if (!response.ok) {\n const { error } = (await response.json()) as FacebookErrorResponse;\n throw new OAuth2Error(response.status, 'invalid_request', error.message);\n }\n return (await response.json()) as FacebookToken;\n },\n async getUserInfo({ id_token, access_token }, { clientId }) {\n invariant(this.jwkSetUri, 'jwkSetUri is required');\n if (id_token) {\n const data = await verifyIdToken<FacebookDecodedIdToken>(id_token, {\n jwkSetUri: this.jwkSetUri,\n issuer: FACEBOOK_ISSUER,\n audience: clientId,\n });\n return {\n data,\n claims: {\n sub: data.sub,\n name: data.name,\n picture: data.picture,\n email: data.email,\n
|
|
1
|
+
{"version":3,"file":"facebook.mjs","names":[],"sources":["../../../src/oauth2/provider/facebook.ts"],"sourcesContent":["import { createHmac } from 'node:crypto';\nimport { invariant } from '@shware/utils';\nimport { OAuth2Error } from '../error';\nimport type { LoginOAuth2NativeParams, OAuth2Token, Provider, UserInfo } from '../types';\nimport { createAuthorizationUri, exchangeAuthorizationCode, verifyIdToken } from './common';\n\n/**\n * `iss` of Limited Login id tokens, per https://limited.facebook.com/.well-known/openid-configuration/\n * (their `aud` is the app id).\n */\nconst FACEBOOK_ISSUER = 'https://www.facebook.com';\n\n/**\n * ref: https://developers.facebook.com/docs/facebook-login/guides/advanced/manual-flow/\n * ref: https://developers.facebook.com/tools/explorer\n * */\nexport function createFacebookProvider(): Provider {\n return {\n authorizationUri: 'https://www.facebook.com/v21.0/dialog/oauth',\n tokenUri: 'https://graph.facebook.com/v19.0/oauth/access_token',\n userInfoUri: 'https://graph.facebook.com/me',\n jwkSetUri: 'https://limited.facebook.com/.well-known/oauth/openid/jwks/',\n userNameAttribute: 'id',\n defaultScope: ['profile', 'email'],\n createAuthorizationUri({ pkce: _, ...params }) {\n return createAuthorizationUri({\n ...params,\n scope: params.scope ?? this.defaultScope,\n authorizationUri: this.authorizationUri,\n });\n },\n async exchangeAuthorizationCode({ pkce: _, ...params }) {\n const response = await exchangeAuthorizationCode({ ...params, tokenUri: this.tokenUri });\n if (!response.ok) {\n const { error } = (await response.json()) as FacebookErrorResponse;\n throw new OAuth2Error(response.status, 'invalid_request', error.message);\n }\n return (await response.json()) as FacebookToken;\n },\n async getUserInfo({ id_token, access_token }, { clientId }) {\n invariant(this.jwkSetUri, 'jwkSetUri is required');\n if (id_token) {\n const data = await verifyIdToken<FacebookDecodedIdToken>(id_token, {\n jwkSetUri: this.jwkSetUri,\n issuer: FACEBOOK_ISSUER,\n audience: clientId,\n });\n return {\n data,\n claims: {\n sub: data.sub,\n name: data.name,\n picture: data.picture,\n email: data.email,\n // Facebook does not say whether the address is verified: left unset, so a host that\n // trusts only `email_verified === true` treats it as unverified.\n },\n };\n }\n invariant(access_token, 'access_token is required');\n invariant(this.userInfoUri, 'userInfoUri is required');\n return fetchUserInfo(this.userInfoUri, access_token);\n },\n async loginOAuth2Native({ clientId, clientSecret, credentials }: LoginOAuth2NativeParams) {\n const { id_token, access_token } = credentials;\n let userInfo: UserInfo;\n if (id_token) {\n // Limited Login: the id token's `aud` must be this app.\n userInfo = await this.getUserInfo(\n { token_type: 'bearer', access_token: '', id_token },\n {\n clientId,\n }\n );\n } else if (access_token) {\n // The Graph API serves any app's user access token, so `/me` alone would accept a token a\n // foreign app obtained for the same user. With `appsecret_proof` Facebook refuses tokens\n // not issued to the app whose secret signed the proof, binding the token to this client.\n if (!clientSecret) {\n throw new OAuth2Error(400, 'invalid_client', 'access_token login needs the app secret');\n }\n invariant(this.userInfoUri, 'userInfoUri is required');\n const proof = createHmac('sha256', clientSecret).update(access_token).digest('hex');\n userInfo = await fetchUserInfo(this.userInfoUri, access_token, proof);\n } else {\n throw new OAuth2Error(400, 'invalid_request', 'id_token or access_token is required');\n }\n const token: OAuth2Token = {\n token_type: 'bearer',\n access_token: access_token ?? '',\n id_token,\n };\n return { token, userInfo };\n },\n };\n}\n\nexport const facebook = createFacebookProvider();\n\nasync function fetchUserInfo(\n userInfoUri: string,\n accessToken: string,\n appSecretProof?: string\n): Promise<UserInfo<FacebookUserInfo>> {\n const url = new URL(userInfoUri);\n const fields = ['id', 'name', 'email', 'picture.width(320).height(320)'];\n url.searchParams.append('access_token', accessToken);\n url.searchParams.append('fields', fields.join(','));\n if (appSecretProof) url.searchParams.append('appsecret_proof', appSecretProof);\n const headers = { Accept: 'application/json' };\n const response = await fetch(url.href, { headers });\n if (!response.ok) {\n throw new OAuth2Error(response.status, 'invalid_request', 'Failed to fetch user info');\n }\n const data = (await response.json()) as FacebookUserInfo;\n return {\n data,\n claims: {\n sub: data.id,\n name: data.name,\n email: data.email,\n picture: data.picture.data.url,\n // Not stated by the Graph API either; see the Limited Login path above.\n },\n };\n}\n\nexport interface FacebookDecodedIdToken {\n sub: string;\n name: string;\n email: string;\n picture: string;\n nonce?: string;\n}\n\nexport interface FacebookUserInfo {\n id: string;\n name: string;\n email: string;\n picture: {\n data: {\n url: string;\n width: number;\n height: number;\n is_silhouette: boolean;\n };\n };\n}\n\nexport interface FacebookToken extends OAuth2Token {\n access_token: string;\n token_type: 'bearer';\n expires_in: number;\n id_token?: string;\n}\n\nexport type FacebookAppCredential =\n | { state: string; id_token: string } // platform=ios and tracking=limited\n | { state: string; access_token: string }; // tracking=enabled\n\ninterface FacebookErrorResponse {\n error: {\n message: string;\n type: 'OAuthException';\n code: number;\n error_subcode: number;\n fbtrace_id: string;\n };\n}\n"],"mappings":";;;;;;;;;AAUA,MAAM,kBAAkB;;;;;AAMxB,SAAgB,yBAAmC;CACjD,OAAO;EACL,kBAAkB;EAClB,UAAU;EACV,aAAa;EACb,WAAW;EACX,mBAAmB;EACnB,cAAc,CAAC,WAAW,OAAO;EACjC,uBAAuB,EAAE,MAAM,GAAG,GAAG,UAAU;GAC7C,OAAO,uBAAuB;IAC5B,GAAG;IACH,OAAO,OAAO,SAAS,KAAK;IAC5B,kBAAkB,KAAK;GACzB,CAAC;EACH;EACA,MAAM,0BAA0B,EAAE,MAAM,GAAG,GAAG,UAAU;GACtD,MAAM,WAAW,MAAM,0BAA0B;IAAE,GAAG;IAAQ,UAAU,KAAK;GAAS,CAAC;GACvF,IAAI,CAAC,SAAS,IAAI;IAChB,MAAM,EAAE,UAAW,MAAM,SAAS,KAAK;IACvC,MAAM,IAAI,YAAY,SAAS,QAAQ,mBAAmB,MAAM,OAAO;GACzE;GACA,OAAQ,MAAM,SAAS,KAAK;EAC9B;EACA,MAAM,YAAY,EAAE,UAAU,gBAAgB,EAAE,YAAY;GAC1D,UAAU,KAAK,WAAW,uBAAuB;GACjD,IAAI,UAAU;IACZ,MAAM,OAAO,MAAM,cAAsC,UAAU;KACjE,WAAW,KAAK;KAChB,QAAQ;KACR,UAAU;IACZ,CAAC;IACD,OAAO;KACL;KACA,QAAQ;MACN,KAAK,KAAK;MACV,MAAM,KAAK;MACX,SAAS,KAAK;MACd,OAAO,KAAK;KAGd;IACF;GACF;GACA,UAAU,cAAc,0BAA0B;GAClD,UAAU,KAAK,aAAa,yBAAyB;GACrD,OAAO,cAAc,KAAK,aAAa,YAAY;EACrD;EACA,MAAM,kBAAkB,EAAE,UAAU,cAAc,eAAwC;GACxF,MAAM,EAAE,UAAU,iBAAiB;GACnC,IAAI;GACJ,IAAI,UAEF,WAAW,MAAM,KAAK,YACpB;IAAE,YAAY;IAAU,cAAc;IAAI;GAAS,GACnD,EACE,SACF,CACF;QACK,IAAI,cAAc;IAIvB,IAAI,CAAC,cACH,MAAM,IAAI,YAAY,KAAK,kBAAkB,yCAAyC;IAExF,UAAU,KAAK,aAAa,yBAAyB;IACrD,MAAM,QAAQ,WAAW,UAAU,YAAY,CAAC,CAAC,OAAO,YAAY,CAAC,CAAC,OAAO,KAAK;IAClF,WAAW,MAAM,cAAc,KAAK,aAAa,cAAc,KAAK;GACtE,OACE,MAAM,IAAI,YAAY,KAAK,mBAAmB,sCAAsC;GAOtF,OAAO;IAAE,OAAA;KAJP,YAAY;KACZ,cAAc,gBAAgB;KAC9B;IAEW;IAAG;GAAS;EAC3B;CACF;AACF;AAEA,MAAa,WAAW,uBAAuB;AAE/C,eAAe,cACb,aACA,aACA,gBACqC;CACrC,MAAM,MAAM,IAAI,IAAI,WAAW;CAC/B,MAAM,SAAS;EAAC;EAAM;EAAQ;EAAS;CAAgC;CACvE,IAAI,aAAa,OAAO,gBAAgB,WAAW;CACnD,IAAI,aAAa,OAAO,UAAU,OAAO,KAAK,GAAG,CAAC;CAClD,IAAI,gBAAgB,IAAI,aAAa,OAAO,mBAAmB,cAAc;CAE7E,MAAM,WAAW,MAAM,MAAM,IAAI,MAAM,EAAE,SAAA,EADvB,QAAQ,mBACqB,EAAE,CAAC;CAClD,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,YAAY,SAAS,QAAQ,mBAAmB,2BAA2B;CAEvF,MAAM,OAAQ,MAAM,SAAS,KAAK;CAClC,OAAO;EACL;EACA,QAAQ;GACN,KAAK,KAAK;GACV,MAAM,KAAK;GACX,OAAO,KAAK;GACZ,SAAS,KAAK,QAAQ,KAAK;EAE7B;CACF;AACF"}
|
|
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
const require_oauth2_error = require("../error.cjs");
|
|
3
3
|
const require_oauth2_provider_common = require("./common.cjs");
|
|
4
4
|
let _shware_utils = require("@shware/utils");
|
|
5
|
-
|
|
5
|
+
// src/oauth2/provider/github.ts
|
|
6
6
|
/**
|
|
7
7
|
* GitHub's REST API rejects any request without a `User-Agent` header with a 403. Node's fetch sends
|
|
8
8
|
* a default one, but Cloudflare Workers' fetch sends none, so every GitHub request sets it explicitly.
|
|
@@ -82,7 +82,6 @@ function createGithubProvider() {
|
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
84
|
const github = createGithubProvider();
|
|
85
|
-
//#endregion
|
|
86
85
|
exports.createGithubProvider = createGithubProvider;
|
|
87
86
|
exports.github = github;
|
|
88
87
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { OAuth2Token, Provider } from "../types.cjs";
|
|
2
|
-
//#region src/oauth2/provider/github.d.ts
|
|
3
2
|
export declare function createGithubProvider(): Provider;
|
|
4
3
|
export declare const github: Provider;
|
|
5
4
|
export interface GithubUserInfo {
|
|
@@ -55,5 +54,4 @@ export interface GithubToken extends OAuth2Token {
|
|
|
55
54
|
expires_in: number;
|
|
56
55
|
refresh_token: string;
|
|
57
56
|
}
|
|
58
|
-
//#endregion
|
|
59
57
|
//# sourceMappingURL=github.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github.d.cts","names":[],"sources":["../../../src/oauth2/provider/github.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"github.d.cts","names":[],"sources":["../../../src/oauth2/provider/github.ts"],"mappings":";wBAmBgB,wBAAwB;qBAqE3B,QAAM;iBAEF;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;IACE;IACA;IACA;IACA;;;iBAWa,oBAAoB;EACnC;EACA;EACA;EACA;EACA"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { OAuth2Token, Provider } from "../types.mjs";
|
|
2
|
-
//#region src/oauth2/provider/github.d.ts
|
|
3
2
|
export declare function createGithubProvider(): Provider;
|
|
4
3
|
export declare const github: Provider;
|
|
5
4
|
export interface GithubUserInfo {
|
|
@@ -55,5 +54,4 @@ export interface GithubToken extends OAuth2Token {
|
|
|
55
54
|
expires_in: number;
|
|
56
55
|
refresh_token: string;
|
|
57
56
|
}
|
|
58
|
-
//#endregion
|
|
59
57
|
//# sourceMappingURL=github.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github.d.mts","names":[],"sources":["../../../src/oauth2/provider/github.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"github.d.mts","names":[],"sources":["../../../src/oauth2/provider/github.ts"],"mappings":";wBAmBgB,wBAAwB;qBAqE3B,QAAM;iBAEF;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;IACE;IACA;IACA;IACA;;;iBAWa,oBAAoB;EACnC;EACA;EACA;EACA;EACA"}
|