CruciDrive’s authorization model is built on three mutually exclusive roles stored in theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/DavidCevallos15/Crucidrive---APP/llms.txt
Use this file to discover all available pages before exploring further.
public.perfiles table: pasajero (rider), conductor (driver), and admin (administrator). Every REST request passes through two chained middlewares — authMiddleware (validates the JWT) and roleMiddleware (checks the role) — before reaching a controller. WebSocket connections are authenticated through an equivalent io.use() guard inside socketHandler.js, ensuring that role-gated behavior is consistent across both transport layers.
Role Definitions
| Role | Description | Key Capabilities |
|---|---|---|
pasajero | An end-user who requests tricimoto rides | Request rides, activate panic button, view live driver map |
conductor | A verified tricimoto driver | Accept ride requests, broadcast GPS position, update ride status |
admin | Platform administrator | Approve drivers, receive panic alerts, audit ride logs |
How roles are stored
Each user’s role is stored in thepublic.perfiles table, which extends Supabase’s auth.users with business-logic fields. A PostgreSQL CHECK constraint is applied to the rol column to prevent any invalid value from ever reaching the database:
perfiles table also stores nombre, telefono (UNIQUE), and activo alongside the role. When an auth.users record is deleted, the corresponding perfiles row is removed automatically via ON DELETE CASCADE. If a viajes row references a deleted user, the FK is preserved via ON DELETE SET NULL to maintain historical records.
Authentication middleware
authMiddleware.js is the first checkpoint on every protected route. It reads the Authorization header, extracts the Bearer token, and validates it against Supabase Auth. If the token is valid, the full Supabase user object is attached to req.user and the request continues to the next handler.
Role middleware
roleMiddleware is a factory function that accepts an array of allowed roles and returns an Express RequestHandler. After authMiddleware has confirmed the JWT is valid, roleMiddleware performs a single lookup against public.perfiles, checks whether the user’s rol is in the allowedRoles array, and — if authorized — attaches the resolved role to req.user.rol for downstream controllers to read.
403 Forbidden response is returned if the user is authenticated but lacks the required role — for example, if a conductor attempts to call POST /api/viajes/solicitar.
WebSocket authentication
Socket.io connections undergo the same JWT validation as REST requests. Theio.use() middleware inside initSocketHandler intercepts every new connection before any event handler fires. The token can be supplied either through socket.handshake.auth.token (the recommended approach) or the Authorization header:
socket.user is available to every event handler on that connection, including update_location (restricted to conductor) and join_chat.
The
admin role is fully defined in the database schema and enforced by the CHECK constraint, but the admin web panel is planned for a future phase. No roleMiddleware(['admin']) routes exist in the current MVP.