neoagent 2.1.18-beta.64 → 2.1.18-beta.66

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.
@@ -13,6 +13,7 @@ AI provider credentials, OAuth client secrets, and deployment controls are not c
13
13
  | `SESSION_SECRET` | required | Random string for session signing. Generate one with `openssl rand -hex 32`. |
14
14
  | `NODE_ENV` | `production` | Set to `development` to enable verbose logs. |
15
15
  | `SECURE_COOKIES` | `false` | Set `true` when NeoAgent is behind a TLS-terminating proxy. |
16
+ | `TRUST_PROXY` | inferred from `PUBLIC_URL`/`SECURE_COOKIES` | Set `true` when NeoAgent runs behind Nginx, Caddy, Cloudflare, Fly, or another reverse proxy that sends `X-Forwarded-*` headers. |
16
17
  | `ALLOWED_ORIGINS` | none | Comma-separated CORS origins, for example `https://example.com`. |
17
18
  | `NEOAGENT_DEPLOYMENT_MODE` | `self_hosted` | `self_hosted` enables in-app update controls; `managed` hides operator-only controls for SaaS deployments. |
18
19
  | `NEOAGENT_RELEASE_CHANNEL` | `stable` | Release track used by the self-hosted updater. |
package/lib/manager.js CHANGED
@@ -444,6 +444,8 @@ async function cmdSetup() {
444
444
  const secureCookiesDefault = current.SECURE_COOKIES ||
445
445
  (String(publicUrl || '').trim().startsWith('https://') ? 'true' : 'false');
446
446
  const secureCookies = await ask('Secure cookies (true/false)', secureCookiesDefault);
447
+ const trustProxyDefault = current.TRUST_PROXY || secureCookiesDefault;
448
+ const trustProxy = await ask('Trust reverse proxy headers (true/false)', trustProxyDefault);
447
449
  const sessionSecret = await askSecret('Session secret', current.SESSION_SECRET || randomSecret());
448
450
  const deploymentMode = await ask(
449
451
  'Deployment mode (self_hosted/managed)',
@@ -546,6 +548,7 @@ async function cmdSetup() {
546
548
  current.TELNYX_WEBHOOK_TOKEN || ''
547
549
  );
548
550
  const normalizedSecureCookies = String(secureCookies || '').trim().toLowerCase() === 'true' ? 'true' : 'false';
551
+ const normalizedTrustProxy = String(trustProxy || '').trim().toLowerCase() === 'true' ? 'true' : 'false';
549
552
  const normalizedDeploymentMode = parseDeploymentMode(deploymentMode);
550
553
  const normalizedReleaseChannel = parseReleaseChannel(releaseChannel) || 'stable';
551
554
 
@@ -554,6 +557,7 @@ async function cmdSetup() {
554
557
  `PORT=${port}`,
555
558
  publicUrl ? `PUBLIC_URL=${publicUrl}` : '',
556
559
  `SECURE_COOKIES=${normalizedSecureCookies}`,
560
+ `TRUST_PROXY=${normalizedTrustProxy}`,
557
561
  `SESSION_SECRET=${sessionSecret}`,
558
562
  `NEOAGENT_DEPLOYMENT_MODE=${normalizedDeploymentMode}`,
559
563
  `NEOAGENT_RELEASE_CHANNEL=${normalizedReleaseChannel}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neoagent",
3
- "version": "2.1.18-beta.64",
3
+ "version": "2.1.18-beta.66",
4
4
  "description": "Proactive personal AI agent with no limits",
5
5
  "license": "MIT",
6
6
  "main": "server/index.js",
@@ -98,7 +98,7 @@ function buildHelmetOptions({ secureCookies }) {
98
98
  };
99
99
  }
100
100
 
101
- function createSessionMiddleware({ secureCookies }) {
101
+ function createSessionMiddleware({ secureCookies, trustProxy }) {
102
102
  return session({
103
103
  store: new SQLiteStore({
104
104
  client: sessionsDb,
@@ -109,6 +109,7 @@ function createSessionMiddleware({ secureCookies }) {
109
109
  }),
110
110
  secret: getSessionSecret(),
111
111
  name: 'neoagent.sid',
112
+ proxy: trustProxy,
112
113
  resave: false,
113
114
  saveUninitialized: false,
114
115
  cookie: {
@@ -120,7 +121,7 @@ function createSessionMiddleware({ secureCookies }) {
120
121
  });
121
122
  }
122
123
 
123
- function applyHttpMiddleware(app, { secureCookies, sessionMiddleware, validateOrigin }) {
124
+ function applyHttpMiddleware(app, { secureCookies, trustProxy, sessionMiddleware, validateOrigin }) {
124
125
  const rawRecordingChunkBody = require('express').raw({ limit: '50mb', type: '*/*' });
125
126
  const jsonBody = require('express').json({
126
127
  limit: '10mb',
@@ -147,9 +148,9 @@ function applyHttpMiddleware(app, { secureCookies, sessionMiddleware, validateOr
147
148
  isRecordingChunkPath(requestPath(req)) ? next() : handler(req, res, next)
148
149
  );
149
150
 
150
- if (secureCookies) {
151
+ if (trustProxy) {
151
152
  app.set('trust proxy', 1);
152
- console.log('[HTTP] trust proxy enabled because secure cookies are active');
153
+ console.log('[HTTP] trust proxy enabled for proxied deployment handling');
153
154
  }
154
155
 
155
156
  app.use(helmet(buildHelmetOptions({ secureCookies })));
package/server/index.js CHANGED
@@ -35,8 +35,24 @@ const { registerErrorHandler } = require('./http/errors');
35
35
  const { startServices, stopServices } = require('./services/manager');
36
36
  const { bindBrowserExtensionGateway } = require('./services/browser/extension/gateway');
37
37
 
38
+ function parseBooleanFlag(value, fallback = false) {
39
+ const normalized = String(value || '').trim().toLowerCase();
40
+ if (['1', 'true', 'yes', 'on'].includes(normalized)) return true;
41
+ if (['0', 'false', 'no', 'off'].includes(normalized)) return false;
42
+ return fallback;
43
+ }
44
+
38
45
  const PORT = Number(process.env.PORT) || 3333;
39
- const SECURE_COOKIES = process.env.SECURE_COOKIES === 'true';
46
+ const PUBLIC_URL = String(process.env.PUBLIC_URL || '').trim();
47
+ const PUBLIC_URL_IS_HTTPS = PUBLIC_URL.startsWith('https://');
48
+ const SECURE_COOKIES = parseBooleanFlag(
49
+ process.env.SECURE_COOKIES,
50
+ PUBLIC_URL_IS_HTTPS,
51
+ );
52
+ const TRUST_PROXY = parseBooleanFlag(
53
+ process.env.TRUST_PROXY,
54
+ SECURE_COOKIES || PUBLIC_URL_IS_HTTPS,
55
+ );
40
56
 
41
57
  function logStartupConfig() {
42
58
  const flags = {
@@ -60,6 +76,11 @@ function logStartupConfig() {
60
76
  console.log(`[Startup] Legacy env fallback: ${LEGACY_ENV_FILE}`);
61
77
  }
62
78
  console.log('[Startup] Key availability:', flags);
79
+ console.log('[Startup] HTTP runtime:', {
80
+ publicUrl: PUBLIC_URL || null,
81
+ secureCookies: SECURE_COOKIES,
82
+ trustProxy: TRUST_PROXY,
83
+ });
63
84
  }
64
85
 
65
86
  logStartupConfig();
@@ -77,12 +98,21 @@ if (!configuredSessionSecret()) {
77
98
  const app = express();
78
99
  const httpServer = createServer(app);
79
100
  const io = createSocketServer(httpServer, { validateOrigin });
80
- const sessionMiddleware = createSessionMiddleware({ secureCookies: SECURE_COOKIES });
101
+ app.locals.httpRuntimeConfig = {
102
+ secureCookies: SECURE_COOKIES,
103
+ trustProxy: TRUST_PROXY,
104
+ publicUrl: PUBLIC_URL || null,
105
+ };
106
+ const sessionMiddleware = createSessionMiddleware({
107
+ secureCookies: SECURE_COOKIES,
108
+ trustProxy: TRUST_PROXY,
109
+ });
81
110
  const activeSockets = new Set();
82
111
 
83
112
  setupConsoleInterceptor(io);
84
113
  applyHttpMiddleware(app, {
85
114
  secureCookies: SECURE_COOKIES,
115
+ trustProxy: TRUST_PROXY,
86
116
  sessionMiddleware,
87
117
  validateOrigin
88
118
  });
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"59aa584fdf100e6c78c785d8a5b565d1de4b48
37
37
 
38
38
  _flutter.loader.load({
39
39
  serviceWorkerSettings: {
40
- serviceWorkerVersion: "2716929298" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
40
+ serviceWorkerVersion: "4140020161" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
41
41
  }
42
42
  });