Skip to main content

Overview

The /api/auth-sync endpoint allows administrators to update a user’s email, password, or username in Supabase Auth and automatically mirror those changes to the usuarios table. This ensures consistency between authentication data and application user records. Use Cases:
  • Updating user email addresses
  • Resetting user passwords
  • Changing usernames
  • Synchronizing Auth and database records
This endpoint requires administrator permissions. Standard users cannot access this endpoint.

Endpoint

POST /api/auth-sync

Authentication

Authorization
string
required
Bearer token of an authenticated administrator.Format: Bearer <access_token>

Permission Requirements

The caller must meet one of the following criteria:
  1. Have a rol field in usuarios table set to:
    • administrador
    • admin
    • superadmin
    • super-admin
  2. Be listed in the ADMIN_EMAILS environment variable

Request Body

id
integer
required
The ID of the user in the usuarios table to update.Example: 123
email
string
New email address for the user. Must be unique across all users.Example: [email protected]
password
string
New password for the user. Updates only the Supabase Auth password.Example: newSecurePassword123!
username
string
New username for the user. Must be unique across all users.Example: john_doe_2024
At least one of email, password, or username must be provided. Sending an empty request body will result in a 400 error.

Response

Success Response (200 OK)

ok
boolean
Always true for successful requests.
auth
object
Supabase Auth user data after the update.
user
object
Updated user record from the usuarios table. Only included if email or username was changed.
Example Response:
{
  "ok": true,
  "auth": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "email": "[email protected]"
  },
  "user": {
    "id": 123,
    "correo": "[email protected]",
    "nombre_usuario": "john_doe_2024",
    "rol": "usuario",
    "fecha_creacion": "2024-01-15T10:30:00Z"
  }
}

Error Responses

400 Bad Request - Invalid User ID

{
  "message": "ID de usuario inválido"
}
Cause: The id field is missing, not a number, or invalid.

400 Bad Request - No Data to Update

{
  "message": "No hay datos para actualizar"
}
Cause: Request body doesn’t contain email, password, or username.

400 Bad Request - Auth Update Failed

{
  "message": "Error actualizando Auth",
  "error": "Invalid email format"
}
Cause: Supabase Auth rejected the update (invalid email format, weak password, etc.).

401 Unauthorized - Missing Token

{
  "message": "Authorization Bearer token requerido"
}
Cause: No Authorization header or header doesn’t start with Bearer .

401 Unauthorized - Invalid Token

{
  "message": "Token inválido",
  "error": "JWT expired"
}
Cause: Access token is expired, invalid, or revoked.

403 Forbidden - Not an Administrator

{
  "message": "Acceso denegado (se requiere administrador)"
}
Cause: Authenticated user doesn’t have administrator permissions.

404 Not Found - User Not Found in Database

{
  "message": "Usuario no encontrado",
  "error": "No rows found"
}
Cause: No user exists in the usuarios table with the provided id.

404 Not Found - Auth User Not Found

{
  "message": "Usuario de Auth no encontrado por correo actual"
}
Cause: No Supabase Auth user found matching the current email in the usuarios table.
The endpoint searches through the first 200 Auth users. If your system has more than 200 users, pagination may need to be implemented.

409 Conflict - Username Exists

{
  "error": "USERNAME_EXISTS",
  "message": "El nombre de usuario ya está en uso"
}
Cause: The provided username is already taken by another user.

409 Conflict - Email Exists

{
  "error": "EMAIL_EXISTS",
  "message": "El correo ya está registrado"
}
Cause: The provided email is already registered to another user.

500 Internal Server Error - Missing Environment Variables

{
  "message": "Supabase env vars missing",
  "details": "Require SUPABASE_URL, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY (or SUPABASE_SERVICE_KEY)",
  "missing": {
    "SUPABASE_URL": false,
    "SUPABASE_ANON_KEY": false,
    "SUPABASE_SERVICE_ROLE_KEY_or_SUPABASE_SERVICE_KEY": true
  }
}
Cause: Required environment variables are not configured.

500 Internal Server Error - Database Error

{
  "message": "Error actualizando usuarios",
  "error": "Database connection failed"
}
Cause: Database operation failed (connection issue, constraint violation, etc.).

Example Requests

curl -X POST https://your-domain.vercel.app/api/auth-sync \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "id": 123,
    "email": "[email protected]"
  }'

Implementation Details

Update Process Flow

  1. Authentication Verification
    • Extract Bearer token from Authorization header
    • Validate token with Supabase Auth
    • Retrieve caller’s user data
  2. Permission Check
    • Query usuarios table for caller’s role
    • Check if role is admin (administrador, admin, superadmin, super-admin)
    • Check if email is in ADMIN_EMAILS whitelist
    • Return 403 if neither condition is met
  3. Target User Lookup
    • Find user in usuarios table by provided id
    • Return 404 if user doesn’t exist
    • Extract current email (correo)
  4. Auth User Matching
    • Search Supabase Auth users for matching email
    • Return 404 if no Auth user found
  5. Duplicate Validation
    • If updating username: check for existing nombre_usuario
    • If updating email: check for existing correo
    • Return 409 conflict if duplicates found
  6. Update Operations
    • Update Supabase Auth user (email, password, user_metadata.username)
    • Mirror changes to usuarios table (correo, nombre_usuario)
    • Return success with updated data

User Identification Strategy

The endpoint uses multiple fallback methods to identify the caller:
  1. Match by auth_user_id column (if exists)
  2. Match by correo equals Auth email
  3. Match by nombre_usuario equals full Auth email
  4. Match by nombre_usuario equals local part of Auth email (before @)
This ensures compatibility with various database schema configurations.

Environment Variables

  • SUPABASE_URL - Supabase project URL
  • SUPABASE_ANON_KEY - Public anonymous key
  • SUPABASE_SERVICE_ROLE_KEY or SUPABASE_SERVICE_KEY - Admin service key
  • ADMIN_EMAILS - Comma-separated admin email whitelist (optional)

Best Practices

  1. Validate Input: Always validate email format and password strength before calling the API
  2. Handle Conflicts: Implement proper error handling for 409 conflicts (duplicate username/email)
  3. Security: Never expose service role keys in client-side code
  4. User Feedback: Provide clear feedback to users when updates fail
  5. Audit Trail: Consider logging all auth-sync operations for security auditing

Build docs developers (and LLMs) love