mirror of
https://github.com/RoastSlav/quickdrop.git
synced 2026-05-12 23:39:30 -05:00
5.4 KiB
5.4 KiB
QuickDrop — Agent Guide
Self-hosted file sharing: Spring Boot 3.5 + Thymeleaf + SQLite (Flyway) + Tailwind. Java 21.
Build & run
- Build:
./mvnw clean package(Windows:mvnw.cmd clean package). Output:target/quickdrop.jar. - Run:
java -jar target/quickdrop.jar→ http://localhost:8080. - Tailwind CSS:
npm run tw:buildrebuildssrc/main/resources/static/css/tailwind.cssfromtailwind-input.css. - No test suite — verify via manual package + smoke test. Logs at
log/quickdrop.log, DB atdb/quickdrop.db, uploads underfiles/(all auto-created byQuickdropApplication). - Docker:
roastslav/quickdrop:latest, exposes 8080; mount/app/db,/app/files,/app/log.
Architecture (follow the layers)
- Controllers (
controller/):FileViewController,AdminViewController,FileRestController(chunked upload + share APIs),ShareViewController,PasswordViewController,IndexViewController. Thymeleaf views insrc/main/resources/templates/. - Services (
service/) own all business logic. Route every file mutation throughFileServiceso history logging, cache eviction, encryption and notifications fire. - Upload pipeline:
POST /api/file/upload-chunk→AsyncFileMergeServicebuffers chunks →FileEncryptionServiceencrypts when password + encryption flag set →FileServicepersists. Intermediate chunk calls returnnull; frontend must handle. Metadata fields:description,keepIndefinitely,password,hidden,fileSize, folder fields,isPaste. - Download:
/file/download/{uuid}streams with on-the-fly decryption and logsDOWNLOADintofile_history_log( types:UPLOAD,RENEWAL,DOWNLOAD). Share links via/api/file/share/{uuid}issue tokens redeemed at/api/file/download/{uuid}/{token}(decrement/delete). - Storage/model: UUID filenames on disk at
fileStoragePath(from settings);file_entityrow holds metadata + optional BCrypt password hash +encryptedflag + folder +isPaste.
Settings (single-row, id=1)
ApplicationSettingsServiceseeds defaults on startup (max 1 GB, 30-day life,files/logspaths, cron0 0 2 * * *, encryption on, default home = upload, SMTP/Discord off, etc.) and re-schedules cleanup when cron changes. Never insert a second settings row.- Template-level feature flags (file list enabled, app password set, admin button, encryption on, previews, pastebin)
are injected by
GlobalControllerAdvice— read from there; don't duplicate.
Security & interceptors
SecurityConfig: optional whole-app password at/password/login, BCrypt, CSRF cookie, permissive CORS. Session timeout configured inWebConfig.- In-memory admin + file session tokens live in
SessionService(not persisted — restarts invalidate). - Add new protected routes via the right interceptor:
AdminPasswordSetupInterceptor(forces/admin/setupuntil admin pwd exists),AdminPasswordInterceptor(/admin/**+ file history),FilePasswordInterceptor(redirects to/file/password/{uuid}when the file has a password and no valid session token).
Migrations & persistence
- Flyway migrations in
src/main/resources/db/migration/V*__*.sql(currently V1–V20). Baseline-on-migrate is enabled — append a newV{n+1}__...sql, never edit existing files. SQLite dialect isorg.hibernate.community.dialect.SQLiteDialect. - Entities in
entity/, Spring Data repos inrepository/. Use@Transactionalon service methods that mutate.
Pagination, search & cache
- Public list (
/files) and admin dashboard usepage/size/queryparams backed byPage<FileEntity>service methods — reuse them and pass all three params through to templates. - Spring Cache keys are
publicFiles,adminFiles,analytics(seeCacheConfig). Any upload, deletion, renewal, visibility/keep toggle, or download must evict these — copy the@CacheEvictpattern fromFileService.
Scheduling & notifications
@EnableScheduling+ScheduleServicehandles expiry deletion (cron from settings), missing-file row cleanup, share token expiry. Reschedule by calling itsrescheduleCleanup(...)when cron changes.NotificationServicebatches email + Discord webhook events per configured interval; call it fromFileService, not controllers.
i18n
- Bundles:
messages.properties,messages_bg.properties,messages_de.properties. Add every new user-facing string to all three (seedocs/i18n.md). Resolver wired inI18nConfig.