Session log — Vodalibrary privacy lockdown and in-page video player
Session log — Vodalibrary privacy lockdown and in-page video player
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
- Email subject and body are now stored in a
settingstable 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) andembed = whitelistwith 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(wassame-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 made
- New
lib/settings.phpwithsettings_init(),get_setting(),set_setting(), plus seeding of defaults. - New
settingstable in vodalibrary_db (key/value with timestamp + updated_by). lib/email.phprewritten to read subject and body from settings, format paragraphs as HTML with auto-linking, and substitute{minutes}.lib/views.php: newview_email_settings()for the admin settings page. Topbar<h1>is now a link to/. Admin sub-nav added toview_admin()andview_email_settings()with the right active tab on each.public/index.php: new/admin/settingsGET (form) and POST (save + send-test) routes. Cache-busting headers added insend().Referrer-Policyloosened.lib/library_view.php: in-page modal player added (overlay + iframe + close button + ESC-to-close + click-backdrop-to-close). Cards switched fromtarget="_blank"link-out todata-playhandler. Modal HTML repositioned to BEFORE the script block (initial deploy had it after, breakinggetElementById). Modal click handler eventually placed at script end (initial deploy had it accidentally injected insidetoggleTag()). Iframe given explicitreferrerpolicy="strict-origin-when-cross-origin"./etc/nginx/sites-available/vodalibrary:add_header Referrer-Policyswitched tostrict-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'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
viewfrompasswordtodisable. Embed whitelist preserved. This is the correct end state. - Pre-change snapshot saved to
/var/www/vodalibrary/data/privacy-snapshot-20260509-182922.jsonso the original per-video state can be restored if ever needed. - Test announcement updated to reflect the new working state.
Follow-ups
- The single video VPP03 Inputting Data (id 227308603) had a transient Vimeo 503 on the first bulk pass — retried successfully and verified.
registeredvodalibraryuserswas 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's
embed = whitelistcontrols WHERE a video can be embedded; it does NOT bypass the password requirement whenview = password. If you want password-bypass for embeds you need either Vimeo Business+ with a private hash (?h=...param) or useview = disablewith whitelist, which is the cleaner pattern. Add to the team's "things we learned about Vimeo" mental model. - Real-world lesson: a strict
Referrer-Policy: same-originwill quietly break ALL third-party embeds (YouTube, Vimeo, Stripe, etc.) by suppressing the origin Referer they need for whitelist checks.strict-origin-when-cross-originis 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're
view = disablelike 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's likely fine.