mirror of
https://github.com/imgfloat/server.git
synced 2026-03-22 23:10:38 +00:00
12 KiB
12 KiB
Repository Guidelines
Snapshot & Stack
- Java Spring Boot 3.2 service that backs the Imgfloat livestream overlays, admin UI, and dashboard.
- Uses Spring MVC controllers, WebSocket/STOMP broadcasts (
SimpMessagingTemplate), OAuth2/Twitch authentication, and scheduled/async services (@EnableScheduling,@EnableAsyncinImgfloatApplication). - Media-heavy assets are stored on disk (
assets/,previews/), processed withffmpeg/ffprobe, and surfaced throughstatic/js/ Thymeleaf templates undersrc/main/resources.
Architecture & Modules
src/main/java/dev/kruhlmann/imgfloat/config: Spring configuration beans (upload limits, security overrides, asset storage wiring).controller: REST + view controllers keep endpoints thin and delegate work to services and repositories.service: business logic (asset management, marketplace seeds, git info, Twitch emote syncing, audit logging, cleanup, media optimization, etc.).service.mediacontains ffmpeg helpers and media detection.repository: Spring Data JPA interfaces for the Imgfloat DB (Asset,Channel,ScriptAsset, etc.) and a separate audit DB underrepository.audit.model:dbpackages mirror schema entities;api.request/responsehold DTOs used by controllers.templates: Thymeleaf views (admin.html,broadcast.html,dashboard.html, etc.).static: frontend JavaScript modules (static/js/admin,static/js/broadcast/*,static/js/customAssets.js, etc.), CSS, icons, and broadcast worker scripts. Keep new assets next to the feature they support.src/main/resources/db/migrationanddb/audit: Flyway migration scripts that must stay in sync with the SQLite schemas referenced byIMGFLOAT_DB_PATHandIMGFLOAT_AUDIT_DB_PATH.
Environment & Configuration
-
.envfiles are only loaded when you runmake run; shellingmvn spring-boot:rundirectly requires manually exporting each variable. -
Required environment variables (set them via
.envlocally or through your deployment tooling):Variable Purpose IMGFLOAT_ASSETS_PATHBase filesystem directory for uploaded assets. AssetStorageServicesanitizes broadcaster segments under this path.IMGFLOAT_PREVIEWS_PATHWhere generated previews (PNG thumbnails) go. IMGFLOAT_DB_PATHSQLite file used by the main Flyway-managed schema ( db/migration).IMGFLOAT_AUDIT_DB_PATHSQLite file for audit logs ( db/audit) and session storage.IMGFLOAT_INITIAL_TWITCH_USERNAME_SYSADMINTwitch login that becomes the initial sysadmin and can manage all channels. IMGFLOAT_GITHUB_CLIENT_OWNER/REPO/VERSIONGitHub release coordinates used by GithubReleaseServiceto build download links for the client bundle.IMGFLOAT_TOKEN_ENCRYPTION_KEYBase64/Base64URL-encoded 32-byte key used by Spring Security to encrypt OAuth tokens at rest. SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE/MAX_REQUEST_SIZEControl upload limits (defaults to 10MB in Makefile, also read byUploadLimitsConfigwhich exposesuploadLimitBytesto controllers/services).TWITCH_CLIENT_ID&TWITCH_CLIENT_SECRETUsed by Spring Security’s OAuth2 client registration in application.yml. -
Optional/operational variables:
Variable Purpose IMGFLOAT_COMMIT_URL_PREFIXEnables the commit chip in the UI ( GitInfoService) when paired withgit-commit-id-plugin.IMGFLOAT_DOCS_URLBase URL for documentation links rendered in templates. IMGFLOAT_IS_STAGINGSet to 1to surface a staging banner across non-broadcast pages. Defaults to0.IMGFLOAT_MARKETPLACE_SCRIPTS_PATHDirectory containing marketplace seed directories ( MarketplaceScriptSeedLoaderreads metadata, source.js, logo, attachments).doc/marketplace-scriptsholds examples.IMGFLOAT_SYSADMIN_CHANNEL_ACCESS_ENABLEDToggle to let sysadmins manage every channel without being added as an admin. TWITCH_REDIRECT_URIOverrides the default redirect URI for OAuth ( {baseUrl}/login/oauth2/code/twitch).IMGFLOAT_TOKEN_ENCRYPTION_PREVIOUS_KEYSComma-delimited base64 keys to decrypt tokens created before rotating IMGFLOAT_TOKEN_ENCRYPTION_KEY. -
AssetStorageServicewill fall back to system temp dirs (java.io.tmpdir/imgfloat-assets&-previews) ifIMGFLOAT_ASSETS_PATH/PREVIEWS_PATHare unset, but storing data on persistent storage is required for production. -
UploadLimitsConfigdefaults to 50MB/100MB for tests if the environment properties are absent; production should honor thespring.servlet.multipart.*values you expose.
Build, Run, & Watch
make build/mvn compile: compile the server.make run: sources.env(if present) and runsmvn spring-boot:run. Use this for local dev; hot reload works viaspring-devtools.make watch: compiles continuously usingentr(sleep loop watchessrc/main). Requiresentrinstalled and you must refresh the browser manually after the compile succeeds.make test/mvn test: run the JUnit 5 + Mockito suite (including integration tests that spin up the Spring context). Run this before pushing changes that touch controllers, services, or persistence logic.make package/mvn clean package: clean build that packages the runnable JAR.springdoc-openapiis on the classpath; the automated Swagger UI can be helpful for understanding the available REST endpoints.
Database & Persistence
- The main SQLite DB (
IMGFLOAT_DB_PATH) holds channel, user, asset, marketplace, and settings tables. Flyway (configured inapplication.yml) runs migrations fromclasspath:db/migration. Don’t bypass these migration scripts when updating schemas. - Audit logs live in the separate
IMGFLOAT_AUDIT_DB_PATHwith migrations undersrc/main/resources/db/audit. The audit DB also stores Spring Session tables;spring.session.jdbc.initialize-schemais set tonever, so the Flyway scripts must include the session table definitions. AuditLogServicesanitizes log entries before persisting them and is used by controllers such asAuditLogApiControllerandAccountService.
Media & Asset Handling
ChannelDirectoryServicehandles uploads. It enforcesuploadLimitBytes(derived fromspring.servlet.multipart.max-file-size), normalizes broadcaster names, and records audit events viaAuditLogService.- Uploaded assets go through
MediaDetectionService,MediaOptimizationService, andAssetStorageServicewhich writes toIMGFLOAT_ASSETS_PATH. Previews (PNGs) are written toIMGFLOAT_PREVIEWS_PATH. AssetStorageServicesanitizes broadcaster segments (sanitizeUserSegment) to avoid traversal and auto-creates directories. When deleting,AssetCleanupServiceruns asynchronously after startup to remove orphan files that are not referenced by any DB record.- Media processing uses
ffmpeg/ffprobeviaFfmpegService. Make sure those binaries are available on the system; otherwise video/preview transcodes and APNG → GIF conversions will fail with warnings logged fromFfmpegService.
Marketplace Scripts & Allowed Domains
- Marketplace seeds live under the path configured by
IMGFLOAT_MARKETPLACE_SCRIPTS_PATH. Each subfolder is a listing identifier and must containmetadata.jsonandsource.js. Optional files:logo.png(renders as the marketplace badge) andattachments/for extra files (filenames must be unique per script). metadata.jsoncombinesname, optionaldescription, optionalbroadcaster, and optionalallowedDomains. Allowed domains control thefetchsandbox in the broadcast worker and are normalized viaChannelDirectoryService.normalizeAllowedDomains. Valid entries are hostname or hostname+port (regex^[a-z0-9.-]+(?::[0-9]{1,5})?$), de-duplicated, lower-cased, and capped at 32 entries per script.- Seeds are cached at startup;
MarketplaceScriptSeedLoaderexposeslistEntriesForQueryandfindByIdso the frontend can show the marketplace catalog without hitting Twitch/SevenTV endpoints. - Example scripts are shipped under
doc/marketplace-scripts/.
Security, Auth, & Tokens
- Spring Security OAuth2 login is configured in
application.ymlunderspring.security.oauth2.client. Twitch is the only configured provider; scopes includeuser:read:emailandmoderation:read. - OAuth tokens are encrypted using
IMGFLOAT_TOKEN_ENCRYPTION_KEY; rotate keys by settingIMGFLOAT_TOKEN_ENCRYPTION_PREVIOUS_KEYSto a comma list of old keys (oldest last) before swapping in a newIMGFLOAT_TOKEN_ENCRYPTION_KEY. IMGFLOAT_INITIAL_TWITCH_USERNAME_SYSADMINseeds the first sysadmin; subsequent sysadmins can be managed via the UI or API. To allow sysadmins to hop between channels without being channel admins, setIMGFLOAT_SYSADMIN_CHANNEL_ACCESS_ENABLED=true.GitInfoServicewill expose a commit link ifIMGFLOAT_COMMIT_URL_PREFIXis configured andgit.propertiesis present (generated by thegit-commit-id-plugin), otherwise it falls back to runninggitdirectly.GithubReleaseServicefails fast whenIMGFLOAT_GITHUB_CLIENT_OWNER,IMGFLOAT_GITHUB_CLIENT_REPO, orIMGFLOAT_GITHUB_CLIENT_VERSIONare missing; these powers the download link in the UI.
Frontend Notes
- Broadcast client code lives in
src/main/resources/static/js/broadcast/(renderer, workers, runtime helpers). When editing overlay scripts, keep worker changes inscript-worker.jsand keep main page logic inrenderer.js. - Admin/dashboard JS modules (
customAssets.js,settings.js, etc.) are plain ES modules bundled through Thymeleaf templates, so keep related CSS/HTML understatic/cssandtemplates. - Templates render dynamic data via controllers such as
ViewController, which also injectsuploadLimitBytes, version info (VersionService), and feature flags (staging banner, docs URL, commit chip wrapped inGitInfoService/GithubReleaseServicevalues).
Testing & Validation
- Tests are under
src/test/java/dev/kruhlmann/imgfloat. Controller integration tests (e.g.,ChannelApiIntegrationTest) boot up the application context—mock external services carefully or rely on the in-memory SQLite test DB created from the Flyway scripts. - Service unit tests (e.g.,
ChannelDirectoryServiceTest) cover asset normalization, allowed domain semantics, and marketplace seed behavior. Add targeted tests for new service logic, API validations, or asset handling (uploads, attachments, downloads). - Run
make testbefore shipping changes; it also generates JaCoCo reports via the Maven plugin.
Coding Style & Contributions
- Java code uses 4-space indentation,
UpperCamelCasefor types,lowerCamelCasefor fields/methods, andUPPER_SNAKE_CASEfor constants. DTOs often userecords when immutability is feasible (ScriptMarketplaceEntry,MarketplaceScriptSeedLoader.SeedScript, etc.). - Prefer constructor injection for Spring components. Controllers should remain thin and delegate to service-layer beans; services orchestrate repositories, asset storage, storage cleanup, Git/Twitch helpers, and messaging (websockets/events).
- Keep assets close to their feature (e.g.,
static/js/broadcast/for overlay code,templates/for the Thymeleaf view referencing that script). - Avoid path traversal by relying on existing sanitizers (
AssetStorageService.sanitizeUserSegment). When adding new file paths, reusesafeJoin/sanitizeUserSegmentpatterns. - When syncing marketplace favorites or script attachments, obey
ChannelDirectoryService.loadScriptAttachmentssemantics—attachments are stored inscript_asset_attachmentrecords and are cleaned up when orphaned.
Operational Tips
AssetCleanupServiceruns asynchronously once per startup (afterApplicationReadyEvent) and purges disk files whose IDs are not referenced by any DB row; do not rely on manual cleanup unless debugging.VersionServicelooks forMETA-INF/maven/dev.kruhlmann/imgfloat/pom.propertiesfirst, falls back to parsingpom.xml(useful when running from source), and throws if no version is available—keep yourpom.versionaccurate for release builds.EmoteSyncScheduler,SevenTvEmoteService,TwitchEmoteService, andTwitchAppAccessTokenServiceorchestrate Twitch/7TV emote catalogs and should be aware of scheduling constraints if you modify emote ingestion.- Static files, marketplace metadata, and assets are best tested locally by running
make runwith the appropriate env variables and by refreshing the admin/broadcast UI manually.