@abyss-project/tools 2.2.0 → 2.4.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 +2 -0
- package/dist/api/index.js +2 -0
- package/dist/api/index.js.map +1 -1
- 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 +8 -1
- package/dist/api/probe-webhook.api.js.map +1 -1
- package/dist/api/probe-webhook.application.api.d.ts +3 -1
- package/dist/api/probe-webhook.application.api.js +14 -1
- package/dist/api/probe-webhook.application.api.js.map +1 -1
- package/dist/index.d.ts +12 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/types/enum/beam.enum.d.ts +8 -2
- package/dist/types/enum/beam.enum.js +9 -2
- package/dist/types/enum/beam.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-usage.request.d.ts +3 -0
- package/dist/types/interface/api/requests/probe-usage.request.js +3 -0
- 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/beam.response.d.ts +2 -1
- 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 +4 -1
- package/dist/types/interface/models/probe-scan.dto.d.ts +8 -0
- package/dist/types/interface/models/probe-webhook-delivery.dto.d.ts +12 -0
- package/dist/types/interface/models/probe-webhook.dto.d.ts +2 -3
- package/dist/types/tests/probe.dto.test.js +40 -1
- package/dist/types/tests/probe.dto.test.js.map +1 -1
- 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-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/package.json +1 -1
- package/src/api/index.ts +2 -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.ts +43 -5
- package/src/api/probe-webhook.application.api.ts +58 -4
- package/src/index.ts +28 -0
- package/src/types/enum/beam.enum.ts +17 -1
- package/src/types/interface/api/requests/index.ts +1 -0
- package/src/types/interface/api/requests/probe-usage.request.ts +7 -0
- package/src/types/interface/api/requests/probe-webhook.request.ts +23 -2
- package/src/types/interface/api/responses/beam.response.ts +10 -1
- package/src/types/interface/api/responses/index.ts +1 -0
- package/src/types/interface/api/responses/probe-scan.response.ts +7 -0
- package/src/types/interface/api/responses/probe-usage.response.ts +25 -0
- package/src/types/interface/api/responses/probe-webhook.response.ts +10 -3
- package/src/types/interface/models/probe-scan.dto.ts +27 -8
- package/src/types/interface/models/probe-webhook-delivery.dto.ts +47 -0
- package/src/types/interface/models/probe-webhook.dto.ts +25 -11
- package/src/types/tests/probe.dto.test.ts +73 -11
- package/src/utils/index.ts +1 -0
- package/src/utils/probe-scan-cost.utils.ts +101 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const __1 = require("..");
|
|
4
|
+
const utils_1 = require("../../utils");
|
|
4
5
|
const _verdicts = { clean: true, infected: true };
|
|
5
6
|
const _modes = { sync: true, async: true };
|
|
6
7
|
const _statuses = {
|
|
@@ -15,6 +16,13 @@ const _scanDetail = {
|
|
|
15
16
|
verdict: __1.ProbeScanVerdict.CLEAN,
|
|
16
17
|
viruses: [],
|
|
17
18
|
context: null,
|
|
19
|
+
fileName: 'invoice.pdf',
|
|
20
|
+
fileSize: 1024,
|
|
21
|
+
mimeType: 'application/pdf',
|
|
22
|
+
mode: __1.ProbeScanMode.SYNC,
|
|
23
|
+
startedAt: new Date(),
|
|
24
|
+
finishedAt: new Date(),
|
|
25
|
+
costUnits: 3,
|
|
18
26
|
};
|
|
19
27
|
const _historyItem = {
|
|
20
28
|
scanId: 's1',
|
|
@@ -28,27 +36,52 @@ const _historyItem = {
|
|
|
28
36
|
context: { applicationFileId: 'af1' },
|
|
29
37
|
startedAt: new Date(),
|
|
30
38
|
finishedAt: new Date(),
|
|
39
|
+
costUnits: 1,
|
|
31
40
|
createdAt: new Date(),
|
|
32
41
|
};
|
|
33
42
|
const _scanSyncData = {
|
|
34
43
|
scanId: 's1',
|
|
35
44
|
verdict: __1.ProbeScanVerdict.CLEAN,
|
|
36
45
|
viruses: [],
|
|
46
|
+
costUnits: 3,
|
|
37
47
|
};
|
|
38
48
|
const _scanAsyncData = { scanId: 's1', status: __1.ProbeScanStatus.QUEUED };
|
|
39
49
|
const _webhook = {
|
|
40
50
|
id: 'w1',
|
|
41
51
|
callbackUrl: 'https://example.com/hook',
|
|
52
|
+
secret: 'shh',
|
|
42
53
|
active: true,
|
|
43
54
|
createdAt: new Date(),
|
|
44
55
|
};
|
|
45
|
-
const _webhookCreated =
|
|
56
|
+
const _webhookCreated = _webhook;
|
|
57
|
+
const _updateBody = { active: false };
|
|
58
|
+
const _updateBody2 = { callbackUrl: 'https://example.com/hook2' };
|
|
46
59
|
const _deliveryPayload = {
|
|
47
60
|
scanId: 's1',
|
|
48
61
|
context: null,
|
|
49
62
|
verdict: __1.ProbeScanVerdict.INFECTED,
|
|
50
63
|
viruses: ['Eicar-Test-Signature'],
|
|
64
|
+
costUnits: 5,
|
|
65
|
+
};
|
|
66
|
+
const _deliveryRecord = {
|
|
67
|
+
id: 'd1',
|
|
68
|
+
webhookId: 'w1',
|
|
69
|
+
scanId: 's1',
|
|
70
|
+
url: 'https://example.com/hook',
|
|
71
|
+
statusCode: 200,
|
|
72
|
+
success: true,
|
|
73
|
+
attemptedAt: new Date(),
|
|
74
|
+
error: null,
|
|
75
|
+
createdAt: new Date(),
|
|
51
76
|
};
|
|
77
|
+
const _deliveryRecordAdHoc = { ..._deliveryRecord, webhookId: null };
|
|
78
|
+
const _usage = { used: 10, limit: 1000, remaining: 990 };
|
|
79
|
+
const _usageUnlimited = { used: 10, limit: -1, remaining: -1 };
|
|
80
|
+
const _asyncCost = (0, utils_1.estimateProbeScanCost)(5 * 1024 * 1024, __1.ProbeScanMode.ASYNC);
|
|
81
|
+
const _syncCost = (0, utils_1.estimateProbeScanCost)(5 * 1024 * 1024, __1.ProbeScanMode.SYNC);
|
|
82
|
+
if (_asyncCost >= _syncCost) {
|
|
83
|
+
throw new Error('estimateProbeScanCost: ASYNC must cost strictly less than SYNC');
|
|
84
|
+
}
|
|
52
85
|
void _verdicts;
|
|
53
86
|
void _modes;
|
|
54
87
|
void _statuses;
|
|
@@ -58,5 +91,11 @@ void _scanSyncData;
|
|
|
58
91
|
void _scanAsyncData;
|
|
59
92
|
void _webhook;
|
|
60
93
|
void _webhookCreated;
|
|
94
|
+
void _updateBody;
|
|
95
|
+
void _updateBody2;
|
|
61
96
|
void _deliveryPayload;
|
|
97
|
+
void _deliveryRecord;
|
|
98
|
+
void _deliveryRecordAdHoc;
|
|
99
|
+
void _usage;
|
|
100
|
+
void _usageUnlimited;
|
|
62
101
|
//# sourceMappingURL=probe.dto.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"probe.dto.test.js","sourceRoot":"","sources":["../../../src/types/tests/probe.dto.test.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"probe.dto.test.js","sourceRoot":"","sources":["../../../src/types/tests/probe.dto.test.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
|
@@ -21,4 +21,5 @@ __exportStar(require("./icons.utils"), exports);
|
|
|
21
21
|
__exportStar(require("./enum.utils"), exports);
|
|
22
22
|
__exportStar(require("./extraction-webhook.utils"), exports);
|
|
23
23
|
__exportStar(require("./probe-webhook-signature.utils"), exports);
|
|
24
|
+
__exportStar(require("./probe-scan-cost.utils"), exports);
|
|
24
25
|
//# sourceMappingURL=index.js.map
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,gDAA8B;AAC9B,gDAA8B;AAC9B,gDAA8B;AAC9B,+CAA6B;AAC7B,6DAA2C;AAC3C,kEAAgD"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,gDAA8B;AAC9B,gDAA8B;AAC9B,gDAA8B;AAC9B,+CAA6B;AAC7B,6DAA2C;AAC3C,kEAAgD;AAChD,0DAAwC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ProbeScanMode } from '../types';
|
|
2
|
+
export declare const PROBE_SCAN_COST_BASE = 1;
|
|
3
|
+
export declare const PROBE_SCAN_COST_K_MB = 1;
|
|
4
|
+
export declare const PROBE_SCAN_COST_MODE_WEIGHT: Record<ProbeScanMode, number>;
|
|
5
|
+
export declare const estimateProbeScanCost: (sizeOctet: number, mode: ProbeScanMode | 'sync' | 'async') => number;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.estimateProbeScanCost = exports.PROBE_SCAN_COST_MODE_WEIGHT = exports.PROBE_SCAN_COST_K_MB = exports.PROBE_SCAN_COST_BASE = void 0;
|
|
4
|
+
const types_1 = require("../types");
|
|
5
|
+
exports.PROBE_SCAN_COST_BASE = 1;
|
|
6
|
+
exports.PROBE_SCAN_COST_K_MB = 1;
|
|
7
|
+
exports.PROBE_SCAN_COST_MODE_WEIGHT = {
|
|
8
|
+
[types_1.ProbeScanMode.ASYNC]: 1,
|
|
9
|
+
[types_1.ProbeScanMode.SYNC]: 3,
|
|
10
|
+
};
|
|
11
|
+
const ONE_MB = 1024 * 1024;
|
|
12
|
+
const estimateProbeScanCost = (sizeOctet, mode) => {
|
|
13
|
+
if (!Number.isFinite(sizeOctet) || sizeOctet <= 0) {
|
|
14
|
+
return 0;
|
|
15
|
+
}
|
|
16
|
+
const megabytes = Math.ceil(sizeOctet / ONE_MB);
|
|
17
|
+
const weight = exports.PROBE_SCAN_COST_MODE_WEIGHT[mode] ?? exports.PROBE_SCAN_COST_MODE_WEIGHT[types_1.ProbeScanMode.ASYNC];
|
|
18
|
+
return Math.round((exports.PROBE_SCAN_COST_BASE + exports.PROBE_SCAN_COST_K_MB * megabytes) * weight);
|
|
19
|
+
};
|
|
20
|
+
exports.estimateProbeScanCost = estimateProbeScanCost;
|
|
21
|
+
//# sourceMappingURL=probe-scan-cost.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe-scan-cost.utils.js","sourceRoot":"","sources":["../../src/utils/probe-scan-cost.utils.ts"],"names":[],"mappings":";;;AAuCA,oCAAyC;AAG5B,QAAA,oBAAoB,GAAG,CAAC,CAAC;AAGzB,QAAA,oBAAoB,GAAG,CAAC,CAAC;AAUzB,QAAA,2BAA2B,GAAkC;IACxE,CAAC,qBAAa,CAAC,KAAK,CAAC,EAAE,CAAC;IACxB,CAAC,qBAAa,CAAC,IAAI,CAAC,EAAE,CAAC;CACxB,CAAC;AAGF,MAAM,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;AA4BpB,MAAM,qBAAqB,GAAG,CACnC,SAAiB,EACjB,IAAsC,EAC9B,EAAE;IACV,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QAClD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC;IAChD,MAAM,MAAM,GACV,mCAA2B,CAAC,IAAI,CAAC,IAAI,mCAA2B,CAAC,qBAAa,CAAC,KAAK,CAAC,CAAC;IACxF,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,4BAAoB,GAAG,4BAAoB,GAAG,SAAS,CAAC,GAAG,MAAM,CAAC,CAAC;AACxF,CAAC,CAAC;AAXW,QAAA,qBAAqB,yBAWhC"}
|
package/package.json
CHANGED
package/src/api/index.ts
CHANGED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// ──────────────────────────────────────────────
|
|
2
|
+
// AbyssProbe usage API — WS5-3 (AbyssProbe UX rework). `GET /usage`: current
|
|
3
|
+
// ACCOUNT_AV_SCAN_UNITS ("tokens") used/limit/remaining for the caller's
|
|
4
|
+
// scope, via the same billing check the quota gate itself already uses (see
|
|
5
|
+
// apps/api/src/utils/probe-scan-billing.util.ts#getProbeScanUsage). Mirrors
|
|
6
|
+
// apps/api/src/api/controllers/probe-usage.controller.ts EXACTLY. No
|
|
7
|
+
// `probe/` path prefix — `@Controller({ prefixPath: '/usage' })` mounts
|
|
8
|
+
// directly at `usage`.
|
|
9
|
+
//
|
|
10
|
+
// See probe-usage.application.api.ts for the application/API-key-auth
|
|
11
|
+
// counterpart (`/application/:applicationId/usage`, Phase 3a).
|
|
12
|
+
// ──────────────────────────────────────────────
|
|
13
|
+
|
|
14
|
+
import { AbyssToolsCore } from '..';
|
|
15
|
+
import type { IProbeUsageScopeQuery, IProbeUsageResponse } from '../types';
|
|
16
|
+
|
|
17
|
+
const DEFAULT_API_KEY_HEADER = 'abyss-api-key';
|
|
18
|
+
|
|
19
|
+
function authHeader(apiKey?: string): Record<string, string> {
|
|
20
|
+
return apiKey ? { [DEFAULT_API_KEY_HEADER]: apiKey } : {};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Renames `organizationId` to the wire's `organization_id` (see probe-scan.api.ts). */
|
|
24
|
+
function serializeProbeQuery<T extends object>(query: T): Record<string, unknown> {
|
|
25
|
+
const out: Record<string, unknown> = {};
|
|
26
|
+
for (const [key, value] of Object.entries(query as Record<string, unknown>)) {
|
|
27
|
+
if (value === undefined || value === null) continue;
|
|
28
|
+
const wireKey = key === 'organizationId' ? 'organization_id' : key;
|
|
29
|
+
out[wireKey] = value;
|
|
30
|
+
}
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* `GET /usage` — current ACCOUNT_AV_SCAN_UNITS consumption for the caller's
|
|
36
|
+
* scope (personal by default, `organizationId` for an organization scope).
|
|
37
|
+
*/
|
|
38
|
+
export const getProbeUsage = async (
|
|
39
|
+
scope: IProbeUsageScopeQuery = {},
|
|
40
|
+
apiKey?: string,
|
|
41
|
+
): Promise<IProbeUsageResponse> =>
|
|
42
|
+
(
|
|
43
|
+
await AbyssToolsCore.axios.get<IProbeUsageResponse>('usage', {
|
|
44
|
+
params: serializeProbeQuery(scope),
|
|
45
|
+
headers: authHeader(apiKey),
|
|
46
|
+
})
|
|
47
|
+
).data;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// ──────────────────────────────────────────────
|
|
2
|
+
// AbyssProbe APPLICATION usage API — WS5-3 (AbyssProbe UX rework). `GET
|
|
3
|
+
// /application/:applicationId/usage`: current ACCOUNT_AV_SCAN_UNITS
|
|
4
|
+
// consumption for the calling application's resolved billing organization.
|
|
5
|
+
// Mirrors apps/api/src/api/controllers/probe-usage-application.controller.ts
|
|
6
|
+
// EXACTLY — the application counterpart of probe-usage.api.ts.
|
|
7
|
+
// ──────────────────────────────────────────────
|
|
8
|
+
|
|
9
|
+
import { AbyssToolsCore, API_KEY_APPLICATION_HEADER } from '..';
|
|
10
|
+
import type { IProbeUsageResponse } from '../types';
|
|
11
|
+
|
|
12
|
+
function authHeaderApplication(applicationApiKey?: string): Record<string, string> {
|
|
13
|
+
return applicationApiKey ? { [API_KEY_APPLICATION_HEADER]: applicationApiKey } : {};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** `GET /application/:applicationId/usage` — current ACCOUNT_AV_SCAN_UNITS consumption for the calling application. */
|
|
17
|
+
export const getProbeUsageApplication = async (
|
|
18
|
+
applicationId: string,
|
|
19
|
+
applicationApiKey?: string,
|
|
20
|
+
): Promise<IProbeUsageResponse> =>
|
|
21
|
+
(
|
|
22
|
+
await AbyssToolsCore.axios.get<IProbeUsageResponse>(`application/${applicationId}/usage`, {
|
|
23
|
+
headers: authHeaderApplication(applicationApiKey),
|
|
24
|
+
})
|
|
25
|
+
).data;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
// ──────────────────────────────────────────────
|
|
2
2
|
// AbyssProbe webhook subscription API — CRUD over registered `probe_webhooks`
|
|
3
|
-
// (create / list / delete
|
|
4
|
-
// apps/api/src/api/controllers/probe-webhook.controller.ts
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
// `webhook`.
|
|
3
|
+
// (create / list / delete / update, + paginated delivery history — mirrors
|
|
4
|
+
// apps/api/src/api/controllers/probe-webhook.controller.ts EXACTLY, see that
|
|
5
|
+
// file's header comment). No `probe/` path prefix — `@Controller({
|
|
6
|
+
// prefixPath: '/webhook' })` mounts directly at `webhook`.
|
|
8
7
|
//
|
|
9
8
|
// See probe-webhook.application.api.ts for the application/API-key-auth
|
|
10
9
|
// counterpart of this client (`/application/:applicationId/webhook...`,
|
|
@@ -15,10 +14,14 @@
|
|
|
15
14
|
import { AbyssToolsCore } from '..';
|
|
16
15
|
import type {
|
|
17
16
|
ICreateProbeWebhookBody,
|
|
17
|
+
IUpdateProbeWebhookBody,
|
|
18
18
|
IProbeWebhookScopeQuery,
|
|
19
|
+
IListProbeWebhookDeliveriesQuery,
|
|
19
20
|
ICreateProbeWebhookResponse,
|
|
20
21
|
IListProbeWebhookResponse,
|
|
21
22
|
IDeleteProbeWebhookResponse,
|
|
23
|
+
IUpdateProbeWebhookResponse,
|
|
24
|
+
IListProbeWebhookDeliveriesResponse,
|
|
22
25
|
} from '../types';
|
|
23
26
|
|
|
24
27
|
const DEFAULT_API_KEY_HEADER = 'abyss-api-key';
|
|
@@ -79,3 +82,38 @@ export const deleteProbeWebhook = async (
|
|
|
79
82
|
headers: authHeader(apiKey),
|
|
80
83
|
})
|
|
81
84
|
).data;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* `PATCH /webhook/:webhookId` (WS5-5) — edit `callbackUrl` and/or `active`.
|
|
88
|
+
* At least one field is required. Scoped like {@link deleteProbeWebhook}
|
|
89
|
+
* (404, never 403, for a webhookId outside the resolved scope). The response
|
|
90
|
+
* includes `secret` — re-displayable now, see {@link IProbeWebhook}.
|
|
91
|
+
*/
|
|
92
|
+
export const updateProbeWebhook = async (
|
|
93
|
+
webhookId: string,
|
|
94
|
+
body: IUpdateProbeWebhookBody,
|
|
95
|
+
scope: IProbeWebhookScopeQuery = {},
|
|
96
|
+
apiKey?: string,
|
|
97
|
+
): Promise<IUpdateProbeWebhookResponse> =>
|
|
98
|
+
(
|
|
99
|
+
await AbyssToolsCore.axios.patch<IUpdateProbeWebhookResponse>(`webhook/${webhookId}`, body, {
|
|
100
|
+
params: serializeProbeQuery(scope),
|
|
101
|
+
headers: authHeader(apiKey),
|
|
102
|
+
})
|
|
103
|
+
).data;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* `GET /webhook/:webhookId/deliveries` (WS5-6) — paginated delivery-attempt
|
|
107
|
+
* history for one registered webhook. Scoped like {@link deleteProbeWebhook}.
|
|
108
|
+
*/
|
|
109
|
+
export const listProbeWebhookDeliveries = async (
|
|
110
|
+
webhookId: string,
|
|
111
|
+
query: IListProbeWebhookDeliveriesQuery = {},
|
|
112
|
+
apiKey?: string,
|
|
113
|
+
): Promise<IListProbeWebhookDeliveriesResponse> =>
|
|
114
|
+
(
|
|
115
|
+
await AbyssToolsCore.axios.get<IListProbeWebhookDeliveriesResponse>(
|
|
116
|
+
`webhook/${webhookId}/deliveries`,
|
|
117
|
+
{ params: serializeProbeQuery(query), headers: authHeader(apiKey) },
|
|
118
|
+
)
|
|
119
|
+
).data;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// ──────────────────────────────────────────────
|
|
2
2
|
// AbyssProbe APPLICATION webhook subscription API — CRUD over registered
|
|
3
|
-
// `probe_webhooks` owned by a calling application (create / list / delete
|
|
4
|
-
//
|
|
5
|
-
//
|
|
3
|
+
// `probe_webhooks` owned by a calling application (create / list / delete /
|
|
4
|
+
// update, + paginated delivery history — same surface as the personal/org
|
|
5
|
+
// client, see probe-webhook.api.ts's header comment). Mirrors
|
|
6
6
|
// apps/api/src/api/controllers/probe-webhook-application.controller.ts
|
|
7
7
|
// EXACTLY — the application counterpart of probe-webhook.api.ts, for
|
|
8
8
|
// inter-service callers (abyss-storage, external integrations)
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
//
|
|
11
11
|
// Reuses every request/response TYPE verbatim (`ICreateProbeWebhookBody`,
|
|
12
12
|
// `ICreateProbeWebhookResponse`, `IListProbeWebhookResponse`,
|
|
13
|
-
// `IDeleteProbeWebhookResponse`
|
|
13
|
+
// `IDeleteProbeWebhookResponse`, `IUpdateProbeWebhookBody`,
|
|
14
|
+
// `IUpdateProbeWebhookResponse`, `IListProbeWebhookDeliveriesQuery`,
|
|
15
|
+
// `IListProbeWebhookDeliveriesResponse`) — never redefined here. No scope
|
|
14
16
|
// argument/query on any of these calls (unlike the personal/org client's
|
|
15
17
|
// `IProbeWebhookScopeQuery`) — an application caller's scope is entirely its
|
|
16
18
|
// `:applicationId` URL segment, resolved server-side by
|
|
@@ -25,15 +27,29 @@
|
|
|
25
27
|
import { AbyssToolsCore, API_KEY_APPLICATION_HEADER } from '..';
|
|
26
28
|
import type {
|
|
27
29
|
ICreateProbeWebhookBody,
|
|
30
|
+
IUpdateProbeWebhookBody,
|
|
31
|
+
IListProbeWebhookDeliveriesQuery,
|
|
28
32
|
ICreateProbeWebhookResponse,
|
|
29
33
|
IListProbeWebhookResponse,
|
|
30
34
|
IDeleteProbeWebhookResponse,
|
|
35
|
+
IUpdateProbeWebhookResponse,
|
|
36
|
+
IListProbeWebhookDeliveriesResponse,
|
|
31
37
|
} from '../types';
|
|
32
38
|
|
|
33
39
|
function authHeaderApplication(applicationApiKey?: string): Record<string, string> {
|
|
34
40
|
return applicationApiKey ? { [API_KEY_APPLICATION_HEADER]: applicationApiKey } : {};
|
|
35
41
|
}
|
|
36
42
|
|
|
43
|
+
/** Renames nothing (no `organizationId` ever travels on an application call) — drops undefined/null and ISO-stringifies `Date`s, mirroring probe-scan.application.api.ts's own local helper. */
|
|
44
|
+
function serializeProbeQuery<T extends object>(query: T): Record<string, unknown> {
|
|
45
|
+
const out: Record<string, unknown> = {};
|
|
46
|
+
for (const [key, value] of Object.entries(query as Record<string, unknown>)) {
|
|
47
|
+
if (value === undefined || value === null) continue;
|
|
48
|
+
out[key] = value instanceof Date ? value.toISOString() : value;
|
|
49
|
+
}
|
|
50
|
+
return out;
|
|
51
|
+
}
|
|
52
|
+
|
|
37
53
|
/**
|
|
38
54
|
* `POST /application/:applicationId/webhook` — register a callbackUrl owned
|
|
39
55
|
* by the calling application. The response's `secret` field (HMAC signing
|
|
@@ -85,3 +101,41 @@ export const deleteProbeWebhookApplication = async (
|
|
|
85
101
|
{ headers: authHeaderApplication(applicationApiKey) },
|
|
86
102
|
)
|
|
87
103
|
).data;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* `PATCH /application/:applicationId/webhook/:webhookId` (WS5-5) — edit
|
|
107
|
+
* `callbackUrl` and/or `active` on a webhook owned by the calling
|
|
108
|
+
* application. Cross-tenant guarded server-side (404, never 403). The
|
|
109
|
+
* response includes `secret` — re-displayable now, see {@link IProbeWebhook}.
|
|
110
|
+
*/
|
|
111
|
+
export const updateProbeWebhookApplication = async (
|
|
112
|
+
applicationId: string,
|
|
113
|
+
webhookId: string,
|
|
114
|
+
body: IUpdateProbeWebhookBody,
|
|
115
|
+
applicationApiKey?: string,
|
|
116
|
+
): Promise<IUpdateProbeWebhookResponse> =>
|
|
117
|
+
(
|
|
118
|
+
await AbyssToolsCore.axios.patch<IUpdateProbeWebhookResponse>(
|
|
119
|
+
`application/${applicationId}/webhook/${webhookId}`,
|
|
120
|
+
body,
|
|
121
|
+
{ headers: authHeaderApplication(applicationApiKey) },
|
|
122
|
+
)
|
|
123
|
+
).data;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* `GET /application/:applicationId/webhook/:webhookId/deliveries` (WS5-6) —
|
|
127
|
+
* paginated delivery-attempt history for one webhook owned by the calling
|
|
128
|
+
* application. Cross-tenant guarded server-side (404, never 403).
|
|
129
|
+
*/
|
|
130
|
+
export const listProbeWebhookDeliveriesApplication = async (
|
|
131
|
+
applicationId: string,
|
|
132
|
+
webhookId: string,
|
|
133
|
+
query: Omit<IListProbeWebhookDeliveriesQuery, 'organizationId'> = {},
|
|
134
|
+
applicationApiKey?: string,
|
|
135
|
+
): Promise<IListProbeWebhookDeliveriesResponse> =>
|
|
136
|
+
(
|
|
137
|
+
await AbyssToolsCore.axios.get<IListProbeWebhookDeliveriesResponse>(
|
|
138
|
+
`application/${applicationId}/webhook/${webhookId}/deliveries`,
|
|
139
|
+
{ params: serializeProbeQuery(query), headers: authHeaderApplication(applicationApiKey) },
|
|
140
|
+
)
|
|
141
|
+
).data;
|
package/src/index.ts
CHANGED
|
@@ -36,6 +36,8 @@ import * as probeScanApi from './api/probe-scan.api';
|
|
|
36
36
|
import * as probeWebhookApi from './api/probe-webhook.api';
|
|
37
37
|
import * as probeScanApplicationApi from './api/probe-scan.application.api';
|
|
38
38
|
import * as probeWebhookApplicationApi from './api/probe-webhook.application.api';
|
|
39
|
+
import * as probeUsageApi from './api/probe-usage.api';
|
|
40
|
+
import * as probeUsageApplicationApi from './api/probe-usage.application.api';
|
|
39
41
|
|
|
40
42
|
export * from './api';
|
|
41
43
|
export * from './types';
|
|
@@ -347,10 +349,18 @@ type AbyssToolsCoreSDK = {
|
|
|
347
349
|
getScan: typeof probeScanApi.getScan;
|
|
348
350
|
/** `GET /scan` — paginated history/search. */
|
|
349
351
|
listScans: typeof probeScanApi.listScans;
|
|
352
|
+
/** `GET /usage` — current ACCOUNT_AV_SCAN_UNITS used/limit/remaining for the caller's scope. */
|
|
353
|
+
usage: {
|
|
354
|
+
get: typeof probeUsageApi.getProbeUsage;
|
|
355
|
+
};
|
|
350
356
|
webhook: {
|
|
351
357
|
create: typeof probeWebhookApi.createProbeWebhook;
|
|
352
358
|
list: typeof probeWebhookApi.listProbeWebhook;
|
|
353
359
|
delete: typeof probeWebhookApi.deleteProbeWebhook;
|
|
360
|
+
/** `PATCH /webhook/:webhookId` — edit callbackUrl and/or active. */
|
|
361
|
+
update: typeof probeWebhookApi.updateProbeWebhook;
|
|
362
|
+
/** `GET /webhook/:webhookId/deliveries` — paginated delivery-attempt history. */
|
|
363
|
+
listDeliveries: typeof probeWebhookApi.listProbeWebhookDeliveries;
|
|
354
364
|
};
|
|
355
365
|
/**
|
|
356
366
|
* Application/API-key-auth counterpart (Phase 3a) — for inter-service
|
|
@@ -371,10 +381,18 @@ type AbyssToolsCoreSDK = {
|
|
|
371
381
|
getScan: typeof probeScanApplicationApi.getScanApplication;
|
|
372
382
|
/** `GET /application/:applicationId/scan` — paginated history/search. */
|
|
373
383
|
listScans: typeof probeScanApplicationApi.listScansApplication;
|
|
384
|
+
/** `GET /application/:applicationId/usage` — current ACCOUNT_AV_SCAN_UNITS used/limit/remaining for the calling application. */
|
|
385
|
+
usage: {
|
|
386
|
+
get: typeof probeUsageApplicationApi.getProbeUsageApplication;
|
|
387
|
+
};
|
|
374
388
|
webhook: {
|
|
375
389
|
create: typeof probeWebhookApplicationApi.createProbeWebhookApplication;
|
|
376
390
|
list: typeof probeWebhookApplicationApi.listProbeWebhookApplication;
|
|
377
391
|
delete: typeof probeWebhookApplicationApi.deleteProbeWebhookApplication;
|
|
392
|
+
/** `PATCH /application/:applicationId/webhook/:webhookId` — edit callbackUrl and/or active. */
|
|
393
|
+
update: typeof probeWebhookApplicationApi.updateProbeWebhookApplication;
|
|
394
|
+
/** `GET /application/:applicationId/webhook/:webhookId/deliveries` — paginated delivery-attempt history. */
|
|
395
|
+
listDeliveries: typeof probeWebhookApplicationApi.listProbeWebhookDeliveriesApplication;
|
|
378
396
|
};
|
|
379
397
|
};
|
|
380
398
|
};
|
|
@@ -775,10 +793,15 @@ export class AbyssToolsCore {
|
|
|
775
793
|
scanAsync: probeScanApi.scanAsync,
|
|
776
794
|
getScan: probeScanApi.getScan,
|
|
777
795
|
listScans: probeScanApi.listScans,
|
|
796
|
+
usage: {
|
|
797
|
+
get: probeUsageApi.getProbeUsage,
|
|
798
|
+
},
|
|
778
799
|
webhook: {
|
|
779
800
|
create: probeWebhookApi.createProbeWebhook,
|
|
780
801
|
list: probeWebhookApi.listProbeWebhook,
|
|
781
802
|
delete: probeWebhookApi.deleteProbeWebhook,
|
|
803
|
+
update: probeWebhookApi.updateProbeWebhook,
|
|
804
|
+
listDeliveries: probeWebhookApi.listProbeWebhookDeliveries,
|
|
782
805
|
},
|
|
783
806
|
application: {
|
|
784
807
|
scan: probeScanApplicationApi.scanApplication,
|
|
@@ -786,10 +809,15 @@ export class AbyssToolsCore {
|
|
|
786
809
|
scanAsync: probeScanApplicationApi.scanAsyncApplication,
|
|
787
810
|
getScan: probeScanApplicationApi.getScanApplication,
|
|
788
811
|
listScans: probeScanApplicationApi.listScansApplication,
|
|
812
|
+
usage: {
|
|
813
|
+
get: probeUsageApplicationApi.getProbeUsageApplication,
|
|
814
|
+
},
|
|
789
815
|
webhook: {
|
|
790
816
|
create: probeWebhookApplicationApi.createProbeWebhookApplication,
|
|
791
817
|
list: probeWebhookApplicationApi.listProbeWebhookApplication,
|
|
792
818
|
delete: probeWebhookApplicationApi.deleteProbeWebhookApplication,
|
|
819
|
+
update: probeWebhookApplicationApi.updateProbeWebhookApplication,
|
|
820
|
+
listDeliveries: probeWebhookApplicationApi.listProbeWebhookDeliveriesApplication,
|
|
793
821
|
},
|
|
794
822
|
},
|
|
795
823
|
},
|
|
@@ -20,7 +20,23 @@ export enum BeamServeDenyReasonCode {
|
|
|
20
20
|
FORBIDDEN_VISIBILITY = 'forbidden_visibility',
|
|
21
21
|
MAX_DOWNLOADS = 'max_downloads',
|
|
22
22
|
SCAN_PENDING = 'scan_pending',
|
|
23
|
-
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Per-file AV verdict surfaced on the public listing (GET /b/:slug) so the
|
|
26
|
+
// front can render a per-file badge — clean / "en analyse" (pending) /
|
|
27
|
+
// "infecté" — independently of the whole-transfer denial reason above.
|
|
28
|
+
// Storage-neutral: AbyssBeam serves an INFECTED file's bytes (spec decision —
|
|
29
|
+
// infected files stay downloadable, not blocked; the front is expected to
|
|
30
|
+
// warn before/at download). Mirrors the storage extension's `FileScanStatus`
|
|
31
|
+
// (`@abyss-project/storage`) byte-for-byte; duplicated locally because this
|
|
32
|
+
// package does not depend on `@abyss-project/storage` (same rationale as
|
|
33
|
+
// BeamServeDenyReasonCode above).
|
|
34
|
+
export enum BeamFileScanStatus {
|
|
35
|
+
PENDING_SCAN = 'pending_scan',
|
|
36
|
+
CLEAN = 'clean',
|
|
37
|
+
INFECTED = 'infected',
|
|
38
|
+
SKIPPED = 'skipped',
|
|
39
|
+
ERROR = 'error',
|
|
24
40
|
}
|
|
25
41
|
|
|
26
42
|
// What a beam_download_events row counted: a single-file download (/b/:slug/
|
|
@@ -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
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// Mirrors apps/api/src/api/controllers/probe-webhook.controller.ts's
|
|
2
|
-
// ScopeQuery/CreateBody and probe-webhook.validator.ts's Joi
|
|
2
|
+
// ScopeQuery/CreateBody/UpdateBody and probe-webhook.validator.ts's Joi
|
|
3
|
+
// schemas.
|
|
3
4
|
|
|
4
|
-
/** Shared by create/list/delete — personal scope (default) or an organization. */
|
|
5
|
+
/** Shared by create/list/delete/update — personal scope (default) or an organization. */
|
|
5
6
|
export interface IProbeWebhookScopeQuery {
|
|
6
7
|
organizationId?: string;
|
|
7
8
|
}
|
|
@@ -10,3 +11,23 @@ export interface ICreateProbeWebhookBody {
|
|
|
10
11
|
/** HTTPS endpoint the verdict is POSTed to. Required, `https://` only. */
|
|
11
12
|
callbackUrl: string;
|
|
12
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
|
+
}
|
|
@@ -2,7 +2,12 @@ import { BasePaginate } from '../type-message/base-paginate';
|
|
|
2
2
|
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
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
BeamVisibility,
|
|
7
|
+
BeamServeDenyReasonCode,
|
|
8
|
+
BeamDownloadKind,
|
|
9
|
+
BeamFileScanStatus,
|
|
10
|
+
} from '../../../enum/beam.enum';
|
|
6
11
|
|
|
7
12
|
export interface IGetBeamData {
|
|
8
13
|
beamTransfer: IBeamTransfer;
|
|
@@ -39,6 +44,9 @@ export type IFinalizeBeamResponse = IResponse<IFinalizeBeamData>;
|
|
|
39
44
|
// Public serving (B3) — safe, purpose-built projection of a transfer for the
|
|
40
45
|
// browser-facing view: no owner ids, no password/manage hashes; adds
|
|
41
46
|
// hasPassword/isLocked/hasThumbnail so the front can render the locked state.
|
|
47
|
+
// `scanStatus` is the per-file AV verdict (storage-neutral — an INFECTED file
|
|
48
|
+
// is still listed and downloadable; the front renders the warning from this
|
|
49
|
+
// field, see BeamFileScanStatus).
|
|
42
50
|
export interface IBeamPublicFile {
|
|
43
51
|
id: string;
|
|
44
52
|
name: string;
|
|
@@ -48,6 +56,7 @@ export interface IBeamPublicFile {
|
|
|
48
56
|
hasThumbnail: boolean;
|
|
49
57
|
width: number | null;
|
|
50
58
|
height: number | null;
|
|
59
|
+
scanStatus: BeamFileScanStatus;
|
|
51
60
|
}
|
|
52
61
|
|
|
53
62
|
export interface IBeamPublicView {
|
|
@@ -12,6 +12,13 @@ export interface IScanSyncData {
|
|
|
12
12
|
scanId: string;
|
|
13
13
|
verdict: ProbeScanVerdict;
|
|
14
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;
|
|
15
22
|
}
|
|
16
23
|
export type IScanSyncResponse = IResponse<IScanSyncData>;
|
|
17
24
|
|
|
@@ -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>;
|