@bananacool467/authtics-host 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -45,14 +45,6 @@ const MIME_TYPES = {
45
45
  '.txt': 'text/plain',
46
46
  '.pdf': 'application/pdf',
47
47
  };
48
- function augmentRes(res) {
49
- const r = res;
50
- r.html = (html) => { res.setHeader("Content-Type", "text/html"); res.end(html); };
51
- r.json = (data) => { res.setHeader("Content-Type", "application/json"); res.end(JSON.stringify(data)); };
52
- r.text = (text) => { res.setHeader("Content-Type", "text/plain"); res.end(text); };
53
- r.status = (code) => { res.statusCode = code; return r; };
54
- return r;
55
- }
56
48
  const getCpu = () => {
57
49
  return new Promise((resolve) => {
58
50
  const start = process.cpuUsage();
@@ -97,29 +89,14 @@ export default class App {
97
89
  server;
98
90
  constructor() {
99
91
  this.server = start();
100
- this.get('/failed-to-handle', async (req, res) => {
101
- if (!usersPaused) {
102
- res.writeHead(302, {
103
- 'Location': '/'
104
- });
105
- res.end();
106
- return;
107
- }
108
- ;
109
- res.writeHead(200, { "Content-Type": "application/json" });
110
- res.end(JSON.stringify({
111
- message: "unhandled request"
112
- }));
113
- });
114
92
  this.post('/__authtics_host_apis__/set-users-paused', async (req, res) => {
115
- const reqBody = (await getJsonBody(req));
116
93
  let datMatched = false;
117
- if (config_.dat && config_.dat == reqBody.dat)
94
+ if (config_.dat && config_.dat == req.cookies.dat)
118
95
  datMatched = true;
119
- if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
96
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(req.cookies.dat))
120
97
  datMatched = true;
121
98
  if (datMatched) {
122
- usersPaused = reqBody.paused;
99
+ usersPaused = req.body.paused;
123
100
  res.writeHead(200, { "Content-Type": "application/json" });
124
101
  res.end(JSON.stringify({
125
102
  message: "ok"
@@ -127,27 +104,27 @@ export default class App {
127
104
  }
128
105
  });
129
106
  this.post('/__authtics_host_apis__/is-users-paused', async (req, res) => {
130
- const reqBody = (await getJsonBody(req));
131
107
  let datMatched = false;
132
- if (config_.dat && config_.dat == reqBody.dat)
108
+ if (config_.dat && config_.dat == req.cookies.dat)
133
109
  datMatched = true;
134
- if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
110
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(req.cookies.dat))
135
111
  datMatched = true;
136
112
  res.writeHead(200, { "Content-Type": "application/json" });
137
- res.end(JSON.stringify({
138
- paused: (datMatched ? false : usersPaused),
139
- realInfo: usersPaused
140
- }));
113
+ if (datMatched) {
114
+ res.end(JSON.stringify({
115
+ paused: (datMatched ? false : usersPaused),
116
+ realInfo: usersPaused
117
+ }));
118
+ }
141
119
  });
142
120
  this.post('/__authtics_host_apis__/get-dat-restriction-missing', async (req, res) => {
143
- const reqBody = (await getJsonBody(req));
144
121
  let datMatched = false;
145
122
  let datRestrictedEnv = false;
146
- if (config_.dat && config_.dat == reqBody.dat)
123
+ if (config_.dat && config_.dat == req.cookies.dat)
147
124
  datMatched = true;
148
125
  if (config_.dat == undefined)
149
126
  datMatched = true;
150
- if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
127
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(req.cookies.dat))
151
128
  datMatched = true;
152
129
  if (datMatched) {
153
130
  if (config_.dat !== undefined)
@@ -159,13 +136,12 @@ export default class App {
159
136
  }
160
137
  });
161
138
  this.post('/__authtics_host_apis__/get-dat-matching', async (req, res) => {
162
- const reqBody = (await getJsonBody(req));
163
139
  let datMatched = false;
164
- if (config_.dat && config_.dat == reqBody.dat)
140
+ if (config_.dat && config_.dat == req.cookies.dat)
165
141
  datMatched = true;
166
142
  if (config_.dat == undefined)
167
143
  datMatched = true;
168
- if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
144
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(req.cookies.dat))
169
145
  datMatched = true;
170
146
  res.writeHead(200, { "Content-Type": "application/json" });
171
147
  res.end(JSON.stringify({
@@ -173,11 +149,10 @@ export default class App {
173
149
  }));
174
150
  });
175
151
  this.post('/__authtics_host_apis__/get-cpu_memory', async (req, res) => {
176
- const reqBody = (await getJsonBody(req));
177
152
  let datMatched = false;
178
- if (config_.dat && config_.dat == reqBody.dat)
153
+ if (config_.dat && config_.dat == req.cookies.dat)
179
154
  datMatched = true;
180
- if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
155
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(req.cookies.dat))
181
156
  datMatched = true;
182
157
  if (datMatched) {
183
158
  const { heapUsed, heapTotal, rss } = process.memoryUsage();
@@ -190,11 +165,10 @@ export default class App {
190
165
  }
191
166
  });
192
167
  this.post('/__authtics_host_apis__/get-user-settings', async (req, res) => {
193
- const reqBody = (await getJsonBody(req));
194
168
  let datMatched = false;
195
- if (config_.dat && config_.dat == reqBody.dat)
169
+ if (config_.dat && config_.dat == req.cookies.dat)
196
170
  datMatched = true;
197
- if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
171
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(req.cookies.dat))
198
172
  datMatched = true;
199
173
  if (datMatched) {
200
174
  res.writeHead(200, { "Content-Type": "application/json" });
@@ -204,11 +178,10 @@ export default class App {
204
178
  }
205
179
  });
206
180
  this.post("/__authtics_host_apis__/get-server-info", async (req, res) => {
207
- const reqBody = (await getJsonBody(req));
208
181
  let datMatched = false;
209
- if (config_.dat && config_.dat == reqBody.dat)
182
+ if (config_.dat && config_.dat == req.cookies.dat)
210
183
  datMatched = true;
211
- if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
184
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(req.cookies.dat))
212
185
  datMatched = true;
213
186
  if (datMatched) {
214
187
  res.writeHead(200, { "Content-Type": "application/json" });
@@ -218,11 +191,10 @@ export default class App {
218
191
  }
219
192
  });
220
193
  this.post("/__authtics_host_apis__/restart", async (req, res) => {
221
- const reqBody = (await getJsonBody(req));
222
194
  let datMatched = false;
223
- if (config_.dat && config_.dat == reqBody.dat)
195
+ if (config_.dat && config_.dat == req.cookies.dat)
224
196
  datMatched = true;
225
- if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
197
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(req.cookies.dat))
226
198
  datMatched = true;
227
199
  if (datMatched) {
228
200
  res.writeHead(200, { "Content-Type": "application/json" });
@@ -237,11 +209,10 @@ export default class App {
237
209
  }
238
210
  });
239
211
  this.post("/__authtics_host_apis__/shutdown", async (req, res) => {
240
- const reqBody = (await getJsonBody(req));
241
212
  let datMatched = false;
242
- if (config_.dat && config_.dat == reqBody.dat)
213
+ if (config_.dat && config_.dat == req.cookies.dat)
243
214
  datMatched = true;
244
- if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
215
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(req.cookies.dat))
245
216
  datMatched = true;
246
217
  if (datMatched) {
247
218
  res.writeHead(200, { "Content-Type": "application/json" });
@@ -252,11 +223,10 @@ export default class App {
252
223
  }
253
224
  });
254
225
  this.post("/__authtics_host_apis__/get-is-ssr", async (req, res) => {
255
- const reqBody = (await getJsonBody(req));
256
226
  let datMatched = false;
257
- if (config_.dat && config_.dat == reqBody.dat)
227
+ if (config_.dat && config_.dat == req.cookies.dat)
258
228
  datMatched = true;
259
- if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
229
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(req.cookies.dat))
260
230
  datMatched = true;
261
231
  if (datMatched) {
262
232
  res.writeHead(200, { "Content-Type": "application/json" });
@@ -266,11 +236,10 @@ export default class App {
266
236
  }
267
237
  });
268
238
  this.post("/__authtics_host_apis__/get-compiler", async (req, res) => {
269
- const reqBody = (await getJsonBody(req));
270
239
  let datMatched = false;
271
- if (config_.dat && config_.dat == reqBody.dat)
240
+ if (config_.dat && config_.dat == req.cookies.dat)
272
241
  datMatched = true;
273
- if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
242
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(req.cookies.dat))
274
243
  datMatched = true;
275
244
  if (datMatched) {
276
245
  res.writeHead(200, { "Content-Type": "application/json" });
@@ -280,11 +249,10 @@ export default class App {
280
249
  }
281
250
  });
282
251
  this.post("/__authtics_host_apis__/get-host-ver", async (req, res) => {
283
- const reqBody = (await getJsonBody(req));
284
252
  let datMatched = false;
285
- if (config_.dat && config_.dat == reqBody.dat)
253
+ if (config_.dat && config_.dat == req.cookies.dat)
286
254
  datMatched = true;
287
- if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
255
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(req.cookies.dat))
288
256
  datMatched = true;
289
257
  if (datMatched) {
290
258
  const packageJsonPath = path.join(__dirname, '../package.json');
@@ -299,14 +267,13 @@ export default class App {
299
267
  }
300
268
  });
301
269
  this.post("/__authtics_host_apis__/get-file-by-pathname", async (req, res) => {
302
- const reqBody = (await getJsonBody(req));
303
270
  let datMatched = false;
304
- if (config_.dat && config_.dat == reqBody.dat)
271
+ if (config_.dat && config_.dat == req.cookies.dat)
305
272
  datMatched = true;
306
- if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
273
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(req.cookies.dat))
307
274
  datMatched = true;
308
275
  if (datMatched) {
309
- const pathname = reqBody.pathname;
276
+ const pathname = req.body.pathname;
310
277
  const pagesDir = config_.autoPage === true ? path.join(process.cwd(), config_.autoPageDir || "") : undefined;
311
278
  const safePath = path.normalize(pathname).replace(/^(\.\.[\/\\])+/, '');
312
279
  let filePath = pagesDir ? path.join(pagesDir, (safePath !== "/" ? safePath : "index") + ".tsx") : undefined;
@@ -337,11 +304,10 @@ export default class App {
337
304
  }
338
305
  });
339
306
  this.post("/__authtics_host_apis__/ping", async (req, res) => {
340
- const reqBody = (await getJsonBody(req));
341
307
  let datMatched = false;
342
- if (config_.dat && config_.dat == reqBody.dat)
308
+ if (config_.dat && config_.dat == req.cookies.dat)
343
309
  datMatched = true;
344
- if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
310
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(req.cookies.dat))
345
311
  datMatched = true;
346
312
  if (datMatched) {
347
313
  res.setHeader("Content-Type", "application/json");
@@ -349,11 +315,10 @@ export default class App {
349
315
  }
350
316
  });
351
317
  this.post('/__authtics_host_apis__/get-connection', async (req, res) => {
352
- const reqBody = (await getJsonBody(req));
353
318
  let datMatched = false;
354
- if (config_.dat && config_.dat == reqBody.dat)
319
+ if (config_.dat && config_.dat == req.cookies.dat)
355
320
  datMatched = true;
356
- if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
321
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(req.cookies.dat))
357
322
  datMatched = true;
358
323
  if (datMatched) {
359
324
  res.writeHead(200, { "Content-Type": "application/json" });
@@ -397,23 +362,244 @@ async function start() {
397
362
  const publicDir = config.autoFile === true ? path.join(process.cwd(), config.autoFileDir || "") : undefined;
398
363
  const apiDir = pagesDir ? path.join(pagesDir, "api") : undefined;
399
364
  const server = createServer(async (req, res) => {
400
- const actuallyShowPanel = showPanel;
401
- const r = augmentRes(res);
402
365
  const { url = "/", method } = req;
366
+ const actuallyShowPanel = showPanel;
367
+ req.ip = (req.headers["x-real-ip"] ||
368
+ req.headers["x-forwarded-for"]?.split(",")[0].trim() ||
369
+ req.socket.remoteAddress ||
370
+ undefined);
371
+ req.ipType = req.ip?.includes(":") ? 6 : req.ip?.includes(".") ? 4 : 0;
372
+ req.ua = req.headers["user-agent"] || undefined;
373
+ let ua = req.headers["user-agent"] || "";
374
+ let browserType = "Unknown";
375
+ let browserVersion = "Unknown";
376
+ if (ua.includes("Chrome") && !ua.includes("Edg")) {
377
+ browserType = "Chrome";
378
+ browserVersion = ua.match(/Chrome\/([\d.]+)/)?.[1] || "Unknown";
379
+ }
380
+ else if (ua.includes("Firefox")) {
381
+ browserType = "Firefox";
382
+ browserVersion = ua.match(/Firefox\/([\d.]+)/)?.[1] || "Unknown";
383
+ }
384
+ else if (ua.includes("Safari") && !ua.includes("Chrome")) {
385
+ browserType = "Safari";
386
+ browserVersion = ua.match(/Version\/([\d.]+)/)?.[1] || "Unknown";
387
+ }
388
+ else if (ua.includes("Edg")) {
389
+ browserType = "Edge";
390
+ browserVersion = ua.match(/Edg\/([\d.]+)/)?.[1] || "Unknown";
391
+ }
392
+ let osType = "Unknown";
393
+ let osVersion = "Unknown";
394
+ if (ua.includes("Windows NT")) {
395
+ osType = "Windows";
396
+ osVersion = ua.match(/Windows NT ([\d.]+)/)?.[1] || "Unknown";
397
+ }
398
+ else if (ua.includes("Mac OS X")) {
399
+ osType = "macOS";
400
+ osVersion = ua.match(/Mac OS X ([\d_]+)/)?.[1]?.replace(/_/g, ".") || "Unknown";
401
+ }
402
+ else if (ua.includes("Android")) {
403
+ osType = "Android";
404
+ osVersion = ua.match(/Android ([\d.]+)/)?.[1] || "Unknown";
405
+ }
406
+ else if (ua.includes("iPhone") || ua.includes("iPad")) {
407
+ osType = "iOS";
408
+ osVersion = ua.match(/OS ([\d_]+)/)?.[1]?.replace(/_/g, ".") || "Unknown";
409
+ }
410
+ else if (ua.includes("Linux")) {
411
+ osType = "Linux";
412
+ }
413
+ req.os = {
414
+ type: osType,
415
+ version: osVersion
416
+ };
417
+ req.browser = {
418
+ type: browserType,
419
+ version: browserVersion
420
+ };
421
+ req.sentTime = Date.now();
422
+ req.body = {};
423
+ try {
424
+ req.body = await getJsonBody(req);
425
+ }
426
+ catch (e) {
427
+ req.body = {};
428
+ }
429
+ req.cookies = {};
430
+ const raw = req.headers.cookie;
431
+ if (raw) {
432
+ raw.split(";").forEach(pair => {
433
+ const [key, val] = pair.trim().split("=");
434
+ req.cookies[key] = val;
435
+ });
436
+ }
437
+ req.dat = req.cookies.dat || undefined;
438
+ req.bodySize = JSON.stringify(req.body).length;
439
+ req.bodyType = req.headers['content-type'] || 'text/plain';
440
+ res.redirect = (url) => {
441
+ res.writeHead(302, {
442
+ 'Location': url
443
+ });
444
+ res.end();
445
+ };
446
+ res.html = (content) => {
447
+ res.setHeader("Content-Type", "text/html");
448
+ res.end(content);
449
+ };
450
+ res.json = (content) => {
451
+ res.setHeader("Content-Type", "application/json");
452
+ res.end(JSON.stringify(content));
453
+ };
454
+ res.text = (content) => {
455
+ res.setHeader("Content-Type", "text/plain");
456
+ res.end(content);
457
+ };
458
+ res.file = (path_) => {
459
+ const path__ = path.join(process.cwd(), path_);
460
+ if (fs.existsSync(path__)) {
461
+ const ext = path.extname(path__);
462
+ const mime = MIME_TYPES[ext] ?? 'application/octet-stream';
463
+ res.setHeader("Content-Type", mime);
464
+ res.end(fs.readFileSync(path__));
465
+ }
466
+ };
467
+ res.status = (code) => {
468
+ res.statusCode = code;
469
+ return res;
470
+ };
471
+ res.reload = function () {
472
+ res.writeHead(302, { Location: req.url + '/' });
473
+ res.end();
474
+ };
475
+ res.setCookie = function (name, value) {
476
+ res.setHeader("Set-Cookie", `${name}=${value}; Path=/`);
477
+ };
478
+ res.rmvCookie = function (name) {
479
+ res.setHeader("Set-Cookie", `${name}=; Path=/; Max-Age=0`);
480
+ };
403
481
  let pathname = url.split("?")[0].split("#")[0];
482
+ const safePath = path.normalize(pathname).replace(/^(\.\.[\/\\])+/, '');
483
+ pathname = safePath;
404
484
  if (pathname !== "/" && pathname.endsWith("/"))
405
485
  pathname = pathname.slice(0, -1);
406
- if (!pathname.includes('/__authtics_host_apis__/')) {
486
+ if (!pathname.includes('/__authtics')) {
407
487
  totalRequests++;
408
488
  }
409
489
  const routeKey = `${method}:${pathname}`;
410
490
  if (routes.has(routeKey)) {
491
+ if (Array.isArray(config_.dat) && !config_.dat.includes(req.cookies.dat) && usersPaused && !routeKey.endsWith('.js')) {
492
+ if (autoPaging) {
493
+ const pausedTsxFile = pagesDir ? path.join(pagesDir, "_paused.tsx") : undefined;
494
+ if (fs.existsSync(pausedTsxFile || "")) {
495
+ try {
496
+ let html = await renderPage(pausedTsxFile || "", url, actuallyShowPanel, compiler, hotReload, autoPaging, config.autoPageDir, (routes.get("APP_TSX") || ""), (f, p) => {
497
+ routes.set(`GET:${p}`, (req, res) => {
498
+ res.setHeader("Content-Type", "application/javascript");
499
+ res.end(f);
500
+ });
501
+ }, req.cookies.dat, config_.dat);
502
+ html = html.replace("<script>", "<script>\nwindow.__paused__ = true;");
503
+ res.setHeader("Content-Type", "text/html");
504
+ return res.end(html);
505
+ }
506
+ catch (e) {
507
+ console.error("[authtics] renderPage error:", e.message);
508
+ res.writeHead(500);
509
+ return res.end(`<html><body><pre>500 | Render error:\n${e.message}</pre></body></html>`);
510
+ }
511
+ }
512
+ }
513
+ if (config.hasPausedRoute) {
514
+ if (!autoPaging) {
515
+ const appTsxPath = routes.get("APP_TSX");
516
+ const appPath = path.join(process.cwd(), appTsxPath);
517
+ if (fs.existsSync(appPath)) {
518
+ try {
519
+ let html = await renderPage(appPath, url, actuallyShowPanel, compiler, hotReload, autoPaging, config.autoPageDir, (routes.get("APP_TSX") || ""), (f, p) => {
520
+ routes.set(`GET:${p}`, (req, res) => {
521
+ res.setHeader("Content-Type", "application/javascript");
522
+ res.end(f);
523
+ });
524
+ }, req.cookies.dat, config_.dat);
525
+ html = html.replace("<script>", "<script>\nwindow.__paused__ = true;");
526
+ res.setHeader("Content-Type", "text/html");
527
+ return res.end(html);
528
+ }
529
+ catch (e) {
530
+ console.error("[authtics] renderPage error:", e.message);
531
+ res.writeHead(500);
532
+ return res.end(`<html><body><pre>500 | Render error:\n${e.message}</pre></body></html>`);
533
+ }
534
+ }
535
+ }
536
+ }
537
+ res.writeHead(200, {
538
+ "Content-Type": "application/json"
539
+ });
540
+ return res.end(JSON.stringify({
541
+ message: "unhandled request"
542
+ }));
543
+ }
544
+ if (config_.dat !== req.cookies.dat && usersPaused && !routeKey.endsWith('.js')) {
545
+ if (autoPaging) {
546
+ const pausedTsxFile = pagesDir ? path.join(pagesDir, "_paused.tsx") : undefined;
547
+ if (fs.existsSync(pausedTsxFile || "")) {
548
+ try {
549
+ let html = await renderPage(pausedTsxFile || "", url, actuallyShowPanel, compiler, hotReload, autoPaging, config.autoPageDir, (routes.get("APP_TSX") || ""), (f, p) => {
550
+ routes.set(`GET:${p}`, (req, res) => {
551
+ res.setHeader("Content-Type", "application/javascript");
552
+ res.end(f);
553
+ });
554
+ }, req.cookies.dat, config_.dat);
555
+ html = html.replace("<script>", "<script>\nwindow.__paused__ = true;");
556
+ res.setHeader("Content-Type", "text/html");
557
+ return res.end(html);
558
+ }
559
+ catch (e) {
560
+ console.error("[authtics] renderPage error:", e.message);
561
+ res.writeHead(500);
562
+ return res.end(`<html><body><pre>500 | Render error:\n${e.message}</pre></body></html>`);
563
+ }
564
+ }
565
+ }
566
+ if (config.hasPausedRoute) {
567
+ if (!autoPaging) {
568
+ const appTsxPath = routes.get("APP_TSX");
569
+ const appPath = path.join(process.cwd(), appTsxPath);
570
+ if (fs.existsSync(appPath)) {
571
+ try {
572
+ let html = await renderPage(appPath, url, actuallyShowPanel, compiler, hotReload, autoPaging, config.autoPageDir, (routes.get("APP_TSX") || ""), (f, p) => {
573
+ routes.set(`GET:${p}`, (req, res) => {
574
+ res.setHeader("Content-Type", "application/javascript");
575
+ res.end(f);
576
+ });
577
+ }, req.cookies.dat, config_.dat);
578
+ html = html.replace("<script>", "<script>\nwindow.__paused__ = true;");
579
+ res.setHeader("Content-Type", "text/html");
580
+ return res.end(html);
581
+ }
582
+ catch (e) {
583
+ console.error("[authtics] renderPage error:", e.message);
584
+ res.writeHead(500);
585
+ return res.end(`<html><body><pre>500 | Render error:\n${e.message}</pre></body></html>`);
586
+ }
587
+ }
588
+ }
589
+ }
590
+ res.writeHead(200, {
591
+ "Content-Type": "application/json"
592
+ });
593
+ return res.end(JSON.stringify({
594
+ message: "unhandled request"
595
+ }));
596
+ }
411
597
  const handler = routes.get(routeKey);
412
598
  if (typeof handler === 'string') {
413
599
  return;
414
600
  }
415
601
  else if (typeof handler === 'function') {
416
- return handler(req, r);
602
+ return handler(req, res);
417
603
  }
418
604
  }
419
605
  if (pathname === '/__authtics_hmr__') {
@@ -429,6 +615,112 @@ async function start() {
429
615
  req.on('close', () => { hmrClients.delete(res); users--; });
430
616
  return;
431
617
  }
618
+ if (Array.isArray(config_.dat) && !config_.dat.includes(req.cookies.dat) && usersPaused) {
619
+ if (autoPaging) {
620
+ const pausedTsxFile = pagesDir ? path.join(pagesDir, "_paused.tsx") : undefined;
621
+ if (fs.existsSync(pausedTsxFile || "")) {
622
+ try {
623
+ let html = await renderPage(pausedTsxFile || "", url, actuallyShowPanel, compiler, hotReload, autoPaging, config.autoPageDir, (routes.get("APP_TSX") || ""), (f, p) => {
624
+ routes.set(`GET:${p}`, (req, res) => {
625
+ res.setHeader("Content-Type", "application/javascript");
626
+ res.end(f);
627
+ });
628
+ }, req.cookies.dat, config_.dat);
629
+ html = html.replace("<script>", "<script>\nwindow.__paused__ = true;");
630
+ res.setHeader("Content-Type", "text/html");
631
+ return res.end(html);
632
+ }
633
+ catch (e) {
634
+ console.error("[authtics] renderPage error:", e.message);
635
+ res.writeHead(500);
636
+ return res.end(`<html><body><pre>500 | Render error:\n${e.message}</pre></body></html>`);
637
+ }
638
+ }
639
+ }
640
+ if (config.hasPausedRoute) {
641
+ if (!autoPaging) {
642
+ const appTsxPath = routes.get("APP_TSX");
643
+ const appPath = path.join(process.cwd(), appTsxPath);
644
+ if (fs.existsSync(appPath)) {
645
+ try {
646
+ let html = await renderPage(appPath, url, actuallyShowPanel, compiler, hotReload, autoPaging, config.autoPageDir, (routes.get("APP_TSX") || ""), (f, p) => {
647
+ routes.set(`GET:${p}`, (req, res) => {
648
+ res.setHeader("Content-Type", "application/javascript");
649
+ res.end(f);
650
+ });
651
+ }, req.cookies.dat, config_.dat);
652
+ html = html.replace("<script>", "<script>\nwindow.__paused__ = true;");
653
+ res.setHeader("Content-Type", "text/html");
654
+ return res.end(html);
655
+ }
656
+ catch (e) {
657
+ console.error("[authtics] renderPage error:", e.message);
658
+ res.writeHead(500);
659
+ return res.end(`<html><body><pre>500 | Render error:\n${e.message}</pre></body></html>`);
660
+ }
661
+ }
662
+ }
663
+ }
664
+ res.writeHead(200, {
665
+ "Content-Type": "application/json"
666
+ });
667
+ return res.end(JSON.stringify({
668
+ message: "unhandled request"
669
+ }));
670
+ }
671
+ if (config.dat !== req.cookies.dat && usersPaused) {
672
+ if (autoPaging) {
673
+ const pausedTsxFile = pagesDir ? path.join(pagesDir, "_paused.tsx") : undefined;
674
+ if (fs.existsSync(pausedTsxFile || "")) {
675
+ try {
676
+ let html = await renderPage(pausedTsxFile || "", url, actuallyShowPanel, compiler, hotReload, autoPaging, config.autoPageDir, (routes.get("APP_TSX") || ""), (f, p) => {
677
+ routes.set(`GET:${p}`, (req, res) => {
678
+ res.setHeader("Content-Type", "application/javascript");
679
+ res.end(f);
680
+ });
681
+ }, req.cookies.dat, config_.dat);
682
+ html = html.replace("<script>", "<script>\nwindow.__paused__ = true;");
683
+ res.setHeader("Content-Type", "text/html");
684
+ return res.end(html);
685
+ }
686
+ catch (e) {
687
+ console.error("[authtics] renderPage error:", e.message);
688
+ res.writeHead(500);
689
+ return res.end(`<html><body><pre>500 | Render error:\n${e.message}</pre></body></html>`);
690
+ }
691
+ }
692
+ }
693
+ if (config.hasPausedRoute) {
694
+ if (!autoPaging) {
695
+ const appTsxPath = routes.get("APP_TSX");
696
+ const appPath = path.join(process.cwd(), appTsxPath);
697
+ if (fs.existsSync(appPath)) {
698
+ try {
699
+ let html = await renderPage(appPath, url, actuallyShowPanel, compiler, hotReload, autoPaging, config.autoPageDir, (routes.get("APP_TSX") || ""), (f, p) => {
700
+ routes.set(`GET:${p}`, (req, res) => {
701
+ res.setHeader("Content-Type", "application/javascript");
702
+ res.end(f);
703
+ });
704
+ }, req.cookies.dat, config_.dat);
705
+ html = html.replace("<script>", "<script>\nwindow.__paused__ = true;");
706
+ res.setHeader("Content-Type", "text/html");
707
+ return res.end(html);
708
+ }
709
+ catch (e) {
710
+ console.error("[authtics] renderPage error:", e.message);
711
+ res.writeHead(500);
712
+ return res.end(`<html><body><pre>500 | Render error:\n${e.message}</pre></body></html>`);
713
+ }
714
+ }
715
+ }
716
+ }
717
+ res.writeHead(200, {
718
+ "Content-Type": "application/json"
719
+ });
720
+ return res.end(JSON.stringify({
721
+ message: "unhandled request"
722
+ }));
723
+ }
432
724
  if (publicDir && fs.existsSync(publicDir)) {
433
725
  const staticPath = path.join(publicDir, pathname);
434
726
  const safePath = path.resolve(staticPath);
@@ -443,7 +735,7 @@ async function start() {
443
735
  const apiFile = path.join(pagesDir, `${pathname}.ts`);
444
736
  const apiFileTsx = path.join(pagesDir, `${pathname}.tsx`);
445
737
  const resolvedApi = fs.existsSync(apiFile) ? apiFile : fs.existsSync(apiFileTsx) ? apiFileTsx : null;
446
- if (resolvedApi) {
738
+ if (resolvedApi && fs.existsSync(resolvedApi)) {
447
739
  try {
448
740
  const apiModule = await jiti.import(resolvedApi, { default: true });
449
741
  const handler = apiModule.default ?? apiModule.handler ?? null;
@@ -451,7 +743,7 @@ async function start() {
451
743
  res.writeHead(500);
452
744
  return res.end(`[authtics] API route ${pathname} must export a default function`);
453
745
  }
454
- return handler(req, r);
746
+ return handler(req, res);
455
747
  }
456
748
  catch (e) {
457
749
  console.error(`[authtics] API route error (${pathname}):`, e.message);
@@ -462,7 +754,12 @@ async function start() {
462
754
  const notFoundPath = path.join(__dirname, '404.js');
463
755
  if (fs.existsSync(notFoundPath)) {
464
756
  try {
465
- let html = await renderPage(notFoundPath, url, actuallyShowPanel, compiler, hotReload, autoPaging, config.autoPageDir, (routes.get("APP_TSX") || ""));
757
+ let html = await renderPage(notFoundPath, url, actuallyShowPanel, compiler, hotReload, autoPaging, config.autoPageDir, (routes.get("APP_TSX") || ""), (f, p) => {
758
+ routes.set(`GET:${p}`, (req, res) => {
759
+ res.setHeader("Content-Type", "application/javascript");
760
+ res.end(f);
761
+ });
762
+ }, req.cookies.dat, config_.dat);
466
763
  res.setHeader("Content-Type", "text/html");
467
764
  res.writeHead(404);
468
765
  html = html.replace("<script>", "<script>\nwindow.__status_code__ = 404;");
@@ -483,7 +780,12 @@ async function start() {
483
780
  const htmlPath = pagesDir ? path.join(pagesDir, `${urlPath}.html`) : undefined;
484
781
  if (tsxPath && fs.existsSync(tsxPath)) {
485
782
  try {
486
- const html = await renderPage(tsxPath, url, actuallyShowPanel, compiler, hotReload, autoPaging, config.autoPageDir, (routes.get("APP_TSX") || ""));
783
+ const html = await renderPage(tsxPath, url, actuallyShowPanel, compiler, hotReload, autoPaging, config.autoPageDir, (routes.get("APP_TSX") || ""), (f, p) => {
784
+ routes.set(`GET:${p}`, (req, res) => {
785
+ res.setHeader("Content-Type", "application/javascript");
786
+ res.end(f);
787
+ });
788
+ }, req.cookies.dat, config_.dat);
487
789
  res.setHeader("Content-Type", "text/html");
488
790
  return res.end(html);
489
791
  }
@@ -502,7 +804,12 @@ async function start() {
502
804
  const appPath = path.join(process.cwd(), appTsxPath);
503
805
  if (fs.existsSync(appPath)) {
504
806
  try {
505
- const html = await renderPage(appPath, url, actuallyShowPanel, compiler, hotReload, autoPaging, config.autoPageDir, (routes.get("APP_TSX") || ""));
807
+ const html = await renderPage(appPath, url, actuallyShowPanel, compiler, hotReload, autoPaging, config.autoPageDir, (routes.get("APP_TSX") || ""), (f, p) => {
808
+ routes.set(`GET:${p}`, (req, res) => {
809
+ res.setHeader("Content-Type", "application/javascript");
810
+ res.end(f);
811
+ });
812
+ }, req.cookies.dat, config_.dat);
506
813
  res.setHeader("Content-Type", "text/html");
507
814
  return res.end(html);
508
815
  }
@@ -516,7 +823,12 @@ async function start() {
516
823
  const notFoundPath = path.join(__dirname, '404.js');
517
824
  if (fs.existsSync(notFoundPath)) {
518
825
  try {
519
- let html = await renderPage(notFoundPath, url, actuallyShowPanel, compiler, hotReload, autoPaging, config.autoPageDir, (routes.get("APP_TSX") || ""));
826
+ let html = await renderPage(notFoundPath, url, actuallyShowPanel, compiler, hotReload, autoPaging, config.autoPageDir, (routes.get("APP_TSX") || ""), (f, p) => {
827
+ routes.set(`GET:${p}`, (req, res) => {
828
+ res.setHeader("Content-Type", "application/javascript");
829
+ res.end(f);
830
+ });
831
+ }, req.cookies.dat, config_.dat);
520
832
  res.setHeader("Content-Type", "text/html");
521
833
  res.writeHead(404);
522
834
  html = html.replace("<script>", "<script>\nwindow.__status_code__ = 404;");