Skip to content

Commit 2fb9339

Browse files
committed
fix: update signature count after signing & add API documentation
- Fix HomePage.vue to update signatureCount after user signs - Fix EmbedPage.vue to use signatureCount from API instead of signatures.length - Adapt E2E tests to reflect signature visibility security model - Create missing API documentation (docs/en/api.md, docs/fr/api.md) - Document Docker healthcheck in deployment guides - Document signature endpoint access control rules - Fix MagicLink auto-detection description in READMEs
1 parent f43c3c5 commit 2fb9339

File tree

12 files changed

+926
-38
lines changed

12 files changed

+926
-38
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ ACKIFY_OAUTH_CLIENT_SECRET=your_client_secret
136136

137137
**Auto-detection**:
138138
- OAuth is enabled automatically if `ACKIFY_OAUTH_CLIENT_ID` and `ACKIFY_OAUTH_CLIENT_SECRET` are set
139-
- MagicLink is enabled automatically if `ACKIFY_MAIL_HOST` is configured
139+
- MagicLink requires explicit activation: `ACKIFY_AUTH_MAGICLINK_ENABLED=true` + SMTP configuration
140+
- SMTP/Email service (for reminders) is enabled automatically when `ACKIFY_MAIL_HOST` is configured
140141
- You can use **both methods simultaneously** for maximum flexibility
141142

142143
See [docs/en/configuration.md](docs/en/configuration.md) for all options.

README_FR.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ ACKIFY_OAUTH_CLIENT_SECRET=votre_client_secret
136136

137137
**Auto-détection** :
138138
- OAuth activé automatiquement si `ACKIFY_OAUTH_CLIENT_ID` et `ACKIFY_OAUTH_CLIENT_SECRET` sont définis
139-
- MagicLink activé automatiquement si `ACKIFY_MAIL_HOST` est configuré
139+
- MagicLink nécessite une activation explicite : `ACKIFY_AUTH_MAGICLINK_ENABLED=true` + configuration SMTP
140+
- Le service SMTP/Email (pour les rappels) est activé automatiquement quand `ACKIFY_MAIL_HOST` est configuré
140141
- Vous pouvez utiliser **les deux méthodes simultanément** pour une flexibilité maximale
141142

142143
Voir [docs/fr/configuration.md](docs/fr/configuration.md) pour toutes les options.

docs/en/api.md

Lines changed: 342 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,342 @@
1+
# API Reference
2+
3+
Complete REST API documentation for Ackify.
4+
5+
## Base URL
6+
7+
```
8+
https://your-domain.com/api/v1
9+
```
10+
11+
## Authentication
12+
13+
Most endpoints require authentication via session cookie (OAuth2 or MagicLink).
14+
15+
**Headers**:
16+
- `X-CSRF-Token` - Required for POST/PUT/DELETE requests
17+
18+
Get CSRF token:
19+
```http
20+
GET /api/v1/csrf
21+
```
22+
23+
## Endpoints
24+
25+
### Health
26+
27+
#### Health Check
28+
29+
```http
30+
GET /api/v1/health
31+
```
32+
33+
**Response** (200 OK):
34+
```json
35+
{
36+
"status": "healthy",
37+
"database": "connected"
38+
}
39+
```
40+
41+
---
42+
43+
### Authentication
44+
45+
#### Start OAuth2 Flow
46+
47+
```http
48+
POST /api/v1/auth/start
49+
```
50+
51+
**Body**:
52+
```json
53+
{
54+
"redirect": "/?doc=policy_2025"
55+
}
56+
```
57+
58+
#### Request MagicLink
59+
60+
```http
61+
POST /api/v1/auth/magic-link/request
62+
```
63+
64+
**Body**:
65+
```json
66+
{
67+
"email": "user@example.com",
68+
"redirect": "/?doc=policy_2025"
69+
}
70+
```
71+
72+
#### Verify MagicLink
73+
74+
```http
75+
GET /api/v1/auth/magic-link/verify?token=xxx
76+
```
77+
78+
#### Logout
79+
80+
```http
81+
GET /api/v1/auth/logout
82+
```
83+
84+
---
85+
86+
### Users
87+
88+
#### Get Current User
89+
90+
```http
91+
GET /api/v1/users/me
92+
```
93+
94+
**Response** (200 OK):
95+
```json
96+
{
97+
"data": {
98+
"sub": "google-oauth2|123456",
99+
"email": "user@example.com",
100+
"name": "John Doe",
101+
"isAdmin": false,
102+
"canCreateDocuments": true
103+
}
104+
}
105+
```
106+
107+
---
108+
109+
### Documents
110+
111+
#### Find or Create Document
112+
113+
```http
114+
GET /api/v1/documents/find-or-create?ref=policy_2025
115+
```
116+
117+
**Response** (200 OK):
118+
```json
119+
{
120+
"data": {
121+
"docId": "policy_2025",
122+
"title": "Security Policy 2025",
123+
"url": "https://example.com/policy.pdf",
124+
"checksum": "sha256:abc123...",
125+
"checksumAlgorithm": "SHA-256",
126+
"signatureCount": 42,
127+
"isNew": false
128+
}
129+
}
130+
```
131+
132+
**Fields**:
133+
- `signatureCount` - Total number of signatures (visible to all users)
134+
- `isNew` - Whether the document was just created
135+
136+
#### Get Document Details
137+
138+
```http
139+
GET /api/v1/documents/{docId}
140+
```
141+
142+
#### List Document Signatures
143+
144+
```http
145+
GET /api/v1/documents/{docId}/signatures
146+
```
147+
148+
**Access Control**:
149+
| User Type | Result |
150+
|-----------|--------|
151+
| Document owner or Admin | All signatures with emails |
152+
| Authenticated user (not owner) | Only their own signature (if signed) |
153+
| Non-authenticated | Empty list |
154+
155+
> **Note**: The signature **count** is always available via `signatureCount` in the document response. This endpoint returns the **detailed list** with email addresses.
156+
157+
**Response** (200 OK):
158+
```json
159+
{
160+
"data": [
161+
{
162+
"id": 1,
163+
"docId": "policy_2025",
164+
"userEmail": "alice@example.com",
165+
"userName": "Alice Smith",
166+
"signedAt": "2025-01-15T14:30:00Z",
167+
"payloadHash": "sha256:e3b0c44...",
168+
"signature": "ed25519:3045022100..."
169+
}
170+
]
171+
}
172+
```
173+
174+
#### List Expected Signers
175+
176+
```http
177+
GET /api/v1/documents/{docId}/expected-signers
178+
```
179+
180+
**Access Control**: Same as `/signatures` endpoint (owner/admin only).
181+
182+
**Response** (200 OK):
183+
```json
184+
{
185+
"data": [
186+
{
187+
"email": "bob@example.com",
188+
"addedAt": "2025-01-10T10:00:00Z",
189+
"hasSigned": false
190+
}
191+
]
192+
}
193+
```
194+
195+
---
196+
197+
### Signatures
198+
199+
#### Create Signature
200+
201+
```http
202+
POST /api/v1/signatures
203+
X-CSRF-Token: xxx
204+
```
205+
206+
**Body**:
207+
```json
208+
{
209+
"docId": "policy_2025"
210+
}
211+
```
212+
213+
**Response** (201 Created):
214+
```json
215+
{
216+
"data": {
217+
"id": 123,
218+
"docId": "policy_2025",
219+
"userEmail": "user@example.com",
220+
"signedAt": "2025-01-15T14:30:00Z",
221+
"payloadHash": "sha256:...",
222+
"signature": "ed25519:..."
223+
}
224+
}
225+
```
226+
227+
**Errors**:
228+
- `409 Conflict` - User has already signed this document
229+
230+
#### Get My Signatures
231+
232+
```http
233+
GET /api/v1/signatures
234+
```
235+
236+
Returns all signatures for the current authenticated user.
237+
238+
#### Get Signature Status
239+
240+
```http
241+
GET /api/v1/documents/{docId}/signatures/status
242+
```
243+
244+
Returns whether the current user has signed the document.
245+
246+
---
247+
248+
### Admin Endpoints
249+
250+
All admin endpoints require the user to be in `ACKIFY_ADMIN_EMAILS`.
251+
252+
#### List All Documents
253+
254+
```http
255+
GET /api/v1/admin/documents
256+
```
257+
258+
#### Get Document with Signers
259+
260+
```http
261+
GET /api/v1/admin/documents/{docId}/signers
262+
```
263+
264+
#### Add Expected Signer
265+
266+
```http
267+
POST /api/v1/admin/documents/{docId}/signers
268+
X-CSRF-Token: xxx
269+
```
270+
271+
**Body**:
272+
```json
273+
{
274+
"email": "newuser@example.com",
275+
"notes": "Optional note"
276+
}
277+
```
278+
279+
#### Remove Expected Signer
280+
281+
```http
282+
DELETE /api/v1/admin/documents/{docId}/signers/{email}
283+
X-CSRF-Token: xxx
284+
```
285+
286+
#### Send Email Reminders
287+
288+
```http
289+
POST /api/v1/admin/documents/{docId}/reminders
290+
X-CSRF-Token: xxx
291+
```
292+
293+
#### Delete Document
294+
295+
```http
296+
DELETE /api/v1/admin/documents/{docId}
297+
X-CSRF-Token: xxx
298+
```
299+
300+
---
301+
302+
## Error Responses
303+
304+
All errors follow this format:
305+
306+
```json
307+
{
308+
"error": {
309+
"code": "ERROR_CODE",
310+
"message": "Human readable message",
311+
"details": {}
312+
}
313+
}
314+
```
315+
316+
**Common Error Codes**:
317+
- `UNAUTHORIZED` (401) - Authentication required
318+
- `FORBIDDEN` (403) - Insufficient permissions
319+
- `NOT_FOUND` (404) - Resource not found
320+
- `CONFLICT` (409) - Resource already exists (e.g., duplicate signature)
321+
- `RATE_LIMITED` (429) - Too many requests
322+
- `VALIDATION_ERROR` (400) - Invalid request body
323+
324+
---
325+
326+
## Rate Limiting
327+
328+
| Endpoint Category | Limit |
329+
|-------------------|-------|
330+
| Authentication | 5 requests/minute |
331+
| Signatures | 100 requests/minute |
332+
| General API | 100 requests/minute |
333+
334+
---
335+
336+
## OpenAPI Specification
337+
338+
The complete OpenAPI 3.0 specification is available at:
339+
340+
```
341+
GET /api/v1/openapi.json
342+
```

0 commit comments

Comments
 (0)