fix(admin): mask all stored configuration secrets and credential URLs
This commit is contained in:
1 parent
a6c9fd8a00
commit
24707a0bfc
7 files changed
+122
-6
No files matched your search
@@ -63,6 +63,54 @@ test('update delegate can update but cannot open configuration', async ({ page }
|
||||
await expect(page.getByRole('heading', { name: 'Конфигурация', exact: true })).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('configuration masks every stored secret even if an older API returns plaintext', async ({ page }) => {
|
||||
await login(page);
|
||||
await page.evaluate(() => {
|
||||
const original = window.fetch;
|
||||
window.fetch = async (input, init) => {
|
||||
const response = await original(input, init);
|
||||
const request = new Request(input, init);
|
||||
if (request.method === 'GET' && new URL(request.url).pathname === '/api/v1/admin/server/config') {
|
||||
const data = await response.json();
|
||||
const common = { group: 'api', type: 'string', secret: true, readonly: false };
|
||||
data.entries = [
|
||||
{ ...common, key: 'ENV_SECRET', env: 'env-canary', local: 'local-canary', effective: 'env-canary', default_value: 'default-canary', source: 'env' },
|
||||
{ ...common, key: 'DEFAULT_SECRET', env: null, local: null, effective: 'default-canary', default_value: 'default-canary', source: 'default' },
|
||||
{ ...common, key: 'READONLY_SECRET', readonly: true, env: 'readonly-canary', local: null, effective: 'readonly-canary', default_value: '', source: 'env' },
|
||||
];
|
||||
return new Response(JSON.stringify(data), { headers: { 'Content-Type': 'application/json' } });
|
||||
}
|
||||
return response;
|
||||
};
|
||||
history.pushState({}, '', '/admin/config');
|
||||
window.dispatchEvent(new PopStateEvent('popstate'));
|
||||
});
|
||||
const env = page.getByLabel('ENV_SECRET · config.local', { exact: true });
|
||||
const defaults = page.getByLabel('DEFAULT_SECRET · config.local', { exact: true });
|
||||
await expect(env).toHaveValue('');
|
||||
await expect(env).toHaveAttribute('type', 'password');
|
||||
await expect(defaults).toHaveValue('');
|
||||
await expect(defaults).toHaveAttribute('placeholder', '');
|
||||
await expect(page.getByText('READONLY_SECRET', { exact: true })).toBeVisible();
|
||||
for (const canary of ['env-canary', 'local-canary', 'default-canary', 'readonly-canary']) {
|
||||
expect(await page.getByRole('main').innerHTML()).not.toContain(canary);
|
||||
}
|
||||
await page.getByRole('button', { name: 'Показать пароль', exact: true }).first().click();
|
||||
await expect(env).toHaveValue('');
|
||||
});
|
||||
|
||||
test('a replacement secret is hidden and cleared from the form after saving', async ({ page }) => {
|
||||
await login(page, 'mobile-admin', '/admin/config');
|
||||
const token = page.getByLabel('GITEA_TOKEN · config.local', { exact: true });
|
||||
await token.fill('replacement-canary');
|
||||
await expect(token).toHaveAttribute('type', 'password');
|
||||
await page.getByRole('button', { name: 'Сохранить', exact: true }).click();
|
||||
await expect(page.getByText('Изменения сохранены в config.local', { exact: true })).toBeVisible();
|
||||
await expect(token).toHaveValue('');
|
||||
await expect(token).toHaveAttribute('placeholder', 'Секрет сохранён');
|
||||
expect(await page.getByRole('main').innerHTML()).not.toContain('replacement-canary');
|
||||
});
|
||||
|
||||
test('ordinary user is redirected away from server management', async ({ page }) => {
|
||||
await login(page, 'alice', '/admin/updates');
|
||||
await expect(page).toHaveURL('/');
|
||||
|
||||
Reference in new issue
Block a user