-
Notifications
You must be signed in to change notification settings - Fork 47
[196] Add reported NCMEC media to a hash bank #1208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
fdc0603
2246834
dda7dbb
e3047ca
7f31f62
6fe382f
14434a0
9fd4122
0a83309
4fb0e40
67d0a78
1e3e14b
05ccced
e5f1225
4422e09
3cc0687
3a241e7
f4edc7a
1e49f86
31d310a
26e5056
a28f240
34b8ed6
65aad73
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,6 +48,11 @@ gql` | |
| contactPersonPhone | ||
| mediaReviewRequirement | ||
| minMediaToReview | ||
| reportedMediaHashBankId | ||
| } | ||
| hashBanks { | ||
| id | ||
| name | ||
| } | ||
| myOrg { | ||
| hasNCMECReportingEnabled | ||
|
|
@@ -83,6 +88,7 @@ type NcmecSettings = { | |
| contactPersonPhone: string; | ||
| mediaReviewRequirement: GQLNcmecMediaReviewRequirement; | ||
| minMediaToReview: string; | ||
| reportedMediaHashBankId: string; | ||
| }; | ||
|
|
||
| export default function NCMECSettings() { | ||
|
|
@@ -104,6 +110,7 @@ export default function NCMECSettings() { | |
| contactPersonPhone: '', | ||
| mediaReviewRequirement: GQLNcmecMediaReviewRequirement.All, | ||
| minMediaToReview: '1', | ||
| reportedMediaHashBankId: '', | ||
| }); | ||
|
|
||
| const { loading, error, data } = useGQLNcmecOrgSettingsQuery({ | ||
|
|
@@ -149,6 +156,8 @@ export default function NCMECSettings() { | |
| data.ncmecOrgSettings.mediaReviewRequirement ?? | ||
| GQLNcmecMediaReviewRequirement.All, | ||
| minMediaToReview: String(data.ncmecOrgSettings.minMediaToReview ?? 1), | ||
| reportedMediaHashBankId: | ||
| data.ncmecOrgSettings.reportedMediaHashBankId?.toString() ?? '', | ||
| }); | ||
| } | ||
| }, [data?.ncmecOrgSettings]); | ||
|
|
@@ -237,6 +246,9 @@ export default function NCMECSettings() { | |
| contactPersonPhone: settings.contactPersonPhone || null, | ||
| mediaReviewRequirement: settings.mediaReviewRequirement, | ||
| minMediaToReview: isMinimumPolicy ? parsedMinMedia : null, | ||
| reportedMediaHashBankId: settings.reportedMediaHashBankId | ||
| ? Number(settings.reportedMediaHashBankId) | ||
| : null, | ||
| }, | ||
| }, | ||
| }); | ||
|
|
@@ -573,6 +585,43 @@ export default function NCMECSettings() { | |
| </Text> | ||
| </div> | ||
|
|
||
| <div className="flex flex-col gap-2"> | ||
| <Label | ||
| htmlFor="reportedMediaHashBankId" | ||
| className="text-sm font-medium" | ||
| > | ||
| Hash bank for reported media | ||
| </Label> | ||
| <Select | ||
| value={settings.reportedMediaHashBankId || '__none__'} | ||
| onValueChange={(value) => | ||
| setSettings({ | ||
| ...settings, | ||
| reportedMediaHashBankId: value === '__none__' ? '' : value, | ||
| }) | ||
| } | ||
| > | ||
| <SelectTrigger id="reportedMediaHashBankId"> | ||
| <SelectValue placeholder="Don't add reported media to a bank" /> | ||
| </SelectTrigger> | ||
| <SelectContent> | ||
| <SelectItem value="__none__"> | ||
| Don't add reported media to a bank | ||
| </SelectItem> | ||
| {(data?.hashBanks ?? []).map((bank) => ( | ||
| <SelectItem key={bank.id} value={bank.id}> | ||
| {bank.name} | ||
| </SelectItem> | ||
| ))} | ||
| </SelectContent> | ||
| </Select> | ||
| <Text size="XS" className="text-gray-500"> | ||
| Media from each report accepted by NCMEC is added to this bank so | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this might be a bit off -- should it be "Media from each report sent to NCMEC"?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I left it as "accepted," since that is the moment the media is stored, nothing is added if NCMEC rejects the report. This also aligns with the documentation you suggested in |
||
| it can be matched if it is uploaded again. Only applies when | ||
| reports are sent to the NCMEC production endpoint. | ||
| </Text> | ||
| </div> | ||
|
|
||
| <div className="flex flex-col gap-2"> | ||
| <Label | ||
| htmlFor="defaultInternetDetailType" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| ALTER TABLE ncmec_reporting.ncmec_org_settings | ||
| ADD COLUMN IF NOT EXISTS reported_media_hash_bank_id integer NULL; | ||
|
|
||
| DO $$ | ||
| BEGIN | ||
| ALTER TABLE ncmec_reporting.ncmec_org_settings | ||
| ADD CONSTRAINT ncmec_org_settings_reported_media_hash_bank_fkey | ||
| FOREIGN KEY (reported_media_hash_bank_id) | ||
| REFERENCES public.hash_banks(id) | ||
| ON DELETE SET NULL; | ||
| EXCEPTION | ||
| WHEN duplicate_object THEN NULL; | ||
| END $$; | ||
|
|
||
| COMMENT ON COLUMN ncmec_reporting.ncmec_org_settings.reported_media_hash_bank_id IS | ||
| 'When set, media from accepted production NCMEC reports is added to this hash bank.'; |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,6 +33,10 @@ import { | |
| makeItemSubmissionBulkWrite, | ||
| type ItemSubmissionBulkWrite, | ||
| } from '../queues/itemSubmissionQueue.js'; | ||
| import { | ||
| makeReportedMediaBankingEnqueue, | ||
| type ReportedMediaBankingEnqueue, | ||
| } from '../queues/reportedMediaBankingQueue.js'; | ||
| import makeActionPublisher, { | ||
| type ActionPublisher, | ||
| type ActionTargetItem, | ||
|
|
@@ -348,6 +352,8 @@ export interface Dependencies { | |
|
|
||
| itemSubmissionQueueBulkWrite: ItemSubmissionBulkWrite; | ||
| itemSubmissionRetryQueueBulkWrite: ItemSubmissionBulkWrite; | ||
| /** Enqueues media of accepted NCMEC reports for hash banking. */ | ||
| reportedMediaBankingEnqueue: ReportedMediaBankingEnqueue; | ||
| IORedis: IORedis.Redis | Cluster; | ||
| /** | ||
| * Dedicated ioredis client for the items-async enqueue path. Same Redis | ||
|
|
@@ -740,6 +746,11 @@ export default async function getBottle( | |
| bottle.factory('itemSubmissionRetryQueueBulkWrite', (container) => | ||
| makeItemSubmissionBulkWrite(container.IORedis, ITEM_SUBMISSION_DLQ_NAME), | ||
| ); | ||
| // Enqueued from the NCMEC submission path, so a Redis outage has to fail | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i'm not sure i follow this comment! can you explain what the intent is in case of a redis outage? IMO, we should not add special handling for postgres or redis downtime. those two services are so fundamental to how coop works, we can safely assume they're up or everything breaks anyway. |
||
| // fast instead of buffering and holding up an accepted report. | ||
| bottle.factory('reportedMediaBankingEnqueue', (container) => | ||
| makeReportedMediaBankingEnqueue(container.IORedisEnqueueNoBuffer), | ||
| ); | ||
|
|
||
| // Loggers | ||
| register(bottle, 'RuleExecutionLogger', makeRuleExecutionLogger); | ||
|
|
@@ -1745,6 +1756,7 @@ export default async function getBottle( | |
| 'Scylla', | ||
| 'itemSubmissionQueueBulkWrite', | ||
| 'itemSubmissionRetryQueueBulkWrite', | ||
| 'reportedMediaBankingEnqueue', | ||
| 'IORedis', | ||
| 'IORedisEnqueueNoBuffer', | ||
| // Storage abstractions | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as in another comment -- shouldn't this be a number?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The value sent to the API is a number now, but this one is string because the
Select. So I keep it as a string here and convert on submit likeminMediaToReviewabove works the same way.