Simple personal certificate management and automated renewal reminders. https://certified.env0.nl
Find a file
Joël van de Wouw ad2a78a989 Replace email-only sharing with secure share pages
Sharing certificates now creates a Share: a public page behind an
unguessable token where the recipient views and downloads the selected
certificates individually or as a ZIP, instead of receiving links or
attachments by email.

- Share model + certificate_share pivot; expiration (1/7/30 days),
  optional password (encrypted so the owner can re-view it), revocation,
  and open tracking
- Public routes under shared/{token}: password unlock gate (throttled,
  session-scoped), per-certificate download, on-the-fly ZIP that is
  AES-256 encrypted when the share has a password, friendly 410 page
  for expired/revoked links
- Share modal on the certificates index now creates the page and
  reveals a copyable link + password; optional transactional email
  (ShareCreatedMail) still sends the link to a recipient
- New Shares page in the sidebar to copy links, look up passwords,
  revoke, and delete shares
- Old signed-URL controller and both attachment/link mailables removed;
  Dutch translations updated; Pest coverage for the full lifecycle

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 15:38:43 +02:00
.claude Initial commit 2026-07-12 14:44:58 +02:00
.github Initial commit 2026-07-12 14:44:58 +02:00
app Replace email-only sharing with secure share pages 2026-07-12 15:38:43 +02:00
bootstrap Initial commit 2026-07-12 14:44:58 +02:00
config Initial commit 2026-07-12 14:44:58 +02:00
database Replace email-only sharing with secure share pages 2026-07-12 15:38:43 +02:00
lang Replace email-only sharing with secure share pages 2026-07-12 15:38:43 +02:00
public Initial commit 2026-07-12 14:44:58 +02:00
resources Replace email-only sharing with secure share pages 2026-07-12 15:38:43 +02:00
routes Replace email-only sharing with secure share pages 2026-07-12 15:38:43 +02:00
storage Initial commit 2026-07-12 14:44:58 +02:00
tests Replace email-only sharing with secure share pages 2026-07-12 15:38:43 +02:00
.editorconfig Initial commit 2026-07-12 14:44:58 +02:00
.env.example Initial commit 2026-07-12 14:44:58 +02:00
.gitattributes Initial commit 2026-07-12 14:44:58 +02:00
.gitignore Initial commit 2026-07-12 14:44:58 +02:00
.npmrc Initial commit 2026-07-12 14:44:58 +02:00
artisan Initial commit 2026-07-12 14:44:58 +02:00
boost.json Initial commit 2026-07-12 14:44:58 +02:00
composer.json Initial commit 2026-07-12 14:44:58 +02:00
composer.lock Initial commit 2026-07-12 14:44:58 +02:00
package-lock.json Initial commit 2026-07-12 14:44:58 +02:00
package.json Initial commit 2026-07-12 14:44:58 +02:00
phpstan.neon Initial commit 2026-07-12 14:44:58 +02:00
phpunit.xml Initial commit 2026-07-12 14:44:58 +02:00
pint.json Initial commit 2026-07-12 14:44:58 +02:00
README.md Initial commit 2026-07-12 14:44:58 +02:00
vite.config.js Initial commit 2026-07-12 14:44:58 +02:00

Certified

Certified is a self-hosted certificate manager built on Laravel 13, Livewire 4, and Flux. It helps you keep track of certificates (diplomas, licenses, compliance documents, etc.), organize them into categories, and get notified before they expire.

Features

  • Certificate management — upload, edit, and download certificates, organized by category
  • OCR extraction — automatically read certificate details on upload via a pluggable OCR backend (Klippa, Mistral, or none)
  • Expiry notifications — email alerts when a certificate is expiring soon or has expired
  • Secure sharing — share a certificate with an external recipient via a signed URL, without requiring them to log in
  • Multi-language support

Stack

  • Laravel 13 (Octane-ready)
  • Livewire 4 + Flux UI
  • Tailwind CSS 4 / Vite
  • Laravel Fortify for authentication

Getting started

composer install
npm install

cp .env.example .env
php artisan key:generate

php artisan migrate

npm run dev
# in another terminal
php artisan serve

Testing

composer test

OCR providers

The OCR backend is configurable via app/Ocr. Available providers: NoneProvider (disabled), KlippaProvider, and MistralProvider. Configure credentials in .env.