Changeset 70679063 in Klonkt


Ignore:
Timestamp:
06/19/2026 07:57:15 AM (3 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
b919a67
Parents:
9b3e12c
Message:

fix: download toggle without page reload + clear explanation page on Google admin login

1) Admin→Audio: the "download-for-email" toggle (⬇) was a form POST with redirect →

full page reload on every click (player + scroll reset). Now AJAX via the existing
/admin/audio/api/:id (accepts downloadable), button state updated in-place, no
reload. (Old POST route stays as an unused fallback.)

2) /auth/login did not show the query error (error:null) → message only appeared in

the URL. Now ?error= is rendered, and the "Google address belongs to an admin"
case gets its own clear explanation block (gerr=admin): why it is rejected + the
two paths (admin = password, fan = different Google account).

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

Location:
src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/routes/auth.js

    r9b3e12c r70679063  
    5252    pageTitle: 'Inloggen',
    5353    bodyClass: 'on-special on-auth',
    54     error: null,
     54    error: req.query.error || null,
     55    gerr: req.query.gerr || null, // foutcode voor een rijkere uitleg (bv. 'admin')
    5556    success: req.query.success || null,
    5657    username: '',
     
    275276      // beheerder, dan moet diegene met wachtwoord inloggen (geen Google-bypass).
    276277      if (user.role === 'god' || user.role === 'admin') {
    277         return fail('Dit adres hoort bij een beheerder — log in met je wachtwoord.');
     278        // Eigen, duidelijke uitleg-pagina (zie auth-login.ejs) i.p.v. een kale melding.
     279        return res.redirect('/auth/login?gerr=admin');
    278280      }
    279281      // Bestaande luisteraar: koppel google_sub/avatar als die ontbreken; weiger
  • src/views/pages/admin-audio.ejs

    r9b3e12c r70679063  
    102102              <button type="button" class="ax-icon-btn" data-track-edit data-id="<%= t.id %>" aria-label="Bewerken" title="Bewerken">✎</button>
    103103              <% if (typeof premiumUnlocked === 'undefined' || premiumUnlocked) { %>
    104                 <form action="/admin/audio/<%= t.id %>/downloadable" method="post" class="ax-track-delete" style="display:inline">
    105                   <button type="submit" class="ax-icon-btn" aria-label="Download-voor-email" title="<%= t.downloadable ? 'Download-voor-email staat AAN — klik om uit te zetten' : 'Download-voor-email staat uit — klik om aan te zetten' %>" style="<%= t.downloadable ? 'color:var(--accent,#6b8f71)' : 'opacity:.5' %>">⬇</button>
    106                 </form>
     104                <button type="button" class="ax-icon-btn" data-track-dl data-id="<%= t.id %>" data-on="<%= t.downloadable ? '1' : '0' %>"
     105                        aria-label="Download-voor-email" title="<%= t.downloadable ? 'Download-voor-email staat AAN — klik om uit te zetten' : 'Download-voor-email staat uit — klik om aan te zetten' %>"
     106                        style="<%= t.downloadable ? 'color:var(--accent,#6b8f71)' : 'opacity:.5' %>">⬇</button>
    107107              <% } %>
    108108              <form action="/admin/audio/<%= t.id %>/delete" method="post" onsubmit="return confirm('Track verwijderen?')" class="ax-track-delete">
     
    939939    });
    940940  });
     941
     942  // Download-voor-email toggle — AJAX (geen pagina-reload meer).
     943  document.querySelectorAll('[data-track-dl]').forEach(btn => {
     944    btn.addEventListener('click', async () => {
     945      if (btn.disabled) return;
     946      const want = btn.dataset.on === '1' ? 0 : 1;
     947      btn.disabled = true;
     948      try {
     949        const res = await fetch('/admin/audio/api/' + btn.dataset.id, {
     950          method: 'POST',
     951          headers: { 'Content-Type': 'application/json' },
     952          body: JSON.stringify({ downloadable: !!want }),
     953        });
     954        if (!res.ok) throw new Error('HTTP ' + res.status);
     955        btn.dataset.on = String(want);
     956        btn.style.color = want ? 'var(--accent,#6b8f71)' : '';
     957        btn.style.opacity = want ? '1' : '.5';
     958        btn.title = want
     959          ? 'Download-voor-email staat AAN — klik om uit te zetten'
     960          : 'Download-voor-email staat uit — klik om aan te zetten';
     961      } catch (e) {
     962        alert('Kon niet wijzigen: ' + (e.message || e));
     963      } finally {
     964        btn.disabled = false;
     965      }
     966    });
     967  });
    941968})();
    942969</script>
  • src/views/pages/auth-login.ejs

    r9b3e12c r70679063  
    22  <h1>Inloggen</h1>
    33  <% if (typeof success !== 'undefined' && success) { %><div class="alert alert-success"><%= success %></div><% } %>
    4   <% if (error) { %><div class="alert alert-error"><%= error %></div><% } %>
     4  <% if (typeof gerr !== 'undefined' && gerr === 'admin') { %>
     5    <div class="auth-notice">
     6      <div class="auth-notice-icon">🔐</div>
     7      <h2 class="auth-notice-title">Dit is een beheerders-account</h2>
     8      <p>Je logde in met Google, maar dit e-mailadres hoort bij de <strong>beheerder</strong> van deze site.
     9         Inloggen met Google is alleen voor luisteraars/fans — beheerders gebruiken altijd hun wachtwoord
     10         (zo kan een Google-login nooit per ongeluk beheerrechten geven).</p>
     11      <ul class="auth-notice-list">
     12        <li><strong>Ben je de beheerder?</strong> Log hieronder in met je <strong>gebruikersnaam + wachtwoord</strong>.</li>
     13        <li><strong>Wil je als fan inloggen?</strong> Gebruik een <strong>ander Google-account</strong> (niet je beheerdersadres).</li>
     14      </ul>
     15    </div>
     16  <% } else if (error) { %><div class="alert alert-error"><%= error %></div><% } %>
    517
    618  <form method="post" action="/auth/login" class="auth-form">
     
    3345  <% } %>
    3446</div>
     47
     48<style>
     49  .auth-notice { border: 1px solid rgba(128,128,128,.28); border-radius: 14px; padding: 18px 20px; margin-bottom: 18px; background: rgba(128,128,128,.06); }
     50  .auth-notice-icon { font-size: 26px; }
     51  .auth-notice-title { font-size: 17px; margin: 4px 0 8px; }
     52  .auth-notice p { margin: 0 0 10px; line-height: 1.55; opacity: .9; }
     53  .auth-notice-list { margin: 0; padding-left: 18px; line-height: 1.6; }
     54  .auth-notice-list li { margin: 4px 0; }
     55</style>
Note: See TracChangeset for help on using the changeset viewer.