@pocketcoder/host 0.0.7 → 0.0.8

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 +1 @@
1
- {"version":3,"file":"oauth-server.d.ts","sourceRoot":"","sources":["../../src/auth/oauth-server.ts"],"names":[],"mappings":"AA2hBA,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,eAAe,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACpD,yDAAyD;IACzD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,WAAW,CAAC,CAsH7D"}
1
+ {"version":3,"file":"oauth-server.d.ts","sourceRoot":"","sources":["../../src/auth/oauth-server.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,eAAe,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACpD,yDAAyD;IACzD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,WAAW,CAAC,CAyH7D"}
@@ -1,534 +1,7 @@
1
1
  import { createServer } from "node:http";
2
+ import { SUCCESS_HTML, ERROR_HTML, FRAGMENT_EXTRACTOR_HTML } from "./templates/index.js";
2
3
  /** Timeout for waiting for the OAuth callback (5 minutes). */
3
4
  const OAUTH_TIMEOUT_MS = 5 * 60 * 1000;
4
- const SUCCESS_HTML = `<!DOCTYPE html>
5
- <html lang="en">
6
- <head>
7
- <meta charset="UTF-8">
8
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
9
- <title>PocketCoder - Success</title>
10
- <link rel="preconnect" href="https://fonts.googleapis.com">
11
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
12
- <link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=Inter:wght@600;700&display=swap" rel="stylesheet">
13
- <style>
14
- :root {
15
- --bg-primary: #000000;
16
- --text-primary: #ffffff;
17
- --text-secondary: #a1a1a6;
18
- --accent: #c9a87c;
19
- --success: #34c759;
20
- }
21
- * { margin: 0; padding: 0; box-sizing: border-box; }
22
- html, body {
23
- height: 100%;
24
- font-family: "DM Sans", -apple-system, BlinkMacSystemFont, sans-serif;
25
- background: var(--bg-primary);
26
- color: var(--text-primary);
27
- -webkit-font-smoothing: antialiased;
28
- }
29
- .container {
30
- display: flex;
31
- flex-direction: column;
32
- align-items: center;
33
- justify-content: center;
34
- min-height: 100vh;
35
- padding: 24px;
36
- position: relative;
37
- overflow: hidden;
38
- }
39
- .stars, .stars-near {
40
- position: absolute;
41
- top: 0; left: 0;
42
- width: 100%; height: 100%;
43
- pointer-events: none;
44
- }
45
- .stars::before {
46
- content: "";
47
- position: absolute;
48
- top: 30%; left: 50%;
49
- width: 2px; height: 2px;
50
- background: transparent;
51
- border-radius: 50%;
52
- box-shadow:
53
- -180px -120px 0 0 rgba(186, 85, 211, 0.6),
54
- 160px -100px 0 0 rgba(135, 206, 250, 0.65),
55
- -220px 80px 0 0 rgba(255, 182, 193, 0.6),
56
- 200px 120px 0 0 rgba(255, 160, 122, 0.55),
57
- -120px 180px 0 0 rgba(147, 112, 219, 0.65),
58
- 140px 200px 0 0 rgba(135, 206, 250, 0.6),
59
- -280px -60px 0 0 rgba(255, 182, 193, 0.55),
60
- 260px -80px 0 0 rgba(186, 85, 211, 0.65),
61
- -160px -200px 0 0 rgba(255, 160, 122, 0.6),
62
- 180px -180px 0 0 rgba(147, 112, 219, 0.55);
63
- animation: twinkle 3.5s ease-in-out infinite;
64
- }
65
- .stars-near::before {
66
- content: "";
67
- position: absolute;
68
- top: 30%; left: 50%;
69
- width: 2px; height: 2px;
70
- background: transparent;
71
- border-radius: 50%;
72
- box-shadow:
73
- -80px -60px 0 0 rgba(186, 85, 211, 0.9),
74
- 70px -50px 0 1px rgba(255, 160, 122, 1),
75
- -90px 40px 0 0 rgba(135, 206, 250, 0.85),
76
- 85px 55px 0 1px rgba(255, 182, 193, 0.9),
77
- -50px 80px 0 0 rgba(147, 112, 219, 0.95),
78
- 60px 90px 0 1px rgba(186, 85, 211, 0.85),
79
- -110px -30px 0 0 rgba(255, 160, 122, 0.9),
80
- 105px -35px 0 1px rgba(135, 206, 250, 0.95);
81
- animation: twinkle 2s ease-in-out infinite;
82
- }
83
- @keyframes twinkle {
84
- 0%, 100% { opacity: 1; }
85
- 50% { opacity: 0.6; }
86
- }
87
- .content {
88
- text-align: center;
89
- position: relative;
90
- z-index: 10;
91
- }
92
- .icon-wrapper {
93
- width: 80px; height: 80px;
94
- margin: 0 auto 24px;
95
- position: relative;
96
- display: flex;
97
- align-items: center;
98
- justify-content: center;
99
- }
100
- .icon-glow {
101
- position: absolute;
102
- width: 100%; height: 100%;
103
- border-radius: 50%;
104
- background: radial-gradient(circle, rgba(52, 199, 89, 0.4) 0%, transparent 70%);
105
- animation: iconGlow 2s ease-in-out infinite;
106
- }
107
- @keyframes iconGlow {
108
- 0%, 100% { transform: scale(1); opacity: 0.8; }
109
- 50% { transform: scale(1.2); opacity: 1; }
110
- }
111
- .icon {
112
- width: 48px; height: 48px;
113
- color: var(--success);
114
- position: relative;
115
- z-index: 1;
116
- }
117
- .app-name {
118
- font-family: "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
119
- font-size: 24px;
120
- font-weight: 700;
121
- letter-spacing: -0.5px;
122
- margin-bottom: 8px;
123
- }
124
- .title {
125
- font-size: 20px;
126
- font-weight: 600;
127
- margin-bottom: 8px;
128
- color: var(--success);
129
- }
130
- .subtitle {
131
- font-size: 16px;
132
- color: var(--text-secondary);
133
- }
134
- </style>
135
- </head>
136
- <body>
137
- <div class="container">
138
- <div class="stars"></div>
139
- <div class="stars-near"></div>
140
- <div class="content">
141
- <div class="icon-wrapper">
142
- <div class="icon-glow"></div>
143
- <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
144
- <polyline points="20 6 9 17 4 12"></polyline>
145
- </svg>
146
- </div>
147
- <h1 class="app-name">PocketCoder</h1>
148
- <p class="title">Authentication successful!</p>
149
- <p class="subtitle">You can close this window.</p>
150
- </div>
151
- </div>
152
- </body>
153
- </html>`;
154
- const ERROR_HTML = `<!DOCTYPE html>
155
- <html lang="en">
156
- <head>
157
- <meta charset="UTF-8">
158
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
159
- <title>PocketCoder - Error</title>
160
- <link rel="preconnect" href="https://fonts.googleapis.com">
161
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
162
- <link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=Inter:wght@600;700&display=swap" rel="stylesheet">
163
- <style>
164
- :root {
165
- --bg-primary: #000000;
166
- --text-primary: #ffffff;
167
- --text-secondary: #a1a1a6;
168
- --error: #ff3b30;
169
- }
170
- * { margin: 0; padding: 0; box-sizing: border-box; }
171
- html, body {
172
- height: 100%;
173
- font-family: "DM Sans", -apple-system, BlinkMacSystemFont, sans-serif;
174
- background: var(--bg-primary);
175
- color: var(--text-primary);
176
- -webkit-font-smoothing: antialiased;
177
- }
178
- .container {
179
- display: flex;
180
- flex-direction: column;
181
- align-items: center;
182
- justify-content: center;
183
- min-height: 100vh;
184
- padding: 24px;
185
- position: relative;
186
- overflow: hidden;
187
- }
188
- .stars, .stars-near {
189
- position: absolute;
190
- top: 0; left: 0;
191
- width: 100%; height: 100%;
192
- pointer-events: none;
193
- }
194
- .stars::before {
195
- content: "";
196
- position: absolute;
197
- top: 30%; left: 50%;
198
- width: 2px; height: 2px;
199
- background: transparent;
200
- border-radius: 50%;
201
- box-shadow:
202
- -180px -120px 0 0 rgba(186, 85, 211, 0.6),
203
- 160px -100px 0 0 rgba(135, 206, 250, 0.65),
204
- -220px 80px 0 0 rgba(255, 182, 193, 0.6),
205
- 200px 120px 0 0 rgba(255, 160, 122, 0.55),
206
- -120px 180px 0 0 rgba(147, 112, 219, 0.65),
207
- 140px 200px 0 0 rgba(135, 206, 250, 0.6),
208
- -280px -60px 0 0 rgba(255, 182, 193, 0.55),
209
- 260px -80px 0 0 rgba(186, 85, 211, 0.65),
210
- -160px -200px 0 0 rgba(255, 160, 122, 0.6),
211
- 180px -180px 0 0 rgba(147, 112, 219, 0.55);
212
- animation: twinkle 3.5s ease-in-out infinite;
213
- }
214
- .stars-near::before {
215
- content: "";
216
- position: absolute;
217
- top: 30%; left: 50%;
218
- width: 2px; height: 2px;
219
- background: transparent;
220
- border-radius: 50%;
221
- box-shadow:
222
- -80px -60px 0 0 rgba(186, 85, 211, 0.9),
223
- 70px -50px 0 1px rgba(255, 160, 122, 1),
224
- -90px 40px 0 0 rgba(135, 206, 250, 0.85),
225
- 85px 55px 0 1px rgba(255, 182, 193, 0.9),
226
- -50px 80px 0 0 rgba(147, 112, 219, 0.95),
227
- 60px 90px 0 1px rgba(186, 85, 211, 0.85),
228
- -110px -30px 0 0 rgba(255, 160, 122, 0.9),
229
- 105px -35px 0 1px rgba(135, 206, 250, 0.95);
230
- animation: twinkle 2s ease-in-out infinite;
231
- }
232
- @keyframes twinkle {
233
- 0%, 100% { opacity: 1; }
234
- 50% { opacity: 0.6; }
235
- }
236
- .content {
237
- text-align: center;
238
- position: relative;
239
- z-index: 10;
240
- }
241
- .icon-wrapper {
242
- width: 80px; height: 80px;
243
- margin: 0 auto 24px;
244
- position: relative;
245
- display: flex;
246
- align-items: center;
247
- justify-content: center;
248
- }
249
- .icon-glow {
250
- position: absolute;
251
- width: 100%; height: 100%;
252
- border-radius: 50%;
253
- background: radial-gradient(circle, rgba(255, 59, 48, 0.4) 0%, transparent 70%);
254
- animation: iconGlow 2s ease-in-out infinite;
255
- }
256
- @keyframes iconGlow {
257
- 0%, 100% { transform: scale(1); opacity: 0.8; }
258
- 50% { transform: scale(1.2); opacity: 1; }
259
- }
260
- .icon {
261
- width: 48px; height: 48px;
262
- color: var(--error);
263
- position: relative;
264
- z-index: 1;
265
- }
266
- .app-name {
267
- font-family: "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
268
- font-size: 24px;
269
- font-weight: 700;
270
- letter-spacing: -0.5px;
271
- margin-bottom: 8px;
272
- }
273
- .title {
274
- font-size: 20px;
275
- font-weight: 600;
276
- margin-bottom: 8px;
277
- color: var(--error);
278
- }
279
- .subtitle {
280
- font-size: 16px;
281
- color: var(--text-secondary);
282
- }
283
- </style>
284
- </head>
285
- <body>
286
- <div class="container">
287
- <div class="stars"></div>
288
- <div class="stars-near"></div>
289
- <div class="content">
290
- <div class="icon-wrapper">
291
- <div class="icon-glow"></div>
292
- <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
293
- <line x1="18" y1="6" x2="6" y2="18"></line>
294
- <line x1="6" y1="6" x2="18" y2="18"></line>
295
- </svg>
296
- </div>
297
- <h1 class="app-name">PocketCoder</h1>
298
- <p class="title">Login Failed</p>
299
- <p class="subtitle">You can close this window.</p>
300
- </div>
301
- </div>
302
- </body>
303
- </html>`;
304
- /**
305
- * HTML page that extracts tokens from URL fragment and posts them back.
306
- * Supabase implicit flow returns tokens in the fragment (#access_token=...).
307
- */
308
- const FRAGMENT_EXTRACTOR_HTML = `<!DOCTYPE html>
309
- <html lang="en">
310
- <head>
311
- <meta charset="UTF-8">
312
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
313
- <title>PocketCoder - Completing Login...</title>
314
- <link rel="preconnect" href="https://fonts.googleapis.com">
315
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
316
- <link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=Inter:wght@600;700&display=swap" rel="stylesheet">
317
- <style>
318
- :root {
319
- --bg-primary: #000000;
320
- --text-primary: #ffffff;
321
- --text-secondary: #a1a1a6;
322
- --accent: #c9a87c;
323
- --success: #34c759;
324
- --error: #ff3b30;
325
- }
326
- * { margin: 0; padding: 0; box-sizing: border-box; }
327
- html, body {
328
- height: 100%;
329
- font-family: "DM Sans", -apple-system, BlinkMacSystemFont, sans-serif;
330
- background: var(--bg-primary);
331
- color: var(--text-primary);
332
- -webkit-font-smoothing: antialiased;
333
- }
334
- .container {
335
- display: flex;
336
- flex-direction: column;
337
- align-items: center;
338
- justify-content: center;
339
- min-height: 100vh;
340
- padding: 24px;
341
- position: relative;
342
- overflow: hidden;
343
- }
344
- .stars, .stars-near {
345
- position: absolute;
346
- top: 0; left: 0;
347
- width: 100%; height: 100%;
348
- pointer-events: none;
349
- }
350
- .stars::before {
351
- content: "";
352
- position: absolute;
353
- top: 30%; left: 50%;
354
- width: 2px; height: 2px;
355
- background: transparent;
356
- border-radius: 50%;
357
- box-shadow:
358
- -180px -120px 0 0 rgba(186, 85, 211, 0.6),
359
- 160px -100px 0 0 rgba(135, 206, 250, 0.65),
360
- -220px 80px 0 0 rgba(255, 182, 193, 0.6),
361
- 200px 120px 0 0 rgba(255, 160, 122, 0.55),
362
- -120px 180px 0 0 rgba(147, 112, 219, 0.65),
363
- 140px 200px 0 0 rgba(135, 206, 250, 0.6),
364
- -280px -60px 0 0 rgba(255, 182, 193, 0.55),
365
- 260px -80px 0 0 rgba(186, 85, 211, 0.65),
366
- -160px -200px 0 0 rgba(255, 160, 122, 0.6),
367
- 180px -180px 0 0 rgba(147, 112, 219, 0.55);
368
- animation: twinkle 3.5s ease-in-out infinite;
369
- }
370
- .stars-near::before {
371
- content: "";
372
- position: absolute;
373
- top: 30%; left: 50%;
374
- width: 2px; height: 2px;
375
- background: transparent;
376
- border-radius: 50%;
377
- box-shadow:
378
- -80px -60px 0 0 rgba(186, 85, 211, 0.9),
379
- 70px -50px 0 1px rgba(255, 160, 122, 1),
380
- -90px 40px 0 0 rgba(135, 206, 250, 0.85),
381
- 85px 55px 0 1px rgba(255, 182, 193, 0.9),
382
- -50px 80px 0 0 rgba(147, 112, 219, 0.95),
383
- 60px 90px 0 1px rgba(186, 85, 211, 0.85),
384
- -110px -30px 0 0 rgba(255, 160, 122, 0.9),
385
- 105px -35px 0 1px rgba(135, 206, 250, 0.95);
386
- animation: twinkle 2s ease-in-out infinite;
387
- }
388
- @keyframes twinkle {
389
- 0%, 100% { opacity: 1; }
390
- 50% { opacity: 0.6; }
391
- }
392
- .content {
393
- text-align: center;
394
- position: relative;
395
- z-index: 10;
396
- }
397
- .icon-wrapper {
398
- width: 80px; height: 80px;
399
- margin: 0 auto 24px;
400
- position: relative;
401
- display: flex;
402
- align-items: center;
403
- justify-content: center;
404
- }
405
- .icon-glow {
406
- position: absolute;
407
- width: 100%; height: 100%;
408
- border-radius: 50%;
409
- background: radial-gradient(circle, rgba(201, 168, 124, 0.4) 0%, transparent 70%);
410
- animation: iconGlow 2s ease-in-out infinite;
411
- }
412
- .icon-glow.success {
413
- background: radial-gradient(circle, rgba(52, 199, 89, 0.4) 0%, transparent 70%);
414
- }
415
- .icon-glow.error {
416
- background: radial-gradient(circle, rgba(255, 59, 48, 0.4) 0%, transparent 70%);
417
- }
418
- @keyframes iconGlow {
419
- 0%, 100% { transform: scale(1); opacity: 0.8; }
420
- 50% { transform: scale(1.2); opacity: 1; }
421
- }
422
- .spinner {
423
- width: 48px; height: 48px;
424
- border: 3px solid rgba(201, 168, 124, 0.2);
425
- border-top-color: var(--accent);
426
- border-radius: 50%;
427
- animation: spin 1s linear infinite;
428
- }
429
- @keyframes spin {
430
- to { transform: rotate(360deg); }
431
- }
432
- .icon {
433
- width: 48px; height: 48px;
434
- position: relative;
435
- z-index: 1;
436
- display: none;
437
- }
438
- .icon.success { color: var(--success); }
439
- .icon.error { color: var(--error); }
440
- .app-name {
441
- font-family: "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
442
- font-size: 24px;
443
- font-weight: 700;
444
- letter-spacing: -0.5px;
445
- margin-bottom: 8px;
446
- }
447
- .title {
448
- font-size: 20px;
449
- font-weight: 600;
450
- margin-bottom: 8px;
451
- color: var(--accent);
452
- }
453
- .title.success { color: var(--success); }
454
- .title.error { color: var(--error); }
455
- .subtitle {
456
- font-size: 16px;
457
- color: var(--text-secondary);
458
- }
459
- </style>
460
- </head>
461
- <body>
462
- <div class="container">
463
- <div class="stars"></div>
464
- <div class="stars-near"></div>
465
- <div class="content">
466
- <div class="icon-wrapper">
467
- <div class="icon-glow" id="iconGlow"></div>
468
- <div class="spinner" id="spinner"></div>
469
- <svg class="icon success" id="successIcon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
470
- <polyline points="20 6 9 17 4 12"></polyline>
471
- </svg>
472
- <svg class="icon error" id="errorIcon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
473
- <line x1="18" y1="6" x2="6" y2="18"></line>
474
- <line x1="6" y1="6" x2="18" y2="18"></line>
475
- </svg>
476
- </div>
477
- <h1 class="app-name">PocketCoder</h1>
478
- <p class="title" id="title">Completing login...</p>
479
- <p class="subtitle" id="subtitle">Please wait</p>
480
- </div>
481
- </div>
482
- <script>
483
- const iconGlow = document.getElementById('iconGlow');
484
- const spinner = document.getElementById('spinner');
485
- const successIcon = document.getElementById('successIcon');
486
- const errorIcon = document.getElementById('errorIcon');
487
- const title = document.getElementById('title');
488
- const subtitle = document.getElementById('subtitle');
489
-
490
- function showSuccess() {
491
- spinner.style.display = 'none';
492
- iconGlow.classList.add('success');
493
- successIcon.style.display = 'block';
494
- title.textContent = 'Authentication successful!';
495
- title.classList.add('success');
496
- subtitle.textContent = 'You can close this window.';
497
- }
498
-
499
- function showError(message) {
500
- spinner.style.display = 'none';
501
- iconGlow.classList.add('error');
502
- errorIcon.style.display = 'block';
503
- title.textContent = 'Login Failed';
504
- title.classList.add('error');
505
- subtitle.textContent = message || 'You can close this window.';
506
- }
507
-
508
- const hash = window.location.hash.substring(1);
509
- const params = new URLSearchParams(hash);
510
- const accessToken = params.get('access_token');
511
- const refreshToken = params.get('refresh_token');
512
- const error = params.get('error');
513
-
514
- if (error) {
515
- showError(error);
516
- } else if (accessToken && refreshToken) {
517
- fetch('/auth/tokens', {
518
- method: 'POST',
519
- headers: { 'Content-Type': 'application/json' },
520
- body: JSON.stringify({ access_token: accessToken, refresh_token: refreshToken })
521
- }).then(() => {
522
- showSuccess();
523
- }).catch(err => {
524
- showError(err.message);
525
- });
526
- } else {
527
- showError('Missing tokens in response');
528
- }
529
- </script>
530
- </body>
531
- </html>`;
532
5
  /**
533
6
  * Start a temporary HTTP server on a random port to receive the OAuth callback.
534
7
  * The server listens only on 127.0.0.1 and closes automatically after the
@@ -550,18 +23,20 @@ export async function startOAuthServer() {
550
23
  const errorParam = reqUrl.searchParams.get("error");
551
24
  if (errorParam) {
552
25
  res.writeHead(400, { "Content-Type": "text/html" });
553
- res.end(ERROR_HTML);
554
26
  error = new Error(errorParam);
555
- settle();
27
+ // Wait for response to be fully sent before settling
28
+ res.on("finish", settle);
29
+ res.end(ERROR_HTML);
556
30
  return;
557
31
  }
558
32
  // Check for code flow (code in query string)
559
33
  const code = reqUrl.searchParams.get("code");
560
34
  if (code) {
561
35
  res.writeHead(200, { "Content-Type": "text/html" });
562
- res.end(SUCCESS_HTML);
563
36
  result = { code };
564
- settle();
37
+ // Wait for response to be fully sent before settling
38
+ res.on("finish", settle);
39
+ res.end(SUCCESS_HTML);
565
40
  return;
566
41
  }
567
42
  // No code - serve HTML to extract tokens from fragment (implicit flow)
@@ -580,9 +55,10 @@ export async function startOAuthServer() {
580
55
  const data = JSON.parse(body);
581
56
  if (data.access_token && data.refresh_token) {
582
57
  res.writeHead(200, { "Content-Type": "application/json" });
583
- res.end(JSON.stringify({ success: true }));
584
58
  result = { access_token: data.access_token, refresh_token: data.refresh_token };
585
- settle();
59
+ // Wait for response to be fully sent before settling
60
+ res.on("finish", settle);
61
+ res.end(JSON.stringify({ success: true }));
586
62
  }
587
63
  else {
588
64
  res.writeHead(400, { "Content-Type": "application/json" });
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-server.js","sourceRoot":"","sources":["../../src/auth/oauth-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"oauth-server.js","sourceRoot":"","sources":["../../src/auth/oauth-server.ts"],"names":[],"mappings":"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"}