Krizaka
Documentation
Exploitation

Admin Console

Pour les décideurs

What an operator controls from orochia-admin — creator verification, moderation, payouts, auctions, accounts, backups — and the four gates around it: IP allow-list, one account, a service token, armed confirmations.

The operator console (krizaka/orochia-admin) is a separate application with its own database, its own single account and its own network gate. It never touches Orochia's database: every decision goes through Orochia's admin API (/api/admin/*, listed in the API reference), server side, with a service token the browser never sees. What an operator decides is recorded in the console's own log.

Sélectionne un module : qui il appelle et qui l'appelle restent allumés — requêtes (HTTP, SQL) en trait plein, événements (messages, webhooks, SSE, NOTIFY, push) en pointillés.

orochia-admin : appelle 2, appelé par 0.

Clients3

orochia-admin

Clients · Orochia

Operator console for Orochia: 2257 creator verification, content reports, payouts and treasury

Appelle

Appelé par

Rien

Application1

Données2

Services externes10

Version texte — 28 modules
Les modules et leurs dépendances de build
ModuleRôleDépôtVersionDépend deUtilisé par
orochia-adminClientsorochia-admin1.0.0krizaka-tailwind (2.0.0-beta.1), krizaka-tokens (2.0.0-beta.1), krizaka-ui (2.0.0-beta.1), orochia-design-system (3.0.0)—
orochia-mobileClientsorochia-mobile1.0.0krizaka-tokens (2.0.0-beta.4), krizaka-ui (2.0.0-beta.4), orochia-design-system (4.0.0)—
orochia-webClientsorochia1.0.0krizaka-i18n (0.1.0), krizaka-icons (0.1.0), krizaka-intl (0.1.0), krizaka-tailwind (2.0.0), krizaka-tokens (2.0.0), krizaka-ui (2.0.0), orochia-design-system (4.0.0)—
orochia-apiApplicationorochia1.0.0orochia-db, orochia-media, orochia-payments, orochia-push—
orochia-configPaquetsorochia1.0.0——
orochia-dbPaquetsorochia1.0.0—orochia-api, orochia-payments
orochia-mediaPaquetsorochia1.0.0—orochia-api
orochia-paymentsPaquetsorochia1.0.0orochia-dborochia-api
orochia-pushPaquetsorochia1.0.0—orochia-api
orochia-design-systemDesign systemorochia-design-system4.1.0krizaka-tailwind (2.2.0), krizaka-tokens (2.2.0), krizaka-ui (2.2.0)orochia-admin, orochia-mobile, orochia-web
krizaka-i18nDesign systemkrizaka-ui0.1.0—orochia-web
krizaka-iconsDesign systemkrizaka-ui0.1.0—orochia-web
krizaka-intlDesign systemkrizaka-ui0.1.0—orochia-web
krizaka-tailwindDesign systemkrizaka-ui2.0.0—orochia-admin, orochia-design-system, orochia-web
krizaka-tokensDesign systemkrizaka-ui2.0.0—orochia-admin, orochia-design-system, orochia-mobile, orochia-web
krizaka-uiDesign systemkrizaka-ui2.0.0—orochia-admin, orochia-design-system, orochia-mobile, orochia-web
admin-postgresqlDonnéesorochia-admin———
postgresqlDonnéesorochia———
bunny-streamServices externesTiers———
ccbillServices externesTiers———
expo-pushServices externesTiers———
facebook-oauthServices externesTiers———
google-oauthServices externesTiers———
mailgunServices externesTiers———
nowpaymentsServices externesTiers———
resendServices externesTiers———
segpayServices externesTiers———
stripeServices externesTiers———
Appels à l'exécution
DeVersTypeVia
orochia-adminorochia-apiHTTP/api/admin/* · service token
orochia-apibunny-streamHTTPcreate video · Tus signature
orochia-apiexpo-pushHTTP@orochia/push · send
orochia-apifacebook-oauthHTTPcode exchange · user info
orochia-apigoogle-oauthHTTPcode exchange · user info
orochia-apimailgunHTTPsend e-mail
orochia-apinowpaymentsHTTPcheckout session over its API
orochia-apiresendHTTPsend e-mail
orochia-apistripeHTTPcheckout session over its API
orochia-mobilebunny-streamHTTPHLS playback · signed URL
orochia-mobileorochia-apiHTTP/api/* · Bearer session
orochia-webbunny-streamHTTPHLS playback · signed URL
orochia-webbunny-streamHTTPTus upload (resumable)
orochia-webccbillHTTPhosted checkout page
orochia-webfacebook-oauthHTTPconsent screen (redirect)
orochia-webgoogle-oauthHTTPconsent screen (redirect)
orochia-webnowpaymentsHTTPhosted checkout page
orochia-weborochia-apiHTTP/api/* · session cookie
orochia-websegpayHTTPhosted checkout page
orochia-webstripeHTTPhosted checkout page
postgresqlorochia-apiLISTEN/NOTIFYLISTEN/NOTIFY orochia_events
expo-pushorochia-mobilepushnotification
orochia-adminadmin-postgresqlSQLoperator accounts · sessions
orochia-apipostgresqlSQL@orochia/db · Drizzle
orochia-apiorochia-mobileSSE/api/conversations/stream
orochia-apiorochia-webSSE/api/auctions/[id]/stream
orochia-apiorochia-webSSE/api/challenges/[id]/stream
orochia-apiorochia-webSSE/api/conversations/stream
bunny-streamorochia-apiwebhook/api/webhooks/bunny
ccbillorochia-apiwebhook/api/webhooks/payments/ccbill
nowpaymentsorochia-apiwebhook/api/webhooks/payments/crypto
segpayorochia-apiwebhook/api/webhooks/payments/segpay
stripeorochia-apiwebhook/api/webhooks/payments/stripe

Parcours — Lecture

  1. Demande de lecture — Le lecteur ne détient aucune URL média : il en demande une à Orochia. (orochia-web → orochia-api) · GET /api/videos/[id]/stream
  2. Contrôle d'accès — Publique, contacts, abonnés ou déblocage payant : la visibilité est vérifiée contre les contacts, abonnements et droits d'accès. (orochia-api → postgresql)
  3. Décision — Pas de droit, pas d'URL : la réponse est un refus ou le paywall. (postgresql → orochia-api)
  4. URL signée · 300 s — Un jeton HMAC-SHA256 lié à la vidéo et à son expiration : un lien partagé meurt en cinq minutes. (orochia-api → orochia-web)
  5. Diffusion 4K HLS — Les segments viennent directement du CDN de Bunny, jamais des serveurs applicatifs. (orochia-web → bunny-stream)

Parcours — Déblocage payant

  1. Demande de déblocage — L'acheteur choisit un montant et une passerelle configurée. (orochia-web → orochia-api) · POST /api/videos/unlock-video
  2. Intention de paiement — Acheteur, créateur, vidéo et montant sont enregistrés avant tout mouvement d'argent. (orochia-api → postgresql)
  3. Page de paiement — L'acheteur part sur la page hébergée du prestataire : Orochia ne voit jamais de carte. (orochia-api → orochia-web)
  4. Paiement — Seules les passerelles dont tous les identifiants sont configurés sont proposées. (orochia-web → ccbill, orochia-web → segpay, orochia-web → nowpayments, orochia-web → stripe)
  5. Webhook signé — Signature vérifiée en temps constant sur le corps brut — aucun mode permissif. (ccbill → orochia-api, segpay → orochia-api, nowpayments → orochia-api, stripe → orochia-api) · POST /api/webhooks/payments/[gateway]
  6. Règlement, une seule fois — Crédit au grand livre et droit d'accès dans une même transaction ; un webhook rejoué ne change rien. (orochia-api → postgresql)

Parcours — Téléversement

  1. Ouverture d'envoi — Seuls les créateurs vérifiés (registres 18 U.S.C. § 2257) peuvent ouvrir une session. (orochia-web → orochia-api) · POST /api/videos/create-upload-session
  2. Création de la vidéo — Orochia enregistre la vidéo chez Bunny Stream et signe une session Tus. (orochia-api → bunny-stream)
  3. Session Tus signée — Le studio reçoit l'adresse d'envoi et sa signature, valables pour cette seule vidéo. (orochia-api → orochia-web)
  4. Envoi reprenable — Le fichier part directement vers Bunny et reprend après une coupure. (orochia-web → bunny-stream)
  5. Encodage terminé — Bunny signale la fin du transcodage par un webhook signé. (bunny-stream → orochia-api) · POST /api/webhooks/bunny
  6. Prête à diffuser — La vidéo devient lisible, sous la visibilité choisie par son créateur. (orochia-api → postgresql)

The operator reaches the console from an allowed IP only, with its one account; the console keeps its account, sessions and operator log in its own PostgreSQL, and calls Orochia server-side on /api/admin/* with the service token — never the Orochia database.

What you control

ScreenWhat an operator sees and decidesOrochia API
OverviewLedger totals, catalogue state and the three queues that need a humanGET /api/admin/overview
2257 Creator VerificationThe review queue; open a creator's identity and age document, approve the creator — only verified creators can uploadGET/PATCH /api/admin/creators, GET /api/admin/documents
Content ReportsTriage: start a review, reopen, resolve with a recorded reason; suspected minors and non-consensual content firstGET/PATCH /api/admin/reports
Treasury & PayoutsRevenue from the ledger; put a payout under review, settle it with the transfer reference, or fail it with a reason (the balance is refunded)GET /api/platform/treasury, GET/PATCH /api/admin/payouts
CatalogueEvery video by state with its open reports; take one down with a recorded reason (DMCA, terms, a confirmed report — its auction is cancelled) or restore itGET/PATCH /api/admin/videos
AuctionsOpen, awaiting and sold auctions and the credits held; cancel one with a reason — the leading bid's credits go back to its bidderGET/DELETE /api/admin/auctions
Creator RegistryEvery creator and their activity; suspend or restore their uploadsGET/PATCH /api/admin/creators
AccountsEvery account, filtered by role, suspension or search; suspend (sign-in blocked, open sessions refused on their next request, open auctions cancelled) with a reason shown to the account, reinstate, or change the role (member, creator, administrator)GET/PATCH /api/admin/users
Platform & DatabaseEnvironment, database size and rows per table, migration history, backups (create, download, delete), the operator log and the factory reset/api/admin/platform*

Screens

Captured on a local development stack (e-mail addresses and the operator's name redacted).

Overview: the three queues that need a human, and the ledger

Overview — the three queues that need a human, and the ledger.

Accounts: role changes and suspensions, each behind a confirmation

Accounts — every account, its role, its checks and its state.

Platform and database: deployment, migrations, backups and tables

Platform & Database — deployment, migrations, backups and rows per table.

The factory reset, armed by a typed phrase

The factory reset — backup first by default, locked until the phrase is typed.

How it is secured

Four gates, each enforced in code:

  1. The network. Every request — the sign-in page included — is refused with 403 unless the client address is in ADMIN_ALLOWED_IPS (comma-separated). On DigitalOcean the address is do-connecting-ip, set by the platform's edge, never by the client. In production the list is mandatory: empty, the console answers 403 to everyone. Only the liveness route /api/health (no data) is outside it.
  2. One account. Nobody signs up. The single operator is defined by environment — ADMIN_EMAIL, ADMIN_NAME, ADMIN_PASSWORD (12 characters or more) — and written to the console's database on first use. The password is stored as a salted scrypt hash and compared in constant time. Sessions are random tokens stored hashed, valid 8 hours, in an httpOnly, SameSite=Strict cookie. Changing the password in the environment revokes every open session.
  3. A service token. The console calls Orochia as a service: Authorization: Bearer OROCHIA_ADMIN_API_TOKEN (32 characters or more, shared by the two deployments only), compared in constant time. Orochia accepts it on its ADMIN routes only, and acts as the platform owner (OROCHIA_OWNER_EMAIL), who must exist, be an administrator and not be suspended — otherwise every call is refused. Without the variable, no token is accepted.
  4. Armed confirmations. Every decision opens a dialog that says what will happen before it does. A decision that affects someone requires a recorded reason (a takedown, a suspension, a failed payout, a cancelled auction) or the transfer reference (a settled payout). Irreversible operations are armed by a phrase: the operator types it before the button works. Benign, reversible steps (start a review, reopen a report) are one click.

Every decision — done or refused, with its target and detail — is written to the operator log, shown on Platform & Database.

Backups and factory reset

  • Backup now writes the whole database (gzipped JSON of every table) to private storage; backups can be described, downloaded and deleted from the console.
  • Factory reset deletes every account, video, payment, auction and setting and rebuilds the schema from the release's migrations — the state of a fresh install. Orochia's owner account is kept; the console, its account and its log live in their own database and are not affected; media files at Bunny are not deleted. It is available only where OROCHIA_ALLOW_DATABASE_RESET=true and never on the public, indexed production, whatever the flag says. The operator must type reset <database name>; "back up first" is on by default, and if that backup fails nothing is deleted.

Run it locally

Start Orochia first, with the same OROCHIA_ADMIN_API_TOKEN in its .env, then:

git clone https://github.com/krizaka/orochia-admin.git && cd orochia-admin
cp .env.example .env.local      # its database, the operator account, the token shared with Orochia
docker exec orochia-postgres-dev psql -U orochia_user -d orochia_db -c "CREATE DATABASE orochia_admin"
npm install
npm run dev                     # http://localhost:3001 — sign in with ADMIN_EMAIL / ADMIN_PASSWORD

Locally (outside production) an empty ADMIN_ALLOWED_IPS lets every address in. On a deployment, deploy/Dockerfile builds a standalone image (port 3001); ADMIN_PASSWORD and OROCHIA_ADMIN_API_TOKEN are app secrets, never in git.

Présentation du produit →

Sur cette page