@atproto/oauth-provider 0.1.2 → 0.2.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/CHANGELOG.md +46 -0
- package/dist/account/account.d.ts +6 -2
- package/dist/account/account.d.ts.map +1 -1
- package/dist/assets/app/bundle-manifest.json +3 -3
- package/dist/assets/app/main.css +1 -1
- package/dist/assets/app/main.js +3 -3
- package/dist/assets/app/main.js.map +1 -1
- package/dist/assets/assets-middleware.d.ts +2 -1
- package/dist/assets/assets-middleware.d.ts.map +1 -1
- package/dist/assets/assets-middleware.js +7 -0
- package/dist/assets/assets-middleware.js.map +1 -1
- package/dist/client/client-manager.d.ts +4 -3
- package/dist/client/client-manager.d.ts.map +1 -1
- package/dist/client/client-manager.js +91 -77
- package/dist/client/client-manager.js.map +1 -1
- package/dist/client/client.d.ts +2 -3
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +6 -12
- package/dist/client/client.js.map +1 -1
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +3 -1
- package/dist/constants.js.map +1 -1
- package/dist/device/device-manager.d.ts +1 -1
- package/dist/device/device-manager.d.ts.map +1 -1
- package/dist/device/device-manager.js +2 -2
- package/dist/device/device-manager.js.map +1 -1
- package/dist/dpop/dpop-manager.d.ts +0 -1
- package/dist/dpop/dpop-manager.d.ts.map +1 -1
- package/dist/dpop/dpop-manager.js +1 -4
- package/dist/dpop/dpop-manager.js.map +1 -1
- package/dist/errors/invalid-authorization-details-error.d.ts +4 -3
- package/dist/errors/invalid-authorization-details-error.d.ts.map +1 -1
- package/dist/errors/invalid-authorization-details-error.js +4 -4
- package/dist/errors/invalid-authorization-details-error.js.map +1 -1
- package/dist/lib/http/parser.d.ts +13 -7
- package/dist/lib/http/parser.d.ts.map +1 -1
- package/dist/lib/http/parser.js +29 -9
- package/dist/lib/http/parser.js.map +1 -1
- package/dist/lib/http/request.d.ts +8 -5
- package/dist/lib/http/request.d.ts.map +1 -1
- package/dist/lib/http/request.js +24 -12
- package/dist/lib/http/request.js.map +1 -1
- package/dist/lib/http/stream.d.ts.map +1 -1
- package/dist/lib/http/stream.js +3 -2
- package/dist/lib/http/stream.js.map +1 -1
- package/dist/metadata/build-metadata.d.ts +0 -1
- package/dist/metadata/build-metadata.d.ts.map +1 -1
- package/dist/metadata/build-metadata.js +9 -49
- package/dist/metadata/build-metadata.js.map +1 -1
- package/dist/oauth-hooks.d.ts +3 -10
- package/dist/oauth-hooks.d.ts.map +1 -1
- package/dist/oauth-provider.d.ts +10 -15
- package/dist/oauth-provider.d.ts.map +1 -1
- package/dist/oauth-provider.js +176 -114
- package/dist/oauth-provider.js.map +1 -1
- package/dist/oauth-verifier.d.ts +1 -2
- package/dist/oauth-verifier.d.ts.map +1 -1
- package/dist/oauth-verifier.js.map +1 -1
- package/dist/output/build-authorize-data.d.ts +6 -0
- package/dist/output/build-authorize-data.d.ts.map +1 -1
- package/dist/output/build-authorize-data.js +1 -0
- package/dist/output/build-authorize-data.js.map +1 -1
- package/dist/replay/replay-manager.d.ts +1 -0
- package/dist/replay/replay-manager.d.ts.map +1 -1
- package/dist/replay/replay-manager.js +3 -0
- package/dist/replay/replay-manager.js.map +1 -1
- package/dist/replay/replay-store.d.ts +1 -1
- package/dist/request/request-info.d.ts +2 -0
- package/dist/request/request-info.d.ts.map +1 -1
- package/dist/request/request-manager.d.ts +3 -9
- package/dist/request/request-manager.d.ts.map +1 -1
- package/dist/request/request-manager.js +52 -77
- package/dist/request/request-manager.js.map +1 -1
- package/dist/request/types.d.ts +10 -10
- package/dist/signer/signed-token-payload.d.ts +88 -88
- package/dist/signer/signer.d.ts +24 -31
- package/dist/signer/signer.d.ts.map +1 -1
- package/dist/signer/signer.js +0 -40
- package/dist/signer/signer.js.map +1 -1
- package/dist/token/token-claims.d.ts +84 -84
- package/dist/token/token-manager.d.ts +1 -2
- package/dist/token/token-manager.d.ts.map +1 -1
- package/dist/token/token-manager.js +10 -37
- package/dist/token/token-manager.js.map +1 -1
- package/dist/token/types.d.ts +10 -10
- package/package.json +3 -3
- package/src/account/account.ts +11 -7
- package/src/assets/app/backend-data.ts +9 -2
- package/src/assets/app/components/accept-form.tsx +65 -51
- package/src/assets/app/components/client-name.tsx +24 -16
- package/src/assets/app/components/url-viewer.tsx +3 -3
- package/src/assets/app/views/accept-view.tsx +7 -4
- package/src/assets/app/views/authorize-view.tsx +2 -1
- package/src/assets/assets-middleware.ts +14 -2
- package/src/client/client-manager.ts +124 -120
- package/src/client/client.ts +5 -17
- package/src/constants.ts +3 -0
- package/src/device/device-manager.ts +7 -1
- package/src/dpop/dpop-manager.ts +1 -6
- package/src/errors/invalid-authorization-details-error.ts +9 -4
- package/src/lib/http/parser.ts +37 -13
- package/src/lib/http/request.ts +61 -15
- package/src/lib/http/stream.ts +5 -2
- package/src/metadata/build-metadata.ts +9 -56
- package/src/oauth-hooks.ts +3 -13
- package/src/oauth-provider.ts +187 -177
- package/src/oauth-verifier.ts +1 -2
- package/src/output/build-authorize-data.ts +8 -0
- package/src/replay/replay-manager.ts +9 -0
- package/src/replay/replay-store.ts +1 -1
- package/src/request/request-info.ts +2 -0
- package/src/request/request-manager.ts +81 -107
- package/src/signer/signer.ts +0 -63
- package/src/token/token-manager.ts +8 -41
- package/dist/oidc/claims.d.ts +0 -16
- package/dist/oidc/claims.d.ts.map +0 -1
- package/dist/oidc/claims.js +0 -29
- package/dist/oidc/claims.js.map +0 -1
- package/dist/oidc/userinfo.d.ts +0 -7
- package/dist/oidc/userinfo.d.ts.map +0 -1
- package/dist/oidc/userinfo.js +0 -3
- package/dist/oidc/userinfo.js.map +0 -1
- package/dist/parameters/claims-requested.d.ts +0 -3
- package/dist/parameters/claims-requested.d.ts.map +0 -1
- package/dist/parameters/claims-requested.js +0 -77
- package/dist/parameters/claims-requested.js.map +0 -1
- package/dist/parameters/oidc-payload.d.ts +0 -31
- package/dist/parameters/oidc-payload.d.ts.map +0 -1
- package/dist/parameters/oidc-payload.js +0 -25
- package/dist/parameters/oidc-payload.js.map +0 -1
- package/src/assets/app/components/client-identifier.tsx +0 -31
- package/src/oidc/claims.ts +0 -35
- package/src/oidc/userinfo.ts +0 -11
- package/src/parameters/claims-requested.ts +0 -106
- package/src/parameters/oidc-payload.ts +0 -28
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.claimRequested = void 0;
|
|
4
|
-
const invalid_request_error_js_1 = require("../errors/invalid-request-error.js");
|
|
5
|
-
function claimRequested(parameters, entityType, claimName, value) {
|
|
6
|
-
if (claimAvailable(parameters, entityType, claimName, value)) {
|
|
7
|
-
return true;
|
|
8
|
-
}
|
|
9
|
-
const entityClaims = parameters.claims?.[entityType];
|
|
10
|
-
if (entityClaims?.[claimName]?.essential === true) {
|
|
11
|
-
// https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.5.5.1
|
|
12
|
-
//
|
|
13
|
-
// > By requesting Claims as Essential Claims, the RP indicates to the
|
|
14
|
-
// > End-User that releasing these Claims will ensure a smooth
|
|
15
|
-
// > authorization for the specific task requested by the End-User. Note
|
|
16
|
-
// > that even if the Claims are not available because the End-User did
|
|
17
|
-
// > not authorize their release or they are not present, the
|
|
18
|
-
// > Authorization Server MUST NOT generate an error when Claims are not
|
|
19
|
-
// > returned, whether they are Essential or Voluntary, unless otherwise
|
|
20
|
-
// > specified in the description of the specific claim.
|
|
21
|
-
switch (claimName) {
|
|
22
|
-
case 'acr':
|
|
23
|
-
// https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.5.5.1.1
|
|
24
|
-
//
|
|
25
|
-
// > If this is an Essential Claim and the requirement cannot be met,
|
|
26
|
-
// > then the Authorization Server MUST treat that outcome as a failed
|
|
27
|
-
// > authentication attempt.
|
|
28
|
-
throw new invalid_request_error_js_1.InvalidRequestError(`Unable to provide essential claim: ${claimName}`);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
exports.claimRequested = claimRequested;
|
|
34
|
-
function claimAvailable(parameters, entityType, claimName, value) {
|
|
35
|
-
if (value === undefined)
|
|
36
|
-
return false;
|
|
37
|
-
if (parameters.claims) {
|
|
38
|
-
const entityClaims = parameters.claims[entityType];
|
|
39
|
-
if (entityClaims === undefined)
|
|
40
|
-
return false;
|
|
41
|
-
const claimConfig = entityClaims[claimName];
|
|
42
|
-
if (claimConfig === undefined)
|
|
43
|
-
return false;
|
|
44
|
-
if (claimConfig === null)
|
|
45
|
-
return true;
|
|
46
|
-
if (claimConfig.value !== undefined &&
|
|
47
|
-
!compareClaimValue(claimConfig.value, value)) {
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
if (claimConfig?.values !== undefined &&
|
|
51
|
-
!claimConfig.values.some((v) => compareClaimValue(v, value))) {
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return true;
|
|
56
|
-
}
|
|
57
|
-
function compareClaimValue(expectedValue, value) {
|
|
58
|
-
const expectedType = typeof expectedValue;
|
|
59
|
-
const valueType = typeof value;
|
|
60
|
-
if (expectedType !== valueType)
|
|
61
|
-
return false;
|
|
62
|
-
switch (typeof expectedValue) {
|
|
63
|
-
case 'undefined':
|
|
64
|
-
case 'string':
|
|
65
|
-
case 'number':
|
|
66
|
-
case 'boolean':
|
|
67
|
-
return expectedValue === value;
|
|
68
|
-
case 'object':
|
|
69
|
-
if (expectedValue === null)
|
|
70
|
-
return value === null;
|
|
71
|
-
// @TODO (?): allow object comparison
|
|
72
|
-
// falls through
|
|
73
|
-
default:
|
|
74
|
-
throw new invalid_request_error_js_1.InvalidRequestError(`Unable to compare claim value of type ${expectedType}`);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
//# sourceMappingURL=claims-requested.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"claims-requested.js","sourceRoot":"","sources":["../../src/parameters/claims-requested.ts"],"names":[],"mappings":";;;AAKA,iFAAwE;AAExE,SAAgB,cAAc,CAC5B,UAAgD,EAChD,UAA0B,EAC1B,SAA8B,EAC9B,KAAc;IAEd,IAAI,cAAc,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC;QAC7D,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,CAAA;IACpD,IAAI,YAAY,EAAE,CAAC,SAAS,CAAC,EAAE,SAAS,KAAK,IAAI,EAAE,CAAC;QAClD,0EAA0E;QAC1E,EAAE;QACF,sEAAsE;QACtE,8DAA8D;QAC9D,wEAAwE;QACxE,uEAAuE;QACvE,6DAA6D;QAC7D,wEAAwE;QACxE,wEAAwE;QACxE,wDAAwD;QACxD,QAAQ,SAAS,EAAE,CAAC;YAClB,KAAK,KAAK;gBACR,4EAA4E;gBAC5E,EAAE;gBACF,qEAAqE;gBACrE,sEAAsE;gBACtE,4BAA4B;gBAC5B,MAAM,IAAI,8CAAmB,CAC3B,sCAAsC,SAAS,EAAE,CAClD,CAAA;QACL,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AApCD,wCAoCC;AAED,SAAS,cAAc,CACrB,UAAgD,EAChD,UAA0B,EAC1B,SAA8B,EAC9B,KAAc;IAEd,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAA;IAErC,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QACtB,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;QAClD,IAAI,YAAY,KAAK,SAAS;YAAE,OAAO,KAAK,CAAA;QAE5C,MAAM,WAAW,GAAG,YAAY,CAAC,SAAS,CAAC,CAAA;QAC3C,IAAI,WAAW,KAAK,SAAS;YAAE,OAAO,KAAK,CAAA;QAC3C,IAAI,WAAW,KAAK,IAAI;YAAE,OAAO,IAAI,CAAA;QAErC,IACE,WAAW,CAAC,KAAK,KAAK,SAAS;YAC/B,CAAC,iBAAiB,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,EAC5C,CAAC;YACD,OAAO,KAAK,CAAA;QACd,CAAC;QAED,IACE,WAAW,EAAE,MAAM,KAAK,SAAS;YACjC,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAC5D,CAAC;YACD,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAID,SAAS,iBAAiB,CACxB,aAA2B,EAC3B,KAAmB;IAEnB,MAAM,YAAY,GAAG,OAAO,aAAa,CAAA;IACzC,MAAM,SAAS,GAAG,OAAO,KAAK,CAAA;IAE9B,IAAI,YAAY,KAAK,SAAS;QAAE,OAAO,KAAK,CAAA;IAE5C,QAAQ,OAAO,aAAa,EAAE,CAAC;QAC7B,KAAK,WAAW,CAAC;QACjB,KAAK,QAAQ,CAAC;QACd,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS;YACZ,OAAO,aAAa,KAAK,KAAK,CAAA;QAChC,KAAK,QAAQ;YACX,IAAI,aAAa,KAAK,IAAI;gBAAE,OAAO,KAAK,KAAK,IAAI,CAAA;QACnD,qCAAqC;QACrC,gBAAgB;QAChB;YACE,MAAM,IAAI,8CAAmB,CAC3B,yCAAyC,YAAY,EAAE,CACxD,CAAA;IACL,CAAC;AACH,CAAC"}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { OAuthAuthenticationRequestParameters } from '@atproto/oauth-types';
|
|
2
|
-
import { Account } from '../account/account.js';
|
|
3
|
-
export declare function oidcPayload(params: OAuthAuthenticationRequestParameters, account: Account): Partial<{
|
|
4
|
-
name?: string | undefined;
|
|
5
|
-
email?: string | undefined;
|
|
6
|
-
email_verified?: boolean | undefined;
|
|
7
|
-
phone_number?: string | undefined;
|
|
8
|
-
phone_number_verified?: boolean | undefined;
|
|
9
|
-
address?: {
|
|
10
|
-
formatted?: string | undefined;
|
|
11
|
-
street_address?: string | undefined;
|
|
12
|
-
locality?: string | undefined;
|
|
13
|
-
region?: string | undefined;
|
|
14
|
-
postal_code?: string | undefined;
|
|
15
|
-
country?: string | undefined;
|
|
16
|
-
} | undefined;
|
|
17
|
-
profile?: string | undefined;
|
|
18
|
-
family_name?: string | undefined;
|
|
19
|
-
given_name?: string | undefined;
|
|
20
|
-
middle_name?: string | undefined;
|
|
21
|
-
nickname?: string | undefined;
|
|
22
|
-
preferred_username?: string | undefined;
|
|
23
|
-
gender?: string | undefined;
|
|
24
|
-
picture?: string | undefined;
|
|
25
|
-
website?: string | undefined;
|
|
26
|
-
birthdate?: string | undefined;
|
|
27
|
-
zoneinfo?: string | undefined;
|
|
28
|
-
locale?: string | undefined;
|
|
29
|
-
updated_at?: number | undefined;
|
|
30
|
-
}>;
|
|
31
|
-
//# sourceMappingURL=oidc-payload.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"oidc-payload.d.ts","sourceRoot":"","sources":["../../src/parameters/oidc-payload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oCAAoC,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAI/C,wBAAgB,WAAW,CACzB,MAAM,EAAE,oCAAoC,EAC5C,OAAO,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoBjB"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.oidcPayload = void 0;
|
|
4
|
-
const claims_js_1 = require("../oidc/claims.js");
|
|
5
|
-
const claims_requested_js_1 = require("./claims-requested.js");
|
|
6
|
-
function oidcPayload(params, account) {
|
|
7
|
-
const payload = {};
|
|
8
|
-
const scopes = params.scope ? params.scope?.split(' ') : undefined;
|
|
9
|
-
if (scopes) {
|
|
10
|
-
for (const [scope, claims] of Object.entries(claims_js_1.OIDC_SCOPE_CLAIMS)) {
|
|
11
|
-
const allowed = scopes.includes(scope);
|
|
12
|
-
for (const claim of claims) {
|
|
13
|
-
const value = allowed ? account[claim] : undefined;
|
|
14
|
-
// Should not throw as RequestManager should have already checked
|
|
15
|
-
// that all the essential claims are available.
|
|
16
|
-
if ((0, claims_requested_js_1.claimRequested)(params, 'id_token', claim, value)) {
|
|
17
|
-
payload[claim] = value; // All good as long as the account props match the claims
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return payload;
|
|
23
|
-
}
|
|
24
|
-
exports.oidcPayload = oidcPayload;
|
|
25
|
-
//# sourceMappingURL=oidc-payload.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"oidc-payload.js","sourceRoot":"","sources":["../../src/parameters/oidc-payload.ts"],"names":[],"mappings":";;;AAEA,iDAA0E;AAC1E,+DAAsD;AAEtD,SAAgB,WAAW,CACzB,MAA4C,EAC5C,OAAgB;IAEhB,MAAM,OAAO,GAAwB,EAAE,CAAA;IAEvC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAClE,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,6BAAiB,CAAC,EAAE,CAAC;YAChE,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;YACtC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;gBAClD,iEAAiE;gBACjE,+CAA+C;gBAC/C,IAAI,IAAA,oCAAc,EAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC;oBACrD,OAAO,CAAC,KAAK,CAAC,GAAG,KAAY,CAAA,CAAC,yDAAyD;gBACzF,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAtBD,kCAsBC"}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isOAuthClientIdDiscoverable,
|
|
3
|
-
isOAuthClientIdLoopback,
|
|
4
|
-
OAuthClientMetadata,
|
|
5
|
-
} from '@atproto/oauth-types'
|
|
6
|
-
import { HTMLAttributes } from 'react'
|
|
7
|
-
|
|
8
|
-
import { UrlViewer } from './url-viewer'
|
|
9
|
-
|
|
10
|
-
export type ClientIdentifierProps = {
|
|
11
|
-
clientId: string
|
|
12
|
-
clientMetadata: OAuthClientMetadata
|
|
13
|
-
as?: keyof JSX.IntrinsicElements
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function ClientIdentifier({
|
|
17
|
-
clientId,
|
|
18
|
-
clientMetadata,
|
|
19
|
-
as: As = 'span',
|
|
20
|
-
...attrs
|
|
21
|
-
}: ClientIdentifierProps & HTMLAttributes<Element>) {
|
|
22
|
-
if (isOAuthClientIdLoopback(clientId)) {
|
|
23
|
-
return <As {...attrs}>An application on your device</As>
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (isOAuthClientIdDiscoverable(clientId)) {
|
|
27
|
-
return <UrlViewer as={As} {...attrs} url={clientId} proto path />
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return <As {...attrs}>{clientMetadata.client_name || clientId}</As>
|
|
31
|
-
}
|
package/src/oidc/claims.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { JwtPayload } from '@atproto/jwk'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @see {@link https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims | OpenID Connect Core 1.0, 5.4. Requesting Claims using Scope Values}
|
|
5
|
-
*/
|
|
6
|
-
export const OIDC_SCOPE_CLAIMS = Object.freeze({
|
|
7
|
-
email: Object.freeze(['email', 'email_verified'] as const),
|
|
8
|
-
phone: Object.freeze(['phone_number', 'phone_number_verified'] as const),
|
|
9
|
-
address: Object.freeze(['address'] as const),
|
|
10
|
-
profile: Object.freeze([
|
|
11
|
-
'name',
|
|
12
|
-
'family_name',
|
|
13
|
-
'given_name',
|
|
14
|
-
'middle_name',
|
|
15
|
-
'nickname',
|
|
16
|
-
'preferred_username',
|
|
17
|
-
'gender',
|
|
18
|
-
'picture',
|
|
19
|
-
'profile',
|
|
20
|
-
'website',
|
|
21
|
-
'birthdate',
|
|
22
|
-
'zoneinfo',
|
|
23
|
-
'locale',
|
|
24
|
-
'updated_at',
|
|
25
|
-
] as const),
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
export const OIDC_STANDARD_CLAIMS = Object.freeze(
|
|
29
|
-
Object.values(OIDC_SCOPE_CLAIMS).flat(),
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
export type OIDCStandardClaim = (typeof OIDC_STANDARD_CLAIMS)[number]
|
|
33
|
-
export type OIDCStandardPayload = Partial<{
|
|
34
|
-
[K in OIDCStandardClaim]?: JwtPayload[K]
|
|
35
|
-
}>
|
package/src/oidc/userinfo.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { OIDCStandardPayload } from './claims.js'
|
|
2
|
-
|
|
3
|
-
export type Userinfo = OIDCStandardPayload & {
|
|
4
|
-
// "The sub (subject) Claim MUST always be returned in the UserInfo Response."
|
|
5
|
-
sub: string
|
|
6
|
-
|
|
7
|
-
// client_id is not mandatory per spec, but we require it here for convenience
|
|
8
|
-
client_id: string
|
|
9
|
-
|
|
10
|
-
username?: string
|
|
11
|
-
}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
OAuthAuthenticationRequestParameters,
|
|
3
|
-
OidcClaimsParameter,
|
|
4
|
-
OidcEntityType,
|
|
5
|
-
} from '@atproto/oauth-types'
|
|
6
|
-
import { InvalidRequestError } from '../errors/invalid-request-error.js'
|
|
7
|
-
|
|
8
|
-
export function claimRequested(
|
|
9
|
-
parameters: OAuthAuthenticationRequestParameters,
|
|
10
|
-
entityType: OidcEntityType,
|
|
11
|
-
claimName: OidcClaimsParameter,
|
|
12
|
-
value: unknown,
|
|
13
|
-
): boolean {
|
|
14
|
-
if (claimAvailable(parameters, entityType, claimName, value)) {
|
|
15
|
-
return true
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const entityClaims = parameters.claims?.[entityType]
|
|
19
|
-
if (entityClaims?.[claimName]?.essential === true) {
|
|
20
|
-
// https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.5.5.1
|
|
21
|
-
//
|
|
22
|
-
// > By requesting Claims as Essential Claims, the RP indicates to the
|
|
23
|
-
// > End-User that releasing these Claims will ensure a smooth
|
|
24
|
-
// > authorization for the specific task requested by the End-User. Note
|
|
25
|
-
// > that even if the Claims are not available because the End-User did
|
|
26
|
-
// > not authorize their release or they are not present, the
|
|
27
|
-
// > Authorization Server MUST NOT generate an error when Claims are not
|
|
28
|
-
// > returned, whether they are Essential or Voluntary, unless otherwise
|
|
29
|
-
// > specified in the description of the specific claim.
|
|
30
|
-
switch (claimName) {
|
|
31
|
-
case 'acr':
|
|
32
|
-
// https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.5.5.1.1
|
|
33
|
-
//
|
|
34
|
-
// > If this is an Essential Claim and the requirement cannot be met,
|
|
35
|
-
// > then the Authorization Server MUST treat that outcome as a failed
|
|
36
|
-
// > authentication attempt.
|
|
37
|
-
throw new InvalidRequestError(
|
|
38
|
-
`Unable to provide essential claim: ${claimName}`,
|
|
39
|
-
)
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return false
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function claimAvailable(
|
|
47
|
-
parameters: OAuthAuthenticationRequestParameters,
|
|
48
|
-
entityType: OidcEntityType,
|
|
49
|
-
claimName: OidcClaimsParameter,
|
|
50
|
-
value: unknown,
|
|
51
|
-
): boolean {
|
|
52
|
-
if (value === undefined) return false
|
|
53
|
-
|
|
54
|
-
if (parameters.claims) {
|
|
55
|
-
const entityClaims = parameters.claims[entityType]
|
|
56
|
-
if (entityClaims === undefined) return false
|
|
57
|
-
|
|
58
|
-
const claimConfig = entityClaims[claimName]
|
|
59
|
-
if (claimConfig === undefined) return false
|
|
60
|
-
if (claimConfig === null) return true
|
|
61
|
-
|
|
62
|
-
if (
|
|
63
|
-
claimConfig.value !== undefined &&
|
|
64
|
-
!compareClaimValue(claimConfig.value, value)
|
|
65
|
-
) {
|
|
66
|
-
return false
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (
|
|
70
|
-
claimConfig?.values !== undefined &&
|
|
71
|
-
!claimConfig.values.some((v) => compareClaimValue(v, value))
|
|
72
|
-
) {
|
|
73
|
-
return false
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return true
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
type DefinedValue = NonNullable<unknown> | null
|
|
81
|
-
|
|
82
|
-
function compareClaimValue(
|
|
83
|
-
expectedValue: DefinedValue,
|
|
84
|
-
value: DefinedValue,
|
|
85
|
-
): boolean {
|
|
86
|
-
const expectedType = typeof expectedValue
|
|
87
|
-
const valueType = typeof value
|
|
88
|
-
|
|
89
|
-
if (expectedType !== valueType) return false
|
|
90
|
-
|
|
91
|
-
switch (typeof expectedValue) {
|
|
92
|
-
case 'undefined':
|
|
93
|
-
case 'string':
|
|
94
|
-
case 'number':
|
|
95
|
-
case 'boolean':
|
|
96
|
-
return expectedValue === value
|
|
97
|
-
case 'object':
|
|
98
|
-
if (expectedValue === null) return value === null
|
|
99
|
-
// @TODO (?): allow object comparison
|
|
100
|
-
// falls through
|
|
101
|
-
default:
|
|
102
|
-
throw new InvalidRequestError(
|
|
103
|
-
`Unable to compare claim value of type ${expectedType}`,
|
|
104
|
-
)
|
|
105
|
-
}
|
|
106
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { OAuthAuthenticationRequestParameters } from '@atproto/oauth-types'
|
|
2
|
-
import { Account } from '../account/account.js'
|
|
3
|
-
import { OIDCStandardPayload, OIDC_SCOPE_CLAIMS } from '../oidc/claims.js'
|
|
4
|
-
import { claimRequested } from './claims-requested.js'
|
|
5
|
-
|
|
6
|
-
export function oidcPayload(
|
|
7
|
-
params: OAuthAuthenticationRequestParameters,
|
|
8
|
-
account: Account,
|
|
9
|
-
) {
|
|
10
|
-
const payload: OIDCStandardPayload = {}
|
|
11
|
-
|
|
12
|
-
const scopes = params.scope ? params.scope?.split(' ') : undefined
|
|
13
|
-
if (scopes) {
|
|
14
|
-
for (const [scope, claims] of Object.entries(OIDC_SCOPE_CLAIMS)) {
|
|
15
|
-
const allowed = scopes.includes(scope)
|
|
16
|
-
for (const claim of claims) {
|
|
17
|
-
const value = allowed ? account[claim] : undefined
|
|
18
|
-
// Should not throw as RequestManager should have already checked
|
|
19
|
-
// that all the essential claims are available.
|
|
20
|
-
if (claimRequested(params, 'id_token', claim, value)) {
|
|
21
|
-
payload[claim] = value as any // All good as long as the account props match the claims
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return payload
|
|
28
|
-
}
|