package handlers import ( "log/slog" "net/http" "warpbox.dev/backend/libs/config" "warpbox.dev/backend/libs/services" "warpbox.dev/backend/libs/web" ) type App struct { cfg config.Config logger *slog.Logger renderer *web.Renderer uploadService *services.UploadService authService *services.AuthService settingsService *services.SettingsService reactionService *services.ReactionService banService *services.BanService rateLimiter *rateLimiter uploadGroups *uploadGrouper } func NewApp(cfg config.Config, logger *slog.Logger, renderer *web.Renderer, uploadService *services.UploadService, authService *services.AuthService, settingsService *services.SettingsService, reactionService *services.ReactionService, banService *services.BanService) *App { return &App{ cfg: cfg, logger: logger, renderer: renderer, uploadService: uploadService, authService: authService, settingsService: settingsService, reactionService: reactionService, banService: banService, rateLimiter: newRateLimiter(), uploadGroups: newUploadGrouper(), } } func (a *App) renderPage(w http.ResponseWriter, r *http.Request, status int, page string, data web.PageData) { if data.CurrentUser == nil { data.CurrentUser = a.currentPublicUser(r) } data.CSRFToken = a.csrfToken(w, r) a.renderer.Render(w, status, page, data) } func (a *App) RegisterRoutes(mux *http.ServeMux) { mux.HandleFunc("GET /", a.Home) mux.HandleFunc("GET /api", a.APIDocs) mux.HandleFunc("GET /register", a.Register) mux.HandleFunc("POST /register", a.RegisterPost) mux.HandleFunc("GET /login", a.Login) mux.HandleFunc("POST /login", a.LoginPost) mux.HandleFunc("POST /logout", a.Logout) mux.HandleFunc("GET /invite/{token}", a.Invite) mux.HandleFunc("POST /invite/{token}", a.InvitePost) mux.HandleFunc("GET /app", a.Dashboard) mux.HandleFunc("POST /app/collections", a.CreateCollection) mux.HandleFunc("POST /app/boxes/{boxID}/rename", a.RenameUserBox) mux.HandleFunc("POST /app/boxes/{boxID}/move", a.MoveUserBox) mux.HandleFunc("POST /app/boxes/{boxID}/delete", a.DeleteUserBox) mux.HandleFunc("GET /account/settings", a.AccountSettings) mux.HandleFunc("POST /account/password", a.ChangePassword) mux.HandleFunc("POST /account/tokens", a.CreateUserToken) mux.HandleFunc("POST /account/tokens/{tokenID}/delete", a.DeleteUserToken) mux.HandleFunc("GET /admin/login", a.AdminLogin) mux.HandleFunc("POST /admin/login", a.AdminLoginPost) mux.HandleFunc("POST /admin/logout", a.AdminLogout) mux.HandleFunc("GET /admin", a.AdminDashboard) mux.HandleFunc("GET /admin/files", a.AdminFiles) mux.HandleFunc("GET /admin/users", a.AdminUsers) mux.HandleFunc("GET /admin/users/{userID}/edit", a.AdminEditUser) mux.HandleFunc("GET /admin/settings", a.AdminSettings) mux.HandleFunc("POST /admin/settings", a.AdminSettingsPost) mux.HandleFunc("GET /admin/logs", a.AdminLogs) mux.HandleFunc("GET /admin/bans", a.AdminBans) mux.HandleFunc("POST /admin/bans", a.AdminCreateBan) mux.HandleFunc("POST /admin/bans/{banID}/unban", a.AdminUnban) mux.HandleFunc("POST /admin/bans/settings", a.AdminBanSettingsPost) mux.HandleFunc("POST /admin/bans/rules", a.AdminBanRulesPost) mux.HandleFunc("POST /admin/bans/rules/{ruleID}/delete", a.AdminBanRuleDelete) mux.HandleFunc("GET /admin/storage", a.AdminStorage) mux.HandleFunc("GET /admin/storage/new", a.AdminNewStorage) mux.HandleFunc("GET /admin/storage/new/s3", a.AdminNewStorageProvider) mux.HandleFunc("GET /admin/storage/new/contabo", a.AdminNewStorageProvider) mux.HandleFunc("GET /admin/storage/new/sftp", a.AdminNewStorageProvider) mux.HandleFunc("GET /admin/storage/new/smb", a.AdminNewStorageProvider) mux.HandleFunc("GET /admin/storage/new/webdav", a.AdminNewStorageProvider) mux.HandleFunc("POST /admin/storage/new/s3", a.AdminCreateStorage) mux.HandleFunc("POST /admin/storage/new/contabo", a.AdminCreateStorage) mux.HandleFunc("POST /admin/storage/new/sftp", a.AdminCreateStorage) mux.HandleFunc("POST /admin/storage/new/smb", a.AdminCreateStorage) mux.HandleFunc("POST /admin/storage/new/webdav", a.AdminCreateStorage) mux.HandleFunc("GET /admin/storage/{backendID}/edit", a.AdminEditStorageForm) mux.HandleFunc("GET /admin/storage/{backendID}/tests", a.AdminStorageTests) mux.HandleFunc("GET /admin/storage/{backendID}/tests.json", a.AdminStorageTestsJSON) mux.HandleFunc("POST /admin/storage/{backendID}/edit", a.AdminEditStorage) mux.HandleFunc("POST /admin/storage/{backendID}/test", a.AdminTestStorage) mux.HandleFunc("POST /admin/storage/{backendID}/speed-test", a.AdminStartStorageSpeedTest) mux.HandleFunc("POST /admin/storage/{backendID}/delete", a.AdminDeleteStorage) mux.HandleFunc("POST /admin/storage/jobs/cleanup", a.AdminRunStorageCleanup) mux.HandleFunc("POST /admin/storage/jobs/thumbnails", a.AdminRunStorageThumbnails) mux.HandleFunc("POST /admin/storage/jobs/verify", a.AdminVerifyStorageBackends) mux.HandleFunc("POST /admin/invites", a.AdminCreateInvite) mux.HandleFunc("POST /admin/users/{userID}/disable", a.AdminDisableUser) mux.HandleFunc("POST /admin/users/{userID}/reset", a.AdminResetUser) mux.HandleFunc("POST /admin/users/{userID}/quota", a.AdminUpdateUserQuota) mux.HandleFunc("POST /admin/users/{userID}/edit", a.AdminUpdateUser) mux.HandleFunc("POST /admin/users/{userID}/policy", a.AdminUpdateUserPolicy) mux.HandleFunc("POST /admin/users/{userID}/storage", a.AdminUpdateUserStorage) mux.HandleFunc("GET /admin/boxes/{boxID}/view", a.AdminViewBox) mux.HandleFunc("GET /admin/boxes/{boxID}/edit", a.AdminEditBox) mux.HandleFunc("POST /admin/boxes/{boxID}/edit", a.AdminUpdateBox) mux.HandleFunc("POST /admin/boxes/{boxID}/files/{fileID}/delete", a.AdminDeleteBoxFile) mux.HandleFunc("POST /admin/boxes/{boxID}/delete", a.AdminDeleteBox) mux.HandleFunc("GET /d/{boxID}", a.DownloadPage) mux.HandleFunc("GET /d/{boxID}/deleted", a.ManageDeleted) mux.HandleFunc("GET /d/{boxID}/manage/{token}", a.ManageBox) mux.HandleFunc("POST /d/{boxID}/manage/{token}/delete", a.ManageDeleteBox) // GET variant so ShareX (which issues a GET to the configured DeletionURL) // can delete a box via its secret one-time delete token. mux.HandleFunc("GET /d/{boxID}/manage/{token}/delete", a.ManageDeleteBox) mux.HandleFunc("POST /d/{boxID}/unlock", a.UnlockBox) mux.HandleFunc("GET /d/{boxID}/zip", a.DownloadZip) mux.HandleFunc("POST /d/{boxID}/f/{fileID}/react", a.ReactToFile) mux.HandleFunc("GET /d/{boxID}/f/{fileID}", a.DownloadFile) mux.HandleFunc("GET /d/{boxID}/f/{fileID}/download", a.DownloadFileContent) mux.HandleFunc("GET /d/{boxID}/thumb/{fileID}", a.Thumbnail) mux.HandleFunc("GET /d/{boxID}/og-image.jpg", a.BoxOGImage) mux.HandleFunc("GET /health", a.Health) mux.HandleFunc("GET /healthz", a.Health) mux.HandleFunc("GET /api/v1/health", a.Health) mux.HandleFunc("GET /api/v1/sharex/warpbox-anonymous.sxcu", a.ShareXAnonymousConfig) mux.HandleFunc("GET /api/v1/schemas/upload-request.json", a.UploadRequestSchema) mux.HandleFunc("GET /api/v1/schemas/upload-response.json", a.UploadResponseSchema) mux.HandleFunc("POST /api/v1/upload", a.Upload) mux.HandleFunc("GET /emoji/{pack}/{file}", a.EmojiAsset) mux.Handle("GET /static/", a.Static()) }