use boot-key query parameter, tighten url match, put randomness in suggestions

This commit is contained in:
Paul Fitzpatrick 2024-05-23 14:59:58 -04:00
parent 07b80b1110
commit 7383b3f8f6
No known key found for this signature in database
GPG Key ID: 07F16BF3214888F6
5 changed files with 12 additions and 11 deletions

View File

@ -98,14 +98,15 @@ export class AdminPanel extends Disposable {
* which could include a legit adminstrator if auth is misconfigured. * which could include a legit adminstrator if auth is misconfigured.
*/ */
private _buildMainContentForOthers(owner: MultiHolder) { private _buildMainContentForOthers(owner: MultiHolder) {
const exampleKey = 'example-' + window.crypto.randomUUID();
return dom.create(AdminSection, t('Administrator Panel Unavailable'), [ return dom.create(AdminSection, t('Administrator Panel Unavailable'), [
dom('p', t(`You do not have access to the administrator panel. dom('p', t(`You do not have access to the administrator panel.
Please log in as an administrator.`)), Please log in as an administrator.`)),
dom( dom(
'p', 'p',
t(`Or, as a fallback, you can set: {{bootKey}} in the environment and visit: {{url}}`, { t(`Or, as a fallback, you can set: {{bootKey}} in the environment and visit: {{url}}`, {
bootKey: dom('pre', 'GRIST_BOOT_KEY=secret'), bootKey: dom('pre', `GRIST_BOOT_KEY=${exampleKey}`),
url: dom('pre', `/admin?key=secret`) url: dom('pre', `/admin?boot-key=${exampleKey}`)
}), }),
), ),
]); ]);

View File

@ -66,9 +66,9 @@ export class BaseAPI {
// This is a fallback mechanism if auth is broken to access the // This is a fallback mechanism if auth is broken to access the
// admin panel. // admin panel.
// TODO: should this be more selective? // TODO: should this be more selective?
if (typeof window !== 'undefined' && window.location) { if (typeof window !== 'undefined' && window.location &&
const url = new URL(window.location.href); window.location.pathname.endsWith('/admin')) {
const bootKey = url.searchParams.get('boot'); const bootKey = new URLSearchParams(window.location.search).get('boot-key')
if (bootKey) { if (bootKey) {
this._headers['X-Boot-Key'] = bootKey; this._headers['X-Boot-Key'] = bootKey;
} }

View File

@ -560,7 +560,7 @@ export class FlexServer implements GristServer {
this.app.get('/boot(/(:bootKey/?)?)?$', async (req, res) => { this.app.get('/boot(/(:bootKey/?)?)?$', async (req, res) => {
// Doing a good redirect is actually pretty subtle and we might // Doing a good redirect is actually pretty subtle and we might
// get it wrong, so just say /boot got moved. // get it wrong, so just say /boot got moved.
res.send('The /boot/key page is now /admin?boot=key'); res.send('The /boot/KEY page is now /admin?boot-key=KEY');
}); });
} }

View File

@ -349,11 +349,11 @@ describe('AdminPanel', function() {
process.env.GRIST_BOOT_KEY = 'zig'; process.env.GRIST_BOOT_KEY = 'zig';
await server.restart(true); await server.restart(true);
await driver.get(`${server.getHost()}/admin?boot=zig`); await driver.get(`${server.getHost()}/admin?boot-key=zig`);
await waitForAdminPanel(); await waitForAdminPanel();
assert.equal(await driver.find('.test-admin-panel').isDisplayed(), true); assert.equal(await driver.find('.test-admin-panel').isDisplayed(), true);
assert.notMatch(await driver.find('.test-admin-panel').getText(), /Administrator Panel Unavailable/); assert.notMatch(await driver.find('.test-admin-panel').getText(), /Administrator Panel Unavailable/);
await driver.get(`${server.getHost()}/admin?boot=zig-wrong`); await driver.get(`${server.getHost()}/admin?boot-key=zig-wrong`);
await waitForAdminPanel(); await waitForAdminPanel();
assert.equal(await driver.find('.test-admin-panel').isDisplayed(), true); assert.equal(await driver.find('.test-admin-panel').isDisplayed(), true);
assert.match(await driver.find('.test-admin-panel').getText(), /Administrator Panel Unavailable/); assert.match(await driver.find('.test-admin-panel').getText(), /Administrator Panel Unavailable/);

View File

@ -20,7 +20,7 @@ describe('Boot', function() {
await gu.waitToPass(async () => { await gu.waitToPass(async () => {
assert.include( assert.include(
await driver.findContentWait('pre', /GRIST_BOOT_KEY/, 2000).getText(), await driver.findContentWait('pre', /GRIST_BOOT_KEY/, 2000).getText(),
'GRIST_BOOT_KEY=secret'); 'GRIST_BOOT_KEY=example-');
}, 3000); }, 3000);
} }
@ -55,12 +55,12 @@ describe('Boot', function() {
}); });
it('gives prompt when key is wrong', async function() { it('gives prompt when key is wrong', async function() {
await driver.get(`${server.getHost()}/admin?boot=bilbo`); await driver.get(`${server.getHost()}/admin?boot-key=bilbo`);
await hasPrompt(); await hasPrompt();
}); });
it('gives page when key is right', async function() { it('gives page when key is right', async function() {
await driver.get(`${server.getHost()}/admin?boot=lala`); await driver.get(`${server.getHost()}/admin?boot-key=lala`);
await driver.findContentWait('div', /Is home page available/, 2000); await driver.findContentWait('div', /Is home page available/, 2000);
}); });
}); });