feat: 1.5.0 prep — API v1 cutover, LICENSE, CHANGELOG, CI
- Remove legacy /api/ mount; all routes now under /api/v1/ only - Update path matchers (CSRF excludes, public routes, audit log, rate limits) - Move standalone routes (/api/network/ips, /api/docs, /api/docs/spec) to v1 - Update openapi.yaml (110 paths), CA pages, and 4 lingering frontend files - Add LICENSE (proprietary EULA), CHANGELOG.md (Keep a Changelog format) - Add .gitea/workflows/ci.yml (test+lint and security audit jobs) - Fix 9 pre-existing no-empty lint errors so CI starts green - Drop ad-hoc scratch reports and *.bak files from repo root All 739 jest tests pass. Lint is clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,65 +7,65 @@ const MAX_ENTRIES = parseInt(process.env.AUDIT_MAX_ENTRIES || '1000', 10);
|
||||
|
||||
// Route path → readable action mapping
|
||||
const ACTION_MAP = {
|
||||
'POST /api/services/update': 'service.reorder',
|
||||
'POST /api/services': 'service.create',
|
||||
'PUT /api/services': 'service.update',
|
||||
'DELETE /api/services/': 'service.delete',
|
||||
'POST /api/site': 'caddy.add-site',
|
||||
'POST /api/site/external': 'caddy.add-external',
|
||||
'DELETE /api/site/': 'caddy.remove-site',
|
||||
'POST /api/caddy/reload': 'caddy.reload',
|
||||
'POST /api/dns/record': 'dns.add-record',
|
||||
'DELETE /api/dns/record': 'dns.delete-record',
|
||||
'POST /api/dns/credentials': 'dns.save-credentials',
|
||||
'DELETE /api/dns/credentials': 'dns.delete-credentials',
|
||||
'POST /api/dns/refresh-token': 'dns.refresh-token',
|
||||
'POST /api/dns/update': 'dns.update-server',
|
||||
'POST /api/containers/': 'container.action',
|
||||
'DELETE /api/containers/': 'container.delete',
|
||||
'POST /api/apps/deploy': 'container.deploy',
|
||||
'DELETE /api/apps/': 'container.undeploy',
|
||||
'POST /api/backups/execute': 'backup.execute',
|
||||
'POST /api/backups/restore/': 'backup.restore',
|
||||
'POST /api/backups/config': 'backup.config',
|
||||
'POST /api/config': 'config.update',
|
||||
'DELETE /api/config': 'config.reset',
|
||||
'POST /api/notifications/config': 'config.notifications',
|
||||
'POST /api/totp/setup': 'auth.totp-setup',
|
||||
'POST /api/totp/verify-setup': 'auth.totp-activate',
|
||||
'POST /api/totp/disable': 'auth.totp-disable',
|
||||
'POST /api/totp/config': 'auth.totp-config',
|
||||
'POST /api/credentials/rotate-key': 'config.rotate-key',
|
||||
'POST /api/updates/update/': 'container.update',
|
||||
'POST /api/updates/rollback/': 'container.rollback',
|
||||
'POST /api/updates/auto-update/': 'container.auto-update',
|
||||
'POST /api/updates/check': 'container.check-updates',
|
||||
'POST /api/health-checks/': 'config.health-check',
|
||||
'DELETE /api/health-checks/': 'config.health-check-delete',
|
||||
'POST /api/monitoring/alerts/': 'config.monitoring-alert',
|
||||
'DELETE /api/monitoring/alerts/': 'config.monitoring-alert-delete',
|
||||
'POST /api/arr/smart-connect': 'service.arr-connect',
|
||||
'POST /api/arr/credentials': 'config.arr-credentials',
|
||||
'DELETE /api/arr/credentials/': 'config.arr-credentials-delete',
|
||||
'POST /api/logo': 'config.logo-upload',
|
||||
'DELETE /api/logo': 'config.logo-delete',
|
||||
'POST /api/favicon': 'config.favicon-upload',
|
||||
'DELETE /api/favicon': 'config.favicon-delete',
|
||||
'POST /api/tailscale/config': 'config.tailscale',
|
||||
'POST /api/tailscale/protect-service': 'config.tailscale-protect',
|
||||
'POST /api/v1/services/update': 'service.reorder',
|
||||
'POST /api/v1/services': 'service.create',
|
||||
'PUT /api/v1/services': 'service.update',
|
||||
'DELETE /api/v1/services/': 'service.delete',
|
||||
'POST /api/v1/site': 'caddy.add-site',
|
||||
'POST /api/v1/site/external': 'caddy.add-external',
|
||||
'DELETE /api/v1/site/': 'caddy.remove-site',
|
||||
'POST /api/v1/caddy/reload': 'caddy.reload',
|
||||
'POST /api/v1/dns/record': 'dns.add-record',
|
||||
'DELETE /api/v1/dns/record': 'dns.delete-record',
|
||||
'POST /api/v1/dns/credentials': 'dns.save-credentials',
|
||||
'DELETE /api/v1/dns/credentials': 'dns.delete-credentials',
|
||||
'POST /api/v1/dns/refresh-token': 'dns.refresh-token',
|
||||
'POST /api/v1/dns/update': 'dns.update-server',
|
||||
'POST /api/v1/containers/': 'container.action',
|
||||
'DELETE /api/v1/containers/': 'container.delete',
|
||||
'POST /api/v1/apps/deploy': 'container.deploy',
|
||||
'DELETE /api/v1/apps/': 'container.undeploy',
|
||||
'POST /api/v1/backups/execute': 'backup.execute',
|
||||
'POST /api/v1/backups/restore/': 'backup.restore',
|
||||
'POST /api/v1/backups/config': 'backup.config',
|
||||
'POST /api/v1/config': 'config.update',
|
||||
'DELETE /api/v1/config': 'config.reset',
|
||||
'POST /api/v1/notifications/config': 'config.notifications',
|
||||
'POST /api/v1/totp/setup': 'auth.totp-setup',
|
||||
'POST /api/v1/totp/verify-setup': 'auth.totp-activate',
|
||||
'POST /api/v1/totp/disable': 'auth.totp-disable',
|
||||
'POST /api/v1/totp/config': 'auth.totp-config',
|
||||
'POST /api/v1/credentials/rotate-key': 'config.rotate-key',
|
||||
'POST /api/v1/updates/update/': 'container.update',
|
||||
'POST /api/v1/updates/rollback/': 'container.rollback',
|
||||
'POST /api/v1/updates/auto-update/': 'container.auto-update',
|
||||
'POST /api/v1/updates/check': 'container.check-updates',
|
||||
'POST /api/v1/health-checks/': 'config.health-check',
|
||||
'DELETE /api/v1/health-checks/': 'config.health-check-delete',
|
||||
'POST /api/v1/monitoring/alerts/': 'config.monitoring-alert',
|
||||
'DELETE /api/v1/monitoring/alerts/': 'config.monitoring-alert-delete',
|
||||
'POST /api/v1/arr/smart-connect': 'service.arr-connect',
|
||||
'POST /api/v1/arr/credentials': 'config.arr-credentials',
|
||||
'DELETE /api/v1/arr/credentials/': 'config.arr-credentials-delete',
|
||||
'POST /api/v1/logo': 'config.logo-upload',
|
||||
'DELETE /api/v1/logo': 'config.logo-delete',
|
||||
'POST /api/v1/favicon': 'config.favicon-upload',
|
||||
'DELETE /api/v1/favicon': 'config.favicon-delete',
|
||||
'POST /api/v1/tailscale/config': 'config.tailscale',
|
||||
'POST /api/v1/tailscale/protect-service': 'config.tailscale-protect',
|
||||
};
|
||||
|
||||
// Paths to skip logging (noisy or internal)
|
||||
const SKIP_PATHS = [
|
||||
'/api/totp/verify',
|
||||
'/api/totp/check-session',
|
||||
'/api/auth/gate/',
|
||||
'/api/auth/app-token/',
|
||||
'/api/audit-logs',
|
||||
'/api/health',
|
||||
'/api/v1/totp/verify',
|
||||
'/api/v1/totp/check-session',
|
||||
'/api/v1/auth/gate/',
|
||||
'/api/v1/auth/app-token/',
|
||||
'/api/v1/audit-logs',
|
||||
'/api/v1/health',
|
||||
'/health',
|
||||
'/api/notifications/test',
|
||||
'/api/notifications/health-check',
|
||||
'/api/v1/notifications/test',
|
||||
'/api/v1/notifications/health-check',
|
||||
];
|
||||
|
||||
class AuditLogger {
|
||||
@@ -82,14 +82,14 @@ class AuditLogger {
|
||||
if (key.startsWith(pattern)) return action;
|
||||
}
|
||||
// Fallback: derive from path
|
||||
const parts = urlPath.replace('/api/', '').split('/');
|
||||
const parts = urlPath.replace('/api/v1/', '').split('/');
|
||||
const category = parts[0] || 'unknown';
|
||||
return `${category}.${method.toLowerCase()}`;
|
||||
}
|
||||
|
||||
extractResource(urlPath) {
|
||||
// Pull a meaningful resource identifier from the URL path
|
||||
const parts = urlPath.replace('/api/', '').split('/');
|
||||
const parts = urlPath.replace('/api/v1/', '').split('/');
|
||||
if (parts.length >= 2) return parts.slice(1).join('/');
|
||||
return parts[0] || '';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user