52 lines
2.4 KiB
JavaScript
52 lines
2.4 KiB
JavaScript
export const SECRET_DEFINITIONS = Object.freeze({
|
|
ANTHROPIC_API_KEY: { label: 'Anthropic API-Key', category: 'AI', editable: true },
|
|
OPENAI_API_KEY: { label: 'OpenAI API-Key', category: 'AI', editable: true },
|
|
OPENROUTER_API_KEY: { label: 'OpenRouter API-Key', category: 'AI', editable: true },
|
|
ETSY_API_KEY: { label: 'Etsy API-Key', category: 'Marktplatz', editable: true },
|
|
ETSY_ACCESS_TOKEN: { label: 'Etsy Access Token', category: 'Marktplatz', editable: false },
|
|
ETSY_REFRESH_TOKEN: { label: 'Etsy Refresh Token', category: 'Marktplatz', editable: false },
|
|
EBAY_CLIENT_SECRET: { label: 'eBay Client Secret', category: 'Marktplatz', editable: true },
|
|
EBAY_ACCESS_TOKEN: { label: 'eBay Access Token', category: 'Marktplatz', editable: false },
|
|
EBAY_REFRESH_TOKEN: { label: 'eBay Refresh Token', category: 'Marktplatz', editable: false },
|
|
LOCAL_IMAGE_TOKEN: { label: 'FLUX Dienst-Token', category: 'FLUX', editable: true },
|
|
SMTP_PASS: { label: 'SMTP-Passwort', category: 'E-Mail', editable: true },
|
|
VENDOO_SETUP_TOKEN: { label: 'Ersteinrichtungs-Token', category: 'System', editable: false },
|
|
COOLIFY_API_TOKEN: { label: 'Coolify API-Token', category: 'Deployment', editable: true },
|
|
COOLIFY_DEPLOY_WEBHOOK_URL: { label: 'Coolify Deploy-Webhook', category: 'Deployment', editable: true },
|
|
});
|
|
|
|
export const SECRET_NAMES = Object.freeze(Object.keys(SECRET_DEFINITIONS));
|
|
const SECRET_NAME = /^[A-Z][A-Z0-9_]{2,80}$/;
|
|
|
|
export function validateSecretName(name) {
|
|
const normalized = String(name || '').trim();
|
|
if (!SECRET_NAME.test(normalized) || !SECRET_DEFINITIONS[normalized]) {
|
|
const error = new Error(`Unbekanntes Secret: ${normalized || '(leer)'}`);
|
|
error.code = 'SECRET_NAME_INVALID';
|
|
throw error;
|
|
}
|
|
return normalized;
|
|
}
|
|
|
|
export function validateSecretValue(value) {
|
|
const normalized = String(value ?? '');
|
|
if (/\r|\n|\0/.test(normalized)) {
|
|
const error = new Error('Secrets dürfen keine Zeilenumbrüche oder Nullbytes enthalten.');
|
|
error.code = 'SECRET_VALUE_INVALID';
|
|
throw error;
|
|
}
|
|
if (Buffer.byteLength(normalized, 'utf8') > 16_384) {
|
|
const error = new Error('Secret ist zu groß.');
|
|
error.code = 'SECRET_VALUE_TOO_LARGE';
|
|
throw error;
|
|
}
|
|
return normalized;
|
|
}
|
|
|
|
export function maskSecret(value) {
|
|
const text = String(value || '');
|
|
if (!text) return '';
|
|
if (text.length <= 4) return '••••';
|
|
return `••••••••${text.slice(-4)}`;
|
|
}
|