@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 +37 -0
- package/dist/api/com/atproto/identity/resolveHandle.d.ts.map +1 -1
- package/dist/api/com/atproto/identity/resolveHandle.js +1 -1
- package/dist/api/com/atproto/identity/resolveHandle.js.map +1 -1
- package/dist/auth-verifier.d.ts.map +1 -1
- package/dist/auth-verifier.js +12 -6
- package/dist/auth-verifier.js.map +1 -1
- package/dist/context.d.ts +2 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +6 -0
- package/dist/context.js.map +1 -1
- package/dist/lexicons/app/bsky/embed/video.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/embed/video.defs.js +2 -4
- package/dist/lexicons/app/bsky/embed/video.defs.js.map +1 -1
- package/dist/scripts/index.d.ts +2 -2
- package/dist/scripts/index.d.ts.map +1 -1
- package/dist/scripts/index.js +2 -2
- package/dist/scripts/index.js.map +1 -1
- package/dist/telemetry.js +8 -186
- package/dist/telemetry.js.map +1 -1
- package/example.env +55 -0
- package/package.json +17 -26
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,
|
|
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,
|
|
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":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAoC,MAAM,aAAa,CAAA;AAC9E,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"auth-verifier.d.ts","sourceRoot":"","sources":["../src/auth-verifier.ts"],"names":[],"mappings":"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"}
|
package/dist/auth-verifier.js
CHANGED
|
@@ -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
|
-
|
|
441
|
-
|
|
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":"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","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
|
|
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: {
|
package/dist/context.d.ts.map
CHANGED
|
@@ -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,
|
|
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'
|
package/dist/context.js.map
CHANGED
|
@@ -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":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAChC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAE3C,QAAA,MAAM,KAAK,yBAAyB,CAAA;AAEpC,KAAK,KAAK,GAAG,OAAO,KAAK,CAAA;AAEzB,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,KAAK,IAAI,GAAG;IACV,KAAK,CAAC,EAAE,sBAAsB,CAAA;IAE9B;;OAEG;IACH,KAAK,EAAE,CAAC,CAAC,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;IAEpB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,SAAS,CAAC,WAAW,CAAA;IAEnC;;OAEG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC,aAAa,CAAA;CACnD,CAAA;AAED,YAAY,EAAE,IAAI,EAAE,CAAA;AAEpB,QAAA,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"video.defs.d.ts","sourceRoot":"","sources":["../../../../../src/lexicons/app/bsky/embed/video.defs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAChC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAE3C,QAAA,MAAM,KAAK,yBAAyB,CAAA;AAEpC,KAAK,KAAK,GAAG,OAAO,KAAK,CAAA;AAEzB,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,KAAK,IAAI,GAAG;IACV,KAAK,CAAC,EAAE,sBAAsB,CAAA;IAE9B;;OAEG;IACH,KAAK,EAAE,CAAC,CAAC,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;IAEpB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,SAAS,CAAC,WAAW,CAAA;IAEnC;;OAEG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC,aAAa,CAAA;CACnD,CAAA;AAED,YAAY,EAAE,IAAI,EAAE,CAAA;AAEpB,QAAA,MAAM,IAAI,sEAqBT,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA;AAEf,QAAA,MAAM,KAAK,yBAAQ,CAAA;AAEnB,KAAK,KAAK,GAAG,OAAO,KAAK,CAAA;AAEzB,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,eAAO,MAAM,SAAS,wHAAyC,CAAA;AAC/D,eAAO,MAAM,MAAM;;eAtDT,sBAAsB;eAKvB,CAAC,CAAC,OAAO;mBACL,OAAO,EAAE;cAKd,MAAM;sBACE,SAAS,CAAC,WAAW;uBAKpB,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC,aAAa;;;eAjB1C,sBAAsB;eAKvB,CAAC,CAAC,OAAO;mBACL,OAAO,EAAE;cAKd,MAAM;sBACE,SAAS,CAAC,WAAW;uBAKpB,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC,aAAa;;CAqCK,CAAA;AACzD,eAAO,MAAM,OAAO;YAvDV,sBAAsB;WAKvB,CAAC,CAAC,OAAO;eACL,OAAO,EAAE;UAKd,MAAM;kBACE,SAAS,CAAC,WAAW;mBAKpB,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC,aAAa;CAsCO,CAAA;AAC3D,eAAO,MAAM,MAAM,uDAAsC,CAAA;AACzD,eAAO,MAAM,KAAK;YAzDR,sBAAsB;WAKvB,CAAC,CAAC,OAAO;eACL,OAAO,EAAE;UAKd,MAAM;kBACE,SAAS,CAAC,WAAW;mBAKpB,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC,aAAa;CAwCG,CAAA;AACvD,eAAO,MAAM,UAAU;YA1Db,sBAAsB;WAKvB,CAAC,CAAC,OAAO;eACL,OAAO,EAAE;UAKd,MAAM;kBACE,SAAS,CAAC,WAAW;mBAKpB,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC,aAAa;cAyCa,CAAA;AACjE,eAAO,MAAM,QAAQ;YA3DX,sBAAsB;WAKvB,CAAC,CAAC,OAAO;eACL,OAAO,EAAE;UAKd,MAAM;kBACE,SAAS,CAAC,WAAW;mBAKpB,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC,aAAa;CA0CS,CAAA;AAC7D,eAAO,MAAM,MAAM;YA5DT,sBAAsB;WAKvB,CAAC,CAAC,OAAO;eACL,OAAO,EAAE;UAKd,MAAM;kBACE,SAAS,CAAC,WAAW;mBAKpB,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC,aAAa;CA2CK,CAAA;AACzD,eAAO,MAAM,UAAU;YA7Db,sBAAsB;WAKvB,CAAC,CAAC,OAAO;eACL,OAAO,EAAE;UAKd,MAAM;kBACE,SAAS,CAAC,WAAW;mBAKpB,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC,aAAa;EA4Ca,CAAA;AACjE,eAAO,MAAM,SAAS;YA9DZ,sBAAsB;WAKvB,CAAC,CAAC,OAAO;eACL,OAAO,EAAE;UAKd,MAAM;kBACE,SAAS,CAAC,WAAW;mBAKpB,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC,aAAa;CA6CW,CAAA;AAC/D,eAAO,MAAM,aAAa;YA/DhB,sBAAsB;WAKvB,CAAC,CAAC,OAAO;eACL,OAAO,EAAE;UAKd,MAAM;kBACE,SAAS,CAAC,WAAW;mBAKpB,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC,aAAa;EA8CmB,CAAA;AAEvE,KAAK,OAAO,GAAG;IACb,KAAK,CAAC,EAAE,8BAA8B,CAAA;IACtC,IAAI,EAAE,CAAC,CAAC,cAAc,CAAA;IACtB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAA;CAChB,CAAA;AAED,YAAY,EAAE,OAAO,EAAE,CAAA;AAEvB,QAAA,MAAM,OAAO,oFAOZ,CAAA;AAED,OAAO,EAAE,OAAO,EAAE,CAAA;AAElB,KAAK,IAAI,GAAG;IACV,KAAK,CAAC,EAAE,2BAA2B,CAAA;IACnC,GAAG,EAAE,CAAC,CAAC,SAAS,CAAA;IAChB,QAAQ,EAAE,CAAC,CAAC,SAAS,CAAA;IACrB,SAAS,CAAC,EAAE,CAAC,CAAC,SAAS,CAAA;IACvB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,SAAS,CAAC,WAAW,CAAA;IAEnC;;OAEG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC,aAAa,CAAA;CACnD,CAAA;AAED,YAAY,EAAE,IAAI,EAAE,CAAA;AAEpB,QAAA,MAAM,IAAI,2EAmBT,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
|
|
@@ -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":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAChC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAE3C,MAAM,KAAK,GAAG,sBAAsB,CAAA;AAIpC,OAAO,EAAE,KAAK,EAAE,CAAA;AAyBhB,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,WAAW,CACtC,KAAK,EACL,MAAM;AACN,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC;IACrB,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IAC1E,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,QAAQ;IAChC,aAAa,CAAC,CAAC,CAAC,KAAK;IACnB,aAAa,CAAC,CAAC,CAAC,GAAG,CAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAQ,CAAC,EACpD,EAAE,SAAS,EAAE,EAAE,EAAE,CAClB,CACF;IACD,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,QAAQ
|
|
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"]}
|
package/dist/scripts/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { publishIdentity, publishIdentityFromFile } from './publish-identity.js';
|
|
2
|
-
import {
|
|
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
|
|
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,
|
|
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"}
|
package/dist/scripts/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { publishIdentity, publishIdentityFromFile } from './publish-identity.js';
|
|
2
|
-
import {
|
|
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':
|
|
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,
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
128
|
-
|
|
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
|
package/dist/telemetry.js.map
CHANGED
|
@@ -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.
|
|
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/
|
|
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/
|
|
92
|
-
"@atproto/oauth-scopes": "^0.5.9",
|
|
78
|
+
"@atproto/aws": "^0.3.14",
|
|
93
79
|
"@atproto/syntax": "^0.7.4",
|
|
94
|
-
"@atproto/
|
|
95
|
-
"@atproto/oauth-provider": "^0.22.
|
|
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.
|
|
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
|
},
|