Web-/Commerce-API (JuByteWeb)

Vollständige Referenz der JuByteWeb-Plattform — dem zentralen Portal für Lizenzen, Store, Bezahlung, Releases/Downloads, Organisationen und das Lizenz-Backend des Nexus Core. JuByteWeb ist eine Next.js-16-App (App Router); alle Endpunkte liegen unter app/api/**/route.ts.

Diese Seite katalogisiert jeden Endpunkt nach Domäne, beschreibt das Datenmodell und zeigt Entwickler-Beispiele. Verwandt: Lizenz-API & Entitlement-Vertrag und Module lizenzieren & verkaufen.

Auth-Klassen in den Tabellen: Public (kein Login), Session (eingeloggter User via Cookie), Admin (Session + Permission-Key, z. B. admin.licenses.view), Token (Shared-Secret/Signatur, für Core/CI/Webhooks).


1. Authentifizierung & Konto

Login, Registrierung, Session

MethodePfadAuthZweck
POST/api/auth/registerPublicRegistrierung (Passwort ≥ 10 Zeichen, AGB/Datenschutz). Enqueued EMAIL_VERIFICATION_REQUESTED + Discord-Notify
POST/api/auth/loginPublicE-Mail/Passwort-Login; bei 2FA requires2fa: true + challengeToken (Rate-Limit 10/min)
POST/api/auth/logoutSessionSession-Cookie widerrufen, AUTH_LOGOUT auditieren
GET/api/auth/meSessionProfil inkl. primärer Gruppe (nach Gewicht), Discord-Status
POST/api/auth/verify-emailPublicemailVerifiedAt setzen, Token löschen, Gruppe „user" zuweisen
POST/api/auth/resend-verificationPublicVerifikations-Mail erneut senden
POST/api/auth/change-passwordSessionPasswort ändern (Rate-Limit 10/min)
POST/api/auth/forgot-passwordPublicPASSWORD_RESET_REQUESTED enqueuen
POST/api/auth/reset-passwordPublicReset-Token prüfen, Passwort setzen

2FA (TOTP)

MethodePfadAuthZweck
POST/api/auth/2fa/setupSessionTOTP-Secret erzeugen → otpauthUrl + qrSvg
POST/api/auth/2fa/enableSessionAktivieren; gibt 10 Backup-Codes zurück
POST/api/auth/2fa/verifyPublicTOTP-Code zum challengeToken prüfen → Session
POST/api/auth/2fa/disableSessionDeaktivieren nach Passwort-Bestätigung

Passkeys (WebAuthn)

MethodePfadAuthZweck
POST/api/auth/passkey/register/startSessionRegistrierungs-Ceremony starten
POST/api/auth/passkey/register/completeSessionPasskey speichern
POST/api/auth/passkey/authenticate/startPublicAuth-Ceremony (optional email für non-discoverable)
POST/api/auth/passkey/authenticate/completePublicAuth abschließen → Session
GET/DELETE/api/auth/passkeys, /api/auth/passkeys/[id]SessionPasskeys auflisten/Details/widerrufen

Sessions & Discord

MethodePfadAuthZweck
GET/api/auth/sessionsSessionAktive Sessions auflisten
POST/api/auth/sessions/revokeSessionBestimmte Session widerrufen
POST/api/auth/discord/startSessionDiscord-OAuth starten → authorizationUrl
GET/api/auth/discord/callbackPublicOAuth-Callback, Discord verknüpfen
POST/api/auth/discord/unlinkSessionDiscord trennen
POST/api/auth/discord/syncSessionDiscordSyncJob (Reason MANUAL) enqueuen

Beispiel: Login mit fetch

const res = await fetch('/api/auth/login', {
  method: 'POST', headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ email, password }),
});
const data = await res.json();
if (data.requires2fa) {
  // → /api/auth/2fa/verify mit { challengeToken: data.challengeToken, code }
}

2. Store & Katalog

MethodePfadAuthZweck
GET/api/store/productsPublicÖffentlicher Katalog: Produkte mit priceTiers, releases, bundleItems
GET/api/admin/productsAdmin admin.products.viewAlle Produkte (inkl. versteckter)
POST/api/admin/productsAdmin admin.products.manageProdukt anlegen (+ Gruppen-/Channel-Grants)
GET/PATCH/DELETE/api/admin/products/[id]AdminProdukt-Detail/ändern/löschen
POST/api/admin/products/[id]/mediaAdmin admin.products.manageLogo/Banner hochladen (multipart)

Preis-Tiers & Bundles

MethodePfadAuthZweck
GET/POST/api/admin/products/[id]/tiersAdminPreis-Tiers auflisten/anlegen (priceEur, durationDays?, featuresJson, maxServers?)
PATCH/DELETE/api/admin/products/[id]/tiers/[tierId]AdminTier ändern/löschen
GET/POST/api/admin/products/[id]/bundle-itemsAdminBundle-Mitglieder auflisten/hinzufügen
DELETE/api/admin/products/[id]/bundle-items/[memberId]AdminMitglied entfernen

Beispiel: öffentlicher Katalog

curl https://test.jubyte.com/api/store/products | jq '.products[] | {key, name, tiers: .priceTiers}'

3. Commerce / Checkout & Bezahlung

MethodePfadAuthZweck
POST/api/commerce/checkoutSessionOrder(s) anlegen, aktive Sales anwenden, PayPal-/PayPal.me-URL zurückgeben (Status → PENDING, Rate-Limit 10/min)
GET/api/commerce/capture?token=<paypal>SessionPayPal-Order capturen → Order ACTIVE, Lizenzen aktivieren, Download-Events
POST/api/webhooks/paypalToken (Signatur)PayPal-Events (PAYMENT.CAPTURE.COMPLETED/REFUNDED…); Signatur prüfen, dedupen, verarbeiten (Rate-Limit 60/min)

Checkout-Request (gekürzt):

{
  "items": [ { "product": "bansystem", "tier": "pro" } ],
  "currency": "EUR",
  "billingName": "Max Mustermann",
  "billingCountry": "DE",
  "withdrawalWaived": true,
  "agreeTerms": true,
  "agreePrivacy": true
}

Antwort: { "orderId": "…", "approvalUrl": "https://www.paypal.com/checkoutnow?token=…" }. Pro Item entsteht eine Order; alle teilen sich die paypalOrderId.

Ablauf (PayPal): checkout (Order erstellen) → Kunde genehmigt → capture (serverseitig) → Webhook (asynchrone Bestätigung + Buchung im Ledger).


4. Orders & Rechnungen

MethodePfadAuthZweck
GET/api/portal/ordersSessionEigene Bestellungen inkl. Zahlungsinfo
GET/api/portal/invoicesSessionEigene Rechnungen (ISSUED/REFUNDED/CANCELLED)
GET/api/portal/invoices/[id]SessionEinzelne Rechnung
GET/api/admin/ordersAdmin admin.orders.viewOrder-Suche (id, product, paypalOrderId, User-E-Mail), paginiert

5. Lizenzen

Portal (eigene/Org-Lizenzen)

MethodePfadAuthZweck
GET/api/portal/licensesSessionEigene + Org-Lizenzen (Status auto → EXPIRED bei Ablauf), Bindungszähler
GET/api/portal/licenses/[id]SessionLizenz-Detail inkl. Server-Bindungen
DELETE/api/portal/licenses/[id]SessionLizenz soft-löschen (REVOKED)
GET/DELETE/api/portal/licenses/[id]/bindings/[bindingId]SessionServer-Bindung ansehen/widerrufen

Admin

MethodePfadAuthZweck
GET/api/admin/licensesAdmin admin.licenses.viewSuche (Key, E-Mail, Produkt, Status, productId), paginiert
POST/api/admin/licensesAdmin admin.licenses.createLizenz manuell ausstellen (Key auto, sofern nicht angegeben)
GET/api/admin/licenses/[id]Admin admin.licenses.viewVoll-Detail (User, Bindungen, Events, Module, Security-Flags)
PATCH/api/admin/licenses/[id]Admin admin.licenses.manageplan/maxServers/expiresAt/status ändern
POST/api/admin/licenses/[id]/assignAdmin admin.licenses.manageNeuem User zuweisen (per userId oder email)
POST`/api/admin/licenses/[id]/revokesuspendunsuspend
GET/POST/api/admin/licenses/[id]/modulesAdminNexus-Modul-Grants lesen / `{action:'grant'
GET/api/admin/licenses/[id]/entitlementAdminSigniertes Entitlement-JWS mit modules[]-Claim erzeugen

Lizenz-Server-API v1 (für den Core)

MethodePfadAuthZweck
POST/api/v1/license/verifyRate-Limit 30/minHeartbeat-Verify: Status, Bindungslimit, Cache; LICENSE_VERIFY-Event
POST/api/v1/license/activateRate-Limit 15/minServer-Aktivierung; Plan-Limits (FREE=1, PRO=50, ENTERPRISE=∞)
POST/api/v1/license/issueCI-TokenLizenzen aus Release-Pipeline ausstellen
POST/api/v1/license/downloadLizenz-KeyLizenz-authentifizierter Artefakt-Download
POST/api/v1/license/heartbeatRate-LimitlastSeenAt der Bindung aktualisieren

Der Entitlement-Vertrag (RS256-JWS, Claims plan/status/expires/limits/features/ modules/grace_hours) ist in der Lizenz-API vollständig beschrieben. Der Core holt und aktiviert ihn automatisch.

Beispiel: Verify (Core → Web)

curl -X POST https://test.jubyte.com/api/v1/license/verify \
  -H "Content-Type: application/json" \
  -d '{"key":"NX-XXXX-XXXX","serverId":"srv-abc","version":"1.2.0","channel":"RELEASE"}'
# → { "allowed": true, "status": "ACTIVE", "license": {…}, "latestStableVersion": "1.2.0" }

6. Releases & Downloads

MethodePfadAuthZweck
GET/api/admin/releasesAdmin admin.releases.viewRelease-Suche (productKey, channel, status), paginiert
POST/api/admin/releasesAdmin admin.releases.manageRelease im DRAFT anlegen (semver + sha256 validiert)
POST/api/admin/releases/[id]/publishAdmin admin.releases.publishVeröffentlichen → PUBLISHED, Cache invalidieren
POST/api/admin/releases/[id]/deprecateAdmin admin.releases.manageAls DEPRECATED markieren
POST/api/admin/releases/publish-ciCI-TokenRelease aus Build-Pipeline anlegen/veröffentlichen
GET/api/download/release/[releaseId]?licenseId=SessionSignierten Download-Token (TTL 300 s); Channel-Grants für BETA/SNAPSHOT
GET/api/download/artifact?token=<signed>PublicArtefakt streamen (Single-Use-Token)
GET/api/portal/downloadsSessionErreichbare Downloads je Lizenz (Bundles aufgelöst, 60 s Cache)
GET/api/portal/releasesSessionErreichbare Releases über alle Lizenzen

Channels: RELEASE (alle), BETA/SNAPSHOT (nur mit Gruppen-Grant via ProductChannelGrant). Release-Status: DRAFT/PUBLISHED/DEPRECATED.


7. Organisationen & Teams

MethodePfadAuthZweck
GET/POST/api/orgsSessionEigene Orgs / Org anlegen (Ersteller = OWNER)
GET/PATCH/api/orgs/[slug]Session + Member/OWNEROrg-Detail / umbenennen, suspendieren
GET/api/orgs/[slug]/membersSession + MemberMitglieder
PATCH/api/orgs/[slug]/members/[userId]/roleSession + ADMINRolle ändern (OWNER/ADMIN/SUPPORT/BILLING)
DELETE/api/orgs/[slug]/members/[userId]Session + OWNERMitglied entfernen
POST/api/orgs/[slug]/inviteSession + OWNEREinladung (7-Tage-TTL), EMAIL_ORG_INVITE
GET/POST/api/org-invites/[token], /acceptPublic/SessionEinladung ansehen/annehmen
POST`/api/orgs/[slug]/licenses/assignunassign`Session + ADMIN/OWNER
GET/PATCH/api/admin/orgs, /api/admin/orgs/[id]Admin admin.orgs.*Org-Suche/-Verwaltung

8. Berechtigungen, Gruppen & Discord-Mapping

MethodePfadAuthZweck
GET/POST/api/admin/groupsAdmin admin.groups.*Gruppen auflisten/anlegen (inkl. System-Gruppen)
GET/PATCH/DELETE/api/admin/groups/[groupId]AdminGruppen-Detail/ändern/löschen
GET/POST/DELETE/api/admin/groups/[groupId]/members[/userId]AdminMitglieder verwalten
GET/POST/api/admin/permissionsAdmin admin.permissions.*Permissions auflisten/anlegen (Key z. B. admin.products.view)
GET/api/portal/permissionsSessionEigene Permissions (aus Gruppenmitgliedschaft)
GET/POST/api/admin/discord/role-mappingsAdmin admin.discord.manageMapping PLAN/PRODUCT/ORG_ROLE → Discord-Rolle
GET/POST/api/admin/discord/group-rolesAdmin admin.discord.manageGruppe → Discord-Rolle

Permission-Key-Muster: admin.{resource}.{action} (z. B. admin.licenses.manage). Store-Sichtbarkeit über store.product.<key>.


9. Nexus-Modul-Registry & Entitlements

MethodePfadAuthZweck
GET/api/admin/modulesAdmin admin.licenses.viewLizenzierbare Module (kind CORE/MODULE, premium, active)
POST/api/admin/modulesAdmin admin.modules.manageModul registrieren — ohne Java-Codeänderung (data-driven)
PATCH/DELETE/api/admin/modules/[id]Admin admin.modules.manageModul ändern/deaktivieren
GET/POST/api/admin/licenses/[id]/modulesAdminModul-Grants einer Lizenz lesen/grant/revoke

Dieses datengetriebene Registry ist das Herzstück der Lizenzintegration: Das ACP selbst ist als kind=CORE modelliert, jedes Plugin als kind=MODULE; beliebig viele Module lassen sich hinzufügen. Die aufgelöste Modul-Liste wird als modules[]-Claim ins signierte Entitlement geschrieben. Siehe Module lizenzieren & verkaufen.


10. Buchhaltung, Sales, Metriken & Admin

MethodePfadAuthZweck
GET/api/admin/accountingAdmin admin.accounting.viewDoppelte Buchführung: Salden, Transaktionen, Umsatz/Deferred/Refunds
GET/POST/api/admin/salesAdmin admin.products.*Rabatte (PERCENTAGE/FIXED_AMOUNT), global oder produktspezifisch
GET/PATCH/DELETE/api/admin/sales/[id]AdminSale-Detail/ändern/löschen
GET/api/admin/metrics/revenueAdmin admin.metrics.viewUmsatz über Zeit
GET/api/admin/metrics/usageAdmin admin.metrics.viewNutzung (aktive User/Lizenzen, Downloads)
POST/api/admin/metrics/recomputeAdmin admin.metrics.manageMetriken neu berechnen
GET/PATCH/api/admin/users, /api/admin/users/[id]Admin admin.users.*User-Suche / Rolle ändern
POST`/api/admin/users/[id]/suspendunsuspenddelete
GET/api/admin/auditAdmin admin.audit.viewAudit-Log aller Admin-Aktionen
GET/POST/api/admin/security-flags, /[id]/resolveAdmin admin.licenses.*Verdächtige Lizenz-Aktivität

Support, Notifications, DSGVO

MethodePfadAuthZweck
GET/api/notificationsSessionBenachrichtigungen (LICENSE_EXPIRING_SOON, TICKET_REPLY…)
GET/POST/api/portal/support/tickets[/id]SessionTickets auflisten/erstellen/antworten
GET/POST/api/admin/support/tickets…Admin admin.support.*Tickets verwalten/beantworten
POST/api/portal/account-deletionSessionKontolöschung beantragen
GET/api/portal/data-exportSessionDSGVO-Datenexport
POST/api/cron/data-retentionCRON_SECRETAbgelaufene Sessions/Tokens/Logs aufräumen

11. Datenmodell (Prisma)

Zentrale Entitäten und Relationen (Auszug):

Identität: User (email unique, role, emailVerifiedAt) ─ Session, UserTwoFactor, UserDiscord, Passkey, EmailVerificationToken, PasswordResetToken, AuditLog.

Lizenzierung: License (key unique, product?/productId?, plan, statusACTIVE/SUSPENDED/EXPIRED/REVOKED, expiresAt?, maxServers?) ─ LicenseBinding (serverId, lastSeenAt), LicenseEvent, LicenseOwnership (USER/ORG), LicenseModuleGrantNexusModule (moduleId unique, kind CORE/MODULE, premium).

Katalog: Product (key/slug unique, category, productType, status) ─ ProductPriceTier (priceEur, durationDays?, featuresJson, maxServers?), ProductBundleItem, ProductGroupGrant, ProductChannelGrant, Release (version, channel, status, artifactKey, sha256), ProductDefault, DownloadLog.

Commerce: Order (statusCREATED/PENDING/ACTIVE/FAILED/CANCELLED/ REFUNDED, paypalOrderId?) ─ Payment (provider PAYPAL, status, amount), Invoice (invoiceNumber unique), WebhookEvent (eventId unique).

Buchhaltung: LedgerAccount (code, type ASSET/LIABILITY/REVENUE/ EXPENSE) ─ LedgerTransaction (referenceType ORDER/PAYMENT/REFUND/MANUAL) ─ LedgerEntry (debit/credit, doppelte Buchung: Soll = Haben). Sale (saleType PERCENTAGE/FIXED_AMOUNT).

Organisationen: Organization (slug unique) ─ OrgMember (role OWNER/ADMIN/SUPPORT/BILLING), OrgGroup, OrgGroupMember, OrgGroupPermission, OrgInvite (7-Tage-TTL), OrgApiKey.

Rechte: Group (name/slug unique, weight, isSystem) ─ Permission (key unique), GroupPermission, UserGroup, GroupDiscordRole. DiscordRoleMapping (type PLAN/PRODUCT/ORG_ROLE), DiscordSyncJob.

Sonstiges: OutboxEvent (transaktionaler Outbox-Pattern), UserNotification, SupportTicket/Reply, AccountDeletionRequest, SecurityFlag, SiteSetting, StoreItem/StoreItemPermission.


12. Konventionen

AspektWert
ValidierungZod (E-Mail lowercased, Passwort 10–128, semver-/sha256-/uuid-/slug-Regex)
Pagination?page= (1-indexiert), ?limit= (1–200); Antwort { items, pagination }
Rate-LimitsLogin/Register 10/min, Activate 15/min, Verify 30/min, Webhook 60/min, Download 5/s
Fehlercodes400 Validation, 401 Auth, 403 Forbidden/Channel/Plan-Limit, 404 Not-Found, 409 Konflikt, 500 Config/Intern
AuditAdmin-Aktionen → AuditLog; Lizenz-Statuswechsel → LicenseEvent
PatternsTransaktionaler Outbox, doppelte Buchführung, Single-Use-Download-Tokens, Permission-RBAC

Beispiel: Admin-Aufruf mit Permission

# Session-Cookie + Permission admin.licenses.view erforderlich
curl https://test.jubyte.com/api/admin/[email protected] \
  -H "Cookie: $SESSION_COOKIE" | jq '.licenses[] | {key, status, plan}'

Siehe auch