add swagger.yaml
This commit is contained in:
+626
@@ -0,0 +1,626 @@
|
|||||||
|
openapi: 3.1.0
|
||||||
|
info:
|
||||||
|
title: Trusted AI Auth API
|
||||||
|
version: '1.0.0'
|
||||||
|
description: >
|
||||||
|
Authentication and session-management endpoints required to reach the protected analyst UI
|
||||||
|
(dashboard, transaction review, company search, and company transactions).
|
||||||
|
servers:
|
||||||
|
- url: https://trusted-ai.local
|
||||||
|
description: Local development (composer run dev)
|
||||||
|
- url: https://api.trusted-ai.example.com
|
||||||
|
description: Production
|
||||||
|
tags:
|
||||||
|
- name: Auth
|
||||||
|
description: Credential, session, and verification endpoints.
|
||||||
|
- name: TwoFactor
|
||||||
|
description: Manage the analyst’s Time-based One Time Password (TOTP) second factor.
|
||||||
|
components:
|
||||||
|
securitySchemes:
|
||||||
|
sessionCookie:
|
||||||
|
type: apiKey
|
||||||
|
in: cookie
|
||||||
|
name: laravel_session
|
||||||
|
description: Issued after login/two-factor completion; required for all protected routes.
|
||||||
|
xsrfToken:
|
||||||
|
type: apiKey
|
||||||
|
in: header
|
||||||
|
name: X-XSRF-TOKEN
|
||||||
|
description: CSRF token minted via `/sanctum/csrf-cookie` (or HTML meta); required by state-changing requests.
|
||||||
|
schemas:
|
||||||
|
AuthUser:
|
||||||
|
type: object
|
||||||
|
required: [id, name, email, emailVerified]
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
example: 143
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
example: Alex Analyst
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
format: email
|
||||||
|
example: analyst@example.com
|
||||||
|
emailVerified:
|
||||||
|
type: boolean
|
||||||
|
description: Indicates whether the analyst passes the `verified` middleware.
|
||||||
|
example: true
|
||||||
|
emailVerifiedAt:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
nullable: true
|
||||||
|
example: '2024-03-18T08:31:12Z'
|
||||||
|
roles:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
example: [analyst]
|
||||||
|
createdAt:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
updatedAt:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
LoginResponse:
|
||||||
|
type: object
|
||||||
|
required: [user, twoFactorRequired]
|
||||||
|
properties:
|
||||||
|
user:
|
||||||
|
$ref: '#/components/schemas/AuthUser'
|
||||||
|
twoFactorRequired:
|
||||||
|
type: boolean
|
||||||
|
description: True when the next step is `/two-factor-challenge`.
|
||||||
|
example: false
|
||||||
|
TwoFactorPending:
|
||||||
|
type: object
|
||||||
|
required: [twoFactorRequired]
|
||||||
|
properties:
|
||||||
|
twoFactorRequired:
|
||||||
|
type: boolean
|
||||||
|
const: true
|
||||||
|
challengeToken:
|
||||||
|
type: string
|
||||||
|
description: Echo of the `login.id` stored server-side; clients must keep the accompanying session cookie.
|
||||||
|
example: 9b6c11f7-527a-4dc9-9c2b-8923e7c7a418
|
||||||
|
remember:
|
||||||
|
type: boolean
|
||||||
|
description: Remember-me preference preserved through the challenge.
|
||||||
|
example: true
|
||||||
|
TwoFactorSuccess:
|
||||||
|
type: object
|
||||||
|
required: [user]
|
||||||
|
properties:
|
||||||
|
user:
|
||||||
|
$ref: '#/components/schemas/AuthUser'
|
||||||
|
ValidationError:
|
||||||
|
type: object
|
||||||
|
required: [message, errors]
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
example: The given data was invalid.
|
||||||
|
errors:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
example:
|
||||||
|
email:
|
||||||
|
- These credentials do not match our records.
|
||||||
|
MessageResponse:
|
||||||
|
type: object
|
||||||
|
required: [message]
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
example: If an account exists, a reset link has been sent.
|
||||||
|
TooManyRequestsError:
|
||||||
|
type: object
|
||||||
|
required: [message, retryAfterSeconds]
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
example: Too many login attempts. Try again in 48 seconds.
|
||||||
|
retryAfterSeconds:
|
||||||
|
type: integer
|
||||||
|
example: 48
|
||||||
|
RecoveryCodes:
|
||||||
|
type: object
|
||||||
|
required: [codes]
|
||||||
|
properties:
|
||||||
|
codes:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
example: [JQ7L-9PKM, ZG28-5TQF]
|
||||||
|
QrCodeSvg:
|
||||||
|
type: object
|
||||||
|
required: [svg]
|
||||||
|
properties:
|
||||||
|
svg:
|
||||||
|
type: string
|
||||||
|
format: byte
|
||||||
|
description: Base64-encoded SVG markup for authenticator enrollment.
|
||||||
|
SecretKey:
|
||||||
|
type: object
|
||||||
|
required: [secret]
|
||||||
|
properties:
|
||||||
|
secret:
|
||||||
|
type: string
|
||||||
|
description: Plain-text TOTP secret for manual entry.
|
||||||
|
example: NB2W45DFOIZA====
|
||||||
|
paths:
|
||||||
|
/auth/session:
|
||||||
|
get:
|
||||||
|
tags: [Auth]
|
||||||
|
summary: Fetch the authenticated analyst
|
||||||
|
description: >
|
||||||
|
Confirms session status and email verification before loading guarded UI routes.
|
||||||
|
security:
|
||||||
|
- sessionCookie: []
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Active, verified session.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/AuthUser'
|
||||||
|
'401':
|
||||||
|
description: Missing or expired session cookie.
|
||||||
|
'403':
|
||||||
|
description: Analyst authenticated but email remains unverified.
|
||||||
|
/login:
|
||||||
|
post:
|
||||||
|
tags: [Auth]
|
||||||
|
summary: Authenticate an analyst
|
||||||
|
description: >
|
||||||
|
Validates credentials and issues a new session cookie, matching the login Volt component.
|
||||||
|
security:
|
||||||
|
- xsrfToken: []
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required: [email, password]
|
||||||
|
properties:
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
format: email
|
||||||
|
example: analyst@example.com
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
format: password
|
||||||
|
example: correct-horse-battery-staple
|
||||||
|
remember:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Login successful; analyst may navigate to protected pages.
|
||||||
|
headers:
|
||||||
|
Set-Cookie:
|
||||||
|
description: Refreshed `laravel_session` cookie.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/LoginResponse'
|
||||||
|
'202':
|
||||||
|
description: Second factor required before granting access.
|
||||||
|
headers:
|
||||||
|
Set-Cookie:
|
||||||
|
description: Session cookie plus `login.id`/`login.remember` context.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/TwoFactorPending'
|
||||||
|
'422':
|
||||||
|
description: Validation failed (bad credentials, throttled).
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ValidationError'
|
||||||
|
'429':
|
||||||
|
description: Too many attempts; obey lockout timings.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/TooManyRequestsError'
|
||||||
|
/two-factor-challenge:
|
||||||
|
post:
|
||||||
|
tags: [Auth]
|
||||||
|
summary: Confirm the TOTP or recovery code
|
||||||
|
description: >
|
||||||
|
Completes the pending session when two-factor authentication is enabled.
|
||||||
|
security:
|
||||||
|
- xsrfToken: []
|
||||||
|
- sessionCookie: []
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
oneOf:
|
||||||
|
- required: [code]
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
pattern: '^\d{6}$'
|
||||||
|
description: 6-digit TOTP value.
|
||||||
|
- required: [recovery_code]
|
||||||
|
properties:
|
||||||
|
recovery_code:
|
||||||
|
type: string
|
||||||
|
description: Emergency recovery code.
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Two-factor validated; session promoted to fully authenticated.
|
||||||
|
headers:
|
||||||
|
Set-Cookie:
|
||||||
|
description: Session cookie extended per remember-me preference.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/TwoFactorSuccess'
|
||||||
|
'422':
|
||||||
|
description: Invalid TOTP or recovery code.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ValidationError'
|
||||||
|
'429':
|
||||||
|
description: Too many challenge attempts (Fortify `two-factor` limiter).
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/TooManyRequestsError'
|
||||||
|
/logout:
|
||||||
|
post:
|
||||||
|
tags: [Auth]
|
||||||
|
summary: Terminate the active session
|
||||||
|
description: >
|
||||||
|
Logs the analyst out and invalidates the session cookie.
|
||||||
|
security:
|
||||||
|
- xsrfToken: []
|
||||||
|
- sessionCookie: []
|
||||||
|
responses:
|
||||||
|
'204':
|
||||||
|
description: Logout succeeded; client should discard session cookies.
|
||||||
|
'401':
|
||||||
|
description: Analyst was not logged in.
|
||||||
|
/register:
|
||||||
|
post:
|
||||||
|
tags: [Auth]
|
||||||
|
summary: Register a new analyst
|
||||||
|
description: >
|
||||||
|
Creates an account and authenticates immediately, matching the register Volt component.
|
||||||
|
security:
|
||||||
|
- xsrfToken: []
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required: [name, email, password, password_confirmation]
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
example: Jamie Investigator
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
format: email
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
format: password
|
||||||
|
password_confirmation:
|
||||||
|
type: string
|
||||||
|
format: password
|
||||||
|
responses:
|
||||||
|
'201':
|
||||||
|
description: Account created; dashboard can load.
|
||||||
|
headers:
|
||||||
|
Set-Cookie:
|
||||||
|
description: Session cookie for the new account.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/LoginResponse'
|
||||||
|
'422':
|
||||||
|
description: Validation errors (duplicate email, weak password, mismatch).
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ValidationError'
|
||||||
|
/forgot-password:
|
||||||
|
post:
|
||||||
|
tags: [Auth]
|
||||||
|
summary: Send password reset link
|
||||||
|
description: >
|
||||||
|
Sends the reset email while obscuring account existence.
|
||||||
|
security:
|
||||||
|
- xsrfToken: []
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required: [email]
|
||||||
|
properties:
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
format: email
|
||||||
|
responses:
|
||||||
|
'202':
|
||||||
|
description: Reset notification dispatched if the account exists.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/MessageResponse'
|
||||||
|
'422':
|
||||||
|
description: Email field invalid.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ValidationError'
|
||||||
|
/reset-password:
|
||||||
|
post:
|
||||||
|
tags: [Auth]
|
||||||
|
summary: Reset password with token
|
||||||
|
description: >
|
||||||
|
Applies a valid reset token and forces the analyst to log in again.
|
||||||
|
security:
|
||||||
|
- xsrfToken: []
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required: [token, email, password, password_confirmation]
|
||||||
|
properties:
|
||||||
|
token:
|
||||||
|
type: string
|
||||||
|
description: Token from the password reset email.
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
format: email
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
format: password
|
||||||
|
password_confirmation:
|
||||||
|
type: string
|
||||||
|
format: password
|
||||||
|
responses:
|
||||||
|
'204':
|
||||||
|
description: Password updated; analyst should be redirected to `/login`.
|
||||||
|
'422':
|
||||||
|
description: Invalid token or password validation failure.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ValidationError'
|
||||||
|
/user/confirm-password:
|
||||||
|
post:
|
||||||
|
tags: [Auth]
|
||||||
|
summary: Confirm password for sensitive operations
|
||||||
|
description: >
|
||||||
|
Required before enabling/disabling 2FA when the `password.confirm` middleware is active.
|
||||||
|
security:
|
||||||
|
- xsrfToken: []
|
||||||
|
- sessionCookie: []
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required: [password]
|
||||||
|
properties:
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
format: password
|
||||||
|
responses:
|
||||||
|
'204':
|
||||||
|
description: Password confirmed for the next 900 seconds.
|
||||||
|
'422':
|
||||||
|
description: Wrong password submitted.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ValidationError'
|
||||||
|
/email/verification-notification:
|
||||||
|
post:
|
||||||
|
tags: [Auth]
|
||||||
|
summary: Resend email verification link
|
||||||
|
description: >
|
||||||
|
Needed because dashboard and investigation routes require the `verified` middleware.
|
||||||
|
security:
|
||||||
|
- xsrfToken: []
|
||||||
|
- sessionCookie: []
|
||||||
|
responses:
|
||||||
|
'202':
|
||||||
|
description: Verification email dispatched (throttled at 6/hour).
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/MessageResponse'
|
||||||
|
'429':
|
||||||
|
description: Throttle limit exceeded.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/TooManyRequestsError'
|
||||||
|
/email/verify/{id}/{hash}:
|
||||||
|
get:
|
||||||
|
tags: [Auth]
|
||||||
|
summary: Mark email address as verified
|
||||||
|
description: >
|
||||||
|
Consumes the signed verification link and redirects to the front end.
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
- name: hash
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: signature
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: expires
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
responses:
|
||||||
|
'302':
|
||||||
|
description: Redirect to `/dashboard?verified=1` (default).
|
||||||
|
headers:
|
||||||
|
Location:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
'403':
|
||||||
|
description: Link expired or signature mismatch.
|
||||||
|
/user/two-factor-authentication:
|
||||||
|
post:
|
||||||
|
tags: [TwoFactor]
|
||||||
|
summary: Start enrolling two-factor authentication
|
||||||
|
description: >
|
||||||
|
Generates the TOTP secret and makes QR/manual data available.
|
||||||
|
security:
|
||||||
|
- xsrfToken: []
|
||||||
|
- sessionCookie: []
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Enrollment started; fetch QR/secret next.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/MessageResponse'
|
||||||
|
example:
|
||||||
|
message: Two-factor authentication seed generated.
|
||||||
|
'423':
|
||||||
|
description: Password confirmation required.
|
||||||
|
'429':
|
||||||
|
description: Too many enable attempts.
|
||||||
|
delete:
|
||||||
|
tags: [TwoFactor]
|
||||||
|
summary: Disable two-factor authentication
|
||||||
|
security:
|
||||||
|
- xsrfToken: []
|
||||||
|
- sessionCookie: []
|
||||||
|
responses:
|
||||||
|
'204':
|
||||||
|
description: Two-factor disabled and secrets cleared.
|
||||||
|
'423':
|
||||||
|
description: Password confirmation required.
|
||||||
|
/user/confirmed-two-factor-authentication:
|
||||||
|
post:
|
||||||
|
tags: [TwoFactor]
|
||||||
|
summary: Confirm two-factor setup
|
||||||
|
description: >
|
||||||
|
Completes enrollment by verifying a TOTP code.
|
||||||
|
security:
|
||||||
|
- xsrfToken: []
|
||||||
|
- sessionCookie: []
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required: [code]
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
pattern: '^\d{6}$'
|
||||||
|
description: 6-digit TOTP code.
|
||||||
|
responses:
|
||||||
|
'204':
|
||||||
|
description: Two-factor authentication confirmed.
|
||||||
|
'422':
|
||||||
|
description: Invalid confirmation code.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ValidationError'
|
||||||
|
/user/two-factor-qr-code:
|
||||||
|
get:
|
||||||
|
tags: [TwoFactor]
|
||||||
|
summary: Retrieve QR code SVG
|
||||||
|
description: >
|
||||||
|
Supplies the SVG rendered in the settings modal during enrollment.
|
||||||
|
security:
|
||||||
|
- sessionCookie: []
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: SVG payload for authenticator scanning.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/QrCodeSvg'
|
||||||
|
'404':
|
||||||
|
description: Two-factor enrollment not in progress.
|
||||||
|
/user/two-factor-secret-key:
|
||||||
|
get:
|
||||||
|
tags: [TwoFactor]
|
||||||
|
summary: Retrieve manual setup key
|
||||||
|
description: >
|
||||||
|
Provides the fallback alphanumeric key shown alongside the QR code.
|
||||||
|
security:
|
||||||
|
- sessionCookie: []
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Secret key for manual entry.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/SecretKey'
|
||||||
|
/user/two-factor-recovery-codes:
|
||||||
|
get:
|
||||||
|
tags: [TwoFactor]
|
||||||
|
summary: List recovery codes
|
||||||
|
security:
|
||||||
|
- sessionCookie: []
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Recovery codes ready for display or download.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/RecoveryCodes'
|
||||||
|
post:
|
||||||
|
tags: [TwoFactor]
|
||||||
|
summary: Regenerate recovery codes
|
||||||
|
security:
|
||||||
|
- xsrfToken: []
|
||||||
|
- sessionCookie: []
|
||||||
|
responses:
|
||||||
|
'201':
|
||||||
|
description: New recovery codes generated and returned.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/RecoveryCodes'
|
||||||
|
'423':
|
||||||
|
description: Password confirmation required.
|
||||||
Reference in New Issue
Block a user