All checks were successful
Build and Publish Docker Image / deploy (push) Successful in 1m38s
- Add `WARPBOX_TRUSTED_PROXIES` configuration to restrict accepted forwarded client IP headers to specific proxy IPs/CIDRs, securing client IP resolution. - Integrate `BanService` into the background cleanup job to automatically purge expired abuse and ban evidence events. - Update documentation with reverse proxy security guidelines and a production systemd deployment guide.
120 lines
6.9 KiB
HTML
120 lines
6.9 KiB
HTML
{{define "admin_user_edit.html"}}{{template "base" .}}{{end}}
|
|
|
|
{{define "content"}}
|
|
<section class="app-shell admin-shell" aria-labelledby="admin-user-edit-title">
|
|
<aside class="app-sidebar">
|
|
<nav class="sidebar-nav">
|
|
<a class="sidebar-link" href="/admin">{{template "icon-dashboard" .}}<span>Overview</span></a>
|
|
<a class="sidebar-link" href="/admin/files">{{template "icon-folder" .}}<span>Files</span></a>
|
|
<a class="sidebar-link is-active" href="/admin/users">{{template "icon-user-circle" .}}<span>Users</span></a>
|
|
<a class="sidebar-link" href="/admin/settings">{{template "icon-settings" .}}<span>Settings</span></a>
|
|
<a class="sidebar-link" href="/admin/storage">{{template "icon-database" .}}<span>Storage</span></a>
|
|
<a class="sidebar-link" href="/admin/logs">{{template "icon-database" .}}<span>Logs</span></a>
|
|
<a class="sidebar-link" href="/admin/bans">{{template "icon-settings" .}}<span>Bans</span></a>
|
|
</nav>
|
|
<hr class="sidebar-sep">
|
|
<nav class="sidebar-nav"><a class="sidebar-link" href="/app">{{template "icon-home-simple" .}}<span>My Files</span></a></nav>
|
|
<hr class="sidebar-sep">
|
|
<form class="sidebar-logout" action="/admin/logout" method="post">
|
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
|
<button class="button button-outline" type="submit">{{template "icon-log-out" .}}<span>Sign out</span></button>
|
|
</form>
|
|
</aside>
|
|
|
|
<div class="app-main">
|
|
<div class="admin-header">
|
|
<div>
|
|
<p class="kicker">Operator console</p>
|
|
<h1 id="admin-user-edit-title">{{.Data.PageTitle}}</h1>
|
|
<p class="muted-copy">{{.Data.UserEdit.Email}} · {{.Data.UserEdit.Role}}</p>
|
|
</div>
|
|
<a class="button button-outline" href="/admin/users">Back to users</a>
|
|
</div>
|
|
|
|
{{if .Data.Error}}<p class="form-error">{{.Data.Error}}</p>{{end}}
|
|
{{if .Data.LastInviteURL}}
|
|
<div class="copy-field">
|
|
<input type="text" value="{{.Data.LastInviteURL}}" readonly id="reset-url-field" aria-label="Reset link">
|
|
<button class="button button-outline button-sm" type="button"
|
|
onclick="navigator.clipboard.writeText(document.getElementById('reset-url-field').value).then(()=>{this.textContent='Copied!';setTimeout(()=>this.textContent='Copy',2000)})">Copy reset link</button>
|
|
</div>
|
|
{{end}}
|
|
|
|
<div class="metric-grid user-edit-metrics">
|
|
<article class="metric-card"><span>Storage used</span><strong>{{.Data.UserEdit.StorageUsed}}</strong></article>
|
|
<article class="metric-card"><span>Uploaded today</span><strong>{{.Data.UserEdit.DailyUsed}}</strong></article>
|
|
<article class="metric-card"><span>Effective quota</span><strong>{{.Data.UserEdit.EffectiveStorage}}</strong></article>
|
|
<article class="metric-card"><span>Effective backend</span><strong>{{.Data.UserEdit.EffectiveBackend}}</strong></article>
|
|
</div>
|
|
|
|
<div class="card admin-table-card">
|
|
<div class="card-content">
|
|
<div class="table-header">
|
|
<div>
|
|
<h2>Identity and limits</h2>
|
|
<p>Blank limit fields inherit the global user defaults. Use -1 for unlimited upload size or daily upload caps. Storage quota set to 0 means unlimited.</p>
|
|
</div>
|
|
</div>
|
|
<form class="settings-form" action="/admin/users/{{.Data.UserEdit.ID}}/edit" method="post">
|
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
|
<div class="settings-section">
|
|
<h3 class="settings-section-title">Account</h3>
|
|
<label><span>Username</span><input name="username" value="{{.Data.UserEdit.Username}}" required></label>
|
|
<label><span>Email</span><input type="email" name="email" value="{{.Data.UserEdit.Email}}" required></label>
|
|
<label><span>Role</span><select name="role">
|
|
<option value="user" {{if eq .Data.UserEdit.Role "user"}}selected{{end}}>User</option>
|
|
<option value="admin" {{if eq .Data.UserEdit.Role "admin"}}selected{{end}}>Admin</option>
|
|
</select></label>
|
|
<label><span>Status</span><select name="status">
|
|
<option value="active" {{if eq .Data.UserEdit.Status "active"}}selected{{end}}>Active</option>
|
|
<option value="disabled" {{if eq .Data.UserEdit.Status "disabled"}}selected{{end}}>Disabled</option>
|
|
</select></label>
|
|
</div>
|
|
|
|
<div class="settings-section">
|
|
<h3 class="settings-section-title">Storage</h3>
|
|
<label>
|
|
<span>Storage backend</span>
|
|
<select name="storage_backend_id">
|
|
<option value="">Inherit global user backend ({{.Data.UserEdit.EffectiveBackend}})</option>
|
|
{{range .Data.Storage}}
|
|
{{if or .Config.Enabled (eq $.Data.UserEdit.StorageBackendID .Config.ID)}}<option value="{{.Config.ID}}" {{if eq $.Data.UserEdit.StorageBackendID .Config.ID}}selected{{end}}>{{.Config.Name}} ({{.Config.ID}})</option>{{end}}
|
|
{{end}}
|
|
</select>
|
|
</label>
|
|
<label><span>Storage quota override (MB)</span><input name="storage_quota_mb" value="{{.Data.UserEdit.StorageQuotaMB}}" placeholder="inherit"></label>
|
|
</div>
|
|
|
|
<div class="settings-section">
|
|
<h3 class="settings-section-title">Upload limits</h3>
|
|
<label><span>Max upload size (MB)</span><input name="max_upload_mb" value="{{.Data.UserEdit.MaxUploadMB}}" placeholder="inherit"></label>
|
|
<label><span>Daily upload cap (MB)</span><input name="daily_upload_mb" value="{{.Data.UserEdit.DailyUploadMB}}" placeholder="inherit"></label>
|
|
<label><span>Max expiration (days)</span><input type="number" min="1" name="max_days" value="{{.Data.UserEdit.MaxDays}}" placeholder="inherit"></label>
|
|
<label><span>Daily boxes</span><input type="number" min="1" name="daily_boxes" value="{{.Data.UserEdit.DailyBoxes}}" placeholder="inherit"></label>
|
|
<label><span>Active boxes</span><input type="number" min="1" name="active_boxes" value="{{.Data.UserEdit.ActiveBoxes}}" placeholder="inherit"></label>
|
|
<label><span>Short-window requests</span><input type="number" min="1" name="short_window_requests" value="{{.Data.UserEdit.ShortWindowRequests}}" placeholder="inherit"></label>
|
|
</div>
|
|
|
|
<button class="button button-primary" type="submit">Save user</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card admin-table-card">
|
|
<div class="card-content">
|
|
<div class="table-header">
|
|
<div>
|
|
<h2>Password reset</h2>
|
|
<p>Create a copyable reset link for this user.</p>
|
|
</div>
|
|
</div>
|
|
<form action="/admin/users/{{.Data.UserEdit.ID}}/reset?next=edit" method="post">
|
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
|
<button class="button button-outline" type="submit">Generate reset link</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
{{end}}
|