@atproto/bsky 0.0.198 → 0.0.200
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 +26 -0
- package/dist/api/age-assurance/const.d.ts +11 -0
- package/dist/api/age-assurance/const.d.ts.map +1 -0
- package/dist/api/age-assurance/const.js +142 -0
- package/dist/api/age-assurance/const.js.map +1 -0
- package/dist/api/age-assurance/index.d.ts +4 -0
- package/dist/api/age-assurance/index.d.ts.map +1 -0
- package/dist/api/age-assurance/index.js +24 -0
- package/dist/api/age-assurance/index.js.map +1 -0
- package/dist/api/age-assurance/kws/age-verified.d.ts +109 -0
- package/dist/api/age-assurance/kws/age-verified.d.ts.map +1 -0
- package/dist/api/age-assurance/kws/age-verified.js +63 -0
- package/dist/api/age-assurance/kws/age-verified.js.map +1 -0
- package/dist/api/age-assurance/kws/const.d.ts +13 -0
- package/dist/api/age-assurance/kws/const.d.ts.map +1 -0
- package/dist/api/age-assurance/kws/const.js +36 -0
- package/dist/api/age-assurance/kws/const.js.map +1 -0
- package/dist/api/age-assurance/kws/external-payload.d.ts +75 -0
- package/dist/api/age-assurance/kws/external-payload.d.ts.map +1 -0
- package/dist/api/age-assurance/kws/external-payload.js +124 -0
- package/dist/api/age-assurance/kws/external-payload.js.map +1 -0
- package/dist/api/age-assurance/kws/external-payload.test.d.ts +2 -0
- package/dist/api/age-assurance/kws/external-payload.test.d.ts.map +1 -0
- package/dist/api/age-assurance/kws/external-payload.test.js +65 -0
- package/dist/api/age-assurance/kws/external-payload.test.js.map +1 -0
- package/dist/api/age-assurance/redirects/kws-age-verified.d.ts +4 -0
- package/dist/api/age-assurance/redirects/kws-age-verified.d.ts.map +1 -0
- package/dist/api/age-assurance/redirects/kws-age-verified.js +76 -0
- package/dist/api/age-assurance/redirects/kws-age-verified.js.map +1 -0
- package/dist/api/age-assurance/stash.d.ts +4 -0
- package/dist/api/age-assurance/stash.d.ts.map +1 -0
- package/dist/api/age-assurance/stash.js +19 -0
- package/dist/api/age-assurance/stash.js.map +1 -0
- package/dist/api/age-assurance/types.d.ts +10 -0
- package/dist/api/age-assurance/types.d.ts.map +1 -0
- package/dist/api/age-assurance/types.js +3 -0
- package/dist/api/age-assurance/types.js.map +1 -0
- package/dist/api/age-assurance/util.d.ts +15 -0
- package/dist/api/age-assurance/util.d.ts.map +1 -0
- package/dist/api/age-assurance/util.js +54 -0
- package/dist/api/age-assurance/util.js.map +1 -0
- package/dist/api/age-assurance/webhooks/kws-age-verified.d.ts +4 -0
- package/dist/api/age-assurance/webhooks/kws-age-verified.d.ts.map +1 -0
- package/dist/api/age-assurance/webhooks/kws-age-verified.js +63 -0
- package/dist/api/age-assurance/webhooks/kws-age-verified.js.map +1 -0
- package/dist/api/app/bsky/ageassurance/begin.d.ts +4 -0
- package/dist/api/app/bsky/ageassurance/begin.d.ts.map +1 -0
- package/dist/api/app/bsky/ageassurance/begin.js +131 -0
- package/dist/api/app/bsky/ageassurance/begin.js.map +1 -0
- package/dist/api/app/bsky/ageassurance/getConfig.d.ts +4 -0
- package/dist/api/app/bsky/ageassurance/getConfig.d.ts.map +1 -0
- package/dist/api/app/bsky/ageassurance/getConfig.js +16 -0
- package/dist/api/app/bsky/ageassurance/getConfig.js.map +1 -0
- package/dist/api/app/bsky/ageassurance/getState.d.ts +4 -0
- package/dist/api/app/bsky/ageassurance/getState.d.ts.map +1 -0
- package/dist/api/app/bsky/ageassurance/getState.js +42 -0
- package/dist/api/app/bsky/ageassurance/getState.js.map +1 -0
- package/dist/api/app/bsky/contact/dismissMatch.d.ts +4 -0
- package/dist/api/app/bsky/contact/dismissMatch.d.ts.map +1 -0
- package/dist/api/app/bsky/contact/dismissMatch.js +23 -0
- package/dist/api/app/bsky/contact/dismissMatch.js.map +1 -0
- package/dist/api/app/bsky/contact/getMatches.d.ts +4 -0
- package/dist/api/app/bsky/contact/getMatches.d.ts.map +1 -0
- package/dist/api/app/bsky/contact/getMatches.js +59 -0
- package/dist/api/app/bsky/contact/getMatches.js.map +1 -0
- package/dist/api/app/bsky/contact/getSyncStatus.d.ts +4 -0
- package/dist/api/app/bsky/contact/getSyncStatus.d.ts.map +1 -0
- package/dist/api/app/bsky/contact/getSyncStatus.js +32 -0
- package/dist/api/app/bsky/contact/getSyncStatus.js.map +1 -0
- package/dist/api/app/bsky/contact/importContacts.d.ts +4 -0
- package/dist/api/app/bsky/contact/importContacts.d.ts.map +1 -0
- package/dist/api/app/bsky/contact/importContacts.js +62 -0
- package/dist/api/app/bsky/contact/importContacts.js.map +1 -0
- package/dist/api/app/bsky/contact/removeData.d.ts +4 -0
- package/dist/api/app/bsky/contact/removeData.d.ts.map +1 -0
- package/dist/api/app/bsky/contact/removeData.js +22 -0
- package/dist/api/app/bsky/contact/removeData.js.map +1 -0
- package/dist/api/app/bsky/contact/startPhoneVerification.d.ts +4 -0
- package/dist/api/app/bsky/contact/startPhoneVerification.d.ts.map +1 -0
- package/dist/api/app/bsky/contact/startPhoneVerification.js +23 -0
- package/dist/api/app/bsky/contact/startPhoneVerification.js.map +1 -0
- package/dist/api/app/bsky/contact/util.d.ts +6 -0
- package/dist/api/app/bsky/contact/util.d.ts.map +1 -0
- package/dist/api/app/bsky/contact/util.js +10 -0
- package/dist/api/app/bsky/contact/util.js.map +1 -0
- package/dist/api/app/bsky/contact/verifyPhone.d.ts +4 -0
- package/dist/api/app/bsky/contact/verifyPhone.d.ts.map +1 -0
- package/dist/api/app/bsky/contact/verifyPhone.js +26 -0
- package/dist/api/app/bsky/contact/verifyPhone.js.map +1 -0
- package/dist/api/app/bsky/graph/getRelationships.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getRelationships.js +4 -0
- package/dist/api/app/bsky/graph/getRelationships.js.map +1 -1
- package/dist/api/external.d.ts.map +1 -1
- package/dist/api/external.js +2 -0
- package/dist/api/external.js.map +1 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +22 -2
- package/dist/api/index.js.map +1 -1
- package/dist/api/kws/api.d.ts.map +1 -1
- package/dist/api/kws/api.js +44 -26
- package/dist/api/kws/api.js.map +1 -1
- package/dist/api/kws/index.d.ts.map +1 -1
- package/dist/api/kws/index.js +3 -1
- package/dist/api/kws/index.js.map +1 -1
- package/dist/api/kws/webhook.d.ts +3 -1
- package/dist/api/kws/webhook.d.ts.map +1 -1
- package/dist/api/kws/webhook.js +48 -20
- package/dist/api/kws/webhook.js.map +1 -1
- package/dist/config.d.ts +22 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +31 -2
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +3 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +3 -0
- package/dist/context.js.map +1 -1
- package/dist/data-plane/bsync/index.d.ts.map +1 -1
- package/dist/data-plane/bsync/index.js +22 -0
- package/dist/data-plane/bsync/index.js.map +1 -1
- package/dist/data-plane/server/db/migrations/20251120T004738098Z-update-actor-age-assurance-v2.d.ts +4 -0
- package/dist/data-plane/server/db/migrations/20251120T004738098Z-update-actor-age-assurance-v2.d.ts.map +1 -0
- package/dist/data-plane/server/db/migrations/20251120T004738098Z-update-actor-age-assurance-v2.js +30 -0
- package/dist/data-plane/server/db/migrations/20251120T004738098Z-update-actor-age-assurance-v2.js.map +1 -0
- package/dist/data-plane/server/db/migrations/index.d.ts +1 -0
- package/dist/data-plane/server/db/migrations/index.d.ts.map +1 -1
- package/dist/data-plane/server/db/migrations/index.js +2 -1
- package/dist/data-plane/server/db/migrations/index.js.map +1 -1
- package/dist/data-plane/server/db/pagination.d.ts +3 -3
- package/dist/data-plane/server/db/tables/actor.d.ts +3 -0
- package/dist/data-plane/server/db/tables/actor.d.ts.map +1 -1
- package/dist/data-plane/server/db/tables/actor.js.map +1 -1
- package/dist/data-plane/server/routes/profile.d.ts.map +1 -1
- package/dist/data-plane/server/routes/profile.js +13 -1
- package/dist/data-plane/server/routes/profile.js.map +1 -1
- package/dist/hydration/actor.js +1 -1
- package/dist/hydration/actor.js.map +1 -1
- package/dist/hydration/hydrator.js +1 -1
- package/dist/hydration/hydrator.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/kws.d.ts +35 -0
- package/dist/kws.d.ts.map +1 -1
- package/dist/kws.js +54 -0
- package/dist/kws.js.map +1 -1
- package/dist/lexicon/index.d.ts +19 -0
- package/dist/lexicon/index.d.ts.map +1 -1
- package/dist/lexicon/index.js +48 -1
- package/dist/lexicon/index.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +664 -0
- package/dist/lexicon/lexicons.d.ts.map +1 -1
- package/dist/lexicon/lexicons.js +354 -0
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/app/bsky/contact/defs.d.ts +24 -0
- package/dist/lexicon/types/app/bsky/contact/defs.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/contact/defs.js +25 -0
- package/dist/lexicon/types/app/bsky/contact/defs.js.map +1 -0
- package/dist/lexicon/types/app/bsky/contact/dismissMatch.d.ts +25 -0
- package/dist/lexicon/types/app/bsky/contact/dismissMatch.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/contact/dismissMatch.js +7 -0
- package/dist/lexicon/types/app/bsky/contact/dismissMatch.js.map +1 -0
- package/dist/lexicon/types/app/bsky/contact/getMatches.d.ts +25 -0
- package/dist/lexicon/types/app/bsky/contact/getMatches.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/contact/getMatches.js +7 -0
- package/dist/lexicon/types/app/bsky/contact/getMatches.js.map +1 -0
- package/dist/lexicon/types/app/bsky/contact/getSyncStatus.d.ts +21 -0
- package/dist/lexicon/types/app/bsky/contact/getSyncStatus.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/contact/getSyncStatus.js +7 -0
- package/dist/lexicon/types/app/bsky/contact/getSyncStatus.js.map +1 -0
- package/dist/lexicon/types/app/bsky/contact/importContacts.d.ts +30 -0
- package/dist/lexicon/types/app/bsky/contact/importContacts.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/contact/importContacts.js +7 -0
- package/dist/lexicon/types/app/bsky/contact/importContacts.js.map +1 -0
- package/dist/lexicon/types/app/bsky/contact/removeData.d.ts +23 -0
- package/dist/lexicon/types/app/bsky/contact/removeData.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/contact/removeData.js +7 -0
- package/dist/lexicon/types/app/bsky/contact/removeData.js.map +1 -0
- package/dist/lexicon/types/app/bsky/contact/startPhoneVerification.d.ts +25 -0
- package/dist/lexicon/types/app/bsky/contact/startPhoneVerification.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/contact/startPhoneVerification.js +7 -0
- package/dist/lexicon/types/app/bsky/contact/startPhoneVerification.js.map +1 -0
- package/dist/lexicon/types/app/bsky/contact/verifyPhone.d.ts +29 -0
- package/dist/lexicon/types/app/bsky/contact/verifyPhone.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/contact/verifyPhone.js +7 -0
- package/dist/lexicon/types/app/bsky/contact/verifyPhone.js.map +1 -0
- package/dist/lexicon/types/app/bsky/graph/defs.d.ts +8 -0
- package/dist/lexicon/types/app/bsky/graph/defs.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/graph/defs.js.map +1 -1
- package/dist/logger.d.ts +1 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +2 -1
- package/dist/logger.js.map +1 -1
- package/dist/proto/bsky_pb.d.ts +4 -0
- package/dist/proto/bsky_pb.d.ts.map +1 -1
- package/dist/proto/bsky_pb.js +10 -0
- package/dist/proto/bsky_pb.js.map +1 -1
- package/dist/proto/rolodex_connect.d.ts +83 -0
- package/dist/proto/rolodex_connect.d.ts.map +1 -0
- package/dist/proto/rolodex_connect.js +90 -0
- package/dist/proto/rolodex_connect.js.map +1 -0
- package/dist/proto/rolodex_pb.d.ts +363 -0
- package/dist/proto/rolodex_pb.d.ts.map +1 -0
- package/dist/proto/rolodex_pb.js +1032 -0
- package/dist/proto/rolodex_pb.js.map +1 -0
- package/dist/rolodex.d.ts +9 -0
- package/dist/rolodex.d.ts.map +1 -0
- package/dist/rolodex.js +25 -0
- package/dist/rolodex.js.map +1 -0
- package/dist/stash.d.ts +1 -0
- package/dist/stash.d.ts.map +1 -1
- package/dist/stash.js +1 -0
- package/dist/stash.js.map +1 -1
- package/dist/util/uris.d.ts +2 -2
- package/dist/util/uris.d.ts.map +1 -1
- package/package.json +16 -15
- package/proto/bsky.proto +1 -0
- package/proto/rolodex.proto +116 -0
- package/src/api/age-assurance/const.ts +142 -0
- package/src/api/age-assurance/index.ts +34 -0
- package/src/api/age-assurance/kws/age-verified.ts +75 -0
- package/src/api/age-assurance/kws/const.ts +33 -0
- package/src/api/age-assurance/kws/external-payload.test.ts +72 -0
- package/src/api/age-assurance/kws/external-payload.ts +149 -0
- package/src/api/age-assurance/redirects/kws-age-verified.ts +107 -0
- package/src/api/age-assurance/stash.ts +22 -0
- package/src/api/age-assurance/types.ts +10 -0
- package/src/api/age-assurance/util.ts +66 -0
- package/src/api/age-assurance/webhooks/kws-age-verified.ts +75 -0
- package/src/api/app/bsky/ageassurance/begin.ts +167 -0
- package/src/api/app/bsky/ageassurance/getConfig.ts +15 -0
- package/src/api/app/bsky/ageassurance/getState.ts +53 -0
- package/src/api/app/bsky/contact/dismissMatch.ts +24 -0
- package/src/api/app/bsky/contact/getMatches.ts +111 -0
- package/src/api/app/bsky/contact/getSyncStatus.ts +35 -0
- package/src/api/app/bsky/contact/importContacts.ts +118 -0
- package/src/api/app/bsky/contact/removeData.ts +23 -0
- package/src/api/app/bsky/contact/startPhoneVerification.ts +24 -0
- package/src/api/app/bsky/contact/util.ts +13 -0
- package/src/api/app/bsky/contact/verifyPhone.ts +27 -0
- package/src/api/app/bsky/graph/getRelationships.ts +4 -0
- package/src/api/external.ts +2 -0
- package/src/api/index.ts +20 -0
- package/src/api/kws/api.ts +55 -34
- package/src/api/kws/index.ts +7 -1
- package/src/api/kws/webhook.ts +57 -34
- package/src/config.ts +53 -2
- package/src/context.ts +6 -0
- package/src/data-plane/bsync/index.ts +31 -0
- package/src/data-plane/server/db/migrations/20251120T004738098Z-update-actor-age-assurance-v2.ts +28 -0
- package/src/data-plane/server/db/migrations/index.ts +1 -0
- package/src/data-plane/server/db/tables/actor.ts +3 -0
- package/src/data-plane/server/routes/profile.ts +12 -1
- package/src/hydration/actor.ts +1 -1
- package/src/hydration/hydrator.ts +1 -1
- package/src/index.ts +13 -0
- package/src/kws.ts +81 -0
- package/src/lexicon/index.ts +101 -0
- package/src/lexicon/lexicons.ts +375 -0
- package/src/lexicon/types/app/bsky/contact/defs.ts +52 -0
- package/src/lexicon/types/app/bsky/contact/dismissMatch.ts +43 -0
- package/src/lexicon/types/app/bsky/contact/getMatches.ts +43 -0
- package/src/lexicon/types/app/bsky/contact/getSyncStatus.ts +39 -0
- package/src/lexicon/types/app/bsky/contact/importContacts.ts +49 -0
- package/src/lexicon/types/app/bsky/contact/removeData.ts +40 -0
- package/src/lexicon/types/app/bsky/contact/startPhoneVerification.ts +43 -0
- package/src/lexicon/types/app/bsky/contact/verifyPhone.ts +48 -0
- package/src/lexicon/types/app/bsky/graph/defs.ts +8 -0
- package/src/logger.ts +2 -0
- package/src/proto/bsky_pb.ts +6 -0
- package/src/proto/rolodex_connect.ts +89 -0
- package/src/proto/rolodex_pb.ts +746 -0
- package/src/rolodex.ts +42 -0
- package/src/stash.ts +3 -0
- package/tests/views/__snapshots__/profile.test.ts.snap +103 -0
- package/tests/views/age-assurance-v2.test.ts +745 -0
- package/tests/views/age-assurance.test.ts +2 -0
- package/tests/views/profile.test.ts +39 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/tsconfig.tests.tsbuildinfo +1 -1
package/src/api/kws/api.ts
CHANGED
|
@@ -1,42 +1,41 @@
|
|
|
1
1
|
import express, { RequestHandler } from 'express'
|
|
2
2
|
import { httpLogger as log } from '../../logger'
|
|
3
|
+
import { AGE_ASSURANCE_CONFIG } from '../age-assurance/const'
|
|
3
4
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from '
|
|
5
|
+
KWSExternalPayloadVersion,
|
|
6
|
+
parseKWSExternalPayloadV1WithV2Compat,
|
|
7
|
+
} from '../age-assurance/kws/external-payload'
|
|
8
|
+
import { createEvent } from '../age-assurance/stash'
|
|
9
|
+
import { computeAgeAssuranceAccessOrThrow } from '../age-assurance/util'
|
|
10
|
+
import { AppContextWithKwsClient } from './types'
|
|
9
11
|
import {
|
|
10
12
|
createStashEvent,
|
|
11
13
|
getClientUa,
|
|
12
|
-
parseExternalPayload,
|
|
13
14
|
parseStatus,
|
|
14
15
|
validateSignature,
|
|
15
16
|
} from './util'
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
function parseQueryParams(
|
|
18
19
|
ctx: AppContextWithKwsClient,
|
|
19
20
|
req: express.Request,
|
|
20
|
-
):
|
|
21
|
+
): {
|
|
22
|
+
status: string
|
|
23
|
+
externalPayload: string
|
|
24
|
+
} {
|
|
21
25
|
try {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
signature: req.query.signature,
|
|
26
|
-
status: req.query.status,
|
|
27
|
-
})
|
|
26
|
+
const status = String(req.query.status)
|
|
27
|
+
const externalPayload = String(req.query.externalPayload)
|
|
28
|
+
const signature = String(req.query.signature)
|
|
28
29
|
|
|
29
|
-
const data = `${intermediate.status}:${intermediate.externalPayload}`
|
|
30
30
|
validateSignature(
|
|
31
31
|
ctx.cfg.kws.verificationSecret,
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
`${status}:${externalPayload}`,
|
|
33
|
+
signature,
|
|
34
34
|
)
|
|
35
35
|
|
|
36
36
|
return {
|
|
37
|
-
|
|
38
|
-
externalPayload
|
|
39
|
-
status: parseStatus(intermediate.status),
|
|
37
|
+
status,
|
|
38
|
+
externalPayload,
|
|
40
39
|
}
|
|
41
40
|
} catch (err) {
|
|
42
41
|
throw new Error('Invalid KWS API request', { cause: err })
|
|
@@ -48,29 +47,51 @@ export const verificationHandler =
|
|
|
48
47
|
async (req: express.Request, res: express.Response) => {
|
|
49
48
|
let actorDid: string | undefined
|
|
50
49
|
try {
|
|
51
|
-
const query =
|
|
52
|
-
const {
|
|
53
|
-
externalPayload,
|
|
54
|
-
status: { verified },
|
|
55
|
-
} = query
|
|
50
|
+
const query = parseQueryParams(ctx, req)
|
|
51
|
+
const { verified } = parseStatus(query.status)
|
|
56
52
|
if (!verified) {
|
|
57
53
|
throw new Error(
|
|
58
54
|
'Unexpected KWS verification response call with unverified status',
|
|
59
55
|
)
|
|
60
56
|
}
|
|
61
57
|
|
|
62
|
-
const { actorDid: externalPayloadActorDid, attemptId } = externalPayload
|
|
63
|
-
actorDid = externalPayloadActorDid
|
|
64
58
|
// Assumes `app.set('trust proxy', ...)` configured with `true` or specific values.
|
|
65
59
|
const completeIp = req.ip
|
|
66
60
|
const completeUa = getClientUa(req)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
61
|
+
const externalPayload = parseKWSExternalPayloadV1WithV2Compat(
|
|
62
|
+
query.externalPayload,
|
|
63
|
+
)
|
|
64
|
+
actorDid = externalPayload.actorDid
|
|
65
|
+
|
|
66
|
+
if (externalPayload.version === KWSExternalPayloadVersion.V2) {
|
|
67
|
+
const { countryCode, regionCode, attemptId } = externalPayload
|
|
68
|
+
const { access } = computeAgeAssuranceAccessOrThrow(
|
|
69
|
+
AGE_ASSURANCE_CONFIG,
|
|
70
|
+
{
|
|
71
|
+
countryCode: countryCode,
|
|
72
|
+
regionCode: regionCode,
|
|
73
|
+
verifiedMinimumAge: 18, // `adult-verified` is 18+ only
|
|
74
|
+
},
|
|
75
|
+
)
|
|
76
|
+
await createEvent(ctx, actorDid, {
|
|
77
|
+
attemptId,
|
|
78
|
+
status: 'assured',
|
|
79
|
+
access,
|
|
80
|
+
countryCode,
|
|
81
|
+
regionCode,
|
|
82
|
+
completeIp,
|
|
83
|
+
completeUa,
|
|
84
|
+
})
|
|
85
|
+
} else {
|
|
86
|
+
await createStashEvent(ctx, {
|
|
87
|
+
actorDid,
|
|
88
|
+
attemptId: externalPayload.attemptId,
|
|
89
|
+
status: 'assured',
|
|
90
|
+
completeIp,
|
|
91
|
+
completeUa,
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
|
|
74
95
|
return res
|
|
75
96
|
.status(302)
|
|
76
97
|
.setHeader(
|
package/src/api/kws/index.ts
CHANGED
|
@@ -9,7 +9,13 @@ export const createRouter = (ctx: AppContext): Router => {
|
|
|
9
9
|
|
|
10
10
|
const router = Router()
|
|
11
11
|
router.use(raw({ type: 'application/json' }))
|
|
12
|
-
router.post(
|
|
12
|
+
router.post(
|
|
13
|
+
'/age-assurance-webhook',
|
|
14
|
+
webhookAuth({
|
|
15
|
+
secret: ctx.cfg.kws.webhookSecret,
|
|
16
|
+
}),
|
|
17
|
+
webhookHandler(ctx),
|
|
18
|
+
)
|
|
13
19
|
router.get('/age-assurance-verification', verificationHandler(ctx))
|
|
14
20
|
return router
|
|
15
21
|
}
|
package/src/api/kws/webhook.ts
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import express, { RequestHandler } from 'express'
|
|
2
2
|
import { httpLogger as log } from '../../logger'
|
|
3
|
+
import { AGE_ASSURANCE_CONFIG } from '../age-assurance/const'
|
|
4
|
+
import {
|
|
5
|
+
KWSExternalPayloadVersion,
|
|
6
|
+
parseKWSExternalPayloadV1WithV2Compat,
|
|
7
|
+
} from '../age-assurance/kws/external-payload'
|
|
8
|
+
import { createEvent } from '../age-assurance/stash'
|
|
9
|
+
import { computeAgeAssuranceAccessOrThrow } from '../age-assurance/util'
|
|
3
10
|
import {
|
|
4
11
|
AppContextWithKwsClient,
|
|
5
12
|
KwsWebhookBody,
|
|
6
13
|
webhookBodyIntermediateSchema,
|
|
7
14
|
} from './types'
|
|
8
|
-
import {
|
|
9
|
-
createStashEvent,
|
|
10
|
-
kwsWwwAuthenticate,
|
|
11
|
-
parseExternalPayload,
|
|
12
|
-
validateSignature,
|
|
13
|
-
} from './util'
|
|
15
|
+
import { createStashEvent, kwsWwwAuthenticate, validateSignature } from './util'
|
|
14
16
|
|
|
15
17
|
export const webhookAuth =
|
|
16
|
-
(
|
|
18
|
+
({ secret }: { secret: string }): RequestHandler =>
|
|
17
19
|
(req: express.Request, res: express.Response, next: express.NextFunction) => {
|
|
18
20
|
const body: Buffer = req.body
|
|
19
21
|
const sigHeader = req.headers['x-kws-signature']
|
|
@@ -34,7 +36,7 @@ export const webhookAuth =
|
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
const data = `${timestamp}.${body}`
|
|
37
|
-
validateSignature(
|
|
39
|
+
validateSignature(secret, data, signature)
|
|
38
40
|
next()
|
|
39
41
|
} catch (err) {
|
|
40
42
|
log.error({ err }, 'Invalid KWS webhook signature')
|
|
@@ -51,21 +53,10 @@ type AgeAssuranceWebhookIntermediateBody = {
|
|
|
51
53
|
}
|
|
52
54
|
}
|
|
53
55
|
|
|
54
|
-
const parseBody = (serialized: string):
|
|
56
|
+
const parseBody = (serialized: string): AgeAssuranceWebhookIntermediateBody => {
|
|
55
57
|
try {
|
|
56
58
|
const value: unknown = JSON.parse(serialized)
|
|
57
|
-
|
|
58
|
-
webhookBodyIntermediateSchema.parse(value)
|
|
59
|
-
|
|
60
|
-
return {
|
|
61
|
-
...intermediate,
|
|
62
|
-
payload: {
|
|
63
|
-
...intermediate.payload,
|
|
64
|
-
externalPayload: parseExternalPayload(
|
|
65
|
-
intermediate.payload.externalPayload,
|
|
66
|
-
),
|
|
67
|
-
},
|
|
68
|
-
}
|
|
59
|
+
return webhookBodyIntermediateSchema.parse(value)
|
|
69
60
|
} catch (err) {
|
|
70
61
|
throw new Error(`Invalid webhook body: ${serialized}`, { cause: err })
|
|
71
62
|
}
|
|
@@ -74,7 +65,7 @@ const parseBody = (serialized: string): KwsWebhookBody => {
|
|
|
74
65
|
export const webhookHandler =
|
|
75
66
|
(ctx: AppContextWithKwsClient): RequestHandler =>
|
|
76
67
|
async (req: express.Request, res: express.Response) => {
|
|
77
|
-
let body:
|
|
68
|
+
let body: AgeAssuranceWebhookIntermediateBody
|
|
78
69
|
try {
|
|
79
70
|
body = parseBody(req.body)
|
|
80
71
|
} catch (err) {
|
|
@@ -82,23 +73,55 @@ export const webhookHandler =
|
|
|
82
73
|
return res.status(400).json(err)
|
|
83
74
|
}
|
|
84
75
|
|
|
85
|
-
const {
|
|
86
|
-
payload: {
|
|
87
|
-
status: { verified },
|
|
88
|
-
externalPayload,
|
|
89
|
-
},
|
|
90
|
-
} = body
|
|
91
|
-
const { actorDid, attemptId } = externalPayload
|
|
76
|
+
const { verified } = body.payload.status
|
|
92
77
|
if (!verified) {
|
|
93
78
|
throw new Error('Unexpected KWS webhook call with unverified status')
|
|
94
79
|
}
|
|
95
80
|
|
|
81
|
+
const externalPayload = parseKWSExternalPayloadV1WithV2Compat(
|
|
82
|
+
body.payload.externalPayload,
|
|
83
|
+
)
|
|
84
|
+
const isV2 = externalPayload.version === KWSExternalPayloadVersion.V2
|
|
85
|
+
|
|
86
|
+
let result: ReturnType<typeof computeAgeAssuranceAccessOrThrow> | undefined
|
|
87
|
+
if (isV2) {
|
|
88
|
+
const { attemptId, actorDid, countryCode, regionCode } = externalPayload
|
|
89
|
+
try {
|
|
90
|
+
result = computeAgeAssuranceAccessOrThrow(AGE_ASSURANCE_CONFIG, {
|
|
91
|
+
countryCode: countryCode,
|
|
92
|
+
regionCode: regionCode,
|
|
93
|
+
verifiedMinimumAge: 18, // `adult-verified` is 18+ only
|
|
94
|
+
})
|
|
95
|
+
} catch (err) {
|
|
96
|
+
// internal errors
|
|
97
|
+
log.error(
|
|
98
|
+
{ err, attemptId, actorDid, countryCode, regionCode },
|
|
99
|
+
'Failed to compute age assurance access',
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
96
104
|
try {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
105
|
+
if (isV2) {
|
|
106
|
+
if (result) {
|
|
107
|
+
const { attemptId, actorDid, countryCode, regionCode } =
|
|
108
|
+
externalPayload
|
|
109
|
+
await createEvent(ctx, actorDid, {
|
|
110
|
+
attemptId,
|
|
111
|
+
status: 'assured',
|
|
112
|
+
access: result.access,
|
|
113
|
+
countryCode,
|
|
114
|
+
regionCode,
|
|
115
|
+
})
|
|
116
|
+
} // else do nothing
|
|
117
|
+
} else {
|
|
118
|
+
const { attemptId, actorDid } = externalPayload
|
|
119
|
+
await createStashEvent(ctx, {
|
|
120
|
+
attemptId: attemptId,
|
|
121
|
+
actorDid: actorDid,
|
|
122
|
+
status: 'assured',
|
|
123
|
+
})
|
|
124
|
+
}
|
|
102
125
|
return res.status(200).end()
|
|
103
126
|
} catch (err) {
|
|
104
127
|
log.error({ err }, 'Failed to handle KWS webhook')
|
package/src/config.ts
CHANGED
|
@@ -13,8 +13,22 @@ export interface KwsConfig {
|
|
|
13
13
|
clientId: string
|
|
14
14
|
redirectUrl: string
|
|
15
15
|
userAgent: string
|
|
16
|
+
/**
|
|
17
|
+
* V1 secret used to validate `adult-verifieid` redirects
|
|
18
|
+
*/
|
|
16
19
|
verificationSecret: string
|
|
20
|
+
/**
|
|
21
|
+
* V1 secret used to validate `adult-verified` webhooks
|
|
22
|
+
*/
|
|
17
23
|
webhookSecret: string
|
|
24
|
+
/**
|
|
25
|
+
* V2 secret used to validate `age-verified` webhooks
|
|
26
|
+
*/
|
|
27
|
+
ageVerifiedWebhookSecret: string
|
|
28
|
+
/**
|
|
29
|
+
* V2 secret used to validate `age-verified` redirects
|
|
30
|
+
*/
|
|
31
|
+
ageVerifiedRedirectSecret: string
|
|
18
32
|
}
|
|
19
33
|
|
|
20
34
|
export interface ServerConfigValues {
|
|
@@ -41,6 +55,10 @@ export interface ServerConfigValues {
|
|
|
41
55
|
courierApiKey?: string
|
|
42
56
|
courierHttpVersion?: '1.1' | '2'
|
|
43
57
|
courierIgnoreBadTls?: boolean
|
|
58
|
+
rolodexUrl?: string
|
|
59
|
+
rolodexApiKey?: string
|
|
60
|
+
rolodexHttpVersion?: '1.1' | '2'
|
|
61
|
+
rolodexIgnoreBadTls?: boolean
|
|
44
62
|
searchUrl?: string
|
|
45
63
|
searchTagsHide: Set<string>
|
|
46
64
|
suggestionsUrl?: string
|
|
@@ -172,6 +190,12 @@ export class ServerConfig {
|
|
|
172
190
|
const courierIgnoreBadTls =
|
|
173
191
|
process.env.BSKY_COURIER_IGNORE_BAD_TLS === 'true'
|
|
174
192
|
assert(courierHttpVersion === '1.1' || courierHttpVersion === '2')
|
|
193
|
+
const rolodexUrl = process.env.BSKY_ROLODEX_URL || undefined
|
|
194
|
+
const rolodexApiKey = process.env.BSKY_ROLODEX_API_KEY || undefined
|
|
195
|
+
const rolodexHttpVersion = process.env.BSKY_ROLODEX_HTTP_VERSION || '2'
|
|
196
|
+
const rolodexIgnoreBadTls =
|
|
197
|
+
process.env.BSKY_ROLODEX_IGNORE_BAD_TLS === 'true'
|
|
198
|
+
assert(rolodexHttpVersion === '1.1' || rolodexHttpVersion === '2')
|
|
175
199
|
const blobRateLimitBypassKey =
|
|
176
200
|
process.env.BSKY_BLOB_RATE_LIMIT_BYPASS_KEY || undefined
|
|
177
201
|
// single domain would be e.g. "mypds.com", subdomains are supported with a leading dot e.g. ".mypds.com"
|
|
@@ -251,6 +275,10 @@ export class ServerConfig {
|
|
|
251
275
|
const kwsUserAgent = process.env.BSKY_KWS_USER_AGENT
|
|
252
276
|
const kwsVerificationSecret = process.env.BSKY_KWS_VERIFICATION_SECRET
|
|
253
277
|
const kwsWebhookSecret = process.env.BSKY_KWS_WEBHOOK_SECRET
|
|
278
|
+
const kwsAgeVerifiedWebhookSecret =
|
|
279
|
+
process.env.BSKY_KWS_AGE_VERIFIED_WEBHOOK_SECRET
|
|
280
|
+
const kwsAgeVerifiedRedirectSecret =
|
|
281
|
+
process.env.BSKY_KWS_AGE_VERIFIED_REDIRECT_SECRET
|
|
254
282
|
if (
|
|
255
283
|
kwsApiKey ||
|
|
256
284
|
kwsApiOrigin ||
|
|
@@ -259,7 +287,9 @@ export class ServerConfig {
|
|
|
259
287
|
kwsRedirectUrl ||
|
|
260
288
|
kwsUserAgent ||
|
|
261
289
|
kwsVerificationSecret ||
|
|
262
|
-
kwsWebhookSecret
|
|
290
|
+
kwsWebhookSecret ||
|
|
291
|
+
kwsAgeVerifiedWebhookSecret ||
|
|
292
|
+
kwsAgeVerifiedRedirectSecret
|
|
263
293
|
) {
|
|
264
294
|
assert(
|
|
265
295
|
kwsApiOrigin &&
|
|
@@ -269,7 +299,9 @@ export class ServerConfig {
|
|
|
269
299
|
kwsUserAgent &&
|
|
270
300
|
kwsVerificationSecret &&
|
|
271
301
|
kwsWebhookSecret &&
|
|
272
|
-
kwsApiKey
|
|
302
|
+
kwsApiKey &&
|
|
303
|
+
kwsAgeVerifiedWebhookSecret &&
|
|
304
|
+
kwsAgeVerifiedRedirectSecret,
|
|
273
305
|
'all KWS environment variables must be set if any are set',
|
|
274
306
|
)
|
|
275
307
|
kws = {
|
|
@@ -281,6 +313,8 @@ export class ServerConfig {
|
|
|
281
313
|
userAgent: kwsUserAgent,
|
|
282
314
|
verificationSecret: kwsVerificationSecret,
|
|
283
315
|
webhookSecret: kwsWebhookSecret,
|
|
316
|
+
ageVerifiedWebhookSecret: kwsAgeVerifiedWebhookSecret,
|
|
317
|
+
ageVerifiedRedirectSecret: kwsAgeVerifiedRedirectSecret,
|
|
284
318
|
}
|
|
285
319
|
}
|
|
286
320
|
|
|
@@ -323,6 +357,10 @@ export class ServerConfig {
|
|
|
323
357
|
courierApiKey,
|
|
324
358
|
courierHttpVersion,
|
|
325
359
|
courierIgnoreBadTls,
|
|
360
|
+
rolodexUrl,
|
|
361
|
+
rolodexApiKey,
|
|
362
|
+
rolodexHttpVersion,
|
|
363
|
+
rolodexIgnoreBadTls,
|
|
326
364
|
blobRateLimitBypassKey,
|
|
327
365
|
blobRateLimitBypassHostname,
|
|
328
366
|
adminPasswords,
|
|
@@ -446,6 +484,19 @@ export class ServerConfig {
|
|
|
446
484
|
return this.cfg.courierIgnoreBadTls
|
|
447
485
|
}
|
|
448
486
|
|
|
487
|
+
get rolodexUrl() {
|
|
488
|
+
return this.cfg.rolodexUrl
|
|
489
|
+
}
|
|
490
|
+
get rolodexApiKey() {
|
|
491
|
+
return this.cfg.rolodexApiKey
|
|
492
|
+
}
|
|
493
|
+
get rolodexHttpVersion() {
|
|
494
|
+
return this.cfg.rolodexHttpVersion
|
|
495
|
+
}
|
|
496
|
+
get rolodexIgnoreBadTls() {
|
|
497
|
+
return this.cfg.rolodexIgnoreBadTls
|
|
498
|
+
}
|
|
499
|
+
|
|
449
500
|
get searchUrl() {
|
|
450
501
|
return this.cfg.searchUrl
|
|
451
502
|
}
|
package/src/context.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { FeatureGates } from './feature-gates'
|
|
|
14
14
|
import { Hydrator } from './hydration/hydrator'
|
|
15
15
|
import { KwsClient } from './kws'
|
|
16
16
|
import { httpLogger as log } from './logger'
|
|
17
|
+
import { RolodexClient } from './rolodex'
|
|
17
18
|
import { StashClient } from './stash'
|
|
18
19
|
import {
|
|
19
20
|
ParsedLabelers,
|
|
@@ -39,6 +40,7 @@ export class AppContext {
|
|
|
39
40
|
bsyncClient: BsyncClient
|
|
40
41
|
stashClient: StashClient
|
|
41
42
|
courierClient: CourierClient | undefined
|
|
43
|
+
rolodexClient: RolodexClient | undefined
|
|
42
44
|
authVerifier: AuthVerifier
|
|
43
45
|
featureGates: FeatureGates
|
|
44
46
|
blobDispatcher: Dispatcher
|
|
@@ -106,6 +108,10 @@ export class AppContext {
|
|
|
106
108
|
return this.opts.courierClient
|
|
107
109
|
}
|
|
108
110
|
|
|
111
|
+
get rolodexClient(): RolodexClient | undefined {
|
|
112
|
+
return this.opts.rolodexClient
|
|
113
|
+
}
|
|
114
|
+
|
|
109
115
|
get authVerifier(): AuthVerifier {
|
|
110
116
|
return this.opts.authVerifier
|
|
111
117
|
}
|
|
@@ -8,6 +8,7 @@ import { TID } from '@atproto/common'
|
|
|
8
8
|
import { jsonStringToLex } from '@atproto/lexicon'
|
|
9
9
|
import { AtUri } from '@atproto/syntax'
|
|
10
10
|
import { ids } from '../../lexicon/lexicons'
|
|
11
|
+
import { Event as AgeAssuranceV2Event } from '../../lexicon/types/app/bsky/ageassurance/defs'
|
|
11
12
|
import { Bookmark } from '../../lexicon/types/app/bsky/bookmark/defs'
|
|
12
13
|
import { SubjectActivitySubscription } from '../../lexicon/types/app/bsky/notification/defs'
|
|
13
14
|
import { AgeAssuranceEvent } from '../../lexicon/types/app/bsky/unspecced/defs'
|
|
@@ -175,6 +176,8 @@ const createRoutes = (db: Database) => (router: ConnectRouter) =>
|
|
|
175
176
|
namespace === Namespaces.AppBskyUnspeccedDefsAgeAssuranceEvent
|
|
176
177
|
) {
|
|
177
178
|
await handleAgeAssuranceEventOperation(db, req, now)
|
|
179
|
+
} else if (namespace === Namespaces.AppBskyAgeassuranceDefsEvent) {
|
|
180
|
+
await handleAgeAssuranceV2EventOperation(db, req, now)
|
|
178
181
|
} else if (namespace === Namespaces.AppBskyBookmarkDefsBookmark) {
|
|
179
182
|
await handleBookmarkOperation(db, req, now)
|
|
180
183
|
}
|
|
@@ -314,6 +317,34 @@ const handleAgeAssuranceEventOperation = async (
|
|
|
314
317
|
.execute()
|
|
315
318
|
}
|
|
316
319
|
|
|
320
|
+
const handleAgeAssuranceV2EventOperation = async (
|
|
321
|
+
db: Database,
|
|
322
|
+
req: PutOperationRequest,
|
|
323
|
+
_now: string,
|
|
324
|
+
) => {
|
|
325
|
+
const { actorDid, method, payload } = req
|
|
326
|
+
if (method !== Method.CREATE) return
|
|
327
|
+
|
|
328
|
+
const parsed = jsonStringToLex(
|
|
329
|
+
Buffer.from(payload).toString('utf8'),
|
|
330
|
+
) as AgeAssuranceV2Event
|
|
331
|
+
const { status, createdAt, access, countryCode, regionCode } = parsed
|
|
332
|
+
|
|
333
|
+
const update = {
|
|
334
|
+
ageAssuranceStatus: status,
|
|
335
|
+
ageAssuranceLastInitiatedAt: status === 'pending' ? createdAt : undefined,
|
|
336
|
+
ageAssuranceAccess: access,
|
|
337
|
+
ageAssuranceCountryCode: countryCode,
|
|
338
|
+
ageAssuranceRegionCode: regionCode,
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return db.db
|
|
342
|
+
.updateTable('actor')
|
|
343
|
+
.set(update)
|
|
344
|
+
.where('did', '=', actorDid)
|
|
345
|
+
.execute()
|
|
346
|
+
}
|
|
347
|
+
|
|
317
348
|
const handleBookmarkOperation = async (
|
|
318
349
|
db: Database,
|
|
319
350
|
req: PutOperationRequest,
|
package/src/data-plane/server/db/migrations/20251120T004738098Z-update-actor-age-assurance-v2.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Kysely } from 'kysely'
|
|
2
|
+
|
|
3
|
+
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
+
await db.schema
|
|
5
|
+
.alterTable('actor')
|
|
6
|
+
.addColumn('ageAssuranceAccess', 'text')
|
|
7
|
+
.execute()
|
|
8
|
+
await db.schema
|
|
9
|
+
.alterTable('actor')
|
|
10
|
+
.addColumn('ageAssuranceCountryCode', 'text')
|
|
11
|
+
.execute()
|
|
12
|
+
await db.schema
|
|
13
|
+
.alterTable('actor')
|
|
14
|
+
.addColumn('ageAssuranceRegionCode', 'text')
|
|
15
|
+
.execute()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
19
|
+
await db.schema.alterTable('actor').dropColumn('ageAssuranceAccess').execute()
|
|
20
|
+
await db.schema
|
|
21
|
+
.alterTable('actor')
|
|
22
|
+
.dropColumn('ageAssuranceCountryCode')
|
|
23
|
+
.execute()
|
|
24
|
+
await db.schema
|
|
25
|
+
.alterTable('actor')
|
|
26
|
+
.dropColumn('ageAssuranceRegionCode')
|
|
27
|
+
.execute()
|
|
28
|
+
}
|
|
@@ -55,3 +55,4 @@ export * as _20250611T140649895Z from './20250611T140649895Z-add-activity-subscr
|
|
|
55
55
|
export * as _20250627T025331240Z from './20250627T025331240Z-add-actor-age-assurance-columns'
|
|
56
56
|
export * as _20250812T183735692Z from './20250812T183735692Z-add-bookmarks'
|
|
57
57
|
export * as _20250813T174955711Z from './20250813T174955711Z-add-post-agg-bookmarks'
|
|
58
|
+
export * as _20251120T004738098Z from './20251120T004738098Z-update-actor-age-assurance-v2'
|
|
@@ -9,6 +9,9 @@ export interface Actor {
|
|
|
9
9
|
trustedVerifier: Generated<boolean>
|
|
10
10
|
ageAssuranceStatus: string | null
|
|
11
11
|
ageAssuranceLastInitiatedAt: string | null
|
|
12
|
+
ageAssuranceAccess: string | null
|
|
13
|
+
ageAssuranceCountryCode: string | null
|
|
14
|
+
ageAssuranceRegionCode: string | null
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
export const tableName = 'actor'
|
|
@@ -134,11 +134,22 @@ export default (db: Database): Partial<ServiceImpl<typeof Service>> => ({
|
|
|
134
134
|
return undefined
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
+
const status = row?.ageAssuranceStatus ?? 'unknown'
|
|
138
|
+
let access = row?.ageAssuranceAccess
|
|
139
|
+
if (status === 'assured') {
|
|
140
|
+
access = 'full'
|
|
141
|
+
} else if (status === 'blocked') {
|
|
142
|
+
access = 'none'
|
|
143
|
+
} else {
|
|
144
|
+
access = 'unknown'
|
|
145
|
+
}
|
|
146
|
+
|
|
137
147
|
return {
|
|
138
|
-
status: row?.ageAssuranceStatus ?? 'unknown',
|
|
139
148
|
lastInitiatedAt: row?.ageAssuranceLastInitiatedAt
|
|
140
149
|
? Timestamp.fromDate(new Date(row?.ageAssuranceLastInitiatedAt))
|
|
141
150
|
: undefined,
|
|
151
|
+
status,
|
|
152
|
+
access,
|
|
142
153
|
}
|
|
143
154
|
}
|
|
144
155
|
|
package/src/hydration/actor.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -30,6 +30,7 @@ import { ImageUriBuilder } from './image/uri'
|
|
|
30
30
|
import { createKwsClient } from './kws'
|
|
31
31
|
import { createServer } from './lexicon'
|
|
32
32
|
import { loggerMiddleware } from './logger'
|
|
33
|
+
import { authWithApiKey as rolodexAuth, createRolodexClient } from './rolodex'
|
|
33
34
|
import { createStashClient } from './stash'
|
|
34
35
|
import { Views } from './views'
|
|
35
36
|
import { VideoUriBuilder } from './views/util'
|
|
@@ -156,6 +157,17 @@ export class BskyAppView {
|
|
|
156
157
|
})
|
|
157
158
|
: undefined
|
|
158
159
|
|
|
160
|
+
const rolodexClient = config.rolodexUrl
|
|
161
|
+
? createRolodexClient({
|
|
162
|
+
baseUrl: config.rolodexUrl,
|
|
163
|
+
httpVersion: config.rolodexHttpVersion ?? '2',
|
|
164
|
+
nodeOptions: { rejectUnauthorized: !config.rolodexIgnoreBadTls },
|
|
165
|
+
interceptors: config.rolodexApiKey
|
|
166
|
+
? [rolodexAuth(config.rolodexApiKey)]
|
|
167
|
+
: [],
|
|
168
|
+
})
|
|
169
|
+
: undefined
|
|
170
|
+
|
|
159
171
|
const kwsClient = config.kws ? createKwsClient(config.kws) : undefined
|
|
160
172
|
|
|
161
173
|
const entrywayJwtPublicKey = config.entrywayJwtPublicKeyHex
|
|
@@ -191,6 +203,7 @@ export class BskyAppView {
|
|
|
191
203
|
bsyncClient,
|
|
192
204
|
stashClient,
|
|
193
205
|
courierClient,
|
|
206
|
+
rolodexClient,
|
|
194
207
|
authVerifier,
|
|
195
208
|
featureGates,
|
|
196
209
|
blobDispatcher,
|