@zksecurity/zkao-sdk 0.14.0-next.9 → 0.16.0-next.11
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/index.d.ts +666 -1
- package/dist/index.js +138 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -216,6 +216,154 @@ interface paths {
|
|
|
216
216
|
patch?: never;
|
|
217
217
|
trace?: never;
|
|
218
218
|
};
|
|
219
|
+
"/projects/{projectId}/reports": {
|
|
220
|
+
parameters: {
|
|
221
|
+
query?: never;
|
|
222
|
+
header?: never;
|
|
223
|
+
path?: never;
|
|
224
|
+
cookie?: never;
|
|
225
|
+
};
|
|
226
|
+
/**
|
|
227
|
+
* List incoming reports
|
|
228
|
+
* @description Requires scope: `read`. Vulnerability reports the programme has received, newest first. Optionally filter by `status`.
|
|
229
|
+
*
|
|
230
|
+
* `publicId` is what `investigateReport` takes. `intakeState` says whether the report has been read and split into claims yet: an investigation waits for `COMPLETE`, so a `PENDING` or `RUNNING` report is one to come back to rather than one to retry.
|
|
231
|
+
*/
|
|
232
|
+
get: operations["listReports"];
|
|
233
|
+
put?: never;
|
|
234
|
+
post?: never;
|
|
235
|
+
delete?: never;
|
|
236
|
+
options?: never;
|
|
237
|
+
head?: never;
|
|
238
|
+
patch?: never;
|
|
239
|
+
trace?: never;
|
|
240
|
+
};
|
|
241
|
+
"/projects/{projectId}/reports/{publicId}/investigate": {
|
|
242
|
+
parameters: {
|
|
243
|
+
query?: never;
|
|
244
|
+
header?: never;
|
|
245
|
+
path?: never;
|
|
246
|
+
cookie?: never;
|
|
247
|
+
};
|
|
248
|
+
get?: never;
|
|
249
|
+
put?: never;
|
|
250
|
+
/**
|
|
251
|
+
* Investigate an incoming report against the code
|
|
252
|
+
* @description Requires scope: `scans:launch`. Runs the triage flow over the report's claims: each is checked against the repository, deduplicated against the findings already confirmed there, and given a proof of concept where one can be written. Returns immediately with the scan doing the work; poll `/projects/{projectId}/scans/{scanId}` and then read its findings.
|
|
253
|
+
*
|
|
254
|
+
* Idempotent. A report already under investigation returns the existing scan with `claimsQueued: null`, so a retry costs nothing.
|
|
255
|
+
*/
|
|
256
|
+
post: operations["investigateReport"];
|
|
257
|
+
delete?: never;
|
|
258
|
+
options?: never;
|
|
259
|
+
head?: never;
|
|
260
|
+
patch?: never;
|
|
261
|
+
trace?: never;
|
|
262
|
+
};
|
|
263
|
+
"/projects/{projectId}/advisories": {
|
|
264
|
+
parameters: {
|
|
265
|
+
query?: never;
|
|
266
|
+
header?: never;
|
|
267
|
+
path?: never;
|
|
268
|
+
cookie?: never;
|
|
269
|
+
};
|
|
270
|
+
/**
|
|
271
|
+
* List advisories
|
|
272
|
+
* @description Requires scope: `read`. The project's coordinated-disclosure advisories, newest first. Optionally filter by `status`.
|
|
273
|
+
*/
|
|
274
|
+
get: operations["listAdvisories"];
|
|
275
|
+
put?: never;
|
|
276
|
+
post?: never;
|
|
277
|
+
delete?: never;
|
|
278
|
+
options?: never;
|
|
279
|
+
head?: never;
|
|
280
|
+
patch?: never;
|
|
281
|
+
trace?: never;
|
|
282
|
+
};
|
|
283
|
+
"/projects/{projectId}/advisories/{publicId}": {
|
|
284
|
+
parameters: {
|
|
285
|
+
query?: never;
|
|
286
|
+
header?: never;
|
|
287
|
+
path?: never;
|
|
288
|
+
cookie?: never;
|
|
289
|
+
};
|
|
290
|
+
/**
|
|
291
|
+
* Get an advisory
|
|
292
|
+
* @description Requires scope: `read`. The advisory, the software it concerns, the versions it affects, and the notices planned for it.
|
|
293
|
+
*
|
|
294
|
+
* `software` is what decides the audience: a contact is notified about an advisory only when they run some of it. `affected` is a separate statement about versions, and is often empty.
|
|
295
|
+
*
|
|
296
|
+
* A notice the plan is holding back carries `blockedReason`. The commonest one is that no affected range names a fixed version, which only the people who shipped the release can supply; record it in the app and the notice becomes schedulable.
|
|
297
|
+
*/
|
|
298
|
+
get: operations["getAdvisory"];
|
|
299
|
+
put?: never;
|
|
300
|
+
post?: never;
|
|
301
|
+
delete?: never;
|
|
302
|
+
options?: never;
|
|
303
|
+
head?: never;
|
|
304
|
+
patch?: never;
|
|
305
|
+
trace?: never;
|
|
306
|
+
};
|
|
307
|
+
"/projects/{projectId}/advisories/{publicId}/affected": {
|
|
308
|
+
parameters: {
|
|
309
|
+
query?: never;
|
|
310
|
+
header?: never;
|
|
311
|
+
path?: never;
|
|
312
|
+
cookie?: never;
|
|
313
|
+
};
|
|
314
|
+
get?: never;
|
|
315
|
+
/**
|
|
316
|
+
* Record which versions an advisory affects
|
|
317
|
+
* @description Requires scope: `advisories:write`. Replaces the whole set of affected ranges, so send what is affected now rather than a patch.
|
|
318
|
+
*
|
|
319
|
+
* `fixedIn` is the point of this endpoint. A patch notice stays blocked until some range names a fixed version, and only the people who shipped the release know it.
|
|
320
|
+
*
|
|
321
|
+
* Versions only. A range may name only software already on the advisory's `software`, and anything else is a `400`. Which software an advisory concerns decides who hears about it, and that is its own statement, made in the app: a call about versions does not change it in either direction.
|
|
322
|
+
*
|
|
323
|
+
* This call never sends anything. It records versions and recomputes the disclosure plan: a notice blocked for want of a fix becomes eligible to go, and one that loses its fix is blocked again, dropping any approval it was carrying so nobody approves wording a later fix rewrites. When an eligible notice is actually sent is governed by the programme's own settings, not by this call.
|
|
324
|
+
*/
|
|
325
|
+
put: operations["replaceAdvisoryAffected"];
|
|
326
|
+
post?: never;
|
|
327
|
+
delete?: never;
|
|
328
|
+
options?: never;
|
|
329
|
+
head?: never;
|
|
330
|
+
patch?: never;
|
|
331
|
+
trace?: never;
|
|
332
|
+
};
|
|
333
|
+
"/projects/{projectId}/advisory-contacts": {
|
|
334
|
+
parameters: {
|
|
335
|
+
query?: never;
|
|
336
|
+
header?: never;
|
|
337
|
+
path?: never;
|
|
338
|
+
cookie?: never;
|
|
339
|
+
};
|
|
340
|
+
/**
|
|
341
|
+
* List the advisory contacts
|
|
342
|
+
* @description Requires scope: `contacts:read`. The programme's contact list, oldest first, which is the order to read it in when reconciling against a record kept elsewhere.
|
|
343
|
+
*
|
|
344
|
+
* Its own scope, not `read`: this list is other people's work addresses and the record of who learns about a vulnerability before the public does, so a routine pipeline token does not reach it.
|
|
345
|
+
*
|
|
346
|
+
* `software` on each row is what notices are matched on. A project with no security programme reads as an empty list.
|
|
347
|
+
*/
|
|
348
|
+
get: operations["listAdvisoryContacts"];
|
|
349
|
+
put?: never;
|
|
350
|
+
/**
|
|
351
|
+
* Add an advisory contact
|
|
352
|
+
* @description Requires scope: `contacts:write`. Puts one address on the programme's contact list.
|
|
353
|
+
*
|
|
354
|
+
* `software` says which of the project's repositories this contact runs, and is required. It is what every notice is matched on: a contact who runs nothing is told nothing.
|
|
355
|
+
*
|
|
356
|
+
* The contact starts `PENDING_VERIFICATION`, and an unconfirmed address receives nothing embargoed. The confirmation mail is sent from the app, not by this call, so nothing is emailed to the address you send here.
|
|
357
|
+
*
|
|
358
|
+
* There is no endpoint that reads the contact list back. It is other people's work addresses and the record of who hears about a vulnerability early.
|
|
359
|
+
*/
|
|
360
|
+
post: operations["addAdvisoryContact"];
|
|
361
|
+
delete?: never;
|
|
362
|
+
options?: never;
|
|
363
|
+
head?: never;
|
|
364
|
+
patch?: never;
|
|
365
|
+
trace?: never;
|
|
366
|
+
};
|
|
219
367
|
"/projects/{projectId}/findings": {
|
|
220
368
|
parameters: {
|
|
221
369
|
query?: never;
|
|
@@ -692,6 +840,131 @@ interface components {
|
|
|
692
840
|
limit: number;
|
|
693
841
|
total: number;
|
|
694
842
|
};
|
|
843
|
+
Report: {
|
|
844
|
+
/** @description The identifier `investigateReport` takes. */
|
|
845
|
+
publicId: string;
|
|
846
|
+
title: string;
|
|
847
|
+
/** @description How it arrived. Today always GitHub private vulnerability reporting. */
|
|
848
|
+
source: string;
|
|
849
|
+
/** @description What the reporter claimed, which is not an assessment. */
|
|
850
|
+
claimedSeverity?: components["schemas"]["Severity"] | null;
|
|
851
|
+
/** @enum {string} */
|
|
852
|
+
status: "NEW" | "TRIAGING" | "NEEDS_INFO" | "ACCEPTED" | "DUPLICATE" | "REJECTED";
|
|
853
|
+
/**
|
|
854
|
+
* @description Whether the report has been read and split into claims. An investigation waits for COMPLETE.
|
|
855
|
+
* @enum {string}
|
|
856
|
+
*/
|
|
857
|
+
intakeState: "PENDING" | "RUNNING" | "REVIEW" | "COMPLETE" | "FAILED";
|
|
858
|
+
/**
|
|
859
|
+
* @description How the investigation is going, or null if none has run.
|
|
860
|
+
* @enum {string|null}
|
|
861
|
+
*/
|
|
862
|
+
evaluationState?: "QUEUED" | "RUNNING" | "COMPLETE" | "FAILED" | null;
|
|
863
|
+
reporterName?: string | null;
|
|
864
|
+
reporterGithubLogin?: string | null;
|
|
865
|
+
/** @description The GitHub advisory it arrived as. */
|
|
866
|
+
githubUrl?: string | null;
|
|
867
|
+
/** Format: date-time */
|
|
868
|
+
acknowledgedAt?: string | null;
|
|
869
|
+
/** Format: date-time */
|
|
870
|
+
createdAt: string;
|
|
871
|
+
};
|
|
872
|
+
PaginatedReports: {
|
|
873
|
+
items: components["schemas"]["Report"][];
|
|
874
|
+
page: number;
|
|
875
|
+
limit: number;
|
|
876
|
+
total: number;
|
|
877
|
+
};
|
|
878
|
+
Advisory: {
|
|
879
|
+
/** @description Readable identifier, e.g. `ADVISORY-ADV-2026-0045`. */
|
|
880
|
+
publicId: string;
|
|
881
|
+
title: string;
|
|
882
|
+
/** @enum {string} */
|
|
883
|
+
severity: "CRITICAL" | "HIGH" | "MEDIUM" | "LOW" | "INFO";
|
|
884
|
+
/** @enum {string} */
|
|
885
|
+
status: "DRAFT" | "SCHEDULED" | "UNDER_EMBARGO" | "PUBLISHED" | "WITHDRAWN";
|
|
886
|
+
/**
|
|
887
|
+
* Format: date-time
|
|
888
|
+
* @description When the embargo lifts. Null until a date is set.
|
|
889
|
+
*/
|
|
890
|
+
disclosureAt?: string | null;
|
|
891
|
+
/** Format: date-time */
|
|
892
|
+
publishedAt?: string | null;
|
|
893
|
+
cveId?: string | null;
|
|
894
|
+
/** @description The GitHub advisory, once one has been filed. */
|
|
895
|
+
ghsaId?: string | null;
|
|
896
|
+
ghsaUrl?: string | null;
|
|
897
|
+
/** @description What GitHub reports. A created entry is a DRAFT, which is private and reaches no scanner; only a published one is public. */
|
|
898
|
+
ghsaState: string;
|
|
899
|
+
/** Format: date-time */
|
|
900
|
+
createdAt: string;
|
|
901
|
+
};
|
|
902
|
+
AdvisoryAffected: {
|
|
903
|
+
id: string;
|
|
904
|
+
repository: {
|
|
905
|
+
owner: string;
|
|
906
|
+
name: string;
|
|
907
|
+
};
|
|
908
|
+
/** @description First version carrying the defect. */
|
|
909
|
+
introducedIn: string;
|
|
910
|
+
/** @description Version that closes the range. Null while no patch exists, which is what holds a patch notice back. */
|
|
911
|
+
fixedIn: string | null;
|
|
912
|
+
};
|
|
913
|
+
AdvisoryNotice: {
|
|
914
|
+
label: string;
|
|
915
|
+
/** @description Days relative to disclosure. Negative is before it, 0 is the day itself. */
|
|
916
|
+
offsetDays: number;
|
|
917
|
+
/** Format: date-time */
|
|
918
|
+
scheduledFor: string;
|
|
919
|
+
/** @enum {string} */
|
|
920
|
+
status: "DRAFT" | "SCHEDULED" | "BLOCKED" | "SENDING" | "SENT" | "CANCELLED";
|
|
921
|
+
/** @description Why the plan is holding this notice back, if it is. */
|
|
922
|
+
blockedReason: string | null;
|
|
923
|
+
/** Format: date-time */
|
|
924
|
+
sentAt: string | null;
|
|
925
|
+
/** @description Contacts written to, as recorded when it went. */
|
|
926
|
+
recipientCount: number;
|
|
927
|
+
};
|
|
928
|
+
AdvisoryDetail: components["schemas"]["Advisory"] & {
|
|
929
|
+
summary: string;
|
|
930
|
+
description: string;
|
|
931
|
+
impact: string;
|
|
932
|
+
cwe?: string | null;
|
|
933
|
+
/** @description The software the advisory is about. A contact hears about it only when they run some of it. */
|
|
934
|
+
software: {
|
|
935
|
+
owner: string;
|
|
936
|
+
name: string;
|
|
937
|
+
}[];
|
|
938
|
+
affected: components["schemas"]["AdvisoryAffected"][];
|
|
939
|
+
notices: components["schemas"]["AdvisoryNotice"][];
|
|
940
|
+
};
|
|
941
|
+
AdvisoryContact: {
|
|
942
|
+
id: string;
|
|
943
|
+
email: string;
|
|
944
|
+
organization: string;
|
|
945
|
+
tier: string;
|
|
946
|
+
/** @description `PENDING_VERIFICATION` until the contact confirms the address. An unconfirmed address receives nothing embargoed. */
|
|
947
|
+
status: string;
|
|
948
|
+
/** @description The software this contact runs, which notices are matched on. */
|
|
949
|
+
software: {
|
|
950
|
+
owner: string;
|
|
951
|
+
name: string;
|
|
952
|
+
}[];
|
|
953
|
+
/** Format: date-time */
|
|
954
|
+
createdAt: string;
|
|
955
|
+
};
|
|
956
|
+
PaginatedAdvisoryContacts: {
|
|
957
|
+
items: components["schemas"]["AdvisoryContact"][];
|
|
958
|
+
page: number;
|
|
959
|
+
limit: number;
|
|
960
|
+
total: number;
|
|
961
|
+
};
|
|
962
|
+
PaginatedAdvisories: {
|
|
963
|
+
items: components["schemas"]["Advisory"][];
|
|
964
|
+
page: number;
|
|
965
|
+
limit: number;
|
|
966
|
+
total: number;
|
|
967
|
+
};
|
|
695
968
|
PaginatedFindings: {
|
|
696
969
|
items: components["schemas"]["Finding"][];
|
|
697
970
|
page: number;
|
|
@@ -809,6 +1082,13 @@ interface components {
|
|
|
809
1082
|
/** @description Number of in-flight jobs signalled to stop. */
|
|
810
1083
|
cancelledJobs: number;
|
|
811
1084
|
};
|
|
1085
|
+
InvestigateReportResult: {
|
|
1086
|
+
publicId: string;
|
|
1087
|
+
/** @description The scan triaging this report's claims. */
|
|
1088
|
+
scanId: string;
|
|
1089
|
+
/** @description Claims queued for triage, or null when an investigation was already running and this call started nothing. */
|
|
1090
|
+
claimsQueued: number | null;
|
|
1091
|
+
};
|
|
812
1092
|
/** @description Optionally attach or reuse a note alongside a resolution change. */
|
|
813
1093
|
ChangeNote: {
|
|
814
1094
|
/** @description Create a new note with this body. */
|
|
@@ -1276,6 +1556,262 @@ interface operations {
|
|
|
1276
1556
|
429: components["responses"]["RateLimited"];
|
|
1277
1557
|
};
|
|
1278
1558
|
};
|
|
1559
|
+
listReports: {
|
|
1560
|
+
parameters: {
|
|
1561
|
+
query?: {
|
|
1562
|
+
page?: components["parameters"]["Page"];
|
|
1563
|
+
limit?: components["parameters"]["Limit"];
|
|
1564
|
+
/** @description Only reports in this triage status. */
|
|
1565
|
+
status?: "NEW" | "TRIAGING" | "NEEDS_INFO" | "ACCEPTED" | "DUPLICATE" | "REJECTED";
|
|
1566
|
+
};
|
|
1567
|
+
header?: never;
|
|
1568
|
+
path: {
|
|
1569
|
+
projectId: components["parameters"]["ProjectId"];
|
|
1570
|
+
};
|
|
1571
|
+
cookie?: never;
|
|
1572
|
+
};
|
|
1573
|
+
requestBody?: never;
|
|
1574
|
+
responses: {
|
|
1575
|
+
/** @description OK */
|
|
1576
|
+
200: {
|
|
1577
|
+
headers: {
|
|
1578
|
+
[name: string]: unknown;
|
|
1579
|
+
};
|
|
1580
|
+
content: {
|
|
1581
|
+
"application/json": components["schemas"]["PaginatedReports"];
|
|
1582
|
+
};
|
|
1583
|
+
};
|
|
1584
|
+
400: components["responses"]["BadRequest"];
|
|
1585
|
+
401: components["responses"]["Unauthorized"];
|
|
1586
|
+
403: components["responses"]["Forbidden"];
|
|
1587
|
+
404: components["responses"]["NotFound"];
|
|
1588
|
+
};
|
|
1589
|
+
};
|
|
1590
|
+
investigateReport: {
|
|
1591
|
+
parameters: {
|
|
1592
|
+
query?: never;
|
|
1593
|
+
header?: never;
|
|
1594
|
+
path: {
|
|
1595
|
+
projectId: components["parameters"]["ProjectId"];
|
|
1596
|
+
/** @description The report's public identifier. */
|
|
1597
|
+
publicId: string;
|
|
1598
|
+
};
|
|
1599
|
+
cookie?: never;
|
|
1600
|
+
};
|
|
1601
|
+
requestBody?: never;
|
|
1602
|
+
responses: {
|
|
1603
|
+
/** @description OK */
|
|
1604
|
+
200: {
|
|
1605
|
+
headers: {
|
|
1606
|
+
[name: string]: unknown;
|
|
1607
|
+
};
|
|
1608
|
+
content: {
|
|
1609
|
+
"application/json": components["schemas"]["InvestigateReportResult"];
|
|
1610
|
+
};
|
|
1611
|
+
};
|
|
1612
|
+
401: components["responses"]["Unauthorized"];
|
|
1613
|
+
402: components["responses"]["InsufficientCredits"];
|
|
1614
|
+
403: components["responses"]["Forbidden"];
|
|
1615
|
+
404: components["responses"]["NotFound"];
|
|
1616
|
+
409: components["responses"]["Conflict"];
|
|
1617
|
+
429: components["responses"]["RateLimited"];
|
|
1618
|
+
};
|
|
1619
|
+
};
|
|
1620
|
+
listAdvisories: {
|
|
1621
|
+
parameters: {
|
|
1622
|
+
query?: {
|
|
1623
|
+
page?: components["parameters"]["Page"];
|
|
1624
|
+
limit?: components["parameters"]["Limit"];
|
|
1625
|
+
/** @description Only advisories in this status. */
|
|
1626
|
+
status?: "DRAFT" | "SCHEDULED" | "UNDER_EMBARGO" | "PUBLISHED" | "WITHDRAWN";
|
|
1627
|
+
};
|
|
1628
|
+
header?: never;
|
|
1629
|
+
path: {
|
|
1630
|
+
projectId: components["parameters"]["ProjectId"];
|
|
1631
|
+
};
|
|
1632
|
+
cookie?: never;
|
|
1633
|
+
};
|
|
1634
|
+
requestBody?: never;
|
|
1635
|
+
responses: {
|
|
1636
|
+
/** @description OK */
|
|
1637
|
+
200: {
|
|
1638
|
+
headers: {
|
|
1639
|
+
[name: string]: unknown;
|
|
1640
|
+
};
|
|
1641
|
+
content: {
|
|
1642
|
+
"application/json": components["schemas"]["PaginatedAdvisories"];
|
|
1643
|
+
};
|
|
1644
|
+
};
|
|
1645
|
+
400: components["responses"]["BadRequest"];
|
|
1646
|
+
401: components["responses"]["Unauthorized"];
|
|
1647
|
+
403: components["responses"]["Forbidden"];
|
|
1648
|
+
404: components["responses"]["NotFound"];
|
|
1649
|
+
};
|
|
1650
|
+
};
|
|
1651
|
+
getAdvisory: {
|
|
1652
|
+
parameters: {
|
|
1653
|
+
query?: never;
|
|
1654
|
+
header?: never;
|
|
1655
|
+
path: {
|
|
1656
|
+
projectId: components["parameters"]["ProjectId"];
|
|
1657
|
+
/** @description The advisory's readable identifier. */
|
|
1658
|
+
publicId: string;
|
|
1659
|
+
};
|
|
1660
|
+
cookie?: never;
|
|
1661
|
+
};
|
|
1662
|
+
requestBody?: never;
|
|
1663
|
+
responses: {
|
|
1664
|
+
/** @description OK */
|
|
1665
|
+
200: {
|
|
1666
|
+
headers: {
|
|
1667
|
+
[name: string]: unknown;
|
|
1668
|
+
};
|
|
1669
|
+
content: {
|
|
1670
|
+
"application/json": {
|
|
1671
|
+
advisory: components["schemas"]["AdvisoryDetail"];
|
|
1672
|
+
};
|
|
1673
|
+
};
|
|
1674
|
+
};
|
|
1675
|
+
401: components["responses"]["Unauthorized"];
|
|
1676
|
+
403: components["responses"]["Forbidden"];
|
|
1677
|
+
404: components["responses"]["NotFound"];
|
|
1678
|
+
};
|
|
1679
|
+
};
|
|
1680
|
+
replaceAdvisoryAffected: {
|
|
1681
|
+
parameters: {
|
|
1682
|
+
query?: never;
|
|
1683
|
+
header?: never;
|
|
1684
|
+
path: {
|
|
1685
|
+
projectId: components["parameters"]["ProjectId"];
|
|
1686
|
+
/** @description The advisory's readable identifier. */
|
|
1687
|
+
publicId: string;
|
|
1688
|
+
};
|
|
1689
|
+
cookie?: never;
|
|
1690
|
+
};
|
|
1691
|
+
requestBody: {
|
|
1692
|
+
content: {
|
|
1693
|
+
"application/json": {
|
|
1694
|
+
affected: {
|
|
1695
|
+
repository: {
|
|
1696
|
+
owner: string;
|
|
1697
|
+
name: string;
|
|
1698
|
+
};
|
|
1699
|
+
/** @description First version carrying the defect. */
|
|
1700
|
+
introducedIn: string;
|
|
1701
|
+
/** @description Version that closes the range, or null. */
|
|
1702
|
+
fixedIn?: string | null;
|
|
1703
|
+
}[];
|
|
1704
|
+
};
|
|
1705
|
+
};
|
|
1706
|
+
};
|
|
1707
|
+
responses: {
|
|
1708
|
+
/** @description OK */
|
|
1709
|
+
200: {
|
|
1710
|
+
headers: {
|
|
1711
|
+
[name: string]: unknown;
|
|
1712
|
+
};
|
|
1713
|
+
content: {
|
|
1714
|
+
"application/json": {
|
|
1715
|
+
advisory: components["schemas"]["AdvisoryDetail"];
|
|
1716
|
+
};
|
|
1717
|
+
};
|
|
1718
|
+
};
|
|
1719
|
+
400: components["responses"]["BadRequest"];
|
|
1720
|
+
401: components["responses"]["Unauthorized"];
|
|
1721
|
+
403: components["responses"]["Forbidden"];
|
|
1722
|
+
404: components["responses"]["NotFound"];
|
|
1723
|
+
409: components["responses"]["Conflict"];
|
|
1724
|
+
};
|
|
1725
|
+
};
|
|
1726
|
+
listAdvisoryContacts: {
|
|
1727
|
+
parameters: {
|
|
1728
|
+
query?: {
|
|
1729
|
+
page?: components["parameters"]["Page"];
|
|
1730
|
+
limit?: components["parameters"]["Limit"];
|
|
1731
|
+
tier?: "EMBARGO" | "DOWNSTREAM" | "ANNOUNCE";
|
|
1732
|
+
status?: "ACTIVE" | "PENDING_VERIFICATION" | "BOUNCED" | "UNSUBSCRIBED";
|
|
1733
|
+
};
|
|
1734
|
+
header?: never;
|
|
1735
|
+
path: {
|
|
1736
|
+
projectId: components["parameters"]["ProjectId"];
|
|
1737
|
+
};
|
|
1738
|
+
cookie?: never;
|
|
1739
|
+
};
|
|
1740
|
+
requestBody?: never;
|
|
1741
|
+
responses: {
|
|
1742
|
+
/** @description OK */
|
|
1743
|
+
200: {
|
|
1744
|
+
headers: {
|
|
1745
|
+
[name: string]: unknown;
|
|
1746
|
+
};
|
|
1747
|
+
content: {
|
|
1748
|
+
"application/json": components["schemas"]["PaginatedAdvisoryContacts"];
|
|
1749
|
+
};
|
|
1750
|
+
};
|
|
1751
|
+
400: components["responses"]["BadRequest"];
|
|
1752
|
+
401: components["responses"]["Unauthorized"];
|
|
1753
|
+
403: components["responses"]["Forbidden"];
|
|
1754
|
+
};
|
|
1755
|
+
};
|
|
1756
|
+
addAdvisoryContact: {
|
|
1757
|
+
parameters: {
|
|
1758
|
+
query?: never;
|
|
1759
|
+
header?: never;
|
|
1760
|
+
path: {
|
|
1761
|
+
projectId: components["parameters"]["ProjectId"];
|
|
1762
|
+
};
|
|
1763
|
+
cookie?: never;
|
|
1764
|
+
};
|
|
1765
|
+
requestBody: {
|
|
1766
|
+
content: {
|
|
1767
|
+
"application/json": {
|
|
1768
|
+
email: string;
|
|
1769
|
+
/** @description The organisation this contact speaks for. */
|
|
1770
|
+
organization: string;
|
|
1771
|
+
/**
|
|
1772
|
+
* @description How early this contact is told. `EMBARGO` hears first and alone, `DOWNSTREAM` joins once a patch exists, `ANNOUNCE` learns at public disclosure.
|
|
1773
|
+
* @enum {string}
|
|
1774
|
+
*/
|
|
1775
|
+
tier: "EMBARGO" | "DOWNSTREAM" | "ANNOUNCE";
|
|
1776
|
+
/** @description The repositories this contact runs. At least one. */
|
|
1777
|
+
software: {
|
|
1778
|
+
owner: string;
|
|
1779
|
+
name: string;
|
|
1780
|
+
}[];
|
|
1781
|
+
name?: string | null;
|
|
1782
|
+
title?: string | null;
|
|
1783
|
+
notes?: string | null;
|
|
1784
|
+
tags?: string[];
|
|
1785
|
+
};
|
|
1786
|
+
};
|
|
1787
|
+
};
|
|
1788
|
+
responses: {
|
|
1789
|
+
/** @description Created */
|
|
1790
|
+
201: {
|
|
1791
|
+
headers: {
|
|
1792
|
+
[name: string]: unknown;
|
|
1793
|
+
};
|
|
1794
|
+
content: {
|
|
1795
|
+
"application/json": {
|
|
1796
|
+
contact: components["schemas"]["AdvisoryContact"];
|
|
1797
|
+
};
|
|
1798
|
+
};
|
|
1799
|
+
};
|
|
1800
|
+
400: components["responses"]["BadRequest"];
|
|
1801
|
+
401: components["responses"]["Unauthorized"];
|
|
1802
|
+
403: components["responses"]["Forbidden"];
|
|
1803
|
+
404: components["responses"]["NotFound"];
|
|
1804
|
+
/** @description That address is already on the programme's contact list. */
|
|
1805
|
+
409: {
|
|
1806
|
+
headers: {
|
|
1807
|
+
[name: string]: unknown;
|
|
1808
|
+
};
|
|
1809
|
+
content: {
|
|
1810
|
+
"application/json": components["schemas"]["Error"];
|
|
1811
|
+
};
|
|
1812
|
+
};
|
|
1813
|
+
};
|
|
1814
|
+
};
|
|
1279
1815
|
listFindings: {
|
|
1280
1816
|
parameters: {
|
|
1281
1817
|
query?: {
|
|
@@ -1720,6 +2256,45 @@ type BillingUsage = Schemas["BillingUsage"];
|
|
|
1720
2256
|
type UsageEvent = Schemas["UsageEvent"];
|
|
1721
2257
|
type UsageEventType = Schemas["UsageEventType"];
|
|
1722
2258
|
type BillingSummary = Schemas["BillingSummary"];
|
|
2259
|
+
type InvestigateReportResult = Schemas["InvestigateReportResult"];
|
|
2260
|
+
type Report = Schemas["Report"];
|
|
2261
|
+
/** The triage statuses a report moves through. */
|
|
2262
|
+
type ReportStatus = "NEW" | "TRIAGING" | "NEEDS_INFO" | "ACCEPTED" | "DUPLICATE" | "REJECTED";
|
|
2263
|
+
type Advisory = Schemas["Advisory"];
|
|
2264
|
+
type AdvisoryDetail = Schemas["AdvisoryDetail"];
|
|
2265
|
+
type AdvisoryAffected = Schemas["AdvisoryAffected"];
|
|
2266
|
+
/** One affected version line, as a caller states it. */
|
|
2267
|
+
type AdvisoryAffectedInput = {
|
|
2268
|
+
repository: {
|
|
2269
|
+
owner: string;
|
|
2270
|
+
name: string;
|
|
2271
|
+
};
|
|
2272
|
+
introducedIn: string;
|
|
2273
|
+
fixedIn?: string | null;
|
|
2274
|
+
};
|
|
2275
|
+
type AdvisoryNotice = Schemas["AdvisoryNotice"];
|
|
2276
|
+
type AdvisoryContact = Schemas["AdvisoryContact"];
|
|
2277
|
+
/** How early a contact is told. */
|
|
2278
|
+
type ContactTier = "EMBARGO" | "DOWNSTREAM" | "ANNOUNCE";
|
|
2279
|
+
/** Whether a contact can be written to. Only ACTIVE hears anything. */
|
|
2280
|
+
type ContactStatus = "ACTIVE" | "PENDING_VERIFICATION" | "BOUNCED" | "UNSUBSCRIBED";
|
|
2281
|
+
/** A contact as a caller states it. */
|
|
2282
|
+
type AdvisoryContactInput = {
|
|
2283
|
+
email: string;
|
|
2284
|
+
organization: string;
|
|
2285
|
+
tier: ContactTier;
|
|
2286
|
+
/** The repositories this contact runs. At least one. */
|
|
2287
|
+
software: {
|
|
2288
|
+
owner: string;
|
|
2289
|
+
name: string;
|
|
2290
|
+
}[];
|
|
2291
|
+
name?: string | null;
|
|
2292
|
+
title?: string | null;
|
|
2293
|
+
notes?: string | null;
|
|
2294
|
+
tags?: string[];
|
|
2295
|
+
};
|
|
2296
|
+
/** The statuses an advisory moves through. */
|
|
2297
|
+
type AdvisoryStatus = "DRAFT" | "SCHEDULED" | "UNDER_EMBARGO" | "PUBLISHED" | "WITHDRAWN";
|
|
1723
2298
|
type UsageMonthSummary = Schemas["UsageMonthSummary"];
|
|
1724
2299
|
type Paginated<T> = {
|
|
1725
2300
|
items: T[];
|
|
@@ -1892,6 +2467,96 @@ declare class ZkaoClient {
|
|
|
1892
2467
|
* scope, which only a zkao site admin can grant; any other token gets 404.
|
|
1893
2468
|
*/
|
|
1894
2469
|
createManualAudit(body: ManualAuditRequest): Promise<ManualAuditResult>;
|
|
2470
|
+
/**
|
|
2471
|
+
* The project's coordinated-disclosure advisories, newest first.
|
|
2472
|
+
*/
|
|
2473
|
+
listAdvisories(opts?: {
|
|
2474
|
+
page?: number;
|
|
2475
|
+
limit?: number;
|
|
2476
|
+
status?: AdvisoryStatus;
|
|
2477
|
+
}): Promise<Paginated<Advisory>>;
|
|
2478
|
+
/**
|
|
2479
|
+
* One advisory, the software it concerns, the versions it affects, and the
|
|
2480
|
+
* notices planned for it.
|
|
2481
|
+
*
|
|
2482
|
+
* `software` is what decides the audience: a contact is notified about an
|
|
2483
|
+
* advisory only when they run some of it. `affected` is a separate statement
|
|
2484
|
+
* about versions, and is often empty.
|
|
2485
|
+
*
|
|
2486
|
+
* A notice the plan is holding back carries `blockedReason`. The commonest
|
|
2487
|
+
* one is that no affected range names a fixed version, which only the people
|
|
2488
|
+
* who shipped the release can supply.
|
|
2489
|
+
*/
|
|
2490
|
+
getAdvisory(publicId: string): Promise<AdvisoryDetail>;
|
|
2491
|
+
/**
|
|
2492
|
+
* Record which versions this advisory affects.
|
|
2493
|
+
*
|
|
2494
|
+
* Replaces the whole set, so send what is affected now rather than a patch.
|
|
2495
|
+
* `fixedIn` is the point: a patch notice stays blocked until some range
|
|
2496
|
+
* names a fixed version, and only the people who shipped the release know
|
|
2497
|
+
* it.
|
|
2498
|
+
*
|
|
2499
|
+
* Versions only. A range may name only software already on the advisory's
|
|
2500
|
+
* `software`, and anything else is a 400: which software an advisory
|
|
2501
|
+
* concerns decides who hears about it, and that is its own statement made
|
|
2502
|
+
* in the app.
|
|
2503
|
+
*
|
|
2504
|
+
* This call never sends anything. It records versions and recomputes the
|
|
2505
|
+
* plan; when an eligible notice is actually sent is the programme's
|
|
2506
|
+
* business.
|
|
2507
|
+
*/
|
|
2508
|
+
replaceAdvisoryAffected(publicId: string, affected: AdvisoryAffectedInput[]): Promise<AdvisoryDetail>;
|
|
2509
|
+
/**
|
|
2510
|
+
* The programme's advisory contacts, oldest first.
|
|
2511
|
+
*
|
|
2512
|
+
* Needs `contacts:read`, which is held apart from `read`: this list is other
|
|
2513
|
+
* people's work addresses and the record of who learns about a vulnerability
|
|
2514
|
+
* before the public does. `software` on each row is what notices are matched
|
|
2515
|
+
* on. A project with no security programme reads as an empty list.
|
|
2516
|
+
*/
|
|
2517
|
+
listAdvisoryContacts(opts?: {
|
|
2518
|
+
page?: number;
|
|
2519
|
+
limit?: number;
|
|
2520
|
+
tier?: ContactTier;
|
|
2521
|
+
status?: ContactStatus;
|
|
2522
|
+
}): Promise<Paginated<AdvisoryContact>>;
|
|
2523
|
+
/**
|
|
2524
|
+
* Put one address on the programme's advisory contact list.
|
|
2525
|
+
*
|
|
2526
|
+
* `software` says which of the project's repositories this contact runs, and
|
|
2527
|
+
* is required: it is what every notice is matched on, so a contact who runs
|
|
2528
|
+
* nothing is told nothing.
|
|
2529
|
+
*
|
|
2530
|
+
* The contact starts `PENDING_VERIFICATION`, and an unconfirmed address
|
|
2531
|
+
* receives nothing embargoed. Nothing is emailed by this call: the
|
|
2532
|
+
* confirmation mail is sent from the app.
|
|
2533
|
+
*/
|
|
2534
|
+
addAdvisoryContact(contact: AdvisoryContactInput): Promise<AdvisoryContact>;
|
|
2535
|
+
/**
|
|
2536
|
+
* Reports the programme has received, newest first.
|
|
2537
|
+
*
|
|
2538
|
+
* `publicId` is what {@link investigateReport} takes. `intakeState` says
|
|
2539
|
+
* whether a report has been read and split into claims yet: an
|
|
2540
|
+
* investigation waits for `COMPLETE`.
|
|
2541
|
+
*/
|
|
2542
|
+
listReports(opts?: {
|
|
2543
|
+
page?: number;
|
|
2544
|
+
limit?: number;
|
|
2545
|
+
status?: ReportStatus;
|
|
2546
|
+
}): Promise<Paginated<Report>>;
|
|
2547
|
+
/**
|
|
2548
|
+
* Check an incoming vulnerability report against the code.
|
|
2549
|
+
*
|
|
2550
|
+
* Requires the `scans:launch` scope. The report's claims are each checked
|
|
2551
|
+
* against the repository, deduplicated against the findings already
|
|
2552
|
+
* confirmed there, and given a proof of concept where one can be written.
|
|
2553
|
+
* Returns at once with the scan doing the work: poll {@link getScan} and
|
|
2554
|
+
* then read its findings.
|
|
2555
|
+
*
|
|
2556
|
+
* Idempotent. A report already under investigation comes back with the
|
|
2557
|
+
* existing scan and `claimsQueued: null`, so a retry costs nothing.
|
|
2558
|
+
*/
|
|
2559
|
+
investigateReport(publicId: string): Promise<InvestigateReportResult>;
|
|
1895
2560
|
listFindings(opts?: {
|
|
1896
2561
|
page?: number;
|
|
1897
2562
|
limit?: number;
|
|
@@ -1970,4 +2635,4 @@ declare class ZkaoClient {
|
|
|
1970
2635
|
}): Promise<UsageMonthSummary[]>;
|
|
1971
2636
|
}
|
|
1972
2637
|
|
|
1973
|
-
export { type BillingBalance, type BillingSummary, type BillingUsage, type CancelScanResult, type ChangeNote, DEFAULT_BASE_URL, type Finding, type FindingDetail, type FindingNote, type LaunchScanRequest, type LaunchScanResult, type ManualAuditRequest, type ManualAuditResult, type Paginated, type PublishArtifactResult, type Repository, type RepositoryGuidance, type ResolutionReason, type ResolutionStatus, type Scan, type ScanDetail, type ScanPreset, type ScanStatus, type SetGuidanceResult, type Severity, TERMINAL_SCAN_STATUSES, type TokenInfo, type TriageStatus, type UsageEvent, type UsageEventType, type UsageMonthSummary, type WaitForRepositoryReadyOptions, type WaitForScanOptions, ZkaoApiError, ZkaoClient, type ZkaoClientOptions, type components, getTokenInfo, isTerminalScanStatus, normalizeBaseUrl, type paths, resolveBaseUrlFromEnv };
|
|
2638
|
+
export { type Advisory, type AdvisoryAffected, type AdvisoryAffectedInput, type AdvisoryContact, type AdvisoryContactInput, type AdvisoryDetail, type AdvisoryNotice, type AdvisoryStatus, type BillingBalance, type BillingSummary, type BillingUsage, type CancelScanResult, type ChangeNote, type ContactStatus, type ContactTier, DEFAULT_BASE_URL, type Finding, type FindingDetail, type FindingNote, type LaunchScanRequest, type LaunchScanResult, type ManualAuditRequest, type ManualAuditResult, type Paginated, type PublishArtifactResult, type Report, type ReportStatus, type Repository, type RepositoryGuidance, type ResolutionReason, type ResolutionStatus, type Scan, type ScanDetail, type ScanPreset, type ScanStatus, type SetGuidanceResult, type Severity, TERMINAL_SCAN_STATUSES, type TokenInfo, type TriageStatus, type UsageEvent, type UsageEventType, type UsageMonthSummary, type WaitForRepositoryReadyOptions, type WaitForScanOptions, ZkaoApiError, ZkaoClient, type ZkaoClientOptions, type components, getTokenInfo, isTerminalScanStatus, normalizeBaseUrl, type paths, resolveBaseUrlFromEnv };
|
package/dist/index.js
CHANGED
|
@@ -376,6 +376,144 @@ var ZkaoClient = class {
|
|
|
376
376
|
async createManualAudit(body) {
|
|
377
377
|
return this.postUntyped("/manual-audits", body);
|
|
378
378
|
}
|
|
379
|
+
// --- Advisories ---------------------------------------------------------
|
|
380
|
+
/**
|
|
381
|
+
* The project's coordinated-disclosure advisories, newest first.
|
|
382
|
+
*/
|
|
383
|
+
async listAdvisories(opts = {}) {
|
|
384
|
+
const res = await this.http.GET("/projects/{projectId}/advisories", {
|
|
385
|
+
params: {
|
|
386
|
+
path: this.path,
|
|
387
|
+
query: { page: opts.page, limit: opts.limit, status: opts.status }
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
return unwrap(res);
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* One advisory, the software it concerns, the versions it affects, and the
|
|
394
|
+
* notices planned for it.
|
|
395
|
+
*
|
|
396
|
+
* `software` is what decides the audience: a contact is notified about an
|
|
397
|
+
* advisory only when they run some of it. `affected` is a separate statement
|
|
398
|
+
* about versions, and is often empty.
|
|
399
|
+
*
|
|
400
|
+
* A notice the plan is holding back carries `blockedReason`. The commonest
|
|
401
|
+
* one is that no affected range names a fixed version, which only the people
|
|
402
|
+
* who shipped the release can supply.
|
|
403
|
+
*/
|
|
404
|
+
async getAdvisory(publicId) {
|
|
405
|
+
const res = await this.http.GET(
|
|
406
|
+
"/projects/{projectId}/advisories/{publicId}",
|
|
407
|
+
{ params: { path: { ...this.path, publicId } } }
|
|
408
|
+
);
|
|
409
|
+
return unwrap(res).advisory;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Record which versions this advisory affects.
|
|
413
|
+
*
|
|
414
|
+
* Replaces the whole set, so send what is affected now rather than a patch.
|
|
415
|
+
* `fixedIn` is the point: a patch notice stays blocked until some range
|
|
416
|
+
* names a fixed version, and only the people who shipped the release know
|
|
417
|
+
* it.
|
|
418
|
+
*
|
|
419
|
+
* Versions only. A range may name only software already on the advisory's
|
|
420
|
+
* `software`, and anything else is a 400: which software an advisory
|
|
421
|
+
* concerns decides who hears about it, and that is its own statement made
|
|
422
|
+
* in the app.
|
|
423
|
+
*
|
|
424
|
+
* This call never sends anything. It records versions and recomputes the
|
|
425
|
+
* plan; when an eligible notice is actually sent is the programme's
|
|
426
|
+
* business.
|
|
427
|
+
*/
|
|
428
|
+
async replaceAdvisoryAffected(publicId, affected) {
|
|
429
|
+
const res = await this.http.PUT(
|
|
430
|
+
"/projects/{projectId}/advisories/{publicId}/affected",
|
|
431
|
+
{
|
|
432
|
+
params: { path: { ...this.path, publicId } },
|
|
433
|
+
body: { affected }
|
|
434
|
+
}
|
|
435
|
+
);
|
|
436
|
+
return unwrap(res).advisory;
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* The programme's advisory contacts, oldest first.
|
|
440
|
+
*
|
|
441
|
+
* Needs `contacts:read`, which is held apart from `read`: this list is other
|
|
442
|
+
* people's work addresses and the record of who learns about a vulnerability
|
|
443
|
+
* before the public does. `software` on each row is what notices are matched
|
|
444
|
+
* on. A project with no security programme reads as an empty list.
|
|
445
|
+
*/
|
|
446
|
+
async listAdvisoryContacts(opts = {}) {
|
|
447
|
+
const res = await this.http.GET(
|
|
448
|
+
"/projects/{projectId}/advisory-contacts",
|
|
449
|
+
{
|
|
450
|
+
params: {
|
|
451
|
+
path: this.path,
|
|
452
|
+
query: {
|
|
453
|
+
page: opts.page,
|
|
454
|
+
limit: opts.limit,
|
|
455
|
+
tier: opts.tier,
|
|
456
|
+
status: opts.status
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
);
|
|
461
|
+
return unwrap(res);
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Put one address on the programme's advisory contact list.
|
|
465
|
+
*
|
|
466
|
+
* `software` says which of the project's repositories this contact runs, and
|
|
467
|
+
* is required: it is what every notice is matched on, so a contact who runs
|
|
468
|
+
* nothing is told nothing.
|
|
469
|
+
*
|
|
470
|
+
* The contact starts `PENDING_VERIFICATION`, and an unconfirmed address
|
|
471
|
+
* receives nothing embargoed. Nothing is emailed by this call: the
|
|
472
|
+
* confirmation mail is sent from the app.
|
|
473
|
+
*/
|
|
474
|
+
async addAdvisoryContact(contact) {
|
|
475
|
+
const res = await this.http.POST("/projects/{projectId}/advisory-contacts", {
|
|
476
|
+
params: { path: this.path },
|
|
477
|
+
body: contact
|
|
478
|
+
});
|
|
479
|
+
return unwrap(res).contact;
|
|
480
|
+
}
|
|
481
|
+
// --- Incoming reports ---------------------------------------------------
|
|
482
|
+
/**
|
|
483
|
+
* Reports the programme has received, newest first.
|
|
484
|
+
*
|
|
485
|
+
* `publicId` is what {@link investigateReport} takes. `intakeState` says
|
|
486
|
+
* whether a report has been read and split into claims yet: an
|
|
487
|
+
* investigation waits for `COMPLETE`.
|
|
488
|
+
*/
|
|
489
|
+
async listReports(opts = {}) {
|
|
490
|
+
const res = await this.http.GET("/projects/{projectId}/reports", {
|
|
491
|
+
params: {
|
|
492
|
+
path: this.path,
|
|
493
|
+
query: { page: opts.page, limit: opts.limit, status: opts.status }
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
return unwrap(res);
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Check an incoming vulnerability report against the code.
|
|
500
|
+
*
|
|
501
|
+
* Requires the `scans:launch` scope. The report's claims are each checked
|
|
502
|
+
* against the repository, deduplicated against the findings already
|
|
503
|
+
* confirmed there, and given a proof of concept where one can be written.
|
|
504
|
+
* Returns at once with the scan doing the work: poll {@link getScan} and
|
|
505
|
+
* then read its findings.
|
|
506
|
+
*
|
|
507
|
+
* Idempotent. A report already under investigation comes back with the
|
|
508
|
+
* existing scan and `claimsQueued: null`, so a retry costs nothing.
|
|
509
|
+
*/
|
|
510
|
+
async investigateReport(publicId) {
|
|
511
|
+
const res = await this.http.POST(
|
|
512
|
+
"/projects/{projectId}/reports/{publicId}/investigate",
|
|
513
|
+
{ params: { path: { ...this.path, publicId } } }
|
|
514
|
+
);
|
|
515
|
+
return unwrap(res);
|
|
516
|
+
}
|
|
379
517
|
// --- Findings -----------------------------------------------------------
|
|
380
518
|
async listFindings(opts = {}) {
|
|
381
519
|
const res = await this.http.GET("/projects/{projectId}/findings", {
|