@bananacool467/authtics-host 0.1.2 → 0.1.5
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/README.md +21 -11
- package/dist/cli.js +81 -8
- package/dist/config.d.ts +3 -3
- package/dist/config.js +12 -2
- package/dist/devPanel.js +213 -10
- package/dist/renderEngine.js +4 -4
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Authtics Host
|
|
2
2
|
|
|
3
|
-
Version 0.1.
|
|
3
|
+
Version 0.1.5
|
|
4
4
|
License: MIT
|
|
5
5
|
|
|
6
6
|
Authtics Host is a framework inspired by Next.js. Authtics Host supports SSR (Server-Side Rendering) and uses esbuild.
|
|
@@ -151,19 +151,29 @@ Then when you run your project, you will get a page just saying **"Hello, World!
|
|
|
151
151
|
|
|
152
152
|
The Developer Panel is what you could use to help you debug your code. The Developer Panel has **7 tabs**:
|
|
153
153
|
|
|
154
|
-
**Console** — Shows current logs
|
|
155
|
-
**Route** — Shows information about the current route
|
|
156
|
-
**Webpage Info** — Shows information about the website/webpage
|
|
157
|
-
**Network** — Shows the current ping and shows sent fetches from the client and shows received from the server after fetching
|
|
158
|
-
**Client Info** — Shows information about your client's User Agent, OS and FPS
|
|
159
|
-
**About Host** — Shows the current version of Authtics Host
|
|
160
|
-
**Server Info** — Shows how much heap was used and how much CPU was used on the server and how much requests there were and how much users are currently on the site and how long the site has been up
|
|
154
|
+
**Console** — Shows current logs.
|
|
155
|
+
**Route** — Shows information about the current route.
|
|
156
|
+
**Webpage Info** — Shows information about the website/webpage.
|
|
157
|
+
**Network** — Shows the current ping and shows sent fetches from the client and shows received from the server after fetching.
|
|
158
|
+
**Client Info** — Shows information about your client's User Agent, OS and FPS.
|
|
159
|
+
**About Host** — Shows the current version of Authtics Host.
|
|
160
|
+
**Server Info** — Shows how much heap was used and how much CPU was used on the server and how much requests there were and how much users are currently on the site and how long the site has been up.
|
|
161
161
|
|
|
162
|
-
The information the Developer Panel shows is just your **DAT** (Developer Access Token).
|
|
162
|
+
The information the Developer Panel shows outside of the tabs is just your **DAT** (Developer Access Token).
|
|
163
163
|
|
|
164
164
|
**(NOTE: If you do not set DAT restriction (Which will be explained on how to set it up in the next section), you will only get access to the Console and Network tabs)**
|
|
165
165
|
|
|
166
|
-
|
|
166
|
+
The Developer Panel also have remote buttons:
|
|
167
|
+
|
|
168
|
+
**Restart App** — Restarts the website.
|
|
169
|
+
**Shut Down App** — Stops the website.
|
|
170
|
+
**Pause Users**/**Resume Users** — Stops users from reaching a site and they will get a JSON error message like this when visiting if Pause Users is on:
|
|
171
|
+
```json
|
|
172
|
+
{ "message": "unhandled request" }
|
|
173
|
+
```
|
|
174
|
+
unless you click **Resume Users**.
|
|
175
|
+
|
|
176
|
+
## Developer Panel Notes And DAT (Developer Access Token)
|
|
167
177
|
|
|
168
178
|
A DAT (Developer Access Token) is your token that is used to access the Developer Panel.
|
|
169
179
|
|
|
@@ -185,7 +195,7 @@ But if you have multiple DATs, then use:
|
|
|
185
195
|
|
|
186
196
|
There isn't any limit of DATs you can add.
|
|
187
197
|
|
|
188
|
-
**(
|
|
198
|
+
**(NOTE: Adding your DAT will give you access to Restart and Shutdown and Pause/Resume Users features)**
|
|
189
199
|
|
|
190
200
|
## Contacting The Developer Of Authtics Host
|
|
191
201
|
|
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);
|
|
@@ -96,6 +97,48 @@ export default class App {
|
|
|
96
97
|
server;
|
|
97
98
|
constructor() {
|
|
98
99
|
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
|
+
this.post('/__authtics_host_apis__/set-users-paused', async (req, res) => {
|
|
115
|
+
const reqBody = (await getJsonBody(req));
|
|
116
|
+
let datMatched = false;
|
|
117
|
+
if (config_.dat && config_.dat == reqBody.dat)
|
|
118
|
+
datMatched = true;
|
|
119
|
+
if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
|
|
120
|
+
datMatched = true;
|
|
121
|
+
if (datMatched) {
|
|
122
|
+
usersPaused = reqBody.paused;
|
|
123
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
124
|
+
res.end(JSON.stringify({
|
|
125
|
+
message: "ok"
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
this.post('/__authtics_host_apis__/is-users-paused', async (req, res) => {
|
|
130
|
+
const reqBody = (await getJsonBody(req));
|
|
131
|
+
let datMatched = false;
|
|
132
|
+
if (config_.dat && config_.dat == reqBody.dat)
|
|
133
|
+
datMatched = true;
|
|
134
|
+
if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
|
|
135
|
+
datMatched = true;
|
|
136
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
137
|
+
res.end(JSON.stringify({
|
|
138
|
+
paused: (datMatched ? false : usersPaused),
|
|
139
|
+
realInfo: usersPaused
|
|
140
|
+
}));
|
|
141
|
+
});
|
|
99
142
|
this.post('/__authtics_host_apis__/get-dat-restriction-missing', async (req, res) => {
|
|
100
143
|
const reqBody = (await getJsonBody(req));
|
|
101
144
|
let datMatched = false;
|
|
@@ -266,8 +309,26 @@ export default class App {
|
|
|
266
309
|
const pathname = reqBody.pathname;
|
|
267
310
|
const pagesDir = config_.autoPage === true ? path.join(process.cwd(), config_.autoPageDir || "") : undefined;
|
|
268
311
|
const safePath = path.normalize(pathname).replace(/^(\.\.[\/\\])+/, '');
|
|
269
|
-
|
|
270
|
-
|
|
312
|
+
let filePath = pagesDir ? path.join(pagesDir, (safePath !== "/" ? safePath : "index") + ".tsx") : undefined;
|
|
313
|
+
let fileExists = filePath ? fs.existsSync(filePath) : true;
|
|
314
|
+
const publicDir = config_.autoFile === true ? path.join(process.cwd(), config_.autoFileDir || "") : undefined;
|
|
315
|
+
if (publicDir && !fileExists) {
|
|
316
|
+
const staticPath = path.join(publicDir, pathname);
|
|
317
|
+
const safePath = path.resolve(staticPath);
|
|
318
|
+
if (safePath.startsWith(path.resolve(publicDir))) {
|
|
319
|
+
filePath = safePath;
|
|
320
|
+
fileExists = fs.existsSync(safePath) && fs.statSync(safePath).isFile();
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (pathname.startsWith("/api/") && pagesDir != null && !fileExists) {
|
|
324
|
+
const apiFile = path.join(pagesDir, `${pathname}.ts`);
|
|
325
|
+
const apiFileTsx = path.join(pagesDir, `${pathname}.tsx`);
|
|
326
|
+
filePath = fs.existsSync(apiFile) ? apiFile : fs.existsSync(apiFileTsx) ? apiFileTsx : apiFile;
|
|
327
|
+
fileExists = filePath == apiFileTsx ? fs.existsSync(apiFileTsx) : fs.existsSync(apiFile);
|
|
328
|
+
}
|
|
329
|
+
if (!fileExists) {
|
|
330
|
+
filePath = "File is unresolvable. Could be because it's not found.";
|
|
331
|
+
}
|
|
271
332
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
272
333
|
res.end(JSON.stringify({
|
|
273
334
|
fileExists,
|
|
@@ -327,10 +388,6 @@ async function start() {
|
|
|
327
388
|
}
|
|
328
389
|
catch {
|
|
329
390
|
}
|
|
330
|
-
if (config.autoPage == null)
|
|
331
|
-
config.autoPage = true;
|
|
332
|
-
if (config.autoFile == null)
|
|
333
|
-
config.autoFile = true;
|
|
334
391
|
const PORT = config.port ?? 3000;
|
|
335
392
|
const showPanel = config.devMode !== false;
|
|
336
393
|
const autoPaging = config.autoPage !== false;
|
|
@@ -402,8 +459,24 @@ async function start() {
|
|
|
402
459
|
return res.end(JSON.stringify({ error: e.message }));
|
|
403
460
|
}
|
|
404
461
|
}
|
|
405
|
-
|
|
406
|
-
|
|
462
|
+
const notFoundPath = path.join(__dirname, '404.js');
|
|
463
|
+
if (fs.existsSync(notFoundPath)) {
|
|
464
|
+
try {
|
|
465
|
+
let html = await renderPage(notFoundPath, url, actuallyShowPanel, compiler, hotReload, autoPaging, config.autoPageDir, (routes.get("APP_TSX") || ""));
|
|
466
|
+
res.setHeader("Content-Type", "text/html");
|
|
467
|
+
res.writeHead(404);
|
|
468
|
+
html = html.replace("<script>", "<script>\nwindow.__status_code__ = 404;");
|
|
469
|
+
res.end(html);
|
|
470
|
+
}
|
|
471
|
+
catch (e) {
|
|
472
|
+
res.writeHead(404);
|
|
473
|
+
res.end(`<html><head></head><body><center><b>404</b> | Not found: ${url}</center></body></html>`);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
res.writeHead(404);
|
|
478
|
+
res.end(`<html><head></head><body><center><b>404</b> | Not found: ${url}</center></body></html>`);
|
|
479
|
+
}
|
|
407
480
|
}
|
|
408
481
|
const urlPath = pathname === "/" ? "/index" : pathname;
|
|
409
482
|
const tsxPath = pagesDir ? path.join(pagesDir, `${urlPath}.tsx`) : undefined;
|
package/dist/config.d.ts
CHANGED
|
@@ -6,10 +6,10 @@ export interface AuthticsConfig {
|
|
|
6
6
|
compilerType?: 'esbuild' | 'babel';
|
|
7
7
|
hotReload?: boolean;
|
|
8
8
|
dat?: string | string[];
|
|
9
|
-
showError?: boolean
|
|
10
|
-
autoPage?: boolean
|
|
9
|
+
showError?: boolean;
|
|
10
|
+
autoPage?: boolean;
|
|
11
11
|
autoPageDir?: string;
|
|
12
|
-
autoFile?: boolean
|
|
12
|
+
autoFile?: boolean;
|
|
13
13
|
autoFileDir?: string;
|
|
14
14
|
}
|
|
15
15
|
export declare function defineConfig(config: AuthticsConfig): AuthticsConfig;
|
package/dist/config.js
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
export function defineConfig(config) {
|
|
2
|
-
if (config.autoPage ==
|
|
2
|
+
if (config.autoPage == undefined)
|
|
3
3
|
config.autoPage = true;
|
|
4
|
-
if (config.autoFile ==
|
|
4
|
+
if (config.autoFile == undefined)
|
|
5
5
|
config.autoFile = true;
|
|
6
|
+
if (config.showError == undefined)
|
|
7
|
+
config.showError = true;
|
|
8
|
+
if (config.compilerType == undefined)
|
|
9
|
+
config.compilerType = 'esbuild';
|
|
10
|
+
if (config.ssr == undefined)
|
|
11
|
+
config.ssr = true;
|
|
12
|
+
if (config.port == undefined || config.port == 0)
|
|
13
|
+
config.port = 3000;
|
|
14
|
+
if (config.devMode == undefined)
|
|
15
|
+
config.devMode = true;
|
|
6
16
|
return config;
|
|
7
17
|
}
|
package/dist/devPanel.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import React, { useState, useEffect, useRef } from 'react';
|
|
3
|
-
import { ShieldCheck, CircleX, ChevronDown, ChevronUp, Bug, AlertTriangle, Info, ArrowLeft, Wifi, Terminal, Route, Globe, ChevronRight, ChevronLeft, Server, TriangleAlert, Eye } from 'lucide-react';
|
|
3
|
+
import { ShieldCheck, CircleX, ChevronDown, ChevronUp, Bug, AlertTriangle, Info, ArrowLeft, Wifi, Terminal, Route, Globe, ChevronRight, ChevronLeft, Server, TriangleAlert, Eye, Zap } from 'lucide-react';
|
|
4
4
|
import Prism from 'prismjs';
|
|
5
5
|
import 'prismjs/components/prism-javascript';
|
|
6
6
|
Prism.languages.javascript['builtin'] = /\b(window|document|console|navigator|localStorage|sessionStorage|fetch|Promise|setTimeout|setInterval|clearTimeout|clearInterval|requestAnimationFrame|Math|JSON|Object|Array|String|Number|Boolean|Date|RegExp|Error|Map|Set|Symbol|Proxy|Reflect|performance|history|location|screen|crypto|indexedDB|alert|confirm|prompt)\b/;
|
|
@@ -63,7 +63,7 @@ function Sparkline({ data, color, label, unit }) {
|
|
|
63
63
|
return _jsx("circle", { cx: last[0], cy: last[1], r: "2.5", fill: color });
|
|
64
64
|
})()] }))] })] }));
|
|
65
65
|
}
|
|
66
|
-
function installNetworkInterceptor(onFetch, setFetch, onBytesClient, onBytesServer) {
|
|
66
|
+
function installNetworkInterceptor(onFetch, setFetch, onEventSource, setEventSource, onWebSocket, setWebSocket, onResource, setResource, onBytesClient, onBytesServer) {
|
|
67
67
|
if (window.__authtics_network_intercepted__)
|
|
68
68
|
return;
|
|
69
69
|
window.__authtics_network_intercepted__ = true;
|
|
@@ -100,6 +100,144 @@ function installNetworkInterceptor(onFetch, setFetch, onBytesClient, onBytesServ
|
|
|
100
100
|
throw e;
|
|
101
101
|
}
|
|
102
102
|
};
|
|
103
|
+
const OriginalWebSocket = window.WebSocket;
|
|
104
|
+
window.WebSocket = function (url, protocols) {
|
|
105
|
+
fetchId++;
|
|
106
|
+
const savedId = fetchId;
|
|
107
|
+
const ws = new OriginalWebSocket(url, protocols);
|
|
108
|
+
if (url.includes('__authtics'))
|
|
109
|
+
return ws;
|
|
110
|
+
onWebSocket({
|
|
111
|
+
url,
|
|
112
|
+
status: 'Connecting...',
|
|
113
|
+
id: savedId,
|
|
114
|
+
type: "WebSocket"
|
|
115
|
+
});
|
|
116
|
+
ws.addEventListener('open', () => {
|
|
117
|
+
setWebSocket({
|
|
118
|
+
url,
|
|
119
|
+
status: 'Connected',
|
|
120
|
+
id: savedId,
|
|
121
|
+
type: "WebSocket"
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
ws.addEventListener('close', () => {
|
|
125
|
+
setWebSocket({
|
|
126
|
+
url,
|
|
127
|
+
status: 'Disconnected',
|
|
128
|
+
id: savedId,
|
|
129
|
+
type: "WebSocket"
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
ws.addEventListener('message', (event) => {
|
|
133
|
+
const bytes = new Blob([event.data]).size;
|
|
134
|
+
onBytesServer(bytes);
|
|
135
|
+
setWebSocket({
|
|
136
|
+
url,
|
|
137
|
+
status: 'Connected',
|
|
138
|
+
id: savedId,
|
|
139
|
+
type: "WebSocket"
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
ws.addEventListener('error', () => {
|
|
143
|
+
const status = ws.readyState === OriginalWebSocket.CLOSED
|
|
144
|
+
? 'Disconnected'
|
|
145
|
+
: 'Connection Failed';
|
|
146
|
+
setWebSocket({
|
|
147
|
+
url,
|
|
148
|
+
status,
|
|
149
|
+
id: savedId,
|
|
150
|
+
type: "WebSocket"
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
const OriginalSend = ws.send;
|
|
154
|
+
ws.send = function (data) {
|
|
155
|
+
let bytes = 0;
|
|
156
|
+
if (typeof data === 'string') {
|
|
157
|
+
bytes = new Blob([data]).size;
|
|
158
|
+
}
|
|
159
|
+
else if (data instanceof Blob) {
|
|
160
|
+
bytes = data.size;
|
|
161
|
+
}
|
|
162
|
+
else if (data instanceof ArrayBuffer || data instanceof SharedArrayBuffer) {
|
|
163
|
+
bytes = data.byteLength;
|
|
164
|
+
}
|
|
165
|
+
else if (ArrayBuffer.isView(data)) {
|
|
166
|
+
bytes = data.byteLength;
|
|
167
|
+
}
|
|
168
|
+
onBytesClient(bytes);
|
|
169
|
+
OriginalSend.call(this, data);
|
|
170
|
+
};
|
|
171
|
+
return ws;
|
|
172
|
+
};
|
|
173
|
+
Object.defineProperty(window.WebSocket, 'prototype', {
|
|
174
|
+
value: OriginalWebSocket.prototype,
|
|
175
|
+
writable: false
|
|
176
|
+
});
|
|
177
|
+
Object.assign(window.WebSocket, OriginalWebSocket);
|
|
178
|
+
const OriginalEventSource = window.EventSource;
|
|
179
|
+
window.EventSource = function (url, eventSourceInitDict) {
|
|
180
|
+
fetchId++;
|
|
181
|
+
const savedId = fetchId;
|
|
182
|
+
const es = new OriginalEventSource(url, eventSourceInitDict);
|
|
183
|
+
if (url.includes('__authtics'))
|
|
184
|
+
return es;
|
|
185
|
+
onEventSource({
|
|
186
|
+
url,
|
|
187
|
+
status: 'Connecting...',
|
|
188
|
+
id: savedId,
|
|
189
|
+
type: "EventSource"
|
|
190
|
+
});
|
|
191
|
+
es.addEventListener('open', () => {
|
|
192
|
+
setEventSource({
|
|
193
|
+
url,
|
|
194
|
+
status: 'Connected',
|
|
195
|
+
id: savedId,
|
|
196
|
+
type: "EventSource"
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
es.addEventListener('message', (event) => {
|
|
200
|
+
const bytes = new Blob([event.data]).size;
|
|
201
|
+
onBytesServer(bytes);
|
|
202
|
+
setEventSource({
|
|
203
|
+
url,
|
|
204
|
+
status: 'Connected',
|
|
205
|
+
id: savedId,
|
|
206
|
+
type: "EventSource"
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
es.addEventListener('error', () => {
|
|
210
|
+
const status = es.readyState === OriginalEventSource.CLOSED
|
|
211
|
+
? 'Disconnected'
|
|
212
|
+
: 'Connection Failed';
|
|
213
|
+
setEventSource({
|
|
214
|
+
url,
|
|
215
|
+
status: status,
|
|
216
|
+
id: savedId,
|
|
217
|
+
type: "EventSource"
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
return es;
|
|
221
|
+
};
|
|
222
|
+
window.EventSource.prototype = OriginalEventSource.prototype;
|
|
223
|
+
Object.assign(window.EventSource, OriginalEventSource);
|
|
224
|
+
setTimeout(() => {
|
|
225
|
+
const queryImg = document.querySelectorAll('img');
|
|
226
|
+
const queryScript = document.querySelectorAll('script');
|
|
227
|
+
const queryLink = document.querySelectorAll('link');
|
|
228
|
+
queryImg.forEach((img) => {
|
|
229
|
+
if (img.src)
|
|
230
|
+
onResource({ url: img.src, type: 'img', id: fetchId++ });
|
|
231
|
+
});
|
|
232
|
+
queryScript.forEach((script) => {
|
|
233
|
+
if (script.src)
|
|
234
|
+
onResource({ url: script.src, type: 'script', id: fetchId++ });
|
|
235
|
+
});
|
|
236
|
+
queryLink.forEach((link) => {
|
|
237
|
+
if (link.href)
|
|
238
|
+
onResource({ url: link.href, type: 'link', id: fetchId++ });
|
|
239
|
+
});
|
|
240
|
+
}, 5000);
|
|
103
241
|
}
|
|
104
242
|
function installConsoleInterceptor() {
|
|
105
243
|
if (window.__authtics_intercepted__)
|
|
@@ -171,6 +309,11 @@ export default function DevPanel() {
|
|
|
171
309
|
const [hasIssue, setHasIssue] = useState(false);
|
|
172
310
|
const [ping__, setPing__] = useState(0);
|
|
173
311
|
const [networkFetches, setNetworkFetches] = useState([]);
|
|
312
|
+
const [eventSources, setEventSources] = useState([]);
|
|
313
|
+
const [usersPaused, setUsersPaused] = useState(false);
|
|
314
|
+
const [usersPausedRealInfo, setUsersPausedRealInfo] = useState(false);
|
|
315
|
+
const [webSockets, setWebSockets] = useState([]);
|
|
316
|
+
const [resourcesFound, setResourcesFound] = useState([]);
|
|
174
317
|
const [status, setStatus] = useState(200);
|
|
175
318
|
const [code, setCode] = useState('');
|
|
176
319
|
const [pathName, setPathName] = useState(undefined);
|
|
@@ -254,7 +397,19 @@ export default function DevPanel() {
|
|
|
254
397
|
if (resp.status === 200) {
|
|
255
398
|
const data = await resp.json();
|
|
256
399
|
setDatMatch(data.isMatching);
|
|
257
|
-
|
|
400
|
+
const resp3 = await fetch('/__authtics_host_apis__/is-users-paused', {
|
|
401
|
+
method: 'POST',
|
|
402
|
+
headers: { 'Content-Type': 'application/json' },
|
|
403
|
+
body: JSON.stringify({ dat: localStorage.getItem('dat') })
|
|
404
|
+
});
|
|
405
|
+
let paused = false;
|
|
406
|
+
if (resp3.status === 200) {
|
|
407
|
+
const data = await resp3.json();
|
|
408
|
+
paused = data.paused;
|
|
409
|
+
setUsersPaused(paused);
|
|
410
|
+
setUsersPausedRealInfo(data.realInfo);
|
|
411
|
+
}
|
|
412
|
+
if (!data.isMatching && !paused) {
|
|
258
413
|
doc?.getElementById('authtics-dev-panel-root')?.remove();
|
|
259
414
|
}
|
|
260
415
|
const resp2 = await fetch('/__authtics_host_apis__/get-dat-restriction-missing', {
|
|
@@ -369,11 +524,9 @@ export default function DevPanel() {
|
|
|
369
524
|
isSSR();
|
|
370
525
|
userSettings();
|
|
371
526
|
getHostVersion();
|
|
372
|
-
setInterval(() => {
|
|
373
|
-
getUsage();
|
|
374
|
-
}, 250);
|
|
375
527
|
setInterval(() => {
|
|
376
528
|
update();
|
|
529
|
+
getUsage();
|
|
377
530
|
}, 500);
|
|
378
531
|
}
|
|
379
532
|
}, 250);
|
|
@@ -469,7 +622,7 @@ export default function DevPanel() {
|
|
|
469
622
|
}, []);
|
|
470
623
|
useEffect(() => {
|
|
471
624
|
installConsoleInterceptor();
|
|
472
|
-
installNetworkInterceptor((f) => setNetworkFetches(prev => [...prev.slice(-49), f]), (f) => setNetworkFetches(prev => prev.map(p => p.id === f.id ? f : p)), (sent) => {
|
|
625
|
+
installNetworkInterceptor((f) => setNetworkFetches(prev => [...prev.slice(-49), f]), (f) => setNetworkFetches(prev => prev.map(p => p.id === f.id ? f : p)), (f) => setEventSources(prev => [...prev.slice(-49), f]), (f) => setEventSources(prev => prev.map(p => p.id === f.id ? f : p)), (f) => setWebSockets(prev => [...prev.slice(-49), f]), (f) => setWebSockets(prev => prev.map(p => p.id === f.id ? f : p)), (f) => setResourcesFound(prev => [...prev.slice(-49), f]), (f) => setResourcesFound(prev => prev.map(p => p.id === f.id ? f : p)), (sent) => {
|
|
473
626
|
pendingSent.current += sent;
|
|
474
627
|
}, (received) => {
|
|
475
628
|
pendingReceived.current += received;
|
|
@@ -595,6 +748,38 @@ export default function DevPanel() {
|
|
|
595
748
|
}
|
|
596
749
|
}));
|
|
597
750
|
};
|
|
751
|
+
const pause_Resume_Users = async () => {
|
|
752
|
+
if (usersPausedRealInfo) {
|
|
753
|
+
const resp = await fetch('/__authtics_host_apis__/set-users-paused', {
|
|
754
|
+
method: 'POST',
|
|
755
|
+
headers: { 'Content-Type': 'application/json' },
|
|
756
|
+
body: JSON.stringify({
|
|
757
|
+
dat: localStorage.getItem('dat'),
|
|
758
|
+
paused: false
|
|
759
|
+
})
|
|
760
|
+
});
|
|
761
|
+
if (resp.status === 200) {
|
|
762
|
+
setUsersPausedRealInfo(false);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
else {
|
|
766
|
+
const resp = await fetch('/__authtics_host_apis__/set-users-paused', {
|
|
767
|
+
method: 'POST',
|
|
768
|
+
headers: { 'Content-Type': 'application/json' },
|
|
769
|
+
body: JSON.stringify({
|
|
770
|
+
dat: localStorage.getItem('dat'),
|
|
771
|
+
paused: true
|
|
772
|
+
})
|
|
773
|
+
});
|
|
774
|
+
if (resp.status === 200) {
|
|
775
|
+
setUsersPausedRealInfo(true);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
};
|
|
779
|
+
if (usersPaused) {
|
|
780
|
+
doc?.getElementById('root')?.remove();
|
|
781
|
+
window.location.href = '/failed-to-handle';
|
|
782
|
+
}
|
|
598
783
|
return (_jsxs(_Fragment, { children: [_jsx("div", { style: {
|
|
599
784
|
position: 'absolute',
|
|
600
785
|
zIndex: 999999,
|
|
@@ -733,7 +918,7 @@ export default function DevPanel() {
|
|
|
733
918
|
border: '1px solid #eee',
|
|
734
919
|
fontSize: '12px',
|
|
735
920
|
color: '#333',
|
|
736
|
-
}, children: [_jsx("span", { children: "Ping" }), _jsx("span", { style: { color: ping__ < 100 ? '#16a34a' : ping__ < 300 ? '#d97706' : '#e53e3e', fontFamily: 'monospace' }, children: ping__ > 0 ? `${ping__}ms` : '??ms' })] }), datRestrictionMissing ? (_jsxs("span", { style: { display: 'flex', opacity: 0.5, fontSize: 10, justifyContent: 'center', alignItems: 'center', gap: '4px' }, children: [_jsx(Info, { size: 10 }), "this analytic is unavaliable. Set \"dat\" in the Authtics Host config to set restriction and then restart."] })) : (_jsx(_Fragment, {})), _jsx(Sparkline, { data: receivedHistory, color: "#3b82f6", label: "Received", unit: " bytes" }), _jsx(Sparkline, { data: sentHistory, color: "#16a34a", label: "Sent", unit: " bytes" }), networkFetches.length === 0
|
|
921
|
+
}, children: [_jsx("span", { children: "Ping" }), _jsx("span", { style: { color: ping__ < 100 ? '#16a34a' : ping__ < 300 ? '#d97706' : '#e53e3e', fontFamily: 'monospace' }, children: ping__ > 0 ? `${ping__}ms` : '??ms' })] }), datRestrictionMissing ? (_jsxs("span", { style: { display: 'flex', opacity: 0.5, fontSize: 10, justifyContent: 'center', alignItems: 'center', gap: '4px' }, children: [_jsx(Info, { size: 10 }), "this analytic is unavaliable. Set \"dat\" in the Authtics Host config to set restriction and then restart."] })) : (_jsx(_Fragment, {})), _jsx(Sparkline, { data: receivedHistory, color: "#3b82f6", label: "Received", unit: " bytes" }), _jsx(Sparkline, { data: sentHistory, color: "#16a34a", label: "Sent", unit: " bytes" }), _jsxs("span", { style: { fontSize: '15px', color: '#333', fontWeight: 'bold' }, children: ["Fetches \u2014 ", networkFetches.length, " total fetches"] }), networkFetches.length === 0
|
|
737
922
|
? _jsx("div", { style: { color: '#aaa', fontSize: '12px', padding: '4px 2px' }, children: "No network requests yet." })
|
|
738
923
|
: [...networkFetches].reverse().map((f, i) => (_jsxs("div", { style: {
|
|
739
924
|
background: '#fff',
|
|
@@ -753,7 +938,25 @@ export default function DevPanel() {
|
|
|
753
938
|
obj___.innerText = f.response?.slice(0, 100) + "...";
|
|
754
939
|
obj___.removeAttribute('expanded');
|
|
755
940
|
e.currentTarget.innerText = `View more (${f.response ? (f.response.split('').length - 100) : 0} bytes hidden)`;
|
|
756
|
-
} }, style: { padding: '8px 10px', borderRadius: '10px', background: '#34a8eb', color: '#fff', border: 'none', cursor: 'pointer', margin: '10px', textAlign: 'center', fontFamily: 'system-ui, sans-serif' }, children: ["View more (", f.response ? (f.response.split('').length - 100) : 0, " bytes hidden)"] })) : (_jsx(_Fragment, {}))) : (_jsx(_Fragment, {}))] }, i)))
|
|
941
|
+
} }, style: { padding: '8px 10px', borderRadius: '10px', background: '#34a8eb', color: '#fff', border: 'none', cursor: 'pointer', margin: '10px', textAlign: 'center', fontFamily: 'system-ui, sans-serif' }, children: ["View more (", f.response ? (f.response.split('').length - 100) : 0, " bytes hidden)"] })) : (_jsx(_Fragment, {}))) : (_jsx(_Fragment, {}))] }, i))), _jsx("span", { style: { fontSize: '15px', color: '#333', fontWeight: 'bold' }, children: "Active connections" }), eventSources.length === 0 ? (_jsx("div", { style: { color: '#aaa', fontSize: '12px', padding: '4px 2px' }, children: "No active connections." })) :
|
|
942
|
+
[...eventSources, ...webSockets].reverse().map((es, i) => (_jsx("div", { style: {
|
|
943
|
+
background: '#fff',
|
|
944
|
+
display: 'flex',
|
|
945
|
+
flexDirection: 'column',
|
|
946
|
+
borderRadius: '10px',
|
|
947
|
+
border: '1px solid #eee',
|
|
948
|
+
fontSize: '11px',
|
|
949
|
+
fontFamily: 'monospace'
|
|
950
|
+
}, children: _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', gap: '8px', padding: '6px 10px' }, children: [_jsxs("span", { style: { color: '#3b82f6', display: 'flex', gap: '4px', justifyContent: 'center', alignItems: 'center' }, children: [es.type === "EventSource" ? _jsx(Zap, { color: "green", size: 12 }) : es.type === "WebSocket" ? _jsx(Globe, { color: "green", size: 12 }) : _jsx(_Fragment, {}), es.type === "EventSource" ? "Event Source" : es.type === "WebSocket" ? "Web Socket" : "???"] }), _jsx("span", { style: { flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', color: '#333' }, children: es.url }), _jsx("span", { style: { color: es.status === 'Connected' ? '#16a34a' : es.status === 'Disconnected' ? '#e53e3e' : 'orange' }, children: es.status === 'Connected' ? 'Active' : es.status === 'Disconnected' ? 'Disconnected' : es.status === 'Connecting...' ? '...' : es.status === 'Connection Failed' ? 'Failed' : 'Unknown' })] }) }, i))), _jsxs("span", { style: { fontSize: '15px', color: '#333', fontWeight: 'bold' }, children: ["Resources Found \u2014 ", resourcesFound.length, " total resources"] }), resourcesFound.length === 0 ? (_jsx("div", { style: { color: '#aaa', fontSize: '12px', padding: '4px 2px' }, children: "No resources found." })) :
|
|
951
|
+
[...resourcesFound].reverse().map((r, i) => (_jsx("div", { style: {
|
|
952
|
+
background: '#fff',
|
|
953
|
+
display: 'flex',
|
|
954
|
+
flexDirection: 'column',
|
|
955
|
+
borderRadius: '10px',
|
|
956
|
+
border: '1px solid #eee',
|
|
957
|
+
fontSize: '11px',
|
|
958
|
+
fontFamily: 'monospace'
|
|
959
|
+
}, children: _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', gap: '8px', padding: '6px 10px' }, children: [_jsx("span", { style: { color: '#3b82f6', display: 'flex', gap: '4px', justifyContent: 'center', alignItems: 'center' }, children: r.type }), _jsx("span", { style: { flex: 1, color: '#333' }, children: r.url })] }) }, i)))] })] })) : routeOpen ? (_jsxs(_Fragment, { children: [_jsxs("div", { style: {
|
|
757
960
|
padding: '6px 8px',
|
|
758
961
|
borderBottom: '1px solid #ddd',
|
|
759
962
|
background: '#fff',
|
|
@@ -997,7 +1200,7 @@ export default function DevPanel() {
|
|
|
997
1200
|
gap: '6px',
|
|
998
1201
|
color: '#fff',
|
|
999
1202
|
flexDirection: 'row',
|
|
1000
|
-
}, children: "Updates to security. Apps with version 0.0.1-beta.9 and over will now require DAT restriction to access remote features like restarting and shutting down the app." }) })) : (_jsx(_Fragment, {})), _jsx(PanelButton, { onClick: () => { restart(); }, fullWidth: true, style: { color: '#fff', justifyContent: 'center', height: '32px', background: '#ba4e4e' }, disabled: datRestrictionMissing, children: _jsx("span", { style: { display: 'flex', alignItems: 'center', gap: '6px', textAlign: 'center' }, children: "Restart App" }) }), datRestrictionMissing ? (_jsxs("span", { style: { display: 'flex', opacity: 0.5, fontSize: 10, justifyContent: 'center', alignItems: 'center', gap: '4px' }, children: [_jsx(Info, { size: 10 }), "Restarting the app is unavaliable. Set \"dat\" in the Authtics Host config to set restriction and then restart."] })) : (_jsx(_Fragment, {})), _jsx(PanelButton, { onClick: () => { shutDown(); }, fullWidth: true, style: { color: '#fff', justifyContent: 'center', height: '32px', background: '#ba4e4e' }, disabled: datRestrictionMissing, children: _jsx("span", { style: { display: 'flex', alignItems: 'center', gap: '6px', textAlign: 'center' }, children: "Shut Down App" }) }), datRestrictionMissing ? (_jsxs("span", { style: { display: 'flex', opacity: 0.5, fontSize: 10, justifyContent: 'center', alignItems: 'center', gap: '4px' }, children: [_jsx(Info, { size: 10 }), "Shutting down the app is unavaliable. Set \"dat\" in the Authtics Host config to set restriction and then restart."] })) : (_jsx(_Fragment, {}))] })] })) }) }), datMatch ? (_jsxs("div", { onClick: () => setOpen(o => !o), style: {
|
|
1203
|
+
}, children: "Updates to security. Apps with version 0.0.1-beta.9 and over will now require DAT restriction to access remote features like restarting and shutting down the app." }) })) : (_jsx(_Fragment, {})), _jsx(PanelButton, { onClick: () => { restart(); }, fullWidth: true, style: { color: '#fff', justifyContent: 'center', height: '32px', background: '#ba4e4e' }, disabled: datRestrictionMissing, children: _jsx("span", { style: { display: 'flex', alignItems: 'center', gap: '6px', textAlign: 'center' }, children: "Restart App" }) }), datRestrictionMissing ? (_jsxs("span", { style: { display: 'flex', opacity: 0.5, fontSize: 10, justifyContent: 'center', alignItems: 'center', gap: '4px' }, children: [_jsx(Info, { size: 10 }), "Restarting the app is unavaliable. Set \"dat\" in the Authtics Host config to set restriction and then restart."] })) : (_jsx(_Fragment, {})), _jsx(PanelButton, { onClick: () => { shutDown(); }, fullWidth: true, style: { color: '#fff', justifyContent: 'center', height: '32px', background: '#ba4e4e' }, disabled: datRestrictionMissing, children: _jsx("span", { style: { display: 'flex', alignItems: 'center', gap: '6px', textAlign: 'center' }, children: "Shut Down App" }) }), datRestrictionMissing ? (_jsxs("span", { style: { display: 'flex', opacity: 0.5, fontSize: 10, justifyContent: 'center', alignItems: 'center', gap: '4px' }, children: [_jsx(Info, { size: 10 }), "Shutting down the app is unavaliable. Set \"dat\" in the Authtics Host config to set restriction and then restart."] })) : (_jsx(_Fragment, {})), _jsx(PanelButton, { onClick: () => { pause_Resume_Users(); }, fullWidth: true, style: { color: '#fff', justifyContent: 'center', height: '32px', background: '#ba4e4e' }, disabled: datRestrictionMissing, children: _jsx("span", { style: { display: 'flex', alignItems: 'center', gap: '6px', textAlign: 'center' }, children: usersPausedRealInfo ? "Resume Users" : "Pause Users" }) }), datRestrictionMissing ? (_jsxs("span", { style: { display: 'flex', opacity: 0.5, fontSize: 10, justifyContent: 'center', alignItems: 'center', gap: '4px' }, children: [_jsx(Info, { size: 10 }), "Pausing users from accessing the app is unavaliable. Set \"dat\" in the Authtics Host config to set restriction and then restart."] })) : (_jsx(_Fragment, {}))] })] })) }) }), datMatch ? (_jsxs("div", { onClick: () => setOpen(o => !o), style: {
|
|
1001
1204
|
display: 'flex',
|
|
1002
1205
|
flexDirection: 'row',
|
|
1003
1206
|
alignItems: 'center',
|
package/dist/renderEngine.js
CHANGED
|
@@ -162,23 +162,23 @@ export async function renderPage(tsxPath, reqUrl, showPanel = true, compiler = '
|
|
|
162
162
|
}
|
|
163
163
|
if (!clientCode || !serverCode) {
|
|
164
164
|
const virtualServer = `
|
|
165
|
-
import Page from ${JSON.stringify(tsxPath)};
|
|
166
165
|
${usesDevPanel ? `import DevPanel from ${JSON.stringify(devPanelPath)};` : ""}
|
|
166
|
+
import Page from ${JSON.stringify(tsxPath)};
|
|
167
167
|
export default Page;
|
|
168
168
|
${usesDevPanel ? `export { DevPanel };` : ""}
|
|
169
169
|
`;
|
|
170
170
|
const virtualClient = `
|
|
171
171
|
import React from "react";
|
|
172
172
|
import { hydrateRoot } from "react-dom/client";
|
|
173
|
-
import Page from ${JSON.stringify(tsxPath)};
|
|
174
173
|
${usesDevPanel ? `import DevPanel from ${JSON.stringify(devPanelPath)};` : ""}
|
|
174
|
+
import Page from ${JSON.stringify(tsxPath)};
|
|
175
175
|
|
|
176
|
-
const rootEl = document.getElementById("root");
|
|
177
|
-
if (rootEl) hydrateRoot(rootEl, React.createElement(Page));
|
|
178
176
|
${usesDevPanel ? `
|
|
179
177
|
const panelEl = document.getElementById("authtics-dev-panel-root");
|
|
180
178
|
if (panelEl) hydrateRoot(panelEl, React.createElement(DevPanel));
|
|
181
179
|
` : ""}
|
|
180
|
+
const rootEl = document.getElementById("root");
|
|
181
|
+
if (rootEl) hydrateRoot(rootEl, React.createElement(Page));
|
|
182
182
|
`;
|
|
183
183
|
if (compiler === 'babel') {
|
|
184
184
|
serverCode = await buildWithBabel(tsxPath, virtualServer, 'node');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bananacool467/authtics-host",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "A Next.js-inspired SSR framework for Node.js with TypeScript and JSX support.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
"dev",
|
|
38
38
|
"developer",
|
|
39
39
|
"HostJS",
|
|
40
|
-
"Host.js"
|
|
40
|
+
"Host.js",
|
|
41
|
+
"website"
|
|
41
42
|
],
|
|
42
43
|
"author": "bananacool467",
|
|
43
44
|
"license": "MIT",
|
|
@@ -46,8 +47,6 @@
|
|
|
46
47
|
"@babel/preset-env": "^7.29.0",
|
|
47
48
|
"@babel/preset-react": "^7.28.5",
|
|
48
49
|
"@babel/preset-typescript": "^7.28.5",
|
|
49
|
-
"@types/babel__core": "^7.20.5",
|
|
50
|
-
"@types/babel__preset-env": "^7.10.0",
|
|
51
50
|
"esbuild": "^0.27.3",
|
|
52
51
|
"jiti": "^2.6.1",
|
|
53
52
|
"lucide-react": "^0.577.0",
|
|
@@ -63,6 +62,8 @@
|
|
|
63
62
|
"@types/prismjs": "^1.26.6",
|
|
64
63
|
"@types/react": "^19.2.14",
|
|
65
64
|
"@types/react-dom": "^19.2.3",
|
|
66
|
-
"@types/react-syntax-highlighter": "^15.5.13"
|
|
65
|
+
"@types/react-syntax-highlighter": "^15.5.13",
|
|
66
|
+
"@types/babel__core": "^7.20.5",
|
|
67
|
+
"@types/babel__preset-env": "^7.10.0"
|
|
67
68
|
}
|
|
68
69
|
}
|