@atproto/oauth-client 0.1.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 +20 -0
- package/LICENSE.txt +7 -0
- package/README.md +124 -0
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +8 -0
- package/dist/constants.js.map +1 -0
- package/dist/fetch-dpop.d.ts +21 -0
- package/dist/fetch-dpop.d.ts.map +1 -0
- package/dist/fetch-dpop.js +149 -0
- package/dist/fetch-dpop.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/lock.d.ts +2 -0
- package/dist/lock.d.ts.map +1 -0
- package/dist/lock.js +33 -0
- package/dist/lock.js.map +1 -0
- package/dist/oauth-agent.d.ts +29 -0
- package/dist/oauth-agent.d.ts.map +1 -0
- package/dist/oauth-agent.js +138 -0
- package/dist/oauth-agent.js.map +1 -0
- package/dist/oauth-authorization-server-metadata-resolver.d.ts +15 -0
- package/dist/oauth-authorization-server-metadata-resolver.d.ts.map +1 -0
- package/dist/oauth-authorization-server-metadata-resolver.js +56 -0
- package/dist/oauth-authorization-server-metadata-resolver.js.map +1 -0
- package/dist/oauth-callback-error.d.ts +7 -0
- package/dist/oauth-callback-error.d.ts.map +1 -0
- package/dist/oauth-callback-error.js +28 -0
- package/dist/oauth-callback-error.js.map +1 -0
- package/dist/oauth-client.d.ts +78 -0
- package/dist/oauth-client.d.ts.map +1 -0
- package/dist/oauth-client.js +278 -0
- package/dist/oauth-client.js.map +1 -0
- package/dist/oauth-protected-resource-metadata-resolver.d.ts +15 -0
- package/dist/oauth-protected-resource-metadata-resolver.d.ts.map +1 -0
- package/dist/oauth-protected-resource-metadata-resolver.js +58 -0
- package/dist/oauth-protected-resource-metadata-resolver.js.map +1 -0
- package/dist/oauth-resolver-error.d.ts +7 -0
- package/dist/oauth-resolver-error.d.ts.map +1 -0
- package/dist/oauth-resolver-error.js +17 -0
- package/dist/oauth-resolver-error.js.map +1 -0
- package/dist/oauth-resolver.d.ts +62 -0
- package/dist/oauth-resolver.d.ts.map +1 -0
- package/dist/oauth-resolver.js +73 -0
- package/dist/oauth-resolver.js.map +1 -0
- package/dist/oauth-response-error.d.ts +11 -0
- package/dist/oauth-response-error.d.ts.map +1 -0
- package/dist/oauth-response-error.js +48 -0
- package/dist/oauth-response-error.js.map +1 -0
- package/dist/oauth-server-agent.d.ts +51 -0
- package/dist/oauth-server-agent.d.ts.map +1 -0
- package/dist/oauth-server-agent.js +228 -0
- package/dist/oauth-server-agent.js.map +1 -0
- package/dist/oauth-server-factory.d.ts +20 -0
- package/dist/oauth-server-factory.d.ts.map +1 -0
- package/dist/oauth-server-factory.js +53 -0
- package/dist/oauth-server-factory.js.map +1 -0
- package/dist/refresh-error.d.ts +7 -0
- package/dist/refresh-error.d.ts.map +1 -0
- package/dist/refresh-error.js +16 -0
- package/dist/refresh-error.js.map +1 -0
- package/dist/runtime-implementation.d.ts +12 -0
- package/dist/runtime-implementation.d.ts.map +1 -0
- package/dist/runtime-implementation.js +3 -0
- package/dist/runtime-implementation.js.map +1 -0
- package/dist/runtime.d.ts +35 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +185 -0
- package/dist/runtime.js.map +1 -0
- package/dist/session-getter.d.ts +30 -0
- package/dist/session-getter.d.ts.map +1 -0
- package/dist/session-getter.js +149 -0
- package/dist/session-getter.js.map +1 -0
- package/dist/types.d.ts +1580 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/util.d.ts +9 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +35 -0
- package/dist/util.js.map +1 -0
- package/dist/validate-client-metadata.d.ts +5 -0
- package/dist/validate-client-metadata.d.ts.map +1 -0
- package/dist/validate-client-metadata.js +46 -0
- package/dist/validate-client-metadata.js.map +1 -0
- package/package.json +46 -0
- package/src/constants.ts +4 -0
- package/src/fetch-dpop.ts +235 -0
- package/src/index.ts +18 -0
- package/src/lock.ts +34 -0
- package/src/oauth-agent.ts +150 -0
- package/src/oauth-authorization-server-metadata-resolver.ts +98 -0
- package/src/oauth-callback-error.ts +16 -0
- package/src/oauth-client.ts +440 -0
- package/src/oauth-protected-resource-metadata-resolver.ts +102 -0
- package/src/oauth-resolver-error.ts +12 -0
- package/src/oauth-resolver.ts +111 -0
- package/src/oauth-response-error.ts +31 -0
- package/src/oauth-server-agent.ts +275 -0
- package/src/oauth-server-factory.ts +41 -0
- package/src/refresh-error.ts +9 -0
- package/src/runtime-implementation.ts +17 -0
- package/src/runtime.ts +211 -0
- package/src/session-getter.ts +182 -0
- package/src/types.ts +26 -0
- package/src/util.ts +51 -0
- package/src/validate-client-metadata.ts +61 -0
- package/tsconfig.build.json +8 -0
- package/tsconfig.json +4 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-implementation.d.ts","sourceRoot":"","sources":["../src/runtime-implementation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAElC,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAA;CACrC,CAAA;AAED,YAAY,EAAE,GAAG,EAAE,CAAA;AAEnB,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;IACjD,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC,CAAA;IACzE,MAAM,EAAE,CACN,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,eAAe,KACvB,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC,CAAA;IACzC,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;CAC5E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-implementation.js","sourceRoot":"","sources":["../src/runtime-implementation.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { JwtHeader, JwtPayload, Key } from '@atproto/jwk';
|
|
2
|
+
import { RuntimeImplementation } from './runtime-implementation.js';
|
|
3
|
+
export declare class Runtime {
|
|
4
|
+
protected implementation: RuntimeImplementation;
|
|
5
|
+
constructor(implementation: RuntimeImplementation);
|
|
6
|
+
generateKey(algs: string[]): Promise<Key>;
|
|
7
|
+
sha256(text: string): Promise<string>;
|
|
8
|
+
generateNonce(length?: number): Promise<string>;
|
|
9
|
+
get hasLock(): boolean;
|
|
10
|
+
withLock<T>(name: string, fn: () => T | PromiseLike<T>): Promise<T>;
|
|
11
|
+
validateIdTokenClaims(token: string, state: string, nonce: string, code?: string, accessToken?: string): Promise<{
|
|
12
|
+
header: JwtHeader;
|
|
13
|
+
payload: JwtPayload;
|
|
14
|
+
}>;
|
|
15
|
+
private validateHashClaim;
|
|
16
|
+
protected generateHashClaim(source: string, header: {
|
|
17
|
+
alg: string;
|
|
18
|
+
crv?: string;
|
|
19
|
+
}): Promise<string>;
|
|
20
|
+
generatePKCE(byteLength?: number): Promise<{
|
|
21
|
+
verifier: string;
|
|
22
|
+
challenge: string;
|
|
23
|
+
method: string;
|
|
24
|
+
}>;
|
|
25
|
+
calculateJwkThumbprint(jwk: any): Promise<string>;
|
|
26
|
+
/**
|
|
27
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc7636#section-4.1}
|
|
28
|
+
* @note It is RECOMMENDED that the output of a suitable random number generator
|
|
29
|
+
* be used to create a 32-octet sequence. The octet sequence is then
|
|
30
|
+
* base64url-encoded to produce a 43-octet URL safe string to use as the code
|
|
31
|
+
* verifier.
|
|
32
|
+
*/
|
|
33
|
+
protected generateVerifier(byteLength?: number): Promise<string>;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,EAAmB,MAAM,cAAc,CAAA;AAI1E,OAAO,EAEL,qBAAqB,EACtB,MAAM,6BAA6B,CAAA;AAEpC,qBAAa,OAAO;IACN,SAAS,CAAC,cAAc,EAAE,qBAAqB;gBAArC,cAAc,EAAE,qBAAqB;IAE9C,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAKzC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMrC,aAAa,CAAC,MAAM,SAAK,GAAG,OAAO,CAAC,MAAM,CAAC;IAKxD,IAAI,OAAO,YAEV;IAEY,QAAQ,CAAC,CAAC,EACrB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAC3B,OAAO,CAAC,CAAC,CAAC;IASA,qBAAqB,CAChC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC;QACT,MAAM,EAAE,SAAS,CAAA;QACjB,OAAO,EAAE,UAAU,CAAA;KACpB,CAAC;YAoBY,iBAAiB;cAiBf,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE;IAU1B,YAAY,CAAC,UAAU,CAAC,EAAE,MAAM;;;;;IAShC,sBAAsB,CAAC,GAAG,KAAA;IAMvC;;;;;;OAMG;cACa,gBAAgB,CAAC,UAAU,SAAK;CAOjD"}
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Runtime = void 0;
|
|
4
|
+
const jwk_1 = require("@atproto/jwk");
|
|
5
|
+
const base64_1 = require("multiformats/bases/base64");
|
|
6
|
+
const lock_js_1 = require("./lock.js");
|
|
7
|
+
class Runtime {
|
|
8
|
+
constructor(implementation) {
|
|
9
|
+
Object.defineProperty(this, "implementation", {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
configurable: true,
|
|
12
|
+
writable: true,
|
|
13
|
+
value: implementation
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
async generateKey(algs) {
|
|
17
|
+
const algsSorted = Array.from(algs).sort(compareAlgos);
|
|
18
|
+
return this.implementation.createKey(algsSorted);
|
|
19
|
+
}
|
|
20
|
+
async sha256(text) {
|
|
21
|
+
const bytes = new TextEncoder().encode(text);
|
|
22
|
+
const digest = await this.implementation.digest(bytes, { name: 'sha256' });
|
|
23
|
+
return base64_1.base64url.baseEncode(digest);
|
|
24
|
+
}
|
|
25
|
+
async generateNonce(length = 16) {
|
|
26
|
+
const bytes = await this.implementation.getRandomValues(length);
|
|
27
|
+
return base64_1.base64url.baseEncode(bytes);
|
|
28
|
+
}
|
|
29
|
+
get hasLock() {
|
|
30
|
+
return !!this.implementation.requestLock;
|
|
31
|
+
}
|
|
32
|
+
async withLock(name, fn) {
|
|
33
|
+
if (this.implementation.requestLock) {
|
|
34
|
+
return this.implementation.requestLock(name, fn);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// Falling back to a local lock
|
|
38
|
+
return (0, lock_js_1.requestLocalLock)(name, fn);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async validateIdTokenClaims(token, state, nonce, code, accessToken) {
|
|
42
|
+
// It's fine to use unsafeDecodeJwt here because the token was received from
|
|
43
|
+
// the server's token endpoint. The following checks are to ensure that the
|
|
44
|
+
// oauth flow was indeed initiated by the client.
|
|
45
|
+
const { header, payload } = (0, jwk_1.unsafeDecodeJwt)(token);
|
|
46
|
+
if (!payload.nonce || payload.nonce !== nonce) {
|
|
47
|
+
throw new TypeError('Nonce mismatch');
|
|
48
|
+
}
|
|
49
|
+
if (payload.c_hash) {
|
|
50
|
+
await this.validateHashClaim(payload.c_hash, code, header);
|
|
51
|
+
}
|
|
52
|
+
if (payload.s_hash) {
|
|
53
|
+
await this.validateHashClaim(payload.s_hash, state, header);
|
|
54
|
+
}
|
|
55
|
+
if (payload.at_hash) {
|
|
56
|
+
await this.validateHashClaim(payload.at_hash, accessToken, header);
|
|
57
|
+
}
|
|
58
|
+
return { header, payload };
|
|
59
|
+
}
|
|
60
|
+
async validateHashClaim(claim, source, header) {
|
|
61
|
+
if (typeof claim !== 'string' || !claim) {
|
|
62
|
+
throw new TypeError(`string "_hash" claim expected`);
|
|
63
|
+
}
|
|
64
|
+
if (typeof source !== 'string' || !source) {
|
|
65
|
+
throw new TypeError(`string value expected`);
|
|
66
|
+
}
|
|
67
|
+
const expected = await this.generateHashClaim(source, header);
|
|
68
|
+
if (expected !== claim) {
|
|
69
|
+
throw new TypeError(`"_hash" does not match`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async generateHashClaim(source, header) {
|
|
73
|
+
const algo = getHashAlgo(header);
|
|
74
|
+
const bytes = new TextEncoder().encode(source);
|
|
75
|
+
const digest = await this.implementation.digest(bytes, algo);
|
|
76
|
+
if (digest.length % 2 !== 0)
|
|
77
|
+
throw new TypeError('Invalid digest length');
|
|
78
|
+
const digestHalf = digest.slice(0, digest.length / 2);
|
|
79
|
+
return base64_1.base64url.baseEncode(digestHalf);
|
|
80
|
+
}
|
|
81
|
+
async generatePKCE(byteLength) {
|
|
82
|
+
const verifier = await this.generateVerifier(byteLength);
|
|
83
|
+
return {
|
|
84
|
+
verifier,
|
|
85
|
+
challenge: await this.sha256(verifier),
|
|
86
|
+
method: 'S256',
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
async calculateJwkThumbprint(jwk) {
|
|
90
|
+
const components = extractJktComponents(jwk);
|
|
91
|
+
const data = JSON.stringify(components);
|
|
92
|
+
return this.sha256(data);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc7636#section-4.1}
|
|
96
|
+
* @note It is RECOMMENDED that the output of a suitable random number generator
|
|
97
|
+
* be used to create a 32-octet sequence. The octet sequence is then
|
|
98
|
+
* base64url-encoded to produce a 43-octet URL safe string to use as the code
|
|
99
|
+
* verifier.
|
|
100
|
+
*/
|
|
101
|
+
async generateVerifier(byteLength = 32) {
|
|
102
|
+
if (byteLength < 32 || byteLength > 96) {
|
|
103
|
+
throw new TypeError('Invalid code_verifier length');
|
|
104
|
+
}
|
|
105
|
+
const bytes = await this.implementation.getRandomValues(byteLength);
|
|
106
|
+
return base64_1.base64url.baseEncode(bytes);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
exports.Runtime = Runtime;
|
|
110
|
+
function getHashAlgo(header) {
|
|
111
|
+
switch (header.alg) {
|
|
112
|
+
case 'HS256':
|
|
113
|
+
case 'RS256':
|
|
114
|
+
case 'PS256':
|
|
115
|
+
case 'ES256':
|
|
116
|
+
case 'ES256K':
|
|
117
|
+
return { name: 'sha256' };
|
|
118
|
+
case 'HS384':
|
|
119
|
+
case 'RS384':
|
|
120
|
+
case 'PS384':
|
|
121
|
+
case 'ES384':
|
|
122
|
+
return { name: 'sha384' };
|
|
123
|
+
case 'HS512':
|
|
124
|
+
case 'RS512':
|
|
125
|
+
case 'PS512':
|
|
126
|
+
case 'ES512':
|
|
127
|
+
return { name: 'sha512' };
|
|
128
|
+
case 'EdDSA':
|
|
129
|
+
switch (header.crv) {
|
|
130
|
+
case 'Ed25519':
|
|
131
|
+
return { name: 'sha512' };
|
|
132
|
+
default:
|
|
133
|
+
throw new TypeError('unrecognized or invalid EdDSA curve provided');
|
|
134
|
+
}
|
|
135
|
+
default:
|
|
136
|
+
throw new TypeError('unrecognized or invalid JWS algorithm provided');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function extractJktComponents(jwk) {
|
|
140
|
+
const get = (field) => {
|
|
141
|
+
const value = jwk[field];
|
|
142
|
+
if (typeof value !== 'string' || !value) {
|
|
143
|
+
throw new TypeError(`"${field}" Parameter missing or invalid`);
|
|
144
|
+
}
|
|
145
|
+
return value;
|
|
146
|
+
};
|
|
147
|
+
switch (jwk.kty) {
|
|
148
|
+
case 'EC':
|
|
149
|
+
return { crv: get('crv'), kty: get('kty'), x: get('x'), y: get('y') };
|
|
150
|
+
case 'OKP':
|
|
151
|
+
return { crv: get('crv'), kty: get('kty'), x: get('x') };
|
|
152
|
+
case 'RSA':
|
|
153
|
+
return { e: get('e'), kty: get('kty'), n: get('n') };
|
|
154
|
+
case 'oct':
|
|
155
|
+
return { k: get('k'), kty: get('kty') };
|
|
156
|
+
default:
|
|
157
|
+
throw new TypeError('"kty" (Key Type) Parameter missing or unsupported');
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* 256K > ES (256 > 384 > 512) > PS (256 > 384 > 512) > RS (256 > 384 > 512) > other (in original order)
|
|
162
|
+
*/
|
|
163
|
+
function compareAlgos(a, b) {
|
|
164
|
+
if (a === 'ES256K')
|
|
165
|
+
return -1;
|
|
166
|
+
if (b === 'ES256K')
|
|
167
|
+
return 1;
|
|
168
|
+
for (const prefix of ['ES', 'PS', 'RS']) {
|
|
169
|
+
if (a.startsWith(prefix)) {
|
|
170
|
+
if (b.startsWith(prefix)) {
|
|
171
|
+
const aLen = parseInt(a.slice(2, 5));
|
|
172
|
+
const bLen = parseInt(b.slice(2, 5));
|
|
173
|
+
// Prefer shorter key lengths
|
|
174
|
+
return aLen - bLen;
|
|
175
|
+
}
|
|
176
|
+
return -1;
|
|
177
|
+
}
|
|
178
|
+
else if (b.startsWith(prefix)) {
|
|
179
|
+
return 1;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Don't know how to compare, keep original order
|
|
183
|
+
return 0;
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":";;;AAAA,sCAA0E;AAC1E,sDAAqD;AAErD,uCAA4C;AAM5C,MAAa,OAAO;IAClB,YAAsB,cAAqC;QAA/C;;;;mBAAU,cAAc;WAAuB;IAAG,CAAC;IAExD,KAAK,CAAC,WAAW,CAAC,IAAc;QACrC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QACtD,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,UAAU,CAAC,CAAA;IAClD,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,IAAY;QAC9B,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAC5C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;QAC1E,OAAO,kBAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;IACrC,CAAC;IAEM,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,EAAE;QACpC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,MAAM,CAAC,CAAA;QAC/D,OAAO,kBAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;IACpC,CAAC;IAED,IAAI,OAAO;QACT,OAAO,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,CAAA;IAC1C,CAAC;IAEM,KAAK,CAAC,QAAQ,CACnB,IAAY,EACZ,EAA4B;QAE5B,IAAI,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QAClD,CAAC;aAAM,CAAC;YACN,+BAA+B;YAC/B,OAAO,IAAA,0BAAgB,EAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QACnC,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,qBAAqB,CAChC,KAAa,EACb,KAAa,EACb,KAAa,EACb,IAAa,EACb,WAAoB;QAKpB,4EAA4E;QAC5E,2EAA2E;QAC3E,iDAAiD;QACjD,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAA,qBAAe,EAAC,KAAK,CAAC,CAAA;QAClD,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;YAC9C,MAAM,IAAI,SAAS,CAAC,gBAAgB,CAAC,CAAA;QACvC,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;QAC5D,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QAC7D,CAAC;QACD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,CAAA;QACpE,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAA;IAC5B,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAC7B,KAAc,EACd,MAAe,EACf,MAAqC;QAErC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;YACxC,MAAM,IAAI,SAAS,CAAC,+BAA+B,CAAC,CAAA;QACtD,CAAC;QACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;YAC1C,MAAM,IAAI,SAAS,CAAC,uBAAuB,CAAC,CAAA;QAC9C,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAC7D,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;YACvB,MAAM,IAAI,SAAS,CAAC,wBAAwB,CAAC,CAAA;QAC/C,CAAC;IACH,CAAC;IAES,KAAK,CAAC,iBAAiB,CAC/B,MAAc,EACd,MAAqC;QAErC,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAA;QAChC,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAC9C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAC5D,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,uBAAuB,CAAC,CAAA;QACzE,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QACrD,OAAO,kBAAS,CAAC,UAAU,CAAC,UAAU,CAAC,CAAA;IACzC,CAAC;IAEM,KAAK,CAAC,YAAY,CAAC,UAAmB;QAC3C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAA;QACxD,OAAO;YACL,QAAQ;YACR,SAAS,EAAE,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;YACtC,MAAM,EAAE,MAAM;SACf,CAAA;IACH,CAAC;IAEM,KAAK,CAAC,sBAAsB,CAAC,GAAG;QACrC,MAAM,UAAU,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAA;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAA;QACvC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC1B,CAAC;IAED;;;;;;OAMG;IACO,KAAK,CAAC,gBAAgB,CAAC,UAAU,GAAG,EAAE;QAC9C,IAAI,UAAU,GAAG,EAAE,IAAI,UAAU,GAAG,EAAE,EAAE,CAAC;YACvC,MAAM,IAAI,SAAS,CAAC,8BAA8B,CAAC,CAAA;QACrD,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,UAAU,CAAC,CAAA;QACnE,OAAO,kBAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;IACpC,CAAC;CACF;AA1HD,0BA0HC;AAED,SAAS,WAAW,CAAC,MAAqC;IACxD,QAAQ,MAAM,CAAC,GAAG,EAAE,CAAC;QACnB,KAAK,OAAO,CAAC;QACb,KAAK,OAAO,CAAC;QACb,KAAK,OAAO,CAAC;QACb,KAAK,OAAO,CAAC;QACb,KAAK,QAAQ;YACX,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;QAC3B,KAAK,OAAO,CAAC;QACb,KAAK,OAAO,CAAC;QACb,KAAK,OAAO,CAAC;QACb,KAAK,OAAO;YACV,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;QAC3B,KAAK,OAAO,CAAC;QACb,KAAK,OAAO,CAAC;QACb,KAAK,OAAO,CAAC;QACb,KAAK,OAAO;YACV,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;QAC3B,KAAK,OAAO;YACV,QAAQ,MAAM,CAAC,GAAG,EAAE,CAAC;gBACnB,KAAK,SAAS;oBACZ,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;gBAC3B;oBACE,MAAM,IAAI,SAAS,CAAC,8CAA8C,CAAC,CAAA;YACvE,CAAC;QACH;YACE,MAAM,IAAI,SAAS,CAAC,gDAAgD,CAAC,CAAA;IACzE,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAG;IAC/B,MAAM,GAAG,GAAG,CAAC,KAAK,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAA;QACxB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;YACxC,MAAM,IAAI,SAAS,CAAC,IAAI,KAAK,gCAAgC,CAAC,CAAA;QAChE,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC,CAAA;IAED,QAAQ,GAAG,CAAC,GAAG,EAAE,CAAC;QAChB,KAAK,IAAI;YACP,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAA;QACvE,KAAK,KAAK;YACR,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAA;QAC1D,KAAK,KAAK;YACR,OAAO,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAA;QACtD,KAAK,KAAK;YACR,OAAO,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAA;QACzC;YACE,MAAM,IAAI,SAAS,CAAC,mDAAmD,CAAC,CAAA;IAC5E,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,CAAS,EAAE,CAAS;IACxC,IAAI,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC,CAAA;IAC7B,IAAI,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAA;IAE5B,KAAK,MAAM,MAAM,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QACxC,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzB,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBACpC,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAEpC,6BAA6B;gBAC7B,OAAO,IAAI,GAAG,IAAI,CAAA;YACpB,CAAC;YACD,OAAO,CAAC,CAAC,CAAA;QACX,CAAC;aAAM,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,CAAA;QACV,CAAC;IACH,CAAC;IAED,iDAAiD;IACjD,OAAO,CAAC,CAAA;AACV,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { CachedGetter, GetCachedOptions, SimpleStore } from '@atproto-labs/simple-store';
|
|
2
|
+
import { Key } from '@atproto/jwk';
|
|
3
|
+
import { TokenSet } from './oauth-server-agent.js';
|
|
4
|
+
import { OAuthServerFactory } from './oauth-server-factory.js';
|
|
5
|
+
import { Runtime } from './runtime.js';
|
|
6
|
+
export type Session = {
|
|
7
|
+
dpopKey: Key;
|
|
8
|
+
tokenSet: TokenSet;
|
|
9
|
+
};
|
|
10
|
+
export type SessionStore = SimpleStore<string, Session>;
|
|
11
|
+
/**
|
|
12
|
+
* There are several advantages to wrapping the sessionStore in a (single)
|
|
13
|
+
* CachedGetter, the main of which is that the cached getter will ensure that at
|
|
14
|
+
* most one fresh call is ever being made. Another advantage, is that it
|
|
15
|
+
* contains the logic for reading from the cache which, if the cache is based on
|
|
16
|
+
* localStorage/indexedDB, will sync across multiple tabs (for a given sub).
|
|
17
|
+
*/
|
|
18
|
+
export declare class SessionGetter extends CachedGetter<string, Session> {
|
|
19
|
+
private readonly runtime;
|
|
20
|
+
constructor(sessionStore: SessionStore, serverFactory: OAuthServerFactory, runtime: Runtime);
|
|
21
|
+
/**
|
|
22
|
+
* @param refresh When `true`, the credentials will be refreshed even if they
|
|
23
|
+
* are not expired. When `false`, the credentials will not be refreshed even
|
|
24
|
+
* if they are expired. When `undefined`, the credentials will be refreshed
|
|
25
|
+
* if, and only if, they are (about to be) expired. Defaults to `undefined`.
|
|
26
|
+
*/
|
|
27
|
+
getSession(sub: string, refresh?: boolean): Promise<Session>;
|
|
28
|
+
get(sub: string, options?: GetCachedOptions): Promise<Session>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=session-getter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-getter.d.ts","sourceRoot":"","sources":["../src/session-getter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACZ,MAAM,4BAA4B,CAAA;AACnC,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAElC,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAE9D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAGtC,MAAM,MAAM,OAAO,GAAG;IACpB,OAAO,EAAE,GAAG,CAAA;IACZ,QAAQ,EAAE,QAAQ,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAEvD;;;;;;GAMG;AACH,qBAAa,aAAc,SAAQ,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC;IAI5D,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAFxB,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,kBAAkB,EAChB,OAAO,EAAE,OAAO;IAyHnC;;;;;OAKG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO;IAczC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;CASrE"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SessionGetter = void 0;
|
|
4
|
+
const simple_store_1 = require("@atproto-labs/simple-store");
|
|
5
|
+
const oauth_response_error_js_1 = require("./oauth-response-error.js");
|
|
6
|
+
const refresh_error_js_1 = require("./refresh-error.js");
|
|
7
|
+
const util_js_1 = require("./util.js");
|
|
8
|
+
/**
|
|
9
|
+
* There are several advantages to wrapping the sessionStore in a (single)
|
|
10
|
+
* CachedGetter, the main of which is that the cached getter will ensure that at
|
|
11
|
+
* most one fresh call is ever being made. Another advantage, is that it
|
|
12
|
+
* contains the logic for reading from the cache which, if the cache is based on
|
|
13
|
+
* localStorage/indexedDB, will sync across multiple tabs (for a given sub).
|
|
14
|
+
*/
|
|
15
|
+
class SessionGetter extends simple_store_1.CachedGetter {
|
|
16
|
+
constructor(sessionStore, serverFactory, runtime) {
|
|
17
|
+
super(async (sub, options, storedSession) => {
|
|
18
|
+
// There needs to be a previous session to be able to refresh. If
|
|
19
|
+
// storedSession is undefined, it means that the store does not contain
|
|
20
|
+
// a session for the given sub. Since this might have been caused by the
|
|
21
|
+
// value being cleared in another process (e.g. another tab), we will
|
|
22
|
+
// give a chance to the process running this code to detect that the
|
|
23
|
+
// session was revoked. This should allow processes not implementing a
|
|
24
|
+
// subscribe/notify between instances to still be "notified" that the
|
|
25
|
+
// session was revoked.
|
|
26
|
+
if (storedSession === undefined) {
|
|
27
|
+
// Because the session is not in the store, the sessionStore.del
|
|
28
|
+
// function will not be called, even if the "deleteOnError" callback
|
|
29
|
+
// returns true when the error is an "OAuthRefreshError". Let's
|
|
30
|
+
// call it here manually.
|
|
31
|
+
await sessionStore.del(sub);
|
|
32
|
+
throw new refresh_error_js_1.RefreshError(sub, 'The session was revoked');
|
|
33
|
+
}
|
|
34
|
+
if (sub !== storedSession.tokenSet.sub) {
|
|
35
|
+
// Fool-proofing (e.g. against invalid session storage)
|
|
36
|
+
throw new refresh_error_js_1.RefreshError(sub, 'Stored session sub mismatch');
|
|
37
|
+
}
|
|
38
|
+
// Since refresh tokens can only be used once, we might run into
|
|
39
|
+
// concurrency issues if multiple tabs/instances are trying to refresh
|
|
40
|
+
// the same token. The chances of this happening when multiple instances
|
|
41
|
+
// are started simultaneously is reduced by randomizing the expiry time
|
|
42
|
+
// (see isStale() bellow). Even so, There still exist chances that
|
|
43
|
+
// multiple tabs will try to refresh the token at the same time. The
|
|
44
|
+
// best solution would be to use a mutex/lock to ensure that only one
|
|
45
|
+
// instance is refreshing the token at a time. A simpler workaround is
|
|
46
|
+
// to check if the value stored in the session store is the same as the
|
|
47
|
+
// one in memory. If it isn't, then another instance has already
|
|
48
|
+
// refreshed the token.
|
|
49
|
+
const { tokenSet, dpopKey } = storedSession;
|
|
50
|
+
const server = await serverFactory.fromIssuer(tokenSet.iss, dpopKey);
|
|
51
|
+
// We must not use the "signal" to cancel the refresh or its storage in
|
|
52
|
+
// case of successful refresh. If we obtain a new refresh token, we must
|
|
53
|
+
// ensure that is gets stored in the session store (by returning the new
|
|
54
|
+
// session object). Failing to do so would result in the new credentials
|
|
55
|
+
// being lost.
|
|
56
|
+
options?.signal?.throwIfAborted();
|
|
57
|
+
const newTokenSet = await server
|
|
58
|
+
.refresh(tokenSet)
|
|
59
|
+
.catch(async (cause) => {
|
|
60
|
+
if (cause instanceof oauth_response_error_js_1.OAuthResponseError &&
|
|
61
|
+
cause.status === 400 &&
|
|
62
|
+
cause.error === 'invalid_grant') {
|
|
63
|
+
// In case there is no lock implementation in the runtime, we will
|
|
64
|
+
// wait for a short time to give the other concurrent instances a
|
|
65
|
+
// chance to finish their refreshing of the token. If a concurrent
|
|
66
|
+
// refresh did occur, we will pretend that this one succeeded.
|
|
67
|
+
if (!runtime.hasLock) {
|
|
68
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
69
|
+
const stored = await this.getStored(sub);
|
|
70
|
+
if (stored === undefined) {
|
|
71
|
+
// Using a distinct error message mainly for debugging
|
|
72
|
+
// purposes
|
|
73
|
+
const msg = 'The session was revoked by another process';
|
|
74
|
+
throw new refresh_error_js_1.RefreshError(sub, msg, { cause });
|
|
75
|
+
}
|
|
76
|
+
else if (stored.tokenSet.access_token !== tokenSet.access_token ||
|
|
77
|
+
stored.tokenSet.refresh_token !== tokenSet.refresh_token) {
|
|
78
|
+
// A concurrent refresh occurred. Pretend this one succeeded.
|
|
79
|
+
return stored.tokenSet;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
// There were no concurrent refresh. The token is (likely)
|
|
83
|
+
// simply no longer valid.
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Throwing an RefreshError to trigger deletion through the
|
|
87
|
+
// deleteOnError callback.
|
|
88
|
+
const msg = cause.errorDescription ?? 'The session was revoked';
|
|
89
|
+
throw new refresh_error_js_1.RefreshError(sub, msg, { cause });
|
|
90
|
+
}
|
|
91
|
+
throw cause;
|
|
92
|
+
});
|
|
93
|
+
if (sub !== newTokenSet.sub) {
|
|
94
|
+
// The server returned another sub. Was the tokenSet manipulated?
|
|
95
|
+
throw new refresh_error_js_1.RefreshError(sub, 'Token set sub mismatch');
|
|
96
|
+
}
|
|
97
|
+
return { ...storedSession, tokenSet: newTokenSet };
|
|
98
|
+
}, sessionStore, {
|
|
99
|
+
isStale: (sub, { tokenSet }) => {
|
|
100
|
+
return (tokenSet.expires_at != null &&
|
|
101
|
+
new Date(tokenSet.expires_at).getTime() <
|
|
102
|
+
// Add some lee way to ensure the token is not expired when it
|
|
103
|
+
// reaches the server.
|
|
104
|
+
Date.now() + 60e3);
|
|
105
|
+
},
|
|
106
|
+
onStoreError: async (err, sub, { tokenSet, dpopKey }) => {
|
|
107
|
+
// If the token data cannot be stored, let's revoke it
|
|
108
|
+
const server = await serverFactory.fromIssuer(tokenSet.iss, dpopKey);
|
|
109
|
+
await server.revoke(tokenSet.refresh_token ?? tokenSet.access_token);
|
|
110
|
+
throw err;
|
|
111
|
+
},
|
|
112
|
+
deleteOnError: async (err) => {
|
|
113
|
+
return err instanceof refresh_error_js_1.RefreshError;
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
Object.defineProperty(this, "runtime", {
|
|
117
|
+
enumerable: true,
|
|
118
|
+
configurable: true,
|
|
119
|
+
writable: true,
|
|
120
|
+
value: runtime
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* @param refresh When `true`, the credentials will be refreshed even if they
|
|
125
|
+
* are not expired. When `false`, the credentials will not be refreshed even
|
|
126
|
+
* if they are expired. When `undefined`, the credentials will be refreshed
|
|
127
|
+
* if, and only if, they are (about to be) expired. Defaults to `undefined`.
|
|
128
|
+
*/
|
|
129
|
+
async getSession(sub, refresh) {
|
|
130
|
+
const session = await this.get(sub, {
|
|
131
|
+
noCache: refresh === true,
|
|
132
|
+
allowStale: refresh === false,
|
|
133
|
+
});
|
|
134
|
+
if (sub !== session.tokenSet.sub) {
|
|
135
|
+
// Fool-proofing (e.g. against invalid session storage)
|
|
136
|
+
throw new Error('Token set does not match the expected sub');
|
|
137
|
+
}
|
|
138
|
+
return session;
|
|
139
|
+
}
|
|
140
|
+
async get(sub, options) {
|
|
141
|
+
return this.runtime.withLock(`@atproto-oauth-client-${sub}`, async () => {
|
|
142
|
+
// Make sure, even if there is no signal in the options, that the request
|
|
143
|
+
// will be cancelled after at most 30 seconds.
|
|
144
|
+
return (0, util_js_1.withSignal)({ signal: options?.signal, timeout: 30e3 }, (signal) => super.get(sub, { ...options, signal }));
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
exports.SessionGetter = SessionGetter;
|
|
149
|
+
//# sourceMappingURL=session-getter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-getter.js","sourceRoot":"","sources":["../src/session-getter.ts"],"names":[],"mappings":"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"}
|