fix(routes): restore ctx access in 15 route files broken by Phase 2.1 refactor
The modular refactor changed function signatures to destructured deps but left internal ctx.* references intact, causing "ctx is not defined" errors on /api/config, /api/logo, and many other endpoints. Also implements loadTotpConfig and saveTotpConfig which were left as stubs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -17,7 +17,8 @@ const platformPaths = require('../../platform-paths');
|
|||||||
* @param {Object} deps.log - Logger instance
|
* @param {Object} deps.log - Logger instance
|
||||||
* @returns {Object} Helper functions
|
* @returns {Object} Helper functions
|
||||||
*/
|
*/
|
||||||
module.exports = function({ docker, caddy, credentialManager, servicesStateManager, fetchT, log }) {
|
module.exports = function(ctx) {
|
||||||
|
const { docker, caddy, credentialManager, servicesStateManager, fetchT, log } = ctx;
|
||||||
|
|
||||||
async function checkPortConflicts(ports, excludeContainerName = null) {
|
async function checkPortConflicts(ports, excludeContainerName = null) {
|
||||||
const conflicts = [];
|
const conflicts = [];
|
||||||
|
|||||||
@@ -36,13 +36,14 @@ module.exports = function(ctx) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Initialize helpers with dependencies
|
// Initialize helpers with dependencies
|
||||||
const helpers = initHelpers(deps);
|
const helpers = initHelpers(ctx);
|
||||||
|
|
||||||
// Mount sub-routes with explicit dependencies
|
// Mount sub-routes — pass full ctx so sub-routes can reference ctx.* properties
|
||||||
router.use(initDeploy({ ...deps, helpers }));
|
const subCtx = Object.assign({}, ctx, { helpers });
|
||||||
router.use(initRemoval({ ...deps, helpers }));
|
router.use(initDeploy(subCtx));
|
||||||
router.use(initTemplates({ ...deps, helpers }));
|
router.use(initRemoval(subCtx));
|
||||||
router.use(initRestore({ ...deps, helpers }));
|
router.use(initTemplates(subCtx));
|
||||||
|
router.use(initRestore(subCtx));
|
||||||
|
|
||||||
return router;
|
return router;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { exists } = require('../../fs-helpers');
|
const { exists } = require('../../fs-helpers');
|
||||||
|
|
||||||
module.exports = function({ docker, caddy, servicesStateManager, asyncHandler, log, helpers }) {
|
module.exports = function(ctx) {
|
||||||
|
const { docker, caddy, servicesStateManager, asyncHandler, errorResponse, log, helpers } = ctx;
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
// Remove deployed app
|
|
||||||
/**
|
/**
|
||||||
* Apps removal routes factory
|
* Apps removal routes factory
|
||||||
* @param {Object} deps - Explicit dependencies
|
* @param {Object} deps - Explicit dependencies
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ const { DOCKER } = require('../../constants');
|
|||||||
* @param {Object} deps.helpers - Apps helpers module
|
* @param {Object} deps.helpers - Apps helpers module
|
||||||
* @returns {express.Router}
|
* @returns {express.Router}
|
||||||
*/
|
*/
|
||||||
module.exports = function({ docker, caddy, servicesStateManager, asyncHandler, log, helpers }) {
|
module.exports = function(ctx) {
|
||||||
|
const { docker, caddy, servicesStateManager, asyncHandler, log, helpers } = ctx;
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ const { exists } = require('../../fs-helpers');
|
|||||||
*/
|
*/
|
||||||
const { REGEX } = require('../../constants');
|
const { REGEX } = require('../../constants');
|
||||||
|
|
||||||
module.exports = function({ servicesStateManager, asyncHandler, helpers }) {
|
module.exports = function(ctx) {
|
||||||
|
const { servicesStateManager, asyncHandler, helpers, docker, caddy, log, errorResponse } = ctx;
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
// Get available app templates
|
// Get available app templates
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ const { logError } = require('../../src/utils/logging');
|
|||||||
* @param {Object} deps.helpers - Arr helpers module
|
* @param {Object} deps.helpers - Arr helpers module
|
||||||
* @returns {express.Router}
|
* @returns {express.Router}
|
||||||
*/
|
*/
|
||||||
module.exports = function({ credentialManager, servicesStateManager, docker, fetchT, asyncHandler, errorResponse, log, helpers, notification, safeErrorMessage }) {
|
module.exports = function(ctx) {
|
||||||
|
const { credentialManager, servicesStateManager, docker, fetchT, asyncHandler, errorResponse, log, helpers, notification, safeErrorMessage } = ctx;
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
// Ctx shim for backward compatibility
|
// Ctx shim for backward compatibility
|
||||||
|
|||||||
@@ -24,14 +24,15 @@ module.exports = function(ctx) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Initialize helpers with dependencies
|
// Initialize helpers with dependencies
|
||||||
const helpers = require('./helpers')(deps);
|
const helpers = require('./helpers')(ctx);
|
||||||
|
|
||||||
// Mount sub-routes with explicit dependencies
|
// Mount sub-routes — pass full ctx so sub-routes can reference ctx.* properties
|
||||||
router.use(require('./detect')({ ...deps, helpers }));
|
const subCtx = Object.assign({}, ctx, { helpers });
|
||||||
router.use(require('./credentials')({ ...deps, helpers }));
|
router.use(require('./detect')(subCtx));
|
||||||
router.use(require('./config')({ ...deps, helpers }));
|
router.use(require('./credentials')(subCtx));
|
||||||
router.use(require('./smart-connect')({ ...deps, helpers }));
|
router.use(require('./config')(subCtx));
|
||||||
router.use(require('./plex')({ ...deps, helpers }));
|
router.use(require('./smart-connect')(subCtx));
|
||||||
|
router.use(require('./plex')(subCtx));
|
||||||
|
|
||||||
return router;
|
return router;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ const { APP_PORTS } = require('../../constants');
|
|||||||
* @param {Object} deps.helpers - Arr helpers module
|
* @param {Object} deps.helpers - Arr helpers module
|
||||||
* @returns {express.Router}
|
* @returns {express.Router}
|
||||||
*/
|
*/
|
||||||
module.exports = function({ fetchT, asyncHandler, errorResponse, log, helpers }) {
|
module.exports = function(ctx) {
|
||||||
|
const { fetchT, asyncHandler, errorResponse, log, helpers } = ctx;
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
// Plex Libraries endpoint
|
// Plex Libraries endpoint
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ const { APP_PORTS } = require('../../constants');
|
|||||||
* @param {Object} deps.helpers - Arr helpers module
|
* @param {Object} deps.helpers - Arr helpers module
|
||||||
* @returns {express.Router}
|
* @returns {express.Router}
|
||||||
*/
|
*/
|
||||||
module.exports = function({ credentialManager, fetchT, asyncHandler, errorResponse, log, helpers }) {
|
module.exports = function(ctx) {
|
||||||
|
const { credentialManager, fetchT, asyncHandler, errorResponse, log, helpers } = ctx;
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
// Smart Connect: Unified orchestration endpoint
|
// Smart Connect: Unified orchestration endpoint
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ try {
|
|||||||
// Image processing libraries not available — favicon conversion disabled
|
// Image processing libraries not available — favicon conversion disabled
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = function({ servicesStateManager, asyncHandler, log }) {
|
module.exports = function(ctx) {
|
||||||
|
const { servicesStateManager, asyncHandler, log } = ctx;
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
// ===== ASSET UPLOAD =====
|
// ===== ASSET UPLOAD =====
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ module.exports = function(ctx) {
|
|||||||
saveTotpConfig: ctx.saveTotpConfig
|
saveTotpConfig: ctx.saveTotpConfig
|
||||||
};
|
};
|
||||||
|
|
||||||
router.use(require('./settings')(baseDeps));
|
router.use(require('./settings')(ctx));
|
||||||
router.use(require('./assets')({ ...baseDeps, CONFIG_FILE: ctx.CONFIG_FILE, readConfig: ctx.readConfig, saveConfig: ctx.saveConfig, errorResponse: ctx.errorResponse }));
|
router.use(require('./assets')(ctx));
|
||||||
router.use(require('./backup')(backupDeps));
|
router.use(require('./backup')(backupDeps));
|
||||||
return router;
|
return router;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,15 +3,13 @@ const { validateConfig } = require('../../config-schema');
|
|||||||
const { exists } = require('../../fs-helpers');
|
const { exists } = require('../../fs-helpers');
|
||||||
const { ValidationError } = require('../../errors');
|
const { ValidationError } = require('../../errors');
|
||||||
|
|
||||||
module.exports = function({ configStateManager, asyncHandler, log }) {
|
|
||||||
/**
|
/**
|
||||||
* Config settings routes factory
|
* Config settings routes factory
|
||||||
* @param {Object} deps - Explicit dependencies
|
* @param {Object} ctx - Application context
|
||||||
* @param {Object} deps.configStateManager - Config state manager
|
|
||||||
* @param {Function} deps.asyncHandler - Async route handler wrapper
|
|
||||||
* @param {Object} deps.log - Logger instance
|
|
||||||
* @returns {express.Router}
|
* @returns {express.Router}
|
||||||
*/
|
*/
|
||||||
|
module.exports = function(ctx) {
|
||||||
|
const { configStateManager, asyncHandler, log } = ctx;
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ const { DOCKER } = require('../../constants');
|
|||||||
* @param {Object} deps.log - Logger instance
|
* @param {Object} deps.log - Logger instance
|
||||||
* @returns {express.Router}
|
* @returns {express.Router}
|
||||||
*/
|
*/
|
||||||
module.exports = function({ docker, credentialManager, servicesStateManager, asyncHandler, errorResponse, log }) {
|
module.exports = function(ctx) {
|
||||||
|
const { docker, credentialManager, servicesStateManager, asyncHandler, errorResponse, log } = ctx;
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -61,9 +61,9 @@ module.exports = function(ctx) {
|
|||||||
res.json({ success: true, recipe: { id: req.params.recipeId, ...recipe } });
|
res.json({ success: true, recipe: { id: req.params.recipeId, ...recipe } });
|
||||||
}, 'recipe-template-detail'));
|
}, 'recipe-template-detail'));
|
||||||
|
|
||||||
// Mount deploy and manage sub-routes
|
// Mount deploy and manage sub-routes — pass full ctx for sub-routes that reference ctx.*
|
||||||
router.use(deployRoutes(deps));
|
router.use(deployRoutes(ctx));
|
||||||
router.use(manageRoutes(deps));
|
router.use(manageRoutes(ctx));
|
||||||
|
|
||||||
return router;
|
return router;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ const express = require('express');
|
|||||||
const { DOCKER } = require('../../constants');
|
const { DOCKER } = require('../../constants');
|
||||||
const { NotFoundError } = require('../../errors');
|
const { NotFoundError } = require('../../errors');
|
||||||
|
|
||||||
module.exports = function({ servicesStateManager, asyncHandler, log }) {
|
module.exports = function(ctx) {
|
||||||
|
const { servicesStateManager, asyncHandler, log } = ctx;
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
/**
|
/**
|
||||||
* Recipes management routes factory
|
* Recipes management routes factory
|
||||||
|
|||||||
@@ -102,13 +102,25 @@ async function createApp() {
|
|||||||
log.warn('server', 'CA cert not found — HTTPS calls may fail', { path: CA_CERT_PATH });
|
log.warn('server', 'CA cert not found — HTTPS calls may fail', { path: CA_CERT_PATH });
|
||||||
}
|
}
|
||||||
|
|
||||||
// TOTP configuration
|
// TOTP configuration (defaults, overridden by loadTotpConfig below)
|
||||||
let totpConfig = {
|
let totpConfig = {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
sessionDuration: 'never',
|
sessionDuration: 'never',
|
||||||
isSetUp: false
|
isSetUp: false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Load TOTP config from file
|
||||||
|
try {
|
||||||
|
if (fs.existsSync(config.TOTP_CONFIG_FILE)) {
|
||||||
|
const loaded = JSON.parse(fs.readFileSync(config.TOTP_CONFIG_FILE, 'utf8'));
|
||||||
|
delete loaded.secret; // secret belongs only in credential-manager
|
||||||
|
Object.assign(totpConfig, loaded);
|
||||||
|
log.info('config', 'TOTP config loaded', { enabled: totpConfig.enabled });
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
log.warn('config', 'Could not load TOTP config', { error: e.message });
|
||||||
|
}
|
||||||
|
|
||||||
// Tailscale configuration
|
// Tailscale configuration
|
||||||
let tailscaleConfig = {
|
let tailscaleConfig = {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
@@ -192,7 +204,12 @@ async function createApp() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function saveTotpConfig() {
|
async function saveTotpConfig() {
|
||||||
// Stub - will be implemented
|
try {
|
||||||
|
const { writeJsonFile } = require('../fs-helpers');
|
||||||
|
await writeJsonFile(config.TOTP_CONFIG_FILE, totpConfig);
|
||||||
|
} catch (e) {
|
||||||
|
log.error('config', 'Could not save TOTP config', { error: e.message });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadNotificationConfig() {
|
async function loadNotificationConfig() {
|
||||||
|
|||||||
Reference in New Issue
Block a user