1 | |
2 |
|
3 | |
4 | * Update Issue |
5 | * Change a Wiz issue's status (e.g. resolve, reject, set in progress). Resolving or rejecting requires both a resolution reason and a note. |
6 | */ |
7 | export async function main( |
8 | auth: RT.Wiz, |
9 | issue_id: string, |
10 | status: "OPEN" | "IN_PROGRESS" | "RESOLVED" | "REJECTED", |
11 | note: string | undefined, |
12 | resolution_reason: |
13 | | "OBJECT_DELETED" |
14 | | "ISSUE_FIXED" |
15 | | "CONTROL_CHANGED" |
16 | | "CONTROL_DISABLED" |
17 | | "CONTROL_DELETED" |
18 | | "FALSE_POSITIVE" |
19 | | "EXCEPTION" |
20 | | "WONT_FIX" |
21 | | undefined, |
22 | due_at: string | undefined |
23 | ) { |
24 | const tokenResponse = await fetch( |
25 | auth.auth_url || "https://auth.app.wiz.io/oauth/token", |
26 | { |
27 | method: "POST", |
28 | headers: { "Content-Type": "application/x-www-form-urlencoded" }, |
29 | body: new URLSearchParams({ |
30 | grant_type: "client_credentials", |
31 | audience: auth.audience || "wiz-api", |
32 | client_id: auth.client_id, |
33 | client_secret: auth.client_secret, |
34 | }), |
35 | } |
36 | ) |
37 | if (!tokenResponse.ok) { |
38 | throw new Error(`${tokenResponse.status} ${await tokenResponse.text()}`) |
39 | } |
40 | const { access_token } = (await tokenResponse.json()) as { |
41 | access_token: string |
42 | } |
43 |
|
44 | const patch: { [key: string]: any } = { status } |
45 | if (note !== undefined && note !== "") patch.note = note |
46 | if (resolution_reason !== undefined) |
47 | patch.resolutionReason = resolution_reason |
48 | if (due_at !== undefined && due_at !== "") patch.dueAt = due_at |
49 |
|
50 | const query = ` |
51 | mutation UpdateIssue($issueId: ID!, $patch: UpdateIssuePatch) { |
52 | updateIssue(input: { id: $issueId, patch: $patch }) { |
53 | issue { |
54 | id |
55 | status |
56 | dueAt |
57 | resolutionReason |
58 | notes { id text createdAt updatedAt user { name email } } |
59 | } |
60 | } |
61 | }` |
62 |
|
63 | const response = await fetch(auth.api_endpoint, { |
64 | method: "POST", |
65 | headers: { |
66 | Authorization: `Bearer ${access_token}`, |
67 | "Content-Type": "application/json", |
68 | Accept: "application/json", |
69 | }, |
70 | body: JSON.stringify({ |
71 | query, |
72 | variables: { issueId: issue_id, patch }, |
73 | }), |
74 | }) |
75 |
|
76 | if (!response.ok) { |
77 | throw new Error(`${response.status} ${await response.text()}`) |
78 | } |
79 |
|
80 | const result = (await response.json()) as { data?: any; errors?: any } |
81 | if (result.errors) { |
82 | throw new Error(JSON.stringify(result.errors)) |
83 | } |
84 | return result.data.updateIssue.issue |
85 | } |
86 |
|