2026-05-29 23:44:05 +03:00
package handlers
import (
"net/http"
"warpbox.dev/backend/libs/helpers"
"warpbox.dev/backend/libs/web"
)
type apiDocsData struct {
BaseURL string
UploadURL string
RequestSchemaURL string
ResponseSchemaURL string
ShareXExamplePath string
ShareXExampleURL string
ShareXDownloadURL string
ShareXFileFieldName string
2026-05-31 22:27:43 +03:00
ShareXGroupWindow string
2026-05-29 23:44:05 +03:00
}
func ( a * App ) APIDocs ( w http . ResponseWriter , r * http . Request ) {
2026-06-01 11:30:38 +03:00
user , loggedIn := a . currentUser ( r )
actor := "anonymous"
if loggedIn {
actor = "user"
}
a . logger . Info ( "api docs viewed" , withRequestLogAttrs ( r ,
"source" , "page" ,
"severity" , "user_activity" ,
"code" , 2501 ,
"actor" , actor ,
"user_id" , user . ID ,
) ... )
2026-05-30 17:23:20 +03:00
a . renderPage ( w , r , http . StatusOK , "api.html" , web . PageData {
2026-05-29 23:44:05 +03:00
Title : "API documentation" ,
Description : "Curl and ShareX upload examples for Warpbox." ,
Data : apiDocsData {
BaseURL : a . cfg . BaseURL ,
UploadURL : a . cfg . BaseURL + "/api/v1/upload" ,
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" ,
2026-05-31 22:27:43 +03:00
ShareXGroupWindow : uploadGroupWindow . String ( ) ,
2026-05-29 23:44:05 +03:00
} ,
} )
}
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" ,
2026-05-31 22:27:43 +03:00
// Group a multi-file selection (sent as back-to-back requests) into
// one box. Remove this header for one box per file.
uploadBatchHeader : "sharex" ,
2026-05-29 23:44:05 +03:00
} ,
"Body" : "MultipartFormData" ,
"FileFormName" : "sharex" ,
2026-05-31 22:27:43 +03:00
"URL" : "{json:boxUrl}" ,
"ThumbnailURL" : "{json:thumbnailUrl}" ,
"DeletionURL" : "{json:deleteUrl}" ,
"ErrorMessage" : "{json:error}" ,
2026-05-29 23:44:05 +03:00
} )
}
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 {
2026-05-31 22:27:43 +03:00
"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" } ,
2026-05-29 23:44:05 +03:00
"files" : map [ string ] any {
"type" : "array" ,
"items" : map [ string ] any {
"type" : "object" ,
"required" : [ ] string { "id" , "name" , "size" , "url" } ,
"properties" : map [ string ] any {
2026-05-31 22:27:43 +03:00
"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" } ,
2026-05-29 23:44:05 +03:00
} ,
} ,
} ,
} ,
} )
}