314 lines
8.6 KiB
YAML
314 lines
8.6 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: Drive v2 API
|
|
version: 0.0.0
|
|
description: >-
|
|
Contract-first API for Drive v2. The current Phase 1 persistence foundation
|
|
exposes only setup status and health operations; product endpoints are added
|
|
with their implementation.
|
|
servers:
|
|
- url: /
|
|
paths:
|
|
/api/v1/setup/status:
|
|
get:
|
|
security: []
|
|
operationId: getSetupStatus
|
|
summary: Report whether the owner account has been initialized
|
|
responses:
|
|
"200":
|
|
description: Current setup state
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/SetupStatus"
|
|
"503":
|
|
description: Setup state cannot be read because a required dependency is unavailable
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/Problem"
|
|
/api/v1/setup:
|
|
post:
|
|
security: []
|
|
operationId: createOwner
|
|
summary: Atomically create the single owner and initial browser session
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/OwnerSetupRequest"
|
|
responses:
|
|
"201":
|
|
description: Owner, recovery codes, root node, and browser session were created
|
|
headers:
|
|
Set-Cookie:
|
|
description: Secure host-only session and CSRF cookies
|
|
schema:
|
|
type: string
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/OwnerSetupResult"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"409":
|
|
description: Owner setup has already completed
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/Problem"
|
|
"422":
|
|
description: Username, display name, or password failed validation
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/Problem"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
/api/v1/sessions:
|
|
post:
|
|
security: []
|
|
operationId: createSession
|
|
summary: Authenticate the owner and create a revocable browser session
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/LoginRequest"
|
|
responses:
|
|
"201":
|
|
description: Browser session created
|
|
headers:
|
|
Set-Cookie:
|
|
description: Secure host-only session and CSRF cookies
|
|
schema:
|
|
type: string
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/BrowserSession"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/AuthenticationRequired"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
/api/v1/sessions/current:
|
|
get:
|
|
security:
|
|
- browserSession: []
|
|
operationId: getCurrentSession
|
|
summary: Read the current browser session
|
|
responses:
|
|
"200":
|
|
description: Current browser session
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/BrowserSession"
|
|
"401":
|
|
$ref: "#/components/responses/AuthenticationRequired"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
delete:
|
|
security:
|
|
- browserSession: []
|
|
operationId: deleteCurrentSession
|
|
summary: Revoke the current browser session
|
|
parameters:
|
|
- name: X-CSRF-Token
|
|
in: header
|
|
required: true
|
|
schema:
|
|
type: string
|
|
minLength: 32
|
|
responses:
|
|
"204":
|
|
description: Session revoked and browser cookies expired
|
|
"401":
|
|
$ref: "#/components/responses/AuthenticationRequired"
|
|
"403":
|
|
description: CSRF validation failed
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/Problem"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
/health/live:
|
|
get:
|
|
security: []
|
|
operationId: getLiveness
|
|
summary: Report process liveness
|
|
responses:
|
|
"200":
|
|
description: Process is live
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/HealthStatus"
|
|
/health/ready:
|
|
get:
|
|
security: []
|
|
operationId: getReadiness
|
|
summary: Report dependency readiness
|
|
responses:
|
|
"200":
|
|
description: Process is ready
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/HealthStatus"
|
|
"503":
|
|
description: A required dependency is unavailable
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/Problem"
|
|
components:
|
|
securitySchemes:
|
|
browserSession:
|
|
type: apiKey
|
|
in: cookie
|
|
name: __Host-drive_session
|
|
responses:
|
|
InvalidRequest:
|
|
description: Request body is malformed or contains unknown fields
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/Problem"
|
|
AuthenticationRequired:
|
|
description: A valid browser session is required
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/Problem"
|
|
InternalError:
|
|
description: The operation failed unexpectedly
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/Problem"
|
|
schemas:
|
|
OwnerSetupRequest:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [username, displayName, password]
|
|
properties:
|
|
username:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 128
|
|
displayName:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 128
|
|
password:
|
|
type: string
|
|
format: password
|
|
minLength: 12
|
|
maxLength: 1024
|
|
LoginRequest:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [username, password]
|
|
properties:
|
|
username:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 128
|
|
password:
|
|
type: string
|
|
format: password
|
|
maxLength: 1024
|
|
OwnerSetupResult:
|
|
type: object
|
|
required: [owner, recoveryCodes, session]
|
|
properties:
|
|
owner:
|
|
$ref: "#/components/schemas/Owner"
|
|
recoveryCodes:
|
|
type: array
|
|
minItems: 10
|
|
maxItems: 10
|
|
items:
|
|
type: string
|
|
session:
|
|
$ref: "#/components/schemas/BrowserSession"
|
|
Owner:
|
|
type: object
|
|
required: [id, username, displayName, rootNodeId]
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
username:
|
|
type: string
|
|
displayName:
|
|
type: string
|
|
rootNodeId:
|
|
type: string
|
|
format: uuid
|
|
BrowserSession:
|
|
type: object
|
|
required: [id, ownerId, username, displayName, authenticatedAt, lastSeenAt, expiresAt]
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
ownerId:
|
|
type: string
|
|
format: uuid
|
|
username:
|
|
type: string
|
|
displayName:
|
|
type: string
|
|
authenticatedAt:
|
|
type: string
|
|
format: date-time
|
|
lastSeenAt:
|
|
type: string
|
|
format: date-time
|
|
expiresAt:
|
|
type: string
|
|
format: date-time
|
|
SetupStatus:
|
|
type: object
|
|
required: [initialized, phase, version]
|
|
properties:
|
|
initialized:
|
|
type: boolean
|
|
phase:
|
|
type: string
|
|
version:
|
|
type: string
|
|
HealthStatus:
|
|
type: object
|
|
required: [status]
|
|
properties:
|
|
status:
|
|
type: string
|
|
enum: [live, ready]
|
|
Problem:
|
|
type: object
|
|
required: [type, title, status, code]
|
|
properties:
|
|
type:
|
|
type: string
|
|
format: uri-reference
|
|
title:
|
|
type: string
|
|
status:
|
|
type: integer
|
|
minimum: 100
|
|
maximum: 599
|
|
detail:
|
|
type: string
|
|
instance:
|
|
type: string
|
|
format: uri-reference
|
|
code:
|
|
type: string
|