package handlers import ( "net/http" "warpbox.dev/backend/libs/helpers" "warpbox.dev/backend/libs/web" ) type apiDocsData struct { BaseURL string UploadURL string HealthURL string RequestSchemaURL string ResponseSchemaURL string ShareXExamplePath string ShareXExampleURL string ShareXDownloadURL string ShareXFileFieldName string ShareXGroupWindow string } func (a *App) APIDocs(w http.ResponseWriter, r *http.Request) { a.renderPage(w, r, http.StatusOK, "api.html", web.PageData{ Title: "API documentation", Description: "Curl and ShareX upload examples for Warpbox.", Data: apiDocsData{ BaseURL: a.cfg.BaseURL, UploadURL: a.cfg.BaseURL + "/api/v1/upload", HealthURL: a.cfg.BaseURL + "/api/v1/health", RequestSchemaURL: a.cfg.BaseURL + "/api/v1/schemas/upload-request.json", ResponseSchemaURL: a.cfg.BaseURL + "/api/v1/schemas/upload-response.json", ShareXExamplePath: "examples/sharex/warpbox-anonymous.sxcu", ShareXExampleURL: a.cfg.BaseURL + "/api/v1/upload", ShareXDownloadURL: a.cfg.BaseURL + "/api/v1/sharex/warpbox-anonymous.sxcu", ShareXFileFieldName: "sharex", ShareXGroupWindow: uploadGroupWindow.String(), }, }) } func (a *App) ShareXAnonymousConfig(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Disposition", `attachment; filename="warpbox-anonymous.sxcu"`) helpers.WriteJSON(w, http.StatusOK, map[string]any{ "Version": "18.0.0", "Name": "Warpbox Anonymous Upload", "DestinationType": "ImageUploader, TextUploader, FileUploader", "RequestMethod": "POST", "RequestURL": a.cfg.BaseURL + "/api/v1/upload", "Headers": map[string]string{ "Accept": "application/json", // Group a multi-file selection (sent as back-to-back requests) into // one box. Remove this header for one box per file. uploadBatchHeader: "sharex", }, "Body": "MultipartFormData", "FileFormName": "sharex", "URL": "{json:boxUrl}", "ThumbnailURL": "{json:thumbnailUrl}", "DeletionURL": "{json:deleteUrl}", "ErrorMessage": "{json:error}", }) } func (a *App) UploadRequestSchema(w http.ResponseWriter, r *http.Request) { helpers.WriteJSON(w, http.StatusOK, map[string]any{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": a.cfg.BaseURL + "/api/v1/schemas/upload-request.json", "title": "Warpbox anonymous upload request", "description": "Multipart/form-data request accepted by POST /api/v1/upload. Send one or more files using either the file or sharex field.", "type": "object", "properties": map[string]any{ "file": map[string]any{ "description": "One or more uploaded files. Use this field for curl and browser-style clients.", "type": "array", "items": map[string]any{"type": "string", "format": "binary"}, }, "sharex": map[string]any{ "description": "One or more uploaded files. Use this field for ShareX custom uploader configs.", "type": "array", "items": map[string]any{"type": "string", "format": "binary"}, }, "max_days": map[string]any{ "description": "Optional number of days before the box expires. Defaults to 7.", "type": "integer", "minimum": 1, }, "max_downloads": map[string]any{ "description": "Optional maximum number of downloads before the box expires.", "type": "integer", "minimum": 1, }, "password": map[string]any{ "description": "Optional box password.", "type": "string", }, "obfuscate_metadata": map[string]any{ "description": "Optional checkbox-style value. When set with a password, hides file names/counts until unlock.", "type": "string", "enum": []string{"on"}, }, }, "anyOf": []any{ map[string]any{"required": []string{"file"}}, map[string]any{"required": []string{"sharex"}}, }, }) } func (a *App) UploadResponseSchema(w http.ResponseWriter, r *http.Request) { helpers.WriteJSON(w, http.StatusOK, map[string]any{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": a.cfg.BaseURL + "/api/v1/schemas/upload-response.json", "title": "Warpbox anonymous upload JSON response", "description": "JSON response returned by POST /api/v1/upload when Accept: application/json is sent.", "type": "object", "required": []string{"boxId", "boxUrl", "zipUrl", "manageUrl", "deleteUrl", "expiresAt", "files"}, "properties": map[string]any{ "boxId": map[string]any{"type": "string"}, "boxUrl": map[string]any{"type": "string", "format": "uri"}, "zipUrl": map[string]any{"type": "string", "format": "uri"}, "thumbnailUrl": map[string]any{"type": "string", "format": "uri", "description": "Thumbnail of the most recently uploaded file (placeholder until generated)."}, "manageUrl": map[string]any{"type": "string", "format": "uri", "description": "Private bearer URL for managing/deleting this upload. Returned only at upload time."}, "deleteUrl": map[string]any{"type": "string", "format": "uri", "description": "Private bearer URL for deleting this upload (GET or POST). Returned only at upload time."}, "expiresAt": map[string]any{"type": "string", "format": "date-time"}, "files": map[string]any{ "type": "array", "items": map[string]any{ "type": "object", "required": []string{"id", "name", "size", "url"}, "properties": map[string]any{ "id": map[string]any{"type": "string"}, "name": map[string]any{"type": "string"}, "size": map[string]any{"type": "string"}, "url": map[string]any{"type": "string", "format": "uri"}, "thumbnailUrl": map[string]any{"type": "string", "format": "uri"}, }, }, }, }, }) }