Diploma Uitreiking 2026 . Diploma Uitreiking 2026 . Diploma Uitreiking 2026 . Diploma Uitreiking 2026 . Diploma Uitreiking 2026 . Diploma Uitreiking 2026 .Diploma Uitreiking 2026 . Diploma Uitreiking 2026 . Diploma Uitreiking 2026 . Diploma Uitreiking 2026 . Diploma Uitreiking 2026 . Diploma Uitreiking 2026 .
CompletedFeatured2026

Diploma Uitreiking 2026

Diploma Uitreiking 2026 is the graduation-ceremony platform for Grafisch Lyceum Rotterdam, live at geslaagd.glr.nl. Families who cannot be in the room enter the access code printed on their invitation and watch their ceremony as a Vimeo livestream, alongside the photos taken that day. Behind that single front door sits a full staff platform: photographers and student photographers upload and manage photos, admins import the ceremony schedule straight from the school planning CSV and run the whole operation, and admin sign-in is protected by a WebAuthn passkey. Production is Plesk shared hosting updated by a git pull, which means no Composer, no npm, and no build step, so the WebAuthn verification, the SMTP mailer, and the intrusion-detection engine are all written by hand in vanilla PHP. The Once Upon A Time visual identity was supplied by the school design team; I implemented it and built the entire application behind it.

RoleFull-Stack Developer
Duration1 month
TeamSolo Project
ClientGrafisch Lyceum Rotterdam
Diploma Uitreiking 2026

The Challenge

The school needed one site to carry a real, emotional, one-shot event. Families who could not be in the room had to reach their ceremony livestream without accounts or passwords, using nothing but a code on their invitation, and they could only ever see their own ceremony. Photographers had to upload during the day without any training. The planning arrived as a messy CSV exported by the school. And because the site holds photos of students and runs on the school domain, it had to survive being publicly exposed and scanned. Production is Plesk shared hosting with no Composer, no npm, and no build step, so anything I needed, I had to write myself.

The Solution

I built it as vanilla PHP 8.3 on MariaDB with zero runtime dependencies. Visitors get a code-only front door that scopes them to exactly one ceremony; staff get role-based workspaces; the school CSV is parsed, previewed, and upserted idempotently so a re-import never duplicates a ceremony. The security layer is the part I am proudest of. I implemented WebAuthn passkey registration and assertion verification from scratch, including a CBOR decoder and COSE-to-PEM key conversion, so admin sign-in is backed by a passkey rather than a password alone. A signature-based detection engine inspects every request for SQL injection, path traversal, command injection, XSS, scanner user-agents, and probing, opens an incident, auto-blocks the source, and emails me a report through a hand-built SMTP client. IP addresses are only ever stored as HMAC hashes, and destructive actions are written to an append-only sealed log, so even clearing the audit log leaves a permanent trace.

Tech Stack

PHPBackend web languageMariaDBMySQL-compatible databaseWebAuthnPasskey authentication standardSecurityHardening, detection, and access controlDockerContainerized environmentsVimeoVideo hosting and livestreaming

Key Metrics

16
Database Tables
4
User Roles
0
Runtime Dependencies
6
Attack Signatures

Details

Category
web
Year
2026
Status
completed
Role
Full-Stack Developer

Key Features

Code-Only Visitor Access

Families enter the access code from their invitation. No account, no password, and they are scoped to exactly one ceremony and its photos.

Livestream & Photo Gallery

Each ceremony streams as a Vimeo embed alongside the photos from that day, with a lightbox and access-checked downloads.

Passkey Admin Login

Admin sign-in is backed by a WebAuthn passkey with a PIN fallback, implemented from scratch with a CBOR decoder, COSE-to-PEM key conversion, and full assertion verification, using no library.

Intrusion Detection

Every request is scanned against six attack categories plus flood and login-burst heuristics, then auto-blocked and reported by email, with every action revertible.

Idempotent CSV Import

The school ceremony planning is imported with delimiter detection and date parsing, previewed with warnings and errors, and upserted so re-importing never duplicates an event.

Role-Based Photo Workspaces

Photographers upload per ceremony, student photographers per date, and admins manage everything, with thumbnails generated on upload and originals kept outside the webroot.

Technical Details

Implementation

Vanilla PHP 8.3 on Apache with MariaDB 10.11 through PDO, no framework, no Composer, no npm, and no build step, because production is Plesk shared hosting updated by a git pull. Application logic is procedural, living in plain snake_case functions across app/*.php, with strict types everywhere. The WebAuthn layer is written from scratch: a CBOR decoder, COSE-to-PEM public key conversion, DER encoding, and full registration and assertion verification, so admin sign-in is backed by a passkey with a PIN fallback. Attack detection runs on every request against six signature categories plus request-rate and login-burst heuristics, records an incident, auto-blocks the source with a revertible action, and sends a report through a hand-built SMTP and MIME client. IP addresses are never stored raw, only as HMAC hashes with a masked label, and PHP session IDs are stored the same way so a leaked database cannot be replayed as a cookie. Photos are thumbnailed with Imagick or GD, stored outside the webroot, and served only behind an access check. The ceremony schedule is imported from the school CSV with delimiter detection, date and time parsing, and an idempotent upsert keyed on a source hash. Local development runs on Docker Compose against the same MariaDB version as production.

Lessons Learned

Writing WebAuthn by hand taught me more about cryptography and binary formats than any tutorial could. I had to decode CBOR, rebuild a COSE key into a PEM public key, and verify a signature over the authenticator data before a single passkey login worked. The bigger lesson was about constraints. Having no dependencies sounds like a limitation, but it forced me to actually understand every layer I was leaning on, from the SMTP handshake to the attestation object. Building for a real audience also changed how I made decisions: this site gets used once, by families, on a day that matters, so a confusing login or a stream that will not play is not a bug I can quietly patch next sprint. That pushed me to make the visitor path as short as it could possibly be, and to over-invest in the security around photos of students.

Design Handbook

Color Palette

Fairy Deep
#002E07Main background, the dark forest the story sits in
Fairy Forest
#146B36Header bar, borders, and success states
Fairy Leaf
#619744Primary accent, buttons, and active tabs
Fairy Vine
#35AA49Bright interactive green and focus rings
Fairy Lime
#BEDA78Soft highlights and muted accent surfaces
Fairy Cream
#FFFBE3Paper panels and body text on the dark ground
Paper Soft
#F6EFC9Secondary paper surfaces and cards
Fairy Gold
#D8A94BWarm fairytale accent and ornaments
Fairy Copper
#B86D42Secondary warm accent
Fairy Black
#010101Deepest ink for text on paper

Typography

Blackmist

Weight: 400
Blackletter display face for headings and the lockup, self-hosted as a single woff2
Once Upon A Time

Bricolage Grotesque

Weight: 300-700
Body text, forms, and all interface copy
Vul je inlogcode in

Patterns & Textures

SVG ornaments and leaf-vine patterns from the school Once Upon A Time identity

Cream paper-texture panels layered over a deep forest-green ground

Storybook framing: warm cream content sitting inside a dark forest

Design Principles

1

One front door: the code on the invitation is all a family needs

2

Dutch throughout, written for parents and grandparents, not for developers

3

The stream comes first, nothing decorative competes with it on a phone

4

Warm cream against a deep green surround, so the ceremony stays the bright thing on screen

Other Projects