@oxyhq/crowdsource-contracts 0.1.0
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/README.md +129 -0
- package/dist/case-envelope.d.ts +1130 -0
- package/dist/case-envelope.d.ts.map +1 -0
- package/dist/case-envelope.js +383 -0
- package/dist/case-envelope.js.map +1 -0
- package/dist/decisions.d.ts +353 -0
- package/dist/decisions.d.ts.map +1 -0
- package/dist/decisions.js +198 -0
- package/dist/decisions.js.map +1 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/json-schema.d.ts +43 -0
- package/dist/json-schema.d.ts.map +1 -0
- package/dist/json-schema.js +83 -0
- package/dist/json-schema.js.map +1 -0
- package/dist/policies.d.ts +286 -0
- package/dist/policies.d.ts.map +1 -0
- package/dist/policies.js +178 -0
- package/dist/policies.js.map +1 -0
- package/dist/primitives.d.ts +185 -0
- package/dist/primitives.d.ts.map +1 -0
- package/dist/primitives.js +231 -0
- package/dist/primitives.js.map +1 -0
- package/dist/reputation-events.d.ts +349 -0
- package/dist/reputation-events.d.ts.map +1 -0
- package/dist/reputation-events.js +128 -0
- package/dist/reputation-events.js.map +1 -0
- package/dist/resources.d.ts +484 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +436 -0
- package/dist/resources.js.map +1 -0
- package/dist/reviews.d.ts +276 -0
- package/dist/reviews.d.ts.map +1 -0
- package/dist/reviews.js +144 -0
- package/dist/reviews.js.map +1 -0
- package/dist/taxonomy.d.ts +266 -0
- package/dist/taxonomy.d.ts.map +1 -0
- package/dist/taxonomy.js +282 -0
- package/dist/taxonomy.js.map +1 -0
- package/dist/webhooks.d.ts +604 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +192 -0
- package/dist/webhooks.js.map +1 -0
- package/package.json +56 -0
- package/src/case-envelope.ts +433 -0
- package/src/decisions.ts +216 -0
- package/src/index.ts +45 -0
- package/src/json-schema.ts +89 -0
- package/src/policies.ts +203 -0
- package/src/primitives.ts +283 -0
- package/src/reputation-events.ts +144 -0
- package/src/resources.ts +489 -0
- package/src/reviews.ts +159 -0
- package/src/taxonomy.ts +313 -0
- package/src/webhooks.ts +215 -0
|
@@ -0,0 +1,604 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Outbound webhooks (§10.6–§10.9) and the signature contract (§10.8).
|
|
3
|
+
*
|
|
4
|
+
* §10.11 asks for two behaviours that pull in opposite directions: unknown
|
|
5
|
+
* EVENTS must be ignored safely, and unknown FIELDS must not break clients.
|
|
6
|
+
* This module gives each its own schema rather than compromising on one.
|
|
7
|
+
*
|
|
8
|
+
* * `WebhookEventEnvelopeSchema` validates only what every event has —
|
|
9
|
+
* identity, type, timing, tenant — and leaves `data` opaque. A receiver
|
|
10
|
+
* verifies the signature, records the event id for idempotency, and ignores
|
|
11
|
+
* what it does not recognise, without a schema update ever being the reason
|
|
12
|
+
* a delivery fails.
|
|
13
|
+
* * `KnownWebhookEventSchema` is the discriminated union of the eight events
|
|
14
|
+
* §10.6 defines, for the branch that actually handles one.
|
|
15
|
+
*
|
|
16
|
+
* Everything here is `.loose()`. These payloads travel from CrowdSource to a
|
|
17
|
+
* tenant, so an unknown field is a newer server, not an attack; stripping it
|
|
18
|
+
* would silently discard data from a receiver that persists `event.data` for
|
|
19
|
+
* later processing — which is precisely what §10.8's "respond 2xx quickly and
|
|
20
|
+
* queue the processing" tells receivers to do.
|
|
21
|
+
*/
|
|
22
|
+
import { z } from 'zod';
|
|
23
|
+
/** §10.6. */
|
|
24
|
+
export declare const WEBHOOK_EVENT_TYPES: readonly ["report.received", "case.created", "case.escalated", "case.decided", "decision.corrected", "appeal.created", "appeal.decided", "case.closed"];
|
|
25
|
+
export declare const WebhookEventTypeSchema: z.ZodEnum<{
|
|
26
|
+
"report.received": "report.received";
|
|
27
|
+
"case.created": "case.created";
|
|
28
|
+
"case.escalated": "case.escalated";
|
|
29
|
+
"case.decided": "case.decided";
|
|
30
|
+
"decision.corrected": "decision.corrected";
|
|
31
|
+
"appeal.created": "appeal.created";
|
|
32
|
+
"appeal.decided": "appeal.decided";
|
|
33
|
+
"case.closed": "case.closed";
|
|
34
|
+
}>;
|
|
35
|
+
export type WebhookEventType = z.infer<typeof WebhookEventTypeSchema>;
|
|
36
|
+
/**
|
|
37
|
+
* Any event type, including ones this version of the contract does not know.
|
|
38
|
+
*
|
|
39
|
+
* Shape-checked but not enumerated, so that "unknown events must be ignored
|
|
40
|
+
* safely" is something a receiver can DO rather than something it is told about
|
|
41
|
+
* after its parse has already thrown.
|
|
42
|
+
*/
|
|
43
|
+
export declare const AnyWebhookEventTypeSchema: z.ZodString;
|
|
44
|
+
/**
|
|
45
|
+
* The envelope every delivery shares (§10.7), with `data` left opaque.
|
|
46
|
+
*
|
|
47
|
+
* Parse with this first. `id` is the idempotency key §10.8 requires receivers
|
|
48
|
+
* to store; `type` decides whether there is anything to do.
|
|
49
|
+
*/
|
|
50
|
+
export declare const WebhookEventEnvelopeSchema: z.ZodObject<{
|
|
51
|
+
type: z.ZodString;
|
|
52
|
+
data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
53
|
+
id: z.ZodString;
|
|
54
|
+
createdAt: z.ZodISODateTime;
|
|
55
|
+
organizationId: z.ZodString;
|
|
56
|
+
applicationId: z.ZodString;
|
|
57
|
+
}, z.core.$loose>;
|
|
58
|
+
export type WebhookEventEnvelope = z.infer<typeof WebhookEventEnvelopeSchema>;
|
|
59
|
+
/**
|
|
60
|
+
* The eight events of §10.6, discriminated on `type`.
|
|
61
|
+
*
|
|
62
|
+
* Only `case.decided` has its payload specified in the plan (§10.7). The other
|
|
63
|
+
* seven carry the case they are about and whatever identifies the object that
|
|
64
|
+
* moved; they are loose, so filling them in later is additive and needs no
|
|
65
|
+
* version bump (§10.11).
|
|
66
|
+
*/
|
|
67
|
+
export declare const KnownWebhookEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
68
|
+
type: z.ZodLiteral<"report.received">;
|
|
69
|
+
data: z.ZodObject<{
|
|
70
|
+
reportId: z.ZodString;
|
|
71
|
+
caseId: z.ZodString;
|
|
72
|
+
status: z.ZodEnum<{
|
|
73
|
+
received: "received";
|
|
74
|
+
merged: "merged";
|
|
75
|
+
invalid: "invalid";
|
|
76
|
+
withdrawn: "withdrawn";
|
|
77
|
+
closed: "closed";
|
|
78
|
+
}>;
|
|
79
|
+
merged: z.ZodBoolean;
|
|
80
|
+
}, z.core.$loose>;
|
|
81
|
+
id: z.ZodString;
|
|
82
|
+
createdAt: z.ZodISODateTime;
|
|
83
|
+
organizationId: z.ZodString;
|
|
84
|
+
applicationId: z.ZodString;
|
|
85
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
86
|
+
type: z.ZodLiteral<"case.created">;
|
|
87
|
+
data: z.ZodObject<{
|
|
88
|
+
caseId: z.ZodString;
|
|
89
|
+
}, z.core.$loose>;
|
|
90
|
+
id: z.ZodString;
|
|
91
|
+
createdAt: z.ZodISODateTime;
|
|
92
|
+
organizationId: z.ZodString;
|
|
93
|
+
applicationId: z.ZodString;
|
|
94
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
95
|
+
type: z.ZodLiteral<"case.escalated">;
|
|
96
|
+
data: z.ZodObject<{
|
|
97
|
+
caseId: z.ZodString;
|
|
98
|
+
}, z.core.$loose>;
|
|
99
|
+
id: z.ZodString;
|
|
100
|
+
createdAt: z.ZodISODateTime;
|
|
101
|
+
organizationId: z.ZodString;
|
|
102
|
+
applicationId: z.ZodString;
|
|
103
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
104
|
+
type: z.ZodLiteral<"case.decided">;
|
|
105
|
+
data: z.ZodObject<{
|
|
106
|
+
caseId: z.ZodString;
|
|
107
|
+
decision: z.ZodObject<{
|
|
108
|
+
id: z.ZodString;
|
|
109
|
+
caseId: z.ZodString;
|
|
110
|
+
revision: z.ZodNumber;
|
|
111
|
+
status: z.ZodEnum<{
|
|
112
|
+
provisional: "provisional";
|
|
113
|
+
final: "final";
|
|
114
|
+
superseded: "superseded";
|
|
115
|
+
corrected: "corrected";
|
|
116
|
+
}>;
|
|
117
|
+
outcome: z.ZodEnum<{
|
|
118
|
+
violation: "violation";
|
|
119
|
+
no_violation: "no_violation";
|
|
120
|
+
insufficient_context: "insufficient_context";
|
|
121
|
+
content_unavailable: "content_unavailable";
|
|
122
|
+
inconclusive: "inconclusive";
|
|
123
|
+
duplicate: "duplicate";
|
|
124
|
+
escalated: "escalated";
|
|
125
|
+
}>;
|
|
126
|
+
contextSufficiency: z.ZodEnum<{
|
|
127
|
+
sufficient: "sufficient";
|
|
128
|
+
insufficient: "insufficient";
|
|
129
|
+
}>;
|
|
130
|
+
confidence: z.ZodNumber;
|
|
131
|
+
findings: z.ZodArray<z.ZodObject<{
|
|
132
|
+
code: z.ZodEnum<{
|
|
133
|
+
"integrity.spam": "integrity.spam";
|
|
134
|
+
"integrity.scam": "integrity.scam";
|
|
135
|
+
"integrity.fraud": "integrity.fraud";
|
|
136
|
+
"integrity.impersonation": "integrity.impersonation";
|
|
137
|
+
"integrity.coordinated_manipulation": "integrity.coordinated_manipulation";
|
|
138
|
+
"harassment.insult": "harassment.insult";
|
|
139
|
+
"harassment.targeted_abuse": "harassment.targeted_abuse";
|
|
140
|
+
"harassment.sexual_harassment": "harassment.sexual_harassment";
|
|
141
|
+
"harassment.doxxing": "harassment.doxxing";
|
|
142
|
+
"harassment.credible_threat": "harassment.credible_threat";
|
|
143
|
+
"hate.dehumanization": "hate.dehumanization";
|
|
144
|
+
"hate.slur": "hate.slur";
|
|
145
|
+
"hate.incitement": "hate.incitement";
|
|
146
|
+
"hate.protected_targeting": "hate.protected_targeting";
|
|
147
|
+
"violence.graphic": "violence.graphic";
|
|
148
|
+
"violence.threat": "violence.threat";
|
|
149
|
+
"violence.instruction": "violence.instruction";
|
|
150
|
+
"violence.celebration": "violence.celebration";
|
|
151
|
+
"sexual_content.nudity": "sexual_content.nudity";
|
|
152
|
+
"sexual_content.explicit_activity": "sexual_content.explicit_activity";
|
|
153
|
+
"sexual_content.non_consensual": "sexual_content.non_consensual";
|
|
154
|
+
"sexual_content.exploitation": "sexual_content.exploitation";
|
|
155
|
+
"child_safety.sexualization": "child_safety.sexualization";
|
|
156
|
+
"child_safety.grooming": "child_safety.grooming";
|
|
157
|
+
"child_safety.exploitation": "child_safety.exploitation";
|
|
158
|
+
"self_harm.promotion": "self_harm.promotion";
|
|
159
|
+
"self_harm.instruction": "self_harm.instruction";
|
|
160
|
+
"self_harm.imminent_risk": "self_harm.imminent_risk";
|
|
161
|
+
"privacy.personal_information": "privacy.personal_information";
|
|
162
|
+
"privacy.intimate_media": "privacy.intimate_media";
|
|
163
|
+
"privacy.location_exposure": "privacy.location_exposure";
|
|
164
|
+
"commerce.prohibited_item": "commerce.prohibited_item";
|
|
165
|
+
"commerce.counterfeit": "commerce.counterfeit";
|
|
166
|
+
"commerce.misleading_listing": "commerce.misleading_listing";
|
|
167
|
+
"commerce.unsafe_product": "commerce.unsafe_product";
|
|
168
|
+
"platform_abuse.ban_evasion": "platform_abuse.ban_evasion";
|
|
169
|
+
"platform_abuse.report_abuse": "platform_abuse.report_abuse";
|
|
170
|
+
"platform_abuse.automation_abuse": "platform_abuse.automation_abuse";
|
|
171
|
+
"other.policy_specific": "other.policy_specific";
|
|
172
|
+
"other.unclassifiable": "other.unclassifiable";
|
|
173
|
+
}>;
|
|
174
|
+
resourceIds: z.ZodArray<z.ZodString>;
|
|
175
|
+
severity: z.ZodEnum<{
|
|
176
|
+
low: "low";
|
|
177
|
+
medium: "medium";
|
|
178
|
+
high: "high";
|
|
179
|
+
critical: "critical";
|
|
180
|
+
}>;
|
|
181
|
+
context: z.ZodOptional<z.ZodEnum<{
|
|
182
|
+
artistic: "artistic";
|
|
183
|
+
educational: "educational";
|
|
184
|
+
documentary: "documentary";
|
|
185
|
+
newsworthy: "newsworthy";
|
|
186
|
+
satire: "satire";
|
|
187
|
+
counter_speech: "counter_speech";
|
|
188
|
+
medical: "medical";
|
|
189
|
+
consensual: "consensual";
|
|
190
|
+
fictional: "fictional";
|
|
191
|
+
}>>;
|
|
192
|
+
scope: z.ZodEnum<{
|
|
193
|
+
application_local: "application_local";
|
|
194
|
+
oxy_network: "oxy_network";
|
|
195
|
+
identity_integrity: "identity_integrity";
|
|
196
|
+
}>;
|
|
197
|
+
attribution: z.ZodOptional<z.ZodEnum<{
|
|
198
|
+
author: "author";
|
|
199
|
+
reporter: "reporter";
|
|
200
|
+
reviewer: "reviewer";
|
|
201
|
+
}>>;
|
|
202
|
+
policyRuleIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
203
|
+
}, z.core.$loose>>;
|
|
204
|
+
recommendedActions: z.ZodArray<z.ZodObject<{
|
|
205
|
+
action: z.ZodEnum<{
|
|
206
|
+
remove_or_restrict: "remove_or_restrict";
|
|
207
|
+
allow_with_label: "allow_with_label";
|
|
208
|
+
remove: "remove";
|
|
209
|
+
hide: "hide";
|
|
210
|
+
label: "label";
|
|
211
|
+
age_gate: "age_gate";
|
|
212
|
+
reduce_distribution: "reduce_distribution";
|
|
213
|
+
freeze_transaction: "freeze_transaction";
|
|
214
|
+
suspend_user: "suspend_user";
|
|
215
|
+
request_changes: "request_changes";
|
|
216
|
+
allow: "allow";
|
|
217
|
+
restore: "restore";
|
|
218
|
+
no_action: "no_action";
|
|
219
|
+
request_more_context: "request_more_context";
|
|
220
|
+
hold: "hold";
|
|
221
|
+
local_manual_review: "local_manual_review";
|
|
222
|
+
keep_restricted_temporarily: "keep_restricted_temporarily";
|
|
223
|
+
escalate: "escalate";
|
|
224
|
+
no_global_effect: "no_global_effect";
|
|
225
|
+
specialist_queue: "specialist_queue";
|
|
226
|
+
legal_queue: "legal_queue";
|
|
227
|
+
safety_queue: "safety_queue";
|
|
228
|
+
}>;
|
|
229
|
+
targetResourceIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
230
|
+
}, z.core.$loose>>;
|
|
231
|
+
jury: z.ZodObject<{
|
|
232
|
+
size: z.ZodNumber;
|
|
233
|
+
decisiveVotes: z.ZodNumber;
|
|
234
|
+
winningVotes: z.ZodNumber;
|
|
235
|
+
agreement: z.ZodNumber;
|
|
236
|
+
specialistPresent: z.ZodBoolean;
|
|
237
|
+
}, z.core.$loose>;
|
|
238
|
+
policyVersions: z.ZodObject<{
|
|
239
|
+
taxonomy: z.ZodString;
|
|
240
|
+
application: z.ZodString;
|
|
241
|
+
oxyConduct: z.ZodString;
|
|
242
|
+
}, z.core.$loose>;
|
|
243
|
+
supersedesDecisionId: z.ZodOptional<z.ZodString>;
|
|
244
|
+
publishedAt: z.ZodISODateTime;
|
|
245
|
+
}, z.core.$loose>;
|
|
246
|
+
}, z.core.$loose>;
|
|
247
|
+
id: z.ZodString;
|
|
248
|
+
createdAt: z.ZodISODateTime;
|
|
249
|
+
organizationId: z.ZodString;
|
|
250
|
+
applicationId: z.ZodString;
|
|
251
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
252
|
+
type: z.ZodLiteral<"decision.corrected">;
|
|
253
|
+
data: z.ZodObject<{
|
|
254
|
+
caseId: z.ZodString;
|
|
255
|
+
decision: z.ZodObject<{
|
|
256
|
+
id: z.ZodString;
|
|
257
|
+
caseId: z.ZodString;
|
|
258
|
+
revision: z.ZodNumber;
|
|
259
|
+
status: z.ZodEnum<{
|
|
260
|
+
provisional: "provisional";
|
|
261
|
+
final: "final";
|
|
262
|
+
superseded: "superseded";
|
|
263
|
+
corrected: "corrected";
|
|
264
|
+
}>;
|
|
265
|
+
outcome: z.ZodEnum<{
|
|
266
|
+
violation: "violation";
|
|
267
|
+
no_violation: "no_violation";
|
|
268
|
+
insufficient_context: "insufficient_context";
|
|
269
|
+
content_unavailable: "content_unavailable";
|
|
270
|
+
inconclusive: "inconclusive";
|
|
271
|
+
duplicate: "duplicate";
|
|
272
|
+
escalated: "escalated";
|
|
273
|
+
}>;
|
|
274
|
+
contextSufficiency: z.ZodEnum<{
|
|
275
|
+
sufficient: "sufficient";
|
|
276
|
+
insufficient: "insufficient";
|
|
277
|
+
}>;
|
|
278
|
+
confidence: z.ZodNumber;
|
|
279
|
+
findings: z.ZodArray<z.ZodObject<{
|
|
280
|
+
code: z.ZodEnum<{
|
|
281
|
+
"integrity.spam": "integrity.spam";
|
|
282
|
+
"integrity.scam": "integrity.scam";
|
|
283
|
+
"integrity.fraud": "integrity.fraud";
|
|
284
|
+
"integrity.impersonation": "integrity.impersonation";
|
|
285
|
+
"integrity.coordinated_manipulation": "integrity.coordinated_manipulation";
|
|
286
|
+
"harassment.insult": "harassment.insult";
|
|
287
|
+
"harassment.targeted_abuse": "harassment.targeted_abuse";
|
|
288
|
+
"harassment.sexual_harassment": "harassment.sexual_harassment";
|
|
289
|
+
"harassment.doxxing": "harassment.doxxing";
|
|
290
|
+
"harassment.credible_threat": "harassment.credible_threat";
|
|
291
|
+
"hate.dehumanization": "hate.dehumanization";
|
|
292
|
+
"hate.slur": "hate.slur";
|
|
293
|
+
"hate.incitement": "hate.incitement";
|
|
294
|
+
"hate.protected_targeting": "hate.protected_targeting";
|
|
295
|
+
"violence.graphic": "violence.graphic";
|
|
296
|
+
"violence.threat": "violence.threat";
|
|
297
|
+
"violence.instruction": "violence.instruction";
|
|
298
|
+
"violence.celebration": "violence.celebration";
|
|
299
|
+
"sexual_content.nudity": "sexual_content.nudity";
|
|
300
|
+
"sexual_content.explicit_activity": "sexual_content.explicit_activity";
|
|
301
|
+
"sexual_content.non_consensual": "sexual_content.non_consensual";
|
|
302
|
+
"sexual_content.exploitation": "sexual_content.exploitation";
|
|
303
|
+
"child_safety.sexualization": "child_safety.sexualization";
|
|
304
|
+
"child_safety.grooming": "child_safety.grooming";
|
|
305
|
+
"child_safety.exploitation": "child_safety.exploitation";
|
|
306
|
+
"self_harm.promotion": "self_harm.promotion";
|
|
307
|
+
"self_harm.instruction": "self_harm.instruction";
|
|
308
|
+
"self_harm.imminent_risk": "self_harm.imminent_risk";
|
|
309
|
+
"privacy.personal_information": "privacy.personal_information";
|
|
310
|
+
"privacy.intimate_media": "privacy.intimate_media";
|
|
311
|
+
"privacy.location_exposure": "privacy.location_exposure";
|
|
312
|
+
"commerce.prohibited_item": "commerce.prohibited_item";
|
|
313
|
+
"commerce.counterfeit": "commerce.counterfeit";
|
|
314
|
+
"commerce.misleading_listing": "commerce.misleading_listing";
|
|
315
|
+
"commerce.unsafe_product": "commerce.unsafe_product";
|
|
316
|
+
"platform_abuse.ban_evasion": "platform_abuse.ban_evasion";
|
|
317
|
+
"platform_abuse.report_abuse": "platform_abuse.report_abuse";
|
|
318
|
+
"platform_abuse.automation_abuse": "platform_abuse.automation_abuse";
|
|
319
|
+
"other.policy_specific": "other.policy_specific";
|
|
320
|
+
"other.unclassifiable": "other.unclassifiable";
|
|
321
|
+
}>;
|
|
322
|
+
resourceIds: z.ZodArray<z.ZodString>;
|
|
323
|
+
severity: z.ZodEnum<{
|
|
324
|
+
low: "low";
|
|
325
|
+
medium: "medium";
|
|
326
|
+
high: "high";
|
|
327
|
+
critical: "critical";
|
|
328
|
+
}>;
|
|
329
|
+
context: z.ZodOptional<z.ZodEnum<{
|
|
330
|
+
artistic: "artistic";
|
|
331
|
+
educational: "educational";
|
|
332
|
+
documentary: "documentary";
|
|
333
|
+
newsworthy: "newsworthy";
|
|
334
|
+
satire: "satire";
|
|
335
|
+
counter_speech: "counter_speech";
|
|
336
|
+
medical: "medical";
|
|
337
|
+
consensual: "consensual";
|
|
338
|
+
fictional: "fictional";
|
|
339
|
+
}>>;
|
|
340
|
+
scope: z.ZodEnum<{
|
|
341
|
+
application_local: "application_local";
|
|
342
|
+
oxy_network: "oxy_network";
|
|
343
|
+
identity_integrity: "identity_integrity";
|
|
344
|
+
}>;
|
|
345
|
+
attribution: z.ZodOptional<z.ZodEnum<{
|
|
346
|
+
author: "author";
|
|
347
|
+
reporter: "reporter";
|
|
348
|
+
reviewer: "reviewer";
|
|
349
|
+
}>>;
|
|
350
|
+
policyRuleIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
351
|
+
}, z.core.$loose>>;
|
|
352
|
+
recommendedActions: z.ZodArray<z.ZodObject<{
|
|
353
|
+
action: z.ZodEnum<{
|
|
354
|
+
remove_or_restrict: "remove_or_restrict";
|
|
355
|
+
allow_with_label: "allow_with_label";
|
|
356
|
+
remove: "remove";
|
|
357
|
+
hide: "hide";
|
|
358
|
+
label: "label";
|
|
359
|
+
age_gate: "age_gate";
|
|
360
|
+
reduce_distribution: "reduce_distribution";
|
|
361
|
+
freeze_transaction: "freeze_transaction";
|
|
362
|
+
suspend_user: "suspend_user";
|
|
363
|
+
request_changes: "request_changes";
|
|
364
|
+
allow: "allow";
|
|
365
|
+
restore: "restore";
|
|
366
|
+
no_action: "no_action";
|
|
367
|
+
request_more_context: "request_more_context";
|
|
368
|
+
hold: "hold";
|
|
369
|
+
local_manual_review: "local_manual_review";
|
|
370
|
+
keep_restricted_temporarily: "keep_restricted_temporarily";
|
|
371
|
+
escalate: "escalate";
|
|
372
|
+
no_global_effect: "no_global_effect";
|
|
373
|
+
specialist_queue: "specialist_queue";
|
|
374
|
+
legal_queue: "legal_queue";
|
|
375
|
+
safety_queue: "safety_queue";
|
|
376
|
+
}>;
|
|
377
|
+
targetResourceIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
378
|
+
}, z.core.$loose>>;
|
|
379
|
+
jury: z.ZodObject<{
|
|
380
|
+
size: z.ZodNumber;
|
|
381
|
+
decisiveVotes: z.ZodNumber;
|
|
382
|
+
winningVotes: z.ZodNumber;
|
|
383
|
+
agreement: z.ZodNumber;
|
|
384
|
+
specialistPresent: z.ZodBoolean;
|
|
385
|
+
}, z.core.$loose>;
|
|
386
|
+
policyVersions: z.ZodObject<{
|
|
387
|
+
taxonomy: z.ZodString;
|
|
388
|
+
application: z.ZodString;
|
|
389
|
+
oxyConduct: z.ZodString;
|
|
390
|
+
}, z.core.$loose>;
|
|
391
|
+
supersedesDecisionId: z.ZodOptional<z.ZodString>;
|
|
392
|
+
publishedAt: z.ZodISODateTime;
|
|
393
|
+
}, z.core.$loose>;
|
|
394
|
+
}, z.core.$loose>;
|
|
395
|
+
id: z.ZodString;
|
|
396
|
+
createdAt: z.ZodISODateTime;
|
|
397
|
+
organizationId: z.ZodString;
|
|
398
|
+
applicationId: z.ZodString;
|
|
399
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
400
|
+
type: z.ZodLiteral<"appeal.created">;
|
|
401
|
+
data: z.ZodObject<{
|
|
402
|
+
caseId: z.ZodString;
|
|
403
|
+
appealId: z.ZodString;
|
|
404
|
+
}, z.core.$loose>;
|
|
405
|
+
id: z.ZodString;
|
|
406
|
+
createdAt: z.ZodISODateTime;
|
|
407
|
+
organizationId: z.ZodString;
|
|
408
|
+
applicationId: z.ZodString;
|
|
409
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
410
|
+
type: z.ZodLiteral<"appeal.decided">;
|
|
411
|
+
data: z.ZodObject<{
|
|
412
|
+
caseId: z.ZodString;
|
|
413
|
+
appealId: z.ZodString;
|
|
414
|
+
decision: z.ZodObject<{
|
|
415
|
+
id: z.ZodString;
|
|
416
|
+
caseId: z.ZodString;
|
|
417
|
+
revision: z.ZodNumber;
|
|
418
|
+
status: z.ZodEnum<{
|
|
419
|
+
provisional: "provisional";
|
|
420
|
+
final: "final";
|
|
421
|
+
superseded: "superseded";
|
|
422
|
+
corrected: "corrected";
|
|
423
|
+
}>;
|
|
424
|
+
outcome: z.ZodEnum<{
|
|
425
|
+
violation: "violation";
|
|
426
|
+
no_violation: "no_violation";
|
|
427
|
+
insufficient_context: "insufficient_context";
|
|
428
|
+
content_unavailable: "content_unavailable";
|
|
429
|
+
inconclusive: "inconclusive";
|
|
430
|
+
duplicate: "duplicate";
|
|
431
|
+
escalated: "escalated";
|
|
432
|
+
}>;
|
|
433
|
+
contextSufficiency: z.ZodEnum<{
|
|
434
|
+
sufficient: "sufficient";
|
|
435
|
+
insufficient: "insufficient";
|
|
436
|
+
}>;
|
|
437
|
+
confidence: z.ZodNumber;
|
|
438
|
+
findings: z.ZodArray<z.ZodObject<{
|
|
439
|
+
code: z.ZodEnum<{
|
|
440
|
+
"integrity.spam": "integrity.spam";
|
|
441
|
+
"integrity.scam": "integrity.scam";
|
|
442
|
+
"integrity.fraud": "integrity.fraud";
|
|
443
|
+
"integrity.impersonation": "integrity.impersonation";
|
|
444
|
+
"integrity.coordinated_manipulation": "integrity.coordinated_manipulation";
|
|
445
|
+
"harassment.insult": "harassment.insult";
|
|
446
|
+
"harassment.targeted_abuse": "harassment.targeted_abuse";
|
|
447
|
+
"harassment.sexual_harassment": "harassment.sexual_harassment";
|
|
448
|
+
"harassment.doxxing": "harassment.doxxing";
|
|
449
|
+
"harassment.credible_threat": "harassment.credible_threat";
|
|
450
|
+
"hate.dehumanization": "hate.dehumanization";
|
|
451
|
+
"hate.slur": "hate.slur";
|
|
452
|
+
"hate.incitement": "hate.incitement";
|
|
453
|
+
"hate.protected_targeting": "hate.protected_targeting";
|
|
454
|
+
"violence.graphic": "violence.graphic";
|
|
455
|
+
"violence.threat": "violence.threat";
|
|
456
|
+
"violence.instruction": "violence.instruction";
|
|
457
|
+
"violence.celebration": "violence.celebration";
|
|
458
|
+
"sexual_content.nudity": "sexual_content.nudity";
|
|
459
|
+
"sexual_content.explicit_activity": "sexual_content.explicit_activity";
|
|
460
|
+
"sexual_content.non_consensual": "sexual_content.non_consensual";
|
|
461
|
+
"sexual_content.exploitation": "sexual_content.exploitation";
|
|
462
|
+
"child_safety.sexualization": "child_safety.sexualization";
|
|
463
|
+
"child_safety.grooming": "child_safety.grooming";
|
|
464
|
+
"child_safety.exploitation": "child_safety.exploitation";
|
|
465
|
+
"self_harm.promotion": "self_harm.promotion";
|
|
466
|
+
"self_harm.instruction": "self_harm.instruction";
|
|
467
|
+
"self_harm.imminent_risk": "self_harm.imminent_risk";
|
|
468
|
+
"privacy.personal_information": "privacy.personal_information";
|
|
469
|
+
"privacy.intimate_media": "privacy.intimate_media";
|
|
470
|
+
"privacy.location_exposure": "privacy.location_exposure";
|
|
471
|
+
"commerce.prohibited_item": "commerce.prohibited_item";
|
|
472
|
+
"commerce.counterfeit": "commerce.counterfeit";
|
|
473
|
+
"commerce.misleading_listing": "commerce.misleading_listing";
|
|
474
|
+
"commerce.unsafe_product": "commerce.unsafe_product";
|
|
475
|
+
"platform_abuse.ban_evasion": "platform_abuse.ban_evasion";
|
|
476
|
+
"platform_abuse.report_abuse": "platform_abuse.report_abuse";
|
|
477
|
+
"platform_abuse.automation_abuse": "platform_abuse.automation_abuse";
|
|
478
|
+
"other.policy_specific": "other.policy_specific";
|
|
479
|
+
"other.unclassifiable": "other.unclassifiable";
|
|
480
|
+
}>;
|
|
481
|
+
resourceIds: z.ZodArray<z.ZodString>;
|
|
482
|
+
severity: z.ZodEnum<{
|
|
483
|
+
low: "low";
|
|
484
|
+
medium: "medium";
|
|
485
|
+
high: "high";
|
|
486
|
+
critical: "critical";
|
|
487
|
+
}>;
|
|
488
|
+
context: z.ZodOptional<z.ZodEnum<{
|
|
489
|
+
artistic: "artistic";
|
|
490
|
+
educational: "educational";
|
|
491
|
+
documentary: "documentary";
|
|
492
|
+
newsworthy: "newsworthy";
|
|
493
|
+
satire: "satire";
|
|
494
|
+
counter_speech: "counter_speech";
|
|
495
|
+
medical: "medical";
|
|
496
|
+
consensual: "consensual";
|
|
497
|
+
fictional: "fictional";
|
|
498
|
+
}>>;
|
|
499
|
+
scope: z.ZodEnum<{
|
|
500
|
+
application_local: "application_local";
|
|
501
|
+
oxy_network: "oxy_network";
|
|
502
|
+
identity_integrity: "identity_integrity";
|
|
503
|
+
}>;
|
|
504
|
+
attribution: z.ZodOptional<z.ZodEnum<{
|
|
505
|
+
author: "author";
|
|
506
|
+
reporter: "reporter";
|
|
507
|
+
reviewer: "reviewer";
|
|
508
|
+
}>>;
|
|
509
|
+
policyRuleIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
510
|
+
}, z.core.$loose>>;
|
|
511
|
+
recommendedActions: z.ZodArray<z.ZodObject<{
|
|
512
|
+
action: z.ZodEnum<{
|
|
513
|
+
remove_or_restrict: "remove_or_restrict";
|
|
514
|
+
allow_with_label: "allow_with_label";
|
|
515
|
+
remove: "remove";
|
|
516
|
+
hide: "hide";
|
|
517
|
+
label: "label";
|
|
518
|
+
age_gate: "age_gate";
|
|
519
|
+
reduce_distribution: "reduce_distribution";
|
|
520
|
+
freeze_transaction: "freeze_transaction";
|
|
521
|
+
suspend_user: "suspend_user";
|
|
522
|
+
request_changes: "request_changes";
|
|
523
|
+
allow: "allow";
|
|
524
|
+
restore: "restore";
|
|
525
|
+
no_action: "no_action";
|
|
526
|
+
request_more_context: "request_more_context";
|
|
527
|
+
hold: "hold";
|
|
528
|
+
local_manual_review: "local_manual_review";
|
|
529
|
+
keep_restricted_temporarily: "keep_restricted_temporarily";
|
|
530
|
+
escalate: "escalate";
|
|
531
|
+
no_global_effect: "no_global_effect";
|
|
532
|
+
specialist_queue: "specialist_queue";
|
|
533
|
+
legal_queue: "legal_queue";
|
|
534
|
+
safety_queue: "safety_queue";
|
|
535
|
+
}>;
|
|
536
|
+
targetResourceIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
537
|
+
}, z.core.$loose>>;
|
|
538
|
+
jury: z.ZodObject<{
|
|
539
|
+
size: z.ZodNumber;
|
|
540
|
+
decisiveVotes: z.ZodNumber;
|
|
541
|
+
winningVotes: z.ZodNumber;
|
|
542
|
+
agreement: z.ZodNumber;
|
|
543
|
+
specialistPresent: z.ZodBoolean;
|
|
544
|
+
}, z.core.$loose>;
|
|
545
|
+
policyVersions: z.ZodObject<{
|
|
546
|
+
taxonomy: z.ZodString;
|
|
547
|
+
application: z.ZodString;
|
|
548
|
+
oxyConduct: z.ZodString;
|
|
549
|
+
}, z.core.$loose>;
|
|
550
|
+
supersedesDecisionId: z.ZodOptional<z.ZodString>;
|
|
551
|
+
publishedAt: z.ZodISODateTime;
|
|
552
|
+
}, z.core.$loose>;
|
|
553
|
+
}, z.core.$loose>;
|
|
554
|
+
id: z.ZodString;
|
|
555
|
+
createdAt: z.ZodISODateTime;
|
|
556
|
+
organizationId: z.ZodString;
|
|
557
|
+
applicationId: z.ZodString;
|
|
558
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
559
|
+
type: z.ZodLiteral<"case.closed">;
|
|
560
|
+
data: z.ZodObject<{
|
|
561
|
+
caseId: z.ZodString;
|
|
562
|
+
}, z.core.$loose>;
|
|
563
|
+
id: z.ZodString;
|
|
564
|
+
createdAt: z.ZodISODateTime;
|
|
565
|
+
organizationId: z.ZodString;
|
|
566
|
+
applicationId: z.ZodString;
|
|
567
|
+
}, z.core.$loose>], "type">;
|
|
568
|
+
export type KnownWebhookEvent = z.infer<typeof KnownWebhookEventSchema>;
|
|
569
|
+
/** §10.8 headers, in their canonical casing. HTTP header names are case-insensitive; look them up accordingly. */
|
|
570
|
+
export declare const WEBHOOK_EVENT_ID_HEADER = "X-CrowdSource-Event-Id";
|
|
571
|
+
export declare const WEBHOOK_TIMESTAMP_HEADER = "X-CrowdSource-Timestamp";
|
|
572
|
+
export declare const WEBHOOK_SIGNATURE_HEADER = "X-CrowdSource-Signature";
|
|
573
|
+
/** The signature scheme prefix, as in `v1=<hex>`. */
|
|
574
|
+
export declare const WEBHOOK_SIGNATURE_VERSION = "v1";
|
|
575
|
+
/** §10.8: reject timestamps more than five minutes away from now. */
|
|
576
|
+
export declare const WEBHOOK_TIMESTAMP_TOLERANCE_SECONDS = 300;
|
|
577
|
+
/** Unix seconds, as the header carries them. */
|
|
578
|
+
export declare const WebhookTimestampHeaderSchema: z.ZodString;
|
|
579
|
+
/** `v1=<64 lowercase hex>` — HMAC-SHA256 of the signed payload. */
|
|
580
|
+
export declare const WebhookSignatureHeaderSchema: z.ZodString;
|
|
581
|
+
/**
|
|
582
|
+
* The exact bytes both sides sign: `timestamp + "." + rawBody` (§10.8).
|
|
583
|
+
*
|
|
584
|
+
* This lives in the contract, not in the signer or the verifier, because a
|
|
585
|
+
* disagreement between those two about what gets signed is invisible until
|
|
586
|
+
* every delivery starts failing — or, far worse, until a signature validates
|
|
587
|
+
* over bytes that are not the ones the receiver goes on to parse. There is no
|
|
588
|
+
* cryptography here and no transport; the HMAC belongs to the backend's signer
|
|
589
|
+
* and the SDK's middleware.
|
|
590
|
+
*
|
|
591
|
+
* `timestamp` is the header value VERBATIM. Re-deriving it from a parsed number
|
|
592
|
+
* is the mistake this signature exists to catch, and the receiver must verify
|
|
593
|
+
* over exactly what arrived.
|
|
594
|
+
*/
|
|
595
|
+
export declare function buildWebhookSignedPayload(timestamp: string, rawBody: string): string;
|
|
596
|
+
/**
|
|
597
|
+
* §10.9's backoff, in seconds after the initial attempt.
|
|
598
|
+
*
|
|
599
|
+
* Published behaviour a tenant plans around, so it belongs to the contract
|
|
600
|
+
* rather than to the delivery worker. After the last one the delivery is
|
|
601
|
+
* `dead_letter`, the tenant is alerted, and replay is manual.
|
|
602
|
+
*/
|
|
603
|
+
export declare const WEBHOOK_RETRY_SCHEDULE_SECONDS: readonly number[];
|
|
604
|
+
//# sourceMappingURL=webhooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,aAAa;AACb,eAAO,MAAM,mBAAmB,yJAStB,CAAC;AACX,eAAO,MAAM,sBAAsB;;;;;;;;;EAA8B,CAAC;AAClE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,aAI+C,CAAC;AAStF;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B;;;;;;;iBAIrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAoE9E;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BASlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,kHAAkH;AAClH,eAAO,MAAM,uBAAuB,2BAA2B,CAAC;AAChE,eAAO,MAAM,wBAAwB,4BAA4B,CAAC;AAClE,eAAO,MAAM,wBAAwB,4BAA4B,CAAC;AAElE,qDAAqD;AACrD,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAE9C,qEAAqE;AACrE,eAAO,MAAM,mCAAmC,MAAM,CAAC;AAEvD,gDAAgD;AAChD,eAAO,MAAM,4BAA4B,aAEQ,CAAC;AAElD,mEAAmE;AACnE,eAAO,MAAM,4BAA4B,aAE6C,CAAC;AAEvF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpF;AAED;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B,EAAE,SAAS,MAAM,EAO1D,CAAC"}
|