feat(admin): add box preview and password bypass for administrators
Introduce an `AdminViewBox` handler and route that allows administrators to view any box directly. If the box is password-protected, the handler bypasses the protection by setting an unlock cookie with an unlock token and logs the bypass event. Additionally, add CSS and JS foundations for a file context menu and preview actions in the file browser UI.
This commit is contained in:
@@ -44,23 +44,69 @@
|
||||
|
||||
<div class="download-list file-browser is-list" data-file-browser>
|
||||
{{range .Data.Files}}
|
||||
<article class="download-item file-card" data-kind="{{.PreviewKind}}">
|
||||
<a class="thumb-link" href="{{.URL}}" aria-label="Preview {{.Name}}">
|
||||
<article class="download-item file-card" data-kind="{{.PreviewKind}}" data-file-context data-preview-url="{{.URL}}" data-view-url="{{.DownloadURL}}?inline=1" data-download-url="{{.DownloadURL}}" data-file-name="{{.Name}}">
|
||||
<a class="thumb-link" href="{{.DownloadURL}}?inline=1" aria-label="View {{.Name}}">
|
||||
<img src="{{.ThumbnailURL}}" alt="" loading="lazy">
|
||||
</a>
|
||||
<a class="file-main" href="{{.URL}}">
|
||||
<a class="file-main" href="{{.DownloadURL}}?inline=1">
|
||||
<strong>{{.Name}}</strong>
|
||||
<small>{{.Size}} · {{.ContentType}}</small>
|
||||
</a>
|
||||
{{if not $.Data.Locked}}
|
||||
<a class="button button-outline" href="{{.DownloadURL}}">
|
||||
<svg viewBox="0 0 24 24" role="img" focusable="false" aria-hidden="true"><path d="M12 3v12m0 0 4-4m-4 4-4-4M5 21h14" /></svg>
|
||||
Download
|
||||
</a>
|
||||
<div class="file-actions">
|
||||
<a class="button button-outline preview-action" href="{{.DownloadURL}}?inline=1" target="_blank" rel="noopener noreferrer" data-preview-action data-view-label="View" data-copy-label="Copy link">
|
||||
<svg data-preview-view-icon viewBox="0 0 24 24" role="img" focusable="false" aria-hidden="true"><path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6-10-6-10-6Z" /><circle cx="12" cy="12" r="3" /></svg>
|
||||
<svg data-preview-copy-icon viewBox="0 0 24 24" role="img" focusable="false" aria-hidden="true" hidden><rect width="14" height="14" x="8" y="8" rx="2" /><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" /></svg>
|
||||
<span data-preview-label>View</span>
|
||||
</a>
|
||||
<a class="button button-outline" href="{{.DownloadURL}}" download="{{.Name}}">
|
||||
<svg viewBox="0 0 24 24" role="img" focusable="false" aria-hidden="true"><path d="M12 3v12m0 0 4-4m-4 4-4-4M5 21h14" /></svg>
|
||||
Download
|
||||
</a>
|
||||
</div>
|
||||
{{end}}
|
||||
</article>
|
||||
{{end}}
|
||||
</div>
|
||||
{{if not .Data.Locked}}
|
||||
<div class="context-menu" data-file-context-menu role="menu" aria-label="File actions" hidden>
|
||||
<div class="context-menu-top">
|
||||
<small>File actions</small>
|
||||
<div class="context-menu-icons" aria-label="Quick actions">
|
||||
<button type="button" role="menuitem" data-context-action="preview" title="Open preview" aria-label="Open preview">
|
||||
<svg viewBox="0 0 24 24" role="img" focusable="false" aria-hidden="true"><path d="M15 3h6v6" /><path d="M10 14 21 3" /><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" /></svg>
|
||||
</button>
|
||||
<button type="button" role="menuitem" data-context-action="copy-preview" title="Copy preview URL" aria-label="Copy preview URL">
|
||||
<svg viewBox="0 0 24 24" role="img" focusable="false" aria-hidden="true"><rect width="14" height="14" x="8" y="8" rx="2" /><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" /></svg>
|
||||
<span data-context-label class="sr-only">Copy</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<button type="button" role="menuitem" data-context-action="preview">
|
||||
<svg viewBox="0 0 24 24" role="img" focusable="false" aria-hidden="true"><path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6-10-6-10-6Z" /><circle cx="12" cy="12" r="3" /></svg>
|
||||
<span data-context-label>Preview</span>
|
||||
</button>
|
||||
<button type="button" role="menuitem" data-context-action="view">
|
||||
<svg viewBox="0 0 24 24" role="img" focusable="false" aria-hidden="true"><path d="M15 3h6v6" /><path d="M10 14 21 3" /><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" /></svg>
|
||||
<span data-context-label>View raw file</span>
|
||||
</button>
|
||||
<hr>
|
||||
<button type="button" role="menuitem" data-context-action="copy-preview">
|
||||
<svg viewBox="0 0 24 24" role="img" focusable="false" aria-hidden="true"><rect width="14" height="14" x="8" y="8" rx="2" /><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" /></svg>
|
||||
<span data-context-label>Copy Preview</span>
|
||||
</button>
|
||||
<button type="button" role="menuitem" data-context-action="copy-download">
|
||||
<svg viewBox="0 0 24 24" role="img" focusable="false" aria-hidden="true"><rect width="14" height="14" x="8" y="8" rx="2" /><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" /></svg>
|
||||
<span data-context-label>Copy Download</span>
|
||||
</button>
|
||||
<hr>
|
||||
<button type="button" role="menuitem" data-context-action="download">
|
||||
<svg viewBox="0 0 24 24" role="img" focusable="false" aria-hidden="true"><path d="M12 3v12m0 0 4-4m-4 4-4-4M5 21h14" /></svg>
|
||||
<span data-context-label>Download</span>
|
||||
</button>
|
||||
</div>
|
||||
{{end}}
|
||||
{{else if not .Data.Locked}}
|
||||
<p class="download-subtitle">{{.Data.ExpiresLabel}}</p>
|
||||
{{end}}
|
||||
|
||||
Reference in New Issue
Block a user