Let only admins change the global settings
BINDERY_ADMIN_USERS lists the admins of the cwa and proxy modes. Only an admin can change the global settings and the global rules, and read or change personal.ini. Without a list, each user is an admin.
This commit is contained in:
@@ -11,7 +11,7 @@ const ROUTES = [
|
||||
[/^\/$/, storiesPage, []],
|
||||
[/^\/story\/(\d+)$/, storyPage, ['storyId']],
|
||||
[/^\/story\/(\d+)\/chapter\/(\d+)$/, chapterPage, ['storyId', 'chapterId']],
|
||||
[/^\/settings$/, settingsPage, []],
|
||||
[/^\/settings$/, settingsPage, [], true],
|
||||
];
|
||||
|
||||
const app = document.getElementById('bindery-app');
|
||||
@@ -23,6 +23,9 @@ let nav = null;
|
||||
let storyTab = null;
|
||||
let storyTabShown = false;
|
||||
|
||||
// The server refuses the changes of a user who is not an admin. The interface only hides what that user cannot use.
|
||||
const isAdmin = () => auth.admin !== false;
|
||||
|
||||
const currentPath = () => window.location.hash.replace(/^#/, '') || '/';
|
||||
// The story of #/story/3 and of its chapter pages, such as #/story/3/chapter/5.
|
||||
const currentStoryId = () => currentPath().match(/^\/story\/(\d+)(?:\/|$)/)?.[1];
|
||||
@@ -44,6 +47,14 @@ function notFound(main) {
|
||||
fill(main, h('section', { class: 'card' }, h('h1', {}, 'Page not found'), h('p', {}, h('a', { href: '#/' }, 'Go to the story list'))));
|
||||
}
|
||||
|
||||
function adminOnly(main) {
|
||||
document.title = 'Settings · Bindery';
|
||||
fill(
|
||||
main,
|
||||
h('section', { class: 'card' }, h('h1', {}, 'Settings'), h('p', {}, 'Only an admin can open the settings. BINDERY_ADMIN_USERS lists the admins.')),
|
||||
);
|
||||
}
|
||||
|
||||
function route() {
|
||||
const main = document.getElementById('main');
|
||||
if (!main) return;
|
||||
@@ -54,9 +65,10 @@ function route() {
|
||||
if (storyTab?.getAttribute('href') !== `#/story/${currentStoryId()}`) hideStoryTab();
|
||||
const found = ROUTES.find(([pattern]) => pattern.test(path));
|
||||
if (found) {
|
||||
const [pattern, page, names] = found;
|
||||
const [pattern, page, names, admin] = found;
|
||||
const match = path.match(pattern);
|
||||
cleanup = page(main, Object.fromEntries(names.map((name, i) => [name, match[i + 1]])), config) || null;
|
||||
if (admin && !isAdmin()) adminOnly(main);
|
||||
else cleanup = page(main, Object.fromEntries(names.map((name, i) => [name, match[i + 1]])), config) || null;
|
||||
} else {
|
||||
notFound(main);
|
||||
}
|
||||
@@ -81,7 +93,7 @@ function shell() {
|
||||
(auth.mode === 'cwa' || auth.mode === 'local' || auth.logout_url) &&
|
||||
h('button', { type: 'button', onclick: () => logout().catch(showError) }, 'Log out'),
|
||||
];
|
||||
nav = h('nav', { 'aria-label': 'Main navigation' }, h('a', { href: '#/' }, 'Stories'), h('a', { href: '#/settings' }, 'Settings'));
|
||||
nav = h('nav', { 'aria-label': 'Main navigation' }, h('a', { href: '#/' }, 'Stories'), isAdmin() && h('a', { href: '#/settings' }, 'Settings'));
|
||||
storyTab = h('a', { class: 'story-tab' });
|
||||
storyTabShown = false;
|
||||
fill(
|
||||
|
||||
Reference in New Issue
Block a user