Documentation Index
Fetch the complete documentation index at: https://mintlify.com/JuanSebasSV/healtyhelp/llms.txt
Use this file to discover all available pages before exploring further.
Auth API
Base path:/api/auth
All protected endpoints require an Authorization: Bearer <token> header. Tokens are signed JWTs issued on login, registration verification, and OAuth callbacks.
Authentication & Authorization
Theprotect middleware validates the JWT from the Authorization header. If the token is missing, expired, or invalid the request is rejected before reaching the route handler.
| Condition | Status | Error |
|---|---|---|
No Authorization header | 401 | "No autorizado - Token no proporcionado" |
| Token expired / invalid signature | 401 | "Token inválido o expirado" |
| User deleted after token issue | 401 | "Usuario no existe o fue eliminado" |
The User Object
All authenticated endpoints that return user data include the following shape:| Field | Type | Description |
|---|---|---|
id | string | MongoDB ObjectId |
name | string | Display name |
email | string | Unique email address |
role | string | "user" or "admin" |
avatar | string | null | Cloudinary URL or null |
googleId | string | null | Google OAuth sub, or null for email accounts |
isVerified | boolean | Email has been confirmed |
hasPassword | boolean | Account has a local password (may be absent on some responses) |
isSuperAdmin | boolean | Super-administrator flag |
birthDate | string | null | ISO 8601 date |
age | number | null | Computed from birthDate |
weight | number | null | In kilograms |
height | number | null | In centimeters |
alergia | string | Free-text allergy description |
termsAccepted | boolean | Has accepted current terms |
termsVersion | string | Version of terms accepted |
profileComplete | boolean | true when age ≥ 18, weight 40–300 kg, height 50–210 cm are all set |
activeTermsVersion | string | Latest published terms version (returned by /me) |
autoLogoutEnabled | boolean | Auto-logout preference |
autoLogoutMinutes | number | Idle timeout in minutes (1–480) |
createdAt | string | ISO 8601 timestamp |
POST /api/auth/register
Creates a new user account and sends a 6-digit email verification code. The account cannot be used until the code is confirmed via/verify-email.
Display name. 2–50 characters, letters only (including accented characters). No three consecutive repeated letters.
Email address. Must be unique.
Minimum 8 characters; must contain at least one uppercase letter, one lowercase letter, and one digit.
ISO 8601 date string (
YYYY-MM-DD). User must be at least 18 years old.Body weight in kg (40–300). Used to pre-compute
profileComplete.Height in cm (50–210). Used to pre-compute
profileComplete.Free-text allergy description.
201
| Status | Condition |
|---|---|
400 | Name validation failed |
400 | birthDate missing or invalid |
400 | User is under 18 |
400 | Email already registered (verified) |
400 | Email already registered but unverified — code is resent, needsVerification: true |
POST /api/auth/login
Authenticates an existing verified user. Implements progressive account lockout after 5 failed attempts (15-minute lockout). A lockout alert email is sent on the 5th failed attempt.Registered email address.
Account password.
200
user contains the User object.
Special case — Google-only account (no local password)
| Status | Condition |
|---|---|
401 | Invalid credentials |
401 | Account not yet verified (needsVerification: true, email echoed back) |
423 | Account locked; locked: true, lockUntil (Unix ms) returned |
POST /api/auth/verify-email
Validates the 6-digit code sent during registration. On success the account is activated and a JWT is returned immediately so the user is logged in without a second step.Email address of the account to verify.
6-digit verification code from the email. Codes expire after 15 minutes.
200
| Status | Condition |
|---|---|
400 | email or code missing |
400 | Code invalid or expired |
POST /api/auth/resend-code
Re-generates and sends a fresh verification code. Only works for accounts that are not yet verified.Email address for the unverified account.
200
| Status | Condition |
|---|---|
404 | User not found |
400 | Account is already verified |
POST /api/auth/forgot-password
Sends a password-reset link to the user’s email address. The link is valid for 30 minutes. For security, a successful response is returned regardless of whether the email exists.Email address associated with the account.
200
| Status | Condition |
|---|---|
400 | Account was created via Google and has no password |
500 | Email delivery failed |
PUT /api/auth/reset-password/:token
Sets a new password using the token received via the forgot-password email. Also clears any existing account lockout. Path parameter| Param | Description |
|---|---|
token | Raw (un-hashed) reset token from the email link |
New password. Must meet the same strength requirements as registration.
200
| Status | Condition |
|---|---|
400 | Token invalid or expired |
400 | Password does not meet requirements |
GET /api/auth/me
Returns the full profile of the currently authenticated user, including the latest published terms version for client-side comparison. Response200
| Status | Condition |
|---|---|
401 | Missing or invalid token |
500 | Server error |
PUT /api/auth/profile
Updates the authenticated user’s profile fields. All body fields are optional; send only the ones to change. Ifweight + already-stored birthDate and height satisfy the validity constraints, profileComplete is automatically set to true.
New display name. Trimmed before saving.
New password. Must meet strength requirements. Not allowed for Google-only accounts.
Body weight in kg. Will be cast with
parseFloat.Allergy notes. Trimmed before saving.
200
| Status | Condition |
|---|---|
400 | Password change attempted on a Google-only account |
400 | New password fails validation |
500 | Save error |
PUT /api/auth/avatar
Uploads a new avatar image via multipart form data. If the user already has a Cloudinary avatar, the previous image is deleted first. RequestContent-Type: multipart/form-data
| Field | Type | Description |
|---|---|---|
avatar | File | Image file to upload |
200
| Status | Condition |
|---|---|
400 | No file received |
500 | Upload or save error |
DELETE /api/auth/avatar
Removes the user’s current avatar from Cloudinary and clears theavatar field.
Response 200
DELETE /api/auth/account
Permanently deletes the authenticated user’s account. Cascades to:- All
Consumodocuments belonging to the user - All review (
resenas) entries across allRecipedocuments - Cloudinary avatar (if set)
isSuperAdmin accounts cannot be deleted.
Must be the exact string
"ELIMINAR" to confirm deletion.200
| Status | Condition |
|---|---|
400 | confirmacion is not "ELIMINAR" |
403 | Account is a Super Administrator |
404 | User not found |
POST /api/auth/accept-terms
Records that the user has accepted the currently active terms and conditions. The latest published terms version is looked up server-side and stored on the user document. Response200
POST /api/auth/complete-profile
Completes the user’s health profile. IfbirthDate is provided, it takes priority; otherwise age (integer) is used to derive an approximate birth date. Once all constraints are satisfied profileComplete is set to true.
ISO 8601 date string. Takes priority over
age if provided.Integer age in years. Used only when no
birthDate is provided and no birthDate is already stored. Minimum 18.Body weight in kg. Must be between 40 and 300.
Height in cm. Must be between 50 and 210.
Allergy notes. Trimmed before saving.
200
| Status | Condition |
|---|---|
400 | birthDate invalid or in the future |
400 | Neither birthDate stored nor valid age supplied |
400 | Computed age is under 18 |
400 | weight out of range (40–300 kg) |
400 | height out of range (50–210 cm) |
404 | User not found |
PATCH /api/auth/preferences
Updates auto-logout session preferences. At least one field must be provided.Enable or disable auto-logout on inactivity.
Idle minutes before logout. Must be an integer between 1 and 480.
200
| Status | Condition |
|---|---|
400 | autoLogoutMinutes not between 1 and 480 |
400 | No valid preferences sent |
GET /api/auth/google
Initiates the Google OAuth 2.0 flow. Redirects the browser to Google’s consent screen requestingprofile and email scopes. This is a browser-redirect endpoint, not an API call.
Flow
- Client navigates to
GET /api/auth/google. - Server redirects to Google.
- Google redirects back to
/api/auth/google/callback. - On success, the server redirects to
{FRONTEND_URL}/google-callback?token=<jwt>. - On failure, the server redirects to
{FRONTEND_URL}/login?error=auth_failed.
GET /api/auth/google/callback
Handled internally by Passport.js. On success, issues a JWT and redirects to the frontend. On failure, redirects with?error=auth_failed. Do not call this endpoint directly.
POST /api/auth/set-google-password
Sets a local password on a Google OAuth account that has none. Allows the user to also sign in with email + password. Can only be called once — once a password is set this endpoint returns400.
New password. Must meet strength requirements (8+ chars, upper, lower, digit).
200
| Status | Condition |
|---|---|
400 | Password fails validation |
400 | Account is not a Google account |
400 | Account already has a password |
404 | User not found |