brightspace-mcp-server 1.6.3 → 3.0.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/README.md +43 -35
- package/build/api/client.d.ts +37 -10
- package/build/api/client.d.ts.map +1 -1
- package/build/api/client.js +158 -100
- package/build/api/client.js.map +1 -1
- package/build/api/errors.d.ts +4 -0
- package/build/api/errors.d.ts.map +1 -1
- package/build/api/errors.js +7 -0
- package/build/api/errors.js.map +1 -1
- package/build/auth/auth-cooldown.d.ts +24 -0
- package/build/auth/auth-cooldown.d.ts.map +1 -0
- package/build/auth/auth-cooldown.js +60 -0
- package/build/auth/auth-cooldown.js.map +1 -0
- package/build/auth/auth-lock.d.ts +7 -0
- package/build/auth/auth-lock.d.ts.map +1 -0
- package/build/auth/auth-lock.js +162 -0
- package/build/auth/auth-lock.js.map +1 -0
- package/build/auth/auth-runner.d.ts +30 -9
- package/build/auth/auth-runner.d.ts.map +1 -1
- package/build/auth/auth-runner.js +171 -56
- package/build/auth/auth-runner.js.map +1 -1
- package/build/auth/browser-auth.d.ts +19 -87
- package/build/auth/browser-auth.d.ts.map +1 -1
- package/build/auth/browser-auth.js +266 -614
- package/build/auth/browser-auth.js.map +1 -1
- package/build/auth/browser-state-store.d.ts +19 -0
- package/build/auth/browser-state-store.d.ts.map +1 -0
- package/build/auth/browser-state-store.js +101 -0
- package/build/auth/browser-state-store.js.map +1 -0
- package/build/auth/credential-store.d.ts +29 -0
- package/build/auth/credential-store.d.ts.map +1 -0
- package/build/auth/credential-store.js +233 -0
- package/build/auth/credential-store.js.map +1 -0
- package/build/auth/encrypted-store.d.ts +25 -0
- package/build/auth/encrypted-store.d.ts.map +1 -0
- package/build/auth/encrypted-store.js +61 -0
- package/build/auth/encrypted-store.js.map +1 -0
- package/build/auth/legacy-profile.d.ts +3 -0
- package/build/auth/legacy-profile.d.ts.map +1 -0
- package/build/auth/legacy-profile.js +41 -0
- package/build/auth/legacy-profile.js.map +1 -0
- package/build/auth/legacy-state.d.ts +14 -0
- package/build/auth/legacy-state.d.ts.map +1 -0
- package/build/auth/legacy-state.js +107 -0
- package/build/auth/legacy-state.js.map +1 -0
- package/build/auth/purdue-sso.d.ts +25 -36
- package/build/auth/purdue-sso.d.ts.map +1 -1
- package/build/auth/purdue-sso.js +210 -191
- package/build/auth/purdue-sso.js.map +1 -1
- package/build/auth/session-store.d.ts +16 -38
- package/build/auth/session-store.d.ts.map +1 -1
- package/build/auth/session-store.js +157 -152
- package/build/auth/session-store.js.map +1 -1
- package/build/auth/sso-flow.d.ts +16 -4
- package/build/auth/sso-flow.d.ts.map +1 -1
- package/build/auth/sso-flow.js +24 -2
- package/build/auth/sso-flow.js.map +1 -1
- package/build/auth/suny-sso.d.ts +6 -2
- package/build/auth/suny-sso.d.ts.map +1 -1
- package/build/auth/suny-sso.js +17 -24
- package/build/auth/suny-sso.js.map +1 -1
- package/build/auth/token-manager.d.ts +10 -3
- package/build/auth/token-manager.d.ts.map +1 -1
- package/build/auth/token-manager.js +62 -26
- package/build/auth/token-manager.js.map +1 -1
- package/build/auth/token-mint.d.ts +2 -2
- package/build/auth/token-mint.d.ts.map +1 -1
- package/build/auth/token-mint.js +31 -9
- package/build/auth/token-mint.js.map +1 -1
- package/build/auth-cli.d.ts +1 -7
- package/build/auth-cli.d.ts.map +1 -1
- package/build/auth-cli.js +71 -70
- package/build/auth-cli.js.map +1 -1
- package/build/index.js +20 -64
- package/build/index.js.map +1 -1
- package/build/setup.js +44 -19
- package/build/setup.js.map +1 -1
- package/build/tools/tool-helpers.d.ts +7 -1
- package/build/tools/tool-helpers.d.ts.map +1 -1
- package/build/tools/tool-helpers.js +96 -11
- package/build/tools/tool-helpers.js.map +1 -1
- package/build/types/index.d.ts +6 -0
- package/build/types/index.d.ts.map +1 -1
- package/build/utils/browser-install.d.ts +23 -0
- package/build/utils/browser-install.d.ts.map +1 -0
- package/build/utils/browser-install.js +33 -0
- package/build/utils/browser-install.js.map +1 -0
- package/build/utils/commands.d.ts +26 -0
- package/build/utils/commands.d.ts.map +1 -0
- package/build/utils/commands.js +26 -0
- package/build/utils/commands.js.map +1 -0
- package/build/utils/config-store.d.ts +1 -0
- package/build/utils/config-store.d.ts.map +1 -1
- package/build/utils/config-store.js +3 -0
- package/build/utils/config-store.js.map +1 -1
- package/build/utils/config.d.ts +2 -1
- package/build/utils/config.d.ts.map +1 -1
- package/build/utils/config.js +32 -10
- package/build/utils/config.js.map +1 -1
- package/build/utils/download-errors.d.ts +45 -0
- package/build/utils/download-errors.d.ts.map +1 -0
- package/build/utils/download-errors.js +45 -0
- package/build/utils/download-errors.js.map +1 -0
- package/build/utils/download-helpers.d.ts.map +1 -1
- package/build/utils/download-helpers.js +2 -1
- package/build/utils/download-helpers.js.map +1 -1
- package/build/utils/file-validator.d.ts +1 -1
- package/build/utils/file-validator.d.ts.map +1 -1
- package/build/utils/file-validator.js +47 -7
- package/build/utils/file-validator.js.map +1 -1
- package/build/utils/install-sites.d.ts +61 -0
- package/build/utils/install-sites.d.ts.map +1 -0
- package/build/utils/install-sites.js +207 -0
- package/build/utils/install-sites.js.map +1 -0
- package/build/utils/secure-config.d.ts +6 -0
- package/build/utils/secure-config.d.ts.map +1 -0
- package/build/utils/secure-config.js +57 -0
- package/build/utils/secure-config.js.map +1 -0
- package/build/utils/self-update.d.ts +61 -0
- package/build/utils/self-update.d.ts.map +1 -0
- package/build/utils/self-update.js +92 -0
- package/build/utils/self-update.js.map +1 -0
- package/build/utils/update-checker.d.ts +85 -7
- package/build/utils/update-checker.d.ts.map +1 -1
- package/build/utils/update-checker.js +141 -36
- package/build/utils/update-checker.js.map +1 -1
- package/package.json +4 -2
package/build/auth/purdue-sso.js
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Purdue Brightspace MCP Server
|
|
3
3
|
* Copyright (c) 2026 Rohan Muppa. All rights reserved.
|
|
4
|
-
* Licensed under MIT
|
|
4
|
+
* Licensed under MIT : see LICENSE file for details.
|
|
5
5
|
*/
|
|
6
6
|
import { BrowserAuthError } from "../utils/errors.js";
|
|
7
7
|
import { log } from "../utils/logger.js";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
formSubmit: 'button[name="_eventId_proceed"], button.d2l-button, input[type="submit"]',
|
|
16
|
-
};
|
|
17
|
-
// Entra labels the account-name button "Next" and only shows "Sign in" on the
|
|
18
|
-
// view that follows. Both are input#idSIButton9, so the label tells them apart.
|
|
19
|
-
const ACCOUNT_NAME_BUTTON = /^next$/i;
|
|
8
|
+
import { MfaApprovalError, UnsupportedAuthenticationError } from "./sso-flow.js";
|
|
9
|
+
import { AUTH_COMMAND } from "../utils/commands.js";
|
|
10
|
+
const EMAIL_SELECTORS = ["input[type=email]", "input[name=loginfmt]"];
|
|
11
|
+
const PASSWORD_SELECTORS = ["input[type=password]", "input[name=passwd]"];
|
|
12
|
+
const SUBMIT_SELECTORS = ["#idSIButton9", "input[type=submit]", "button[type=submit]"];
|
|
13
|
+
const FIELD_TIMEOUT_MS = 30_000;
|
|
14
|
+
const FIELD_POLL_MS = 250;
|
|
20
15
|
/**
|
|
21
16
|
* Entra's number-match digits. The tenant shows a two-digit number that has to
|
|
22
17
|
* be typed into Microsoft Authenticator, and nothing else on the machine
|
|
@@ -24,16 +19,22 @@ const ACCOUNT_NAME_BUTTON = /^next$/i;
|
|
|
24
19
|
* logged. Plain DOM text, no OCR.
|
|
25
20
|
*/
|
|
26
21
|
const NUMBER_MATCH_SELECTOR = "#idRichContext_DisplaySign";
|
|
22
|
+
const MFA_CODE_SELECTORS = ["#idTxtBx_SAOTCC_OTC", 'input[name="otc"]'];
|
|
23
|
+
const MFA_CODE_SUBMIT_SELECTORS = ["#idSubmit_SAOTCC_Continue", "#idSIButton9"];
|
|
27
24
|
/** How often to look for the number while waiting on MFA. */
|
|
28
25
|
const NUMBER_MATCH_POLL_MS = 2000;
|
|
29
26
|
/** A person has to find their phone, unlock it, and read a prompt. */
|
|
30
27
|
const MFA_TIMEOUT_MS = 5 * 60 * 1000;
|
|
31
|
-
/**
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
/** Microsoft expects Purdue's full sign-in name, while setup also accepts a career account. */
|
|
29
|
+
function signInName(username, baseUrl) {
|
|
30
|
+
const isPurdue = baseUrl && new URL(baseUrl).hostname.toLowerCase() === "purdue.brightspace.com";
|
|
31
|
+
return isPurdue && !username.includes("@") ? `${username}@purdue.edu` : username;
|
|
34
32
|
}
|
|
35
33
|
export class PurdueSSOFlow {
|
|
36
34
|
config;
|
|
35
|
+
accountHintSubmitted = false;
|
|
36
|
+
/** One authenticator code per login. See submitMfaCode. */
|
|
37
|
+
mfaCodeSubmitted = false;
|
|
37
38
|
constructor(config) {
|
|
38
39
|
this.config = config;
|
|
39
40
|
}
|
|
@@ -43,204 +44,236 @@ export class PurdueSSOFlow {
|
|
|
43
44
|
hasCredentials() {
|
|
44
45
|
return Boolean(this.config.username && this.config.password);
|
|
45
46
|
}
|
|
47
|
+
async prepareLogin(page) {
|
|
48
|
+
await this.handleCampusSelector(page);
|
|
49
|
+
}
|
|
50
|
+
/** First half of Brightspace Bar's choreography, with no password access. */
|
|
51
|
+
async identifyAccount(page) {
|
|
52
|
+
if (!this.config.username)
|
|
53
|
+
return false;
|
|
54
|
+
const email = signInName(this.config.username, this.config.baseUrl);
|
|
55
|
+
if (!await this.fillWhenReady(page, EMAIL_SELECTORS, email))
|
|
56
|
+
return false;
|
|
57
|
+
if (!await this.clickWhenReady(page, SUBMIT_SELECTORS))
|
|
58
|
+
return false;
|
|
59
|
+
this.accountHintSubmitted = true;
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
46
62
|
/**
|
|
47
63
|
* Execute the complete Microsoft Entra ID SSO login flow for Purdue.
|
|
48
|
-
* Handles
|
|
64
|
+
* Handles the school selector, saved credentials, device MFA approval, and stay-signed-in.
|
|
49
65
|
*
|
|
50
66
|
* @param page - Playwright page instance (already navigated to Brightspace or redirected to login)
|
|
51
|
-
* @returns true
|
|
67
|
+
* @returns true after reaching Brightspace home; failures are typed errors
|
|
52
68
|
*/
|
|
53
69
|
async login(page) {
|
|
54
70
|
try {
|
|
55
71
|
log("INFO", "Starting SSO login flow");
|
|
56
72
|
// Step 1: Handle campus selector on purdue.brightspace.com/d2l/login
|
|
57
73
|
await this.handleCampusSelector(page);
|
|
58
|
-
//
|
|
59
|
-
await this.
|
|
60
|
-
|
|
74
|
+
// Restored Microsoft state can lead directly to MFA or stay-signed-in.
|
|
75
|
+
const postCredential = await this.anyVisible(page, [
|
|
76
|
+
NUMBER_MATCH_SELECTOR,
|
|
77
|
+
"#idDiv_SAOTCAS_Title",
|
|
78
|
+
"#idDiv_SAOTCC_Title",
|
|
79
|
+
"#KmsiCheckboxField",
|
|
80
|
+
]);
|
|
81
|
+
const kmsi = await page.getByText("Stay signed in?").first().isVisible().catch(() => false);
|
|
82
|
+
if (!page.url().includes("/d2l/home") && !postCredential && !kmsi)
|
|
83
|
+
await this.enterCredentials(page);
|
|
84
|
+
// Wait for device approval and print Microsoft's number match.
|
|
61
85
|
await this.handleMFA(page);
|
|
62
|
-
// Step 4: Handle "Stay signed in?" prompt
|
|
63
|
-
await this.handleStaySignedIn(page);
|
|
64
|
-
// Step 5: Wait for successful redirect to Brightspace home
|
|
65
|
-
await page.waitForURL(/\/d2l\/home/, { timeout: 120000 });
|
|
66
|
-
log("INFO", "Login successful - reached Brightspace home");
|
|
67
86
|
return true;
|
|
68
87
|
}
|
|
69
88
|
catch (error) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Manual login fallback: let the user type credentials and complete MFA themselves.
|
|
76
|
-
* The browser stays open in headed mode while we wait for /d2l/home.
|
|
77
|
-
*/
|
|
78
|
-
async manualLogin(page) {
|
|
79
|
-
try {
|
|
80
|
-
log("INFO", "Starting manual login flow (no saved credentials)");
|
|
81
|
-
log("INFO", "Please log in using the browser window that just opened.");
|
|
82
|
-
// Navigate past the campus selector so the user lands on the Shibboleth form
|
|
83
|
-
await this.handleCampusSelector(page);
|
|
84
|
-
// Wait up to 5 minutes for the user to complete login manually
|
|
85
|
-
log("INFO", "Waiting up to 5 minutes for you to complete login and MFA...");
|
|
86
|
-
await page.waitForURL(/\/d2l\/home/, { timeout: 300000 });
|
|
87
|
-
log("INFO", "Manual login successful - reached Brightspace home");
|
|
88
|
-
return true;
|
|
89
|
-
}
|
|
90
|
-
catch (error) {
|
|
91
|
-
log("ERROR", "Manual login flow failed or timed out", error);
|
|
92
|
-
return false;
|
|
89
|
+
if (error instanceof BrowserAuthError)
|
|
90
|
+
throw error;
|
|
91
|
+
throw new UnsupportedAuthenticationError("The identity provider could not complete headless sign-in. Check saved credentials and supported MFA settings.", error);
|
|
93
92
|
}
|
|
94
93
|
}
|
|
95
94
|
async handleCampusSelector(page) {
|
|
96
95
|
const currentUrl = page.url();
|
|
97
96
|
if (currentUrl.includes("purdue.brightspace.com") && currentUrl.includes("/d2l/login")) {
|
|
98
|
-
//
|
|
99
|
-
//
|
|
97
|
+
// Follow the live Purdue control first, as Brightspace Bar does, so a
|
|
98
|
+
// tenant-side destination change does not leave this client behind.
|
|
99
|
+
const campus = page.getByText(/Purdue West Lafayette/i).first();
|
|
100
|
+
if (await campus.isVisible().catch(() => false)) {
|
|
101
|
+
log("INFO", "Campus selector detected : selecting Purdue West Lafayette");
|
|
102
|
+
await campus.click();
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// Retain the known endpoint as a fallback if the control has not rendered.
|
|
100
106
|
const baseUrl = new URL(currentUrl).origin;
|
|
101
|
-
log("INFO", "Campus selector detected
|
|
102
|
-
await page.goto(`${baseUrl}/d2l/lp/auth/saml/initiate-login?entityId=https://idp.purdue.edu/idp/shibboleth`, { waitUntil: "
|
|
107
|
+
log("INFO", "Campus selector detected : navigating directly to Shibboleth IdP");
|
|
108
|
+
await page.goto(`${baseUrl}/d2l/lp/auth/saml/initiate-login?entityId=https://idp.purdue.edu/idp/shibboleth`, { waitUntil: "domcontentloaded", timeout: 30000 });
|
|
103
109
|
}
|
|
104
|
-
// Already on sso.purdue.edu or past the campus selector
|
|
110
|
+
// Already on sso.purdue.edu or past the campus selector : nothing to do
|
|
105
111
|
}
|
|
106
112
|
async enterCredentials(page) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if (!this.config.password) {
|
|
117
|
-
throw new BrowserAuthError("Password is required for SSO login", "credentials");
|
|
113
|
+
if (!this.config.username)
|
|
114
|
+
throw new BrowserAuthError("Username is required for SSO login", "credentials");
|
|
115
|
+
if (!this.config.password)
|
|
116
|
+
throw new BrowserAuthError("Password is required for SSO login", "credentials");
|
|
117
|
+
log("INFO", "Entering credentials");
|
|
118
|
+
if (!this.accountHintSubmitted) {
|
|
119
|
+
const email = signInName(this.config.username, this.config.baseUrl);
|
|
120
|
+
if (!await this.fillWhenReady(page, EMAIL_SELECTORS, email)) {
|
|
121
|
+
throw new UnsupportedAuthenticationError("The Microsoft email field did not appear. Headless sign-in cannot continue.");
|
|
118
122
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (usernameField) {
|
|
122
|
-
await usernameField.fill(this.config.username);
|
|
123
|
+
if (!await this.clickWhenReady(page, SUBMIT_SELECTORS)) {
|
|
124
|
+
throw new UnsupportedAuthenticationError("The Microsoft email submit button did not appear. Headless sign-in cannot continue.");
|
|
123
125
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
126
|
+
}
|
|
127
|
+
this.accountHintSubmitted = false;
|
|
128
|
+
if (!await this.fillWhenReady(page, PASSWORD_SELECTORS, this.config.password)) {
|
|
129
|
+
throw new UnsupportedAuthenticationError("The Microsoft password field did not appear. Headless sign-in cannot continue.");
|
|
130
|
+
}
|
|
131
|
+
if (!await this.clickWhenReady(page, SUBMIT_SELECTORS)) {
|
|
132
|
+
throw new UnsupportedAuthenticationError("The Microsoft password submit button did not appear. Headless sign-in cannot continue.");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/** Ported from Brightspace Bar's proven four-step Entra choreography. */
|
|
136
|
+
async actWhenReady(page, selectors, act) {
|
|
137
|
+
const deadline = Date.now() + FIELD_TIMEOUT_MS;
|
|
138
|
+
do {
|
|
139
|
+
for (const selector of selectors) {
|
|
140
|
+
const target = page.locator(selector).first();
|
|
141
|
+
if (await target.isVisible().catch(() => false)) {
|
|
142
|
+
await act(target);
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
136
145
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
146
|
+
await page.waitForTimeout(FIELD_POLL_MS);
|
|
147
|
+
} while (Date.now() < deadline);
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
async fillWhenReady(page, selectors, value) {
|
|
151
|
+
return this.actWhenReady(page, selectors, target => target.fill(value));
|
|
152
|
+
}
|
|
153
|
+
async clickWhenReady(page, selectors) {
|
|
154
|
+
// Entra often detaches the button after the click has already navigated.
|
|
155
|
+
return this.actWhenReady(page, selectors, target => target.click().catch(() => { }));
|
|
156
|
+
}
|
|
157
|
+
/** Match Brightspace Bar's selector loop instead of trusting the first DOM match. */
|
|
158
|
+
async anyVisible(page, selectors) {
|
|
159
|
+
for (const selector of selectors) {
|
|
160
|
+
if (await page.locator(selector).first().isVisible().catch(() => false))
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
/** Brightspace Bar's bounded number/auth/KMSI polling loop. */
|
|
166
|
+
async handleMFA(page) {
|
|
167
|
+
if (!this.config.baseUrl) {
|
|
168
|
+
throw new UnsupportedAuthenticationError("A school URL is required to verify headless authentication.");
|
|
169
|
+
}
|
|
170
|
+
const deadline = Date.now() + MFA_TIMEOUT_MS;
|
|
171
|
+
let challenged = false;
|
|
172
|
+
let announced = null;
|
|
173
|
+
try {
|
|
174
|
+
while (Date.now() < deadline) {
|
|
175
|
+
if (await this.submitMfaCode(page))
|
|
176
|
+
challenged = true;
|
|
177
|
+
const number = await this.readNumberMatch(page);
|
|
178
|
+
const challengeVisible = number !== null ||
|
|
179
|
+
await page.locator("#idDiv_SAOTCAS_Title").first().isVisible().catch(() => false) ||
|
|
180
|
+
await page.locator("#idDiv_SAOTCC_Title").first().isVisible().catch(() => false);
|
|
181
|
+
if (challengeVisible && !challenged) {
|
|
182
|
+
challenged = true;
|
|
183
|
+
log("WARN", "Waiting up to 5 minutes for Microsoft MFA approval on your device.");
|
|
184
|
+
}
|
|
185
|
+
if (number && number !== announced) {
|
|
186
|
+
announced = number;
|
|
187
|
+
log("WARN", `Number match: ${number}. Enter it in Microsoft Authenticator.`);
|
|
188
|
+
}
|
|
189
|
+
if (await this.isAuthenticated(page)) {
|
|
190
|
+
log("INFO", "Login successful - verified Brightspace home");
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
await this.clickProvenKmsi(page);
|
|
194
|
+
await page.waitForTimeout(NUMBER_MATCH_POLL_MS);
|
|
140
195
|
}
|
|
141
|
-
await page.waitForLoadState("networkidle");
|
|
142
196
|
}
|
|
143
197
|
catch (error) {
|
|
144
|
-
|
|
145
|
-
|
|
198
|
+
if (error instanceof BrowserAuthError)
|
|
199
|
+
throw error;
|
|
200
|
+
if (challenged)
|
|
201
|
+
throw new MfaApprovalError(error);
|
|
202
|
+
throw new UnsupportedAuthenticationError("Headless sign-in stopped before a supported MFA challenge completed.", error);
|
|
146
203
|
}
|
|
204
|
+
if (challenged)
|
|
205
|
+
throw new MfaApprovalError();
|
|
206
|
+
throw new UnsupportedAuthenticationError("Sign-in did not reach a supported MFA challenge or Brightspace within 5 minutes.");
|
|
147
207
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
208
|
+
async submitMfaCode(page) {
|
|
209
|
+
const input = await this.firstVisible(page, MFA_CODE_SELECTORS);
|
|
210
|
+
if (!input)
|
|
211
|
+
return false;
|
|
212
|
+
if (this.config.headless === false)
|
|
213
|
+
return false;
|
|
214
|
+
// Ask once per login. This runs on every two-second poll, and Microsoft
|
|
215
|
+
// commonly leaves the field on screen while it validates, so without this
|
|
216
|
+
// a correct code gets a second prompt on the next tick. That prompt blocks
|
|
217
|
+
// on stdin, and the deadline is only checked between iterations, so the
|
|
218
|
+
// five-minute budget can never fire while parked there.
|
|
219
|
+
if (this.mfaCodeSubmitted)
|
|
220
|
+
return false;
|
|
221
|
+
if (!this.config.requestMfaCode) {
|
|
222
|
+
throw new UnsupportedAuthenticationError(`This MFA method requires a code. Run \`${AUTH_COMMAND}\` in a terminal to enter it.`);
|
|
160
223
|
}
|
|
161
|
-
|
|
224
|
+
this.mfaCodeSubmitted = true;
|
|
225
|
+
const code = await this.config.requestMfaCode();
|
|
226
|
+
if (!/^\d{6,8}$/.test(code))
|
|
227
|
+
throw new UnsupportedAuthenticationError("The MFA code must contain 6-8 digits.");
|
|
228
|
+
await input.fill(code);
|
|
229
|
+
const submit = await this.firstVisible(page, MFA_CODE_SUBMIT_SELECTORS);
|
|
230
|
+
if (submit)
|
|
231
|
+
await submit.click();
|
|
232
|
+
else
|
|
233
|
+
await input.press("Enter");
|
|
234
|
+
log("INFO", "Authenticator code submitted");
|
|
235
|
+
return true;
|
|
162
236
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
* button label can: it reads "Next" there and "Sign in" on the view that
|
|
169
|
-
* follows. Filling the password against the account-name page leaves the
|
|
170
|
-
* browser parked with both fields populated and nothing submitted.
|
|
171
|
-
*/
|
|
172
|
-
async submitAccountName(page) {
|
|
173
|
-
const submit = await this.findVisible(page, SELECTORS.formSubmit);
|
|
174
|
-
if (!submit)
|
|
175
|
-
return;
|
|
176
|
-
if (!ACCOUNT_NAME_BUTTON.test(await controlLabel(submit)))
|
|
177
|
-
return;
|
|
178
|
-
log("INFO", "Account-name page detected — submitting account name");
|
|
179
|
-
await submit.click();
|
|
180
|
-
// The sign-in view has arrived once the button stops saying "Next".
|
|
181
|
-
for (let attempt = 0; attempt < 30; attempt += 1) {
|
|
182
|
-
await page.waitForTimeout(500);
|
|
183
|
-
const current = await this.findVisible(page, SELECTORS.formSubmit);
|
|
184
|
-
if (current && !ACCOUNT_NAME_BUTTON.test(await controlLabel(current)))
|
|
185
|
-
return;
|
|
237
|
+
async firstVisible(page, selectors) {
|
|
238
|
+
for (const selector of selectors) {
|
|
239
|
+
const target = page.locator(selector).first();
|
|
240
|
+
if (await target.isVisible().catch(() => false))
|
|
241
|
+
return target;
|
|
186
242
|
}
|
|
187
|
-
|
|
243
|
+
return null;
|
|
188
244
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
// run alongside the wait rather than before or after it.
|
|
192
|
-
const pending = { done: false };
|
|
193
|
-
let release = () => { };
|
|
194
|
-
const released = new Promise((resolve) => {
|
|
195
|
-
release = resolve;
|
|
196
|
-
});
|
|
197
|
-
const watcher = this.watchNumberMatch(page, pending, released);
|
|
245
|
+
/** The login shell also exposes D2L.LP, so verify origin and home as well. */
|
|
246
|
+
async isAuthenticated(page) {
|
|
198
247
|
try {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
await page.
|
|
207
|
-
const
|
|
208
|
-
return
|
|
209
|
-
|
|
210
|
-
href.includes("/sso/") ||
|
|
211
|
-
href.includes("SAMLResponse");
|
|
212
|
-
}, { timeout: MFA_TIMEOUT_MS });
|
|
213
|
-
log("INFO", `MFA completed - redirected to: ${page.url()}`);
|
|
248
|
+
const expected = new URL(this.config.baseUrl);
|
|
249
|
+
const current = new URL(page.url());
|
|
250
|
+
if (current.origin !== expected.origin || !/^\/d2l\/home(?:\/|$)/.test(current.pathname))
|
|
251
|
+
return false;
|
|
252
|
+
const cookies = await page.context().cookies(expected.origin);
|
|
253
|
+
if (!cookies.some(cookie => cookie.name === "d2lSessionVal" && Boolean(cookie.value)))
|
|
254
|
+
return false;
|
|
255
|
+
return await page.evaluate(() => {
|
|
256
|
+
const d2l = window.D2L;
|
|
257
|
+
return Boolean(d2l?.LP);
|
|
258
|
+
});
|
|
214
259
|
}
|
|
215
|
-
catch
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
pending.done = true;
|
|
220
|
-
release();
|
|
221
|
-
await watcher;
|
|
260
|
+
catch {
|
|
261
|
+
// Redirects can replace the execution context. Keep polling; this
|
|
262
|
+
// verdict never causes credentials to be entered a second time.
|
|
263
|
+
return false;
|
|
222
264
|
}
|
|
223
265
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
if (number && number !== last) {
|
|
236
|
-
last = number;
|
|
237
|
-
log("WARN", `Number match: ${number}. Enter it in Microsoft Authenticator.`);
|
|
238
|
-
}
|
|
239
|
-
// Racing the release keeps the wait from outliving the MFA it watches.
|
|
240
|
-
await Promise.race([
|
|
241
|
-
page.waitForTimeout(NUMBER_MATCH_POLL_MS).catch(() => { }),
|
|
242
|
-
released,
|
|
243
|
-
]);
|
|
266
|
+
async clickProvenKmsi(page) {
|
|
267
|
+
if (new URL(page.url()).hostname !== "login.microsoftonline.com")
|
|
268
|
+
return;
|
|
269
|
+
const proven = await page.locator("#KmsiCheckboxField").first().isVisible().catch(() => false) ||
|
|
270
|
+
await page.getByText("Stay signed in?").first().isVisible().catch(() => false);
|
|
271
|
+
if (!proven)
|
|
272
|
+
return;
|
|
273
|
+
const yes = page.locator("#idSIButton9").first();
|
|
274
|
+
if (await yes.isVisible().catch(() => false)) {
|
|
275
|
+
await yes.click().catch(() => { });
|
|
276
|
+
log("DEBUG", 'Clicked Yes on "Stay signed in?"');
|
|
244
277
|
}
|
|
245
278
|
}
|
|
246
279
|
/** The digits on screen, or null when Entra is not showing any. */
|
|
@@ -251,22 +284,8 @@ export class PurdueSSOFlow {
|
|
|
251
284
|
if (!(await sign.isVisible().catch(() => false)))
|
|
252
285
|
return null;
|
|
253
286
|
const text = await sign.textContent().catch(() => null);
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
async handleStaySignedIn(page) {
|
|
257
|
-
try {
|
|
258
|
-
log("DEBUG", "Checking for 'Stay signed in?' prompt");
|
|
259
|
-
const staySignedInButton = await page.waitForSelector(SELECTORS.staySignedInYes, { timeout: 10000 });
|
|
260
|
-
if (staySignedInButton) {
|
|
261
|
-
log("INFO", "Clicking 'Yes' on 'Stay signed in?' prompt");
|
|
262
|
-
await staySignedInButton.click();
|
|
263
|
-
await page.waitForLoadState("networkidle");
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
catch (error) {
|
|
267
|
-
// Prompt may not appear - this is normal
|
|
268
|
-
log("DEBUG", "No 'Stay signed in?' prompt found (this is normal)");
|
|
269
|
-
}
|
|
287
|
+
const number = text?.trim();
|
|
288
|
+
return number && /^\d{1,3}$/.test(number) ? number : null;
|
|
270
289
|
}
|
|
271
290
|
}
|
|
272
291
|
//# sourceMappingURL=purdue-sso.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"purdue-sso.js","sourceRoot":"","sources":["../../src/auth/purdue-sso.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAEzC,MAAM,SAAS,GAAG;IAChB,aAAa,EAAE,gBAAgB;IAC/B,aAAa,EAAE,gBAAgB;IAC/B,YAAY,EAAE,iCAAiC;IAC/C,eAAe,EAAE,iCAAiC;IAClD,2EAA2E;IAC3E,yDAAyD;IACzD,UAAU,EAAE,0EAA0E;CAC9E,CAAC;AAEX,8EAA8E;AAC9E,gFAAgF;AAChF,MAAM,mBAAmB,GAAG,SAAS,CAAC;AAEtC;;;;;GAKG;AACH,MAAM,qBAAqB,GAAG,4BAA4B,CAAC;AAE3D,6DAA6D;AAC7D,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAElC,sEAAsE;AACtE,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAErC,gEAAgE;AAChE,KAAK,UAAU,YAAY,CACzB,MAA+C;IAE/C,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,CAC5B,CAAE,EAAuB,CAAC,KAAK,IAAI,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAChE,CAAC;AACJ,CAAC;AAOD,MAAM,OAAO,aAAa;IAChB,MAAM,CAAkB;IAEhC,YAAY,MAAuB;QACjC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/D,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,CAAC,IAAU;QACpB,IAAI,CAAC;YACH,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;YAEvC,qEAAqE;YACrE,MAAM,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;YAEtC,mEAAmE;YACnE,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;YAElC,yDAAyD;YACzD,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAE3B,0CAA0C;YAC1C,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;YAEpC,2DAA2D;YAC3D,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1D,GAAG,CAAC,MAAM,EAAE,6CAA6C,CAAC,CAAC;YAE3D,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,OAAO,EAAE,uBAAuB,EAAE,KAAK,CAAC,CAAC;YAC7C,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,WAAW,CAAC,IAAU;QAC1B,IAAI,CAAC;YACH,GAAG,CAAC,MAAM,EAAE,mDAAmD,CAAC,CAAC;YACjE,GAAG,CAAC,MAAM,EAAE,0DAA0D,CAAC,CAAC;YAExE,6EAA6E;YAC7E,MAAM,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;YAEtC,+DAA+D;YAC/D,GAAG,CAAC,MAAM,EAAE,8DAA8D,CAAC,CAAC;YAC5E,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1D,GAAG,CAAC,MAAM,EAAE,oDAAoD,CAAC,CAAC;YAElE,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,OAAO,EAAE,uCAAuC,EAAE,KAAK,CAAC,CAAC;YAC7D,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAAC,IAAU;QAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,IAAI,UAAU,CAAC,QAAQ,CAAC,wBAAwB,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACvF,sEAAsE;YACtE,gEAAgE;YAChE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC;YAC3C,GAAG,CAAC,MAAM,EAAE,kEAAkE,CAAC,CAAC;YAChF,MAAM,IAAI,CAAC,IAAI,CACb,GAAG,OAAO,iFAAiF,EAC3F,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,CAC7C,CAAC;QACJ,CAAC;QACD,wEAAwE;IAC1E,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,IAAU;QACvC,IAAI,CAAC;YACH,GAAG,CAAC,OAAO,EAAE,wBAAwB,CAAC,CAAC;YAEvC,mFAAmF;YACnF,iFAAiF;YACjF,MAAM,gBAAgB,GAAG,qDAAqD,CAAC;YAC/E,MAAM,IAAI,CAAC,eAAe,CAAC,gBAAgB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YAEjE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;gBAC1B,MAAM,IAAI,gBAAgB,CACxB,oCAAoC,EACpC,aAAa,CACd,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;gBAC1B,MAAM,IAAI,gBAAgB,CACxB,oCAAoC,EACpC,aAAa,CACd,CAAC;YACJ,CAAC;YAED,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;YACpC,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;YACrE,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACjD,CAAC;YAED,wEAAwE;YACxE,0EAA0E;YAC1E,uEAAuE;YACvE,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEnC,MAAM,gBAAgB,GAAG,wCAAwC,CAAC;YAClE,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;YACrE,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACjD,CAAC;YAED,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;YACxE,IAAI,YAAY,EAAE,CAAC;gBACjB,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,iDAAiD;gBACjD,MAAM,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YACtC,CAAC;YAED,MAAM,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,MAAM,EAAE,oEAAoE,EAAE,KAAK,CAAC,CAAC;YACzF,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACK,KAAK,CAAC,WAAW,CACvB,IAAU,EACV,QAAgB;QAEhB,KAAK,MAAM,MAAM,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7C,IAAI,MAAM,MAAM,CAAC,SAAS,EAAE;gBAAE,OAAO,MAAM,CAAC;QAC9C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACK,KAAK,CAAC,iBAAiB,CAAC,IAAU;QACxC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;QAClE,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;YAAE,OAAO;QAElE,GAAG,CAAC,MAAM,EAAE,sDAAsD,CAAC,CAAC;QACpE,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QAErB,oEAAoE;QACpE,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,EAAE,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;YAC/B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;YACnE,IAAI,OAAO,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;gBAAE,OAAO;QAChF,CAAC;QACD,GAAG,CAAC,MAAM,EAAE,+DAA+D,CAAC,CAAC;IAC/E,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,IAAU;QAChC,0EAA0E;QAC1E,yDAAyD;QACzD,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QAChC,IAAI,OAAO,GAAe,GAAG,EAAE,GAAE,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAC7C,OAAO,GAAG,OAAO,CAAC;QACpB,CAAC,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAE/D,IAAI,CAAC;YACH,GAAG,CAAC,MAAM,EAAE,sDAAsD,CAAC,CAAC;YACpE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;YAClC,GAAG,CAAC,MAAM,EAAE,oGAAoG,CAAC,CAAC;YAElH,+DAA+D;YAC/D,oEAAoE;YACpE,qEAAqE;YACrE,qEAAqE;YACrE,MAAM,IAAI,CAAC,UAAU,CACnB,CAAC,GAAG,EAAE,EAAE;gBACN,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;gBAC5B,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;oBACtB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;oBACrB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;oBACtB,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;YACvC,CAAC,EACD,EAAE,OAAO,EAAE,cAAc,EAAE,CAC5B,CAAC;YACF,GAAG,CAAC,MAAM,EAAE,kCAAkC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC9D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,gBAAgB,CACxB,wCAAwC,EACxC,cAAc,EACd,KAAc,CACf,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,OAAO,EAAE,CAAC;YACV,MAAM,OAAO,CAAC;QAChB,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACK,KAAK,CAAC,gBAAgB,CAC5B,IAAU,EACV,OAA0B,EAC1B,QAAuB;QAEvB,IAAI,IAAI,GAAkB,IAAI,CAAC;QAC/B,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACrB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YAChD,IAAI,MAAM,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBAC9B,IAAI,GAAG,MAAM,CAAC;gBACd,GAAG,CAAC,MAAM,EAAE,iBAAiB,MAAM,wCAAwC,CAAC,CAAC;YAC/E,CAAC;YACD,uEAAuE;YACvE,MAAM,OAAO,CAAC,IAAI,CAAC;gBACjB,IAAI,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;gBACzD,QAAQ;aACT,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,mEAAmE;IAC3D,KAAK,CAAC,eAAe,CAAC,IAAU;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,KAAK,EAAE,CAAC;QACzD,0EAA0E;QAC1E,wEAAwE;QACxE,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAC9D,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACxD,OAAO,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;IAC9B,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAC,IAAU;QACzC,IAAI,CAAC;YACH,GAAG,CAAC,OAAO,EAAE,uCAAuC,CAAC,CAAC;YACtD,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC,eAAe,CACnD,SAAS,CAAC,eAAe,EACzB,EAAE,OAAO,EAAE,KAAK,EAAE,CACnB,CAAC;YACF,IAAI,kBAAkB,EAAE,CAAC;gBACvB,GAAG,CAAC,MAAM,EAAE,4CAA4C,CAAC,CAAC;gBAC1D,MAAM,kBAAkB,CAAC,KAAK,EAAE,CAAC;gBACjC,MAAM,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,yCAAyC;YACzC,GAAG,CAAC,OAAO,EAAE,oDAAoD,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"purdue-sso.js","sourceRoot":"","sources":["../../src/auth/purdue-sso.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,50 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Brightspace MCP Server
|
|
3
3
|
* Copyright (c) 2026 Rohan Muppa. All rights reserved.
|
|
4
|
-
* Licensed under MIT
|
|
4
|
+
* Licensed under MIT. See LICENSE file for details.
|
|
5
5
|
*/
|
|
6
6
|
import type { TokenData } from "../types/index.js";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
* Uses AES-256-GCM for encryption with a key derived from username + hostname.
|
|
10
|
-
*/
|
|
7
|
+
import { type SecureStoreOptions } from "./encrypted-store.js";
|
|
8
|
+
/** AES-GCM session persistence with a random key held by the native secret store. */
|
|
11
9
|
export declare class SessionStore {
|
|
10
|
+
private readonly options;
|
|
12
11
|
private readonly sessionDir;
|
|
13
12
|
private readonly sessionFilePath;
|
|
14
|
-
constructor(sessionDir?: string);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
private
|
|
20
|
-
|
|
21
|
-
* Derive AES-256 key from username and hostname using scrypt.
|
|
22
|
-
* Uses a per-installation random salt to prevent precomputation attacks.
|
|
23
|
-
*/
|
|
24
|
-
private deriveKey;
|
|
25
|
-
/**
|
|
26
|
-
* Encrypt plaintext using AES-256-GCM.
|
|
27
|
-
* Returns IV, auth tag, and ciphertext as hex strings.
|
|
28
|
-
*/
|
|
29
|
-
private encrypt;
|
|
30
|
-
/**
|
|
31
|
-
* Decrypt ciphertext using AES-256-GCM.
|
|
32
|
-
* Returns plaintext string, or throws if auth tag verification fails.
|
|
33
|
-
*/
|
|
34
|
-
private decrypt;
|
|
35
|
-
/**
|
|
36
|
-
* Save token to disk with encryption.
|
|
37
|
-
* Creates session directory if it doesn't exist.
|
|
38
|
-
*/
|
|
13
|
+
constructor(sessionDir?: string, options?: SecureStoreOptions);
|
|
14
|
+
private withWriteLock;
|
|
15
|
+
private readFile;
|
|
16
|
+
private decode;
|
|
17
|
+
private loadUnlocked;
|
|
18
|
+
private saveUnlocked;
|
|
19
|
+
private storeError;
|
|
39
20
|
save(token: TokenData): Promise<void>;
|
|
40
|
-
/**
|
|
41
|
-
* Load token from disk with decryption.
|
|
42
|
-
* Returns null if file doesn't exist or is corrupted (graceful degradation).
|
|
43
|
-
*/
|
|
21
|
+
/** Missing files return null. Damaged or inaccessible secrets fail without MFA. */
|
|
44
22
|
load(): Promise<TokenData | null>;
|
|
45
|
-
/**
|
|
46
|
-
* Clear session by deleting the session file.
|
|
47
|
-
*/
|
|
48
23
|
clear(): Promise<void>;
|
|
24
|
+
/** Prevent a slow mint from replacing credentials saved by a newer login. */
|
|
25
|
+
saveIfCurrent(token: TokenData, expected: TokenData | null): Promise<boolean>;
|
|
26
|
+
clearIfCurrent(expected: TokenData): Promise<boolean>;
|
|
49
27
|
}
|
|
50
28
|
//# sourceMappingURL=session-store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../../src/auth/session-store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../../src/auth/session-store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,mBAAmB,CAAC;AAIhE,OAAO,EAAsF,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AA6BnJ,qFAAqF;AACrF,qBAAa,YAAY;IAIuB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHtE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;gBAE7B,UAAU,SAAsB,EAAmB,OAAO,GAAE,kBAAuB;YAKjF,aAAa;YAmBb,QAAQ;YASR,MAAM;YAyBN,YAAY;YAQZ,YAAY;IAK1B,OAAO,CAAC,UAAU;IAKZ,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAY3C,mFAAmF;IAC7E,IAAI,IAAI,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAWjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAa5B,6EAA6E;IACvE,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;IAY7E,cAAc,CAAC,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;CAW5D"}
|