1 | |
2 |
|
3 | import * as wmill from "windmill-client" |
4 |
|
5 | async function getManagementToken(auth: RT.Auth0): Promise<string> { |
6 | const response = await fetch(`https://${auth.domain}/oauth/token`, { |
7 | method: "POST", |
8 | headers: { "Content-Type": "application/json" }, |
9 | body: JSON.stringify({ |
10 | grant_type: "client_credentials", |
11 | client_id: auth.client_id, |
12 | client_secret: auth.client_secret, |
13 | audience: `https://${auth.domain}/api/v2/`, |
14 | }), |
15 | }) |
16 | if (!response.ok) { |
17 | throw new Error(`${response.status} ${await response.text()}`) |
18 | } |
19 | const { access_token } = (await response.json()) as { access_token: string } |
20 | return access_token |
21 | } |
22 | |
23 | * New Log Event |
24 | * Emits new tenant log events (logins, errors, admin changes) since the last run, using Auth0 checkpoint pagination. The first run records the current position and returns nothing. |
25 | */ |
26 | export async function main(auth: RT.Auth0) { |
27 | const token = await getManagementToken(auth) |
28 | const lastLogId: string | undefined = await wmill.getState() |
29 |
|
30 | |
31 | if (!lastLogId) { |
32 | const bootstrapUrl = new URL(`https://${auth.domain}/api/v2/logs`) |
33 | bootstrapUrl.searchParams.append("take", "1") |
34 | bootstrapUrl.searchParams.append("sort", "date:-1") |
35 | const bootstrapResponse = await fetch(bootstrapUrl, { |
36 | headers: { |
37 | Authorization: `Bearer ${token}`, |
38 | Accept: "application/json", |
39 | }, |
40 | }) |
41 | if (!bootstrapResponse.ok) { |
42 | throw new Error( |
43 | `${bootstrapResponse.status} ${await bootstrapResponse.text()}` |
44 | ) |
45 | } |
46 | const latest = (await bootstrapResponse.json()) as { log_id: string }[] |
47 | if (latest.length > 0) await wmill.setState(latest[0].log_id) |
48 | return [] |
49 | } |
50 |
|
51 | const url = new URL(`https://${auth.domain}/api/v2/logs`) |
52 | url.searchParams.append("from", lastLogId) |
53 | url.searchParams.append("take", "100") |
54 |
|
55 | const response = await fetch(url, { |
56 | headers: { |
57 | Authorization: `Bearer ${token}`, |
58 | Accept: "application/json", |
59 | }, |
60 | }) |
61 | if (!response.ok) { |
62 | throw new Error(`${response.status} ${await response.text()}`) |
63 | } |
64 |
|
65 | const logs = (await response.json()) as { log_id: string }[] |
66 | if (logs.length > 0) await wmill.setState(logs[logs.length - 1].log_id) |
67 | return logs |
68 | } |
69 |
|