Files
WarpBox/admin-overview.md

17 KiB

WarpBox Admin Overview

This document maps the current WarpBox admin area, explains how the existing pages and permission model work, then proposes an overhaul path for a more useful admin product: dashboard, account management, API keys, and a role/group based authorization system.

Project Context

WarpBox is a small self-hosted file sharing app. Its core product is deliberately simple:

  • create temporary upload boxes
  • upload one or more files
  • optionally protect the box with a password
  • share a generated link
  • allow individual downloads or ZIP downloads
  • support one-time ZIP handoff
  • store uploads on the local filesystem
  • store app metadata in local BadgerDB

The project has a strong retro desktop identity. The admin area should keep that personality, but become more operationally useful. Best direction: retro surface, modern information architecture. Admin actions should feel clear, forgiving, and inspectable rather than dense or mysterious.

Current Admin Architecture

Admin routes are registered under /admin in lib/server/admin.go.

Current pages:

  • /admin/login
  • /admin
  • /admin/boxes
  • /admin/users
  • /admin/tags
  • /admin/settings

Admin templates live in:

  • templates/admin_login.html
  • templates/admin.html
  • templates/admin_boxes.html
  • templates/admin_users.html
  • templates/admin_tags.html
  • templates/admin_settings.html

Styling uses:

  • static/css/admin.css
  • shared retro UI styles from static/css/app.css and static/css/window.css

Metadata lives in BadgerDB through lib/metastore. Current admin-relevant records are:

  • users
  • tags
  • sessions
  • settings overrides

Current Login And Session Flow

Admin login is bootstrapped from environment configuration:

  • WARPBOX_ADMIN_PASSWORD
  • WARPBOX_ADMIN_USERNAME
  • WARPBOX_ADMIN_EMAIL
  • WARPBOX_ADMIN_ENABLED

On startup, BootstrapAdmin ensures a protected admin tag exists. If a user matching the admin username already exists, the admin tag is attached to that user. If no user exists and WARPBOX_ADMIN_PASSWORD is set, a first admin user is created.

Login behavior:

  • GET /admin/login shows login form when admin login is enabled.
  • POST /admin/login checks username/password.
  • password hashes use bcrypt.
  • disabled users cannot log in.
  • user must have effective AdminAccess.
  • successful login creates a BadgerDB session with random session token and CSRF token.
  • session cookie name is warpbox_admin_session.
  • cookie path is /admin.
  • cookie is HTTP-only.
  • cookie Secure flag is controlled by WARPBOX_ADMIN_COOKIE_SECURE.
  • session TTL is controlled by WARPBOX_SESSION_TTL_SECONDS.

All protected admin routes require:

  • valid session cookie
  • unexpired session
  • valid CSRF token for non-GET requests
  • existing enabled user
  • effective AdminAccess

Admin responses set no-store headers and X-Content-Type-Options: nosniff.

Current Dashboard Page

Route:

  • GET /admin

Template:

  • templates/admin.html

Current behavior:

  • shows signed-in username
  • provides logout button
  • shows four large links:
    • Boxes
    • Users
    • Tags
    • Settings

Current limitation:

  • this is not a dashboard yet. It has no statistics, recent activity, health status, quota information, user counts, storage totals, warnings, or next actions.

Good future role:

  • make this the admin home screen, with live operational summary and clear links into deeper management pages.

Current Boxes Page

Route:

  • GET /admin/boxes

Required permission:

  • AdminBoxesView

Current behavior:

  • loads all box summaries from filesystem via boxstore.ListBoxSummaries()
  • shows summary counters:
    • total boxes
    • total storage
    • expired boxes
  • table columns:
    • box id
    • file count
    • size
    • created time
    • expiry time
    • flags
  • flags include:
    • expired
    • one-time
    • password
  • box id links to /box/{id}

Current limitations:

  • no search
  • no filters
  • no pagination
  • no delete action
  • no bulk cleanup
  • no storage trend
  • no per-box detail drawer
  • no visibility into failed uploads, incomplete boxes, thumbnail state, or one-time consumption state
  • expired boxes are counted but not directly actionable

Good future role:

  • operational file-sharing monitor and cleanup center.

Current Users Page

Routes:

  • GET /admin/users
  • POST /admin/users

Required permission:

  • AdminUsersManage

Current behavior:

  • create user with username, email, password, and selected tags
  • list users sorted by username
  • show username, email, assigned tags, created time, status
  • enable/disable user
  • active session user cannot disable themselves

Current user model:

  • ID
  • Username
  • Email
  • PasswordHash
  • TagIDs
  • CreatedAt
  • UpdatedAt
  • Disabled
  • optional per-user max file size
  • optional per-user max box size
  • optional per-user max expiry seconds

Current limitations:

  • no edit user page
  • no password reset flow
  • no email verification or invite flow
  • no delete/archive user action
  • no user detail screen
  • no role preview
  • no effective permissions display
  • no API key management
  • no account activity
  • no per-user storage/upload stats
  • per-user limit fields exist in the model but are not exposed in the admin UI

Good future role:

  • user account command center, optimized for quick scanning, safe edits, and permission clarity.

Current Tags Page

Routes:

  • GET /admin/tags
  • POST /admin/tags

Required permission:

  • AdminUsersManage

Current behavior:

  • create a tag
  • set description
  • attach permission booleans
  • attach optional limits
  • list existing tags
  • built-in admin tag is protected and forced to full admin permissions

Current tag permissions:

  • upload allowed
  • one-time download allowed
  • ZIP download allowed
  • renewable allowed
  • admin access
  • manage users
  • manage settings
  • view boxes
  • max file size bytes
  • max box size bytes
  • allowed expiry seconds
  • renew on access seconds exists in model but is not exposed in current tag form
  • renew on download seconds exists in model but is not exposed in current tag form

Permission resolution:

  • user permissions are resolved from all assigned tags plus user-level overrides
  • boolean permissions are additive: any tag can grant a permission
  • size limits use the more permissive value
  • global max file/box limits still cap resolved user limits
  • allowed expiry seconds are merged from all tags and sorted
  • global feature flags can still disable ZIP or one-time downloads even if a tag allows them

Current limitations:

  • tags mix labels, roles, groups, limits, and admin capability grants in one concept
  • no edit tag page
  • no delete tag action
  • no user count per tag
  • no permission preview
  • no conflict detection
  • no clear distinction between "role grants access" and "plan defines quotas"
  • permission logic is powerful but hard to explain to administrators

Good future role:

  • replace tags with explicit roles/groups/plans. Keep old tags only as migration input.

Current Settings Page

Routes:

  • GET /admin/settings
  • POST /admin/settings

Required permission:

  • AdminSettingsManage

Current behavior:

  • shows configured settings table
  • columns:
    • setting
    • value
    • source
    • environment variable name
  • editable values can be overridden from admin UI when WARPBOX_ALLOW_ADMIN_SETTINGS_OVERRIDE=true
  • overrides are stored in BadgerDB
  • runtime config is updated after save

Editable settings currently include:

  • guest uploads enabled
  • API enabled
  • ZIP downloads enabled
  • one-time downloads enabled
  • one-time download expiry seconds
  • renew on access enabled
  • renew on download enabled
  • default guest expiry seconds
  • max guest expiry seconds
  • default user max file size bytes
  • default user max box size bytes
  • session TTL seconds
  • box poll interval milliseconds
  • thumbnail batch size
  • thumbnail interval seconds

Non-editable/hard settings include:

  • data directory
  • global max file size bytes
  • global max box size bytes
  • one-time download retry on failure

Current limitations:

  • settings are presented as raw technical rows
  • no grouping
  • no descriptions
  • no validation hints beyond backend errors
  • byte fields require raw bytes
  • duration fields require raw seconds/milliseconds
  • no "restart required" or "runtime applied" distinction beyond current editability
  • no audit trail for setting changes

Good future role:

  • organized system configuration, with human units, clear safety boundaries, and change history.

Current API Key State

There is visible API key UX in the upload page:

  • "Use API key for larger quota"
  • API key input
  • local validation with regex
  • value saved locally in browser localStorage
  • cURL command includes Authorization: Bearer YOUR_API_KEY when enabled

Important current reality:

  • no backend API key model was found
  • no API key generation route was found
  • no server-side Authorization bearer validation was found
  • no per-user API key ownership or revocation exists yet
  • no current upload flow applies user permissions from an API key

So API keys are a product placeholder, not a functional feature yet.

Main Current Gaps

  • Dashboard is only navigation.
  • User management only creates and disables accounts.
  • Tags are doing too many jobs.
  • API keys are UI-only.
  • Admin pages lack search, filters, pagination, and detail views.
  • No audit log.
  • No admin-visible system health.
  • No storage cleanup controls.
  • No account self-service area for non-admin users.
  • Existing permission model is additive and permissive, which can surprise admins.

Build a full admin solution around four clear concepts:

  • Dashboard: current health and useful actions.
  • Accounts: people who can sign in or use API keys.
  • Roles/Groups: permission bundles and admin capabilities.
  • Plans/Limits: quotas and upload policy.

This separates identity from authorization from quotas. It should make the system easier to explain and safer to operate.

Proposed Dashboard

Recommended dashboard cards:

  • total active boxes
  • total storage used
  • expired boxes waiting cleanup
  • boxes created today / last 24 hours
  • uploads completed today / last 24 hours
  • failed or incomplete uploads
  • active users
  • disabled users
  • API keys active
  • admin sessions active
  • thumbnail queue / worker state
  • current global limits
  • guest uploads status
  • ZIP downloads status
  • one-time downloads status

Recommended dashboard sections:

  • "Needs attention"
    • expired boxes
    • failed uploads
    • one-time boxes stuck incomplete
    • high storage usage
    • disabled API setting while API key UI is visible
  • "Recent boxes"
    • latest boxes with flags and size
  • "Recent admin activity"
    • user created, role changed, setting changed, API key revoked
  • "System"
    • data directory
    • BadgerDB status
    • uploads directory size
    • thumbnail worker timing
    • config source summary

UX idea:

  • dashboard should answer "is WarpBox healthy?", "what changed recently?", and "what should I do next?" in one glance.

Proposed Account Management

Recommended account list:

  • search by username/email
  • filter by status, role/group, plan, API key presence
  • columns:
    • user
    • email
    • status
    • roles/groups
    • plan/limits
    • API keys
    • created
    • last login / last API use
    • storage used
    • boxes created

Recommended account detail page:

  • profile
  • status controls
  • password reset / force password change
  • roles/groups assignment
  • plan/limits assignment
  • effective permissions preview
  • API keys tab
  • recent activity tab
  • boxes owned by user

Recommended safe actions:

  • disable user
  • revoke all sessions
  • revoke all API keys
  • reset password
  • assign role/group
  • assign plan
  • archive user

Recommended UX details:

  • show effective permission summary before save
  • warn when removing own admin access
  • require confirmation for disabling final admin
  • prevent accidental lockout at backend level
  • show inherited vs direct settings clearly

Proposed API Key System

Data model idea:

  • API key id
  • user id
  • name/label
  • hashed secret
  • secret prefix for display
  • scopes
  • created at
  • expires at
  • last used at
  • revoked at
  • created by
  • optional allowed IP/CIDR list

Security rules:

  • show raw key only once on creation
  • store only hash server-side
  • allow revoke, rotate, rename
  • support expiry dates
  • log last-used timestamp
  • rate limit failed key attempts
  • avoid putting API keys in URLs

User-facing API key page:

  • create key
  • name key
  • choose expiry
  • view active/revoked keys
  • revoke key
  • copy cURL example
  • see last used time

Admin-facing API key controls:

  • view user key count and last use
  • revoke a user key
  • revoke all keys for disabled user
  • optionally create key on behalf of user
  • audit key creation/revocation

Permission behavior:

  • bearer key resolves to user
  • user roles/groups/plans determine upload policy
  • key scopes can further restrict user permission but not exceed it
  • API key can enable higher quota only if assigned user's plan allows it

Initial scopes:

  • box:create
  • box:upload
  • box:read
  • box:download
  • box:delete-own

Proposed Role/Group System

Replace tags with explicit authorization objects.

Recommended models:

  • Role: permission bundle, e.g. admin, operator, uploader, viewer
  • Group: collection of users with assigned roles and optional plan
  • Plan: quota/limit policy, e.g. guest, standard, trusted, unlimited

Roles should answer:

  • what can this user do?

Plans should answer:

  • how much can this user use?

Groups should answer:

  • who receives these defaults together?

Recommended permissions:

  • admin.access
  • admin.dashboard.view
  • admin.users.view
  • admin.users.manage
  • admin.roles.manage
  • admin.settings.view
  • admin.settings.manage
  • admin.boxes.view
  • admin.boxes.manage
  • boxes.create
  • boxes.download.zip
  • boxes.download.one_time
  • boxes.password.set
  • boxes.renew
  • api_keys.manage_own
  • api_keys.manage_any

Recommended limit fields:

  • max file size
  • max box size
  • max boxes per day
  • max storage active at once
  • max expiry
  • allowed expiry choices
  • max API keys
  • API key max TTL
  • guest upload allowed
  • ZIP allowed
  • one-time allowed
  • renew allowed

Recommended resolver:

  • start with system defaults
  • apply assigned plan quotas
  • apply group plan when user has no direct plan
  • apply direct user overrides last
  • roles grant permissions
  • scopes restrict API key actions
  • hard global limits cap everything

Migration strategy:

  • create role equivalents from current tag admin booleans
  • create plan equivalents from current tag upload limits
  • assign users based on existing TagIDs
  • keep read-only legacy tag view during migration
  • remove tag creation from final UI

Extra Feature Ideas

Storage and cleanup:

  • expired box cleanup page
  • bulk delete expired boxes
  • storage by age chart
  • largest boxes list
  • orphaned manifest/file scanner
  • thumbnail cleanup/rebuild tools

Security:

  • audit log
  • active admin sessions page
  • revoke sessions
  • failed login tracking
  • optional two-factor auth for admins
  • final-admin protection
  • configurable password policy

Operations:

  • system health page
  • config export
  • backup/restore notes for data directory and BadgerDB
  • maintenance mode
  • manual thumbnail worker run
  • background job status

User experience:

  • account self-service page
  • personal upload history
  • personal quota meter
  • personal API keys
  • upload presets
  • saved retention preferences

Admin UX:

  • global search
  • command palette
  • filters saved per admin
  • CSV export for users/boxes
  • inline detail drawer for boxes/users
  • change preview before saving roles/plans

Product:

  • named boxes supported server-side
  • custom slug support server-side
  • private/listed boxes if public listing is added
  • max view count server-side
  • ownership model: boxes created by user/API key belong to that user
  • public share page controls based on owner plan

Suggested Implementation Phases

Phase 1: make current admin useful

  • add real dashboard statistics
  • add search/filter/pagination to boxes and users
  • expose effective permissions on user rows/details
  • add user edit form
  • add storage cleanup actions

Phase 2: implement API keys

  • add API key model in BadgerDB
  • add create/revoke/list routes
  • hash keys server-side
  • validate bearer keys on API endpoints
  • connect key to user permissions
  • add self-service API key UI

Phase 3: replace tags

  • add roles/plans/groups models
  • add resolver
  • add migration from tags
  • update user management UI
  • deprecate tag creation

Phase 4: polish into full admin solution

  • audit log
  • account detail pages
  • system health
  • advanced cleanup
  • activity timeline
  • safer setting editor

Product Principle For The Overhaul

Keep WarpBox small, local, and understandable. The admin area should not become enterprise software cosplay. It should give the operator sharp tools:

  • see what is happening
  • fix common problems
  • manage people safely
  • give trusted users more power
  • keep storage under control
  • make permission decisions obvious

Best version: a retro control panel that behaves like a modern, careful admin console.