Voyti

Voyti

User management, authentication & authorization

Stateless Client

A REST API for a browser-based single-page application, or SPA (or any other stateless client), built on voyti-api’s bearer-token infrastructure: credential login/logout, self-registration, password reset, own-profile and own-sessions management, plus admin RBAC and audit-log endpoints.

Create an issue

POST v1/auth/login verifies a username/email + password and returns {"status": "ok", "token": "..."} - a bearer token for the same Authorization: Bearer <token> scheme voyti-api uses everywhere else. It replicates the exact event sequence core’s SessionController::login() dispatches (BeforeLoginEvent/FailedLoginEvent/AfterLoginEvent), so voyti-lockout and audit-log/session listeners work unmodified regardless of whether a login came from the HTML app or this API. If the account has 2FA enabled, login instead returns a challenge - see below.

Public

Route name Method Path Purpose
voyti/api-v1-auth-login POST v1/auth/login Credential login. Returns a bearer token, or a challenge_required body if 2FA is enabled for the account
voyti/api-v1-auth-register POST v1/auth/register Self-registration
voyti/api-v1-auth-register-confirm GET v1/auth/register/confirm/{id}/{code} Confirm an emailed registration code
voyti/api-v1-auth-register-resend POST v1/auth/register/resend Resend the confirmation email
voyti/api-v1-auth-password-reset-request POST v1/auth/password-reset/request Request a password-recovery email
voyti/api-v1-auth-password-reset-confirm POST v1/auth/password-reset/confirm Set a new password from an emailed recovery code

Authenticated

Route name Method Path Purpose
voyti/api-v1-auth-logout POST v1/auth/logout Revoke the calling bearer token
voyti/api-v1-auth-me-show GET v1/auth/me The current account’s profile
voyti/api-v1-auth-me-update PATCH v1/auth/me Update username/password directly; an email change is routed through the confirmation flow instead of applied immediately
voyti/api-v1-auth-sessions-index GET v1/auth/sessions List the account’s active bearer tokens
voyti/api-v1-auth-sessions-terminate DELETE v1/auth/sessions/{id} Revoke one bearer token by its stored hash

Reuse the same admin-gated group voyti-api-user’s endpoints do (AccessRuleMiddleware enforces administratorPermissionName). RBAC mirrors core’s HTML admin screen: {itemType} is role or permission. Per-user assignment management isn’t included here yet - it’s a separate sub-resource, not a property of the item itself.

Route name Method Path Purpose
voyti/api-v1-audit-log-index GET v1/audit-log Paginated, filterable audit-log listing
voyti/api-v1-rbac-index GET v1/rbac/{itemType} List roles or permissions
voyti/api-v1-rbac-create POST v1/rbac/{itemType} Create a role or permission
voyti/api-v1-rbac-update PATCH v1/rbac/{itemType}/{name} Update name/description/rule/children
voyti/api-v1-rbac-delete DELETE v1/rbac/{itemType}/{name} Delete a role or permission

When voyti-2fa is installed, a login for an account with 2FA enabled returns a challenge instead of a token:

{ "status": "challenge_required", "challengeToken": "...", "method": "totp", "isCodeBased": true, "expiresIn": 300 }

Submit the code (or a backup code, or a WebAuthn-style payload/domain pair for client-collected methods) along with the challengeToken to receive the real bearer token:

Route name Method Path Purpose
voyti/api-v1-auth-challenge-verify POST v1/auth/challenge/verify Verify the 2FA code (or backup code, or WebAuthn-style payload) and receive the real bearer token

Enrollment and management are also available - enabling/disabling a code-based method and regenerating backup codes, mirroring the same re-authentication rule as the HTML settings page. Enable returns a fresh set of backup codes directly in the response, since a JSON caller has no follow-up reveal page to redirect to:

Route name Method Path Purpose
voyti/api-v1-2fa-status GET v1/2fa Whether 2FA is enabled, which method, available methods, and whether unused backup codes remain
voyti/api-v1-2fa-enable POST v1/2fa/enable Enable a code-based method; returns a fresh set of backup codes
voyti/api-v1-2fa-disable POST v1/2fa/disable Disable 2FA (re-authentication required)
voyti/api-v1-2fa-backup-codes-regenerate POST v1/2fa/backup-codes/regenerate Invalidate existing backup codes and issue a fresh set (re-authentication required)

A code-based method’s own setup step must run first, or enable has nothing to verify a submitted code against - mirroring each package’s HTML setup screen. When voyti-2fa-totp is installed, setup/renew issue the QR code and secret; setup reuses the account’s existing secret, renew always issues a fresh one. When voyti-2fa-email is installed, send-code emails a fresh code (never returned in the response - only the mailer sees it):

Route name Method Path Purpose
voyti/api-v1-2fa-totp-setup GET v1/2fa/totp/setup QR code and secret, reusing the account’s existing pending secret if one exists
voyti/api-v1-2fa-totp-renew POST v1/2fa/totp/renew Always issues a fresh QR code and secret
voyti/api-v1-2fa-email-send-code POST v1/2fa/email/send-code Emails a fresh verification code

Registering a client-collected method (WebAuthn) isn’t done through the generic action above - it runs through its own dedicated ceremony. When voyti-2fa-webauthn is installed, the pending challenge normally kept in the session is instead persisted on the account’s own (not-yet-enabled) two-factor row between the two requests, since a bearer-token caller has no session continuity across them:

Route name Method Path Purpose
voyti/api-v1-2fa-webauthn-register-start POST v1/2fa/webauthn/register/start Builds the navigator.credentials.create() options and stashes the ceremony challenge
voyti/api-v1-2fa-webauthn-register-finish POST v1/2fa/webauthn/register/finish Verifies the attestation response, enables 2FA, and returns fresh backup codes

When voyti-gdpr is installed, self-service data export and account anonymization become available, delegating to that package’s own GdprExportService and AnonymizeUserService:

Route name Method Path Purpose
voyti/api-v1-gdpr-export GET v1/gdpr/export Data export as JSON
voyti/api-v1-gdpr-anonymize POST v1/gdpr/anonymize Password-confirmed anonymization; also revokes every bearer token for the account

When voyti-social-auth is installed, a popup-based OAuth2 flow becomes available. Unlike the HTML app’s social login, this doesn’t establish a session in the SPA itself - the popup completes the provider round-trip, then redirects to redirectUrl with a short-lived, single-use code rather than the bearer token directly, so the token never ends up in a URL or browser history entry:

Route name Method Path Purpose
voyti/api-v1-auth-social-callback GET v1/auth/social/{authclient} Starts (and handles the provider’s callback for) the OAuth2 popup flow
voyti/api-v1-auth-social-exchange POST v1/auth/social/exchange Trade the one-time code from the popup redirect for a real bearer token
// config/params.php
return [
    'yiirocks/voyti' => [
        'api' => [
            'social' => [
                'redirectUrl' => 'https://spa.example.com/oauth-callback',
            ],
        ],
    ],
];
redirectUrl string
''
SPA URL the OAuth2 popup redirects to after a social login attempt, with either ?code=... (success) or ?error=... in the query string. Required for the social-auth bridge to work; requests fail with 500 until it's set.

Only the guest-login path is supported: connecting a social account to an already-authenticated user, and completing a “pending” account link that needs manual registration first, both require request context this stateless popup callback doesn’t have. Either case is reported to the SPA as an error query parameter instead.