fix: remove CDN swagger UI, revert CSP, translate apiToken i18n keys to German
- Delete public/doc-assets/swagger.html and swagger-init.js (CDN dependency violates project constraints) - Remove /docs route from server/index.js - Revert styleSrc and fontSrc in CSP to not include cdn.jsdelivr.net - Translate all 22 settings.apiToken* keys in de.json from English to German Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +0,0 @@
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
window.ui = window.SwaggerUIBundle({
|
||||
url: '/openapi.json',
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
docExpansion: 'list',
|
||||
persistAuthorization: true,
|
||||
displayRequestDuration: true,
|
||||
filter: true,
|
||||
});
|
||||
});
|
||||
@@ -1,37 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Oikos API Docs</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css">
|
||||
<style>
|
||||
body { margin: 0; background: #f6f8fb; }
|
||||
.docs-topbar {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 14px 20px;
|
||||
background: #0f172a;
|
||||
color: #fff;
|
||||
font: 14px/1.4 system-ui, sans-serif;
|
||||
}
|
||||
.docs-links { display: flex; gap: 12px; flex-wrap: wrap; }
|
||||
.docs-links a { color: #93c5fd; text-decoration: none; }
|
||||
.docs-links a:hover { text-decoration: underline; }
|
||||
</style>
|
||||
<script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js" defer></script>
|
||||
<script src="/doc-assets/swagger-init.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="docs-topbar">
|
||||
<strong>Oikos API Documentation</strong>
|
||||
<nav class="docs-links">
|
||||
<a href="/openapi.json" target="_blank" rel="noreferrer">openapi.json</a>
|
||||
<a href="/openapi.json?download=1">Download JSON</a>
|
||||
</nav>
|
||||
</header>
|
||||
<div id="swagger-ui"></div>
|
||||
</body>
|
||||
</html>
|
||||
+22
-22
@@ -630,28 +630,28 @@
|
||||
"currencyLabel": "Währung",
|
||||
"currencyHint": "Legt die Währung für den gesamten Budget-Bereich fest.",
|
||||
"currencySaved": "Währung gespeichert.",
|
||||
"apiTokensTitle": "API Tokens",
|
||||
"apiTokensCardTitle": "Access Tokens",
|
||||
"apiTokensHint": "Create API tokens for external integrations. The full token is shown only once after creation.",
|
||||
"apiTokenNameLabel": "Token name",
|
||||
"apiTokenExpiresLabel": "Expiration date",
|
||||
"apiTokenExpiresHint": "Leave empty to create a token without expiration.",
|
||||
"apiTokenCreatedLabel": "New API token",
|
||||
"apiTokenCreatedHint": "Store this token securely. It cannot be shown again.",
|
||||
"apiTokenCreate": "Create token",
|
||||
"apiTokenInvalidExpiration": "Please enter a valid expiration date.",
|
||||
"apiTokenCreatedToast": "API token created.",
|
||||
"apiTokenRevokedToast": "API token revoked.",
|
||||
"apiTokenRevokeConfirm": "Revoke API token \"{{name}}\"?",
|
||||
"apiTokenRevoke": "Revoke token",
|
||||
"apiTokenRevoked": "Revoked",
|
||||
"apiTokenExpired": "Expired",
|
||||
"apiTokenActive": "Active",
|
||||
"apiTokenPrefix": "Prefix",
|
||||
"apiTokenExpires": "Expires",
|
||||
"apiTokenNeverExpires": "No expiration",
|
||||
"apiTokenLastUsed": "Last used",
|
||||
"apiTokenNeverUsed": "Never used",
|
||||
"apiTokensTitle": "API-Tokens",
|
||||
"apiTokensCardTitle": "Zugriffstoken",
|
||||
"apiTokensHint": "Erstelle API-Tokens für externe Integrationen. Der vollständige Token wird nach der Erstellung nur einmal angezeigt.",
|
||||
"apiTokenNameLabel": "Tokenname",
|
||||
"apiTokenExpiresLabel": "Ablaufdatum",
|
||||
"apiTokenExpiresHint": "Leer lassen, um einen Token ohne Ablaufdatum zu erstellen.",
|
||||
"apiTokenCreatedLabel": "Neuer API-Token",
|
||||
"apiTokenCreatedHint": "Speichere diesen Token sicher. Er kann nicht erneut angezeigt werden.",
|
||||
"apiTokenCreate": "Token erstellen",
|
||||
"apiTokenInvalidExpiration": "Bitte gib ein gültiges Ablaufdatum ein.",
|
||||
"apiTokenCreatedToast": "API-Token erstellt.",
|
||||
"apiTokenRevokedToast": "API-Token widerrufen.",
|
||||
"apiTokenRevokeConfirm": "API-Token \"{{name}}\" widerrufen?",
|
||||
"apiTokenRevoke": "Token widerrufen",
|
||||
"apiTokenRevoked": "Widerrufen",
|
||||
"apiTokenExpired": "Abgelaufen",
|
||||
"apiTokenActive": "Aktiv",
|
||||
"apiTokenPrefix": "Präfix",
|
||||
"apiTokenExpires": "Läuft ab",
|
||||
"apiTokenNeverExpires": "Kein Ablaufdatum",
|
||||
"apiTokenLastUsed": "Zuletzt verwendet",
|
||||
"apiTokenNeverUsed": "Nie verwendet",
|
||||
"ics": {
|
||||
"title": "ICS-Abonnements",
|
||||
"add": "Abonnement hinzufügen",
|
||||
|
||||
+2
-5
@@ -57,10 +57,10 @@ app.use(helmet({
|
||||
// Alpine.js CDN (optional, falls verwendet)
|
||||
'https://cdn.jsdelivr.net',
|
||||
],
|
||||
styleSrc: ["'self'", "'unsafe-inline'", 'https://cdn.jsdelivr.net'],
|
||||
styleSrc: ["'self'", "'unsafe-inline'"],
|
||||
imgSrc: ["'self'", 'data:'],
|
||||
connectSrc: ["'self'"],
|
||||
fontSrc: ["'self'", 'data:', 'https://cdn.jsdelivr.net'],
|
||||
fontSrc: ["'self'"],
|
||||
objectSrc: ["'none'"],
|
||||
frameSrc: ["'none'"],
|
||||
// upgrade-insecure-requests nur mit HTTPS aktivieren
|
||||
@@ -176,9 +176,6 @@ function sendOpenApi(req, res) {
|
||||
|
||||
app.get('/api/v1/openapi.json', sendOpenApi);
|
||||
app.get('/openapi.json', sendOpenApi);
|
||||
app.get('/docs', (_req, res) => {
|
||||
res.sendFile(path.join(import.meta.dirname, '..', 'public', 'doc-assets', 'swagger.html'));
|
||||
});
|
||||
|
||||
// Alle weiteren API-Routen erfordern Authentifizierung + CSRF-Schutz
|
||||
app.use('/api/v1', requireAuth);
|
||||
|
||||
Reference in New Issue
Block a user