DC-005: Fix all 138 broken test paths after src/ refactor
After the DC-005 module reorganization (41 files moved into src/ subdirs),
138 test suites failed because the refactor script's path-rewrite logic
missed three categories:
1. Files inside src/ doing 'require("./src/...")' — should be 'require("../...")'
2. Files in src/X/Y/ doing 'require("../../../src/...")' — should be 'require("../../...")'
3. Test files in __tests__/ with leftover 'require("../../../src/...")' paths
Root cause: the original refactor script ran before all files were moved,
so it computed relative paths against stale filesystem state.
Result:
- 30/30 test suites pass
- 879/879 tests pass (was: 18/30 suites, 614/687 tests)
Also fixed:
- routes/apps/restore.js: wrong responses import path
- routes/*/*.js: '../../src/utilities/X' → '../src/utilities/X' (depth 2 routes)
This commit is contained in:
129 files changed
+591
-310
No files matched your search
@@ -1,4 +1,4 @@
|
|||||||
const { APP_TEMPLATES, TEMPLATE_CATEGORIES, DIFFICULTY_LEVELS } = require('../app-templates');
|
const { APP_TEMPLATES, TEMPLATE_CATEGORIES, DIFFICULTY_LEVELS } = require('../src/docker/app-templates');
|
||||||
|
|
||||||
describe('App Templates', () => {
|
describe('App Templates', () => {
|
||||||
const templates = Object.values(APP_TEMPLATES);
|
const templates = Object.values(APP_TEMPLATES);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
// Must mock crypto-utils BEFORE auth-manager is required,
|
// Must mock crypto-utils BEFORE auth-manager is required,
|
||||||
// because auth-manager.js line 13: const JWT_SECRET = cryptoUtils.loadOrCreateKey()
|
// because auth-manager.js line 13: const JWT_SECRET = cryptoUtils.loadOrCreateKey()
|
||||||
const mockFixedKey = Buffer.alloc(32, 'jwt-test-key-pad');
|
const mockFixedKey = Buffer.alloc(32, 'jwt-test-key-pad');
|
||||||
jest.mock('../crypto-utils', () => ({
|
jest.mock('../src/security/crypto-utils', () => ({
|
||||||
loadOrCreateKey: jest.fn(() => mockFixedKey),
|
loadOrCreateKey: jest.fn(() => mockFixedKey),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../credential-manager', () => ({
|
jest.mock('../src/managers/credential-manager', () => ({
|
||||||
store: jest.fn().mockResolvedValue(true),
|
store: jest.fn().mockResolvedValue(true),
|
||||||
retrieve: jest.fn().mockResolvedValue(null),
|
retrieve: jest.fn().mockResolvedValue(null),
|
||||||
delete: jest.fn().mockResolvedValue(true),
|
delete: jest.fn().mockResolvedValue(true),
|
||||||
@@ -13,8 +13,8 @@ jest.mock('../credential-manager', () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const authManager = require('../auth-manager');
|
const authManager = require('../src/managers/auth-manager');
|
||||||
const credentialManager = require('../credential-manager');
|
const credentialManager = require('../src/managers/credential-manager');
|
||||||
|
|
||||||
describe('AuthManager', () => {
|
describe('AuthManager', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|||||||
@@ -9,14 +9,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
const { AutoRestartManager, DEFAULT_POLICY } = require('../auto-restart-manager');
|
const { AutoRestartManager, DEFAULT_POLICY } = require('../src/managers/auto-restart-manager');
|
||||||
|
|
||||||
jest.mock('../fs-helpers', () => ({
|
jest.mock('../src/utilities/fs-helpers', () => ({
|
||||||
readJsonFile: jest.fn().mockResolvedValue({}),
|
readJsonFile: jest.fn().mockResolvedValue({}),
|
||||||
writeJsonFile: jest.fn().mockResolvedValue(undefined),
|
writeJsonFile: jest.fn().mockResolvedValue(undefined),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const fsHelpers = require('../fs-helpers');
|
const fsHelpers = require('../src/utilities/fs-helpers');
|
||||||
|
|
||||||
function makeManager(overrides = {}) {
|
function makeManager(overrides = {}) {
|
||||||
const servicesStateManager = {
|
const servicesStateManager = {
|
||||||
|
|||||||
@@ -3,19 +3,19 @@
|
|||||||
|
|
||||||
jest.mock('fs');
|
jest.mock('fs');
|
||||||
jest.mock('child_process');
|
jest.mock('child_process');
|
||||||
jest.mock('../credential-manager', () => ({
|
jest.mock('../src/managers/credential-manager', () => ({
|
||||||
exportBackup: jest.fn().mockReturnValue({ encrypted: 'cred-data' }),
|
exportBackup: jest.fn().mockReturnValue({ encrypted: 'cred-data' }),
|
||||||
importBackup: jest.fn()
|
importBackup: jest.fn()
|
||||||
}));
|
}));
|
||||||
jest.mock('../resource-monitor', () => ({
|
jest.mock('../src/managers/resource-monitor', () => ({
|
||||||
exportStats: jest.fn().mockReturnValue({ stats: [{ cpu: 10 }] }),
|
exportStats: jest.fn().mockReturnValue({ stats: [{ cpu: 10 }] }),
|
||||||
importStats: jest.fn()
|
importStats: jest.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const credentialManager = require('../credential-manager');
|
const credentialManager = require('../src/managers/credential-manager');
|
||||||
const resourceMonitor = require('../resource-monitor');
|
const resourceMonitor = require('../src/managers/resource-monitor');
|
||||||
|
|
||||||
// Setup defaults BEFORE requiring singleton (constructor calls loadConfig/loadHistory)
|
// Setup defaults BEFORE requiring singleton (constructor calls loadConfig/loadHistory)
|
||||||
fs.existsSync.mockReturnValue(false);
|
fs.existsSync.mockReturnValue(false);
|
||||||
@@ -24,7 +24,7 @@ fs.writeFileSync.mockReturnValue(undefined);
|
|||||||
fs.mkdirSync.mockReturnValue(undefined);
|
fs.mkdirSync.mockReturnValue(undefined);
|
||||||
fs.unlinkSync.mockReturnValue(undefined);
|
fs.unlinkSync.mockReturnValue(undefined);
|
||||||
|
|
||||||
const backupManager = require('../backup-manager');
|
const backupManager = require('../src/utilities/backup-manager');
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
const { ConfigDriftDetector } = require('../config-drift-detector');
|
const { ConfigDriftDetector } = require('../src/managers/config-drift-detector');
|
||||||
|
|
||||||
function makeContainer(overrides = {}) {
|
function makeContainer(overrides = {}) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
// Mock dependencies before requiring the module
|
// Mock dependencies before requiring the module
|
||||||
jest.mock('../keychain-manager', () => ({
|
jest.mock('../src/security/keychain-manager', () => ({
|
||||||
available: false,
|
available: false,
|
||||||
store: jest.fn().mockResolvedValue(false),
|
store: jest.fn().mockResolvedValue(false),
|
||||||
retrieve: jest.fn().mockResolvedValue(null),
|
retrieve: jest.fn().mockResolvedValue(null),
|
||||||
delete: jest.fn().mockResolvedValue(true),
|
delete: jest.fn().mockResolvedValue(true),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../crypto-utils', () => ({
|
jest.mock('../src/security/crypto-utils', () => ({
|
||||||
encrypt: jest.fn(data => `enc:tag:${Buffer.from(String(data)).toString('base64')}`),
|
encrypt: jest.fn(data => `enc:tag:${Buffer.from(String(data)).toString('base64')}`),
|
||||||
decrypt: jest.fn(data => {
|
decrypt: jest.fn(data => {
|
||||||
const parts = data.split(':');
|
const parts = data.split(':');
|
||||||
@@ -40,8 +40,8 @@ describe('CredentialManager', () => {
|
|||||||
// Re-get mocked modules
|
// Re-get mocked modules
|
||||||
fs = require('fs');
|
fs = require('fs');
|
||||||
lockfile = require('proper-lockfile');
|
lockfile = require('proper-lockfile');
|
||||||
keychainManager = require('../keychain-manager');
|
keychainManager = require('../src/security/keychain-manager');
|
||||||
cryptoUtils = require('../crypto-utils');
|
cryptoUtils = require('../src/security/crypto-utils');
|
||||||
|
|
||||||
// Reset mock implementations
|
// Reset mock implementations
|
||||||
fs.existsSync.mockReturnValue(true);
|
fs.existsSync.mockReturnValue(true);
|
||||||
@@ -50,7 +50,7 @@ describe('CredentialManager', () => {
|
|||||||
lockfile.lock.mockResolvedValue(jest.fn().mockResolvedValue());
|
lockfile.lock.mockResolvedValue(jest.fn().mockResolvedValue());
|
||||||
keychainManager.available = false;
|
keychainManager.available = false;
|
||||||
|
|
||||||
credentialManager = require('../credential-manager');
|
credentialManager = require('../src/managers/credential-manager');
|
||||||
credentialManager.cache.clear();
|
credentialManager.cache.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -72,10 +72,10 @@ describe('CredentialManager', () => {
|
|||||||
fs.writeFileSync.mockImplementation(() => {});
|
fs.writeFileSync.mockImplementation(() => {});
|
||||||
lockfile = require('proper-lockfile');
|
lockfile = require('proper-lockfile');
|
||||||
lockfile.lock.mockResolvedValue(jest.fn().mockResolvedValue());
|
lockfile.lock.mockResolvedValue(jest.fn().mockResolvedValue());
|
||||||
keychainManager = require('../keychain-manager');
|
keychainManager = require('../src/security/keychain-manager');
|
||||||
keychainManager.available = true;
|
keychainManager.available = true;
|
||||||
keychainManager.store.mockResolvedValue(true);
|
keychainManager.store.mockResolvedValue(true);
|
||||||
credentialManager = require('../credential-manager');
|
credentialManager = require('../src/managers/credential-manager');
|
||||||
|
|
||||||
const result = await credentialManager.store('test.key', 'value');
|
const result = await credentialManager.store('test.key', 'value');
|
||||||
expect(result).toBe(true);
|
expect(result).toBe(true);
|
||||||
@@ -91,11 +91,11 @@ describe('CredentialManager', () => {
|
|||||||
fs.writeFileSync.mockImplementation(() => {});
|
fs.writeFileSync.mockImplementation(() => {});
|
||||||
lockfile = require('proper-lockfile');
|
lockfile = require('proper-lockfile');
|
||||||
lockfile.lock.mockResolvedValue(jest.fn().mockResolvedValue());
|
lockfile.lock.mockResolvedValue(jest.fn().mockResolvedValue());
|
||||||
keychainManager = require('../keychain-manager');
|
keychainManager = require('../src/security/keychain-manager');
|
||||||
keychainManager.available = true;
|
keychainManager.available = true;
|
||||||
keychainManager.store.mockResolvedValue(false);
|
keychainManager.store.mockResolvedValue(false);
|
||||||
cryptoUtils = require('../crypto-utils');
|
cryptoUtils = require('../src/security/crypto-utils');
|
||||||
credentialManager = require('../credential-manager');
|
credentialManager = require('../src/managers/credential-manager');
|
||||||
|
|
||||||
const result = await credentialManager.store('test.key', 'value');
|
const result = await credentialManager.store('test.key', 'value');
|
||||||
expect(result).toBe(true);
|
expect(result).toBe(true);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const TEST_KEY_HEX = TEST_KEY.toString('hex');
|
|||||||
// Load the module once — no jest.resetModules() needed
|
// Load the module once — no jest.resetModules() needed
|
||||||
// We control key state via clearCachedKey() + env vars
|
// We control key state via clearCachedKey() + env vars
|
||||||
process.env.DASHCADDY_ENCRYPTION_KEY = TEST_KEY_HEX;
|
process.env.DASHCADDY_ENCRYPTION_KEY = TEST_KEY_HEX;
|
||||||
const cryptoUtils = require('../crypto-utils');
|
const cryptoUtils = require('../src/security/crypto-utils');
|
||||||
|
|
||||||
describe('Crypto Utils', () => {
|
describe('Crypto Utils', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const crypto = require('crypto');
|
|||||||
|
|
||||||
// Mock crypto-utils to provide a predictable signing key
|
// Mock crypto-utils to provide a predictable signing key
|
||||||
const mockFixedKey = Buffer.alloc(32, 'test-key-material');
|
const mockFixedKey = Buffer.alloc(32, 'test-key-material');
|
||||||
jest.mock('../crypto-utils', () => ({
|
jest.mock('../src/security/crypto-utils', () => ({
|
||||||
loadOrCreateKey: jest.fn(() => mockFixedKey),
|
loadOrCreateKey: jest.fn(() => mockFixedKey),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ const {
|
|||||||
csrfCookieMiddleware,
|
csrfCookieMiddleware,
|
||||||
csrfValidationMiddleware,
|
csrfValidationMiddleware,
|
||||||
renewCSRFToken
|
renewCSRFToken
|
||||||
} = require('../csrf-protection');
|
} = require('../src/security/csrf-protection');
|
||||||
const { createMockReqRes } = require('./helpers/test-utils');
|
const { createMockReqRes } = require('./helpers/test-utils');
|
||||||
|
|
||||||
describe('CSRF Protection', () => {
|
describe('CSRF Protection', () => {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ jest.mock('dns', () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const DNSPropagationChecker = require('../dns-propagation');
|
const DNSPropagationChecker = require('../src/dns/dns-propagation');
|
||||||
|
|
||||||
describe('DNSPropagationChecker', () => {
|
describe('DNSPropagationChecker', () => {
|
||||||
let checker;
|
let checker;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ describe('DockerSecurity Module', () => {
|
|||||||
|
|
||||||
// Reset modules to get fresh instance
|
// Reset modules to get fresh instance
|
||||||
jest.resetModules();
|
jest.resetModules();
|
||||||
dockerSecurity = require('../docker-security');
|
dockerSecurity = require('../src/security/docker-security');
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -58,7 +58,7 @@ describe('DockerSecurity Module', () => {
|
|||||||
|
|
||||||
// Force module reload
|
// Force module reload
|
||||||
jest.resetModules();
|
jest.resetModules();
|
||||||
const freshInstance = require('../docker-security');
|
const freshInstance = require('../src/security/docker-security');
|
||||||
const status = freshInstance.getStatus();
|
const status = freshInstance.getStatus();
|
||||||
|
|
||||||
expect(status.trustedImagesCount).toBe(1);
|
expect(status.trustedImagesCount).toBe(1);
|
||||||
@@ -77,7 +77,7 @@ describe('DockerSecurity Module', () => {
|
|||||||
fs.writeFileSync(TEST_CONFIG_FILE, 'INVALID JSON{{{');
|
fs.writeFileSync(TEST_CONFIG_FILE, 'INVALID JSON{{{');
|
||||||
|
|
||||||
jest.resetModules();
|
jest.resetModules();
|
||||||
const freshInstance = require('../docker-security');
|
const freshInstance = require('../src/security/docker-security');
|
||||||
const status = freshInstance.getStatus();
|
const status = freshInstance.getStatus();
|
||||||
|
|
||||||
// Should fall back to default config
|
// Should fall back to default config
|
||||||
@@ -89,7 +89,7 @@ describe('DockerSecurity Module', () => {
|
|||||||
process.env.DOCKER_SECURITY_CONFIG = '/nonexistent/path/config.json';
|
process.env.DOCKER_SECURITY_CONFIG = '/nonexistent/path/config.json';
|
||||||
|
|
||||||
jest.resetModules();
|
jest.resetModules();
|
||||||
const freshInstance = require('../docker-security');
|
const freshInstance = require('../src/security/docker-security');
|
||||||
const status = freshInstance.getStatus();
|
const status = freshInstance.getStatus();
|
||||||
|
|
||||||
// Should fall back to default config
|
// Should fall back to default config
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ jest.mock('../src/utils/logging', () => ({
|
|||||||
LOG_LEVELS: { debug: 0, info: 1, warn: 2, error: 3 }
|
LOG_LEVELS: { debug: 0, info: 1, warn: 2, error: 3 }
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const { errorMiddleware, notFoundHandler } = require('../error-handler');
|
const { errorMiddleware, notFoundHandler } = require('../src/utilities/error-handler');
|
||||||
const {
|
const {
|
||||||
AppError,
|
AppError,
|
||||||
ValidationError,
|
ValidationError,
|
||||||
@@ -20,7 +20,7 @@ const {
|
|||||||
NotFoundError,
|
NotFoundError,
|
||||||
RateLimitError,
|
RateLimitError,
|
||||||
DockerError,
|
DockerError,
|
||||||
} = require('../errors');
|
} = require('../src/utilities/errors');
|
||||||
|
|
||||||
describe('Error Handler', () => {
|
describe('Error Handler', () => {
|
||||||
let req, res, next;
|
let req, res, next;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const {
|
|||||||
CaddyError,
|
CaddyError,
|
||||||
DNSError,
|
DNSError,
|
||||||
ServiceUnavailableError
|
ServiceUnavailableError
|
||||||
} = require('../errors');
|
} = require('../src/utilities/errors');
|
||||||
|
|
||||||
describe('Error Classes', () => {
|
describe('Error Classes', () => {
|
||||||
describe('AppError', () => {
|
describe('AppError', () => {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ describe('HealthChecker', () => {
|
|||||||
fs.writeFileSync.mockImplementation(() => {});
|
fs.writeFileSync.mockImplementation(() => {});
|
||||||
|
|
||||||
// Fresh instance each test
|
// Fresh instance each test
|
||||||
HealthChecker = require('../health-checker').constructor;
|
HealthChecker = require('../src/monitoring/health-checker').constructor;
|
||||||
healthChecker = new HealthChecker();
|
healthChecker = new HealthChecker();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ describe('HealthChecker', () => {
|
|||||||
services: { svc1: { url: 'http://test.local', enabled: true } }
|
services: { svc1: { url: 'http://test.local', enabled: true } }
|
||||||
}));
|
}));
|
||||||
|
|
||||||
HealthChecker = require('../health-checker').constructor;
|
HealthChecker = require('../src/monitoring/health-checker').constructor;
|
||||||
const hc = new HealthChecker();
|
const hc = new HealthChecker();
|
||||||
expect(hc.config.services.svc1).toBeDefined();
|
expect(hc.config.services.svc1).toBeDefined();
|
||||||
});
|
});
|
||||||
@@ -52,7 +52,7 @@ describe('HealthChecker', () => {
|
|||||||
fs.existsSync.mockReturnValue(true);
|
fs.existsSync.mockReturnValue(true);
|
||||||
fs.readFileSync.mockReturnValue('invalid json');
|
fs.readFileSync.mockReturnValue('invalid json');
|
||||||
|
|
||||||
HealthChecker = require('../health-checker').constructor;
|
HealthChecker = require('../src/monitoring/health-checker').constructor;
|
||||||
const hc = new HealthChecker();
|
const hc = new HealthChecker();
|
||||||
expect(hc.config).toEqual({ services: {} });
|
expect(hc.config).toEqual({ services: {} });
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ function buildTestApp(routeFactory, deps, prefix = '/api') {
|
|||||||
const router = routeFactory(deps);
|
const router = routeFactory(deps);
|
||||||
app.use(prefix, router);
|
app.use(prefix, router);
|
||||||
// Error handler
|
// Error handler
|
||||||
const { errorMiddleware } = require('../../error-handler');
|
const { errorMiddleware } = require('../../../src/utilities/error-handler');
|
||||||
app.use(errorMiddleware);
|
app.use(errorMiddleware);
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const {
|
|||||||
isValidPort,
|
isValidPort,
|
||||||
isPrivateIP,
|
isPrivateIP,
|
||||||
validateSecurePath
|
validateSecurePath
|
||||||
} = require('../input-validator');
|
} = require('../src/security/input-validator');
|
||||||
|
|
||||||
describe('Input Validator', () => {
|
describe('Input Validator', () => {
|
||||||
function fail(message) {
|
function fail(message) {
|
||||||
@@ -480,7 +480,7 @@ describe('Input Validator', () => {
|
|||||||
|
|
||||||
// Re-require after mocking fs
|
// Re-require after mocking fs
|
||||||
function getValidateSecurePath() {
|
function getValidateSecurePath() {
|
||||||
return require('../input-validator').validateSecurePath;
|
return require('../src/security/input-validator').validateSecurePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
it('resolves valid path within allowed roots', async () => {
|
it('resolves valid path within allowed roots', async () => {
|
||||||
|
|||||||
@@ -29,13 +29,13 @@ jest.mock('fs', () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.mock('../docker-maintenance', () => ({
|
jest.mock('../src/docker/docker-maintenance', () => ({
|
||||||
getDiskUsage: jest.fn().mockResolvedValue(null),
|
getDiskUsage: jest.fn().mockResolvedValue(null),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const Docker = require('dockerode');
|
const Docker = require('dockerode');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const logDigest = require('../log-digest');
|
const logDigest = require('../src/security/log-digest');
|
||||||
|
|
||||||
describe('LogDigest (singleton)', () => {
|
describe('LogDigest (singleton)', () => {
|
||||||
let dockerInstance;
|
let dockerInstance;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
* state in beforeEach.
|
* state in beforeEach.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const metrics = require('../metrics');
|
const metrics = require('../src/monitoring/metrics');
|
||||||
|
|
||||||
describe('Metrics (singleton)', () => {
|
describe('Metrics (singleton)', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ jest.mock('nodemailer', () => ({
|
|||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const nodemailer = require('nodemailer');
|
const nodemailer = require('nodemailer');
|
||||||
const NotificationManager = require('../notification-manager');
|
const NotificationManager = require('../src/managers/notification-manager');
|
||||||
|
|
||||||
describe('NotificationManager', () => {
|
describe('NotificationManager', () => {
|
||||||
let nm;
|
let nm;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const { paginate, parsePaginationParams, DEFAULT_LIMIT, MAX_LIMIT } = require('../pagination');
|
const { paginate, parsePaginationParams, DEFAULT_LIMIT, MAX_LIMIT } = require('../src/utilities/pagination');
|
||||||
|
|
||||||
describe('Pagination — DashCaddy list endpoints', () => {
|
describe('Pagination — DashCaddy list endpoints', () => {
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ fs.unlinkSync.mockReturnValue(undefined);
|
|||||||
lockfile.lock.mockResolvedValue(jest.fn().mockResolvedValue());
|
lockfile.lock.mockResolvedValue(jest.fn().mockResolvedValue());
|
||||||
lockfile.check.mockResolvedValue(false);
|
lockfile.check.mockResolvedValue(false);
|
||||||
|
|
||||||
const portLockManager = require('../port-lock-manager');
|
const portLockManager = require('../src/managers/port-lock-manager');
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ fs.existsSync.mockReturnValue(false);
|
|||||||
fs.readFileSync.mockReturnValue('{}');
|
fs.readFileSync.mockReturnValue('{}');
|
||||||
fs.writeFileSync.mockReturnValue(undefined);
|
fs.writeFileSync.mockReturnValue(undefined);
|
||||||
|
|
||||||
const resourceMonitor = require('../resource-monitor');
|
const resourceMonitor = require('../src/managers/resource-monitor');
|
||||||
|
|
||||||
function makeStat(overrides = {}) {
|
function makeStat(overrides = {}) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ function buildApp(mockDeps) {
|
|||||||
const app = express();
|
const app = express();
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
const { errorMiddleware } = require('../../error-handler');
|
const { errorMiddleware } = require('../../src/utilities/error-handler');
|
||||||
const containersRouteFactory = require('../../routes/containers');
|
const containersRouteFactory = require('../../routes/containers');
|
||||||
app.use('/api/containers', containersRouteFactory(mockDeps));
|
app.use('/api/containers', containersRouteFactory(mockDeps));
|
||||||
app.use(errorMiddleware);
|
app.use(errorMiddleware);
|
||||||
|
|||||||
@@ -52,21 +52,21 @@ jest.mock('../../platform-paths', () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// Mock fs-helpers.exists
|
// Mock fs-helpers.exists
|
||||||
jest.mock('../../fs-helpers', () => ({
|
jest.mock('../../src/utilities/fs-helpers', () => ({
|
||||||
exists: jest.fn().mockResolvedValue(true),
|
exists: jest.fn().mockResolvedValue(true),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../../url-resolver', () => ({
|
jest.mock('../../src/utilities/url-resolver', () => ({
|
||||||
resolveServiceUrl: jest.fn((id) => `https://${id}.test`),
|
resolveServiceUrl: jest.fn((id) => `https://${id}.test`),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../../pagination', () => ({
|
jest.mock('../../src/utilities/pagination', () => ({
|
||||||
paginate: jest.fn((data, params) => ({ data, pagination: null })),
|
paginate: jest.fn((data, params) => ({ data, pagination: null })),
|
||||||
parsePaginationParams: jest.fn(() => null),
|
parsePaginationParams: jest.fn(() => null),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const { exists } = require('../../fs-helpers');
|
const { exists } = require('../../src/utilities/fs-helpers');
|
||||||
const { resolveServiceUrl } = require('../../url-resolver');
|
const { resolveServiceUrl } = require('../../src/utilities/url-resolver');
|
||||||
const { execSync } = require('child_process');
|
const { execSync } = require('child_process');
|
||||||
|
|
||||||
describe('Health Routes', () => {
|
describe('Health Routes', () => {
|
||||||
|
|||||||
@@ -9,27 +9,27 @@ function asyncHandler(fn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mock modules that services.js requires at top-level
|
// Mock modules that services.js requires at top-level
|
||||||
jest.mock('../../constants', () => ({
|
jest.mock('../../src/utilities/constants', () => ({
|
||||||
APP: { USER_AGENTS: { PROBE: 'DashCaddy/1.0' } },
|
APP: { USER_AGENTS: { PROBE: 'DashCaddy/1.0' } },
|
||||||
REGEX: { SUBDOMAIN: /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/ },
|
REGEX: { SUBDOMAIN: /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/ },
|
||||||
TIMEOUTS: { DEFAULT: 10000 },
|
TIMEOUTS: { DEFAULT: 10000 },
|
||||||
HTTP_STATUS: { OK: 200, CREATED: 201, NO_CONTENT: 204, BAD_REQUEST: 400, UNAUTHORIZED: 401, FORBIDDEN: 403, NOT_FOUND: 404, CONFLICT: 409, INTERNAL_ERROR: 500 }
|
HTTP_STATUS: { OK: 200, CREATED: 201, NO_CONTENT: 204, BAD_REQUEST: 400, UNAUTHORIZED: 401, FORBIDDEN: 403, NOT_FOUND: 404, CONFLICT: 409, INTERNAL_ERROR: 500 }
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../../input-validator', () => ({
|
jest.mock('../../src/security/input-validator', () => ({
|
||||||
validateServiceConfig: jest.fn(),
|
validateServiceConfig: jest.fn(),
|
||||||
isValidPort: jest.fn(p => p >= 1 && p <= 65535),
|
isValidPort: jest.fn(p => p >= 1 && p <= 65535),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../../fs-helpers', () => ({
|
jest.mock('../../src/utilities/fs-helpers', () => ({
|
||||||
exists: jest.fn().mockResolvedValue(true),
|
exists: jest.fn().mockResolvedValue(true),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../../url-resolver', () => ({
|
jest.mock('../../src/utilities/url-resolver', () => ({
|
||||||
resolveServiceUrl: jest.fn((id) => `https://${id}.test`),
|
resolveServiceUrl: jest.fn((id) => `https://${id}.test`),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../../pagination', () => ({
|
jest.mock('../../src/utilities/pagination', () => ({
|
||||||
paginate: jest.fn((data, params) => ({ data, pagination: null })),
|
paginate: jest.fn((data, params) => ({ data, pagination: null })),
|
||||||
parsePaginationParams: jest.fn(() => null),
|
parsePaginationParams: jest.fn(() => null),
|
||||||
}));
|
}));
|
||||||
@@ -45,8 +45,8 @@ jest.mock('../../src/utils/responses', () => ({
|
|||||||
|
|
||||||
// errors module NOT mocked — used for real ValidationError/NotFoundError/ConflictError
|
// errors module NOT mocked — used for real ValidationError/NotFoundError/ConflictError
|
||||||
|
|
||||||
const { exists } = require('../../fs-helpers');
|
const { exists } = require('../../src/utilities/fs-helpers');
|
||||||
const { validateServiceConfig } = require('../../input-validator');
|
const { validateServiceConfig } = require('../../src/security/input-validator');
|
||||||
|
|
||||||
function createApp(depsOverride = {}) {
|
function createApp(depsOverride = {}) {
|
||||||
const defaultDeps = {
|
const defaultDeps = {
|
||||||
@@ -450,7 +450,7 @@ describe('Services Routes', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('rejects invalid port', async () => {
|
it('rejects invalid port', async () => {
|
||||||
const { isValidPort } = require('../../input-validator');
|
const { isValidPort } = require('../../src/security/input-validator');
|
||||||
isValidPort.mockReturnValue(false);
|
isValidPort.mockReturnValue(false);
|
||||||
const { app } = createApp();
|
const { app } = createApp();
|
||||||
const res = await request(app)
|
const res = await request(app)
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ jest.mock('tls', () => ({
|
|||||||
connect: jest.fn(),
|
connect: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('../fs-helpers', () => ({
|
jest.mock('../src/utilities/fs-helpers', () => ({
|
||||||
readJsonFile: jest.fn().mockResolvedValue(null),
|
readJsonFile: jest.fn().mockResolvedValue(null),
|
||||||
writeJsonFile: jest.fn().mockResolvedValue(undefined),
|
writeJsonFile: jest.fn().mockResolvedValue(undefined),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const tls = require('tls');
|
const tls = require('tls');
|
||||||
const fsHelpers = require('../fs-helpers');
|
const fsHelpers = require('../src/utilities/fs-helpers');
|
||||||
const SSLMonitor = require('../ssl-monitor');
|
const SSLMonitor = require('../src/monitoring/ssl-monitor');
|
||||||
|
|
||||||
function makeSocket({ cert = null, error = null } = {}) {
|
function makeSocket({ cert = null, error = null } = {}) {
|
||||||
const { EventEmitter } = require('events');
|
const { EventEmitter } = require('events');
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ jest.mock('fs', () => ({
|
|||||||
|
|
||||||
const lockfile = require('proper-lockfile');
|
const lockfile = require('proper-lockfile');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const StateManager = require('../state-manager');
|
const StateManager = require('../src/managers/state-manager');
|
||||||
|
|
||||||
describe('StateManager', () => {
|
describe('StateManager', () => {
|
||||||
let sm;
|
let sm;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ fs.existsSync.mockReturnValue(false);
|
|||||||
fs.readFileSync.mockReturnValue('{}');
|
fs.readFileSync.mockReturnValue('{}');
|
||||||
fs.writeFileSync.mockReturnValue(undefined);
|
fs.writeFileSync.mockReturnValue(undefined);
|
||||||
|
|
||||||
const updateManager = require('../update-manager');
|
const updateManager = require('../src/managers/update-manager');
|
||||||
|
|
||||||
// Helper to create a fake https request that responds with a given statusCode/headers/body
|
// Helper to create a fake https request that responds with a given statusCode/headers/body
|
||||||
function mockHttpsResponse({ statusCode = 200, headers = {}, body = '' } = {}) {
|
function mockHttpsResponse({ statusCode = 200, headers = {}, body = '' } = {}) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const { resolveServiceUrl } = require('../url-resolver');
|
const { resolveServiceUrl } = require('../src/utilities/url-resolver');
|
||||||
|
|
||||||
describe('URL Resolver — DashCaddy service URL resolution', () => {
|
describe('URL Resolver — DashCaddy service URL resolution', () => {
|
||||||
const buildServiceUrl = jest.fn(id => `https://${id}.sami`);
|
const buildServiceUrl = jest.fn(id => `https://${id}.sami`);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('js-yaml');
|
||||||
const { DOCKER, REGEX } = require('../../constants');
|
const { DOCKER, REGEX } = require('../../../src/utilities/constants');
|
||||||
const { ValidationError } = require('../../errors');
|
const { ValidationError } = require('../../../src/utilities/errors');
|
||||||
const platformPaths = require('../../platform-paths');
|
const platformPaths = require('../../platform-paths');
|
||||||
const { ok } = require('../../src/utils/responses');
|
const { ok } = require('../src/utils/responses');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Docker Compose import routes
|
* Docker Compose import routes
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ const express = require('express');
|
|||||||
const fsp = require('fs').promises;
|
const fsp = require('fs').promises;
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const validatorLib = require('validator');
|
const validatorLib = require('validator');
|
||||||
const { REGEX, DOCKER } = require('../../constants');
|
const { REGEX, DOCKER } = require('../../../src/utilities/constants');
|
||||||
const { isValidPort } = require('../../input-validator');
|
const { isValidPort } = require('../../../src/security/input-validator');
|
||||||
const { exists } = require('../../fs-helpers');
|
const { exists } = require('../../../src/utilities/fs-helpers');
|
||||||
const platformPaths = require('../../platform-paths');
|
const platformPaths = require('../../platform-paths');
|
||||||
const { ValidationError } = require('../../errors');
|
const { ValidationError } = require('../../../src/utilities/errors');
|
||||||
const { logError } = require('../../src/utils/logging');
|
const { logError } = require('../src/utils/logging');
|
||||||
const { ok } = require('../../src/utils/responses');
|
const { ok } = require('../src/utils/responses');
|
||||||
/**
|
/**
|
||||||
* Apps deployment routes factory
|
* Apps deployment routes factory
|
||||||
* @param {Object} deps - Explicit dependencies
|
* @param {Object} deps - Explicit dependencies
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ const fs = require('fs');
|
|||||||
const fsp = require('fs').promises;
|
const fsp = require('fs').promises;
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const { REGEX, DOCKER } = require('../../constants');
|
const { REGEX, DOCKER } = require('../../../src/utilities/constants');
|
||||||
const { exists } = require('../../fs-helpers');
|
const { exists } = require('../../../src/utilities/fs-helpers');
|
||||||
const platformPaths = require('../../platform-paths');
|
const platformPaths = require('../../platform-paths');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { exists } = require('../../fs-helpers');
|
const { exists } = require('../../../src/utilities/fs-helpers');
|
||||||
const { logError } = require('../../src/utils/logging');
|
const { logError } = require('../src/utils/logging');
|
||||||
const { ok } = require('../../src/utils/responses');
|
const { ok } = require('../src/utils/responses');
|
||||||
|
|
||||||
module.exports = function({
|
module.exports = function({
|
||||||
docker, caddy, servicesStateManager, asyncHandler, log, helpers,
|
docker, caddy, servicesStateManager, asyncHandler, log, helpers,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const { DOCKER } = require('../../constants');
|
const { DOCKER } = require('../../../src/utilities/constants');
|
||||||
const { ok, validationError, notFound, errorResponse } = require('../../src/utils/responses');
|
const { ok, validationError, notFound, errorResponse } = require('../../../src/utilities/responses');
|
||||||
|
|
||||||
const DEFAULT_BACKUP_DIR = process.env.BACKUP_DIR || path.join(__dirname, '..', 'backups');
|
const DEFAULT_BACKUP_DIR = process.env.BACKUP_DIR || path.join(__dirname, '..', 'backups');
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { exists } = require('../../fs-helpers');
|
const { exists } = require('../../../src/utilities/fs-helpers');
|
||||||
/**
|
/**
|
||||||
* Apps templates routes factory
|
* Apps templates routes factory
|
||||||
* @param {Object} deps - Explicit dependencies
|
* @param {Object} deps - Explicit dependencies
|
||||||
@@ -19,8 +19,8 @@ const { exists } = require('../../fs-helpers');
|
|||||||
* @param {string} deps.SERVICES_FILE - Services file path
|
* @param {string} deps.SERVICES_FILE - Services file path
|
||||||
* @returns {express.Router}
|
* @returns {express.Router}
|
||||||
*/
|
*/
|
||||||
const { REGEX } = require('../../constants');
|
const { REGEX } = require('../../../src/utilities/constants');
|
||||||
const { ok } = require('../../src/utils/responses');
|
const { ok } = require('../src/utils/responses');
|
||||||
|
|
||||||
module.exports = function({
|
module.exports = function({
|
||||||
servicesStateManager, asyncHandler, helpers,
|
servicesStateManager, asyncHandler, helpers,
|
||||||
@@ -55,7 +55,7 @@ module.exports = function({
|
|||||||
const { appId } = req.params;
|
const { appId } = req.params;
|
||||||
const template = ctx.APP_TEMPLATES[appId];
|
const template = ctx.APP_TEMPLATES[appId];
|
||||||
if (!template) {
|
if (!template) {
|
||||||
const { NotFoundError } = require('../../errors');
|
const { NotFoundError } = require('../../../src/utilities/errors');
|
||||||
throw new NotFoundError('App template');
|
throw new NotFoundError('App template');
|
||||||
}
|
}
|
||||||
ok(res, { template });
|
ok(res, { template });
|
||||||
@@ -90,7 +90,7 @@ module.exports = function({
|
|||||||
// Update subdomain for deployed app
|
// Update subdomain for deployed app
|
||||||
router.post('/update-subdomain', asyncHandler(async (req, res) => {
|
router.post('/update-subdomain', asyncHandler(async (req, res) => {
|
||||||
const { serviceId, oldSubdomain, newSubdomain, containerId, ip } = req.body;
|
const { serviceId, oldSubdomain, newSubdomain, containerId, ip } = req.body;
|
||||||
const { ValidationError } = require('../../errors');
|
const { ValidationError } = require('../../../src/utilities/errors');
|
||||||
|
|
||||||
if (!oldSubdomain || typeof oldSubdomain !== 'string') {
|
if (!oldSubdomain || typeof oldSubdomain !== 'string') {
|
||||||
throw new ValidationError('oldSubdomain is required');
|
throw new ValidationError('oldSubdomain is required');
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { APP_PORTS, ARR_SERVICES } = require('../../constants');
|
const { APP_PORTS, ARR_SERVICES } = require('../../../src/utilities/constants');
|
||||||
const { validateURL, validateToken } = require('../../input-validator');
|
const { validateURL, validateToken } = require('../../../src/security/input-validator');
|
||||||
const { ValidationError, AuthenticationError, NotFoundError } = require('../../errors');
|
const { ValidationError, AuthenticationError, NotFoundError } = require('../../../src/utilities/errors');
|
||||||
const { logError } = require('../../src/utils/logging');
|
const { logError } = require('../src/utils/logging');
|
||||||
const { ok, successMessage } = require('../../src/utils/responses');
|
const { ok, successMessage } = require('../src/utils/responses');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Arr configuration routes factory
|
* Arr configuration routes factory
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { validateURL, validateToken } = require('../../input-validator');
|
const { validateURL, validateToken } = require('../../../src/security/input-validator');
|
||||||
const { ValidationError } = require('../../errors');
|
const { ValidationError } = require('../../../src/utilities/errors');
|
||||||
const { ok, successMessage } = require('../../src/utils/responses');
|
const { ok, successMessage } = require('../src/utils/responses');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Arr credentials routes factory
|
* Arr credentials routes factory
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { APP_PORTS, ARR_SERVICES } = require('../../constants');
|
const { APP_PORTS, ARR_SERVICES } = require('../../../src/utilities/constants');
|
||||||
const { ok } = require('../../src/utils/responses');
|
const { ok } = require('../src/utils/responses');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Arr service detection routes factory
|
* Arr service detection routes factory
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const { APP_PORTS } = require('../../constants');
|
const { APP_PORTS } = require('../../../src/utilities/constants');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Arr helpers factory
|
* Arr helpers factory
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { APP_PORTS } = require('../../constants');
|
const { APP_PORTS } = require('../../../src/utilities/constants');
|
||||||
const { ok } = require('../../src/utils/responses');
|
const { ok } = require('../src/utils/responses');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plex routes factory
|
* Plex routes factory
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { APP_PORTS } = require('../../constants');
|
const { APP_PORTS } = require('../../../src/utilities/constants');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Arr smart-connect routes factory
|
* Arr smart-connect routes factory
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { ValidationError, ForbiddenError, NotFoundError } = require('../../errors');
|
const { ValidationError, ForbiddenError, NotFoundError } = require('../../../src/utilities/errors');
|
||||||
const { ok, successMessage } = require('../../src/utils/responses');
|
const { ok, successMessage } = require('../src/utils/responses');
|
||||||
/**
|
/**
|
||||||
* Auth API keys routes factory
|
* Auth API keys routes factory
|
||||||
* @param {Object} deps - Explicit dependencies
|
* @param {Object} deps - Explicit dependencies
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const { SESSION_TTL, APP, PLEX, TIMEOUTS, buildMediaAuth } = require('../../constants');
|
const { SESSION_TTL, APP, PLEX, TIMEOUTS, buildMediaAuth } = require('../../../src/utilities/constants');
|
||||||
const { createCache, CACHE_CONFIGS } = require('../../cache-config');
|
const { createCache, CACHE_CONFIGS } = require('../../../src/utilities/cache-config');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auth session handlers routes factory
|
* Auth session handlers routes factory
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { SESSION_TTL, APP, PLEX, TIMEOUTS, buildMediaAuth } = require('../../constants');
|
const { SESSION_TTL, APP, PLEX, TIMEOUTS, buildMediaAuth } = require('../../../src/utilities/constants');
|
||||||
const { AuthenticationError, NotFoundError } = require('../../errors');
|
const { AuthenticationError, NotFoundError } = require('../../../src/utilities/errors');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auth SSO gate routes factory
|
* Auth SSO gate routes factory
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { ValidationError, AuthenticationError } = require('../../errors');
|
const { ValidationError, AuthenticationError } = require('../../../src/utilities/errors');
|
||||||
const { ok, successMessage } = require('../../src/utils/responses');
|
const { ok, successMessage } = require('../src/utils/responses');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auth TOTP routes factory
|
* Auth TOTP routes factory
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { success } = require('../src/utils/responses');
|
const { success } = require('../src/utils/responses');
|
||||||
const { ValidationError, NotFoundError } = require('../errors');
|
const { ValidationError, NotFoundError } = require('../src/utilities/errors');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auto-restart route factory
|
* Auto-restart route factory
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ module.exports = function({ backupManager, licenseManager, asyncHandler }) {
|
|||||||
const { appId, enabled, schedule, retention, runImmediately, destination, destinationPath } = req.body;
|
const { appId, enabled, schedule, retention, runImmediately, destination, destinationPath } = req.body;
|
||||||
|
|
||||||
if (!appId) {
|
if (!appId) {
|
||||||
const { ValidationError } = require('../errors');
|
const { ValidationError } = require('../src/utilities/errors');
|
||||||
throw new ValidationError('appId is required');
|
throw new ValidationError('appId is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ module.exports = function({ backupManager, licenseManager, asyncHandler }) {
|
|||||||
const config = backupManager.getConfig();
|
const config = backupManager.getConfig();
|
||||||
|
|
||||||
if (!config.backups || !config.backups[appId]) {
|
if (!config.backups || !config.backups[appId]) {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError(`No backup schedule found for app: ${appId}`, 'DC-404');
|
throw new NotFoundError(`No backup schedule found for app: ${appId}`, 'DC-404');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +153,7 @@ module.exports = function({ backupManager, licenseManager, asyncHandler }) {
|
|||||||
|
|
||||||
const backupConfig = config.backups && config.backups[appId];
|
const backupConfig = config.backups && config.backups[appId];
|
||||||
if (!backupConfig) {
|
if (!backupConfig) {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError(`No backup schedule found for app: ${appId}`, 'DC-404');
|
throw new NotFoundError(`No backup schedule found for app: ${appId}`, 'DC-404');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,13 +229,13 @@ module.exports = function({ backupManager, licenseManager, asyncHandler }) {
|
|||||||
|
|
||||||
// Security: prevent path traversal
|
// Security: prevent path traversal
|
||||||
if (filename.includes('..') || filename.includes('/') || filename.includes('\\')) {
|
if (filename.includes('..') || filename.includes('/') || filename.includes('\\')) {
|
||||||
const { ValidationError } = require('../errors');
|
const { ValidationError } = require('../src/utilities/errors');
|
||||||
throw new ValidationError('Invalid filename');
|
throw new ValidationError('Invalid filename');
|
||||||
}
|
}
|
||||||
|
|
||||||
const filepath = path.join(DEFAULT_BACKUP_DIR, filename);
|
const filepath = path.join(DEFAULT_BACKUP_DIR, filename);
|
||||||
if (!fs.existsSync(filepath)) {
|
if (!fs.existsSync(filepath)) {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError(`Backup file not found: ${filename}`, 'DC-404');
|
throw new NotFoundError(`Backup file not found: ${filename}`, 'DC-404');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,13 +365,13 @@ module.exports = function({ backupManager, licenseManager, asyncHandler }) {
|
|||||||
|
|
||||||
// Security: prevent path traversal
|
// Security: prevent path traversal
|
||||||
if (filename.includes('..') || filename.includes('/') || filename.includes('\\')) {
|
if (filename.includes('..') || filename.includes('/') || filename.includes('\\')) {
|
||||||
const { ValidationError } = require('../errors');
|
const { ValidationError } = require('../src/utilities/errors');
|
||||||
throw new ValidationError('Invalid filename');
|
throw new ValidationError('Invalid filename');
|
||||||
}
|
}
|
||||||
|
|
||||||
const filepath = path.join(DEFAULT_BACKUP_DIR, filename);
|
const filepath = path.join(DEFAULT_BACKUP_DIR, filename);
|
||||||
if (!fs.existsSync(filepath)) {
|
if (!fs.existsSync(filepath)) {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError(`Backup file not found: ${filename}`, 'DC-404');
|
throw new NotFoundError(`Backup file not found: ${filename}`, 'DC-404');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,7 +502,7 @@ module.exports = function({ backupManager, licenseManager, asyncHandler }) {
|
|||||||
router.post('/backups/test-destination', asyncHandler(async (req, res) => {
|
router.post('/backups/test-destination', asyncHandler(async (req, res) => {
|
||||||
const destination = req.body;
|
const destination = req.body;
|
||||||
if (!destination || !destination.type) {
|
if (!destination || !destination.type) {
|
||||||
const { ValidationError } = require('../errors');
|
const { ValidationError } = require('../src/utilities/errors');
|
||||||
throw new ValidationError('destination.type is required');
|
throw new ValidationError('destination.type is required');
|
||||||
}
|
}
|
||||||
const result = await backupManager.testDestination(destination);
|
const result = await backupManager.testDestination(destination);
|
||||||
@@ -512,10 +512,10 @@ module.exports = function({ backupManager, licenseManager, asyncHandler }) {
|
|||||||
// Get cloud credentials (masked) for a provider
|
// Get cloud credentials (masked) for a provider
|
||||||
// Provider: dropbox | webdav | sftp
|
// Provider: dropbox | webdav | sftp
|
||||||
router.get('/backups/credentials/:provider', asyncHandler(async (req, res) => {
|
router.get('/backups/credentials/:provider', asyncHandler(async (req, res) => {
|
||||||
const credentialManager = require('../credential-manager');
|
const credentialManager = require('../src/managers/credential-manager');
|
||||||
const provider = req.params.provider;
|
const provider = req.params.provider;
|
||||||
if (!['dropbox', 'webdav', 'sftp'].includes(provider)) {
|
if (!['dropbox', 'webdav', 'sftp'].includes(provider)) {
|
||||||
const { ValidationError } = require('../errors');
|
const { ValidationError } = require('../src/utilities/errors');
|
||||||
throw new ValidationError('Invalid provider');
|
throw new ValidationError('Invalid provider');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,8 +544,8 @@ module.exports = function({ backupManager, licenseManager, asyncHandler }) {
|
|||||||
|
|
||||||
// Save cloud credentials for a provider
|
// Save cloud credentials for a provider
|
||||||
router.post('/backups/credentials/:provider', asyncHandler(async (req, res) => {
|
router.post('/backups/credentials/:provider', asyncHandler(async (req, res) => {
|
||||||
const credentialManager = require('../credential-manager');
|
const credentialManager = require('../src/managers/credential-manager');
|
||||||
const { ValidationError } = require('../errors');
|
const { ValidationError } = require('../src/utilities/errors');
|
||||||
const provider = req.params.provider;
|
const provider = req.params.provider;
|
||||||
|
|
||||||
if (!['dropbox', 'webdav', 'sftp'].includes(provider)) {
|
if (!['dropbox', 'webdav', 'sftp'].includes(provider)) {
|
||||||
@@ -585,8 +585,8 @@ module.exports = function({ backupManager, licenseManager, asyncHandler }) {
|
|||||||
|
|
||||||
// Delete cloud credentials for a provider
|
// Delete cloud credentials for a provider
|
||||||
router.delete('/backups/credentials/:provider', asyncHandler(async (req, res) => {
|
router.delete('/backups/credentials/:provider', asyncHandler(async (req, res) => {
|
||||||
const credentialManager = require('../credential-manager');
|
const credentialManager = require('../src/managers/credential-manager');
|
||||||
const { ValidationError } = require('../errors');
|
const { ValidationError } = require('../src/utilities/errors');
|
||||||
const provider = req.params.provider;
|
const provider = req.params.provider;
|
||||||
|
|
||||||
if (!['dropbox', 'webdav', 'sftp'].includes(provider)) {
|
if (!['dropbox', 'webdav', 'sftp'].includes(provider)) {
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ const express = require('express');
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const fsp = require('fs').promises;
|
const fsp = require('fs').promises;
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { exists, isAccessible } = require('../fs-helpers');
|
const { exists, isAccessible } = require('../src/utilities/fs-helpers');
|
||||||
const { paginate, parsePaginationParams } = require('../pagination');
|
const { paginate, parsePaginationParams } = require('../src/utilities/pagination');
|
||||||
const { ValidationError, ForbiddenError } = require('../errors');
|
const { ValidationError, ForbiddenError } = require('../src/utilities/errors');
|
||||||
const { ok } = require('../src/utils/responses');
|
const { ok } = require('../src/utils/responses');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -99,7 +99,7 @@ module.exports = function({ asyncHandler, validateSecurePath, auditLogger, docke
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!await exists(resolvedPath)) {
|
if (!await exists(resolvedPath)) {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError('Path');
|
throw new NotFoundError('Path');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ const fs = require('fs');
|
|||||||
const fsp = require('fs').promises;
|
const fsp = require('fs').promises;
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { execSync } = require('child_process');
|
const { execSync } = require('child_process');
|
||||||
const { exists } = require('../fs-helpers');
|
const { exists } = require('../src/utilities/fs-helpers');
|
||||||
const { ValidationError } = require('../errors');
|
const { ValidationError } = require('../src/utilities/errors');
|
||||||
const { ok } = require('../src/utils/responses');
|
const { ok } = require('../src/utils/responses');
|
||||||
const platformPaths = require('../platform-paths');
|
const platformPaths = require('../platform-paths');
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ module.exports = function(ctx) {
|
|||||||
if (await exists(certInfoPath)) {
|
if (await exists(certInfoPath)) {
|
||||||
certInfoFile = certInfoPath;
|
certInfoFile = certInfoPath;
|
||||||
} else {
|
} else {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError('CA certificate information');
|
throw new NotFoundError('CA certificate information');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ module.exports = function(ctx) {
|
|||||||
if (await exists(dashcaCertPath)) certPath = dashcaCertPath;
|
if (await exists(dashcaCertPath)) certPath = dashcaCertPath;
|
||||||
else if (await exists(hostCertPath)) certPath = hostCertPath;
|
else if (await exists(hostCertPath)) certPath = hostCertPath;
|
||||||
else {
|
else {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError('Root CA certificate');
|
throw new NotFoundError('Root CA certificate');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ module.exports = function(ctx) {
|
|||||||
if (await exists(certInfoPath)) {
|
if (await exists(certInfoPath)) {
|
||||||
certInfoFile = certInfoPath;
|
certInfoFile = certInfoPath;
|
||||||
} else {
|
} else {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError('CA certificate information. Deploy DashCA first or ensure cert-info.json exists.');
|
throw new NotFoundError('CA certificate information. Deploy DashCA first or ensure cert-info.json exists.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ module.exports = function(ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!templateContent) {
|
if (!templateContent) {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError(`Install script template (${templateName})`);
|
throw new NotFoundError(`Install script template (${templateName})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { success } = require('../src/utils/responses');
|
const { success } = require('../src/utils/responses');
|
||||||
const { ValidationError, NotFoundError } = require('../errors');
|
const { ValidationError, NotFoundError } = require('../src/utilities/errors');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Config-drift route factory
|
* Config-drift route factory
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const fsp = require('fs').promises;
|
const fsp = require('fs').promises;
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { LIMITS } = require('../../constants');
|
const { LIMITS } = require('../../../src/utilities/constants');
|
||||||
const { exists } = require('../../fs-helpers');
|
const { exists } = require('../../../src/utilities/fs-helpers');
|
||||||
const { ValidationError } = require('../../errors');
|
const { ValidationError } = require('../../../src/utilities/errors');
|
||||||
const platformPaths = require('../../platform-paths');
|
const platformPaths = require('../../platform-paths');
|
||||||
const { ok, successMessage } = require('../../src/utils/responses');
|
const { ok, successMessage } = require('../src/utils/responses');
|
||||||
/**
|
/**
|
||||||
* Config assets routes factory
|
* Config assets routes factory
|
||||||
* @param {Object} deps - Explicit dependencies
|
* @param {Object} deps - Explicit dependencies
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
const fsp = require('fs').promises;
|
const fsp = require('fs').promises;
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { CADDY } = require('../../constants');
|
const { CADDY } = require('../../../src/utilities/constants');
|
||||||
const { exists } = require('../../fs-helpers');
|
const { exists } = require('../../../src/utilities/fs-helpers');
|
||||||
const { ValidationError, AuthenticationError } = require('../../errors');
|
const { ValidationError, AuthenticationError } = require('../../../src/utilities/errors');
|
||||||
const platformPaths = require('../../platform-paths');
|
const platformPaths = require('../../platform-paths');
|
||||||
const { ok } = require('../../src/utils/responses');
|
const { ok } = require('../src/utils/responses');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Config backup routes factory
|
* Config backup routes factory
|
||||||
@@ -380,7 +380,7 @@ module.exports = function(deps) {
|
|||||||
if (results.restored.includes('encryptionKey')) {
|
if (results.restored.includes('encryptionKey')) {
|
||||||
try {
|
try {
|
||||||
// Clear the cached key so crypto-utils reloads from the new file on next use
|
// Clear the cached key so crypto-utils reloads from the new file on next use
|
||||||
const cryptoUtils = require('../../crypto-utils');
|
const cryptoUtils = require('../../../src/security/crypto-utils');
|
||||||
if (typeof cryptoUtils.clearCachedKey === 'function') {
|
if (typeof cryptoUtils.clearCachedKey === 'function') {
|
||||||
cryptoUtils.clearCachedKey();
|
cryptoUtils.clearCachedKey();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
const fsp = require('fs').promises;
|
const fsp = require('fs').promises;
|
||||||
const { validateConfig } = require('../../config-schema');
|
const { validateConfig } = require('../../../src/utilities/config-schema');
|
||||||
const { exists } = require('../../fs-helpers');
|
const { exists } = require('../../../src/utilities/fs-helpers');
|
||||||
const { ValidationError } = require('../../errors');
|
const { ValidationError } = require('../../../src/utilities/errors');
|
||||||
const { ok, successMessage } = require('../../src/utils/responses');
|
const { ok, successMessage } = require('../src/utils/responses');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Config settings routes factory
|
* Config settings routes factory
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { DOCKER } = require('../constants');
|
const { DOCKER } = require('../src/utilities/constants');
|
||||||
const { paginate, parsePaginationParams } = require('../pagination');
|
const { paginate, parsePaginationParams } = require('../src/utilities/pagination');
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
const { success } = require('../src/utils/responses');
|
const { success } = require('../src/utils/responses');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { success, error: errorResponse } = require('../src/utils/responses');
|
const { success, error: errorResponse } = require('../src/utils/responses');
|
||||||
const { NotFoundError, ValidationError } = require('../errors');
|
const { NotFoundError, ValidationError } = require('../src/utilities/errors');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dependencies route factory
|
* Dependencies route factory
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ const express = require('express');
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const fsp = require('fs').promises;
|
const fsp = require('fs').promises;
|
||||||
const validatorLib = require('validator');
|
const validatorLib = require('validator');
|
||||||
const { APP, TIMEOUTS, CADDY, DNS_RECORD_TYPES, REGEX, SESSION_TTL } = require('../constants');
|
const { APP, TIMEOUTS, CADDY, DNS_RECORD_TYPES, REGEX, SESSION_TTL } = require('../src/utilities/constants');
|
||||||
const { exists } = require('../fs-helpers');
|
const { exists } = require('../src/utilities/fs-helpers');
|
||||||
const { success, error: errorResponse } = require('../src/utils/responses');
|
const { success, error: errorResponse } = require('../src/utils/responses');
|
||||||
const { ValidationError, AuthenticationError, NotFoundError } = require('../errors');
|
const { ValidationError, AuthenticationError, NotFoundError } = require('../src/utilities/errors');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DNS routes factory
|
* DNS routes factory
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { success } = require('../src/utils/responses');
|
const { success } = require('../src/utils/responses');
|
||||||
const { ValidationError } = require('../errors');
|
const { ValidationError } = require('../src/utilities/errors');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Docker resources route factory (volumes, networks, disk usage)
|
* Docker resources route factory (volumes, networks, disk usage)
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const fsp = require('fs').promises;
|
const fsp = require('fs').promises;
|
||||||
const { exists } = require('../fs-helpers');
|
const { exists } = require('../src/utilities/fs-helpers');
|
||||||
const { paginate, parsePaginationParams } = require('../pagination');
|
const { paginate, parsePaginationParams } = require('../src/utilities/pagination');
|
||||||
const { success } = require('../src/utils/responses');
|
const { success } = require('../src/utils/responses');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ const express = require('express');
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { execSync } = require('child_process');
|
const { execSync } = require('child_process');
|
||||||
const { TIMEOUTS } = require('../constants');
|
const { TIMEOUTS } = require('../src/utilities/constants');
|
||||||
const { exists } = require('../fs-helpers');
|
const { exists } = require('../src/utilities/fs-helpers');
|
||||||
const { paginate, parsePaginationParams } = require('../pagination');
|
const { paginate, parsePaginationParams } = require('../src/utilities/pagination');
|
||||||
const platformPaths = require('../platform-paths');
|
const platformPaths = require('../platform-paths');
|
||||||
const { resolveServiceUrl } = require('../url-resolver');
|
const { resolveServiceUrl } = require('../src/utilities/url-resolver');
|
||||||
const { success, error: errorResponse, errorResponse: sendError, ok, notFound } = require('../src/utils/responses');
|
const { success, error: errorResponse, errorResponse: sendError, ok, notFound } = require('../src/utils/responses');
|
||||||
const { ValidationError } = require('../errors');
|
const { ValidationError } = require('../src/utilities/errors');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Health routes factory
|
* Health routes factory
|
||||||
@@ -190,7 +190,7 @@ module.exports = function({
|
|||||||
|
|
||||||
// Load service config
|
// Load service config
|
||||||
if (!await exists(SERVICES_FILE)) {
|
if (!await exists(SERVICES_FILE)) {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError('Services file');
|
throw new NotFoundError('Services file');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ module.exports = function({
|
|||||||
const service = services.find(s => (s.id || s.name?.toLowerCase()) === serviceId);
|
const service = services.find(s => (s.id || s.name?.toLowerCase()) === serviceId);
|
||||||
|
|
||||||
if (!service) {
|
if (!service) {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError('Service');
|
throw new NotFoundError('Service');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,7 +331,7 @@ module.exports = function({
|
|||||||
const hours = parseInt(req.query.hours) || 24;
|
const hours = parseInt(req.query.hours) || 24;
|
||||||
const stats = healthChecker.getServiceStats(req.params.serviceId, hours);
|
const stats = healthChecker.getServiceStats(req.params.serviceId, hours);
|
||||||
if (!stats) {
|
if (!stats) {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError('Service');
|
throw new NotFoundError('Service');
|
||||||
}
|
}
|
||||||
success(res, { stats });
|
success(res, { stats });
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { success, error: errorResponse } = require('../src/utils/responses');
|
const { success, error: errorResponse } = require('../src/utils/responses');
|
||||||
const { ValidationError } = require('../errors');
|
const { ValidationError } = require('../src/utilities/errors');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* License routes factory
|
* License routes factory
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ const express = require('express');
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const fsp = require('fs').promises;
|
const fsp = require('fs').promises;
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { exists } = require('../fs-helpers');
|
const { exists } = require('../src/utilities/fs-helpers');
|
||||||
const { paginate, parsePaginationParams } = require('../pagination');
|
const { paginate, parsePaginationParams } = require('../src/utilities/pagination');
|
||||||
const { NotFoundError, ValidationError, ForbiddenError } = require('../errors');
|
const { NotFoundError, ValidationError, ForbiddenError } = require('../src/utilities/errors');
|
||||||
const { ok } = require('../src/utils/responses');
|
const { ok } = require('../src/utils/responses');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,7 +48,7 @@ module.exports = function({ asyncHandler, docker, logDigest, dockerMaintenance }
|
|||||||
info = await container.inspect();
|
info = await container.inspect();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.statusCode === 404 || (err.message && err.message.includes('no such container'))) {
|
if (err.statusCode === 404 || (err.message && err.message.includes('no such container'))) {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError(`Container ${containerId}`);
|
throw new NotFoundError(`Container ${containerId}`);
|
||||||
}
|
}
|
||||||
throw err;
|
throw err;
|
||||||
@@ -97,7 +97,7 @@ module.exports = function({ asyncHandler, docker, logDigest, dockerMaintenance }
|
|||||||
await container.inspect();
|
await container.inspect();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.statusCode === 404 || (err.message && err.message.includes('no such container'))) {
|
if (err.statusCode === 404 || (err.message && err.message.includes('no such container'))) {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError(`Container ${containerId}`);
|
throw new NotFoundError(`Container ${containerId}`);
|
||||||
}
|
}
|
||||||
throw err;
|
throw err;
|
||||||
@@ -232,7 +232,7 @@ module.exports = function({ asyncHandler, docker, logDigest, dockerMaintenance }
|
|||||||
try {
|
try {
|
||||||
resolvedPath = await fsp.realpath(normalizedPath);
|
resolvedPath = await fsp.realpath(normalizedPath);
|
||||||
} catch {
|
} catch {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError('Log file');
|
throw new NotFoundError('Log file');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,7 +247,7 @@ module.exports = function({ asyncHandler, docker, logDigest, dockerMaintenance }
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!await exists(resolvedPath)) {
|
if (!await exists(resolvedPath)) {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError('Log file');
|
throw new NotFoundError('Log file');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ module.exports = function({ resourceMonitor, docker, asyncHandler, log, notifica
|
|||||||
router.get('/monitoring/stats/:containerId', asyncHandler(async (req, res) => {
|
router.get('/monitoring/stats/:containerId', asyncHandler(async (req, res) => {
|
||||||
const stats = resourceMonitor.getCurrentStats(req.params.containerId);
|
const stats = resourceMonitor.getCurrentStats(req.params.containerId);
|
||||||
if (!stats) {
|
if (!stats) {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError('Container');
|
throw new NotFoundError('Container');
|
||||||
}
|
}
|
||||||
success(res, { stats });
|
success(res, { stats });
|
||||||
@@ -55,7 +55,7 @@ module.exports = function({ resourceMonitor, docker, asyncHandler, log, notifica
|
|||||||
const startTime = parseInt(req.query.startTime, 10);
|
const startTime = parseInt(req.query.startTime, 10);
|
||||||
const endTime = parseInt(req.query.endTime, 10);
|
const endTime = parseInt(req.query.endTime, 10);
|
||||||
if (Number.isNaN(startTime) || Number.isNaN(endTime) || startTime >= endTime) {
|
if (Number.isNaN(startTime) || Number.isNaN(endTime) || startTime >= endTime) {
|
||||||
const { ValidationError } = require('../errors');
|
const { ValidationError } = require('../src/utilities/errors');
|
||||||
throw new ValidationError('Invalid startTime/endTime');
|
throw new ValidationError('Invalid startTime/endTime');
|
||||||
}
|
}
|
||||||
const result = resourceMonitor.getHistoryByRange(containerId, startTime, endTime);
|
const result = resourceMonitor.getHistoryByRange(containerId, startTime, endTime);
|
||||||
@@ -74,7 +74,7 @@ module.exports = function({ resourceMonitor, docker, asyncHandler, log, notifica
|
|||||||
const hours = parseInt(req.query.hours) || 24;
|
const hours = parseInt(req.query.hours) || 24;
|
||||||
const aggregated = resourceMonitor.getAggregatedStats(req.params.containerId, hours);
|
const aggregated = resourceMonitor.getAggregatedStats(req.params.containerId, hours);
|
||||||
if (!aggregated) {
|
if (!aggregated) {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError('Monitoring data');
|
throw new NotFoundError('Monitoring data');
|
||||||
}
|
}
|
||||||
success(res, { aggregated, hours });
|
success(res, { aggregated, hours });
|
||||||
@@ -92,7 +92,7 @@ module.exports = function({ resourceMonitor, docker, asyncHandler, log, notifica
|
|||||||
router.post('/monitoring/alerts/config', asyncHandler(async (req, res) => {
|
router.post('/monitoring/alerts/config', asyncHandler(async (req, res) => {
|
||||||
const { configs } = req.body;
|
const { configs } = req.body;
|
||||||
if (!configs || typeof configs !== 'object') {
|
if (!configs || typeof configs !== 'object') {
|
||||||
const { ValidationError } = require('../errors');
|
const { ValidationError } = require('../src/utilities/errors');
|
||||||
throw new ValidationError('configs object required');
|
throw new ValidationError('configs object required');
|
||||||
}
|
}
|
||||||
for (const [containerId, config] of Object.entries(configs)) {
|
for (const [containerId, config] of Object.entries(configs)) {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { validateURL, validateToken } = require('../input-validator');
|
const { validateURL, validateToken } = require('../src/security/input-validator');
|
||||||
const validatorLib = require('validator');
|
const validatorLib = require('validator');
|
||||||
const { paginate, parsePaginationParams } = require('../pagination');
|
const { paginate, parsePaginationParams } = require('../src/utilities/pagination');
|
||||||
const { ValidationError } = require('../errors');
|
const { ValidationError } = require('../src/utilities/errors');
|
||||||
const { ok, successMessage } = require('../src/utils/responses');
|
const { ok, successMessage } = require('../src/utils/responses');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { ValidationError } = require('../../errors');
|
const { ValidationError } = require('../../../src/utilities/errors');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const { DOCKER } = require('../../constants');
|
const { DOCKER } = require('../../../src/utilities/constants');
|
||||||
const { ok } = require('../../src/utils/responses');
|
const { ok } = require('../src/utils/responses');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recipes deployment routes factory
|
* Recipes deployment routes factory
|
||||||
@@ -28,7 +28,7 @@ module.exports = function({ docker, credentialManager: _credentialManager, servi
|
|||||||
// eslint-disable-next-line complexity
|
// eslint-disable-next-line complexity
|
||||||
router.post('/deploy', asyncHandler(async (req, res) => {
|
router.post('/deploy', asyncHandler(async (req, res) => {
|
||||||
const { recipeId, config } = req.body;
|
const { recipeId, config } = req.body;
|
||||||
const { RECIPE_TEMPLATES } = require('../../recipe-templates');
|
const { RECIPE_TEMPLATES } = require('../../../src/recipes/recipe-templates');
|
||||||
|
|
||||||
const recipe = RECIPE_TEMPLATES[recipeId];
|
const recipe = RECIPE_TEMPLATES[recipeId];
|
||||||
if (!recipe) throw new ValidationError('Invalid recipe template', 'recipeId');
|
if (!recipe) throw new ValidationError('Invalid recipe template', 'recipeId');
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const deployRoutes = require('./deploy');
|
const deployRoutes = require('./deploy');
|
||||||
const manageRoutes = require('./manage');
|
const manageRoutes = require('./manage');
|
||||||
const { NotFoundError } = require('../../errors');
|
const { NotFoundError } = require('../../../src/utilities/errors');
|
||||||
const { ok } = require('../../src/utils/responses');
|
const { ok } = require('../src/utils/responses');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recipes routes aggregator
|
* Recipes routes aggregator
|
||||||
@@ -32,7 +32,7 @@ module.exports = function(ctx) {
|
|||||||
|
|
||||||
// GET /api/recipes/templates — list all recipe templates
|
// GET /api/recipes/templates — list all recipe templates
|
||||||
router.get('/templates', deps.asyncHandler(async (req, res) => {
|
router.get('/templates', deps.asyncHandler(async (req, res) => {
|
||||||
const { RECIPE_TEMPLATES, RECIPE_CATEGORIES } = require('../../recipe-templates');
|
const { RECIPE_TEMPLATES, RECIPE_CATEGORIES } = require('../../../src/recipes/recipe-templates');
|
||||||
const templates = Object.entries(RECIPE_TEMPLATES).map(([id, recipe]) => ({
|
const templates = Object.entries(RECIPE_TEMPLATES).map(([id, recipe]) => ({
|
||||||
id,
|
id,
|
||||||
name: recipe.name,
|
name: recipe.name,
|
||||||
@@ -61,7 +61,7 @@ module.exports = function(ctx) {
|
|||||||
|
|
||||||
// GET /api/recipes/templates/:recipeId — get single recipe template detail
|
// GET /api/recipes/templates/:recipeId — get single recipe template detail
|
||||||
router.get('/templates/:recipeId', deps.asyncHandler(async (req, res) => {
|
router.get('/templates/:recipeId', deps.asyncHandler(async (req, res) => {
|
||||||
const { RECIPE_TEMPLATES } = require('../../recipe-templates');
|
const { RECIPE_TEMPLATES } = require('../../../src/recipes/recipe-templates');
|
||||||
const recipe = RECIPE_TEMPLATES[req.params.recipeId];
|
const recipe = RECIPE_TEMPLATES[req.params.recipeId];
|
||||||
if (!recipe) throw new NotFoundError(`Recipe template ${req.params.recipeId}`);
|
if (!recipe) throw new NotFoundError(`Recipe template ${req.params.recipeId}`);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { DOCKER } = require('../../constants');
|
const { DOCKER } = require('../../../src/utilities/constants');
|
||||||
const { NotFoundError } = require('../../errors');
|
const { NotFoundError } = require('../../../src/utilities/errors');
|
||||||
const { ok } = require('../../src/utils/responses');
|
const { ok } = require('../src/utils/responses');
|
||||||
|
|
||||||
module.exports = function({ servicesStateManager, asyncHandler, log, docker, notification, buildDomain, caddy }) {
|
module.exports = function({ servicesStateManager, asyncHandler, log, docker, notification, buildDomain, caddy }) {
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
@@ -269,7 +269,7 @@ module.exports = function({ servicesStateManager, asyncHandler, log, docker, not
|
|||||||
* Find all Docker containers belonging to a recipe by label
|
* Find all Docker containers belonging to a recipe by label
|
||||||
*/
|
*/
|
||||||
async function findRecipeContainers(recipeId) {
|
async function findRecipeContainers(recipeId) {
|
||||||
const { RECIPE_TEMPLATES } = require('../../recipe-templates');
|
const { RECIPE_TEMPLATES } = require('../../../src/recipes/recipe-templates');
|
||||||
const recipe = RECIPE_TEMPLATES[recipeId];
|
const recipe = RECIPE_TEMPLATES[recipeId];
|
||||||
const recipeLabel = recipe
|
const recipeLabel = recipe
|
||||||
? recipe.name.toLowerCase().replace(/\s+/g, '-')
|
? recipe.name.toLowerCase().replace(/\s+/g, '-')
|
||||||
@@ -293,7 +293,7 @@ module.exports = function({ servicesStateManager, asyncHandler, log, docker, not
|
|||||||
* Find recipe ID by its label (name slug)
|
* Find recipe ID by its label (name slug)
|
||||||
*/
|
*/
|
||||||
function findRecipeIdByLabel(label) {
|
function findRecipeIdByLabel(label) {
|
||||||
const { RECIPE_TEMPLATES } = require('../../recipe-templates');
|
const { RECIPE_TEMPLATES } = require('../../../src/recipes/recipe-templates');
|
||||||
for (const [id, recipe] of Object.entries(RECIPE_TEMPLATES)) {
|
for (const [id, recipe] of Object.entries(RECIPE_TEMPLATES)) {
|
||||||
if (recipe.name.toLowerCase().replace(/\s+/g, '-') === label) {
|
if (recipe.name.toLowerCase().replace(/\s+/g, '-') === label) {
|
||||||
return id;
|
return id;
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ const http = require('http');
|
|||||||
const https = require('https');
|
const https = require('https');
|
||||||
const tls = require('tls');
|
const tls = require('tls');
|
||||||
const validatorLib = require('validator');
|
const validatorLib = require('validator');
|
||||||
const { APP, REGEX, TIMEOUTS } = require('../constants');
|
const { APP, REGEX, TIMEOUTS } = require('../src/utilities/constants');
|
||||||
const { validateServiceConfig, isValidPort } = require('../input-validator');
|
const { validateServiceConfig, isValidPort } = require('../src/security/input-validator');
|
||||||
const { exists } = require('../fs-helpers');
|
const { exists } = require('../src/utilities/fs-helpers');
|
||||||
const { paginate, parsePaginationParams } = require('../pagination');
|
const { paginate, parsePaginationParams } = require('../src/utilities/pagination');
|
||||||
const { ValidationError, NotFoundError, ConflictError } = require('../errors');
|
const { ValidationError, NotFoundError, ConflictError } = require('../src/utilities/errors');
|
||||||
const { resolveServiceUrl } = require('../url-resolver');
|
const { resolveServiceUrl } = require('../src/utilities/url-resolver');
|
||||||
const { success, error: errorResponse } = require('../src/utils/responses');
|
const { success, error: errorResponse } = require('../src/utils/responses');
|
||||||
const platformPaths = require('../platform-paths');
|
const platformPaths = require('../platform-paths');
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const { CADDY, REGEX, LIMITS } = require('../constants');
|
const { CADDY, REGEX, LIMITS } = require('../src/utilities/constants');
|
||||||
const { ValidationError, ConflictError, NotFoundError } = require('../errors');
|
const { ValidationError, ConflictError, NotFoundError } = require('../src/utilities/errors');
|
||||||
const { validateURL } = require('../input-validator');
|
const { validateURL } = require('../src/security/input-validator');
|
||||||
const { ok, successMessage } = require('../src/utils/responses');
|
const { ok, successMessage } = require('../src/utils/responses');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const { TAILSCALE } = require('../constants');
|
const { TAILSCALE } = require('../src/utilities/constants');
|
||||||
const { exists } = require('../fs-helpers');
|
const { exists } = require('../src/utilities/fs-helpers');
|
||||||
const { ValidationError, NotFoundError } = require('../errors');
|
const { ValidationError, NotFoundError } = require('../src/utilities/errors');
|
||||||
const { ok, successMessage, unauthorized } = require('../src/utils/responses');
|
const { ok, successMessage, unauthorized } = require('../src/utils/responses');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -156,7 +156,7 @@ module.exports = function({
|
|||||||
const match = content.match(blockRegex);
|
const match = content.match(blockRegex);
|
||||||
|
|
||||||
if (!match) {
|
if (!match) {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../src/utilities/errors');
|
||||||
throw new NotFoundError(`Service ${domain} in Caddyfile`);
|
throw new NotFoundError(`Service ${domain} in Caddyfile`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const express = require('express');
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { success } = require('../src/utils/responses');
|
const { success } = require('../src/utils/responses');
|
||||||
const { ValidationError, NotFoundError } = require('../errors');
|
const { ValidationError, NotFoundError } = require('../src/utilities/errors');
|
||||||
const platformPaths = require('../platform-paths');
|
const platformPaths = require('../platform-paths');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { paginate, parsePaginationParams } = require('../pagination');
|
const { paginate, parsePaginationParams } = require('../src/utilities/pagination');
|
||||||
const { ValidationError } = require('../errors');
|
const { ValidationError } = require('../src/utilities/errors');
|
||||||
const { ok, successMessage } = require('../src/utils/responses');
|
const { ok, successMessage } = require('../src/utils/responses');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Fix the remaining broken require paths after DC-005 refactor.
|
||||||
|
|
||||||
|
Two patterns to fix:
|
||||||
|
1. `require('./src/...')` and `require('../../src/...')` and `require('../../../src/...')`
|
||||||
|
in files inside `src/` directories → should be `require('../...')` (relative to src/)
|
||||||
|
2. `require('../../../src/...')` in test files in `__tests__/` → should be `require('../src/...')`
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
DASHCADDY_API = Path('/root/dashcaddy-krystie/dashcaddy-api')
|
||||||
|
|
||||||
|
# Pattern to match require('../../../src/X/Y') and capture
|
||||||
|
# We need to detect the file's location and rewrite based on that
|
||||||
|
# A simple approach: find any require that contains 'src/' in the path,
|
||||||
|
# and rewrite it to be relative to the file's location.
|
||||||
|
|
||||||
|
def fix_file(filepath: Path) -> bool:
|
||||||
|
"""Returns True if file was changed."""
|
||||||
|
content = filepath.read_text()
|
||||||
|
original = content
|
||||||
|
|
||||||
|
# Find the file's directory relative to dashcaddy-api root
|
||||||
|
rel_dir = filepath.parent.relative_to(DASHCADDY_API)
|
||||||
|
depth = len(rel_dir.parts)
|
||||||
|
|
||||||
|
# If file is in src/X/Y/file.js, depth is 3 (src, X, Y)
|
||||||
|
# If file is in __tests__/file.js, depth is 1
|
||||||
|
# If file is in __tests__/routes/file.js, depth is 2
|
||||||
|
|
||||||
|
# Find all require() calls that contain 'src/'
|
||||||
|
# Pattern: require('(.....)*src/path')
|
||||||
|
def replacer(match):
|
||||||
|
quote = match.group(1) # the quote char
|
||||||
|
path = match.group(2) # the path inside quotes
|
||||||
|
# Calculate what the path SHOULD be
|
||||||
|
if 'src/' not in path:
|
||||||
|
return match.group(0)
|
||||||
|
|
||||||
|
# Extract the part after 'src/'
|
||||||
|
idx = path.find('src/')
|
||||||
|
after_src = path[idx + 4:] # everything after 'src/'
|
||||||
|
|
||||||
|
if filepath.parts[-3] == 'src':
|
||||||
|
# File is in src/X/file.js - depth 3
|
||||||
|
# Should be '../<after_src>'
|
||||||
|
new_path = '../' + after_src
|
||||||
|
elif filepath.parts[-4] == 'src':
|
||||||
|
# File is in src/X/Y/file.js - depth 4
|
||||||
|
# Should be '../../<after_src>'
|
||||||
|
new_path = '../../' + after_src
|
||||||
|
elif filepath.parts[-2] == '__tests__' or filepath.parent.name == '__tests__':
|
||||||
|
# File is in __tests__/file.js - depth 1 (relative to api root)
|
||||||
|
# Should be '../src/<after_src>'
|
||||||
|
new_path = '../src/' + after_src
|
||||||
|
elif filepath.parts[-2] == 'routes' and filepath.parts[-3] == '__tests__':
|
||||||
|
# File is in __tests__/routes/file.js - depth 2
|
||||||
|
# Should be '../../src/<after_src>'
|
||||||
|
new_path = '../../src/' + after_src
|
||||||
|
elif 'src' in rel_dir.parts:
|
||||||
|
# Other src nested location
|
||||||
|
# Count how many .. we need
|
||||||
|
src_depth = len(rel_dir.parts) - list(rel_dir.parts).index('src') - 1
|
||||||
|
new_path = '../' * src_depth + after_src
|
||||||
|
else:
|
||||||
|
# Other location, leave it
|
||||||
|
return match.group(0)
|
||||||
|
|
||||||
|
return f"require({quote}{new_path}{quote})"
|
||||||
|
|
||||||
|
new_content = re.sub(
|
||||||
|
r"require\((['\"])([^'\"]*src/[^'\"]*)\1\)",
|
||||||
|
replacer,
|
||||||
|
content
|
||||||
|
)
|
||||||
|
|
||||||
|
if new_content != original:
|
||||||
|
filepath.write_text(new_content)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
changed = []
|
||||||
|
for js_file in DASHCADDY_API.rglob('*.js'):
|
||||||
|
# Skip node_modules
|
||||||
|
if 'node_modules' in js_file.parts:
|
||||||
|
continue
|
||||||
|
if fix_file(js_file):
|
||||||
|
changed.append(str(js_file.relative_to(DASHCADDY_API)))
|
||||||
|
|
||||||
|
print(f"Changed {len(changed)} files:")
|
||||||
|
for f in changed:
|
||||||
|
print(f" {f}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -0,0 +1,180 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* Refactor helper: rewrites require('./xxx') / require('../xxx') paths in
|
||||||
|
* dashcaddy-api to point to the new src/<subdir>/xxx.js locations.
|
||||||
|
*
|
||||||
|
* Algorithm:
|
||||||
|
* 1. For each require() call with a relative spec:
|
||||||
|
* 2. If the resolved file exists, leave it alone.
|
||||||
|
* 3. If the resolved file does NOT exist, the bare name of the spec
|
||||||
|
* (or the directory name 'dns-providers') might be one of the
|
||||||
|
* modules that was moved out of the repo root. In that case, rewrite
|
||||||
|
* the spec to the correct relative path to the new location.
|
||||||
|
* 4. Otherwise leave alone.
|
||||||
|
*/
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const REPO = process.cwd();
|
||||||
|
|
||||||
|
// Map: bare module name (no extension) -> new repo-relative path (no extension)
|
||||||
|
const NEW_LOCATIONS = {
|
||||||
|
'auth-manager': 'src/managers/auth-manager',
|
||||||
|
'credential-manager': 'src/managers/credential-manager',
|
||||||
|
'license-manager': 'src/managers/license-manager',
|
||||||
|
'port-lock-manager': 'src/managers/port-lock-manager',
|
||||||
|
'state-manager': 'src/managers/state-manager',
|
||||||
|
'notification-manager': 'src/managers/notification-manager',
|
||||||
|
'resource-monitor': 'src/managers/resource-monitor',
|
||||||
|
'config-drift-detector': 'src/managers/config-drift-detector',
|
||||||
|
'auto-restart-manager': 'src/managers/auto-restart-manager',
|
||||||
|
'update-manager': 'src/managers/update-manager',
|
||||||
|
'dependency-manager': 'src/managers/dependency-manager',
|
||||||
|
'csrf-protection': 'src/security/csrf-protection',
|
||||||
|
'crypto-utils': 'src/security/crypto-utils',
|
||||||
|
'docker-security': 'src/security/docker-security',
|
||||||
|
'input-validator': 'src/security/input-validator',
|
||||||
|
'keychain-manager': 'src/security/keychain-manager',
|
||||||
|
'log-digest': 'src/security/log-digest',
|
||||||
|
'audit-logger': 'src/security/audit-logger',
|
||||||
|
'docker-maintenance': 'src/docker/docker-maintenance',
|
||||||
|
'app-templates': 'src/docker/app-templates',
|
||||||
|
'self-updater': 'src/docker/self-updater',
|
||||||
|
'dns-propagation': 'src/dns/dns-propagation',
|
||||||
|
'recipe-templates': 'src/recipes/recipe-templates',
|
||||||
|
'bundled-workflows': 'src/recipes/bundled-workflows',
|
||||||
|
'health-checker': 'src/monitoring/health-checker',
|
||||||
|
'metrics': 'src/monitoring/metrics',
|
||||||
|
'ssl-monitor': 'src/monitoring/ssl-monitor',
|
||||||
|
'backup-manager': 'src/utilities/backup-manager',
|
||||||
|
'error-handler': 'src/utilities/error-handler',
|
||||||
|
'errors': 'src/utilities/errors',
|
||||||
|
'fs-helpers': 'src/utilities/fs-helpers',
|
||||||
|
'pagination': 'src/utilities/pagination',
|
||||||
|
'url-resolver': 'src/utilities/url-resolver',
|
||||||
|
'config-schema': 'src/utilities/config-schema',
|
||||||
|
'constants': 'src/utilities/constants',
|
||||||
|
'middleware': 'src/utilities/middleware',
|
||||||
|
'startup-validator': 'src/utilities/startup-validator',
|
||||||
|
'cache-config': 'src/utilities/cache-config',
|
||||||
|
};
|
||||||
|
|
||||||
|
const SKIP_DIRS = new Set(['node_modules', '.git']);
|
||||||
|
const SKIP_FILE_PATTERNS = [/\/scripts\/refactor-requires\.js$/];
|
||||||
|
|
||||||
|
function* walk(dir) {
|
||||||
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
if (SKIP_DIRS.has(entry.name)) continue;
|
||||||
|
const full = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
yield* walk(full);
|
||||||
|
} else if (entry.name.endsWith('.js')) {
|
||||||
|
yield full;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toRelativeFromFile(filePath, targetRel) {
|
||||||
|
const fromDir = path.dirname(filePath);
|
||||||
|
const targetAbs = path.resolve(REPO, targetRel);
|
||||||
|
let rel = path.relative(fromDir, targetAbs);
|
||||||
|
if (!rel.startsWith('.')) rel = './' + rel;
|
||||||
|
return rel.split(path.sep).join('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
function fileExistsWithJsOrIndex(p) {
|
||||||
|
// exists if p is a file, or p is a dir with index.js
|
||||||
|
try {
|
||||||
|
if (fs.existsSync(p) && fs.statSync(p).isFile()) return true;
|
||||||
|
} catch (_) {}
|
||||||
|
try {
|
||||||
|
if (fs.existsSync(p + '.js') && fs.statSync(p + '.js').isFile()) return true;
|
||||||
|
} catch (_) {}
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
fs.existsSync(p) &&
|
||||||
|
fs.statSync(p).isDirectory() &&
|
||||||
|
fs.existsSync(path.join(p, 'index.js'))
|
||||||
|
)
|
||||||
|
return true;
|
||||||
|
} catch (_) {}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function refactor(filePath) {
|
||||||
|
const relFile = path.relative(REPO, filePath);
|
||||||
|
if (SKIP_FILE_PATTERNS.some((re) => re.test(relFile))) return false;
|
||||||
|
|
||||||
|
const content = fs.readFileSync(filePath, 'utf8');
|
||||||
|
let changed = false;
|
||||||
|
|
||||||
|
const requireRe = /require\(\s*(['"])([^'"]+)\1\s*\)/g;
|
||||||
|
const newContent = content.replace(requireRe, (full, quote, spec) => {
|
||||||
|
if (!spec.startsWith('.')) return full; // package require, leave alone
|
||||||
|
const fromDir = path.dirname(filePath);
|
||||||
|
const resolvedBase = path.resolve(fromDir, spec);
|
||||||
|
// If the resolved file exists, the require is correct as-is.
|
||||||
|
if (fileExistsWithJsOrIndex(resolvedBase)) {
|
||||||
|
// But — check for the special case: require to <REPO>/dns-providers/x
|
||||||
|
// which after move becomes <REPO>/src/dns/dns-providers/x — wait,
|
||||||
|
// that doesn't exist anymore. The dir was moved.
|
||||||
|
const dnsProvidersOld = path.resolve(REPO, 'dns-providers');
|
||||||
|
if (
|
||||||
|
resolvedBase === dnsProvidersOld ||
|
||||||
|
resolvedBase.startsWith(dnsProvidersOld + path.sep)
|
||||||
|
) {
|
||||||
|
const subPath = resolvedBase === dnsProvidersOld ? '' : resolvedBase.slice(dnsProvidersOld.length + 1);
|
||||||
|
const newResolved = path.resolve(REPO, 'src/dns/dns-providers', subPath);
|
||||||
|
let rel = path.relative(fromDir, newResolved);
|
||||||
|
if (!rel.startsWith('.')) rel = './' + rel;
|
||||||
|
const newSpec = rel.split(path.sep).join('/');
|
||||||
|
changed = true;
|
||||||
|
return `require(${quote}${newSpec}${quote})`;
|
||||||
|
}
|
||||||
|
return full;
|
||||||
|
}
|
||||||
|
// The file does not exist. Check if the bare name is a moved module.
|
||||||
|
const bare = path.basename(resolvedBase);
|
||||||
|
if (bare in NEW_LOCATIONS) {
|
||||||
|
const target = NEW_LOCATIONS[bare];
|
||||||
|
const newSpec = toRelativeFromFile(filePath, target);
|
||||||
|
changed = true;
|
||||||
|
return `require(${quote}${newSpec}${quote})`;
|
||||||
|
}
|
||||||
|
// Bare not in map. Check for the special case: the spec points into
|
||||||
|
// the OLD dns-providers dir (now src/dns/dns-providers). E.g. spec
|
||||||
|
// could be '../dns-providers/registry' or './dns-providers/registry'
|
||||||
|
// from somewhere else.
|
||||||
|
if (spec.includes('dns-providers')) {
|
||||||
|
const dnsProvidersOld = path.resolve(REPO, 'dns-providers');
|
||||||
|
if (
|
||||||
|
resolvedBase === dnsProvidersOld ||
|
||||||
|
resolvedBase.startsWith(dnsProvidersOld + path.sep)
|
||||||
|
) {
|
||||||
|
const subPath =
|
||||||
|
resolvedBase === dnsProvidersOld ? '' : resolvedBase.slice(dnsProvidersOld.length + 1);
|
||||||
|
const newResolved = path.resolve(REPO, 'src/dns/dns-providers', subPath);
|
||||||
|
let rel = path.relative(fromDir, newResolved);
|
||||||
|
if (!rel.startsWith('.')) rel = './' + rel;
|
||||||
|
const newSpec = rel.split(path.sep).join('/');
|
||||||
|
changed = true;
|
||||||
|
return `require(${quote}${newSpec}${quote})`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return full;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
fs.writeFileSync(filePath, newContent);
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
for (const file of walk(REPO)) {
|
||||||
|
if (refactor(file)) {
|
||||||
|
count += 1;
|
||||||
|
console.log('rewrote', path.relative(REPO, file));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`\nDone: rewrote ${count} file(s).`);
|
||||||
+22
-22
@@ -33,7 +33,7 @@ process.on('uncaughtException', (error) => {
|
|||||||
const CONFIG_FILE = process.env.CONFIG_FILE || platformPaths.servicesFile.replace('services.json', 'config.json');
|
const CONFIG_FILE = process.env.CONFIG_FILE || platformPaths.servicesFile.replace('services.json', 'config.json');
|
||||||
|
|
||||||
// Validate startup configuration
|
// Validate startup configuration
|
||||||
const { validateStartupConfig } = require('./startup-validator');
|
const { validateStartupConfig } = require('../src/utilities/startup-validator');
|
||||||
await validateStartupConfig({
|
await validateStartupConfig({
|
||||||
log,
|
log,
|
||||||
CADDYFILE_PATH,
|
CADDYFILE_PATH,
|
||||||
@@ -56,23 +56,23 @@ process.on('uncaughtException', (error) => {
|
|||||||
|
|
||||||
// Attach WebSocket exec handler (with auth)
|
// Attach WebSocket exec handler (with auth)
|
||||||
const attachExecWS = require('./routes/exec');
|
const attachExecWS = require('./routes/exec');
|
||||||
const authManager = require('./auth-manager');
|
const authManager = require('../src/managers/auth-manager');
|
||||||
attachExecWS(server, log, authManager);
|
attachExecWS(server, log, authManager);
|
||||||
log.info('server', 'WebSocket exec handler attached (auth enforced)');
|
log.info('server', 'WebSocket exec handler attached (auth enforced)');
|
||||||
|
|
||||||
// Start feature modules
|
// Start feature modules
|
||||||
const resourceMonitor = require('./resource-monitor');
|
const resourceMonitor = require('../src/managers/resource-monitor');
|
||||||
const backupManager = require('./backup-manager');
|
const backupManager = require('../src/utilities/backup-manager');
|
||||||
const healthChecker = require('./health-checker');
|
const healthChecker = require('../src/monitoring/health-checker');
|
||||||
const updateManager = require('./update-manager');
|
const updateManager = require('../src/managers/update-manager');
|
||||||
const selfUpdater = require('./self-updater');
|
const selfUpdater = require('../src/docker/self-updater');
|
||||||
const portLockManager = require('./port-lock-manager');
|
const portLockManager = require('../src/managers/port-lock-manager');
|
||||||
|
|
||||||
// Optional modules
|
// Optional modules
|
||||||
let dockerMaintenance, logDigest, bundledWorkflows;
|
let dockerMaintenance, logDigest, bundledWorkflows;
|
||||||
try { dockerMaintenance = require('./docker-maintenance'); } catch { /* optional */ }
|
try { dockerMaintenance = require('../src/docker/docker-maintenance'); } catch { /* optional */ }
|
||||||
try { logDigest = require('./log-digest'); } catch { /* optional */ }
|
try { logDigest = require('../src/security/log-digest'); } catch { /* optional */ }
|
||||||
try { bundledWorkflows = require('./bundled-workflows'); } catch { /* optional */ }
|
try { bundledWorkflows = require('../src/recipes/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
|
// NOTE: createApp() already initializes the workflow engine in src/app.js
|
||||||
@@ -85,7 +85,7 @@ process.on('uncaughtException', (error) => {
|
|||||||
// Create a context with needed services
|
// Create a context with needed services
|
||||||
const workflowCtx = {
|
const workflowCtx = {
|
||||||
docker: { client: require('dockerode')() },
|
docker: { client: require('dockerode')() },
|
||||||
notification: require('./notification-manager')({
|
notification: require('../src/managers/notification-manager')({
|
||||||
NOTIFICATIONS_FILE: process.env.NOTIFICATIONS_FILE || require('./platform-paths').notificationsFile,
|
NOTIFICATIONS_FILE: process.env.NOTIFICATIONS_FILE || require('./platform-paths').notificationsFile,
|
||||||
fetchT,
|
fetchT,
|
||||||
log,
|
log,
|
||||||
@@ -137,8 +137,8 @@ process.on('uncaughtException', (error) => {
|
|||||||
// Health checker (with service sync)
|
// Health checker (with service sync)
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
const { syncHealthCheckerServices } = require('./startup-validator');
|
const { syncHealthCheckerServices } = require('../src/utilities/startup-validator');
|
||||||
const StateManager = require('./state-manager');
|
const StateManager = require('../src/managers/state-manager');
|
||||||
const servicesStateManager = new StateManager(SERVICES_FILE);
|
const servicesStateManager = new StateManager(SERVICES_FILE);
|
||||||
|
|
||||||
await syncHealthCheckerServices({
|
await syncHealthCheckerServices({
|
||||||
@@ -150,7 +150,7 @@ process.on('uncaughtException', (error) => {
|
|||||||
? `https://${config.domain}/${subdomain}`
|
? `https://${config.domain}/${subdomain}`
|
||||||
: `https://${subdomain}${config.tld}`,
|
: `https://${subdomain}${config.tld}`,
|
||||||
siteConfig: config,
|
siteConfig: config,
|
||||||
APP: require('./constants').APP
|
APP: require('../src/utilities/constants').APP
|
||||||
});
|
});
|
||||||
|
|
||||||
healthChecker.start();
|
healthChecker.start();
|
||||||
@@ -232,11 +232,11 @@ process.on('uncaughtException', (error) => {
|
|||||||
const shutdown = (signal) => {
|
const shutdown = (signal) => {
|
||||||
log.info('shutdown', `${signal} received, draining connections...`);
|
log.info('shutdown', `${signal} received, draining connections...`);
|
||||||
|
|
||||||
const resourceMonitor = require('./resource-monitor');
|
const resourceMonitor = require('../src/managers/resource-monitor');
|
||||||
const backupManager = require('./backup-manager');
|
const backupManager = require('../src/utilities/backup-manager');
|
||||||
const healthChecker = require('./health-checker');
|
const healthChecker = require('../src/monitoring/health-checker');
|
||||||
const updateManager = require('./update-manager');
|
const updateManager = require('../src/managers/update-manager');
|
||||||
const selfUpdater = require('./self-updater');
|
const selfUpdater = require('../src/docker/self-updater');
|
||||||
|
|
||||||
resourceMonitor.stop();
|
resourceMonitor.stop();
|
||||||
backupManager.stop();
|
backupManager.stop();
|
||||||
@@ -245,12 +245,12 @@ process.on('uncaughtException', (error) => {
|
|||||||
selfUpdater.stop();
|
selfUpdater.stop();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const dockerMaintenance = require('./docker-maintenance');
|
const dockerMaintenance = require('../src/docker/docker-maintenance');
|
||||||
dockerMaintenance.stop();
|
dockerMaintenance.stop();
|
||||||
} catch { /* optional */ }
|
} catch { /* optional */ }
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const logDigest = require('./log-digest');
|
const logDigest = require('../src/security/log-digest');
|
||||||
logDigest.stop();
|
logDigest.stop();
|
||||||
} catch { /* optional */ }
|
} catch { /* optional */ }
|
||||||
|
|
||||||
|
|||||||
+40
-40
@@ -15,41 +15,41 @@ const { errorResponse, ok } = require('./utils/responses');
|
|||||||
const { asyncHandler } = require('./utils/async-handler');
|
const { asyncHandler } = require('./utils/async-handler');
|
||||||
|
|
||||||
// Managers and utilities
|
// Managers and utilities
|
||||||
const StateManager = require('../state-manager');
|
const StateManager = require('managers/state-manager');
|
||||||
const platformPaths = require('../platform-paths');
|
const platformPaths = require('../platform-paths');
|
||||||
const { LicenseManager } = require('../license-manager');
|
const { LicenseManager } = require('managers/license-manager');
|
||||||
const credentialManager = require('../credential-manager');
|
const credentialManager = require('managers/credential-manager');
|
||||||
const authManager = require('../auth-manager');
|
const authManager = require('managers/auth-manager');
|
||||||
const dockerSecurity = require('../docker-security');
|
const dockerSecurity = require('security/docker-security');
|
||||||
const auditLogger = require('../audit-logger');
|
const auditLogger = require('security/audit-logger');
|
||||||
const portLockManager = require('../port-lock-manager');
|
const portLockManager = require('managers/port-lock-manager');
|
||||||
const resourceMonitor = require('../resource-monitor');
|
const resourceMonitor = require('managers/resource-monitor');
|
||||||
const backupManager = require('../backup-manager');
|
const backupManager = require('utilities/backup-manager');
|
||||||
const healthChecker = require('../health-checker');
|
const healthChecker = require('monitoring/health-checker');
|
||||||
const updateManager = require('../update-manager');
|
const updateManager = require('managers/update-manager');
|
||||||
const selfUpdater = require('../self-updater');
|
const selfUpdater = require('docker/self-updater');
|
||||||
const configureMiddleware = require('../middleware');
|
const configureMiddleware = require('utilities/middleware');
|
||||||
const { validateStartupConfig: _validateStartupConfig, syncHealthCheckerServices } = require('../startup-validator');
|
const { validateStartupConfig: _validateStartupConfig, syncHealthCheckerServices } = require('utilities/startup-validator');
|
||||||
const { CSRF_HEADER_NAME } = require('../csrf-protection');
|
const { CSRF_HEADER_NAME } = require('security/csrf-protection');
|
||||||
const { resolveServiceUrl } = require('../url-resolver');
|
const { resolveServiceUrl } = require('utilities/url-resolver');
|
||||||
const metrics = require('../metrics');
|
const metrics = require('monitoring/metrics');
|
||||||
const { validateURL } = require('../input-validator');
|
const { validateURL } = require('security/input-validator');
|
||||||
|
|
||||||
// Optional modules
|
// Optional modules
|
||||||
let dockerMaintenance, logDigest;
|
let dockerMaintenance, logDigest;
|
||||||
try { dockerMaintenance = require('../docker-maintenance'); } catch (_) { /* optional module */ }
|
try { dockerMaintenance = require('docker/docker-maintenance'); } catch (_) { /* optional module */ }
|
||||||
try { logDigest = require('../log-digest'); } catch (_) { /* optional module */ }
|
try { logDigest = require('security/log-digest'); } catch (_) { /* optional module */ }
|
||||||
|
|
||||||
// Workflow engine (bundled workflows)
|
// Workflow engine (bundled workflows)
|
||||||
let bundledWorkflowsModule;
|
let bundledWorkflowsModule;
|
||||||
let workflowEngine = null;
|
let workflowEngine = null;
|
||||||
try {
|
try {
|
||||||
bundledWorkflowsModule = require('../bundled-workflows');
|
bundledWorkflowsModule = require('recipes/bundled-workflows');
|
||||||
} catch (_) { /* optional module */ }
|
} catch (_) { /* optional module */ }
|
||||||
|
|
||||||
// Templates
|
// Templates
|
||||||
const { APP_TEMPLATES, TEMPLATE_CATEGORIES, DIFFICULTY_LEVELS } = require('../app-templates');
|
const { APP_TEMPLATES, TEMPLATE_CATEGORIES, DIFFICULTY_LEVELS } = require('docker/app-templates');
|
||||||
const { RECIPE_TEMPLATES, RECIPE_CATEGORIES } = require('../recipe-templates');
|
const { RECIPE_TEMPLATES, RECIPE_CATEGORIES } = require('recipes/recipe-templates');
|
||||||
|
|
||||||
// Route modules
|
// Route modules
|
||||||
const healthRoutes = require('../routes/health');
|
const healthRoutes = require('../routes/health');
|
||||||
@@ -79,17 +79,17 @@ const dockerResourcesRoutes = require('../routes/docker-resources');
|
|||||||
const eventsRoutes = require('../routes/events');
|
const eventsRoutes = require('../routes/events');
|
||||||
const workflowsRoutes = require('../routes/workflows');
|
const workflowsRoutes = require('../routes/workflows');
|
||||||
const dependenciesRoutes = require('../routes/dependencies');
|
const dependenciesRoutes = require('../routes/dependencies');
|
||||||
const DependencyManager = require('../dependency-manager');
|
const DependencyManager = require('managers/dependency-manager');
|
||||||
const autoRestartRoutes = require('../routes/auto-restart');
|
const autoRestartRoutes = require('../routes/auto-restart');
|
||||||
const configDriftRoutes = require('../routes/config-drift');
|
const configDriftRoutes = require('../routes/config-drift');
|
||||||
const sslMonitorRoutes = require('../routes/ssl-monitor');
|
const sslMonitorRoutes = require('../routes/ssl-monitor');
|
||||||
const { AutoRestartManager } = require('../auto-restart-manager');
|
const { AutoRestartManager } = require('managers/auto-restart-manager');
|
||||||
const { ConfigDriftDetector } = require('../config-drift-detector');
|
const { ConfigDriftDetector } = require('managers/config-drift-detector');
|
||||||
const SSLMonitor = require('../ssl-monitor');
|
const SSLMonitor = require('monitoring/ssl-monitor');
|
||||||
const DNSPropagationChecker = require('../dns-propagation');
|
const DNSPropagationChecker = require('dns/dns-propagation');
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
const { APP } = require('../constants');
|
const { APP } = require('utilities/constants');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and configure the Express application
|
* Create and configure the Express application
|
||||||
@@ -216,15 +216,15 @@ async function createApp() {
|
|||||||
auditLogger,
|
auditLogger,
|
||||||
authManager,
|
authManager,
|
||||||
log,
|
log,
|
||||||
cryptoUtils: require('../crypto-utils'),
|
cryptoUtils: require('security/crypto-utils'),
|
||||||
isValidContainerId,
|
isValidContainerId,
|
||||||
isTailscaleIP,
|
isTailscaleIP,
|
||||||
getTailscaleStatus,
|
getTailscaleStatus,
|
||||||
RATE_LIMITS: require('../constants').RATE_LIMITS,
|
RATE_LIMITS: require('utilities/constants').RATE_LIMITS,
|
||||||
LIMITS: require('../constants').LIMITS,
|
LIMITS: require('utilities/constants').LIMITS,
|
||||||
APP: require('../constants').APP,
|
APP: require('utilities/constants').APP,
|
||||||
CACHE_CONFIGS: require('../cache-config').CACHE_CONFIGS,
|
CACHE_CONFIGS: require('utilities/cache-config').CACHE_CONFIGS,
|
||||||
createCache: require('../cache-config').createCache,
|
createCache: require('utilities/cache-config').createCache,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { strictLimiter } = middlewareResult;
|
const { strictLimiter } = middlewareResult;
|
||||||
@@ -237,7 +237,7 @@ async function createApp() {
|
|||||||
|
|
||||||
// eslint-disable-next-line require-await -- may grow awaits as config loading evolves
|
// eslint-disable-next-line require-await -- may grow awaits as config loading evolves
|
||||||
async function readConfig() {
|
async function readConfig() {
|
||||||
const { readJsonFile } = require('../fs-helpers');
|
const { readJsonFile } = require('utilities/fs-helpers');
|
||||||
return readJsonFile(config.CONFIG_FILE, {});
|
return readJsonFile(config.CONFIG_FILE, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,7 +260,7 @@ async function createApp() {
|
|||||||
|
|
||||||
async function saveTotpConfig() {
|
async function saveTotpConfig() {
|
||||||
try {
|
try {
|
||||||
const { writeJsonFile } = require('../fs-helpers');
|
const { writeJsonFile } = require('utilities/fs-helpers');
|
||||||
await writeJsonFile(config.TOTP_CONFIG_FILE, totpConfig);
|
await writeJsonFile(config.TOTP_CONFIG_FILE, totpConfig);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.error('config', 'Could not save TOTP config', { error: e.message });
|
log.error('config', 'Could not save TOTP config', { error: e.message });
|
||||||
@@ -731,7 +731,7 @@ async function createApp() {
|
|||||||
// Lightweight probe endpoint
|
// Lightweight probe endpoint
|
||||||
app.get('/probe/:id', boundAsyncHandler(async (req, res) => {
|
app.get('/probe/:id', boundAsyncHandler(async (req, res) => {
|
||||||
const id = req.params.id;
|
const id = req.params.id;
|
||||||
const { exists } = require('../fs-helpers');
|
const { exists } = require('utilities/fs-helpers');
|
||||||
|
|
||||||
let service = null;
|
let service = null;
|
||||||
if (id !== 'internet' && await exists(config.SERVICES_FILE)) {
|
if (id !== 'internet' && await exists(config.SERVICES_FILE)) {
|
||||||
@@ -871,7 +871,7 @@ async function createApp() {
|
|||||||
|
|
||||||
app.get('/api/v1/docs/spec', boundAsyncHandler(async (req, res) => {
|
app.get('/api/v1/docs/spec', boundAsyncHandler(async (req, res) => {
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { exists } = require('../fs-helpers');
|
const { exists } = require('utilities/fs-helpers');
|
||||||
const fsp = require('fs').promises;
|
const fsp = require('fs').promises;
|
||||||
|
|
||||||
const specPath = path.join(__dirname, '../openapi.yaml');
|
const specPath = path.join(__dirname, '../openapi.yaml');
|
||||||
@@ -884,7 +884,7 @@ async function createApp() {
|
|||||||
}, 'api-docs-spec'));
|
}, 'api-docs-spec'));
|
||||||
|
|
||||||
// Error handlers (MUST be last)
|
// Error handlers (MUST be last)
|
||||||
const { notFoundHandler, errorMiddleware } = require('../error-handler');
|
const { notFoundHandler, errorMiddleware } = require('utilities/error-handler');
|
||||||
app.use('/api', notFoundHandler);
|
app.use('/api', notFoundHandler);
|
||||||
app.use(errorMiddleware);
|
app.use(errorMiddleware);
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
const paths = require('./paths');
|
const paths = require('./paths');
|
||||||
const site = require('./site');
|
const site = require('./site');
|
||||||
const { APP, LIMITS, TIMEOUTS, RETRIES, CADDY } = require('../../constants');
|
const { APP, LIMITS, TIMEOUTS, RETRIES, CADDY } = require('../utilities/constants');
|
||||||
|
|
||||||
// Load logging level
|
// Load logging level
|
||||||
const LOG_LEVELS = { debug: 0, info: 1, warn: 2, error: 3 };
|
const LOG_LEVELS = { debug: 0, info: 1, warn: 2, error: 3 };
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
* updated config back, and the rest of the app only ever sees the current
|
* updated config back, and the rest of the app only ever sees the current
|
||||||
* schema.
|
* schema.
|
||||||
*/
|
*/
|
||||||
const { validateConfig } = require('../../config-schema');
|
const { validateConfig } = require('../utilities/config-schema');
|
||||||
const { CADDY } = require('../../constants');
|
const { CADDY } = require('../utilities/constants');
|
||||||
const { loadAndMigrate, CURRENT_VERSION } = require('./migrations');
|
const { loadAndMigrate, CURRENT_VERSION } = require('./migrations');
|
||||||
|
|
||||||
const siteConfig = {
|
const siteConfig = {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Caddy context - Caddyfile manipulation and reload
|
* Caddy context - Caddyfile manipulation and reload
|
||||||
*/
|
*/
|
||||||
const fsp = require('fs').promises;
|
const fsp = require('fs').promises;
|
||||||
const { RETRIES } = require('../../constants');
|
const { RETRIES } = require('../utilities/constants');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically read-modify-write the Caddyfile and reload Caddy.
|
* Atomically read-modify-write the Caddyfile and reload Caddy.
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
*
|
*
|
||||||
* This module now delegates to the provider system internally.
|
* This module now delegates to the provider system internally.
|
||||||
*/
|
*/
|
||||||
const { TIMEOUTS, SESSION_TTL, CADDY } = require('../../constants');
|
const { TIMEOUTS, SESSION_TTL, CADDY } = require('../utilities/constants');
|
||||||
const { createCache, CACHE_CONFIGS } = require('../../cache-config');
|
const { createCache, CACHE_CONFIGS } = require('../utilities/cache-config');
|
||||||
const { createProviderDnsContext } = require('./provider-dns');
|
const { createProviderDnsContext } = require('./provider-dns');
|
||||||
|
|
||||||
// DNS token management
|
// DNS token management
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Docker context - Docker client and operations
|
* Docker context - Docker client and operations
|
||||||
*/
|
*/
|
||||||
const Docker = require('dockerode');
|
const Docker = require('dockerode');
|
||||||
const { DOCKER } = require('../../constants');
|
const { DOCKER } = require('../utilities/constants');
|
||||||
|
|
||||||
const docker = new Docker();
|
const docker = new Docker();
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const { createDockerContext } = require('./docker');
|
|||||||
const { createCaddyContext } = require('./caddy');
|
const { createCaddyContext } = require('./caddy');
|
||||||
const { createDnsContext } = require('./dns');
|
const { createDnsContext } = require('./dns');
|
||||||
const { createSessionContext } = require('./session');
|
const { createSessionContext } = require('./session');
|
||||||
const NotificationManager = require('../../notification-manager');
|
const NotificationManager = require('../managers/notification-manager');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assemble the full application context
|
* Assemble the full application context
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
* Falls back to legacy Technitium context for backward compatibility
|
* Falls back to legacy Technitium context for backward compatibility
|
||||||
* when no provider is explicitly configured.
|
* when no provider is explicitly configured.
|
||||||
*/
|
*/
|
||||||
const { createCache, CACHE_CONFIGS } = require('../../cache-config');
|
const { createCache, CACHE_CONFIGS } = require('../utilities/cache-config');
|
||||||
const { TIMEOUTS, SESSION_TTL, CADDY } = require('../../constants');
|
const { TIMEOUTS, SESSION_TTL, CADDY } = require('../utilities/constants');
|
||||||
const registry = require('../../dns-providers/registry');
|
const registry = require('../../dns-providers/registry');
|
||||||
|
|
||||||
// Per-server token cache (legacy Technitium)
|
// Per-server token cache (legacy Technitium)
|
||||||
|
|||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1
-1
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
const Docker = require('dockerode');
|
const Docker = require('dockerode');
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
const { DOCKER } = require('./constants');
|
const { DOCKER } = require('../utilities/constants');
|
||||||
|
|
||||||
const docker = new Docker();
|
const docker = new Docker();
|
||||||
|
|
||||||
File renamed without changes.
@@ -7,7 +7,7 @@
|
|||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const credentialManager = require('./credential-manager');
|
const credentialManager = require('./credential-manager');
|
||||||
const cryptoUtils = require('./crypto-utils');
|
const cryptoUtils = require('../security/crypto-utils');
|
||||||
|
|
||||||
// JWT signing secret - derived from encryption key for consistency
|
// JWT signing secret - derived from encryption key for consistency
|
||||||
const JWT_SECRET = cryptoUtils.loadOrCreateKey();
|
const JWT_SECRET = cryptoUtils.loadOrCreateKey();
|
||||||
+1
-1
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { readJsonFile, writeJsonFile } = require('./fs-helpers');
|
const { readJsonFile, writeJsonFile } = require('../utilities/fs-helpers');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default policy values applied when a new policy is created.
|
* Default policy values applied when a new policy is created.
|
||||||
File renamed without changes.
+2
-2
@@ -4,8 +4,8 @@
|
|||||||
* Uses OS keychain when available, falls back to encrypted file storage
|
* Uses OS keychain when available, falls back to encrypted file storage
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const keychainManager = require('./keychain-manager');
|
const keychainManager = require('../security/keychain-manager');
|
||||||
const cryptoUtils = require('./crypto-utils');
|
const cryptoUtils = require('../security/crypto-utils');
|
||||||
const lockfile = require('proper-lockfile');
|
const lockfile = require('proper-lockfile');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
File renamed without changes.
@@ -15,7 +15,7 @@ const os = require('os');
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { verifyCode, parseCode, VALID_DURATIONS } = require('./license-keygen');
|
const { verifyCode, parseCode, VALID_DURATIONS } = require('./license-keygen');
|
||||||
const { errorResponse } = require('./src/utils/responses');
|
const { errorResponse } = require('../utils/responses');
|
||||||
|
|
||||||
const LICENSE_CRED_KEY = 'license.activation';
|
const LICENSE_CRED_KEY = 'license.activation';
|
||||||
const LICENSE_SERVER_URL = process.env.LICENSE_SERVER_URL || null; // Set when license server exists
|
const LICENSE_SERVER_URL = process.env.LICENSE_SERVER_URL || null; // Set when license server exists
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loaded 100 of 129 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user