Allow creating labels with expiry ()

*  Allow creating labels with expiry

* 🧹 Cleanup
This commit is contained in:
Foysal Ahamed 2025-01-31 11:48:10 -08:00 committed by GitHub
parent 8fd5dcea92
commit d377d1a9be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 64 additions and 5 deletions
lexicons/tools/ozone/moderation
packages
api/src/client
lexicons.ts
types/tools/ozone/moderation
ozone
src
api/moderation
lexicon
lexicons.ts
types/tools/ozone/moderation
mod-service
tests
pds/src/lexicon
lexicons.ts
types/tools/ozone/moderation

@ -374,6 +374,10 @@
"negateLabelVals": {
"type": "array",
"items": { "type": "string" }
},
"durationInHours": {
"type": "integer",
"description": "Indicates how long the label will remain on the subject. Only applies on labels that are being added."
}
}
},

@ -11549,6 +11549,11 @@ export const schemaDict = {
type: 'string',
},
},
durationInHours: {
type: 'integer',
description:
'Indicates how long the label will remain on the subject. Only applies on labels that are being added.',
},
},
},
modEventAcknowledge: {

@ -347,6 +347,8 @@ export interface ModEventLabel {
comment?: string
createLabelVals: string[]
negateLabelVals: string[]
/** Indicates how long the label will remain on the subject. Only applies on labels that are being added. */
durationInHours?: number
[k: string]: unknown
}

@ -207,6 +207,7 @@ const handleModerationEvent = async ({
? result.event.negateLabelVals.split(' ')
: undefined,
},
result.event.durationInHours ?? undefined,
)
}

@ -11549,6 +11549,11 @@ export const schemaDict = {
type: 'string',
},
},
durationInHours: {
type: 'integer',
description:
'Indicates how long the label will remain on the subject. Only applies on labels that are being added.',
},
},
},
modEventAcknowledge: {

@ -347,6 +347,8 @@ export interface ModEventLabel {
comment?: string
createLabelVals: string[]
negateLabelVals: string[]
/** Indicates how long the label will remain on the subject. Only applies on labels that are being added. */
durationInHours?: number
[k: string]: unknown
}

@ -1159,13 +1159,19 @@ export class ModerationService {
uri: string,
cid: string | null,
labels: { create?: string[]; negate?: string[] },
durationInHours?: number,
): Promise<Label[]> {
const exp =
durationInHours !== undefined
? addHoursToDate(durationInHours).toISOString()
: undefined
const { create = [], negate = [] } = labels
const toCreate = create.map((val) => ({
src: this.cfg.service.did,
uri,
cid: cid ?? undefined,
val,
exp,
cts: new Date().toISOString(),
}))
const toNegate = negate.map((val) => ({

@ -113,6 +113,7 @@ export class ModerationViews {
[
'tools.ozone.moderation.defs#modEventMuteReporter',
'tools.ozone.moderation.defs#modEventTakedown',
'tools.ozone.moderation.defs#modEventLabel',
'tools.ozone.moderation.defs#modEventMute',
].includes(event.action)
) {

@ -24,6 +24,7 @@ import { EventReverser } from '../src'
import { ImageInvalidator } from '../src/image-invalidator'
import { TAKEDOWN_LABEL } from '../src/mod-service'
import { ids } from '../src/lexicon/lexicons'
import { HOUR } from '@atproto/common'
describe('moderation', () => {
let network: TestNetwork
@ -514,6 +515,24 @@ describe('moderation', () => {
await expect(getRepoLabels(sc.dids.bob)).resolves.toEqual(['kittens'])
})
it('creates expiring label', async () => {
await emitLabelEvent({
createLabelVals: ['temp'],
negateLabelVals: [],
subject: {
$type: 'com.atproto.admin.defs#repoRef',
did: sc.dids.bob,
},
durationInHours: 24,
})
const repo = await getRepo(sc.dids.bob)
// Losely check that the expiry date is set to above 23 hours from now
expect(
`${repo?.labels?.[0].exp}` >
new Date(Date.now() + 23 * HOUR).toISOString(),
).toBeTruthy()
})
it('does not allow triage moderators to label.', async () => {
const attemptLabel = modClient.emitEvent(
{
@ -708,14 +727,16 @@ describe('moderation', () => {
subject: ToolsOzoneModerationEmitEvent.InputSchema['subject']
createLabelVals: ModEventLabel['createLabelVals']
negateLabelVals: ModEventLabel['negateLabelVals']
durationInHours?: ModEventLabel['durationInHours']
},
) {
const { createLabelVals, negateLabelVals } = opts
const { createLabelVals, negateLabelVals, durationInHours } = opts
const result = await modClient.emitEvent({
event: {
$type: 'tools.ozone.moderation.defs#modEventLabel',
createLabelVals,
negateLabelVals,
durationInHours,
},
createdBy: 'did:example:admin',
reason: 'Y',
@ -740,7 +761,7 @@ describe('moderation', () => {
}
async function getRecordLabels(uri: string) {
const result = await agent.api.tools.ozone.moderation.getRecord(
const result = await agent.tools.ozone.moderation.getRecord(
{ uri },
{
headers: await network.ozone.modHeaders(
@ -752,8 +773,8 @@ describe('moderation', () => {
return labels.map((l) => l.val)
}
async function getRepoLabels(did: string) {
const result = await agent.api.tools.ozone.moderation.getRepo(
async function getRepo(did: string) {
const result = await agent.tools.ozone.moderation.getRepo(
{ did },
{
headers: await network.ozone.modHeaders(
@ -761,7 +782,12 @@ describe('moderation', () => {
),
},
)
const labels = result.data.labels ?? []
return result.data
}
async function getRepoLabels(did: string) {
const result = await getRepo(did)
const labels = result.labels ?? []
return labels.map((l) => l.val)
}
})

@ -11549,6 +11549,11 @@ export const schemaDict = {
type: 'string',
},
},
durationInHours: {
type: 'integer',
description:
'Indicates how long the label will remain on the subject. Only applies on labels that are being added.',
},
},
},
modEventAcknowledge: {

@ -347,6 +347,8 @@ export interface ModEventLabel {
comment?: string
createLabelVals: string[]
negateLabelVals: string[]
/** Indicates how long the label will remain on the subject. Only applies on labels that are being added. */
durationInHours?: number
[k: string]: unknown
}