@atproto/ozone 0.2.9 → 0.2.11
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/package.json +25 -21
- package/bin/migration-create.ts +0 -38
- package/jest.config.cjs +0 -22
- package/src/api/chat/getActorMetadata.ts +0 -23
- package/src/api/chat/getConvo.ts +0 -23
- package/src/api/chat/getConvoMembers.ts +0 -23
- package/src/api/chat/getConvos.ts +0 -23
- package/src/api/chat/getMessageContext.ts +0 -42
- package/src/api/chat/index.ts +0 -16
- package/src/api/communication/createTemplate.ts +0 -51
- package/src/api/communication/deleteTemplate.ts +0 -23
- package/src/api/communication/listTemplates.ts +0 -31
- package/src/api/communication/updateTemplate.ts +0 -51
- package/src/api/health.ts +0 -27
- package/src/api/index.ts +0 -146
- package/src/api/label/fetchLabels.ts +0 -32
- package/src/api/label/queryLabels.ts +0 -57
- package/src/api/label/subscribeLabels.ts +0 -25
- package/src/api/moderation/cancelScheduledActions.ts +0 -72
- package/src/api/moderation/emitEvent.ts +0 -475
- package/src/api/moderation/getAccountTimeline.ts +0 -160
- package/src/api/moderation/getEvent.ts +0 -19
- package/src/api/moderation/getRecord.ts +0 -40
- package/src/api/moderation/getRecords.ts +0 -50
- package/src/api/moderation/getRepo.ts +0 -34
- package/src/api/moderation/getReporterStats.ts +0 -18
- package/src/api/moderation/getRepos.ts +0 -41
- package/src/api/moderation/getSubjects.ts +0 -101
- package/src/api/moderation/listScheduledActions.ts +0 -45
- package/src/api/moderation/queryEvents.ts +0 -72
- package/src/api/moderation/queryStatuses.ts +0 -23
- package/src/api/moderation/scheduleAction.ts +0 -129
- package/src/api/moderation/searchRepos.ts +0 -46
- package/src/api/moderation/util.ts +0 -96
- package/src/api/proxied.ts +0 -327
- package/src/api/queue/assignModerator.ts +0 -31
- package/src/api/queue/createQueue.ts +0 -62
- package/src/api/queue/deleteQueue.ts +0 -56
- package/src/api/queue/getAssignments.ts +0 -19
- package/src/api/queue/listQueues.ts +0 -39
- package/src/api/queue/routeReports.ts +0 -44
- package/src/api/queue/unassignModerator.ts +0 -26
- package/src/api/queue/updateQueue.ts +0 -54
- package/src/api/report/assignModerator.ts +0 -36
- package/src/api/report/createActivity.ts +0 -57
- package/src/api/report/createReport.ts +0 -93
- package/src/api/report/getAssignments.ts +0 -20
- package/src/api/report/getHistoricalStats.ts +0 -41
- package/src/api/report/getLatestReport.ts +0 -44
- package/src/api/report/getLiveStats.ts +0 -26
- package/src/api/report/getReport.ts +0 -55
- package/src/api/report/listActivities.ts +0 -37
- package/src/api/report/queryActivities.ts +0 -64
- package/src/api/report/queryReports.ts +0 -44
- package/src/api/report/reassignQueue.ts +0 -68
- package/src/api/report/refreshStats.ts +0 -27
- package/src/api/report/unassignModerator.ts +0 -21
- package/src/api/safelink/addRule.ts +0 -48
- package/src/api/safelink/queryEvents.ts +0 -32
- package/src/api/safelink/queryRules.ts +0 -58
- package/src/api/safelink/removeRule.ts +0 -42
- package/src/api/safelink/updateRule.ts +0 -48
- package/src/api/server/getConfig.ts +0 -35
- package/src/api/set/addValues.ts +0 -28
- package/src/api/set/deleteSet.ts +0 -34
- package/src/api/set/deleteValues.ts +0 -31
- package/src/api/set/getValues.ts +0 -42
- package/src/api/set/querySets.ts +0 -36
- package/src/api/set/upsertSet.ts +0 -38
- package/src/api/setting/listOptions.ts +0 -44
- package/src/api/setting/removeOptions.ts +0 -64
- package/src/api/setting/upsertOption.ts +0 -156
- package/src/api/team/addMember.ts +0 -51
- package/src/api/team/deleteMember.ts +0 -29
- package/src/api/team/listMembers.ts +0 -20
- package/src/api/team/updateMember.ts +0 -47
- package/src/api/util.ts +0 -265
- package/src/api/verification/grantVerifications.ts +0 -90
- package/src/api/verification/listVerifications.ts +0 -44
- package/src/api/verification/revokeVerifications.ts +0 -43
- package/src/api/well-known.ts +0 -46
- package/src/assignment/index.ts +0 -728
- package/src/auth-verifier.ts +0 -227
- package/src/background.ts +0 -183
- package/src/communication-service/template.ts +0 -110
- package/src/communication-service/util.ts +0 -8
- package/src/config/config.ts +0 -211
- package/src/config/env.ts +0 -95
- package/src/config/index.ts +0 -3
- package/src/config/secrets.ts +0 -17
- package/src/context.ts +0 -399
- package/src/daemon/blob-diverter.ts +0 -186
- package/src/daemon/context.ts +0 -247
- package/src/daemon/event-pusher.ts +0 -363
- package/src/daemon/event-reverser.ts +0 -128
- package/src/daemon/index.ts +0 -33
- package/src/daemon/job-cursor.ts +0 -33
- package/src/daemon/materialized-view-refresher.ts +0 -33
- package/src/daemon/queue-router.ts +0 -101
- package/src/daemon/scheduled-action-processor.ts +0 -304
- package/src/daemon/stats-computer.ts +0 -101
- package/src/daemon/strike-expiry-processor.ts +0 -95
- package/src/daemon/team-profile-synchronizer.ts +0 -15
- package/src/daemon/verification-listener.ts +0 -169
- package/src/db/index.ts +0 -203
- package/src/db/migrations/20231219T205730722Z-init.ts +0 -170
- package/src/db/migrations/20240116T085607200Z-communication-template.ts +0 -23
- package/src/db/migrations/20240201T051104136Z-mod-event-blobs.ts +0 -15
- package/src/db/migrations/20240208T213404429Z-add-tags-column-to-moderation-subject.ts +0 -31
- package/src/db/migrations/20240228T003647759Z-add-label-sigs.ts +0 -25
- package/src/db/migrations/20240408T192432676Z-mute-reporting.ts +0 -15
- package/src/db/migrations/20240506T225055595Z-message-subject.ts +0 -21
- package/src/db/migrations/20240521T211332580Z-member.ts +0 -17
- package/src/db/migrations/20240814T003647759Z-event-created-at-index.ts +0 -13
- package/src/db/migrations/20240903T205730722Z-add-template-lang.ts +0 -12
- package/src/db/migrations/20240904T205730722Z-add-subject-did-index.ts +0 -13
- package/src/db/migrations/20241001T205730722Z-subject-status-review-state-index.ts +0 -15
- package/src/db/migrations/20241008T205730722Z-sets.ts +0 -53
- package/src/db/migrations/20241018T205730722Z-setting.ts +0 -27
- package/src/db/migrations/20241026T205730722Z-add-hosting-status-to-subject-status.ts +0 -57
- package/src/db/migrations/20241220T144630860Z-stats-materialized-views.ts +0 -215
- package/src/db/migrations/20250204T003647759Z-add-subject-priority-score.ts +0 -22
- package/src/db/migrations/20250211T003647759Z-add-reporter-stats-index.ts +0 -38
- package/src/db/migrations/20250211T132135150Z-moderation-event-message-partial-idx.ts +0 -26
- package/src/db/migrations/20250221T132135150Z-member-details.ts +0 -14
- package/src/db/migrations/20250404T201720309Z-subject-status-sort-idxs.ts +0 -18
- package/src/db/migrations/20250415T201720309Z-verification.ts +0 -34
- package/src/db/migrations/20250417T201720309Z-firehose-cursor.ts +0 -16
- package/src/db/migrations/20250609T110704000Z-safelink.ts +0 -53
- package/src/db/migrations/20250618T180246000Z-add-mod-tool-to-moderation-event.ts +0 -18
- package/src/db/migrations/20250701T000000000Z-add-age-assurance-state.ts +0 -25
- package/src/db/migrations/20250715T000000000Z-add-mod-event-external-id.ts +0 -15
- package/src/db/migrations/20250718T150931000Z-update-appeal-reason-stats.ts +0 -310
- package/src/db/migrations/20250813T000000000Z-mod-tool-batch-id-index.ts +0 -14
- package/src/db/migrations/20250923T000000000Z-scheduled-actions.ts +0 -56
- package/src/db/migrations/20251008T120000000Z-add-strike-system.ts +0 -87
- package/src/db/migrations/20260210T154806448Z-mod-event-created-by-indexes.ts +0 -22
- package/src/db/migrations/20260219T164523000Z-create-report-table.ts +0 -155
- package/src/db/migrations/20260219T165302248Z-moderator-assignment.ts +0 -42
- package/src/db/migrations/20260225T000000000Z-add-report-queue-table.ts +0 -41
- package/src/db/migrations/20260313T000000000Z-add-report-activity-table.ts +0 -48
- package/src/db/migrations/20260318T152058935Z-add-report-stat.ts +0 -35
- package/src/db/migrations/20260428T000000000Z-add-expiring-tag-table.ts +0 -32
- package/src/db/migrations/20260513T202941104Z-add-subject-convo-id.ts +0 -114
- package/src/db/migrations/20260602T120000000Z-add-report-activity-created-index.ts +0 -17
- package/src/db/migrations/index.ts +0 -44
- package/src/db/migrations/provider.ts +0 -26
- package/src/db/pagination.ts +0 -335
- package/src/db/schema/account_events_stats.ts +0 -16
- package/src/db/schema/account_record_events_stats.ts +0 -15
- package/src/db/schema/account_record_status_stats.ts +0 -15
- package/src/db/schema/account_strike.ts +0 -13
- package/src/db/schema/blob_push_event.ts +0 -21
- package/src/db/schema/communication_template.ts +0 -19
- package/src/db/schema/expiring_tag.ts +0 -18
- package/src/db/schema/firehose_cursor.ts +0 -13
- package/src/db/schema/index.ts +0 -60
- package/src/db/schema/job_cursor.ts +0 -13
- package/src/db/schema/label.ts +0 -22
- package/src/db/schema/member.ts +0 -22
- package/src/db/schema/moderation_event.ts +0 -61
- package/src/db/schema/moderation_subject_status.ts +0 -52
- package/src/db/schema/moderator_assignment.ts +0 -16
- package/src/db/schema/ozone_set.ts +0 -24
- package/src/db/schema/record_events_stats.ts +0 -15
- package/src/db/schema/record_push_event.ts +0 -21
- package/src/db/schema/repo_push_event.ts +0 -19
- package/src/db/schema/report.ts +0 -28
- package/src/db/schema/report_activity.ts +0 -22
- package/src/db/schema/report_queue.ts +0 -21
- package/src/db/schema/report_stat.ts +0 -27
- package/src/db/schema/safelink.ts +0 -39
- package/src/db/schema/scheduled-action.ts +0 -25
- package/src/db/schema/setting.ts +0 -24
- package/src/db/schema/signing_key.ts +0 -10
- package/src/db/schema/verification.ts +0 -21
- package/src/db/types.ts +0 -24
- package/src/error.ts +0 -12
- package/src/image-invalidator.ts +0 -7
- package/src/index.ts +0 -154
- package/src/jetstream/service.ts +0 -107
- package/src/logger.ts +0 -29
- package/src/mod-service/expiring-tags.ts +0 -104
- package/src/mod-service/index.ts +0 -1842
- package/src/mod-service/profile.ts +0 -139
- package/src/mod-service/report.ts +0 -429
- package/src/mod-service/status.ts +0 -549
- package/src/mod-service/strike.ts +0 -96
- package/src/mod-service/subject.ts +0 -311
- package/src/mod-service/types.ts +0 -96
- package/src/mod-service/util.ts +0 -99
- package/src/mod-service/views.ts +0 -912
- package/src/queue/service.ts +0 -603
- package/src/report/activity.ts +0 -281
- package/src/report/handle-report-update.ts +0 -209
- package/src/report/reassign.ts +0 -109
- package/src/report/stats.ts +0 -852
- package/src/report/views.ts +0 -239
- package/src/safelink/service.ts +0 -304
- package/src/scheduled-action/service.ts +0 -281
- package/src/scheduled-action/types.ts +0 -17
- package/src/sequencer/index.ts +0 -2
- package/src/sequencer/outbox.ts +0 -123
- package/src/sequencer/sequencer.ts +0 -147
- package/src/set/service.ts +0 -230
- package/src/setting/constants.ts +0 -3
- package/src/setting/service.ts +0 -148
- package/src/setting/types.ts +0 -3
- package/src/setting/validators.ts +0 -333
- package/src/tag-service/content-tagger.ts +0 -30
- package/src/tag-service/embed-tagger.ts +0 -70
- package/src/tag-service/index.ts +0 -70
- package/src/tag-service/language-data.ts +0 -561
- package/src/tag-service/language-tagger.ts +0 -101
- package/src/tag-service/util.ts +0 -13
- package/src/team/index.ts +0 -296
- package/src/util.ts +0 -230
- package/src/verification/issuer.ts +0 -146
- package/src/verification/service.ts +0 -208
- package/src/verification/util.ts +0 -53
- package/test.env +0 -2
- package/tests/3p-labeler.test.ts +0 -288
- package/tests/__snapshots__/account-strikes.test.ts.snap +0 -159
- package/tests/__snapshots__/age-assurance.test.ts.snap +0 -66
- package/tests/__snapshots__/blob-divert.test.ts.snap +0 -219
- package/tests/__snapshots__/get-account-timeline.test.ts.snap +0 -36
- package/tests/__snapshots__/get-record.test.ts.snap +0 -271
- package/tests/__snapshots__/get-records.test.ts.snap +0 -175
- package/tests/__snapshots__/get-repo.test.ts.snap +0 -91
- package/tests/__snapshots__/get-repos.test.ts.snap +0 -127
- package/tests/__snapshots__/get-starter-pack.test.ts.snap +0 -535
- package/tests/__snapshots__/get-subjects.test.ts.snap +0 -529
- package/tests/__snapshots__/moderation-events.test.ts.snap +0 -347
- package/tests/__snapshots__/moderation-statuses.test.ts.snap +0 -276
- package/tests/__snapshots__/moderation.test.ts.snap +0 -85
- package/tests/__snapshots__/report-reason.test.ts.snap +0 -14
- package/tests/__snapshots__/safelink.test.ts.snap +0 -179
- package/tests/__snapshots__/scheduled-action.test.ts.snap +0 -61
- package/tests/__snapshots__/sets.test.ts.snap +0 -46
- package/tests/__snapshots__/settings.test.ts.snap +0 -52
- package/tests/__snapshots__/team.test.ts.snap +0 -374
- package/tests/__snapshots__/verification-listener.test.ts.snap +0 -152
- package/tests/__snapshots__/verification.test.ts.snap +0 -302
- package/tests/_util.ts +0 -242
- package/tests/account-strikes.test.ts +0 -184
- package/tests/ack-all-subjects-of-account.test.ts +0 -177
- package/tests/age-assurance.test.ts +0 -372
- package/tests/blob-divert.test.ts +0 -106
- package/tests/communication-templates.test.ts +0 -149
- package/tests/content-tagger.test.ts +0 -170
- package/tests/db.test.ts +0 -184
- package/tests/expiring-label.test.ts +0 -72
- package/tests/expiring-tags.test.ts +0 -232
- package/tests/get-account-timeline.test.ts +0 -85
- package/tests/get-config.test.ts +0 -55
- package/tests/get-lists.test.ts +0 -111
- package/tests/get-profiles.test.ts +0 -70
- package/tests/get-record.test.ts +0 -130
- package/tests/get-records.test.ts +0 -91
- package/tests/get-repo.test.ts +0 -171
- package/tests/get-report.test.ts +0 -136
- package/tests/get-reporter-stats.test.ts +0 -132
- package/tests/get-repos.test.ts +0 -91
- package/tests/get-starter-pack.test.ts +0 -115
- package/tests/get-subjects.test.ts +0 -81
- package/tests/mod-tool.test.ts +0 -268
- package/tests/moderation-appeals.test.ts +0 -260
- package/tests/moderation-events.test.ts +0 -756
- package/tests/moderation-status-tags.test.ts +0 -140
- package/tests/moderation-statuses.test.ts +0 -495
- package/tests/moderation.test.ts +0 -992
- package/tests/protected-tags.test.ts +0 -218
- package/tests/query-labels.test.ts +0 -238
- package/tests/query-reports.test.ts +0 -608
- package/tests/queue-assignment.test.ts +0 -428
- package/tests/queue-router.test.ts +0 -306
- package/tests/queues.test.ts +0 -690
- package/tests/record-and-account-events.test.ts +0 -197
- package/tests/repo-search.test.ts +0 -136
- package/tests/report-action.test.ts +0 -308
- package/tests/report-activity.test.ts +0 -711
- package/tests/report-assignment.test.ts +0 -517
- package/tests/report-muting.test.ts +0 -100
- package/tests/report-reason.test.ts +0 -154
- package/tests/report-reassign-queue.test.ts +0 -340
- package/tests/report-routing.test.ts +0 -245
- package/tests/report-stats.test.ts +0 -545
- package/tests/revoke-account-credentials.test.ts +0 -54
- package/tests/safelink.test.ts +0 -534
- package/tests/scheduled-action-processor.test.ts +0 -488
- package/tests/scheduled-action.test.ts +0 -334
- package/tests/sequencer.test.ts +0 -227
- package/tests/server.test.ts +0 -62
- package/tests/sets.test.ts +0 -246
- package/tests/settings.test.ts +0 -308
- package/tests/strike-expiry-processor.test.ts +0 -299
- package/tests/subject-priority-score.test.ts +0 -96
- package/tests/takedown.test.ts +0 -105
- package/tests/team.test.ts +0 -216
- package/tests/verification-listener.test.ts +0 -129
- package/tests/verification.test.ts +0 -186
- package/tsconfig.build.json +0 -9
- package/tsconfig.build.tsbuildinfo +0 -1
- package/tsconfig.json +0 -7
- package/tsconfig.tests.json +0 -8
|
@@ -1,311 +0,0 @@
|
|
|
1
|
-
import { AtUri } from '@atproto/syntax'
|
|
2
|
-
import { InvalidRequestError } from '@atproto/xrpc-server'
|
|
3
|
-
import * as ChatBskyConvoDefs from '../lexicon/types/chat/bsky/convo/defs.js'
|
|
4
|
-
import { RepoRef, isRepoRef } from '../lexicon/types/com/atproto/admin/defs.js'
|
|
5
|
-
import { InputSchema as ReportInput } from '../lexicon/types/com/atproto/moderation/createReport.js'
|
|
6
|
-
import * as ComAtprotoRepoStrongRef from '../lexicon/types/com/atproto/repo/strongRef.js'
|
|
7
|
-
import { InputSchema as ActionInput } from '../lexicon/types/tools/ozone/moderation/emitEvent.js'
|
|
8
|
-
import { $Typed, asPredicate } from '../lexicon/util.js'
|
|
9
|
-
import { ModerationEventRow, ModerationSubjectStatusRow } from './types.js'
|
|
10
|
-
|
|
11
|
-
type SubjectInput = ReportInput['subject'] | ActionInput['subject']
|
|
12
|
-
|
|
13
|
-
type StrongRef = ComAtprotoRepoStrongRef.Main
|
|
14
|
-
const isStrongRef = asPredicate(ComAtprotoRepoStrongRef.validateMain)
|
|
15
|
-
|
|
16
|
-
type MessageRef = ChatBskyConvoDefs.MessageRef
|
|
17
|
-
const isValidMessageRef = asPredicate(ChatBskyConvoDefs.validateMessageRef)
|
|
18
|
-
|
|
19
|
-
type ConvoRef = ChatBskyConvoDefs.ConvoRef
|
|
20
|
-
const isValidConvoRef = asPredicate(ChatBskyConvoDefs.validateConvoRef)
|
|
21
|
-
|
|
22
|
-
const isMessageRefWithoutConvoId = (
|
|
23
|
-
subject: unknown,
|
|
24
|
-
): subject is $Typed<Omit<MessageRef, 'convoId'> & { convoId?: string }> =>
|
|
25
|
-
subject != null &&
|
|
26
|
-
typeof subject === 'object' &&
|
|
27
|
-
isValidMessageRef({ convoId: '', ...subject })
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Cast subject input into ModSubject.
|
|
31
|
-
* @description Represents the subject types that can appear in the moderation event stream.
|
|
32
|
-
* NOTE: Downstream services should be updated to handle new subject types including appview.
|
|
33
|
-
*/
|
|
34
|
-
export const subjectFromInput = (
|
|
35
|
-
subject: SubjectInput,
|
|
36
|
-
blobs?: string[],
|
|
37
|
-
): ModSubject => {
|
|
38
|
-
if (isRepoRef(subject)) {
|
|
39
|
-
if (blobs && blobs.length > 0) {
|
|
40
|
-
throw new InvalidRequestError('Blobs do not apply to repo subjects')
|
|
41
|
-
}
|
|
42
|
-
return new RepoSubject(subject.did)
|
|
43
|
-
}
|
|
44
|
-
if (isStrongRef(subject)) {
|
|
45
|
-
return new RecordSubject(subject.uri, subject.cid, blobs)
|
|
46
|
-
}
|
|
47
|
-
// @NOTE #messageRef is not a report input for com.atproto.moderation.createReport.
|
|
48
|
-
// we are taking advantage of the open union in order for bsky.chat to interoperate here.
|
|
49
|
-
if (isValidMessageRef(subject)) {
|
|
50
|
-
return new MessageSubject(subject.did, subject.convoId, subject.messageId)
|
|
51
|
-
}
|
|
52
|
-
// @NOTE #convoRef is a new type for reporting entire conversations.
|
|
53
|
-
// Similar to messageRef, we take advantage of the open union to support this.
|
|
54
|
-
if (isValidConvoRef(subject)) {
|
|
55
|
-
return new ConvoSubject(subject.did, subject.convoId)
|
|
56
|
-
}
|
|
57
|
-
// @TODO we should start to require subject.convoId is a string in order to properly validate
|
|
58
|
-
// the #messageRef. temporarily allowing it to be optional as a stopgap for rollout.
|
|
59
|
-
// The next "if" can be removed once convoId is consistently provided.
|
|
60
|
-
if (isMessageRefWithoutConvoId(subject)) {
|
|
61
|
-
return new MessageSubject(
|
|
62
|
-
subject.did,
|
|
63
|
-
subject.convoId ?? '',
|
|
64
|
-
subject.messageId,
|
|
65
|
-
)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
throw new InvalidRequestError('Invalid subject')
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export const subjectFromEventRow = (row: ModerationEventRow): ModSubject => {
|
|
72
|
-
if (
|
|
73
|
-
row.subjectType === 'com.atproto.repo.strongRef' &&
|
|
74
|
-
row.subjectUri &&
|
|
75
|
-
row.subjectCid
|
|
76
|
-
) {
|
|
77
|
-
return new RecordSubject(
|
|
78
|
-
row.subjectUri,
|
|
79
|
-
row.subjectCid,
|
|
80
|
-
row.subjectBlobCids ?? [],
|
|
81
|
-
)
|
|
82
|
-
} else if (
|
|
83
|
-
row.subjectType === 'chat.bsky.convo.defs#messageRef' &&
|
|
84
|
-
row.subjectMessageId
|
|
85
|
-
) {
|
|
86
|
-
const convoId =
|
|
87
|
-
typeof row.meta?.['convoId'] === 'string' ? row.meta['convoId'] : ''
|
|
88
|
-
return new MessageSubject(row.subjectDid, convoId, row.subjectMessageId)
|
|
89
|
-
} else if (
|
|
90
|
-
row.subjectType === 'chat.bsky.convo.defs#convoRef' &&
|
|
91
|
-
row.subjectConvoId
|
|
92
|
-
) {
|
|
93
|
-
return new ConvoSubject(row.subjectDid, row.subjectConvoId)
|
|
94
|
-
} else {
|
|
95
|
-
return new RepoSubject(row.subjectDid)
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export const subjectFromStatusRow = (
|
|
100
|
-
row: ModerationSubjectStatusRow,
|
|
101
|
-
): ModSubject => {
|
|
102
|
-
if (row.recordPath && row.recordCid) {
|
|
103
|
-
// Not too intuitive but the recordpath is basically <collection>/<rkey>
|
|
104
|
-
// which is what the last 2 params of .make() arguments are
|
|
105
|
-
const uri = AtUri.make(row.did, ...row.recordPath.split('/')).toString()
|
|
106
|
-
return new RecordSubject(uri.toString(), row.recordCid, row.blobCids ?? [])
|
|
107
|
-
} else if (row.convoId) {
|
|
108
|
-
// Conversation subject - restore from subject status row
|
|
109
|
-
return new ConvoSubject(row.did, row.convoId)
|
|
110
|
-
} else {
|
|
111
|
-
return new RepoSubject(row.did)
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
type SubjectInfo = {
|
|
116
|
-
subjectType:
|
|
117
|
-
| 'com.atproto.admin.defs#repoRef'
|
|
118
|
-
| 'com.atproto.repo.strongRef'
|
|
119
|
-
| 'chat.bsky.convo.defs#messageRef'
|
|
120
|
-
| 'chat.bsky.convo.defs#convoRef'
|
|
121
|
-
subjectDid: string
|
|
122
|
-
subjectUri: string | null
|
|
123
|
-
subjectCid: string | null
|
|
124
|
-
subjectBlobCids: string[] | null
|
|
125
|
-
subjectMessageId: string | null
|
|
126
|
-
subjectConvoId: string | null
|
|
127
|
-
meta: Record<string, string | undefined> | null
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
export interface ModSubject {
|
|
131
|
-
did: string
|
|
132
|
-
recordPath: string | undefined
|
|
133
|
-
convoId: string | undefined
|
|
134
|
-
blobCids?: string[]
|
|
135
|
-
isRepo(): this is RepoSubject
|
|
136
|
-
isRecord(): this is RecordSubject
|
|
137
|
-
isMessage(): this is MessageSubject
|
|
138
|
-
isConvo(): this is ConvoSubject
|
|
139
|
-
info(): SubjectInfo
|
|
140
|
-
lex():
|
|
141
|
-
| $Typed<RepoRef>
|
|
142
|
-
| $Typed<StrongRef>
|
|
143
|
-
| $Typed<MessageRef>
|
|
144
|
-
| $Typed<ConvoRef>
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
export class RepoSubject implements ModSubject {
|
|
148
|
-
blobCids = undefined
|
|
149
|
-
recordPath = undefined
|
|
150
|
-
convoId = undefined
|
|
151
|
-
constructor(public did: string) {}
|
|
152
|
-
isRepo(): this is RepoSubject {
|
|
153
|
-
return true
|
|
154
|
-
}
|
|
155
|
-
isRecord(): this is RecordSubject {
|
|
156
|
-
return false
|
|
157
|
-
}
|
|
158
|
-
isMessage(): this is MessageSubject {
|
|
159
|
-
return false
|
|
160
|
-
}
|
|
161
|
-
isConvo(): this is ConvoSubject {
|
|
162
|
-
return false
|
|
163
|
-
}
|
|
164
|
-
info() {
|
|
165
|
-
return {
|
|
166
|
-
subjectType: 'com.atproto.admin.defs#repoRef' as const,
|
|
167
|
-
subjectDid: this.did,
|
|
168
|
-
subjectUri: null,
|
|
169
|
-
subjectCid: null,
|
|
170
|
-
subjectBlobCids: null,
|
|
171
|
-
subjectMessageId: null,
|
|
172
|
-
subjectConvoId: null,
|
|
173
|
-
meta: null,
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
lex(): $Typed<RepoRef> {
|
|
177
|
-
return {
|
|
178
|
-
$type: 'com.atproto.admin.defs#repoRef',
|
|
179
|
-
did: this.did,
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
export class RecordSubject implements ModSubject {
|
|
185
|
-
parsedUri: AtUri
|
|
186
|
-
did: string
|
|
187
|
-
recordPath: string
|
|
188
|
-
convoId = undefined
|
|
189
|
-
constructor(
|
|
190
|
-
public uri: string,
|
|
191
|
-
public cid: string,
|
|
192
|
-
public blobCids?: string[],
|
|
193
|
-
) {
|
|
194
|
-
this.parsedUri = new AtUri(uri)
|
|
195
|
-
this.did = this.parsedUri.hostname
|
|
196
|
-
this.recordPath = `${this.parsedUri.collection}/${this.parsedUri.rkey}`
|
|
197
|
-
}
|
|
198
|
-
isRepo(): this is RepoSubject {
|
|
199
|
-
return false
|
|
200
|
-
}
|
|
201
|
-
isRecord(): this is RecordSubject {
|
|
202
|
-
return true
|
|
203
|
-
}
|
|
204
|
-
isMessage(): this is MessageSubject {
|
|
205
|
-
return false
|
|
206
|
-
}
|
|
207
|
-
isConvo(): this is ConvoSubject {
|
|
208
|
-
return false
|
|
209
|
-
}
|
|
210
|
-
info() {
|
|
211
|
-
return {
|
|
212
|
-
subjectType: 'com.atproto.repo.strongRef' as const,
|
|
213
|
-
subjectDid: this.did,
|
|
214
|
-
subjectUri: this.uri,
|
|
215
|
-
subjectCid: this.cid,
|
|
216
|
-
subjectBlobCids: this.blobCids ?? [],
|
|
217
|
-
subjectMessageId: null,
|
|
218
|
-
subjectConvoId: null,
|
|
219
|
-
meta: null,
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
lex(): $Typed<StrongRef> {
|
|
223
|
-
return {
|
|
224
|
-
$type: 'com.atproto.repo.strongRef',
|
|
225
|
-
uri: this.uri,
|
|
226
|
-
cid: this.cid,
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
export class MessageSubject implements ModSubject {
|
|
232
|
-
blobCids = undefined
|
|
233
|
-
recordPath = undefined
|
|
234
|
-
constructor(
|
|
235
|
-
public did: string,
|
|
236
|
-
public convoId: string,
|
|
237
|
-
public messageId: string,
|
|
238
|
-
) {}
|
|
239
|
-
isRepo(): this is RepoSubject {
|
|
240
|
-
return false
|
|
241
|
-
}
|
|
242
|
-
isRecord(): this is RecordSubject {
|
|
243
|
-
return false
|
|
244
|
-
}
|
|
245
|
-
isMessage(): this is MessageSubject {
|
|
246
|
-
return true
|
|
247
|
-
}
|
|
248
|
-
isConvo(): this is ConvoSubject {
|
|
249
|
-
return false
|
|
250
|
-
}
|
|
251
|
-
info() {
|
|
252
|
-
return {
|
|
253
|
-
subjectType: 'chat.bsky.convo.defs#messageRef' as const,
|
|
254
|
-
subjectDid: this.did,
|
|
255
|
-
subjectUri: null,
|
|
256
|
-
subjectCid: null,
|
|
257
|
-
subjectBlobCids: null,
|
|
258
|
-
subjectMessageId: this.messageId,
|
|
259
|
-
subjectConvoId: this.convoId,
|
|
260
|
-
meta: { convoId: this.convoId || undefined },
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
lex(): $Typed<MessageRef> {
|
|
264
|
-
return {
|
|
265
|
-
$type: 'chat.bsky.convo.defs#messageRef',
|
|
266
|
-
did: this.did,
|
|
267
|
-
convoId: this.convoId,
|
|
268
|
-
messageId: this.messageId,
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
export class ConvoSubject implements ModSubject {
|
|
274
|
-
blobCids = undefined
|
|
275
|
-
recordPath = undefined
|
|
276
|
-
constructor(
|
|
277
|
-
public did: string,
|
|
278
|
-
public convoId: string,
|
|
279
|
-
) {}
|
|
280
|
-
isRepo(): this is RepoSubject {
|
|
281
|
-
return false
|
|
282
|
-
}
|
|
283
|
-
isRecord(): this is RecordSubject {
|
|
284
|
-
return false
|
|
285
|
-
}
|
|
286
|
-
isMessage(): this is MessageSubject {
|
|
287
|
-
return false
|
|
288
|
-
}
|
|
289
|
-
isConvo(): this is ConvoSubject {
|
|
290
|
-
return true
|
|
291
|
-
}
|
|
292
|
-
info() {
|
|
293
|
-
return {
|
|
294
|
-
subjectType: 'chat.bsky.convo.defs#convoRef' as const,
|
|
295
|
-
subjectDid: this.did,
|
|
296
|
-
subjectUri: null,
|
|
297
|
-
subjectCid: null,
|
|
298
|
-
subjectBlobCids: null,
|
|
299
|
-
subjectMessageId: null,
|
|
300
|
-
subjectConvoId: this.convoId,
|
|
301
|
-
meta: { convoId: this.convoId || undefined },
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
lex(): $Typed<ConvoRef> {
|
|
305
|
-
return {
|
|
306
|
-
$type: 'chat.bsky.convo.defs#convoRef',
|
|
307
|
-
did: this.did,
|
|
308
|
-
convoId: this.convoId,
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
}
|
package/src/mod-service/types.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { type Selectable } from 'kysely'
|
|
2
|
-
import { ModerationEvent } from '../db/schema/moderation_event.js'
|
|
3
|
-
import { ModerationSubjectStatus } from '../db/schema/moderation_subject_status.js'
|
|
4
|
-
import { ModEventView } from '../lexicon/types/tools/ozone/moderation/defs.js'
|
|
5
|
-
import { ModSubject } from './subject.js'
|
|
6
|
-
|
|
7
|
-
export type ModerationEventRow = Selectable<ModerationEvent>
|
|
8
|
-
export type ReversibleModerationEvent = Pick<
|
|
9
|
-
ModerationEventRow,
|
|
10
|
-
'createdBy' | 'comment' | 'action'
|
|
11
|
-
> & {
|
|
12
|
-
createdAt?: Date
|
|
13
|
-
subject: ModSubject
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export type ModerationEventRowWithHandle = ModerationEventRow & {
|
|
17
|
-
subjectHandle?: string | null
|
|
18
|
-
creatorHandle?: string | null
|
|
19
|
-
}
|
|
20
|
-
export type ModerationSubjectStatusRow = Selectable<ModerationSubjectStatus>
|
|
21
|
-
export type ModerationSubjectStatusRowWithStats = ModerationSubjectStatusRow & {
|
|
22
|
-
// account_events_stats
|
|
23
|
-
takedownCount: number | null
|
|
24
|
-
suspendCount: number | null
|
|
25
|
-
escalateCount: number | null
|
|
26
|
-
reportCount: number | null
|
|
27
|
-
appealCount: number | null
|
|
28
|
-
|
|
29
|
-
// account_record_events_stats
|
|
30
|
-
totalReports: number | null
|
|
31
|
-
reportedCount: number | null
|
|
32
|
-
escalatedCount: number | null
|
|
33
|
-
appealedCount: number | null
|
|
34
|
-
|
|
35
|
-
// account_record_status_stats
|
|
36
|
-
subjectCount: number | null
|
|
37
|
-
pendingCount: number | null
|
|
38
|
-
processedCount: number | null
|
|
39
|
-
takendownCount: number | null
|
|
40
|
-
|
|
41
|
-
// account_strike
|
|
42
|
-
strikeCount: number | null
|
|
43
|
-
totalStrikeCount: number | null
|
|
44
|
-
firstStrikeAt: string | null
|
|
45
|
-
lastStrikeAt: string | null
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export type ModerationSubjectStatusRowWithHandle =
|
|
49
|
-
ModerationSubjectStatusRowWithStats & { handle: string | null }
|
|
50
|
-
|
|
51
|
-
export type ModEventType = ModEventView['event']
|
|
52
|
-
|
|
53
|
-
type AccountHostingView = {
|
|
54
|
-
$type: 'tools.ozone.moderation.defs#accountHosting'
|
|
55
|
-
status: 'active' | 'takendown' | 'suspended' | 'deleted' | 'deactivated'
|
|
56
|
-
createdAt?: Date
|
|
57
|
-
updatedAt?: Date
|
|
58
|
-
deletedAt?: Date
|
|
59
|
-
deactivatedAt?: Date
|
|
60
|
-
reactivatedAt?: Date
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
type RecordHostingView = {
|
|
64
|
-
$type: 'tools.ozone.moderation.defs#recordHosting'
|
|
65
|
-
status: 'active' | 'deleted'
|
|
66
|
-
createdAt?: Date
|
|
67
|
-
updatedAt?: Date
|
|
68
|
-
deletedAt?: Date
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export type ModerationSubjectHostingView =
|
|
72
|
-
| AccountHostingView
|
|
73
|
-
| RecordHostingView
|
|
74
|
-
|
|
75
|
-
export type ReporterStats = {
|
|
76
|
-
did: string
|
|
77
|
-
accountReportCount: number
|
|
78
|
-
recordReportCount: number
|
|
79
|
-
reportedAccountCount: number
|
|
80
|
-
reportedRecordCount: number
|
|
81
|
-
takendownAccountCount: number
|
|
82
|
-
takendownRecordCount: number
|
|
83
|
-
labeledAccountCount: number
|
|
84
|
-
labeledRecordCount: number
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export type ReporterStatsResult = {
|
|
88
|
-
accountReportCount?: number
|
|
89
|
-
recordReportCount?: number
|
|
90
|
-
reportedAccountCount?: number
|
|
91
|
-
reportedRecordCount?: number
|
|
92
|
-
takendownAccountCount?: number
|
|
93
|
-
takendownRecordCount?: number
|
|
94
|
-
labeledAccountCount?: number
|
|
95
|
-
labeledRecordCount?: number
|
|
96
|
-
}
|
package/src/mod-service/util.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import net from 'node:net'
|
|
2
|
-
import { sql } from 'kysely'
|
|
3
|
-
import AtpAgent from '@atproto/api'
|
|
4
|
-
import { cborEncode, noUndefinedVals } from '@atproto/common'
|
|
5
|
-
import { Keypair } from '@atproto/crypto'
|
|
6
|
-
import { IdResolver } from '@atproto/identity'
|
|
7
|
-
import { LabelRow } from '../db/schema/label.js'
|
|
8
|
-
import { DbRef } from '../db/types.js'
|
|
9
|
-
import { Label } from '../lexicon/types/com/atproto/label/defs.js'
|
|
10
|
-
|
|
11
|
-
export type SignedLabel = Label & { sig: Uint8Array }
|
|
12
|
-
|
|
13
|
-
export const formatLabel = (row: LabelRow): Label => {
|
|
14
|
-
return noUndefinedVals({
|
|
15
|
-
ver: 1,
|
|
16
|
-
src: row.src,
|
|
17
|
-
uri: row.uri,
|
|
18
|
-
cid: row.cid === '' ? undefined : row.cid,
|
|
19
|
-
val: row.val,
|
|
20
|
-
neg: row.neg === true ? true : undefined,
|
|
21
|
-
cts: row.cts,
|
|
22
|
-
exp: row.exp ?? undefined,
|
|
23
|
-
sig: row.sig ? new Uint8Array(row.sig) : undefined,
|
|
24
|
-
} satisfies Label) as unknown as Label
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export const formatLabelRow = (
|
|
28
|
-
label: Label,
|
|
29
|
-
signingKeyId?: number,
|
|
30
|
-
): Omit<LabelRow, 'id'> => {
|
|
31
|
-
return {
|
|
32
|
-
src: label.src,
|
|
33
|
-
uri: label.uri,
|
|
34
|
-
cid: label.cid ?? '',
|
|
35
|
-
val: label.val,
|
|
36
|
-
neg: !!label.neg,
|
|
37
|
-
cts: label.cts,
|
|
38
|
-
exp: label.exp ?? null,
|
|
39
|
-
sig: label.sig ? Buffer.from(label.sig) : null,
|
|
40
|
-
signingKeyId: signingKeyId ?? null,
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export const signLabel = async (
|
|
45
|
-
label: Label,
|
|
46
|
-
signingKey: Keypair,
|
|
47
|
-
): Promise<SignedLabel> => {
|
|
48
|
-
const { ver, src, uri, cid, val, neg, cts, exp } = label
|
|
49
|
-
// @TODO cborEncode now ignores undefined properties, so we might not need to
|
|
50
|
-
// reformat the label here. We might want to consider this if we ever re-visit
|
|
51
|
-
// the logic below:
|
|
52
|
-
const reformatted = noUndefinedVals({
|
|
53
|
-
ver: ver ?? 1,
|
|
54
|
-
src,
|
|
55
|
-
uri,
|
|
56
|
-
cid,
|
|
57
|
-
val,
|
|
58
|
-
neg: neg === true ? true : undefined,
|
|
59
|
-
cts,
|
|
60
|
-
exp,
|
|
61
|
-
} satisfies Label) as unknown as Label
|
|
62
|
-
|
|
63
|
-
const bytes = cborEncode(reformatted)
|
|
64
|
-
const sig = await signingKey.sign(bytes)
|
|
65
|
-
return {
|
|
66
|
-
...reformatted,
|
|
67
|
-
sig,
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export const isSafeUrl = (url: URL) => {
|
|
72
|
-
if (url.protocol !== 'https:') return false
|
|
73
|
-
if (!url.hostname || url.hostname === 'localhost') return false
|
|
74
|
-
if (net.isIP(url.hostname) !== 0) return false
|
|
75
|
-
return true
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export const getPdsAgentForRepo = async (
|
|
79
|
-
idResolver: IdResolver,
|
|
80
|
-
did: string,
|
|
81
|
-
devMode?: boolean,
|
|
82
|
-
) => {
|
|
83
|
-
const { pds } = await idResolver.did.resolveAtprotoData(did)
|
|
84
|
-
const url = new URL(pds)
|
|
85
|
-
if (!devMode && !isSafeUrl(url)) {
|
|
86
|
-
return { url, agent: null }
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return { url, agent: new AtpAgent({ service: url }) }
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export const dateFromDatetime = (datetime: Date) => {
|
|
93
|
-
const [date] = datetime.toISOString().split('T')
|
|
94
|
-
return date
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export const dateFromDbDatetime = (dateRef: DbRef) => {
|
|
98
|
-
return sql<string>`SPLIT_PART(${dateRef}, 'T', 1)`
|
|
99
|
-
}
|