UNPKG

@atproto/ozone

Version:

Backend service for moderating the Bluesky network.

66 lines 3.28 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = default_1; const xrpc_server_1 = require("@atproto/xrpc-server"); const subject_1 = require("../../mod-service/subject"); const tag_service_1 = require("../../tag-service"); const util_1 = require("../../tag-service/util"); const util_2 = require("../util"); function default_1(server, ctx) { server.com.atproto.moderation.createReport({ auth: ctx.authVerifier.standard, handler: async ({ input, auth }) => { const requester = 'iss' in auth.credentials ? auth.credentials.iss : ctx.cfg.service.did; const { reasonType, reason, modTool } = input.body; const subject = (0, subject_1.subjectFromInput)(input.body.subject); // If the report is an appeal, the requester must be the author of the subject if ((0, util_2.isAppealReport)(reasonType) && requester !== subject.did) { throw new xrpc_server_1.ForbiddenError('You cannot appeal this report'); } const db = ctx.db; await Promise.all([ assertValidReporter(ctx.modService(db), reasonType, requester), ctx.moderationServiceProfile().validateReasonType(reasonType), ]); const report = await db.transaction(async (dbTxn) => { const moderationTxn = ctx.modService(dbTxn); const { event: reportEvent, subjectStatus } = await moderationTxn.report({ reason, subject, reasonType, reportedBy: requester || ctx.cfg.service.did, modTool, }); const tagService = new tag_service_1.TagService(subject, subjectStatus, ctx.cfg.service.did, moderationTxn); await tagService.evaluateForSubject([(0, util_1.getTagForReport)(reasonType)]); return reportEvent; }); const body = ctx.modService(db).views.formatReport(report); return { encoding: 'application/json', body, }; }, }); } const assertValidReporter = async (modService, reasonType, did) => { const reporterStatus = await modService.getCurrentStatus({ did }); // If we don't have a mod status for the reporter, no need to do further checks if (!reporterStatus.length) { return; } // For appeals, we just need to make sure that the account does not have pending appeal if ((0, util_2.isAppealReport)(reasonType)) { if (reporterStatus[0]?.appealed) { throw new xrpc_server_1.ForbiddenError('Awaiting decision on previous appeal', 'AlreadyAppealed'); } return; } // For non appeals, we need to make sure the reporter account is not already in takendown status // This is necessary because we allow takendown accounts call createReport but that's only meant for appeals // and we need to make sure takendown accounts don't abuse this endpoint if (reporterStatus[0]?.takendown) { throw new xrpc_server_1.ForbiddenError('Report not accepted from takendown account', 'AccountTakedown'); } }; //# sourceMappingURL=createReport.js.map