feat(api): add API documentation and ShareX integration
- 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.
This commit is contained in:
96
backend/templates/pages/api.html
Normal file
96
backend/templates/pages/api.html
Normal file
@@ -0,0 +1,96 @@
|
||||
{{define "api.html"}}{{template "base" .}}{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
<section class="docs-view" aria-labelledby="api-title">
|
||||
<div class="docs-header">
|
||||
<p class="kicker">Developer docs</p>
|
||||
<h1 id="api-title">Warpbox API</h1>
|
||||
<p>Anonymous uploads for curl, scripts, and ShareX. The upload endpoint accepts multipart files and returns either plain text or JSON based on the <code>Accept</code> header.</p>
|
||||
</div>
|
||||
|
||||
<div class="docs-grid">
|
||||
<article class="card docs-card">
|
||||
<div class="card-content">
|
||||
<h2>Endpoints</h2>
|
||||
<dl class="endpoint-list">
|
||||
<div><dt>Upload</dt><dd><code>POST /api/v1/upload</code></dd></div>
|
||||
<div><dt>Health</dt><dd><code>GET /api/v1/health</code></dd></div>
|
||||
<div><dt>Request schema</dt><dd><a href="/api/v1/schemas/upload-request.json"><code>/api/v1/schemas/upload-request.json</code></a></dd></div>
|
||||
<div><dt>Response schema</dt><dd><a href="/api/v1/schemas/upload-response.json"><code>/api/v1/schemas/upload-response.json</code></a></dd></div>
|
||||
</dl>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="card docs-card">
|
||||
<div class="card-content">
|
||||
<h2>Curl upload</h2>
|
||||
<p>Without a JSON <code>Accept</code> header, Warpbox prints one plain box URL for shell-friendly usage.</p>
|
||||
<pre><code>curl -F file=@./report.pdf {{.Data.UploadURL}}</code></pre>
|
||||
<p>For automation, request JSON to get file URLs and the private manage/delete URLs.</p>
|
||||
<pre><code>curl -F file=@./report.pdf \
|
||||
-H 'Accept: application/json' \
|
||||
{{.Data.UploadURL}}</code></pre>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="card docs-card">
|
||||
<div class="card-content">
|
||||
<h2>JSON response</h2>
|
||||
<p>The raw delete token is returned only once inside <code>manageUrl</code> and <code>deleteUrl</code>. Keep those links private.</p>
|
||||
<pre><code>{
|
||||
"boxId": "abc123",
|
||||
"boxUrl": "{{.Data.BaseURL}}/d/abc123",
|
||||
"zipUrl": "{{.Data.BaseURL}}/d/abc123/zip",
|
||||
"manageUrl": "{{.Data.BaseURL}}/d/abc123/manage/private-token",
|
||||
"deleteUrl": "{{.Data.BaseURL}}/d/abc123/manage/private-token/delete",
|
||||
"expiresAt": "2026-06-05T12:00:00Z",
|
||||
"files": [
|
||||
{
|
||||
"id": "file123",
|
||||
"name": "report.pdf",
|
||||
"size": "2.4 MiB",
|
||||
"url": "{{.Data.BaseURL}}/d/abc123/f/file123"
|
||||
}
|
||||
]
|
||||
}</code></pre>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="card docs-card">
|
||||
<div class="card-content">
|
||||
<h2>ShareX setup</h2>
|
||||
<ol class="docs-steps">
|
||||
<li>Download the instance config: <a href="/api/v1/sharex/warpbox-anonymous.sxcu"><code>/api/v1/sharex/warpbox-anonymous.sxcu</code></a>.</li>
|
||||
<li>Or open the tracked template at <code>{{.Data.ShareXExamplePath}}</code> and change <code>RequestURL</code> to <code>{{.Data.ShareXExampleURL}}</code>.</li>
|
||||
<li>Keep <code>FileFormName</code> as <code>{{.Data.ShareXFileFieldName}}</code>.</li>
|
||||
<li>Import the <code>.sxcu</code> file into ShareX as a custom uploader.</li>
|
||||
<li>Upload a file. ShareX will use <code>boxUrl</code> as the public URL and <code>manageUrl</code> as the deletion URL.</li>
|
||||
</ol>
|
||||
<pre><code>{
|
||||
"RequestMethod": "POST",
|
||||
"RequestURL": "{{.Data.ShareXExampleURL}}",
|
||||
"Headers": { "Accept": "application/json" },
|
||||
"Body": "MultipartFormData",
|
||||
"FileFormName": "{{.Data.ShareXFileFieldName}}",
|
||||
"URL": "$json:boxUrl$",
|
||||
"DeletionURL": "$json:manageUrl$"
|
||||
}</code></pre>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="card docs-card docs-card-wide">
|
||||
<div class="card-content">
|
||||
<h2>Multipart fields</h2>
|
||||
<div class="field-grid">
|
||||
<span><code>file</code></span><p>One or more files for curl, browser, and generic multipart clients.</p>
|
||||
<span><code>sharex</code></span><p>One or more files from ShareX custom uploader configs.</p>
|
||||
<span><code>max_days</code></span><p>Optional number of days before expiration. Defaults to 7.</p>
|
||||
<span><code>max_downloads</code></span><p>Optional download count limit.</p>
|
||||
<span><code>password</code></span><p>Optional password required before viewing/downloading.</p>
|
||||
<span><code>obfuscate_metadata</code></span><p>Optional <code>on</code>; hides names/counts until unlock when a password is set.</p>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
{{end}}
|
||||
@@ -80,6 +80,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="result-list" id="result-list"></div>
|
||||
<p class="manage-link" id="manage-link" hidden>
|
||||
<span>Keep this private:</span>
|
||||
<a href="/" target="_blank" rel="noopener noreferrer">Manage or delete this upload</a>
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
32
backend/templates/pages/manage.html
Normal file
32
backend/templates/pages/manage.html
Normal file
@@ -0,0 +1,32 @@
|
||||
{{define "manage.html"}}{{template "base" .}}{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
<section class="download-view" aria-labelledby="manage-title">
|
||||
<div class="card download-card">
|
||||
<div class="card-content">
|
||||
<div class="file-emblem" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24" role="img" focusable="false"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="M19 6l-1 14H6L5 6" /><path d="M10 11v5" /><path d="M14 11v5" /></svg>
|
||||
</div>
|
||||
<h1 id="manage-title">Manage upload</h1>
|
||||
<p class="download-subtitle">This private link can delete the entire box.</p>
|
||||
|
||||
<dl class="manage-details">
|
||||
<div><dt>Box</dt><dd><code>{{.Data.Box.ID}}</code></dd></div>
|
||||
<div><dt>Files</dt><dd>{{.Data.FileCount}}</dd></div>
|
||||
<div><dt>Total size</dt><dd>{{.Data.TotalSize}}</dd></div>
|
||||
<div><dt>Expires</dt><dd>{{.Data.ExpiresLabel}}</dd></div>
|
||||
<div><dt>Downloads</dt><dd>{{.Data.DownloadCount}}{{if .Data.MaxDownloads}} / {{.Data.MaxDownloads}}{{end}}</dd></div>
|
||||
<div><dt>Protected</dt><dd>{{if .Data.Protected}}Yes{{else}}No{{end}}</dd></div>
|
||||
</dl>
|
||||
|
||||
<form action="{{.Data.DeleteActionURL}}" method="post">
|
||||
<button class="button button-danger button-wide" type="submit">
|
||||
<svg viewBox="0 0 24 24" role="img" focusable="false" aria-hidden="true"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="M19 6l-1 14H6L5 6" /></svg>
|
||||
Delete upload
|
||||
</button>
|
||||
</form>
|
||||
<a class="button button-outline button-wide" href="/d/{{.Data.Box.ID}}">Back to box</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{{end}}
|
||||
16
backend/templates/pages/manage_deleted.html
Normal file
16
backend/templates/pages/manage_deleted.html
Normal file
@@ -0,0 +1,16 @@
|
||||
{{define "manage_deleted.html"}}{{template "base" .}}{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
<section class="download-view" aria-labelledby="deleted-title">
|
||||
<div class="card download-card">
|
||||
<div class="card-content">
|
||||
<div class="file-emblem" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24" role="img" focusable="false"><path d="M20 6 9 17l-5-5" /></svg>
|
||||
</div>
|
||||
<h1 id="deleted-title">Upload deleted</h1>
|
||||
<p class="download-subtitle">Box <code>{{.Data.ID}}</code> and all of its files have been removed.</p>
|
||||
<a class="button button-primary button-wide" href="/">Upload another file</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user