@atproto/xrpc-server 0.10.13 → 0.10.15
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 +23 -0
- package/dist/auth.d.ts +3 -2
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +18 -0
- package/dist/auth.js.map +1 -1
- package/dist/errors.d.ts +7 -14
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +19 -6
- package/dist/errors.js.map +1 -1
- package/dist/server.d.ts +27 -11
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +115 -78
- package/dist/server.js.map +1 -1
- package/dist/stream/frames.d.ts +5 -1
- package/dist/stream/frames.d.ts.map +1 -1
- package/dist/stream/frames.js +32 -5
- package/dist/stream/frames.js.map +1 -1
- package/dist/stream/types.d.ts +18 -44
- package/dist/stream/types.d.ts.map +1 -1
- package/dist/stream/types.js +10 -10
- package/dist/stream/types.js.map +1 -1
- package/dist/types.d.ts +47 -70
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +28 -15
- package/dist/types.js.map +1 -1
- package/dist/util.d.ts +18 -9
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +180 -37
- package/dist/util.js.map +1 -1
- package/package.json +12 -8
- package/src/auth.ts +28 -2
- package/src/errors.ts +23 -7
- package/src/server.ts +307 -111
- package/src/stream/frames.ts +39 -6
- package/src/stream/types.ts +14 -14
- package/src/types.ts +106 -25
- package/src/util.ts +272 -60
- package/tests/_util.ts +62 -5
- package/tests/bodies.test.ts +442 -387
- package/tests/procedures.test.ts +71 -52
- package/tests/queries.test.ts +56 -39
- package/tests/subscriptions.test.ts +234 -221
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @atproto/xrpc-server
|
|
2
2
|
|
|
3
|
+
## 0.10.15
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#4691](https://github.com/bluesky-social/atproto/pull/4691) [`e8969b6`](https://github.com/bluesky-social/atproto/commit/e8969b6b3d3fed8912be53fd72b4d5288ca34766) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add support for method defined through `@atproto/lex` in addition to `@atproto/lexicon` "codegen"
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`52834ab`](https://github.com/bluesky-social/atproto/commit/52834aba182da8df3611fd9dff924e6c6a3973a7), [`f7c2610`](https://github.com/bluesky-social/atproto/commit/f7c26103a6d4e24e5bedbb6fd908be140420e0dd), [`f7c2610`](https://github.com/bluesky-social/atproto/commit/f7c26103a6d4e24e5bedbb6fd908be140420e0dd), [`52834ab`](https://github.com/bluesky-social/atproto/commit/52834aba182da8df3611fd9dff924e6c6a3973a7), [`52834ab`](https://github.com/bluesky-social/atproto/commit/52834aba182da8df3611fd9dff924e6c6a3973a7), [`52834ab`](https://github.com/bluesky-social/atproto/commit/52834aba182da8df3611fd9dff924e6c6a3973a7), [`52834ab`](https://github.com/bluesky-social/atproto/commit/52834aba182da8df3611fd9dff924e6c6a3973a7), [`52834ab`](https://github.com/bluesky-social/atproto/commit/52834aba182da8df3611fd9dff924e6c6a3973a7), [`52834ab`](https://github.com/bluesky-social/atproto/commit/52834aba182da8df3611fd9dff924e6c6a3973a7), [`52834ab`](https://github.com/bluesky-social/atproto/commit/52834aba182da8df3611fd9dff924e6c6a3973a7), [`52834ab`](https://github.com/bluesky-social/atproto/commit/52834aba182da8df3611fd9dff924e6c6a3973a7)]:
|
|
10
|
+
- @atproto/lex-schema@0.0.14
|
|
11
|
+
- @atproto/common@0.5.14
|
|
12
|
+
- @atproto/lex-data@0.0.13
|
|
13
|
+
- @atproto/lex-client@0.0.15
|
|
14
|
+
- @atproto/lexicon@0.6.2
|
|
15
|
+
- @atproto/lex-cbor@0.0.14
|
|
16
|
+
- @atproto/lex-json@0.0.13
|
|
17
|
+
|
|
18
|
+
## 0.10.14
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- Updated dependencies [[`66b7295`](https://github.com/bluesky-social/atproto/commit/66b72950e8bcb39cac3382116bd282b3bb692f16)]:
|
|
23
|
+
- @atproto/lex-cbor@0.0.13
|
|
24
|
+
- @atproto/common@0.5.13
|
|
25
|
+
|
|
3
26
|
## 0.10.13
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
package/dist/auth.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as crypto from '@atproto/crypto';
|
|
2
|
+
import { DidString } from '@atproto/lex-schema';
|
|
2
3
|
type ServiceJwtParams = {
|
|
3
4
|
iss: string;
|
|
4
5
|
aud: string;
|
|
@@ -8,7 +9,7 @@ type ServiceJwtParams = {
|
|
|
8
9
|
keypair: crypto.Keypair;
|
|
9
10
|
};
|
|
10
11
|
type ServiceJwtPayload = {
|
|
11
|
-
iss: string
|
|
12
|
+
iss: DidString | `${DidString}#${string}`;
|
|
12
13
|
aud: string;
|
|
13
14
|
exp: number;
|
|
14
15
|
lxm?: string;
|
|
@@ -23,7 +24,7 @@ export declare const createServiceAuthHeaders: (params: ServiceJwtParams) => Pro
|
|
|
23
24
|
export type VerifySignatureWithKeyFn = (key: string, msgBytes: Uint8Array, sigBytes: Uint8Array, alg: string) => Promise<boolean>;
|
|
24
25
|
export declare const verifyJwt: (jwtStr: string, ownDid: string | null, // null indicates to skip the audience check
|
|
25
26
|
lxm: string | null, // null indicates to skip the lxm check
|
|
26
|
-
getSigningKey: (iss: string
|
|
27
|
+
getSigningKey: (iss: DidString | `${DidString}#${string}`, forceRefresh: boolean) => Promise<string>, verifySignatureWithKey?: VerifySignatureWithKeyFn) => Promise<ServiceJwtPayload>;
|
|
27
28
|
export declare const cryptoVerifySignatureWithKey: VerifySignatureWithKeyFn;
|
|
28
29
|
export {};
|
|
29
30
|
//# sourceMappingURL=auth.d.ts.map
|
package/dist/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAA;AACzC,OAAO,EAAE,SAAS,EAAe,MAAM,qBAAqB,CAAA;AAG5D,KAAK,gBAAgB,GAAG;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,OAAO,EAAE,MAAM,CAAC,OAAO,CAAA;CACxB,CAAA;AAMD,KAAK,iBAAiB,GAAG;IACvB,GAAG,EAAE,SAAS,GAAG,GAAG,SAAS,IAAI,MAAM,EAAE,CAAA;IACzC,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;CACb,CAAA;AAED,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,gBAAgB,KACvB,OAAO,CAAC,MAAM,CAsBhB,CAAA;AAED,eAAO,MAAM,wBAAwB,GAAU,QAAQ,gBAAgB;;;;EAKtE,CAAA;AAMD,MAAM,MAAM,wBAAwB,GAAG,CACrC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,UAAU,EACpB,QAAQ,EAAE,UAAU,EACpB,GAAG,EAAE,MAAM,KACR,OAAO,CAAC,OAAO,CAAC,CAAA;AAErB,eAAO,MAAM,SAAS,GACpB,QAAQ,MAAM,EACd,QAAQ,MAAM,GAAG,IAAI,EAAE,4CAA4C;AACnE,KAAK,MAAM,GAAG,IAAI,EAAE,uCAAuC;AAC3D,eAAe,CACb,GAAG,EAAE,SAAS,GAAG,GAAG,SAAS,IAAI,MAAM,EAAE,EACzC,YAAY,EAAE,OAAO,KAClB,OAAO,CAAC,MAAM,CAAC,EACpB,yBAAwB,wBAAuD,KAC9E,OAAO,CAAC,iBAAiB,CA+F3B,CAAA;AAED,eAAO,MAAM,4BAA4B,EAAE,wBAU1C,CAAA"}
|
package/dist/auth.js
CHANGED
|
@@ -37,6 +37,7 @@ exports.cryptoVerifySignatureWithKey = exports.verifyJwt = exports.createService
|
|
|
37
37
|
const common = __importStar(require("@atproto/common"));
|
|
38
38
|
const common_1 = require("@atproto/common");
|
|
39
39
|
const crypto = __importStar(require("@atproto/crypto"));
|
|
40
|
+
const lex_schema_1 = require("@atproto/lex-schema");
|
|
40
41
|
const errors_1 = require("./errors");
|
|
41
42
|
const createServiceJwt = async (params) => {
|
|
42
43
|
const { iss, aud, keypair } = params;
|
|
@@ -106,6 +107,9 @@ getSigningKey, verifySignatureWithKey = exports.cryptoVerifySignatureWithKey) =>
|
|
|
106
107
|
? `bad jwt lexicon method ("lxm"). must match: ${lxm}`
|
|
107
108
|
: `missing jwt lexicon method ("lxm"). must match: ${lxm}`, 'BadJwtLexiconMethod');
|
|
108
109
|
}
|
|
110
|
+
if (!payload.iss || !isDidStringOrService(payload.iss)) {
|
|
111
|
+
throw new errors_1.AuthRequiredError('jwt iss is not a valid did', 'BadJwtIss');
|
|
112
|
+
}
|
|
109
113
|
const msgBytes = Buffer.from(parts.slice(0, 2).join('.'), 'utf8');
|
|
110
114
|
const sigBytes = Buffer.from(sig, 'base64url');
|
|
111
115
|
const signingKey = await getSigningKey(payload.iss, false);
|
|
@@ -166,4 +170,18 @@ const parsePayload = (b64) => {
|
|
|
166
170
|
}
|
|
167
171
|
return payload;
|
|
168
172
|
};
|
|
173
|
+
function isDidStringOrService(value) {
|
|
174
|
+
const hashIdx = value.indexOf('#');
|
|
175
|
+
if (hashIdx === -1) {
|
|
176
|
+
return (0, lex_schema_1.isDidString)(value);
|
|
177
|
+
}
|
|
178
|
+
// basic validation of the fragment part
|
|
179
|
+
const fragmentLen = value.length - hashIdx - 1;
|
|
180
|
+
if (fragmentLen < 1 || value.includes('#', hashIdx + 1)) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
// Validate the did part
|
|
184
|
+
const didPart = value.slice(0, hashIdx);
|
|
185
|
+
return (0, lex_schema_1.isDidString)(didPart);
|
|
186
|
+
}
|
|
169
187
|
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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","sourcesContent":["import * as common from '@atproto/common'\nimport { MINUTE } from '@atproto/common'\nimport * as crypto from '@atproto/crypto'\nimport { AuthRequiredError } from './errors'\n\ntype ServiceJwtParams = {\n iss: string\n aud: string\n iat?: number\n exp?: number\n lxm: string | null\n keypair: crypto.Keypair\n}\n\ntype ServiceJwtHeaders = {\n alg: string\n} & Record<string, unknown>\n\ntype ServiceJwtPayload = {\n iss: string\n aud: string\n exp: number\n lxm?: string\n jti?: string\n}\n\nexport const createServiceJwt = async (\n params: ServiceJwtParams,\n): Promise<string> => {\n const { iss, aud, keypair } = params\n const iat = params.iat ?? Math.floor(Date.now() / 1e3)\n const exp = params.exp ?? iat + MINUTE / 1e3\n const lxm = params.lxm ?? undefined\n const jti = await crypto.randomStr(16, 'hex')\n const header = {\n typ: 'JWT',\n alg: keypair.jwtAlg,\n }\n const payload = common.noUndefinedVals({\n iat,\n iss,\n aud,\n exp,\n lxm,\n jti,\n })\n const toSignStr = `${jsonToB64Url(header)}.${jsonToB64Url(payload)}`\n const toSign = Buffer.from(toSignStr, 'utf8')\n const sig = Buffer.from(await keypair.sign(toSign))\n return `${toSignStr}.${sig.toString('base64url')}`\n}\n\nexport const createServiceAuthHeaders = async (params: ServiceJwtParams) => {\n const jwt = await createServiceJwt(params)\n return {\n headers: { authorization: `Bearer ${jwt}` },\n }\n}\n\nconst jsonToB64Url = (json: Record<string, unknown>): string => {\n return Buffer.from(JSON.stringify(json)).toString('base64url')\n}\n\nexport type VerifySignatureWithKeyFn = (\n key: string,\n msgBytes: Uint8Array,\n sigBytes: Uint8Array,\n alg: string,\n) => Promise<boolean>\n\nexport const verifyJwt = async (\n jwtStr: string,\n ownDid: string | null, // null indicates to skip the audience check\n lxm: string | null, // null indicates to skip the lxm check\n getSigningKey: (iss: string, forceRefresh: boolean) => Promise<string>,\n verifySignatureWithKey: VerifySignatureWithKeyFn = cryptoVerifySignatureWithKey,\n): Promise<ServiceJwtPayload> => {\n const parts = jwtStr.split('.')\n if (parts.length !== 3) {\n throw new AuthRequiredError('poorly formatted jwt', 'BadJwt')\n }\n\n const header = parseHeader(parts[0])\n\n // The spec does not describe what to do with the \"typ\" claim. We can,\n // however, forbid some values that are not compatible with our use case.\n if (\n // service tokens are not OAuth 2.0 access tokens\n // https://datatracker.ietf.org/doc/html/rfc9068\n header['typ'] === 'at+jwt' ||\n // \"refresh+jwt\" is a non-standard type used by the @atproto packages\n header['typ'] === 'refresh+jwt' ||\n // \"DPoP\" proofs are not meant to be used as service tokens\n // https://datatracker.ietf.org/doc/html/rfc9449\n header['typ'] === 'dpop+jwt'\n ) {\n throw new AuthRequiredError(\n `Invalid jwt type \"${header['typ']}\"`,\n 'BadJwtType',\n )\n }\n\n const payload = parsePayload(parts[1])\n const sig = parts[2]\n\n if (Date.now() / 1000 > payload.exp) {\n throw new AuthRequiredError('jwt expired', 'JwtExpired')\n }\n if (ownDid !== null && payload.aud !== ownDid) {\n throw new AuthRequiredError(\n 'jwt audience does not match service did',\n 'BadJwtAudience',\n )\n }\n if (lxm !== null && payload.lxm !== lxm) {\n throw new AuthRequiredError(\n payload.lxm !== undefined\n ? `bad jwt lexicon method (\"lxm\"). must match: ${lxm}`\n : `missing jwt lexicon method (\"lxm\"). must match: ${lxm}`,\n 'BadJwtLexiconMethod',\n )\n }\n\n const msgBytes = Buffer.from(parts.slice(0, 2).join('.'), 'utf8')\n const sigBytes = Buffer.from(sig, 'base64url')\n\n const signingKey = await getSigningKey(payload.iss, false)\n const { alg } = header\n\n let validSig: boolean\n try {\n validSig = await verifySignatureWithKey(signingKey, msgBytes, sigBytes, alg)\n } catch (err) {\n throw new AuthRequiredError(\n 'could not verify jwt signature',\n 'BadJwtSignature',\n )\n }\n\n if (!validSig) {\n // get fresh signing key in case it failed due to a recent rotation\n const freshSigningKey = await getSigningKey(payload.iss, true)\n try {\n validSig =\n freshSigningKey !== signingKey\n ? await verifySignatureWithKey(\n freshSigningKey,\n msgBytes,\n sigBytes,\n alg,\n )\n : false\n } catch (err) {\n throw new AuthRequiredError(\n 'could not verify jwt signature',\n 'BadJwtSignature',\n )\n }\n }\n\n if (!validSig) {\n throw new AuthRequiredError(\n 'jwt signature does not match jwt issuer',\n 'BadJwtSignature',\n )\n }\n\n return payload\n}\n\nexport const cryptoVerifySignatureWithKey: VerifySignatureWithKeyFn = async (\n key: string,\n msgBytes: Uint8Array,\n sigBytes: Uint8Array,\n alg: string,\n) => {\n return crypto.verifySignature(key, msgBytes, sigBytes, {\n jwtAlg: alg,\n allowMalleableSig: true,\n })\n}\n\nconst parseB64UrlToJson = (b64: string) => {\n return JSON.parse(Buffer.from(b64, 'base64url').toString('utf8'))\n}\n\nconst parseHeader = (b64: string): ServiceJwtHeaders => {\n const header = parseB64UrlToJson(b64)\n if (!header || typeof header !== 'object' || typeof header.alg !== 'string') {\n throw new AuthRequiredError('poorly formatted jwt', 'BadJwt')\n }\n return header\n}\n\nconst parsePayload = (b64: string): ServiceJwtPayload => {\n const payload = parseB64UrlToJson(b64)\n if (\n !payload ||\n typeof payload !== 'object' ||\n typeof payload.iss !== 'string' ||\n typeof payload.aud !== 'string' ||\n typeof payload.exp !== 'number' ||\n (payload.lxm && typeof payload.lxm !== 'string') ||\n (payload.nonce && typeof payload.nonce !== 'string')\n ) {\n throw new AuthRequiredError('poorly formatted jwt', 'BadJwt')\n }\n return payload\n}\n"]}
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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","sourcesContent":["import * as common from '@atproto/common'\nimport { MINUTE } from '@atproto/common'\nimport * as crypto from '@atproto/crypto'\nimport { DidString, isDidString } from '@atproto/lex-schema'\nimport { AuthRequiredError } from './errors'\n\ntype ServiceJwtParams = {\n iss: string\n aud: string\n iat?: number\n exp?: number\n lxm: string | null\n keypair: crypto.Keypair\n}\n\ntype ServiceJwtHeaders = {\n alg: string\n} & Record<string, unknown>\n\ntype ServiceJwtPayload = {\n iss: DidString | `${DidString}#${string}`\n aud: string\n exp: number\n lxm?: string\n jti?: string\n}\n\nexport const createServiceJwt = async (\n params: ServiceJwtParams,\n): Promise<string> => {\n const { iss, aud, keypair } = params\n const iat = params.iat ?? Math.floor(Date.now() / 1e3)\n const exp = params.exp ?? iat + MINUTE / 1e3\n const lxm = params.lxm ?? undefined\n const jti = await crypto.randomStr(16, 'hex')\n const header = {\n typ: 'JWT',\n alg: keypair.jwtAlg,\n }\n const payload = common.noUndefinedVals({\n iat,\n iss,\n aud,\n exp,\n lxm,\n jti,\n })\n const toSignStr = `${jsonToB64Url(header)}.${jsonToB64Url(payload)}`\n const toSign = Buffer.from(toSignStr, 'utf8')\n const sig = Buffer.from(await keypair.sign(toSign))\n return `${toSignStr}.${sig.toString('base64url')}`\n}\n\nexport const createServiceAuthHeaders = async (params: ServiceJwtParams) => {\n const jwt = await createServiceJwt(params)\n return {\n headers: { authorization: `Bearer ${jwt}` },\n }\n}\n\nconst jsonToB64Url = (json: Record<string, unknown>): string => {\n return Buffer.from(JSON.stringify(json)).toString('base64url')\n}\n\nexport type VerifySignatureWithKeyFn = (\n key: string,\n msgBytes: Uint8Array,\n sigBytes: Uint8Array,\n alg: string,\n) => Promise<boolean>\n\nexport const verifyJwt = async (\n jwtStr: string,\n ownDid: string | null, // null indicates to skip the audience check\n lxm: string | null, // null indicates to skip the lxm check\n getSigningKey: (\n iss: DidString | `${DidString}#${string}`,\n forceRefresh: boolean,\n ) => Promise<string>,\n verifySignatureWithKey: VerifySignatureWithKeyFn = cryptoVerifySignatureWithKey,\n): Promise<ServiceJwtPayload> => {\n const parts = jwtStr.split('.')\n if (parts.length !== 3) {\n throw new AuthRequiredError('poorly formatted jwt', 'BadJwt')\n }\n\n const header = parseHeader(parts[0])\n\n // The spec does not describe what to do with the \"typ\" claim. We can,\n // however, forbid some values that are not compatible with our use case.\n if (\n // service tokens are not OAuth 2.0 access tokens\n // https://datatracker.ietf.org/doc/html/rfc9068\n header['typ'] === 'at+jwt' ||\n // \"refresh+jwt\" is a non-standard type used by the @atproto packages\n header['typ'] === 'refresh+jwt' ||\n // \"DPoP\" proofs are not meant to be used as service tokens\n // https://datatracker.ietf.org/doc/html/rfc9449\n header['typ'] === 'dpop+jwt'\n ) {\n throw new AuthRequiredError(\n `Invalid jwt type \"${header['typ']}\"`,\n 'BadJwtType',\n )\n }\n\n const payload = parsePayload(parts[1])\n const sig = parts[2]\n\n if (Date.now() / 1000 > payload.exp) {\n throw new AuthRequiredError('jwt expired', 'JwtExpired')\n }\n if (ownDid !== null && payload.aud !== ownDid) {\n throw new AuthRequiredError(\n 'jwt audience does not match service did',\n 'BadJwtAudience',\n )\n }\n if (lxm !== null && payload.lxm !== lxm) {\n throw new AuthRequiredError(\n payload.lxm !== undefined\n ? `bad jwt lexicon method (\"lxm\"). must match: ${lxm}`\n : `missing jwt lexicon method (\"lxm\"). must match: ${lxm}`,\n 'BadJwtLexiconMethod',\n )\n }\n if (!payload.iss || !isDidStringOrService(payload.iss)) {\n throw new AuthRequiredError('jwt iss is not a valid did', 'BadJwtIss')\n }\n\n const msgBytes = Buffer.from(parts.slice(0, 2).join('.'), 'utf8')\n const sigBytes = Buffer.from(sig, 'base64url')\n\n const signingKey = await getSigningKey(payload.iss, false)\n const { alg } = header\n\n let validSig: boolean\n try {\n validSig = await verifySignatureWithKey(signingKey, msgBytes, sigBytes, alg)\n } catch (err) {\n throw new AuthRequiredError(\n 'could not verify jwt signature',\n 'BadJwtSignature',\n )\n }\n\n if (!validSig) {\n // get fresh signing key in case it failed due to a recent rotation\n const freshSigningKey = await getSigningKey(payload.iss, true)\n try {\n validSig =\n freshSigningKey !== signingKey\n ? await verifySignatureWithKey(\n freshSigningKey,\n msgBytes,\n sigBytes,\n alg,\n )\n : false\n } catch (err) {\n throw new AuthRequiredError(\n 'could not verify jwt signature',\n 'BadJwtSignature',\n )\n }\n }\n\n if (!validSig) {\n throw new AuthRequiredError(\n 'jwt signature does not match jwt issuer',\n 'BadJwtSignature',\n )\n }\n\n return payload\n}\n\nexport const cryptoVerifySignatureWithKey: VerifySignatureWithKeyFn = async (\n key: string,\n msgBytes: Uint8Array,\n sigBytes: Uint8Array,\n alg: string,\n) => {\n return crypto.verifySignature(key, msgBytes, sigBytes, {\n jwtAlg: alg,\n allowMalleableSig: true,\n })\n}\n\nconst parseB64UrlToJson = (b64: string) => {\n return JSON.parse(Buffer.from(b64, 'base64url').toString('utf8'))\n}\n\nconst parseHeader = (b64: string): ServiceJwtHeaders => {\n const header = parseB64UrlToJson(b64)\n if (!header || typeof header !== 'object' || typeof header.alg !== 'string') {\n throw new AuthRequiredError('poorly formatted jwt', 'BadJwt')\n }\n return header\n}\n\nconst parsePayload = (b64: string): ServiceJwtPayload => {\n const payload = parseB64UrlToJson(b64)\n if (\n !payload ||\n typeof payload !== 'object' ||\n typeof payload.iss !== 'string' ||\n typeof payload.aud !== 'string' ||\n typeof payload.exp !== 'number' ||\n (payload.lxm && typeof payload.lxm !== 'string') ||\n (payload.nonce && typeof payload.nonce !== 'string')\n ) {\n throw new AuthRequiredError('poorly formatted jwt', 'BadJwt')\n }\n return payload\n}\n\nfunction isDidStringOrService(\n value: string,\n): value is DidString | `${DidString}#${string}` {\n const hashIdx = value.indexOf('#')\n if (hashIdx === -1) {\n return isDidString(value)\n }\n\n // basic validation of the fragment part\n const fragmentLen = value.length - hashIdx - 1\n if (fragmentLen < 1 || value.includes('#', hashIdx + 1)) {\n return false\n }\n\n // Validate the did part\n const didPart = value.slice(0, hashIdx)\n return isDidString(didPart)\n}\n"]}
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,19 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { l } from '@atproto/lex-schema';
|
|
2
2
|
import { ResponseType } from '@atproto/xrpc';
|
|
3
|
-
export declare const errorResult:
|
|
4
|
-
status:
|
|
5
|
-
error:
|
|
6
|
-
message:
|
|
7
|
-
}, "strip", z.ZodTypeAny, {
|
|
8
|
-
status: number;
|
|
9
|
-
error?: string | undefined;
|
|
10
|
-
message?: string | undefined;
|
|
11
|
-
}, {
|
|
12
|
-
status: number;
|
|
13
|
-
error?: string | undefined;
|
|
14
|
-
message?: string | undefined;
|
|
3
|
+
export declare const errorResult: l.ObjectSchema<{
|
|
4
|
+
readonly status: l.IntegerSchema;
|
|
5
|
+
readonly error: l.OptionalSchema<l.StringSchema<{}>>;
|
|
6
|
+
readonly message: l.OptionalSchema<l.StringSchema<{}>>;
|
|
15
7
|
}>;
|
|
16
|
-
export type ErrorResult =
|
|
8
|
+
export type ErrorResult = l.Infer<typeof errorResult>;
|
|
17
9
|
export declare function isErrorResult(v: unknown): v is ErrorResult;
|
|
18
10
|
export declare function excludeErrorResult<V>(v: V): Exclude<V, ErrorResult>;
|
|
19
11
|
export { ResponseType };
|
|
@@ -23,6 +15,7 @@ export declare class XRPCError extends Error {
|
|
|
23
15
|
customErrorName?: string | undefined;
|
|
24
16
|
constructor(type: ResponseType, errorMessage?: string | undefined, customErrorName?: string | undefined, options?: ErrorOptions);
|
|
25
17
|
get statusCode(): number;
|
|
18
|
+
get error(): string | undefined;
|
|
26
19
|
get payload(): {
|
|
27
20
|
error: string | undefined;
|
|
28
21
|
message: string | undefined;
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.js
CHANGED
|
@@ -4,15 +4,16 @@ exports.MethodNotImplementedError = exports.UpstreamTimeoutError = exports.NotEn
|
|
|
4
4
|
exports.isErrorResult = isErrorResult;
|
|
5
5
|
exports.excludeErrorResult = excludeErrorResult;
|
|
6
6
|
const http_errors_1 = require("http-errors");
|
|
7
|
-
const
|
|
7
|
+
const lex_client_1 = require("@atproto/lex-client");
|
|
8
|
+
const lex_schema_1 = require("@atproto/lex-schema");
|
|
8
9
|
const xrpc_1 = require("@atproto/xrpc");
|
|
9
10
|
Object.defineProperty(exports, "ResponseType", { enumerable: true, get: function () { return xrpc_1.ResponseType; } });
|
|
10
11
|
// @NOTE Do not depend (directly or indirectly) on "./types" here, as it would
|
|
11
12
|
// create a circular dependency.
|
|
12
|
-
exports.errorResult =
|
|
13
|
-
status:
|
|
14
|
-
error:
|
|
15
|
-
message:
|
|
13
|
+
exports.errorResult = lex_schema_1.l.object({
|
|
14
|
+
status: lex_schema_1.l.integer({ minimum: 400 }),
|
|
15
|
+
error: lex_schema_1.l.optional(lex_schema_1.l.string()),
|
|
16
|
+
message: lex_schema_1.l.optional(lex_schema_1.l.string()),
|
|
16
17
|
});
|
|
17
18
|
function isErrorResult(v) {
|
|
18
19
|
return exports.errorResult.safeParse(v).success;
|
|
@@ -54,9 +55,12 @@ class XRPCError extends Error {
|
|
|
54
55
|
}
|
|
55
56
|
return type;
|
|
56
57
|
}
|
|
58
|
+
get error() {
|
|
59
|
+
return this.customErrorName ?? this.typeName;
|
|
60
|
+
}
|
|
57
61
|
get payload() {
|
|
58
62
|
return {
|
|
59
|
-
error: this.
|
|
63
|
+
error: this.error,
|
|
60
64
|
message: this.type === xrpc_1.ResponseType.InternalServerError
|
|
61
65
|
? this.typeStr // Do not respond with error details for 500s
|
|
62
66
|
: this.errorMessage || this.typeStr,
|
|
@@ -76,6 +80,15 @@ class XRPCError extends Error {
|
|
|
76
80
|
const { error, message, type } = mapFromClientError(cause);
|
|
77
81
|
return new XRPCError(type, message, error, { cause });
|
|
78
82
|
}
|
|
83
|
+
if (cause instanceof lex_client_1.XrpcError) {
|
|
84
|
+
const { status, body } = cause.toDownstreamError();
|
|
85
|
+
return new XRPCError(status, body.message, body.error, { cause });
|
|
86
|
+
}
|
|
87
|
+
if (cause instanceof lex_client_1.LexError) {
|
|
88
|
+
const data = cause.toJSON();
|
|
89
|
+
const type = xrpc_1.ResponseType.InternalServerError;
|
|
90
|
+
return new XRPCError(type, data.message, data.error, { cause });
|
|
91
|
+
}
|
|
79
92
|
if ((0, http_errors_1.isHttpError)(cause)) {
|
|
80
93
|
return new XRPCError(cause.status, cause.message, cause.name, { cause });
|
|
81
94
|
}
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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","sourcesContent":["import { isHttpError } from 'http-errors'\nimport { z } from 'zod'\nimport {\n ResponseType,\n ResponseTypeStrings,\n XRPCError as XRPCClientError,\n httpResponseCodeToName,\n httpResponseCodeToString,\n} from '@atproto/xrpc'\n\n// @NOTE Do not depend (directly or indirectly) on \"./types\" here, as it would\n// create a circular dependency.\n\nexport const errorResult = z.object({\n status: z.number(),\n error: z.string().optional(),\n message: z.string().optional(),\n})\nexport type ErrorResult = z.infer<typeof errorResult>\n\nexport function isErrorResult(v: unknown): v is ErrorResult {\n return errorResult.safeParse(v).success\n}\n\nexport function excludeErrorResult<V>(v: V) {\n if (isErrorResult(v)) throw XRPCError.fromErrorResult(v)\n return v as Exclude<V, ErrorResult>\n}\n\nexport { ResponseType }\n\nexport class XRPCError extends Error {\n constructor(\n public type: ResponseType,\n public errorMessage?: string,\n public customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(errorMessage, options)\n }\n\n get statusCode(): number {\n const { type } = this\n\n // Fool-proofing. `new XRPCError(123.5 as number, '')` does not generate a TypeScript error.\n // Because of this, we can end-up with any numeric value instead of an actual `ResponseType`.\n // For legacy reasons, the `type` argument is not checked in the constructor, so we check it here.\n if (type < 400 || type >= 600 || !Number.isFinite(type)) {\n return 500\n }\n\n return type\n }\n\n get payload() {\n return {\n error: this.customErrorName ?? this.typeName,\n message:\n this.type === ResponseType.InternalServerError\n ? this.typeStr // Do not respond with error details for 500s\n : this.errorMessage || this.typeStr,\n }\n }\n\n get typeName(): string | undefined {\n return ResponseType[this.type]\n }\n\n get typeStr(): string | undefined {\n return ResponseTypeStrings[this.type]\n }\n\n static fromError(cause: unknown): XRPCError {\n if (cause instanceof XRPCError) {\n return cause\n }\n\n if (cause instanceof XRPCClientError) {\n const { error, message, type } = mapFromClientError(cause)\n return new XRPCError(type, message, error, { cause })\n }\n\n if (isHttpError(cause)) {\n return new XRPCError(cause.status, cause.message, cause.name, { cause })\n }\n\n if (isErrorResult(cause)) {\n return this.fromErrorResult(cause)\n }\n\n if (cause instanceof Error) {\n return new InternalServerError(cause.message, undefined, { cause })\n }\n\n return new InternalServerError(\n 'Unexpected internal server error',\n undefined,\n { cause },\n )\n }\n\n static fromErrorResult(err: ErrorResult): XRPCError {\n return new XRPCError(err.status, err.message, err.error, { cause: err })\n }\n}\n\nexport class InvalidRequestError extends XRPCError {\n constructor(\n errorMessage?: string,\n customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(ResponseType.InvalidRequest, errorMessage, customErrorName, options)\n }\n\n [Symbol.hasInstance](instance: unknown): boolean {\n return (\n instance instanceof XRPCError &&\n instance.type === ResponseType.InvalidRequest\n )\n }\n}\n\nexport class AuthRequiredError extends XRPCError {\n constructor(\n errorMessage?: string,\n customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(\n ResponseType.AuthenticationRequired,\n errorMessage,\n customErrorName,\n options,\n )\n }\n\n [Symbol.hasInstance](instance: unknown): boolean {\n return (\n instance instanceof XRPCError &&\n instance.type === ResponseType.AuthenticationRequired\n )\n }\n}\n\nexport class ForbiddenError extends XRPCError {\n constructor(\n errorMessage?: string,\n customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(ResponseType.Forbidden, errorMessage, customErrorName, options)\n }\n\n [Symbol.hasInstance](instance: unknown): boolean {\n return (\n instance instanceof XRPCError && instance.type === ResponseType.Forbidden\n )\n }\n}\n\nexport class InternalServerError extends XRPCError {\n constructor(\n errorMessage?: string,\n customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(\n ResponseType.InternalServerError,\n errorMessage,\n customErrorName,\n options,\n )\n }\n\n [Symbol.hasInstance](instance: unknown): boolean {\n return (\n instance instanceof XRPCError &&\n instance.type === ResponseType.InternalServerError\n )\n }\n}\n\nexport class UpstreamFailureError extends XRPCError {\n constructor(\n errorMessage?: string,\n customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(ResponseType.UpstreamFailure, errorMessage, customErrorName, options)\n }\n\n [Symbol.hasInstance](instance: unknown): boolean {\n return (\n instance instanceof XRPCError &&\n instance.type === ResponseType.UpstreamFailure\n )\n }\n}\n\nexport class NotEnoughResourcesError extends XRPCError {\n constructor(\n errorMessage?: string,\n customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(\n ResponseType.NotEnoughResources,\n errorMessage,\n customErrorName,\n options,\n )\n }\n\n [Symbol.hasInstance](instance: unknown): boolean {\n return (\n instance instanceof XRPCError &&\n instance.type === ResponseType.NotEnoughResources\n )\n }\n}\n\nexport class UpstreamTimeoutError extends XRPCError {\n constructor(\n errorMessage?: string,\n customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(ResponseType.UpstreamTimeout, errorMessage, customErrorName, options)\n }\n\n [Symbol.hasInstance](instance: unknown): boolean {\n return (\n instance instanceof XRPCError &&\n instance.type === ResponseType.UpstreamTimeout\n )\n }\n}\n\nexport class MethodNotImplementedError extends XRPCError {\n constructor(\n errorMessage?: string,\n customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(\n ResponseType.MethodNotImplemented,\n errorMessage,\n customErrorName,\n options,\n )\n }\n\n [Symbol.hasInstance](instance: unknown): boolean {\n return (\n instance instanceof XRPCError &&\n instance.type === ResponseType.MethodNotImplemented\n )\n }\n}\n\n/**\n * Converts an upstream XRPC {@link ResponseType} into a downstream {@link ResponseType}.\n */\nfunction mapFromClientError(error: XRPCClientError): {\n error: string\n message: string\n type: ResponseType\n} {\n switch (error.status) {\n case ResponseType.InvalidResponse:\n // Upstream server returned an XRPC response that is not compatible with our internal lexicon definitions for that XRPC method.\n // @NOTE This could be reflected as both a 500 (\"we\" are at fault) and 502 (\"they\" are at fault). Let's be gents about it.\n return {\n error: httpResponseCodeToName(ResponseType.InternalServerError),\n message: httpResponseCodeToString(ResponseType.InternalServerError),\n type: ResponseType.InternalServerError,\n }\n case ResponseType.Unknown:\n // Typically a network error / unknown host\n return {\n error: httpResponseCodeToName(ResponseType.InternalServerError),\n message: httpResponseCodeToString(ResponseType.InternalServerError),\n type: ResponseType.InternalServerError,\n }\n default:\n return {\n error: error.error,\n message: error.message,\n type: error.status,\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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","sourcesContent":["import { isHttpError } from 'http-errors'\nimport { LexError, XrpcError } from '@atproto/lex-client'\nimport { l } from '@atproto/lex-schema'\nimport {\n ResponseType,\n ResponseTypeStrings,\n XRPCError as XRPCClientError,\n httpResponseCodeToName,\n httpResponseCodeToString,\n} from '@atproto/xrpc'\n\n// @NOTE Do not depend (directly or indirectly) on \"./types\" here, as it would\n// create a circular dependency.\n\nexport const errorResult = l.object({\n status: l.integer({ minimum: 400 }),\n error: l.optional(l.string()),\n message: l.optional(l.string()),\n})\nexport type ErrorResult = l.Infer<typeof errorResult>\n\nexport function isErrorResult(v: unknown): v is ErrorResult {\n return errorResult.safeParse(v).success\n}\n\nexport function excludeErrorResult<V>(v: V) {\n if (isErrorResult(v)) throw XRPCError.fromErrorResult(v)\n return v as Exclude<V, ErrorResult>\n}\n\nexport { ResponseType }\n\nexport class XRPCError extends Error {\n constructor(\n public type: ResponseType,\n public errorMessage?: string,\n public customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(errorMessage, options)\n }\n\n get statusCode(): number {\n const { type } = this\n\n // Fool-proofing. `new XRPCError(123.5 as number, '')` does not generate a TypeScript error.\n // Because of this, we can end-up with any numeric value instead of an actual `ResponseType`.\n // For legacy reasons, the `type` argument is not checked in the constructor, so we check it here.\n if (type < 400 || type >= 600 || !Number.isFinite(type)) {\n return 500\n }\n\n return type\n }\n\n get error(): string | undefined {\n return this.customErrorName ?? this.typeName\n }\n\n get payload() {\n return {\n error: this.error,\n message:\n this.type === ResponseType.InternalServerError\n ? this.typeStr // Do not respond with error details for 500s\n : this.errorMessage || this.typeStr,\n }\n }\n\n get typeName(): string | undefined {\n return ResponseType[this.type]\n }\n\n get typeStr(): string | undefined {\n return ResponseTypeStrings[this.type]\n }\n\n static fromError(cause: unknown): XRPCError {\n if (cause instanceof XRPCError) {\n return cause\n }\n\n if (cause instanceof XRPCClientError) {\n const { error, message, type } = mapFromClientError(cause)\n return new XRPCError(type, message, error, { cause })\n }\n\n if (cause instanceof XrpcError) {\n const { status, body } = cause.toDownstreamError()\n return new XRPCError(status, body.message, body.error, { cause })\n }\n\n if (cause instanceof LexError) {\n const data = cause.toJSON()\n const type = ResponseType.InternalServerError\n return new XRPCError(type, data.message, data.error, { cause })\n }\n\n if (isHttpError(cause)) {\n return new XRPCError(cause.status, cause.message, cause.name, { cause })\n }\n\n if (isErrorResult(cause)) {\n return this.fromErrorResult(cause)\n }\n\n if (cause instanceof Error) {\n return new InternalServerError(cause.message, undefined, { cause })\n }\n\n return new InternalServerError(\n 'Unexpected internal server error',\n undefined,\n { cause },\n )\n }\n\n static fromErrorResult(err: ErrorResult): XRPCError {\n return new XRPCError(err.status, err.message, err.error, { cause: err })\n }\n}\n\nexport class InvalidRequestError extends XRPCError {\n constructor(\n errorMessage?: string,\n customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(ResponseType.InvalidRequest, errorMessage, customErrorName, options)\n }\n\n [Symbol.hasInstance](instance: unknown): boolean {\n return (\n instance instanceof XRPCError &&\n instance.type === ResponseType.InvalidRequest\n )\n }\n}\n\nexport class AuthRequiredError extends XRPCError {\n constructor(\n errorMessage?: string,\n customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(\n ResponseType.AuthenticationRequired,\n errorMessage,\n customErrorName,\n options,\n )\n }\n\n [Symbol.hasInstance](instance: unknown): boolean {\n return (\n instance instanceof XRPCError &&\n instance.type === ResponseType.AuthenticationRequired\n )\n }\n}\n\nexport class ForbiddenError extends XRPCError {\n constructor(\n errorMessage?: string,\n customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(ResponseType.Forbidden, errorMessage, customErrorName, options)\n }\n\n [Symbol.hasInstance](instance: unknown): boolean {\n return (\n instance instanceof XRPCError && instance.type === ResponseType.Forbidden\n )\n }\n}\n\nexport class InternalServerError extends XRPCError {\n constructor(\n errorMessage?: string,\n customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(\n ResponseType.InternalServerError,\n errorMessage,\n customErrorName,\n options,\n )\n }\n\n [Symbol.hasInstance](instance: unknown): boolean {\n return (\n instance instanceof XRPCError &&\n instance.type === ResponseType.InternalServerError\n )\n }\n}\n\nexport class UpstreamFailureError extends XRPCError {\n constructor(\n errorMessage?: string,\n customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(ResponseType.UpstreamFailure, errorMessage, customErrorName, options)\n }\n\n [Symbol.hasInstance](instance: unknown): boolean {\n return (\n instance instanceof XRPCError &&\n instance.type === ResponseType.UpstreamFailure\n )\n }\n}\n\nexport class NotEnoughResourcesError extends XRPCError {\n constructor(\n errorMessage?: string,\n customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(\n ResponseType.NotEnoughResources,\n errorMessage,\n customErrorName,\n options,\n )\n }\n\n [Symbol.hasInstance](instance: unknown): boolean {\n return (\n instance instanceof XRPCError &&\n instance.type === ResponseType.NotEnoughResources\n )\n }\n}\n\nexport class UpstreamTimeoutError extends XRPCError {\n constructor(\n errorMessage?: string,\n customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(ResponseType.UpstreamTimeout, errorMessage, customErrorName, options)\n }\n\n [Symbol.hasInstance](instance: unknown): boolean {\n return (\n instance instanceof XRPCError &&\n instance.type === ResponseType.UpstreamTimeout\n )\n }\n}\n\nexport class MethodNotImplementedError extends XRPCError {\n constructor(\n errorMessage?: string,\n customErrorName?: string,\n options?: ErrorOptions,\n ) {\n super(\n ResponseType.MethodNotImplemented,\n errorMessage,\n customErrorName,\n options,\n )\n }\n\n [Symbol.hasInstance](instance: unknown): boolean {\n return (\n instance instanceof XRPCError &&\n instance.type === ResponseType.MethodNotImplemented\n )\n }\n}\n\n/**\n * Converts an upstream XRPC {@link ResponseType} into a downstream {@link ResponseType}.\n */\nfunction mapFromClientError(error: XRPCClientError): {\n error: string\n message: string\n type: ResponseType\n} {\n switch (error.status) {\n case ResponseType.InvalidResponse:\n // Upstream server returned an XRPC response that is not compatible with our internal lexicon definitions for that XRPC method.\n // @NOTE This could be reflected as both a 500 (\"we\" are at fault) and 502 (\"they\" are at fault). Let's be gents about it.\n return {\n error: httpResponseCodeToName(ResponseType.InternalServerError),\n message: httpResponseCodeToString(ResponseType.InternalServerError),\n type: ResponseType.InternalServerError,\n }\n case ResponseType.Unknown:\n // Typically a network error / unknown host\n return {\n error: httpResponseCodeToName(ResponseType.InternalServerError),\n message: httpResponseCodeToString(ResponseType.InternalServerError),\n type: ResponseType.InternalServerError,\n }\n default:\n return {\n error: error.error,\n message: error.message,\n type: error.status,\n }\n }\n}\n"]}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { IncomingMessage } from 'node:http';
|
|
2
|
-
import
|
|
2
|
+
import { Express, RequestHandler, Router } from 'express';
|
|
3
|
+
import { l } from '@atproto/lex-schema';
|
|
3
4
|
import { LexXrpcProcedure, LexXrpcQuery, LexXrpcSubscription, LexiconDoc, Lexicons } from '@atproto/lexicon';
|
|
4
5
|
import { RateLimiterI, RouteRateLimiter } from './rate-limiter';
|
|
5
6
|
import { XrpcStreamServer } from './stream';
|
|
6
|
-
import { Auth, AuthResult,
|
|
7
|
+
import { Auth, AuthResult, CatchallHandler, HandlerContext, Input, LexMethodConfig, LexMethodHandler, LexSubscriptionConfig, LexSubscriptionHandler, MethodAuthContext, MethodConfig, MethodConfigOrHandler, MethodHandler, Options, Output, Params, StreamAuthContext, StreamConfig, StreamConfigOrHandler, StreamContext } from './types';
|
|
8
|
+
import { AuthVerifierInternal, InputVerifierInternal, OutputVerifierInternal, ParamsVerifierInternal } from './util';
|
|
7
9
|
export declare function createServer(lexicons?: LexiconDoc[], options?: Options): Server;
|
|
8
10
|
export declare class Server {
|
|
9
11
|
router: Express;
|
|
@@ -14,21 +16,35 @@ export declare class Server {
|
|
|
14
16
|
globalRateLimiter?: RouteRateLimiter<HandlerContext>;
|
|
15
17
|
sharedRateLimiters?: Map<string, RateLimiterI<HandlerContext>>;
|
|
16
18
|
constructor(lexicons?: LexiconDoc[], opts?: Options);
|
|
19
|
+
listen(port: number, callback?: () => void): import("http").Server<typeof IncomingMessage, typeof import("http").ServerResponse>;
|
|
20
|
+
add<M extends l.Procedure | l.Query | l.Subscription, A extends AuthResult>(ns: l.Main<M>, config: M extends l.Procedure | l.Query ? LexMethodConfig<M, A> & {
|
|
21
|
+
auth: Exclude<unknown, void>;
|
|
22
|
+
} : M extends l.Subscription ? LexSubscriptionConfig<M, A> & {
|
|
23
|
+
auth: Exclude<unknown, void>;
|
|
24
|
+
} : never): void;
|
|
25
|
+
add<M extends l.Procedure | l.Query | l.Subscription>(ns: l.Main<M>, config: M extends l.Procedure | l.Query ? LexMethodConfig<M, void> | LexMethodHandler<M, void> : M extends l.Subscription ? LexSubscriptionConfig<M, void> | LexSubscriptionHandler<M, void> : never): void;
|
|
26
|
+
protected addProcedureSchema<M extends l.Procedure, A extends Auth>(schema: M, config: LexMethodConfig<M, A>): void;
|
|
27
|
+
protected addQuerySchema<M extends l.Query, A extends Auth>(schema: M, config: LexMethodConfig<M, A>): void;
|
|
28
|
+
protected addSubscriptionSchema<M extends l.Subscription, A extends Auth = void>(schema: M, config: LexSubscriptionConfig<M, A>): void;
|
|
17
29
|
method<A extends Auth = Auth>(nsid: string, configOrFn: MethodConfigOrHandler<A>): void;
|
|
18
30
|
addMethod<A extends Auth = Auth>(nsid: string, configOrFn: MethodConfigOrHandler<A>): void;
|
|
19
|
-
streamMethod<A extends Auth = Auth>(nsid: string, configOrFn: StreamConfigOrHandler<A>): void;
|
|
20
|
-
addStreamMethod<A extends Auth = Auth>(nsid: string, configOrFn: StreamConfigOrHandler<A>): void;
|
|
31
|
+
streamMethod<A extends Auth = Auth>(nsid: string, configOrFn: StreamConfigOrHandler<A, Params>): void;
|
|
32
|
+
addStreamMethod<A extends Auth = Auth>(nsid: string, configOrFn: StreamConfigOrHandler<A, Params>): void;
|
|
21
33
|
addLexicon(doc: LexiconDoc): void;
|
|
22
34
|
addLexicons(docs: LexiconDoc[]): void;
|
|
23
35
|
protected addRoute<A extends Auth = Auth>(nsid: string, def: LexXrpcQuery | LexXrpcProcedure, config: MethodConfig<A>): Promise<void>;
|
|
24
36
|
catchall: CatchallHandler;
|
|
25
|
-
|
|
26
|
-
protected
|
|
27
|
-
protected
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
37
|
+
createHandler<A extends Auth = Auth, P extends Params = Params, I extends Input = Input, O extends Output = Output>(nsid: string, def: LexXrpcQuery | LexXrpcProcedure, cfg: MethodConfig<A, P, I, O>): RequestHandler;
|
|
38
|
+
protected createHandlerInternal<A extends Auth, P extends Params, I extends Input, O extends Output>(authVerifier: AuthVerifierInternal<MethodAuthContext<P>, A> | null, paramsVerifier: ParamsVerifierInternal<P>, inputVerifier: InputVerifierInternal<I>, routeLimiter: RouteRateLimiter<HandlerContext<A, P, I>> | undefined, handler: MethodHandler<A, P, I, O>, validateResOutput: null | OutputVerifierInternal<O>): RequestHandler;
|
|
39
|
+
protected addSubscription<A extends Auth = Auth>(nsid: string, def: LexXrpcSubscription, cfg: StreamConfig<A, Params>): Promise<void>;
|
|
40
|
+
protected addSubscriptionInternal<A extends Auth, P extends Params>(nsid: string, paramsVerifier: ParamsVerifierInternal<P>, authVerifier: AuthVerifierInternal<StreamAuthContext<P>, A> | null, handler: (ctx: StreamContext<A, P>) => AsyncIterable<unknown>): void;
|
|
41
|
+
private createAuthVerifier;
|
|
42
|
+
private createLexiconParamsVerifier;
|
|
43
|
+
private createLexiconInputVerifier;
|
|
44
|
+
private createLexiconOutputVerifier;
|
|
45
|
+
private createSchemaParamsVerifier;
|
|
46
|
+
private createSchemaInputVerifier;
|
|
47
|
+
private createSchemaOutputVerifier;
|
|
32
48
|
private enableStreamingOnListen;
|
|
33
49
|
private createRouteRateLimiter;
|
|
34
50
|
}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAG3C,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|