✨ Allow creating labels with expiry (#3476)
* ✨ Allow creating labels with expiry * 🧹 Cleanup
This commit is contained in:
parent
8fd5dcea92
commit
d377d1a9be
lexicons/tools/ozone/moderation
packages
api/src/client
ozone
src
api/moderation
lexicon
mod-service
tests
pds/src/lexicon
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user