@bananacool467/authtics-host 0.0.1-beta.7 → 0.0.1-beta.9

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 CHANGED
@@ -1,9 +1,11 @@
1
1
  # Authtics Host
2
2
 
3
- Version 0.0.1-beta.7
3
+ Version 0.0.1-beta.9
4
4
  License: MIT
5
5
 
6
- (NOTE: This version is in BETA, bugs are expected)
6
+ **(UPDATE (Security Update): Now versions, 0.0.1-beta.9 and over now requires DAT (Developer Access Token) restriction to access remote controls such as: Restarting and Shutting Down)**
7
+
8
+ **(NOTE: This version is in BETA, bugs are expected)**
7
9
 
8
10
  Authtics Host is a framework inspired by Next.js. Authtics Host supports SSR (Server-Side Rendering) and uses esbuild.
9
11
 
@@ -33,14 +35,14 @@ To make your app, with auto paging and auto filing, your file tree should look l
33
35
 
34
36
  **(NOTE: the public folder is for auto filing)**
35
37
 
36
- index.ts should look like:
38
+ `index.ts` should look like:
37
39
  ```ts
38
40
  import { App } from "@bananacool467/authtics-host";
39
41
 
40
42
  const app = new App();
41
43
  ```
42
44
 
43
- authtics_host.config.ts should look like:
45
+ `authtics_host.config.ts` should look like:
44
46
  ```ts
45
47
  import { defineConfig } from "@bananacool467/authtics-host";
46
48
 
@@ -55,7 +57,7 @@ export default defineConfig({
55
57
  })
56
58
  ```
57
59
 
58
- client/pages/index.tsx should look like:
60
+ `client/pages/index.tsx` should look like:
59
61
  ```tsx
60
62
  export default function Index () {
61
63
  return (
@@ -75,7 +77,7 @@ To make your app, without auto paging and auto filing, your file tree should loo
75
77
  index.tsx
76
78
  ```
77
79
 
78
- index.ts should look like:
80
+ `index.ts` should look like:
79
81
  ```ts
80
82
  import { App } from "@bananacool467/authtics-host";
81
83
 
@@ -83,7 +85,7 @@ const app = new App();
83
85
  app.registerApp("client/app.tsx");
84
86
  ```
85
87
 
86
- authtics_host.config.ts should look like:
88
+ `authtics_host.config.ts` should look like:
87
89
  ```ts
88
90
  import { defineConfig } from "@bananacool467/authtics-host";
89
91
 
@@ -96,7 +98,7 @@ export default defineConfig({
96
98
  })
97
99
  ```
98
100
 
99
- client/app.tsx should look like:
101
+ `client/app.tsx` should look like:
100
102
  ```tsx
101
103
  import { Route } from "@bananacool467/authtics-host";
102
104
  import Index from "./pages/index";
@@ -110,7 +112,7 @@ export default function App() {
110
112
  }
111
113
  ```
112
114
 
113
- client/pages/index.tsx should look like:
115
+ `client/pages/index.tsx` should look like:
114
116
  ```tsx
115
117
  export default function Index () {
116
118
  return (
@@ -119,14 +121,14 @@ export default function Index () {
119
121
  }
120
122
  ```
121
123
 
122
- ## To run the project
124
+ ## To Run The Project
123
125
 
124
- Make sure Node 22 is installed:
126
+ Make sure **Node 22** is installed:
125
127
  ```
126
128
  nvm install 22
127
129
  ```
128
130
 
129
- To switch to Node 22 use:
131
+ To switch to **Node 22** use:
130
132
  ```
131
133
  nvm use 22
132
134
  ```
@@ -138,9 +140,9 @@ node --experimental-strip-types index.ts
138
140
 
139
141
  ## Result
140
142
 
141
- Then when you run your project, you will get a page just saying **"Hello, World!"** and you should see a panel at the bottom-right.
143
+ Then when you run your project, you will get a page just saying **"Hello, World!"** and you should see a clickable Developer Panel at the bottom-right.
142
144
 
143
- ## Developer Panel Notes and Warnings And DAT (Developer Access Token)
145
+ ## Developer Panel Notes And Warnings And DAT (Developer Access Token)
144
146
 
145
147
  A DAT (Developer Access Token) is your token that is used to access the Developer Panel.
146
148
 
@@ -164,6 +166,6 @@ There isn't any limit of DATs you can add.
164
166
 
165
167
  **(Warning: Make sure `devMode` is set to `false` in production. If `devMode` is on and DAT restriction is disabled, anyone can access the restart and shutdown endpoints.)**
166
168
 
167
- ## Contacting
169
+ ## Contacting The Developer Of Authtics Host
168
170
 
169
171
  If you ever encounter a bug, report it to (or have questions, contact): authtics@proton.me
package/dist/cli.js CHANGED
@@ -110,6 +110,39 @@ export default class App {
110
110
  server;
111
111
  constructor() {
112
112
  this.server = start();
113
+ this.post('/__authtics_host_apis__/get-dat-restriction-missing', async (req, res) => {
114
+ const reqBody = (await getJsonBody(req));
115
+ let datMatched = false;
116
+ let datRestrictedEnv = false;
117
+ if (config_.dat && config_.dat == reqBody.dat)
118
+ datMatched = true;
119
+ if (config_.dat == undefined)
120
+ datMatched = true;
121
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
122
+ datMatched = true;
123
+ if (datMatched) {
124
+ if (config_.dat !== undefined)
125
+ datRestrictedEnv = true;
126
+ res.writeHead(200, { "Content-Type": "application/json" });
127
+ res.end(JSON.stringify({
128
+ enabled: datRestrictedEnv
129
+ }));
130
+ }
131
+ });
132
+ this.post('/__authtics_host_apis__/get-dat-matching', async (req, res) => {
133
+ const reqBody = (await getJsonBody(req));
134
+ let datMatched = false;
135
+ if (config_.dat && config_.dat == reqBody.dat)
136
+ datMatched = true;
137
+ if (config_.dat == undefined)
138
+ datMatched = true;
139
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
140
+ datMatched = true;
141
+ res.writeHead(200, { "Content-Type": "application/json" });
142
+ res.end(JSON.stringify({
143
+ isMatching: datMatched
144
+ }));
145
+ });
113
146
  this.post('/__authtics_host_apis__/get-cpu_memory', async (req, res) => {
114
147
  const reqBody = (await getJsonBody(req));
115
148
  let datMatched = false;
@@ -166,8 +199,6 @@ export default class App {
166
199
  let datMatched = false;
167
200
  if (config_.dat && config_.dat == reqBody.dat)
168
201
  datMatched = true;
169
- if (config_.dat == undefined)
170
- datMatched = true;
171
202
  if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
172
203
  datMatched = true;
173
204
  if (datMatched) {
@@ -189,8 +220,6 @@ export default class App {
189
220
  let datMatched = false;
190
221
  if (config_.dat && config_.dat == reqBody.dat)
191
222
  datMatched = true;
192
- if (config_.dat == undefined)
193
- datMatched = true;
194
223
  if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
195
224
  datMatched = true;
196
225
  if (datMatched) {
@@ -233,6 +262,27 @@ export default class App {
233
262
  }));
234
263
  }
235
264
  });
265
+ this.post("/__authtics_host_apis__/get-host-ver", async (req, res) => {
266
+ const reqBody = (await getJsonBody(req));
267
+ let datMatched = false;
268
+ if (config_.dat && config_.dat == reqBody.dat)
269
+ datMatched = true;
270
+ if (config_.dat == undefined)
271
+ datMatched = true;
272
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
273
+ datMatched = true;
274
+ if (datMatched) {
275
+ const packageJsonPath = path.join(__dirname, '../package.json');
276
+ let packageJson;
277
+ if (fs.existsSync(packageJsonPath))
278
+ packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
279
+ const packageJsonVersion = packageJson.version || "Unknown";
280
+ res.writeHead(200, { "Content-Type": "application/json" });
281
+ res.end(JSON.stringify({
282
+ version: packageJsonVersion
283
+ }));
284
+ }
285
+ });
236
286
  this.post("/__authtics_host_apis__/get-file-by-pathname", async (req, res) => {
237
287
  const reqBody = (await getJsonBody(req));
238
288
  let datMatched = false;
@@ -245,7 +295,8 @@ export default class App {
245
295
  if (datMatched) {
246
296
  const pathname = reqBody.pathname;
247
297
  const pagesDir = config_.autoPage === true ? path.join(process.cwd(), config_.autoPageDir || "") : undefined;
248
- const filePath = pagesDir ? path.join(pagesDir, pathname + ".tsx") : undefined;
298
+ const safePath = path.normalize(pathname).replace(/^(\.\.[\/\\])+/, '');
299
+ const filePath = pagesDir ? path.join(pagesDir, safePath + ".tsx") : undefined;
249
300
  const fileExists = filePath ? fs.existsSync(filePath) : true;
250
301
  res.writeHead(200, { "Content-Type": "application/json" });
251
302
  res.end(JSON.stringify({
package/dist/devPanel.js CHANGED
@@ -138,14 +138,14 @@ function installConsoleInterceptor() {
138
138
  };
139
139
  });
140
140
  }
141
- function PanelButton({ onClick, onClick2, children, style, fullWidth }) {
141
+ function PanelButton({ onClick, onClick2, children, style, fullWidth, disabled }) {
142
142
  const [hovered, setHovered] = useState(false);
143
143
  const [pressed, setPressed] = useState(false);
144
144
  return (_jsx("div", { onClick: (e) => {
145
- if (onClick) {
145
+ if (onClick && !disabled) {
146
146
  onClick();
147
147
  }
148
- else if (onClick2) {
148
+ else if (onClick2 && !disabled) {
149
149
  onClick2(e);
150
150
  }
151
151
  }, onMouseEnter: () => setHovered(true), onMouseLeave: () => { setHovered(false); setPressed(false); }, onMouseDown: () => setPressed(true), onMouseUp: () => setPressed(false), style: {
@@ -194,12 +194,14 @@ export default function DevPanel() {
194
194
  const [isSsr, setIsSsr] = useState(false);
195
195
  const cpuUsage = useRef(0);
196
196
  const heapUsage = useRef(0);
197
+ const [datMatch, setDatMatch] = useState(false);
197
198
  const [compilerType, setCompilerType] = useState("?");
198
199
  const [errorDetail, setErrorDetail] = useState(undefined);
199
200
  const [httpVersion, setHttpVersion] = useState("v?.?");
200
201
  const [errorBoxOpenable, setErrorBoxOpenable] = useState(false);
201
202
  const [uptime, setUptime] = useState("00:00:00:00");
202
203
  const [requests, setRequests] = useState(0);
204
+ const [hostVersion, setHostVersion] = useState("Loading...");
203
205
  const [users, setUsers] = useState(0);
204
206
  const [token, setToken] = useState(null);
205
207
  const [tokenLength, setTokenLength] = useState(0);
@@ -211,6 +213,7 @@ export default function DevPanel() {
211
213
  const frames = useRef(0);
212
214
  const consoleScrollRef = useRef(null);
213
215
  const [isAtBottom, setIsAtBottom] = useState(true);
216
+ const [datRestrictionMissing, setDatRestrictionMissing] = useState(true);
214
217
  const [pos, setPos] = React.useState({ x: 20, y: 20 });
215
218
  const [dragging, setDragging] = React.useState(false);
216
219
  const offset = React.useRef({ x: 0, y: 0 });
@@ -476,6 +479,30 @@ useEffect(() => {
476
479
  setPath(data.filePath);
477
480
  }
478
481
  };
482
+ const getDatMatching = async () => {
483
+ const resp = await fetch('/__authtics_host_apis__/get-dat-matching', {
484
+ method: 'POST',
485
+ headers: { 'Content-Type': 'application/json' },
486
+ body: JSON.stringify({ dat: localStorage.getItem('dat') })
487
+ });
488
+ if (resp.status === 200) {
489
+ const data = await resp.json();
490
+ setDatMatch(data.isMatching);
491
+ if (!data.isMatching) {
492
+ doc?.getElementById('authtics-dev-panel-root')?.remove();
493
+ return;
494
+ }
495
+ const resp2 = await fetch('/__authtics_host_apis__/get-dat-restriction-missing', {
496
+ method: 'POST',
497
+ headers: { 'Content-Type': 'application/json' },
498
+ body: JSON.stringify({ dat: localStorage.getItem('dat') })
499
+ });
500
+ if (resp2.status === 200) {
501
+ const data = await resp2.json();
502
+ setDatRestrictionMissing(!data.enabled);
503
+ }
504
+ }
505
+ };
479
506
  const isSSR = async () => {
480
507
  const resp = await fetch('/__authtics_host_apis__/get-is-ssr', {
481
508
  method: 'POST',
@@ -499,6 +526,17 @@ useEffect(() => {
499
526
  heapUsage.current = data.heapUsed;
500
527
  }
501
528
  };
529
+ const getHostVersion = async () => {
530
+ const resp = await fetch('/__authtics_host_apis__/get-host-ver', {
531
+ method: 'POST',
532
+ headers: { 'Content-Type': 'application/json' },
533
+ body: JSON.stringify({ dat: localStorage.getItem('dat') })
534
+ });
535
+ if (resp.status === 200) {
536
+ const data = await resp.json();
537
+ setHostVersion(data.version);
538
+ }
539
+ };
502
540
  const getCompilerType = async () => {
503
541
  const resp = await fetch('/__authtics_host_apis__/get-compiler', {
504
542
  method: 'POST',
@@ -559,6 +597,8 @@ useEffect(() => {
559
597
  getHttpVersion();
560
598
  isSSR();
561
599
  userSettings();
600
+ getHostVersion();
601
+ getDatMatching();
562
602
  setInterval(() => {
563
603
  getUsage();
564
604
  }, 250);
@@ -642,17 +682,6 @@ useEffect(() => {
642
682
  }, []);
643
683
  // Chart tick every 2 seconds — snapshot pending bytes then reset
644
684
  useEffect(() => {
645
- /*let nE;
646
- const navigationEntries = performance.getEntriesByType("navigation");
647
- if (navigationEntries.length > 0) {
648
- const navigationEntry = navigationEntries[0] as PerformanceNavigationTiming;
649
- nE = navigationEntry;
650
- }
651
- let statusCode = 404;
652
- if (nE instanceof PerformanceNavigationTiming) {
653
- statusCode = nE.responseStatus;
654
- }
655
- setStatus(statusCode);*/
656
685
  const interval = setInterval(() => {
657
686
  const s = pendingSent.current;
658
687
  const r = pendingReceived.current;
@@ -1104,7 +1133,7 @@ useEffect(() => {
1104
1133
  border: '1px solid #eee',
1105
1134
  fontSize: '12px',
1106
1135
  color: '#333',
1107
- }, children: [_jsx("span", { style: { fontSize: '12px', color: '#333' }, children: "Version" }), _jsx("span", { style: { fontSize: '12px', color: 'blue' }, children: "v0.0.1-beta.7" })] }), _jsxs("div", { style: {
1136
+ }, children: [_jsx("span", { style: { fontSize: '12px', color: '#333' }, children: "Version" }), _jsxs("span", { style: { fontSize: '12px', color: 'blue' }, children: ["v", hostVersion] })] }), _jsxs("div", { style: {
1108
1137
  display: 'flex',
1109
1138
  justifyContent: 'space-between',
1110
1139
  padding: '6px 10px',
@@ -1186,7 +1215,17 @@ useEffect(() => {
1186
1215
  gap: '6px',
1187
1216
  color: '#fff',
1188
1217
  flexDirection: 'row',
1189
- }, children: [_jsx(CircleX, { size: 12 }), "Invalid Developer Access Token (DAT)"] }) })) : (_jsx(_Fragment, {})), _jsx(PanelButton, { onClick: () => { restart(); }, fullWidth: true, style: { color: '#fff', justifyContent: 'center', height: '32px', background: '#ba4e4e' }, children: _jsx("span", { style: { display: 'flex', alignItems: 'center', gap: '6px', textAlign: 'center' }, children: "Restart App" }) }), _jsx(PanelButton, { onClick: () => { shutDown(); }, fullWidth: true, style: { color: '#fff', justifyContent: 'center', height: '32px', background: '#ba4e4e' }, children: _jsx("span", { style: { display: 'flex', alignItems: 'center', gap: '6px', textAlign: 'center' }, children: "Shut Down App" }) })] })] })) }) }), compilerType !== "?" ? (_jsxs("div", { onClick: () => setOpen(o => !o), style: {
1218
+ }, children: [_jsx(CircleX, { size: 12 }), "Invalid Developer Access Token (DAT)"] }) })) : (_jsx(_Fragment, {})), hostVersion === "0.0.1-beta.9" ? (_jsx(_Fragment, { children: _jsx("div", { style: {
1219
+ display: 'flex',
1220
+ background: 'orange',
1221
+ borderRadius: '10px',
1222
+ padding: '6px 10px',
1223
+ justifyContent: 'left',
1224
+ alignItems: 'center',
1225
+ gap: '6px',
1226
+ color: '#fff',
1227
+ flexDirection: 'row',
1228
+ }, 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."] })) : (_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."] })) : (_jsx(_Fragment, {}))] })] })) }) }), datMatch ? (_jsxs("div", { onClick: () => setOpen(o => !o), style: {
1190
1229
  display: 'flex',
1191
1230
  flexDirection: 'row',
1192
1231
  alignItems: 'center',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bananacool467/authtics-host",
3
- "version": "0.0.1-beta.7",
3
+ "version": "0.0.1-beta.9",
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",