document.addEventListener('DOMContentLoaded', function () { var state = { workspaceId: null, secrets: [], profiles: [], search: '', loading: false, error: '', modalMode: 'create', modalSecretId: null, }; var modal = document.getElementById('secret-modal'); var tbody = document.getElementById('secrets-tbody'); var profilesList = document.getElementById('auth-profiles-list'); var summary = document.getElementById('secrets-summary'); var profilesSummary = document.getElementById('secret-profiles-summary'); var searchInput = document.getElementById('secret-search'); var modalTitle = document.getElementById('secret-modal-title'); var modalName = document.getElementById('secret-name'); var modalKind = document.getElementById('secret-kind'); var modalNote = document.getElementById('secret-modal-note'); var modalSubmit = document.getElementById('secret-modal-submit-btn'); var kindHint = document.getElementById('secret-kind-hint'); var stringLabel = document.getElementById('secret-string-label'); var stringField = document.getElementById('secret-string-value'); var usernameField = document.getElementById('secret-username'); var passwordField = document.getElementById('secret-password'); var jsonField = document.getElementById('secret-json-value'); function tKey(key) { return typeof t === 'function' ? t(key) : key; } function tfKey(key, vars) { return typeof tf === 'function' ? tf(key, vars) : tKey(key); } function currentWorkspaceId() { var workspace = window.getCurrentWorkspace ? window.getCurrentWorkspace() : null; return workspace ? workspace.id : null; } function currentWorkspace() { return window.getCurrentWorkspace ? window.getCurrentWorkspace() : null; } function secretKindLabel(kind) { return tKey('secrets.kind.' + String(kind || '').toLowerCase()); } function authKindLabel(kind) { return tKey('secrets.auth_kind.' + String(kind || '').toLowerCase()); } function formatDate(value) { if (!value) return '—'; return new Date(value).toLocaleDateString(); } function secretIdsForProfile(profile) { var config = profile && profile.config ? profile.config : {}; if (config.bearer) return [config.bearer.secret_id]; if (config.basic) return [config.basic.username_secret_id, config.basic.password_secret_id]; if (config.api_key_header) return [config.api_key_header.secret_id]; if (config.api_key_query) return [config.api_key_query.secret_id]; return []; } function profileSummary(profile, secretsById) { var config = profile && profile.config ? profile.config : {}; if (config.bearer) { return tfKey('secrets.profiles.summary_bearer', { header: config.bearer.header_name, secret: secretName(secretsById, config.bearer.secret_id), }); } if (config.basic) { return tfKey('secrets.profiles.summary_basic', { username: secretName(secretsById, config.basic.username_secret_id), password: secretName(secretsById, config.basic.password_secret_id), }); } if (config.api_key_header) { return tfKey('secrets.profiles.summary_api_key_header', { header: config.api_key_header.header_name, secret: secretName(secretsById, config.api_key_header.secret_id), }); } if (config.api_key_query) { return tfKey('secrets.profiles.summary_api_key_query', { param: config.api_key_query.param_name, secret: secretName(secretsById, config.api_key_query.secret_id), }); } return tKey('secrets.profiles.summary_unknown'); } function secretName(secretsById, secretId) { var secret = secretsById[secretId]; return secret ? secret.name : secretId; } function usageBySecret() { var usage = {}; state.profiles.forEach(function (profile) { secretIdsForProfile(profile).forEach(function (secretId) { if (!secretId) return; if (!usage[secretId]) usage[secretId] = []; usage[secretId].push(profile); }); }); return usage; } function resetModalFields() { modalName.value = ''; modalKind.value = 'token'; stringField.value = ''; usernameField.value = ''; passwordField.value = ''; jsonField.value = '{\n "value": ""\n}'; } function openModal(mode, secret) { state.modalMode = mode; state.modalSecretId = secret ? secret.id : null; resetModalFields(); if (mode === 'rotate' && secret) { modalTitle.textContent = tKey('secrets.modal.rotate_title'); modalName.value = secret.name; modalName.disabled = true; modalKind.value = secret.kind; modalKind.disabled = true; modalSubmit.textContent = tKey('secrets.modal.rotate_action'); modalNote.textContent = tKey('secrets.modal.rotate_note'); } else { modalTitle.textContent = tKey('secrets.modal.create_title'); modalName.disabled = false; modalKind.disabled = false; modalSubmit.textContent = tKey('secrets.modal.create_action'); modalNote.textContent = tKey('secrets.modal.create_note'); } updateKindFields(); modal.classList.add('open'); setTimeout(function () { if (mode === 'rotate') { stringField.focus(); } else { modalName.focus(); } }, 30); } function closeModal() { modal.classList.remove('open'); state.modalMode = 'create'; state.modalSecretId = null; } function updateKindFields() { var kind = modalKind.value; document.querySelectorAll('[data-kind-field="string"]').forEach(function (element) { element.style.display = kind === 'token' || kind === 'header' ? '' : 'none'; }); document.querySelectorAll('[data-kind-field="basic"]').forEach(function (element) { element.style.display = kind === 'username_password' ? '' : 'none'; }); document.querySelectorAll('[data-kind-field="json"]').forEach(function (element) { element.style.display = kind === 'generic' ? '' : 'none'; }); if (kind === 'token') { stringLabel.textContent = tKey('secrets.modal.value'); } else if (kind === 'header') { stringLabel.textContent = tKey('secrets.modal.header_value'); } else { stringLabel.textContent = tKey('secrets.modal.value'); } kindHint.textContent = tKey('secrets.hint.' + kind); } function buildSecretValue() { var kind = modalKind.value; if (kind === 'token' || kind === 'header') { var value = stringField.value.trim(); if (!value) { throw new Error(tKey('secrets.validation.value_required')); } return value; } if (kind === 'username_password') { var username = usernameField.value.trim(); var password = passwordField.value; if (!username || !password) { throw new Error(tKey('secrets.validation.username_password_required')); } return { username: username, password: password, }; } try { return JSON.parse(jsonField.value); } catch (_error) { throw new Error(tKey('secrets.validation.json_invalid')); } } function renderSecrets() { var usage = usageBySecret(); var query = state.search.toLowerCase(); var rows = state.secrets.filter(function (secret) { return !query || secret.name.toLowerCase().includes(query) || String(secret.kind || '').toLowerCase().includes(query); }); var active = state.secrets.filter(function (secret) { return secret.status === 'active'; }).length; summary.textContent = tfKey('secrets.active.subtitle', { active: active, total: state.secrets.length, }); tbody.innerHTML = ''; if (state.loading && state.secrets.length === 0) { var loadingRow = document.createElement('tr'); var loadingCell = document.createElement('td'); loadingCell.colSpan = 7; loadingCell.style.cssText = 'text-align:center;padding:36px;color:var(--text-muted);'; loadingCell.textContent = tKey('secrets.loading'); loadingRow.appendChild(loadingCell); tbody.appendChild(loadingRow); return; } if (state.error) { var errorRow = document.createElement('tr'); var errorCell = document.createElement('td'); errorCell.colSpan = 7; errorCell.style.cssText = 'text-align:center;padding:36px;color:var(--danger,#f85149);'; errorCell.textContent = state.error; errorRow.appendChild(errorCell); tbody.appendChild(errorRow); return; } if (!rows.length) { var emptyRow = document.createElement('tr'); var emptyCell = document.createElement('td'); emptyCell.colSpan = 7; emptyCell.style.cssText = 'text-align:center;padding:36px;color:var(--text-muted);'; emptyCell.textContent = state.secrets.length ? tKey('secrets.empty.search') : tKey('secrets.empty.none'); emptyRow.appendChild(emptyCell); tbody.appendChild(emptyRow); return; } rows.forEach(function (secret) { var tr = document.createElement('tr'); var references = usage[secret.id] || []; tr.innerHTML = [ '