@commandgarden/cli 2.10.0 → 2.11.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/main.js +6 -6
- package/node_modules/@commandgarden/app/dist/client/assets/{Slides-D3xcxd9t.js → Slides-BvMlkL-3.js} +5 -15
- package/node_modules/@commandgarden/app/dist/client/assets/index-BD8reQ8T.js +496 -0
- package/node_modules/@commandgarden/app/dist/client/assets/{index-DbqYLIqy.css → index-wgb9-PIF.css} +1 -1
- package/node_modules/@commandgarden/app/dist/client/index.html +19 -19
- package/node_modules/@commandgarden/app/dist/server/daemon-client.test.js +47 -0
- package/node_modules/@commandgarden/app/dist/server/journal/journal.service.d.ts +1 -0
- package/node_modules/@commandgarden/app/dist/server/journal/journal.service.js +25 -6
- package/node_modules/@commandgarden/app/dist/server/journal/journal.types.d.ts +26 -0
- package/node_modules/@commandgarden/app/dist/server/journal/sources/meetings.source.d.ts +10 -4
- package/node_modules/@commandgarden/app/dist/server/journal/sources/meetings.source.js +36 -29
- package/node_modules/@commandgarden/app/dist/server/journal/sources/timetracking.source.d.ts +10 -1
- package/node_modules/@commandgarden/app/dist/server/journal/sources/timetracking.source.js +62 -8
- package/node_modules/@commandgarden/app/dist/server/routes/journal.d.ts +12 -0
- package/node_modules/@commandgarden/app/dist/server/routes/journal.js +87 -5
- package/node_modules/@commandgarden/app/dist/server/routes/routes.test.js +137 -0
- package/node_modules/@commandgarden/app/dist/server/store.d.ts +27 -0
- package/node_modules/@commandgarden/app/dist/server/store.js +130 -39
- package/node_modules/@commandgarden/app/dist/server/store.test.js +59 -0
- package/node_modules/@commandgarden/app/package.json +42 -42
- package/node_modules/@commandgarden/chrome/dist/content-script.js.map +1 -1
- package/node_modules/@commandgarden/chrome/dist/fetch-interceptor.js +44 -0
- package/node_modules/@commandgarden/chrome/dist/manifest.json +26 -26
- package/node_modules/@commandgarden/chrome/dist/popup.html +218 -218
- package/node_modules/@commandgarden/chrome/dist/popup.js.map +1 -1
- package/node_modules/@commandgarden/chrome/dist/service-worker.js +11 -3
- package/node_modules/@commandgarden/chrome/dist/service-worker.js.map +2 -2
- package/node_modules/@commandgarden/chrome/package.json +26 -26
- package/node_modules/@commandgarden/daemon/connectors/ado-git-commits.eval.js +100 -100
- package/node_modules/@commandgarden/daemon/connectors/ado-git-commits.yaml +70 -70
- package/node_modules/@commandgarden/daemon/connectors/gcs-kb-content.yaml +61 -61
- package/node_modules/@commandgarden/daemon/connectors/gcs-kb-pages.yaml +54 -54
- package/node_modules/@commandgarden/daemon/connectors/jira-my-tickets.eval.js +115 -115
- package/node_modules/@commandgarden/daemon/connectors/jira-my-tickets.yaml +54 -54
- package/node_modules/@commandgarden/daemon/connectors/lib/msal-token.js +20 -20
- package/node_modules/@commandgarden/daemon/connectors/outlook-my-meetings.eval.js +204 -198
- package/node_modules/@commandgarden/daemon/connectors/outlook-my-meetings.yaml +42 -42
- package/node_modules/@commandgarden/daemon/connectors/saba-pending-training.eval.js +94 -94
- package/node_modules/@commandgarden/daemon/connectors/saba-pending-training.yaml +34 -34
- package/node_modules/@commandgarden/daemon/connectors/socket-security-news.yaml +63 -63
- package/node_modules/@commandgarden/daemon/connectors/teams-room-availability.eval.js +437 -437
- package/node_modules/@commandgarden/daemon/connectors/teams-room-availability.yaml +53 -53
- package/node_modules/@commandgarden/daemon/connectors/teams-rooms-availability.eval.js +547 -547
- package/node_modules/@commandgarden/daemon/connectors/teams-rooms-availability.yaml +48 -48
- package/node_modules/@commandgarden/daemon/connectors/timetracking-projects.eval.js +52 -52
- package/node_modules/@commandgarden/daemon/connectors/timetracking-projects.yaml +42 -42
- package/node_modules/@commandgarden/daemon/connectors/timetracking-report.eval.js +81 -81
- package/node_modules/@commandgarden/daemon/connectors/timetracking-report.yaml +52 -52
- package/node_modules/@commandgarden/daemon/connectors/tldrsec-newsletter.eval.js +27 -27
- package/node_modules/@commandgarden/daemon/connectors/tldrsec-newsletter.yaml +38 -38
- package/node_modules/@commandgarden/daemon/connectors/tokenmaster-clients-list.yaml +55 -55
- package/node_modules/@commandgarden/daemon/dist/audit-store.js +8 -8
- package/node_modules/@commandgarden/daemon/dist/cdp-client.d.ts +24 -0
- package/node_modules/@commandgarden/daemon/dist/cdp-client.d.ts.map +1 -0
- package/node_modules/@commandgarden/daemon/dist/cdp-client.js +150 -0
- package/node_modules/@commandgarden/daemon/dist/cdp-client.js.map +1 -0
- package/node_modules/@commandgarden/daemon/package.json +32 -32
- package/node_modules/@commandgarden/shared/package.json +32 -32
- package/package.json +58 -58
- package/node_modules/@commandgarden/app/dist/client/assets/index-_jNYPoLF.js +0 -461
|
@@ -1,115 +1,115 @@
|
|
|
1
|
-
// Runs in page context via js_evaluate step.
|
|
2
|
-
// Fetches Jira Cloud tickets assigned to the user using the browser's
|
|
3
|
-
// authenticated session (Atlassian cookies — no API token required).
|
|
4
|
-
//
|
|
5
|
-
// Uses Jira REST API v3 with JQL queries to find:
|
|
6
|
-
// - Resolved tickets within the date range
|
|
7
|
-
// - Currently in-progress tickets
|
|
8
|
-
// - Blockers: in-progress items not updated in 3+ days
|
|
9
|
-
//
|
|
10
|
-
// Template variables interpolated before execution:
|
|
11
|
-
// ${{ args.fromDate }}
|
|
12
|
-
// ${{ args.toDate }}
|
|
13
|
-
// ${{ args.assignee | default("") }}
|
|
14
|
-
|
|
15
|
-
function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
|
|
16
|
-
|
|
17
|
-
const JIRA_BASE = 'https://mercedes-benz.atlassian.net';
|
|
18
|
-
const API = `${JIRA_BASE}/rest/api/3`;
|
|
19
|
-
|
|
20
|
-
const fromDate = '${{ args.fromDate }}'.trim();
|
|
21
|
-
const toDate = '${{ args.toDate }}'.trim();
|
|
22
|
-
const assigneeArg = '${{ args.assignee | default("") }}'.trim();
|
|
23
|
-
|
|
24
|
-
if (!fromDate || !toDate) {
|
|
25
|
-
throw new Error('Missing required args: fromDate, toDate');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Use currentUser() if no assignee provided — Jira JQL function that
|
|
29
|
-
// resolves to the logged-in user without knowing their username.
|
|
30
|
-
const assignee = assigneeArg || 'currentUser()';
|
|
31
|
-
// JQL uses currentUser() as a function (no quotes), but a literal
|
|
32
|
-
// username needs quotes. Detect which format to use.
|
|
33
|
-
const assigneeJql = assignee === 'currentUser()' ? 'currentUser()' : `"${assignee}"`;
|
|
34
|
-
|
|
35
|
-
// ── Wait for Jira to finish SSO/redirect (up to 30s) ──────────────────
|
|
36
|
-
const __deadline = Date.now() + 30000;
|
|
37
|
-
while (Date.now() < __deadline) {
|
|
38
|
-
if (location.hostname === 'mercedes-benz.atlassian.net') break;
|
|
39
|
-
await sleep(1000);
|
|
40
|
-
}
|
|
41
|
-
if (location.hostname !== 'mercedes-benz.atlassian.net') {
|
|
42
|
-
throw new Error('Not signed in to Jira — log in at mercedes-benz.atlassian.net and retry');
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// ── Helper: run a JQL search and return issues ────────────────────────
|
|
46
|
-
// Uses the browser's session cookies for auth (same-origin fetch).
|
|
47
|
-
async function jqlSearch(jql, maxResults = 100) {
|
|
48
|
-
// Jira Cloud deprecated /rest/api/3/search (HTTP 410) — must use /rest/api/3/search/jql
|
|
49
|
-
const url = `${API}/search/jql?jql=${encodeURIComponent(jql)}&maxResults=${maxResults}&fields=summary,status,issuetype,resolutiondate,updated`;
|
|
50
|
-
const resp = await fetch(url, {
|
|
51
|
-
headers: { Accept: 'application/json' },
|
|
52
|
-
credentials: 'include', // send Atlassian session cookies
|
|
53
|
-
});
|
|
54
|
-
if (!resp.ok) {
|
|
55
|
-
const text = await resp.text().catch(() => '');
|
|
56
|
-
throw new Error(`Jira search failed (HTTP ${resp.status}): ${text.slice(0, 200)}`);
|
|
57
|
-
}
|
|
58
|
-
const body = await resp.json();
|
|
59
|
-
return body.issues || [];
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// ── Run two JQL queries ───────────────────────────────────────────────
|
|
63
|
-
|
|
64
|
-
// Resolved: tickets resolved/closed within the date range
|
|
65
|
-
const resolvedJql = `assignee = ${assigneeJql} AND status changed TO ("Done", "Closed", "Resolved") DURING ("${fromDate}", "${toDate}") ORDER BY resolutiondate DESC`;
|
|
66
|
-
|
|
67
|
-
// In-progress: currently active tickets assigned to the user
|
|
68
|
-
const inProgressJql = `assignee = ${assigneeJql} AND status IN ("In Progress", "In Review", "To Do", "Open") ORDER BY updated ASC`;
|
|
69
|
-
|
|
70
|
-
const [resolvedIssues, inProgressIssues] = await Promise.all([
|
|
71
|
-
jqlSearch(resolvedJql),
|
|
72
|
-
jqlSearch(inProgressJql),
|
|
73
|
-
]);
|
|
74
|
-
|
|
75
|
-
// ── Build output rows ─────────────────────────────────────────────────
|
|
76
|
-
const now = Date.now();
|
|
77
|
-
const rows = [];
|
|
78
|
-
|
|
79
|
-
for (const issue of resolvedIssues) {
|
|
80
|
-
const f = issue.fields || {};
|
|
81
|
-
rows.push({
|
|
82
|
-
key: issue.key,
|
|
83
|
-
summary: f.summary || '(no title)',
|
|
84
|
-
status: f.status?.name || '',
|
|
85
|
-
type: f.issuetype?.name || '',
|
|
86
|
-
resolvedDate: (f.resolutiondate || '').slice(0, 10),
|
|
87
|
-
updatedDate: (f.updated || '').slice(0, 10),
|
|
88
|
-
staleDays: 0,
|
|
89
|
-
category: 'resolved',
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
for (const issue of inProgressIssues) {
|
|
94
|
-
const f = issue.fields || {};
|
|
95
|
-
const updated = f.updated;
|
|
96
|
-
// Calculate staleDays: days since the ticket was last updated
|
|
97
|
-
const staleDays = updated
|
|
98
|
-
? Math.floor((now - new Date(updated).getTime()) / 86400000)
|
|
99
|
-
: 0;
|
|
100
|
-
// Tickets not updated in 3+ days are flagged as blockers
|
|
101
|
-
const category = staleDays >= 3 ? 'blocker' : 'inProgress';
|
|
102
|
-
|
|
103
|
-
rows.push({
|
|
104
|
-
key: issue.key,
|
|
105
|
-
summary: f.summary || '(no title)',
|
|
106
|
-
status: f.status?.name || '',
|
|
107
|
-
type: f.issuetype?.name || '',
|
|
108
|
-
resolvedDate: '',
|
|
109
|
-
updatedDate: (updated || '').slice(0, 10),
|
|
110
|
-
staleDays,
|
|
111
|
-
category,
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return rows;
|
|
1
|
+
// Runs in page context via js_evaluate step.
|
|
2
|
+
// Fetches Jira Cloud tickets assigned to the user using the browser's
|
|
3
|
+
// authenticated session (Atlassian cookies — no API token required).
|
|
4
|
+
//
|
|
5
|
+
// Uses Jira REST API v3 with JQL queries to find:
|
|
6
|
+
// - Resolved tickets within the date range
|
|
7
|
+
// - Currently in-progress tickets
|
|
8
|
+
// - Blockers: in-progress items not updated in 3+ days
|
|
9
|
+
//
|
|
10
|
+
// Template variables interpolated before execution:
|
|
11
|
+
// ${{ args.fromDate }}
|
|
12
|
+
// ${{ args.toDate }}
|
|
13
|
+
// ${{ args.assignee | default("") }}
|
|
14
|
+
|
|
15
|
+
function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
|
|
16
|
+
|
|
17
|
+
const JIRA_BASE = 'https://mercedes-benz.atlassian.net';
|
|
18
|
+
const API = `${JIRA_BASE}/rest/api/3`;
|
|
19
|
+
|
|
20
|
+
const fromDate = '${{ args.fromDate }}'.trim();
|
|
21
|
+
const toDate = '${{ args.toDate }}'.trim();
|
|
22
|
+
const assigneeArg = '${{ args.assignee | default("") }}'.trim();
|
|
23
|
+
|
|
24
|
+
if (!fromDate || !toDate) {
|
|
25
|
+
throw new Error('Missing required args: fromDate, toDate');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Use currentUser() if no assignee provided — Jira JQL function that
|
|
29
|
+
// resolves to the logged-in user without knowing their username.
|
|
30
|
+
const assignee = assigneeArg || 'currentUser()';
|
|
31
|
+
// JQL uses currentUser() as a function (no quotes), but a literal
|
|
32
|
+
// username needs quotes. Detect which format to use.
|
|
33
|
+
const assigneeJql = assignee === 'currentUser()' ? 'currentUser()' : `"${assignee}"`;
|
|
34
|
+
|
|
35
|
+
// ── Wait for Jira to finish SSO/redirect (up to 30s) ──────────────────
|
|
36
|
+
const __deadline = Date.now() + 30000;
|
|
37
|
+
while (Date.now() < __deadline) {
|
|
38
|
+
if (location.hostname === 'mercedes-benz.atlassian.net') break;
|
|
39
|
+
await sleep(1000);
|
|
40
|
+
}
|
|
41
|
+
if (location.hostname !== 'mercedes-benz.atlassian.net') {
|
|
42
|
+
throw new Error('Not signed in to Jira — log in at mercedes-benz.atlassian.net and retry');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ── Helper: run a JQL search and return issues ────────────────────────
|
|
46
|
+
// Uses the browser's session cookies for auth (same-origin fetch).
|
|
47
|
+
async function jqlSearch(jql, maxResults = 100) {
|
|
48
|
+
// Jira Cloud deprecated /rest/api/3/search (HTTP 410) — must use /rest/api/3/search/jql
|
|
49
|
+
const url = `${API}/search/jql?jql=${encodeURIComponent(jql)}&maxResults=${maxResults}&fields=summary,status,issuetype,resolutiondate,updated`;
|
|
50
|
+
const resp = await fetch(url, {
|
|
51
|
+
headers: { Accept: 'application/json' },
|
|
52
|
+
credentials: 'include', // send Atlassian session cookies
|
|
53
|
+
});
|
|
54
|
+
if (!resp.ok) {
|
|
55
|
+
const text = await resp.text().catch(() => '');
|
|
56
|
+
throw new Error(`Jira search failed (HTTP ${resp.status}): ${text.slice(0, 200)}`);
|
|
57
|
+
}
|
|
58
|
+
const body = await resp.json();
|
|
59
|
+
return body.issues || [];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ── Run two JQL queries ───────────────────────────────────────────────
|
|
63
|
+
|
|
64
|
+
// Resolved: tickets resolved/closed within the date range
|
|
65
|
+
const resolvedJql = `assignee = ${assigneeJql} AND status changed TO ("Done", "Closed", "Resolved") DURING ("${fromDate}", "${toDate}") ORDER BY resolutiondate DESC`;
|
|
66
|
+
|
|
67
|
+
// In-progress: currently active tickets assigned to the user
|
|
68
|
+
const inProgressJql = `assignee = ${assigneeJql} AND status IN ("In Progress", "In Review", "To Do", "Open") ORDER BY updated ASC`;
|
|
69
|
+
|
|
70
|
+
const [resolvedIssues, inProgressIssues] = await Promise.all([
|
|
71
|
+
jqlSearch(resolvedJql),
|
|
72
|
+
jqlSearch(inProgressJql),
|
|
73
|
+
]);
|
|
74
|
+
|
|
75
|
+
// ── Build output rows ─────────────────────────────────────────────────
|
|
76
|
+
const now = Date.now();
|
|
77
|
+
const rows = [];
|
|
78
|
+
|
|
79
|
+
for (const issue of resolvedIssues) {
|
|
80
|
+
const f = issue.fields || {};
|
|
81
|
+
rows.push({
|
|
82
|
+
key: issue.key,
|
|
83
|
+
summary: f.summary || '(no title)',
|
|
84
|
+
status: f.status?.name || '',
|
|
85
|
+
type: f.issuetype?.name || '',
|
|
86
|
+
resolvedDate: (f.resolutiondate || '').slice(0, 10),
|
|
87
|
+
updatedDate: (f.updated || '').slice(0, 10),
|
|
88
|
+
staleDays: 0,
|
|
89
|
+
category: 'resolved',
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
for (const issue of inProgressIssues) {
|
|
94
|
+
const f = issue.fields || {};
|
|
95
|
+
const updated = f.updated;
|
|
96
|
+
// Calculate staleDays: days since the ticket was last updated
|
|
97
|
+
const staleDays = updated
|
|
98
|
+
? Math.floor((now - new Date(updated).getTime()) / 86400000)
|
|
99
|
+
: 0;
|
|
100
|
+
// Tickets not updated in 3+ days are flagged as blockers
|
|
101
|
+
const category = staleDays >= 3 ? 'blocker' : 'inProgress';
|
|
102
|
+
|
|
103
|
+
rows.push({
|
|
104
|
+
key: issue.key,
|
|
105
|
+
summary: f.summary || '(no title)',
|
|
106
|
+
status: f.status?.name || '',
|
|
107
|
+
type: f.issuetype?.name || '',
|
|
108
|
+
resolvedDate: '',
|
|
109
|
+
updatedDate: (updated || '').slice(0, 10),
|
|
110
|
+
staleDays,
|
|
111
|
+
category,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return rows;
|
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
site: jira
|
|
2
|
-
name: my-tickets
|
|
3
|
-
version: "2.0"
|
|
4
|
-
description: "Jira Cloud tickets assigned to the user — resolved, in-progress, and blockers"
|
|
5
|
-
access: read
|
|
6
|
-
|
|
7
|
-
domains:
|
|
8
|
-
- "mercedes-benz.atlassian.net"
|
|
9
|
-
capabilities:
|
|
10
|
-
- navigate
|
|
11
|
-
- js_evaluate
|
|
12
|
-
|
|
13
|
-
args:
|
|
14
|
-
- name: fromDate
|
|
15
|
-
type: string
|
|
16
|
-
required: true
|
|
17
|
-
help: "Start date in YYYY-MM-DD format"
|
|
18
|
-
pattern: "^\\d{4}-\\d{2}-\\d{2}$"
|
|
19
|
-
- name: toDate
|
|
20
|
-
type: string
|
|
21
|
-
required: true
|
|
22
|
-
help: "End date in YYYY-MM-DD format"
|
|
23
|
-
pattern: "^\\d{4}-\\d{2}-\\d{2}$"
|
|
24
|
-
- name: assignee
|
|
25
|
-
type: string
|
|
26
|
-
required: false
|
|
27
|
-
help: "Override assignee (Jira username or 'currentUser()'). Default: currentUser()"
|
|
28
|
-
|
|
29
|
-
columns:
|
|
30
|
-
- name: key
|
|
31
|
-
type: string
|
|
32
|
-
- name: summary
|
|
33
|
-
type: string
|
|
34
|
-
- name: status
|
|
35
|
-
type: string
|
|
36
|
-
- name: type
|
|
37
|
-
type: string
|
|
38
|
-
- name: resolvedDate
|
|
39
|
-
type: string
|
|
40
|
-
- name: updatedDate
|
|
41
|
-
type: string
|
|
42
|
-
- name: staleDays
|
|
43
|
-
type: number
|
|
44
|
-
- name: category
|
|
45
|
-
type: string
|
|
46
|
-
|
|
47
|
-
pipeline:
|
|
48
|
-
- step: navigate
|
|
49
|
-
url: "https://mercedes-benz.atlassian.net/"
|
|
50
|
-
- step: wait
|
|
51
|
-
selector: "body"
|
|
52
|
-
timeout: 30000
|
|
53
|
-
- step: js_evaluate
|
|
54
|
-
file: jira-my-tickets.eval.js
|
|
1
|
+
site: jira
|
|
2
|
+
name: my-tickets
|
|
3
|
+
version: "2.0"
|
|
4
|
+
description: "Jira Cloud tickets assigned to the user — resolved, in-progress, and blockers"
|
|
5
|
+
access: read
|
|
6
|
+
|
|
7
|
+
domains:
|
|
8
|
+
- "mercedes-benz.atlassian.net"
|
|
9
|
+
capabilities:
|
|
10
|
+
- navigate
|
|
11
|
+
- js_evaluate
|
|
12
|
+
|
|
13
|
+
args:
|
|
14
|
+
- name: fromDate
|
|
15
|
+
type: string
|
|
16
|
+
required: true
|
|
17
|
+
help: "Start date in YYYY-MM-DD format"
|
|
18
|
+
pattern: "^\\d{4}-\\d{2}-\\d{2}$"
|
|
19
|
+
- name: toDate
|
|
20
|
+
type: string
|
|
21
|
+
required: true
|
|
22
|
+
help: "End date in YYYY-MM-DD format"
|
|
23
|
+
pattern: "^\\d{4}-\\d{2}-\\d{2}$"
|
|
24
|
+
- name: assignee
|
|
25
|
+
type: string
|
|
26
|
+
required: false
|
|
27
|
+
help: "Override assignee (Jira username or 'currentUser()'). Default: currentUser()"
|
|
28
|
+
|
|
29
|
+
columns:
|
|
30
|
+
- name: key
|
|
31
|
+
type: string
|
|
32
|
+
- name: summary
|
|
33
|
+
type: string
|
|
34
|
+
- name: status
|
|
35
|
+
type: string
|
|
36
|
+
- name: type
|
|
37
|
+
type: string
|
|
38
|
+
- name: resolvedDate
|
|
39
|
+
type: string
|
|
40
|
+
- name: updatedDate
|
|
41
|
+
type: string
|
|
42
|
+
- name: staleDays
|
|
43
|
+
type: number
|
|
44
|
+
- name: category
|
|
45
|
+
type: string
|
|
46
|
+
|
|
47
|
+
pipeline:
|
|
48
|
+
- step: navigate
|
|
49
|
+
url: "https://mercedes-benz.atlassian.net/"
|
|
50
|
+
- step: wait
|
|
51
|
+
selector: "body"
|
|
52
|
+
timeout: 30000
|
|
53
|
+
- step: js_evaluate
|
|
54
|
+
file: jira-my-tickets.eval.js
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
// Shared MSAL token polling snippet for eval.js files.
|
|
2
|
-
// Paste this into any eval.js that needs an authenticated session.
|
|
3
|
-
// Polls sessionStorage for a valid access token for up to 60s.
|
|
4
|
-
|
|
5
|
-
const __deadline = Date.now() + 60000;
|
|
6
|
-
let token;
|
|
7
|
-
while (Date.now() < __deadline) {
|
|
8
|
-
const k = Object.keys(sessionStorage).find(x => x.includes('accesstoken'));
|
|
9
|
-
if (k) {
|
|
10
|
-
try {
|
|
11
|
-
const tokenData = JSON.parse(sessionStorage.getItem(k));
|
|
12
|
-
if (Number(tokenData.expiresOn) > Math.floor(Date.now() / 1000) + 30) {
|
|
13
|
-
token = tokenData.secret;
|
|
14
|
-
break;
|
|
15
|
-
}
|
|
16
|
-
} catch (_) {}
|
|
17
|
-
}
|
|
18
|
-
await new Promise(r => setTimeout(r, 1000));
|
|
19
|
-
}
|
|
20
|
-
if (!token) throw new Error('No valid MSAL access token after 60s — log in and retry');
|
|
1
|
+
// Shared MSAL token polling snippet for eval.js files.
|
|
2
|
+
// Paste this into any eval.js that needs an authenticated session.
|
|
3
|
+
// Polls sessionStorage for a valid access token for up to 60s.
|
|
4
|
+
|
|
5
|
+
const __deadline = Date.now() + 60000;
|
|
6
|
+
let token;
|
|
7
|
+
while (Date.now() < __deadline) {
|
|
8
|
+
const k = Object.keys(sessionStorage).find(x => x.includes('accesstoken'));
|
|
9
|
+
if (k) {
|
|
10
|
+
try {
|
|
11
|
+
const tokenData = JSON.parse(sessionStorage.getItem(k));
|
|
12
|
+
if (Number(tokenData.expiresOn) > Math.floor(Date.now() / 1000) + 30) {
|
|
13
|
+
token = tokenData.secret;
|
|
14
|
+
break;
|
|
15
|
+
}
|
|
16
|
+
} catch (_) {}
|
|
17
|
+
}
|
|
18
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
19
|
+
}
|
|
20
|
+
if (!token) throw new Error('No valid MSAL access token after 60s — log in and retry');
|