@atproto/ozone 0.1.150 → 0.1.152
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 +16 -0
- package/dist/api/moderation/queryEvents.d.ts.map +1 -1
- package/dist/api/moderation/queryEvents.js +2 -1
- package/dist/api/moderation/queryEvents.js.map +1 -1
- package/dist/context.d.ts +3 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +7 -1
- package/dist/context.js.map +1 -1
- package/dist/daemon/context.d.ts +3 -0
- package/dist/daemon/context.d.ts.map +1 -1
- package/dist/daemon/context.js +11 -1
- package/dist/daemon/context.js.map +1 -1
- package/dist/daemon/index.d.ts +1 -0
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +3 -1
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/strike-expiry-processor.d.ts +18 -0
- package/dist/daemon/strike-expiry-processor.d.ts.map +1 -0
- package/dist/daemon/strike-expiry-processor.js +111 -0
- package/dist/daemon/strike-expiry-processor.js.map +1 -0
- package/dist/db/migrations/20251008T120000000Z-add-strike-system.d.ts +4 -0
- package/dist/db/migrations/20251008T120000000Z-add-strike-system.d.ts.map +1 -0
- package/dist/db/migrations/20251008T120000000Z-add-strike-system.js +75 -0
- package/dist/db/migrations/20251008T120000000Z-add-strike-system.js.map +1 -0
- package/dist/db/migrations/index.d.ts +1 -0
- package/dist/db/migrations/index.d.ts.map +1 -1
- package/dist/db/migrations/index.js +2 -1
- package/dist/db/migrations/index.js.map +1 -1
- package/dist/db/schema/account_strike.d.ts +12 -0
- package/dist/db/schema/account_strike.d.ts.map +1 -0
- package/dist/db/schema/account_strike.js +5 -0
- package/dist/db/schema/account_strike.js.map +1 -0
- package/dist/db/schema/index.d.ts +3 -1
- package/dist/db/schema/index.d.ts.map +1 -1
- package/dist/db/schema/index.js.map +1 -1
- package/dist/db/schema/job_cursor.d.ts +11 -0
- package/dist/db/schema/job_cursor.d.ts.map +1 -0
- package/dist/db/schema/job_cursor.js +5 -0
- package/dist/db/schema/job_cursor.js.map +1 -0
- package/dist/db/schema/moderation_event.d.ts +3 -0
- package/dist/db/schema/moderation_event.d.ts.map +1 -1
- package/dist/db/schema/moderation_event.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +208 -0
- package/dist/lexicon/lexicons.d.ts.map +1 -1
- package/dist/lexicon/lexicons.js +104 -0
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts +12 -0
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/actor/defs.js.map +1 -1
- package/dist/lexicon/types/app/bsky/feed/defs.d.ts +4 -0
- package/dist/lexicon/types/app/bsky/feed/defs.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/feed/defs.js.map +1 -1
- package/dist/lexicon/types/tools/ozone/moderation/defs.d.ts +35 -0
- package/dist/lexicon/types/tools/ozone/moderation/defs.d.ts.map +1 -1
- package/dist/lexicon/types/tools/ozone/moderation/defs.js +9 -0
- package/dist/lexicon/types/tools/ozone/moderation/defs.js.map +1 -1
- package/dist/lexicon/types/tools/ozone/moderation/queryEvents.d.ts +2 -0
- package/dist/lexicon/types/tools/ozone/moderation/queryEvents.d.ts.map +1 -1
- package/dist/lexicon/types/tools/ozone/moderation/queryEvents.js.map +1 -1
- package/dist/lexicon/types/tools/ozone/moderation/queryStatuses.d.ts +2 -0
- package/dist/lexicon/types/tools/ozone/moderation/queryStatuses.d.ts.map +1 -1
- package/dist/lexicon/types/tools/ozone/moderation/queryStatuses.js.map +1 -1
- package/dist/mod-service/index.d.ts +9 -3
- package/dist/mod-service/index.d.ts.map +1 -1
- package/dist/mod-service/index.js +59 -6
- package/dist/mod-service/index.js.map +1 -1
- package/dist/mod-service/status.d.ts +44 -2
- package/dist/mod-service/status.d.ts.map +1 -1
- package/dist/mod-service/status.js +7 -0
- package/dist/mod-service/status.js.map +1 -1
- package/dist/mod-service/strike.d.ts +19 -0
- package/dist/mod-service/strike.d.ts.map +1 -0
- package/dist/mod-service/strike.js +86 -0
- package/dist/mod-service/strike.js.map +1 -0
- package/dist/mod-service/types.d.ts +4 -0
- package/dist/mod-service/types.d.ts.map +1 -1
- package/dist/mod-service/types.js.map +1 -1
- package/dist/mod-service/views.d.ts.map +1 -1
- package/dist/mod-service/views.js +20 -4
- package/dist/mod-service/views.js.map +1 -1
- package/dist/setting/constants.d.ts +1 -0
- package/dist/setting/constants.d.ts.map +1 -1
- package/dist/setting/constants.js +2 -1
- package/dist/setting/constants.js.map +1 -1
- package/dist/setting/validators.d.ts.map +1 -1
- package/dist/setting/validators.js +179 -0
- package/dist/setting/validators.js.map +1 -1
- package/package.json +3 -3
- package/src/api/moderation/queryEvents.ts +2 -0
- package/src/context.ts +20 -11
- package/src/daemon/context.ts +15 -1
- package/src/daemon/index.ts +1 -0
- package/src/daemon/strike-expiry-processor.ts +111 -0
- package/src/db/migrations/20251008T120000000Z-add-strike-system.ts +87 -0
- package/src/db/migrations/index.ts +1 -0
- package/src/db/schema/account_strike.ts +13 -0
- package/src/db/schema/index.ts +4 -0
- package/src/db/schema/job_cursor.ts +13 -0
- package/src/db/schema/moderation_event.ts +3 -0
- package/src/lexicon/lexicons.ts +119 -0
- package/src/lexicon/types/app/bsky/actor/defs.ts +6 -0
- package/src/lexicon/types/app/bsky/feed/defs.ts +2 -0
- package/src/lexicon/types/tools/ozone/moderation/defs.ts +44 -0
- package/src/lexicon/types/tools/ozone/moderation/queryEvents.ts +2 -0
- package/src/lexicon/types/tools/ozone/moderation/queryStatuses.ts +2 -0
- package/src/mod-service/index.ts +70 -3
- package/src/mod-service/status.ts +9 -0
- package/src/mod-service/strike.ts +96 -0
- package/src/mod-service/types.ts +6 -0
- package/src/mod-service/views.ts +25 -4
- package/src/setting/constants.ts +1 -0
- package/src/setting/validators.ts +231 -1
- package/tests/__snapshots__/account-strikes.test.ts.snap +159 -0
- package/tests/account-strikes.test.ts +184 -0
- package/tests/query-labels.test.ts +1 -0
- package/tests/strike-expiry-processor.test.ts +299 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/tsconfig.tests.tsbuildinfo +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"views.js","sourceRoot":"","sources":["../../src/mod-service/views.ts"],"names":[],"mappings":"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","sourcesContent":["import { sql } from 'kysely'\nimport {\n AppBskyActorDefs,\n AtpAgent,\n ComAtprotoRepoGetRecord,\n} from '@atproto/api'\nimport { chunkArray, dedupeStrs } from '@atproto/common'\nimport { Keypair } from '@atproto/crypto'\nimport { IdResolver } from '@atproto/identity'\nimport { BlobRef } from '@atproto/lexicon'\nimport { AtUri, INVALID_HANDLE, normalizeDatetimeAlways } from '@atproto/syntax'\nimport { Database } from '../db'\nimport { LabelRow } from '../db/schema/label'\nimport { ids } from '../lexicon/lexicons'\nimport { FeedViewPost } from '../lexicon/types/app/bsky/feed/defs'\nimport { AccountView } from '../lexicon/types/com/atproto/admin/defs'\nimport {\n Label,\n validateSelfLabels,\n} from '../lexicon/types/com/atproto/label/defs'\nimport { OutputSchema as ReportOutput } from '../lexicon/types/com/atproto/moderation/createReport'\nimport { REASONOTHER } from '../lexicon/types/com/atproto/moderation/defs'\nimport {\n BlobView,\n ModEventView,\n ModEventViewDetail,\n RecordView,\n RecordViewDetail,\n RepoView,\n SubjectStatusView,\n isAccountEvent,\n isAgeAssuranceEvent,\n isAgeAssuranceOverrideEvent,\n isIdentityEvent,\n isModEventAcknowledge,\n isModEventComment,\n isModEventEmail,\n isModEventEscalate,\n isModEventLabel,\n isModEventMute,\n isModEventMuteReporter,\n isModEventPriorityScore,\n isModEventReport,\n isModEventTag,\n isModEventTakedown,\n isRecordEvent,\n isScheduleTakedownEvent,\n} from '../lexicon/types/tools/ozone/moderation/defs'\nimport { Un$Typed, asPredicate } from '../lexicon/util'\nimport { dbLogger, httpLogger } from '../logger'\nimport { ParsedLabelers } from '../util'\nimport { moderationSubjectStatusQueryBuilder } from './status'\nimport { subjectFromEventRow, subjectFromStatusRow } from './subject'\nimport {\n ModerationEventRowWithHandle,\n ModerationSubjectStatusRowWithHandle,\n} from './types'\nimport { formatLabel, getPdsAgentForRepo, signLabel } from './util'\n\nconst isValidSelfLabels = asPredicate(validateSelfLabels)\n\nconst ifString = (val: unknown): string | undefined =>\n typeof val === 'string' ? val : undefined\nconst ifBoolean = (val: unknown): boolean | undefined =>\n typeof val === 'boolean' ? val : undefined\nconst ifNumber = (val: unknown): number | undefined =>\n typeof val === 'number' ? val : undefined\n\nexport type AuthHeaders = {\n headers: {\n authorization: string\n 'atproto-accept-labelers'?: string\n }\n}\n\nexport class ModerationViews {\n constructor(\n private db: Database,\n private signingKey: Keypair,\n private signingKeyId: number,\n private appviewAgent: AtpAgent,\n private appviewAuth: (method: string) => Promise<AuthHeaders>,\n public idResolver: IdResolver,\n public devMode?: boolean,\n ) {}\n\n async getAccoutInfosByDid(dids: string[]): Promise<Map<string, AccountView>> {\n if (dids.length === 0) return new Map()\n const auth = await this.appviewAuth(ids.ComAtprotoAdminGetAccountInfos)\n if (!auth) return new Map()\n try {\n const res = await this.appviewAgent.com.atproto.admin.getAccountInfos(\n {\n dids: dedupeStrs(dids),\n },\n auth,\n )\n return res.data.infos.reduce((acc, cur) => {\n return acc.set(cur.did, cur)\n }, new Map<string, AccountView>())\n } catch (err) {\n httpLogger.error(\n { err, dids },\n 'failed to resolve account infos from appview',\n )\n return new Map()\n }\n }\n\n async repos(dids: string[]): Promise<Map<string, RepoView>> {\n if (dids.length === 0) return new Map()\n const [infos, subjectStatuses] = await Promise.all([\n this.getAccoutInfosByDid(dids),\n this.getSubjectStatus(dids),\n ])\n\n return dids.reduce((acc, did) => {\n const info = infos.get(did)\n if (!info) return acc\n const status = subjectStatuses.get(did)\n return acc.set(did, {\n // No email or invite info on appview\n did,\n handle: info.handle,\n relatedRecords: info.relatedRecords ?? [],\n indexedAt: info.indexedAt,\n moderation: {\n subjectStatus: status ? this.formatSubjectStatus(status) : undefined,\n },\n })\n }, new Map<string, RepoView>())\n }\n\n formatEvent(row: ModerationEventRowWithHandle): Un$Typed<ModEventView> {\n const eventView: Un$Typed<ModEventView> = {\n id: row.id,\n event: {\n $type: row.action,\n comment: row.comment ?? undefined,\n },\n subject: subjectFromEventRow(row).lex(),\n subjectBlobCids: row.subjectBlobCids ?? [],\n createdBy: row.createdBy,\n createdAt: row.createdAt,\n subjectHandle: row.subjectHandle ?? undefined,\n creatorHandle: row.creatorHandle ?? undefined,\n modTool: row.modTool\n ? {\n name: row.modTool.name,\n meta: row.modTool.meta,\n }\n : undefined,\n }\n\n const { event } = eventView\n const meta = row.meta || {}\n\n if (\n isModEventMuteReporter(event) ||\n isModEventTakedown(event) ||\n isModEventLabel(event) ||\n isModEventMute(event)\n ) {\n event.durationInHours = row.durationInHours ?? undefined\n }\n\n if (\n (isModEventTakedown(event) || isModEventAcknowledge(event)) &&\n meta.acknowledgeAccountSubjects\n ) {\n event.acknowledgeAccountSubjects = ifBoolean(\n meta.acknowledgeAccountSubjects,\n )!\n }\n\n if (isModEventPriorityScore(event)) {\n event.score = ifNumber(meta?.priorityScore) ?? 0\n }\n\n if (\n isModEventTakedown(event) &&\n typeof meta.policies === 'string' &&\n meta.policies.length > 0\n ) {\n event.policies = meta.policies.split(',')\n }\n\n if (isModEventLabel(event)) {\n event.createLabelVals = row.createLabelVals?.length\n ? row.createLabelVals.split(' ')\n : []\n event.negateLabelVals = row.negateLabelVals?.length\n ? row.negateLabelVals.split(' ')\n : []\n } else if (\n isModEventAcknowledge(event) ||\n isModEventTakedown(event) ||\n isModEventEscalate(event)\n ) {\n // This is for legacy data only, for new events, these types of events\n // won't have labels attached:\n\n if (row.createLabelVals?.length) {\n // @ts-expect-error legacy\n event.createLabelVals = row.createLabelVals.split(' ')\n }\n\n if (row.negateLabelVals?.length) {\n // @ts-expect-error legacy\n event.negateLabelVals = row.negateLabelVals.split(' ')\n }\n }\n\n if (isModEventReport(event)) {\n event.isReporterMuted = !!meta.isReporterMuted\n event.reportType = ifString(meta.reportType)!\n }\n\n if (isModEventEmail(event)) {\n event.content = ifString(meta.content)!\n event.subjectLine = ifString(meta.subjectLine)!\n }\n\n if (isModEventComment(event) && meta.sticky) {\n event.sticky = true\n }\n\n if (isModEventTag(event)) {\n event.add = row.addedTags || []\n event.remove = row.removedTags || []\n }\n\n if (isAccountEvent(event)) {\n event.active = !!meta.active\n event.timestamp = ifString(meta.timestamp)!\n event.status = ifString(meta.status)!\n }\n\n if (isIdentityEvent(event)) {\n event.timestamp = ifString(meta.timestamp)!\n event.handle = ifString(meta.handle)!\n event.pdsHost = ifString(meta.pdsHost)!\n event.tombstone = !!meta.tombstone\n }\n\n if (isRecordEvent(event)) {\n event.op = ifString(meta.op)!\n event.cid = ifString(meta.cid)!\n event.timestamp = ifString(meta.timestamp)!\n }\n\n if (isAgeAssuranceEvent(event)) {\n event.status = ifString(meta.status)!\n event.createdAt = ifString(meta.createdAt)!\n event.attemptId = ifString(meta.attemptId)!\n event.initIp = ifString(meta.initIp)\n event.initUa = ifString(meta.initUa)\n event.completeIp = ifString(meta.completeIp)\n event.completeUa = ifString(meta.completeUa)\n }\n\n if (isAgeAssuranceOverrideEvent(event)) {\n event.status = ifString(meta.status)!\n }\n\n if (isScheduleTakedownEvent(event)) {\n event.executeAt = ifString(meta.executeAt)\n event.executeAfter = ifString(meta.executeAfter)\n event.executeUntil = ifString(meta.executeUntil)\n }\n\n return eventView\n }\n\n async eventDetail(\n result: ModerationEventRowWithHandle,\n ): Promise<ModEventViewDetail> {\n const subjectId =\n result.subjectType === 'com.atproto.admin.defs#repoRef'\n ? result.subjectDid\n : result.subjectUri\n if (!subjectId) {\n throw new Error(`Bad subject: ${result.id}`)\n }\n const subject = await this.subject(subjectId)\n const eventView = this.formatEvent(result)\n const allBlobs = 'value' in subject ? findBlobRefs(subject.value) : []\n const subjectBlobs = await this.blob(\n allBlobs.filter((blob) =>\n eventView.subjectBlobCids.includes(blob.ref.toString()),\n ),\n )\n return {\n ...eventView,\n subject,\n subjectBlobs,\n }\n }\n\n async repoDetails(\n dids: string[],\n labelers?: ParsedLabelers,\n ): Promise<Map<string, RepoView>> {\n const results = new Map<string, RepoView>()\n if (!dids.length) {\n return results\n }\n\n const [repos, localLabels, externalLabels] = await Promise.all([\n this.repos(dids),\n this.labels(dids),\n this.getExternalLabels(dids, labelers),\n ])\n\n repos.forEach((repo, did) => {\n const labels = [\n ...(localLabels.get(did) || []),\n ...(externalLabels.get(did) || []),\n ]\n const repoView = {\n ...repo,\n labels,\n moderation: {\n ...repo.moderation,\n },\n }\n results.set(did, repoView)\n })\n\n return results\n }\n\n async fetchRecord(\n params: ComAtprotoRepoGetRecord.QueryParams,\n appviewAuth: AuthHeaders,\n ) {\n try {\n const record = await this.appviewAgent.com.atproto.repo.getRecord(\n params,\n appviewAuth,\n )\n return record\n } catch (err) {\n if (err instanceof ComAtprotoRepoGetRecord.RecordNotFoundError) {\n // If pds fetch fails, just return null regardless of the error\n try {\n const { agent: pdsAgent } = await getPdsAgentForRepo(\n this.idResolver,\n params.repo,\n this.devMode,\n )\n if (!pdsAgent) {\n return null\n }\n\n const record = await pdsAgent.com.atproto.repo.getRecord(params)\n return record\n } catch (error) {\n return null\n }\n }\n\n return null\n }\n }\n\n async fetchRecords(\n subjects: RecordSubject[],\n ): Promise<Map<string, RecordInfo>> {\n const appviewAuth = await this.appviewAuth(ids.ComAtprotoRepoGetRecord)\n if (!appviewAuth) return new Map()\n\n const fetched = await Promise.all(\n subjects.map(async (subject) => {\n const uri = new AtUri(subject.uri)\n const params = {\n repo: uri.hostname,\n collection: uri.collection,\n rkey: uri.rkey,\n cid: subject.cid,\n }\n return this.fetchRecord(params, appviewAuth)\n }),\n )\n return fetched.reduce((acc, cur) => {\n if (!cur) return acc\n const data = cur.data\n const indexedAt = new Date().toISOString()\n return acc.set(data.uri, { ...data, cid: data.cid ?? '', indexedAt })\n }, new Map<string, RecordInfo>())\n }\n\n async records(subjects: RecordSubject[]) {\n const uris = subjects.map((record) => new AtUri(record.uri))\n const dids = uris.map((u) => u.hostname)\n\n const [repos, subjectStatuses, records] = await Promise.all([\n this.repos(dids),\n this.getSubjectStatus(subjects.map((s) => s.uri)),\n this.fetchRecords(subjects),\n ])\n\n const map = new Map<\n string,\n // Because the result of this function is used to build RecordViewDetail,\n // we explicitly type the result without the $type field, so can be used\n // as both RecordView and RecordViewDetail, without having to cast or\n // override the $type field.\n RecordView & {\n $type?: undefined\n moderation: { $type?: undefined; subjectStatus?: SubjectStatusView }\n }\n >()\n\n for (const uri of uris) {\n const repo = repos.get(uri.hostname)\n if (!repo) continue\n const record = records.get(uri.toString())\n if (!record) continue\n const subjectStatus = subjectStatuses.get(uri.toString())\n\n map.set(uri.toString(), {\n uri: uri.toString(),\n cid: record.cid,\n value: record.value,\n blobCids: findBlobRefs(record.value).map((blob) => blob.ref.toString()),\n indexedAt: record.indexedAt,\n repo,\n moderation: {\n subjectStatus: subjectStatus\n ? this.formatSubjectStatus(subjectStatus)\n : undefined,\n },\n })\n }\n\n return map\n }\n\n async recordDetails(\n subjects: RecordSubject[],\n labelers?: ParsedLabelers,\n ): Promise<Map<string, RecordViewDetail>> {\n const results = new Map<string, RecordViewDetail>()\n if (!subjects.length) {\n return results\n }\n\n const subjectUris = subjects.map((s) => s.uri)\n const [records, subjectStatusesResult, localLabels, externalLabels] =\n await Promise.all([\n this.records(subjects),\n this.getSubjectStatus(subjectUris),\n this.labels(subjectUris),\n this.getExternalLabels(subjectUris, labelers),\n ])\n\n await Promise.all(\n Array.from(records.entries()).map(async ([uri, record]) => {\n const selfLabels = getSelfLabels({\n uri: record.uri,\n cid: record.cid,\n record: record.value,\n })\n\n const status = subjectStatusesResult.get(uri)\n const blobs = await this.blob(findBlobRefs(record.value))\n\n results.set(uri, {\n ...record,\n blobs,\n moderation: {\n ...record.moderation,\n subjectStatus: status\n ? this.formatSubjectStatus(status)\n : undefined,\n },\n labels: [\n ...(localLabels.get(uri) || []),\n ...selfLabels,\n ...(externalLabels.get(uri) || []),\n ],\n })\n }),\n )\n\n return results\n }\n\n async getExternalLabels(\n subjects: string[],\n labelers?: ParsedLabelers,\n ): Promise<Map<string, Label[]>> {\n const results = new Map<string, Label[]>()\n if (!labelers?.dids.length && !labelers?.redact.size) return results\n try {\n const {\n data: { labels },\n } = await this.appviewAgent.com.atproto.label.queryLabels({\n uriPatterns: subjects,\n sources: labelers.dids,\n })\n labels.forEach((label) => {\n if (!results.has(label.uri)) {\n results.set(label.uri, [label])\n return\n }\n results.get(label.uri)?.push(label)\n })\n return results\n } catch (err) {\n httpLogger.error(\n { err, subjects, labelers },\n 'failed to resolve labels from appview',\n )\n return results\n }\n }\n\n formatReport(report: ModerationEventRowWithHandle): ReportOutput {\n return {\n id: report.id,\n createdAt: report.createdAt,\n // Ideally, we would never have a report entry that does not have a reasonType but at the schema level\n // we are not guarantying that so in whatever case, if we end up with such entries, default to 'other'\n reasonType: report.meta?.reportType\n ? (report.meta?.reportType as string)\n : REASONOTHER,\n reason: report.comment ?? undefined,\n reportedBy: report.createdBy,\n subject: subjectFromEventRow(report).lex() as ReportOutput['subject'],\n }\n }\n // Partial view for subjects\n\n async subject(subject: string): Promise<SubjectView> {\n if (subject.startsWith('did:')) {\n const repos = await this.repos([subject])\n const repo = repos.get(subject)\n if (repo) {\n return {\n ...repo,\n $type: 'tools.ozone.moderation.defs#repoView',\n }\n } else {\n return {\n $type: 'tools.ozone.moderation.defs#repoViewNotFound',\n did: subject,\n }\n }\n } else {\n const records = await this.records([{ uri: subject }])\n const record = records.get(subject)\n if (record) {\n return {\n ...record,\n $type: 'tools.ozone.moderation.defs#recordView',\n }\n } else {\n return {\n $type: 'tools.ozone.moderation.defs#recordViewNotFound',\n uri: subject,\n }\n }\n }\n }\n\n // Partial view for blobs\n\n async blob(blobs: BlobRef[]): Promise<BlobView[]> {\n if (!blobs.length) return []\n const { ref } = this.db.db.dynamic\n const modStatusResults = await moderationSubjectStatusQueryBuilder(\n this.db.db,\n )\n .where(\n sql<string>`${ref(\n 'moderation_subject_status.blobCids',\n )} @> ${JSON.stringify(blobs.map((blob) => blob.ref.toString()))}`,\n )\n .executeTakeFirst()\n\n const statusByCid = (modStatusResults?.blobCids || [])?.reduce(\n (acc, cur) => Object.assign(acc, { [cur]: modStatusResults }),\n {},\n )\n // Intentionally missing details field, since we don't have any on appview.\n // We also don't know when the blob was created, so we use a canned creation time.\n const unknownTime = new Date(0).toISOString()\n return blobs.map((blob) => {\n const cid = blob.ref.toString()\n const subjectStatus = statusByCid[cid]\n ? this.formatSubjectStatus(statusByCid[cid])\n : undefined\n\n return {\n cid,\n mimeType: blob.mimeType,\n size: blob.size,\n createdAt: unknownTime,\n moderation: {\n subjectStatus,\n },\n }\n })\n }\n\n async labels(\n subjects: string[],\n includeNeg?: boolean,\n ): Promise<Map<string, Label[]>> {\n const now = new Date().toISOString()\n const labels = new Map<string, Label[]>()\n const res = await this.db.db\n .selectFrom('label')\n .where('label.uri', 'in', subjects)\n .where((qb) =>\n qb.where('label.exp', 'is', null).orWhere('label.exp', '>', now),\n )\n .if(!includeNeg, (qb) => qb.where('neg', '=', false))\n .selectAll()\n .execute()\n\n await Promise.all(\n res.map(async (labelRow) => {\n const signedLabel = await this.formatLabelAndEnsureSig(labelRow)\n\n const current = labels.get(labelRow.uri)\n if (current) current.push(signedLabel)\n else labels.set(labelRow.uri, [signedLabel])\n }),\n )\n return labels\n }\n\n async formatLabelAndEnsureSig(row: LabelRow) {\n const formatted = formatLabel(row)\n if (!!row.sig && row.signingKeyId === this.signingKeyId) {\n return formatted\n }\n const signed = await signLabel(formatted, this.signingKey)\n try {\n await this.db.db\n .updateTable('label')\n .set({ sig: Buffer.from(signed.sig), signingKeyId: this.signingKeyId })\n .where('id', '=', row.id)\n .execute()\n } catch (err) {\n dbLogger.error({ err, label: row }, 'failed to update resigned label')\n }\n return signed\n }\n\n async getSubjectStatus(\n subjects: string[],\n ): Promise<Map<string, ModerationSubjectStatusRowWithHandle>> {\n if (!subjects.length) return new Map()\n\n const parsedSubjects = subjects.map(parseSubjectId)\n\n const builder = moderationSubjectStatusQueryBuilder(this.db.db)\n //\n .where((qb) => {\n for (const sub of parsedSubjects) {\n qb = qb.orWhere((qb) =>\n qb\n .where('moderation_subject_status.did', '=', sub.did)\n .where(\n 'moderation_subject_status.recordPath',\n '=',\n sub.recordPath ?? '',\n ),\n )\n }\n return qb\n })\n\n const [statusRes, accountsByDid] = await Promise.all([\n builder.execute(),\n this.getAccoutInfosByDid(parsedSubjects.map((s) => s.did)),\n ])\n\n return new Map(\n statusRes.map((row): [string, ModerationSubjectStatusRowWithHandle] => {\n const subjectId = formatSubjectId(row.did, row.recordPath)\n const handle = accountsByDid.get(row.did)?.handle ?? INVALID_HANDLE\n return [subjectId, { ...row, handle }]\n }),\n )\n }\n\n formatSubjectStatus(\n status: ModerationSubjectStatusRowWithHandle,\n ): SubjectStatusView {\n const statusView: SubjectStatusView = {\n id: status.id,\n reviewState: status.reviewState,\n createdAt: status.createdAt,\n updatedAt: status.updatedAt,\n comment: status.comment ?? undefined,\n lastReviewedBy: status.lastReviewedBy ?? undefined,\n lastReviewedAt: status.lastReviewedAt ?? undefined,\n lastReportedAt: status.lastReportedAt ?? undefined,\n lastAppealedAt: status.lastAppealedAt ?? undefined,\n muteUntil: status.muteUntil ?? undefined,\n muteReportingUntil: status.muteReportingUntil ?? undefined,\n suspendUntil: status.suspendUntil ?? undefined,\n takendown: status.takendown ?? undefined,\n appealed: status.appealed ?? undefined,\n subjectRepoHandle: status.handle ?? undefined,\n subjectBlobCids: status.blobCids || [],\n tags: status.tags || [],\n priorityScore: status.priorityScore,\n ageAssuranceState: status.ageAssuranceState ?? undefined,\n ageAssuranceUpdatedBy: status.ageAssuranceUpdatedBy ?? undefined,\n subject: subjectFromStatusRow(\n status,\n ).lex() as SubjectStatusView['subject'],\n\n accountStats: {\n // Explicitly typing to allow for easy manipulation (e.g. to strip from tests snapshots)\n $type: 'tools.ozone.moderation.defs#accountStats',\n\n // account_events_stats\n reportCount: status.reportCount ?? undefined,\n appealCount: status.appealCount ?? undefined,\n suspendCount: status.suspendCount ?? undefined,\n takedownCount: status.takedownCount ?? undefined,\n escalateCount: status.escalateCount ?? undefined,\n },\n\n recordsStats: {\n // Explicitly typing to allow for easy manipulation (e.g. to strip from tests snapshots)\n $type: 'tools.ozone.moderation.defs#recordsStats',\n\n // account_record_events_stats\n totalReports: status.totalReports ?? undefined,\n reportedCount: status.reportedCount ?? undefined,\n escalatedCount: status.escalatedCount ?? undefined,\n appealedCount: status.appealedCount ?? undefined,\n\n // account_record_status_stats\n subjectCount: status.subjectCount ?? undefined,\n pendingCount: status.pendingCount ?? undefined,\n processedCount: status.processedCount ?? undefined,\n takendownCount: status.takendownCount ?? undefined,\n },\n }\n\n if (status.recordPath !== '') {\n statusView.hosting = {\n $type: 'tools.ozone.moderation.defs#recordHosting',\n updatedAt: status.hostingUpdatedAt ?? undefined,\n deletedAt: status.hostingDeletedAt ?? undefined,\n status: status.hostingStatus ?? 'unknown',\n }\n } else {\n statusView.hosting = {\n $type: 'tools.ozone.moderation.defs#accountHosting',\n updatedAt: status.hostingUpdatedAt ?? undefined,\n deletedAt: status.hostingDeletedAt ?? undefined,\n status: status.hostingStatus ?? 'unknown',\n deactivatedAt: status.hostingDeactivatedAt ?? undefined,\n reactivatedAt: status.hostingReactivatedAt ?? undefined,\n }\n }\n\n return statusView\n }\n\n async fetchAuthorFeed(actor: string): Promise<FeedViewPost[]> {\n const auth = await this.appviewAuth(ids.AppBskyFeedGetAuthorFeed)\n if (!auth) return []\n const {\n data: { feed },\n } = await this.appviewAgent.app.bsky.feed.getAuthorFeed({ actor }, auth)\n\n return feed\n }\n\n async getProfiles(dids: string[]) {\n const profiles = new Map<string, AppBskyActorDefs.ProfileViewDetailed>()\n\n const auth = await this.appviewAuth(ids.AppBskyActorGetProfiles)\n if (!auth) return profiles\n\n for (const actors of chunkArray(dids, 25)) {\n const { data } = await this.appviewAgent.getProfiles({ actors }, auth)\n\n data.profiles.forEach((profile) => {\n profiles.set(profile.did, profile)\n })\n }\n\n return profiles\n }\n}\n\ntype RecordSubject = { uri: string; cid?: string }\n\ntype SubjectView = ModEventViewDetail['subject']\n// @TODO tidy\n// type SubjectView = ModEventViewDetail['subject'] & ReportViewDetail['subject']\n\ntype RecordInfo = {\n uri: string\n cid: string\n value: Record<string, unknown>\n indexedAt: string\n}\n\nfunction parseSubjectId(subject: string): { did: string; recordPath?: string } {\n if (subject.startsWith('did:')) {\n return { did: subject }\n }\n const uri = new AtUri(subject)\n return { did: uri.hostname, recordPath: `${uri.collection}/${uri.rkey}` }\n}\n\nfunction formatSubjectId(did: string, recordPath?: string) {\n return recordPath ? `at://${did}/${recordPath}` : did\n}\n\nfunction findBlobRefs(value: unknown, refs: BlobRef[] = []) {\n if (value instanceof BlobRef) {\n refs.push(value)\n } else if (Array.isArray(value)) {\n value.forEach((val) => findBlobRefs(val, refs))\n } else if (value && typeof value === 'object') {\n Object.values(value).forEach((val) => findBlobRefs(val, refs))\n }\n return refs\n}\n\nexport function getSelfLabels(details: {\n uri: string | null\n cid: string | null\n record: Record<string, unknown> | null\n}): Label[] {\n const { uri, cid, record } = details\n if (!uri || !cid || !record) return []\n if (!isValidSelfLabels(record.labels)) return []\n const src = new AtUri(uri).host // record creator\n const cts =\n typeof record.createdAt === 'string'\n ? normalizeDatetimeAlways(record.createdAt)\n : new Date(0).toISOString()\n return record.labels.values.map(({ val }) => {\n return { src, uri, cid, val, cts }\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"views.js","sourceRoot":"","sources":["../../src/mod-service/views.ts"],"names":[],"mappings":";;;AAu1BA,sCAgBC;AAv2BD,mCAA4B;AAC5B,sCAIqB;AACrB,4CAAwD;AAGxD,8CAA0C;AAC1C,4CAAgF;AAGhF,kDAAyC;AAGzC,kEAGgD;AAEhD,uEAA0E;AAC1E,uEA0BqD;AACrD,0CAAuD;AACvD,sCAAgD;AAEhD,qCAA8D;AAC9D,uCAAqE;AAKrE,iCAAmE;AAEnE,MAAM,iBAAiB,GAAG,IAAA,kBAAW,EAAC,yBAAkB,CAAC,CAAA;AAEzD,MAAM,QAAQ,GAAG,CAAC,GAAY,EAAsB,EAAE,CACpD,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAA;AAC3C,MAAM,SAAS,GAAG,CAAC,GAAY,EAAuB,EAAE,CACtD,OAAO,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAA;AAC5C,MAAM,QAAQ,GAAG,CAAC,GAAY,EAAsB,EAAE,CACpD,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAA;AAS3C,MAAa,eAAe;IAC1B,YACU,EAAY,EACZ,UAAmB,EACnB,YAAoB,EACpB,YAAsB,EACtB,WAAqD,EACtD,UAAsB,EACtB,OAAiB;QANxB;;;;mBAAQ,EAAE;WAAU;QACpB;;;;mBAAQ,UAAU;WAAS;QAC3B;;;;mBAAQ,YAAY;WAAQ;QAC5B;;;;mBAAQ,YAAY;WAAU;QAC9B;;;;mBAAQ,WAAW;WAA0C;QAC7D;;;;mBAAO,UAAU;WAAY;QAC7B;;;;mBAAO,OAAO;WAAU;IACvB,CAAC;IAEJ,KAAK,CAAC,mBAAmB,CAAC,IAAc;QACtC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,GAAG,EAAE,CAAA;QACvC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,cAAG,CAAC,8BAA8B,CAAC,CAAA;QACvE,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,GAAG,EAAE,CAAA;QAC3B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CACnE;gBACE,IAAI,EAAE,IAAA,mBAAU,EAAC,IAAI,CAAC;aACvB,EACD,IAAI,CACL,CAAA;YACD,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;gBACxC,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;YAC9B,CAAC,EAAE,IAAI,GAAG,EAAuB,CAAC,CAAA;QACpC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,mBAAU,CAAC,KAAK,CACd,EAAE,GAAG,EAAE,IAAI,EAAE,EACb,8CAA8C,CAC/C,CAAA;YACD,OAAO,IAAI,GAAG,EAAE,CAAA;QAClB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAc;QACxB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,GAAG,EAAE,CAAA;QACvC,MAAM,CAAC,KAAK,EAAE,eAAe,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACjD,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC;YAC9B,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;SAC5B,CAAC,CAAA;QAEF,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAC3B,IAAI,CAAC,IAAI;gBAAE,OAAO,GAAG,CAAA;YACrB,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACvC,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE;gBAClB,qCAAqC;gBACrC,GAAG;gBACH,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,EAAE;gBACzC,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,UAAU,EAAE;oBACV,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;iBACrE;aACF,CAAC,CAAA;QACJ,CAAC,EAAE,IAAI,GAAG,EAAoB,CAAC,CAAA;IACjC,CAAC;IAED,WAAW,CAAC,GAAiC;QAC3C,MAAM,SAAS,GAA2B;YACxC,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,KAAK,EAAE;gBACL,KAAK,EAAE,GAAG,CAAC,MAAM;gBACjB,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,SAAS;aAClC;YACD,OAAO,EAAE,IAAA,6BAAmB,EAAC,GAAG,CAAC,CAAC,GAAG,EAAE;YACvC,eAAe,EAAE,GAAG,CAAC,eAAe,IAAI,EAAE;YAC1C,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,aAAa,EAAE,GAAG,CAAC,aAAa,IAAI,SAAS;YAC7C,aAAa,EAAE,GAAG,CAAC,aAAa,IAAI,SAAS;YAC7C,OAAO,EAAE,GAAG,CAAC,OAAO;gBAClB,CAAC,CAAC;oBACE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI;oBACtB,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI;iBACvB;gBACH,CAAC,CAAC,SAAS;SACd,CAAA;QAED,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,CAAA;QAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,EAAE,CAAA;QAE3B,IACE,IAAA,6BAAsB,EAAC,KAAK,CAAC;YAC7B,IAAA,yBAAkB,EAAC,KAAK,CAAC;YACzB,IAAA,sBAAe,EAAC,KAAK,CAAC;YACtB,IAAA,qBAAc,EAAC,KAAK,CAAC,EACrB,CAAC;YACD,KAAK,CAAC,eAAe,GAAG,GAAG,CAAC,eAAe,IAAI,SAAS,CAAA;QAC1D,CAAC;QAED,IACE,CAAC,IAAA,yBAAkB,EAAC,KAAK,CAAC,IAAI,IAAA,4BAAqB,EAAC,KAAK,CAAC,CAAC;YAC3D,IAAI,CAAC,0BAA0B,EAC/B,CAAC;YACD,KAAK,CAAC,0BAA0B,GAAG,SAAS,CAC1C,IAAI,CAAC,0BAA0B,CAC/B,CAAA;QACJ,CAAC;QAED,IAAI,IAAA,8BAAuB,EAAC,KAAK,CAAC,EAAE,CAAC;YACnC,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,CAAA;QAClD,CAAC;QAED,IACE,IAAA,yBAAkB,EAAC,KAAK,CAAC;YACzB,IAAA,sBAAe,EAAC,KAAK,CAAC;YACtB,IAAA,gCAAyB,EAAC,KAAK,CAAC,EAChC,CAAC;YACD,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAClE,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAC3C,CAAC;YAED,KAAK,CAAC,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;YAC7C,KAAK,CAAC,aAAa,GAAG,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;YAEjD,IAAI,IAAA,yBAAkB,EAAC,KAAK,CAAC,IAAI,IAAA,sBAAe,EAAC,KAAK,CAAC,EAAE,CAAC;gBACxD,KAAK,CAAC,eAAe,GAAG,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;YACvD,CAAC;QACH,CAAC;QAED,IAAI,IAAA,sBAAe,EAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,KAAK,CAAC,eAAe,GAAG,GAAG,CAAC,eAAe,EAAE,MAAM;gBACjD,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC;gBAChC,CAAC,CAAC,EAAE,CAAA;YACN,KAAK,CAAC,eAAe,GAAG,GAAG,CAAC,eAAe,EAAE,MAAM;gBACjD,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC;gBAChC,CAAC,CAAC,EAAE,CAAA;QACR,CAAC;aAAM,IACL,IAAA,4BAAqB,EAAC,KAAK,CAAC;YAC5B,IAAA,yBAAkB,EAAC,KAAK,CAAC;YACzB,IAAA,yBAAkB,EAAC,KAAK,CAAC,EACzB,CAAC;YACD,sEAAsE;YACtE,8BAA8B;YAE9B,IAAI,GAAG,CAAC,eAAe,EAAE,MAAM,EAAE,CAAC;gBAChC,0BAA0B;gBAC1B,KAAK,CAAC,eAAe,GAAG,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YACxD,CAAC;YAED,IAAI,GAAG,CAAC,eAAe,EAAE,MAAM,EAAE,CAAC;gBAChC,0BAA0B;gBAC1B,KAAK,CAAC,eAAe,GAAG,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YACxD,CAAC;QACH,CAAC;QAED,IAAI,IAAA,uBAAgB,EAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,KAAK,CAAC,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC,eAAe,CAAA;YAC9C,KAAK,CAAC,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAE,CAAA;QAC/C,CAAC;QAED,IAAI,IAAA,sBAAe,EAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,KAAK,CAAC,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAE,CAAA;YACvC,KAAK,CAAC,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAE,CAAA;QACjD,CAAC;QAED,IAAI,IAAA,wBAAiB,EAAC,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC5C,KAAK,CAAC,MAAM,GAAG,IAAI,CAAA;QACrB,CAAC;QAED,IAAI,IAAA,oBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;YACzB,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,SAAS,IAAI,EAAE,CAAA;YAC/B,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,WAAW,IAAI,EAAE,CAAA;QACtC,CAAC;QAED,IAAI,IAAA,qBAAc,EAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAA;YAC5B,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAE,CAAA;YAC3C,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAE,CAAA;QACvC,CAAC;QAED,IAAI,IAAA,sBAAe,EAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAE,CAAA;YAC3C,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAE,CAAA;YACrC,KAAK,CAAC,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAE,CAAA;YACvC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAA;QACpC,CAAC;QAED,IAAI,IAAA,oBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;YACzB,KAAK,CAAC,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAE,CAAA;YAC7B,KAAK,CAAC,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAE,CAAA;YAC/B,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAE,CAAA;QAC7C,CAAC;QAED,IAAI,IAAA,0BAAmB,EAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAE,CAAA;YACrC,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAE,CAAA;YAC3C,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAE,CAAA;YAC3C,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YACpC,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YACpC,KAAK,CAAC,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;YAC5C,KAAK,CAAC,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAC9C,CAAC;QAED,IAAI,IAAA,kCAA2B,EAAC,KAAK,CAAC,EAAE,CAAC;YACvC,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAE,CAAA;QACvC,CAAC;QAED,IAAI,IAAA,8BAAuB,EAAC,KAAK,CAAC,EAAE,CAAC;YACnC,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YAC1C,KAAK,CAAC,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;YAChD,KAAK,CAAC,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QAClD,CAAC;QAED,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,KAAK,CAAC,WAAW,CACf,MAAoC;QAEpC,MAAM,SAAS,GACb,MAAM,CAAC,WAAW,KAAK,gCAAgC;YACrD,CAAC,CAAC,MAAM,CAAC,UAAU;YACnB,CAAC,CAAC,MAAM,CAAC,UAAU,CAAA;QACvB,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,CAAC,EAAE,EAAE,CAAC,CAAA;QAC9C,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;QAC1C,MAAM,QAAQ,GAAG,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QACtE,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,IAAI,CAClC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CACvB,SAAS,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CACxD,CACF,CAAA;QACD,OAAO;YACL,GAAG,SAAS;YACZ,OAAO;YACP,YAAY;SACb,CAAA;IACH,CAAC;IAED,KAAK,CAAC,WAAW,CACf,IAAc,EACd,QAAyB;QAEzB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAA;QAC3C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,OAAO,CAAA;QAChB,CAAC;QAED,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,cAAc,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC7D,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACjB,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvC,CAAC,CAAA;QAEF,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YAC1B,MAAM,MAAM,GAAG;gBACb,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;gBAC/B,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;aACnC,CAAA;YACD,MAAM,QAAQ,GAAG;gBACf,GAAG,IAAI;gBACP,MAAM;gBACN,UAAU,EAAE;oBACV,GAAG,IAAI,CAAC,UAAU;iBACnB;aACF,CAAA;YACD,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;QAC5B,CAAC,CAAC,CAAA;QAEF,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,KAAK,CAAC,WAAW,CACf,MAA2C,EAC3C,WAAwB;QAExB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAC/D,MAAM,EACN,WAAW,CACZ,CAAA;YACD,OAAO,MAAM,CAAA;QACf,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,6BAAuB,CAAC,mBAAmB,EAAE,CAAC;gBAC/D,+DAA+D;gBAC/D,IAAI,CAAC;oBACH,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAA,yBAAkB,EAClD,IAAI,CAAC,UAAU,EACf,MAAM,CAAC,IAAI,EACX,IAAI,CAAC,OAAO,CACb,CAAA;oBACD,IAAI,CAAC,QAAQ,EAAE,CAAC;wBACd,OAAO,IAAI,CAAA;oBACb,CAAC;oBAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;oBAChE,OAAO,MAAM,CAAA;gBACf,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,IAAI,CAAA;gBACb,CAAC;YACH,CAAC;YAED,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,QAAyB;QAEzB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,cAAG,CAAC,uBAAuB,CAAC,CAAA;QACvE,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,GAAG,EAAE,CAAA;QAElC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YAC7B,MAAM,GAAG,GAAG,IAAI,cAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAClC,MAAM,MAAM,GAAG;gBACb,IAAI,EAAE,GAAG,CAAC,QAAQ;gBAClB,UAAU,EAAE,GAAG,CAAC,UAAU;gBAC1B,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,GAAG,EAAE,OAAO,CAAC,GAAG;aACjB,CAAA;YACD,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;QAC9C,CAAC,CAAC,CACH,CAAA;QACD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YACjC,IAAI,CAAC,GAAG;gBAAE,OAAO,GAAG,CAAA;YACpB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAA;YACrB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;YAC1C,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAA;QACvE,CAAC,EAAE,IAAI,GAAG,EAAsB,CAAC,CAAA;IACnC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,QAAyB;QACrC,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,cAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;QAExC,MAAM,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC1D,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAChB,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACjD,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC;SAC5B,CAAC,CAAA;QAEF,MAAM,GAAG,GAAG,IAAI,GAAG,EAUhB,CAAA;QAEH,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YACpC,IAAI,CAAC,IAAI;gBAAE,SAAQ;YACnB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAA;YAC1C,IAAI,CAAC,MAAM;gBAAE,SAAQ;YACrB,MAAM,aAAa,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAA;YAEzD,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;gBACtB,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE;gBACnB,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,QAAQ,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;gBACvE,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,IAAI;gBACJ,UAAU,EAAE;oBACV,aAAa,EAAE,aAAa;wBAC1B,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,aAAa,CAAC;wBACzC,CAAC,CAAC,SAAS;iBACd;aACF,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,KAAK,CAAC,aAAa,CACjB,QAAyB,EACzB,QAAyB;QAEzB,MAAM,OAAO,GAAG,IAAI,GAAG,EAA4B,CAAA;QACnD,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACrB,OAAO,OAAO,CAAA;QAChB,CAAC;QAED,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAC9C,MAAM,CAAC,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,cAAc,CAAC,GACjE,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;YACtB,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC;YAClC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;YACxB,IAAI,CAAC,iBAAiB,CAAC,WAAW,EAAE,QAAQ,CAAC;SAC9C,CAAC,CAAA;QAEJ,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE;YACxD,MAAM,UAAU,GAAG,aAAa,CAAC;gBAC/B,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,MAAM,EAAE,MAAM,CAAC,KAAK;aACrB,CAAC,CAAA;YAEF,MAAM,MAAM,GAAG,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAC7C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;YAEzD,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE;gBACf,GAAG,MAAM;gBACT,KAAK;gBACL,UAAU,EAAE;oBACV,GAAG,MAAM,CAAC,UAAU;oBACpB,aAAa,EAAE,MAAM;wBACnB,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC;wBAClC,CAAC,CAAC,SAAS;iBACd;gBACD,MAAM,EAAE;oBACN,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;oBAC/B,GAAG,UAAU;oBACb,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;iBACnC;aACF,CAAC,CAAA;QACJ,CAAC,CAAC,CACH,CAAA;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,KAAK,CAAC,iBAAiB,CACrB,QAAkB,EAClB,QAAyB;QAEzB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAmB,CAAA;QAC1C,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI;YAAE,OAAO,OAAO,CAAA;QACpE,IAAI,CAAC;YACH,MAAM,EACJ,IAAI,EAAE,EAAE,MAAM,EAAE,GACjB,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC;gBACxD,WAAW,EAAE,QAAQ;gBACrB,OAAO,EAAE,QAAQ,CAAC,IAAI;aACvB,CAAC,CAAA;YACF,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;gBACvB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;oBAC/B,OAAM;gBACR,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;YACrC,CAAC,CAAC,CAAA;YACF,OAAO,OAAO,CAAA;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,mBAAU,CAAC,KAAK,CACd,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAC3B,uCAAuC,CACxC,CAAA;YACD,OAAO,OAAO,CAAA;QAChB,CAAC;IACH,CAAC;IAED,YAAY,CAAC,MAAoC;QAC/C,OAAO;YACL,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,sGAAsG;YACtG,sGAAsG;YACtG,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE,UAAU;gBACjC,CAAC,CAAE,MAAM,CAAC,IAAI,EAAE,UAAqB;gBACrC,CAAC,CAAC,kBAAW;YACf,MAAM,EAAE,MAAM,CAAC,OAAO,IAAI,SAAS;YACnC,UAAU,EAAE,MAAM,CAAC,SAAS;YAC5B,OAAO,EAAE,IAAA,6BAAmB,EAAC,MAAM,CAAC,CAAC,GAAG,EAA6B;SACtE,CAAA;IACH,CAAC;IACD,4BAA4B;IAE5B,KAAK,CAAC,OAAO,CAAC,OAAe;QAC3B,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAA;YACzC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YAC/B,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO;oBACL,GAAG,IAAI;oBACP,KAAK,EAAE,sCAAsC;iBAC9C,CAAA;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO;oBACL,KAAK,EAAE,8CAA8C;oBACrD,GAAG,EAAE,OAAO;iBACb,CAAA;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;YACtD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YACnC,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO;oBACL,GAAG,MAAM;oBACT,KAAK,EAAE,wCAAwC;iBAChD,CAAA;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO;oBACL,KAAK,EAAE,gDAAgD;oBACvD,GAAG,EAAE,OAAO;iBACb,CAAA;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,yBAAyB;IAEzB,KAAK,CAAC,IAAI,CAAC,KAAgB;QACzB,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO,EAAE,CAAA;QAC5B,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAA;QAClC,MAAM,gBAAgB,GAAG,MAAM,IAAA,4CAAmC,EAChE,IAAI,CAAC,EAAE,CAAC,EAAE,CACX;aACE,KAAK,CACJ,IAAA,YAAG,EAAQ,GAAG,GAAG,CACf,oCAAoC,CACrC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,CACnE;aACA,gBAAgB,EAAE,CAAA;QAErB,MAAM,WAAW,GAAG,CAAC,gBAAgB,EAAE,QAAQ,IAAI,EAAE,CAAC,EAAE,MAAM,CAC5D,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAC7D,EAAE,CACH,CAAA;QACD,2EAA2E;QAC3E,kFAAkF;QAClF,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;QAC7C,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACxB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAA;YAC/B,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,CAAC;gBACpC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;gBAC5C,CAAC,CAAC,SAAS,CAAA;YAEb,OAAO;gBACL,GAAG;gBACH,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,SAAS,EAAE,WAAW;gBACtB,UAAU,EAAE;oBACV,aAAa;iBACd;aACF,CAAA;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,MAAM,CACV,QAAkB,EAClB,UAAoB;QAEpB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QACpC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAmB,CAAA;QACzC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,EAAE;aACzB,UAAU,CAAC,OAAO,CAAC;aACnB,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,QAAQ,CAAC;aAClC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CACZ,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,EAAE,GAAG,CAAC,CACjE;aACA,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;aACpD,SAAS,EAAE;aACX,OAAO,EAAE,CAAA;QAEZ,MAAM,OAAO,CAAC,GAAG,CACf,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;YACzB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAA;YAEhE,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;YACxC,IAAI,OAAO;gBAAE,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;;gBACjC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;QAC9C,CAAC,CAAC,CACH,CAAA;QACD,OAAO,MAAM,CAAA;IACf,CAAC;IAED,KAAK,CAAC,uBAAuB,CAAC,GAAa;QACzC,MAAM,SAAS,GAAG,IAAA,kBAAW,EAAC,GAAG,CAAC,CAAA;QAClC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,YAAY,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YACxD,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAA,gBAAS,EAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;QAC1D,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,EAAE,CAAC,EAAE;iBACb,WAAW,CAAC,OAAO,CAAC;iBACpB,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC;iBACtE,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;iBACxB,OAAO,EAAE,CAAA;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,iBAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,iCAAiC,CAAC,CAAA;QACxE,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC;IAED,KAAK,CAAC,gBAAgB,CACpB,QAAkB;QAElB,IAAI,CAAC,QAAQ,CAAC,MAAM;YAAE,OAAO,IAAI,GAAG,EAAE,CAAA;QAEtC,MAAM,cAAc,GAAG,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;QAEnD,MAAM,OAAO,GAAG,IAAA,4CAAmC,EAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YAC7D,EAAE;aACD,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE;YACZ,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;gBACjC,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CACrB,EAAE;qBACC,KAAK,CAAC,+BAA+B,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC;qBACpD,KAAK,CACJ,sCAAsC,EACtC,GAAG,EACH,GAAG,CAAC,UAAU,IAAI,EAAE,CACrB,CACJ,CAAA;YACH,CAAC;YACD,OAAO,EAAE,CAAA;QACX,CAAC,CAAC,CAAA;QAEJ,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACnD,OAAO,CAAC,OAAO,EAAE;YACjB,IAAI,CAAC,mBAAmB,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;SAC3D,CAAC,CAAA;QAEF,OAAO,IAAI,GAAG,CACZ,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAkD,EAAE;YACpE,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,UAAU,CAAC,CAAA;YAC1D,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,uBAAc,CAAA;YACnE,OAAO,CAAC,SAAS,EAAE,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,CAAC,CAAA;QACxC,CAAC,CAAC,CACH,CAAA;IACH,CAAC;IAED,mBAAmB,CACjB,MAA4C;QAE5C,MAAM,UAAU,GAAsB;YACpC,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,SAAS;YACpC,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,SAAS;YAClD,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,SAAS;YAClD,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,SAAS;YAClD,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,SAAS;YAClD,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,SAAS;YACxC,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,IAAI,SAAS;YAC1D,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,SAAS;YAC9C,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,SAAS;YACxC,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,SAAS;YACtC,iBAAiB,EAAE,MAAM,CAAC,MAAM,IAAI,SAAS;YAC7C,eAAe,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE;YACtC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE;YACvB,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,IAAI,SAAS;YACxD,qBAAqB,EAAE,MAAM,CAAC,qBAAqB,IAAI,SAAS;YAChE,OAAO,EAAE,IAAA,8BAAoB,EAC3B,MAAM,CACP,CAAC,GAAG,EAAkC;YAEvC,YAAY,EAAE;gBACZ,wFAAwF;gBACxF,KAAK,EAAE,0CAA0C;gBAEjD,uBAAuB;gBACvB,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,SAAS;gBAC5C,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,SAAS;gBAC5C,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,SAAS;gBAC9C,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,SAAS;gBAChD,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,SAAS;aACjD;YAED,YAAY,EAAE;gBACZ,wFAAwF;gBACxF,KAAK,EAAE,0CAA0C;gBAEjD,8BAA8B;gBAC9B,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,SAAS;gBAC9C,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,SAAS;gBAChD,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,SAAS;gBAClD,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,SAAS;gBAEhD,8BAA8B;gBAC9B,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,SAAS;gBAC9C,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,SAAS;gBAC9C,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,SAAS;gBAClD,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,SAAS;aACnD;YAED,aAAa,EACX,MAAM,CAAC,WAAW,KAAK,IAAI,IAAI,MAAM,CAAC,gBAAgB,KAAK,IAAI;gBAC7D,CAAC,CAAC;oBACE,KAAK,EAAE,2CAA2C;oBAClD,iBAAiB,EAAE,MAAM,CAAC,WAAW,IAAI,SAAS;oBAClD,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,IAAI,SAAS;oBACtD,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,SAAS;oBAChD,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,SAAS;iBAC/C;gBACH,CAAC,CAAC,SAAS;SAChB,CAAA;QAED,IAAI,MAAM,CAAC,UAAU,KAAK,EAAE,EAAE,CAAC;YAC7B,UAAU,CAAC,OAAO,GAAG;gBACnB,KAAK,EAAE,2CAA2C;gBAClD,SAAS,EAAE,MAAM,CAAC,gBAAgB,IAAI,SAAS;gBAC/C,SAAS,EAAE,MAAM,CAAC,gBAAgB,IAAI,SAAS;gBAC/C,MAAM,EAAE,MAAM,CAAC,aAAa,IAAI,SAAS;aAC1C,CAAA;QACH,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,OAAO,GAAG;gBACnB,KAAK,EAAE,4CAA4C;gBACnD,SAAS,EAAE,MAAM,CAAC,gBAAgB,IAAI,SAAS;gBAC/C,SAAS,EAAE,MAAM,CAAC,gBAAgB,IAAI,SAAS;gBAC/C,MAAM,EAAE,MAAM,CAAC,aAAa,IAAI,SAAS;gBACzC,aAAa,EAAE,MAAM,CAAC,oBAAoB,IAAI,SAAS;gBACvD,aAAa,EAAE,MAAM,CAAC,oBAAoB,IAAI,SAAS;aACxD,CAAA;QACH,CAAC;QAED,OAAO,UAAU,CAAA;IACnB,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,KAAa;QACjC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,cAAG,CAAC,wBAAwB,CAAC,CAAA;QACjE,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAA;QACpB,MAAM,EACJ,IAAI,EAAE,EAAE,IAAI,EAAE,GACf,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,CAAA;QAExE,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,IAAc;QAC9B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAgD,CAAA;QAExE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,cAAG,CAAC,uBAAuB,CAAC,CAAA;QAChE,IAAI,CAAC,IAAI;YAAE,OAAO,QAAQ,CAAA;QAE1B,KAAK,MAAM,MAAM,IAAI,IAAA,mBAAU,EAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;YAC1C,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,CAAA;YAEtE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBAChC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;YACpC,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,QAAQ,CAAA;IACjB,CAAC;CACF;AAruBD,0CAquBC;AAeD,SAAS,cAAc,CAAC,OAAe;IACrC,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAA;IACzB,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,cAAK,CAAC,OAAO,CAAC,CAAA;IAC9B,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,IAAI,EAAE,EAAE,CAAA;AAC3E,CAAC;AAED,SAAS,eAAe,CAAC,GAAW,EAAE,UAAmB;IACvD,OAAO,UAAU,CAAC,CAAC,CAAC,QAAQ,GAAG,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,GAAG,CAAA;AACvD,CAAC;AAED,SAAS,YAAY,CAAC,KAAc,EAAE,OAAkB,EAAE;IACxD,IAAI,KAAK,YAAY,iBAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAClB,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAA;IACjD,CAAC;SAAM,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAA;IAChE,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAgB,aAAa,CAAC,OAI7B;IACC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAA;IACpC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAA;IACtC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAA;IAChD,MAAM,GAAG,GAAG,IAAI,cAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAA,CAAC,iBAAiB;IACjD,MAAM,GAAG,GACP,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ;QAClC,CAAC,CAAC,IAAA,gCAAuB,EAAC,MAAM,CAAC,SAAS,CAAC;QAC3C,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;IAC/B,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;QAC1C,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAA;IACpC,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { sql } from 'kysely'\nimport {\n AppBskyActorDefs,\n AtpAgent,\n ComAtprotoRepoGetRecord,\n} from '@atproto/api'\nimport { chunkArray, dedupeStrs } from '@atproto/common'\nimport { Keypair } from '@atproto/crypto'\nimport { IdResolver } from '@atproto/identity'\nimport { BlobRef } from '@atproto/lexicon'\nimport { AtUri, INVALID_HANDLE, normalizeDatetimeAlways } from '@atproto/syntax'\nimport { Database } from '../db'\nimport { LabelRow } from '../db/schema/label'\nimport { ids } from '../lexicon/lexicons'\nimport { FeedViewPost } from '../lexicon/types/app/bsky/feed/defs'\nimport { AccountView } from '../lexicon/types/com/atproto/admin/defs'\nimport {\n Label,\n validateSelfLabels,\n} from '../lexicon/types/com/atproto/label/defs'\nimport { OutputSchema as ReportOutput } from '../lexicon/types/com/atproto/moderation/createReport'\nimport { REASONOTHER } from '../lexicon/types/com/atproto/moderation/defs'\nimport {\n BlobView,\n ModEventView,\n ModEventViewDetail,\n RecordView,\n RecordViewDetail,\n RepoView,\n SubjectStatusView,\n isAccountEvent,\n isAgeAssuranceEvent,\n isAgeAssuranceOverrideEvent,\n isIdentityEvent,\n isModEventAcknowledge,\n isModEventComment,\n isModEventEmail,\n isModEventEscalate,\n isModEventLabel,\n isModEventMute,\n isModEventMuteReporter,\n isModEventPriorityScore,\n isModEventReport,\n isModEventReverseTakedown,\n isModEventTag,\n isModEventTakedown,\n isRecordEvent,\n isScheduleTakedownEvent,\n} from '../lexicon/types/tools/ozone/moderation/defs'\nimport { Un$Typed, asPredicate } from '../lexicon/util'\nimport { dbLogger, httpLogger } from '../logger'\nimport { ParsedLabelers } from '../util'\nimport { moderationSubjectStatusQueryBuilder } from './status'\nimport { subjectFromEventRow, subjectFromStatusRow } from './subject'\nimport {\n ModerationEventRowWithHandle,\n ModerationSubjectStatusRowWithHandle,\n} from './types'\nimport { formatLabel, getPdsAgentForRepo, signLabel } from './util'\n\nconst isValidSelfLabels = asPredicate(validateSelfLabels)\n\nconst ifString = (val: unknown): string | undefined =>\n typeof val === 'string' ? val : undefined\nconst ifBoolean = (val: unknown): boolean | undefined =>\n typeof val === 'boolean' ? val : undefined\nconst ifNumber = (val: unknown): number | undefined =>\n typeof val === 'number' ? val : undefined\n\nexport type AuthHeaders = {\n headers: {\n authorization: string\n 'atproto-accept-labelers'?: string\n }\n}\n\nexport class ModerationViews {\n constructor(\n private db: Database,\n private signingKey: Keypair,\n private signingKeyId: number,\n private appviewAgent: AtpAgent,\n private appviewAuth: (method: string) => Promise<AuthHeaders>,\n public idResolver: IdResolver,\n public devMode?: boolean,\n ) {}\n\n async getAccoutInfosByDid(dids: string[]): Promise<Map<string, AccountView>> {\n if (dids.length === 0) return new Map()\n const auth = await this.appviewAuth(ids.ComAtprotoAdminGetAccountInfos)\n if (!auth) return new Map()\n try {\n const res = await this.appviewAgent.com.atproto.admin.getAccountInfos(\n {\n dids: dedupeStrs(dids),\n },\n auth,\n )\n return res.data.infos.reduce((acc, cur) => {\n return acc.set(cur.did, cur)\n }, new Map<string, AccountView>())\n } catch (err) {\n httpLogger.error(\n { err, dids },\n 'failed to resolve account infos from appview',\n )\n return new Map()\n }\n }\n\n async repos(dids: string[]): Promise<Map<string, RepoView>> {\n if (dids.length === 0) return new Map()\n const [infos, subjectStatuses] = await Promise.all([\n this.getAccoutInfosByDid(dids),\n this.getSubjectStatus(dids),\n ])\n\n return dids.reduce((acc, did) => {\n const info = infos.get(did)\n if (!info) return acc\n const status = subjectStatuses.get(did)\n return acc.set(did, {\n // No email or invite info on appview\n did,\n handle: info.handle,\n relatedRecords: info.relatedRecords ?? [],\n indexedAt: info.indexedAt,\n moderation: {\n subjectStatus: status ? this.formatSubjectStatus(status) : undefined,\n },\n })\n }, new Map<string, RepoView>())\n }\n\n formatEvent(row: ModerationEventRowWithHandle): Un$Typed<ModEventView> {\n const eventView: Un$Typed<ModEventView> = {\n id: row.id,\n event: {\n $type: row.action,\n comment: row.comment ?? undefined,\n },\n subject: subjectFromEventRow(row).lex(),\n subjectBlobCids: row.subjectBlobCids ?? [],\n createdBy: row.createdBy,\n createdAt: row.createdAt,\n subjectHandle: row.subjectHandle ?? undefined,\n creatorHandle: row.creatorHandle ?? undefined,\n modTool: row.modTool\n ? {\n name: row.modTool.name,\n meta: row.modTool.meta,\n }\n : undefined,\n }\n\n const { event } = eventView\n const meta = row.meta || {}\n\n if (\n isModEventMuteReporter(event) ||\n isModEventTakedown(event) ||\n isModEventLabel(event) ||\n isModEventMute(event)\n ) {\n event.durationInHours = row.durationInHours ?? undefined\n }\n\n if (\n (isModEventTakedown(event) || isModEventAcknowledge(event)) &&\n meta.acknowledgeAccountSubjects\n ) {\n event.acknowledgeAccountSubjects = ifBoolean(\n meta.acknowledgeAccountSubjects,\n )!\n }\n\n if (isModEventPriorityScore(event)) {\n event.score = ifNumber(meta?.priorityScore) ?? 0\n }\n\n if (\n isModEventTakedown(event) ||\n isModEventEmail(event) ||\n isModEventReverseTakedown(event)\n ) {\n if (typeof meta.policies === 'string' && meta.policies.length > 0) {\n event.policies = meta.policies.split(',')\n }\n\n event.strikeCount = ifNumber(row.strikeCount)\n event.severityLevel = ifString(row.severityLevel)\n\n if (isModEventTakedown(event) || isModEventEmail(event)) {\n event.strikeExpiresAt = ifString(row.strikeExpiresAt)\n }\n }\n\n if (isModEventLabel(event)) {\n event.createLabelVals = row.createLabelVals?.length\n ? row.createLabelVals.split(' ')\n : []\n event.negateLabelVals = row.negateLabelVals?.length\n ? row.negateLabelVals.split(' ')\n : []\n } else if (\n isModEventAcknowledge(event) ||\n isModEventTakedown(event) ||\n isModEventEscalate(event)\n ) {\n // This is for legacy data only, for new events, these types of events\n // won't have labels attached:\n\n if (row.createLabelVals?.length) {\n // @ts-expect-error legacy\n event.createLabelVals = row.createLabelVals.split(' ')\n }\n\n if (row.negateLabelVals?.length) {\n // @ts-expect-error legacy\n event.negateLabelVals = row.negateLabelVals.split(' ')\n }\n }\n\n if (isModEventReport(event)) {\n event.isReporterMuted = !!meta.isReporterMuted\n event.reportType = ifString(meta.reportType)!\n }\n\n if (isModEventEmail(event)) {\n event.content = ifString(meta.content)!\n event.subjectLine = ifString(meta.subjectLine)!\n }\n\n if (isModEventComment(event) && meta.sticky) {\n event.sticky = true\n }\n\n if (isModEventTag(event)) {\n event.add = row.addedTags || []\n event.remove = row.removedTags || []\n }\n\n if (isAccountEvent(event)) {\n event.active = !!meta.active\n event.timestamp = ifString(meta.timestamp)!\n event.status = ifString(meta.status)!\n }\n\n if (isIdentityEvent(event)) {\n event.timestamp = ifString(meta.timestamp)!\n event.handle = ifString(meta.handle)!\n event.pdsHost = ifString(meta.pdsHost)!\n event.tombstone = !!meta.tombstone\n }\n\n if (isRecordEvent(event)) {\n event.op = ifString(meta.op)!\n event.cid = ifString(meta.cid)!\n event.timestamp = ifString(meta.timestamp)!\n }\n\n if (isAgeAssuranceEvent(event)) {\n event.status = ifString(meta.status)!\n event.createdAt = ifString(meta.createdAt)!\n event.attemptId = ifString(meta.attemptId)!\n event.initIp = ifString(meta.initIp)\n event.initUa = ifString(meta.initUa)\n event.completeIp = ifString(meta.completeIp)\n event.completeUa = ifString(meta.completeUa)\n }\n\n if (isAgeAssuranceOverrideEvent(event)) {\n event.status = ifString(meta.status)!\n }\n\n if (isScheduleTakedownEvent(event)) {\n event.executeAt = ifString(meta.executeAt)\n event.executeAfter = ifString(meta.executeAfter)\n event.executeUntil = ifString(meta.executeUntil)\n }\n\n return eventView\n }\n\n async eventDetail(\n result: ModerationEventRowWithHandle,\n ): Promise<ModEventViewDetail> {\n const subjectId =\n result.subjectType === 'com.atproto.admin.defs#repoRef'\n ? result.subjectDid\n : result.subjectUri\n if (!subjectId) {\n throw new Error(`Bad subject: ${result.id}`)\n }\n const subject = await this.subject(subjectId)\n const eventView = this.formatEvent(result)\n const allBlobs = 'value' in subject ? findBlobRefs(subject.value) : []\n const subjectBlobs = await this.blob(\n allBlobs.filter((blob) =>\n eventView.subjectBlobCids.includes(blob.ref.toString()),\n ),\n )\n return {\n ...eventView,\n subject,\n subjectBlobs,\n }\n }\n\n async repoDetails(\n dids: string[],\n labelers?: ParsedLabelers,\n ): Promise<Map<string, RepoView>> {\n const results = new Map<string, RepoView>()\n if (!dids.length) {\n return results\n }\n\n const [repos, localLabels, externalLabels] = await Promise.all([\n this.repos(dids),\n this.labels(dids),\n this.getExternalLabels(dids, labelers),\n ])\n\n repos.forEach((repo, did) => {\n const labels = [\n ...(localLabels.get(did) || []),\n ...(externalLabels.get(did) || []),\n ]\n const repoView = {\n ...repo,\n labels,\n moderation: {\n ...repo.moderation,\n },\n }\n results.set(did, repoView)\n })\n\n return results\n }\n\n async fetchRecord(\n params: ComAtprotoRepoGetRecord.QueryParams,\n appviewAuth: AuthHeaders,\n ) {\n try {\n const record = await this.appviewAgent.com.atproto.repo.getRecord(\n params,\n appviewAuth,\n )\n return record\n } catch (err) {\n if (err instanceof ComAtprotoRepoGetRecord.RecordNotFoundError) {\n // If pds fetch fails, just return null regardless of the error\n try {\n const { agent: pdsAgent } = await getPdsAgentForRepo(\n this.idResolver,\n params.repo,\n this.devMode,\n )\n if (!pdsAgent) {\n return null\n }\n\n const record = await pdsAgent.com.atproto.repo.getRecord(params)\n return record\n } catch (error) {\n return null\n }\n }\n\n return null\n }\n }\n\n async fetchRecords(\n subjects: RecordSubject[],\n ): Promise<Map<string, RecordInfo>> {\n const appviewAuth = await this.appviewAuth(ids.ComAtprotoRepoGetRecord)\n if (!appviewAuth) return new Map()\n\n const fetched = await Promise.all(\n subjects.map(async (subject) => {\n const uri = new AtUri(subject.uri)\n const params = {\n repo: uri.hostname,\n collection: uri.collection,\n rkey: uri.rkey,\n cid: subject.cid,\n }\n return this.fetchRecord(params, appviewAuth)\n }),\n )\n return fetched.reduce((acc, cur) => {\n if (!cur) return acc\n const data = cur.data\n const indexedAt = new Date().toISOString()\n return acc.set(data.uri, { ...data, cid: data.cid ?? '', indexedAt })\n }, new Map<string, RecordInfo>())\n }\n\n async records(subjects: RecordSubject[]) {\n const uris = subjects.map((record) => new AtUri(record.uri))\n const dids = uris.map((u) => u.hostname)\n\n const [repos, subjectStatuses, records] = await Promise.all([\n this.repos(dids),\n this.getSubjectStatus(subjects.map((s) => s.uri)),\n this.fetchRecords(subjects),\n ])\n\n const map = new Map<\n string,\n // Because the result of this function is used to build RecordViewDetail,\n // we explicitly type the result without the $type field, so can be used\n // as both RecordView and RecordViewDetail, without having to cast or\n // override the $type field.\n RecordView & {\n $type?: undefined\n moderation: { $type?: undefined; subjectStatus?: SubjectStatusView }\n }\n >()\n\n for (const uri of uris) {\n const repo = repos.get(uri.hostname)\n if (!repo) continue\n const record = records.get(uri.toString())\n if (!record) continue\n const subjectStatus = subjectStatuses.get(uri.toString())\n\n map.set(uri.toString(), {\n uri: uri.toString(),\n cid: record.cid,\n value: record.value,\n blobCids: findBlobRefs(record.value).map((blob) => blob.ref.toString()),\n indexedAt: record.indexedAt,\n repo,\n moderation: {\n subjectStatus: subjectStatus\n ? this.formatSubjectStatus(subjectStatus)\n : undefined,\n },\n })\n }\n\n return map\n }\n\n async recordDetails(\n subjects: RecordSubject[],\n labelers?: ParsedLabelers,\n ): Promise<Map<string, RecordViewDetail>> {\n const results = new Map<string, RecordViewDetail>()\n if (!subjects.length) {\n return results\n }\n\n const subjectUris = subjects.map((s) => s.uri)\n const [records, subjectStatusesResult, localLabels, externalLabels] =\n await Promise.all([\n this.records(subjects),\n this.getSubjectStatus(subjectUris),\n this.labels(subjectUris),\n this.getExternalLabels(subjectUris, labelers),\n ])\n\n await Promise.all(\n Array.from(records.entries()).map(async ([uri, record]) => {\n const selfLabels = getSelfLabels({\n uri: record.uri,\n cid: record.cid,\n record: record.value,\n })\n\n const status = subjectStatusesResult.get(uri)\n const blobs = await this.blob(findBlobRefs(record.value))\n\n results.set(uri, {\n ...record,\n blobs,\n moderation: {\n ...record.moderation,\n subjectStatus: status\n ? this.formatSubjectStatus(status)\n : undefined,\n },\n labels: [\n ...(localLabels.get(uri) || []),\n ...selfLabels,\n ...(externalLabels.get(uri) || []),\n ],\n })\n }),\n )\n\n return results\n }\n\n async getExternalLabels(\n subjects: string[],\n labelers?: ParsedLabelers,\n ): Promise<Map<string, Label[]>> {\n const results = new Map<string, Label[]>()\n if (!labelers?.dids.length && !labelers?.redact.size) return results\n try {\n const {\n data: { labels },\n } = await this.appviewAgent.com.atproto.label.queryLabels({\n uriPatterns: subjects,\n sources: labelers.dids,\n })\n labels.forEach((label) => {\n if (!results.has(label.uri)) {\n results.set(label.uri, [label])\n return\n }\n results.get(label.uri)?.push(label)\n })\n return results\n } catch (err) {\n httpLogger.error(\n { err, subjects, labelers },\n 'failed to resolve labels from appview',\n )\n return results\n }\n }\n\n formatReport(report: ModerationEventRowWithHandle): ReportOutput {\n return {\n id: report.id,\n createdAt: report.createdAt,\n // Ideally, we would never have a report entry that does not have a reasonType but at the schema level\n // we are not guarantying that so in whatever case, if we end up with such entries, default to 'other'\n reasonType: report.meta?.reportType\n ? (report.meta?.reportType as string)\n : REASONOTHER,\n reason: report.comment ?? undefined,\n reportedBy: report.createdBy,\n subject: subjectFromEventRow(report).lex() as ReportOutput['subject'],\n }\n }\n // Partial view for subjects\n\n async subject(subject: string): Promise<SubjectView> {\n if (subject.startsWith('did:')) {\n const repos = await this.repos([subject])\n const repo = repos.get(subject)\n if (repo) {\n return {\n ...repo,\n $type: 'tools.ozone.moderation.defs#repoView',\n }\n } else {\n return {\n $type: 'tools.ozone.moderation.defs#repoViewNotFound',\n did: subject,\n }\n }\n } else {\n const records = await this.records([{ uri: subject }])\n const record = records.get(subject)\n if (record) {\n return {\n ...record,\n $type: 'tools.ozone.moderation.defs#recordView',\n }\n } else {\n return {\n $type: 'tools.ozone.moderation.defs#recordViewNotFound',\n uri: subject,\n }\n }\n }\n }\n\n // Partial view for blobs\n\n async blob(blobs: BlobRef[]): Promise<BlobView[]> {\n if (!blobs.length) return []\n const { ref } = this.db.db.dynamic\n const modStatusResults = await moderationSubjectStatusQueryBuilder(\n this.db.db,\n )\n .where(\n sql<string>`${ref(\n 'moderation_subject_status.blobCids',\n )} @> ${JSON.stringify(blobs.map((blob) => blob.ref.toString()))}`,\n )\n .executeTakeFirst()\n\n const statusByCid = (modStatusResults?.blobCids || [])?.reduce(\n (acc, cur) => Object.assign(acc, { [cur]: modStatusResults }),\n {},\n )\n // Intentionally missing details field, since we don't have any on appview.\n // We also don't know when the blob was created, so we use a canned creation time.\n const unknownTime = new Date(0).toISOString()\n return blobs.map((blob) => {\n const cid = blob.ref.toString()\n const subjectStatus = statusByCid[cid]\n ? this.formatSubjectStatus(statusByCid[cid])\n : undefined\n\n return {\n cid,\n mimeType: blob.mimeType,\n size: blob.size,\n createdAt: unknownTime,\n moderation: {\n subjectStatus,\n },\n }\n })\n }\n\n async labels(\n subjects: string[],\n includeNeg?: boolean,\n ): Promise<Map<string, Label[]>> {\n const now = new Date().toISOString()\n const labels = new Map<string, Label[]>()\n const res = await this.db.db\n .selectFrom('label')\n .where('label.uri', 'in', subjects)\n .where((qb) =>\n qb.where('label.exp', 'is', null).orWhere('label.exp', '>', now),\n )\n .if(!includeNeg, (qb) => qb.where('neg', '=', false))\n .selectAll()\n .execute()\n\n await Promise.all(\n res.map(async (labelRow) => {\n const signedLabel = await this.formatLabelAndEnsureSig(labelRow)\n\n const current = labels.get(labelRow.uri)\n if (current) current.push(signedLabel)\n else labels.set(labelRow.uri, [signedLabel])\n }),\n )\n return labels\n }\n\n async formatLabelAndEnsureSig(row: LabelRow) {\n const formatted = formatLabel(row)\n if (!!row.sig && row.signingKeyId === this.signingKeyId) {\n return formatted\n }\n const signed = await signLabel(formatted, this.signingKey)\n try {\n await this.db.db\n .updateTable('label')\n .set({ sig: Buffer.from(signed.sig), signingKeyId: this.signingKeyId })\n .where('id', '=', row.id)\n .execute()\n } catch (err) {\n dbLogger.error({ err, label: row }, 'failed to update resigned label')\n }\n return signed\n }\n\n async getSubjectStatus(\n subjects: string[],\n ): Promise<Map<string, ModerationSubjectStatusRowWithHandle>> {\n if (!subjects.length) return new Map()\n\n const parsedSubjects = subjects.map(parseSubjectId)\n\n const builder = moderationSubjectStatusQueryBuilder(this.db.db)\n //\n .where((qb) => {\n for (const sub of parsedSubjects) {\n qb = qb.orWhere((qb) =>\n qb\n .where('moderation_subject_status.did', '=', sub.did)\n .where(\n 'moderation_subject_status.recordPath',\n '=',\n sub.recordPath ?? '',\n ),\n )\n }\n return qb\n })\n\n const [statusRes, accountsByDid] = await Promise.all([\n builder.execute(),\n this.getAccoutInfosByDid(parsedSubjects.map((s) => s.did)),\n ])\n\n return new Map(\n statusRes.map((row): [string, ModerationSubjectStatusRowWithHandle] => {\n const subjectId = formatSubjectId(row.did, row.recordPath)\n const handle = accountsByDid.get(row.did)?.handle ?? INVALID_HANDLE\n return [subjectId, { ...row, handle }]\n }),\n )\n }\n\n formatSubjectStatus(\n status: ModerationSubjectStatusRowWithHandle,\n ): SubjectStatusView {\n const statusView: SubjectStatusView = {\n id: status.id,\n reviewState: status.reviewState,\n createdAt: status.createdAt,\n updatedAt: status.updatedAt,\n comment: status.comment ?? undefined,\n lastReviewedBy: status.lastReviewedBy ?? undefined,\n lastReviewedAt: status.lastReviewedAt ?? undefined,\n lastReportedAt: status.lastReportedAt ?? undefined,\n lastAppealedAt: status.lastAppealedAt ?? undefined,\n muteUntil: status.muteUntil ?? undefined,\n muteReportingUntil: status.muteReportingUntil ?? undefined,\n suspendUntil: status.suspendUntil ?? undefined,\n takendown: status.takendown ?? undefined,\n appealed: status.appealed ?? undefined,\n subjectRepoHandle: status.handle ?? undefined,\n subjectBlobCids: status.blobCids || [],\n tags: status.tags || [],\n priorityScore: status.priorityScore,\n ageAssuranceState: status.ageAssuranceState ?? undefined,\n ageAssuranceUpdatedBy: status.ageAssuranceUpdatedBy ?? undefined,\n subject: subjectFromStatusRow(\n status,\n ).lex() as SubjectStatusView['subject'],\n\n accountStats: {\n // Explicitly typing to allow for easy manipulation (e.g. to strip from tests snapshots)\n $type: 'tools.ozone.moderation.defs#accountStats',\n\n // account_events_stats\n reportCount: status.reportCount ?? undefined,\n appealCount: status.appealCount ?? undefined,\n suspendCount: status.suspendCount ?? undefined,\n takedownCount: status.takedownCount ?? undefined,\n escalateCount: status.escalateCount ?? undefined,\n },\n\n recordsStats: {\n // Explicitly typing to allow for easy manipulation (e.g. to strip from tests snapshots)\n $type: 'tools.ozone.moderation.defs#recordsStats',\n\n // account_record_events_stats\n totalReports: status.totalReports ?? undefined,\n reportedCount: status.reportedCount ?? undefined,\n escalatedCount: status.escalatedCount ?? undefined,\n appealedCount: status.appealedCount ?? undefined,\n\n // account_record_status_stats\n subjectCount: status.subjectCount ?? undefined,\n pendingCount: status.pendingCount ?? undefined,\n processedCount: status.processedCount ?? undefined,\n takendownCount: status.takendownCount ?? undefined,\n },\n\n accountStrike:\n status.strikeCount !== null || status.totalStrikeCount !== null\n ? {\n $type: 'tools.ozone.moderation.defs#accountStrike',\n activeStrikeCount: status.strikeCount ?? undefined,\n totalStrikeCount: status.totalStrikeCount ?? undefined,\n firstStrikeAt: status.firstStrikeAt ?? undefined,\n lastStrikeAt: status.lastStrikeAt ?? undefined,\n }\n : undefined,\n }\n\n if (status.recordPath !== '') {\n statusView.hosting = {\n $type: 'tools.ozone.moderation.defs#recordHosting',\n updatedAt: status.hostingUpdatedAt ?? undefined,\n deletedAt: status.hostingDeletedAt ?? undefined,\n status: status.hostingStatus ?? 'unknown',\n }\n } else {\n statusView.hosting = {\n $type: 'tools.ozone.moderation.defs#accountHosting',\n updatedAt: status.hostingUpdatedAt ?? undefined,\n deletedAt: status.hostingDeletedAt ?? undefined,\n status: status.hostingStatus ?? 'unknown',\n deactivatedAt: status.hostingDeactivatedAt ?? undefined,\n reactivatedAt: status.hostingReactivatedAt ?? undefined,\n }\n }\n\n return statusView\n }\n\n async fetchAuthorFeed(actor: string): Promise<FeedViewPost[]> {\n const auth = await this.appviewAuth(ids.AppBskyFeedGetAuthorFeed)\n if (!auth) return []\n const {\n data: { feed },\n } = await this.appviewAgent.app.bsky.feed.getAuthorFeed({ actor }, auth)\n\n return feed\n }\n\n async getProfiles(dids: string[]) {\n const profiles = new Map<string, AppBskyActorDefs.ProfileViewDetailed>()\n\n const auth = await this.appviewAuth(ids.AppBskyActorGetProfiles)\n if (!auth) return profiles\n\n for (const actors of chunkArray(dids, 25)) {\n const { data } = await this.appviewAgent.getProfiles({ actors }, auth)\n\n data.profiles.forEach((profile) => {\n profiles.set(profile.did, profile)\n })\n }\n\n return profiles\n }\n}\n\ntype RecordSubject = { uri: string; cid?: string }\n\ntype SubjectView = ModEventViewDetail['subject']\n// @TODO tidy\n// type SubjectView = ModEventViewDetail['subject'] & ReportViewDetail['subject']\n\ntype RecordInfo = {\n uri: string\n cid: string\n value: Record<string, unknown>\n indexedAt: string\n}\n\nfunction parseSubjectId(subject: string): { did: string; recordPath?: string } {\n if (subject.startsWith('did:')) {\n return { did: subject }\n }\n const uri = new AtUri(subject)\n return { did: uri.hostname, recordPath: `${uri.collection}/${uri.rkey}` }\n}\n\nfunction formatSubjectId(did: string, recordPath?: string) {\n return recordPath ? `at://${did}/${recordPath}` : did\n}\n\nfunction findBlobRefs(value: unknown, refs: BlobRef[] = []) {\n if (value instanceof BlobRef) {\n refs.push(value)\n } else if (Array.isArray(value)) {\n value.forEach((val) => findBlobRefs(val, refs))\n } else if (value && typeof value === 'object') {\n Object.values(value).forEach((val) => findBlobRefs(val, refs))\n }\n return refs\n}\n\nexport function getSelfLabels(details: {\n uri: string | null\n cid: string | null\n record: Record<string, unknown> | null\n}): Label[] {\n const { uri, cid, record } = details\n if (!uri || !cid || !record) return []\n if (!isValidSelfLabels(record.labels)) return []\n const src = new AtUri(uri).host // record creator\n const cts =\n typeof record.createdAt === 'string'\n ? normalizeDatetimeAlways(record.createdAt)\n : new Date(0).toISOString()\n return record.labels.values.map(({ val }) => {\n return { src, uri, cid, val, cts }\n })\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export declare const ProtectedTagSettingKey = "tools.ozone.setting.protectedTags";
|
|
2
2
|
export declare const PolicyListSettingKey = "tools.ozone.setting.policyList";
|
|
3
|
+
export declare const SeverityLevelSettingKey = "tools.ozone.setting.severityLevels";
|
|
3
4
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/setting/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,sCAAsC,CAAA;AACzE,eAAO,MAAM,oBAAoB,mCAAmC,CAAA"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/setting/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,sCAAsC,CAAA;AACzE,eAAO,MAAM,oBAAoB,mCAAmC,CAAA;AACpE,eAAO,MAAM,uBAAuB,uCAAuC,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PolicyListSettingKey = exports.ProtectedTagSettingKey = void 0;
|
|
3
|
+
exports.SeverityLevelSettingKey = exports.PolicyListSettingKey = exports.ProtectedTagSettingKey = void 0;
|
|
4
4
|
exports.ProtectedTagSettingKey = 'tools.ozone.setting.protectedTags';
|
|
5
5
|
exports.PolicyListSettingKey = 'tools.ozone.setting.policyList';
|
|
6
|
+
exports.SeverityLevelSettingKey = 'tools.ozone.setting.severityLevels';
|
|
6
7
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/setting/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,sBAAsB,GAAG,mCAAmC,CAAA;AAC5D,QAAA,oBAAoB,GAAG,gCAAgC,CAAA","sourcesContent":["export const ProtectedTagSettingKey = 'tools.ozone.setting.protectedTags'\nexport const PolicyListSettingKey = 'tools.ozone.setting.policyList'\n"]}
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/setting/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,sBAAsB,GAAG,mCAAmC,CAAA;AAC5D,QAAA,oBAAoB,GAAG,gCAAgC,CAAA;AACvD,QAAA,uBAAuB,GAAG,oCAAoC,CAAA","sourcesContent":["export const ProtectedTagSettingKey = 'tools.ozone.setting.protectedTags'\nexport const PolicyListSettingKey = 'tools.ozone.setting.policyList'\nexport const SeverityLevelSettingKey = 'tools.ozone.setting.severityLevels'\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/setting/validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AAEnC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/setting/validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AAEnC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAO9C,eAAO,MAAM,iBAAiB,wBAElB,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAkTxD,CAAA"}
|
|
@@ -6,6 +6,21 @@ const constants_1 = require("./constants");
|
|
|
6
6
|
exports.settingValidators = new Map([
|
|
7
7
|
[
|
|
8
8
|
constants_1.ProtectedTagSettingKey,
|
|
9
|
+
/*
|
|
10
|
+
* Example configuration:
|
|
11
|
+
* {
|
|
12
|
+
* "sensitive-tag": {
|
|
13
|
+
* "roles": ["tools.ozone.team.defs#roleAdmin", "tools.ozone.team.defs#roleModerator"],
|
|
14
|
+
* "moderators": ["did:plc:example1", "did:plc:example2"]
|
|
15
|
+
* },
|
|
16
|
+
* "high-risk-tag": {
|
|
17
|
+
* "roles": ["tools.ozone.team.defs#roleAdmin"]
|
|
18
|
+
* },
|
|
19
|
+
* "admin-only-tag": {
|
|
20
|
+
* "moderators": ["did:plc:admin1"]
|
|
21
|
+
* }
|
|
22
|
+
* }
|
|
23
|
+
*/
|
|
9
24
|
async (setting) => {
|
|
10
25
|
if (setting.managerRole !== 'tools.ozone.team.defs#roleAdmin') {
|
|
11
26
|
throw new xrpc_server_1.InvalidRequestError('Only admins should be able to configure protected tags');
|
|
@@ -41,6 +56,61 @@ exports.settingValidators = new Map([
|
|
|
41
56
|
],
|
|
42
57
|
[
|
|
43
58
|
constants_1.PolicyListSettingKey,
|
|
59
|
+
/*
|
|
60
|
+
* Example configuration:
|
|
61
|
+
* {
|
|
62
|
+
* "harassment": {
|
|
63
|
+
* "name": "Anti-Harassment",
|
|
64
|
+
* "description": "Content that harasses, intimidates, or bullies users",
|
|
65
|
+
* "severityLevels": {
|
|
66
|
+
* "sev-1": {
|
|
67
|
+
* "description": "Minor harassment",
|
|
68
|
+
* "isDefault": true
|
|
69
|
+
* },
|
|
70
|
+
* "sev-2": {
|
|
71
|
+
* "description": "Moderate harassment",
|
|
72
|
+
* "isDefault": false
|
|
73
|
+
* },
|
|
74
|
+
* "sev-4": {
|
|
75
|
+
* "description": "Severe harassment",
|
|
76
|
+
* "isDefault": false
|
|
77
|
+
* }
|
|
78
|
+
* }
|
|
79
|
+
* },
|
|
80
|
+
* "death-threats": {
|
|
81
|
+
* "name": "Death Threats",
|
|
82
|
+
* "description": "Threats of violence or death against individuals",
|
|
83
|
+
* "severityLevels": {
|
|
84
|
+
* "death-threat": {
|
|
85
|
+
* "description": "Death threat violation",
|
|
86
|
+
* "isDefault": true
|
|
87
|
+
* }
|
|
88
|
+
* }
|
|
89
|
+
* },
|
|
90
|
+
* "spam": {
|
|
91
|
+
* "name": "Spam",
|
|
92
|
+
* "description": "Unsolicited or repetitive content",
|
|
93
|
+
* "severityLevels": {
|
|
94
|
+
* "sev-0": {
|
|
95
|
+
* "description": "Minor spam",
|
|
96
|
+
* "isDefault": false
|
|
97
|
+
* },
|
|
98
|
+
* "sev-1": {
|
|
99
|
+
* "description": "Moderate spam",
|
|
100
|
+
* "isDefault": true
|
|
101
|
+
* },
|
|
102
|
+
* "sev-2": {
|
|
103
|
+
* "description": "Severe spam",
|
|
104
|
+
* "isDefault": false
|
|
105
|
+
* }
|
|
106
|
+
* }
|
|
107
|
+
* },
|
|
108
|
+
* "minimal-policy": {
|
|
109
|
+
* "name": "Basic Policy",
|
|
110
|
+
* "description": "Simple policy without severity levels"
|
|
111
|
+
* }
|
|
112
|
+
* }
|
|
113
|
+
*/
|
|
44
114
|
async (setting) => {
|
|
45
115
|
if (setting.managerRole !== 'tools.ozone.team.defs#roleAdmin') {
|
|
46
116
|
throw new xrpc_server_1.InvalidRequestError('Only admins should be able to manage policy list');
|
|
@@ -55,6 +125,115 @@ exports.settingValidators = new Map([
|
|
|
55
125
|
if (!val['name'] || !val['description']) {
|
|
56
126
|
throw new xrpc_server_1.InvalidRequestError(`Must define a name and description for policy ${key}`);
|
|
57
127
|
}
|
|
128
|
+
if (val['severityLevels'] !== undefined) {
|
|
129
|
+
if (typeof val['severityLevels'] !== 'object') {
|
|
130
|
+
throw new xrpc_server_1.InvalidRequestError(`Severity levels must be an object for policy ${key}`);
|
|
131
|
+
}
|
|
132
|
+
let hasDefault = false;
|
|
133
|
+
for (const [severityKey, severityVal] of Object.entries(val['severityLevels'])) {
|
|
134
|
+
if (!severityVal || typeof severityVal !== 'object') {
|
|
135
|
+
throw new xrpc_server_1.InvalidRequestError(`Invalid configuration for severity level ${severityKey} in policy ${key}`);
|
|
136
|
+
}
|
|
137
|
+
if (severityVal['description'] !== undefined &&
|
|
138
|
+
typeof severityVal['description'] !== 'string') {
|
|
139
|
+
throw new xrpc_server_1.InvalidRequestError(`Description must be a string for severity level ${severityKey} in policy ${key}`);
|
|
140
|
+
}
|
|
141
|
+
if (severityVal['isDefault'] !== undefined) {
|
|
142
|
+
if (typeof severityVal['isDefault'] !== 'boolean') {
|
|
143
|
+
throw new xrpc_server_1.InvalidRequestError(`isDefault must be a boolean for severity level ${severityKey} in policy ${key}`);
|
|
144
|
+
}
|
|
145
|
+
if (severityVal['isDefault']) {
|
|
146
|
+
if (hasDefault) {
|
|
147
|
+
throw new xrpc_server_1.InvalidRequestError(`Only one severity level can be the default for policy ${key}`);
|
|
148
|
+
}
|
|
149
|
+
hasDefault = true;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
[
|
|
158
|
+
constants_1.SeverityLevelSettingKey,
|
|
159
|
+
/*
|
|
160
|
+
* Example configuration:
|
|
161
|
+
* {
|
|
162
|
+
* "sev-0": {
|
|
163
|
+
* "strikeCount": 0
|
|
164
|
+
* },
|
|
165
|
+
* "sev-1": {
|
|
166
|
+
* "strikeCount": 1,
|
|
167
|
+
* "strikeOnOccurrence": 2
|
|
168
|
+
* },
|
|
169
|
+
* "sev-2": {
|
|
170
|
+
* "strikeCount": 2
|
|
171
|
+
* },
|
|
172
|
+
* "sev-4": {
|
|
173
|
+
* "strikeCount": 4,
|
|
174
|
+
* "expiresInDays": 365
|
|
175
|
+
* },
|
|
176
|
+
* "sev-5": {
|
|
177
|
+
* "needsTakedown": true
|
|
178
|
+
* },
|
|
179
|
+
* "death-threat": {
|
|
180
|
+
* "strikeCount": 4,
|
|
181
|
+
* "firstOccurrenceStrikeCount": 4,
|
|
182
|
+
* },
|
|
183
|
+
* "custom-severity": {
|
|
184
|
+
* "strikeCount": 3,
|
|
185
|
+
* "strikeOnOccurrence": 1,
|
|
186
|
+
* },
|
|
187
|
+
* "escalating-severity": {
|
|
188
|
+
* "firstOccurrenceStrikeCount": 2,
|
|
189
|
+
* "repeatOccurrenceStrikeCount": 5
|
|
190
|
+
* }
|
|
191
|
+
* }
|
|
192
|
+
*/
|
|
193
|
+
async (setting) => {
|
|
194
|
+
if (setting.managerRole !== 'tools.ozone.team.defs#roleAdmin') {
|
|
195
|
+
throw new xrpc_server_1.InvalidRequestError('Only admins should be able to manage severity levels');
|
|
196
|
+
}
|
|
197
|
+
if (typeof setting.value !== 'object') {
|
|
198
|
+
throw new xrpc_server_1.InvalidRequestError('Invalid value');
|
|
199
|
+
}
|
|
200
|
+
for (const [key, val] of Object.entries(setting.value)) {
|
|
201
|
+
if (!val || typeof val !== 'object') {
|
|
202
|
+
throw new xrpc_server_1.InvalidRequestError(`Invalid configuration for severity level ${key}`);
|
|
203
|
+
}
|
|
204
|
+
if (val['strikeCount'] !== undefined) {
|
|
205
|
+
if (typeof val['strikeCount'] !== 'number' ||
|
|
206
|
+
!Number.isInteger(val['strikeCount']) ||
|
|
207
|
+
val['strikeCount'] < 0) {
|
|
208
|
+
throw new xrpc_server_1.InvalidRequestError(`Strike count must be a non-negative integer for severity level ${key}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (val['strikeOnOccurrence'] !== undefined) {
|
|
212
|
+
if (typeof val['strikeOnOccurrence'] !== 'number' ||
|
|
213
|
+
!Number.isInteger(val['strikeOnOccurrence']) ||
|
|
214
|
+
val['strikeOnOccurrence'] < 1) {
|
|
215
|
+
throw new xrpc_server_1.InvalidRequestError(`Strike on occurrence must be a positive integer for severity level ${key}`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (val['needsTakedown'] !== undefined) {
|
|
219
|
+
if (typeof val['needsTakedown'] !== 'boolean') {
|
|
220
|
+
throw new xrpc_server_1.InvalidRequestError(`Needs takedown must be a boolean for severity level ${key}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (val['expiresInDays'] !== undefined) {
|
|
224
|
+
if (typeof val['expiresInDays'] !== 'number' ||
|
|
225
|
+
!Number.isInteger(val['expiresInDays']) ||
|
|
226
|
+
val['expiresInDays'] < 0) {
|
|
227
|
+
throw new xrpc_server_1.InvalidRequestError(`Expires in days must be a non-negative integer for severity level ${key}`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (val['firstOccurrenceStrikeCount'] !== undefined) {
|
|
231
|
+
if (typeof val['firstOccurrenceStrikeCount'] !== 'number' ||
|
|
232
|
+
!Number.isInteger(val['firstOccurrenceStrikeCount']) ||
|
|
233
|
+
val['firstOccurrenceStrikeCount'] < 0) {
|
|
234
|
+
throw new xrpc_server_1.InvalidRequestError(`First occurrence strike count must be a non-negative integer for severity level ${key}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
58
237
|
}
|
|
59
238
|
},
|
|
60
239
|
],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../../src/setting/validators.ts"],"names":[],"mappings":"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","sourcesContent":["import { Selectable } from 'kysely'\nimport { InvalidRequestError } from '@atproto/xrpc-server'\nimport { Setting } from '../db/schema/setting'\nimport { PolicyListSettingKey, ProtectedTagSettingKey } from './constants'\n\nexport const settingValidators = new Map<\n string,\n (setting: Partial<Selectable<Setting>>) => Promise<void>\n>([\n [\n ProtectedTagSettingKey,\n async (setting: Partial<Selectable<Setting>>) => {\n if (setting.managerRole !== 'tools.ozone.team.defs#roleAdmin') {\n throw new InvalidRequestError(\n 'Only admins should be able to configure protected tags',\n )\n }\n\n if (typeof setting.value !== 'object') {\n throw new InvalidRequestError('Invalid value')\n }\n for (const [key, val] of Object.entries(setting.value)) {\n if (!val || typeof val !== 'object') {\n throw new InvalidRequestError(`Invalid configuration for tag ${key}`)\n }\n\n if (!val['roles'] && !val['moderators']) {\n throw new InvalidRequestError(\n `Must define who a list of moderators or a role who can action subjects with ${key} tag`,\n )\n }\n\n if (val['roles']) {\n if (!Array.isArray(val['roles'])) {\n throw new InvalidRequestError(\n `Roles must be an array of moderator roles for tag ${key}`,\n )\n }\n if (!val['roles']?.length) {\n throw new InvalidRequestError(\n `Must define at least one role for tag ${key}`,\n )\n }\n }\n\n if (val['moderators']) {\n if (!Array.isArray(val['moderators'])) {\n throw new InvalidRequestError(\n `Moderators must be an array of moderator DIDs for tag ${key}`,\n )\n }\n if (!val['moderators']?.length) {\n throw new InvalidRequestError(\n `Must define at least one moderator DID for tag ${key}`,\n )\n }\n }\n }\n },\n ],\n [\n PolicyListSettingKey,\n async (setting: Partial<Selectable<Setting>>) => {\n if (setting.managerRole !== 'tools.ozone.team.defs#roleAdmin') {\n throw new InvalidRequestError(\n 'Only admins should be able to manage policy list',\n )\n }\n\n if (typeof setting.value !== 'object') {\n throw new InvalidRequestError('Invalid value')\n }\n for (const [key, val] of Object.entries(setting.value)) {\n if (!val || typeof val !== 'object') {\n throw new InvalidRequestError(\n `Invalid configuration for policy ${key}`,\n )\n }\n\n if (!val['name'] || !val['description']) {\n throw new InvalidRequestError(\n `Must define a name and description for policy ${key}`,\n )\n }\n }\n },\n ],\n])\n"]}
|
|
1
|
+
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../../src/setting/validators.ts"],"names":[],"mappings":";;;AACA,sDAA0D;AAE1D,2CAIoB;AAEP,QAAA,iBAAiB,GAAG,IAAI,GAAG,CAGtC;IACA;QACE,kCAAsB;QACtB;;;;;;;;;;;;;;WAcG;QACH,KAAK,EAAE,OAAqC,EAAE,EAAE;YAC9C,IAAI,OAAO,CAAC,WAAW,KAAK,iCAAiC,EAAE,CAAC;gBAC9D,MAAM,IAAI,iCAAmB,CAC3B,wDAAwD,CACzD,CAAA;YACH,CAAC;YAED,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACtC,MAAM,IAAI,iCAAmB,CAAC,eAAe,CAAC,CAAA;YAChD,CAAC;YACD,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;oBACpC,MAAM,IAAI,iCAAmB,CAAC,iCAAiC,GAAG,EAAE,CAAC,CAAA;gBACvE,CAAC;gBAED,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;oBACxC,MAAM,IAAI,iCAAmB,CAC3B,+EAA+E,GAAG,MAAM,CACzF,CAAA;gBACH,CAAC;gBAED,IAAI,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;oBACjB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;wBACjC,MAAM,IAAI,iCAAmB,CAC3B,qDAAqD,GAAG,EAAE,CAC3D,CAAA;oBACH,CAAC;oBACD,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;wBAC1B,MAAM,IAAI,iCAAmB,CAC3B,yCAAyC,GAAG,EAAE,CAC/C,CAAA;oBACH,CAAC;gBACH,CAAC;gBAED,IAAI,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;oBACtB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;wBACtC,MAAM,IAAI,iCAAmB,CAC3B,yDAAyD,GAAG,EAAE,CAC/D,CAAA;oBACH,CAAC;oBACD,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;wBAC/B,MAAM,IAAI,iCAAmB,CAC3B,kDAAkD,GAAG,EAAE,CACxD,CAAA;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;KACF;IACD;QACE,gCAAoB;QACpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAsDG;QACH,KAAK,EAAE,OAAqC,EAAE,EAAE;YAC9C,IAAI,OAAO,CAAC,WAAW,KAAK,iCAAiC,EAAE,CAAC;gBAC9D,MAAM,IAAI,iCAAmB,CAC3B,kDAAkD,CACnD,CAAA;YACH,CAAC;YAED,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACtC,MAAM,IAAI,iCAAmB,CAAC,eAAe,CAAC,CAAA;YAChD,CAAC;YACD,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;oBACpC,MAAM,IAAI,iCAAmB,CAC3B,oCAAoC,GAAG,EAAE,CAC1C,CAAA;gBACH,CAAC;gBAED,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;oBACxC,MAAM,IAAI,iCAAmB,CAC3B,iDAAiD,GAAG,EAAE,CACvD,CAAA;gBACH,CAAC;gBAED,IAAI,GAAG,CAAC,gBAAgB,CAAC,KAAK,SAAS,EAAE,CAAC;oBACxC,IAAI,OAAO,GAAG,CAAC,gBAAgB,CAAC,KAAK,QAAQ,EAAE,CAAC;wBAC9C,MAAM,IAAI,iCAAmB,CAC3B,gDAAgD,GAAG,EAAE,CACtD,CAAA;oBACH,CAAC;oBAED,IAAI,UAAU,GAAG,KAAK,CAAA;oBACtB,KAAK,MAAM,CAAC,WAAW,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CACrD,GAAG,CAAC,gBAAgB,CAAC,CACtB,EAAE,CAAC;wBACF,IAAI,CAAC,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;4BACpD,MAAM,IAAI,iCAAmB,CAC3B,4CAA4C,WAAW,cAAc,GAAG,EAAE,CAC3E,CAAA;wBACH,CAAC;wBAED,IACE,WAAW,CAAC,aAAa,CAAC,KAAK,SAAS;4BACxC,OAAO,WAAW,CAAC,aAAa,CAAC,KAAK,QAAQ,EAC9C,CAAC;4BACD,MAAM,IAAI,iCAAmB,CAC3B,mDAAmD,WAAW,cAAc,GAAG,EAAE,CAClF,CAAA;wBACH,CAAC;wBAED,IAAI,WAAW,CAAC,WAAW,CAAC,KAAK,SAAS,EAAE,CAAC;4BAC3C,IAAI,OAAO,WAAW,CAAC,WAAW,CAAC,KAAK,SAAS,EAAE,CAAC;gCAClD,MAAM,IAAI,iCAAmB,CAC3B,kDAAkD,WAAW,cAAc,GAAG,EAAE,CACjF,CAAA;4BACH,CAAC;4BACD,IAAI,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;gCAC7B,IAAI,UAAU,EAAE,CAAC;oCACf,MAAM,IAAI,iCAAmB,CAC3B,yDAAyD,GAAG,EAAE,CAC/D,CAAA;gCACH,CAAC;gCACD,UAAU,GAAG,IAAI,CAAA;4BACnB,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;KACF;IACD;QACE,mCAAuB;QACvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAiCG;QACH,KAAK,EAAE,OAAqC,EAAE,EAAE;YAC9C,IAAI,OAAO,CAAC,WAAW,KAAK,iCAAiC,EAAE,CAAC;gBAC9D,MAAM,IAAI,iCAAmB,CAC3B,sDAAsD,CACvD,CAAA;YACH,CAAC;YAED,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACtC,MAAM,IAAI,iCAAmB,CAAC,eAAe,CAAC,CAAA;YAChD,CAAC;YAED,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;oBACpC,MAAM,IAAI,iCAAmB,CAC3B,4CAA4C,GAAG,EAAE,CAClD,CAAA;gBACH,CAAC;gBAED,IAAI,GAAG,CAAC,aAAa,CAAC,KAAK,SAAS,EAAE,CAAC;oBACrC,IACE,OAAO,GAAG,CAAC,aAAa,CAAC,KAAK,QAAQ;wBACtC,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;wBACrC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,EACtB,CAAC;wBACD,MAAM,IAAI,iCAAmB,CAC3B,kEAAkE,GAAG,EAAE,CACxE,CAAA;oBACH,CAAC;gBACH,CAAC;gBAED,IAAI,GAAG,CAAC,oBAAoB,CAAC,KAAK,SAAS,EAAE,CAAC;oBAC5C,IACE,OAAO,GAAG,CAAC,oBAAoB,CAAC,KAAK,QAAQ;wBAC7C,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;wBAC5C,GAAG,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAC7B,CAAC;wBACD,MAAM,IAAI,iCAAmB,CAC3B,sEAAsE,GAAG,EAAE,CAC5E,CAAA;oBACH,CAAC;gBACH,CAAC;gBAED,IAAI,GAAG,CAAC,eAAe,CAAC,KAAK,SAAS,EAAE,CAAC;oBACvC,IAAI,OAAO,GAAG,CAAC,eAAe,CAAC,KAAK,SAAS,EAAE,CAAC;wBAC9C,MAAM,IAAI,iCAAmB,CAC3B,uDAAuD,GAAG,EAAE,CAC7D,CAAA;oBACH,CAAC;gBACH,CAAC;gBAED,IAAI,GAAG,CAAC,eAAe,CAAC,KAAK,SAAS,EAAE,CAAC;oBACvC,IACE,OAAO,GAAG,CAAC,eAAe,CAAC,KAAK,QAAQ;wBACxC,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;wBACvC,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,EACxB,CAAC;wBACD,MAAM,IAAI,iCAAmB,CAC3B,qEAAqE,GAAG,EAAE,CAC3E,CAAA;oBACH,CAAC;gBACH,CAAC;gBAED,IAAI,GAAG,CAAC,4BAA4B,CAAC,KAAK,SAAS,EAAE,CAAC;oBACpD,IACE,OAAO,GAAG,CAAC,4BAA4B,CAAC,KAAK,QAAQ;wBACrD,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;wBACpD,GAAG,CAAC,4BAA4B,CAAC,GAAG,CAAC,EACrC,CAAC;wBACD,MAAM,IAAI,iCAAmB,CAC3B,mFAAmF,GAAG,EAAE,CACzF,CAAA;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;KACF;CACF,CAAC,CAAA","sourcesContent":["import { Selectable } from 'kysely'\nimport { InvalidRequestError } from '@atproto/xrpc-server'\nimport { Setting } from '../db/schema/setting'\nimport {\n PolicyListSettingKey,\n ProtectedTagSettingKey,\n SeverityLevelSettingKey,\n} from './constants'\n\nexport const settingValidators = new Map<\n string,\n (setting: Partial<Selectable<Setting>>) => Promise<void>\n>([\n [\n ProtectedTagSettingKey,\n /*\n * Example configuration:\n * {\n * \"sensitive-tag\": {\n * \"roles\": [\"tools.ozone.team.defs#roleAdmin\", \"tools.ozone.team.defs#roleModerator\"],\n * \"moderators\": [\"did:plc:example1\", \"did:plc:example2\"]\n * },\n * \"high-risk-tag\": {\n * \"roles\": [\"tools.ozone.team.defs#roleAdmin\"]\n * },\n * \"admin-only-tag\": {\n * \"moderators\": [\"did:plc:admin1\"]\n * }\n * }\n */\n async (setting: Partial<Selectable<Setting>>) => {\n if (setting.managerRole !== 'tools.ozone.team.defs#roleAdmin') {\n throw new InvalidRequestError(\n 'Only admins should be able to configure protected tags',\n )\n }\n\n if (typeof setting.value !== 'object') {\n throw new InvalidRequestError('Invalid value')\n }\n for (const [key, val] of Object.entries(setting.value)) {\n if (!val || typeof val !== 'object') {\n throw new InvalidRequestError(`Invalid configuration for tag ${key}`)\n }\n\n if (!val['roles'] && !val['moderators']) {\n throw new InvalidRequestError(\n `Must define who a list of moderators or a role who can action subjects with ${key} tag`,\n )\n }\n\n if (val['roles']) {\n if (!Array.isArray(val['roles'])) {\n throw new InvalidRequestError(\n `Roles must be an array of moderator roles for tag ${key}`,\n )\n }\n if (!val['roles']?.length) {\n throw new InvalidRequestError(\n `Must define at least one role for tag ${key}`,\n )\n }\n }\n\n if (val['moderators']) {\n if (!Array.isArray(val['moderators'])) {\n throw new InvalidRequestError(\n `Moderators must be an array of moderator DIDs for tag ${key}`,\n )\n }\n if (!val['moderators']?.length) {\n throw new InvalidRequestError(\n `Must define at least one moderator DID for tag ${key}`,\n )\n }\n }\n }\n },\n ],\n [\n PolicyListSettingKey,\n /*\n * Example configuration:\n * {\n * \"harassment\": {\n * \"name\": \"Anti-Harassment\",\n * \"description\": \"Content that harasses, intimidates, or bullies users\",\n * \"severityLevels\": {\n * \"sev-1\": {\n * \"description\": \"Minor harassment\",\n * \"isDefault\": true\n * },\n * \"sev-2\": {\n * \"description\": \"Moderate harassment\",\n * \"isDefault\": false\n * },\n * \"sev-4\": {\n * \"description\": \"Severe harassment\",\n * \"isDefault\": false\n * }\n * }\n * },\n * \"death-threats\": {\n * \"name\": \"Death Threats\",\n * \"description\": \"Threats of violence or death against individuals\",\n * \"severityLevels\": {\n * \"death-threat\": {\n * \"description\": \"Death threat violation\",\n * \"isDefault\": true\n * }\n * }\n * },\n * \"spam\": {\n * \"name\": \"Spam\",\n * \"description\": \"Unsolicited or repetitive content\",\n * \"severityLevels\": {\n * \"sev-0\": {\n * \"description\": \"Minor spam\",\n * \"isDefault\": false\n * },\n * \"sev-1\": {\n * \"description\": \"Moderate spam\",\n * \"isDefault\": true\n * },\n * \"sev-2\": {\n * \"description\": \"Severe spam\",\n * \"isDefault\": false\n * }\n * }\n * },\n * \"minimal-policy\": {\n * \"name\": \"Basic Policy\",\n * \"description\": \"Simple policy without severity levels\"\n * }\n * }\n */\n async (setting: Partial<Selectable<Setting>>) => {\n if (setting.managerRole !== 'tools.ozone.team.defs#roleAdmin') {\n throw new InvalidRequestError(\n 'Only admins should be able to manage policy list',\n )\n }\n\n if (typeof setting.value !== 'object') {\n throw new InvalidRequestError('Invalid value')\n }\n for (const [key, val] of Object.entries(setting.value)) {\n if (!val || typeof val !== 'object') {\n throw new InvalidRequestError(\n `Invalid configuration for policy ${key}`,\n )\n }\n\n if (!val['name'] || !val['description']) {\n throw new InvalidRequestError(\n `Must define a name and description for policy ${key}`,\n )\n }\n\n if (val['severityLevels'] !== undefined) {\n if (typeof val['severityLevels'] !== 'object') {\n throw new InvalidRequestError(\n `Severity levels must be an object for policy ${key}`,\n )\n }\n\n let hasDefault = false\n for (const [severityKey, severityVal] of Object.entries(\n val['severityLevels'],\n )) {\n if (!severityVal || typeof severityVal !== 'object') {\n throw new InvalidRequestError(\n `Invalid configuration for severity level ${severityKey} in policy ${key}`,\n )\n }\n\n if (\n severityVal['description'] !== undefined &&\n typeof severityVal['description'] !== 'string'\n ) {\n throw new InvalidRequestError(\n `Description must be a string for severity level ${severityKey} in policy ${key}`,\n )\n }\n\n if (severityVal['isDefault'] !== undefined) {\n if (typeof severityVal['isDefault'] !== 'boolean') {\n throw new InvalidRequestError(\n `isDefault must be a boolean for severity level ${severityKey} in policy ${key}`,\n )\n }\n if (severityVal['isDefault']) {\n if (hasDefault) {\n throw new InvalidRequestError(\n `Only one severity level can be the default for policy ${key}`,\n )\n }\n hasDefault = true\n }\n }\n }\n }\n }\n },\n ],\n [\n SeverityLevelSettingKey,\n /*\n * Example configuration:\n * {\n * \"sev-0\": {\n * \"strikeCount\": 0\n * },\n * \"sev-1\": {\n * \"strikeCount\": 1,\n * \"strikeOnOccurrence\": 2\n * },\n * \"sev-2\": {\n * \"strikeCount\": 2\n * },\n * \"sev-4\": {\n * \"strikeCount\": 4,\n * \"expiresInDays\": 365\n * },\n * \"sev-5\": {\n * \"needsTakedown\": true\n * },\n * \"death-threat\": {\n * \"strikeCount\": 4,\n * \"firstOccurrenceStrikeCount\": 4,\n * },\n * \"custom-severity\": {\n * \"strikeCount\": 3,\n * \"strikeOnOccurrence\": 1,\n * },\n * \"escalating-severity\": {\n * \"firstOccurrenceStrikeCount\": 2,\n * \"repeatOccurrenceStrikeCount\": 5\n * }\n * }\n */\n async (setting: Partial<Selectable<Setting>>) => {\n if (setting.managerRole !== 'tools.ozone.team.defs#roleAdmin') {\n throw new InvalidRequestError(\n 'Only admins should be able to manage severity levels',\n )\n }\n\n if (typeof setting.value !== 'object') {\n throw new InvalidRequestError('Invalid value')\n }\n\n for (const [key, val] of Object.entries(setting.value)) {\n if (!val || typeof val !== 'object') {\n throw new InvalidRequestError(\n `Invalid configuration for severity level ${key}`,\n )\n }\n\n if (val['strikeCount'] !== undefined) {\n if (\n typeof val['strikeCount'] !== 'number' ||\n !Number.isInteger(val['strikeCount']) ||\n val['strikeCount'] < 0\n ) {\n throw new InvalidRequestError(\n `Strike count must be a non-negative integer for severity level ${key}`,\n )\n }\n }\n\n if (val['strikeOnOccurrence'] !== undefined) {\n if (\n typeof val['strikeOnOccurrence'] !== 'number' ||\n !Number.isInteger(val['strikeOnOccurrence']) ||\n val['strikeOnOccurrence'] < 1\n ) {\n throw new InvalidRequestError(\n `Strike on occurrence must be a positive integer for severity level ${key}`,\n )\n }\n }\n\n if (val['needsTakedown'] !== undefined) {\n if (typeof val['needsTakedown'] !== 'boolean') {\n throw new InvalidRequestError(\n `Needs takedown must be a boolean for severity level ${key}`,\n )\n }\n }\n\n if (val['expiresInDays'] !== undefined) {\n if (\n typeof val['expiresInDays'] !== 'number' ||\n !Number.isInteger(val['expiresInDays']) ||\n val['expiresInDays'] < 0\n ) {\n throw new InvalidRequestError(\n `Expires in days must be a non-negative integer for severity level ${key}`,\n )\n }\n }\n\n if (val['firstOccurrenceStrikeCount'] !== undefined) {\n if (\n typeof val['firstOccurrenceStrikeCount'] !== 'number' ||\n !Number.isInteger(val['firstOccurrenceStrikeCount']) ||\n val['firstOccurrenceStrikeCount'] < 0\n ) {\n throw new InvalidRequestError(\n `First occurrence strike count must be a non-negative integer for severity level ${key}`,\n )\n }\n }\n }\n },\n ],\n])\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/ozone",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.152",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Backend service for moderating the Bluesky network.",
|
|
6
6
|
"keywords": [
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"uint8arrays": "3.0.0",
|
|
36
36
|
"undici": "^6.14.1",
|
|
37
37
|
"ws": "^8.12.0",
|
|
38
|
-
"@atproto/api": "^0.17.
|
|
38
|
+
"@atproto/api": "^0.17.6",
|
|
39
39
|
"@atproto/common": "^0.4.12",
|
|
40
40
|
"@atproto/crypto": "^0.4.4",
|
|
41
41
|
"@atproto/identity": "^0.4.9",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"ts-node": "^10.8.2",
|
|
56
56
|
"typescript": "^5.6.3",
|
|
57
57
|
"@atproto/lex-cli": "^0.9.6",
|
|
58
|
-
"@atproto/pds": "^0.4.
|
|
58
|
+
"@atproto/pds": "^0.4.190"
|
|
59
59
|
},
|
|
60
60
|
"scripts": {
|
|
61
61
|
"codegen": "lex gen-server --yes ./src/lexicon ../../lexicons/com/atproto/*/* ../../lexicons/app/bsky/*/* ../../lexicons/chat/bsky/*/* ../../lexicons/tools/ozone/*/*",
|
|
@@ -29,6 +29,7 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
29
29
|
modTool,
|
|
30
30
|
ageAssuranceState,
|
|
31
31
|
batchId,
|
|
32
|
+
withStrike,
|
|
32
33
|
} = params
|
|
33
34
|
const db = ctx.db
|
|
34
35
|
const modService = ctx.modService(db)
|
|
@@ -55,6 +56,7 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
55
56
|
modTool,
|
|
56
57
|
ageAssuranceState,
|
|
57
58
|
batchId,
|
|
59
|
+
withStrike,
|
|
58
60
|
})
|
|
59
61
|
return {
|
|
60
62
|
encoding: 'application/json',
|