OctoWiki

Admin Panel

The internal /admin operations console — server-rendered Jet templates, the three-tier RBAC (viewer/admin/super_admin) plus view-only mode, and a feature-by-feature inventory of every admin control from clients and catalog to orders, payouts, and vendor credentials.

The admin panel ("warden") is the internal operations console — server-rendered Jet templates under /admin/*, cookie-session auth, RBAC. It's the only place vendor topology is visible; everything customer-facing stays vendor-free. Routes in http/routes/admin.go (378 lines), handlers http/handler/admin_*.go, views views/admin/, layout views/layouts/admin/base.jet.

Auth mechanics (Valkey sessions, 2FA gate, RBAC roles) are in Auth & Access Control. This page is the feature inventory.

RBAC — three middleware tiers

Routes are layered by wrapping groups:

  • adminAuth (admin.go:31) — any authenticated admin; all read/list/detail pages.
  • writeMiddleware (admin.go:35) — applied per-route on every mutation. SessionData.CanWrite(): view-only mode → false (overrides all); super-admin → true; else role must be admin (a viewer is read-only).
  • adminSuper (admin.go:366, AdminSuperUserMiddleware) — user management only.
  • View-only mode (POST /session/view-only-mode, admin.go:47) is a self-service session toggle — deliberately not write-gated — that makes even an admin read-only for the session.

Feature-flag gating wraps whole sections in if FeatureFlags.Is<X>Enabled(): Vouchers (admin.go:69), Payouts (:234), eSIM (:287), Top-ups (:322). A disabled feature's admin routes are never registered.

Feature inventory

Auth, profile & 2FA

Public GET/POST /login, GET/POST /login/2fa/verify. Authenticated: /logout (all roles), /profile/password, /profile/2fa/{setup,disable,backup-codes}, GET /api/2fa/status. Handlers admin_auth.go, admin_2fa.go.

User management (super-admin only)

adminSuper group: POST /users, GET /admin-users, /admin-users/create, /admin-users/:id/toggle-status, /admin-users/:id/reset-password, /admin-users/:id/reset-2fa, and /clients/:id/portal-user/:user_id/reset-password. Handlers admin_users.go.

Read-only AJAX APIs (always available): /api/dashboard/{stats,recent-orders,charts,top-products,top-clients,cron-jobs} (admin_dashboard_api.go); search /search/clients, /api/clients/search, /api/{countries,currencies,timezones}.

Clients

GET /clients, /clients/:id; create/edit (/clients/create, /clients/:id/update-details); activation toggle (/clients/:id/status); discounts CRUD; wallet top-up / deduct / create (/clients/:id/wallets/{topup,deduct,create}); portal-user create; reset credentials (/clients/:id/reset-credentials). Handlers admin_client.go, admin_ui.go. Shopify store config lives on the client edit form — see Shopify.

Products & catalog

Products list/detail/edit + create/update/auto-save; vendor-product mapping add/update/delete (/products/:id/vendor-products/*); per-client discount import + enabled-products import + catalog export (Excel); product/vendor blacklists add/delete. Handlers admin_ui.go, admin_vendor_catalog_mapping.go, product_import.go. See Products & Catalog.

Vendor catalog & vendors

  • Catalog: GET /vendors/:id/catalog (+ snapshots, current-stats, unmapped); trigger sync (POST /vendors/:id/catalog/sync); bulk-map / create-product-and-map; discount export/import.
  • Vendors: list/new/edit/detail; balances (GET /vendors/:id/balances) + manual balance sync (POST /vendors/:id/balances/sync); vendor attributes CRUD (where credentials are entered). Handlers external_vendors.go, admin_vendor_catalog_mapping.go.

Orders (voucher)

Create; cancel / refund / retry / reset / resend-email (/orders/:orderID/{cancel,refund,retry,reset}, /orders/:id/resend-email). Product-search AJAX helpers. Handlers admin_api_order.go, admin_ui.go, plus bulk/individual vendor-order checkpoint handlers. See Order Lifecycle.

Inventory & prefetch

Dashboard + list + denominations + available-count; import (Excel) + tag/untag (/inventory/{tag,untag}); read-only inventory-dashboard APIs. Prefetch create/kill (/prefetch/create, /prefetch/:id/kill). Handlers admin_inventory.go, admin_inventory_dashboard.go.

Top-ups (flag-gated)

Products/recharges pages + APIs; product update; recharge cancel / refund / retry (/api/topups/recharges/:id/{cancel,refund,retry}); per-client product listing. Handlers admin_topup.go, admin_topup_recharges.go, admin_recharge_actions.go. See Top-up & eSIM Flows.

eSIM (flag-gated)

Products/orders pages; sync products / variants / resync; product & variant update; per-client variant upsert; order actions cancel / refund / retry / reset / resend / force-deliver (/api/esim/orders/:id/*); Grasshopper push (push/push-all/sync eSIM products, upsert gift-cards-from-esims). Handlers admin_esim.go, admin_esim_actions.go, admin_grasshopper.go.

Payouts (flag-gated)

Dashboard/list/detail pages + APIs; provider management (update/status/attributes — where payout API keys live); client payout configs (update/enable/disable, audit-logged); scheduled payouts (pause/resume/cancel); beneficiary-provider links (list/link/update/delete). Handlers admin_payout_api.go, admin_payout_ui.go, admin_scheduled_payout.go, admin_beneficiary_provider.go. See Payouts.

Integrations

  • Shopify mappings: GET/POST /api/clients/:id/shopify-mappings + toggle (admin_shopify_mappings.go).
  • G2A: integration page, generate credentials, enable toggle, mapping CRUD (admin_g2a.go). See G2A.
  • Website leads: GET /website/leads + status patch (admin_website_leads.go).

Forex & jobs

Forex list / create / delete (admin_ui.go); job executions list/detail/log + alerts/stats APIs (admin_job_executions.go). See Jobs & Observability.

UI conventions

  • Layout views/layouts/admin/base.jet; ~29 views use showToast(message, type) and ~13 use await confirmAction({...}).
  • Never alert() / confirm() — always showToast (message-first) and confirmAction (async). See no-alert-use-toast and no-confirm-use-modal.
  • CSRF tokens render in templates but are not validated (middleware commented out) — the panel relies on SameSite=Strict. See auth findings.

Notable destructive / high-privilege actions

ActionRouteGuard
Client wallet top-up / deduct/clients/:id/wallets/{topup,deduct}write
Client (de)activation/clients/:id/statuswrite
Reset client credentials/clients/:id/reset-credentialswrite
Order cancel / refund/orders/:orderID/{cancel,refund}write
eSIM force-deliver/api/esim/orders/:id/force-deliverwrite
Recharge cancel / refund/api/topups/recharges/:id/{cancel,refund}write
Trigger vendor catalog sync/vendors/:id/catalog/syncwrite
Manual vendor balance sync/vendors/:id/balances/syncwrite
Vendor attribute (credential) CRUD/vendors/:id/attributes/*write
Generate G2A credentials/clients/:id/g2a/credentialswrite
Reset admin user password / 2FA/admin-users/:id/*super

Findings

  • All mutations are gated only by write/super — there is no per-action confirmation enforced server-side; the confirm modal is client-side only (confirmAction), and only ~13 views use it, so some destructive POSTs (wallet deduct, force-deliver, catalog sync) rely on the operator not fat-fingering. Worth auditing that every destructive button calls confirmAction.
  • eSIM force-deliver marks an order delivered without a vendor code — a powerful manual override; ensure it's logged and confined to super/admin.
  • Payout provider & vendor attribute endpoints expose where secrets are entered — confirm the detail views don't echo is_secret values back.

Key files

  • Routes: http/routes/admin.go
  • Handlers: http/handler/admin_*.go (~30 files)
  • Views: views/admin/*.jet, layout views/layouts/admin/base.jet
  • Middleware: http/handler/admin_middleware.go (AdminAuthMiddleware, AdminWriteMiddleware, AdminSuperUserMiddleware)

On this page