- Add an API documentation page with curl and ShareX examples. - Implement a dynamic ShareX configuration endpoint (`/api/v1/sharex/warpbox-anonymous.sxcu`) that generates a `.sxcu` file pre-configured with the instance's base URL. - Update anonymous uploads to return a private management link (`manageUrl`) and a deletion link (`deleteUrl`) in JSON responses. - Update README with details on Stage 3 Anonymous Integrations. - Add styling for the new API documentation view and management details.
134 lines
5.2 KiB
Go
134 lines
5.2 KiB
Go
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
|
|
}
|
|
|
|
func (a *App) APIDocs(w http.ResponseWriter, r *http.Request) {
|
|
a.renderer.Render(w, 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",
|
|
},
|
|
})
|
|
}
|
|
|
|
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",
|
|
},
|
|
"Body": "MultipartFormData",
|
|
"FileFormName": "sharex",
|
|
"URL": "$json:boxUrl$",
|
|
"DeletionURL": "$json:manageUrl$",
|
|
})
|
|
}
|
|
|
|
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"},
|
|
"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 POST URL for deleting this upload. 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"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
}
|