Changeset a64f642 in Klonkt


Ignore:
Timestamp:
06/14/2026 04:28:57 PM (3 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
ab544fd
Parents:
640b39c
Message:

admin: read-only ("View mode") configurable per user in Admin -> Users

Toggle in the user list (POST /admin/users/:id/readonly, god-only, not on
yourself). Sets users.readonly on/off so an account can view everything but
cannot modify anything.

Co-Authored-By: Claude <noreply@…>

Location:
src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/routes/admin-users.js

    r640b39c ra64f642  
    2929router.get('/', requireGod, (req, res) => {
    3030  const users = db.prepare(`
    31     SELECT u.id, u.username, u.email, u.role, u.created_at, u.avatar_url,
     31    SELECT u.id, u.username, u.email, u.role, u.created_at, u.avatar_url, u.readonly,
    3232           (SELECT COUNT(*) FROM posts p WHERE p.author_id = u.id) AS post_count,
    3333           (SELECT COUNT(*) FROM sites s  WHERE s.owner_id  = u.id) AS site_count
     
    7171});
    7272
     73// ==================== READ-ONLY (kijk-account) ====================
     74router.post('/:id/readonly', requireGod, (req, res) => {
     75  const target = db.prepare('SELECT id FROM users WHERE id = ?').get(req.params.id);
     76  if (!target) return res.redirect('/admin/users?error=User+not+found');
     77  // Niet op jezelf — voorkomt dat een god zichzelf alleen-lezen maakt en vastloopt.
     78  if (target.id === req.session.user.id) {
     79    return res.redirect('/admin/users?error=' + encodeURIComponent('Kan jezelf niet op alleen-lezen zetten'));
     80  }
     81  const ro = req.body.readonly === '1' ? 1 : 0;
     82  db.prepare('UPDATE users SET readonly = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?')
     83    .run(ro, req.params.id);
     84  res.redirect('/admin/users?success=' + encodeURIComponent(ro ? 'Kijk-modus aan' : 'Kijk-modus uit'));
     85});
     86
    7387// ==================== DELETE ====================
    7488router.post('/:id/delete', requireGod, (req, res) => {
  • src/views/pages/admin-users.ejs

    r640b39c ra64f642  
    6666            </form>
    6767
     68            <form method="post" action="/admin/users/<%= u.id %>/readonly" class="ax-role-form">
     69              <label class="ax-role ax-ro" title="Alleen-lezen: kan alles bekijken, niets wijzigen">
     70                <span>Kijk-modus</span>
     71                <input type="checkbox" name="readonly" value="1" <%= u.readonly ? 'checked' : '' %>
     72                       onchange="this.form.submit()" <% if (u.id === user.id) { %>disabled<% } %>>
     73              </label>
     74            </form>
     75
    6876            <% if (u.id !== user.id && (u.post_count + u.site_count === 0)) { %>
    6977              <form method="post" action="/admin/users/<%= u.id %>/delete" class="ax-delete-form"
     
    222230}
    223231.ax-role select:disabled { cursor: not-allowed; opacity: 0.5; }
     232.ax-ro { align-items: center; }
     233.ax-ro input { width: 18px; height: 18px; cursor: pointer; margin-top: 0.15rem; accent-color: var(--accent); }
     234.ax-ro input:disabled { cursor: not-allowed; opacity: 0.5; }
    224235.ax-delete-form { margin: 0; }
    225236.ax-icon-btn {
Note: See TracChangeset for help on using the changeset viewer.