1 | |
2 |
|
3 | |
4 | * Get Issue |
5 | * Retrieve a single Wiz issue by its ID, including the triggering rule, the affected entity, projects and notes. |
6 | */ |
7 | export async function main(auth: RT.Wiz, issue_id: string) { |
8 | const tokenResponse = await fetch( |
9 | auth.auth_url || "https://auth.app.wiz.io/oauth/token", |
10 | { |
11 | method: "POST", |
12 | headers: { "Content-Type": "application/x-www-form-urlencoded" }, |
13 | body: new URLSearchParams({ |
14 | grant_type: "client_credentials", |
15 | audience: auth.audience || "wiz-api", |
16 | client_id: auth.client_id, |
17 | client_secret: auth.client_secret, |
18 | }), |
19 | } |
20 | ) |
21 | if (!tokenResponse.ok) { |
22 | throw new Error(`${tokenResponse.status} ${await tokenResponse.text()}`) |
23 | } |
24 | const { access_token } = (await tokenResponse.json()) as { |
25 | access_token: string |
26 | } |
27 |
|
28 | const query = ` |
29 | query GetIssue($filterBy: IssueFilters, $first: Int) { |
30 | issues: issuesV2(filterBy: $filterBy, first: $first) { |
31 | nodes { |
32 | id |
33 | type |
34 | severity |
35 | status |
36 | createdAt |
37 | updatedAt |
38 | dueAt |
39 | resolvedAt |
40 | statusChangedAt |
41 | resolutionReason |
42 | sourceRule { |
43 | __typename |
44 | ... on Control { id name description resolutionRecommendation } |
45 | ... on CloudConfigurationRule { id name description remediationInstructions serviceType } |
46 | ... on CloudEventRule { id name description sourceType } |
47 | } |
48 | entitySnapshot { |
49 | id |
50 | name |
51 | type |
52 | nativeType |
53 | status |
54 | cloudPlatform |
55 | cloudProviderURL |
56 | region |
57 | subscriptionName |
58 | subscriptionExternalId |
59 | providerId |
60 | externalId |
61 | tags |
62 | } |
63 | projects { id name slug businessUnit riskProfile { businessImpact } } |
64 | notes { id text createdAt updatedAt user { name email } serviceAccount { name } } |
65 | serviceTickets { externalId name url } |
66 | } |
67 | } |
68 | }` |
69 |
|
70 | const response = await fetch(auth.api_endpoint, { |
71 | method: "POST", |
72 | headers: { |
73 | Authorization: `Bearer ${access_token}`, |
74 | "Content-Type": "application/json", |
75 | Accept: "application/json", |
76 | }, |
77 | body: JSON.stringify({ |
78 | query, |
79 | variables: { filterBy: { id: issue_id }, first: 1 }, |
80 | }), |
81 | }) |
82 |
|
83 | if (!response.ok) { |
84 | throw new Error(`${response.status} ${await response.text()}`) |
85 | } |
86 |
|
87 | const result = (await response.json()) as { data?: any; errors?: any } |
88 | if (result.errors) { |
89 | throw new Error(JSON.stringify(result.errors)) |
90 | } |
91 | return result.data.issues.nodes[0] ?? null |
92 | } |
93 |
|