@atproto/api 0.18.8 → 0.18.10
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 +17 -0
- package/dist/atp-agent.d.ts +8 -2
- package/dist/atp-agent.d.ts.map +1 -1
- package/dist/atp-agent.js +115 -80
- package/dist/atp-agent.js.map +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +6 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/lexicons.d.ts +60 -8
- package/dist/client/lexicons.d.ts.map +1 -1
- package/dist/client/lexicons.js +35 -4
- package/dist/client/lexicons.js.map +1 -1
- package/dist/client/types/app/bsky/unspecced/getSuggestedUsers.d.ts +2 -0
- package/dist/client/types/app/bsky/unspecced/getSuggestedUsers.d.ts.map +1 -1
- package/dist/client/types/app/bsky/unspecced/getSuggestedUsers.js.map +1 -1
- package/dist/client/types/app/bsky/unspecced/getSuggestedUsersSkeleton.d.ts +2 -0
- package/dist/client/types/app/bsky/unspecced/getSuggestedUsersSkeleton.d.ts.map +1 -1
- package/dist/client/types/app/bsky/unspecced/getSuggestedUsersSkeleton.js.map +1 -1
- package/dist/client/types/com/atproto/server/deleteSession.d.ts +7 -1
- package/dist/client/types/com/atproto/server/deleteSession.d.ts.map +1 -1
- package/dist/client/types/com/atproto/server/deleteSession.js +23 -0
- package/dist/client/types/com/atproto/server/deleteSession.js.map +1 -1
- package/dist/client/types/com/atproto/server/getSession.d.ts +3 -3
- package/dist/client/types/com/atproto/server/getSession.d.ts.map +1 -1
- package/dist/client/types/com/atproto/server/getSession.js.map +1 -1
- package/dist/client/types/com/atproto/server/refreshSession.d.ts +9 -0
- package/dist/client/types/com/atproto/server/refreshSession.d.ts.map +1 -1
- package/dist/client/types/com/atproto/server/refreshSession.js +17 -1
- package/dist/client/types/com/atproto/server/refreshSession.js.map +1 -1
- package/package.json +2 -2
- package/src/atp-agent.ts +147 -99
- package/src/client/index.ts +5 -6
- package/src/client/lexicons.ts +38 -4
- package/src/client/types/app/bsky/unspecced/getSuggestedUsers.ts +2 -0
- package/src/client/types/app/bsky/unspecced/getSuggestedUsersSkeleton.ts +2 -0
- package/src/client/types/com/atproto/server/deleteSession.ts +17 -0
- package/src/client/types/com/atproto/server/getSession.ts +1 -1
- package/src/client/types/com/atproto/server/refreshSession.ts +17 -0
- package/tests/dispatcher.test.ts +13 -10
- package/tsconfig.tests.tsbuildinfo +0 -1
|
@@ -11,6 +11,8 @@ export type QueryParams = {
|
|
|
11
11
|
export type InputSchema = undefined;
|
|
12
12
|
export interface OutputSchema {
|
|
13
13
|
actors: AppBskyActorDefs.ProfileView[];
|
|
14
|
+
/** Snowflake for this recommendation, use when submitting recommendation events. */
|
|
15
|
+
recId?: number;
|
|
14
16
|
}
|
|
15
17
|
export interface CallOptions {
|
|
16
18
|
signal?: AbortSignal;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getSuggestedUsers.d.ts","sourceRoot":"","sources":["../../../../../../src/client/types/app/bsky/unspecced/getSuggestedUsers.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,UAAU,EAAa,MAAM,eAAe,CAAA;AASrD,OAAO,KAAK,KAAK,gBAAgB,MAAM,kBAAkB,CAAA;AAMzD,MAAM,MAAM,WAAW,GAAG;IACxB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AACD,MAAM,MAAM,WAAW,GAAG,SAAS,CAAA;AAEnC,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,gBAAgB,CAAC,WAAW,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"getSuggestedUsers.d.ts","sourceRoot":"","sources":["../../../../../../src/client/types/app/bsky/unspecced/getSuggestedUsers.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,UAAU,EAAa,MAAM,eAAe,CAAA;AASrD,OAAO,KAAK,KAAK,gBAAgB,MAAM,kBAAkB,CAAA;AAMzD,MAAM,MAAM,WAAW,GAAG;IACxB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AACD,MAAM,MAAM,WAAW,GAAG,SAAS,CAAA;AAEnC,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,gBAAgB,CAAC,WAAW,EAAE,CAAA;IACtC,oFAAoF;IACpF,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,OAAO,CAAC,EAAE,UAAU,CAAA;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,UAAU,CAAA;IACnB,IAAI,EAAE,YAAY,CAAA;CACnB;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,OAEhC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getSuggestedUsers.js","sourceRoot":"","sources":["../../../../../../src/client/types/app/bsky/unspecced/getSuggestedUsers.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"getSuggestedUsers.js","sourceRoot":"","sources":["../../../../../../src/client/types/app/bsky/unspecced/getSuggestedUsers.ts"],"names":[],"mappings":";;AA0CA,gCAEC;AAtCD,mDAA4D;AAC5D,2CAIyB;AAGzB,MAAM,QAAQ,GAAG,eAAS,EACxB,QAAQ,GAAG,mBAAS,CAAA;AACtB,MAAM,EAAE,GAAG,sCAAsC,CAAA;AA0BjD,SAAgB,UAAU,CAAC,CAAM;IAC/B,OAAO,CAAC,CAAA;AACV,CAAC","sourcesContent":["/**\n * GENERATED CODE - DO NOT MODIFY\n */\nimport { HeadersMap, XRPCError } from '@atproto/xrpc'\nimport { type ValidationResult, BlobRef } from '@atproto/lexicon'\nimport { CID } from 'multiformats/cid'\nimport { validate as _validate } from '../../../../lexicons'\nimport {\n type $Typed,\n is$typed as _is$typed,\n type OmitKey,\n} from '../../../../util'\nimport type * as AppBskyActorDefs from '../actor/defs.js'\n\nconst is$typed = _is$typed,\n validate = _validate\nconst id = 'app.bsky.unspecced.getSuggestedUsers'\n\nexport type QueryParams = {\n /** Category of users to get suggestions for. */\n category?: string\n limit?: number\n}\nexport type InputSchema = undefined\n\nexport interface OutputSchema {\n actors: AppBskyActorDefs.ProfileView[]\n /** Snowflake for this recommendation, use when submitting recommendation events. */\n recId?: number\n}\n\nexport interface CallOptions {\n signal?: AbortSignal\n headers?: HeadersMap\n}\n\nexport interface Response {\n success: boolean\n headers: HeadersMap\n data: OutputSchema\n}\n\nexport function toKnownErr(e: any) {\n return e\n}\n"]}
|
|
@@ -12,6 +12,8 @@ export type QueryParams = {
|
|
|
12
12
|
export type InputSchema = undefined;
|
|
13
13
|
export interface OutputSchema {
|
|
14
14
|
dids: string[];
|
|
15
|
+
/** Snowflake for this recommendation, use when submitting recommendation events. */
|
|
16
|
+
recId?: number;
|
|
15
17
|
}
|
|
16
18
|
export interface CallOptions {
|
|
17
19
|
signal?: AbortSignal;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getSuggestedUsersSkeleton.d.ts","sourceRoot":"","sources":["../../../../../../src/client/types/app/bsky/unspecced/getSuggestedUsersSkeleton.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,UAAU,EAAa,MAAM,eAAe,CAAA;AAcrD,MAAM,MAAM,WAAW,GAAG;IACxB,+FAA+F;IAC/F,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AACD,MAAM,MAAM,WAAW,GAAG,SAAS,CAAA;AAEnC,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,EAAE,CAAA;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,OAAO,CAAC,EAAE,UAAU,CAAA;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,UAAU,CAAA;IACnB,IAAI,EAAE,YAAY,CAAA;CACnB;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,OAEhC"}
|
|
1
|
+
{"version":3,"file":"getSuggestedUsersSkeleton.d.ts","sourceRoot":"","sources":["../../../../../../src/client/types/app/bsky/unspecced/getSuggestedUsersSkeleton.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,UAAU,EAAa,MAAM,eAAe,CAAA;AAcrD,MAAM,MAAM,WAAW,GAAG;IACxB,+FAA+F;IAC/F,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AACD,MAAM,MAAM,WAAW,GAAG,SAAS,CAAA;AAEnC,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,oFAAoF;IACpF,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,OAAO,CAAC,EAAE,UAAU,CAAA;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,UAAU,CAAA;IACnB,IAAI,EAAE,YAAY,CAAA;CACnB;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,OAEhC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getSuggestedUsersSkeleton.js","sourceRoot":"","sources":["../../../../../../src/client/types/app/bsky/unspecced/getSuggestedUsersSkeleton.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"getSuggestedUsersSkeleton.js","sourceRoot":"","sources":["../../../../../../src/client/types/app/bsky/unspecced/getSuggestedUsersSkeleton.ts"],"names":[],"mappings":";;AA2CA,gCAEC;AAvCD,mDAA4D;AAC5D,2CAIyB;AAEzB,MAAM,QAAQ,GAAG,eAAS,EACxB,QAAQ,GAAG,mBAAS,CAAA;AACtB,MAAM,EAAE,GAAG,8CAA8C,CAAA;AA4BzD,SAAgB,UAAU,CAAC,CAAM;IAC/B,OAAO,CAAC,CAAA;AACV,CAAC","sourcesContent":["/**\n * GENERATED CODE - DO NOT MODIFY\n */\nimport { HeadersMap, XRPCError } from '@atproto/xrpc'\nimport { type ValidationResult, BlobRef } from '@atproto/lexicon'\nimport { CID } from 'multiformats/cid'\nimport { validate as _validate } from '../../../../lexicons'\nimport {\n type $Typed,\n is$typed as _is$typed,\n type OmitKey,\n} from '../../../../util'\n\nconst is$typed = _is$typed,\n validate = _validate\nconst id = 'app.bsky.unspecced.getSuggestedUsersSkeleton'\n\nexport type QueryParams = {\n /** DID of the account making the request (not included for public/unauthenticated queries). */\n viewer?: string\n /** Category of users to get suggestions for. */\n category?: string\n limit?: number\n}\nexport type InputSchema = undefined\n\nexport interface OutputSchema {\n dids: string[]\n /** Snowflake for this recommendation, use when submitting recommendation events. */\n recId?: number\n}\n\nexport interface CallOptions {\n signal?: AbortSignal\n headers?: HeadersMap\n}\n\nexport interface Response {\n success: boolean\n headers: HeadersMap\n data: OutputSchema\n}\n\nexport function toKnownErr(e: any) {\n return e\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* GENERATED CODE - DO NOT MODIFY
|
|
3
3
|
*/
|
|
4
|
-
import { HeadersMap } from '@atproto/xrpc';
|
|
4
|
+
import { HeadersMap, XRPCError } from '@atproto/xrpc';
|
|
5
5
|
export type QueryParams = {};
|
|
6
6
|
export type InputSchema = undefined;
|
|
7
7
|
export interface CallOptions {
|
|
@@ -13,5 +13,11 @@ export interface Response {
|
|
|
13
13
|
success: boolean;
|
|
14
14
|
headers: HeadersMap;
|
|
15
15
|
}
|
|
16
|
+
export declare class InvalidTokenError extends XRPCError {
|
|
17
|
+
constructor(src: XRPCError);
|
|
18
|
+
}
|
|
19
|
+
export declare class ExpiredTokenError extends XRPCError {
|
|
20
|
+
constructor(src: XRPCError);
|
|
21
|
+
}
|
|
16
22
|
export declare function toKnownErr(e: any): any;
|
|
17
23
|
//# sourceMappingURL=deleteSession.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deleteSession.d.ts","sourceRoot":"","sources":["../../../../../../src/client/types/com/atproto/server/deleteSession.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"deleteSession.d.ts","sourceRoot":"","sources":["../../../../../../src/client/types/com/atproto/server/deleteSession.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAcrD,MAAM,MAAM,WAAW,GAAG,EAAE,CAAA;AAC5B,MAAM,MAAM,WAAW,GAAG,SAAS,CAAA;AAEnC,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,OAAO,CAAC,EAAE,UAAU,CAAA;IACpB,EAAE,CAAC,EAAE,WAAW,CAAA;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,UAAU,CAAA;CACpB;AAED,qBAAa,iBAAkB,SAAQ,SAAS;gBAClC,GAAG,EAAE,SAAS;CAG3B;AAED,qBAAa,iBAAkB,SAAQ,SAAS;gBAClC,GAAG,EAAE,SAAS;CAG3B;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,OAOhC"}
|
|
@@ -1,11 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ExpiredTokenError = exports.InvalidTokenError = void 0;
|
|
3
4
|
exports.toKnownErr = toKnownErr;
|
|
5
|
+
/**
|
|
6
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
7
|
+
*/
|
|
8
|
+
const xrpc_1 = require("@atproto/xrpc");
|
|
4
9
|
const lexicons_1 = require("../../../../lexicons");
|
|
5
10
|
const util_1 = require("../../../../util");
|
|
6
11
|
const is$typed = util_1.is$typed, validate = lexicons_1.validate;
|
|
7
12
|
const id = 'com.atproto.server.deleteSession';
|
|
13
|
+
class InvalidTokenError extends xrpc_1.XRPCError {
|
|
14
|
+
constructor(src) {
|
|
15
|
+
super(src.status, src.error, src.message, src.headers, { cause: src });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.InvalidTokenError = InvalidTokenError;
|
|
19
|
+
class ExpiredTokenError extends xrpc_1.XRPCError {
|
|
20
|
+
constructor(src) {
|
|
21
|
+
super(src.status, src.error, src.message, src.headers, { cause: src });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.ExpiredTokenError = ExpiredTokenError;
|
|
8
25
|
function toKnownErr(e) {
|
|
26
|
+
if (e instanceof xrpc_1.XRPCError) {
|
|
27
|
+
if (e.error === 'InvalidToken')
|
|
28
|
+
return new InvalidTokenError(e);
|
|
29
|
+
if (e.error === 'ExpiredToken')
|
|
30
|
+
return new ExpiredTokenError(e);
|
|
31
|
+
}
|
|
9
32
|
return e;
|
|
10
33
|
}
|
|
11
34
|
//# sourceMappingURL=deleteSession.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deleteSession.js","sourceRoot":"","sources":["../../../../../../src/client/types/com/atproto/server/deleteSession.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"deleteSession.js","sourceRoot":"","sources":["../../../../../../src/client/types/com/atproto/server/deleteSession.ts"],"names":[],"mappings":";;;AA2CA,gCAOC;AAlDD;;GAEG;AACH,wCAAqD;AAGrD,mDAA4D;AAC5D,2CAIyB;AAEzB,MAAM,QAAQ,GAAG,eAAS,EACxB,QAAQ,GAAG,mBAAS,CAAA;AACtB,MAAM,EAAE,GAAG,kCAAkC,CAAA;AAgB7C,MAAa,iBAAkB,SAAQ,gBAAS;IAC9C,YAAY,GAAc;QACxB,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IACxE,CAAC;CACF;AAJD,8CAIC;AAED,MAAa,iBAAkB,SAAQ,gBAAS;IAC9C,YAAY,GAAc;QACxB,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IACxE,CAAC;CACF;AAJD,8CAIC;AAED,SAAgB,UAAU,CAAC,CAAM;IAC/B,IAAI,CAAC,YAAY,gBAAS,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,KAAK,KAAK,cAAc;YAAE,OAAO,IAAI,iBAAiB,CAAC,CAAC,CAAC,CAAA;QAC/D,IAAI,CAAC,CAAC,KAAK,KAAK,cAAc;YAAE,OAAO,IAAI,iBAAiB,CAAC,CAAC,CAAC,CAAA;IACjE,CAAC;IAED,OAAO,CAAC,CAAA;AACV,CAAC","sourcesContent":["/**\n * GENERATED CODE - DO NOT MODIFY\n */\nimport { HeadersMap, XRPCError } from '@atproto/xrpc'\nimport { type ValidationResult, BlobRef } from '@atproto/lexicon'\nimport { CID } from 'multiformats/cid'\nimport { validate as _validate } from '../../../../lexicons'\nimport {\n type $Typed,\n is$typed as _is$typed,\n type OmitKey,\n} from '../../../../util'\n\nconst is$typed = _is$typed,\n validate = _validate\nconst id = 'com.atproto.server.deleteSession'\n\nexport type QueryParams = {}\nexport type InputSchema = undefined\n\nexport interface CallOptions {\n signal?: AbortSignal\n headers?: HeadersMap\n qp?: QueryParams\n}\n\nexport interface Response {\n success: boolean\n headers: HeadersMap\n}\n\nexport class InvalidTokenError extends XRPCError {\n constructor(src: XRPCError) {\n super(src.status, src.error, src.message, src.headers, { cause: src })\n }\n}\n\nexport class ExpiredTokenError extends XRPCError {\n constructor(src: XRPCError) {\n super(src.status, src.error, src.message, src.headers, { cause: src })\n }\n}\n\nexport function toKnownErr(e: any) {\n if (e instanceof XRPCError) {\n if (e.error === 'InvalidToken') return new InvalidTokenError(e)\n if (e.error === 'ExpiredToken') return new ExpiredTokenError(e)\n }\n\n return e\n}\n"]}
|
|
@@ -7,12 +7,12 @@ export type InputSchema = undefined;
|
|
|
7
7
|
export interface OutputSchema {
|
|
8
8
|
handle: string;
|
|
9
9
|
did: string;
|
|
10
|
-
email?: string;
|
|
11
|
-
emailConfirmed?: boolean;
|
|
12
|
-
emailAuthFactor?: boolean;
|
|
13
10
|
didDoc?: {
|
|
14
11
|
[_ in string]: unknown;
|
|
15
12
|
};
|
|
13
|
+
email?: string;
|
|
14
|
+
emailConfirmed?: boolean;
|
|
15
|
+
emailAuthFactor?: boolean;
|
|
16
16
|
active?: boolean;
|
|
17
17
|
/** If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted. */
|
|
18
18
|
status?: 'takendown' | 'suspended' | 'deactivated' | (string & {});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getSession.d.ts","sourceRoot":"","sources":["../../../../../../src/client/types/com/atproto/server/getSession.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,UAAU,EAAa,MAAM,eAAe,CAAA;AAcrD,MAAM,MAAM,WAAW,GAAG,EAAE,CAAA;AAC5B,MAAM,MAAM,WAAW,GAAG,SAAS,CAAA;AAEnC,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,
|
|
1
|
+
{"version":3,"file":"getSession.d.ts","sourceRoot":"","sources":["../../../../../../src/client/types/com/atproto/server/getSession.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,UAAU,EAAa,MAAM,eAAe,CAAA;AAcrD,MAAM,MAAM,WAAW,GAAG,EAAE,CAAA;AAC5B,MAAM,MAAM,WAAW,GAAG,SAAS,CAAA;AAEnC,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE;SAAG,CAAC,IAAI,MAAM,GAAG,OAAO;KAAE,CAAA;IACnC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,oOAAoO;IACpO,MAAM,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,aAAa,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;CACnE;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,OAAO,CAAC,EAAE,UAAU,CAAA;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,UAAU,CAAA;IACnB,IAAI,EAAE,YAAY,CAAA;CACnB;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,OAEhC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getSession.js","sourceRoot":"","sources":["../../../../../../src/client/types/com/atproto/server/getSession.ts"],"names":[],"mappings":";;AA2CA,gCAEC;AAvCD,mDAA4D;AAC5D,2CAIyB;AAEzB,MAAM,QAAQ,GAAG,eAAS,EACxB,QAAQ,GAAG,mBAAS,CAAA;AACtB,MAAM,EAAE,GAAG,+BAA+B,CAAA;AA4B1C,SAAgB,UAAU,CAAC,CAAM;IAC/B,OAAO,CAAC,CAAA;AACV,CAAC","sourcesContent":["/**\n * GENERATED CODE - DO NOT MODIFY\n */\nimport { HeadersMap, XRPCError } from '@atproto/xrpc'\nimport { type ValidationResult, BlobRef } from '@atproto/lexicon'\nimport { CID } from 'multiformats/cid'\nimport { validate as _validate } from '../../../../lexicons'\nimport {\n type $Typed,\n is$typed as _is$typed,\n type OmitKey,\n} from '../../../../util'\n\nconst is$typed = _is$typed,\n validate = _validate\nconst id = 'com.atproto.server.getSession'\n\nexport type QueryParams = {}\nexport type InputSchema = undefined\n\nexport interface OutputSchema {\n handle: string\n did: string\n
|
|
1
|
+
{"version":3,"file":"getSession.js","sourceRoot":"","sources":["../../../../../../src/client/types/com/atproto/server/getSession.ts"],"names":[],"mappings":";;AA2CA,gCAEC;AAvCD,mDAA4D;AAC5D,2CAIyB;AAEzB,MAAM,QAAQ,GAAG,eAAS,EACxB,QAAQ,GAAG,mBAAS,CAAA;AACtB,MAAM,EAAE,GAAG,+BAA+B,CAAA;AA4B1C,SAAgB,UAAU,CAAC,CAAM;IAC/B,OAAO,CAAC,CAAA;AACV,CAAC","sourcesContent":["/**\n * GENERATED CODE - DO NOT MODIFY\n */\nimport { HeadersMap, XRPCError } from '@atproto/xrpc'\nimport { type ValidationResult, BlobRef } from '@atproto/lexicon'\nimport { CID } from 'multiformats/cid'\nimport { validate as _validate } from '../../../../lexicons'\nimport {\n type $Typed,\n is$typed as _is$typed,\n type OmitKey,\n} from '../../../../util'\n\nconst is$typed = _is$typed,\n validate = _validate\nconst id = 'com.atproto.server.getSession'\n\nexport type QueryParams = {}\nexport type InputSchema = undefined\n\nexport interface OutputSchema {\n handle: string\n did: string\n didDoc?: { [_ in string]: unknown }\n email?: string\n emailConfirmed?: boolean\n emailAuthFactor?: boolean\n active?: boolean\n /** If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted. */\n status?: 'takendown' | 'suspended' | 'deactivated' | (string & {})\n}\n\nexport interface CallOptions {\n signal?: AbortSignal\n headers?: HeadersMap\n}\n\nexport interface Response {\n success: boolean\n headers: HeadersMap\n data: OutputSchema\n}\n\nexport function toKnownErr(e: any) {\n return e\n}\n"]}
|
|
@@ -12,6 +12,9 @@ export interface OutputSchema {
|
|
|
12
12
|
didDoc?: {
|
|
13
13
|
[_ in string]: unknown;
|
|
14
14
|
};
|
|
15
|
+
email?: string;
|
|
16
|
+
emailConfirmed?: boolean;
|
|
17
|
+
emailAuthFactor?: boolean;
|
|
15
18
|
active?: boolean;
|
|
16
19
|
/** Hosting status of the account. If not specified, then assume 'active'. */
|
|
17
20
|
status?: 'takendown' | 'suspended' | 'deactivated' | (string & {});
|
|
@@ -29,5 +32,11 @@ export interface Response {
|
|
|
29
32
|
export declare class AccountTakedownError extends XRPCError {
|
|
30
33
|
constructor(src: XRPCError);
|
|
31
34
|
}
|
|
35
|
+
export declare class InvalidTokenError extends XRPCError {
|
|
36
|
+
constructor(src: XRPCError);
|
|
37
|
+
}
|
|
38
|
+
export declare class ExpiredTokenError extends XRPCError {
|
|
39
|
+
constructor(src: XRPCError);
|
|
40
|
+
}
|
|
32
41
|
export declare function toKnownErr(e: any): any;
|
|
33
42
|
//# sourceMappingURL=refreshSession.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refreshSession.d.ts","sourceRoot":"","sources":["../../../../../../src/client/types/com/atproto/server/refreshSession.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAcrD,MAAM,MAAM,WAAW,GAAG,EAAE,CAAA;AAC5B,MAAM,MAAM,WAAW,GAAG,SAAS,CAAA;AAEnC,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE;SAAG,CAAC,IAAI,MAAM,GAAG,OAAO;KAAE,CAAA;IACnC,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,aAAa,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;CACnE;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,OAAO,CAAC,EAAE,UAAU,CAAA;IACpB,EAAE,CAAC,EAAE,WAAW,CAAA;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,UAAU,CAAA;IACnB,IAAI,EAAE,YAAY,CAAA;CACnB;AAED,qBAAa,oBAAqB,SAAQ,SAAS;gBACrC,GAAG,EAAE,SAAS;CAG3B;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,
|
|
1
|
+
{"version":3,"file":"refreshSession.d.ts","sourceRoot":"","sources":["../../../../../../src/client/types/com/atproto/server/refreshSession.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAcrD,MAAM,MAAM,WAAW,GAAG,EAAE,CAAA;AAC5B,MAAM,MAAM,WAAW,GAAG,SAAS,CAAA;AAEnC,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE;SAAG,CAAC,IAAI,MAAM,GAAG,OAAO;KAAE,CAAA;IACnC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,aAAa,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;CACnE;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,OAAO,CAAC,EAAE,UAAU,CAAA;IACpB,EAAE,CAAC,EAAE,WAAW,CAAA;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,UAAU,CAAA;IACnB,IAAI,EAAE,YAAY,CAAA;CACnB;AAED,qBAAa,oBAAqB,SAAQ,SAAS;gBACrC,GAAG,EAAE,SAAS;CAG3B;AAED,qBAAa,iBAAkB,SAAQ,SAAS;gBAClC,GAAG,EAAE,SAAS;CAG3B;AAED,qBAAa,iBAAkB,SAAQ,SAAS;gBAClC,GAAG,EAAE,SAAS;CAG3B;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,OAQhC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AccountTakedownError = void 0;
|
|
3
|
+
exports.ExpiredTokenError = exports.InvalidTokenError = exports.AccountTakedownError = void 0;
|
|
4
4
|
exports.toKnownErr = toKnownErr;
|
|
5
5
|
/**
|
|
6
6
|
* GENERATED CODE - DO NOT MODIFY
|
|
@@ -16,10 +16,26 @@ class AccountTakedownError extends xrpc_1.XRPCError {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
exports.AccountTakedownError = AccountTakedownError;
|
|
19
|
+
class InvalidTokenError extends xrpc_1.XRPCError {
|
|
20
|
+
constructor(src) {
|
|
21
|
+
super(src.status, src.error, src.message, src.headers, { cause: src });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.InvalidTokenError = InvalidTokenError;
|
|
25
|
+
class ExpiredTokenError extends xrpc_1.XRPCError {
|
|
26
|
+
constructor(src) {
|
|
27
|
+
super(src.status, src.error, src.message, src.headers, { cause: src });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.ExpiredTokenError = ExpiredTokenError;
|
|
19
31
|
function toKnownErr(e) {
|
|
20
32
|
if (e instanceof xrpc_1.XRPCError) {
|
|
21
33
|
if (e.error === 'AccountTakedown')
|
|
22
34
|
return new AccountTakedownError(e);
|
|
35
|
+
if (e.error === 'InvalidToken')
|
|
36
|
+
return new InvalidTokenError(e);
|
|
37
|
+
if (e.error === 'ExpiredToken')
|
|
38
|
+
return new ExpiredTokenError(e);
|
|
23
39
|
}
|
|
24
40
|
return e;
|
|
25
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refreshSession.js","sourceRoot":"","sources":["../../../../../../src/client/types/com/atproto/server/refreshSession.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"refreshSession.js","sourceRoot":"","sources":["../../../../../../src/client/types/com/atproto/server/refreshSession.ts"],"names":[],"mappings":";;;AAgEA,gCAQC;AAxED;;GAEG;AACH,wCAAqD;AAGrD,mDAA4D;AAC5D,2CAIyB;AAEzB,MAAM,QAAQ,GAAG,eAAS,EACxB,QAAQ,GAAG,mBAAS,CAAA;AACtB,MAAM,EAAE,GAAG,mCAAmC,CAAA;AA+B9C,MAAa,oBAAqB,SAAQ,gBAAS;IACjD,YAAY,GAAc;QACxB,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IACxE,CAAC;CACF;AAJD,oDAIC;AAED,MAAa,iBAAkB,SAAQ,gBAAS;IAC9C,YAAY,GAAc;QACxB,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IACxE,CAAC;CACF;AAJD,8CAIC;AAED,MAAa,iBAAkB,SAAQ,gBAAS;IAC9C,YAAY,GAAc;QACxB,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IACxE,CAAC;CACF;AAJD,8CAIC;AAED,SAAgB,UAAU,CAAC,CAAM;IAC/B,IAAI,CAAC,YAAY,gBAAS,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,KAAK,KAAK,iBAAiB;YAAE,OAAO,IAAI,oBAAoB,CAAC,CAAC,CAAC,CAAA;QACrE,IAAI,CAAC,CAAC,KAAK,KAAK,cAAc;YAAE,OAAO,IAAI,iBAAiB,CAAC,CAAC,CAAC,CAAA;QAC/D,IAAI,CAAC,CAAC,KAAK,KAAK,cAAc;YAAE,OAAO,IAAI,iBAAiB,CAAC,CAAC,CAAC,CAAA;IACjE,CAAC;IAED,OAAO,CAAC,CAAA;AACV,CAAC","sourcesContent":["/**\n * GENERATED CODE - DO NOT MODIFY\n */\nimport { HeadersMap, XRPCError } from '@atproto/xrpc'\nimport { type ValidationResult, BlobRef } from '@atproto/lexicon'\nimport { CID } from 'multiformats/cid'\nimport { validate as _validate } from '../../../../lexicons'\nimport {\n type $Typed,\n is$typed as _is$typed,\n type OmitKey,\n} from '../../../../util'\n\nconst is$typed = _is$typed,\n validate = _validate\nconst id = 'com.atproto.server.refreshSession'\n\nexport type QueryParams = {}\nexport type InputSchema = undefined\n\nexport interface OutputSchema {\n accessJwt: string\n refreshJwt: string\n handle: string\n did: string\n didDoc?: { [_ in string]: unknown }\n email?: string\n emailConfirmed?: boolean\n emailAuthFactor?: boolean\n active?: boolean\n /** Hosting status of the account. If not specified, then assume 'active'. */\n status?: 'takendown' | 'suspended' | 'deactivated' | (string & {})\n}\n\nexport interface CallOptions {\n signal?: AbortSignal\n headers?: HeadersMap\n qp?: QueryParams\n}\n\nexport interface Response {\n success: boolean\n headers: HeadersMap\n data: OutputSchema\n}\n\nexport class AccountTakedownError extends XRPCError {\n constructor(src: XRPCError) {\n super(src.status, src.error, src.message, src.headers, { cause: src })\n }\n}\n\nexport class InvalidTokenError extends XRPCError {\n constructor(src: XRPCError) {\n super(src.status, src.error, src.message, src.headers, { cause: src })\n }\n}\n\nexport class ExpiredTokenError extends XRPCError {\n constructor(src: XRPCError) {\n super(src.status, src.error, src.message, src.headers, { cause: src })\n }\n}\n\nexport function toKnownErr(e: any) {\n if (e instanceof XRPCError) {\n if (e.error === 'AccountTakedown') return new AccountTakedownError(e)\n if (e.error === 'InvalidToken') return new InvalidTokenError(e)\n if (e.error === 'ExpiredToken') return new ExpiredTokenError(e)\n }\n\n return e\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/api",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.10",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Client library for atproto and Bluesky",
|
|
6
6
|
"keywords": [
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"multiformats": "^9.9.0",
|
|
22
22
|
"tlds": "^1.234.0",
|
|
23
23
|
"zod": "^3.23.8",
|
|
24
|
-
"@atproto/common-web": "^0.4.7",
|
|
25
24
|
"@atproto/lexicon": "^0.6.0",
|
|
25
|
+
"@atproto/common-web": "^0.4.10",
|
|
26
26
|
"@atproto/syntax": "^0.4.2",
|
|
27
27
|
"@atproto/xrpc": "^0.7.7"
|
|
28
28
|
},
|
package/src/atp-agent.ts
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
ComAtprotoServerCreateSession,
|
|
14
14
|
ComAtprotoServerGetSession,
|
|
15
15
|
ComAtprotoServerNS,
|
|
16
|
+
ComAtprotoServerRefreshSession,
|
|
16
17
|
} from './client'
|
|
17
18
|
import { schemas } from './client/lexicons'
|
|
18
19
|
import { SessionManager } from './session-manager'
|
|
@@ -222,11 +223,9 @@ export class CredentialSession implements SessionManager {
|
|
|
222
223
|
if (!this.session?.refreshJwt) {
|
|
223
224
|
return initialRes
|
|
224
225
|
}
|
|
225
|
-
const isExpiredToken =
|
|
226
|
-
initialRes
|
|
227
|
-
[400],
|
|
228
|
-
['ExpiredToken'],
|
|
229
|
-
)
|
|
226
|
+
const isExpiredToken =
|
|
227
|
+
initialRes.status === 401 ||
|
|
228
|
+
(await isErrorResponse(initialRes, [400], ['ExpiredToken']))
|
|
230
229
|
|
|
231
230
|
if (!isExpiredToken) {
|
|
232
231
|
return initialRes
|
|
@@ -276,6 +275,10 @@ export class CredentialSession implements SessionManager {
|
|
|
276
275
|
data: ComAtprotoServerCreateAccount.InputSchema,
|
|
277
276
|
opts?: ComAtprotoServerCreateAccount.CallOptions,
|
|
278
277
|
): Promise<ComAtprotoServerCreateAccount.Response> {
|
|
278
|
+
// Clear any existing session
|
|
279
|
+
this.session = undefined
|
|
280
|
+
this.refreshSessionPromise = undefined
|
|
281
|
+
|
|
279
282
|
try {
|
|
280
283
|
const res = await this.server.createAccount(data, opts)
|
|
281
284
|
this.session = {
|
|
@@ -304,6 +307,10 @@ export class CredentialSession implements SessionManager {
|
|
|
304
307
|
async login(
|
|
305
308
|
opts: AtpAgentLoginOpts,
|
|
306
309
|
): Promise<ComAtprotoServerCreateSession.Response> {
|
|
310
|
+
// Clear any existing session
|
|
311
|
+
this.session = undefined
|
|
312
|
+
this.refreshSessionPromise = undefined
|
|
313
|
+
|
|
307
314
|
try {
|
|
308
315
|
const res = await this.server.createSession({
|
|
309
316
|
identifier: opts.identifier,
|
|
@@ -311,6 +318,11 @@ export class CredentialSession implements SessionManager {
|
|
|
311
318
|
authFactorToken: opts.authFactorToken,
|
|
312
319
|
allowTakendown: opts.allowTakendown,
|
|
313
320
|
})
|
|
321
|
+
|
|
322
|
+
if (this.session) {
|
|
323
|
+
throw new Error('Concurrent login detected')
|
|
324
|
+
}
|
|
325
|
+
|
|
314
326
|
this.session = {
|
|
315
327
|
accessJwt: res.data.accessJwt,
|
|
316
328
|
refreshJwt: res.data.refreshJwt,
|
|
@@ -351,42 +363,95 @@ export class CredentialSession implements SessionManager {
|
|
|
351
363
|
|
|
352
364
|
/**
|
|
353
365
|
* Resume a pre-existing session with this agent.
|
|
366
|
+
*
|
|
367
|
+
* @note that a rejected promise from this method indicates a failure to
|
|
368
|
+
* refresh the session after resuming it but does not indicate a failure to
|
|
369
|
+
* set the session itself. In case of rejection, check the presence of
|
|
370
|
+
* {@link CredentialSession.session} after calling this method to ensure the
|
|
371
|
+
* session was set.
|
|
354
372
|
*/
|
|
355
373
|
async resumeSession(
|
|
356
374
|
session: AtpSessionData,
|
|
357
|
-
): Promise<
|
|
375
|
+
): Promise<
|
|
376
|
+
| ComAtprotoServerGetSession.Response
|
|
377
|
+
| ComAtprotoServerRefreshSession.Response
|
|
378
|
+
> {
|
|
379
|
+
// Protect against multiple calls to resumeSession that would trigger a
|
|
380
|
+
// refresh for the same session simultaneously.
|
|
381
|
+
// Ideally, this check would be based on a session identifier, but since
|
|
382
|
+
// we don't have one, we will just check the refresh token.
|
|
383
|
+
if (session.refreshJwt === this.session?.refreshJwt) {
|
|
384
|
+
// Protect against refreshes in progress
|
|
385
|
+
await this.refreshSessionPromise
|
|
386
|
+
|
|
387
|
+
// Another concurrent operation may have replaced the session while we
|
|
388
|
+
// were waiting for the refresh to complete.
|
|
389
|
+
if (session.did !== this.session?.did) {
|
|
390
|
+
throw new Error('DID mismatch on resumeSession')
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
return this.server.getSession(undefined, {
|
|
394
|
+
headers: { authorization: `Bearer ${this.session.accessJwt}` },
|
|
395
|
+
})
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// Set the current session, then force a refresh, replacing any pending
|
|
399
|
+
// refresh operation.
|
|
358
400
|
this.session = session
|
|
401
|
+
this.refreshSessionPromise = undefined
|
|
402
|
+
|
|
403
|
+
const promise = this._refreshSessionInner()
|
|
404
|
+
|
|
405
|
+
// Discard any concurrent refresh, replacing it with this one.
|
|
406
|
+
this.refreshSessionPromise = promise
|
|
407
|
+
.then(
|
|
408
|
+
(): void => {},
|
|
409
|
+
(): void => {},
|
|
410
|
+
)
|
|
411
|
+
.finally(() => {
|
|
412
|
+
this.refreshSessionPromise = undefined
|
|
413
|
+
})
|
|
414
|
+
|
|
415
|
+
return promise
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Internal helper to refresh sessions
|
|
420
|
+
* - Wraps the actual implementation in a promise-guard to ensure only
|
|
421
|
+
* one refresh is attempted at a time.
|
|
422
|
+
*/
|
|
423
|
+
async refreshSession(): Promise<void> {
|
|
424
|
+
if (!this.session) return
|
|
425
|
+
|
|
426
|
+
// Do not refresh if we already have a refresh in progress
|
|
427
|
+
return (this.refreshSessionPromise ||= this._refreshSessionInner()
|
|
428
|
+
.then(
|
|
429
|
+
(): void => {},
|
|
430
|
+
(): void => {},
|
|
431
|
+
)
|
|
432
|
+
.finally(() => {
|
|
433
|
+
this.refreshSessionPromise = undefined
|
|
434
|
+
}))
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Internal helper to refresh sessions (actual behavior)
|
|
439
|
+
*/
|
|
440
|
+
private async _refreshSessionInner(): Promise<ComAtprotoServerRefreshSession.Response> {
|
|
441
|
+
const { session } = this
|
|
442
|
+
|
|
443
|
+
// Should never happen
|
|
444
|
+
if (!session) throw new Error('No session to refresh')
|
|
359
445
|
|
|
360
446
|
try {
|
|
361
|
-
const res = await this.server
|
|
362
|
-
.
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
if (
|
|
367
|
-
err instanceof XRPCError &&
|
|
368
|
-
['ExpiredToken', 'InvalidToken'].includes(err.error) &&
|
|
369
|
-
session.refreshJwt
|
|
370
|
-
) {
|
|
371
|
-
try {
|
|
372
|
-
const res = await this.server.refreshSession(undefined, {
|
|
373
|
-
headers: { authorization: `Bearer ${session.refreshJwt}` },
|
|
374
|
-
})
|
|
375
|
-
|
|
376
|
-
session.accessJwt = res.data.accessJwt
|
|
377
|
-
session.refreshJwt = res.data.refreshJwt
|
|
378
|
-
|
|
379
|
-
return this.server.getSession(undefined, {
|
|
380
|
-
headers: { authorization: `Bearer ${session.accessJwt}` },
|
|
381
|
-
})
|
|
382
|
-
} catch {
|
|
383
|
-
// Noop, we'll throw the original error
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
throw err
|
|
387
|
-
})
|
|
447
|
+
const res = await this.server.refreshSession(undefined, {
|
|
448
|
+
headers: { authorization: `Bearer ${session.refreshJwt}` },
|
|
449
|
+
})
|
|
450
|
+
|
|
451
|
+
const { data } = res
|
|
388
452
|
|
|
389
|
-
if
|
|
453
|
+
// Something is very wrong if the DID changes during a refresh
|
|
454
|
+
if (data.did !== session.did) {
|
|
390
455
|
throw new XRPCError(
|
|
391
456
|
ResponseType.InvalidRequest,
|
|
392
457
|
'Invalid session',
|
|
@@ -394,27 +459,58 @@ export class CredentialSession implements SessionManager {
|
|
|
394
459
|
)
|
|
395
460
|
}
|
|
396
461
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
462
|
+
// Historically, refreshSession did not return all the fields from
|
|
463
|
+
// getSession. In particular, email, emailConfirmed and emailAuthFactor
|
|
464
|
+
// were missing. Similarly, some servers might not return the didDoc in
|
|
465
|
+
// refreshSession. We fetch them via getSession if missing, allowing to
|
|
466
|
+
// ensure that we are always talking with the right PDS.
|
|
467
|
+
if (data.emailConfirmed == null || data.didDoc == null) {
|
|
468
|
+
try {
|
|
469
|
+
const res = await this.server.getSession(undefined, {
|
|
470
|
+
headers: { authorization: `Bearer ${data.accessJwt}` },
|
|
471
|
+
})
|
|
472
|
+
|
|
473
|
+
// Fool proofing (should always match)
|
|
474
|
+
if (res.data.did === data.did) {
|
|
475
|
+
Object.assign(data, res.data)
|
|
476
|
+
}
|
|
477
|
+
} catch {
|
|
478
|
+
// Noop, we'll keep the current values we have
|
|
479
|
+
}
|
|
480
|
+
}
|
|
403
481
|
|
|
404
482
|
// protect against concurrent session updates
|
|
405
|
-
if (this.session
|
|
406
|
-
|
|
407
|
-
|
|
483
|
+
if (this.session !== session) {
|
|
484
|
+
return Promise.reject(new Error('Concurrent session update detected'))
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// succeeded, update the session
|
|
488
|
+
this.session = {
|
|
489
|
+
did: data.did,
|
|
490
|
+
accessJwt: data.accessJwt,
|
|
491
|
+
refreshJwt: data.refreshJwt,
|
|
492
|
+
handle: data.handle ?? session.handle,
|
|
493
|
+
email: data.email ?? session.email,
|
|
494
|
+
emailConfirmed: data.emailConfirmed ?? session.emailConfirmed,
|
|
495
|
+
emailAuthFactor: data.emailAuthFactor ?? session.emailAuthFactor,
|
|
496
|
+
active: data.active ?? session.active ?? true,
|
|
497
|
+
status: data.status ?? session.status,
|
|
408
498
|
}
|
|
409
499
|
|
|
500
|
+
this._updateApiEndpoint(res.data.didDoc)
|
|
501
|
+
this.persistSession?.('update', this.session)
|
|
502
|
+
|
|
410
503
|
return res
|
|
411
504
|
} catch (err) {
|
|
412
505
|
// protect against concurrent session updates
|
|
413
506
|
if (this.session === session) {
|
|
414
507
|
if (
|
|
415
508
|
err instanceof XRPCError &&
|
|
416
|
-
|
|
509
|
+
(err.status === 401 ||
|
|
510
|
+
err.error === 'InvalidDID' ||
|
|
511
|
+
['ExpiredToken', 'InvalidToken'].includes(err.error))
|
|
417
512
|
) {
|
|
513
|
+
// failed due to a bad refresh token
|
|
418
514
|
this.session = undefined
|
|
419
515
|
this.persistSession?.('expired', undefined)
|
|
420
516
|
} else {
|
|
@@ -428,57 +524,6 @@ export class CredentialSession implements SessionManager {
|
|
|
428
524
|
}
|
|
429
525
|
}
|
|
430
526
|
|
|
431
|
-
/**
|
|
432
|
-
* Internal helper to refresh sessions
|
|
433
|
-
* - Wraps the actual implementation in a promise-guard to ensure only
|
|
434
|
-
* one refresh is attempted at a time.
|
|
435
|
-
*/
|
|
436
|
-
async refreshSession(): Promise<void> {
|
|
437
|
-
return (this.refreshSessionPromise ||= this._refreshSessionInner().finally(
|
|
438
|
-
() => {
|
|
439
|
-
this.refreshSessionPromise = undefined
|
|
440
|
-
},
|
|
441
|
-
))
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
/**
|
|
445
|
-
* Internal helper to refresh sessions (actual behavior)
|
|
446
|
-
*/
|
|
447
|
-
private async _refreshSessionInner() {
|
|
448
|
-
if (!this.session?.refreshJwt) {
|
|
449
|
-
return
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
try {
|
|
453
|
-
const res = await this.server.refreshSession(undefined, {
|
|
454
|
-
headers: { authorization: `Bearer ${this.session.refreshJwt}` },
|
|
455
|
-
})
|
|
456
|
-
// succeeded, update the session
|
|
457
|
-
this.session = {
|
|
458
|
-
...this.session,
|
|
459
|
-
accessJwt: res.data.accessJwt,
|
|
460
|
-
refreshJwt: res.data.refreshJwt,
|
|
461
|
-
handle: res.data.handle,
|
|
462
|
-
did: res.data.did,
|
|
463
|
-
}
|
|
464
|
-
this._updateApiEndpoint(res.data.didDoc)
|
|
465
|
-
this.persistSession?.('update', this.session)
|
|
466
|
-
} catch (err) {
|
|
467
|
-
if (
|
|
468
|
-
err instanceof XRPCError &&
|
|
469
|
-
err.error &&
|
|
470
|
-
['ExpiredToken', 'InvalidToken'].includes(err.error)
|
|
471
|
-
) {
|
|
472
|
-
// failed due to a bad refresh token
|
|
473
|
-
this.session = undefined
|
|
474
|
-
this.persistSession?.('expired', undefined)
|
|
475
|
-
}
|
|
476
|
-
// else: other failures should be ignored - the issue will
|
|
477
|
-
// propagate in the _dispatch() second attempt to run
|
|
478
|
-
// the request
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
|
|
482
527
|
/**
|
|
483
528
|
* Helper to update the pds endpoint dynamically.
|
|
484
529
|
*
|
|
@@ -490,11 +535,14 @@ export class CredentialSession implements SessionManager {
|
|
|
490
535
|
* when the PDSes are operated by a single org.)
|
|
491
536
|
*/
|
|
492
537
|
private _updateApiEndpoint(didDoc: unknown) {
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
this.pdsUrl =
|
|
538
|
+
const endpoint = isValidDidDoc(didDoc) ? getPdsEndpoint(didDoc) : undefined
|
|
539
|
+
if (endpoint) {
|
|
540
|
+
this.pdsUrl = new URL(endpoint)
|
|
496
541
|
} else {
|
|
497
|
-
// If the did doc is invalid, we clear the pdsUrl (should
|
|
542
|
+
// If the did doc is invalid (or missing), we clear the pdsUrl (should
|
|
543
|
+
// never happen). This is fine if the auth server and PDS are the same
|
|
544
|
+
// service, or if the auth server will proxy requests to the right PDS
|
|
545
|
+
// (which is the case for Bluesky's "entryway").
|
|
498
546
|
this.pdsUrl = undefined
|
|
499
547
|
}
|
|
500
548
|
}
|
package/src/client/index.ts
CHANGED
|
@@ -4528,12 +4528,11 @@ export class ComAtprotoServerNS {
|
|
|
4528
4528
|
data?: ComAtprotoServerDeleteSession.InputSchema,
|
|
4529
4529
|
opts?: ComAtprotoServerDeleteSession.CallOptions,
|
|
4530
4530
|
): Promise<ComAtprotoServerDeleteSession.Response> {
|
|
4531
|
-
return this._client
|
|
4532
|
-
'com.atproto.server.deleteSession',
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
)
|
|
4531
|
+
return this._client
|
|
4532
|
+
.call('com.atproto.server.deleteSession', opts?.qp, data, opts)
|
|
4533
|
+
.catch((e) => {
|
|
4534
|
+
throw ComAtprotoServerDeleteSession.toKnownErr(e)
|
|
4535
|
+
})
|
|
4537
4536
|
}
|
|
4538
4537
|
|
|
4539
4538
|
describeServer(
|