@onenomad/engram-mcp 1.1.0 → 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.
@@ -1,217 +1,228 @@
1
- /**
2
- * Device-code login + logout against pyre-web.
3
- *
4
- * Flow:
5
- * 1. POST /api/auth/device-code → user_code, device_code, verification_url, expires_in, interval.
6
- * 2. Print the URL + code, best-effort open the browser.
7
- * 3. Poll /api/auth/device-code/poll until approved / denied / expired / timeout.
8
- * 4. On approval, write ~/.pyre/credentials.json. The api_url written
9
- * to disk is the server-returned canonical URL from the poll
10
- * response, NOT the one the user typed at login time. Server is
11
- * the source of truth -- it may normalise / redirect / hand back
12
- * a different storage endpoint than the login endpoint.
13
- *
14
- * No hardcoded URLs. The CLI requires the user to supply the server
15
- * URL at login (positional arg, --server flag, or PYRE_API_URL env).
16
- * Shipping prod is "users point at prod when they log in."
17
- *
18
- * Everything except the final success/failure line goes to stderr. The
19
- * URL + code block goes to stdout so a caller piping our output to a
20
- * file gets only the actionable bits.
21
- */
22
- import { hostname, platform } from 'node:os';
23
- import { spawn } from 'node:child_process';
24
- import { writeCredentials, deleteCredentials, credentialsPath } from './credentials.js';
25
- const PACKAGE_NAME = 'engram-memory';
26
- /**
27
- * Resolve a user-supplied server URL from CLI arg / flag / env, in
28
- * that precedence. Returns null when none of the three sources gave
29
- * us a URL — caller is expected to print the spec'd error message
30
- * and exit 1.
31
- */
32
- export function resolveServerUrl(opts) {
33
- const trim = (s) => {
34
- const t = s?.trim();
35
- if (!t)
36
- return null;
37
- return t.replace(/\/+$/, '');
38
- };
39
- return trim(opts.positional) ?? trim(opts.flag) ?? trim(process.env.PYRE_API_URL);
40
- }
41
- function sleepDefault(ms) {
42
- return new Promise(resolve => setTimeout(resolve, ms));
43
- }
44
- function openInBrowser(url) {
45
- try {
46
- const p = platform();
47
- if (p === 'darwin') {
48
- spawn('open', [url], { stdio: 'ignore', detached: true }).unref();
49
- }
50
- else if (p === 'win32') {
51
- // The empty title arg matters — `start <url>` treats the URL as the title.
52
- spawn('cmd', ['/c', 'start', '', url], { stdio: 'ignore', detached: true }).unref();
53
- }
54
- else {
55
- spawn('xdg-open', [url], { stdio: 'ignore', detached: true }).unref();
56
- }
57
- }
58
- catch {
59
- // Best-effort — the printed URL is always the fallback.
60
- }
61
- }
62
- async function postJson(fetchImpl, url, body) {
63
- const res = await fetchImpl(url, {
64
- method: 'POST',
65
- headers: { 'content-type': 'application/json', 'accept': 'application/json' },
66
- body: JSON.stringify(body),
67
- });
68
- const text = await res.text();
69
- let json = null;
70
- if (text.length > 0) {
71
- try {
72
- json = JSON.parse(text);
73
- }
74
- catch {
75
- // Fall through — non-JSON response is itself a failure to surface.
76
- throw new Error(`non-JSON response from ${url} (status ${res.status}): ${text.slice(0, 200)}`);
77
- }
78
- }
79
- return { status: res.status, json: json };
80
- }
81
- /**
82
- * Start a device-code pairing. Retries up to 3 times with 1s/2s/4s
83
- * backoff on transient network failures before giving up.
84
- */
85
- async function startDeviceCode(fetchImpl, apiUrl, deviceName, sleep) {
86
- const url = `${apiUrl}/api/auth/device-code`;
87
- const backoffs = [1000, 2000, 4000];
88
- let lastErr;
89
- for (let attempt = 0; attempt < backoffs.length; attempt++) {
90
- try {
91
- const { status, json } = await postJson(fetchImpl, url, { device_name: deviceName, package_name: PACKAGE_NAME });
92
- if (status >= 200 && status < 300) {
93
- if (!json.user_code || !json.device_code || !json.verification_url) {
94
- throw new Error(`malformed device-code response: ${JSON.stringify(json)}`);
95
- }
96
- return json;
97
- }
98
- throw new Error(`server returned HTTP ${status}${json?.error ? `: ${json.error}` : ''}`);
99
- }
100
- catch (err) {
101
- lastErr = err;
102
- if (attempt < backoffs.length - 1) {
103
- await sleep(backoffs[attempt]);
104
- }
105
- }
106
- }
107
- throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));
108
- }
109
- /**
110
- * Run the login flow end-to-end. Returns 0 on success, non-zero on
111
- * failure. Prints user-visible messages to stdout/stderr as documented
112
- * in the deliverable spec.
113
- */
114
- export async function runLogin(opts) {
115
- const apiUrl = opts.apiUrl.trim().replace(/\/+$/, '');
116
- const deviceName = opts.deviceName ?? hostname();
117
- const fetchImpl = opts.fetchImpl ?? fetch;
118
- const sleep = opts.sleep ?? sleepDefault;
119
- const now = opts.now ?? Date.now;
120
- const open = opts.openBrowser ?? openInBrowser;
121
- let start;
122
- try {
123
- start = await startDeviceCode(fetchImpl, apiUrl, deviceName, sleep);
124
- }
125
- catch (err) {
126
- process.stderr.write(`Could not reach ${apiUrl}: ${err.message}.\n`);
127
- return 1;
128
- }
129
- // The URL + code block — stdout, in one piece so it's easy to grab.
130
- process.stdout.write(`Open this URL in your browser to authorize:\n` +
131
- `\n` +
132
- ` ${start.verification_url}\n` +
133
- `\n` +
134
- `Enter this code when prompted: ${start.user_code}\n` +
135
- `(waiting for approval — Ctrl+C to cancel)\n`);
136
- open(start.verification_url);
137
- const intervalMs = Math.max(1, start.interval) * 1000;
138
- const expiresAt = now() + start.expires_in * 1000;
139
- const pollUrl = `${apiUrl}/api/auth/device-code/poll`;
140
- while (now() < expiresAt) {
141
- await sleep(intervalMs);
142
- if (now() >= expiresAt)
143
- break;
144
- let pollRes;
145
- try {
146
- pollRes = await postJson(fetchImpl, pollUrl, { device_code: start.device_code });
147
- }
148
- catch (err) {
149
- // Transient log to stderr and keep polling until expires_in
150
- // wins.
151
- process.stderr.write(`engram: poll error (will retry): ${err.message}\n`);
152
- continue;
153
- }
154
- // 410 carries `{ status: "expired" }` per the spec.
155
- if (pollRes.status === 410) {
156
- process.stderr.write(`Pairing code expired. Run \`engram-mcp login\` again.\n`);
157
- return 1;
158
- }
159
- if (pollRes.status < 200 || pollRes.status >= 300) {
160
- process.stderr.write(`engram: poll returned HTTP ${pollRes.status} (will retry)\n`);
161
- continue;
162
- }
163
- const body = pollRes.json;
164
- switch (body.status) {
165
- case 'pending':
166
- continue;
167
- case 'denied':
168
- process.stderr.write(`Authorization denied.\n`);
169
- return 1;
170
- case 'expired':
171
- process.stderr.write(`Pairing code expired. Run \`engram-mcp login\` again.\n`);
172
- return 1;
173
- case 'approved': {
174
- const creds = {
175
- api_url: body.api_url,
176
- api_key: body.api_key,
177
- label: body.label,
178
- scopes: body.scopes,
179
- issued_at: new Date().toISOString(),
180
- };
181
- try {
182
- writeCredentials(creds, opts.credentialsFile);
183
- }
184
- catch (err) {
185
- process.stderr.write(`engram: could not write credentials: ${err.message}\n`);
186
- return 1;
187
- }
188
- const where = opts.credentialsFile ?? '~/.pyre/credentials.json';
189
- process.stdout.write(`Logged in. Credentials saved to ${where}.\n`);
190
- return 0;
191
- }
192
- default:
193
- // Unknown status — keep polling. Defensive only; the type
194
- // union above is exhaustive against the documented API.
195
- continue;
196
- }
197
- }
198
- process.stderr.write(`Login timed out.\n`);
199
- return 1;
200
- }
201
- /**
202
- * Idempotent logout — exits 0 whether or not the file existed.
203
- */
204
- export function runLogout(opts = {}) {
205
- const removed = deleteCredentials(opts.credentialsFile);
206
- if (removed) {
207
- process.stdout.write(`Logged out.\n`);
208
- }
209
- else {
210
- process.stdout.write(`Already logged out.\n`);
211
- }
212
- return 0;
213
- }
214
- // Re-export so callers (cli.ts) can resolve the documented path string
215
- // for the success message.
216
- export { credentialsPath };
1
+ /**
2
+ * Device-code login + logout against pyre-web.
3
+ *
4
+ * Flow:
5
+ * 1. POST /api/auth/device-code → user_code, device_code, verification_url, expires_in, interval.
6
+ * 2. Print the URL + code, best-effort open the browser.
7
+ * 3. Poll /api/auth/device-code/poll until approved / denied / expired / timeout.
8
+ * 4. On approval, write ~/.pyre/credentials.json. The api_url written
9
+ * to disk is the server-returned canonical URL from the poll
10
+ * response, NOT the one the user typed at login time. Server is
11
+ * the source of truth -- it may normalise / redirect / hand back
12
+ * a different storage endpoint than the login endpoint.
13
+ *
14
+ * No hardcoded URLs. The CLI requires the user to supply the server
15
+ * URL at login (positional arg, --server flag, or PYRE_API_URL env).
16
+ * Shipping prod is "users point at prod when they log in."
17
+ *
18
+ * Everything except the final success/failure line goes to stderr. The
19
+ * URL + code block goes to stdout so a caller piping our output to a
20
+ * file gets only the actionable bits.
21
+ */
22
+ import { hostname, platform } from 'node:os';
23
+ import { spawn } from 'node:child_process';
24
+ import { writeCredentials, deleteCredentials, credentialsPath } from './credentials.js';
25
+ const PACKAGE_NAME = 'engram-memory';
26
+ /**
27
+ * Resolve a user-supplied server URL from CLI arg / flag / env, in
28
+ * that precedence. Returns null when none of the three sources gave
29
+ * us a URL — caller is expected to print the spec'd error message
30
+ * and exit 1.
31
+ */
32
+ export function resolveServerUrl(opts) {
33
+ const trim = (s) => {
34
+ const t = s?.trim();
35
+ if (!t)
36
+ return null;
37
+ return t.replace(/\/+$/, '');
38
+ };
39
+ return trim(opts.positional) ?? trim(opts.flag) ?? trim(process.env.PYRE_API_URL);
40
+ }
41
+ function sleepDefault(ms) {
42
+ return new Promise(resolve => setTimeout(resolve, ms));
43
+ }
44
+ function openInBrowser(url) {
45
+ try {
46
+ const p = platform();
47
+ if (p === 'darwin') {
48
+ spawn('open', [url], { stdio: 'ignore', detached: true }).unref();
49
+ }
50
+ else if (p === 'win32') {
51
+ // The empty title arg matters — `start <url>` treats the URL as the title.
52
+ spawn('cmd', ['/c', 'start', '', url], { stdio: 'ignore', detached: true }).unref();
53
+ }
54
+ else {
55
+ spawn('xdg-open', [url], { stdio: 'ignore', detached: true }).unref();
56
+ }
57
+ }
58
+ catch {
59
+ // Best-effort — the printed URL is always the fallback.
60
+ }
61
+ }
62
+ async function postJson(fetchImpl, url, body) {
63
+ const res = await fetchImpl(url, {
64
+ method: 'POST',
65
+ headers: { 'content-type': 'application/json', 'accept': 'application/json' },
66
+ body: JSON.stringify(body),
67
+ });
68
+ const text = await res.text();
69
+ let json = null;
70
+ if (text.length > 0) {
71
+ try {
72
+ json = JSON.parse(text);
73
+ }
74
+ catch {
75
+ // Fall through — non-JSON response is itself a failure to surface.
76
+ throw new Error(`non-JSON response from ${url} (status ${res.status}): ${text.slice(0, 200)}`);
77
+ }
78
+ }
79
+ return { status: res.status, json: json };
80
+ }
81
+ /**
82
+ * Start a device-code pairing. Retries up to 3 times with 1s/2s/4s
83
+ * backoff on transient network failures before giving up.
84
+ */
85
+ export async function startDeviceCode(fetchImpl, apiUrl, deviceName, sleep) {
86
+ const url = `${apiUrl}/api/auth/device-code`;
87
+ const backoffs = [1000, 2000, 4000];
88
+ let lastErr;
89
+ for (let attempt = 0; attempt < backoffs.length; attempt++) {
90
+ try {
91
+ const { status, json } = await postJson(fetchImpl, url, { device_name: deviceName, package_name: PACKAGE_NAME });
92
+ if (status >= 200 && status < 300) {
93
+ if (!json.user_code || !json.device_code || !json.verification_url) {
94
+ throw new Error(`malformed device-code response: ${JSON.stringify(json)}`);
95
+ }
96
+ return json;
97
+ }
98
+ throw new Error(`server returned HTTP ${status}${json?.error ? `: ${json.error}` : ''}`);
99
+ }
100
+ catch (err) {
101
+ lastErr = err;
102
+ if (attempt < backoffs.length - 1) {
103
+ await sleep(backoffs[attempt]);
104
+ }
105
+ }
106
+ }
107
+ throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));
108
+ }
109
+ /**
110
+ * Single poll of /api/auth/device-code/poll. Normalises HTTP 410 to
111
+ * the `expired` status the rest of the codebase already handles.
112
+ * Other non-2xx responses are surfaced as thrown errors so callers
113
+ * (CLI's loop, MCP tool) can decide whether to retry or give up.
114
+ */
115
+ export async function pollDeviceCode(fetchImpl, apiUrl, deviceCode) {
116
+ const pollUrl = `${apiUrl}/api/auth/device-code/poll`;
117
+ const res = await postJson(fetchImpl, pollUrl, { device_code: deviceCode });
118
+ if (res.status === 410)
119
+ return { status: 'expired' };
120
+ if (res.status < 200 || res.status >= 300) {
121
+ throw new Error(`poll returned HTTP ${res.status}`);
122
+ }
123
+ return res.json;
124
+ }
125
+ /**
126
+ * Build a Credentials object from an approved poll response. Centralises
127
+ * the shape used by both the CLI and the MCP tool path.
128
+ */
129
+ export function credentialsFromApproval(approved) {
130
+ return {
131
+ api_url: approved.api_url,
132
+ api_key: approved.api_key,
133
+ label: approved.label,
134
+ scopes: approved.scopes,
135
+ issued_at: new Date().toISOString(),
136
+ };
137
+ }
138
+ /**
139
+ * Run the login flow end-to-end. Returns 0 on success, non-zero on
140
+ * failure. Prints user-visible messages to stdout/stderr as documented
141
+ * in the deliverable spec.
142
+ */
143
+ export async function runLogin(opts) {
144
+ const apiUrl = opts.apiUrl.trim().replace(/\/+$/, '');
145
+ const deviceName = opts.deviceName ?? hostname();
146
+ const fetchImpl = opts.fetchImpl ?? fetch;
147
+ const sleep = opts.sleep ?? sleepDefault;
148
+ const now = opts.now ?? Date.now;
149
+ const open = opts.openBrowser ?? openInBrowser;
150
+ let start;
151
+ try {
152
+ start = await startDeviceCode(fetchImpl, apiUrl, deviceName, sleep);
153
+ }
154
+ catch (err) {
155
+ process.stderr.write(`Could not reach ${apiUrl}: ${err.message}.\n`);
156
+ return 1;
157
+ }
158
+ // The URL + code block — stdout, in one piece so it's easy to grab.
159
+ process.stdout.write(`Open this URL in your browser to authorize:\n` +
160
+ `\n` +
161
+ ` ${start.verification_url}\n` +
162
+ `\n` +
163
+ `Enter this code when prompted: ${start.user_code}\n` +
164
+ `(waiting for approval — Ctrl+C to cancel)\n`);
165
+ open(start.verification_url);
166
+ const intervalMs = Math.max(1, start.interval) * 1000;
167
+ const expiresAt = now() + start.expires_in * 1000;
168
+ while (now() < expiresAt) {
169
+ await sleep(intervalMs);
170
+ if (now() >= expiresAt)
171
+ break;
172
+ let body;
173
+ try {
174
+ body = await pollDeviceCode(fetchImpl, apiUrl, start.device_code);
175
+ }
176
+ catch (err) {
177
+ // Transient — log and keep polling until expires_in wins.
178
+ process.stderr.write(`engram: poll error (will retry): ${err.message}\n`);
179
+ continue;
180
+ }
181
+ switch (body.status) {
182
+ case 'pending':
183
+ continue;
184
+ case 'denied':
185
+ process.stderr.write(`Authorization denied.\n`);
186
+ return 1;
187
+ case 'expired':
188
+ process.stderr.write(`Pairing code expired. Run \`engram-mcp login\` again.\n`);
189
+ return 1;
190
+ case 'approved': {
191
+ const creds = credentialsFromApproval(body);
192
+ try {
193
+ writeCredentials(creds, opts.credentialsFile);
194
+ }
195
+ catch (err) {
196
+ process.stderr.write(`engram: could not write credentials: ${err.message}\n`);
197
+ return 1;
198
+ }
199
+ const where = opts.credentialsFile ?? '~/.pyre/credentials.json';
200
+ process.stdout.write(`Logged in. Credentials saved to ${where}.\n`);
201
+ return 0;
202
+ }
203
+ default:
204
+ // Unknown status keep polling. Defensive only; the type
205
+ // union above is exhaustive against the documented API.
206
+ continue;
207
+ }
208
+ }
209
+ process.stderr.write(`Login timed out.\n`);
210
+ return 1;
211
+ }
212
+ /**
213
+ * Idempotent logout — exits 0 whether or not the file existed.
214
+ */
215
+ export function runLogout(opts = {}) {
216
+ const removed = deleteCredentials(opts.credentialsFile);
217
+ if (removed) {
218
+ process.stdout.write(`Logged out.\n`);
219
+ }
220
+ else {
221
+ process.stdout.write(`Already logged out.\n`);
222
+ }
223
+ return 0;
224
+ }
225
+ // Re-export so callers (cli.ts) can resolve the documented path string
226
+ // for the success message.
227
+ export { credentialsPath };
217
228
  //# sourceMappingURL=login.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/auth/login.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,eAAe,EAAoB,MAAM,kBAAkB,CAAC;AAE1G,MAAM,YAAY,GAAG,eAAe,CAAC;AAwCrC;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAA4C;IAC3E,MAAM,IAAI,GAAG,CAAC,CAAqB,EAAiB,EAAE;QACpD,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC;QACpB,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACpB,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC/B,CAAC,CAAC;IACF,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AACpF,CAAC;AAED,SAAS,YAAY,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,aAAa,CAAC,GAAW;IAChC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;QACrB,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;YACnB,KAAK,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;QACpE,CAAC;aAAM,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC;YACzB,2EAA2E;YAC3E,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;QACtF,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;QACxE,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,wDAAwD;IAC1D,CAAC;AACH,CAAC;AAED,KAAK,UAAU,QAAQ,CACrB,SAAuB,EACvB,GAAW,EACX,IAAa;IAEb,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE;QAC/B,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,QAAQ,EAAE,kBAAkB,EAAE;QAC7E,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,IAAI,GAAY,IAAI,CAAC;IACzB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,IAAI,CAAC;YAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YACtC,mEAAmE;YACnE,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,YAAY,GAAG,CAAC,MAAM,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,IAAS,EAAE,CAAC;AACjD,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,eAAe,CAC5B,SAAuB,EACvB,MAAc,EACd,UAAkB,EAClB,KAAoC;IAEpC,MAAM,GAAG,GAAG,GAAG,MAAM,uBAAuB,CAAC;IAC7C,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACpC,IAAI,OAAgB,CAAC;IACrB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC;QAC3D,IAAI,CAAC;YACH,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,QAAQ,CACrC,SAAS,EACT,GAAG,EACH,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,CACxD,CAAC;YACF,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;gBAClC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACnE,MAAM,IAAI,KAAK,CAAC,mCAAmC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC7E,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,wBAAwB,MAAM,GAAG,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3F,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,GAAG,GAAG,CAAC;YACd,IAAI,OAAO,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAClC,MAAM,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,OAAO,YAAY,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;AACxE,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAkB;IAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,QAAQ,EAAE,CAAC;IACjD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC;IAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,YAAY,CAAC;IACzC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACjC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,IAAI,aAAa,CAAC;IAE/C,IAAI,KAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;IACtE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,MAAM,KAAM,GAAa,CAAC,OAAO,KAAK,CAAC,CAAC;QAChF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,oEAAoE;IACpE,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,+CAA+C;QAC/C,IAAI;QACJ,KAAK,KAAK,CAAC,gBAAgB,IAAI;QAC/B,IAAI;QACJ,kCAAkC,KAAK,CAAC,SAAS,IAAI;QACrD,6CAA6C,CAC9C,CAAC;IAEF,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAE7B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IACtD,MAAM,SAAS,GAAG,GAAG,EAAE,GAAG,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;IAClD,MAAM,OAAO,GAAG,GAAG,MAAM,4BAA4B,CAAC;IAEtD,OAAO,GAAG,EAAE,GAAG,SAAS,EAAE,CAAC;QACzB,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC;QACxB,IAAI,GAAG,EAAE,IAAI,SAAS;YAAE,MAAM;QAE9B,IAAI,OAAiD,CAAC;QACtD,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,QAAQ,CAAiB,SAAS,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QACnG,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,8DAA8D;YAC9D,QAAQ;YACR,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAqC,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;YACrF,SAAS;QACX,CAAC;QAED,oDAAoD;QACpD,IAAI,OAAO,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;YAChF,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;YAClD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,OAAO,CAAC,MAAM,iBAAiB,CAAC,CAAC;YACpF,SAAS;QACX,CAAC;QAED,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QAC1B,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;YACpB,KAAK,SAAS;gBACZ,SAAS;YACX,KAAK,QAAQ;gBACX,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;gBAChD,OAAO,CAAC,CAAC;YACX,KAAK,SAAS;gBACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;gBAChF,OAAO,CAAC,CAAC;YACX,KAAK,UAAU,CAAC,CAAC,CAAC;gBAChB,MAAM,KAAK,GAAgB;oBACzB,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACpC,CAAC;gBACF,IAAI,CAAC;oBACH,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;gBAChD,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAyC,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;oBACzF,OAAO,CAAC,CAAC;gBACX,CAAC;gBACD,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,IAAI,0BAA0B,CAAC;gBACjE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,KAAK,KAAK,CAAC,CAAC;gBACpE,OAAO,CAAC,CAAC;YACX,CAAC;YACD;gBACE,0DAA0D;gBAC1D,wDAAwD;gBACxD,SAAS;QACb,CAAC;IACH,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC3C,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,OAAqC,EAAE;IAC/D,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACxD,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACxC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,uEAAuE;AACvE,2BAA2B;AAC3B,OAAO,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/auth/login.ts"],"names":[],"mappings":"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"}