@abyss-project/tools 2.1.0 → 2.2.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/dist/api/index.d.ts +4 -0
- package/dist/api/index.js +4 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/probe-scan.api.d.ts +15 -0
- package/dist/api/probe-scan.api.js +74 -0
- package/dist/api/probe-scan.api.js.map +1 -0
- package/dist/api/probe-scan.api.test.d.ts +1 -0
- package/dist/api/probe-scan.api.test.js +37 -0
- package/dist/api/probe-scan.api.test.js.map +1 -0
- package/dist/api/probe-scan.application.api.d.ts +7 -0
- package/dist/api/probe-scan.application.api.js +40 -0
- package/dist/api/probe-scan.application.api.js.map +1 -0
- package/dist/api/probe-scan.application.api.test.d.ts +1 -0
- package/dist/api/probe-scan.application.api.test.js +37 -0
- package/dist/api/probe-scan.application.api.test.js.map +1 -0
- package/dist/api/probe-webhook.api.d.ts +4 -0
- package/dist/api/probe-webhook.api.js +34 -0
- package/dist/api/probe-webhook.api.js.map +1 -0
- package/dist/api/probe-webhook.api.test.d.ts +1 -0
- package/dist/api/probe-webhook.api.test.js +33 -0
- package/dist/api/probe-webhook.api.test.js.map +1 -0
- package/dist/api/probe-webhook.application.api.d.ts +4 -0
- package/dist/api/probe-webhook.application.api.js +14 -0
- package/dist/api/probe-webhook.application.api.js.map +1 -0
- package/dist/api/probe-webhook.application.api.test.d.ts +1 -0
- package/dist/api/probe-webhook.application.api.test.js +33 -0
- package/dist/api/probe-webhook.application.api.test.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +32 -1
- package/dist/index.js.map +1 -1
- package/dist/types/enum/api-error.enum.d.ts +1 -5
- package/dist/types/enum/api-error.enum.js +0 -4
- package/dist/types/enum/api-error.enum.js.map +1 -1
- package/dist/types/enum/index.d.ts +1 -1
- package/dist/types/enum/index.js +1 -1
- package/dist/types/enum/index.js.map +1 -1
- package/dist/types/enum/probe-scan.enum.d.ts +14 -0
- package/dist/types/enum/probe-scan.enum.js +21 -0
- package/dist/types/enum/probe-scan.enum.js.map +1 -0
- package/dist/types/interface/api/requests/index.d.ts +2 -0
- package/dist/types/interface/api/requests/index.js +2 -0
- package/dist/types/interface/api/requests/index.js.map +1 -1
- package/dist/types/interface/api/requests/probe-scan.request.d.ts +22 -0
- package/dist/types/interface/api/{responses/file-scan.response.js → requests/probe-scan.request.js} +1 -1
- package/dist/types/interface/api/requests/probe-scan.request.js.map +1 -0
- package/dist/types/interface/api/requests/probe-webhook.request.d.ts +6 -0
- package/dist/types/{enum/file-scan-status.enum.js → interface/api/requests/probe-webhook.request.js} +1 -1
- package/dist/types/interface/api/requests/probe-webhook.request.js.map +1 -0
- package/dist/types/interface/api/responses/beam.response.d.ts +1 -3
- package/dist/types/interface/api/responses/index.d.ts +2 -0
- package/dist/types/interface/api/responses/index.js +2 -0
- package/dist/types/interface/api/responses/index.js.map +1 -1
- package/dist/types/interface/api/responses/probe-scan.response.d.ts +18 -0
- package/dist/types/interface/api/responses/probe-scan.response.js +3 -0
- package/dist/types/interface/api/responses/probe-scan.response.js.map +1 -0
- package/dist/types/interface/api/responses/probe-webhook.response.d.ts +10 -0
- package/dist/types/interface/api/responses/probe-webhook.response.js +3 -0
- package/dist/types/interface/api/responses/probe-webhook.response.js.map +1 -0
- package/dist/types/interface/models/atlas-document.dto.d.ts +0 -3
- package/dist/types/interface/models/beam.dto.d.ts +0 -3
- package/dist/types/interface/models/board-card-document.dto.d.ts +0 -3
- package/dist/types/interface/models/extraction.dto.d.ts +0 -2
- package/dist/types/interface/models/extraction.dto.js.map +1 -1
- package/dist/types/interface/models/index.d.ts +3 -0
- package/dist/types/interface/models/index.js +3 -0
- package/dist/types/interface/models/index.js.map +1 -1
- package/dist/types/interface/models/probe-scan.dto.d.ts +22 -0
- package/dist/types/interface/models/{file-scan.dto.js → probe-scan.dto.js} +1 -1
- package/dist/types/interface/models/probe-scan.dto.js.map +1 -0
- package/dist/types/interface/models/probe-webhook-delivery.dto.d.ts +7 -0
- package/dist/types/interface/models/probe-webhook-delivery.dto.js +3 -0
- package/dist/types/interface/models/probe-webhook-delivery.dto.js.map +1 -0
- package/dist/types/interface/models/probe-webhook.dto.d.ts +9 -0
- package/dist/types/interface/{api/requests/file-scan.request.js → models/probe-webhook.dto.js} +1 -1
- package/dist/types/interface/models/probe-webhook.dto.js.map +1 -0
- package/dist/types/tests/probe.dto.test.d.ts +1 -0
- package/dist/types/tests/probe.dto.test.js +62 -0
- package/dist/types/tests/probe.dto.test.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/probe-webhook-signature.utils.d.ts +8 -0
- package/dist/utils/probe-webhook-signature.utils.js +22 -0
- package/dist/utils/probe-webhook-signature.utils.js.map +1 -0
- package/package.json +1 -1
- package/src/api/index.ts +6 -0
- package/src/api/probe-scan.api.test.ts +21 -0
- package/src/api/probe-scan.api.ts +191 -0
- package/src/api/probe-scan.application.api.test.ts +21 -0
- package/src/api/probe-scan.application.api.ts +157 -0
- package/src/api/probe-webhook.api.test.ts +17 -0
- package/src/api/probe-webhook.api.ts +81 -0
- package/src/api/probe-webhook.application.api.test.ts +18 -0
- package/src/api/probe-webhook.application.api.ts +87 -0
- package/src/index.ts +86 -0
- package/src/types/enum/api-error.enum.ts +0 -25
- package/src/types/enum/index.ts +1 -1
- package/src/types/enum/probe-scan.enum.ts +44 -0
- package/src/types/interface/api/requests/index.ts +2 -0
- package/src/types/interface/api/requests/probe-scan.request.ts +50 -0
- package/src/types/interface/api/requests/probe-webhook.request.ts +12 -0
- package/src/types/interface/api/responses/beam.response.ts +1 -15
- package/src/types/interface/api/responses/index.ts +2 -0
- package/src/types/interface/api/responses/probe-scan.response.ts +38 -0
- package/src/types/interface/api/responses/probe-webhook.response.ts +17 -0
- package/src/types/interface/models/atlas-document.dto.ts +0 -18
- package/src/types/interface/models/beam.dto.ts +0 -22
- package/src/types/interface/models/board-card-document.dto.ts +0 -18
- package/src/types/interface/models/extraction.dto.ts +0 -17
- package/src/types/interface/models/index.ts +3 -0
- package/src/types/interface/models/probe-scan.dto.ts +48 -0
- package/src/types/interface/models/probe-webhook-delivery.dto.ts +26 -0
- package/src/types/interface/models/probe-webhook.dto.ts +25 -0
- package/src/types/tests/beam.dto.spec.ts +0 -2
- package/src/types/tests/probe.dto.test.ts +97 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/probe-webhook-signature.utils.ts +56 -0
- package/dist/api/file-scan.api.d.ts +0 -5
- package/dist/api/file-scan.api.js +0 -49
- package/dist/api/file-scan.api.js.map +0 -1
- package/dist/types/enum/analysis-status.enum.d.ts +0 -7
- package/dist/types/enum/analysis-status.enum.js +0 -12
- package/dist/types/enum/analysis-status.enum.js.map +0 -1
- package/dist/types/enum/file-scan-status.enum.d.ts +0 -1
- package/dist/types/enum/file-scan-status.enum.js.map +0 -1
- package/dist/types/interface/api/requests/file-scan.request.d.ts +0 -3
- package/dist/types/interface/api/requests/file-scan.request.js.map +0 -1
- package/dist/types/interface/api/responses/file-scan.response.d.ts +0 -7
- package/dist/types/interface/api/responses/file-scan.response.js.map +0 -1
- package/dist/types/interface/models/file-scan.dto.d.ts +0 -11
- package/dist/types/interface/models/file-scan.dto.js.map +0 -1
- package/src/types/enum/file-scan-status.enum.ts +0 -23
package/src/index.ts
CHANGED
|
@@ -32,6 +32,10 @@ import * as extractionApi from './api/extraction.api';
|
|
|
32
32
|
import * as extractionSettingsApi from './api/extraction-settings.api';
|
|
33
33
|
import * as extractionPlanPresetApi from './api/extraction-plan-preset.api';
|
|
34
34
|
import * as monitorApi from './api/monitor.api';
|
|
35
|
+
import * as probeScanApi from './api/probe-scan.api';
|
|
36
|
+
import * as probeWebhookApi from './api/probe-webhook.api';
|
|
37
|
+
import * as probeScanApplicationApi from './api/probe-scan.application.api';
|
|
38
|
+
import * as probeWebhookApplicationApi from './api/probe-webhook.application.api';
|
|
35
39
|
|
|
36
40
|
export * from './api';
|
|
37
41
|
export * from './types';
|
|
@@ -42,8 +46,24 @@ export * from './server-sent-events';
|
|
|
42
46
|
const DEFAULT_BASE_URL = 'https://tools-api.abyss-project.fr/api/';
|
|
43
47
|
|
|
44
48
|
export const API_KEY_HEADER = 'abyss-api-key';
|
|
49
|
+
/**
|
|
50
|
+
* Application-level API key header (Phase 3a — AbyssProbe application/API-key
|
|
51
|
+
* authentication). Same literal value every other Abyss service's own core
|
|
52
|
+
* package independently declares for its `ApplicationMiddleware` (abyss-
|
|
53
|
+
* storage, abyss-monitor, abyss-console — see
|
|
54
|
+
* probe-application.middleware.ts for the mirrored resolution logic).
|
|
55
|
+
*/
|
|
56
|
+
export const API_KEY_APPLICATION_HEADER = 'abyss-api-key-application';
|
|
45
57
|
export const ADMIN_TOKEN_HEADER = 'abyss-admin-token';
|
|
46
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Header carrying the HMAC-SHA256 signature of a probe webhook delivery's
|
|
61
|
+
* raw JSON body (see apps/api/src/services/probe-webhook-delivery.service.ts).
|
|
62
|
+
* Verify it with {@link verifyProbeWebhookSignature} (re-exported from './utils').
|
|
63
|
+
*/
|
|
64
|
+
export const PROBE_WEBHOOK_SIGNATURE_HEADER = 'x-probe-signature';
|
|
65
|
+
export const PROBE_WEBHOOK_SIGNATURE_ALGORITHM = 'sha256';
|
|
66
|
+
|
|
47
67
|
const NUMBER_RETRY_API = 10;
|
|
48
68
|
const BASE_DELAY_BETWEEN_RETRY = 5000;
|
|
49
69
|
const RETRY_CODES = [
|
|
@@ -316,6 +336,48 @@ type AbyssToolsCoreSDK = {
|
|
|
316
336
|
monitor: {
|
|
317
337
|
up: typeof monitorApi.upMonitor;
|
|
318
338
|
};
|
|
339
|
+
probe: {
|
|
340
|
+
/** `POST /scan` — sync (default) or async depending on `options.mode`. */
|
|
341
|
+
scan: typeof probeScanApi.scan;
|
|
342
|
+
/** `POST /scan` forced to `mode: sync` — precisely-typed 200 response. */
|
|
343
|
+
scanSync: typeof probeScanApi.scanSync;
|
|
344
|
+
/** `POST /scan?mode=async` — precisely-typed 202 response. */
|
|
345
|
+
scanAsync: typeof probeScanApi.scanAsync;
|
|
346
|
+
/** `GET /scan/:scanId` — poll a scan's status/verdict. */
|
|
347
|
+
getScan: typeof probeScanApi.getScan;
|
|
348
|
+
/** `GET /scan` — paginated history/search. */
|
|
349
|
+
listScans: typeof probeScanApi.listScans;
|
|
350
|
+
webhook: {
|
|
351
|
+
create: typeof probeWebhookApi.createProbeWebhook;
|
|
352
|
+
list: typeof probeWebhookApi.listProbeWebhook;
|
|
353
|
+
delete: typeof probeWebhookApi.deleteProbeWebhook;
|
|
354
|
+
};
|
|
355
|
+
/**
|
|
356
|
+
* Application/API-key-auth counterpart (Phase 3a) — for inter-service
|
|
357
|
+
* callers (abyss-storage, external integrations) instead of a
|
|
358
|
+
* personal/org session. Same request/response contracts as the methods
|
|
359
|
+
* above, hitting `/application/:applicationId/...` and authenticated
|
|
360
|
+
* with the `abyss-api-key-application` header ({@link
|
|
361
|
+
* API_KEY_APPLICATION_HEADER}) instead of the personal `abyss-api-key`.
|
|
362
|
+
*/
|
|
363
|
+
application: {
|
|
364
|
+
/** `POST /application/:applicationId/scan` — sync (default) or async depending on `options.mode`. */
|
|
365
|
+
scan: typeof probeScanApplicationApi.scanApplication;
|
|
366
|
+
/** `POST /application/:applicationId/scan` forced to `mode: sync` — precisely-typed 200 response. */
|
|
367
|
+
scanSync: typeof probeScanApplicationApi.scanSyncApplication;
|
|
368
|
+
/** `POST /application/:applicationId/scan?mode=async` — precisely-typed 202 response. */
|
|
369
|
+
scanAsync: typeof probeScanApplicationApi.scanAsyncApplication;
|
|
370
|
+
/** `GET /application/:applicationId/scan/:scanId` — poll a scan's status/verdict. */
|
|
371
|
+
getScan: typeof probeScanApplicationApi.getScanApplication;
|
|
372
|
+
/** `GET /application/:applicationId/scan` — paginated history/search. */
|
|
373
|
+
listScans: typeof probeScanApplicationApi.listScansApplication;
|
|
374
|
+
webhook: {
|
|
375
|
+
create: typeof probeWebhookApplicationApi.createProbeWebhookApplication;
|
|
376
|
+
list: typeof probeWebhookApplicationApi.listProbeWebhookApplication;
|
|
377
|
+
delete: typeof probeWebhookApplicationApi.deleteProbeWebhookApplication;
|
|
378
|
+
};
|
|
379
|
+
};
|
|
380
|
+
};
|
|
319
381
|
tag: {
|
|
320
382
|
list: typeof tagApi.listTag;
|
|
321
383
|
create: typeof tagApi.createTag;
|
|
@@ -707,6 +769,30 @@ export class AbyssToolsCore {
|
|
|
707
769
|
monitor: {
|
|
708
770
|
up: monitorApi.upMonitor,
|
|
709
771
|
},
|
|
772
|
+
probe: {
|
|
773
|
+
scan: probeScanApi.scan,
|
|
774
|
+
scanSync: probeScanApi.scanSync,
|
|
775
|
+
scanAsync: probeScanApi.scanAsync,
|
|
776
|
+
getScan: probeScanApi.getScan,
|
|
777
|
+
listScans: probeScanApi.listScans,
|
|
778
|
+
webhook: {
|
|
779
|
+
create: probeWebhookApi.createProbeWebhook,
|
|
780
|
+
list: probeWebhookApi.listProbeWebhook,
|
|
781
|
+
delete: probeWebhookApi.deleteProbeWebhook,
|
|
782
|
+
},
|
|
783
|
+
application: {
|
|
784
|
+
scan: probeScanApplicationApi.scanApplication,
|
|
785
|
+
scanSync: probeScanApplicationApi.scanSyncApplication,
|
|
786
|
+
scanAsync: probeScanApplicationApi.scanAsyncApplication,
|
|
787
|
+
getScan: probeScanApplicationApi.getScanApplication,
|
|
788
|
+
listScans: probeScanApplicationApi.listScansApplication,
|
|
789
|
+
webhook: {
|
|
790
|
+
create: probeWebhookApplicationApi.createProbeWebhookApplication,
|
|
791
|
+
list: probeWebhookApplicationApi.listProbeWebhookApplication,
|
|
792
|
+
delete: probeWebhookApplicationApi.deleteProbeWebhookApplication,
|
|
793
|
+
},
|
|
794
|
+
},
|
|
795
|
+
},
|
|
710
796
|
tag: {
|
|
711
797
|
list: tagApi.listTag,
|
|
712
798
|
create: tagApi.createTag,
|
|
@@ -20,29 +20,4 @@ export enum Code {
|
|
|
20
20
|
atlasDocumentLimitReached = 'atlas_document_limit_reached',
|
|
21
21
|
boardCardDocumentLimitReached = 'board_card_document_limit_reached',
|
|
22
22
|
boardCardMoveInvalidDestination = 'board_card_move_invalid_destination',
|
|
23
|
-
// AV v3 P2 async-enforce: thrown by assertNotPendingScan while a document's
|
|
24
|
-
// antivirus scan is still running (scanStatus === 'pending_scan'). Mapped
|
|
25
|
-
// to HTTP 423 in http-response-error.module.ts.
|
|
26
|
-
boardCardDocumentAnalysing = 'board_card_document_analysing',
|
|
27
|
-
atlasDocumentAnalysing = 'atlas_document_analysing',
|
|
28
|
-
// AV v3 P3 async-enforce: thrown by extractionFileService.assertNotPendingScan
|
|
29
|
-
// while an ARCHIVE-OWNED extraction_files row's antivirus scan is still
|
|
30
|
-
// running (scanStatus === 'pending_scan'). Gates only derived OUTPUTS
|
|
31
|
-
// (bundle/records/diff/export/share) — never the extraction metadata
|
|
32
|
-
// itself, which already ran synchronously before any verdict was known.
|
|
33
|
-
// Mapped to HTTP 423 in http-response-error.module.ts.
|
|
34
|
-
extractionFileAnalysing = 'extraction_file_analysing',
|
|
35
|
-
// AV v3 P3 async-enforce server backstop: thrown by
|
|
36
|
-
// beamUploadService.attachFiles when a resolved storage file's scanStatus
|
|
37
|
-
// is not PENDING_SCAN at attach time. AbyssBeam's presign is front-driven
|
|
38
|
-
// (resumable-upload.ts calls AbyssStorage directly, never through this
|
|
39
|
-
// backend), so a client could omit `antivirus: { scan: true }` on its own
|
|
40
|
-
// presign request; a properly-enrolled fresh upload is always
|
|
41
|
-
// PENDING_SCAN the moment attach is called (the async worker has not run
|
|
42
|
-
// yet), so anything else — most tellingly a null/absent scanStatus,
|
|
43
|
-
// meaning no scan was ever requested — means enrollment was bypassed and
|
|
44
|
-
// the attach is rejected outright. Not mapped in http-response-error
|
|
45
|
-
// .module.ts's statusByCode table, so it falls through to the default 400
|
|
46
|
-
// (a rejected request, not a "still analysing" 423 state).
|
|
47
|
-
beamFileNotEnrolled = 'beam_file_not_enrolled',
|
|
48
23
|
}
|
package/src/types/enum/index.ts
CHANGED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Mirrors apps/api/src/database/probe-scan.enum.ts EXACTLY (same string
|
|
2
|
+
// values — this SDK talks to that API over the wire, so the values must
|
|
3
|
+
// match byte-for-byte). Kept as a single file here too, on purpose: the
|
|
4
|
+
// server groups all three enums in one file for the same reason (they are
|
|
5
|
+
// one cohesive scan vocabulary), see that file's header comment.
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Antivirus scan verdict. `null` on the wire while the scan has not reached
|
|
9
|
+
* `DONE` yet (see {@link ProbeScanStatus}) — a scan that never completes
|
|
10
|
+
* (e.g. the engine throws) is left at its last real status with no
|
|
11
|
+
* fabricated verdict.
|
|
12
|
+
*/
|
|
13
|
+
export enum ProbeScanVerdict {
|
|
14
|
+
CLEAN = 'clean',
|
|
15
|
+
INFECTED = 'infected',
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* How the scan was (or will be) run: `SYNC` blocks the request until the
|
|
20
|
+
* engine returns the verdict inline; `ASYNC` queues the job and delivers the
|
|
21
|
+
* verdict later via a registered webhook and/or the per-request
|
|
22
|
+
* `callbackUrl`, and/or by polling `GET /scan/:scanId`.
|
|
23
|
+
*/
|
|
24
|
+
export enum ProbeScanMode {
|
|
25
|
+
SYNC = 'sync',
|
|
26
|
+
ASYNC = 'async',
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Scan lifecycle. A SYNC scan skips `QUEUED` entirely (created directly at
|
|
31
|
+
* `SCANNING`). An ASYNC scan is created at `QUEUED`, flipped to `SCANNING`
|
|
32
|
+
* once a worker picks the job off the queue, then to `DONE` or `ERROR`.
|
|
33
|
+
*
|
|
34
|
+
* `ERROR` (async-only) is a TERMINAL, no-verdict state — there is no
|
|
35
|
+
* automatic requeue/retry (the uploaded bytes are deleted the moment the job
|
|
36
|
+
* ends, success or failure). A caller that wants to retry submits a brand
|
|
37
|
+
* new `POST /scan?mode=async`.
|
|
38
|
+
*/
|
|
39
|
+
export enum ProbeScanStatus {
|
|
40
|
+
QUEUED = 'queued',
|
|
41
|
+
SCANNING = 'scanning',
|
|
42
|
+
DONE = 'done',
|
|
43
|
+
ERROR = 'error',
|
|
44
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ProbeScanMode, ProbeScanStatus, ProbeScanVerdict } from '../../../enum';
|
|
2
|
+
|
|
3
|
+
// Mirrors apps/api/src/api/controllers/probe-scan.controller.ts's ScanBody +
|
|
4
|
+
// HistoryQuery, and apps/api/src/api/validators/probe-scan.validator.ts's
|
|
5
|
+
// historyQuery() Joi schema (field names/optionality).
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Options accepted by `sdk.probe.scan(file, options)` — `POST /scan`. `mode`
|
|
9
|
+
* and `organizationId` travel as query params (`?mode=async&organization_id=`);
|
|
10
|
+
* `context` and `callbackUrl` travel as multipart text fields alongside the
|
|
11
|
+
* file — the sdk client handles that split, callers just pass one object.
|
|
12
|
+
*/
|
|
13
|
+
export interface IScanOptions {
|
|
14
|
+
/** sync (default — verdict returned inline) or async (queued, 202 + webhook/poll). */
|
|
15
|
+
mode?: ProbeScanMode;
|
|
16
|
+
/** Personal scope (default) or an organization the caller belongs to. */
|
|
17
|
+
organizationId?: string;
|
|
18
|
+
/** Free-form caller reference (e.g. `{ applicationFileId }`), stored verbatim. */
|
|
19
|
+
context?: Record<string, unknown>;
|
|
20
|
+
/** ASYNC-only per-request delivery override (https only). Ignored for a SYNC scan. */
|
|
21
|
+
callbackUrl?: string;
|
|
22
|
+
/** Filename reported to the server (defaults to `'file'`). Cosmetic only. */
|
|
23
|
+
filename?: string;
|
|
24
|
+
/** Content-Type hint used when constructing a Blob from a raw buffer/Uint8Array in a browser context. */
|
|
25
|
+
mimeType?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* `GET /scan` query — all filters optional, combined with AND.
|
|
30
|
+
* `contextKey`/`contextValue` must be supplied together (business-reference
|
|
31
|
+
* search inside the free-form `context` JSONB column) — supplying one
|
|
32
|
+
* without the other is rejected by the API (400).
|
|
33
|
+
*/
|
|
34
|
+
export interface IListScansQuery {
|
|
35
|
+
organizationId?: string;
|
|
36
|
+
verdict?: ProbeScanVerdict;
|
|
37
|
+
mode?: ProbeScanMode;
|
|
38
|
+
status?: ProbeScanStatus;
|
|
39
|
+
/** Date range on `createdAt`, inclusive at both ends. */
|
|
40
|
+
from?: Date;
|
|
41
|
+
to?: Date;
|
|
42
|
+
/** Case-insensitive partial match on the original file name. */
|
|
43
|
+
fileName?: string;
|
|
44
|
+
contextKey?: string;
|
|
45
|
+
contextValue?: string;
|
|
46
|
+
/** @default 1 */
|
|
47
|
+
page?: number;
|
|
48
|
+
/** @default 20, server max 200. */
|
|
49
|
+
limit?: number;
|
|
50
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Mirrors apps/api/src/api/controllers/probe-webhook.controller.ts's
|
|
2
|
+
// ScopeQuery/CreateBody and probe-webhook.validator.ts's Joi schemas.
|
|
3
|
+
|
|
4
|
+
/** Shared by create/list/delete — personal scope (default) or an organization. */
|
|
5
|
+
export interface IProbeWebhookScopeQuery {
|
|
6
|
+
organizationId?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface ICreateProbeWebhookBody {
|
|
10
|
+
/** HTTPS endpoint the verdict is POSTed to. Required, `https://` only. */
|
|
11
|
+
callbackUrl: string;
|
|
12
|
+
}
|
|
@@ -3,7 +3,6 @@ import { IResponse } from '../type-message/response';
|
|
|
3
3
|
import { IBeamTransfer, IBeamFile, IBeamRecipient } from '../../models/beam.dto';
|
|
4
4
|
import { IContentShare } from '../../models/content-share.dto';
|
|
5
5
|
import { BeamVisibility, BeamServeDenyReasonCode, BeamDownloadKind } from '../../../enum/beam.enum';
|
|
6
|
-
import { FileScanStatus } from '../../../enum/file-scan-status.enum';
|
|
7
6
|
|
|
8
7
|
export interface IGetBeamData {
|
|
9
8
|
beamTransfer: IBeamTransfer;
|
|
@@ -41,16 +40,7 @@ export type IFinalizeBeamResponse = IResponse<IFinalizeBeamData>;
|
|
|
41
40
|
// browser-facing view: no owner ids, no password/manage hashes; adds
|
|
42
41
|
// hasPassword/isLocked/hasThumbnail so the front can render the locked state.
|
|
43
42
|
export interface IBeamPublicFile {
|
|
44
|
-
|
|
45
|
-
// beam serve path that is not gated by beamServingService.gateFile (it is
|
|
46
|
-
// a metadata list, not a byte stream). Per the link-live-gate-per-file
|
|
47
|
-
// decision the share link itself always works, but a file whose own
|
|
48
|
-
// scanStatus is not (yet) CLEAN must not hand out a servable identifier:
|
|
49
|
-
// id is null and hasThumbnail is forced false so the front cannot build a
|
|
50
|
-
// download/thumb URL for a pending or quarantined file. A legacy NULL
|
|
51
|
-
// scanStatus (row written before this column existed) is treated as
|
|
52
|
-
// servable, matching gateFile.
|
|
53
|
-
id: string | null;
|
|
43
|
+
id: string;
|
|
54
44
|
name: string;
|
|
55
45
|
sizeOctet: number;
|
|
56
46
|
mimeType: string | null;
|
|
@@ -58,10 +48,6 @@ export interface IBeamPublicFile {
|
|
|
58
48
|
hasThumbnail: boolean;
|
|
59
49
|
width: number | null;
|
|
60
50
|
height: number | null;
|
|
61
|
-
// Exposed as-is (never redacted) regardless of servability, so the front
|
|
62
|
-
// can render an "analysing" placeholder for a withheld file instead of it
|
|
63
|
-
// just silently vanishing from the list.
|
|
64
|
-
scanStatus: FileScanStatus | null;
|
|
65
51
|
}
|
|
66
52
|
|
|
67
53
|
export interface IBeamPublicView {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { IResponse } from '../type-message/response';
|
|
2
|
+
import { BasePaginate } from '../type-message/base-paginate';
|
|
3
|
+
import { ProbeScanStatus, ProbeScanVerdict } from '../../../enum';
|
|
4
|
+
import { IProbeScanDetail, IProbeScanHistoryItem } from '../../models';
|
|
5
|
+
|
|
6
|
+
// Mirrors apps/api/src/api/controllers/probe-scan.controller.ts's local
|
|
7
|
+
// ScanSyncResponseData / ScanAsyncResponseData / GetScanResponseData /
|
|
8
|
+
// PaginateScanResponseData EXACTLY.
|
|
9
|
+
|
|
10
|
+
/** `POST /scan` (default, or explicit `?mode=sync`) — HTTP 200. */
|
|
11
|
+
export interface IScanSyncData {
|
|
12
|
+
scanId: string;
|
|
13
|
+
verdict: ProbeScanVerdict;
|
|
14
|
+
viruses: string[];
|
|
15
|
+
}
|
|
16
|
+
export type IScanSyncResponse = IResponse<IScanSyncData>;
|
|
17
|
+
|
|
18
|
+
/** `POST /scan?mode=async` — HTTP 202, job queued. */
|
|
19
|
+
export interface IScanAsyncData {
|
|
20
|
+
scanId: string;
|
|
21
|
+
status: ProbeScanStatus.QUEUED;
|
|
22
|
+
}
|
|
23
|
+
export type IScanAsyncResponse = IResponse<IScanAsyncData>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* `POST /scan`'s actual response body is one or the other of the two data
|
|
27
|
+
* shapes above, discriminated by the request's own `mode` (sync -> 200 +
|
|
28
|
+
* {@link IScanSyncData}, async -> 202 + {@link IScanAsyncData}). A caller
|
|
29
|
+
* that only ever uses one mode should prefer the sdk's `scanSync`/`scanAsync`
|
|
30
|
+
* wrappers, which return the precise, non-union type.
|
|
31
|
+
*/
|
|
32
|
+
export type IScanResponse = IScanSyncResponse | IScanAsyncResponse;
|
|
33
|
+
|
|
34
|
+
/** `GET /scan/:scanId` — HTTP 200. */
|
|
35
|
+
export type IGetScanResponse = IResponse<IProbeScanDetail>;
|
|
36
|
+
|
|
37
|
+
/** `GET /scan` — HTTP 200, paginated history/search. */
|
|
38
|
+
export type IPaginateScanResponse = IResponse<BasePaginate<IProbeScanHistoryItem>>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { IResponse } from '../type-message/response';
|
|
2
|
+
import { IProbeWebhook, IProbeWebhookCreated } from '../../models';
|
|
3
|
+
|
|
4
|
+
// Mirrors apps/api/src/api/controllers/probe-webhook.controller.ts's local
|
|
5
|
+
// response shapes EXACTLY.
|
|
6
|
+
|
|
7
|
+
/** `POST /webhook` — HTTP 201. The only response that ever carries `secret`. */
|
|
8
|
+
export type ICreateProbeWebhookResponse = IResponse<IProbeWebhookCreated>;
|
|
9
|
+
|
|
10
|
+
/** `GET /webhook` — HTTP 200. A flat scope-filtered list, NOT paginated. */
|
|
11
|
+
export interface IListProbeWebhookData {
|
|
12
|
+
webhooks: IProbeWebhook[];
|
|
13
|
+
}
|
|
14
|
+
export type IListProbeWebhookResponse = IResponse<IListProbeWebhookData>;
|
|
15
|
+
|
|
16
|
+
/** `DELETE /webhook/:webhookId` — HTTP 200. */
|
|
17
|
+
export type IDeleteProbeWebhookResponse = IResponse<{ ok: true }>;
|
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
import { IAtlasPage } from './atlas-page.dto';
|
|
2
2
|
import { IAtlas } from './atlas.dto';
|
|
3
|
-
import { FileScanStatus } from '../../enum/file-scan-status.enum';
|
|
4
3
|
|
|
5
4
|
export interface IAtlasDocument {
|
|
6
5
|
id: string;
|
|
7
6
|
atlasPageId: string;
|
|
8
7
|
atlasId: string;
|
|
9
8
|
name: string;
|
|
10
|
-
// AV v3 P2 async-enforce — WIRE CAVEAT: these 4 fields type as always-present
|
|
11
|
-
// here (the true, always-populated stored/model shape), but the HTTP JSON
|
|
12
|
-
// response actually redacts all four to `null` while scanStatus is
|
|
13
|
-
// 'pending_scan' (see the AtlasDocument model's toJSON() override) —
|
|
14
|
-
// pending_scan grants no servable identifier to any caller, owner included.
|
|
15
|
-
// A future front consumer of this DTO must treat them as possibly-null at
|
|
16
|
-
// runtime whenever scanStatus === 'pending_scan', despite the `string` type.
|
|
17
9
|
externalId: string;
|
|
18
10
|
publicAccessId: string;
|
|
19
11
|
thumbnailId: string | null;
|
|
@@ -21,16 +13,6 @@ export interface IAtlasDocument {
|
|
|
21
13
|
sizeOctet: number;
|
|
22
14
|
mimeType: string;
|
|
23
15
|
checksum: string;
|
|
24
|
-
// AV v3 P2 async-enforce: antivirus verdict mirrored from AbyssStorage,
|
|
25
|
-
// seeded pending_scan at the UPLOAD webhook, updated by applyScanResult /
|
|
26
|
-
// purgeInfected on the SCAN_RESULT webhook. Null for rows created before
|
|
27
|
-
// this column existed. See assertNotPendingScan for the 423 gate.
|
|
28
|
-
scanStatus: FileScanStatus | null;
|
|
29
|
-
// Id of the user who requested this upload (currentUser at presign time),
|
|
30
|
-
// resolved server-side — never client-supplied. Null for an API-key/
|
|
31
|
-
// anonymous upload. Used ONLY to notify the uploader if the file is later
|
|
32
|
-
// found infected (purgeInfected) — not a permission/ownership field.
|
|
33
|
-
uploadedByUserId: string | null;
|
|
34
16
|
createdAt?: Date;
|
|
35
17
|
updatedAt?: Date;
|
|
36
18
|
|
|
@@ -2,7 +2,6 @@ import { IOrganization } from './organization.dto';
|
|
|
2
2
|
import { IUser } from './user.dto';
|
|
3
3
|
import { IProject } from './project.dto';
|
|
4
4
|
import { BeamVisibility, BeamDownloadKind } from '../../enum/beam.enum';
|
|
5
|
-
import { FileScanStatus } from '../../enum/file-scan-status.enum';
|
|
6
5
|
|
|
7
6
|
export interface IBeamTransfer {
|
|
8
7
|
id: string;
|
|
@@ -39,13 +38,6 @@ export interface IBeamTransfer {
|
|
|
39
38
|
export interface IBeamFile {
|
|
40
39
|
id: string;
|
|
41
40
|
transferId: string;
|
|
42
|
-
// AV v3 P3 async-enforce — WIRE CAVEAT: typed as always-present here (the
|
|
43
|
-
// true, always-populated stored/model shape), but the HTTP JSON response
|
|
44
|
-
// actually redacts this (and thumbnailStorageFileId) to null while
|
|
45
|
-
// scanStatus is 'pending_scan' (see the BeamFile model's get() override) —
|
|
46
|
-
// pending_scan grants no servable identifier to any caller. A future front
|
|
47
|
-
// consumer of this DTO must treat it as possibly-null at runtime whenever
|
|
48
|
-
// scanStatus === 'pending_scan', despite the `string` type.
|
|
49
41
|
// abyss-storage applicationFileId (PRIVATE bucket); resolved at serve time (B4).
|
|
50
42
|
storageFileId: string;
|
|
51
43
|
thumbnailStorageFileId: string | null;
|
|
@@ -59,20 +51,6 @@ export interface IBeamFile {
|
|
|
59
51
|
position: number;
|
|
60
52
|
createdAt?: Date;
|
|
61
53
|
|
|
62
|
-
// AV v3 P3 async-enforce: antivirus verdict mirrored from AbyssStorage,
|
|
63
|
-
// seeded at attach time (beamUploadService#attachFiles — REQUIRES
|
|
64
|
-
// pending_scan, a server-side backstop against a client presign that
|
|
65
|
-
// omitted antivirus enrollment; see resumable-upload.ts) and updated by
|
|
66
|
-
// applyScanResult / purgeInfected on the SCAN_RESULT webhook. Null for
|
|
67
|
-
// rows created before this column existed. See
|
|
68
|
-
// beamServingService#gateFile for the per-file serve gate.
|
|
69
|
-
scanStatus: FileScanStatus | null;
|
|
70
|
-
// Id of the user who requested this attach (currentUser at attach time,
|
|
71
|
-
// resolved server-side — never client-supplied). Null for an anonymous
|
|
72
|
-
// transfer's attach. Used ONLY to notify the uploader if the file is later
|
|
73
|
-
// found infected (purgeInfected) — not a permission/ownership field.
|
|
74
|
-
uploadedByUserId: string | null;
|
|
75
|
-
|
|
76
54
|
transfer?: IBeamTransfer;
|
|
77
55
|
}
|
|
78
56
|
|
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
import { IBoardCard } from './board-card.dto';
|
|
2
2
|
import { IBoard } from './board.dto';
|
|
3
|
-
import { FileScanStatus } from '../../enum/file-scan-status.enum';
|
|
4
3
|
|
|
5
4
|
export interface IBoardCardDocument {
|
|
6
5
|
id: string;
|
|
7
6
|
boardCardId: string;
|
|
8
7
|
boardId: string;
|
|
9
8
|
name: string;
|
|
10
|
-
// AV v3 P2 async-enforce — WIRE CAVEAT: these 4 fields type as always-present
|
|
11
|
-
// here (the true, always-populated stored/model shape), but the HTTP JSON
|
|
12
|
-
// response actually redacts all four to `null` while scanStatus is
|
|
13
|
-
// 'pending_scan' (see the BoardCardDocument model's toJSON() override) —
|
|
14
|
-
// pending_scan grants no servable identifier to any caller, owner included.
|
|
15
|
-
// A future front consumer of this DTO must treat them as possibly-null at
|
|
16
|
-
// runtime whenever scanStatus === 'pending_scan', despite the `string` type.
|
|
17
9
|
externalId: string;
|
|
18
10
|
publicAccessId: string;
|
|
19
11
|
thumbnailId: string | null;
|
|
@@ -21,16 +13,6 @@ export interface IBoardCardDocument {
|
|
|
21
13
|
checksum: string;
|
|
22
14
|
mimeType: string;
|
|
23
15
|
sizeOctet: number;
|
|
24
|
-
// AV v3 P2 async-enforce: antivirus verdict mirrored from AbyssStorage,
|
|
25
|
-
// seeded pending_scan at the UPLOAD webhook, updated by applyScanResult /
|
|
26
|
-
// purgeInfected on the SCAN_RESULT webhook. Null for rows created before
|
|
27
|
-
// this column existed. See assertNotPendingScan for the 423 gate.
|
|
28
|
-
scanStatus: FileScanStatus | null;
|
|
29
|
-
// Id of the user who requested this upload (currentUser at presign time),
|
|
30
|
-
// resolved server-side — never client-supplied. Null for an API-key/
|
|
31
|
-
// anonymous upload. Used ONLY to notify the uploader if the file is later
|
|
32
|
-
// found infected (purgeInfected) — not a permission/ownership field.
|
|
33
|
-
uploadedByUserId: string | null;
|
|
34
16
|
updatedAt?: Date;
|
|
35
17
|
createdAt?: Date;
|
|
36
18
|
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
import { ExtractionWarningCode } from '../../../types/enum/extraction-warning.enum';
|
|
7
7
|
import { ExtractionFeedbackIssueType } from '../../../types/enum/extraction-feedback-issue-type.enum';
|
|
8
8
|
import { DocumentType } from '../../../types/enum/document-type.enum';
|
|
9
|
-
import { FileScanStatus } from '../../enum/file-scan-status.enum';
|
|
10
9
|
import type { IFieldValue, IExecutionManifest, IGlobalConfidence } from './extraction-plan.dto';
|
|
11
10
|
|
|
12
11
|
// Re-export so consumers can import ExtractionFeedbackIssueType from the DTO barrel.
|
|
@@ -67,13 +66,6 @@ export interface IExtractionFile {
|
|
|
67
66
|
pdfMimeType: string;
|
|
68
67
|
pdfPageCount: number | null;
|
|
69
68
|
pdfFilename: string | null;
|
|
70
|
-
// AV v3 P3 async-enforce — WIRE CAVEAT: typed always-present here (the
|
|
71
|
-
// stored/model shape), but the HTTP JSON response redacts this to `null`
|
|
72
|
-
// while scanStatus is 'pending_scan' (see the ExtractionFile model's
|
|
73
|
-
// get() override) — pending_scan grants no servable identifier to any
|
|
74
|
-
// caller, owner included. Never gated for a by-reference (caller-owned)
|
|
75
|
-
// file: AbyssExtract never mirrors a scan verdict locally for those (see
|
|
76
|
-
// scanStatus below), gating on the caller's live verdict instead.
|
|
77
69
|
applicationFileId: string | null;
|
|
78
70
|
userExternalId: string | null;
|
|
79
71
|
userMetadata: Record<string, unknown> | null;
|
|
@@ -82,15 +74,6 @@ export interface IExtractionFile {
|
|
|
82
74
|
detectedIban: string | null;
|
|
83
75
|
detectedBic: string | null;
|
|
84
76
|
detectedCurrency: string | null;
|
|
85
|
-
// AV v3 P3 async-enforce: antivirus verdict mirrored from AbyssStorage for
|
|
86
|
-
// an ARCHIVE-OWNED file only (seeded at extractionFileService.upsert from
|
|
87
|
-
// the archive-upload response — see extraction-extract.service.ts#archivePdf).
|
|
88
|
-
// Null for by-reference files (gated live on the caller's own verdict
|
|
89
|
-
// instead — no local mirror, since AbyssExtract never receives a
|
|
90
|
-
// SCAN_RESULT webhook for a file it did not request the scan for) and for
|
|
91
|
-
// rows created before this column existed. See assertNotPendingScan for
|
|
92
|
-
// the 423 gate this enables on derived-output endpoints.
|
|
93
|
-
scanStatus: FileScanStatus | null;
|
|
94
77
|
createdAt: string;
|
|
95
78
|
updatedAt: string;
|
|
96
79
|
}
|
|
@@ -32,3 +32,6 @@ export * from './content-share.dto';
|
|
|
32
32
|
export * from './extraction.dto';
|
|
33
33
|
export * from './extraction-plan.dto';
|
|
34
34
|
export * from './extraction-spatial-template.dto';
|
|
35
|
+
export * from './probe-scan.dto';
|
|
36
|
+
export * from './probe-webhook.dto';
|
|
37
|
+
export * from './probe-webhook-delivery.dto';
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ProbeScanMode, ProbeScanStatus, ProbeScanVerdict } from '../../enum';
|
|
2
|
+
|
|
3
|
+
// Mirrors apps/api/src/api/controllers/probe-scan.controller.ts's local
|
|
4
|
+
// response interfaces. AbyssProbe deliberately returns TWO different scan
|
|
5
|
+
// shapes depending on the endpoint — never the raw `probe_scans` row, and
|
|
6
|
+
// never a single one-size-fits-all model — so this file mirrors that with
|
|
7
|
+
// two distinct interfaces rather than forcing one canonical "IProbeScan".
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* `GET /scan/:scanId` shape (poll the queued -> scanning -> done/error
|
|
11
|
+
* progression). Deliberately minimal: no fileName/fileSize/mimeType/mode/
|
|
12
|
+
* timestamps, no internal ownership columns (userId/organizationId/
|
|
13
|
+
* callbackUrl) — a caller polling by id already knows what it submitted.
|
|
14
|
+
*/
|
|
15
|
+
export interface IProbeScanDetail {
|
|
16
|
+
scanId: string;
|
|
17
|
+
status: ProbeScanStatus;
|
|
18
|
+
/** null until `status` is DONE. */
|
|
19
|
+
verdict: ProbeScanVerdict | null;
|
|
20
|
+
/** null until `status` is DONE; [] when DONE and clean. */
|
|
21
|
+
viruses: string[] | null;
|
|
22
|
+
/** Free-form caller reference echoed back verbatim (see IProbeScanHistoryItem#context). */
|
|
23
|
+
context: Record<string, unknown> | null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* One row of `GET /scan`'s paginated history/search list. Richer than
|
|
28
|
+
* {@link IProbeScanDetail} (adds fileName/fileSize/mimeType/mode/timestamps)
|
|
29
|
+
* but still never echoes internal ownership columns (userId, organizationId,
|
|
30
|
+
* callbackUrl) — a caller already knows their own scope from the request
|
|
31
|
+
* they made.
|
|
32
|
+
*/
|
|
33
|
+
export interface IProbeScanHistoryItem {
|
|
34
|
+
scanId: string;
|
|
35
|
+
fileName: string;
|
|
36
|
+
fileSize: number;
|
|
37
|
+
mimeType: string;
|
|
38
|
+
verdict: ProbeScanVerdict | null;
|
|
39
|
+
viruses: string[] | null;
|
|
40
|
+
mode: ProbeScanMode;
|
|
41
|
+
status: ProbeScanStatus;
|
|
42
|
+
context: Record<string, unknown> | null;
|
|
43
|
+
/** Set the moment the engine call starts (SYNC: row-creation time; ASYNC: when a worker picks the job off the queue). */
|
|
44
|
+
startedAt: Date;
|
|
45
|
+
/** Set once the engine call returns. null while status is not DONE. */
|
|
46
|
+
finishedAt: Date | null;
|
|
47
|
+
createdAt: Date;
|
|
48
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ProbeScanVerdict } from '../../enum';
|
|
2
|
+
|
|
3
|
+
// Mirrors apps/api/src/services/probe-webhook-delivery.service.ts's
|
|
4
|
+
// ProbeWebhookPayload EXACTLY (same field set, same JSON.stringify'd body a
|
|
5
|
+
// receiver's raw request body will deserialize into) — this is the payload
|
|
6
|
+
// AbyssProbe POSTs to every registered webhook's `callbackUrl` (and to a
|
|
7
|
+
// scan's own per-request `callbackUrl`, see probe-scan docs) once an ASYNC
|
|
8
|
+
// scan reaches a verdict (`status: DONE`).
|
|
9
|
+
//
|
|
10
|
+
// `verdict` is typed as the concrete enum here (not `string` like the
|
|
11
|
+
// server's internal type) because delivery only ever happens on a DONE scan,
|
|
12
|
+
// where the verdict is always set — see dispatchProbeScanWebhooks's guard.
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Body of a webhook delivery, signed via HMAC-SHA256 of
|
|
16
|
+
* `JSON.stringify(payload)` — see {@link PROBE_WEBHOOK_SIGNATURE_HEADER} and
|
|
17
|
+
* {@link verifyProbeWebhookSignature} (this package's root / utils).
|
|
18
|
+
*/
|
|
19
|
+
export interface IProbeWebhookDeliveryPayload {
|
|
20
|
+
scanId: string;
|
|
21
|
+
/** Free-form caller reference, echoed back verbatim (see IProbeScanHistoryItem#context). */
|
|
22
|
+
context: Record<string, unknown> | null;
|
|
23
|
+
verdict: ProbeScanVerdict;
|
|
24
|
+
/** [] when clean. */
|
|
25
|
+
viruses: string[];
|
|
26
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Mirrors apps/api/src/api/controllers/probe-webhook.controller.ts's local
|
|
2
|
+
// WebhookResponseData / CreateWebhookResponseData. Public shape of a
|
|
3
|
+
// registered `probe_webhooks` row — never carries `secret` except right
|
|
4
|
+
// after creation (see IProbeWebhookCreated below); never echoes the
|
|
5
|
+
// internal ownership columns (userId/organizationId/applicationId) either,
|
|
6
|
+
// same discipline as the scan models.
|
|
7
|
+
|
|
8
|
+
export interface IProbeWebhook {
|
|
9
|
+
id: string;
|
|
10
|
+
/** HTTPS endpoint the verdict is POSTed to. */
|
|
11
|
+
callbackUrl: string;
|
|
12
|
+
/** Disabled webhooks are skipped by dispatch (soft-off, not deleted). */
|
|
13
|
+
active: boolean;
|
|
14
|
+
createdAt: Date;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Create-only response shape: the ONE time `secret` is ever returned by the
|
|
19
|
+
* API ("Secret generated server-side, returned once on create"). Store it
|
|
20
|
+
* immediately — there is no reset-secret / re-reveal endpoint (see this
|
|
21
|
+
* package's header note on the deliberately small CRUD surface).
|
|
22
|
+
*/
|
|
23
|
+
export interface IProbeWebhookCreated extends IProbeWebhook {
|
|
24
|
+
secret: string;
|
|
25
|
+
}
|