@abyss-project/probe 2.0.1 → 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/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 +10 -1
- package/src/api/index.ts +7 -6
- 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-webhook.application.api.ts +128 -141
- package/src/index.ts +262 -205
- package/src/types/enum/api-error.enum.ts +35 -33
- package/src/types/enum/probe-scan.enum.ts +45 -44
- package/src/types/interface/api/requests/index.ts +4 -3
- package/src/types/interface/api/requests/probe-delivery-subscription.request.ts +42 -0
- package/src/types/interface/api/requests/probe-webhook.request.ts +31 -33
- package/src/types/interface/api/responses/index.ts +4 -3
- package/src/types/interface/api/responses/probe-delivery-subscription.response.ts +27 -0
- package/src/types/interface/models/probe-webhook-delivery.dto.ts +70 -73
- package/src/types/tests/probe.dto.test.ts +192 -156
- package/src/utils/probe-webhook-signature.utils.ts +57 -56
- 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
|
@@ -1,156 +1,192 @@
|
|
|
1
|
-
// Type-level compile test for AbyssProbe's DTO/response shapes — asserts
|
|
2
|
-
// they match the server contract (probe-scan.controller.ts /
|
|
3
|
-
// probe-webhook.controller.ts / probe-usage.controller.ts /
|
|
4
|
-
// probe-webhook-delivery.service.ts) at compile time: any incompatible
|
|
5
|
-
// rename/removal on either side fails `npm run build` here. No jest runner
|
|
6
|
-
// in this SDK package; compile guard only (mirrors
|
|
7
|
-
// ../api/extraction-plan-preset.api.test.ts). Run: npx tsc --noEmit.
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
ProbeScanVerdict,
|
|
11
|
-
ProbeScanMode,
|
|
12
|
-
ProbeScanStatus,
|
|
13
|
-
IProbeScanDetail,
|
|
14
|
-
IProbeScanHistoryItem,
|
|
15
|
-
IProbeWebhook,
|
|
16
|
-
IProbeWebhookDelivery,
|
|
17
|
-
IProbeWebhookDeliveryPayload,
|
|
18
|
-
IScanSyncData,
|
|
19
|
-
IScanAsyncData,
|
|
20
|
-
IUpdateProbeWebhookBody,
|
|
21
|
-
IProbeUsageData,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
1
|
+
// Type-level compile test for AbyssProbe's DTO/response shapes — asserts
|
|
2
|
+
// they match the server contract (probe-scan.controller.ts /
|
|
3
|
+
// probe-webhook-application.controller.ts / probe-usage.controller.ts /
|
|
4
|
+
// probe-webhook-delivery.service.ts) at compile time: any incompatible
|
|
5
|
+
// rename/removal on either side fails `npm run build` here. No jest runner
|
|
6
|
+
// in this SDK package; compile guard only (mirrors
|
|
7
|
+
// ../api/extraction-plan-preset.api.test.ts). Run: npx tsc --noEmit.
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
ProbeScanVerdict,
|
|
11
|
+
ProbeScanMode,
|
|
12
|
+
ProbeScanStatus,
|
|
13
|
+
IProbeScanDetail,
|
|
14
|
+
IProbeScanHistoryItem,
|
|
15
|
+
IProbeWebhook,
|
|
16
|
+
IProbeWebhookDelivery,
|
|
17
|
+
IProbeWebhookDeliveryPayload,
|
|
18
|
+
IScanSyncData,
|
|
19
|
+
IScanAsyncData,
|
|
20
|
+
IUpdateProbeWebhookBody,
|
|
21
|
+
IProbeUsageData,
|
|
22
|
+
ICreateProbeDeliverySubscriptionBody,
|
|
23
|
+
IUpdateProbeDeliverySubscriptionBody,
|
|
24
|
+
IPaginateProbeDeliveryQuery,
|
|
25
|
+
IPaginateProbeDeliverySubscriptionQuery,
|
|
26
|
+
ICreateProbeDeliverySubscriptionResponse,
|
|
27
|
+
IGetProbeDeliverySubscriptionResponse,
|
|
28
|
+
Code,
|
|
29
|
+
} from '..';
|
|
30
|
+
// estimateProbeScanCost lives in src/utils/ (a SIBLING of src/types/, not
|
|
31
|
+
// re-exported by the types barrel this file otherwise imports from) — see
|
|
32
|
+
// probe-scan-cost.utils.ts's own header comment for why it is a plain
|
|
33
|
+
// top-level export rather than a `sdk.probe.*` method.
|
|
34
|
+
import { estimateProbeScanCost } from '../../utils';
|
|
35
|
+
|
|
36
|
+
// Enum exhaustiveness: fails to compile if a member is added/removed/renamed
|
|
37
|
+
// here without updating this file — a cheap drift guard for values
|
|
38
|
+
// transported verbatim over the wire (this SDK does not control the
|
|
39
|
+
// server's enum, so a silent value drift is exactly what this must catch).
|
|
40
|
+
const _verdicts: Record<ProbeScanVerdict, true> = { clean: true, infected: true };
|
|
41
|
+
const _modes: Record<ProbeScanMode, true> = { sync: true, async: true };
|
|
42
|
+
const _statuses: Record<ProbeScanStatus, true> = {
|
|
43
|
+
queued: true,
|
|
44
|
+
scanning: true,
|
|
45
|
+
done: true,
|
|
46
|
+
error: true,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// GET /scan/:scanId — WS5-4: full metadata parity with IProbeScanHistoryItem
|
|
50
|
+
// (fileName/fileSize/mimeType/mode/startedAt/finishedAt/costUnits).
|
|
51
|
+
const _scanDetail: IProbeScanDetail = {
|
|
52
|
+
scanId: 's1',
|
|
53
|
+
status: ProbeScanStatus.DONE,
|
|
54
|
+
verdict: ProbeScanVerdict.CLEAN,
|
|
55
|
+
viruses: [],
|
|
56
|
+
context: null,
|
|
57
|
+
fileName: 'invoice.pdf',
|
|
58
|
+
fileSize: 1024,
|
|
59
|
+
mimeType: 'application/pdf',
|
|
60
|
+
mode: ProbeScanMode.SYNC,
|
|
61
|
+
startedAt: new Date(),
|
|
62
|
+
finishedAt: new Date(),
|
|
63
|
+
costUnits: 3,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// GET /scan history row — WS5-1: costUnits added.
|
|
67
|
+
const _historyItem: IProbeScanHistoryItem = {
|
|
68
|
+
scanId: 's1',
|
|
69
|
+
fileName: 'invoice.pdf',
|
|
70
|
+
fileSize: 1024,
|
|
71
|
+
mimeType: 'application/pdf',
|
|
72
|
+
verdict: ProbeScanVerdict.INFECTED,
|
|
73
|
+
viruses: ['Eicar-Test-Signature'],
|
|
74
|
+
mode: ProbeScanMode.ASYNC,
|
|
75
|
+
status: ProbeScanStatus.DONE,
|
|
76
|
+
context: { applicationFileId: 'af1' },
|
|
77
|
+
startedAt: new Date(),
|
|
78
|
+
finishedAt: new Date(),
|
|
79
|
+
costUnits: 1,
|
|
80
|
+
createdAt: new Date(),
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// POST /scan — sync (200) / async (202) data shapes. WS5-1: costUnits added to the sync shape (always known/billed by the time a 200 is returned).
|
|
84
|
+
const _scanSyncData: IScanSyncData = {
|
|
85
|
+
scanId: 's1',
|
|
86
|
+
verdict: ProbeScanVerdict.CLEAN,
|
|
87
|
+
viruses: [],
|
|
88
|
+
costUnits: 3,
|
|
89
|
+
};
|
|
90
|
+
const _scanAsyncData: IScanAsyncData = { scanId: 's1', status: ProbeScanStatus.QUEUED };
|
|
91
|
+
|
|
92
|
+
// Webhook subscription — WS5-7: secret is now ALWAYS present (list/create/
|
|
93
|
+
// update) and the create response returns IProbeWebhook.
|
|
94
|
+
const _webhook: IProbeWebhook = {
|
|
95
|
+
id: 'w1',
|
|
96
|
+
callbackUrl: 'https://example.com/hook',
|
|
97
|
+
secret: 'shh',
|
|
98
|
+
active: true,
|
|
99
|
+
createdAt: new Date(),
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// PATCH /application/:applicationId/webhook/:webhookId body (WS5-5) — every field optional (at least one required server-side).
|
|
103
|
+
const _updateBody: IUpdateProbeWebhookBody = { active: false };
|
|
104
|
+
const _updateBody2: IUpdateProbeWebhookBody = { callbackUrl: 'https://example.com/hook2' };
|
|
105
|
+
|
|
106
|
+
// Webhook delivery payload — the exact body signed by x-probe-signature
|
|
107
|
+
// (see verifyProbeWebhookSignature). WS5-1: costUnits added.
|
|
108
|
+
const _deliveryPayload: IProbeWebhookDeliveryPayload = {
|
|
109
|
+
scanId: 's1',
|
|
110
|
+
context: null,
|
|
111
|
+
verdict: ProbeScanVerdict.INFECTED,
|
|
112
|
+
viruses: ['Eicar-Test-Signature'],
|
|
113
|
+
costUnits: 5,
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// GET /application/:applicationId/webhook/:webhookId/deliveries row (WS5-6) — a persisted delivery-attempt.
|
|
117
|
+
const _deliveryRecord: IProbeWebhookDelivery = {
|
|
118
|
+
id: 'd1',
|
|
119
|
+
webhookId: 'w1',
|
|
120
|
+
scanId: 's1',
|
|
121
|
+
url: 'https://example.com/hook',
|
|
122
|
+
statusCode: 200,
|
|
123
|
+
success: true,
|
|
124
|
+
attemptedAt: new Date(),
|
|
125
|
+
error: null,
|
|
126
|
+
createdAt: new Date(),
|
|
127
|
+
};
|
|
128
|
+
// webhookId stays nullable: it mirrors the column's real type.
|
|
129
|
+
const _deliveryRecordAdHoc: IProbeWebhookDelivery = { ..._deliveryRecord, webhookId: null };
|
|
130
|
+
|
|
131
|
+
// Delivery subscriptions (P5 #792) — the client's subscriptions live in Flow; the body names the
|
|
132
|
+
// one event and the URL, the scope is the caller (or `organizationId`, or the application).
|
|
133
|
+
const _createSubscription: ICreateProbeDeliverySubscriptionBody = {
|
|
134
|
+
eventTypes: ['PROBE_SCAN_COMPLETED'],
|
|
135
|
+
url: 'https://example.com/hook',
|
|
136
|
+
};
|
|
137
|
+
const _updateSubscription: IUpdateProbeDeliverySubscriptionBody = { isEnabled: false };
|
|
138
|
+
const _subscriptionQuery: IPaginateProbeDeliverySubscriptionQuery = {
|
|
139
|
+
organizationId: 'o1',
|
|
140
|
+
isEnabled: true,
|
|
141
|
+
page: 1,
|
|
142
|
+
limit: 20,
|
|
143
|
+
};
|
|
144
|
+
const _deliveryQuery: IPaginateProbeDeliveryQuery = { organizationId: 'o1', page: 2 };
|
|
145
|
+
// The secret is on the creation answer only.
|
|
146
|
+
declare const created: ICreateProbeDeliverySubscriptionResponse;
|
|
147
|
+
declare const read: IGetProbeDeliverySubscriptionResponse;
|
|
148
|
+
const _secret: string = created.data.secret;
|
|
149
|
+
// @ts-expect-error a read never carries the secret
|
|
150
|
+
const _noSecret: string = read.data.secret;
|
|
151
|
+
const _callbackCode: Code = Code.probeCallbackRequiresSubscription;
|
|
152
|
+
|
|
153
|
+
// GET /usage data shape (WS5-3).
|
|
154
|
+
const _usage: IProbeUsageData = { used: 10, limit: 1000, remaining: 990 };
|
|
155
|
+
// -1 is the established "unlimited" sentinel (see estimateProbeScanCost's
|
|
156
|
+
// server-side counterpart, utils/billing-emit.util.ts#UNLIMITED_EXPIRY_DAYS).
|
|
157
|
+
const _usageUnlimited: IProbeUsageData = { used: 10, limit: -1, remaining: -1 };
|
|
158
|
+
|
|
159
|
+
// estimateProbeScanCost (WS5-2) — pure shared cost model, ASYNC must cost
|
|
160
|
+
// strictly less than SYNC for the same size (the scanner UI's "background
|
|
161
|
+
// analysis saves tokens" tooltip depends on this). A one-byte compile-time
|
|
162
|
+
// smoke check; the full behavioural suite lives in probe-scan-cost.utils.test.ts.
|
|
163
|
+
const _asyncCost: number = estimateProbeScanCost(5 * 1024 * 1024, ProbeScanMode.ASYNC);
|
|
164
|
+
const _syncCost: number = estimateProbeScanCost(5 * 1024 * 1024, ProbeScanMode.SYNC);
|
|
165
|
+
if (_asyncCost >= _syncCost) {
|
|
166
|
+
throw new Error('estimateProbeScanCost: ASYNC must cost strictly less than SYNC');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
void _verdicts;
|
|
170
|
+
void _modes;
|
|
171
|
+
void _statuses;
|
|
172
|
+
void _scanDetail;
|
|
173
|
+
void _historyItem;
|
|
174
|
+
void _scanSyncData;
|
|
175
|
+
void _scanAsyncData;
|
|
176
|
+
void _webhook;
|
|
177
|
+
void _createSubscription;
|
|
178
|
+
void _updateSubscription;
|
|
179
|
+
void _subscriptionQuery;
|
|
180
|
+
void _deliveryQuery;
|
|
181
|
+
void _secret;
|
|
182
|
+
void _noSecret;
|
|
183
|
+
void _callbackCode;
|
|
184
|
+
void _updateBody;
|
|
185
|
+
void _updateBody2;
|
|
186
|
+
void _deliveryPayload;
|
|
187
|
+
void _deliveryRecord;
|
|
188
|
+
void _deliveryRecordAdHoc;
|
|
189
|
+
void _usage;
|
|
190
|
+
void _usageUnlimited;
|
|
191
|
+
|
|
192
|
+
export {};
|
|
@@ -1,56 +1,57 @@
|
|
|
1
|
-
// ──────────────────────────────────────────────
|
|
2
|
-
// AbyssProbe webhook signature verification (helper for
|
|
3
|
-
// webhook
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
// the
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
secret
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
.
|
|
42
|
-
.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
Buffer.from(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
1
|
+
// ──────────────────────────────────────────────
|
|
2
|
+
// AbyssProbe webhook signature verification (helper for the RECEIVER of the
|
|
3
|
+
// internal webhook — AbyssStorage's antivirus subscription — until its client
|
|
4
|
+
// subscriptions move to Flow, P5 #792 L2). A client's own subscription is
|
|
5
|
+
// signed by Flow, whose helper verifies it.
|
|
6
|
+
//
|
|
7
|
+
// Mirrors this package's own extraction-webhook.utils.ts
|
|
8
|
+
// (verifyExtractionWebhook) — the same package's own precedent for this
|
|
9
|
+
// exact problem — adapted to AbyssProbe's actual wire format: the signature
|
|
10
|
+
// header (see PROBE_WEBHOOK_SIGNATURE_HEADER in this package's root index)
|
|
11
|
+
// carries the RAW hex HMAC digest with no `sha256=` prefix (unlike
|
|
12
|
+
// the extraction signature header `x-rcb-signature: sha256=<hex>`) — see
|
|
13
|
+
// apps/api/src/services/probe-webhook-delivery.service.ts's `sign()`.
|
|
14
|
+
//
|
|
15
|
+
// Lazy-requires `crypto` so the SDK stays browser-compatible when this
|
|
16
|
+
// utility is never invoked (a browser page is never the receiving end of a
|
|
17
|
+
// server-to-server webhook).
|
|
18
|
+
// ──────────────────────────────────────────────
|
|
19
|
+
|
|
20
|
+
export interface VerifyProbeWebhookSignatureInput {
|
|
21
|
+
/** The exact bytes/string the receiver's HTTP framework handed it — must be the RAW body, not a re-serialized JSON.parse/stringify round trip (whitespace/key-order would change the HMAC). */
|
|
22
|
+
rawBody: string | Buffer;
|
|
23
|
+
/** The incoming `x-probe-signature` header value. */
|
|
24
|
+
signatureHeader: string | undefined;
|
|
25
|
+
/** This webhook registration's secret (re-displayable on IProbeWebhook). */
|
|
26
|
+
secret: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Recompute the HMAC-SHA256 of `rawBody` with `secret` and constant-time
|
|
31
|
+
* compare it against `signatureHeader`. Returns `false` (never throws) for
|
|
32
|
+
* any malformed input — a hostile/truncated header must not crash the
|
|
33
|
+
* receiver.
|
|
34
|
+
*/
|
|
35
|
+
export function verifyProbeWebhookSignature(input: VerifyProbeWebhookSignatureInput): boolean {
|
|
36
|
+
if (!input.signatureHeader || !input.secret) return false;
|
|
37
|
+
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
39
|
+
const crypto = require('crypto');
|
|
40
|
+
const computed: string = crypto
|
|
41
|
+
.createHmac('sha256', input.secret)
|
|
42
|
+
.update(input.rawBody)
|
|
43
|
+
.digest('hex');
|
|
44
|
+
|
|
45
|
+
if (input.signatureHeader.length !== computed.length) return false;
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
return crypto.timingSafeEqual(
|
|
49
|
+
Buffer.from(input.signatureHeader, 'hex'),
|
|
50
|
+
Buffer.from(computed, 'hex'),
|
|
51
|
+
);
|
|
52
|
+
} catch {
|
|
53
|
+
// Buffer.from(..., 'hex') on a non-hex string yields a shorter buffer,
|
|
54
|
+
// which would otherwise make timingSafeEqual throw on a length mismatch.
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { ICreateProbeWebhookBody, IUpdateProbeWebhookBody, IProbeWebhookScopeQuery, IListProbeWebhookDeliveriesQuery, ICreateProbeWebhookResponse, IListProbeWebhookResponse, IDeleteProbeWebhookResponse, IUpdateProbeWebhookResponse, IListProbeWebhookDeliveriesResponse } from '../types';
|
|
2
|
-
export declare const createProbeWebhook: (body: ICreateProbeWebhookBody, scope?: IProbeWebhookScopeQuery, apiKey?: string) => Promise<ICreateProbeWebhookResponse>;
|
|
3
|
-
export declare const listProbeWebhook: (scope?: IProbeWebhookScopeQuery, apiKey?: string) => Promise<IListProbeWebhookResponse>;
|
|
4
|
-
export declare const deleteProbeWebhook: (webhookId: string, scope?: IProbeWebhookScopeQuery, apiKey?: string) => Promise<IDeleteProbeWebhookResponse>;
|
|
5
|
-
export declare const updateProbeWebhook: (webhookId: string, body: IUpdateProbeWebhookBody, scope?: IProbeWebhookScopeQuery, apiKey?: string) => Promise<IUpdateProbeWebhookResponse>;
|
|
6
|
-
export declare const listProbeWebhookDeliveries: (webhookId: string, query?: IListProbeWebhookDeliveriesQuery, apiKey?: string) => Promise<IListProbeWebhookDeliveriesResponse>;
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.listProbeWebhookDeliveries = exports.updateProbeWebhook = exports.deleteProbeWebhook = exports.listProbeWebhook = exports.createProbeWebhook = void 0;
|
|
4
|
-
const __1 = require("..");
|
|
5
|
-
const DEFAULT_API_KEY_HEADER = 'abyss-api-key';
|
|
6
|
-
function authHeader(apiKey) {
|
|
7
|
-
return apiKey ? { [DEFAULT_API_KEY_HEADER]: apiKey } : {};
|
|
8
|
-
}
|
|
9
|
-
function serializeProbeQuery(query) {
|
|
10
|
-
const out = {};
|
|
11
|
-
for (const [key, value] of Object.entries(query)) {
|
|
12
|
-
if (value === undefined || value === null)
|
|
13
|
-
continue;
|
|
14
|
-
const wireKey = key === 'organizationId' ? 'organization_id' : key;
|
|
15
|
-
out[wireKey] = value instanceof Date ? value.toISOString() : value;
|
|
16
|
-
}
|
|
17
|
-
return out;
|
|
18
|
-
}
|
|
19
|
-
const createProbeWebhook = async (body, scope = {}, apiKey) => (await __1.AbyssProbeCore.axios.post('webhook', body, {
|
|
20
|
-
params: serializeProbeQuery(scope),
|
|
21
|
-
headers: authHeader(apiKey),
|
|
22
|
-
})).data;
|
|
23
|
-
exports.createProbeWebhook = createProbeWebhook;
|
|
24
|
-
const listProbeWebhook = async (scope = {}, apiKey) => (await __1.AbyssProbeCore.axios.get('webhook', {
|
|
25
|
-
params: serializeProbeQuery(scope),
|
|
26
|
-
headers: authHeader(apiKey),
|
|
27
|
-
})).data;
|
|
28
|
-
exports.listProbeWebhook = listProbeWebhook;
|
|
29
|
-
const deleteProbeWebhook = async (webhookId, scope = {}, apiKey) => (await __1.AbyssProbeCore.axios.delete(`webhook/${webhookId}`, {
|
|
30
|
-
params: serializeProbeQuery(scope),
|
|
31
|
-
headers: authHeader(apiKey),
|
|
32
|
-
})).data;
|
|
33
|
-
exports.deleteProbeWebhook = deleteProbeWebhook;
|
|
34
|
-
const updateProbeWebhook = async (webhookId, body, scope = {}, apiKey) => (await __1.AbyssProbeCore.axios.patch(`webhook/${webhookId}`, body, {
|
|
35
|
-
params: serializeProbeQuery(scope),
|
|
36
|
-
headers: authHeader(apiKey),
|
|
37
|
-
})).data;
|
|
38
|
-
exports.updateProbeWebhook = updateProbeWebhook;
|
|
39
|
-
const listProbeWebhookDeliveries = async (webhookId, query = {}, apiKey) => (await __1.AbyssProbeCore.axios.get(`webhook/${webhookId}/deliveries`, { params: serializeProbeQuery(query), headers: authHeader(apiKey) })).data;
|
|
40
|
-
exports.listProbeWebhookDeliveries = listProbeWebhookDeliveries;
|
|
41
|
-
//# sourceMappingURL=probe-webhook.api.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"probe-webhook.api.js","sourceRoot":"","sources":["../../src/api/probe-webhook.api.ts"],"names":[],"mappings":";;;AAaA,0BAAoC;AAapC,MAAM,sBAAsB,GAAG,eAAe,CAAC;AAE/C,SAAS,UAAU,CAAC,MAAe;IACjC,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5D,CAAC;AAGD,SAAS,mBAAmB,CAAmB,KAAQ;IACrD,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;QAC5E,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;YAAE,SAAS;QACpD,MAAM,OAAO,GAAG,GAAG,KAAK,gBAAgB,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC;QACnE,GAAG,CAAC,OAAO,CAAC,GAAG,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IACrE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAOM,MAAM,kBAAkB,GAAG,KAAK,EACrC,IAA6B,EAC7B,QAAiC,EAAE,EACnC,MAAe,EACuB,EAAE,CACxC,CACE,MAAM,kBAAc,CAAC,KAAK,CAAC,IAAI,CAA8B,SAAS,EAAE,IAAI,EAAE;IAC5E,MAAM,EAAE,mBAAmB,CAAC,KAAK,CAAC;IAClC,OAAO,EAAE,UAAU,CAAC,MAAM,CAAC;CAC5B,CAAC,CACH,CAAC,IAAI,CAAC;AAVI,QAAA,kBAAkB,sBAUtB;AAGF,MAAM,gBAAgB,GAAG,KAAK,EACnC,QAAiC,EAAE,EACnC,MAAe,EACqB,EAAE,CACtC,CACE,MAAM,kBAAc,CAAC,KAAK,CAAC,GAAG,CAA4B,SAAS,EAAE;IACnE,MAAM,EAAE,mBAAmB,CAAC,KAAK,CAAC;IAClC,OAAO,EAAE,UAAU,CAAC,MAAM,CAAC;CAC5B,CAAC,CACH,CAAC,IAAI,CAAC;AATI,QAAA,gBAAgB,oBASpB;AAGF,MAAM,kBAAkB,GAAG,KAAK,EACrC,SAAiB,EACjB,QAAiC,EAAE,EACnC,MAAe,EACuB,EAAE,CACxC,CACE,MAAM,kBAAc,CAAC,KAAK,CAAC,MAAM,CAA8B,WAAW,SAAS,EAAE,EAAE;IACrF,MAAM,EAAE,mBAAmB,CAAC,KAAK,CAAC;IAClC,OAAO,EAAE,UAAU,CAAC,MAAM,CAAC;CAC5B,CAAC,CACH,CAAC,IAAI,CAAC;AAVI,QAAA,kBAAkB,sBAUtB;AAQF,MAAM,kBAAkB,GAAG,KAAK,EACrC,SAAiB,EACjB,IAA6B,EAC7B,QAAiC,EAAE,EACnC,MAAe,EACuB,EAAE,CACxC,CACE,MAAM,kBAAc,CAAC,KAAK,CAAC,KAAK,CAA8B,WAAW,SAAS,EAAE,EAAE,IAAI,EAAE;IAC1F,MAAM,EAAE,mBAAmB,CAAC,KAAK,CAAC;IAClC,OAAO,EAAE,UAAU,CAAC,MAAM,CAAC;CAC5B,CAAC,CACH,CAAC,IAAI,CAAC;AAXI,QAAA,kBAAkB,sBAWtB;AAMF,MAAM,0BAA0B,GAAG,KAAK,EAC7C,SAAiB,EACjB,QAA0C,EAAE,EAC5C,MAAe,EAC+B,EAAE,CAChD,CACE,MAAM,kBAAc,CAAC,KAAK,CAAC,GAAG,CAC5B,WAAW,SAAS,aAAa,EACjC,EAAE,MAAM,EAAE,mBAAmB,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,CACpE,CACF,CAAC,IAAI,CAAC;AAVI,QAAA,0BAA0B,8BAU9B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
const api = __importStar(require("./probe-webhook.api"));
|
|
37
|
-
const _create = api.createProbeWebhook;
|
|
38
|
-
const _list = api.listProbeWebhook;
|
|
39
|
-
const _delete = api.deleteProbeWebhook;
|
|
40
|
-
void _create;
|
|
41
|
-
void _list;
|
|
42
|
-
void _delete;
|
|
43
|
-
//# sourceMappingURL=probe-webhook.api.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"probe-webhook.api.test.js","sourceRoot":"","sources":["../../src/api/probe-webhook.api.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,yDAA2C;AAI3C,MAAM,OAAO,GAAkC,GAAG,CAAC,kBAAkB,CAAC;AACtE,MAAM,KAAK,GAAgC,GAAG,CAAC,gBAAgB,CAAC;AAChE,MAAM,OAAO,GAAkC,GAAG,CAAC,kBAAkB,CAAC;AAEtE,KAAK,OAAO,CAAC;AACb,KAAK,KAAK,CAAC;AACX,KAAK,OAAO,CAAC"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
// Type-level compile test for the probe-webhook api surface.
|
|
2
|
-
// No jest runner in this SDK package; compile guard only.
|
|
3
|
-
// Run: npx tsc --noEmit (from packages/abyss_probe_core), or `npm run build`.
|
|
4
|
-
|
|
5
|
-
import * as api from './probe-webhook.api';
|
|
6
|
-
|
|
7
|
-
// All three functions must be exported — deliberately no update/reset-secret
|
|
8
|
-
// (see probe-webhook.controller.ts's header comment on the small CRUD surface).
|
|
9
|
-
const _create: typeof api.createProbeWebhook = api.createProbeWebhook;
|
|
10
|
-
const _list: typeof api.listProbeWebhook = api.listProbeWebhook;
|
|
11
|
-
const _delete: typeof api.deleteProbeWebhook = api.deleteProbeWebhook;
|
|
12
|
-
|
|
13
|
-
void _create;
|
|
14
|
-
void _list;
|
|
15
|
-
void _delete;
|
|
16
|
-
|
|
17
|
-
export {};
|