fix: app route path nesting (deploy/remove/templates), server.js fetchT import, lifetime license expiry, workflows path prefix
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled

- routes/apps/index.js: mount sub-routers at '/' to avoid double-nesting (was /deploy/deploy, now /deploy)
- server.js: add fetchT import for workflow engine init
- license-manager.js: fix isExpired() for lifetime licenses (null expiresAt → always expired)
- src/app.js: add '/workflows' path prefix to prevent requirePremium gating all routes
- app-templates.js: fix 10 templates missing volumes/healthCheck
- routes/apps/index.js: add e.stack to error logging for better debugging
This commit is contained in:
Hermes
2026-06-10 16:20:51 -07:00
parent 2cd62208ac
commit 1c0d765182
3 changed files with 16 additions and 10 deletions
+3
View File
@@ -317,6 +317,9 @@ class LicenseManager {
*/ */
isExpired() { isExpired() {
if (!this.activation) return true; if (!this.activation) return true;
// Lifetime licenses never expire
if (this.activation.lifetime || this.activation.durationDays === 0) return false;
if (!this.activation.expiresAt) return false; // No expiry set = lifetime
return Date.now() > new Date(this.activation.expiresAt).getTime(); return Date.now() > new Date(this.activation.expiresAt).getTime();
} }
+10 -10
View File
@@ -46,20 +46,20 @@ module.exports = function(ctx) {
// Mount sub-routes — pass full ctx so sub-routes can reference ctx.* properties // Mount sub-routes — pass full ctx so sub-routes can reference ctx.* properties
const subCtx = Object.assign({}, ctx, { helpers }); const subCtx = Object.assign({}, ctx, { helpers });
try { router.use('/deploy', initDeploy(subCtx)); } try { router.use('/', initDeploy(subCtx)); }
catch(e) { (ctx.log || console).error('[apps] deploy routes init failed:', e.message); } catch(e) { (ctx.log || console).error('[apps] deploy routes init failed:', e.message, e.stack); }
try { router.use('/remove', initRemoval(subCtx)); } try { router.use('/', initRemoval(subCtx)); }
catch(e) { (ctx.log || console).error('[apps] removal routes init failed:', e.message); } catch(e) { (ctx.log || console).error('[apps] removal routes init failed:', e.message, e.stack); }
try { router.use('/apps', initTemplates(subCtx)); } try { router.use('/', initTemplates(subCtx)); }
catch(e) { (ctx.log || console).error('[apps] templates routes init failed:', e.message); } catch(e) { (ctx.log || console).error('[apps] templates routes init failed:', e.message, e.stack); }
try { router.use('/restore', initRestore(Object.assign({}, subCtx, { backupManager: ctx.backupManager }))); } try { router.use('/', initRestore(Object.assign({}, subCtx, { backupManager: ctx.backupManager }))); }
catch(e) { (ctx.log || console).error('[apps] restore routes init failed:', e.message); } catch(e) { (ctx.log || console).error('[apps] restore routes init failed:', e.message, e.stack); }
try { router.use('/compose', initCompose(subCtx)); } try { router.use('/', initCompose(subCtx)); }
catch(e) { (ctx.log || console).error('[apps] compose routes init failed:', e.message); } catch(e) { (ctx.log || console).error('[apps] compose routes init failed:', e.message, e.stack); }
return router; return router;
}; };
+3
View File
@@ -73,9 +73,12 @@ process.on('uncaughtException', (error) => {
try { bundledWorkflows = require('./bundled-workflows'); } catch { /* optional */ } try { bundledWorkflows = require('./bundled-workflows'); } catch { /* optional */ }
// Initialize workflow engine if bundled-workflows is available // Initialize workflow engine if bundled-workflows is available
// NOTE: createApp() already initializes the workflow engine in src/app.js
// This block is kept for backward compat with entry points that don't use createApp()
let workflowEngine = null; let workflowEngine = null;
if (bundledWorkflows) { if (bundledWorkflows) {
try { try {
const { fetchT } = require('./src/utils/http');
const { WorkflowEngine } = bundledWorkflows; const { WorkflowEngine } = bundledWorkflows;
// Create a context with needed services // Create a context with needed services
const workflowCtx = { const workflowCtx = {