brightspace-mcp-server 1.6.3 → 2.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.
Files changed (92) hide show
  1. package/README.md +34 -7
  2. package/build/api/client.d.ts +5 -3
  3. package/build/api/client.d.ts.map +1 -1
  4. package/build/api/client.js +71 -79
  5. package/build/api/client.js.map +1 -1
  6. package/build/api/errors.d.ts +4 -0
  7. package/build/api/errors.d.ts.map +1 -1
  8. package/build/api/errors.js +7 -0
  9. package/build/api/errors.js.map +1 -1
  10. package/build/auth/auth-cooldown.d.ts +16 -0
  11. package/build/auth/auth-cooldown.d.ts.map +1 -0
  12. package/build/auth/auth-cooldown.js +47 -0
  13. package/build/auth/auth-cooldown.js.map +1 -0
  14. package/build/auth/auth-lock.d.ts +7 -0
  15. package/build/auth/auth-lock.d.ts.map +1 -0
  16. package/build/auth/auth-lock.js +114 -0
  17. package/build/auth/auth-lock.js.map +1 -0
  18. package/build/auth/auth-runner.d.ts +17 -7
  19. package/build/auth/auth-runner.d.ts.map +1 -1
  20. package/build/auth/auth-runner.js +122 -26
  21. package/build/auth/auth-runner.js.map +1 -1
  22. package/build/auth/browser-auth.d.ts +17 -86
  23. package/build/auth/browser-auth.d.ts.map +1 -1
  24. package/build/auth/browser-auth.js +256 -615
  25. package/build/auth/browser-auth.js.map +1 -1
  26. package/build/auth/browser-state-store.d.ts +19 -0
  27. package/build/auth/browser-state-store.d.ts.map +1 -0
  28. package/build/auth/browser-state-store.js +101 -0
  29. package/build/auth/browser-state-store.js.map +1 -0
  30. package/build/auth/credential-store.d.ts +29 -0
  31. package/build/auth/credential-store.d.ts.map +1 -0
  32. package/build/auth/credential-store.js +233 -0
  33. package/build/auth/credential-store.js.map +1 -0
  34. package/build/auth/encrypted-store.d.ts +25 -0
  35. package/build/auth/encrypted-store.d.ts.map +1 -0
  36. package/build/auth/encrypted-store.js +61 -0
  37. package/build/auth/encrypted-store.js.map +1 -0
  38. package/build/auth/legacy-profile.d.ts +3 -0
  39. package/build/auth/legacy-profile.d.ts.map +1 -0
  40. package/build/auth/legacy-profile.js +41 -0
  41. package/build/auth/legacy-profile.js.map +1 -0
  42. package/build/auth/legacy-state.d.ts +14 -0
  43. package/build/auth/legacy-state.d.ts.map +1 -0
  44. package/build/auth/legacy-state.js +107 -0
  45. package/build/auth/legacy-state.js.map +1 -0
  46. package/build/auth/purdue-sso.d.ts +18 -36
  47. package/build/auth/purdue-sso.d.ts.map +1 -1
  48. package/build/auth/purdue-sso.js +165 -192
  49. package/build/auth/purdue-sso.js.map +1 -1
  50. package/build/auth/session-store.d.ts +16 -38
  51. package/build/auth/session-store.d.ts.map +1 -1
  52. package/build/auth/session-store.js +157 -152
  53. package/build/auth/session-store.js.map +1 -1
  54. package/build/auth/sso-flow.d.ts +14 -3
  55. package/build/auth/sso-flow.d.ts.map +1 -1
  56. package/build/auth/sso-flow.js +16 -1
  57. package/build/auth/sso-flow.js.map +1 -1
  58. package/build/auth/suny-sso.d.ts +3 -2
  59. package/build/auth/suny-sso.d.ts.map +1 -1
  60. package/build/auth/suny-sso.js +15 -24
  61. package/build/auth/suny-sso.js.map +1 -1
  62. package/build/auth/token-manager.d.ts +10 -3
  63. package/build/auth/token-manager.d.ts.map +1 -1
  64. package/build/auth/token-manager.js +62 -26
  65. package/build/auth/token-manager.js.map +1 -1
  66. package/build/auth/token-mint.d.ts +2 -2
  67. package/build/auth/token-mint.d.ts.map +1 -1
  68. package/build/auth/token-mint.js +31 -9
  69. package/build/auth/token-mint.js.map +1 -1
  70. package/build/auth-cli.d.ts +1 -7
  71. package/build/auth-cli.d.ts.map +1 -1
  72. package/build/auth-cli.js +29 -73
  73. package/build/auth-cli.js.map +1 -1
  74. package/build/index.js +8 -4
  75. package/build/index.js.map +1 -1
  76. package/build/setup.js +14 -8
  77. package/build/setup.js.map +1 -1
  78. package/build/types/index.d.ts +6 -0
  79. package/build/types/index.d.ts.map +1 -1
  80. package/build/utils/config-store.d.ts +1 -0
  81. package/build/utils/config-store.d.ts.map +1 -1
  82. package/build/utils/config-store.js +3 -0
  83. package/build/utils/config-store.js.map +1 -1
  84. package/build/utils/config.d.ts +2 -1
  85. package/build/utils/config.d.ts.map +1 -1
  86. package/build/utils/config.js +30 -10
  87. package/build/utils/config.js.map +1 -1
  88. package/build/utils/secure-config.d.ts +6 -0
  89. package/build/utils/secure-config.d.ts.map +1 -0
  90. package/build/utils/secure-config.js +57 -0
  91. package/build/utils/secure-config.js.map +1 -0
  92. package/package.json +4 -2
package/README.md CHANGED
@@ -6,7 +6,7 @@ Talk to your Brightspace courses with AI. Ask about grades, due dates, quizzes,
6
6
 
7
7
  This is an [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that connects your AI to D2L Brightspace so it can pull your grades, assignments, syllabus, and course content on demand.
8
8
 
9
- Works with any school that uses D2L Brightspace, including Purdue, SUNY, USC, and hundreds more.
9
+ Connects to D2L Brightspace. Automatic login supports Purdue's Microsoft Entra flow and SUNY campus selection. Other schools need a compatible automated sign-in flow; unsupported login pages return an actionable error.
10
10
 
11
11
  <p align="center">
12
12
  <img src="https://raw.githubusercontent.com/RohanMuppa/brightspace-mcp-server/main/docs/how-it-works.svg" alt="Architecture diagram" width="100%">
@@ -19,7 +19,7 @@ Works with any school that uses D2L Brightspace, including Purdue, SUNY, USC, an
19
19
 
20
20
  ## Install
21
21
 
22
- **You need:** [Node.js 18+](https://nodejs.org/) (download the current LTS, 20 or newer)
22
+ **You need:** [Node.js 20+](https://nodejs.org/) and an available native credential store: macOS Keychain, Windows Credential Manager, or Linux Secret Service. Linux requires `secret-tool` and an unlocked desktop keyring. Install `libsecret-tools` on Debian/Ubuntu, or the package providing `secret-tool` on your distribution. A container or SSH session without Secret Service cannot persist authentication in v2.
23
23
 
24
24
  **Option 1: Let your AI do it**
25
25
 
@@ -50,7 +50,7 @@ you're at and skips SUNY's campus picker when you sign in:
50
50
  npx brightspace-mcp-server setup --suny
51
51
  ```
52
52
 
53
- The wizard walks you through login and MFA, auto configures Claude Desktop and Cursor, and prints the config to paste into ChatGPT Desktop if it is installed. Restart your AI client when it finishes.
53
+ The wizard saves your password in the native credential store and runs login in a headless browser. At Purdue, approve Microsoft Authenticator using the number printed in the terminal. No browser window opens. The wizard can configure Claude Desktop and Cursor. Restart your AI client when it finishes.
54
54
 
55
55
  Any other D2L school: run `setup` without a flag and paste your Brightspace URL (for example `https://yourschool.brightspace.com`).
56
56
 
@@ -71,13 +71,29 @@ You still need to run `npx brightspace-mcp-server setup` first to save your cred
71
71
 
72
72
  ## Session Expired?
73
73
 
74
- You should rarely see this. Access tokens are re-minted from your saved session cookie in the background, with no browser, in about 200 ms. A browser only opens when the Brightspace session itself has ended. How long that takes is set by your school, not by this tool, and it has not been measured over a long enough stretch to quote a number here. If the automatic re-login fails, run:
74
+ Returning the next day normally requires no action. The server renews short-lived API tokens over HTTPS using the saved Brightspace session. If that session ends, a headless browser restores your saved Microsoft session and tries silent SSO. If Microsoft requires sign-in, your saved credentials are entered automatically and you complete MFA on your phone.
75
+
76
+ Your school's policy controls when MFA is required. There is no local 24-hour cutoff, and the server no longer discards browser state after one hour. A network outage preserves the saved session and returns a temporary error.
77
+
78
+ If you miss an MFA request, automatic browser authentication waits four hours before trying again. Existing tokens and HTTP token renewal still work. Browser-based SSO also pauses because Microsoft can send another phone prompt during a redirect, even without a password submission. Run this command in a terminal to retry immediately and see the MFA number:
75
79
 
76
80
  ```bash
77
81
  npx brightspace-mcp-server auth
78
82
  ```
79
83
 
80
- **MFA at Purdue** is Microsoft Authenticator number matching: a two digit number appears in the browser and is also printed in the terminal. Enter it on your phone. Other schools may use Duo or their own app.
84
+ **MFA at Purdue** is Microsoft Authenticator number matching: enter the terminal-displayed number on your phone. The MCP also sends authentication progress as logging notifications to clients that display them. Some desktop clients hide server logs, so use the terminal command above if the number is not visible. Unsupported identity-provider pages require a supported sign-in handler; the server does not silently open a visible browser.
85
+
86
+ ## Upgrading to 2.0.0
87
+
88
+ - Restart existing MCP processes after upgrading. v1 and v2 should not authenticate simultaneously against the same session directory.
89
+ - Named accounts use separate directories below `~/.d2l-session/accounts/`, keyed by school and username. The first v2 login for a named account may require MFA because v1 browser state does not prove which username it belongs to. Switching accounts never replays another account's cookies.
90
+ - On first use, the server moves a v1 config password into the native credential store, verifies it, then removes it from `config.json`. Tokens and browser storage migrate to authenticated encryption using a new random key in that store.
91
+ - A locked or unavailable credential store stops migration and preserves existing files. Unlock it and retry. macOS may ask you to allow the Node executable to access Keychain.
92
+ - After migration, the old storage snapshot is moved to Trash. After successful browser authentication, the inactive `browser-data` profile is also moved to Trash. Those legacy copies remain recoverable there; existing `.corrupted.*` backups are not automatically removed.
93
+ - The server uses a fresh browser context for each authentication attempt. It saves only encrypted browser storage, with no permanent Chromium profile.
94
+ - Keep `D2L_SESSION_DIR` on this computer's local filesystem. Sharing it through NFS or a network drive is unsupported; its encryption key belongs to this operating-system account.
95
+ - `D2L_HEADLESS` remains recognized for compatibility; v2 authentication always runs headlessly. Environment-supplied passwords remain accepted as input and are saved in native secure storage. Remove old password values from your own `.env` or client configuration after migration.
96
+ - If you change your password, run `setup` again. If the encryption key was deleted, restore the native credential entry or use a new session directory and authenticate. Unreadable saved sessions are preserved rather than silently replaced.
81
97
 
82
98
  ## What You Can Ask About
83
99
 
@@ -96,8 +112,9 @@ npx brightspace-mcp-server auth
96
112
 
97
113
  ## Security
98
114
 
99
- - Your username and password stay on your machine in `~/.brightspace-mcp/config.json`, readable only by your user (mode 0600). They are typed into your school's real login page and nowhere else.
100
- - Session tokens and cookies live in `~/.d2l-session/`, encrypted with AES-256-GCM.
115
+ - Your school URL and username live in `~/.brightspace-mcp/config.json`. Your password lives in the native credential store. macOS and Windows use `@napi-rs/keyring`; Linux uses `secret-tool` directly to require Secret Service without a temporary kernel-key fallback. Linux secrets travel through stdin, never command-line arguments.
116
+ - Each account directory stores `session.json` for access tokens and `storage-state.encrypted.json` for cookies and browser storage. Both use AES-256-GCM with a random key held in the native credential store. The application never writes new plaintext password or browser-state snapshots. `D2L_SESSION_DIR` changes the local root of these account directories.
117
+ - On Unix, session files are mode 0600 and their directory is mode 0700. Security also depends on your operating-system account: software running as you may be able to access the same credential store. Runtime memory and recoverable v1 files in Trash are outside the encrypted-file guarantee.
101
118
  - All traffic to Brightspace is HTTPS.
102
119
  - On startup the server asks the npm registry whether a newer version exists. When running through `npx`, it clears this package's own stale npx cache directories so the next start downloads the new version. It never installs anything itself. Set `D2L_NO_UPDATE_CHECK=1` to turn the check off.
103
120
  - Read only: this server never submits, posts, or changes anything in Brightspace.
@@ -132,6 +149,16 @@ If you ever suspect you're on an old version (the auth banner prints the version
132
149
  npx clear-npx-cache
133
150
  ```
134
151
 
152
+ ## What's new in 2.0.0
153
+
154
+ - Headless saved-credential login and terminal MFA, with silent session reuse across restarts.
155
+ - Native secure credential storage and encrypted browser-state migration from v1.
156
+ - Removed the one-hour browser-state cutoff and destructive profile recovery.
157
+ - Process-level authentication coordination, failed-MFA cooldown, and transport errors that preserve your session.
158
+ - Publishing waits for the test matrix on macOS, Windows, and Linux.
159
+
160
+ Authentication recovery patterns were informed by [Brightspace Bar](https://github.com/DavidChen-006/Brightspace-Bar), distributed under the MIT license.
161
+
135
162
  ## What's new in 1.6.1
136
163
 
137
164
  - Your saved login now survives a network change. The session file was encrypted with a key derived from the machine hostname, which on campus wifi is a DHCP name that changes with the lease. When it changed, the saved session became unreadable and you were sent back through a full MFA login. Upgrading costs one final login, then it stops.
@@ -12,7 +12,7 @@ import type { D2LApiClientOptions, ApiVersions } from "./types.js";
12
12
  * - Supports both Bearer tokens and cookie-based auth (auto-detected via "cookie:" prefix)
13
13
  * - Client-side rate limiting using token bucket algorithm
14
14
  * - In-memory response caching with per-data-type TTLs
15
- * - 401 retry logic: retry once with fresh token, then clear and throw
15
+ * - 401 recovery: refresh the token before requesting browser authentication
16
16
  * - HTTPS-only enforcement
17
17
  * - Browser-like User-Agent for requests
18
18
  * - Raw response passthrough (no transformation)
@@ -61,6 +61,8 @@ export declare class D2LApiClient {
61
61
  * @throws NetworkError on network/fetch failures
62
62
  */
63
63
  getRaw(path: string): Promise<Response>;
64
+ /** One HTTP refresh and at most one browser login per caller. */
65
+ private withAuthentication;
64
66
  /** One rate limiter token per attempt. */
65
67
  private throttled;
66
68
  /** Retry 429, 5xx, and network failures. A 401 is never retried here. */
@@ -71,11 +73,11 @@ export declare class D2LApiClient {
71
73
  */
72
74
  private tryAutoReauth;
73
75
  /**
74
- * Internal method to make HTTP request with 401 retry logic.
76
+ * Make one HTTP request. Authentication recovery is shared with raw downloads.
75
77
  */
76
78
  private makeRequest;
77
79
  /**
78
- * Internal method to make HTTP request for raw binary data with 401 retry logic.
80
+ * Make one HTTP request for raw binary data.
79
81
  */
80
82
  private makeRawRequest;
81
83
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAwB,MAAM,YAAY,CAAC;AAezF;;;;;;;;;;;;GAYG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsC;IACnE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAyB;IACxD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAA4B;gBAEhC,OAAO,EAAE,mBAAmB;IAuCxC;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQjC;;;OAGG;IACH,IAAI,WAAW,IAAI,WAAW,CAO7B;IAED;;;;;;;;OAQG;IACG,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC;IA8BlE;;;;;;;;;OASG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAsB7C,0CAA0C;YAC5B,SAAS;IAKvB,yEAAyE;IACzE,OAAO,CAAC,QAAQ;IAQhB;;;OAGG;YACW,aAAa;IAgB3B;;OAEG;YACW,WAAW;IAyHzB;;OAEG;YACW,cAAc;IAuH5B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAoBxB;;;;OAIG;IACH,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAKxB;;;;;OAKG;IACH,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAK3C;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAK9B;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB;;OAEG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;CACF"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAwB,MAAM,YAAY,CAAC;AAqCzF;;;;;;;;;;;;GAYG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsC;IACnE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAyB;IACxD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAA4B;gBAEhC,OAAO,EAAE,mBAAmB;IAuCxC;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQjC;;;OAGG;IACH,IAAI,WAAW,IAAI,WAAW,CAO7B;IAED;;;;;;;;OAQG;IACG,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC;IAUlE;;;;;;;;;OASG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAI7C,iEAAiE;YACnD,kBAAkB;IA+BhC,0CAA0C;YAC5B,SAAS;IAKvB,yEAAyE;IACzE,OAAO,CAAC,QAAQ;IAQhB;;;OAGG;YACW,aAAa;IAgB3B;;OAEG;YACW,WAAW;IA6FzB;;OAEG;YACW,cAAc;IA2F5B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAoBxB;;;;OAIG;IACH,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAKxB;;;;;OAKG;IACH,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAK3C;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAK9B;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB;;OAEG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;CACF"}
@@ -10,11 +10,35 @@ import { discoverVersions } from "./version-discovery.js";
10
10
  import { ApiError, RateLimitError, NetworkError } from "./errors.js";
11
11
  import { withRetry, isRetryableFailure, retryAfterMsFrom } from "./retry.js";
12
12
  import { log } from "../utils/logger.js";
13
- /**
14
- * The marker in the HTML stub a dead session gets instead of a payload. D2L
15
- * answers HTTP 200 on that path, so the status alone cannot detect it.
16
- */
17
- const EXPIRED_SESSION_MARKER = "sessionExpired=1";
13
+ /** An ordinary course HTML link to the login page is not an expired session. */
14
+ function isExpiredSessionRedirect(body, baseUrl) {
15
+ const expiredTarget = (target) => {
16
+ try {
17
+ const url = new URL(target.replace(/&amp;/gi, "&").replace(/\\\//g, "/"), baseUrl);
18
+ return url.origin === new URL(baseUrl).origin && url.pathname === "/d2l/login" &&
19
+ url.searchParams.get("sessionExpired") === "1";
20
+ }
21
+ catch {
22
+ return false;
23
+ }
24
+ };
25
+ for (const script of body.matchAll(/<script\b[^>]*>([\s\S]*?)<\/script\s*>/gi)) {
26
+ const redirect = /(?:(?:window|document)\s*\.\s*)?location\s*(?:\.\s*(?:replace|assign)\s*\(\s*|(?:\.\s*href\s*)?=\s*)(["'])(.*?)\1/g;
27
+ for (const match of script[1].matchAll(redirect)) {
28
+ if (expiredTarget(match[2]))
29
+ return true;
30
+ }
31
+ }
32
+ for (const meta of body.matchAll(/<meta\b[^>]*>/gi)) {
33
+ const attributes = new Map([...meta[0].matchAll(/([\w-]+)\s*=\s*(["'])(.*?)\2/g)].map(match => [match[1].toLowerCase(), match[3]]));
34
+ if (attributes.get("http-equiv")?.toLowerCase() !== "refresh")
35
+ continue;
36
+ const target = attributes.get("content")?.match(/^\s*\d+(?:\.\d+)?\s*;\s*url\s*=\s*(.*?)\s*$/i)?.[1];
37
+ if (target && expiredTarget(target))
38
+ return true;
39
+ }
40
+ return false;
41
+ }
18
42
  /**
19
43
  * D2L API client with authentication, caching, rate limiting, and version discovery.
20
44
  *
@@ -23,7 +47,7 @@ const EXPIRED_SESSION_MARKER = "sessionExpired=1";
23
47
  * - Supports both Bearer tokens and cookie-based auth (auto-detected via "cookie:" prefix)
24
48
  * - Client-side rate limiting using token bucket algorithm
25
49
  * - In-memory response caching with per-data-type TTLs
26
- * - 401 retry logic: retry once with fresh token, then clear and throw
50
+ * - 401 recovery: refresh the token before requesting browser authentication
27
51
  * - HTTPS-only enforcement
28
52
  * - Browser-like User-Agent for requests
29
53
  * - Raw response passthrough (no transformation)
@@ -101,25 +125,7 @@ export class D2LApiClient {
101
125
  log("DEBUG", `Cache hit: ${path}`);
102
126
  return this.cache.get(path);
103
127
  }
104
- // Get authentication token, auto-reauth if expired
105
- let token = await this.tokenManager.getToken();
106
- if (!token) {
107
- token = await this.tryAutoReauth(path);
108
- }
109
- const authed = token;
110
- // Transient failures are retried inside the rate limiter, so every
111
- // attempt pays for a bucket token and a retry storm cannot bypass it.
112
- try {
113
- return await this.retrying(() => this.throttled(() => this.makeRequest(path, authed, options)));
114
- }
115
- catch (error) {
116
- if (error instanceof ApiError && error.status === 401) {
117
- // Final attempt: auto-reauth and retry once
118
- const freshToken = await this.tryAutoReauth(path);
119
- return await this.throttled(() => this.makeRequest(path, freshToken, options));
120
- }
121
- throw error;
122
- }
128
+ return this.withAuthentication(path, token => this.makeRequest(path, token, options));
123
129
  }
124
130
  /**
125
131
  * Make a GET request to the D2L API and return raw Response object.
@@ -132,23 +138,41 @@ export class D2LApiClient {
132
138
  * @throws NetworkError on network/fetch failures
133
139
  */
134
140
  async getRaw(path) {
135
- // Get authentication token, auto-reauth if expired
141
+ return this.withAuthentication(path, token => this.makeRawRequest(path, token));
142
+ }
143
+ /** One HTTP refresh and at most one browser login per caller. */
144
+ async withAuthentication(path, request) {
136
145
  let token = await this.tokenManager.getToken();
146
+ let authenticated = false;
137
147
  if (!token) {
138
148
  token = await this.tryAutoReauth(path);
149
+ authenticated = true;
139
150
  }
140
- const authed = token;
151
+ const send = (current) => this.retrying(() => this.throttled(() => request(current)));
141
152
  try {
142
- return await this.retrying(() => this.throttled(() => this.makeRawRequest(path, authed)));
153
+ return await send(token);
143
154
  }
144
155
  catch (error) {
145
- if (error instanceof ApiError && error.status === 401) {
146
- // Final attempt: auto-reauth and retry once
147
- const freshToken = await this.tryAutoReauth(path);
148
- return await this.throttled(() => this.makeRawRequest(path, freshToken));
156
+ if (!(error instanceof ApiError) || error.status !== 401)
157
+ throw error;
158
+ if (authenticated)
159
+ throw error;
160
+ }
161
+ // A rejected JWT does not prove its underlying cookie is expired. Read a
162
+ // token written by another process or mint over HTTP before opening login.
163
+ // TokenRefreshError propagates here, so a temporary outage never starts MFA.
164
+ const fresh = await this.tokenManager.getToken(token.accessToken);
165
+ if (fresh && fresh.accessToken !== token.accessToken) {
166
+ try {
167
+ return await send(fresh);
168
+ }
169
+ catch (error) {
170
+ if (!(error instanceof ApiError) || error.status !== 401)
171
+ throw error;
149
172
  }
150
- throw error;
151
173
  }
174
+ const loggedIn = await this.tryAutoReauth(path, fresh?.accessToken ?? token.accessToken);
175
+ return send(loggedIn);
152
176
  }
153
177
  /** One rate limiter token per attempt. */
154
178
  async throttled(fn) {
@@ -167,12 +191,12 @@ export class D2LApiClient {
167
191
  * Attempt auto-reauthentication via the onAuthExpired callback.
168
192
  * If successful, returns the fresh token. Otherwise throws 401 ApiError.
169
193
  */
170
- async tryAutoReauth(path) {
194
+ async tryAutoReauth(path, rejectedAccessToken) {
171
195
  if (this.onAuthExpired) {
172
196
  log("INFO", "Attempting auto-reauthentication...");
173
197
  const success = await this.onAuthExpired();
174
198
  if (success) {
175
- const freshToken = await this.tokenManager.getToken();
199
+ const freshToken = await this.tokenManager.getToken(rejectedAccessToken);
176
200
  if (freshToken) {
177
201
  log("INFO", "Auto-reauthentication succeeded, retrying request");
178
202
  return freshToken;
@@ -183,36 +207,21 @@ export class D2LApiClient {
183
207
  throw new ApiError(401, path, "Session expired. Please re-authenticate via brightspace-auth.");
184
208
  }
185
209
  /**
186
- * Internal method to make HTTP request with 401 retry logic.
210
+ * Make one HTTP request. Authentication recovery is shared with raw downloads.
187
211
  */
188
- async makeRequest(path, token, options, isRetry = false) {
212
+ async makeRequest(path, token, options) {
189
213
  const url = `${this.baseUrl}${path}`;
190
214
  const headers = this.buildAuthHeaders(token);
191
215
  try {
192
- log("DEBUG", `${isRetry ? "Retrying" : "Requesting"} GET ${path}`);
216
+ log("DEBUG", `Requesting GET ${path}`);
193
217
  const response = await fetch(url, {
194
218
  method: "GET",
195
219
  headers,
196
220
  signal: AbortSignal.timeout(this.timeoutMs),
197
221
  });
198
- // Handle 401 with retry logic
222
+ // Preserve cookie material: a 401 only rejects this access token.
199
223
  if (response.status === 401) {
200
- if (isRetry) {
201
- // Second 401 - clear token and throw
202
- log("DEBUG", "Second 401 response, clearing token");
203
- await this.tokenManager.clearToken();
204
- throw new ApiError(401, path, "Session expired. Please re-authenticate via brightspace-auth.");
205
- }
206
- // First 401 - try to get fresher token
207
- log("DEBUG", "First 401 response, attempting retry with fresh token");
208
- const freshToken = await this.tokenManager.getToken();
209
- if (!freshToken || freshToken.accessToken === token.accessToken) {
210
- // No fresher token available
211
- await this.tokenManager.clearToken();
212
- throw new ApiError(401, path, "Session expired. Please re-authenticate via brightspace-auth.");
213
- }
214
- // Retry with fresh token
215
- return await this.makeRequest(path, freshToken, options, true);
224
+ throw new ApiError(401, path, "Brightspace rejected the access token.");
216
225
  }
217
226
  // Handle 429 rate limiting
218
227
  if (response.status === 429) {
@@ -242,9 +251,8 @@ export class D2LApiClient {
242
251
  catch {
243
252
  // Only now consider the stub: a real payload that merely mentions the
244
253
  // marker still parses, so it can never be misread as a dead session.
245
- if (responseBody.includes(EXPIRED_SESSION_MARKER)) {
254
+ if (isExpiredSessionRedirect(responseBody, this.baseUrl)) {
246
255
  log("DEBUG", "Response carried the session-expired stub, treating it as a 401");
247
- await this.tokenManager.clearToken();
248
256
  throw new ApiError(401, path, "Session expired. Please re-authenticate via brightspace-auth.");
249
257
  }
250
258
  throw new ApiError(response.status, path, `Expected JSON from ${path} but the body did not parse`);
@@ -268,36 +276,21 @@ export class D2LApiClient {
268
276
  }
269
277
  }
270
278
  /**
271
- * Internal method to make HTTP request for raw binary data with 401 retry logic.
279
+ * Make one HTTP request for raw binary data.
272
280
  */
273
- async makeRawRequest(path, token, isRetry = false) {
281
+ async makeRawRequest(path, token) {
274
282
  const url = `${this.baseUrl}${path}`;
275
283
  const headers = this.buildAuthHeaders(token);
276
284
  try {
277
- log("DEBUG", `${isRetry ? "Retrying" : "Requesting"} GET ${path} (raw)`);
285
+ log("DEBUG", `Requesting GET ${path} (raw)`);
278
286
  const response = await fetch(url, {
279
287
  method: "GET",
280
288
  headers,
281
289
  signal: AbortSignal.timeout(this.timeoutMs),
282
290
  });
283
- // Handle 401 with retry logic
291
+ // Preserve cookie material for the shared HTTP refresh path.
284
292
  if (response.status === 401) {
285
- if (isRetry) {
286
- // Second 401 - clear token and throw
287
- log("DEBUG", "Second 401 response, clearing token");
288
- await this.tokenManager.clearToken();
289
- throw new ApiError(401, path, "Session expired. Please re-authenticate via brightspace-auth.");
290
- }
291
- // First 401 - try to get fresher token
292
- log("DEBUG", "First 401 response, attempting retry with fresh token");
293
- const freshToken = await this.tokenManager.getToken();
294
- if (!freshToken || freshToken.accessToken === token.accessToken) {
295
- // No fresher token available
296
- await this.tokenManager.clearToken();
297
- throw new ApiError(401, path, "Session expired. Please re-authenticate via brightspace-auth.");
298
- }
299
- // Retry with fresh token
300
- return await this.makeRawRequest(path, freshToken, true);
293
+ throw new ApiError(401, path, "Brightspace rejected the access token.");
301
294
  }
302
295
  // Handle 429 rate limiting
303
296
  if (response.status === 429) {
@@ -327,9 +320,8 @@ export class D2LApiClient {
327
320
  const contentType = (response.headers.get("content-type") ?? "").toLowerCase();
328
321
  if (contentType.startsWith("text/html")) {
329
322
  const body = await response.text();
330
- if (body.includes(EXPIRED_SESSION_MARKER)) {
323
+ if (isExpiredSessionRedirect(body, this.baseUrl)) {
331
324
  log("DEBUG", "File download answered with the session-expired stub, treating it as a 401");
332
- await this.tokenManager.clearToken();
333
325
  throw new ApiError(401, path, "Session expired. Please re-authenticate via brightspace-auth.");
334
326
  }
335
327
  // A legitimate HTML page: hand back an equivalent response with the
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
@@ -20,4 +20,8 @@ export declare class RateLimitError extends ApiError {
20
20
  export declare class NetworkError extends AuthError {
21
21
  constructor(message: string, cause?: Error);
22
22
  }
23
+ /** A temporary token-mint failure must never start browser authentication. */
24
+ export declare class TokenRefreshError extends NetworkError {
25
+ constructor(detail: string, cause?: Error);
26
+ }
23
27
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/api/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,qBAAa,QAAS,SAAQ,SAAS;aAEnB,MAAM,EAAE,MAAM;aACd,QAAQ,EAAE,MAAM;aAEhB,YAAY,CAAC,EAAE,MAAM;gBAHrB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChC,OAAO,EAAE,MAAM,EACC,YAAY,CAAC,EAAE,MAAM,YAAA,EACrC,KAAK,CAAC,EAAE,KAAK;CAKhB;AAGD,qBAAa,SAAU,SAAQ,QAAQ;gBAEnC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,EACrB,KAAK,CAAC,EAAE,KAAK;CAKhB;AAGD,qBAAa,cAAe,SAAQ,QAAQ;aAGxB,UAAU,CAAC,EAAE,MAAM;gBADnC,QAAQ,EAAE,MAAM,EACA,UAAU,CAAC,EAAE,MAAM,YAAA;CAQtC;AAID,qBAAa,YAAa,SAAQ,SAAS;gBAC7B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAI3C"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/api/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,qBAAa,QAAS,SAAQ,SAAS;aAEnB,MAAM,EAAE,MAAM;aACd,QAAQ,EAAE,MAAM;aAEhB,YAAY,CAAC,EAAE,MAAM;gBAHrB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChC,OAAO,EAAE,MAAM,EACC,YAAY,CAAC,EAAE,MAAM,YAAA,EACrC,KAAK,CAAC,EAAE,KAAK;CAKhB;AAGD,qBAAa,SAAU,SAAQ,QAAQ;gBAEnC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,EACrB,KAAK,CAAC,EAAE,KAAK;CAKhB;AAGD,qBAAa,cAAe,SAAQ,QAAQ;aAGxB,UAAU,CAAC,EAAE,MAAM;gBADnC,QAAQ,EAAE,MAAM,EACA,UAAU,CAAC,EAAE,MAAM,YAAA;CAQtC;AAID,qBAAa,YAAa,SAAQ,SAAS;gBAC7B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAI3C;AAED,8EAA8E;AAC9E,qBAAa,iBAAkB,SAAQ,YAAY;gBACrC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAI1C"}
@@ -44,4 +44,11 @@ export class NetworkError extends AuthError {
44
44
  this.name = "NetworkError";
45
45
  }
46
46
  }
47
+ /** A temporary token-mint failure must never start browser authentication. */
48
+ export class TokenRefreshError extends NetworkError {
49
+ constructor(detail, cause) {
50
+ super(`Token refresh is temporarily unavailable: ${detail}. Your saved session was retained. Try again later.`, cause);
51
+ this.name = "TokenRefreshError";
52
+ }
53
+ }
47
54
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/api/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,qCAAqC;AACrC,MAAM,OAAO,QAAS,SAAQ,SAAS;IAEnB;IACA;IAEA;IAJlB,YACkB,MAAc,EACd,QAAgB,EAChC,OAAe,EACC,YAAqB,EACrC,KAAa;QAEb,KAAK,CAAC,2BAA2B,MAAM,QAAQ,QAAQ,KAAK,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;QAN9D,WAAM,GAAN,MAAM,CAAQ;QACd,aAAQ,GAAR,QAAQ,CAAQ;QAEhB,iBAAY,GAAZ,YAAY,CAAS;QAIrC,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF;AAED,iEAAiE;AACjE,MAAM,OAAO,SAAU,SAAQ,QAAQ;IACrC,YACE,MAAc,EACd,QAAgB,EAChB,OAAe,EACf,YAAqB,EACrB,KAAa;QAEb,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;QACtD,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,2CAA2C;AAC3C,MAAM,OAAO,cAAe,SAAQ,QAAQ;IAGxB;IAFlB,YACE,QAAgB,EACA,UAAmB;QAEnC,MAAM,OAAO,GAAG,UAAU;YACxB,CAAC,CAAC,0CAA0C,UAAU,GAAG;YACzD,CAAC,CAAC,2BAA2B,CAAC;QAChC,KAAK,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QALd,eAAU,GAAV,UAAU,CAAS;QAMnC,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,4CAA4C;AAC5C,2CAA2C;AAC3C,MAAM,OAAO,YAAa,SAAQ,SAAS;IACzC,YAAY,OAAe,EAAE,KAAa;QACxC,KAAK,CAAC,+BAA+B,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;QACvD,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/api/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,qCAAqC;AACrC,MAAM,OAAO,QAAS,SAAQ,SAAS;IAEnB;IACA;IAEA;IAJlB,YACkB,MAAc,EACd,QAAgB,EAChC,OAAe,EACC,YAAqB,EACrC,KAAa;QAEb,KAAK,CAAC,2BAA2B,MAAM,QAAQ,QAAQ,KAAK,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;QAN9D,WAAM,GAAN,MAAM,CAAQ;QACd,aAAQ,GAAR,QAAQ,CAAQ;QAEhB,iBAAY,GAAZ,YAAY,CAAS;QAIrC,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF;AAED,iEAAiE;AACjE,MAAM,OAAO,SAAU,SAAQ,QAAQ;IACrC,YACE,MAAc,EACd,QAAgB,EAChB,OAAe,EACf,YAAqB,EACrB,KAAa;QAEb,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;QACtD,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,2CAA2C;AAC3C,MAAM,OAAO,cAAe,SAAQ,QAAQ;IAGxB;IAFlB,YACE,QAAgB,EACA,UAAmB;QAEnC,MAAM,OAAO,GAAG,UAAU;YACxB,CAAC,CAAC,0CAA0C,UAAU,GAAG;YACzD,CAAC,CAAC,2BAA2B,CAAC;QAChC,KAAK,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QALd,eAAU,GAAV,UAAU,CAAS;QAMnC,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,4CAA4C;AAC5C,2CAA2C;AAC3C,MAAM,OAAO,YAAa,SAAQ,SAAS;IACzC,YAAY,OAAe,EAAE,KAAa;QACxC,KAAK,CAAC,+BAA+B,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;QACvD,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED,8EAA8E;AAC9E,MAAM,OAAO,iBAAkB,SAAQ,YAAY;IACjD,YAAY,MAAc,EAAE,KAAa;QACvC,KAAK,CAAC,6CAA6C,MAAM,qDAAqD,EAAE,KAAK,CAAC,CAAC;QACvH,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ export declare const MFA_COOLDOWN_MS: number;
2
+ export declare class AuthenticationCooldownError extends Error {
3
+ readonly retryAt: number;
4
+ readonly code = "AUTH_COOLDOWN";
5
+ constructor(retryAt: number);
6
+ }
7
+ /** Non-secret retry metadata. Call only while holding the authentication lock. */
8
+ export declare class AuthCooldown {
9
+ private readonly file;
10
+ constructor(sessionDir: string);
11
+ assertAllowed(): Promise<void>;
12
+ recordMfaFailure(): Promise<void>;
13
+ clear(): Promise<void>;
14
+ private write;
15
+ }
16
+ //# sourceMappingURL=auth-cooldown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-cooldown.d.ts","sourceRoot":"","sources":["../../src/auth/auth-cooldown.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,QAAqB,CAAC;AAElD,qBAAa,2BAA4B,SAAQ,KAAK;aAExB,OAAO,EAAE,MAAM;IAD3C,QAAQ,CAAC,IAAI,mBAAmB;gBACJ,OAAO,EAAE,MAAM;CAI5C;AAED,kFAAkF;AAClF,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;gBAClB,UAAU,EAAE,MAAM;IAIxB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAY9B,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAId,KAAK;CAMpB"}
@@ -0,0 +1,47 @@
1
+ import * as fs from "node:fs/promises";
2
+ import * as path from "node:path";
3
+ import { randomUUID } from "node:crypto";
4
+ export const MFA_COOLDOWN_MS = 4 * 60 * 60 * 1000;
5
+ export class AuthenticationCooldownError extends Error {
6
+ retryAt;
7
+ code = "AUTH_COOLDOWN";
8
+ constructor(retryAt) {
9
+ super(`A previous MFA attempt failed. Automatic login resumes at ${new Date(retryAt).toISOString()}. Run brightspace-auth to retry now.`);
10
+ this.retryAt = retryAt;
11
+ this.name = "AuthenticationCooldownError";
12
+ }
13
+ }
14
+ /** Non-secret retry metadata. Call only while holding the authentication lock. */
15
+ export class AuthCooldown {
16
+ file;
17
+ constructor(sessionDir) {
18
+ this.file = path.join(sessionDir, "auth-status.json");
19
+ }
20
+ async assertAllowed() {
21
+ let content;
22
+ try {
23
+ content = await fs.readFile(this.file, "utf8");
24
+ }
25
+ catch (error) {
26
+ if (error.code === "ENOENT")
27
+ return;
28
+ throw error;
29
+ }
30
+ const status = JSON.parse(content);
31
+ if (typeof status.retryAt === "number" && status.retryAt > Date.now())
32
+ throw new AuthenticationCooldownError(status.retryAt);
33
+ }
34
+ async recordMfaFailure() {
35
+ await this.write({ retryAt: Date.now() + MFA_COOLDOWN_MS });
36
+ }
37
+ async clear() {
38
+ await this.write({ retryAt: 0 });
39
+ }
40
+ async write(status) {
41
+ await fs.mkdir(path.dirname(this.file), { recursive: true, mode: 0o700 });
42
+ const temporary = `${this.file}.${randomUUID()}.tmp`;
43
+ await fs.writeFile(temporary, JSON.stringify(status), { mode: 0o600, flag: "wx" });
44
+ await fs.rename(temporary, this.file);
45
+ }
46
+ }
47
+ //# sourceMappingURL=auth-cooldown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-cooldown.js","sourceRoot":"","sources":["../../src/auth/auth-cooldown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAElD,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IAExB;IADnB,IAAI,GAAG,eAAe,CAAC;IAChC,YAA4B,OAAe;QACzC,KAAK,CAAC,6DAA6D,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,sCAAsC,CAAC,CAAC;QADhH,YAAO,GAAP,OAAO,CAAQ;QAEzC,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC;IAC5C,CAAC;CACF;AAED,kFAAkF;AAClF,MAAM,OAAO,YAAY;IACN,IAAI,CAAS;IAC9B,YAAY,UAAkB;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,IAAI,OAAe,CAAC;QACpB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO;YAC/D,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAyB,CAAC;QAC3D,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE;YAAE,MAAM,IAAI,2BAA2B,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/H,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,eAAe,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IACnC,CAAC;IAEO,KAAK,CAAC,KAAK,CAAC,MAA2B;QAC7C,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1E,MAAM,SAAS,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,UAAU,EAAE,MAAM,CAAC;QACrD,MAAM,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACnF,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ export declare class AuthenticationInProgressError extends Error {
2
+ readonly code = "AUTH_IN_PROGRESS";
3
+ constructor();
4
+ }
5
+ /** Acquire a process-shared lock without waiting or relying on its age. */
6
+ export declare function acquireProcessLock(lockPath: string): Promise<() => Promise<void>>;
7
+ //# sourceMappingURL=auth-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-lock.d.ts","sourceRoot":"","sources":["../../src/auth/auth-lock.ts"],"names":[],"mappings":"AAKA,qBAAa,6BAA8B,SAAQ,KAAK;IACtD,QAAQ,CAAC,IAAI,sBAAsB;;CAKpC;AAoDD,2EAA2E;AAC3E,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAIvF"}