597 lines
9.8 KiB
Markdown
597 lines
9.8 KiB
Markdown
# b0esche.cloud API Reference
|
|
|
|
Base URL: `https://go.b0esche.cloud`
|
|
|
|
## Authentication
|
|
|
|
All authenticated endpoints require a JWT token in the Authorization header:
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
---
|
|
|
|
## Health Check
|
|
|
|
### GET /health
|
|
Check if the API is running.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"status": "ok",
|
|
"timestamp": "2026-01-13T19:00:00Z"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Authentication Endpoints
|
|
|
|
### Passkey Registration
|
|
|
|
#### POST /auth/passkey/register/start
|
|
Start passkey registration for a new user.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"username": "johndoe"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"publicKey": {
|
|
"challenge": "base64-encoded-challenge",
|
|
"rp": {
|
|
"name": "b0esche.cloud",
|
|
"id": "www.b0esche.cloud"
|
|
},
|
|
"user": {
|
|
"id": "base64-user-id",
|
|
"name": "johndoe",
|
|
"displayName": "johndoe"
|
|
},
|
|
"pubKeyCredParams": [...],
|
|
"timeout": 300000,
|
|
"attestation": "none"
|
|
}
|
|
}
|
|
```
|
|
|
|
#### POST /auth/passkey/register/verify
|
|
Complete passkey registration.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"username": "johndoe",
|
|
"credential": {
|
|
"id": "credential-id",
|
|
"rawId": "base64-raw-id",
|
|
"type": "public-key",
|
|
"response": {
|
|
"clientDataJSON": "base64-client-data",
|
|
"attestationObject": "base64-attestation"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"user": {
|
|
"id": "uuid",
|
|
"username": "johndoe"
|
|
},
|
|
"token": "jwt-token"
|
|
}
|
|
```
|
|
|
|
### Passkey Login
|
|
|
|
#### POST /auth/passkey/login/start
|
|
Start passkey authentication.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"username": "johndoe"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"publicKey": {
|
|
"challenge": "base64-challenge",
|
|
"timeout": 300000,
|
|
"rpId": "www.b0esche.cloud",
|
|
"allowCredentials": [...]
|
|
}
|
|
}
|
|
```
|
|
|
|
#### POST /auth/passkey/login/verify
|
|
Complete passkey authentication.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"username": "johndoe",
|
|
"credential": {
|
|
"id": "credential-id",
|
|
"rawId": "base64-raw-id",
|
|
"type": "public-key",
|
|
"response": {
|
|
"clientDataJSON": "base64-client-data",
|
|
"authenticatorData": "base64-auth-data",
|
|
"signature": "base64-signature"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"user": {
|
|
"id": "uuid",
|
|
"username": "johndoe",
|
|
"role": "user"
|
|
},
|
|
"token": "jwt-token"
|
|
}
|
|
```
|
|
|
|
### Device Management
|
|
|
|
#### GET /auth/passkey/devices
|
|
List user's registered passkeys.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"devices": [
|
|
{
|
|
"id": "uuid",
|
|
"credentialId": "credential-id",
|
|
"deviceLabel": "MacBook Pro",
|
|
"createdAt": "2026-01-01T00:00:00Z",
|
|
"lastUsedAt": "2026-01-13T19:00:00Z",
|
|
"backupEligible": true
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
#### POST /auth/passkey/devices/add
|
|
Add a new passkey to existing account.
|
|
|
|
#### DELETE /auth/passkey/devices/{passkeyId}
|
|
Remove a passkey from account.
|
|
|
|
### Recovery Codes
|
|
|
|
#### POST /auth/recovery/codes/generate
|
|
Generate new recovery codes (invalidates old ones).
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"codes": [
|
|
"XXXX-XXXX-XXXX",
|
|
"YYYY-YYYY-YYYY",
|
|
...
|
|
],
|
|
"expiresAt": "2027-01-13T00:00:00Z"
|
|
}
|
|
```
|
|
|
|
#### POST /auth/recovery/codes/use
|
|
Use a recovery code to authenticate.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"username": "johndoe",
|
|
"code": "XXXX-XXXX-XXXX"
|
|
}
|
|
```
|
|
|
|
### Password (Optional Fallback)
|
|
|
|
#### POST /auth/password/add
|
|
Add password to account.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"password": "secure-password"
|
|
}
|
|
```
|
|
|
|
#### DELETE /auth/password/remove
|
|
Remove password from account.
|
|
|
|
---
|
|
|
|
## User Endpoints
|
|
|
|
### GET /api/me
|
|
Get current user profile.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"id": "uuid",
|
|
"username": "johndoe",
|
|
"email": "john@example.com",
|
|
"displayName": "John Doe",
|
|
"role": "user",
|
|
"createdAt": "2026-01-01T00:00:00Z"
|
|
}
|
|
```
|
|
|
|
### PATCH /api/me
|
|
Update user profile.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"displayName": "John D.",
|
|
"email": "newemail@example.com"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Organization Endpoints
|
|
|
|
### GET /api/organizations
|
|
List user's organizations.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"organizations": [
|
|
{
|
|
"id": "uuid",
|
|
"name": "My Team",
|
|
"slug": "my-team",
|
|
"role": "owner",
|
|
"memberCount": 5,
|
|
"createdAt": "2026-01-01T00:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### POST /api/organizations
|
|
Create a new organization.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"name": "My New Team",
|
|
"slug": "my-new-team"
|
|
}
|
|
```
|
|
|
|
### GET /api/organizations/{orgId}
|
|
Get organization details.
|
|
|
|
### PATCH /api/organizations/{orgId}
|
|
Update organization.
|
|
|
|
### DELETE /api/organizations/{orgId}
|
|
Delete organization (owner only).
|
|
|
|
### GET /api/organizations/{orgId}/members
|
|
List organization members.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"members": [
|
|
{
|
|
"id": "uuid",
|
|
"userId": "user-uuid",
|
|
"username": "johndoe",
|
|
"displayName": "John Doe",
|
|
"role": "owner",
|
|
"joinedAt": "2026-01-01T00:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### POST /api/organizations/{orgId}/members
|
|
Add member to organization.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"userId": "user-uuid",
|
|
"role": "member"
|
|
}
|
|
```
|
|
|
|
### PATCH /api/organizations/{orgId}/members/{memberId}
|
|
Update member role.
|
|
|
|
### DELETE /api/organizations/{orgId}/members/{memberId}
|
|
Remove member from organization.
|
|
|
|
---
|
|
|
|
## File Endpoints
|
|
|
|
### GET /api/files
|
|
List files in a directory.
|
|
|
|
**Query Parameters:**
|
|
| Parameter | Type | Description |
|
|
|-----------|------|-------------|
|
|
| `path` | string | Directory path (default: `/`) |
|
|
| `orgId` | string | Organization ID (optional) |
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"files": [
|
|
{
|
|
"id": "uuid",
|
|
"name": "document.pdf",
|
|
"path": "/documents/document.pdf",
|
|
"type": "file",
|
|
"mimeType": "application/pdf",
|
|
"size": 1048576,
|
|
"createdAt": "2026-01-01T00:00:00Z",
|
|
"modifiedAt": "2026-01-13T19:00:00Z"
|
|
},
|
|
{
|
|
"id": "uuid",
|
|
"name": "photos",
|
|
"path": "/photos",
|
|
"type": "folder",
|
|
"createdAt": "2026-01-01T00:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### POST /api/files/upload
|
|
Upload a file.
|
|
|
|
**Request:** `multipart/form-data`
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `file` | file | The file to upload |
|
|
| `path` | string | Destination path |
|
|
| `orgId` | string | Organization ID (optional) |
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"file": {
|
|
"id": "uuid",
|
|
"name": "uploaded-file.pdf",
|
|
"path": "/documents/uploaded-file.pdf",
|
|
"size": 1048576
|
|
}
|
|
}
|
|
```
|
|
|
|
### GET /api/files/download
|
|
Download a file.
|
|
|
|
**Query Parameters:**
|
|
| Parameter | Type | Description |
|
|
|-----------|------|-------------|
|
|
| `path` | string | File path |
|
|
| `orgId` | string | Organization ID (optional) |
|
|
|
|
**Response:** File binary with appropriate Content-Type header.
|
|
|
|
### POST /api/files/folder
|
|
Create a folder.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"path": "/new-folder",
|
|
"orgId": "org-uuid"
|
|
}
|
|
```
|
|
|
|
### DELETE /api/files
|
|
Delete a file or folder.
|
|
|
|
**Query Parameters:**
|
|
| Parameter | Type | Description |
|
|
|-----------|------|-------------|
|
|
| `path` | string | Path to delete |
|
|
| `orgId` | string | Organization ID (optional) |
|
|
|
|
### POST /api/files/move
|
|
Move/rename a file or folder.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"sourcePath": "/old-name.pdf",
|
|
"destinationPath": "/new-name.pdf",
|
|
"orgId": "org-uuid"
|
|
}
|
|
```
|
|
|
|
### POST /api/files/copy
|
|
Copy a file or folder.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"sourcePath": "/original.pdf",
|
|
"destinationPath": "/copy.pdf",
|
|
"orgId": "org-uuid"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Admin Endpoints
|
|
|
|
*Requires admin or superadmin role.*
|
|
|
|
### GET /api/admin/users
|
|
List all users.
|
|
|
|
**Query Parameters:**
|
|
| Parameter | Type | Description |
|
|
|-----------|------|-------------|
|
|
| `page` | int | Page number (default: 1) |
|
|
| `limit` | int | Items per page (default: 50) |
|
|
| `search` | string | Search by username/email |
|
|
|
|
### GET /api/admin/users/{userId}
|
|
Get user details.
|
|
|
|
### PATCH /api/admin/users/{userId}
|
|
Update user (role, status).
|
|
|
|
### DELETE /api/admin/users/{userId}
|
|
Delete user account.
|
|
|
|
### Admin Invitations
|
|
|
|
#### GET /auth/admin/invitations
|
|
List admin invitations.
|
|
|
|
#### POST /auth/admin/invitations
|
|
Create admin invitation.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"username": "newadmin",
|
|
"roleId": "admin-role-uuid",
|
|
"expiresIn": 86400
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"invitation": {
|
|
"id": "uuid",
|
|
"token": "invite-token",
|
|
"expiresAt": "2026-01-14T19:00:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
#### POST /auth/admin/invitations/{token}/accept
|
|
Accept an admin invitation.
|
|
|
|
#### DELETE /auth/admin/invitations/{token}
|
|
Revoke an invitation.
|
|
|
|
---
|
|
|
|
## Activity Endpoints
|
|
|
|
### GET /api/activities
|
|
Get activity log.
|
|
|
|
**Query Parameters:**
|
|
| Parameter | Type | Description |
|
|
|-----------|------|-------------|
|
|
| `page` | int | Page number |
|
|
| `limit` | int | Items per page |
|
|
| `orgId` | string | Filter by organization |
|
|
| `userId` | string | Filter by user |
|
|
| `action` | string | Filter by action type |
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"activities": [
|
|
{
|
|
"id": "uuid",
|
|
"userId": "user-uuid",
|
|
"username": "johndoe",
|
|
"action": "file.upload",
|
|
"resourceType": "file",
|
|
"resourceId": "/documents/report.pdf",
|
|
"metadata": {
|
|
"size": 1048576
|
|
},
|
|
"createdAt": "2026-01-13T19:00:00Z"
|
|
}
|
|
],
|
|
"pagination": {
|
|
"page": 1,
|
|
"limit": 50,
|
|
"total": 150
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Error Responses
|
|
|
|
All errors follow this format:
|
|
|
|
```json
|
|
{
|
|
"error": {
|
|
"code": "ERROR_CODE",
|
|
"message": "Human-readable error message",
|
|
"details": {}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Common Error Codes
|
|
|
|
| Code | HTTP Status | Description |
|
|
|------|-------------|-------------|
|
|
| `UNAUTHORIZED` | 401 | Missing or invalid token |
|
|
| `FORBIDDEN` | 403 | Insufficient permissions |
|
|
| `NOT_FOUND` | 404 | Resource not found |
|
|
| `VALIDATION_ERROR` | 400 | Invalid request data |
|
|
| `CONFLICT` | 409 | Resource already exists |
|
|
| `INTERNAL_ERROR` | 500 | Server error |
|
|
|
|
---
|
|
|
|
## Rate Limiting
|
|
|
|
- **Authentication endpoints**: 10 requests/minute
|
|
- **API endpoints**: 100 requests/minute
|
|
- **File uploads**: 50 requests/hour
|
|
|
|
Rate limit headers:
|
|
```
|
|
X-RateLimit-Limit: 100
|
|
X-RateLimit-Remaining: 95
|
|
X-RateLimit-Reset: 1705172400
|
|
```
|
|
|
|
---
|
|
|
|
## Webhooks (Future)
|
|
|
|
Planned webhook events:
|
|
- `user.created`
|
|
- `user.deleted`
|
|
- `file.uploaded`
|
|
- `file.deleted`
|
|
- `org.member.added`
|
|
- `org.member.removed`
|