aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/admin-page.js
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/admin-page.js')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/admin-page.js34
1 files changed, 34 insertions, 0 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/admin-page.js b/packages/meshbay-hub/src/meshbay_hub/static/admin-page.js
index c40d240..d5cc7a8 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/admin-page.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/admin-page.js
@@ -17,6 +17,7 @@ export function AdminPage({ token, role }) {
// and a rejected one never looks applied.
const [mailDraft, setMailDraft] = useState(null);
const [loginDraft, setLoginDraft] = useState(null);
+ const [sessionDraft, setSessionDraft] = useState(null);
const [users, setUsers] = useState([]);
const [usersTotal, setUsersTotal] = useState(0);
const [userSearch, setUserSearch] = useState('');
@@ -45,6 +46,7 @@ export function AdminPage({ token, role }) {
setSettings(data);
setMailDraft({ ...data.mail });
setLoginDraft({ ...data.login });
+ setSessionDraft({ ...data.session });
} catch (e) { setError(e.message); }
try {
setMailStatus(await hubFetch('/v1/admin/mail', { token }));
@@ -64,6 +66,7 @@ export function AdminPage({ token, role }) {
// answer rather than left showing a number that was not stored.
setMailDraft({ ...data.mail });
setLoginDraft({ ...data.login });
+ setSessionDraft({ ...data.session });
if (patch.mail) {
try {
setMailStatus(await hubFetch('/v1/admin/mail', { token }));
@@ -198,6 +201,8 @@ const MAIL_FIELDS = [
const LOGIN_FIELDS = ['max_failures', 'lockout_minutes'];
+const SESSION_FIELDS = ['browser_idle_hours', 'refresh_idle_hours', 'max_hours'];
+
// Only what changed, and only what is a number: an empty field is someone
// mid-edit, not a request to set zero.
const changedNumbers = (fields, draft, stored) => Object.fromEntries(fields
@@ -296,6 +301,35 @@ const TABS = ['general', 'stats', 'users', 'groups', 'nodes', 'logs', 'blocklist
</div>
`}
</div>
+
+ <div class="settings-section">
+ <h3 class="settings-heading">${t('admin.session_heading')}</h3>
+ <p class="settings-hint">${t('admin.session_hint')}</p>
+
+ ${sessionDraft && SESSION_FIELDS.map(key => html`
+ <div class="settings-row" key=${key}>
+ <span class="settings-label">${t('admin.session_' + key)}</span>
+ <input type="number" class="settings-number"
+ min=${(settings.session_bounds?.[key] || [0])[0]}
+ max=${(settings.session_bounds?.[key] || [0, 0])[1]}
+ value=${sessionDraft[key]}
+ disabled=${!canEditSettings || settingsSaving}
+ onInput=${e => setSessionDraft(d => ({ ...d, [key]: e.target.value }))} />
+ </div>
+ `)}
+
+ ${canEditSettings && sessionDraft && html`
+ <div class="settings-row">
+ <button class="btn" disabled=${settingsSaving}
+ onClick=${() => saveSettings({
+ session: changedNumbers(SESSION_FIELDS, sessionDraft, settings.session),
+ })}>${t('admin.session_save')}</button>
+ <button class="btn btn-secondary" disabled=${settingsSaving}
+ onClick=${() => setSessionDraft({ ...settings.session_defaults })}
+ >${t('admin.mail_reset_defaults')}</button>
+ </div>
+ `}
+ </div>
`}
`}