@abyss-project/probe 1.0.0 → 2.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 -0
- package/.prettierrc +5 -0
- package/README.md +4 -14
- 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 +4 -6
- package/dist/api/probe-scan.api.js +34 -30
- package/dist/api/probe-scan.api.js.map +1 -1
- package/dist/api/probe-scan.api.test.js +27 -7
- package/dist/api/probe-scan.api.test.js.map +1 -1
- 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 +51 -0
- package/dist/api/probe-scan.application.api.test.js.map +1 -0
- package/dist/api/probe-usage.api.d.ts +2 -0
- package/dist/api/probe-usage.api.js +24 -0
- package/dist/api/probe-usage.api.js.map +1 -0
- package/dist/api/probe-usage.application.api.d.ts +2 -0
- package/dist/api/probe-usage.application.api.js +12 -0
- package/dist/api/probe-usage.application.api.js.map +1 -0
- package/dist/api/probe-webhook.api.d.ts +3 -1
- package/dist/api/probe-webhook.api.js +28 -8
- package/dist/api/probe-webhook.api.js.map +1 -1
- package/dist/api/probe-webhook.api.test.js +17 -7
- package/dist/api/probe-webhook.api.test.js.map +1 -1
- package/dist/api/probe-webhook.application.api.d.ts +6 -0
- package/dist/api/probe-webhook.application.api.js +27 -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 +43 -0
- package/dist/api/probe-webhook.application.api.test.js.map +1 -0
- package/dist/constants/index.d.ts +1 -0
- package/dist/{types/interface/models/probe-scan.model.js → constants/index.js} +1 -1
- package/dist/constants/index.js.map +1 -0
- package/dist/index.d.ts +42 -9
- package/dist/index.js +65 -20
- package/dist/index.js.map +1 -1
- package/dist/types/enum/api-error.enum.d.ts +15 -1
- package/dist/types/enum/api-error.enum.js +14 -0
- package/dist/types/enum/api-error.enum.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/index.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-usage.request.d.ts +3 -0
- package/dist/types/interface/{models/probe-webhook.model.js → api/requests/probe-usage.request.js} +1 -1
- package/dist/types/interface/api/requests/probe-usage.request.js.map +1 -0
- package/dist/types/interface/api/requests/probe-webhook.request.d.ts +8 -0
- 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-scan.response.d.ts +1 -0
- package/dist/types/interface/api/responses/probe-usage.response.d.ts +7 -0
- package/dist/types/interface/api/responses/probe-usage.response.js +3 -0
- package/dist/types/interface/api/responses/probe-usage.response.js.map +1 -0
- package/dist/types/interface/api/responses/probe-webhook.response.d.ts +5 -2
- package/dist/types/interface/index.d.ts +0 -1
- package/dist/types/interface/index.js +0 -1
- package/dist/types/interface/index.js.map +1 -1
- package/dist/types/interface/models/index.d.ts +3 -2
- package/dist/types/interface/models/index.js +3 -2
- package/dist/types/interface/models/index.js.map +1 -1
- package/dist/types/interface/models/{probe-scan.model.d.ts → probe-scan.dto.d.ts} +8 -0
- package/dist/types/interface/models/probe-scan.dto.js +3 -0
- package/dist/types/interface/models/probe-scan.dto.js.map +1 -0
- package/dist/types/interface/models/probe-webhook-delivery.dto.d.ts +19 -0
- package/dist/types/interface/models/probe-webhook-delivery.dto.js.map +1 -0
- package/dist/types/interface/models/{probe-webhook.model.d.ts → probe-webhook.dto.d.ts} +1 -3
- package/dist/types/interface/models/probe-webhook.dto.js +3 -0
- package/dist/types/interface/models/probe-webhook.dto.js.map +1 -0
- package/dist/types/tests/probe.dto.test.js +39 -2
- package/dist/types/tests/probe.dto.test.js.map +1 -1
- package/dist/utils/enum.utils.d.ts +1 -0
- package/dist/utils/enum.utils.js +3 -0
- package/dist/utils/enum.utils.js.map +1 -0
- package/dist/utils/error.utils.d.ts +15 -0
- package/dist/utils/error.utils.js +25 -0
- package/dist/utils/error.utils.js.map +1 -0
- package/dist/utils/index.d.ts +3 -1
- package/dist/utils/index.js +3 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/probe-scan-cost.utils.d.ts +5 -0
- package/dist/utils/probe-scan-cost.utils.js +21 -0
- package/dist/utils/probe-scan-cost.utils.js.map +1 -0
- package/dist/utils/probe-webhook-signature.utils.d.ts +0 -2
- package/dist/utils/probe-webhook-signature.utils.js +1 -2
- package/dist/utils/probe-webhook-signature.utils.js.map +1 -1
- package/package.json +24 -14
- package/src/api/index.ts +6 -0
- package/src/api/probe-scan.api.test.ts +47 -0
- package/src/api/probe-scan.api.ts +203 -0
- package/src/api/probe-scan.application.api.test.ts +35 -0
- package/src/api/probe-scan.application.api.ts +157 -0
- package/src/api/probe-usage.api.ts +47 -0
- package/src/api/probe-usage.application.api.ts +25 -0
- package/src/api/probe-webhook.api.test.ts +17 -0
- package/src/api/probe-webhook.api.ts +119 -0
- package/src/api/probe-webhook.application.api.test.ts +18 -0
- package/src/api/probe-webhook.application.api.ts +141 -0
- package/src/constants/index.ts +1 -0
- package/src/index.ts +205 -0
- package/src/types/enum/api-error.enum.ts +33 -0
- package/src/types/enum/index.ts +2 -0
- package/src/types/enum/probe-scan.enum.ts +44 -0
- package/src/types/index.ts +2 -0
- package/src/types/interface/api/index.ts +5 -0
- package/src/types/interface/api/requests/index.ts +3 -0
- package/src/types/interface/api/requests/probe-scan.request.ts +54 -0
- package/src/types/interface/api/requests/probe-usage.request.ts +7 -0
- package/src/types/interface/api/requests/probe-webhook.request.ts +33 -0
- package/src/types/interface/api/responses/index.ts +3 -0
- package/src/types/interface/api/responses/probe-scan.response.ts +45 -0
- package/src/types/interface/api/responses/probe-usage.response.ts +25 -0
- package/src/types/interface/api/responses/probe-webhook.response.ts +24 -0
- package/src/types/interface/api/type-message/api-error.ts +7 -0
- package/src/types/interface/api/type-message/base-paginate.ts +11 -0
- package/src/types/interface/api/type-message/response.ts +6 -0
- package/src/types/interface/index.ts +2 -0
- package/src/types/interface/models/index.ts +3 -0
- package/src/types/interface/models/probe-scan.dto.ts +67 -0
- package/src/types/interface/models/probe-webhook-delivery.dto.ts +73 -0
- package/src/types/interface/models/probe-webhook.dto.ts +29 -0
- package/src/types/tests/probe.dto.test.ts +156 -0
- package/src/utils/enum.utils.ts +1 -0
- package/src/utils/error.utils.ts +30 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/probe-scan-cost.utils.ts +101 -0
- package/src/utils/probe-webhook-signature.utils.ts +56 -0
- package/tsconfig.check.json +15 -0
- package/dist/types/interface/dto/index.d.ts +0 -1
- package/dist/types/interface/dto/index.js +0 -18
- package/dist/types/interface/dto/index.js.map +0 -1
- package/dist/types/interface/dto/probe-webhook-delivery.dto.d.ts +0 -7
- package/dist/types/interface/dto/probe-webhook-delivery.dto.js.map +0 -1
- package/dist/types/interface/models/probe-scan.model.js.map +0 -1
- package/dist/types/interface/models/probe-webhook.model.js.map +0 -1
- package/dist/utils/http.utils.d.ts +0 -3
- package/dist/utils/http.utils.js +0 -20
- package/dist/utils/http.utils.js.map +0 -1
- /package/dist/types/interface/{dto → models}/probe-webhook-delivery.dto.js +0 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import axiosRetry, { IAxiosRetryConfig, isNetworkOrIdempotentRequestError } from 'axios-retry';
|
|
3
|
+
import * as probeScanApi from './api/probe-scan.api';
|
|
4
|
+
import * as probeWebhookApi from './api/probe-webhook.api';
|
|
5
|
+
import * as probeScanApplicationApi from './api/probe-scan.application.api';
|
|
6
|
+
import * as probeWebhookApplicationApi from './api/probe-webhook.application.api';
|
|
7
|
+
import * as probeUsageApi from './api/probe-usage.api';
|
|
8
|
+
import * as probeUsageApplicationApi from './api/probe-usage.application.api';
|
|
9
|
+
|
|
10
|
+
export * from './api';
|
|
11
|
+
export * from './types';
|
|
12
|
+
export * from './utils';
|
|
13
|
+
export * from './constants';
|
|
14
|
+
|
|
15
|
+
const DEFAULT_BASE_URL = 'https://probe-api.abyss-project.fr/api/';
|
|
16
|
+
|
|
17
|
+
export const API_KEY_HEADER = 'abyss-api-key';
|
|
18
|
+
/**
|
|
19
|
+
* Application-level API key header (AbyssProbe application/API-key
|
|
20
|
+
* authentication). Same literal value every other Abyss service's own core
|
|
21
|
+
* package independently declares for its `ApplicationMiddleware`.
|
|
22
|
+
*/
|
|
23
|
+
export const API_KEY_APPLICATION_HEADER = 'abyss-api-key-application';
|
|
24
|
+
export const ADMIN_TOKEN_HEADER = 'abyss-admin-token';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Header carrying the HMAC-SHA256 signature of a probe webhook delivery's
|
|
28
|
+
* raw JSON body. Verify it with {@link verifyProbeWebhookSignature}
|
|
29
|
+
* (re-exported from './utils').
|
|
30
|
+
*/
|
|
31
|
+
export const PROBE_WEBHOOK_SIGNATURE_HEADER = 'x-probe-signature';
|
|
32
|
+
export const PROBE_WEBHOOK_SIGNATURE_ALGORITHM = 'sha256';
|
|
33
|
+
|
|
34
|
+
const NUMBER_RETRY_API = 10;
|
|
35
|
+
const BASE_DELAY_BETWEEN_RETRY = 5000;
|
|
36
|
+
const RETRY_CODES = [
|
|
37
|
+
502, // Bad Gateway
|
|
38
|
+
503, // Service Unavailable
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
type CoreConfig = {
|
|
42
|
+
token?: string;
|
|
43
|
+
apiKey?: string;
|
|
44
|
+
adminToken?: string;
|
|
45
|
+
baseURL?: string;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
type AbyssProbeCoreSDK = {
|
|
49
|
+
probe: {
|
|
50
|
+
/** `POST /scan` — sync (default) or async depending on `options.mode`. */
|
|
51
|
+
scan: typeof probeScanApi.scan;
|
|
52
|
+
/** `POST /scan` forced to `mode: sync` — precisely-typed 200 response. */
|
|
53
|
+
scanSync: typeof probeScanApi.scanSync;
|
|
54
|
+
/** `POST /scan?mode=async` — precisely-typed 202 response. */
|
|
55
|
+
scanAsync: typeof probeScanApi.scanAsync;
|
|
56
|
+
/** `GET /scan/:scanId` — poll a scan's status/verdict. */
|
|
57
|
+
getScan: typeof probeScanApi.getScan;
|
|
58
|
+
/** `GET /scan` — paginated history/search. */
|
|
59
|
+
listScans: typeof probeScanApi.listScans;
|
|
60
|
+
/** `GET /usage` — current ACCOUNT_AV_SCAN_UNITS used/limit/remaining for the caller's scope. */
|
|
61
|
+
usage: {
|
|
62
|
+
get: typeof probeUsageApi.getProbeUsage;
|
|
63
|
+
};
|
|
64
|
+
webhook: {
|
|
65
|
+
create: typeof probeWebhookApi.createProbeWebhook;
|
|
66
|
+
list: typeof probeWebhookApi.listProbeWebhook;
|
|
67
|
+
delete: typeof probeWebhookApi.deleteProbeWebhook;
|
|
68
|
+
/** `PATCH /webhook/:webhookId` — edit callbackUrl and/or active. */
|
|
69
|
+
update: typeof probeWebhookApi.updateProbeWebhook;
|
|
70
|
+
/** `GET /webhook/:webhookId/deliveries` — paginated delivery-attempt history. */
|
|
71
|
+
listDeliveries: typeof probeWebhookApi.listProbeWebhookDeliveries;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Application/API-key-auth counterpart (Phase 3a) — for inter-service
|
|
75
|
+
* callers (abyss-storage, external integrations) instead of a
|
|
76
|
+
* personal/org session. Same request/response contracts as the methods
|
|
77
|
+
* above, hitting `/application/:applicationId/...` and authenticated
|
|
78
|
+
* with the `abyss-api-key-application` header ({@link
|
|
79
|
+
* API_KEY_APPLICATION_HEADER}) instead of the personal `abyss-api-key`.
|
|
80
|
+
*/
|
|
81
|
+
application: {
|
|
82
|
+
/** `POST /application/:applicationId/scan` — sync (default) or async depending on `options.mode`. */
|
|
83
|
+
scan: typeof probeScanApplicationApi.scanApplication;
|
|
84
|
+
/** `POST /application/:applicationId/scan` forced to `mode: sync` — precisely-typed 200 response. */
|
|
85
|
+
scanSync: typeof probeScanApplicationApi.scanSyncApplication;
|
|
86
|
+
/** `POST /application/:applicationId/scan?mode=async` — precisely-typed 202 response. */
|
|
87
|
+
scanAsync: typeof probeScanApplicationApi.scanAsyncApplication;
|
|
88
|
+
/** `GET /application/:applicationId/scan/:scanId` — poll a scan's status/verdict. */
|
|
89
|
+
getScan: typeof probeScanApplicationApi.getScanApplication;
|
|
90
|
+
/** `GET /application/:applicationId/scan` — paginated history/search. */
|
|
91
|
+
listScans: typeof probeScanApplicationApi.listScansApplication;
|
|
92
|
+
/** `GET /application/:applicationId/usage` — current ACCOUNT_AV_SCAN_UNITS used/limit/remaining for the calling application. */
|
|
93
|
+
usage: {
|
|
94
|
+
get: typeof probeUsageApplicationApi.getProbeUsageApplication;
|
|
95
|
+
};
|
|
96
|
+
webhook: {
|
|
97
|
+
create: typeof probeWebhookApplicationApi.createProbeWebhookApplication;
|
|
98
|
+
list: typeof probeWebhookApplicationApi.listProbeWebhookApplication;
|
|
99
|
+
delete: typeof probeWebhookApplicationApi.deleteProbeWebhookApplication;
|
|
100
|
+
/** `PATCH /application/:applicationId/webhook/:webhookId` — edit callbackUrl and/or active. */
|
|
101
|
+
update: typeof probeWebhookApplicationApi.updateProbeWebhookApplication;
|
|
102
|
+
/** `GET /application/:applicationId/webhook/:webhookId/deliveries` — paginated delivery-attempt history. */
|
|
103
|
+
listDeliveries: typeof probeWebhookApplicationApi.listProbeWebhookDeliveriesApplication;
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export class AbyssProbeCore {
|
|
110
|
+
private static config = {
|
|
111
|
+
token: '',
|
|
112
|
+
apiKey: '',
|
|
113
|
+
adminToken: '',
|
|
114
|
+
baseURL: DEFAULT_BASE_URL,
|
|
115
|
+
};
|
|
116
|
+
static axios = axios.create({
|
|
117
|
+
baseURL: this.config.baseURL,
|
|
118
|
+
withCredentials: true,
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
private static _sdk: AbyssProbeCoreSDK | null = null;
|
|
122
|
+
|
|
123
|
+
public static get sdk(): AbyssProbeCoreSDK {
|
|
124
|
+
if (!AbyssProbeCore._sdk) {
|
|
125
|
+
AbyssProbeCore._sdk = AbyssProbeCore.buildSDK();
|
|
126
|
+
}
|
|
127
|
+
return AbyssProbeCore._sdk;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
private static buildSDK(): AbyssProbeCoreSDK {
|
|
131
|
+
return {
|
|
132
|
+
probe: {
|
|
133
|
+
scan: probeScanApi.scan,
|
|
134
|
+
scanSync: probeScanApi.scanSync,
|
|
135
|
+
scanAsync: probeScanApi.scanAsync,
|
|
136
|
+
getScan: probeScanApi.getScan,
|
|
137
|
+
listScans: probeScanApi.listScans,
|
|
138
|
+
usage: {
|
|
139
|
+
get: probeUsageApi.getProbeUsage,
|
|
140
|
+
},
|
|
141
|
+
webhook: {
|
|
142
|
+
create: probeWebhookApi.createProbeWebhook,
|
|
143
|
+
list: probeWebhookApi.listProbeWebhook,
|
|
144
|
+
delete: probeWebhookApi.deleteProbeWebhook,
|
|
145
|
+
update: probeWebhookApi.updateProbeWebhook,
|
|
146
|
+
listDeliveries: probeWebhookApi.listProbeWebhookDeliveries,
|
|
147
|
+
},
|
|
148
|
+
application: {
|
|
149
|
+
scan: probeScanApplicationApi.scanApplication,
|
|
150
|
+
scanSync: probeScanApplicationApi.scanSyncApplication,
|
|
151
|
+
scanAsync: probeScanApplicationApi.scanAsyncApplication,
|
|
152
|
+
getScan: probeScanApplicationApi.getScanApplication,
|
|
153
|
+
listScans: probeScanApplicationApi.listScansApplication,
|
|
154
|
+
usage: {
|
|
155
|
+
get: probeUsageApplicationApi.getProbeUsageApplication,
|
|
156
|
+
},
|
|
157
|
+
webhook: {
|
|
158
|
+
create: probeWebhookApplicationApi.createProbeWebhookApplication,
|
|
159
|
+
list: probeWebhookApplicationApi.listProbeWebhookApplication,
|
|
160
|
+
delete: probeWebhookApplicationApi.deleteProbeWebhookApplication,
|
|
161
|
+
update: probeWebhookApplicationApi.updateProbeWebhookApplication,
|
|
162
|
+
listDeliveries: probeWebhookApplicationApi.listProbeWebhookDeliveriesApplication,
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
public static enableAxiosRetry(axiosRetryConfig?: IAxiosRetryConfig): void {
|
|
170
|
+
axiosRetry(AbyssProbeCore.axios, {
|
|
171
|
+
retries: NUMBER_RETRY_API,
|
|
172
|
+
retryDelay: (retryCount) => retryCount * BASE_DELAY_BETWEEN_RETRY,
|
|
173
|
+
retryCondition: (error) =>
|
|
174
|
+
isNetworkOrIdempotentRequestError(error) ||
|
|
175
|
+
RETRY_CODES.includes(error.response?.status || 502),
|
|
176
|
+
...axiosRetryConfig,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
public static setConfig(config: CoreConfig): void {
|
|
181
|
+
AbyssProbeCore._sdk = null;
|
|
182
|
+
|
|
183
|
+
AbyssProbeCore.config = { ...AbyssProbeCore.config, ...config };
|
|
184
|
+
|
|
185
|
+
if (config.baseURL) {
|
|
186
|
+
AbyssProbeCore.axios.defaults.baseURL = config.baseURL;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (config.token) {
|
|
190
|
+
AbyssProbeCore.axios.defaults.headers.common.Authorization = `Bearer ${config.token}`;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (config.apiKey) {
|
|
194
|
+
AbyssProbeCore.axios.defaults.headers.common[API_KEY_HEADER] = `${config.apiKey}`;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (config.adminToken) {
|
|
198
|
+
AbyssProbeCore.axios.defaults.headers.common[ADMIN_TOKEN_HEADER] = `${config.adminToken}`;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
public static getConfig(): CoreConfig {
|
|
203
|
+
return AbyssProbeCore.config;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export enum ErrorType {
|
|
2
|
+
apiError = 'api_error',
|
|
3
|
+
authError = 'authentication_error',
|
|
4
|
+
resourceError = 'resource_error',
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export enum Code {
|
|
8
|
+
// HTTP Error
|
|
9
|
+
tokenFailure = 'token_authentication_failure',
|
|
10
|
+
authenticationFailure = 'authentication_credentials_failure',
|
|
11
|
+
accessNotAllowed = 'access_not_allowed',
|
|
12
|
+
notFound = 'not_found',
|
|
13
|
+
validationError = 'resource_validation_error',
|
|
14
|
+
constraintError = 'resource_constraint_error',
|
|
15
|
+
internalServerError = 'internal_server_error',
|
|
16
|
+
serviceUnavailable = 'service_unavailable',
|
|
17
|
+
invalidData = 'invalid_data',
|
|
18
|
+
notImplemented = 'not_implemented',
|
|
19
|
+
retrospectiveCannotBeModifiedWhenCompleted = 'retrospective_cannot_be_modified_when_completed',
|
|
20
|
+
retrospectiveActionNotAllowedInPhase = 'retrospective_action_not_allowed_in_phase',
|
|
21
|
+
retrospectiveVoteBudgetExhausted = 'retrospective_vote_budget_exhausted',
|
|
22
|
+
retrospectiveActionLimitReached = 'retrospective_action_limit_reached',
|
|
23
|
+
atlasDocumentLimitReached = 'atlas_document_limit_reached',
|
|
24
|
+
boardCardDocumentLimitReached = 'board_card_document_limit_reached',
|
|
25
|
+
boardCardMoveInvalidDestination = 'board_card_move_invalid_destination',
|
|
26
|
+
boardCardLinkLimitReached = 'board_card_link_limit_reached',
|
|
27
|
+
boardCardLinkAlreadyExists = 'board_card_link_already_exists',
|
|
28
|
+
boardCardLinkToSelf = 'board_card_link_to_self',
|
|
29
|
+
shortLinkProtected = 'short_link_protected',
|
|
30
|
+
drawImageLimitReached = 'draw_image_limit_reached',
|
|
31
|
+
drawImageOwnerRequired = 'draw_image_owner_required',
|
|
32
|
+
drawImageNotInDraw = 'draw_image_not_in_draw',
|
|
33
|
+
}
|
|
@@ -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,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
|
+
}
|
|
@@ -0,0 +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
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Mirrors apps/api/src/api/controllers/probe-webhook.controller.ts's
|
|
2
|
+
// ScopeQuery/CreateBody/UpdateBody and probe-webhook.validator.ts's Joi
|
|
3
|
+
// schemas.
|
|
4
|
+
|
|
5
|
+
/** Shared by create/list/delete/update — personal scope (default) or an organization. */
|
|
6
|
+
export interface IProbeWebhookScopeQuery {
|
|
7
|
+
organizationId?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ICreateProbeWebhookBody {
|
|
11
|
+
/** HTTPS endpoint the verdict is POSTed to. Required, `https://` only. */
|
|
12
|
+
callbackUrl: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* `PATCH /webhook/:webhookId` body (WS5-5) — at least one field required
|
|
17
|
+
* (mirrors probe-webhook.validator.ts#updateBody's `.min(1)`); omitted
|
|
18
|
+
* fields are left unchanged.
|
|
19
|
+
*/
|
|
20
|
+
export interface IUpdateProbeWebhookBody {
|
|
21
|
+
/** HTTPS endpoint the verdict is POSTed to, `https://` only. */
|
|
22
|
+
callbackUrl?: string;
|
|
23
|
+
/** Disabled webhooks are skipped by dispatch (soft-off, not deleted). */
|
|
24
|
+
active?: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** `GET /webhook/:webhookId/deliveries` query (WS5-6) — paginated. */
|
|
28
|
+
export interface IListProbeWebhookDeliveriesQuery extends IProbeWebhookScopeQuery {
|
|
29
|
+
/** @default 1 */
|
|
30
|
+
page?: number;
|
|
31
|
+
/** @default 20 */
|
|
32
|
+
limit?: number;
|
|
33
|
+
}
|
|
@@ -0,0 +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>>;
|
|
@@ -0,0 +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>;
|
|
@@ -0,0 +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>>;
|
|
@@ -0,0 +1,67 @@
|
|
|
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). WS5-4 (AbyssProbe UX rework) widened this to full metadata
|
|
12
|
+
* parity with {@link IProbeScanHistoryItem} (fileName/fileSize/mimeType/
|
|
13
|
+
* mode/startedAt/finishedAt/costUnits) — the scanner UI's "Détails" section
|
|
14
|
+
* needs the same info whether it got there via the list or via a direct
|
|
15
|
+
* poll — still never echoing internal ownership columns (userId,
|
|
16
|
+
* organizationId, callbackUrl) — a caller polling by id already knows what
|
|
17
|
+
* it submitted.
|
|
18
|
+
*/
|
|
19
|
+
export interface IProbeScanDetail {
|
|
20
|
+
scanId: string;
|
|
21
|
+
status: ProbeScanStatus;
|
|
22
|
+
/** null until `status` is DONE. */
|
|
23
|
+
verdict: ProbeScanVerdict | null;
|
|
24
|
+
/** null until `status` is DONE; [] when DONE and clean. */
|
|
25
|
+
viruses: string[] | null;
|
|
26
|
+
/** Free-form caller reference echoed back verbatim (see IProbeScanHistoryItem#context). */
|
|
27
|
+
context: Record<string, unknown> | null;
|
|
28
|
+
fileName: string;
|
|
29
|
+
fileSize: number;
|
|
30
|
+
mimeType: string;
|
|
31
|
+
mode: ProbeScanMode;
|
|
32
|
+
/** Set the moment the engine call starts (SYNC: row-creation time; ASYNC: when a worker picks the job off the queue). */
|
|
33
|
+
startedAt: Date;
|
|
34
|
+
/** Set once the engine call returns. null while status is not DONE. */
|
|
35
|
+
finishedAt: Date | null;
|
|
36
|
+
/**
|
|
37
|
+
* `ACCOUNT_AV_SCAN_UNITS` this scan consumed (see `estimateProbeScanCost`
|
|
38
|
+
* — this package's own shared pure cost model). null until `status` is
|
|
39
|
+
* DONE; stays null forever for a scan that errors out (no verdict was ever
|
|
40
|
+
* reached, so nothing was ever billed).
|
|
41
|
+
*/
|
|
42
|
+
costUnits: number | null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* One row of `GET /scan`'s paginated history/search list. Never echoes
|
|
47
|
+
* internal ownership columns (userId, organizationId, callbackUrl) — a
|
|
48
|
+
* caller already knows their own scope from the request they made.
|
|
49
|
+
*/
|
|
50
|
+
export interface IProbeScanHistoryItem {
|
|
51
|
+
scanId: string;
|
|
52
|
+
fileName: string;
|
|
53
|
+
fileSize: number;
|
|
54
|
+
mimeType: string;
|
|
55
|
+
verdict: ProbeScanVerdict | null;
|
|
56
|
+
viruses: string[] | null;
|
|
57
|
+
mode: ProbeScanMode;
|
|
58
|
+
status: ProbeScanStatus;
|
|
59
|
+
context: Record<string, unknown> | null;
|
|
60
|
+
/** Set the moment the engine call starts (SYNC: row-creation time; ASYNC: when a worker picks the job off the queue). */
|
|
61
|
+
startedAt: Date;
|
|
62
|
+
/** Set once the engine call returns. null while status is not DONE. */
|
|
63
|
+
finishedAt: Date | null;
|
|
64
|
+
/** See {@link IProbeScanDetail#costUnits}. */
|
|
65
|
+
costUnits: number | null;
|
|
66
|
+
createdAt: Date;
|
|
67
|
+
}
|