Sealearn’s authentication system issues signed JSON Web Tokens (JWTs) that clients include in every subsequent request to protected endpoints. Tokens are generated using a secret stored in theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/DerBasilisk/SEA-ServicioEvaluaconAsistida/llms.txt
Use this file to discover all available pages before exploring further.
JWT_SECRET environment variable and expire after 7 days. You can obtain a token through email/password registration and login, or by completing an OAuth2 flow with Google or Discord. New accounts created via email/password registration must verify their email address before they can log in — OAuth2 accounts are automatically considered verified.
How authentication works
Every JWT encodes the user’s_id and is signed with HS256. To authenticate a request, include the token in the Authorization header:
The verificarToken middleware
Protected routes are guarded by the verificarToken middleware, which:
- Reads the
Authorizationheader and rejects requests that do not include aBearertoken with401 Token Requerido. - Verifies the token signature and expiry against
JWT_SECRET. - Loads the corresponding user document from the database (excluding the hashed password). If no user matches the token’s
_id, it returns401with"Usuario no encontrado". - Attaches the user document to
req.usuarioso downstream handlers can access it.
401 with the message "Token expirado, Inicia Sesión Nuevamente". If the token’s signature is invalid, it returns 401 with "Token Invalido".
Endpoints
POST /api/auth/register
Creates a new user account from an email/password combination. After the account is created a verification email is sent to the supplied address. No JWT token is returned — the user must verify their email before logging in.The verification link included in the email is valid for 24 hours. If it expires, use POST /api/auth/resend-verification to request a fresh one.
Request body
Unique username for the account. Must be 3–20 characters and may only contain letters, digits, and underscores (
^[a-zA-Z0-9_]{3,20}$).Email address for the account. Must be a valid email format. Stored in lowercase.
Password for the account. Minimum 6 characters. Stored as a bcrypt hash (cost factor 12) — never returned in any response.
Responses
| Status | Meaning |
|---|---|
201 | Account created; verification email dispatched. |
400 | Missing fields, or the username/email is already registered. |
500 | Internal server error. |
true on success.Human-readable confirmation, e.g.
"Usuario registrado. Revisa tu correo para verificar la cuenta.".GET /api/auth/google
Redirects the browser to the Google OAuth2 consent screen. Requested scopes areprofile and email. This endpoint is intended to be opened directly in the browser — not called from a backend service.
GET /api/auth/google/callback
The redirect target registered in the Google Cloud Console. After Google posts the authorization code here, Passport.js exchanges it for user profile data, finds or creates the matching Sealearn user, signs a 7-day JWT, and redirects the browser to:token query parameter from this URL and persist it (e.g., in localStorage) for use in subsequent API calls.
If Google authentication fails (user denies consent, etc.), the browser is redirected to:
GET /api/auth/discord
Redirects the browser to the Discord OAuth2 authorization screen. This endpoint is intended to be opened directly in the browser.GET /api/auth/discord/callback
The redirect URI registered in the Discord Developer Portal. After Discord posts the authorization code here, Passport.js exchanges it for user profile data, finds or creates the matching Sealearn user, signs a 7-day JWT, and redirects the browser to:GET /api/auth/verify-email
Validates an email verification token sent in the registration email. This endpoint is typically accessed by clicking the link in the verification email rather than being called programmatically.Query parameters
The 64-character hex verification token included in the registration email.
Behavior
| Condition | Redirect target |
|---|---|
| Token is valid and not expired | FRONTEND_URL/login?verified=true |
token query param is missing | FRONTEND_URL/verify-email?error=missing_token |
| Token not found or expired | FRONTEND_URL/verify-email?error=invalid_or_expired |
| Server error | FRONTEND_URL/verify-email?error=server_error |
POST /api/auth/resend-verification
Generates a new 24-hour verification token and resends the verification email to the given address. Use this when a user’s original verification link has expired.Request body
The email address of the unverified account.
Responses
| Status | Meaning |
|---|---|
200 | Email resent successfully. |
400 | Email not provided, or the account is already verified. |
404 | No account found for this email address. |
500 | Internal server error. |
true on success."Correo de verificación reenviado".DELETE /api/auth/delete-account
Permanently deletes the authenticated user’s account and all associated data. This action is irreversible. Requires authentication. Include a validAuthorization: Bearer <token> header.
Responses
| Status | Meaning |
|---|---|
200 | Account deleted successfully. |
401 | Missing, expired, or invalid token. |
500 | Internal server error. |
true on success."Cuenta eliminada".Password Reset
Password reset is a two-step process: first request a reset link via email, then submit the new password alongside the token from the link.POST /api/password/forgot
Sends a password-reset email to the given address. The email contains a link with a single-use token that is valid for 1 hour. The token is stored as a SHA-256 hash — the raw token only ever appears inside the email link and is never stored in plain text.This endpoint always returns a
200 response regardless of whether the email address is registered, to prevent user enumeration.Request body
The email address associated with the account.
Responses
| Status | Meaning |
|---|---|
200 | Request processed (email sent if the address exists). |
400 | email field missing from request body. |
500 | Error sending the reset email. |
true on success.Always
"Si el email existe, recibirás un link en breve".POST /api/password/reset
Sets a new password for the account identified by a valid reset token. The token is the raw value from the reset email link (before hashing). Once used, the token is invalidated.Request body
The raw (unhashed) reset token from the password-reset email link.
The new password. Minimum 6 characters.
Responses
| Status | Meaning |
|---|---|
200 | Password updated successfully. |
400 | Missing fields, password too short, or token invalid/expired. |
500 | Internal server error. |
true on success."Contraseña actualizada correctamente".