@atproto/pds 0.5.28 → 0.5.29

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 CHANGED
@@ -1,5 +1,42 @@
1
1
  # @atproto/pds
2
2
 
3
+ ## 0.5.29
4
+
5
+ ### Patch Changes
6
+
7
+ - [#5399](https://github.com/bluesky-social/atproto/pull/5399) [`b2d9a77`](https://github.com/bluesky-social/atproto/commit/b2d9a7715e00472b45ef6db2dc07f1e16be5bccd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add `example.env` file to the NPM package
8
+
9
+ - [#5390](https://github.com/bluesky-social/atproto/pull/5390) [`924bb41`](https://github.com/bluesky-social/atproto/commit/924bb410ed9fa4a60d3ed623d8fd40aef310b142) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Fix `rebuild-repo` script
10
+
11
+ - [#5397](https://github.com/bluesky-social/atproto/pull/5397) [`aff31c8`](https://github.com/bluesky-social/atproto/commit/aff31c815dd69168f3529e667e8bc6e61272bc63) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Extract the OpenTelemetry Node bootstrap out of the PDS into a new
12
+ `@atproto-labs/opentelemetry-node` package. It exposes a `setup()` function from
13
+ its main entrypoint, plus two subpath entrypoints:
14
+
15
+ - `@atproto-labs/opentelemetry-node/conventions` re-exports
16
+ `@opentelemetry/semantic-conventions` alongside the atproto XRPC attribute keys.
17
+ - `@atproto-labs/opentelemetry-node/instrumentation` exposes
18
+ `getDefaultAtprotoInstrumentations()`, the instrumentations common to atproto
19
+ services (which `setup()` registers automatically).
20
+
21
+ As part of this move, the shared runtime instrumentation now enables
22
+ `captureUncaughtException`, so the PDS records uncaught exceptions as OTEL runtime
23
+ events when telemetry is enabled.
24
+
25
+ - [#5314](https://github.com/bluesky-social/atproto/pull/5314) [`cded706`](https://github.com/bluesky-social/atproto/commit/cded70638b908c49961faa957892ed76b292c1b5) Thanks [@IdkGoodName](https://github.com/IdkGoodName)! - Fixes `com.atproto.identity.resolveHandle` route throwing `InvalidRequest` instead of `HandleNotFound` error
26
+
27
+ - [#5396](https://github.com/bluesky-social/atproto/pull/5396) [`066e1b4`](https://github.com/bluesky-social/atproto/commit/066e1b4d669eee5dfaa4f7aefb986bbf722c5629) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add default OTEL resource attributes (name, namespace, version, env name)
28
+
29
+ - [#5350](https://github.com/bluesky-social/atproto/pull/5350) [`1f3f67c`](https://github.com/bluesky-social/atproto/commit/1f3f67c4b5bac19cc226b24f55d90ffd431d0d72) Thanks [@mary-ext](https://github.com/mary-ext)! - Remove the `maxGraphemes` and `maxLength` constraints from the `alt` field of `app.bsky.embed.video`, matching `app.bsky.embed.images`
30
+
31
+ - [#5348](https://github.com/bluesky-social/atproto/pull/5348) [`5c3b7c9`](https://github.com/bluesky-social/atproto/commit/5c3b7c9c87efa4d48d41bc55af61f5b1f1e04920) Thanks [@dreyfus92](https://github.com/dreyfus92)! - Remove `key-encoder` dependency (and its `elliptic`/`asn1.js`/`bn.js` transitive tree) in favor of Node's native JWK key import and the already-present `@noble/curves`
32
+
33
+ - Updated dependencies [[`aff31c8`](https://github.com/bluesky-social/atproto/commit/aff31c815dd69168f3529e667e8bc6e61272bc63), [`5c3b7c9`](https://github.com/bluesky-social/atproto/commit/5c3b7c9c87efa4d48d41bc55af61f5b1f1e04920)]:
34
+ - @atproto-labs/opentelemetry-node@0.1.0
35
+ - @atproto/aws@0.3.14
36
+ - @atproto/xrpc-server@0.12.5
37
+ - @atproto/oauth-provider@0.22.3
38
+ - @atproto-labs/xrpc-utils@0.1.18
39
+
3
40
  ## 0.5.28
4
41
 
5
42
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"resolveHandle.d.ts","sourceRoot":"","sources":["../../../../../src/api/com/atproto/identity/resolveHandle.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAIxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAwCvD"}
1
+ {"version":3,"file":"resolveHandle.d.ts","sourceRoot":"","sources":["../../../../../src/api/com/atproto/identity/resolveHandle.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAIxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA2CvD"}
@@ -18,7 +18,7 @@ export default function (server, ctx) {
18
18
  const supportedHandle = ctx.cfg.identity.serviceHandleDomains.some((host) => handle.endsWith(host) || handle === host.slice(1));
19
19
  // this should be in our DB & we couldn't find it, so fail
20
20
  if (supportedHandle) {
21
- throw new InvalidRequestError('Unable to resolve handle');
21
+ throw new InvalidRequestError('Unable to resolve handle', 'HandleNotFound');
22
22
  }
23
23
  }
24
24
  const did = ctx.bskyAppView
@@ -1 +1 @@
1
- {"version":3,"file":"resolveHandle.js","sourceRoot":"","sources":["../../../../../src/api/com/atproto/identity/resolveHandle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1C,OAAO,EAAE,mBAAmB,EAAe,MAAM,sBAAsB,CAAA;AAEvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAA;AACtE,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AAEnD,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QAClE,MAAM,MAAM,GAAG,wBAAwB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAEtD,qEAAqE;QACrE,uCAAuC;QACvC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YACtB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;YACxD,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO;oBACL,QAAQ,EAAE,kBAA2B;oBACrC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,GAAgB,EAAE;iBACrC,CAAA;YACH,CAAC;YAED,MAAM,eAAe,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,oBAAoB,CAAC,IAAI,CAChE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAC5D,CAAA;YACD,0DAA0D;YAC1D,IAAI,eAAe,EAAE,CAAC;gBACpB,MAAM,IAAI,mBAAmB,CAAC,0BAA0B,CAAC,CAAA;YAC3D,CAAC;QACH,CAAC;QAED,MAAM,GAAG,GAAc,GAAG,CAAC,WAAW;YACpC,CAAC,CAAC,MAAM,GAAG,CAAC,WAAW,CAAC,MAAM;iBACzB,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,CAAC;iBACpD,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,wBAAwB,CAAC;YACjD,CAAC,CAAC,MAAM,GAAG,CAAC,UAAU,CAAC,MAAM;iBACxB,OAAO,CAAC,MAAM,CAAC;iBACf,IAAI,CACH,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB,EAAE,CAAC,EAC7D,wBAAwB,CACzB,CAAA;QAEP,OAAO;YACL,QAAQ,EAAE,kBAA2B;YACrC,IAAI,EAAE,EAAE,GAAG,EAAE;SACd,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,wBAAwB,CAAC,KAAe;IAC/C,MAAM,IAAI,mBAAmB,CAAC,0BAA0B,EAAE,SAAS,EAAE;QACnE,KAAK;KACN,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { isDidString } from '@atproto/lex'\nimport type { DidString } from '@atproto/syntax'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport { baseNormalizeAndValidate } from '../../../../handle/index.js'\nimport { com } from '../../../../lexicons/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n server.add(com.atproto.identity.resolveHandle, async ({ params }) => {\n const handle = baseNormalizeAndValidate(params.handle)\n\n // when behind an entryway, the entryway is authoritative for handles\n // rather than this pds' local accounts\n if (!ctx.cfg.entryway) {\n const user = await ctx.accountManager.getAccount(handle)\n if (user) {\n return {\n encoding: 'application/json' as const,\n body: { did: user.did as DidString },\n }\n }\n\n const supportedHandle = ctx.cfg.identity.serviceHandleDomains.some(\n (host) => handle.endsWith(host) || handle === host.slice(1),\n )\n // this should be in our DB & we couldn't find it, so fail\n if (supportedHandle) {\n throw new InvalidRequestError('Unable to resolve handle')\n }\n }\n\n const did: DidString = ctx.bskyAppView\n ? await ctx.bskyAppView.client\n .call(com.atproto.identity.resolveHandle, { handle })\n .then((r) => r.did, throwInvalidRequestError)\n : await ctx.idResolver.handle\n .resolve(handle)\n .then(\n (v) => (v && isDidString(v) ? v : throwInvalidRequestError()),\n throwInvalidRequestError,\n )\n\n return {\n encoding: 'application/json' as const,\n body: { did },\n }\n })\n}\n\nfunction throwInvalidRequestError(cause?: unknown): never {\n throw new InvalidRequestError('Unable to resolve handle', undefined, {\n cause,\n })\n}\n"]}
1
+ {"version":3,"file":"resolveHandle.js","sourceRoot":"","sources":["../../../../../src/api/com/atproto/identity/resolveHandle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1C,OAAO,EAAE,mBAAmB,EAAe,MAAM,sBAAsB,CAAA;AAEvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAA;AACtE,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AAEnD,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QAClE,MAAM,MAAM,GAAG,wBAAwB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAEtD,qEAAqE;QACrE,uCAAuC;QACvC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YACtB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;YACxD,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO;oBACL,QAAQ,EAAE,kBAA2B;oBACrC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,GAAgB,EAAE;iBACrC,CAAA;YACH,CAAC;YAED,MAAM,eAAe,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,oBAAoB,CAAC,IAAI,CAChE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAC5D,CAAA;YACD,0DAA0D;YAC1D,IAAI,eAAe,EAAE,CAAC;gBACpB,MAAM,IAAI,mBAAmB,CAC3B,0BAA0B,EAC1B,gBAAgB,CACjB,CAAA;YACH,CAAC;QACH,CAAC;QAED,MAAM,GAAG,GAAc,GAAG,CAAC,WAAW;YACpC,CAAC,CAAC,MAAM,GAAG,CAAC,WAAW,CAAC,MAAM;iBACzB,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,CAAC;iBACpD,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,wBAAwB,CAAC;YACjD,CAAC,CAAC,MAAM,GAAG,CAAC,UAAU,CAAC,MAAM;iBACxB,OAAO,CAAC,MAAM,CAAC;iBACf,IAAI,CACH,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB,EAAE,CAAC,EAC7D,wBAAwB,CACzB,CAAA;QAEP,OAAO;YACL,QAAQ,EAAE,kBAA2B;YACrC,IAAI,EAAE,EAAE,GAAG,EAAE;SACd,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,wBAAwB,CAAC,KAAe;IAC/C,MAAM,IAAI,mBAAmB,CAAC,0BAA0B,EAAE,SAAS,EAAE;QACnE,KAAK;KACN,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { isDidString } from '@atproto/lex'\nimport type { DidString } from '@atproto/syntax'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport { baseNormalizeAndValidate } from '../../../../handle/index.js'\nimport { com } from '../../../../lexicons/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n server.add(com.atproto.identity.resolveHandle, async ({ params }) => {\n const handle = baseNormalizeAndValidate(params.handle)\n\n // when behind an entryway, the entryway is authoritative for handles\n // rather than this pds' local accounts\n if (!ctx.cfg.entryway) {\n const user = await ctx.accountManager.getAccount(handle)\n if (user) {\n return {\n encoding: 'application/json' as const,\n body: { did: user.did as DidString },\n }\n }\n\n const supportedHandle = ctx.cfg.identity.serviceHandleDomains.some(\n (host) => handle.endsWith(host) || handle === host.slice(1),\n )\n // this should be in our DB & we couldn't find it, so fail\n if (supportedHandle) {\n throw new InvalidRequestError(\n 'Unable to resolve handle',\n 'HandleNotFound',\n )\n }\n }\n\n const did: DidString = ctx.bskyAppView\n ? await ctx.bskyAppView.client\n .call(com.atproto.identity.resolveHandle, { handle })\n .then((r) => r.did, throwInvalidRequestError)\n : await ctx.idResolver.handle\n .resolve(handle)\n .then(\n (v) => (v && isDidString(v) ? v : throwInvalidRequestError()),\n throwInvalidRequestError,\n )\n\n return {\n encoding: 'application/json' as const,\n body: { did },\n }\n })\n}\n\nfunction throwInvalidRequestError(cause?: unknown): never {\n throw new InvalidRequestError('Unable to resolve handle', undefined, {\n cause,\n })\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"auth-verifier.d.ts","sourceRoot":"","sources":["../src/auth-verifier.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth-verifier.d.ts","sourceRoot":"","sources":["../src/auth-verifier.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { createPublicKey, createSecretKey } from 'node:crypto';
2
+ import { secp256k1 } from '@noble/curves/secp256k1';
2
3
  import * as jose from 'jose';
3
- import KeyEncoderModule from 'key-encoder';
4
4
  import { getVerificationMaterial } from '@atproto/common';
5
5
  import { getDidKeyFromMultibase } from '@atproto/identity';
6
6
  import { isDidString, } from '@atproto/lex';
@@ -10,8 +10,6 @@ import { AuthRequiredError, ForbiddenError, InvalidRequestError, XRPCError, pars
10
10
  import { ACCESS_STANDARD, AuthScope, isAuthScope } from './auth-scope.js';
11
11
  import { softDeleted } from './db/index.js';
12
12
  import { appendVary } from './util/http.js';
13
- // key-encoder is CJS with exports.default; Node ESM interop wraps it as { default: Class }
14
- const KeyEncoder = ((m) => m.default ?? m)(KeyEncoderModule);
15
13
  export class AuthVerifier {
16
14
  constructor(accountManager, idResolver, oauthVerifier, opts) {
17
15
  this.accountManager = accountManager;
@@ -435,10 +433,18 @@ const parseBasicAuth = (req) => {
435
433
  export const createSecretKeyObject = (secret) => {
436
434
  return createSecretKey(Buffer.from(secret));
437
435
  };
438
- const keyEncoder = new KeyEncoder('secp256k1');
439
436
  export const createPublicKeyObject = (publicKeyHex) => {
440
- const key = keyEncoder.encodePublic(publicKeyHex, 'raw', 'pem');
441
- return createPublicKey({ format: 'pem', key });
437
+ // accepts compressed or uncompressed keys; validates the point is on-curve
438
+ const point = secp256k1.ProjectivePoint.fromHex(publicKeyHex).toRawBytes(false);
439
+ return createPublicKey({
440
+ format: 'jwk',
441
+ key: {
442
+ kty: 'EC',
443
+ crv: 'secp256k1',
444
+ x: Buffer.from(point.subarray(1, 33)).toString('base64url'),
445
+ y: Buffer.from(point.subarray(33, 65)).toString('base64url'),
446
+ },
447
+ });
442
448
  };
443
449
  function setAuthHeaders(res) {
444
450
  res.setHeader('Cache-Control', 'private');
@@ -1 +1 @@
1
- {"version":3,"file":"auth-verifier.js","sourceRoot":"","sources":["../src/auth-verifier.ts"],"names":[],"mappings":"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","sourcesContent":["import { type KeyObject, createPublicKey, createSecretKey } from 'node:crypto'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport * as jose from 'jose'\nimport KeyEncoderModule from 'key-encoder'\nimport { getVerificationMaterial } from '@atproto/common'\nimport { type IdResolver, getDidKeyFromMultibase } from '@atproto/identity'\nimport {\n type AtIdentifierString,\n type DidString,\n isDidString,\n} from '@atproto/lex'\nimport {\n OAuthError,\n WWWAuthenticateError,\n} from '@atproto/oauth-provider/errors'\nimport type {\n OAuthVerifier,\n VerifyTokenPayloadOptions,\n} from '@atproto/oauth-provider/verifier'\nimport {\n type ScopePermissions,\n ScopePermissionsTransition,\n} from '@atproto/oauth-scopes'\nimport {\n AuthRequiredError,\n type Awaitable,\n ForbiddenError,\n InvalidRequestError,\n type MethodAuthContext,\n type MethodAuthVerifier,\n type Params,\n XRPCError,\n parseReqNsid,\n verifyJwt as verifyServiceJwt,\n} from '@atproto/xrpc-server'\nimport type { AccountManager } from './account-manager/account-manager.js'\nimport type { ActorAccount } from './account-manager/helpers/account.js'\nimport type {\n AccessOutput,\n AdminTokenOutput,\n ModServiceOutput,\n OAuthOutput,\n RefreshOutput,\n UnauthenticatedOutput,\n UserServiceAuthOutput,\n} from './auth-output.js'\nimport { ACCESS_STANDARD, AuthScope, isAuthScope } from './auth-scope.js'\nimport { softDeleted } from './db/index.js'\nimport { appendVary } from './util/http.js'\nimport type { WithRequired } from './util/types.js'\n\n// key-encoder is CJS with exports.default; Node ESM interop wraps it as { default: Class }\nconst KeyEncoder = ((m) => m.default ?? m)(KeyEncoderModule)\n\nexport type VerifiedOptions = {\n checkTakedown?: boolean\n checkDeactivated?: boolean\n}\n\nexport type ScopedOptions<S extends AuthScope = AuthScope> = {\n scopes?: readonly S[]\n}\n\nexport type ExtraScopedOptions<S extends AuthScope = AuthScope> = {\n additional?: readonly S[]\n}\n\nexport type AuthorizedOptions<P extends Params = Params> = {\n authorize: (\n permissions: ScopePermissions,\n ctx: MethodAuthContext<P>,\n ) => Awaitable<void>\n}\n\nexport type AuthVerifierOpts = {\n publicUrl: string\n jwtKey: KeyObject\n adminPass: string\n dids: {\n pds: string\n entryway?: string\n modService?: string\n }\n}\n\nexport type VerifyBearerJwtOptions<S extends AuthScope = AuthScope> =\n WithRequired<\n Omit<jose.JWTVerifyOptions, 'scopes'> & {\n scopes: readonly S[]\n },\n 'audience' | 'typ'\n >\n\nexport type VerifyBearerJwtResult<S extends AuthScope = AuthScope> = {\n sub: DidString\n aud: string\n jti: string | undefined\n scope: S\n}\n\nexport class AuthVerifier {\n private _publicUrl: string\n private _jwtKey: KeyObject\n private _adminPass: string\n public dids: AuthVerifierOpts['dids']\n\n constructor(\n public accountManager: AccountManager,\n public idResolver: IdResolver,\n public oauthVerifier: OAuthVerifier,\n opts: AuthVerifierOpts,\n ) {\n this._publicUrl = opts.publicUrl\n this._jwtKey = opts.jwtKey\n this._adminPass = opts.adminPass\n this.dids = opts.dids\n }\n\n // verifiers (arrow fns to preserve scope)\n\n public unauthenticated: MethodAuthVerifier<UnauthenticatedOutput> = (ctx) => {\n setAuthHeaders(ctx.res)\n\n // @NOTE this auth method is typically used as fallback when no other auth\n // method is applicable. This means that the presence of an \"authorization\"\n // header means that that header is invalid (as it did not match any of the\n // other auth methods).\n if (ctx.req.headers['authorization']) {\n throw new AuthRequiredError('Invalid authorization header')\n }\n\n return {\n credentials: null,\n }\n }\n\n /** @deprecated We are steering away from this auth method */\n public adminToken: MethodAuthVerifier<AdminTokenOutput> = async (ctx) => {\n setAuthHeaders(ctx.res)\n const parsed = parseBasicAuth(ctx.req)\n if (!parsed) {\n throw new AuthRequiredError()\n }\n const { username, password } = parsed\n if (username !== 'admin' || password !== this._adminPass) {\n throw new AuthRequiredError()\n }\n\n return { credentials: { type: 'admin_token' } }\n }\n\n public modService: MethodAuthVerifier<ModServiceOutput> = async (ctx) => {\n setAuthHeaders(ctx.res)\n if (!this.dids.modService) {\n throw new AuthRequiredError('Untrusted issuer', 'UntrustedIss')\n }\n const payload = await this.verifyServiceJwt(ctx.req, {\n iss: [this.dids.modService, `${this.dids.modService}#atproto_labeler`],\n })\n return {\n credentials: {\n type: 'mod_service',\n did: payload.iss,\n },\n }\n }\n\n /** @deprecated We are steering away from {@link adminToken} auth. Use {@link modService} instead. */\n public moderator: MethodAuthVerifier<AdminTokenOutput | ModServiceOutput> =\n async (ctx) => {\n const type = extractAuthType(ctx.req)\n if (type === AuthType.BEARER) {\n return this.modService(ctx)\n } else {\n return this.adminToken(ctx)\n }\n }\n\n protected access<S extends AuthScope>(\n options: VerifiedOptions & Required<ScopedOptions<S>>,\n ): MethodAuthVerifier<AccessOutput<S>> {\n const { scopes, ...statusOptions } = options\n\n const verifyJwtOptions: VerifyBearerJwtOptions<S> = {\n audience: this.dids.pds,\n typ: 'at+jwt',\n scopes:\n // @NOTE We can reject taken down credentials based on the scope if\n // \"checkTakedown\" is set.\n statusOptions.checkTakedown && scopes.includes(AuthScope.Takendown as S)\n ? scopes.filter((s) => s !== AuthScope.Takendown)\n : scopes,\n }\n\n return async (ctx) => {\n setAuthHeaders(ctx.res)\n\n const { sub: did, scope } = await this.verifyBearerJwt(\n ctx.req,\n verifyJwtOptions,\n )\n\n await this.verifyStatus(did, statusOptions)\n\n return {\n credentials: { type: 'access', did, scope },\n }\n }\n }\n\n public refresh(options?: {\n allowExpired?: boolean\n }): MethodAuthVerifier<RefreshOutput> {\n const verifyOptions: VerifyBearerJwtOptions<AuthScope.Refresh> = {\n clockTolerance: options?.allowExpired ? Infinity : undefined,\n typ: 'refresh+jwt',\n // when using entryway, proxying refresh credentials\n audience: this.dids.entryway ? this.dids.entryway : this.dids.pds,\n scopes: [AuthScope.Refresh],\n }\n\n return async (ctx) => {\n setAuthHeaders(ctx.res)\n\n const result = await this.verifyBearerJwt(ctx.req, verifyOptions)\n\n const tokenId = result.jti\n if (!tokenId) {\n throw new AuthRequiredError(\n 'Unexpected missing refresh token id',\n 'MissingTokenId',\n )\n }\n\n return {\n credentials: {\n type: 'refresh',\n did: result.sub,\n scope: result.scope,\n tokenId,\n },\n }\n }\n }\n\n public authorization<P extends Params>({\n scopes = ACCESS_STANDARD,\n additional = [],\n ...options\n }: VerifiedOptions &\n ScopedOptions &\n ExtraScopedOptions &\n AuthorizedOptions<P>): MethodAuthVerifier<AccessOutput | OAuthOutput, P> {\n const access = this.access({\n ...options,\n scopes: [...scopes, ...additional],\n })\n const oauth = this.oauth(options)\n\n return async (ctx) => {\n const type = extractAuthType(ctx.req)\n\n if (type === AuthType.BEARER) {\n return access(ctx)\n }\n\n if (type === AuthType.DPOP) {\n return oauth(ctx)\n }\n\n // Auth headers are set through the access and oauth methods so we only\n // need to set them here if we reach this point\n setAuthHeaders(ctx.res)\n\n if (type !== null) {\n throw new InvalidRequestError(\n 'Unexpected authorization type',\n 'InvalidToken',\n )\n }\n\n throw new AuthRequiredError(undefined, 'AuthMissing')\n }\n }\n\n public authorizationOrModService<P extends Params>(\n opts: VerifiedOptions & ExtraScopedOptions & AuthorizedOptions<P>,\n ): MethodAuthVerifier<AccessOutput | OAuthOutput | ModServiceOutput, P> {\n const authorization = this.authorization(opts)\n return async (ctx) => {\n try {\n return await this.modService(ctx)\n } catch (err) {\n if (err instanceof AuthRequiredError) {\n return authorization(ctx)\n }\n throw err\n }\n }\n }\n\n public authorizationOrAdminTokenOptional<P extends Params>(\n opts: VerifiedOptions & ExtraScopedOptions & AuthorizedOptions<P>,\n ): MethodAuthVerifier<\n OAuthOutput | AccessOutput | AdminTokenOutput | UnauthenticatedOutput,\n P\n > {\n const authorization = this.authorization(opts)\n return async (ctx) => {\n const type = extractAuthType(ctx.req)\n if (type === AuthType.BEARER || type === AuthType.DPOP) {\n return authorization(ctx)\n } else if (type === AuthType.BASIC) {\n return this.adminToken(ctx)\n } else {\n return this.unauthenticated(ctx)\n }\n }\n }\n\n public userServiceAuth: MethodAuthVerifier<UserServiceAuthOutput> = async (\n ctx,\n ) => {\n setAuthHeaders(ctx.res)\n const payload = await this.verifyServiceJwt(ctx.req)\n return {\n credentials: {\n type: 'user_service_auth',\n did: payload.iss,\n },\n }\n }\n\n public userServiceAuthOptional: MethodAuthVerifier<\n UserServiceAuthOutput | UnauthenticatedOutput\n > = async (ctx) => {\n const type = extractAuthType(ctx.req)\n if (type === AuthType.BEARER) {\n return await this.userServiceAuth(ctx)\n } else {\n return this.unauthenticated(ctx)\n }\n }\n\n public authorizationOrUserServiceAuth<P extends Params>(\n options: VerifiedOptions &\n ScopedOptions &\n ExtraScopedOptions &\n AuthorizedOptions<P>,\n ): MethodAuthVerifier<UserServiceAuthOutput | OAuthOutput | AccessOutput, P> {\n const authorizationVerifier = this.authorization(options)\n return async (ctx) => {\n if (isDefinitelyServiceAuth(ctx.req)) {\n return this.userServiceAuth(ctx)\n } else {\n return authorizationVerifier(ctx)\n }\n }\n }\n\n protected oauth<P extends Params>({\n authorize,\n ...verifyStatusOptions\n }: VerifiedOptions & AuthorizedOptions<P>): MethodAuthVerifier<\n OAuthOutput,\n P\n > {\n const verifyTokenOptions: VerifyTokenPayloadOptions = {\n audience: [this.dids.pds],\n scope: ['atproto'],\n }\n\n return async (ctx) => {\n setAuthHeaders(ctx.res)\n\n const { req, res } = ctx\n\n // https://datatracker.ietf.org/doc/html/rfc9449#section-8.2\n const dpopNonce = this.oauthVerifier.nextDpopNonce()\n if (dpopNonce) {\n res.setHeader('DPoP-Nonce', dpopNonce)\n res.appendHeader('Access-Control-Expose-Headers', 'DPoP-Nonce')\n }\n\n const originalUrl = req.originalUrl || req.url || '/'\n const url = new URL(originalUrl, this._publicUrl)\n\n const { scope, sub: did } = await this.oauthVerifier\n .authenticateRequest(\n req.method || 'GET',\n url,\n req.headers,\n verifyTokenOptions,\n )\n .catch((err) => {\n // Make sure to include any WWW-Authenticate header in the response\n // (particularly useful for DPoP's \"use_dpop_nonce\" error)\n if (err instanceof WWWAuthenticateError) {\n res.setHeader('WWW-Authenticate', err.wwwAuthenticateHeader)\n res.appendHeader(\n 'Access-Control-Expose-Headers',\n 'WWW-Authenticate',\n )\n }\n\n if (err instanceof OAuthError) {\n throw new XRPCError(err.status, err.error_description, err.error)\n }\n\n throw err\n })\n\n if (!isDidString(did)) {\n throw new InvalidRequestError('Malformed token', 'InvalidToken')\n }\n\n await this.verifyStatus(did, verifyStatusOptions)\n\n const permissions = new ScopePermissionsTransition(scope?.split(' '))\n\n // Should never happen\n if (!permissions.scopes.has('atproto')) {\n throw new InvalidRequestError(\n 'OAuth token does not have \"atproto\" scope',\n 'InvalidToken',\n )\n }\n\n await authorize(permissions, ctx)\n\n return {\n credentials: {\n type: 'oauth',\n did,\n permissions,\n },\n }\n }\n }\n\n protected async verifyStatus(\n did: DidString,\n options: VerifiedOptions,\n ): Promise<void> {\n if (options.checkDeactivated || options.checkTakedown) {\n await this.findAccount(did, options)\n }\n }\n\n /**\n * Finds an account by its handle or DID, returning possibly deactivated or\n * taken down accounts (unless `options.checkDeactivated` or\n * `options.checkTakedown` are set to true, respectively).\n */\n public async findAccount(\n handleOrDid: AtIdentifierString,\n options: VerifiedOptions,\n ): Promise<ActorAccount> {\n const account = await this.accountManager.getAccount(handleOrDid, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n if (!account) {\n // will be turned into ExpiredToken for the client if proxied by entryway\n throw new ForbiddenError('Account not found', 'AccountNotFound')\n }\n if (options.checkTakedown && softDeleted(account)) {\n throw new AuthRequiredError(\n 'Account has been taken down',\n 'AccountTakedown',\n )\n }\n if (options.checkDeactivated && account.deactivatedAt) {\n throw new AuthRequiredError(\n 'Account is deactivated',\n 'AccountDeactivated',\n )\n }\n return account\n }\n\n /**\n * Wraps {@link jose.jwtVerify} into a function that also validates the token\n * payload's type and wraps errors into {@link InvalidRequestError}.\n */\n protected async verifyBearerJwt<S extends AuthScope = AuthScope>(\n req: IncomingMessage,\n { scopes, ...options }: VerifyBearerJwtOptions<S>,\n ): Promise<VerifyBearerJwtResult<S>> {\n const token = bearerTokenFromReq(req)\n if (!token) {\n throw new AuthRequiredError(undefined, 'AuthMissing')\n }\n\n const { payload } = await jose\n .jwtVerify(token, this._jwtKey, options)\n .catch((cause) => {\n if (cause instanceof jose.errors.JWTExpired) {\n throw new InvalidRequestError('Token has expired', 'ExpiredToken', {\n cause,\n })\n } else {\n throw new InvalidRequestError(\n 'Token could not be verified',\n 'InvalidToken',\n { cause },\n )\n }\n })\n\n const { sub, aud, scope, lxm, cnf, jti } = payload\n\n if (typeof lxm !== 'undefined') {\n // Service auth tokens should never make it to here. But since service\n // auth tokens do not have a \"typ\" header, the \"typ\" check above will not\n // catch them. This check here is mainly to protect against the\n // hypothetical case in which a PDS would issue service auth tokens using\n // its private key.\n throw new InvalidRequestError('Malformed token', 'InvalidToken')\n }\n if (typeof cnf !== 'undefined') {\n // Proof-of-Possession (PoP) tokens are not allowed here\n // https://www.rfc-editor.org/rfc/rfc7800.html\n throw new InvalidRequestError('Malformed token', 'InvalidToken')\n }\n if (typeof sub !== 'string' || !isDidString(sub)) {\n throw new InvalidRequestError('Malformed token', 'InvalidToken')\n }\n if (typeof aud !== 'string' || !aud.startsWith('did:')) {\n throw new InvalidRequestError('Malformed token', 'InvalidToken')\n }\n if (typeof jti !== 'string' && typeof jti !== 'undefined') {\n throw new InvalidRequestError('Malformed token', 'InvalidToken')\n }\n if (!isAuthScope(scope) || !scopes.includes(scope as any)) {\n throw new InvalidRequestError('Bad token scope', 'InvalidToken')\n }\n\n return { sub, aud, jti, scope: scope as S }\n }\n\n protected async verifyServiceJwt(\n req: IncomingMessage,\n opts?: { iss?: string[] },\n ) {\n const jwtStr = bearerTokenFromReq(req)\n if (!jwtStr) {\n throw new AuthRequiredError('missing jwt', 'MissingJwt')\n }\n\n const nsid = parseReqNsid(req)\n const payload = await verifyServiceJwt(\n jwtStr,\n null,\n nsid,\n async (iss, forceRefresh) => {\n if (opts?.iss && !opts.iss.includes(iss)) {\n throw new AuthRequiredError('Untrusted issuer', 'UntrustedIss')\n }\n const [did, serviceId] = iss.split('#')\n const keyId =\n serviceId === 'atproto_labeler' ? 'atproto_label' : 'atproto'\n const didDoc = await this.idResolver.did.resolve(did, forceRefresh)\n if (!didDoc) {\n throw new AuthRequiredError('could not resolve iss did')\n }\n const parsedKey = getVerificationMaterial(didDoc, keyId)\n if (!parsedKey) {\n throw new AuthRequiredError('missing or bad key in did doc')\n }\n const didKey = getDidKeyFromMultibase(parsedKey)\n if (!didKey) {\n throw new AuthRequiredError('missing or bad key in did doc')\n }\n return didKey\n },\n )\n if (\n payload.aud !== this.dids.pds &&\n (!this.dids.entryway || payload.aud !== this.dids.entryway)\n ) {\n throw new AuthRequiredError(\n 'jwt audience does not match service did',\n 'BadJwtAudience',\n )\n }\n return payload\n }\n}\n\n// HELPERS\n// ---------\n\nexport function isUserOrAdmin(\n auth: AccessOutput | OAuthOutput | AdminTokenOutput | UnauthenticatedOutput,\n did: string,\n): boolean {\n if (!auth.credentials) {\n return false\n } else if (auth.credentials.type === 'admin_token') {\n return true\n } else {\n return auth.credentials.did === did\n }\n}\n\nenum AuthType {\n BASIC = 'Basic',\n BEARER = 'Bearer',\n DPOP = 'DPoP',\n}\n\nconst parseAuthorizationHeader = (\n req: IncomingMessage,\n): [type: null] | [type: AuthType, token: string] => {\n const authorization = req.headers['authorization']\n if (!authorization) return [null]\n\n const result = authorization.split(' ')\n if (result.length !== 2) {\n throw new InvalidRequestError(\n 'Malformed authorization header',\n 'InvalidToken',\n )\n }\n\n // authorization type is case-insensitive\n const authType = result[0].toUpperCase()\n\n const type = Object.hasOwn(AuthType, authType) ? AuthType[authType] : null\n if (type) return [type, result[1]]\n\n throw new InvalidRequestError(\n `Unsupported authorization type: ${result[0]}`,\n 'InvalidToken',\n )\n}\n\n/**\n * @note Not all service auth tokens are guaranteed to have \"lxm\" claim, so this\n * function should not be used to verify service auth tokens. It is only used to\n * check if a token is definitely a service auth token.\n */\nconst isDefinitelyServiceAuth = (req: IncomingMessage): boolean => {\n const token = bearerTokenFromReq(req)\n if (!token) return false\n const payload = jose.decodeJwt(token)\n return payload['lxm'] != null\n}\n\nconst extractAuthType = (req: IncomingMessage): AuthType | null => {\n const [type] = parseAuthorizationHeader(req)\n return type\n}\n\nexport const bearerTokenFromReq = (req: IncomingMessage) => {\n const [type, token] = parseAuthorizationHeader(req)\n return type === AuthType.BEARER ? token : null\n}\n\nconst parseBasicAuth = (\n req: IncomingMessage,\n): { username: string; password: string } | null => {\n try {\n const [type, b64] = parseAuthorizationHeader(req)\n if (type !== AuthType.BASIC) return null\n const decoded = Buffer.from(b64, 'base64').toString('utf8')\n // We must not use split(':') because the password can contain colons\n const colon = decoded.indexOf(':')\n if (colon === -1) return null\n const username = decoded.slice(0, colon)\n const password = decoded.slice(colon + 1)\n return { username, password }\n } catch (err) {\n return null\n }\n}\n\nexport const createSecretKeyObject = (secret: string): KeyObject => {\n return createSecretKey(Buffer.from(secret))\n}\n\nconst keyEncoder = new KeyEncoder('secp256k1')\nexport const createPublicKeyObject = (publicKeyHex: string): KeyObject => {\n const key = keyEncoder.encodePublic(publicKeyHex, 'raw', 'pem')\n return createPublicKey({ format: 'pem', key })\n}\n\nfunction setAuthHeaders(res: ServerResponse) {\n res.setHeader('Cache-Control', 'private')\n appendVary(res, 'Authorization')\n}\n"]}
1
+ {"version":3,"file":"auth-verifier.js","sourceRoot":"","sources":["../src/auth-verifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE9E,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACnD,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAC5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAmB,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAC3E,OAAO,EAGL,WAAW,GACZ,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,UAAU,EACV,oBAAoB,GACrB,MAAM,gCAAgC,CAAA;AAKvC,OAAO,EAEL,0BAA0B,GAC3B,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,iBAAiB,EAEjB,cAAc,EACd,mBAAmB,EAInB,SAAS,EACT,YAAY,EACZ,SAAS,IAAI,gBAAgB,GAC9B,MAAM,sBAAsB,CAAA;AAY7B,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAiD3C,MAAM,OAAO,YAAY;IAMvB,YACS,cAA8B,EAC9B,UAAsB,EACtB,aAA4B,EACnC,IAAsB;QAHf,mBAAc,GAAd,cAAc,CAAgB;QAC9B,eAAU,GAAV,UAAU,CAAY;QACtB,kBAAa,GAAb,aAAa,CAAe;QASrC,0CAA0C;QAEnC,oBAAe,GAA8C,CAAC,GAAG,EAAE,EAAE;YAC1E,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAEvB,0EAA0E;YAC1E,2EAA2E;YAC3E,2EAA2E;YAC3E,uBAAuB;YACvB,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;gBACrC,MAAM,IAAI,iBAAiB,CAAC,8BAA8B,CAAC,CAAA;YAC7D,CAAC;YAED,OAAO;gBACL,WAAW,EAAE,IAAI;aAClB,CAAA;QACH,CAAC,CAAA;QAED,6DAA6D;QACtD,eAAU,GAAyC,KAAK,EAAE,GAAG,EAAE,EAAE;YACtE,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACvB,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACtC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,iBAAiB,EAAE,CAAA;YAC/B,CAAC;YACD,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAA;YACrC,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;gBACzD,MAAM,IAAI,iBAAiB,EAAE,CAAA;YAC/B,CAAC;YAED,OAAO,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,CAAA;QACjD,CAAC,CAAA;QAEM,eAAU,GAAyC,KAAK,EAAE,GAAG,EAAE,EAAE;YACtE,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACvB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;gBAC1B,MAAM,IAAI,iBAAiB,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAA;YACjE,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE;gBACnD,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,kBAAkB,CAAC;aACvE,CAAC,CAAA;YACF,OAAO;gBACL,WAAW,EAAE;oBACX,IAAI,EAAE,aAAa;oBACnB,GAAG,EAAE,OAAO,CAAC,GAAG;iBACjB;aACF,CAAA;QACH,CAAC,CAAA;QAED,qGAAqG;QAC9F,cAAS,GACd,KAAK,EAAE,GAAG,EAAE,EAAE;YACZ,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACrC,IAAI,IAAI,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;gBAC7B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;YAC7B,CAAC;QACH,CAAC,CAAA;QAgJI,oBAAe,GAA8C,KAAK,EACvE,GAAG,EACH,EAAE;YACF,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACvB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACpD,OAAO;gBACL,WAAW,EAAE;oBACX,IAAI,EAAE,mBAAmB;oBACzB,GAAG,EAAE,OAAO,CAAC,GAAG;iBACjB;aACF,CAAA;QACH,CAAC,CAAA;QAEM,4BAAuB,GAE1B,KAAK,EAAE,GAAG,EAAE,EAAE;YAChB,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACrC,IAAI,IAAI,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;gBAC7B,OAAO,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAA;YACxC,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAA;YAClC,CAAC;QACH,CAAC,CAAA;QAtOC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAA;QAChC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAA;QAC1B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAA;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;IACvB,CAAC;IA8DS,MAAM,CACd,OAAqD;QAErD,MAAM,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE,GAAG,OAAO,CAAA;QAE5C,MAAM,gBAAgB,GAA8B;YAClD,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG;YACvB,GAAG,EAAE,QAAQ;YACb,MAAM;YACJ,mEAAmE;YACnE,0BAA0B;YAC1B,aAAa,CAAC,aAAa,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAc,CAAC;gBACtE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,SAAS,CAAC;gBACjD,CAAC,CAAC,MAAM;SACb,CAAA;QAED,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE;YACnB,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAEvB,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,eAAe,CACpD,GAAG,CAAC,GAAG,EACP,gBAAgB,CACjB,CAAA;YAED,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,aAAa,CAAC,CAAA;YAE3C,OAAO;gBACL,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE;aAC5C,CAAA;QACH,CAAC,CAAA;IACH,CAAC;IAEM,OAAO,CAAC,OAEd;QACC,MAAM,aAAa,GAA8C;YAC/D,cAAc,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;YAC5D,GAAG,EAAE,aAAa;YAClB,oDAAoD;YACpD,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YACjE,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC;SAC5B,CAAA;QAED,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE;YACnB,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAEvB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,aAAa,CAAC,CAAA;YAEjE,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAA;YAC1B,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,iBAAiB,CACzB,qCAAqC,EACrC,gBAAgB,CACjB,CAAA;YACH,CAAC;YAED,OAAO;gBACL,WAAW,EAAE;oBACX,IAAI,EAAE,SAAS;oBACf,GAAG,EAAE,MAAM,CAAC,GAAG;oBACf,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,OAAO;iBACR;aACF,CAAA;QACH,CAAC,CAAA;IACH,CAAC;IAEM,aAAa,CAAmB,EACrC,MAAM,GAAG,eAAe,EACxB,UAAU,GAAG,EAAE,EACf,GAAG,OAAO,EAIU;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YACzB,GAAG,OAAO;YACV,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,GAAG,UAAU,CAAC;SACnC,CAAC,CAAA;QACF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAEjC,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE;YACnB,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAErC,IAAI,IAAI,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;gBAC7B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAA;YACpB,CAAC;YAED,IAAI,IAAI,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAC3B,OAAO,KAAK,CAAC,GAAG,CAAC,CAAA;YACnB,CAAC;YAED,uEAAuE;YACvE,+CAA+C;YAC/C,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAEvB,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAClB,MAAM,IAAI,mBAAmB,CAC3B,+BAA+B,EAC/B,cAAc,CACf,CAAA;YACH,CAAC;YAED,MAAM,IAAI,iBAAiB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;QACvD,CAAC,CAAA;IACH,CAAC;IAEM,yBAAyB,CAC9B,IAAiE;QAEjE,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;QAC9C,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE;YACnB,IAAI,CAAC;gBACH,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;YACnC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,GAAG,YAAY,iBAAiB,EAAE,CAAC;oBACrC,OAAO,aAAa,CAAC,GAAG,CAAC,CAAA;gBAC3B,CAAC;gBACD,MAAM,GAAG,CAAA;YACX,CAAC;QACH,CAAC,CAAA;IACH,CAAC;IAEM,iCAAiC,CACtC,IAAiE;QAKjE,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;QAC9C,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE;YACnB,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACrC,IAAI,IAAI,KAAK,QAAQ,CAAC,MAAM,IAAI,IAAI,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACvD,OAAO,aAAa,CAAC,GAAG,CAAC,CAAA;YAC3B,CAAC;iBAAM,IAAI,IAAI,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC;gBACnC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;YAC7B,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAA;YAClC,CAAC;QACH,CAAC,CAAA;IACH,CAAC;IA0BM,8BAA8B,CACnC,OAGsB;QAEtB,MAAM,qBAAqB,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;QACzD,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE;YACnB,IAAI,uBAAuB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrC,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAA;YAClC,CAAC;iBAAM,CAAC;gBACN,OAAO,qBAAqB,CAAC,GAAG,CAAC,CAAA;YACnC,CAAC;QACH,CAAC,CAAA;IACH,CAAC;IAES,KAAK,CAAmB,EAChC,SAAS,EACT,GAAG,mBAAmB,EACiB;QAIvC,MAAM,kBAAkB,GAA8B;YACpD,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;YACzB,KAAK,EAAE,CAAC,SAAS,CAAC;SACnB,CAAA;QAED,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE;YACnB,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAEvB,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,CAAA;YAExB,4DAA4D;YAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAA;YACpD,IAAI,SAAS,EAAE,CAAC;gBACd,GAAG,CAAC,SAAS,CAAC,YAAY,EAAE,SAAS,CAAC,CAAA;gBACtC,GAAG,CAAC,YAAY,CAAC,+BAA+B,EAAE,YAAY,CAAC,CAAA;YACjE,CAAC;YAED,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAA;YACrD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;YAEjD,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa;iBACjD,mBAAmB,CAClB,GAAG,CAAC,MAAM,IAAI,KAAK,EACnB,GAAG,EACH,GAAG,CAAC,OAAO,EACX,kBAAkB,CACnB;iBACA,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBACb,mEAAmE;gBACnE,0DAA0D;gBAC1D,IAAI,GAAG,YAAY,oBAAoB,EAAE,CAAC;oBACxC,GAAG,CAAC,SAAS,CAAC,kBAAkB,EAAE,GAAG,CAAC,qBAAqB,CAAC,CAAA;oBAC5D,GAAG,CAAC,YAAY,CACd,+BAA+B,EAC/B,kBAAkB,CACnB,CAAA;gBACH,CAAC;gBAED,IAAI,GAAG,YAAY,UAAU,EAAE,CAAC;oBAC9B,MAAM,IAAI,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,iBAAiB,EAAE,GAAG,CAAC,KAAK,CAAC,CAAA;gBACnE,CAAC;gBAED,MAAM,GAAG,CAAA;YACX,CAAC,CAAC,CAAA;YAEJ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtB,MAAM,IAAI,mBAAmB,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAA;YAClE,CAAC;YAED,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAA;YAEjD,MAAM,WAAW,GAAG,IAAI,0BAA0B,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;YAErE,sBAAsB;YACtB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBACvC,MAAM,IAAI,mBAAmB,CAC3B,2CAA2C,EAC3C,cAAc,CACf,CAAA;YACH,CAAC;YAED,MAAM,SAAS,CAAC,WAAW,EAAE,GAAG,CAAC,CAAA;YAEjC,OAAO;gBACL,WAAW,EAAE;oBACX,IAAI,EAAE,OAAO;oBACb,GAAG;oBACH,WAAW;iBACZ;aACF,CAAA;QACH,CAAC,CAAA;IACH,CAAC;IAES,KAAK,CAAC,YAAY,CAC1B,GAAc,EACd,OAAwB;QAExB,IAAI,OAAO,CAAC,gBAAgB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;YACtD,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,WAAW,CACtB,WAA+B,EAC/B,OAAwB;QAExB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,WAAW,EAAE;YAChE,kBAAkB,EAAE,IAAI;YACxB,gBAAgB,EAAE,IAAI;SACvB,CAAC,CAAA;QACF,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,yEAAyE;YACzE,MAAM,IAAI,cAAc,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,CAAA;QAClE,CAAC;QACD,IAAI,OAAO,CAAC,aAAa,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,iBAAiB,CACzB,6BAA6B,EAC7B,iBAAiB,CAClB,CAAA;QACH,CAAC;QACD,IAAI,OAAO,CAAC,gBAAgB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;YACtD,MAAM,IAAI,iBAAiB,CACzB,wBAAwB,EACxB,oBAAoB,CACrB,CAAA;QACH,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC;IAED;;;OAGG;IACO,KAAK,CAAC,eAAe,CAC7B,GAAoB,EACpB,EAAE,MAAM,EAAE,GAAG,OAAO,EAA6B;QAEjD,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAA;QACrC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,iBAAiB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;QACvD,CAAC;QAED,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI;aAC3B,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC;aACvC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACf,IAAI,KAAK,YAAY,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;gBAC5C,MAAM,IAAI,mBAAmB,CAAC,mBAAmB,EAAE,cAAc,EAAE;oBACjE,KAAK;iBACN,CAAC,CAAA;YACJ,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,mBAAmB,CAC3B,6BAA6B,EAC7B,cAAc,EACd,EAAE,KAAK,EAAE,CACV,CAAA;YACH,CAAC;QACH,CAAC,CAAC,CAAA;QAEJ,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAA;QAElD,IAAI,OAAO,GAAG,KAAK,WAAW,EAAE,CAAC;YAC/B,sEAAsE;YACtE,yEAAyE;YACzE,+DAA+D;YAC/D,yEAAyE;YACzE,mBAAmB;YACnB,MAAM,IAAI,mBAAmB,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAA;QAClE,CAAC;QACD,IAAI,OAAO,GAAG,KAAK,WAAW,EAAE,CAAC;YAC/B,wDAAwD;YACxD,8CAA8C;YAC9C,MAAM,IAAI,mBAAmB,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAA;QAClE,CAAC;QACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,mBAAmB,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAA;QAClE,CAAC;QACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACvD,MAAM,IAAI,mBAAmB,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAA;QAClE,CAAC;QACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAK,WAAW,EAAE,CAAC;YAC1D,MAAM,IAAI,mBAAmB,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAA;QAClE,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAY,CAAC,EAAE,CAAC;YAC1D,MAAM,IAAI,mBAAmB,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAA;QAClE,CAAC;QAED,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAU,EAAE,CAAA;IAC7C,CAAC;IAES,KAAK,CAAC,gBAAgB,CAC9B,GAAoB,EACpB,IAAyB;QAEzB,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAA;QACtC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,iBAAiB,CAAC,aAAa,EAAE,YAAY,CAAC,CAAA;QAC1D,CAAC;QAED,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;QAC9B,MAAM,OAAO,GAAG,MAAM,gBAAgB,CACpC,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,EAAE;YAC1B,IAAI,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzC,MAAM,IAAI,iBAAiB,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAA;YACjE,CAAC;YACD,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YACvC,MAAM,KAAK,GACT,SAAS,KAAK,iBAAiB,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAA;YAC/D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,CAAA;YACnE,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,iBAAiB,CAAC,2BAA2B,CAAC,CAAA;YAC1D,CAAC;YACD,MAAM,SAAS,GAAG,uBAAuB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;YACxD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,iBAAiB,CAAC,+BAA+B,CAAC,CAAA;YAC9D,CAAC;YACD,MAAM,MAAM,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAA;YAChD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,iBAAiB,CAAC,+BAA+B,CAAC,CAAA;YAC9D,CAAC;YACD,OAAO,MAAM,CAAA;QACf,CAAC,CACF,CAAA;QACD,IACE,OAAO,CAAC,GAAG,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG;YAC7B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,KAAK,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,EAC3D,CAAC;YACD,MAAM,IAAI,iBAAiB,CACzB,yCAAyC,EACzC,gBAAgB,CACjB,CAAA;QACH,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC;CACF;AAED,UAAU;AACV,YAAY;AAEZ,MAAM,UAAU,aAAa,CAC3B,IAA2E,EAC3E,GAAW;IAEX,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACtB,OAAO,KAAK,CAAA;IACd,CAAC;SAAM,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;QACnD,OAAO,IAAI,CAAA;IACb,CAAC;SAAM,CAAC;QACN,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,KAAK,GAAG,CAAA;IACrC,CAAC;AACH,CAAC;AAED,IAAK,QAIJ;AAJD,WAAK,QAAQ;IACX,2BAAe,CAAA;IACf,6BAAiB,CAAA;IACjB,yBAAa,CAAA;AACf,CAAC,EAJI,QAAQ,KAAR,QAAQ,QAIZ;AAED,MAAM,wBAAwB,GAAG,CAC/B,GAAoB,EAC4B,EAAE;IAClD,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;IAClD,IAAI,CAAC,aAAa;QAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IAEjC,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACvC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,mBAAmB,CAC3B,gCAAgC,EAChC,cAAc,CACf,CAAA;IACH,CAAC;IAED,yCAAyC;IACzC,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;IAExC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAC1E,IAAI,IAAI;QAAE,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;IAElC,MAAM,IAAI,mBAAmB,CAC3B,mCAAmC,MAAM,CAAC,CAAC,CAAC,EAAE,EAC9C,cAAc,CACf,CAAA;AACH,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,uBAAuB,GAAG,CAAC,GAAoB,EAAW,EAAE;IAChE,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAA;IACrC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAA;IACxB,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IACrC,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,CAAA;AAC/B,CAAC,CAAA;AAED,MAAM,eAAe,GAAG,CAAC,GAAoB,EAAmB,EAAE;IAChE,MAAM,CAAC,IAAI,CAAC,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAA;IAC5C,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,GAAoB,EAAE,EAAE;IACzD,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAA;IACnD,OAAO,IAAI,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA;AAChD,CAAC,CAAA;AAED,MAAM,cAAc,GAAG,CACrB,GAAoB,EAC2B,EAAE;IACjD,IAAI,CAAC;QACH,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAA;QACjD,IAAI,IAAI,KAAK,QAAQ,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA;QACxC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;QAC3D,qEAAqE;QACrE,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAClC,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;QAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;QACxC,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;QACzC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAA;IAC/B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAAc,EAAa,EAAE;IACjE,OAAO,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;AAC7C,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,YAAoB,EAAa,EAAE;IACvE,2EAA2E;IAC3E,MAAM,KAAK,GACT,SAAS,CAAC,eAAe,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;IACnE,OAAO,eAAe,CAAC;QACrB,MAAM,EAAE,KAAK;QACb,GAAG,EAAE;YACH,GAAG,EAAE,IAAI;YACT,GAAG,EAAE,WAAW;YAChB,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;YAC3D,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;SAC7D;KACF,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,SAAS,cAAc,CAAC,GAAmB;IACzC,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,SAAS,CAAC,CAAA;IACzC,UAAU,CAAC,GAAG,EAAE,eAAe,CAAC,CAAA;AAClC,CAAC","sourcesContent":["import { type KeyObject, createPublicKey, createSecretKey } from 'node:crypto'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport { secp256k1 } from '@noble/curves/secp256k1'\nimport * as jose from 'jose'\nimport { getVerificationMaterial } from '@atproto/common'\nimport { type IdResolver, getDidKeyFromMultibase } from '@atproto/identity'\nimport {\n type AtIdentifierString,\n type DidString,\n isDidString,\n} from '@atproto/lex'\nimport {\n OAuthError,\n WWWAuthenticateError,\n} from '@atproto/oauth-provider/errors'\nimport type {\n OAuthVerifier,\n VerifyTokenPayloadOptions,\n} from '@atproto/oauth-provider/verifier'\nimport {\n type ScopePermissions,\n ScopePermissionsTransition,\n} from '@atproto/oauth-scopes'\nimport {\n AuthRequiredError,\n type Awaitable,\n ForbiddenError,\n InvalidRequestError,\n type MethodAuthContext,\n type MethodAuthVerifier,\n type Params,\n XRPCError,\n parseReqNsid,\n verifyJwt as verifyServiceJwt,\n} from '@atproto/xrpc-server'\nimport type { AccountManager } from './account-manager/account-manager.js'\nimport type { ActorAccount } from './account-manager/helpers/account.js'\nimport type {\n AccessOutput,\n AdminTokenOutput,\n ModServiceOutput,\n OAuthOutput,\n RefreshOutput,\n UnauthenticatedOutput,\n UserServiceAuthOutput,\n} from './auth-output.js'\nimport { ACCESS_STANDARD, AuthScope, isAuthScope } from './auth-scope.js'\nimport { softDeleted } from './db/index.js'\nimport { appendVary } from './util/http.js'\nimport type { WithRequired } from './util/types.js'\n\nexport type VerifiedOptions = {\n checkTakedown?: boolean\n checkDeactivated?: boolean\n}\n\nexport type ScopedOptions<S extends AuthScope = AuthScope> = {\n scopes?: readonly S[]\n}\n\nexport type ExtraScopedOptions<S extends AuthScope = AuthScope> = {\n additional?: readonly S[]\n}\n\nexport type AuthorizedOptions<P extends Params = Params> = {\n authorize: (\n permissions: ScopePermissions,\n ctx: MethodAuthContext<P>,\n ) => Awaitable<void>\n}\n\nexport type AuthVerifierOpts = {\n publicUrl: string\n jwtKey: KeyObject\n adminPass: string\n dids: {\n pds: string\n entryway?: string\n modService?: string\n }\n}\n\nexport type VerifyBearerJwtOptions<S extends AuthScope = AuthScope> =\n WithRequired<\n Omit<jose.JWTVerifyOptions, 'scopes'> & {\n scopes: readonly S[]\n },\n 'audience' | 'typ'\n >\n\nexport type VerifyBearerJwtResult<S extends AuthScope = AuthScope> = {\n sub: DidString\n aud: string\n jti: string | undefined\n scope: S\n}\n\nexport class AuthVerifier {\n private _publicUrl: string\n private _jwtKey: KeyObject\n private _adminPass: string\n public dids: AuthVerifierOpts['dids']\n\n constructor(\n public accountManager: AccountManager,\n public idResolver: IdResolver,\n public oauthVerifier: OAuthVerifier,\n opts: AuthVerifierOpts,\n ) {\n this._publicUrl = opts.publicUrl\n this._jwtKey = opts.jwtKey\n this._adminPass = opts.adminPass\n this.dids = opts.dids\n }\n\n // verifiers (arrow fns to preserve scope)\n\n public unauthenticated: MethodAuthVerifier<UnauthenticatedOutput> = (ctx) => {\n setAuthHeaders(ctx.res)\n\n // @NOTE this auth method is typically used as fallback when no other auth\n // method is applicable. This means that the presence of an \"authorization\"\n // header means that that header is invalid (as it did not match any of the\n // other auth methods).\n if (ctx.req.headers['authorization']) {\n throw new AuthRequiredError('Invalid authorization header')\n }\n\n return {\n credentials: null,\n }\n }\n\n /** @deprecated We are steering away from this auth method */\n public adminToken: MethodAuthVerifier<AdminTokenOutput> = async (ctx) => {\n setAuthHeaders(ctx.res)\n const parsed = parseBasicAuth(ctx.req)\n if (!parsed) {\n throw new AuthRequiredError()\n }\n const { username, password } = parsed\n if (username !== 'admin' || password !== this._adminPass) {\n throw new AuthRequiredError()\n }\n\n return { credentials: { type: 'admin_token' } }\n }\n\n public modService: MethodAuthVerifier<ModServiceOutput> = async (ctx) => {\n setAuthHeaders(ctx.res)\n if (!this.dids.modService) {\n throw new AuthRequiredError('Untrusted issuer', 'UntrustedIss')\n }\n const payload = await this.verifyServiceJwt(ctx.req, {\n iss: [this.dids.modService, `${this.dids.modService}#atproto_labeler`],\n })\n return {\n credentials: {\n type: 'mod_service',\n did: payload.iss,\n },\n }\n }\n\n /** @deprecated We are steering away from {@link adminToken} auth. Use {@link modService} instead. */\n public moderator: MethodAuthVerifier<AdminTokenOutput | ModServiceOutput> =\n async (ctx) => {\n const type = extractAuthType(ctx.req)\n if (type === AuthType.BEARER) {\n return this.modService(ctx)\n } else {\n return this.adminToken(ctx)\n }\n }\n\n protected access<S extends AuthScope>(\n options: VerifiedOptions & Required<ScopedOptions<S>>,\n ): MethodAuthVerifier<AccessOutput<S>> {\n const { scopes, ...statusOptions } = options\n\n const verifyJwtOptions: VerifyBearerJwtOptions<S> = {\n audience: this.dids.pds,\n typ: 'at+jwt',\n scopes:\n // @NOTE We can reject taken down credentials based on the scope if\n // \"checkTakedown\" is set.\n statusOptions.checkTakedown && scopes.includes(AuthScope.Takendown as S)\n ? scopes.filter((s) => s !== AuthScope.Takendown)\n : scopes,\n }\n\n return async (ctx) => {\n setAuthHeaders(ctx.res)\n\n const { sub: did, scope } = await this.verifyBearerJwt(\n ctx.req,\n verifyJwtOptions,\n )\n\n await this.verifyStatus(did, statusOptions)\n\n return {\n credentials: { type: 'access', did, scope },\n }\n }\n }\n\n public refresh(options?: {\n allowExpired?: boolean\n }): MethodAuthVerifier<RefreshOutput> {\n const verifyOptions: VerifyBearerJwtOptions<AuthScope.Refresh> = {\n clockTolerance: options?.allowExpired ? Infinity : undefined,\n typ: 'refresh+jwt',\n // when using entryway, proxying refresh credentials\n audience: this.dids.entryway ? this.dids.entryway : this.dids.pds,\n scopes: [AuthScope.Refresh],\n }\n\n return async (ctx) => {\n setAuthHeaders(ctx.res)\n\n const result = await this.verifyBearerJwt(ctx.req, verifyOptions)\n\n const tokenId = result.jti\n if (!tokenId) {\n throw new AuthRequiredError(\n 'Unexpected missing refresh token id',\n 'MissingTokenId',\n )\n }\n\n return {\n credentials: {\n type: 'refresh',\n did: result.sub,\n scope: result.scope,\n tokenId,\n },\n }\n }\n }\n\n public authorization<P extends Params>({\n scopes = ACCESS_STANDARD,\n additional = [],\n ...options\n }: VerifiedOptions &\n ScopedOptions &\n ExtraScopedOptions &\n AuthorizedOptions<P>): MethodAuthVerifier<AccessOutput | OAuthOutput, P> {\n const access = this.access({\n ...options,\n scopes: [...scopes, ...additional],\n })\n const oauth = this.oauth(options)\n\n return async (ctx) => {\n const type = extractAuthType(ctx.req)\n\n if (type === AuthType.BEARER) {\n return access(ctx)\n }\n\n if (type === AuthType.DPOP) {\n return oauth(ctx)\n }\n\n // Auth headers are set through the access and oauth methods so we only\n // need to set them here if we reach this point\n setAuthHeaders(ctx.res)\n\n if (type !== null) {\n throw new InvalidRequestError(\n 'Unexpected authorization type',\n 'InvalidToken',\n )\n }\n\n throw new AuthRequiredError(undefined, 'AuthMissing')\n }\n }\n\n public authorizationOrModService<P extends Params>(\n opts: VerifiedOptions & ExtraScopedOptions & AuthorizedOptions<P>,\n ): MethodAuthVerifier<AccessOutput | OAuthOutput | ModServiceOutput, P> {\n const authorization = this.authorization(opts)\n return async (ctx) => {\n try {\n return await this.modService(ctx)\n } catch (err) {\n if (err instanceof AuthRequiredError) {\n return authorization(ctx)\n }\n throw err\n }\n }\n }\n\n public authorizationOrAdminTokenOptional<P extends Params>(\n opts: VerifiedOptions & ExtraScopedOptions & AuthorizedOptions<P>,\n ): MethodAuthVerifier<\n OAuthOutput | AccessOutput | AdminTokenOutput | UnauthenticatedOutput,\n P\n > {\n const authorization = this.authorization(opts)\n return async (ctx) => {\n const type = extractAuthType(ctx.req)\n if (type === AuthType.BEARER || type === AuthType.DPOP) {\n return authorization(ctx)\n } else if (type === AuthType.BASIC) {\n return this.adminToken(ctx)\n } else {\n return this.unauthenticated(ctx)\n }\n }\n }\n\n public userServiceAuth: MethodAuthVerifier<UserServiceAuthOutput> = async (\n ctx,\n ) => {\n setAuthHeaders(ctx.res)\n const payload = await this.verifyServiceJwt(ctx.req)\n return {\n credentials: {\n type: 'user_service_auth',\n did: payload.iss,\n },\n }\n }\n\n public userServiceAuthOptional: MethodAuthVerifier<\n UserServiceAuthOutput | UnauthenticatedOutput\n > = async (ctx) => {\n const type = extractAuthType(ctx.req)\n if (type === AuthType.BEARER) {\n return await this.userServiceAuth(ctx)\n } else {\n return this.unauthenticated(ctx)\n }\n }\n\n public authorizationOrUserServiceAuth<P extends Params>(\n options: VerifiedOptions &\n ScopedOptions &\n ExtraScopedOptions &\n AuthorizedOptions<P>,\n ): MethodAuthVerifier<UserServiceAuthOutput | OAuthOutput | AccessOutput, P> {\n const authorizationVerifier = this.authorization(options)\n return async (ctx) => {\n if (isDefinitelyServiceAuth(ctx.req)) {\n return this.userServiceAuth(ctx)\n } else {\n return authorizationVerifier(ctx)\n }\n }\n }\n\n protected oauth<P extends Params>({\n authorize,\n ...verifyStatusOptions\n }: VerifiedOptions & AuthorizedOptions<P>): MethodAuthVerifier<\n OAuthOutput,\n P\n > {\n const verifyTokenOptions: VerifyTokenPayloadOptions = {\n audience: [this.dids.pds],\n scope: ['atproto'],\n }\n\n return async (ctx) => {\n setAuthHeaders(ctx.res)\n\n const { req, res } = ctx\n\n // https://datatracker.ietf.org/doc/html/rfc9449#section-8.2\n const dpopNonce = this.oauthVerifier.nextDpopNonce()\n if (dpopNonce) {\n res.setHeader('DPoP-Nonce', dpopNonce)\n res.appendHeader('Access-Control-Expose-Headers', 'DPoP-Nonce')\n }\n\n const originalUrl = req.originalUrl || req.url || '/'\n const url = new URL(originalUrl, this._publicUrl)\n\n const { scope, sub: did } = await this.oauthVerifier\n .authenticateRequest(\n req.method || 'GET',\n url,\n req.headers,\n verifyTokenOptions,\n )\n .catch((err) => {\n // Make sure to include any WWW-Authenticate header in the response\n // (particularly useful for DPoP's \"use_dpop_nonce\" error)\n if (err instanceof WWWAuthenticateError) {\n res.setHeader('WWW-Authenticate', err.wwwAuthenticateHeader)\n res.appendHeader(\n 'Access-Control-Expose-Headers',\n 'WWW-Authenticate',\n )\n }\n\n if (err instanceof OAuthError) {\n throw new XRPCError(err.status, err.error_description, err.error)\n }\n\n throw err\n })\n\n if (!isDidString(did)) {\n throw new InvalidRequestError('Malformed token', 'InvalidToken')\n }\n\n await this.verifyStatus(did, verifyStatusOptions)\n\n const permissions = new ScopePermissionsTransition(scope?.split(' '))\n\n // Should never happen\n if (!permissions.scopes.has('atproto')) {\n throw new InvalidRequestError(\n 'OAuth token does not have \"atproto\" scope',\n 'InvalidToken',\n )\n }\n\n await authorize(permissions, ctx)\n\n return {\n credentials: {\n type: 'oauth',\n did,\n permissions,\n },\n }\n }\n }\n\n protected async verifyStatus(\n did: DidString,\n options: VerifiedOptions,\n ): Promise<void> {\n if (options.checkDeactivated || options.checkTakedown) {\n await this.findAccount(did, options)\n }\n }\n\n /**\n * Finds an account by its handle or DID, returning possibly deactivated or\n * taken down accounts (unless `options.checkDeactivated` or\n * `options.checkTakedown` are set to true, respectively).\n */\n public async findAccount(\n handleOrDid: AtIdentifierString,\n options: VerifiedOptions,\n ): Promise<ActorAccount> {\n const account = await this.accountManager.getAccount(handleOrDid, {\n includeDeactivated: true,\n includeTakenDown: true,\n })\n if (!account) {\n // will be turned into ExpiredToken for the client if proxied by entryway\n throw new ForbiddenError('Account not found', 'AccountNotFound')\n }\n if (options.checkTakedown && softDeleted(account)) {\n throw new AuthRequiredError(\n 'Account has been taken down',\n 'AccountTakedown',\n )\n }\n if (options.checkDeactivated && account.deactivatedAt) {\n throw new AuthRequiredError(\n 'Account is deactivated',\n 'AccountDeactivated',\n )\n }\n return account\n }\n\n /**\n * Wraps {@link jose.jwtVerify} into a function that also validates the token\n * payload's type and wraps errors into {@link InvalidRequestError}.\n */\n protected async verifyBearerJwt<S extends AuthScope = AuthScope>(\n req: IncomingMessage,\n { scopes, ...options }: VerifyBearerJwtOptions<S>,\n ): Promise<VerifyBearerJwtResult<S>> {\n const token = bearerTokenFromReq(req)\n if (!token) {\n throw new AuthRequiredError(undefined, 'AuthMissing')\n }\n\n const { payload } = await jose\n .jwtVerify(token, this._jwtKey, options)\n .catch((cause) => {\n if (cause instanceof jose.errors.JWTExpired) {\n throw new InvalidRequestError('Token has expired', 'ExpiredToken', {\n cause,\n })\n } else {\n throw new InvalidRequestError(\n 'Token could not be verified',\n 'InvalidToken',\n { cause },\n )\n }\n })\n\n const { sub, aud, scope, lxm, cnf, jti } = payload\n\n if (typeof lxm !== 'undefined') {\n // Service auth tokens should never make it to here. But since service\n // auth tokens do not have a \"typ\" header, the \"typ\" check above will not\n // catch them. This check here is mainly to protect against the\n // hypothetical case in which a PDS would issue service auth tokens using\n // its private key.\n throw new InvalidRequestError('Malformed token', 'InvalidToken')\n }\n if (typeof cnf !== 'undefined') {\n // Proof-of-Possession (PoP) tokens are not allowed here\n // https://www.rfc-editor.org/rfc/rfc7800.html\n throw new InvalidRequestError('Malformed token', 'InvalidToken')\n }\n if (typeof sub !== 'string' || !isDidString(sub)) {\n throw new InvalidRequestError('Malformed token', 'InvalidToken')\n }\n if (typeof aud !== 'string' || !aud.startsWith('did:')) {\n throw new InvalidRequestError('Malformed token', 'InvalidToken')\n }\n if (typeof jti !== 'string' && typeof jti !== 'undefined') {\n throw new InvalidRequestError('Malformed token', 'InvalidToken')\n }\n if (!isAuthScope(scope) || !scopes.includes(scope as any)) {\n throw new InvalidRequestError('Bad token scope', 'InvalidToken')\n }\n\n return { sub, aud, jti, scope: scope as S }\n }\n\n protected async verifyServiceJwt(\n req: IncomingMessage,\n opts?: { iss?: string[] },\n ) {\n const jwtStr = bearerTokenFromReq(req)\n if (!jwtStr) {\n throw new AuthRequiredError('missing jwt', 'MissingJwt')\n }\n\n const nsid = parseReqNsid(req)\n const payload = await verifyServiceJwt(\n jwtStr,\n null,\n nsid,\n async (iss, forceRefresh) => {\n if (opts?.iss && !opts.iss.includes(iss)) {\n throw new AuthRequiredError('Untrusted issuer', 'UntrustedIss')\n }\n const [did, serviceId] = iss.split('#')\n const keyId =\n serviceId === 'atproto_labeler' ? 'atproto_label' : 'atproto'\n const didDoc = await this.idResolver.did.resolve(did, forceRefresh)\n if (!didDoc) {\n throw new AuthRequiredError('could not resolve iss did')\n }\n const parsedKey = getVerificationMaterial(didDoc, keyId)\n if (!parsedKey) {\n throw new AuthRequiredError('missing or bad key in did doc')\n }\n const didKey = getDidKeyFromMultibase(parsedKey)\n if (!didKey) {\n throw new AuthRequiredError('missing or bad key in did doc')\n }\n return didKey\n },\n )\n if (\n payload.aud !== this.dids.pds &&\n (!this.dids.entryway || payload.aud !== this.dids.entryway)\n ) {\n throw new AuthRequiredError(\n 'jwt audience does not match service did',\n 'BadJwtAudience',\n )\n }\n return payload\n }\n}\n\n// HELPERS\n// ---------\n\nexport function isUserOrAdmin(\n auth: AccessOutput | OAuthOutput | AdminTokenOutput | UnauthenticatedOutput,\n did: string,\n): boolean {\n if (!auth.credentials) {\n return false\n } else if (auth.credentials.type === 'admin_token') {\n return true\n } else {\n return auth.credentials.did === did\n }\n}\n\nenum AuthType {\n BASIC = 'Basic',\n BEARER = 'Bearer',\n DPOP = 'DPoP',\n}\n\nconst parseAuthorizationHeader = (\n req: IncomingMessage,\n): [type: null] | [type: AuthType, token: string] => {\n const authorization = req.headers['authorization']\n if (!authorization) return [null]\n\n const result = authorization.split(' ')\n if (result.length !== 2) {\n throw new InvalidRequestError(\n 'Malformed authorization header',\n 'InvalidToken',\n )\n }\n\n // authorization type is case-insensitive\n const authType = result[0].toUpperCase()\n\n const type = Object.hasOwn(AuthType, authType) ? AuthType[authType] : null\n if (type) return [type, result[1]]\n\n throw new InvalidRequestError(\n `Unsupported authorization type: ${result[0]}`,\n 'InvalidToken',\n )\n}\n\n/**\n * @note Not all service auth tokens are guaranteed to have \"lxm\" claim, so this\n * function should not be used to verify service auth tokens. It is only used to\n * check if a token is definitely a service auth token.\n */\nconst isDefinitelyServiceAuth = (req: IncomingMessage): boolean => {\n const token = bearerTokenFromReq(req)\n if (!token) return false\n const payload = jose.decodeJwt(token)\n return payload['lxm'] != null\n}\n\nconst extractAuthType = (req: IncomingMessage): AuthType | null => {\n const [type] = parseAuthorizationHeader(req)\n return type\n}\n\nexport const bearerTokenFromReq = (req: IncomingMessage) => {\n const [type, token] = parseAuthorizationHeader(req)\n return type === AuthType.BEARER ? token : null\n}\n\nconst parseBasicAuth = (\n req: IncomingMessage,\n): { username: string; password: string } | null => {\n try {\n const [type, b64] = parseAuthorizationHeader(req)\n if (type !== AuthType.BASIC) return null\n const decoded = Buffer.from(b64, 'base64').toString('utf8')\n // We must not use split(':') because the password can contain colons\n const colon = decoded.indexOf(':')\n if (colon === -1) return null\n const username = decoded.slice(0, colon)\n const password = decoded.slice(colon + 1)\n return { username, password }\n } catch (err) {\n return null\n }\n}\n\nexport const createSecretKeyObject = (secret: string): KeyObject => {\n return createSecretKey(Buffer.from(secret))\n}\n\nexport const createPublicKeyObject = (publicKeyHex: string): KeyObject => {\n // accepts compressed or uncompressed keys; validates the point is on-curve\n const point =\n secp256k1.ProjectivePoint.fromHex(publicKeyHex).toRawBytes(false)\n return createPublicKey({\n format: 'jwk',\n key: {\n kty: 'EC',\n crv: 'secp256k1',\n x: Buffer.from(point.subarray(1, 33)).toString('base64url'),\n y: Buffer.from(point.subarray(33, 65)).toString('base64url'),\n },\n })\n}\n\nfunction setAuthHeaders(res: ServerResponse) {\n res.setHeader('Cache-Control', 'private')\n appendVary(res, 'Authorization')\n}\n"]}
package/dist/context.d.ts CHANGED
@@ -13,7 +13,7 @@ import { ActorStore } from './actor-store/actor-store.js';
13
13
  import { AuthVerifier } from './auth-verifier.js';
14
14
  import { BackgroundQueue } from './background.js';
15
15
  import { BskyAppView } from './bsky-app-view.js';
16
- import type { ServerConfig, ServerSecrets } from './config/index.js';
16
+ import { type ServerConfig, type ServerEnvironment, type ServerSecrets } from './config/index.js';
17
17
  import { Crawlers } from './crawlers.js';
18
18
  import { DidSqliteCache } from './did-cache/index.js';
19
19
  import { ServerMailer } from './mailer/index.js';
@@ -72,6 +72,7 @@ export declare class AppContext implements AsyncDisposable {
72
72
  plcRotationKey: crypto.Keypair;
73
73
  cfg: ServerConfig;
74
74
  constructor(opts: AppContextOptions);
75
+ static fromEnv(env?: ServerEnvironment): Promise<AppContext>;
75
76
  static fromConfig(cfg: ServerConfig, secrets: ServerSecrets, overrides?: Partial<AppContextOptions>): Promise<AppContext>;
76
77
  appviewAuthHeaders(did: string, lxm: string): Promise<{
77
78
  headers: {
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AACnC,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAGpC,OAAO,KAAK,KAAK,MAAM,MAAM,QAAQ,CAAA;AAErC,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAA;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAIL,aAAa,EACd,MAAM,kCAAkC,CAAA;AAEzC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAK9C,OAAO,EAAE,KAAK,KAAK,EAAiB,MAAM,0BAA0B,CAAA;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAA;AAGrE,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;AAEzD,OAAO,EACL,YAAY,EAGb,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACpE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAKrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAEzD,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,8BAA8B,CAAA;AAErC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAEhD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,EAAE,UAAU,CAAA;IACtB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAA;IACrC,WAAW,EAAE,kBAAkB,CAAA;IAC/B,MAAM,EAAE,YAAY,CAAA;IACpB,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,QAAQ,EAAE,cAAc,CAAA;IACxB,UAAU,EAAE,UAAU,CAAA;IACtB,SAAS,EAAE,GAAG,CAAC,MAAM,CAAA;IACrB,cAAc,EAAE,cAAc,CAAA;IAC9B,SAAS,EAAE,SAAS,CAAA;IACpB,eAAe,EAAE,eAAe,CAAA;IAChC,YAAY,CAAC,EAAE,KAAK,CAAA;IACpB,QAAQ,EAAE,QAAQ,CAAA;IAClB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,UAAU,EAAE,MAAM,CAAC,UAAU,CAAA;IAC7B,SAAS,EAAE,KAAK,CAAA;IAChB,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,YAAY,EAAE,YAAY,CAAA;IAC1B,cAAc,EAAE,MAAM,CAAC,OAAO,CAAA;IAC9B,GAAG,EAAE,YAAY,CAAA;CAClB,CAAA;AAED,qBAAa,UAAW,YAAW,eAAe;IACzC,UAAU,EAAE,UAAU,CAAA;IACtB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAA;IACrC,WAAW,EAAE,kBAAkB,CAAA;IAC/B,MAAM,EAAE,YAAY,CAAA;IACpB,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,QAAQ,EAAE,cAAc,CAAA;IACxB,UAAU,EAAE,UAAU,CAAA;IACtB,SAAS,EAAE,GAAG,CAAC,MAAM,CAAA;IACrB,cAAc,EAAE,cAAc,CAAA;IAC9B,SAAS,EAAE,SAAS,CAAA;IACpB,eAAe,EAAE,eAAe,CAAA;IAChC,YAAY,CAAC,EAAE,KAAK,CAAA;IACpB,QAAQ,EAAE,QAAQ,CAAA;IAClB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAA;IAC7B,SAAS,EAAE,KAAK,CAAA;IAChB,YAAY,EAAE,YAAY,CAAA;IAC1B,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,cAAc,EAAE,MAAM,CAAC,OAAO,CAAA;IAC9B,GAAG,EAAE,YAAY,CAAA;IAExB,YAAY,IAAI,EAAE,iBAAiB,EAyBlC;IAED,OAAa,UAAU,CACrB,GAAG,EAAE,YAAY,EACjB,OAAO,EAAE,aAAa,EACtB,SAAS,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,GACrC,OAAO,CAAC,UAAU,CAAC,CA8XrB;IAEK,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;;;;OAGhD;IAEK,mBAAmB,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;;OAQvE;IAED,uBAAuB,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO;;MAE3C;IAEK,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;;;;OAQ7D;IAEK,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,mBAQzD;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAkB7B;IAEK,CAAC,MAAM,CAAC,YAAY,CAAC,kBAE1B;CACF;eAUc,UAAU"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
package/dist/context.js CHANGED
@@ -18,6 +18,7 @@ import { authPassthru, forwardedFor } from './api/proxy.js';
18
18
  import { AuthVerifier, createPublicKeyObject, createSecretKeyObject, } from './auth-verifier.js';
19
19
  import { BackgroundQueue } from './background.js';
20
20
  import { BskyAppView } from './bsky-app-view.js';
21
+ import { envToCfg, envToSecrets, readEnv, } from './config/index.js';
21
22
  import { Crawlers } from './crawlers.js';
22
23
  import { DidSqliteCache } from './did-cache/index.js';
23
24
  import { DiskBlobStore } from './disk-blobstore.js';
@@ -57,6 +58,11 @@ export class AppContext {
57
58
  this.plcRotationKey = opts.plcRotationKey;
58
59
  this.cfg = opts.cfg;
59
60
  }
61
+ static async fromEnv(env = readEnv()) {
62
+ const cfg = envToCfg(env);
63
+ const secrets = envToSecrets(env);
64
+ return AppContext.fromConfig(cfg, secrets);
65
+ }
60
66
  static async fromConfig(cfg, secrets, overrides) {
61
67
  // @TODO Implement using an AsyncDisposableStack
62
68
  const blobstore = cfg.blobstore.provider === 's3'
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport * as plc from '@did-plc/lib'\nimport type express from 'express'\nimport type { Redis } from 'ioredis'\nimport * as nodemailer from 'nodemailer'\nimport * as ui8 from 'uint8arrays'\nimport type * as undici from 'undici'\nimport { KmsKeypair, S3BlobStore } from '@atproto/aws'\nimport * as crypto from '@atproto/crypto'\nimport { IdResolver } from '@atproto/identity'\nimport { Client } from '@atproto/lex'\nimport {\n AccessTokenMode,\n JoseKey,\n LexResolver,\n OAuthProvider,\n} from '@atproto/oauth-provider/provider'\nimport { OAuthVerifier } from '@atproto/oauth-provider/verifier'\nimport type { BlobStore } from '@atproto/repo'\nimport {\n createServiceAuthHeaders,\n createServiceJwt,\n} from '@atproto/xrpc-server'\nimport { type Fetch, safeFetchWrap } from '@atproto-labs/fetch-node'\nimport { AccountManager } from './account-manager/account-manager.js'\nimport { OAuthStore } from './account-manager/oauth-store.js'\nimport { ScopeReferenceGetter } from './account-manager/scope-reference-getter.js'\nimport { ActorStore } from './actor-store/actor-store.js'\nimport { authPassthru, forwardedFor } from './api/proxy.js'\nimport {\n AuthVerifier,\n createPublicKeyObject,\n createSecretKeyObject,\n} from './auth-verifier.js'\nimport { BackgroundQueue } from './background.js'\nimport { BskyAppView } from './bsky-app-view.js'\nimport type { ServerConfig, ServerSecrets } from './config/index.js'\nimport { Crawlers } from './crawlers.js'\nimport { DidSqliteCache } from './did-cache/index.js'\nimport { DiskBlobStore } from './disk-blobstore.js'\nimport { events } from './events.js'\nimport { ImageUrlBuilder } from './image/image-url-builder.js'\nimport { fetchLogger, lexiconResolverLogger, oauthLogger } from './logger.js'\nimport { ServerMailer } from './mailer/index.js'\nimport { ModerationMailer } from './mailer/moderation.js'\nimport { buildProxyAgent } from './pipethrough.js'\nimport {\n LocalViewer,\n type LocalViewerCreator,\n} from './read-after-write/viewer.js'\nimport { getRedisClient } from './redis.js'\nimport { Sequencer } from './sequencer/index.js'\n\nexport type AppContextOptions = {\n actorStore: ActorStore\n blobstore: (did: string) => BlobStore\n localViewer: LocalViewerCreator\n mailer: ServerMailer\n moderationMailer: ModerationMailer\n didCache: DidSqliteCache\n idResolver: IdResolver\n plcClient: plc.Client\n accountManager: AccountManager\n sequencer: Sequencer\n backgroundQueue: BackgroundQueue\n redisScratch?: Redis\n crawlers: Crawlers\n bskyAppView?: BskyAppView\n moderationClient?: Client\n reportingClient?: Client\n entrywayClient?: Client\n entrywayAdminClient?: Client\n proxyAgent: undici.Dispatcher\n safeFetch: Fetch\n oauthProvider?: OAuthProvider\n authVerifier: AuthVerifier\n plcRotationKey: crypto.Keypair\n cfg: ServerConfig\n}\n\nexport class AppContext implements AsyncDisposable {\n public actorStore: ActorStore\n public blobstore: (did: string) => BlobStore\n public localViewer: LocalViewerCreator\n public mailer: ServerMailer\n public moderationMailer: ModerationMailer\n public didCache: DidSqliteCache\n public idResolver: IdResolver\n public plcClient: plc.Client\n public accountManager: AccountManager\n public sequencer: Sequencer\n public backgroundQueue: BackgroundQueue\n public redisScratch?: Redis\n public crawlers: Crawlers\n public bskyAppView?: BskyAppView\n public moderationClient: Client | undefined\n public reportingClient: Client | undefined\n public entrywayClient: Client | undefined\n public entrywayAdminClient: Client | undefined\n public proxyAgent: undici.Dispatcher\n public safeFetch: Fetch\n public authVerifier: AuthVerifier\n public oauthProvider?: OAuthProvider\n public plcRotationKey: crypto.Keypair\n public cfg: ServerConfig\n\n constructor(opts: AppContextOptions) {\n this.actorStore = opts.actorStore\n this.blobstore = opts.blobstore\n this.localViewer = opts.localViewer\n this.mailer = opts.mailer\n this.moderationMailer = opts.moderationMailer\n this.didCache = opts.didCache\n this.idResolver = opts.idResolver\n this.plcClient = opts.plcClient\n this.accountManager = opts.accountManager\n this.sequencer = opts.sequencer\n this.backgroundQueue = opts.backgroundQueue\n this.redisScratch = opts.redisScratch\n this.crawlers = opts.crawlers\n this.bskyAppView = opts.bskyAppView\n this.moderationClient = opts.moderationClient\n this.reportingClient = opts.reportingClient\n this.entrywayClient = opts.entrywayClient\n this.entrywayAdminClient = opts.entrywayAdminClient\n this.proxyAgent = opts.proxyAgent\n this.safeFetch = opts.safeFetch\n this.authVerifier = opts.authVerifier\n this.oauthProvider = opts.oauthProvider\n this.plcRotationKey = opts.plcRotationKey\n this.cfg = opts.cfg\n }\n\n static async fromConfig(\n cfg: ServerConfig,\n secrets: ServerSecrets,\n overrides?: Partial<AppContextOptions>,\n ): Promise<AppContext> {\n // @TODO Implement using an AsyncDisposableStack\n\n const blobstore =\n cfg.blobstore.provider === 's3'\n ? S3BlobStore.creator({\n bucket: cfg.blobstore.bucket,\n region: cfg.blobstore.region,\n endpoint: cfg.blobstore.endpoint,\n forcePathStyle: cfg.blobstore.forcePathStyle,\n credentials: cfg.blobstore.credentials,\n uploadTimeoutMs: cfg.blobstore.uploadTimeoutMs,\n requestTimeoutMs: cfg.blobstore.requestTimeoutMs,\n })\n : DiskBlobStore.creator(\n cfg.blobstore.location,\n cfg.blobstore.tempLocation,\n )\n\n const mailTransport =\n cfg.email !== null\n ? nodemailer.createTransport(cfg.email.smtpUrl)\n : nodemailer.createTransport({ jsonTransport: true })\n\n const mailer = new ServerMailer(mailTransport, cfg.email, cfg.branding)\n\n const modMailTransport =\n cfg.moderationEmail !== null\n ? nodemailer.createTransport(cfg.moderationEmail.smtpUrl)\n : nodemailer.createTransport({ jsonTransport: true })\n\n const moderationMailer = new ModerationMailer(modMailTransport, cfg)\n\n const didCache = new DidSqliteCache(\n cfg.db.didCacheDbLoc,\n cfg.identity.cacheStaleTTL,\n cfg.identity.cacheMaxTTL,\n cfg.db.disableWalAutoCheckpoint,\n )\n await didCache.migrateOrThrow()\n\n const idResolver = new IdResolver({\n plcUrl: cfg.identity.plcUrl,\n didCache,\n timeout: cfg.identity.resolverTimeout,\n backupNameservers: cfg.identity.handleBackupNameservers,\n })\n const plcClient = new plc.Client(cfg.identity.plcUrl)\n\n const backgroundQueue = new BackgroundQueue(undefined, { concurrency: 5 })\n const crawlers = new Crawlers(\n backgroundQueue,\n cfg.service.hostname,\n cfg.crawlers,\n )\n const sequencer = new Sequencer(\n cfg.db.sequencerDbLoc,\n crawlers,\n undefined,\n cfg.db.disableWalAutoCheckpoint,\n )\n const redisScratch = cfg.redis\n ? getRedisClient(cfg.redis.address, cfg.redis.password)\n : undefined\n\n const bskyAppView = cfg.bskyAppView\n ? new BskyAppView({\n ...cfg.bskyAppView,\n validateResponse: cfg.service.devMode,\n })\n : undefined\n\n const moderationClient = cfg.modService\n ? new Client(\n { service: cfg.modService.url },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: cfg.service.devMode,\n },\n )\n : undefined\n const reportingClient = cfg.reportService\n ? new Client(\n { service: cfg.reportService.url },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: cfg.service.devMode,\n },\n )\n : undefined\n const entrywayClient = cfg.entryway\n ? new Client(\n { service: cfg.entryway.url },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: cfg.service.devMode,\n },\n )\n : undefined\n const entrywayAdminClient =\n cfg.entryway && secrets.entrywayAdminToken\n ? new Client(\n {\n service: cfg.entryway.url,\n headers: {\n authorization: basicAuthHeader(\n 'admin',\n secrets.entrywayAdminToken,\n ),\n },\n },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: cfg.service.devMode,\n },\n )\n : undefined\n\n const jwtSecretKey = createSecretKeyObject(secrets.jwtSecret)\n const jwtPublicKey = cfg.entryway\n ? createPublicKeyObject(cfg.entryway.jwtPublicKeyHex)\n : null\n\n const imageUrlBuilder = new ImageUrlBuilder(\n cfg.service.hostname,\n bskyAppView,\n )\n\n const actorStore = new ActorStore(cfg.actorStore, {\n blobstore,\n backgroundQueue,\n })\n\n const plcRotationKey =\n secrets.plcRotationKey.provider === 'kms'\n ? await KmsKeypair.load({\n keyId: secrets.plcRotationKey.keyId,\n })\n : await crypto.Secp256k1Keypair.import(\n secrets.plcRotationKey.privateKeyHex,\n )\n\n const accountManager = new AccountManager(\n cfg,\n actorStore,\n idResolver,\n jwtSecretKey,\n mailer,\n sequencer,\n plcClient,\n plcRotationKey,\n )\n await accountManager.migrateOrThrow()\n\n const localViewer = LocalViewer.creator(\n accountManager,\n imageUrlBuilder,\n bskyAppView,\n )\n\n // An agent for performing HTTP requests based on user provided URLs.\n const proxyAgent = buildProxyAgent(cfg.proxy)\n\n /**\n * A fetch() function that protects against SSRF attacks, large responses &\n * known bad domains. This function can safely be used to fetch user\n * provided URLs (unless \"disableSsrfProtection\" is true, of course).\n *\n * @note **DO NOT** wrap `safeFetch` with any logging or other transforms as\n * this might prevent the use of explicit `redirect: \"follow\"` init from\n * working. See {@link safeFetchWrap}.\n */\n const safeFetch = safeFetchWrap({\n allowIpHost: false,\n allowImplicitRedirect: false,\n responseMaxSize: cfg.fetch.maxResponseSize,\n ssrfProtection: !cfg.fetch.disableSsrfProtection,\n\n fetch: function (input, init) {\n const method =\n init?.method ?? (input instanceof Request ? input.method : 'GET')\n const uri = input instanceof Request ? input.url : String(input)\n\n fetchLogger.info({ method, uri }, 'fetch')\n\n return globalThis.fetch.call(this, input, init)\n },\n })\n\n const oauthProvider = cfg.oauth.provider\n ? new OAuthProvider({\n issuer: cfg.oauth.issuer,\n keyset: [await JoseKey.fromKeyLike(jwtSecretKey, undefined, 'HS256')],\n store: new OAuthStore(\n accountManager,\n actorStore,\n imageUrlBuilder,\n backgroundQueue,\n mailer,\n sequencer,\n plcClient,\n plcRotationKey,\n cfg.service.publicUrl,\n cfg.identity.recoveryDidKey,\n ),\n redis: redisScratch,\n dpopSecret: secrets.dpopSecret,\n inviteCodeRequired: cfg.invites.required,\n availableUserDomains: cfg.identity.serviceHandleDomains,\n hcaptcha: cfg.oauth.provider.hcaptcha,\n branding: cfg.oauth.provider.branding,\n safeFetch,\n lexResolver: new LexResolver({\n fetch: safeFetch,\n plcDirectoryUrl: cfg.identity.plcUrl,\n hooks: {\n onResolveAuthority: ({ nsid }) => {\n lexiconResolverLogger.debug(\n { nsid: nsid.toString() },\n 'Resolving lexicon DID authority',\n )\n // Override the lexicon did resolution to point to a custom PDS\n return cfg.lexicon.didAuthority\n },\n onResolveAuthorityResult({ nsid, did }) {\n lexiconResolverLogger.info(\n { nsid: nsid.toString(), did },\n 'Resolved lexicon DID',\n )\n },\n onResolveAuthorityError({ nsid, err }) {\n lexiconResolverLogger.error(\n { nsid: nsid.toString(), err },\n 'Lexicon DID resolution error',\n )\n },\n onFetchResult({ uri, cid }) {\n lexiconResolverLogger.info(\n { uri: uri.toString(), cid: cid.toString() },\n 'Fetched lexicon',\n )\n },\n onFetchError({ err, uri }) {\n lexiconResolverLogger.error(\n { uri: uri.toString(), err },\n 'Lexicon fetch error',\n )\n },\n },\n }),\n metadata: {\n protected_resources: [new URL(cfg.oauth.issuer).origin],\n },\n // If the PDS is both an authorization server & resource server (no\n // entryway), we can afford to check the token validity on every\n // request. This allows revoked tokens to be rejected immediately.\n // This also allows JWT to be shorter since some claims (notably the\n // \"scope\" claim) do not need to be included in the token.\n accessTokenMode: AccessTokenMode.stateful,\n\n getClientInfo(clientId) {\n return {\n isTrusted: cfg.oauth.provider?.trustedClients?.includes(clientId),\n }\n },\n onSignedUp({ account, data, clientId }) {\n events.accountCreated({\n source: 'oauth',\n did: account.did,\n clientId,\n invited: data.inviteCode != null,\n deactivated: false,\n })\n },\n onSignedIn({ account, clientId }) {\n events.signedIn({\n did: account.did,\n clientId,\n })\n },\n onAuthorized({ account, client }) {\n events.oauthAuthorized({\n did: account.did,\n clientId: client.id,\n clientFirstParty: client.isFirstParty,\n clientTrusted: client.isTrusted,\n clientConfidential: client.isConfidential,\n })\n },\n onTokenCreated({ account, client }) {\n events.sessionCreated({\n source: 'oauth',\n did: account.did,\n clientId: client.id,\n })\n },\n onTokenRefreshed({ account, client }) {\n events.sessionRefreshed({\n source: 'oauth',\n did: account.did,\n clientId: client.id,\n })\n },\n })\n : undefined\n\n const scopeRefGetter = entrywayClient\n ? new ScopeReferenceGetter(entrywayClient, redisScratch)\n : undefined\n\n const oauthVerifier: OAuthVerifier =\n oauthProvider ?? // OAuthProvider extends OAuthVerifier\n new OAuthVerifier({\n issuer: cfg.oauth.issuer,\n keyset: [await JoseKey.fromKeyLike(jwtPublicKey!, undefined, 'ES256K')],\n dpopSecret: secrets.dpopSecret,\n redis: redisScratch,\n onDecodeToken: async ({ payload, dpopProof }) => {\n // @TODO drop this once oauth provider no longer accepts DPoP proof with\n // query or fragment in \"htu\" claim.\n if (dpopProof?.htu.match(/[?#]/)) {\n oauthLogger.info(\n { htu: dpopProof.htu, client_id: payload.client_id },\n 'DPoP proof \"htu\" contains query or fragment',\n )\n }\n\n if (scopeRefGetter) {\n payload.scope = await scopeRefGetter.dereference(payload.scope)\n }\n\n return payload\n },\n })\n\n const authVerifier = new AuthVerifier(\n accountManager,\n idResolver,\n oauthVerifier,\n {\n publicUrl: cfg.service.publicUrl,\n jwtKey: jwtPublicKey ?? jwtSecretKey,\n adminPass: secrets.adminPassword,\n dids: {\n pds: cfg.service.did,\n entryway: cfg.entryway?.did,\n modService: cfg.modService?.did,\n },\n },\n )\n\n return new AppContext({\n actorStore,\n blobstore,\n localViewer,\n mailer,\n moderationMailer,\n didCache,\n idResolver,\n plcClient,\n accountManager,\n sequencer,\n backgroundQueue,\n redisScratch,\n crawlers,\n bskyAppView,\n moderationClient,\n reportingClient,\n entrywayClient,\n entrywayAdminClient,\n proxyAgent,\n safeFetch,\n authVerifier,\n oauthProvider,\n plcRotationKey,\n cfg,\n ...(overrides ?? {}),\n })\n }\n\n async appviewAuthHeaders(did: string, lxm: string) {\n assert(this.bskyAppView)\n return this.serviceAuthHeaders(did, this.bskyAppView.did, lxm)\n }\n\n async entrywayAuthHeaders(req: express.Request, did: string, lxm: string) {\n assert(this.cfg.entryway)\n const headers = await this.serviceAuthHeaders(\n did,\n this.cfg.entryway.did,\n lxm,\n )\n return forwardedFor(req, headers)\n }\n\n entrywayPassthruHeaders(req: express.Request) {\n return forwardedFor(req, authPassthru(req))\n }\n\n async serviceAuthHeaders(did: string, aud: string, lxm: string) {\n const keypair = await this.actorStore.keypair(did)\n return createServiceAuthHeaders({\n iss: did,\n aud,\n lxm,\n keypair,\n })\n }\n\n async serviceAuthJwt(did: string, aud: string, lxm: string) {\n const keypair = await this.actorStore.keypair(did)\n return createServiceJwt({\n iss: did,\n aud,\n lxm,\n keypair,\n })\n }\n\n async destroy(): Promise<void> {\n try {\n await this.backgroundQueue.destroy()\n } finally {\n try {\n await this.sequencer.destroy()\n } finally {\n try {\n await this.accountManager.close()\n } finally {\n try {\n await this.redisScratch?.quit()\n } finally {\n await this.proxyAgent.destroy()\n }\n }\n }\n }\n }\n\n async [Symbol.asyncDispose]() {\n await this.destroy()\n }\n}\n\nconst basicAuthHeader = (username: string, password: string) => {\n const encoded = ui8.toString(\n ui8.fromString(`${username}:${password}`, 'utf8'),\n 'base64pad',\n )\n return `Basic ${encoded}`\n}\n\nexport default AppContext\n"]}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport * as plc from '@did-plc/lib'\nimport type express from 'express'\nimport type { Redis } from 'ioredis'\nimport * as nodemailer from 'nodemailer'\nimport * as ui8 from 'uint8arrays'\nimport type * as undici from 'undici'\nimport { KmsKeypair, S3BlobStore } from '@atproto/aws'\nimport * as crypto from '@atproto/crypto'\nimport { IdResolver } from '@atproto/identity'\nimport { Client } from '@atproto/lex'\nimport {\n AccessTokenMode,\n JoseKey,\n LexResolver,\n OAuthProvider,\n} from '@atproto/oauth-provider/provider'\nimport { OAuthVerifier } from '@atproto/oauth-provider/verifier'\nimport type { BlobStore } from '@atproto/repo'\nimport {\n createServiceAuthHeaders,\n createServiceJwt,\n} from '@atproto/xrpc-server'\nimport { type Fetch, safeFetchWrap } from '@atproto-labs/fetch-node'\nimport { AccountManager } from './account-manager/account-manager.js'\nimport { OAuthStore } from './account-manager/oauth-store.js'\nimport { ScopeReferenceGetter } from './account-manager/scope-reference-getter.js'\nimport { ActorStore } from './actor-store/actor-store.js'\nimport { authPassthru, forwardedFor } from './api/proxy.js'\nimport {\n AuthVerifier,\n createPublicKeyObject,\n createSecretKeyObject,\n} from './auth-verifier.js'\nimport { BackgroundQueue } from './background.js'\nimport { BskyAppView } from './bsky-app-view.js'\nimport {\n type ServerConfig,\n type ServerEnvironment,\n type ServerSecrets,\n envToCfg,\n envToSecrets,\n readEnv,\n} from './config/index.js'\nimport { Crawlers } from './crawlers.js'\nimport { DidSqliteCache } from './did-cache/index.js'\nimport { DiskBlobStore } from './disk-blobstore.js'\nimport { events } from './events.js'\nimport { ImageUrlBuilder } from './image/image-url-builder.js'\nimport { fetchLogger, lexiconResolverLogger, oauthLogger } from './logger.js'\nimport { ServerMailer } from './mailer/index.js'\nimport { ModerationMailer } from './mailer/moderation.js'\nimport { buildProxyAgent } from './pipethrough.js'\nimport {\n LocalViewer,\n type LocalViewerCreator,\n} from './read-after-write/viewer.js'\nimport { getRedisClient } from './redis.js'\nimport { Sequencer } from './sequencer/index.js'\n\nexport type AppContextOptions = {\n actorStore: ActorStore\n blobstore: (did: string) => BlobStore\n localViewer: LocalViewerCreator\n mailer: ServerMailer\n moderationMailer: ModerationMailer\n didCache: DidSqliteCache\n idResolver: IdResolver\n plcClient: plc.Client\n accountManager: AccountManager\n sequencer: Sequencer\n backgroundQueue: BackgroundQueue\n redisScratch?: Redis\n crawlers: Crawlers\n bskyAppView?: BskyAppView\n moderationClient?: Client\n reportingClient?: Client\n entrywayClient?: Client\n entrywayAdminClient?: Client\n proxyAgent: undici.Dispatcher\n safeFetch: Fetch\n oauthProvider?: OAuthProvider\n authVerifier: AuthVerifier\n plcRotationKey: crypto.Keypair\n cfg: ServerConfig\n}\n\nexport class AppContext implements AsyncDisposable {\n public actorStore: ActorStore\n public blobstore: (did: string) => BlobStore\n public localViewer: LocalViewerCreator\n public mailer: ServerMailer\n public moderationMailer: ModerationMailer\n public didCache: DidSqliteCache\n public idResolver: IdResolver\n public plcClient: plc.Client\n public accountManager: AccountManager\n public sequencer: Sequencer\n public backgroundQueue: BackgroundQueue\n public redisScratch?: Redis\n public crawlers: Crawlers\n public bskyAppView?: BskyAppView\n public moderationClient: Client | undefined\n public reportingClient: Client | undefined\n public entrywayClient: Client | undefined\n public entrywayAdminClient: Client | undefined\n public proxyAgent: undici.Dispatcher\n public safeFetch: Fetch\n public authVerifier: AuthVerifier\n public oauthProvider?: OAuthProvider\n public plcRotationKey: crypto.Keypair\n public cfg: ServerConfig\n\n constructor(opts: AppContextOptions) {\n this.actorStore = opts.actorStore\n this.blobstore = opts.blobstore\n this.localViewer = opts.localViewer\n this.mailer = opts.mailer\n this.moderationMailer = opts.moderationMailer\n this.didCache = opts.didCache\n this.idResolver = opts.idResolver\n this.plcClient = opts.plcClient\n this.accountManager = opts.accountManager\n this.sequencer = opts.sequencer\n this.backgroundQueue = opts.backgroundQueue\n this.redisScratch = opts.redisScratch\n this.crawlers = opts.crawlers\n this.bskyAppView = opts.bskyAppView\n this.moderationClient = opts.moderationClient\n this.reportingClient = opts.reportingClient\n this.entrywayClient = opts.entrywayClient\n this.entrywayAdminClient = opts.entrywayAdminClient\n this.proxyAgent = opts.proxyAgent\n this.safeFetch = opts.safeFetch\n this.authVerifier = opts.authVerifier\n this.oauthProvider = opts.oauthProvider\n this.plcRotationKey = opts.plcRotationKey\n this.cfg = opts.cfg\n }\n\n static async fromEnv(\n env: ServerEnvironment = readEnv(),\n ): Promise<AppContext> {\n const cfg = envToCfg(env)\n const secrets = envToSecrets(env)\n return AppContext.fromConfig(cfg, secrets)\n }\n\n static async fromConfig(\n cfg: ServerConfig,\n secrets: ServerSecrets,\n overrides?: Partial<AppContextOptions>,\n ): Promise<AppContext> {\n // @TODO Implement using an AsyncDisposableStack\n\n const blobstore =\n cfg.blobstore.provider === 's3'\n ? S3BlobStore.creator({\n bucket: cfg.blobstore.bucket,\n region: cfg.blobstore.region,\n endpoint: cfg.blobstore.endpoint,\n forcePathStyle: cfg.blobstore.forcePathStyle,\n credentials: cfg.blobstore.credentials,\n uploadTimeoutMs: cfg.blobstore.uploadTimeoutMs,\n requestTimeoutMs: cfg.blobstore.requestTimeoutMs,\n })\n : DiskBlobStore.creator(\n cfg.blobstore.location,\n cfg.blobstore.tempLocation,\n )\n\n const mailTransport =\n cfg.email !== null\n ? nodemailer.createTransport(cfg.email.smtpUrl)\n : nodemailer.createTransport({ jsonTransport: true })\n\n const mailer = new ServerMailer(mailTransport, cfg.email, cfg.branding)\n\n const modMailTransport =\n cfg.moderationEmail !== null\n ? nodemailer.createTransport(cfg.moderationEmail.smtpUrl)\n : nodemailer.createTransport({ jsonTransport: true })\n\n const moderationMailer = new ModerationMailer(modMailTransport, cfg)\n\n const didCache = new DidSqliteCache(\n cfg.db.didCacheDbLoc,\n cfg.identity.cacheStaleTTL,\n cfg.identity.cacheMaxTTL,\n cfg.db.disableWalAutoCheckpoint,\n )\n await didCache.migrateOrThrow()\n\n const idResolver = new IdResolver({\n plcUrl: cfg.identity.plcUrl,\n didCache,\n timeout: cfg.identity.resolverTimeout,\n backupNameservers: cfg.identity.handleBackupNameservers,\n })\n const plcClient = new plc.Client(cfg.identity.plcUrl)\n\n const backgroundQueue = new BackgroundQueue(undefined, { concurrency: 5 })\n const crawlers = new Crawlers(\n backgroundQueue,\n cfg.service.hostname,\n cfg.crawlers,\n )\n const sequencer = new Sequencer(\n cfg.db.sequencerDbLoc,\n crawlers,\n undefined,\n cfg.db.disableWalAutoCheckpoint,\n )\n const redisScratch = cfg.redis\n ? getRedisClient(cfg.redis.address, cfg.redis.password)\n : undefined\n\n const bskyAppView = cfg.bskyAppView\n ? new BskyAppView({\n ...cfg.bskyAppView,\n validateResponse: cfg.service.devMode,\n })\n : undefined\n\n const moderationClient = cfg.modService\n ? new Client(\n { service: cfg.modService.url },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: cfg.service.devMode,\n },\n )\n : undefined\n const reportingClient = cfg.reportService\n ? new Client(\n { service: cfg.reportService.url },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: cfg.service.devMode,\n },\n )\n : undefined\n const entrywayClient = cfg.entryway\n ? new Client(\n { service: cfg.entryway.url },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: cfg.service.devMode,\n },\n )\n : undefined\n const entrywayAdminClient =\n cfg.entryway && secrets.entrywayAdminToken\n ? new Client(\n {\n service: cfg.entryway.url,\n headers: {\n authorization: basicAuthHeader(\n 'admin',\n secrets.entrywayAdminToken,\n ),\n },\n },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: cfg.service.devMode,\n },\n )\n : undefined\n\n const jwtSecretKey = createSecretKeyObject(secrets.jwtSecret)\n const jwtPublicKey = cfg.entryway\n ? createPublicKeyObject(cfg.entryway.jwtPublicKeyHex)\n : null\n\n const imageUrlBuilder = new ImageUrlBuilder(\n cfg.service.hostname,\n bskyAppView,\n )\n\n const actorStore = new ActorStore(cfg.actorStore, {\n blobstore,\n backgroundQueue,\n })\n\n const plcRotationKey =\n secrets.plcRotationKey.provider === 'kms'\n ? await KmsKeypair.load({\n keyId: secrets.plcRotationKey.keyId,\n })\n : await crypto.Secp256k1Keypair.import(\n secrets.plcRotationKey.privateKeyHex,\n )\n\n const accountManager = new AccountManager(\n cfg,\n actorStore,\n idResolver,\n jwtSecretKey,\n mailer,\n sequencer,\n plcClient,\n plcRotationKey,\n )\n await accountManager.migrateOrThrow()\n\n const localViewer = LocalViewer.creator(\n accountManager,\n imageUrlBuilder,\n bskyAppView,\n )\n\n // An agent for performing HTTP requests based on user provided URLs.\n const proxyAgent = buildProxyAgent(cfg.proxy)\n\n /**\n * A fetch() function that protects against SSRF attacks, large responses &\n * known bad domains. This function can safely be used to fetch user\n * provided URLs (unless \"disableSsrfProtection\" is true, of course).\n *\n * @note **DO NOT** wrap `safeFetch` with any logging or other transforms as\n * this might prevent the use of explicit `redirect: \"follow\"` init from\n * working. See {@link safeFetchWrap}.\n */\n const safeFetch = safeFetchWrap({\n allowIpHost: false,\n allowImplicitRedirect: false,\n responseMaxSize: cfg.fetch.maxResponseSize,\n ssrfProtection: !cfg.fetch.disableSsrfProtection,\n\n fetch: function (input, init) {\n const method =\n init?.method ?? (input instanceof Request ? input.method : 'GET')\n const uri = input instanceof Request ? input.url : String(input)\n\n fetchLogger.info({ method, uri }, 'fetch')\n\n return globalThis.fetch.call(this, input, init)\n },\n })\n\n const oauthProvider = cfg.oauth.provider\n ? new OAuthProvider({\n issuer: cfg.oauth.issuer,\n keyset: [await JoseKey.fromKeyLike(jwtSecretKey, undefined, 'HS256')],\n store: new OAuthStore(\n accountManager,\n actorStore,\n imageUrlBuilder,\n backgroundQueue,\n mailer,\n sequencer,\n plcClient,\n plcRotationKey,\n cfg.service.publicUrl,\n cfg.identity.recoveryDidKey,\n ),\n redis: redisScratch,\n dpopSecret: secrets.dpopSecret,\n inviteCodeRequired: cfg.invites.required,\n availableUserDomains: cfg.identity.serviceHandleDomains,\n hcaptcha: cfg.oauth.provider.hcaptcha,\n branding: cfg.oauth.provider.branding,\n safeFetch,\n lexResolver: new LexResolver({\n fetch: safeFetch,\n plcDirectoryUrl: cfg.identity.plcUrl,\n hooks: {\n onResolveAuthority: ({ nsid }) => {\n lexiconResolverLogger.debug(\n { nsid: nsid.toString() },\n 'Resolving lexicon DID authority',\n )\n // Override the lexicon did resolution to point to a custom PDS\n return cfg.lexicon.didAuthority\n },\n onResolveAuthorityResult({ nsid, did }) {\n lexiconResolverLogger.info(\n { nsid: nsid.toString(), did },\n 'Resolved lexicon DID',\n )\n },\n onResolveAuthorityError({ nsid, err }) {\n lexiconResolverLogger.error(\n { nsid: nsid.toString(), err },\n 'Lexicon DID resolution error',\n )\n },\n onFetchResult({ uri, cid }) {\n lexiconResolverLogger.info(\n { uri: uri.toString(), cid: cid.toString() },\n 'Fetched lexicon',\n )\n },\n onFetchError({ err, uri }) {\n lexiconResolverLogger.error(\n { uri: uri.toString(), err },\n 'Lexicon fetch error',\n )\n },\n },\n }),\n metadata: {\n protected_resources: [new URL(cfg.oauth.issuer).origin],\n },\n // If the PDS is both an authorization server & resource server (no\n // entryway), we can afford to check the token validity on every\n // request. This allows revoked tokens to be rejected immediately.\n // This also allows JWT to be shorter since some claims (notably the\n // \"scope\" claim) do not need to be included in the token.\n accessTokenMode: AccessTokenMode.stateful,\n\n getClientInfo(clientId) {\n return {\n isTrusted: cfg.oauth.provider?.trustedClients?.includes(clientId),\n }\n },\n onSignedUp({ account, data, clientId }) {\n events.accountCreated({\n source: 'oauth',\n did: account.did,\n clientId,\n invited: data.inviteCode != null,\n deactivated: false,\n })\n },\n onSignedIn({ account, clientId }) {\n events.signedIn({\n did: account.did,\n clientId,\n })\n },\n onAuthorized({ account, client }) {\n events.oauthAuthorized({\n did: account.did,\n clientId: client.id,\n clientFirstParty: client.isFirstParty,\n clientTrusted: client.isTrusted,\n clientConfidential: client.isConfidential,\n })\n },\n onTokenCreated({ account, client }) {\n events.sessionCreated({\n source: 'oauth',\n did: account.did,\n clientId: client.id,\n })\n },\n onTokenRefreshed({ account, client }) {\n events.sessionRefreshed({\n source: 'oauth',\n did: account.did,\n clientId: client.id,\n })\n },\n })\n : undefined\n\n const scopeRefGetter = entrywayClient\n ? new ScopeReferenceGetter(entrywayClient, redisScratch)\n : undefined\n\n const oauthVerifier: OAuthVerifier =\n oauthProvider ?? // OAuthProvider extends OAuthVerifier\n new OAuthVerifier({\n issuer: cfg.oauth.issuer,\n keyset: [await JoseKey.fromKeyLike(jwtPublicKey!, undefined, 'ES256K')],\n dpopSecret: secrets.dpopSecret,\n redis: redisScratch,\n onDecodeToken: async ({ payload, dpopProof }) => {\n // @TODO drop this once oauth provider no longer accepts DPoP proof with\n // query or fragment in \"htu\" claim.\n if (dpopProof?.htu.match(/[?#]/)) {\n oauthLogger.info(\n { htu: dpopProof.htu, client_id: payload.client_id },\n 'DPoP proof \"htu\" contains query or fragment',\n )\n }\n\n if (scopeRefGetter) {\n payload.scope = await scopeRefGetter.dereference(payload.scope)\n }\n\n return payload\n },\n })\n\n const authVerifier = new AuthVerifier(\n accountManager,\n idResolver,\n oauthVerifier,\n {\n publicUrl: cfg.service.publicUrl,\n jwtKey: jwtPublicKey ?? jwtSecretKey,\n adminPass: secrets.adminPassword,\n dids: {\n pds: cfg.service.did,\n entryway: cfg.entryway?.did,\n modService: cfg.modService?.did,\n },\n },\n )\n\n return new AppContext({\n actorStore,\n blobstore,\n localViewer,\n mailer,\n moderationMailer,\n didCache,\n idResolver,\n plcClient,\n accountManager,\n sequencer,\n backgroundQueue,\n redisScratch,\n crawlers,\n bskyAppView,\n moderationClient,\n reportingClient,\n entrywayClient,\n entrywayAdminClient,\n proxyAgent,\n safeFetch,\n authVerifier,\n oauthProvider,\n plcRotationKey,\n cfg,\n ...(overrides ?? {}),\n })\n }\n\n async appviewAuthHeaders(did: string, lxm: string) {\n assert(this.bskyAppView)\n return this.serviceAuthHeaders(did, this.bskyAppView.did, lxm)\n }\n\n async entrywayAuthHeaders(req: express.Request, did: string, lxm: string) {\n assert(this.cfg.entryway)\n const headers = await this.serviceAuthHeaders(\n did,\n this.cfg.entryway.did,\n lxm,\n )\n return forwardedFor(req, headers)\n }\n\n entrywayPassthruHeaders(req: express.Request) {\n return forwardedFor(req, authPassthru(req))\n }\n\n async serviceAuthHeaders(did: string, aud: string, lxm: string) {\n const keypair = await this.actorStore.keypair(did)\n return createServiceAuthHeaders({\n iss: did,\n aud,\n lxm,\n keypair,\n })\n }\n\n async serviceAuthJwt(did: string, aud: string, lxm: string) {\n const keypair = await this.actorStore.keypair(did)\n return createServiceJwt({\n iss: did,\n aud,\n lxm,\n keypair,\n })\n }\n\n async destroy(): Promise<void> {\n try {\n await this.backgroundQueue.destroy()\n } finally {\n try {\n await this.sequencer.destroy()\n } finally {\n try {\n await this.accountManager.close()\n } finally {\n try {\n await this.redisScratch?.quit()\n } finally {\n await this.proxyAgent.destroy()\n }\n }\n }\n }\n }\n\n async [Symbol.asyncDispose]() {\n await this.destroy()\n }\n}\n\nconst basicAuthHeader = (username: string, password: string) => {\n const encoded = ui8.toString(\n ui8.fromString(`${username}:${password}`, 'utf8'),\n 'base64pad',\n )\n return `Basic ${encoded}`\n}\n\nexport default AppContext\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"video.defs.d.ts","sourceRoot":"","sources":["../../../../../src/lexicons/app/bsky/embed/video.defs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"video.defs.d.ts","sourceRoot":"","sources":["../../../../../src/lexicons/app/bsky/embed/video.defs.ts"],"names":[],"mappings":"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"}
@@ -11,8 +11,7 @@ const main = /*#__PURE__*/ l.typedObject($nsid, 'main',
11
11
  captions: /*#__PURE__*/ l.optional(
12
12
  /*#__PURE__*/ l.array(
13
13
  /*#__PURE__*/ l.ref((() => caption)), { maxLength: 20 })),
14
- alt: /*#__PURE__*/ l.optional(
15
- /*#__PURE__*/ l.string({ maxGraphemes: 1000, maxLength: 10000 })),
14
+ alt: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),
16
15
  aspectRatio: /*#__PURE__*/ l.optional(
17
16
  /*#__PURE__*/ l.ref((() => EmbedDefs.aspectRatio))),
18
17
  presentation: /*#__PURE__*/ l.optional(
@@ -44,8 +43,7 @@ const view = /*#__PURE__*/ l.typedObject($nsid, 'view',
44
43
  playlist: /*#__PURE__*/ l.string({ format: 'uri' }),
45
44
  thumbnail: /*#__PURE__*/ l.optional(
46
45
  /*#__PURE__*/ l.string({ format: 'uri' })),
47
- alt: /*#__PURE__*/ l.optional(
48
- /*#__PURE__*/ l.string({ maxGraphemes: 1000, maxLength: 10000 })),
46
+ alt: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),
49
47
  aspectRatio: /*#__PURE__*/ l.optional(
50
48
  /*#__PURE__*/ l.ref((() => EmbedDefs.aspectRatio))),
51
49
  presentation: /*#__PURE__*/ l.optional(
@@ -1 +1 @@
1
- {"version":3,"file":"video.defs.js","sourceRoot":"","sources":["../../../../../src/lexicons/app/bsky/embed/video.defs.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nimport { l } from '@atproto/lex'\nimport * as EmbedDefs from './defs.defs.js'\n\nconst $nsid = 'app.bsky.embed.video'\n\ntype $nsid = typeof $nsid\n\nexport { $nsid }\n\ntype Main = {\n $type?: 'app.bsky.embed.video'\n\n /**\n * The mp4 video file. May be up to 300mb, formerly limited to 100mb.\n */\n video: l.BlobRef\n captions?: Caption[]\n\n /**\n * Alt text description of the video, for accessibility.\n */\n alt?: string\n aspectRatio?: EmbedDefs.AspectRatio\n\n /**\n * A hint to the client about how to present the video.\n */\n presentation?: 'default' | 'gif' | l.UnknownString\n}\n\nexport type { Main }\n\nconst main = /*#__PURE__*/ l.typedObject<Main>(\n $nsid,\n 'main',\n /*#__PURE__*/ l.object({\n video: /*#__PURE__*/ l.blob({ accept: ['video/mp4'], maxSize: 300000000 }),\n captions: /*#__PURE__*/ l.optional(\n /*#__PURE__*/ l.array(\n /*#__PURE__*/ l.ref<Caption>((() => caption) as any),\n { maxLength: 20 },\n ),\n ),\n alt: /*#__PURE__*/ l.optional(\n /*#__PURE__*/ l.string({ maxGraphemes: 1000, maxLength: 10000 }),\n ),\n aspectRatio: /*#__PURE__*/ l.optional(\n /*#__PURE__*/ l.ref<EmbedDefs.AspectRatio>(\n (() => EmbedDefs.aspectRatio) as any,\n ),\n ),\n presentation: /*#__PURE__*/ l.optional(\n /*#__PURE__*/ l.string<{ knownValues: ['default', 'gif'] }>(),\n ),\n }),\n)\n\nexport { main }\n\nconst $type = $nsid\n\ntype $type = typeof $type\n\nexport { $type }\n\nexport const $isTypeOf = /*#__PURE__*/ main.isTypeOf.bind(main)\nexport const $build = /*#__PURE__*/ main.build.bind(main)\nexport const $assert = /*#__PURE__*/ main.assert.bind(main)\nexport const $check = /*#__PURE__*/ main.check.bind(main)\nexport const $cast = /*#__PURE__*/ main.cast.bind(main)\nexport const $ifMatches = /*#__PURE__*/ main.ifMatches.bind(main)\nexport const $matches = /*#__PURE__*/ main.matches.bind(main)\nexport const $parse = /*#__PURE__*/ main.parse.bind(main)\nexport const $safeParse = /*#__PURE__*/ main.safeParse.bind(main)\nexport const $validate = /*#__PURE__*/ main.validate.bind(main)\nexport const $safeValidate = /*#__PURE__*/ main.safeValidate.bind(main)\n\ntype Caption = {\n $type?: 'app.bsky.embed.video#caption'\n lang: l.LanguageString\n file: l.BlobRef\n}\n\nexport type { Caption }\n\nconst caption = /*#__PURE__*/ l.typedObject<Caption>(\n $nsid,\n 'caption',\n /*#__PURE__*/ l.object({\n lang: /*#__PURE__*/ l.string({ format: 'language' }),\n file: /*#__PURE__*/ l.blob({ accept: ['text/vtt'], maxSize: 20000 }),\n }),\n)\n\nexport { caption }\n\ntype View = {\n $type?: 'app.bsky.embed.video#view'\n cid: l.CidString\n playlist: l.UriString\n thumbnail?: l.UriString\n alt?: string\n aspectRatio?: EmbedDefs.AspectRatio\n\n /**\n * A hint to the client about how to present the video.\n */\n presentation?: 'default' | 'gif' | l.UnknownString\n}\n\nexport type { View }\n\nconst view = /*#__PURE__*/ l.typedObject<View>(\n $nsid,\n 'view',\n /*#__PURE__*/ l.object({\n cid: /*#__PURE__*/ l.string({ format: 'cid' }),\n playlist: /*#__PURE__*/ l.string({ format: 'uri' }),\n thumbnail: /*#__PURE__*/ l.optional(\n /*#__PURE__*/ l.string({ format: 'uri' }),\n ),\n alt: /*#__PURE__*/ l.optional(\n /*#__PURE__*/ l.string({ maxGraphemes: 1000, maxLength: 10000 }),\n ),\n aspectRatio: /*#__PURE__*/ l.optional(\n /*#__PURE__*/ l.ref<EmbedDefs.AspectRatio>(\n (() => EmbedDefs.aspectRatio) as any,\n ),\n ),\n presentation: /*#__PURE__*/ l.optional(\n /*#__PURE__*/ l.string<{ knownValues: ['default', 'gif'] }>(),\n ),\n }),\n)\n\nexport { view }\n"]}
1
+ {"version":3,"file":"video.defs.js","sourceRoot":"","sources":["../../../../../src/lexicons/app/bsky/embed/video.defs.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nimport { l } from '@atproto/lex'\nimport * as EmbedDefs from './defs.defs.js'\n\nconst $nsid = 'app.bsky.embed.video'\n\ntype $nsid = typeof $nsid\n\nexport { $nsid }\n\ntype Main = {\n $type?: 'app.bsky.embed.video'\n\n /**\n * The mp4 video file. May be up to 300mb, formerly limited to 100mb.\n */\n video: l.BlobRef\n captions?: Caption[]\n\n /**\n * Alt text description of the video, for accessibility.\n */\n alt?: string\n aspectRatio?: EmbedDefs.AspectRatio\n\n /**\n * A hint to the client about how to present the video.\n */\n presentation?: 'default' | 'gif' | l.UnknownString\n}\n\nexport type { Main }\n\nconst main = /*#__PURE__*/ l.typedObject<Main>(\n $nsid,\n 'main',\n /*#__PURE__*/ l.object({\n video: /*#__PURE__*/ l.blob({ accept: ['video/mp4'], maxSize: 300000000 }),\n captions: /*#__PURE__*/ l.optional(\n /*#__PURE__*/ l.array(\n /*#__PURE__*/ l.ref<Caption>((() => caption) as any),\n { maxLength: 20 },\n ),\n ),\n alt: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),\n aspectRatio: /*#__PURE__*/ l.optional(\n /*#__PURE__*/ l.ref<EmbedDefs.AspectRatio>(\n (() => EmbedDefs.aspectRatio) as any,\n ),\n ),\n presentation: /*#__PURE__*/ l.optional(\n /*#__PURE__*/ l.string<{ knownValues: ['default', 'gif'] }>(),\n ),\n }),\n)\n\nexport { main }\n\nconst $type = $nsid\n\ntype $type = typeof $type\n\nexport { $type }\n\nexport const $isTypeOf = /*#__PURE__*/ main.isTypeOf.bind(main)\nexport const $build = /*#__PURE__*/ main.build.bind(main)\nexport const $assert = /*#__PURE__*/ main.assert.bind(main)\nexport const $check = /*#__PURE__*/ main.check.bind(main)\nexport const $cast = /*#__PURE__*/ main.cast.bind(main)\nexport const $ifMatches = /*#__PURE__*/ main.ifMatches.bind(main)\nexport const $matches = /*#__PURE__*/ main.matches.bind(main)\nexport const $parse = /*#__PURE__*/ main.parse.bind(main)\nexport const $safeParse = /*#__PURE__*/ main.safeParse.bind(main)\nexport const $validate = /*#__PURE__*/ main.validate.bind(main)\nexport const $safeValidate = /*#__PURE__*/ main.safeValidate.bind(main)\n\ntype Caption = {\n $type?: 'app.bsky.embed.video#caption'\n lang: l.LanguageString\n file: l.BlobRef\n}\n\nexport type { Caption }\n\nconst caption = /*#__PURE__*/ l.typedObject<Caption>(\n $nsid,\n 'caption',\n /*#__PURE__*/ l.object({\n lang: /*#__PURE__*/ l.string({ format: 'language' }),\n file: /*#__PURE__*/ l.blob({ accept: ['text/vtt'], maxSize: 20000 }),\n }),\n)\n\nexport { caption }\n\ntype View = {\n $type?: 'app.bsky.embed.video#view'\n cid: l.CidString\n playlist: l.UriString\n thumbnail?: l.UriString\n alt?: string\n aspectRatio?: EmbedDefs.AspectRatio\n\n /**\n * A hint to the client about how to present the video.\n */\n presentation?: 'default' | 'gif' | l.UnknownString\n}\n\nexport type { View }\n\nconst view = /*#__PURE__*/ l.typedObject<View>(\n $nsid,\n 'view',\n /*#__PURE__*/ l.object({\n cid: /*#__PURE__*/ l.string({ format: 'cid' }),\n playlist: /*#__PURE__*/ l.string({ format: 'uri' }),\n thumbnail: /*#__PURE__*/ l.optional(\n /*#__PURE__*/ l.string({ format: 'uri' }),\n ),\n alt: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),\n aspectRatio: /*#__PURE__*/ l.optional(\n /*#__PURE__*/ l.ref<EmbedDefs.AspectRatio>(\n (() => EmbedDefs.aspectRatio) as any,\n ),\n ),\n presentation: /*#__PURE__*/ l.optional(\n /*#__PURE__*/ l.string<{ knownValues: ['default', 'gif'] }>(),\n ),\n }),\n)\n\nexport { view }\n"]}
@@ -1,10 +1,10 @@
1
1
  import { publishIdentity, publishIdentityFromFile } from './publish-identity.js';
2
- import { rebuildRepo } from './rebuild-repo.js';
2
+ import { rebuildRepoScript } from './rebuild-repo.js';
3
3
  import { rotateKeys, rotateKeysFromFile, rotateKeysRecovery } from './rotate-keys.js';
4
4
  import { sequencerRecovery } from './sequencer-recovery/index.js';
5
5
  import { repairRepos } from './sequencer-recovery/repair-repos.js';
6
6
  export declare const scripts: {
7
- 'rebuild-repo': typeof rebuildRepo;
7
+ 'rebuild-repo': typeof rebuildRepoScript;
8
8
  'sequencer-recovery': typeof sequencerRecovery;
9
9
  'recovery-repair-repos': typeof repairRepos;
10
10
  'rotate-keys': typeof rotateKeys;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scripts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAA;AAElE,eAAO,MAAM,OAAO;IAClB,cAAc;IACd,oBAAoB;IACpB,uBAAuB;IACvB,aAAa;IACb,kBAAkB;IAClB,sBAAsB;IACtB,kBAAkB;IAClB,uBAAuB;CACxB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scripts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAA;AAElE,eAAO,MAAM,OAAO;;;;;;;;;CASmD,CAAA"}
@@ -1,10 +1,10 @@
1
1
  import { publishIdentity, publishIdentityFromFile } from './publish-identity.js';
2
- import { rebuildRepo } from './rebuild-repo.js';
2
+ import { rebuildRepoScript } from './rebuild-repo.js';
3
3
  import { rotateKeys, rotateKeysFromFile, rotateKeysRecovery, } from './rotate-keys.js';
4
4
  import { sequencerRecovery } from './sequencer-recovery/index.js';
5
5
  import { repairRepos } from './sequencer-recovery/repair-repos.js';
6
6
  export const scripts = {
7
- 'rebuild-repo': rebuildRepo,
7
+ 'rebuild-repo': rebuildRepoScript,
8
8
  'sequencer-recovery': sequencerRecovery,
9
9
  'recovery-repair-repos': repairRepos,
10
10
  'rotate-keys': rotateKeys,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scripts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAA;AAElE,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,cAAc,EAAE,WAAW;IAC3B,oBAAoB,EAAE,iBAAiB;IACvC,uBAAuB,EAAE,WAAW;IACpC,aAAa,EAAE,UAAU;IACzB,kBAAkB,EAAE,kBAAkB;IACtC,sBAAsB,EAAE,kBAAkB;IAC1C,kBAAkB,EAAE,eAAe;IACnC,uBAAuB,EAAE,uBAAuB;CACjD,CAAA","sourcesContent":["import { publishIdentity, publishIdentityFromFile } from './publish-identity.js'\nimport { rebuildRepo } from './rebuild-repo.js'\nimport {\n rotateKeys,\n rotateKeysFromFile,\n rotateKeysRecovery,\n} from './rotate-keys.js'\nimport { sequencerRecovery } from './sequencer-recovery/index.js'\nimport { repairRepos } from './sequencer-recovery/repair-repos.js'\n\nexport const scripts = {\n 'rebuild-repo': rebuildRepo,\n 'sequencer-recovery': sequencerRecovery,\n 'recovery-repair-repos': repairRepos,\n 'rotate-keys': rotateKeys,\n 'rotate-keys-file': rotateKeysFromFile,\n 'rotate-keys-recovery': rotateKeysRecovery,\n 'publish-identity': publishIdentity,\n 'publish-identity-file': publishIdentityFromFile,\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scripts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAA;AAElE,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,cAAc,EAAE,iBAAiB;IACjC,oBAAoB,EAAE,iBAAiB;IACvC,uBAAuB,EAAE,WAAW;IACpC,aAAa,EAAE,UAAU;IACzB,kBAAkB,EAAE,kBAAkB;IACtC,sBAAsB,EAAE,kBAAkB;IAC1C,kBAAkB,EAAE,eAAe;IACnC,uBAAuB,EAAE,uBAAuB;CACqB,CAAA","sourcesContent":["import { publishIdentity, publishIdentityFromFile } from './publish-identity.js'\nimport { rebuildRepoScript } from './rebuild-repo.js'\nimport {\n rotateKeys,\n rotateKeysFromFile,\n rotateKeysRecovery,\n} from './rotate-keys.js'\nimport { sequencerRecovery } from './sequencer-recovery/index.js'\nimport { repairRepos } from './sequencer-recovery/repair-repos.js'\n\nexport const scripts = {\n 'rebuild-repo': rebuildRepoScript,\n 'sequencer-recovery': sequencerRecovery,\n 'recovery-repair-repos': repairRepos,\n 'rotate-keys': rotateKeys,\n 'rotate-keys-file': rotateKeysFromFile,\n 'rotate-keys-recovery': rotateKeysRecovery,\n 'publish-identity': publishIdentity,\n 'publish-identity-file': publishIdentityFromFile,\n} satisfies Record<string, (ctx: any, args: string[]) => Promise<void>>\n"]}
package/dist/telemetry.js CHANGED
@@ -1,193 +1,15 @@
1
- import { register } from 'node:module';
2
- import { diag } from '@opentelemetry/api';
3
- import { getResourceDetectors } from '@opentelemetry/auto-instrumentations-node';
4
- import { getBooleanFromEnv, getStringFromEnv, getStringListFromEnv, } from '@opentelemetry/core';
5
1
  import { AwsInstrumentation } from '@opentelemetry/instrumentation-aws-sdk';
6
- import { ExpressInstrumentation, ExpressLayerType, } from '@opentelemetry/instrumentation-express';
7
- import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
8
2
  import { IORedisInstrumentation } from '@opentelemetry/instrumentation-ioredis';
9
- import { PinoInstrumentation } from '@opentelemetry/instrumentation-pino';
10
- import { RuntimeNodeInstrumentation } from '@opentelemetry/instrumentation-runtime-node';
11
- import { UndiciInstrumentation } from '@opentelemetry/instrumentation-undici';
12
- import { NodeSDK } from '@opentelemetry/sdk-node';
13
- import { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';
14
3
  import { BetterSqlite3Instrumentation } from 'opentelemetry-plugin-better-sqlite3';
15
- const ATTR_XRPC_METHOD = 'xrpc.method';
16
- const ATTR_XRPC_PROXIED = 'xrpc.proxied';
17
- const ATTR_XRPC_PROXY = 'xrpc.proxy';
18
- // @NOTE Hand-rolled equivalent of "@opentelemetry/auto-instrumentations-node"'s
19
- // register script, because that one lacks better-sqlite3 instrumentation and
20
- // doesn't let us customize the HTTP span naming for XRPC. We use `NodeSDK`
21
- // rather than `registerInstrumentations` to get exporter setup from the
22
- // conventional OTEL_* env vars for free.
23
- // @NOTE Telemetry is opt-in via exporter endpoint rather than a non-standard
24
- // flag: configuring an OTLP endpoint is what enables the SDK. OTEL_SDK_DISABLED
25
- // remains a kill switch, per spec.
26
- const otelDisabled = getBooleanFromEnv('OTEL_SDK_DISABLED');
27
- const tracesConfigured = isSignalConfigured('TRACES');
28
- const metricsConfigured = isSignalConfigured('METRICS');
29
- const logsConfigured = isSignalConfigured('LOGS');
30
- const otelConfigured = tracesConfigured || metricsConfigured || logsConfigured;
31
- const otelEnabled = !otelDisabled && otelConfigured;
32
- if (otelEnabled) {
33
- try {
34
- register('@opentelemetry/instrumentation/hook.mjs', import.meta.url);
35
- const sdk = new NodeSDK({
36
- // @NOTE Unlike sdk-node's default detectors, these include the
37
- // "container" detector.
38
- resourceDetectors: getResourceDetectors(),
39
- instrumentations: getInstrumentations(),
40
- // @NOTE The gate above enables the SDK as soon as *any* signal is
41
- // configured, but NodeSDK then defaults every unspecified
42
- // OTEL_{SIGNAL}_EXPORTER to "otlp" on http://localhost:4318 — shipping
43
- // signals the operator never opted into. An *empty* pipeline opts a
44
- // signal out: NodeSDK only reads OTEL_{SIGNAL}_EXPORTER when the pipeline
45
- // option is `undefined`, and registers no provider when handed an empty
46
- // one. Opted-in signals get `undefined` so they stay env-configured.
47
- spanProcessors: tracesConfigured ? undefined : [],
48
- metricReaders: metricsConfigured ? undefined : [],
49
- logRecordProcessors: logsConfigured ? undefined : [],
50
- });
51
- sdk.start();
52
- // @NOTE On SIGINT/SIGTERM the PDS releases its resources without calling
53
- // process.exit(), so the event loop empties and Node emits "beforeExit"
54
- // (https://nodejs.org/api/process.html#event-beforeexit). That's our window
55
- // to flush pending telemetry.
56
- process.once('beforeExit', () => {
57
- sdk.shutdown().catch((err) => {
58
- diag.error('Error terminating OpenTelemetry SDK', err);
59
- });
60
- });
61
- }
62
- catch (err) {
63
- diag.error('Error initializing OpenTelemetry SDK', err);
64
- }
65
- }
66
- function getInstrumentations() {
67
- return [
68
- // @NOTE Not using getNodeAutoInstrumentations: it pulls in many
69
- // instrumentations we don't need, with no easy way to filter them out.
70
- new RuntimeNodeInstrumentation(),
71
- new HttpInstrumentation({
72
- // Derives "http.route" (and the span name) from the normalized XRPC path,
73
- // for both incoming and outgoing requests.
74
- //
75
- // @NOTE Must be applyCustomAttributesOnSpan (fires on response finish),
76
- // not requestHook (fires on request start). The express instrumentation
77
- // overwrites the shared rpcMetadata.route on every layer it enters, which
78
- // in this app resolves to "/" more often than not (multiple express apps
79
- // and routers mounted at "/", plus catchall middlewares with no route
80
- // layer). On finish, the http instrumentation copies rpcMetadata.route
81
- // into "http.route" and renames the span from it, clobbering anything a
82
- // requestHook set. This hook runs after that, so it wins.
83
- applyCustomAttributesOnSpan: (span, request) => {
84
- const { url, method, proxy } = 'path' in request
85
- ? // ClientRequest
86
- {
87
- url: request.path,
88
- method: request.method,
89
- proxy: request.getHeader('atproto-proxy'),
90
- }
91
- : // IncomingMessage
92
- {
93
- url: request.url ?? '/',
94
- method: request.method ?? 'GET',
95
- proxy: request.headers['atproto-proxy'],
96
- };
97
- const lxm = method === 'GET' || method === 'POST'
98
- ? extractNormalizedLxm(url)
99
- : undefined;
100
- // Normalized route for XRPC, raw path otherwise
101
- const route = lxm ? `/xrpc/${lxm}` : url.split('?')[0];
102
- span.setAttribute(ATTR_HTTP_ROUTE, route);
103
- if (lxm) {
104
- span.updateName(`${method} /xrpc/${lxm}`);
105
- span.setAttribute(ATTR_XRPC_METHOD, lxm);
106
- span.setAttribute(ATTR_XRPC_PROXIED, !!proxy);
107
- if (proxy) {
108
- span.setAttribute(ATTR_XRPC_PROXY, proxy);
109
- }
110
- }
111
- },
112
- }),
113
- new ExpressInstrumentation({
114
- ignoreLayersType: [ExpressLayerType.MIDDLEWARE],
115
- }),
116
- new UndiciInstrumentation({
117
- requestHook: (span, request) => {
118
- const lxm = extractNormalizedLxm(request.path);
119
- if (lxm) {
120
- span.setAttribute(ATTR_XRPC_METHOD, lxm);
121
- }
122
- },
123
- }),
4
+ import pkg from '@atproto/pds/package.json' with { type: 'json' };
5
+ import { setup } from '@atproto-labs/opentelemetry-node';
6
+ setup(() => ({
7
+ name: pkg.name,
8
+ version: pkg.version,
9
+ instrumentations: [
124
10
  new AwsInstrumentation(),
125
11
  new IORedisInstrumentation(),
126
12
  new BetterSqlite3Instrumentation(),
127
- // @NOTE Keep log correlation (trace_id/span_id injected into pino records)
128
- // but disable log sending: it JSON.parse()s every record on the main thread
129
- // and would forward all subsystems indiscriminately. Events we actually want
130
- // in the OTEL stack go through the Logs API explicitly (see ./events.ts).
131
- new PinoInstrumentation({ disableLogSending: true }),
132
- ];
133
- }
134
- /**
135
- * A signal counts as configured when an OTLP endpoint applies to it
136
- * (signal-specific or generic) and its exporter isn't set to "none".
137
- *
138
- * @NOTE OTEL_{SIGNAL}_EXPORTER is a comma-separated list, and the SDK handles
139
- * "none" alongside other exporters inconsistently (metrics & logs disable the
140
- * signal, traces falls back to "otlp"). Such a combination is a
141
- * misconfiguration, so we treat any list containing "none" as disabling.
142
- */
143
- function isSignalConfigured(signal) {
144
- if (getStringListFromEnv(`OTEL_${signal}_EXPORTER`)?.includes('none')) {
145
- return false;
146
- }
147
- return (!!getStringFromEnv(`OTEL_EXPORTER_OTLP_${signal}_ENDPOINT`) ||
148
- !!getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT'));
149
- }
150
- // @NOTE Hand-rolled (rather than using URL/split) because this runs on every
151
- // instrumented request. Should become obsolete once we have dedicated
152
- // XrpcClient/XrpcServer instrumentations.
153
- function extractNormalizedLxm(url) {
154
- if (typeof url !== 'string') {
155
- return undefined;
156
- }
157
- // 9 = "/xrpc/".length + shortest conceivable NSID ("a.b")
158
- if (url.length < 9 || !url.startsWith('/xrpc/')) {
159
- return undefined;
160
- }
161
- const firstMethodCharPos = 6; // "/xrpc/".length
162
- // Characters that can never open an NSID (note "_" skips "/xrpc/_health")
163
- const nextChar = url.charCodeAt(firstMethodCharPos);
164
- if (nextChar === 0x2e /* '.' */ ||
165
- nextChar === 0x2f /* '/' */ ||
166
- nextChar === 0x3f /* '?' */ ||
167
- nextChar === 0x5f /* '_' */) {
168
- return undefined;
169
- }
170
- const queryIndex = url.indexOf('?', firstMethodCharPos + 1);
171
- let lastMethodCharPos = queryIndex === -1 ? url.length - 1 : queryIndex - 1;
172
- // Ignore the trailing slash, if there is one
173
- if (url.charCodeAt(lastMethodCharPos) === 0x2f /* '/' */) {
174
- lastMethodCharPos--;
175
- }
176
- if (lastMethodCharPos < 9) {
177
- return undefined;
178
- }
179
- // Make sure there is no other slash in the path
180
- if (url.lastIndexOf('/', lastMethodCharPos) !== firstMethodCharPos - 1) {
181
- return undefined;
182
- }
183
- // Require at least one dot, and not as the last character
184
- const lastDotPos = url.lastIndexOf('.', lastMethodCharPos);
185
- if (lastDotPos === -1 || lastDotPos === lastMethodCharPos) {
186
- return undefined;
187
- }
188
- // @NOTE Only the domain authority is case-insensitive; the trailing name
189
- // segment is not, so it must be preserved as-is to avoid conflating
190
- // distinct NSIDs.
191
- return `${url.substring(firstMethodCharPos, lastDotPos).toLowerCase()}${url.substring(lastDotPos, lastMethodCharPos + 1)}`;
192
- }
13
+ ],
14
+ }));
193
15
  //# sourceMappingURL=telemetry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"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","sourcesContent":["import { register } from 'node:module'\nimport { diag } from '@opentelemetry/api'\nimport { getResourceDetectors } from '@opentelemetry/auto-instrumentations-node'\nimport {\n getBooleanFromEnv,\n getStringFromEnv,\n getStringListFromEnv,\n} from '@opentelemetry/core'\nimport type { Instrumentation } from '@opentelemetry/instrumentation'\nimport { AwsInstrumentation } from '@opentelemetry/instrumentation-aws-sdk'\nimport {\n ExpressInstrumentation,\n ExpressLayerType,\n} from '@opentelemetry/instrumentation-express'\nimport { HttpInstrumentation } from '@opentelemetry/instrumentation-http'\nimport { IORedisInstrumentation } from '@opentelemetry/instrumentation-ioredis'\nimport { PinoInstrumentation } from '@opentelemetry/instrumentation-pino'\nimport { RuntimeNodeInstrumentation } from '@opentelemetry/instrumentation-runtime-node'\nimport { UndiciInstrumentation } from '@opentelemetry/instrumentation-undici'\nimport { NodeSDK } from '@opentelemetry/sdk-node'\nimport { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions'\nimport { BetterSqlite3Instrumentation } from 'opentelemetry-plugin-better-sqlite3'\n\nconst ATTR_XRPC_METHOD = 'xrpc.method'\nconst ATTR_XRPC_PROXIED = 'xrpc.proxied'\nconst ATTR_XRPC_PROXY = 'xrpc.proxy'\n\n// @NOTE Hand-rolled equivalent of \"@opentelemetry/auto-instrumentations-node\"'s\n// register script, because that one lacks better-sqlite3 instrumentation and\n// doesn't let us customize the HTTP span naming for XRPC. We use `NodeSDK`\n// rather than `registerInstrumentations` to get exporter setup from the\n// conventional OTEL_* env vars for free.\n\n// @NOTE Telemetry is opt-in via exporter endpoint rather than a non-standard\n// flag: configuring an OTLP endpoint is what enables the SDK. OTEL_SDK_DISABLED\n// remains a kill switch, per spec.\nconst otelDisabled = getBooleanFromEnv('OTEL_SDK_DISABLED')\nconst tracesConfigured = isSignalConfigured('TRACES')\nconst metricsConfigured = isSignalConfigured('METRICS')\nconst logsConfigured = isSignalConfigured('LOGS')\nconst otelConfigured = tracesConfigured || metricsConfigured || logsConfigured\nconst otelEnabled = !otelDisabled && otelConfigured\n\nif (otelEnabled) {\n try {\n register('@opentelemetry/instrumentation/hook.mjs', import.meta.url)\n\n const sdk = new NodeSDK({\n // @NOTE Unlike sdk-node's default detectors, these include the\n // \"container\" detector.\n resourceDetectors: getResourceDetectors(),\n instrumentations: getInstrumentations(),\n\n // @NOTE The gate above enables the SDK as soon as *any* signal is\n // configured, but NodeSDK then defaults every unspecified\n // OTEL_{SIGNAL}_EXPORTER to \"otlp\" on http://localhost:4318 — shipping\n // signals the operator never opted into. An *empty* pipeline opts a\n // signal out: NodeSDK only reads OTEL_{SIGNAL}_EXPORTER when the pipeline\n // option is `undefined`, and registers no provider when handed an empty\n // one. Opted-in signals get `undefined` so they stay env-configured.\n spanProcessors: tracesConfigured ? undefined : [],\n metricReaders: metricsConfigured ? undefined : [],\n logRecordProcessors: logsConfigured ? undefined : [],\n })\n\n sdk.start()\n\n // @NOTE On SIGINT/SIGTERM the PDS releases its resources without calling\n // process.exit(), so the event loop empties and Node emits \"beforeExit\"\n // (https://nodejs.org/api/process.html#event-beforeexit). That's our window\n // to flush pending telemetry.\n process.once('beforeExit', () => {\n sdk.shutdown().catch((err) => {\n diag.error('Error terminating OpenTelemetry SDK', err)\n })\n })\n } catch (err) {\n diag.error('Error initializing OpenTelemetry SDK', err)\n }\n}\n\nfunction getInstrumentations(): Instrumentation[] {\n return [\n // @NOTE Not using getNodeAutoInstrumentations: it pulls in many\n // instrumentations we don't need, with no easy way to filter them out.\n new RuntimeNodeInstrumentation(),\n new HttpInstrumentation({\n // Derives \"http.route\" (and the span name) from the normalized XRPC path,\n // for both incoming and outgoing requests.\n //\n // @NOTE Must be applyCustomAttributesOnSpan (fires on response finish),\n // not requestHook (fires on request start). The express instrumentation\n // overwrites the shared rpcMetadata.route on every layer it enters, which\n // in this app resolves to \"/\" more often than not (multiple express apps\n // and routers mounted at \"/\", plus catchall middlewares with no route\n // layer). On finish, the http instrumentation copies rpcMetadata.route\n // into \"http.route\" and renames the span from it, clobbering anything a\n // requestHook set. This hook runs after that, so it wins.\n applyCustomAttributesOnSpan: (span, request) => {\n const { url, method, proxy } =\n 'path' in request\n ? // ClientRequest\n {\n url: request.path,\n method: request.method,\n proxy: request.getHeader('atproto-proxy'),\n }\n : // IncomingMessage\n {\n url: request.url ?? '/',\n method: request.method ?? 'GET',\n proxy: request.headers['atproto-proxy'],\n }\n\n const lxm =\n method === 'GET' || method === 'POST'\n ? extractNormalizedLxm(url)\n : undefined\n\n // Normalized route for XRPC, raw path otherwise\n const route = lxm ? `/xrpc/${lxm}` : url.split('?')[0]\n span.setAttribute(ATTR_HTTP_ROUTE, route)\n\n if (lxm) {\n span.updateName(`${method} /xrpc/${lxm}`)\n span.setAttribute(ATTR_XRPC_METHOD, lxm)\n span.setAttribute(ATTR_XRPC_PROXIED, !!proxy)\n\n if (proxy) {\n span.setAttribute(ATTR_XRPC_PROXY, proxy)\n }\n }\n },\n }),\n new ExpressInstrumentation({\n ignoreLayersType: [ExpressLayerType.MIDDLEWARE],\n }),\n new UndiciInstrumentation({\n requestHook: (span, request) => {\n const lxm = extractNormalizedLxm(request.path)\n if (lxm) {\n span.setAttribute(ATTR_XRPC_METHOD, lxm)\n }\n },\n }),\n new AwsInstrumentation(),\n new IORedisInstrumentation(),\n new BetterSqlite3Instrumentation(),\n // @NOTE Keep log correlation (trace_id/span_id injected into pino records)\n // but disable log sending: it JSON.parse()s every record on the main thread\n // and would forward all subsystems indiscriminately. Events we actually want\n // in the OTEL stack go through the Logs API explicitly (see ./events.ts).\n new PinoInstrumentation({ disableLogSending: true }),\n ]\n}\n\n/**\n * A signal counts as configured when an OTLP endpoint applies to it\n * (signal-specific or generic) and its exporter isn't set to \"none\".\n *\n * @NOTE OTEL_{SIGNAL}_EXPORTER is a comma-separated list, and the SDK handles\n * \"none\" alongside other exporters inconsistently (metrics & logs disable the\n * signal, traces falls back to \"otlp\"). Such a combination is a\n * misconfiguration, so we treat any list containing \"none\" as disabling.\n */\nfunction isSignalConfigured(signal: 'TRACES' | 'METRICS' | 'LOGS'): boolean {\n if (getStringListFromEnv(`OTEL_${signal}_EXPORTER`)?.includes('none')) {\n return false\n }\n\n return (\n !!getStringFromEnv(`OTEL_EXPORTER_OTLP_${signal}_ENDPOINT`) ||\n !!getStringFromEnv('OTEL_EXPORTER_OTLP_ENDPOINT')\n )\n}\n\n// @NOTE Hand-rolled (rather than using URL/split) because this runs on every\n// instrumented request. Should become obsolete once we have dedicated\n// XrpcClient/XrpcServer instrumentations.\nfunction extractNormalizedLxm(url: unknown): string | undefined {\n if (typeof url !== 'string') {\n return undefined\n }\n\n // 9 = \"/xrpc/\".length + shortest conceivable NSID (\"a.b\")\n if (url.length < 9 || !url.startsWith('/xrpc/')) {\n return undefined\n }\n\n const firstMethodCharPos = 6 // \"/xrpc/\".length\n\n // Characters that can never open an NSID (note \"_\" skips \"/xrpc/_health\")\n const nextChar = url.charCodeAt(firstMethodCharPos)\n if (\n nextChar === 0x2e /* '.' */ ||\n nextChar === 0x2f /* '/' */ ||\n nextChar === 0x3f /* '?' */ ||\n nextChar === 0x5f /* '_' */\n ) {\n return undefined\n }\n\n const queryIndex = url.indexOf('?', firstMethodCharPos + 1)\n\n let lastMethodCharPos = queryIndex === -1 ? url.length - 1 : queryIndex - 1\n\n // Ignore the trailing slash, if there is one\n if (url.charCodeAt(lastMethodCharPos) === 0x2f /* '/' */) {\n lastMethodCharPos--\n }\n\n if (lastMethodCharPos < 9) {\n return undefined\n }\n\n // Make sure there is no other slash in the path\n if (url.lastIndexOf('/', lastMethodCharPos) !== firstMethodCharPos - 1) {\n return undefined\n }\n\n // Require at least one dot, and not as the last character\n const lastDotPos = url.lastIndexOf('.', lastMethodCharPos)\n if (lastDotPos === -1 || lastDotPos === lastMethodCharPos) {\n return undefined\n }\n\n // @NOTE Only the domain authority is case-insensitive; the trailing name\n // segment is not, so it must be preserved as-is to avoid conflating\n // distinct NSIDs.\n return `${url.substring(firstMethodCharPos, lastDotPos).toLowerCase()}${url.substring(lastDotPos, lastMethodCharPos + 1)}`\n}\n"]}
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAA;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAA;AAC/E,OAAO,EAAE,4BAA4B,EAAE,MAAM,qCAAqC,CAAA;AAClF,OAAO,GAAG,MAAM,2BAA2B,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACjE,OAAO,EAAE,KAAK,EAAE,MAAM,kCAAkC,CAAA;AAExD,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IACX,IAAI,EAAE,GAAG,CAAC,IAAI;IACd,OAAO,EAAE,GAAG,CAAC,OAAO;IACpB,gBAAgB,EAAE;QAChB,IAAI,kBAAkB,EAAE;QACxB,IAAI,sBAAsB,EAAE;QAC5B,IAAI,4BAA4B,EAAE;KACnC;CACF,CAAC,CAAC,CAAA","sourcesContent":["import { AwsInstrumentation } from '@opentelemetry/instrumentation-aws-sdk'\nimport { IORedisInstrumentation } from '@opentelemetry/instrumentation-ioredis'\nimport { BetterSqlite3Instrumentation } from 'opentelemetry-plugin-better-sqlite3'\nimport pkg from '@atproto/pds/package.json' with { type: 'json' }\nimport { setup } from '@atproto-labs/opentelemetry-node'\n\nsetup(() => ({\n name: pkg.name,\n version: pkg.version,\n instrumentations: [\n new AwsInstrumentation(),\n new IORedisInstrumentation(),\n new BetterSqlite3Instrumentation(),\n ],\n}))\n"]}
package/example.env ADDED
@@ -0,0 +1,55 @@
1
+ # See more env options in src/config/env.ts
2
+ # Hostname - the public domain that you intend to deploy your service at
3
+ PDS_HOSTNAME="example.com"
4
+ PDS_PORT="2583"
5
+
6
+ # Database config - use one or the other
7
+ PDS_DATA_DIRECTORY="data"
8
+
9
+ # Blobstore - filesystem location to store uploaded blobs
10
+ PDS_BLOBSTORE_DISK_LOCATION="blobs"
11
+
12
+ # Private keys - these are each expected to be 64 char hex strings (256 bit)
13
+ PDS_REPO_SIGNING_KEY_K256_PRIVATE_KEY_HEX="3ee68..."
14
+ PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX="e049f..."
15
+
16
+ # Secrets - update to secure high-entropy strings
17
+ PDS_DPOP_SECRET="32-random-bytes-hex-encoded"
18
+ PDS_JWT_SECRET="jwt-secret"
19
+ PDS_ADMIN_PASSWORD="admin-pass"
20
+
21
+ # Environment - example is for live network
22
+ PDS_DID_PLC_URL="https://plc.directory"
23
+ PDS_BSKY_APP_VIEW_URL="https://api.bsky.app"
24
+ PDS_BSKY_APP_VIEW_DID="did:web:api.bsky.app"
25
+ PDS_CRAWLERS="https://bsky.network"
26
+
27
+ # OAuth Provider - branding for the login / consent screens
28
+ PDS_SERVICE_NAME="John's self hosted PDS"
29
+ PDS_LOGO_URL=
30
+ PDS_PRIMARY_COLOR="#7507e3"
31
+ PDS_ERROR_COLOR=
32
+ PDS_HOME_URL=
33
+ PDS_TERMS_OF_SERVICE_URL=
34
+ PDS_PRIVACY_POLICY_URL=
35
+ PDS_SUPPORT_URL=
36
+ # Auth screen background images, shown behind the login card, by colour scheme
37
+ PDS_BACKGROUND_LIGHT_URL=
38
+ PDS_BACKGROUND_DARK_URL=
39
+
40
+ # Debugging
41
+ NODE_TLS_REJECT_UNAUTHORIZED=1
42
+ LOG_ENABLED=0
43
+ LOG_LEVEL=info
44
+ PDS_INVITE_REQUIRED=1
45
+ PDS_DISABLE_SSRF_PROTECTION=0
46
+
47
+ # Telemetry (optional) - requires running with `node --import @atproto/pds/telemetry`.
48
+ # See:
49
+ # - https://opentelemetry.io/docs/languages/sdk-configuration/general/
50
+ # - https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/
51
+ #OTEL_SERVICE_NAME="pds"
52
+ #OTEL_NODE_RESOURCE_DETECTORS="container,env,host"
53
+ #OTEL_EXPORTER_OTLP_ENDPOINT="https://otel-collector.example.com"
54
+ #OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
55
+ #OTEL_SEMCONV_STABILITY_OPT_IN="http"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/pds",
3
- "version": "0.5.28",
3
+ "version": "0.5.29",
4
4
  "license": "MIT",
5
5
  "description": "Reference implementation of atproto Personal Data Server (PDS)",
6
6
  "keywords": [
@@ -15,6 +15,7 @@
15
15
  },
16
16
  "files": [
17
17
  "./dist",
18
+ "example.env",
18
19
  "./README.md",
19
20
  "./CHANGELOG.md"
20
21
  ],
@@ -36,21 +37,11 @@
36
37
  "dependencies": {
37
38
  "@did-plc/lib": "^0.0.4",
38
39
  "@hapi/address": "^5.1.1",
40
+ "@noble/curves": "^1.7.0",
39
41
  "@opentelemetry/api": "^1.9.1",
40
42
  "@opentelemetry/api-logs": "^0.219.0",
41
- "@opentelemetry/auto-instrumentations-node": "^0.77.0",
42
- "@opentelemetry/core": "^2.9.0",
43
- "@opentelemetry/instrumentation": "^0.219.0",
44
43
  "@opentelemetry/instrumentation-aws-sdk": "^0.74.0",
45
- "@opentelemetry/instrumentation-express": "^0.67.0",
46
- "@opentelemetry/instrumentation-http": "^0.219.0",
47
44
  "@opentelemetry/instrumentation-ioredis": "^0.67.0",
48
- "@opentelemetry/instrumentation-pino": "^0.65.0",
49
- "@opentelemetry/instrumentation-runtime-node": "^0.32.0",
50
- "@opentelemetry/instrumentation-undici": "^0.29.0",
51
- "@opentelemetry/resource-detector-container": "^0.8.10",
52
- "@opentelemetry/sdk-node": "^0.219.0",
53
- "@opentelemetry/semantic-conventions": "^1.41.1",
54
45
  "better-sqlite3": "^12.0.0",
55
46
  "compression": "^1.7.4",
56
47
  "cors": "^2.8.5",
@@ -62,7 +53,6 @@
62
53
  "http-terminator": "^3.2.0",
63
54
  "ioredis": "^5.3.2",
64
55
  "jose": "^5.0.1",
65
- "key-encoder": "^2.0.3",
66
56
  "kysely": "^0.29.2",
67
57
  "nodemailer": "^6.8.0",
68
58
  "nodemailer-html-to-text": "^3.2.0",
@@ -75,24 +65,25 @@
75
65
  "undici": "^8.5.0",
76
66
  "zod": "^3.23.8",
77
67
  "@atproto-labs/fetch-node": "^0.3.7",
68
+ "@atproto-labs/xrpc-utils": "^0.1.18",
69
+ "@atproto-labs/simple-store": "^0.5.1",
78
70
  "@atproto-labs/simple-store-redis": "^0.1.6",
79
- "@atproto-labs/xrpc-utils": "^0.1.17",
80
- "@atproto/aws": "^0.3.13",
81
- "@atproto/crypto": "^0.5.4",
82
- "@atproto/common": "^0.8.0",
83
71
  "@atproto/did": "^0.5.4",
84
- "@atproto/lex": "^0.3.6",
85
- "@atproto/lex-cbor": "^0.1.6",
86
- "@atproto-labs/simple-store": "^0.5.1",
87
72
  "@atproto/identity": "^0.5.9",
88
73
  "@atproto-labs/simple-store-memory": "^0.2.6",
89
- "@atproto/repo": "^0.10.11",
74
+ "@atproto/lex-cbor": "^0.1.6",
75
+ "@atproto/crypto": "^0.5.4",
76
+ "@atproto/common": "^0.8.0",
90
77
  "@atproto/lex-json": "^0.1.6",
91
- "@atproto/lex-data": "^0.1.7",
92
- "@atproto/oauth-scopes": "^0.5.9",
78
+ "@atproto/aws": "^0.3.14",
93
79
  "@atproto/syntax": "^0.7.4",
94
- "@atproto/xrpc-server": "^0.12.4",
95
- "@atproto/oauth-provider": "^0.22.2"
80
+ "@atproto-labs/opentelemetry-node": "^0.1.0",
81
+ "@atproto/oauth-provider": "^0.22.3",
82
+ "@atproto/oauth-scopes": "^0.5.9",
83
+ "@atproto/xrpc-server": "^0.12.5",
84
+ "@atproto/lex": "^0.3.6",
85
+ "@atproto/lex-data": "^0.1.7",
86
+ "@atproto/repo": "^0.10.11"
96
87
  },
97
88
  "devDependencies": {
98
89
  "@did-plc/server": "^0.0.1",
@@ -107,7 +98,7 @@
107
98
  "jest": "^30.0.0",
108
99
  "puppeteer": "^23.11.1",
109
100
  "ws": "^8.12.0",
110
- "@atproto/api": "^0.20.40",
101
+ "@atproto/api": "^0.20.41",
111
102
  "@atproto/lex-document": "^0.1.9",
112
103
  "@atproto/oauth-client-browser-example": "^0.1.7"
113
104
  },