Commit Graph
6 Commits
Author SHA1 Message Date
surtic86andClaude Opus 5 4530298398 Cut over-engineering found by a repo-wide audit
docker / test (8.5) (push) Successful in 3m10s
linter / quality (push) Successful in 1m5s
tests / ci (8.5) (push) Successful in 3m9s
docker / build-and-push (push) Successful in 21m5s
docker / release (push) Skipped
- Config: auth, services, logging, queue and database only repeated the
  framework's own files and are gone; the others keep only the keys that
  differ (app version, cache serializable_classes, session cookie name,
  Markdown mail theme, the shares disk, three Octane values, Livewire's
  pagination theme and payload guards).
- Email verification is removed: User never implemented MustVerifyEmail,
  so it was never enforced, and SealShare has a single admin and no
  registration. CreateNewUser goes with it.
- FileEncryptionService::encryptFile() and generateSalt() were only used
  by tests; tests build files with encryptTestFile() in tests/Pest.php.
- The expiration options are defined once, as Share::EXPIRATIONS. "30 Days"
  now lasts 30 days instead of a calendar month, and Admin settings only
  save a default expiration that is one of the options.
- One-caller helpers are inlined, the uploader reads chunk responses with
  XHR's responseType, and starter-kit leftovers are removed.
- Docker: PHP reads the PHP_* limits from the environment itself
  (${VAR:-default} in uploads.ini); both entrypoints stop writing the ini.
  docker-compose.yml shares the app and scheduler variables through one
  anchor. The dev image installs gd for the screenshot publisher and fake
  test images.
- Development runs in Docker only: the composer dev script, concurrently,
  laravel/pail, laravel/sail, autoprefixer and the shell-quote override
  are gone.
- phpunit.xml forces the test environment with <server> entries, so tests
  run in the dev container no longer use its real database.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 23:14:33 +02:00
surtic86andClaude Opus 5 026912f98a Run development on the production stack with a Vite dev server
docker-compose.dev.yml extends docker-compose.yml, so development runs the
scheduler too, and takes its settings from .env, which selects the file
through COMPOSE_FILE. The dev image is a stage of the Dockerfile and shares
the production image's PHP extensions; the app listens on port 80 as in
production.

A vite service runs the dev server with hot reload. No ports are published:
OrbStack serves https://app.sealshare.orb.local and
https://vite.sealshare.orb.local, with the ports pinned by label. Without
OrbStack, docker-compose.ports.yml publishes APP_PORT and VITE_PORT on
127.0.0.1. vite.config.js takes the dev server's address from
VITE_DEV_SERVER_URL and listens on IPv4 and IPv6, as OrbStack's proxy
connects over either.

Each start installs Composer packages, clears caches, migrates and links
storage.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 22:17:36 +02:00
Andreas Reinhold / reiniandClaude Opus 5 c1906d2009 Stop the SQLite volume from hiding new migrations
Uploads on share.kadenpartner.ch failed with 409 on every chunk after
the update to 2.1. The example docker-compose.yml mounts the SQLite
volume over all of /app/database. Docker fills a volume from the image
only when it is created, so the container kept the 2.0 migrations and
never saw the 2.1 one. share_files.uploaded_chunks was never created,
so the chunk endpoint read null and answered 409. SQLite takes the
unknown "completed_at" in whereNull() as a string, so nothing failed
earlier.

- The image keeps a copy of its migrations in docker/migrations. On
  startup the entrypoint adds the ones missing from database/migrations
  before migrating, so installs with the old mount recover by pulling
  the new image.
- docker-compose.example.yml and docker-compose.yml mount
  sealshare_database at /app/database/sqlite and set DB_DATABASE to the
  file in it. An existing volume can be moved there without losing
  data: its database.sqlite lands at exactly that path.
- Tested with a locally built image: a volume created by 2.0.1 with the
  old mount gets the migration once (not again on restart) and keeps
  its settings; the same volume moved to the new path keeps its data;
  a fresh volume with the new layout starts healthy.
- README and CHANGELOG (Unreleased) describe the new path and how to
  switch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 10:53:27 +02:00
Andreas Reinhold / reiniandClaude Opus 5 40e35bab0e Encrypt uploads in the browser and send them in chunks
A 6 GB upload kept a customer waiting long after its progress bar
reached 100%. The server wrote every upload three times: PHP's
temporary file, Livewire's copy of it ("Processing files...") and the
encrypted file ("Create Share Link"), each a full rewrite of a slow
disk. The unencrypted copy also stayed behind in livewire-tmp.

Now the uploader's browser encrypts each file in 16 MB chunks with
WebCrypto and PUTs them one at a time; the server checks each chunk in
memory and writes it once, already encrypted. Creating the share only
wraps its key and saves the options. A 200 MB upload through the
Docker image took 2.8 s, and its download matched byte for byte.

- SEALCHK2: a 19-byte header (chunk size, 7-byte nonce prefix), then
  ciphertext and tag per chunk. Each nonce holds the chunk index and a
  last-chunk flag (the STREAM construction), so cut or reordered files
  fail to decrypt. SEALCHK1 and the single-block format still read.
- Envelope encryption: one random key per share. With a password it is
  wrapped with Argon2id (sodium, libsodium's interactive limits) in
  shares.wrapped_key, which names its parameters. Password shares from
  before keep their PBKDF2-derived key.
- The upload page registers each selection with FileUploader into a
  pending share of its own, lists the files with their progress, retries
  a failed chunk after 1-16 s, then offers Retry; Remove and Cancel
  abort. UploadChunkController only accepts chunks from the session that
  started the share: a repeat is acknowledged, a skip gets 409 with the
  count stored. Chunks go out as Blobs, which Chromium sends about eight
  times faster than ArrayBuffers.
- Uploads need a secure context: over plain HTTP the page says HTTPS is
  needed and takes no files. The Docker image gains AUTO_HTTPS, which
  serves Let's Encrypt on 443 for SERVER_NAME and redirects 80; without
  it the container stays on HTTP 80 behind a proxy. docker/Caddyfile was
  never loaded and is gone; docker/healthcheck.sh covers both modes.
- "Download all" streams the ZIP with maennchen/zipstream-php (STORE,
  ZIP64) instead of decrypting whole files into memory and writing the
  archive unencrypted to /tmp.
- Pending shares count towards the quota, stay out of the admin
  dashboard and 404 everywhere else. shares:cleanup deletes uploads idle
  for 4 hours and Livewire temporary files older than that.
- PHP's upload limits no longer cap the admin's max file size and
  default to 64M; LIVEWIRE_MAX_UPLOAD_TIME is gone and
  UPLOAD_CHUNK_SIZE_MB is new.
- Tests cover the format, key wrapping, registration limits, the chunk
  endpoint's answers, completing a share, the streamed ZIP, cleanup,
  and in Chromium a real chunked upload and the HTTPS warning; the
  selected-files overflow test runs again. README, website, CHANGELOG
  and .ai/rules follow.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 20:49:17 +02:00
Andreas Reinhold / reiniandClaude Opus 5 c4a17b65c8 Move SealShare onto Livewire Material
Replaces maryUI and daisyUI with nonameweb/livewire-material: the Vibrant
indigo scheme, a system/light/dark theme under sealshare-theme, one top
app bar with the account menu, the upload drop zone and link-ready
moments, M3 fields, dialogs instead of wire:confirm, snackbars instead of
flashed messages, a sortable admin table, and the starter-kit cleanup.
Docker builds assets after Composer; CI drops the Flux step.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
2026-09-13 10:49:38 +02:00
surtic86andClaude Opus 4.6 e37b322dde Add SealShare file sharing application with encryption, branding, auth, Docker, and Octane support
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 11:43:20 +01:00