Veilig delen van vertrouwelijke informatie

Genereer een beveiligde link
Vul uw naam in.
Vul een geldig e-mailadres in.
Vul de naam van de ontvanger in.
Vul een geldig e-mailadres in.
0/30
Toegangscode is verplicht (minimaal 4 tekens).
De toegangscode wordt nooit verstuurd via e-mail. Stuur deze separaat aan de ontvanger (bijv. via telefoon of chat).
Secret ophalen
Contact

Heeft u vragen, verbeteringen en/of opmerkingen over See It Once? Vul dan onderstaand contactformulier in. Wij nemen zo spoedig mogelijk contact met u op.

Vul uw naam in.
Vul een geldig e-mailadres in.
0/1000
Vul een bericht in (minimaal 10 tekens).
Technische werking
Architectuur
See It Once bestaat uit drie Docker-containers die via een intern netwerk communiceren: een Nginx-frontend die de interface serveert, een Node.js/Express-backend die de REST API aanbiedt, en Redis als in-memory datastore met ingebouwde TTL-ondersteuning. Alle API-verzoeken van de browser lopen via de Nginx-proxy naar de backend — de browser communiceert nooit rechtstreeks met Node.js.
Twee-staps verificatieflow
Het aanmaken van een secret verloopt via een bevestigde twee-staps flow:

Stap 1 — Aanmaken De verzender vult naam, e-mailadres, naam en e-mailadres van de ontvanger, de inhoud en een verplichte toegangscode in. De browser versleutelt het secret lokaal met PBKDF2 + AES-256-GCM op basis van de toegangscode, vóórdat er iets naar de server wordt gestuurd. De backend slaat het versleutelde secret tijdelijk op als pending in Redis (TTL: 1 uur) en stuurt een bevestigingsmail naar de verzender.

Stap 2 — Bevestiging De verzender klikt op de bevestigingsknop in de e-mail. De backend verifieert het eenmalige token, activeert het secret definitief in Redis en stuurt een notificatiemail naar de ontvanger met uitsluitend het id — zonder sleutel of toegangscode.

Stap 3 — Ophalen De ontvanger klikt op de link in de notificatiemail, voert de toegangscode in die de verzender separaat heeft gecommuniceerd (telefoon, chat) en de browser ontsleutelt het secret volledig lokaal. Daarna wordt het secret permanent van de server verwijderd.
Verplichte toegangscode (versleutelingslaag)
Een toegangscode is altijd verplicht. De browser versleutelt het secret vóór verzending via PBKDF2 (200.000 iteraties, SHA-256) gevolgd door AES-256-GCM. De toegangscode verlaat de browser nooit en wordt nergens opgeslagen — ook niet door de server. De ontvanger kan het secret alleen ontsleutelen met de toegangscode die de verzender separaat communiceert. Zelfs de server-operator kan de inhoud niet inzien.
Verzendersverificatie via e-mail
Voordat de ontvanger een notificatie krijgt, moet de verzender de actie bevestigen via een eenmalige bevestigingslink die naar zijn eigen e-mailadres wordt gestuurd. Dit voorkomt misbruik: een bot of onbekende bezoeker die het formulier invult kan de flow niet voltooien zonder toegang tot het opgegeven e-mailaccount. De bevestigingslink bevat een willekeurig token van 32 bytes en is 1 uur geldig en eenmalig bruikbaar.
Notificatiemail naar ontvanger
De notificatiemail aan de ontvanger bevat uitsluitend het id van het secret — geen sleutel, geen toegangscode. Onderschepping van de e-mail geeft een aanvaller niets bruikbaars: zonder de toegangscode (die via een apart kanaal wordt gecommuniceerd) is het secret niet te ontsleutelen.
Foutieve toegangscodepogingen
Bij een verkeerde toegangscode meldt de browser dit via POST /api/secret/{id}/fail. Na 3 mislukte pogingen verwijdert de backend het secret definitief, ongeacht de resterende TTL.
Automatisch verlopen & datapersistentie
Niet-geopende secrets worden automatisch verwijderd door Redis na de ingestelde vervaltijd (15 minuten tot 7 dagen). De backend luistert via een aparte subscriber-verbinding op Redis keyspace-events; zodra een secret verloopt, worden de statistieken direct bijgewerkt.

Redis is geconfigureerd met AOF-persistentie (appendfsync everysec) en aanvullende RDB-snapshots. Bij een herstart of update blijven alle nog-niet-verlopen secrets en statistieken bewaard — maximaal 1 seconde dataverlies bij een onverwachte crash.
Invoervalidatie
Elk API-endpoint valideert inkomende data via Zod-schema's vóórdat enige businesslogica wordt uitgevoerd. Ontbrekende velden, verkeerde typen of waarden buiten de toegestane grenzen worden direct afgewezen met een duidelijke foutmelding. URL-parameters zoals id en key worden gefilterd op toegestane tekens ([a-f0-9]) voordat ze Redis ingaan.
Beveiliging & rate limiting
De backend zet via Helmet automatisch HTTP-beveiligingsheaders (X-Frame-Options, X-Content-Type-Options, Referrer-Policy e.a.). Verzoeken worden op drie niveaus beperkt via express-rate-limit:

· Globaal: max 100 req/min per IP op alle API-routes
· Secret aanmaken: max 20 req/min per IP
· Contactformulier: max 3 req/10 min per IP

De server retourneert bij onbekende routes altijd een JSON-404 en bij onverwachte fouten een JSON-500 — stack traces worden nooit naar de client gestuurd.
Wat de server nooit ziet
De server ontvangt nooit de decryptiesleutel, het extra wachtwoord of de leesbare tekst van het secret. De enige manier om een secret te lezen is via de exacte link met de juiste key — en die link is na één gebruik permanent ongeldig.
Dataflow samengevat
1 · Aanmaken Browser versleutelt secret lokaal (PBKDF2 + AES-256-GCM) → Zod valideert invoer → backend slaat pending op in Redis (1 uur TTL) → bevestigingsmail naar verzender

2 · Bevestigen Verzender klikt bevestigingslink → token geverifieerd & verwijderd → secret geactiveerd in Redis met gekozen TTL → notificatiemail naar ontvanger (alleen id, geen sleutel)

3 · Ophalen Ontvanger opent link (alleen id) → voert toegangscode in → browser ontsleutelt lokaal → secret getoond → backend verwijdert secret permanent uit Redis
🔒
AES-256-GCM encryptie
De decryptiesleutel is uitsluitend in de link aanwezig, nooit op de server opgeslagen.
Eenmalige toegang
Bericht wordt direct verwijderd nadat het eenmaal gelezen is.
Automatisch verlopen
Ongelezen berichten worden automatisch verwijderd na de gekozen tijd.
🛡
Lokaal gehost en privacygericht
Gehost in Nederland. Geen logging, geen tracking.