nothumanallowed 16.0.41 → 16.0.42
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/package.json +1 -1
- package/src/constants.mjs +1 -1
- package/src/server/routes/webcraft.mjs +70 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "16.0.
|
|
3
|
+
"version": "16.0.42",
|
|
4
4
|
"description": "Local AI assistant: 80 tools (Gmail, Calendar, Drive, GitHub, Slack, browser, code, files), 38 agents, visual workflows (Studio, AWF, WebCraft). Install with `npm i -g nothumanallowed`, run with `nha ui`. Free tier built-in (Liara), no API key required. Your data stays on your PC — OAuth tokens local, no cloud. Open-source MIT.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/constants.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'url';
|
|
|
5
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = path.dirname(__filename);
|
|
7
7
|
|
|
8
|
-
export const VERSION = '16.0.
|
|
8
|
+
export const VERSION = '16.0.42';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
|
@@ -5136,7 +5136,76 @@ function createApp() {
|
|
|
5136
5136
|
const express = createApp;
|
|
5137
5137
|
express.json = function (opts) { return async (req, res, next) => { if (/json/i.test(req.headers['content-type'] || '')) req.body = await parseBody(req); next(); }; };
|
|
5138
5138
|
express.urlencoded = function (opts) { return async (req, res, next) => { if (/urlencoded/i.test(req.headers['content-type'] || '')) req.body = await parseBody(req); next(); }; };
|
|
5139
|
-
|
|
5139
|
+
|
|
5140
|
+
// MIME type table for static files
|
|
5141
|
+
const _MIME = {
|
|
5142
|
+
'.html': 'text/html; charset=utf-8',
|
|
5143
|
+
'.htm': 'text/html; charset=utf-8',
|
|
5144
|
+
'.css': 'text/css; charset=utf-8',
|
|
5145
|
+
'.js': 'application/javascript; charset=utf-8',
|
|
5146
|
+
'.mjs': 'application/javascript; charset=utf-8',
|
|
5147
|
+
'.json': 'application/json; charset=utf-8',
|
|
5148
|
+
'.png': 'image/png',
|
|
5149
|
+
'.jpg': 'image/jpeg',
|
|
5150
|
+
'.jpeg': 'image/jpeg',
|
|
5151
|
+
'.gif': 'image/gif',
|
|
5152
|
+
'.webp': 'image/webp',
|
|
5153
|
+
'.svg': 'image/svg+xml',
|
|
5154
|
+
'.ico': 'image/x-icon',
|
|
5155
|
+
'.woff': 'font/woff',
|
|
5156
|
+
'.woff2': 'font/woff2',
|
|
5157
|
+
'.ttf': 'font/ttf',
|
|
5158
|
+
'.otf': 'font/otf',
|
|
5159
|
+
'.eot': 'application/vnd.ms-fontobject',
|
|
5160
|
+
'.txt': 'text/plain; charset=utf-8',
|
|
5161
|
+
'.xml': 'application/xml',
|
|
5162
|
+
'.pdf': 'application/pdf',
|
|
5163
|
+
'.map': 'application/json',
|
|
5164
|
+
'.mp4': 'video/mp4',
|
|
5165
|
+
'.webm': 'video/webm',
|
|
5166
|
+
'.mp3': 'audio/mpeg',
|
|
5167
|
+
'.wav': 'audio/wav',
|
|
5168
|
+
};
|
|
5169
|
+
|
|
5170
|
+
// Real express.static implementation — serves files from disk with proper
|
|
5171
|
+
// MIME types. Supports index.html for directory requests, path traversal
|
|
5172
|
+
// protection. Falls through to next() when the file doesn't exist.
|
|
5173
|
+
express.static = function (root, opts) {
|
|
5174
|
+
opts = opts || {};
|
|
5175
|
+
const indexFile = opts.index === false ? null : (opts.index || 'index.html');
|
|
5176
|
+
const rootAbs = require('path').resolve(root);
|
|
5177
|
+
return function (req, res, next) {
|
|
5178
|
+
if (req.method !== 'GET' && req.method !== 'HEAD') return next();
|
|
5179
|
+
try {
|
|
5180
|
+
let relPath = decodeURIComponent((req.path || req.url || '/').split('?')[0]);
|
|
5181
|
+
// Path traversal protection
|
|
5182
|
+
if (relPath.includes('\\\\0') || relPath.includes('..')) return next();
|
|
5183
|
+
if (relPath.startsWith('/')) relPath = relPath.slice(1);
|
|
5184
|
+
const abs = require('path').resolve(rootAbs, relPath);
|
|
5185
|
+
// Ensure resolved path stays within root
|
|
5186
|
+
if (!abs.startsWith(rootAbs)) return next();
|
|
5187
|
+
let stat;
|
|
5188
|
+
try { stat = require('fs').statSync(abs); } catch { return next(); }
|
|
5189
|
+
let filePath = abs;
|
|
5190
|
+
if (stat.isDirectory()) {
|
|
5191
|
+
if (!indexFile) return next();
|
|
5192
|
+
filePath = require('path').join(abs, indexFile);
|
|
5193
|
+
try { stat = require('fs').statSync(filePath); } catch { return next(); }
|
|
5194
|
+
if (!stat.isFile()) return next();
|
|
5195
|
+
}
|
|
5196
|
+
const ext = require('path').extname(filePath).toLowerCase();
|
|
5197
|
+
const mime = _MIME[ext] || 'application/octet-stream';
|
|
5198
|
+
res.setHeader('Content-Type', mime);
|
|
5199
|
+
res.setHeader('Content-Length', String(stat.size));
|
|
5200
|
+
res.setHeader('Cache-Control', 'public, max-age=0');
|
|
5201
|
+
if (req.method === 'HEAD') return res.end();
|
|
5202
|
+
require('fs').createReadStream(filePath).pipe(res);
|
|
5203
|
+
} catch (e) {
|
|
5204
|
+
return next();
|
|
5205
|
+
}
|
|
5206
|
+
};
|
|
5207
|
+
};
|
|
5208
|
+
|
|
5140
5209
|
express.Router = function () { const r = createApp(); return r; };
|
|
5141
5210
|
module.exports = express;
|
|
5142
5211
|
module.exports.default = express;
|