@atproto/bsky 0.0.15 → 0.0.17
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 +18 -0
- package/dist/api/com/atproto/moderation/util.d.ts +4 -3
- package/dist/cache/read-through.d.ts +30 -0
- package/dist/config.d.ts +18 -0
- package/dist/context.d.ts +21 -6
- package/dist/daemon/config.d.ts +15 -0
- package/dist/daemon/context.d.ts +15 -0
- package/dist/daemon/index.d.ts +23 -0
- package/dist/daemon/logger.d.ts +3 -0
- package/dist/daemon/notifications.d.ts +18 -0
- package/dist/daemon/services.d.ts +11 -0
- package/dist/db/database-schema.d.ts +1 -2
- package/dist/db/index.js +41 -1
- package/dist/db/index.js.map +3 -3
- package/dist/db/migrations/20231003T202833377Z-create-moderation-subject-status.d.ts +3 -0
- package/dist/db/migrations/20231205T000257238Z-remove-did-cache.d.ts +3 -0
- package/dist/db/migrations/index.d.ts +2 -0
- package/dist/db/pagination.d.ts +2 -1
- package/dist/db/{periodic-moderation-action-reversal.d.ts → periodic-moderation-event-reversal.d.ts} +3 -5
- package/dist/db/tables/moderation.d.ts +24 -34
- package/dist/did-cache.d.ts +10 -7
- package/dist/feed-gen/types.d.ts +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +4370 -2758
- package/dist/index.js.map +3 -3
- package/dist/indexer/context.d.ts +2 -0
- package/dist/indexer/index.d.ts +1 -0
- package/dist/lexicon/index.d.ts +23 -18
- package/dist/lexicon/lexicons.d.ts +561 -412
- package/dist/lexicon/types/app/bsky/feed/defs.d.ts +1 -7
- package/dist/lexicon/types/app/bsky/graph/defs.d.ts +1 -0
- package/dist/lexicon/types/com/atproto/admin/defs.d.ts +114 -48
- package/dist/lexicon/types/com/atproto/admin/{resolveModerationReports.d.ts → deleteAccount.d.ts} +2 -13
- package/dist/lexicon/types/com/atproto/admin/{takeModerationAction.d.ts → emitModerationEvent.d.ts} +5 -6
- package/dist/lexicon/types/com/atproto/admin/{getModerationAction.d.ts → getModerationEvent.d.ts} +1 -1
- package/dist/lexicon/types/com/atproto/admin/{getModerationActions.d.ts → queryModerationEvents.d.ts} +5 -1
- package/dist/lexicon/types/com/atproto/admin/{getModerationReports.d.ts → queryModerationStatuses.d.ts} +12 -6
- package/dist/lexicon/types/com/atproto/admin/sendEmail.d.ts +1 -0
- package/dist/lexicon/types/com/atproto/{admin/getModerationReport.d.ts → temp/importRepo.d.ts} +10 -7
- package/dist/lexicon/types/com/atproto/temp/pushBlob.d.ts +25 -0
- package/dist/lexicon/types/com/atproto/{admin/reverseModerationAction.d.ts → temp/transferAccount.d.ts} +11 -5
- package/dist/logger.d.ts +1 -0
- package/dist/migrate-moderation-data.d.ts +1 -0
- package/dist/redis.d.ts +10 -1
- package/dist/services/actor/index.d.ts +18 -4
- package/dist/services/actor/views.d.ts +6 -8
- package/dist/services/feed/index.d.ts +7 -4
- package/dist/services/feed/util.d.ts +9 -1
- package/dist/services/feed/views.d.ts +11 -21
- package/dist/services/graph/index.d.ts +5 -29
- package/dist/services/graph/types.d.ts +1 -0
- package/dist/services/index.d.ts +3 -7
- package/dist/services/label/index.d.ts +10 -4
- package/dist/services/moderation/index.d.ts +134 -72
- package/dist/services/moderation/pagination.d.ts +36 -0
- package/dist/services/moderation/status.d.ts +13 -0
- package/dist/services/moderation/types.d.ts +35 -0
- package/dist/services/moderation/views.d.ts +18 -14
- package/dist/services/types.d.ts +3 -0
- package/dist/services/util/notification.d.ts +5 -0
- package/dist/services/util/post.d.ts +6 -6
- package/dist/util/debug.d.ts +1 -1
- package/dist/util/retry.d.ts +1 -6
- package/package.json +11 -11
- package/src/api/app/bsky/feed/getActorFeeds.ts +2 -1
- package/src/api/app/bsky/feed/getActorLikes.ts +1 -3
- package/src/api/app/bsky/feed/getAuthorFeed.ts +1 -3
- package/src/api/app/bsky/feed/getFeed.ts +9 -9
- package/src/api/app/bsky/feed/getFeedGenerator.ts +3 -0
- package/src/api/app/bsky/feed/getFeedGenerators.ts +2 -1
- package/src/api/app/bsky/feed/getListFeed.ts +1 -3
- package/src/api/app/bsky/feed/getPostThread.ts +15 -54
- package/src/api/app/bsky/feed/getPosts.ts +21 -18
- package/src/api/app/bsky/feed/getSuggestedFeeds.ts +2 -1
- package/src/api/app/bsky/feed/getTimeline.ts +1 -3
- package/src/api/app/bsky/feed/searchPosts.ts +20 -17
- package/src/api/app/bsky/graph/getList.ts +6 -3
- package/src/api/app/bsky/graph/getListBlocks.ts +3 -2
- package/src/api/app/bsky/graph/getListMutes.ts +2 -1
- package/src/api/app/bsky/graph/getLists.ts +2 -1
- package/src/api/app/bsky/unspecced/getPopularFeedGenerators.ts +3 -1
- package/src/api/blob-resolver.ts +6 -11
- package/src/api/com/atproto/admin/emitModerationEvent.ts +220 -0
- package/src/api/com/atproto/admin/{getModerationActions.ts → getModerationEvent.ts} +5 -11
- package/src/api/com/atproto/admin/getRecord.ts +1 -0
- package/src/api/com/atproto/admin/{getModerationReports.ts → queryModerationEvents.ts} +13 -16
- package/src/api/com/atproto/admin/queryModerationStatuses.ts +55 -0
- package/src/api/com/atproto/moderation/createReport.ts +9 -7
- package/src/api/com/atproto/moderation/util.ts +38 -20
- package/src/api/index.ts +8 -14
- package/src/auth.ts +29 -21
- package/src/auto-moderator/index.ts +26 -19
- package/src/cache/read-through.ts +151 -0
- package/src/config.ts +90 -1
- package/src/context.ts +11 -7
- package/src/daemon/config.ts +60 -0
- package/src/daemon/context.ts +27 -0
- package/src/daemon/index.ts +78 -0
- package/src/daemon/logger.ts +6 -0
- package/src/daemon/notifications.ts +54 -0
- package/src/daemon/services.ts +22 -0
- package/src/db/database-schema.ts +0 -2
- package/src/db/migrations/20231003T202833377Z-create-moderation-subject-status.ts +123 -0
- package/src/db/migrations/20231205T000257238Z-remove-did-cache.ts +14 -0
- package/src/db/migrations/index.ts +2 -0
- package/src/db/pagination.ts +26 -3
- package/src/db/{periodic-moderation-action-reversal.ts → periodic-moderation-event-reversal.ts} +50 -46
- package/src/db/tables/moderation.ts +35 -52
- package/src/did-cache.ts +33 -56
- package/src/feed-gen/bsky-team.ts +1 -1
- package/src/feed-gen/hot-classic.ts +1 -1
- package/src/feed-gen/index.ts +0 -4
- package/src/feed-gen/mutuals.ts +6 -2
- package/src/feed-gen/types.ts +1 -1
- package/src/index.ts +57 -17
- package/src/indexer/context.ts +5 -0
- package/src/indexer/index.ts +10 -7
- package/src/lexicon/index.ts +80 -67
- package/src/lexicon/lexicons.ts +698 -507
- package/src/lexicon/types/app/bsky/feed/defs.ts +1 -18
- package/src/lexicon/types/app/bsky/graph/defs.ts +1 -0
- package/src/lexicon/types/com/atproto/admin/defs.ts +276 -84
- package/src/lexicon/types/com/atproto/admin/{resolveModerationReports.ts → deleteAccount.ts} +2 -13
- package/src/lexicon/types/com/atproto/admin/{takeModerationAction.ts → emitModerationEvent.ts} +13 -11
- package/src/lexicon/types/com/atproto/admin/{getModerationReport.ts → getModerationEvent.ts} +1 -1
- package/src/lexicon/types/com/atproto/admin/{getModerationActions.ts → queryModerationEvents.ts} +8 -1
- package/src/lexicon/types/com/atproto/admin/{getModerationReports.ts → queryModerationStatuses.ts} +21 -14
- package/src/lexicon/types/com/atproto/admin/sendEmail.ts +1 -0
- package/src/lexicon/types/com/atproto/{admin/getModerationAction.ts → temp/importRepo.ts} +11 -7
- package/src/lexicon/types/com/atproto/temp/pushBlob.ts +39 -0
- package/src/lexicon/types/com/atproto/{admin/reverseModerationAction.ts → temp/transferAccount.ts} +18 -5
- package/src/logger.ts +2 -0
- package/src/migrate-moderation-data.ts +414 -0
- package/src/redis.ts +43 -3
- package/src/services/actor/index.ts +55 -7
- package/src/services/actor/views.ts +18 -21
- package/src/services/feed/index.ts +52 -19
- package/src/services/feed/util.ts +47 -19
- package/src/services/feed/views.ts +87 -13
- package/src/services/graph/index.ts +21 -3
- package/src/services/graph/types.ts +1 -0
- package/src/services/index.ts +14 -14
- package/src/services/indexing/index.ts +7 -10
- package/src/services/indexing/plugins/block.ts +2 -3
- package/src/services/indexing/plugins/feed-generator.ts +2 -3
- package/src/services/indexing/plugins/follow.ts +2 -3
- package/src/services/indexing/plugins/like.ts +2 -3
- package/src/services/indexing/plugins/list-block.ts +2 -3
- package/src/services/indexing/plugins/list-item.ts +2 -3
- package/src/services/indexing/plugins/list.ts +2 -3
- package/src/services/indexing/plugins/post.ts +16 -4
- package/src/services/indexing/plugins/repost.ts +2 -3
- package/src/services/indexing/plugins/thread-gate.ts +2 -3
- package/src/services/label/index.ts +68 -25
- package/src/services/moderation/index.ts +380 -395
- package/src/services/moderation/pagination.ts +96 -0
- package/src/services/moderation/status.ts +241 -0
- package/src/services/moderation/types.ts +49 -0
- package/src/services/moderation/views.ts +278 -329
- package/src/services/types.ts +4 -0
- package/src/services/util/notification.ts +70 -0
- package/src/util/debug.ts +2 -2
- package/src/util/retry.ts +1 -44
- package/tests/__snapshots__/feed-generation.test.ts.snap +322 -6
- package/tests/__snapshots__/indexing.test.ts.snap +0 -6
- package/tests/admin/__snapshots__/get-record.test.ts.snap +30 -132
- package/tests/admin/__snapshots__/get-repo.test.ts.snap +14 -60
- package/tests/admin/__snapshots__/moderation-events.test.ts.snap +146 -0
- package/tests/admin/__snapshots__/moderation-statuses.test.ts.snap +64 -0
- package/tests/admin/__snapshots__/moderation.test.ts.snap +0 -125
- package/tests/admin/get-record.test.ts +5 -9
- package/tests/admin/get-repo.test.ts +10 -12
- package/tests/admin/moderation-events.test.ts +221 -0
- package/tests/admin/moderation-statuses.test.ts +145 -0
- package/tests/admin/moderation.test.ts +512 -860
- package/tests/admin/repo-search.test.ts +3 -3
- package/tests/algos/hot-classic.test.ts +1 -2
- package/tests/auth.test.ts +1 -1
- package/tests/auto-moderator/fuzzy-matcher.test.ts +2 -1
- package/tests/auto-moderator/labeler.test.ts +19 -20
- package/tests/auto-moderator/takedowns.test.ts +61 -28
- package/tests/blob-resolver.test.ts +4 -2
- package/tests/daemon.test.ts +191 -0
- package/tests/did-cache.test.ts +20 -5
- package/tests/feed-generation.test.ts +57 -9
- package/tests/handle-invalidation.test.ts +1 -5
- package/tests/indexing.test.ts +20 -13
- package/tests/redis-cache.test.ts +231 -0
- package/tests/seeds/basic.ts +3 -0
- package/tests/subscription/repo.test.ts +4 -7
- package/tests/views/__snapshots__/block-lists.test.ts.snap +3 -9
- package/tests/views/__snapshots__/blocks.test.ts.snap +0 -9
- package/tests/views/__snapshots__/mute-lists.test.ts.snap +5 -5
- package/tests/views/__snapshots__/mutes.test.ts.snap +0 -3
- package/tests/views/__snapshots__/thread.test.ts.snap +0 -30
- package/tests/views/actor-search.test.ts +2 -3
- package/tests/views/author-feed.test.ts +42 -36
- package/tests/views/follows.test.ts +40 -35
- package/tests/views/list-feed.test.ts +17 -9
- package/tests/views/notifications.test.ts +13 -9
- package/tests/views/profile.test.ts +20 -19
- package/tests/views/thread.test.ts +117 -94
- package/tests/views/threadgating.test.ts +89 -19
- package/tests/views/timeline.test.ts +21 -13
- package/dist/api/com/atproto/admin/resolveModerationReports.d.ts +0 -3
- package/dist/api/com/atproto/admin/reverseModerationAction.d.ts +0 -3
- package/dist/api/com/atproto/admin/takeModerationAction.d.ts +0 -3
- package/dist/db/tables/did-cache.d.ts +0 -10
- package/dist/feed-gen/best-of-follows.d.ts +0 -29
- package/dist/feed-gen/whats-hot.d.ts +0 -29
- package/dist/feed-gen/with-friends.d.ts +0 -3
- package/dist/label-cache.d.ts +0 -19
- package/src/api/com/atproto/admin/getModerationAction.ts +0 -44
- package/src/api/com/atproto/admin/getModerationReport.ts +0 -43
- package/src/api/com/atproto/admin/resolveModerationReports.ts +0 -24
- package/src/api/com/atproto/admin/reverseModerationAction.ts +0 -115
- package/src/api/com/atproto/admin/takeModerationAction.ts +0 -156
- package/src/db/tables/did-cache.ts +0 -13
- package/src/feed-gen/best-of-follows.ts +0 -74
- package/src/feed-gen/whats-hot.ts +0 -101
- package/src/feed-gen/with-friends.ts +0 -39
- package/src/label-cache.ts +0 -90
- package/tests/admin/__snapshots__/get-moderation-action.test.ts.snap +0 -172
- package/tests/admin/__snapshots__/get-moderation-actions.test.ts.snap +0 -178
- package/tests/admin/__snapshots__/get-moderation-report.test.ts.snap +0 -177
- package/tests/admin/__snapshots__/get-moderation-reports.test.ts.snap +0 -307
- package/tests/admin/get-moderation-action.test.ts +0 -100
- package/tests/admin/get-moderation-actions.test.ts +0 -164
- package/tests/admin/get-moderation-report.test.ts +0 -100
- package/tests/admin/get-moderation-reports.test.ts +0 -332
- package/tests/algos/whats-hot.test.ts +0 -118
- package/tests/algos/with-friends.test.ts +0 -145
- /package/dist/api/com/atproto/admin/{getModerationAction.d.ts → emitModerationEvent.d.ts} +0 -0
- /package/dist/api/com/atproto/admin/{getModerationActions.d.ts → getModerationEvent.d.ts} +0 -0
- /package/dist/api/com/atproto/admin/{getModerationReport.d.ts → queryModerationEvents.d.ts} +0 -0
- /package/dist/api/com/atproto/admin/{getModerationReports.d.ts → queryModerationStatuses.d.ts} +0 -0
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
import { CID } from 'multiformats/cid'
|
|
2
2
|
import { InvalidRequestError } from '@atproto/xrpc-server'
|
|
3
3
|
import { AtUri } from '@atproto/syntax'
|
|
4
|
-
import { ModerationAction } from '../../../../db/tables/moderation'
|
|
5
|
-
import { ModerationReport } from '../../../../db/tables/moderation'
|
|
6
4
|
import { InputSchema as ReportInput } from '../../../../lexicon/types/com/atproto/moderation/createReport'
|
|
7
|
-
import { InputSchema as ActionInput } from '../../../../lexicon/types/com/atproto/admin/
|
|
8
|
-
import {
|
|
9
|
-
ACKNOWLEDGE,
|
|
10
|
-
FLAG,
|
|
11
|
-
TAKEDOWN,
|
|
12
|
-
ESCALATE,
|
|
13
|
-
} from '../../../../lexicon/types/com/atproto/admin/defs'
|
|
5
|
+
import { InputSchema as ActionInput } from '../../../../lexicon/types/com/atproto/admin/emitModerationEvent'
|
|
14
6
|
import {
|
|
15
7
|
REASONOTHER,
|
|
16
8
|
REASONSPAM,
|
|
@@ -19,6 +11,13 @@ import {
|
|
|
19
11
|
REASONSEXUAL,
|
|
20
12
|
REASONVIOLATION,
|
|
21
13
|
} from '../../../../lexicon/types/com/atproto/moderation/defs'
|
|
14
|
+
import {
|
|
15
|
+
REVIEWCLOSED,
|
|
16
|
+
REVIEWESCALATED,
|
|
17
|
+
REVIEWOPEN,
|
|
18
|
+
} from '../../../../lexicon/types/com/atproto/admin/defs'
|
|
19
|
+
import { ModerationEvent } from '../../../../db/tables/moderation'
|
|
20
|
+
import { ModerationSubjectStatusRow } from '../../../../services/moderation/types'
|
|
22
21
|
|
|
23
22
|
type SubjectInput = ReportInput['subject'] | ActionInput['subject']
|
|
24
23
|
|
|
@@ -34,8 +33,9 @@ export const getSubject = (subject: SubjectInput) => {
|
|
|
34
33
|
typeof subject.uri === 'string' &&
|
|
35
34
|
typeof subject.cid === 'string'
|
|
36
35
|
) {
|
|
36
|
+
const uri = new AtUri(subject.uri)
|
|
37
37
|
return {
|
|
38
|
-
uri
|
|
38
|
+
uri,
|
|
39
39
|
cid: CID.parse(subject.cid),
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -44,23 +44,28 @@ export const getSubject = (subject: SubjectInput) => {
|
|
|
44
44
|
|
|
45
45
|
export const getReasonType = (reasonType: ReportInput['reasonType']) => {
|
|
46
46
|
if (reasonTypes.has(reasonType)) {
|
|
47
|
-
return reasonType as
|
|
47
|
+
return reasonType as NonNullable<ModerationEvent['meta']>['reportType']
|
|
48
48
|
}
|
|
49
49
|
throw new InvalidRequestError('Invalid reason type')
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
export const
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
action === FLAG ||
|
|
56
|
-
action === ACKNOWLEDGE ||
|
|
57
|
-
action === ESCALATE
|
|
58
|
-
) {
|
|
59
|
-
return action as ModerationAction['action']
|
|
52
|
+
export const getEventType = (type: string) => {
|
|
53
|
+
if (eventTypes.has(type)) {
|
|
54
|
+
return type as ModerationEvent['action']
|
|
60
55
|
}
|
|
61
|
-
throw new InvalidRequestError('Invalid
|
|
56
|
+
throw new InvalidRequestError('Invalid event type')
|
|
62
57
|
}
|
|
63
58
|
|
|
59
|
+
export const getReviewState = (reviewState?: string) => {
|
|
60
|
+
if (!reviewState) return undefined
|
|
61
|
+
if (reviewStates.has(reviewState)) {
|
|
62
|
+
return reviewState as ModerationSubjectStatusRow['reviewState']
|
|
63
|
+
}
|
|
64
|
+
throw new InvalidRequestError('Invalid review state')
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const reviewStates = new Set([REVIEWCLOSED, REVIEWESCALATED, REVIEWOPEN])
|
|
68
|
+
|
|
64
69
|
const reasonTypes = new Set([
|
|
65
70
|
REASONOTHER,
|
|
66
71
|
REASONSPAM,
|
|
@@ -69,3 +74,16 @@ const reasonTypes = new Set([
|
|
|
69
74
|
REASONSEXUAL,
|
|
70
75
|
REASONVIOLATION,
|
|
71
76
|
])
|
|
77
|
+
|
|
78
|
+
const eventTypes = new Set([
|
|
79
|
+
'com.atproto.admin.defs#modEventTakedown',
|
|
80
|
+
'com.atproto.admin.defs#modEventAcknowledge',
|
|
81
|
+
'com.atproto.admin.defs#modEventEscalate',
|
|
82
|
+
'com.atproto.admin.defs#modEventComment',
|
|
83
|
+
'com.atproto.admin.defs#modEventLabel',
|
|
84
|
+
'com.atproto.admin.defs#modEventReport',
|
|
85
|
+
'com.atproto.admin.defs#modEventMute',
|
|
86
|
+
'com.atproto.admin.defs#modEventUnmute',
|
|
87
|
+
'com.atproto.admin.defs#modEventReverseTakedown',
|
|
88
|
+
'com.atproto.admin.defs#modEventEmail',
|
|
89
|
+
])
|
package/src/api/index.ts
CHANGED
|
@@ -41,18 +41,15 @@ import registerPush from './app/bsky/notification/registerPush'
|
|
|
41
41
|
import getPopularFeedGenerators from './app/bsky/unspecced/getPopularFeedGenerators'
|
|
42
42
|
import getTimelineSkeleton from './app/bsky/unspecced/getTimelineSkeleton'
|
|
43
43
|
import createReport from './com/atproto/moderation/createReport'
|
|
44
|
-
import
|
|
45
|
-
import reverseModerationAction from './com/atproto/admin/reverseModerationAction'
|
|
46
|
-
import takeModerationAction from './com/atproto/admin/takeModerationAction'
|
|
44
|
+
import emitModerationEvent from './com/atproto/admin/emitModerationEvent'
|
|
47
45
|
import searchRepos from './com/atproto/admin/searchRepos'
|
|
48
46
|
import adminGetRecord from './com/atproto/admin/getRecord'
|
|
49
47
|
import getRepo from './com/atproto/admin/getRepo'
|
|
50
|
-
import
|
|
51
|
-
import getModerationActions from './com/atproto/admin/getModerationActions'
|
|
52
|
-
import getModerationReport from './com/atproto/admin/getModerationReport'
|
|
53
|
-
import getModerationReports from './com/atproto/admin/getModerationReports'
|
|
48
|
+
import queryModerationStatuses from './com/atproto/admin/queryModerationStatuses'
|
|
54
49
|
import resolveHandle from './com/atproto/identity/resolveHandle'
|
|
55
50
|
import getRecord from './com/atproto/repo/getRecord'
|
|
51
|
+
import queryModerationEvents from './com/atproto/admin/queryModerationEvents'
|
|
52
|
+
import getModerationEvent from './com/atproto/admin/getModerationEvent'
|
|
56
53
|
import fetchLabels from './com/atproto/temp/fetchLabels'
|
|
57
54
|
|
|
58
55
|
export * as health from './health'
|
|
@@ -105,16 +102,13 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
105
102
|
getTimelineSkeleton(server, ctx)
|
|
106
103
|
// com.atproto
|
|
107
104
|
createReport(server, ctx)
|
|
108
|
-
|
|
109
|
-
reverseModerationAction(server, ctx)
|
|
110
|
-
takeModerationAction(server, ctx)
|
|
105
|
+
emitModerationEvent(server, ctx)
|
|
111
106
|
searchRepos(server, ctx)
|
|
112
107
|
adminGetRecord(server, ctx)
|
|
113
108
|
getRepo(server, ctx)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
getModerationReports(server, ctx)
|
|
109
|
+
getModerationEvent(server, ctx)
|
|
110
|
+
queryModerationEvents(server, ctx)
|
|
111
|
+
queryModerationStatuses(server, ctx)
|
|
118
112
|
resolveHandle(server, ctx)
|
|
119
113
|
getRecord(server, ctx)
|
|
120
114
|
fetchLabels(server, ctx)
|
package/src/auth.ts
CHANGED
|
@@ -7,35 +7,43 @@ import { ServerConfig } from './config'
|
|
|
7
7
|
const BASIC = 'Basic '
|
|
8
8
|
const BEARER = 'Bearer '
|
|
9
9
|
|
|
10
|
-
export const authVerifier =
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
export const authVerifier = (
|
|
11
|
+
idResolver: IdResolver,
|
|
12
|
+
opts: { aud: string | null },
|
|
13
|
+
) => {
|
|
14
|
+
const getSigningKey = async (
|
|
15
|
+
did: string,
|
|
16
|
+
forceRefresh: boolean,
|
|
17
|
+
): Promise<string> => {
|
|
18
|
+
const atprotoData = await idResolver.did.resolveAtprotoData(
|
|
19
|
+
did,
|
|
20
|
+
forceRefresh,
|
|
21
|
+
)
|
|
22
|
+
return atprotoData.signingKey
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return async (reqCtx: { req: express.Request; res: express.Response }) => {
|
|
13
26
|
const jwtStr = getJwtStrFromReq(reqCtx.req)
|
|
14
27
|
if (!jwtStr) {
|
|
15
28
|
throw new AuthRequiredError('missing jwt', 'MissingJwt')
|
|
16
29
|
}
|
|
17
|
-
const payload = await verifyJwt(
|
|
18
|
-
jwtStr,
|
|
19
|
-
opts.aud,
|
|
20
|
-
async (did, forceRefresh) => {
|
|
21
|
-
const atprotoData = await idResolver.did.resolveAtprotoData(
|
|
22
|
-
did,
|
|
23
|
-
forceRefresh,
|
|
24
|
-
)
|
|
25
|
-
return atprotoData.signingKey
|
|
26
|
-
},
|
|
27
|
-
)
|
|
30
|
+
const payload = await verifyJwt(jwtStr, opts.aud, getSigningKey)
|
|
28
31
|
return { credentials: { did: payload.iss }, artifacts: { aud: opts.aud } }
|
|
29
32
|
}
|
|
33
|
+
}
|
|
30
34
|
|
|
31
|
-
export const authOptionalVerifier =
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
export const authOptionalVerifier = (
|
|
36
|
+
idResolver: IdResolver,
|
|
37
|
+
opts: { aud: string | null },
|
|
38
|
+
) => {
|
|
39
|
+
const verifyAccess = authVerifier(idResolver, opts)
|
|
40
|
+
return async (reqCtx: { req: express.Request; res: express.Response }) => {
|
|
34
41
|
if (!reqCtx.req.headers.authorization) {
|
|
35
42
|
return { credentials: { did: null } }
|
|
36
43
|
}
|
|
37
|
-
return
|
|
44
|
+
return verifyAccess(reqCtx)
|
|
38
45
|
}
|
|
46
|
+
}
|
|
39
47
|
|
|
40
48
|
export const authOptionalAccessOrRoleVerifier = (
|
|
41
49
|
idResolver: IdResolver,
|
|
@@ -127,9 +135,9 @@ export const buildBasicAuth = (username: string, password: string): string => {
|
|
|
127
135
|
}
|
|
128
136
|
|
|
129
137
|
export const getJwtStrFromReq = (req: express.Request): string | null => {
|
|
130
|
-
const { authorization
|
|
131
|
-
if (!authorization
|
|
138
|
+
const { authorization } = req.headers
|
|
139
|
+
if (!authorization?.startsWith(BEARER)) {
|
|
132
140
|
return null
|
|
133
141
|
}
|
|
134
|
-
return authorization.
|
|
142
|
+
return authorization.slice(BEARER.length).trim()
|
|
135
143
|
}
|
|
@@ -61,7 +61,6 @@ export class AutoModerator {
|
|
|
61
61
|
'moderation service not properly configured',
|
|
62
62
|
)
|
|
63
63
|
}
|
|
64
|
-
|
|
65
64
|
this.imgLabeler = hiveApiKey ? new HiveLabeler(hiveApiKey, ctx) : undefined
|
|
66
65
|
this.textLabeler = new KeywordLabeler(ctx.cfg.labelerKeywords)
|
|
67
66
|
if (abyssEndpoint && abyssPassword) {
|
|
@@ -157,18 +156,22 @@ export class AutoModerator {
|
|
|
157
156
|
if (!this.textFlagger) return
|
|
158
157
|
const matches = this.textFlagger.getMatches(text)
|
|
159
158
|
if (matches.length < 1) return
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
159
|
+
await this.ctx.db.transaction(async (dbTxn) => {
|
|
160
|
+
if (!this.services.moderation) {
|
|
161
|
+
log.error(
|
|
162
|
+
{ subject, text, matches },
|
|
163
|
+
'no moderation service setup to flag record text',
|
|
164
|
+
)
|
|
165
|
+
return
|
|
166
|
+
}
|
|
167
|
+
return this.services.moderation(dbTxn).report({
|
|
168
|
+
reasonType: REASONOTHER,
|
|
169
|
+
reason: `Automatically flagged for possible slurs: ${matches.join(
|
|
170
|
+
', ',
|
|
171
|
+
)}`,
|
|
172
|
+
subject,
|
|
173
|
+
reportedBy: this.ctx.cfg.labelerDid,
|
|
174
|
+
})
|
|
172
175
|
})
|
|
173
176
|
}
|
|
174
177
|
|
|
@@ -244,15 +247,17 @@ export class AutoModerator {
|
|
|
244
247
|
}
|
|
245
248
|
|
|
246
249
|
if (this.pushAgent) {
|
|
247
|
-
await this.pushAgent.com.atproto.admin.
|
|
248
|
-
|
|
250
|
+
await this.pushAgent.com.atproto.admin.emitModerationEvent({
|
|
251
|
+
event: {
|
|
252
|
+
$type: 'com.atproto.admin.defs#modEventTakedown',
|
|
253
|
+
comment: takedownReason,
|
|
254
|
+
},
|
|
249
255
|
subject: {
|
|
250
256
|
$type: 'com.atproto.repo.strongRef',
|
|
251
257
|
uri: uri.toString(),
|
|
252
258
|
cid: recordCid.toString(),
|
|
253
259
|
},
|
|
254
260
|
subjectBlobCids: takedownCids.map((c) => c.toString()),
|
|
255
|
-
reason: takedownReason,
|
|
256
261
|
createdBy: this.ctx.cfg.labelerDid,
|
|
257
262
|
})
|
|
258
263
|
} else {
|
|
@@ -261,11 +266,13 @@ export class AutoModerator {
|
|
|
261
266
|
throw new Error('no mod push agent or uri invalidator setup')
|
|
262
267
|
}
|
|
263
268
|
const modSrvc = this.services.moderation(dbTxn)
|
|
264
|
-
const action = await modSrvc.
|
|
265
|
-
|
|
269
|
+
const action = await modSrvc.logEvent({
|
|
270
|
+
event: {
|
|
271
|
+
$type: 'com.atproto.admin.defs#modEventTakedown',
|
|
272
|
+
comment: takedownReason,
|
|
273
|
+
},
|
|
266
274
|
subject: { uri, cid: recordCid },
|
|
267
275
|
subjectBlobCids: takedownCids,
|
|
268
|
-
reason: takedownReason,
|
|
269
276
|
createdBy: this.ctx.cfg.labelerDid,
|
|
270
277
|
})
|
|
271
278
|
await modSrvc.takedownRecord({
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { cacheLogger as log } from '../logger'
|
|
2
|
+
import { Redis } from '../redis'
|
|
3
|
+
|
|
4
|
+
export type CacheItem<T> = {
|
|
5
|
+
val: T | null // null here is for negative caching
|
|
6
|
+
updatedAt: number
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type CacheOptions<T> = {
|
|
10
|
+
staleTTL: number
|
|
11
|
+
maxTTL: number
|
|
12
|
+
fetchMethod: (key: string) => Promise<T | null>
|
|
13
|
+
fetchManyMethod?: (keys: string[]) => Promise<Record<string, T | null>>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class ReadThroughCache<T> {
|
|
17
|
+
constructor(public redis: Redis, public opts: CacheOptions<T>) {}
|
|
18
|
+
|
|
19
|
+
private async _fetchMany(keys: string[]): Promise<Record<string, T | null>> {
|
|
20
|
+
let result: Record<string, T | null> = {}
|
|
21
|
+
if (this.opts.fetchManyMethod) {
|
|
22
|
+
result = await this.opts.fetchManyMethod(keys)
|
|
23
|
+
} else {
|
|
24
|
+
const got = await Promise.all(keys.map((k) => this.opts.fetchMethod(k)))
|
|
25
|
+
for (let i = 0; i < keys.length; i++) {
|
|
26
|
+
result[keys[i]] = got[i] ?? null
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// ensure caching negatives
|
|
30
|
+
for (const key of keys) {
|
|
31
|
+
result[key] ??= null
|
|
32
|
+
}
|
|
33
|
+
return result
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private async fetchAndCache(key: string): Promise<T | null> {
|
|
37
|
+
const fetched = await this.opts.fetchMethod(key)
|
|
38
|
+
this.set(key, fetched).catch((err) =>
|
|
39
|
+
log.error({ err, key }, 'failed to set cache value'),
|
|
40
|
+
)
|
|
41
|
+
return fetched
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private async fetchAndCacheMany(keys: string[]): Promise<Record<string, T>> {
|
|
45
|
+
const fetched = await this._fetchMany(keys)
|
|
46
|
+
this.setMany(fetched).catch((err) =>
|
|
47
|
+
log.error({ err, keys }, 'failed to set cache values'),
|
|
48
|
+
)
|
|
49
|
+
return removeNulls(fetched)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async get(key: string, opts?: { revalidate?: boolean }): Promise<T | null> {
|
|
53
|
+
if (opts?.revalidate) {
|
|
54
|
+
return this.fetchAndCache(key)
|
|
55
|
+
}
|
|
56
|
+
let cached: CacheItem<T> | null
|
|
57
|
+
try {
|
|
58
|
+
const got = await this.redis.get(key)
|
|
59
|
+
cached = got ? JSON.parse(got) : null
|
|
60
|
+
} catch (err) {
|
|
61
|
+
cached = null
|
|
62
|
+
log.warn({ key, err }, 'failed to fetch value from cache')
|
|
63
|
+
}
|
|
64
|
+
if (!cached || this.isExpired(cached)) {
|
|
65
|
+
return this.fetchAndCache(key)
|
|
66
|
+
}
|
|
67
|
+
if (this.isStale(cached)) {
|
|
68
|
+
this.fetchAndCache(key).catch((err) =>
|
|
69
|
+
log.warn({ key, err }, 'failed to refresh stale cache value'),
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
return cached.val
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async getMany(
|
|
76
|
+
keys: string[],
|
|
77
|
+
opts?: { revalidate?: boolean },
|
|
78
|
+
): Promise<Record<string, T>> {
|
|
79
|
+
if (opts?.revalidate) {
|
|
80
|
+
return this.fetchAndCacheMany(keys)
|
|
81
|
+
}
|
|
82
|
+
let cached: Record<string, string>
|
|
83
|
+
try {
|
|
84
|
+
cached = await this.redis.getMulti(keys)
|
|
85
|
+
} catch (err) {
|
|
86
|
+
cached = {}
|
|
87
|
+
log.warn({ keys, err }, 'failed to fetch values from cache')
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const stale: string[] = []
|
|
91
|
+
const toFetch: string[] = []
|
|
92
|
+
const results: Record<string, T> = {}
|
|
93
|
+
for (const key of keys) {
|
|
94
|
+
const val = cached[key] ? (JSON.parse(cached[key]) as CacheItem<T>) : null
|
|
95
|
+
if (!val || this.isExpired(val)) {
|
|
96
|
+
toFetch.push(key)
|
|
97
|
+
continue
|
|
98
|
+
}
|
|
99
|
+
if (this.isStale(val)) {
|
|
100
|
+
stale.push(key)
|
|
101
|
+
}
|
|
102
|
+
if (val.val) {
|
|
103
|
+
results[key] = val.val
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const fetched = await this.fetchAndCacheMany(toFetch)
|
|
107
|
+
this.fetchAndCacheMany(stale).catch((err) =>
|
|
108
|
+
log.warn({ keys, err }, 'failed to refresh stale cache values'),
|
|
109
|
+
)
|
|
110
|
+
return {
|
|
111
|
+
...results,
|
|
112
|
+
...fetched,
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async set(key: string, val: T | null) {
|
|
117
|
+
await this.setMany({ [key]: val })
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async setMany(vals: Record<string, T | null>) {
|
|
121
|
+
const items: Record<string, string> = {}
|
|
122
|
+
for (const key of Object.keys(vals)) {
|
|
123
|
+
items[key] = JSON.stringify({
|
|
124
|
+
val: vals[key],
|
|
125
|
+
updatedAt: Date.now(),
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
await this.redis.setMulti(items, this.opts.maxTTL)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async clearEntry(key: string) {
|
|
132
|
+
await this.redis.del(key)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
isExpired(result: CacheItem<T>) {
|
|
136
|
+
return Date.now() > result.updatedAt + this.opts.maxTTL
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
isStale(result: CacheItem<T>) {
|
|
140
|
+
return Date.now() > result.updatedAt + this.opts.staleTTL
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const removeNulls = <T>(obj: Record<string, T | null>): Record<string, T> => {
|
|
145
|
+
return Object.entries(obj).reduce((acc, [key, val]) => {
|
|
146
|
+
if (val !== null) {
|
|
147
|
+
acc[key] = val
|
|
148
|
+
}
|
|
149
|
+
return acc
|
|
150
|
+
}, {} as Record<string, T>)
|
|
151
|
+
}
|
package/src/config.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import assert from 'assert'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
DAY,
|
|
4
|
+
HOUR,
|
|
5
|
+
MINUTE,
|
|
6
|
+
SECOND,
|
|
7
|
+
parseIntWithFallback,
|
|
8
|
+
} from '@atproto/common'
|
|
3
9
|
|
|
4
10
|
export interface ServerConfigValues {
|
|
5
11
|
version: string
|
|
@@ -12,9 +18,15 @@ export interface ServerConfigValues {
|
|
|
12
18
|
dbReplicaPostgresUrls?: string[]
|
|
13
19
|
dbReplicaTags?: Record<string, number[]> // E.g. { timeline: [0], thread: [1] }
|
|
14
20
|
dbPostgresSchema?: string
|
|
21
|
+
redisHost?: string // either set redis host, or both sentinel name and hosts
|
|
22
|
+
redisSentinelName?: string
|
|
23
|
+
redisSentinelHosts?: string[]
|
|
24
|
+
redisPassword?: string
|
|
15
25
|
didPlcUrl: string
|
|
16
26
|
didCacheStaleTTL: number
|
|
17
27
|
didCacheMaxTTL: number
|
|
28
|
+
labelCacheStaleTTL: number
|
|
29
|
+
labelCacheMaxTTL: number
|
|
18
30
|
handleResolveNameservers?: string[]
|
|
19
31
|
imgUriEndpoint?: string
|
|
20
32
|
blobCacheLocation?: string
|
|
@@ -24,6 +36,9 @@ export interface ServerConfigValues {
|
|
|
24
36
|
moderatorPassword?: string
|
|
25
37
|
triagePassword?: string
|
|
26
38
|
moderationPushUrl?: string
|
|
39
|
+
rateLimitsEnabled: boolean
|
|
40
|
+
rateLimitBypassKey?: string
|
|
41
|
+
rateLimitBypassIps?: string[]
|
|
27
42
|
}
|
|
28
43
|
|
|
29
44
|
export class ServerConfig {
|
|
@@ -38,6 +53,19 @@ export class ServerConfig {
|
|
|
38
53
|
const feedGenDid = process.env.FEED_GEN_DID
|
|
39
54
|
const envPort = parseInt(process.env.PORT || '', 10)
|
|
40
55
|
const port = isNaN(envPort) ? 2584 : envPort
|
|
56
|
+
const redisHost =
|
|
57
|
+
overrides?.redisHost || process.env.REDIS_HOST || undefined
|
|
58
|
+
const redisSentinelName =
|
|
59
|
+
overrides?.redisSentinelName ||
|
|
60
|
+
process.env.REDIS_SENTINEL_NAME ||
|
|
61
|
+
undefined
|
|
62
|
+
const redisSentinelHosts =
|
|
63
|
+
overrides?.redisSentinelHosts ||
|
|
64
|
+
(process.env.REDIS_SENTINEL_HOSTS
|
|
65
|
+
? process.env.REDIS_SENTINEL_HOSTS.split(',')
|
|
66
|
+
: [])
|
|
67
|
+
const redisPassword =
|
|
68
|
+
overrides?.redisPassword || process.env.REDIS_PASSWORD || undefined
|
|
41
69
|
const didPlcUrl = process.env.DID_PLC_URL || 'http://localhost:2582'
|
|
42
70
|
const didCacheStaleTTL = parseIntWithFallback(
|
|
43
71
|
process.env.DID_CACHE_STALE_TTL,
|
|
@@ -47,6 +75,14 @@ export class ServerConfig {
|
|
|
47
75
|
process.env.DID_CACHE_MAX_TTL,
|
|
48
76
|
DAY,
|
|
49
77
|
)
|
|
78
|
+
const labelCacheStaleTTL = parseIntWithFallback(
|
|
79
|
+
process.env.LABEL_CACHE_STALE_TTL,
|
|
80
|
+
30 * SECOND,
|
|
81
|
+
)
|
|
82
|
+
const labelCacheMaxTTL = parseIntWithFallback(
|
|
83
|
+
process.env.LABEL_CACHE_MAX_TTL,
|
|
84
|
+
MINUTE,
|
|
85
|
+
)
|
|
50
86
|
const handleResolveNameservers = process.env.HANDLE_RESOLVE_NAMESERVERS
|
|
51
87
|
? process.env.HANDLE_RESOLVE_NAMESERVERS.split(',')
|
|
52
88
|
: []
|
|
@@ -82,6 +118,14 @@ export class ServerConfig {
|
|
|
82
118
|
overrides?.moderationPushUrl ||
|
|
83
119
|
process.env.MODERATION_PUSH_URL ||
|
|
84
120
|
undefined
|
|
121
|
+
const rateLimitsEnabled = process.env.RATE_LIMITS_ENABLED === 'true'
|
|
122
|
+
const rateLimitBypassKey = process.env.RATE_LIMIT_BYPASS_KEY
|
|
123
|
+
const rateLimitBypassIps = process.env.RATE_LIMIT_BYPASS_IPS
|
|
124
|
+
? process.env.RATE_LIMIT_BYPASS_IPS.split(',').map((ipOrCidr) =>
|
|
125
|
+
ipOrCidr.split('/')[0]?.trim(),
|
|
126
|
+
)
|
|
127
|
+
: undefined
|
|
128
|
+
|
|
85
129
|
return new ServerConfig({
|
|
86
130
|
version,
|
|
87
131
|
debugMode,
|
|
@@ -93,9 +137,15 @@ export class ServerConfig {
|
|
|
93
137
|
dbReplicaPostgresUrls,
|
|
94
138
|
dbReplicaTags,
|
|
95
139
|
dbPostgresSchema,
|
|
140
|
+
redisHost,
|
|
141
|
+
redisSentinelName,
|
|
142
|
+
redisSentinelHosts,
|
|
143
|
+
redisPassword,
|
|
96
144
|
didPlcUrl,
|
|
97
145
|
didCacheStaleTTL,
|
|
98
146
|
didCacheMaxTTL,
|
|
147
|
+
labelCacheStaleTTL,
|
|
148
|
+
labelCacheMaxTTL,
|
|
99
149
|
handleResolveNameservers,
|
|
100
150
|
imgUriEndpoint,
|
|
101
151
|
blobCacheLocation,
|
|
@@ -105,6 +155,9 @@ export class ServerConfig {
|
|
|
105
155
|
moderatorPassword,
|
|
106
156
|
triagePassword,
|
|
107
157
|
moderationPushUrl,
|
|
158
|
+
rateLimitsEnabled,
|
|
159
|
+
rateLimitBypassKey,
|
|
160
|
+
rateLimitBypassIps,
|
|
108
161
|
...stripUndefineds(overrides ?? {}),
|
|
109
162
|
})
|
|
110
163
|
}
|
|
@@ -162,6 +215,22 @@ export class ServerConfig {
|
|
|
162
215
|
return this.cfg.dbPostgresSchema
|
|
163
216
|
}
|
|
164
217
|
|
|
218
|
+
get redisHost() {
|
|
219
|
+
return this.cfg.redisHost
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
get redisSentinelName() {
|
|
223
|
+
return this.cfg.redisSentinelName
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
get redisSentinelHosts() {
|
|
227
|
+
return this.cfg.redisSentinelHosts
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
get redisPassword() {
|
|
231
|
+
return this.cfg.redisPassword
|
|
232
|
+
}
|
|
233
|
+
|
|
165
234
|
get didCacheStaleTTL() {
|
|
166
235
|
return this.cfg.didCacheStaleTTL
|
|
167
236
|
}
|
|
@@ -170,6 +239,14 @@ export class ServerConfig {
|
|
|
170
239
|
return this.cfg.didCacheMaxTTL
|
|
171
240
|
}
|
|
172
241
|
|
|
242
|
+
get labelCacheStaleTTL() {
|
|
243
|
+
return this.cfg.labelCacheStaleTTL
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
get labelCacheMaxTTL() {
|
|
247
|
+
return this.cfg.labelCacheMaxTTL
|
|
248
|
+
}
|
|
249
|
+
|
|
173
250
|
get handleResolveNameservers() {
|
|
174
251
|
return this.cfg.handleResolveNameservers
|
|
175
252
|
}
|
|
@@ -209,6 +286,18 @@ export class ServerConfig {
|
|
|
209
286
|
get moderationPushUrl() {
|
|
210
287
|
return this.cfg.moderationPushUrl
|
|
211
288
|
}
|
|
289
|
+
|
|
290
|
+
get rateLimitsEnabled() {
|
|
291
|
+
return this.cfg.rateLimitsEnabled
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
get rateLimitBypassKey() {
|
|
295
|
+
return this.cfg.rateLimitBypassKey
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
get rateLimitBypassIps() {
|
|
299
|
+
return this.cfg.rateLimitBypassIps
|
|
300
|
+
}
|
|
212
301
|
}
|
|
213
302
|
|
|
214
303
|
function getTagIdxs(str?: string): number[] {
|
package/src/context.ts
CHANGED
|
@@ -8,11 +8,11 @@ import { ServerConfig } from './config'
|
|
|
8
8
|
import { ImageUriBuilder } from './image/uri'
|
|
9
9
|
import { Services } from './services'
|
|
10
10
|
import * as auth from './auth'
|
|
11
|
-
import
|
|
11
|
+
import DidRedisCache from './did-cache'
|
|
12
12
|
import { BackgroundQueue } from './background'
|
|
13
13
|
import { MountedAlgos } from './feed-gen/types'
|
|
14
|
-
import { LabelCache } from './label-cache'
|
|
15
14
|
import { NotificationServer } from './notifications'
|
|
15
|
+
import { Redis } from './redis'
|
|
16
16
|
|
|
17
17
|
export class AppContext {
|
|
18
18
|
public moderationPushAgent: AtpAgent | undefined
|
|
@@ -24,8 +24,8 @@ export class AppContext {
|
|
|
24
24
|
services: Services
|
|
25
25
|
signingKey: Keypair
|
|
26
26
|
idResolver: IdResolver
|
|
27
|
-
didCache:
|
|
28
|
-
|
|
27
|
+
didCache: DidRedisCache
|
|
28
|
+
redis: Redis
|
|
29
29
|
backgroundQueue: BackgroundQueue
|
|
30
30
|
searchAgent?: AtpAgent
|
|
31
31
|
algos: MountedAlgos
|
|
@@ -70,12 +70,12 @@ export class AppContext {
|
|
|
70
70
|
return this.opts.idResolver
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
get didCache():
|
|
73
|
+
get didCache(): DidRedisCache {
|
|
74
74
|
return this.opts.didCache
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
get
|
|
78
|
-
return this.opts.
|
|
77
|
+
get redis(): Redis {
|
|
78
|
+
return this.opts.redis
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
get notifServer(): NotificationServer {
|
|
@@ -94,6 +94,10 @@ export class AppContext {
|
|
|
94
94
|
return auth.authVerifier(this.idResolver, { aud: null })
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
get authOptionalVerifierAnyAudience() {
|
|
98
|
+
return auth.authOptionalVerifier(this.idResolver, { aud: null })
|
|
99
|
+
}
|
|
100
|
+
|
|
97
101
|
get authOptionalVerifier() {
|
|
98
102
|
return auth.authOptionalVerifier(this.idResolver, {
|
|
99
103
|
aud: this.cfg.serverDid,
|