@atproto/oauth-provider 0.10.2 → 0.11.1
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 +29 -0
- 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/customization/branding.d.ts +5 -19
- package/dist/customization/branding.d.ts.map +1 -1
- package/dist/customization/customization.d.ts +7 -25
- package/dist/customization/customization.d.ts.map +1 -1
- package/dist/customization/links.d.ts +3 -13
- package/dist/customization/links.d.ts.map +1 -1
- package/dist/customization/links.js +1 -1
- package/dist/customization/links.js.map +1 -1
- package/dist/lexicon/lexicon-data.d.ts +9 -0
- package/dist/lexicon/lexicon-data.d.ts.map +1 -0
- package/dist/lexicon/lexicon-data.js +3 -0
- package/dist/lexicon/lexicon-data.js.map +1 -0
- package/dist/lexicon/lexicon-getter.d.ts +15 -0
- package/dist/lexicon/lexicon-getter.d.ts.map +1 -0
- package/dist/lexicon/lexicon-getter.js +55 -0
- package/dist/lexicon/lexicon-getter.js.map +1 -0
- package/dist/lexicon/lexicon-manager.d.ts +60 -0
- package/dist/lexicon/lexicon-manager.d.ts.map +1 -0
- package/dist/lexicon/lexicon-manager.js +105 -0
- package/dist/lexicon/lexicon-manager.js.map +1 -0
- package/dist/lexicon/lexicon-store.d.ts +13 -0
- package/dist/lexicon/lexicon-store.d.ts.map +1 -0
- package/dist/lexicon/lexicon-store.js +24 -0
- package/dist/lexicon/lexicon-store.js.map +1 -0
- package/dist/lib/html/hydration-data.d.ts.map +1 -1
- package/dist/lib/html/hydration-data.js +1 -2
- package/dist/lib/html/hydration-data.js.map +1 -1
- package/dist/lib/nsid.d.ts +4 -0
- package/dist/lib/nsid.d.ts.map +1 -0
- package/dist/lib/nsid.js +15 -0
- package/dist/lib/nsid.js.map +1 -0
- package/dist/lib/util/locale.d.ts +1 -15
- package/dist/lib/util/locale.d.ts.map +1 -1
- package/dist/lib/util/locale.js +2 -7
- package/dist/lib/util/locale.js.map +1 -1
- package/dist/oauth-provider.d.ts +14 -9
- package/dist/oauth-provider.d.ts.map +1 -1
- package/dist/oauth-provider.js +15 -6
- package/dist/oauth-provider.js.map +1 -1
- package/dist/oauth-store.d.ts +1 -0
- package/dist/oauth-store.d.ts.map +1 -1
- package/dist/oauth-store.js +1 -0
- package/dist/oauth-store.js.map +1 -1
- package/dist/request/request-manager.d.ts +3 -1
- package/dist/request/request-manager.d.ts.map +1 -1
- package/dist/request/request-manager.js +19 -4
- package/dist/request/request-manager.js.map +1 -1
- package/dist/result/authorization-result-authorize-page.d.ts +5 -3
- package/dist/result/authorization-result-authorize-page.d.ts.map +1 -1
- package/dist/router/assets/send-authorization-page.d.ts.map +1 -1
- package/dist/router/assets/send-authorization-page.js +1 -0
- package/dist/router/assets/send-authorization-page.js.map +1 -1
- package/dist/token/token-data.d.ts +7 -0
- package/dist/token/token-data.d.ts.map +1 -1
- package/dist/token/token-manager.d.ts +5 -6
- package/dist/token/token-manager.d.ts.map +1 -1
- package/dist/token/token-manager.js +37 -13
- package/dist/token/token-manager.js.map +1 -1
- package/dist/token/token-store.d.ts +16 -2
- package/dist/token/token-store.d.ts.map +1 -1
- package/dist/token/token-store.js.map +1 -1
- package/package.json +12 -10
- package/src/constants.ts +3 -0
- package/src/customization/links.ts +2 -2
- package/src/lexicon/lexicon-data.ts +9 -0
- package/src/lexicon/lexicon-getter.ts +62 -0
- package/src/lexicon/lexicon-manager.ts +116 -0
- package/src/lexicon/lexicon-store.ts +36 -0
- package/src/lib/html/hydration-data.ts +1 -2
- package/src/lib/nsid.ts +10 -0
- package/src/lib/util/locale.ts +3 -9
- package/src/oauth-provider.ts +30 -9
- package/src/oauth-store.ts +1 -0
- package/src/request/request-manager.ts +26 -7
- package/src/result/authorization-result-authorize-page.ts +5 -3
- package/src/router/assets/send-authorization-page.ts +1 -0
- package/src/token/token-data.ts +8 -0
- package/src/token/token-manager.ts +68 -34
- package/src/token/token-store.ts +17 -5
- package/tsconfig.build.tsbuildinfo +1 -1
@@ -5,6 +5,7 @@ import { AccessTokenMode } from '../access-token/access-token-mode.js';
|
|
5
5
|
import { ClientAuth } from '../client/client-auth.js';
|
6
6
|
import { Client } from '../client/client.js';
|
7
7
|
import { DeviceId } from '../device/device-id.js';
|
8
|
+
import { LexiconManager } from '../lexicon/lexicon-manager.js';
|
8
9
|
import { RequestMetadata } from '../lib/http/request.js';
|
9
10
|
import { OAuthHooks } from '../oauth-hooks.js';
|
10
11
|
import { DpopProof } from '../oauth-verifier.js';
|
@@ -19,19 +20,17 @@ export { AccessTokenMode, Signer };
|
|
19
20
|
export type { OAuthHooks, TokenStore, VerifyTokenClaimsResult };
|
20
21
|
export declare class TokenManager {
|
21
22
|
protected readonly store: TokenStore;
|
23
|
+
protected readonly lexiconManager: LexiconManager;
|
22
24
|
protected readonly signer: Signer;
|
23
25
|
protected readonly hooks: OAuthHooks;
|
24
26
|
protected readonly accessTokenMode: AccessTokenMode;
|
25
27
|
protected readonly tokenMaxAge: number;
|
26
|
-
constructor(store: TokenStore, signer: Signer, hooks: OAuthHooks, accessTokenMode: AccessTokenMode, tokenMaxAge?: number);
|
28
|
+
constructor(store: TokenStore, lexiconManager: LexiconManager, signer: Signer, hooks: OAuthHooks, accessTokenMode: AccessTokenMode, tokenMaxAge?: number);
|
27
29
|
protected createTokenExpiry(now?: Date): Date;
|
28
|
-
protected buildAccessToken(tokenId: TokenId, account: Account, client: Client, parameters: OAuthAuthorizationRequestParameters,
|
29
|
-
now: Date;
|
30
|
-
expiresAt: Date;
|
31
|
-
}): Promise<OAuthAccessToken>;
|
30
|
+
protected buildAccessToken(tokenId: TokenId, account: Account, client: Client, parameters: OAuthAuthorizationRequestParameters, createdAt: Date, expiresAt: Date, scope: string): Promise<OAuthAccessToken>;
|
32
31
|
createToken(client: Client, clientAuth: ClientAuth, clientMetadata: RequestMetadata, account: Account, deviceId: null | DeviceId, parameters: OAuthAuthorizationRequestParameters, code: Code): Promise<OAuthTokenResponse>;
|
33
32
|
protected validateTokenParams(client: Client, clientAuth: ClientAuth, parameters: OAuthAuthorizationRequestParameters): Promise<void>;
|
34
|
-
protected buildTokenResponse(
|
33
|
+
protected buildTokenResponse(tokenType: OAuthTokenType, accessToken: OAuthAccessToken, refreshToken: string | undefined, expiresAt: Date, sub: Sub, scope: string): OAuthTokenResponse;
|
35
34
|
rotateToken(client: Client, clientAuth: ClientAuth, clientMetadata: RequestMetadata, tokenInfo: TokenInfo): Promise<OAuthTokenResponse>;
|
36
35
|
/**
|
37
36
|
* @note The token validity is not guaranteed. The caller must ensure that the
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"token-manager.d.ts","sourceRoot":"","sources":["../../src/token/token-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAe,MAAM,cAAc,CAAA;
|
1
|
+
{"version":3,"file":"token-manager.d.ts","sourceRoot":"","sources":["../../src/token/token-manager.ts"],"names":[],"mappings":"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"}
|
@@ -2,6 +2,7 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.TokenManager = exports.Signer = exports.AccessTokenMode = void 0;
|
4
4
|
const jwk_1 = require("@atproto/jwk");
|
5
|
+
const lexicon_resolver_1 = require("@atproto/lexicon-resolver");
|
5
6
|
const access_token_mode_js_1 = require("../access-token/access-token-mode.js");
|
6
7
|
Object.defineProperty(exports, "AccessTokenMode", { enumerable: true, get: function () { return access_token_mode_js_1.AccessTokenMode; } });
|
7
8
|
const constants_js_1 = require("../constants.js");
|
@@ -18,12 +19,14 @@ const token_id_js_1 = require("./token-id.js");
|
|
18
19
|
const verify_token_claims_js_1 = require("./verify-token-claims.js");
|
19
20
|
class TokenManager {
|
20
21
|
store;
|
22
|
+
lexiconManager;
|
21
23
|
signer;
|
22
24
|
hooks;
|
23
25
|
accessTokenMode;
|
24
26
|
tokenMaxAge;
|
25
|
-
constructor(store, signer, hooks, accessTokenMode, tokenMaxAge = constants_js_1.TOKEN_MAX_AGE) {
|
27
|
+
constructor(store, lexiconManager, signer, hooks, accessTokenMode, tokenMaxAge = constants_js_1.TOKEN_MAX_AGE) {
|
26
28
|
this.store = store;
|
29
|
+
this.lexiconManager = lexiconManager;
|
27
30
|
this.signer = signer;
|
28
31
|
this.hooks = hooks;
|
29
32
|
this.accessTokenMode = accessTokenMode;
|
@@ -32,16 +35,16 @@ class TokenManager {
|
|
32
35
|
createTokenExpiry(now = new Date()) {
|
33
36
|
return new Date(now.getTime() + this.tokenMaxAge);
|
34
37
|
}
|
35
|
-
async buildAccessToken(tokenId, account, client, parameters,
|
38
|
+
async buildAccessToken(tokenId, account, client, parameters, createdAt, expiresAt, scope) {
|
36
39
|
return this.signer.createAccessToken({
|
37
40
|
jti: tokenId,
|
38
41
|
sub: account.sub,
|
39
|
-
exp: (0, date_js_1.dateToEpoch)(
|
40
|
-
iat: (0, date_js_1.dateToEpoch)(
|
42
|
+
exp: (0, date_js_1.dateToEpoch)(expiresAt),
|
43
|
+
iat: (0, date_js_1.dateToEpoch)(createdAt),
|
41
44
|
cnf: parameters.dpop_jkt ? { jkt: parameters.dpop_jkt } : undefined,
|
42
45
|
...(this.accessTokenMode === access_token_mode_js_1.AccessTokenMode.stateless && {
|
43
46
|
aud: account.aud,
|
44
|
-
scope
|
47
|
+
scope,
|
45
48
|
// https://datatracker.ietf.org/doc/html/rfc8693#section-4.3
|
46
49
|
client_id: client.id,
|
47
50
|
}),
|
@@ -55,6 +58,15 @@ class TokenManager {
|
|
55
58
|
: undefined;
|
56
59
|
const now = new Date();
|
57
60
|
const expiresAt = this.createTokenExpiry(now);
|
61
|
+
const scope = await this.lexiconManager
|
62
|
+
.buildTokenScope(parameters.scope)
|
63
|
+
.catch((cause) => {
|
64
|
+
throw new invalid_request_error_js_1.InvalidRequestError(cause instanceof lexicon_resolver_1.LexiconResolutionError
|
65
|
+
? cause.message
|
66
|
+
: 'Unable to retrieve included permission sets', cause);
|
67
|
+
});
|
68
|
+
const accessToken = await this.buildAccessToken(tokenId, account, client, parameters, now, expiresAt, scope);
|
69
|
+
const response = this.buildTokenResponse(inferTokenType(parameters), accessToken, refreshToken, expiresAt, account.sub, scope);
|
58
70
|
const tokenData = {
|
59
71
|
createdAt: now,
|
60
72
|
updatedAt: now,
|
@@ -65,10 +77,9 @@ class TokenManager {
|
|
65
77
|
sub: account.sub,
|
66
78
|
parameters,
|
67
79
|
details: null,
|
80
|
+
scope,
|
68
81
|
code,
|
69
82
|
};
|
70
|
-
const accessToken = await this.buildAccessToken(tokenId, account, client, parameters, { now, expiresAt });
|
71
|
-
const response = await this.buildTokenResponse(client, accessToken, refreshToken, expiresAt, parameters, account.sub);
|
72
83
|
await this.store.createToken(tokenId, tokenData, refreshToken);
|
73
84
|
try {
|
74
85
|
await (0, function_js_1.callAsync)(this.hooks.onTokenCreated, {
|
@@ -92,12 +103,12 @@ class TokenManager {
|
|
92
103
|
throw new invalid_grant_error_js_1.InvalidGrantError(`DPoP JKT is required for DPoP bound access tokens`);
|
93
104
|
}
|
94
105
|
}
|
95
|
-
buildTokenResponse(
|
106
|
+
buildTokenResponse(tokenType, accessToken, refreshToken, expiresAt, sub, scope) {
|
96
107
|
return {
|
97
108
|
access_token: accessToken,
|
98
|
-
token_type:
|
109
|
+
token_type: tokenType,
|
99
110
|
refresh_token: refreshToken,
|
100
|
-
scope
|
111
|
+
scope,
|
101
112
|
// @NOTE using a getter so that the value gets computed when the JSON
|
102
113
|
// response is generated, allowing to value to be as accurate as possible.
|
103
114
|
get expires_in() {
|
@@ -117,6 +128,10 @@ class TokenManager {
|
|
117
128
|
const nextRefreshToken = await (0, refresh_token_js_1.generateRefreshToken)();
|
118
129
|
const now = new Date();
|
119
130
|
const expiresAt = this.createTokenExpiry(now);
|
131
|
+
// @NOTE since the permission sets are stored in a persistent store,
|
132
|
+
// it's fine to propagate a 500 (server_error) here as the values should
|
133
|
+
// be retrievable from the store.
|
134
|
+
const scope = await this.lexiconManager.buildTokenScope(parameters.scope);
|
120
135
|
await this.store.rotateToken(tokenInfo.id, nextTokenId, nextRefreshToken, {
|
121
136
|
updatedAt: now,
|
122
137
|
expiresAt,
|
@@ -127,9 +142,10 @@ class TokenManager {
|
|
127
142
|
// - Allow clients to become "confidential" if they were previously
|
128
143
|
// "public"
|
129
144
|
clientAuth,
|
145
|
+
scope,
|
130
146
|
});
|
131
|
-
const accessToken = await this.buildAccessToken(nextTokenId, account, client, parameters,
|
132
|
-
const response =
|
147
|
+
const accessToken = await this.buildAccessToken(nextTokenId, account, client, parameters, now, expiresAt, scope);
|
148
|
+
const response = this.buildTokenResponse(inferTokenType(parameters), accessToken, nextRefreshToken, expiresAt, account.sub, scope);
|
133
149
|
await (0, function_js_1.callAsync)(this.hooks.onTokenRefreshed, {
|
134
150
|
client,
|
135
151
|
clientAuth,
|
@@ -232,7 +248,9 @@ class TokenManager {
|
|
232
248
|
// These are not stored in the JWT access token in "light" access token
|
233
249
|
// mode. See `buildAccessToken`.
|
234
250
|
aud: account.aud,
|
235
|
-
|
251
|
+
// Note we fallback to parameters.scope for sessions created before
|
252
|
+
// TokenData.scope was introduced.
|
253
|
+
scope: data.scope ?? parameters.scope,
|
236
254
|
client_id: data.clientId,
|
237
255
|
};
|
238
256
|
return (0, verify_token_claims_js_1.verifyTokenClaims)(token, tokenId, tokenType, tokenClaims, dpopProof, verifyOptions);
|
@@ -248,4 +266,10 @@ exports.TokenManager = TokenManager;
|
|
248
266
|
function isCurrentTokenExpired(tokenInfo) {
|
249
267
|
return tokenInfo.data.expiresAt.getTime() < Date.now();
|
250
268
|
}
|
269
|
+
function inferTokenType(parameters) {
|
270
|
+
if (parameters.dpop_jkt) {
|
271
|
+
return 'DPoP';
|
272
|
+
}
|
273
|
+
return 'Bearer';
|
274
|
+
}
|
251
275
|
//# sourceMappingURL=token-manager.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"token-manager.js","sourceRoot":"","sources":["../../src/token/token-manager.ts"],"names":[],"mappings":";;;AAAA,sCAAqD;
|
1
|
+
{"version":3,"file":"token-manager.js","sourceRoot":"","sources":["../../src/token/token-manager.ts"],"names":[],"mappings":"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"}
|
@@ -15,9 +15,23 @@ export type TokenInfo = {
|
|
15
15
|
account: Account;
|
16
16
|
currentRefreshToken: null | RefreshToken;
|
17
17
|
};
|
18
|
-
export type NewTokenData =
|
18
|
+
export type NewTokenData = {
|
19
|
+
clientAuth: TokenData['clientAuth'];
|
20
|
+
expiresAt: TokenData['expiresAt'];
|
21
|
+
updatedAt: TokenData['updatedAt'];
|
22
|
+
scope: NonNullable<TokenData['scope']>;
|
23
|
+
};
|
24
|
+
export type CreateTokenData = TokenData & {
|
25
|
+
scope: NonNullable<TokenData['scope']>;
|
26
|
+
};
|
27
|
+
/**
|
28
|
+
* @param data historically, {@link TokenData.scope} was not present in
|
29
|
+
* {@link TokenData}, causing it to be "nullable" when returned from
|
30
|
+
* {@link TokenStore.readToken}. We use {@link CreateTokenData} here to allow
|
31
|
+
* the store implementation to expect its presence.
|
32
|
+
*/
|
19
33
|
export interface TokenStore {
|
20
|
-
createToken(tokenId: TokenId, data:
|
34
|
+
createToken(tokenId: TokenId, data: CreateTokenData, refreshToken?: RefreshToken): Awaitable<void>;
|
21
35
|
readToken(tokenId: TokenId): Awaitable<null | TokenInfo>;
|
22
36
|
deleteToken(tokenId: TokenId): Awaitable<void>;
|
23
37
|
rotateToken(tokenId: TokenId, newTokenId: TokenId, newRefreshToken: RefreshToken, newData: NewTokenData): Awaitable<void>;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"token-store.d.ts","sourceRoot":"","sources":["../../src/token/token-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAyB,MAAM,qBAAqB,CAAA;AACtE,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAGvC,cAAc,oBAAoB,CAAA;AAClC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,CAAA;AAEvC,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,OAAO,CAAA;IACX,IAAI,EAAE,SAAS,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,mBAAmB,EAAE,IAAI,GAAG,YAAY,CAAA;CACzC,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,
|
1
|
+
{"version":3,"file":"token-store.d.ts","sourceRoot":"","sources":["../../src/token/token-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAyB,MAAM,qBAAqB,CAAA;AACtE,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAGvC,cAAc,oBAAoB,CAAA;AAClC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,CAAA;AAEvC,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,OAAO,CAAA;IACX,IAAI,EAAE,SAAS,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,mBAAmB,EAAE,IAAI,GAAG,YAAY,CAAA;CACzC,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,UAAU,EAAE,SAAS,CAAC,YAAY,CAAC,CAAA;IACnC,SAAS,EAAE,SAAS,CAAC,WAAW,CAAC,CAAA;IACjC,SAAS,EAAE,SAAS,CAAC,WAAW,CAAC,CAAA;IACjC,KAAK,EAAE,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;CACvC,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG;IACxC,KAAK,EAAE,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;CACvC,CAAA;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,WAAW,CACT,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,eAAe,EACrB,YAAY,CAAC,EAAE,YAAY,GAC1B,SAAS,CAAC,IAAI,CAAC,CAAA;IAElB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,CAAA;IAExD,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;IAE9C,WAAW,CACT,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,OAAO,EACnB,eAAe,EAAE,YAAY,EAC7B,OAAO,EAAE,YAAY,GACpB,SAAS,CAAC,IAAI,CAAC,CAAA;IAElB;;;;OAIG;IACH,uBAAuB,CACrB,YAAY,EAAE,YAAY,GACzB,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,CAAA;IAE9B,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,CAAA;IAExD,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC,CAAA;CACpD;AAED,eAAO,MAAM,YAAY,qHAQvB,CAAA;AAEF,wBAAgB,YAAY,CAAC,CAAC,SAAS,OAAO,CAAC,UAAU,CAAC,EACxD,cAAc,CAAC,EAAE,CAAC,GACjB,CAAC,GAAG,UAAU,CAKhB"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"token-store.js","sourceRoot":"","sources":["../../src/token/token-store.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;
|
1
|
+
{"version":3,"file":"token-store.js","sourceRoot":"","sources":["../../src/token/token-store.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAgFA,oCAOC;AAtFD,iDAAsE;AAOtE,gEAAgE;AAChE,qDAAkC;AAClC,kDAA+B;AAC/B,gDAA6B;AA2DhB,QAAA,YAAY,GAAG,IAAA,+BAAqB,EAAa;IAC5D,aAAa;IACb,WAAW;IACX,aAAa;IACb,aAAa;IACb,yBAAyB;IACzB,iBAAiB;IACjB,mBAAmB;CACpB,CAAC,CAAA;AAEF,SAAgB,YAAY,CAC1B,cAAkB;IAElB,IAAI,CAAC,cAAc,IAAI,CAAC,IAAA,oBAAY,EAAC,cAAc,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAA;IACtD,CAAC;IACD,OAAO,cAAc,CAAA;AACvB,CAAC"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@atproto/oauth-provider",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.11.1",
|
4
4
|
"license": "MIT",
|
5
5
|
"description": "Generic OAuth2 and OpenID Connect provider for Node.js. Currently only supports features needed for Atproto.",
|
6
6
|
"keywords": [
|
@@ -43,20 +43,22 @@
|
|
43
43
|
"jose": "^5.2.0",
|
44
44
|
"zod": "^3.23.8",
|
45
45
|
"@atproto-labs/fetch": "0.2.3",
|
46
|
-
"@atproto-labs/fetch-node": "0.1.9",
|
47
46
|
"@atproto-labs/pipe": "0.1.1",
|
48
|
-
"@atproto-labs/
|
49
|
-
"@atproto-labs/simple-store
|
47
|
+
"@atproto-labs/fetch-node": "0.1.10",
|
48
|
+
"@atproto-labs/simple-store": "0.3.0",
|
49
|
+
"@atproto-labs/simple-store-memory": "0.1.4",
|
50
50
|
"@atproto/common": "^0.4.11",
|
51
|
-
"@atproto/did": "0.
|
51
|
+
"@atproto/did": "0.2.0",
|
52
52
|
"@atproto/jwk": "0.5.0",
|
53
53
|
"@atproto/jwk-jose": "0.1.10",
|
54
|
+
"@atproto/lexicon": "0.5.0",
|
55
|
+
"@atproto/lexicon-resolver": "0.2.0",
|
54
56
|
"@atproto/oauth-types": "0.4.1",
|
55
|
-
"@atproto/oauth-provider-api": "0.
|
56
|
-
"@atproto/oauth-provider-frontend": "0.
|
57
|
-
"@atproto/oauth-provider-ui": "0.
|
58
|
-
"@atproto/oauth-scopes": "0.0
|
59
|
-
"@atproto/syntax": "0.4.
|
57
|
+
"@atproto/oauth-provider-api": "0.3.0",
|
58
|
+
"@atproto/oauth-provider-frontend": "0.2.0",
|
59
|
+
"@atproto/oauth-provider-ui": "0.3.0",
|
60
|
+
"@atproto/oauth-scopes": "0.1.0",
|
61
|
+
"@atproto/syntax": "0.4.1"
|
60
62
|
},
|
61
63
|
"devDependencies": {
|
62
64
|
"@types/cookie": "^0.6.0",
|
package/src/constants.ts
CHANGED
@@ -74,4 +74,7 @@ export const SESSION_FIXATION_MAX_AGE = 5 * SECOND
|
|
74
74
|
/** 1 day */
|
75
75
|
export const CODE_CHALLENGE_REPLAY_TIMEFRAME = 1 * DAY
|
76
76
|
|
77
|
+
/** 5 minutes */
|
78
|
+
export const LEXICON_REFRESH_FREQUENCY = 5 * MINUTE
|
79
|
+
|
77
80
|
export const NODE_ENV = process.env.NODE_ENV || 'production'
|
@@ -1,9 +1,9 @@
|
|
1
1
|
import { z } from 'zod'
|
2
2
|
import { isLinkRel } from '../lib/html/build-document.js'
|
3
|
-
import {
|
3
|
+
import { multiLangStringSchema } from '../lib/util/locale.js'
|
4
4
|
|
5
5
|
export const linksSchema = z.object({
|
6
|
-
title:
|
6
|
+
title: z.union([z.string(), multiLangStringSchema]),
|
7
7
|
href: z.string().url(),
|
8
8
|
rel: z.string().refine(isLinkRel, 'Invalid link rel').optional(),
|
9
9
|
})
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import {
|
2
|
+
LexiconResolutionError,
|
3
|
+
LexiconResolver,
|
4
|
+
resolveLexicon,
|
5
|
+
} from '@atproto/lexicon-resolver'
|
6
|
+
import { Nsid } from '@atproto/oauth-scopes'
|
7
|
+
import { CachedGetter } from '@atproto-labs/simple-store'
|
8
|
+
import { LEXICON_REFRESH_FREQUENCY } from '../constants.js'
|
9
|
+
import { LexiconData, LexiconStore } from './lexicon-store.js'
|
10
|
+
|
11
|
+
/**
|
12
|
+
* This utility class handles the retrieval and caching of lexicon
|
13
|
+
* data. In particular, it handles failed retrieval attempts by returning cached
|
14
|
+
* data.
|
15
|
+
*
|
16
|
+
* @private
|
17
|
+
*/
|
18
|
+
export class LexiconGetter extends CachedGetter<Nsid, LexiconData> {
|
19
|
+
constructor(store: LexiconStore, resolver: LexiconResolver = resolveLexicon) {
|
20
|
+
super(
|
21
|
+
async (input, options, storedData) => {
|
22
|
+
const now = new Date()
|
23
|
+
// @TODO We would want to be able to explicit that the Lexicon needs
|
24
|
+
// to be fresh, which is not possible yet with the current interface
|
25
|
+
// of LexiconResolver.
|
26
|
+
const result = await resolver(input).catch((err) => {
|
27
|
+
// We swallow LexiconResolutionError errors, returning potentially
|
28
|
+
// "null" values here to avoid hammering the resolver with requests
|
29
|
+
// for the same lexicon that is known to be unavailable. The getter
|
30
|
+
// should be called again based on the isStale() function below.
|
31
|
+
if (err instanceof LexiconResolutionError) return undefined
|
32
|
+
|
33
|
+
// Unexpected error are propagated
|
34
|
+
throw err
|
35
|
+
})
|
36
|
+
|
37
|
+
return {
|
38
|
+
// Keep original createdAt, if available
|
39
|
+
createdAt: storedData?.createdAt ?? now,
|
40
|
+
// Always update updatedAt
|
41
|
+
updatedAt: now,
|
42
|
+
// Update the data with fresh data, if available, or keep cached
|
43
|
+
// values (if any) otherwise.
|
44
|
+
lastSucceededAt: result ? now : storedData?.lastSucceededAt ?? null,
|
45
|
+
uri: result ? result.uri.toString() : storedData?.uri ?? null,
|
46
|
+
lexicon: result ? result.lexicon : storedData?.lexicon ?? null,
|
47
|
+
}
|
48
|
+
},
|
49
|
+
{
|
50
|
+
set: async (nsid, data) => store.storeLexicon(nsid, data),
|
51
|
+
get: async (nsid) => (await store.findLexicon(nsid)) ?? undefined,
|
52
|
+
del: async (nsid) => store.deleteLexicon(nsid),
|
53
|
+
},
|
54
|
+
{
|
55
|
+
isStale: (nsid, data) => {
|
56
|
+
const timeSinceLastUpdate = Date.now() - data.updatedAt.getTime()
|
57
|
+
return timeSinceLastUpdate >= LEXICON_REFRESH_FREQUENCY
|
58
|
+
},
|
59
|
+
},
|
60
|
+
)
|
61
|
+
}
|
62
|
+
}
|
@@ -0,0 +1,116 @@
|
|
1
|
+
import { LexPermissionSet } from '@atproto/lexicon'
|
2
|
+
import {
|
3
|
+
LexiconResolutionError,
|
4
|
+
LexiconResolver,
|
5
|
+
} from '@atproto/lexicon-resolver'
|
6
|
+
import { IncludeScope, Nsid } from '@atproto/oauth-scopes'
|
7
|
+
import { LexiconGetter } from './lexicon-getter.js'
|
8
|
+
import { LexiconStore } from './lexicon-store.js'
|
9
|
+
|
10
|
+
export * from './lexicon-store.js'
|
11
|
+
|
12
|
+
export class LexiconManager {
|
13
|
+
protected readonly lexiconGetter: LexiconGetter
|
14
|
+
|
15
|
+
constructor(store: LexiconStore, resolveLexicon?: LexiconResolver) {
|
16
|
+
this.lexiconGetter = new LexiconGetter(store, resolveLexicon)
|
17
|
+
}
|
18
|
+
|
19
|
+
public async getPermissionSetsFromScope(scope?: string) {
|
20
|
+
const { includeScopes } = parseScope(scope)
|
21
|
+
return this.extractPermissionSets(includeScopes)
|
22
|
+
}
|
23
|
+
|
24
|
+
/**
|
25
|
+
* Transforms a scope string from an authorization request into a scope
|
26
|
+
* composed solely of granular permission scopes, transforming any NSID
|
27
|
+
* into its corresponding permission scopes.
|
28
|
+
*/
|
29
|
+
public async buildTokenScope(scope: string): Promise<string> {
|
30
|
+
const { includeScopes, otherScopes } = parseScope(scope)
|
31
|
+
|
32
|
+
// If the scope does not contain any "include:<nsid>" scopes, return it as-is.
|
33
|
+
if (!includeScopes.length) return scope
|
34
|
+
|
35
|
+
const permissionSets = await this.extractPermissionSets(includeScopes)
|
36
|
+
|
37
|
+
return Array.from(includeScopes)
|
38
|
+
.flatMap(nsidToPermissionScopes, permissionSets)
|
39
|
+
.concat(otherScopes)
|
40
|
+
.join(' ')
|
41
|
+
}
|
42
|
+
|
43
|
+
/**
|
44
|
+
* Given a list of scope values, extract those that are NSIDs and return their
|
45
|
+
* corresponding permission sets.
|
46
|
+
*/
|
47
|
+
protected async extractPermissionSets(includeScopes: IncludeScope[]) {
|
48
|
+
const nsids = extractNsids(includeScopes)
|
49
|
+
return this.getPermissionSets(nsids)
|
50
|
+
}
|
51
|
+
|
52
|
+
protected async getPermissionSets(nsids: Set<Nsid>) {
|
53
|
+
return new Map<string, LexPermissionSet>(
|
54
|
+
await Promise.all(Array.from(nsids, this.getPermissionSetEntry, this)),
|
55
|
+
)
|
56
|
+
}
|
57
|
+
|
58
|
+
protected async getPermissionSetEntry(
|
59
|
+
nsid: Nsid,
|
60
|
+
): Promise<[nsid: Nsid, permissionSet: LexPermissionSet]> {
|
61
|
+
const permissionSet = await this.getPermissionSet(nsid)
|
62
|
+
return [nsid, permissionSet]
|
63
|
+
}
|
64
|
+
|
65
|
+
protected async getPermissionSet(nsid: Nsid): Promise<LexPermissionSet> {
|
66
|
+
const { lexicon } = await this.lexiconGetter.get(nsid)
|
67
|
+
|
68
|
+
if (!lexicon) {
|
69
|
+
throw LexiconResolutionError.from(nsid)
|
70
|
+
}
|
71
|
+
|
72
|
+
if (lexicon.defs.main?.type !== 'permission-set') {
|
73
|
+
const description = 'Lexicon document is not a permission set'
|
74
|
+
throw LexiconResolutionError.from(nsid, description)
|
75
|
+
}
|
76
|
+
|
77
|
+
return lexicon.defs.main
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
function parseScope(scope?: string) {
|
82
|
+
const includeScopes: IncludeScope[] = []
|
83
|
+
const otherScopes: string[] = []
|
84
|
+
|
85
|
+
if (scope) {
|
86
|
+
for (const scopeValue of scope.split(' ')) {
|
87
|
+
const parsed = IncludeScope.fromString(scopeValue)
|
88
|
+
if (parsed) {
|
89
|
+
includeScopes.push(parsed)
|
90
|
+
} else {
|
91
|
+
otherScopes.push(scopeValue)
|
92
|
+
}
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
return {
|
97
|
+
includeScopes,
|
98
|
+
otherScopes,
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
function extractNsids(includeScopes: IncludeScope[]): Set<Nsid> {
|
103
|
+
return new Set(Array.from(includeScopes, extractNsid))
|
104
|
+
}
|
105
|
+
|
106
|
+
function extractNsid(nsidScope: IncludeScope): Nsid {
|
107
|
+
return nsidScope.nsid
|
108
|
+
}
|
109
|
+
|
110
|
+
export function nsidToPermissionScopes(
|
111
|
+
this: Map<string, LexPermissionSet>,
|
112
|
+
includeScope: IncludeScope,
|
113
|
+
): string[] {
|
114
|
+
const permissionSet = this.get(includeScope.nsid)!
|
115
|
+
return includeScope.toPermissions(permissionSet).map(String)
|
116
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import { LexiconDoc } from '@atproto/lexicon'
|
2
|
+
import { Awaitable, buildInterfaceChecker } from '../lib/util/type.js'
|
3
|
+
import { LexiconData } from './lexicon-data.js'
|
4
|
+
|
5
|
+
export type { Awaitable, LexiconData, LexiconDoc }
|
6
|
+
|
7
|
+
export interface LexiconStore {
|
8
|
+
findLexicon(nsid: string): Awaitable<LexiconData | null>
|
9
|
+
storeLexicon(nsid: string, data: LexiconData): Awaitable<void>
|
10
|
+
deleteLexicon(nsid: string): Awaitable<void>
|
11
|
+
}
|
12
|
+
|
13
|
+
export const isLexiconStore = buildInterfaceChecker<LexiconStore>([
|
14
|
+
'findLexicon',
|
15
|
+
'storeLexicon',
|
16
|
+
'deleteLexicon',
|
17
|
+
])
|
18
|
+
|
19
|
+
export function ifLexiconStore<V extends Partial<LexiconStore>>(
|
20
|
+
implementation?: V,
|
21
|
+
): (V & LexiconStore) | undefined {
|
22
|
+
if (implementation && isLexiconStore(implementation)) {
|
23
|
+
return implementation
|
24
|
+
}
|
25
|
+
|
26
|
+
return undefined
|
27
|
+
}
|
28
|
+
|
29
|
+
export function asLexiconStore<V extends Partial<LexiconStore>>(
|
30
|
+
implementation?: V,
|
31
|
+
): V & LexiconStore {
|
32
|
+
const store = ifLexiconStore(implementation)
|
33
|
+
if (store) return store
|
34
|
+
|
35
|
+
throw new Error('Invalid LexiconStore implementation')
|
36
|
+
}
|
@@ -14,7 +14,6 @@ export function* hydrationDataGenerator(
|
|
14
14
|
}
|
15
15
|
// The script tag is removed after the data is assigned to the global
|
16
16
|
// variables to prevent other scripts from reading the values. The "app"
|
17
|
-
// script will read the global variable and then unset it.
|
18
|
-
// `readBackendData()` in "src/assets/app/backend-data.ts".
|
17
|
+
// script will read the global variable and then unset it.
|
19
18
|
yield js`document.currentScript.remove();`
|
20
19
|
}
|
package/src/lib/nsid.ts
ADDED
package/src/lib/util/locale.ts
CHANGED
@@ -5,14 +5,8 @@ export const localeSchema = z
|
|
5
5
|
.regex(/^[a-z]{2,3}(-[A-Z]{2})?$/, 'Invalid locale')
|
6
6
|
export type Locale = z.infer<typeof localeSchema>
|
7
7
|
|
8
|
-
export const multiLangStringSchema = z.
|
9
|
-
|
10
|
-
z.
|
8
|
+
export const multiLangStringSchema = z.record(
|
9
|
+
localeSchema,
|
10
|
+
z.string().optional(),
|
11
11
|
)
|
12
12
|
export type MultiLangString = z.infer<typeof multiLangStringSchema>
|
13
|
-
|
14
|
-
export const localizedStringSchema = z.union([
|
15
|
-
z.string(),
|
16
|
-
multiLangStringSchema,
|
17
|
-
])
|
18
|
-
export type LocalizedString = z.infer<typeof localizedStringSchema>
|