Skip to main content

Documentation 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.

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 the 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:
Authorization: Bearer <token>

The verificarToken middleware

Protected routes are guarded by the verificarToken middleware, which:
  1. Reads the Authorization header and rejects requests that do not include a Bearer token with 401 Token Requerido.
  2. Verifies the token signature and expiry against JWT_SECRET.
  3. Loads the corresponding user document from the database (excluding the hashed password). If no user matches the token’s _id, it returns 401 with "Usuario no encontrado".
  4. Attaches the user document to req.usuario so downstream handlers can access it.
If the token has expired, the middleware returns 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

username
string
required
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
string
required
Email address for the account. Must be a valid email format. Stored in lowercase.
password
string
required
Password for the account. Minimum 6 characters. Stored as a bcrypt hash (cost factor 12) — never returned in any response.

Responses

StatusMeaning
201Account created; verification email dispatched.
400Missing fields, or the username/email is already registered.
500Internal server error.
201 Created
ok
boolean
true on success.
message
string
Human-readable confirmation, e.g. "Usuario registrado. Revisa tu correo para verificar la cuenta.".
curl -X POST https://api.sealearn.app/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "username": "piranha42",
    "email": "piranha42@example.com",
    "password": "s3cur3P@ss"
  }'

GET /api/auth/google

Redirects the browser to the Google OAuth2 consent screen. Requested scopes are profile and email. This endpoint is intended to be opened directly in the browser — not called from a backend service.
# Open in browser
GET https://api.sealearn.app/api/auth/google

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:
FRONTEND_URL/auth/callback?token=<jwt>
The frontend should extract the 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:
FRONTEND_URL/login?error=google

GET /api/auth/discord

Redirects the browser to the Discord OAuth2 authorization screen. This endpoint is intended to be opened directly in the browser.
# Open in browser
GET https://api.sealearn.app/api/auth/discord

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:
FRONTEND_URL/auth/callback?token=<jwt>
If Discord authentication fails, the browser is redirected to:
FRONTEND_URL/login?error=discord

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

token
string
required
The 64-character hex verification token included in the registration email.

Behavior

ConditionRedirect target
Token is valid and not expiredFRONTEND_URL/login?verified=true
token query param is missingFRONTEND_URL/verify-email?error=missing_token
Token not found or expiredFRONTEND_URL/verify-email?error=invalid_or_expired
Server errorFRONTEND_URL/verify-email?error=server_error
# Typically followed from an email link, but can be tested with curl:
curl -L "https://api.sealearn.app/api/auth/verify-email?token=<64-char-hex-token>"

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

email
string
required
The email address of the unverified account.

Responses

StatusMeaning
200Email resent successfully.
400Email not provided, or the account is already verified.
404No account found for this email address.
500Internal server error.
200 OK
ok
boolean
true on success.
message
string
"Correo de verificación reenviado".
curl -X POST https://api.sealearn.app/api/auth/resend-verification \
  -H "Content-Type: application/json" \
  -d '{ "email": "piranha42@example.com" }'

DELETE /api/auth/delete-account

Permanently deletes the authenticated user’s account and all associated data. This action is irreversible. Requires authentication. Include a valid Authorization: Bearer <token> header.

Responses

StatusMeaning
200Account deleted successfully.
401Missing, expired, or invalid token.
500Internal server error.
200 OK
ok
boolean
true on success.
message
string
"Cuenta eliminada".
curl -X DELETE https://api.sealearn.app/api/auth/delete-account \
  -H "Authorization: Bearer <token>"

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

email
string
required
The email address associated with the account.

Responses

StatusMeaning
200Request processed (email sent if the address exists).
400email field missing from request body.
500Error sending the reset email.
200 OK
ok
boolean
true on success.
message
string
Always "Si el email existe, recibirás un link en breve".
curl -X POST https://api.sealearn.app/api/password/forgot \
  -H "Content-Type: application/json" \
  -d '{ "email": "piranha42@example.com" }'

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

token
string
required
The raw (unhashed) reset token from the password-reset email link.
password
string
required
The new password. Minimum 6 characters.

Responses

StatusMeaning
200Password updated successfully.
400Missing fields, password too short, or token invalid/expired.
500Internal server error.
200 OK
ok
boolean
true on success.
message
string
"Contraseña actualizada correctamente".
Reset tokens expire after 1 hour. If the token has expired, the user must request a new reset link via POST /api/password/forgot.
curl -X POST https://api.sealearn.app/api/password/reset \
  -H "Content-Type: application/json" \
  -d '{
    "token": "<raw-token-from-email>",
    "password": "newS3cur3P@ss"
  }'

Build docs developers (and LLMs) love