@abyss-project/probe 2.0.0 → 3.0.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/.eslintrc.js +32 -32
- package/.prettierrc +5 -5
- package/README.md +22 -22
- package/dist/api/index.d.ts +2 -1
- package/dist/api/index.js +2 -1
- package/dist/api/index.js.map +1 -1
- package/dist/api/probe-delivery-subscription.api.d.ts +11 -0
- package/dist/api/probe-delivery-subscription.api.js +42 -0
- package/dist/api/probe-delivery-subscription.api.js.map +1 -0
- package/dist/api/probe-delivery-subscription.application.api.d.ts +11 -0
- package/dist/api/probe-delivery-subscription.application.api.js +38 -0
- package/dist/api/probe-delivery-subscription.application.api.js.map +1 -0
- package/dist/api/probe-webhook.application.api.d.ts +1 -1
- package/dist/api/probe-webhook.application.api.js.map +1 -1
- package/dist/index.d.ts +29 -7
- package/dist/index.js +29 -7
- package/dist/index.js.map +1 -1
- package/dist/types/enum/api-error.enum.d.ts +2 -1
- package/dist/types/enum/api-error.enum.js +1 -0
- package/dist/types/enum/api-error.enum.js.map +1 -1
- package/dist/types/enum/probe-scan.enum.js.map +1 -1
- package/dist/types/interface/api/requests/index.d.ts +1 -0
- package/dist/types/interface/api/requests/index.js +1 -0
- package/dist/types/interface/api/requests/index.js.map +1 -1
- package/dist/types/interface/api/requests/probe-delivery-subscription.request.d.ts +23 -0
- package/dist/types/interface/api/requests/probe-delivery-subscription.request.js +3 -0
- package/dist/types/interface/api/requests/probe-delivery-subscription.request.js.map +1 -0
- package/dist/types/interface/api/requests/probe-webhook.request.d.ts +1 -4
- package/dist/types/interface/api/responses/index.d.ts +1 -0
- package/dist/types/interface/api/responses/index.js +1 -0
- package/dist/types/interface/api/responses/index.js.map +1 -1
- package/dist/types/interface/api/responses/probe-delivery-subscription.response.d.ts +10 -0
- package/dist/types/interface/api/responses/probe-delivery-subscription.response.js +3 -0
- package/dist/types/interface/api/responses/probe-delivery-subscription.response.js.map +1 -0
- package/dist/types/tests/probe.dto.test.js +22 -0
- package/dist/types/tests/probe.dto.test.js.map +1 -1
- package/dist/utils/probe-webhook-signature.utils.js.map +1 -1
- package/package.json +19 -15
- package/src/api/index.ts +2 -1
- package/src/api/probe-delivery-subscription.api.ts +183 -0
- package/src/api/probe-delivery-subscription.application.api.ts +186 -0
- package/src/api/probe-scan.api.test.ts +47 -47
- package/src/api/probe-scan.api.ts +203 -203
- package/src/api/probe-scan.application.api.test.ts +35 -35
- package/src/api/probe-scan.application.api.ts +157 -157
- package/src/api/probe-usage.api.ts +47 -47
- package/src/api/probe-usage.application.api.ts +25 -25
- package/src/api/probe-webhook.application.api.test.ts +18 -18
- package/src/api/probe-webhook.application.api.ts +10 -23
- package/src/constants/index.ts +1 -1
- package/src/index.ts +73 -16
- package/src/types/enum/api-error.enum.ts +2 -0
- package/src/types/enum/index.ts +2 -2
- package/src/types/enum/probe-scan.enum.ts +3 -2
- package/src/types/index.ts +2 -2
- package/src/types/interface/api/index.ts +5 -5
- package/src/types/interface/api/requests/index.ts +1 -0
- package/src/types/interface/api/requests/probe-delivery-subscription.request.ts +42 -0
- package/src/types/interface/api/requests/probe-scan.request.ts +54 -54
- package/src/types/interface/api/requests/probe-usage.request.ts +7 -7
- package/src/types/interface/api/requests/probe-webhook.request.ts +9 -11
- package/src/types/interface/api/responses/index.ts +1 -0
- package/src/types/interface/api/responses/probe-delivery-subscription.response.ts +27 -0
- package/src/types/interface/api/responses/probe-scan.response.ts +45 -45
- package/src/types/interface/api/responses/probe-usage.response.ts +25 -25
- package/src/types/interface/api/responses/probe-webhook.response.ts +24 -24
- package/src/types/interface/api/type-message/api-error.ts +7 -7
- package/src/types/interface/api/type-message/base-paginate.ts +11 -11
- package/src/types/interface/api/type-message/response.ts +6 -6
- package/src/types/interface/index.ts +2 -2
- package/src/types/interface/models/index.ts +3 -3
- package/src/types/interface/models/probe-scan.dto.ts +67 -67
- package/src/types/interface/models/probe-webhook-delivery.dto.ts +11 -14
- package/src/types/interface/models/probe-webhook.dto.ts +29 -29
- package/src/types/tests/probe.dto.test.ts +40 -4
- package/src/utils/enum.utils.ts +1 -1
- package/src/utils/error.utils.ts +30 -30
- package/src/utils/index.ts +4 -4
- package/src/utils/probe-scan-cost.utils.ts +101 -101
- package/src/utils/probe-webhook-signature.utils.ts +4 -3
- package/tsconfig.check.json +15 -15
- package/tsconfig.json +36 -36
- package/dist/api/probe-webhook.api.d.ts +0 -6
- package/dist/api/probe-webhook.api.js +0 -41
- package/dist/api/probe-webhook.api.js.map +0 -1
- package/dist/api/probe-webhook.api.test.d.ts +0 -1
- package/dist/api/probe-webhook.api.test.js +0 -43
- package/dist/api/probe-webhook.api.test.js.map +0 -1
- package/src/api/probe-webhook.api.test.ts +0 -17
- package/src/api/probe-webhook.api.ts +0 -119
package/src/index.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import axiosRetry, { IAxiosRetryConfig, isNetworkOrIdempotentRequestError } from 'axios-retry';
|
|
3
3
|
import * as probeScanApi from './api/probe-scan.api';
|
|
4
|
-
import * as
|
|
4
|
+
import * as probeDeliverySubscriptionApi from './api/probe-delivery-subscription.api';
|
|
5
5
|
import * as probeScanApplicationApi from './api/probe-scan.application.api';
|
|
6
|
+
import * as probeDeliverySubscriptionApplicationApi from './api/probe-delivery-subscription.application.api';
|
|
6
7
|
import * as probeWebhookApplicationApi from './api/probe-webhook.application.api';
|
|
7
8
|
import * as probeUsageApi from './api/probe-usage.api';
|
|
8
9
|
import * as probeUsageApplicationApi from './api/probe-usage.application.api';
|
|
@@ -26,7 +27,9 @@ export const ADMIN_TOKEN_HEADER = 'abyss-admin-token';
|
|
|
26
27
|
/**
|
|
27
28
|
* Header carrying the HMAC-SHA256 signature of a probe webhook delivery's
|
|
28
29
|
* raw JSON body. Verify it with {@link verifyProbeWebhookSignature}
|
|
29
|
-
* (re-exported from './utils').
|
|
30
|
+
* (re-exported from './utils'). INTERNAL (P5 #792): AbyssStorage's antivirus
|
|
31
|
+
* subscription is the only receiver until L2 — the deliveries of a client's
|
|
32
|
+
* subscription are signed by Flow.
|
|
30
33
|
*/
|
|
31
34
|
export const PROBE_WEBHOOK_SIGNATURE_HEADER = 'x-probe-signature';
|
|
32
35
|
export const PROBE_WEBHOOK_SIGNATURE_ALGORITHM = 'sha256';
|
|
@@ -61,14 +64,25 @@ type AbyssProbeCoreSDK = {
|
|
|
61
64
|
usage: {
|
|
62
65
|
get: typeof probeUsageApi.getProbeUsage;
|
|
63
66
|
};
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
/**
|
|
68
|
+
* The subscriptions to the verdict of the caller's scans (`PROBE_SCAN_COMPLETED`), kept in
|
|
69
|
+
* Flow: personal scope, or an organization with `organizationId`. The deliveries are signed
|
|
70
|
+
* by Flow; the secret leaves with `create` and `resetSecret` only.
|
|
71
|
+
*/
|
|
72
|
+
deliverySubscription: {
|
|
73
|
+
paginate: typeof probeDeliverySubscriptionApi.paginateProbeDeliverySubscription;
|
|
74
|
+
get: typeof probeDeliverySubscriptionApi.getProbeDeliverySubscription;
|
|
75
|
+
create: typeof probeDeliverySubscriptionApi.createProbeDeliverySubscription;
|
|
76
|
+
update: typeof probeDeliverySubscriptionApi.updateProbeDeliverySubscription;
|
|
77
|
+
delete: typeof probeDeliverySubscriptionApi.deleteProbeDeliverySubscription;
|
|
78
|
+
resetSecret: typeof probeDeliverySubscriptionApi.resetSecretProbeDeliverySubscription;
|
|
79
|
+
delivery: {
|
|
80
|
+
/** Deliveries of every subscription of the scope. */
|
|
81
|
+
paginateByScope: typeof probeDeliverySubscriptionApi.paginateProbeScopeDelivery;
|
|
82
|
+
paginate: typeof probeDeliverySubscriptionApi.paginateProbeDelivery;
|
|
83
|
+
get: typeof probeDeliverySubscriptionApi.getProbeDelivery;
|
|
84
|
+
replay: typeof probeDeliverySubscriptionApi.replayProbeDelivery;
|
|
85
|
+
};
|
|
72
86
|
};
|
|
73
87
|
/**
|
|
74
88
|
* Application/API-key-auth counterpart (Phase 3a) — for inter-service
|
|
@@ -93,6 +107,22 @@ type AbyssProbeCoreSDK = {
|
|
|
93
107
|
usage: {
|
|
94
108
|
get: typeof probeUsageApplicationApi.getProbeUsageApplication;
|
|
95
109
|
};
|
|
110
|
+
/** Same as `probe.deliverySubscription`, for the application (`FULL_ACCESS`). */
|
|
111
|
+
deliverySubscription: {
|
|
112
|
+
paginate: typeof probeDeliverySubscriptionApplicationApi.paginateProbeDeliverySubscriptionApplication;
|
|
113
|
+
get: typeof probeDeliverySubscriptionApplicationApi.getProbeDeliverySubscriptionApplication;
|
|
114
|
+
create: typeof probeDeliverySubscriptionApplicationApi.createProbeDeliverySubscriptionApplication;
|
|
115
|
+
update: typeof probeDeliverySubscriptionApplicationApi.updateProbeDeliverySubscriptionApplication;
|
|
116
|
+
delete: typeof probeDeliverySubscriptionApplicationApi.deleteProbeDeliverySubscriptionApplication;
|
|
117
|
+
resetSecret: typeof probeDeliverySubscriptionApplicationApi.resetSecretProbeDeliverySubscriptionApplication;
|
|
118
|
+
delivery: {
|
|
119
|
+
paginateByScope: typeof probeDeliverySubscriptionApplicationApi.paginateProbeScopeDeliveryApplication;
|
|
120
|
+
paginate: typeof probeDeliverySubscriptionApplicationApi.paginateProbeDeliveryApplication;
|
|
121
|
+
get: typeof probeDeliverySubscriptionApplicationApi.getProbeDeliveryApplication;
|
|
122
|
+
replay: typeof probeDeliverySubscriptionApplicationApi.replayProbeDeliveryApplication;
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
/** INTERNAL (P5 #792): AbyssStorage's antivirus subscription, until L2. */
|
|
96
126
|
webhook: {
|
|
97
127
|
create: typeof probeWebhookApplicationApi.createProbeWebhookApplication;
|
|
98
128
|
list: typeof probeWebhookApplicationApi.listProbeWebhookApplication;
|
|
@@ -138,12 +168,19 @@ export class AbyssProbeCore {
|
|
|
138
168
|
usage: {
|
|
139
169
|
get: probeUsageApi.getProbeUsage,
|
|
140
170
|
},
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
update:
|
|
146
|
-
|
|
171
|
+
deliverySubscription: {
|
|
172
|
+
paginate: probeDeliverySubscriptionApi.paginateProbeDeliverySubscription,
|
|
173
|
+
get: probeDeliverySubscriptionApi.getProbeDeliverySubscription,
|
|
174
|
+
create: probeDeliverySubscriptionApi.createProbeDeliverySubscription,
|
|
175
|
+
update: probeDeliverySubscriptionApi.updateProbeDeliverySubscription,
|
|
176
|
+
delete: probeDeliverySubscriptionApi.deleteProbeDeliverySubscription,
|
|
177
|
+
resetSecret: probeDeliverySubscriptionApi.resetSecretProbeDeliverySubscription,
|
|
178
|
+
delivery: {
|
|
179
|
+
paginateByScope: probeDeliverySubscriptionApi.paginateProbeScopeDelivery,
|
|
180
|
+
paginate: probeDeliverySubscriptionApi.paginateProbeDelivery,
|
|
181
|
+
get: probeDeliverySubscriptionApi.getProbeDelivery,
|
|
182
|
+
replay: probeDeliverySubscriptionApi.replayProbeDelivery,
|
|
183
|
+
},
|
|
147
184
|
},
|
|
148
185
|
application: {
|
|
149
186
|
scan: probeScanApplicationApi.scanApplication,
|
|
@@ -154,6 +191,26 @@ export class AbyssProbeCore {
|
|
|
154
191
|
usage: {
|
|
155
192
|
get: probeUsageApplicationApi.getProbeUsageApplication,
|
|
156
193
|
},
|
|
194
|
+
deliverySubscription: {
|
|
195
|
+
paginate:
|
|
196
|
+
probeDeliverySubscriptionApplicationApi.paginateProbeDeliverySubscriptionApplication,
|
|
197
|
+
get: probeDeliverySubscriptionApplicationApi.getProbeDeliverySubscriptionApplication,
|
|
198
|
+
create:
|
|
199
|
+
probeDeliverySubscriptionApplicationApi.createProbeDeliverySubscriptionApplication,
|
|
200
|
+
update:
|
|
201
|
+
probeDeliverySubscriptionApplicationApi.updateProbeDeliverySubscriptionApplication,
|
|
202
|
+
delete:
|
|
203
|
+
probeDeliverySubscriptionApplicationApi.deleteProbeDeliverySubscriptionApplication,
|
|
204
|
+
resetSecret:
|
|
205
|
+
probeDeliverySubscriptionApplicationApi.resetSecretProbeDeliverySubscriptionApplication,
|
|
206
|
+
delivery: {
|
|
207
|
+
paginateByScope:
|
|
208
|
+
probeDeliverySubscriptionApplicationApi.paginateProbeScopeDeliveryApplication,
|
|
209
|
+
paginate: probeDeliverySubscriptionApplicationApi.paginateProbeDeliveryApplication,
|
|
210
|
+
get: probeDeliverySubscriptionApplicationApi.getProbeDeliveryApplication,
|
|
211
|
+
replay: probeDeliverySubscriptionApplicationApi.replayProbeDeliveryApplication,
|
|
212
|
+
},
|
|
213
|
+
},
|
|
157
214
|
webhook: {
|
|
158
215
|
create: probeWebhookApplicationApi.createProbeWebhookApplication,
|
|
159
216
|
list: probeWebhookApplicationApi.listProbeWebhookApplication,
|
|
@@ -30,4 +30,6 @@ export enum Code {
|
|
|
30
30
|
drawImageLimitReached = 'draw_image_limit_reached',
|
|
31
31
|
drawImageOwnerRequired = 'draw_image_owner_required',
|
|
32
32
|
drawImageNotInDraw = 'draw_image_not_in_draw',
|
|
33
|
+
/** A scan `callbackUrl` in a scope with no enabled delivery subscription to sign it with (422). */
|
|
34
|
+
probeCallbackRequiresSubscription = 'probe_callback_requires_subscription',
|
|
33
35
|
}
|
package/src/types/enum/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './api-error.enum';
|
|
2
|
-
export * from './probe-scan.enum';
|
|
1
|
+
export * from './api-error.enum';
|
|
2
|
+
export * from './probe-scan.enum';
|
|
@@ -18,8 +18,9 @@ export enum ProbeScanVerdict {
|
|
|
18
18
|
/**
|
|
19
19
|
* How the scan was (or will be) run: `SYNC` blocks the request until the
|
|
20
20
|
* engine returns the verdict inline; `ASYNC` queues the job and delivers the
|
|
21
|
-
* verdict later
|
|
22
|
-
* `callbackUrl
|
|
21
|
+
* verdict later through the scope's delivery subscriptions (Flow) and/or the
|
|
22
|
+
* per-request `callbackUrl` (delivered once through such a subscription), and/or by
|
|
23
|
+
* polling `GET /scan/:scanId`.
|
|
23
24
|
*/
|
|
24
25
|
export enum ProbeScanMode {
|
|
25
26
|
SYNC = 'sync',
|
package/src/types/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './enum';
|
|
2
|
-
export * from './interface';
|
|
1
|
+
export * from './enum';
|
|
2
|
+
export * from './interface';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export * from './requests';
|
|
2
|
-
export * from './responses';
|
|
3
|
-
export * from './type-message/response';
|
|
4
|
-
export * from './type-message/api-error';
|
|
5
|
-
export * from './type-message/base-paginate';
|
|
1
|
+
export * from './requests';
|
|
2
|
+
export * from './responses';
|
|
3
|
+
export * from './type-message/response';
|
|
4
|
+
export * from './type-message/api-error';
|
|
5
|
+
export * from './type-message/base-paginate';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { DeliveryStatus } from '@abyss-project/flow';
|
|
2
|
+
|
|
3
|
+
// Mirrors apps/api/src/api/validators/probe-delivery-subscription.validator.ts. A client's
|
|
4
|
+
// subscriptions to the verdict of its scans live in Flow; AbyssProbe checks who may manage them
|
|
5
|
+
// and calls Flow for the scope (the caller, an organisation, or an application).
|
|
6
|
+
|
|
7
|
+
/** Personal scope (default) or an organization, for the personal/org client. */
|
|
8
|
+
export interface IProbeDeliverySubscriptionScopeQuery {
|
|
9
|
+
organizationId?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface IPaginateProbeDeliverySubscriptionQuery
|
|
13
|
+
extends IProbeDeliverySubscriptionScopeQuery {
|
|
14
|
+
/** @default 1 */
|
|
15
|
+
page?: number;
|
|
16
|
+
/** @default 20 */
|
|
17
|
+
limit?: number;
|
|
18
|
+
isEnabled?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ICreateProbeDeliverySubscriptionBody {
|
|
22
|
+
/** Only `PROBE_SCAN_COMPLETED` (`DeliveryEventType.PROBE_SCAN_COMPLETED` of `@abyss-project/flow`). */
|
|
23
|
+
eventTypes: string[];
|
|
24
|
+
/** HTTPS endpoint the verdict is POSTed to. */
|
|
25
|
+
url: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** At least one field is required. */
|
|
29
|
+
export interface IUpdateProbeDeliverySubscriptionBody {
|
|
30
|
+
eventTypes?: string[];
|
|
31
|
+
url?: string;
|
|
32
|
+
isEnabled?: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Deliveries of one subscription, or of every subscription of the scope. */
|
|
36
|
+
export interface IPaginateProbeDeliveryQuery extends IProbeDeliverySubscriptionScopeQuery {
|
|
37
|
+
/** @default 1 */
|
|
38
|
+
page?: number;
|
|
39
|
+
/** @default 20 */
|
|
40
|
+
limit?: number;
|
|
41
|
+
status?: DeliveryStatus;
|
|
42
|
+
}
|
|
@@ -1,54 +1,54 @@
|
|
|
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
|
-
/**
|
|
25
|
-
* Content-Type stamped on the file part when the caller passes raw bytes
|
|
26
|
-
* (`Buffer`/`Uint8Array`). Ignored when the file is already a `Blob` — a
|
|
27
|
-
* browser `File` and `fs.openAsBlob(path)` carry their own type.
|
|
28
|
-
*/
|
|
29
|
-
mimeType?: string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* `GET /scan` query — all filters optional, combined with AND.
|
|
34
|
-
* `contextKey`/`contextValue` must be supplied together (business-reference
|
|
35
|
-
* search inside the free-form `context` JSONB column) — supplying one
|
|
36
|
-
* without the other is rejected by the API (400).
|
|
37
|
-
*/
|
|
38
|
-
export interface IListScansQuery {
|
|
39
|
-
organizationId?: string;
|
|
40
|
-
verdict?: ProbeScanVerdict;
|
|
41
|
-
mode?: ProbeScanMode;
|
|
42
|
-
status?: ProbeScanStatus;
|
|
43
|
-
/** Date range on `createdAt`, inclusive at both ends. */
|
|
44
|
-
from?: Date;
|
|
45
|
-
to?: Date;
|
|
46
|
-
/** Case-insensitive partial match on the original file name. */
|
|
47
|
-
fileName?: string;
|
|
48
|
-
contextKey?: string;
|
|
49
|
-
contextValue?: string;
|
|
50
|
-
/** @default 1 */
|
|
51
|
-
page?: number;
|
|
52
|
-
/** @default 20, server max 200. */
|
|
53
|
-
limit?: number;
|
|
54
|
-
}
|
|
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
|
+
/**
|
|
25
|
+
* Content-Type stamped on the file part when the caller passes raw bytes
|
|
26
|
+
* (`Buffer`/`Uint8Array`). Ignored when the file is already a `Blob` — a
|
|
27
|
+
* browser `File` and `fs.openAsBlob(path)` carry their own type.
|
|
28
|
+
*/
|
|
29
|
+
mimeType?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* `GET /scan` query — all filters optional, combined with AND.
|
|
34
|
+
* `contextKey`/`contextValue` must be supplied together (business-reference
|
|
35
|
+
* search inside the free-form `context` JSONB column) — supplying one
|
|
36
|
+
* without the other is rejected by the API (400).
|
|
37
|
+
*/
|
|
38
|
+
export interface IListScansQuery {
|
|
39
|
+
organizationId?: string;
|
|
40
|
+
verdict?: ProbeScanVerdict;
|
|
41
|
+
mode?: ProbeScanMode;
|
|
42
|
+
status?: ProbeScanStatus;
|
|
43
|
+
/** Date range on `createdAt`, inclusive at both ends. */
|
|
44
|
+
from?: Date;
|
|
45
|
+
to?: Date;
|
|
46
|
+
/** Case-insensitive partial match on the original file name. */
|
|
47
|
+
fileName?: string;
|
|
48
|
+
contextKey?: string;
|
|
49
|
+
contextValue?: string;
|
|
50
|
+
/** @default 1 */
|
|
51
|
+
page?: number;
|
|
52
|
+
/** @default 20, server max 200. */
|
|
53
|
+
limit?: number;
|
|
54
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
// WS5-3 (AbyssProbe UX rework) — `GET /usage` / `GET /application/:applicationId/usage`.
|
|
2
|
-
// Mirrors apps/api/src/api/validators/probe-usage.validator.ts's Joi schema.
|
|
3
|
-
|
|
4
|
-
/** `GET /usage` query — personal scope (default) or an organization. Not needed for the application variant (its scope is the `:applicationId` URL segment). */
|
|
5
|
-
export interface IProbeUsageScopeQuery {
|
|
6
|
-
organizationId?: string;
|
|
7
|
-
}
|
|
1
|
+
// WS5-3 (AbyssProbe UX rework) — `GET /usage` / `GET /application/:applicationId/usage`.
|
|
2
|
+
// Mirrors apps/api/src/api/validators/probe-usage.validator.ts's Joi schema.
|
|
3
|
+
|
|
4
|
+
/** `GET /usage` query — personal scope (default) or an organization. Not needed for the application variant (its scope is the `:applicationId` URL segment). */
|
|
5
|
+
export interface IProbeUsageScopeQuery {
|
|
6
|
+
organizationId?: string;
|
|
7
|
+
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
// Mirrors apps/api/src/api/controllers/probe-webhook.controller.ts's
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
organizationId?: string;
|
|
8
|
-
}
|
|
1
|
+
// Mirrors apps/api/src/api/controllers/probe-webhook-application.controller.ts's
|
|
2
|
+
// CreateBody/UpdateBody and probe-webhook.validator.ts's Joi schemas.
|
|
3
|
+
//
|
|
4
|
+
// INTERNAL (P5 #792): the application webhooks serve AbyssStorage's antivirus subscription until
|
|
5
|
+
// its client subscriptions move to Flow (L2). A client's own subscriptions are the Flow
|
|
6
|
+
// delivery subscriptions (probe-delivery-subscription.request.ts).
|
|
9
7
|
|
|
10
8
|
export interface ICreateProbeWebhookBody {
|
|
11
9
|
/** HTTPS endpoint the verdict is POSTed to. Required, `https://` only. */
|
|
@@ -13,7 +11,7 @@ export interface ICreateProbeWebhookBody {
|
|
|
13
11
|
}
|
|
14
12
|
|
|
15
13
|
/**
|
|
16
|
-
* `PATCH /webhook/:webhookId` body (WS5-5) — at least one field required
|
|
14
|
+
* `PATCH /application/:applicationId/webhook/:webhookId` body (WS5-5) — at least one field required
|
|
17
15
|
* (mirrors probe-webhook.validator.ts#updateBody's `.min(1)`); omitted
|
|
18
16
|
* fields are left unchanged.
|
|
19
17
|
*/
|
|
@@ -24,8 +22,8 @@ export interface IUpdateProbeWebhookBody {
|
|
|
24
22
|
active?: boolean;
|
|
25
23
|
}
|
|
26
24
|
|
|
27
|
-
/** `GET /webhook/:webhookId/deliveries` query (WS5-6) — paginated. */
|
|
28
|
-
export interface IListProbeWebhookDeliveriesQuery
|
|
25
|
+
/** `GET /application/:applicationId/webhook/:webhookId/deliveries` query (WS5-6) — paginated. */
|
|
26
|
+
export interface IListProbeWebhookDeliveriesQuery {
|
|
29
27
|
/** @default 1 */
|
|
30
28
|
page?: number;
|
|
31
29
|
/** @default 20 */
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ICreateDeliverySubscriptionResponse,
|
|
3
|
+
IDeleteDeliverySubscriptionResponse,
|
|
4
|
+
IGetDeliveryResponse,
|
|
5
|
+
IGetDeliverySubscriptionResponse,
|
|
6
|
+
IPaginateDeliveryResponse,
|
|
7
|
+
IPaginateDeliverySubscriptionResponse,
|
|
8
|
+
IReplayDeliveryResponse,
|
|
9
|
+
IResetSecretDeliverySubscriptionResponse,
|
|
10
|
+
IUpdateDeliverySubscriptionResponse,
|
|
11
|
+
} from '@abyss-project/flow';
|
|
12
|
+
|
|
13
|
+
// The answers are Flow's own, passed through: the subscription and delivery models of
|
|
14
|
+
// `@abyss-project/flow`. The secret leaves only with a creation and a reset.
|
|
15
|
+
|
|
16
|
+
export type IPaginateProbeDeliverySubscriptionResponse = IPaginateDeliverySubscriptionResponse;
|
|
17
|
+
export type IGetProbeDeliverySubscriptionResponse = IGetDeliverySubscriptionResponse;
|
|
18
|
+
/** `secret` is returned here once. */
|
|
19
|
+
export type ICreateProbeDeliverySubscriptionResponse = ICreateDeliverySubscriptionResponse;
|
|
20
|
+
export type IUpdateProbeDeliverySubscriptionResponse = IUpdateDeliverySubscriptionResponse;
|
|
21
|
+
export type IDeleteProbeDeliverySubscriptionResponse = IDeleteDeliverySubscriptionResponse;
|
|
22
|
+
/** The new `secret` is returned here once; the previous one stops signing. */
|
|
23
|
+
export type IResetSecretProbeDeliverySubscriptionResponse =
|
|
24
|
+
IResetSecretDeliverySubscriptionResponse;
|
|
25
|
+
export type IPaginateProbeDeliveryResponse = IPaginateDeliveryResponse;
|
|
26
|
+
export type IGetProbeDeliveryResponse = IGetDeliveryResponse;
|
|
27
|
+
export type IReplayProbeDeliveryResponse = IReplayDeliveryResponse;
|
|
@@ -1,45 +1,45 @@
|
|
|
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
|
-
* `ACCOUNT_AV_SCAN_UNITS` this scan consumed (WS5-1/2 — see
|
|
17
|
-
* `estimateProbeScanCost`). Always a number here (never null): a SYNC
|
|
18
|
-
* response is only ever sent once the scan has reached a verdict, at
|
|
19
|
-
* which point the cost is always known and already billed.
|
|
20
|
-
*/
|
|
21
|
-
costUnits: number;
|
|
22
|
-
}
|
|
23
|
-
export type IScanSyncResponse = IResponse<IScanSyncData>;
|
|
24
|
-
|
|
25
|
-
/** `POST /scan?mode=async` — HTTP 202, job queued. */
|
|
26
|
-
export interface IScanAsyncData {
|
|
27
|
-
scanId: string;
|
|
28
|
-
status: ProbeScanStatus.QUEUED;
|
|
29
|
-
}
|
|
30
|
-
export type IScanAsyncResponse = IResponse<IScanAsyncData>;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* `POST /scan`'s actual response body is one or the other of the two data
|
|
34
|
-
* shapes above, discriminated by the request's own `mode` (sync -> 200 +
|
|
35
|
-
* {@link IScanSyncData}, async -> 202 + {@link IScanAsyncData}). A caller
|
|
36
|
-
* that only ever uses one mode should prefer the sdk's `scanSync`/`scanAsync`
|
|
37
|
-
* wrappers, which return the precise, non-union type.
|
|
38
|
-
*/
|
|
39
|
-
export type IScanResponse = IScanSyncResponse | IScanAsyncResponse;
|
|
40
|
-
|
|
41
|
-
/** `GET /scan/:scanId` — HTTP 200. */
|
|
42
|
-
export type IGetScanResponse = IResponse<IProbeScanDetail>;
|
|
43
|
-
|
|
44
|
-
/** `GET /scan` — HTTP 200, paginated history/search. */
|
|
45
|
-
export type IPaginateScanResponse = IResponse<BasePaginate<IProbeScanHistoryItem>>;
|
|
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
|
+
* `ACCOUNT_AV_SCAN_UNITS` this scan consumed (WS5-1/2 — see
|
|
17
|
+
* `estimateProbeScanCost`). Always a number here (never null): a SYNC
|
|
18
|
+
* response is only ever sent once the scan has reached a verdict, at
|
|
19
|
+
* which point the cost is always known and already billed.
|
|
20
|
+
*/
|
|
21
|
+
costUnits: number;
|
|
22
|
+
}
|
|
23
|
+
export type IScanSyncResponse = IResponse<IScanSyncData>;
|
|
24
|
+
|
|
25
|
+
/** `POST /scan?mode=async` — HTTP 202, job queued. */
|
|
26
|
+
export interface IScanAsyncData {
|
|
27
|
+
scanId: string;
|
|
28
|
+
status: ProbeScanStatus.QUEUED;
|
|
29
|
+
}
|
|
30
|
+
export type IScanAsyncResponse = IResponse<IScanAsyncData>;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* `POST /scan`'s actual response body is one or the other of the two data
|
|
34
|
+
* shapes above, discriminated by the request's own `mode` (sync -> 200 +
|
|
35
|
+
* {@link IScanSyncData}, async -> 202 + {@link IScanAsyncData}). A caller
|
|
36
|
+
* that only ever uses one mode should prefer the sdk's `scanSync`/`scanAsync`
|
|
37
|
+
* wrappers, which return the precise, non-union type.
|
|
38
|
+
*/
|
|
39
|
+
export type IScanResponse = IScanSyncResponse | IScanAsyncResponse;
|
|
40
|
+
|
|
41
|
+
/** `GET /scan/:scanId` — HTTP 200. */
|
|
42
|
+
export type IGetScanResponse = IResponse<IProbeScanDetail>;
|
|
43
|
+
|
|
44
|
+
/** `GET /scan` — HTTP 200, paginated history/search. */
|
|
45
|
+
export type IPaginateScanResponse = IResponse<BasePaginate<IProbeScanHistoryItem>>;
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import { IResponse } from '../type-message/response';
|
|
2
|
-
|
|
3
|
-
// WS5-3 (AbyssProbe UX rework) — mirrors
|
|
4
|
-
// apps/api/src/api/controllers/probe-usage.controller.ts's local response
|
|
5
|
-
// shape EXACTLY. Current ACCOUNT_AV_SCAN_UNITS ("tokens") consumption for the
|
|
6
|
-
// caller's scope, via the same billing check the quota gate itself uses.
|
|
7
|
-
|
|
8
|
-
export interface IProbeUsageData {
|
|
9
|
-
/** Units consumed so far in the current billing period. */
|
|
10
|
-
used: number;
|
|
11
|
-
/**
|
|
12
|
-
* Plan cap. `-1` is this codebase's established "unlimited" sentinel (see
|
|
13
|
-
* `utils/billing-emit.util.ts#UNLIMITED_EXPIRY_DAYS` server-side) — an
|
|
14
|
-
* unmetered plan tier reports `-1` here rather than `Infinity`/`null`, so
|
|
15
|
-
* treat a negative value as "no cap", never a literal negative quota.
|
|
16
|
-
*/
|
|
17
|
-
limit: number;
|
|
18
|
-
/**
|
|
19
|
-
* `limit - used`, floored at 0 — except it mirrors `limit`'s own `-1`
|
|
20
|
-
* sentinel unchanged when `limit` is unlimited (never a finite number in
|
|
21
|
-
* that case).
|
|
22
|
-
*/
|
|
23
|
-
remaining: number;
|
|
24
|
-
}
|
|
25
|
-
export type IProbeUsageResponse = IResponse<IProbeUsageData>;
|
|
1
|
+
import { IResponse } from '../type-message/response';
|
|
2
|
+
|
|
3
|
+
// WS5-3 (AbyssProbe UX rework) — mirrors
|
|
4
|
+
// apps/api/src/api/controllers/probe-usage.controller.ts's local response
|
|
5
|
+
// shape EXACTLY. Current ACCOUNT_AV_SCAN_UNITS ("tokens") consumption for the
|
|
6
|
+
// caller's scope, via the same billing check the quota gate itself uses.
|
|
7
|
+
|
|
8
|
+
export interface IProbeUsageData {
|
|
9
|
+
/** Units consumed so far in the current billing period. */
|
|
10
|
+
used: number;
|
|
11
|
+
/**
|
|
12
|
+
* Plan cap. `-1` is this codebase's established "unlimited" sentinel (see
|
|
13
|
+
* `utils/billing-emit.util.ts#UNLIMITED_EXPIRY_DAYS` server-side) — an
|
|
14
|
+
* unmetered plan tier reports `-1` here rather than `Infinity`/`null`, so
|
|
15
|
+
* treat a negative value as "no cap", never a literal negative quota.
|
|
16
|
+
*/
|
|
17
|
+
limit: number;
|
|
18
|
+
/**
|
|
19
|
+
* `limit - used`, floored at 0 — except it mirrors `limit`'s own `-1`
|
|
20
|
+
* sentinel unchanged when `limit` is unlimited (never a finite number in
|
|
21
|
+
* that case).
|
|
22
|
+
*/
|
|
23
|
+
remaining: number;
|
|
24
|
+
}
|
|
25
|
+
export type IProbeUsageResponse = IResponse<IProbeUsageData>;
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { IResponse } from '../type-message/response';
|
|
2
|
-
import { BasePaginate } from '../type-message/base-paginate';
|
|
3
|
-
import { IProbeWebhook, IProbeWebhookDelivery } from '../../models';
|
|
4
|
-
|
|
5
|
-
// Mirrors apps/api/src/api/controllers/probe-webhook.controller.ts's local
|
|
6
|
-
// response shapes EXACTLY.
|
|
7
|
-
|
|
8
|
-
/** `POST /webhook` — HTTP 201. `secret` is re-displayable (WS5-7) — also returned by GET/PATCH, not just here. */
|
|
9
|
-
export type ICreateProbeWebhookResponse = IResponse<IProbeWebhook>;
|
|
10
|
-
|
|
11
|
-
/** `GET /webhook` — HTTP 200. A flat scope-filtered list, NOT paginated. `secret` included per row (WS5-7). */
|
|
12
|
-
export interface IListProbeWebhookData {
|
|
13
|
-
webhooks: IProbeWebhook[];
|
|
14
|
-
}
|
|
15
|
-
export type IListProbeWebhookResponse = IResponse<IListProbeWebhookData>;
|
|
16
|
-
|
|
17
|
-
/** `DELETE /webhook/:webhookId` — HTTP 200. */
|
|
18
|
-
export type IDeleteProbeWebhookResponse = IResponse<{ ok: true }>;
|
|
19
|
-
|
|
20
|
-
/** `PATCH /webhook/:webhookId` — HTTP 200 (WS5-5). `secret` included, same as every other webhook read. */
|
|
21
|
-
export type IUpdateProbeWebhookResponse = IResponse<IProbeWebhook>;
|
|
22
|
-
|
|
23
|
-
/** `GET /webhook/:webhookId/deliveries` — HTTP 200, paginated (WS5-6). */
|
|
24
|
-
export type IListProbeWebhookDeliveriesResponse = IResponse<BasePaginate<IProbeWebhookDelivery>>;
|
|
1
|
+
import { IResponse } from '../type-message/response';
|
|
2
|
+
import { BasePaginate } from '../type-message/base-paginate';
|
|
3
|
+
import { IProbeWebhook, IProbeWebhookDelivery } from '../../models';
|
|
4
|
+
|
|
5
|
+
// Mirrors apps/api/src/api/controllers/probe-webhook.controller.ts's local
|
|
6
|
+
// response shapes EXACTLY.
|
|
7
|
+
|
|
8
|
+
/** `POST /webhook` — HTTP 201. `secret` is re-displayable (WS5-7) — also returned by GET/PATCH, not just here. */
|
|
9
|
+
export type ICreateProbeWebhookResponse = IResponse<IProbeWebhook>;
|
|
10
|
+
|
|
11
|
+
/** `GET /webhook` — HTTP 200. A flat scope-filtered list, NOT paginated. `secret` included per row (WS5-7). */
|
|
12
|
+
export interface IListProbeWebhookData {
|
|
13
|
+
webhooks: IProbeWebhook[];
|
|
14
|
+
}
|
|
15
|
+
export type IListProbeWebhookResponse = IResponse<IListProbeWebhookData>;
|
|
16
|
+
|
|
17
|
+
/** `DELETE /webhook/:webhookId` — HTTP 200. */
|
|
18
|
+
export type IDeleteProbeWebhookResponse = IResponse<{ ok: true }>;
|
|
19
|
+
|
|
20
|
+
/** `PATCH /webhook/:webhookId` — HTTP 200 (WS5-5). `secret` included, same as every other webhook read. */
|
|
21
|
+
export type IUpdateProbeWebhookResponse = IResponse<IProbeWebhook>;
|
|
22
|
+
|
|
23
|
+
/** `GET /webhook/:webhookId/deliveries` — HTTP 200, paginated (WS5-6). */
|
|
24
|
+
export type IListProbeWebhookDeliveriesResponse = IResponse<BasePaginate<IProbeWebhookDelivery>>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Code, ErrorType } from '../../../enum';
|
|
2
|
-
|
|
3
|
-
export interface IApiError {
|
|
4
|
-
code: Code;
|
|
5
|
-
type: ErrorType;
|
|
6
|
-
message?: string;
|
|
7
|
-
}
|
|
1
|
+
import { Code, ErrorType } from '../../../enum';
|
|
2
|
+
|
|
3
|
+
export interface IApiError {
|
|
4
|
+
code: Code;
|
|
5
|
+
type: ErrorType;
|
|
6
|
+
message?: string;
|
|
7
|
+
}
|