@bananacool467/authtics-host 0.1.4 → 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
@@ -9,6 +9,7 @@ let config_ = {};
9
9
  let uptime = 0;
10
10
  let totalRequests = 0;
11
11
  let users = 0;
12
+ let usersPaused = false;
12
13
  const jiti = createJiti(import.meta.url);
13
14
  const routes = new Map();
14
15
  const __filename = url.fileURLToPath(import.meta.url);
@@ -44,14 +45,6 @@ const MIME_TYPES = {
44
45
  '.txt': 'text/plain',
45
46
  '.pdf': 'application/pdf',
46
47
  };
47
- function augmentRes(res) {
48
- const r = res;
49
- r.html = (html) => { res.setHeader("Content-Type", "text/html"); res.end(html); };
50
- r.json = (data) => { res.setHeader("Content-Type", "application/json"); res.end(JSON.stringify(data)); };
51
- r.text = (text) => { res.setHeader("Content-Type", "text/plain"); res.end(text); };
52
- r.status = (code) => { res.statusCode = code; return r; };
53
- return r;
54
- }
55
48
  const getCpu = () => {
56
49
  return new Promise((resolve) => {
57
50
  const start = process.cpuUsage();
@@ -96,15 +89,42 @@ export default class App {
96
89
  server;
97
90
  constructor() {
98
91
  this.server = start();
92
+ this.post('/__authtics_host_apis__/set-users-paused', async (req, res) => {
93
+ let datMatched = false;
94
+ if (config_.dat && config_.dat == req.cookies.dat)
95
+ datMatched = true;
96
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(req.cookies.dat))
97
+ datMatched = true;
98
+ if (datMatched) {
99
+ usersPaused = req.body.paused;
100
+ res.writeHead(200, { "Content-Type": "application/json" });
101
+ res.end(JSON.stringify({
102
+ message: "ok"
103
+ }));
104
+ }
105
+ });
106
+ this.post('/__authtics_host_apis__/is-users-paused', async (req, res) => {
107
+ let datMatched = false;
108
+ if (config_.dat && config_.dat == req.cookies.dat)
109
+ datMatched = true;
110
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(req.cookies.dat))
111
+ datMatched = true;
112
+ res.writeHead(200, { "Content-Type": "application/json" });
113
+ if (datMatched) {
114
+ res.end(JSON.stringify({
115
+ paused: (datMatched ? false : usersPaused),
116
+ realInfo: usersPaused
117
+ }));
118
+ }
119
+ });
99
120
  this.post('/__authtics_host_apis__/get-dat-restriction-missing', async (req, res) => {
100
- const reqBody = (await getJsonBody(req));
101
121
  let datMatched = false;
102
122
  let datRestrictedEnv = false;
103
- if (config_.dat && config_.dat == reqBody.dat)
123
+ if (config_.dat && config_.dat == req.cookies.dat)
104
124
  datMatched = true;
105
125
  if (config_.dat == undefined)
106
126
  datMatched = true;
107
- 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))
108
128
  datMatched = true;
109
129
  if (datMatched) {
110
130
  if (config_.dat !== undefined)
@@ -116,13 +136,12 @@ export default class App {
116
136
  }
117
137
  });
118
138
  this.post('/__authtics_host_apis__/get-dat-matching', async (req, res) => {
119
- const reqBody = (await getJsonBody(req));
120
139
  let datMatched = false;
121
- if (config_.dat && config_.dat == reqBody.dat)
140
+ if (config_.dat && config_.dat == req.cookies.dat)
122
141
  datMatched = true;
123
142
  if (config_.dat == undefined)
124
143
  datMatched = true;
125
- 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))
126
145
  datMatched = true;
127
146
  res.writeHead(200, { "Content-Type": "application/json" });
128
147
  res.end(JSON.stringify({
@@ -130,11 +149,10 @@ export default class App {
130
149
  }));
131
150
  });
132
151
  this.post('/__authtics_host_apis__/get-cpu_memory', async (req, res) => {
133
- const reqBody = (await getJsonBody(req));
134
152
  let datMatched = false;
135
- if (config_.dat && config_.dat == reqBody.dat)
153
+ if (config_.dat && config_.dat == req.cookies.dat)
136
154
  datMatched = true;
137
- 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))
138
156
  datMatched = true;
139
157
  if (datMatched) {
140
158
  const { heapUsed, heapTotal, rss } = process.memoryUsage();
@@ -147,11 +165,10 @@ export default class App {
147
165
  }
148
166
  });
149
167
  this.post('/__authtics_host_apis__/get-user-settings', async (req, res) => {
150
- const reqBody = (await getJsonBody(req));
151
168
  let datMatched = false;
152
- if (config_.dat && config_.dat == reqBody.dat)
169
+ if (config_.dat && config_.dat == req.cookies.dat)
153
170
  datMatched = true;
154
- 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))
155
172
  datMatched = true;
156
173
  if (datMatched) {
157
174
  res.writeHead(200, { "Content-Type": "application/json" });
@@ -161,11 +178,10 @@ export default class App {
161
178
  }
162
179
  });
163
180
  this.post("/__authtics_host_apis__/get-server-info", async (req, res) => {
164
- const reqBody = (await getJsonBody(req));
165
181
  let datMatched = false;
166
- if (config_.dat && config_.dat == reqBody.dat)
182
+ if (config_.dat && config_.dat == req.cookies.dat)
167
183
  datMatched = true;
168
- 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))
169
185
  datMatched = true;
170
186
  if (datMatched) {
171
187
  res.writeHead(200, { "Content-Type": "application/json" });
@@ -175,11 +191,10 @@ export default class App {
175
191
  }
176
192
  });
177
193
  this.post("/__authtics_host_apis__/restart", async (req, res) => {
178
- const reqBody = (await getJsonBody(req));
179
194
  let datMatched = false;
180
- if (config_.dat && config_.dat == reqBody.dat)
195
+ if (config_.dat && config_.dat == req.cookies.dat)
181
196
  datMatched = true;
182
- 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))
183
198
  datMatched = true;
184
199
  if (datMatched) {
185
200
  res.writeHead(200, { "Content-Type": "application/json" });
@@ -194,11 +209,10 @@ export default class App {
194
209
  }
195
210
  });
196
211
  this.post("/__authtics_host_apis__/shutdown", async (req, res) => {
197
- const reqBody = (await getJsonBody(req));
198
212
  let datMatched = false;
199
- if (config_.dat && config_.dat == reqBody.dat)
213
+ if (config_.dat && config_.dat == req.cookies.dat)
200
214
  datMatched = true;
201
- 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))
202
216
  datMatched = true;
203
217
  if (datMatched) {
204
218
  res.writeHead(200, { "Content-Type": "application/json" });
@@ -209,11 +223,10 @@ export default class App {
209
223
  }
210
224
  });
211
225
  this.post("/__authtics_host_apis__/get-is-ssr", async (req, res) => {
212
- const reqBody = (await getJsonBody(req));
213
226
  let datMatched = false;
214
- if (config_.dat && config_.dat == reqBody.dat)
227
+ if (config_.dat && config_.dat == req.cookies.dat)
215
228
  datMatched = true;
216
- 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))
217
230
  datMatched = true;
218
231
  if (datMatched) {
219
232
  res.writeHead(200, { "Content-Type": "application/json" });
@@ -223,11 +236,10 @@ export default class App {
223
236
  }
224
237
  });
225
238
  this.post("/__authtics_host_apis__/get-compiler", async (req, res) => {
226
- const reqBody = (await getJsonBody(req));
227
239
  let datMatched = false;
228
- if (config_.dat && config_.dat == reqBody.dat)
240
+ if (config_.dat && config_.dat == req.cookies.dat)
229
241
  datMatched = true;
230
- 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))
231
243
  datMatched = true;
232
244
  if (datMatched) {
233
245
  res.writeHead(200, { "Content-Type": "application/json" });
@@ -237,11 +249,10 @@ export default class App {
237
249
  }
238
250
  });
239
251
  this.post("/__authtics_host_apis__/get-host-ver", async (req, res) => {
240
- const reqBody = (await getJsonBody(req));
241
252
  let datMatched = false;
242
- if (config_.dat && config_.dat == reqBody.dat)
253
+ if (config_.dat && config_.dat == req.cookies.dat)
243
254
  datMatched = true;
244
- 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))
245
256
  datMatched = true;
246
257
  if (datMatched) {
247
258
  const packageJsonPath = path.join(__dirname, '../package.json');
@@ -256,14 +267,13 @@ export default class App {
256
267
  }
257
268
  });
258
269
  this.post("/__authtics_host_apis__/get-file-by-pathname", async (req, res) => {
259
- const reqBody = (await getJsonBody(req));
260
270
  let datMatched = false;
261
- if (config_.dat && config_.dat == reqBody.dat)
271
+ if (config_.dat && config_.dat == req.cookies.dat)
262
272
  datMatched = true;
263
- 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))
264
274
  datMatched = true;
265
275
  if (datMatched) {
266
- const pathname = reqBody.pathname;
276
+ const pathname = req.body.pathname;
267
277
  const pagesDir = config_.autoPage === true ? path.join(process.cwd(), config_.autoPageDir || "") : undefined;
268
278
  const safePath = path.normalize(pathname).replace(/^(\.\.[\/\\])+/, '');
269
279
  let filePath = pagesDir ? path.join(pagesDir, (safePath !== "/" ? safePath : "index") + ".tsx") : undefined;
@@ -294,11 +304,10 @@ export default class App {
294
304
  }
295
305
  });
296
306
  this.post("/__authtics_host_apis__/ping", async (req, res) => {
297
- const reqBody = (await getJsonBody(req));
298
307
  let datMatched = false;
299
- if (config_.dat && config_.dat == reqBody.dat)
308
+ if (config_.dat && config_.dat == req.cookies.dat)
300
309
  datMatched = true;
301
- 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))
302
311
  datMatched = true;
303
312
  if (datMatched) {
304
313
  res.setHeader("Content-Type", "application/json");
@@ -306,11 +315,10 @@ export default class App {
306
315
  }
307
316
  });
308
317
  this.post('/__authtics_host_apis__/get-connection', async (req, res) => {
309
- const reqBody = (await getJsonBody(req));
310
318
  let datMatched = false;
311
- if (config_.dat && config_.dat == reqBody.dat)
319
+ if (config_.dat && config_.dat == req.cookies.dat)
312
320
  datMatched = true;
313
- 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))
314
322
  datMatched = true;
315
323
  if (datMatched) {
316
324
  res.writeHead(200, { "Content-Type": "application/json" });
@@ -345,10 +353,6 @@ async function start() {
345
353
  }
346
354
  catch {
347
355
  }
348
- if (config.autoPage == null)
349
- config.autoPage = true;
350
- if (config.autoFile == null)
351
- config.autoFile = true;
352
356
  const PORT = config.port ?? 3000;
353
357
  const showPanel = config.devMode !== false;
354
358
  const autoPaging = config.autoPage !== false;
@@ -358,23 +362,244 @@ async function start() {
358
362
  const publicDir = config.autoFile === true ? path.join(process.cwd(), config.autoFileDir || "") : undefined;
359
363
  const apiDir = pagesDir ? path.join(pagesDir, "api") : undefined;
360
364
  const server = createServer(async (req, res) => {
361
- const actuallyShowPanel = showPanel;
362
- const r = augmentRes(res);
363
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
+ };
364
481
  let pathname = url.split("?")[0].split("#")[0];
482
+ const safePath = path.normalize(pathname).replace(/^(\.\.[\/\\])+/, '');
483
+ pathname = safePath;
365
484
  if (pathname !== "/" && pathname.endsWith("/"))
366
485
  pathname = pathname.slice(0, -1);
367
- if (!pathname.includes('/__authtics_host_apis__/')) {
486
+ if (!pathname.includes('/__authtics')) {
368
487
  totalRequests++;
369
488
  }
370
489
  const routeKey = `${method}:${pathname}`;
371
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
+ }
372
597
  const handler = routes.get(routeKey);
373
598
  if (typeof handler === 'string') {
374
599
  return;
375
600
  }
376
601
  else if (typeof handler === 'function') {
377
- return handler(req, r);
602
+ return handler(req, res);
378
603
  }
379
604
  }
380
605
  if (pathname === '/__authtics_hmr__') {
@@ -390,6 +615,112 @@ async function start() {
390
615
  req.on('close', () => { hmrClients.delete(res); users--; });
391
616
  return;
392
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
+ }
393
724
  if (publicDir && fs.existsSync(publicDir)) {
394
725
  const staticPath = path.join(publicDir, pathname);
395
726
  const safePath = path.resolve(staticPath);
@@ -404,7 +735,7 @@ async function start() {
404
735
  const apiFile = path.join(pagesDir, `${pathname}.ts`);
405
736
  const apiFileTsx = path.join(pagesDir, `${pathname}.tsx`);
406
737
  const resolvedApi = fs.existsSync(apiFile) ? apiFile : fs.existsSync(apiFileTsx) ? apiFileTsx : null;
407
- if (resolvedApi) {
738
+ if (resolvedApi && fs.existsSync(resolvedApi)) {
408
739
  try {
409
740
  const apiModule = await jiti.import(resolvedApi, { default: true });
410
741
  const handler = apiModule.default ?? apiModule.handler ?? null;
@@ -412,7 +743,7 @@ async function start() {
412
743
  res.writeHead(500);
413
744
  return res.end(`[authtics] API route ${pathname} must export a default function`);
414
745
  }
415
- return handler(req, r);
746
+ return handler(req, res);
416
747
  }
417
748
  catch (e) {
418
749
  console.error(`[authtics] API route error (${pathname}):`, e.message);
@@ -423,7 +754,12 @@ async function start() {
423
754
  const notFoundPath = path.join(__dirname, '404.js');
424
755
  if (fs.existsSync(notFoundPath)) {
425
756
  try {
426
- 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);
427
763
  res.setHeader("Content-Type", "text/html");
428
764
  res.writeHead(404);
429
765
  html = html.replace("<script>", "<script>\nwindow.__status_code__ = 404;");
@@ -444,7 +780,12 @@ async function start() {
444
780
  const htmlPath = pagesDir ? path.join(pagesDir, `${urlPath}.html`) : undefined;
445
781
  if (tsxPath && fs.existsSync(tsxPath)) {
446
782
  try {
447
- 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);
448
789
  res.setHeader("Content-Type", "text/html");
449
790
  return res.end(html);
450
791
  }
@@ -463,7 +804,12 @@ async function start() {
463
804
  const appPath = path.join(process.cwd(), appTsxPath);
464
805
  if (fs.existsSync(appPath)) {
465
806
  try {
466
- 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);
467
813
  res.setHeader("Content-Type", "text/html");
468
814
  return res.end(html);
469
815
  }
@@ -477,7 +823,12 @@ async function start() {
477
823
  const notFoundPath = path.join(__dirname, '404.js');
478
824
  if (fs.existsSync(notFoundPath)) {
479
825
  try {
480
- 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);
481
832
  res.setHeader("Content-Type", "text/html");
482
833
  res.writeHead(404);
483
834
  html = html.replace("<script>", "<script>\nwindow.__status_code__ = 404;");