Session log — Vodalibrary privacy lockdown and in-page video player

← All session logs

Session log — Vodalibrary privacy lockdown and in-page video player

9 May 2026 · Hasmukh with Claude · Three big additions to vodalibrary.online. Editable Mobilearn-branded sign-in email with an admin settings page, an in-page modal video player so users stay inside the library, and the big one: locked down all 1,201 vodac-tagged Vimeo videos so they only play inside vodalibrary.online. The privacy lockdown took a wrong turn first (view=password + embed=whitelist did not bypass the password) before settling on view=disable + embed=whitelist.

Brief

Summary

Three big additions to vodalibrary.online today. First, an editable sign-in email: Hasmukh wanted a custom Mobilearn-branded preamble on every magic-link email, and now has an Admin Settings page where he can rewrite the subject and body himself any time. Second, a "Library" navigation button on admin pages. Third, the big one: locked down all 1,201 vodac-tagged Vimeo videos so they can ONLY play inside vodalibrary.online (not at vimeo.com, not on any other site), and built an in-page modal player so users watch videos in the library instead of being kicked out to vimeo.com. The privacy lockdown took a wrong turn first (we tried view=password + embed=whitelist before discovering Vimeo's whitelist doesn't bypass the password for embeds) and a couple of rounds of debugging the player UI, but ended up clean.

Decisions

Decisions

  • Email subject and body are now stored in a settings table in MySQL, key/value, with a single Admin Settings page to edit them. Defaults seed on first run and persist across deploys. The body uses {minutes} as a placeholder for the magic-link TTL.
  • Email template architecture: the editable body is the entire greeting + identity + call-to-action paragraph. The Sign in button, the "or paste this address" fallback link, and the small "if you didn't ask for this" footer are appended automatically by code.
  • Admin sub-nav: small horizontal bar with "← Library", "People & activity", "Email settings". Same bar on all admin pages, with the active tab highlighted in red.
  • Topbar site title is now a link to / so the user can always navigate home from anywhere.
  • Vimeo privacy model: Path C ("embed-only via vodalibrary.online"). Every vodac-tagged video set to view = disable (invisible at vimeo.com, no password prompt) and embed = whitelist with vodalibrary.online whitelisted (only embeds on our domain play). This is materially stronger than Path B (password-based) and was the right call from the start.
  • Library cards now play in-page in a modal lightbox, no link-out to vimeo.com. The "Open on Vimeo ↗" link is still there for power users.
  • Referrer-Policy on the site is strict-origin-when-cross-origin (was same-origin). The tighter same-origin policy was preventing Vimeo's whitelist check from seeing our domain at all, breaking embeds. The new policy still hides the path but lets Vimeo see the origin, which is the minimum it needs.
  • Cache-busting headers added to all PHP responses (Cache-Control: no-cache, no-store, must-revalidate) to prevent browsers serving stale JS after deployments.
Changes

Changes made

  • New lib/settings.php with settings_init(), get_setting(), set_setting(), plus seeding of defaults.
  • New settings table in vodalibrary_db (key/value with timestamp + updated_by).
  • lib/email.php rewritten to read subject and body from settings, format paragraphs as HTML with auto-linking, and substitute {minutes}.
  • lib/views.php: new view_email_settings() for the admin settings page. Topbar <h1> is now a link to /. Admin sub-nav added to view_admin() and view_email_settings() with the right active tab on each.
  • public/index.php: new /admin/settings GET (form) and POST (save + send-test) routes. Cache-busting headers added in send(). Referrer-Policy loosened.
  • lib/library_view.php: in-page modal player added (overlay + iframe + close button + ESC-to-close + click-backdrop-to-close). Cards switched from target="_blank" link-out to data-play handler. Modal HTML repositioned to BEFORE the script block (initial deploy had it after, breaking getElementById). Modal click handler eventually placed at script end (initial deploy had it accidentally injected inside toggleTag()). Iframe given explicit referrerpolicy="strict-origin-when-cross-origin".
  • /etc/nginx/sites-available/vodalibrary: add_header Referrer-Policy switched to strict-origin-when-cross-origin.
  • Vimeo bulk operation 1 (~32 min, 1,201 videos): set view = password (preserving 67 already-password videos), embed = whitelist, added vodalibrary.online to each video&#x27;s whitelist. This was a wrong turn. It worked at the API level but the embeds still asked for the password.
  • Vimeo bulk operation 2 (~22 min, 1,201 videos): switched view from password to disable. Embed whitelist preserved. This is the correct end state.
  • Pre-change snapshot saved to /var/www/vodalibrary/data/privacy-snapshot-20260509-182922.json so the original per-video state can be restored if ever needed.
  • Test announcement updated to reflect the new working state.
Follow-ups

Follow-ups

  • The single video VPP03 Inputting Data (id 227308603) had a transient Vimeo 503 on the first bulk pass — retried successfully and verified.
  • registeredvodalibraryusers was set as a Vimeo password during the wrong-turn pass, then made irrelevant by the switch to view=disable. Worth noting in case anyone wonders why a password setting once existed.
  • Real-world lesson: Vimeo&#x27;s embed = whitelist controls WHERE a video can be embedded; it does NOT bypass the password requirement when view = password. If you want password-bypass for embeds you need either Vimeo Business+ with a private hash (?h=... param) or use view = disable with whitelist, which is the cleaner pattern. Add to the team&#x27;s "things we learned about Vimeo" mental model.
  • Real-world lesson: a strict Referrer-Policy: same-origin will quietly break ALL third-party embeds (YouTube, Vimeo, Stripe, etc.) by suppressing the origin Referer they need for whitelist checks. strict-origin-when-cross-origin is the right default for sites that embed third-party content.
  • Browser cache for inline JS is sticky even with hard-refresh in some cases. Cache-busting headers now added preventatively, but the diagnostic recipe is: open DevTools → check for the vlib build: console marker. If absent, hit it from a private/incognito window.
  • The 67 videos that originally had pre-existing Vimeo passwords have lost those (now they&#x27;re view = disable like the rest). If anyone outside vodalibrary.online used to watch them via the old password URL, that path is now dead. We should monitor for any "where did these go" complaints, but it&#x27;s likely fine.