ultisuite-backend/internal/api/docs/openapi.yaml
R3D347HR4Y bd7534658a Refactor and enhance unified frontend and API features
- Updated environment configuration to unify frontend for mail and drive under a single service.
- Revised README to reflect changes in frontend setup and routing for the unified application.
- Introduced new API documentation endpoints for better accessibility of API specifications.
- Enhanced drive and mail services with improved handling of file uploads and metadata enrichment.
- Implemented new API token management features, including creation, listing, and revocation of tokens.
- Added tests for new functionalities in drive and mail services to ensure reliability and correctness.
2026-06-07 15:44:30 +02:00

553 lines
15 KiB
YAML

openapi: 3.1.0
info:
title: Ulti Suite API
version: 1.0.0
description: |
API REST Ultimail, UltiDrive et Contacts exposée par **ultid** sous `/api/v1`.
## Authentification
Deux modes :
| Mode | Header | Usage |
|------|--------|-------|
| **Session utilisateur** | `Authorization: Bearer <jwt_oidc>` | Interface web, apps avec login OIDC (Authentik) |
| **Token API** | `Authorization: Bearer ulti_<secret>` | Agents IA, scripts, intégrations programmatiques |
Les tokens API portent des permissions **fine-grained** (lecture/écriture par ressource) et des **scopes** optionnels (comptes mail, dossiers Drive).
## Permissions tokens API
Ressources principales :
- **Mail** : `mail.mailboxes`, `mail.labels`, `mail.messages`, `mail.search`, `mail.send`, `mail.attachments`, `mail.settings`, `mail.identities`, `mail.automation`
- **Drive** : `drive.folders`, `drive.files`, `drive.thumbnails`, `drive.download`, `drive.share`, `drive.upload`, `drive.rename`, `drive.move`, `drive.copy`
- **Contacts** : `contacts.read`, `contacts.search`, `contacts.write`, `contacts.delete`, `contacts.labels`
- **Automatisations** : `automation.rules`, `automation.webhooks`, `automation.llm`, `automation.search`, `automation.api_tokens` (super admin)
Chaque ressource accepte `read` et/ou `write` selon le cas.
## Scopes
- **mail_scope** : `{ "all_accounts": true }` ou `{ "all_accounts": false, "account_ids": ["uuid", ...] }`
- **drive_scope** : `{ "all_folders": true }` ou `{ "all_folders": false, "folder_paths": ["/Projects", ...] }`
servers:
- url: /api/v1
description: API ultid (proxifiée par nginx)
tags:
- name: Tokens API
description: Gestion des jetons programmatiques
- name: Mail
description: Messages, boîtes, envoi
- name: Drive
description: Fichiers et dossiers Nextcloud
- name: Contacts
description: Carnet d'adresses
- name: Automatisations
description: Règles, webhooks, fournisseurs
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT or ulti_token
description: JWT OIDC (session) ou token API `ulti_…`
schemas:
ApiTokenPermissionGrant:
type: object
required: [resource, read, write]
properties:
resource:
type: string
example: mail.messages
read:
type: boolean
write:
type: boolean
ApiTokenMailScope:
type: object
properties:
all_accounts:
type: boolean
account_ids:
type: array
items:
type: string
format: uuid
ApiTokenDriveScope:
type: object
properties:
all_folders:
type: boolean
folder_paths:
type: array
items:
type: string
example: /Projects
ApiToken:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
token_prefix:
type: string
example: ulti_a3f9b2c1
permissions:
type: array
items:
$ref: '#/components/schemas/ApiTokenPermissionGrant'
mail_scope:
$ref: '#/components/schemas/ApiTokenMailScope'
drive_scope:
$ref: '#/components/schemas/ApiTokenDriveScope'
created_at:
type: string
format: date-time
last_used_at:
type: string
format: date-time
expires_at:
type: string
format: date-time
ApiTokenCreated:
allOf:
- $ref: '#/components/schemas/ApiToken'
- type: object
required: [token]
properties:
token:
type: string
description: Secret complet — affiché une seule fois à la création
CreateApiTokenRequest:
type: object
required: [name, permissions, mail_scope, drive_scope]
properties:
name:
type: string
permissions:
type: array
items:
$ref: '#/components/schemas/ApiTokenPermissionGrant'
mail_scope:
$ref: '#/components/schemas/ApiTokenMailScope'
drive_scope:
$ref: '#/components/schemas/ApiTokenDriveScope'
expires_at:
type: string
format: date-time
MessageSummary:
type: object
properties:
id:
type: string
format: uuid
account_id:
type: string
format: uuid
subject:
type: string
snippet:
type: string
date:
type: string
format: date-time
DriveFile:
type: object
properties:
path:
type: string
name:
type: string
type:
type: string
enum: [file, directory]
size:
type: integer
mime_type:
type: string
last_modified:
type: string
format: date-time
Error:
type: object
properties:
error:
type: object
properties:
code:
type: string
message:
type: string
security:
- bearerAuth: []
paths:
/mail/api-tokens:
get:
tags: [Tokens API]
summary: Lister les tokens API
description: Nécessite une session OIDC ou un token avec `automation.api_tokens` (écriture).
responses:
'200':
description: Liste des tokens actifs (sans secret)
content:
application/json:
schema:
type: object
properties:
tokens:
type: array
items:
$ref: '#/components/schemas/ApiToken'
post:
tags: [Tokens API]
summary: Créer un token API
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateApiTokenRequest'
example:
name: Agent tri support
permissions:
- resource: mail.messages
read: true
write: false
- resource: mail.labels
read: true
write: true
mail_scope:
all_accounts: false
account_ids: ["550e8400-e29b-41d4-a716-446655440000"]
drive_scope:
all_folders: true
folder_paths: []
responses:
'201':
description: Token créé — copier le champ `token` immédiatement
content:
application/json:
schema:
$ref: '#/components/schemas/ApiTokenCreated'
/mail/api-tokens/{tokenID}:
delete:
tags: [Tokens API]
summary: Révoquer un token API
parameters:
- name: tokenID
in: path
required: true
schema:
type: string
format: uuid
responses:
'204':
description: Token révoqué
/mail/messages:
get:
tags: [Mail]
summary: Lister les messages
description: |
Permission requise : `mail.messages` (lecture).
Scope mail appliqué automatiquement si le token est restreint à certains comptes.
parameters:
- name: account_id
in: query
schema:
type: string
format: uuid
- name: folder
in: query
schema:
type: string
example: inbox
- name: page
in: query
schema:
type: integer
- name: page_size
in: query
schema:
type: integer
responses:
'200':
description: Page de messages
content:
application/json:
schema:
type: object
properties:
messages:
type: array
items:
$ref: '#/components/schemas/MessageSummary'
/mail/messages/{messageID}:
get:
tags: [Mail]
summary: Lire un message
description: Vérifie que le message appartient à un compte autorisé par le token.
parameters:
- name: messageID
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: Message complet
'403':
description: Compte hors scope du token
/mail/search:
get:
tags: [Mail]
summary: Rechercher des messages
description: Permission `mail.search` (lecture).
parameters:
- name: q
in: query
schema:
type: string
- name: account_id
in: query
schema:
type: string
format: uuid
- name: from
in: query
schema:
type: string
responses:
'200':
description: Résultats de recherche
/mail/send:
post:
tags: [Mail]
summary: Envoyer un message
description: Permission `mail.send` (écriture). `account_id` doit être dans le scope.
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [account_id, to, subject]
properties:
account_id:
type: string
format: uuid
to:
type: array
items:
type: string
subject:
type: string
body_html:
type: string
responses:
'200':
description: Message envoyé ou mis en file
/mail/rules:
get:
tags: [Automatisations]
summary: Lister les règles de tri
description: Permission `automation.rules` (lecture).
responses:
'200':
description: Règles
post:
tags: [Automatisations]
summary: Créer une règle
description: Permission `automation.rules` (écriture).
responses:
'201':
description: Règle créée
/mail/webhooks:
get:
tags: [Automatisations]
summary: Lister les webhooks
description: Permission `automation.webhooks` (lecture).
responses:
'200':
description: Webhooks
post:
tags: [Automatisations]
summary: Créer un webhook
responses:
'201':
description: Webhook créé
/drive/files/{path}:
get:
tags: [Drive]
summary: Lister un dossier
description: Permission `drive.folders` ou `drive.files` (lecture). Path relatif au Drive.
parameters:
- name: path
in: path
required: true
schema:
type: string
example: Projects/docs
responses:
'200':
description: Contenu du dossier
content:
application/json:
schema:
type: object
properties:
files:
type: array
items:
$ref: '#/components/schemas/DriveFile'
post:
tags: [Drive]
summary: Uploader un fichier
description: Permission `drive.upload` (écriture). Path = dossier cible.
parameters:
- name: path
in: path
required: true
schema:
type: string
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
responses:
'201':
description: Fichier uploadé
/drive/download/{path}:
get:
tags: [Drive]
summary: Télécharger un fichier
description: Permission `drive.download` (lecture).
parameters:
- name: path
in: path
required: true
schema:
type: string
responses:
'200':
description: Contenu binaire
/drive/preview/{path}:
get:
tags: [Drive]
summary: Miniature / aperçu
description: Permission `drive.thumbnails` (lecture).
parameters:
- name: path
in: path
required: true
schema:
type: string
responses:
'200':
description: Image ou flux de prévisualisation
/contacts/search:
get:
tags: [Contacts]
summary: Rechercher des contacts
description: Permission `contacts.search` (lecture).
parameters:
- name: q
in: query
required: true
schema:
type: string
responses:
'200':
description: Contacts correspondants
/contacts/books/{bookID}:
get:
tags: [Contacts]
summary: Lister les contacts d'un carnet
description: Permission `contacts.read` (lecture).
parameters:
- name: bookID
in: path
required: true
schema:
type: string
responses:
'200':
description: Contacts du carnet
post:
tags: [Contacts]
summary: Créer un contact
description: Permission `contacts.write` (écriture).
responses:
'201':
description: Contact créé
/contacts/discovery/llm-settings:
get:
tags: [Automatisations]
summary: Lire les fournisseurs LLM
description: Permission `automation.llm` (lecture).
responses:
'200':
description: Configuration LLM
put:
tags: [Automatisations]
summary: Mettre à jour les fournisseurs LLM
description: Permission `automation.llm` (écriture).
responses:
'200':
description: Configuration mise à jour
/search:
get:
tags: [Mail, Drive, Contacts]
summary: Recherche cross-suite
description: |
Vérifie les permissions selon `types` :
- `mail` → `mail.search`
- `drive` → `drive.files`
- `contacts` → `contacts.search`
parameters:
- name: q
in: query
required: true
schema:
type: string
- name: types
in: query
schema:
type: string
example: mail,contacts,drive
- name: account_id
in: query
schema:
type: string
format: uuid
responses:
'200':
description: Résultats agrégés