{ "openapi": "3.0.0", "info": { "title": "OAuth2 Identity Server API", "description": "Servidor de identidad/OAuth2 (Laravel Passport) para que aplicaciones de terceros se autentiquen y gestionen usuarios. Pensada para ser consumida por aplicaciones cliente de terceros (Angular, Flutter, NestJS, etc.) que quieran construir su propio panel sin depender de la sesión de Laravel.", "version": "1.0.0" }, "servers": [ { "url": "/api", "description": "API base URL" } ], "paths": { "/analytics/summary": { "get": { "tags": [ "Analytics" ], "summary": "Métricas de uso: logins por día, por app, usuarios más activos y actividad reciente", "description": "Requiere el permiso users.view (o un token client_credentials, que actúa como servicio de confianza).", "operationId": "b34ca6a4b161498d5b34ed3054ddc39d", "parameters": [ { "name": "days", "in": "query", "description": "Ventana en días (7-90, default 30)", "required": false, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Resumen de analíticas" }, "403": { "description": "Sin permiso users.view" } }, "security": [ { "oauth2": [ "users:read" ] } ] } }, "/apps": { "get": { "tags": [ "Users" ], "summary": "Listar todas las apps (clientes OAuth) registradas en el sistema", "description": "Requiere el permiso users.view (o un token client_credentials, que actúa como servicio de confianza). Se usa para armar el selector de \"roles por app\".", "operationId": "5a879a1d739e5b67999e22de46d3223b", "responses": { "200": { "description": "Listado de apps" }, "403": { "description": "Sin permiso users.view" } }, "security": [ { "oauth2": [ "users:read" ] } ] } }, "/authorized-apps": { "get": { "tags": [ "Account" ], "summary": "Listar apps de terceros a las que le diste acceso a tu cuenta", "operationId": "52cd9fb5a0e5a127774bdd7fa8456851", "responses": { "200": { "description": "Listado de tokens/apps autorizadas" } }, "security": [ { "oauth2": [ "account:read" ] } ] } }, "/authorized-apps/{tokenId}": { "delete": { "tags": [ "Account" ], "summary": "Revocar el acceso de una app de terceros", "operationId": "59b2351fe30ac2a4c717926d094d08c9", "parameters": [ { "name": "tokenId", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Acceso revocado" }, "404": { "description": "No existe o no es tuyo" } }, "security": [ { "oauth2": [ "account:write" ] } ] } }, "/clients": { "get": { "tags": [ "Account" ], "summary": "Listar tus clientes OAuth (apps que registraste)", "operationId": "6536f8d22d25758c3e14dbbe8e228af0", "responses": { "200": { "description": "Listado de clientes", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Client" } } } } }, "422": { "description": "El token no tiene un usuario asociado (ej. client_credentials)" } }, "security": [ { "oauth2": [ "account:read" ] } ] }, "post": { "tags": [ "Account" ], "summary": "Registrar un nuevo cliente OAuth (tu app)", "operationId": "74a35b85418e09c2489915865dd22445", "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "name", "grant_type" ], "properties": { "name": { "type": "string" }, "grant_type": { "type": "string", "enum": [ "authorization_code", "client_credentials", "password" ] }, "redirect_uris": { "type": "array", "items": { "type": "string" } }, "confidential": { "type": "boolean", "default": true } }, "type": "object" } } } }, "responses": { "201": { "description": "Cliente creado (incluye plain_secret una sola vez)" }, "422": { "description": "Datos inválidos o token sin usuario asociado" } }, "security": [ { "oauth2": [ "account:write" ] } ] } }, "/clients/{client}": { "put": { "tags": [ "Account" ], "summary": "Editar uno de tus clientes OAuth", "operationId": "01a0e98b651c8cda71034d93d40b8b27", "parameters": [ { "name": "client", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Cliente actualizado", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Client" } } } }, "404": { "description": "No es tuyo o no existe" } }, "security": [ { "oauth2": [ "account:write" ] } ] }, "delete": { "tags": [ "Account" ], "summary": "Revocar uno de tus clientes OAuth (y sus tokens)", "operationId": "ed21785e71ab67958cf6216b6cf263a3", "parameters": [ { "name": "client", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Revocado" }, "404": { "description": "No es tuyo o no existe" } }, "security": [ { "oauth2": [ "account:write" ] } ] } }, "/personal-access-tokens": { "get": { "tags": [ "Account" ], "summary": "Listar tus Personal Access Tokens", "operationId": "b94780059af9e6c94456302b3142b3cb", "responses": { "200": { "description": "Listado de tokens" } }, "security": [ { "oauth2": [ "account:read" ] } ] }, "post": { "tags": [ "Account" ], "summary": "Crear un Personal Access Token (tipo API key)", "operationId": "6e653bdc7fa6bdd2768842f92d575ae7", "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "name" ], "properties": { "name": { "type": "string" }, "scopes": { "type": "array", "items": { "type": "string" } } }, "type": "object" } } } }, "responses": { "201": { "description": "Token creado (access_token solo se muestra esta vez)" } }, "security": [ { "oauth2": [ "account:write" ] } ] } }, "/personal-access-tokens/{tokenId}": { "delete": { "tags": [ "Account" ], "summary": "Revocar un Personal Access Token", "operationId": "d72271ccb6b2630a6d33c20516229723", "parameters": [ { "name": "tokenId", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Revocado" }, "404": { "description": "No existe o no es tuyo" } }, "security": [ { "oauth2": [ "account:write" ] } ] } }, "/user": { "get": { "tags": [ "Users" ], "summary": "Usuario del token actual (whoami) + sus roles global y en la app que llama", "operationId": "853204b4b2f8a255a3721aaca3407e72", "responses": { "200": { "description": "Usuario autenticado", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } } }, "401": { "description": "Token inválido o sin usuario asociado (ej. client_credentials)" } }, "security": [ { "oauth2": [] } ] } }, "/users": { "get": { "tags": [ "Users" ], "summary": "Listar usuarios", "description": "Incluye usuarios pendientes de aprobación del panel admin (ver campo approved_at) — esa aprobación solo gobierna el acceso al panel de sesión de esta app, no la consulta de usuarios vía API.", "operationId": "7208c29037df2b8bb02499ba39ed8a78", "responses": { "200": { "description": "Listado de usuarios", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/User" } } } } }, "403": { "description": "Sin permiso users.view" } }, "security": [ { "oauth2": [ "users:read" ] } ] }, "post": { "tags": [ "Users" ], "summary": "Crear un usuario", "operationId": "262eb5ca1fdea354023c0a8870442c1e", "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "name", "email", "password" ], "properties": { "name": { "type": "string" }, "email": { "type": "string", "format": "email" }, "password": { "type": "string", "format": "password" }, "role": { "type": "string", "example": "user" } }, "type": "object" } } } }, "responses": { "201": { "description": "Usuario creado", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } } }, "403": { "description": "Sin permiso users.create" } }, "security": [ { "oauth2": [ "users:write" ] } ] } }, "/users/{user}": { "get": { "tags": [ "Users" ], "summary": "Ver un usuario (el propio siempre permitido; otros requieren users.view)", "operationId": "a8a7a1f979a2abb839b4b320238106fc", "parameters": [ { "name": "user", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Datos del usuario", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } } }, "403": { "description": "Sin permiso users.view" } }, "security": [ { "oauth2": [ "users:read" ] } ] }, "put": { "tags": [ "Users" ], "summary": "Editar un usuario (el propio siempre permitido; rol/estado y otros usuarios requieren users.update)", "operationId": "4ac3faef1359369686fdd433daad2bee", "parameters": [ { "name": "user", "in": "path", "required": true, "schema": { "type": "integer" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "properties": { "name": { "type": "string" }, "email": { "type": "string", "format": "email" }, "password": { "type": "string", "format": "password" }, "is_active": { "type": "boolean" }, "role": { "type": "string" } }, "type": "object" } } } }, "responses": { "200": { "description": "Usuario actualizado", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } } }, "403": { "description": "Sin permiso users.update" } }, "security": [ { "oauth2": [ "users:write" ] } ] }, "delete": { "tags": [ "Users" ], "summary": "Borrar un usuario (requiere users.delete; no se puede autoeliminar)", "operationId": "371ba09bb6d4a95792dd93040f8812b3", "parameters": [ { "name": "user", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "204": { "description": "Usuario borrado" }, "403": { "description": "Sin permiso users.delete" }, "422": { "description": "No se puede autoeliminar ni borrar al último admin" } }, "security": [ { "oauth2": [ "users:write" ] } ] } }, "/users/trashed": { "get": { "tags": [ "Users" ], "summary": "Listar usuarios borrados (papelera)", "operationId": "ac10f52342c5e5c0d77d46764b6e0637", "responses": { "200": { "description": "Listado de usuarios en la papelera", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/User" } } } } }, "403": { "description": "Sin permiso users.view" } }, "security": [ { "oauth2": [ "users:read" ] } ] } }, "/users/{id}/restore": { "post": { "tags": [ "Users" ], "summary": "Restaurar un usuario borrado", "operationId": "0ec16b4b1d92c2d61463d74d9c045701", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Usuario restaurado", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } } }, "403": { "description": "Sin permiso users.update" } }, "security": [ { "oauth2": [ "users:write" ] } ] } }, "/users/{id}/force": { "delete": { "tags": [ "Users" ], "summary": "Borrar un usuario definitivamente (tiene que estar en la papelera)", "operationId": "093b171b76c7e960668a7c9adf16e9ef", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "204": { "description": "Borrado definitivamente" }, "403": { "description": "Sin permiso users.delete" } }, "security": [ { "oauth2": [ "users:write" ] } ] } }, "/users/pending": { "get": { "tags": [ "Users" ], "summary": "Listar usuarios autorregistrados que todavía no aprobó ningún admin", "operationId": "373548f0068d0e9154443cb895254faf", "responses": { "200": { "description": "Listado de usuarios pendientes", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/User" } } } } }, "403": { "description": "Sin permiso users.view" } }, "security": [ { "oauth2": [ "users:read" ] } ] } }, "/users/{user}/approve": { "post": { "tags": [ "Users" ], "summary": "Aprobar un registro pendiente", "operationId": "c9f59dde1d9a997c3f33c22af5ffc0f0", "parameters": [ { "name": "user", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Usuario aprobado", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } } }, "403": { "description": "Sin permiso users.update" } }, "security": [ { "oauth2": [ "users:write" ] } ] } }, "/users/{user}/app-roles": { "get": { "tags": [ "Users" ], "summary": "Roles que el usuario tiene en cada app (el propio siempre permitido; otros requieren users.view)", "operationId": "9f0336429727034d7b79d1dd1ec210e2", "parameters": [ { "name": "user", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Roles agrupados por app" } }, "security": [ { "oauth2": [ "users:read" ] } ] }, "post": { "tags": [ "Users" ], "summary": "Asignar un rol a un usuario dentro de una app (requiere users.update; sin bypass por self)", "operationId": "108e24d381e03dcbde787f187bff167f", "parameters": [ { "name": "user", "in": "path", "required": true, "schema": { "type": "integer" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "required": [ "client_id", "role" ], "properties": { "client_id": { "type": "string", "format": "uuid" }, "role": { "type": "string", "example": "admin" } }, "type": "object" } } } }, "responses": { "201": { "description": "Rol asignado" }, "403": { "description": "Sin permiso users.update" } }, "security": [ { "oauth2": [ "users:write" ] } ] } }, "/users/{user}/app-roles/{clientId}/{role}": { "delete": { "tags": [ "Users" ], "summary": "Quitarle a un usuario un rol dentro de una app (requiere users.update)", "operationId": "60321b766e2a52bc435d7c93ed35a6dc", "parameters": [ { "name": "user", "in": "path", "required": true, "schema": { "type": "integer" } }, { "name": "clientId", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "role", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "Rol quitado" }, "403": { "description": "Sin permiso users.update" } }, "security": [ { "oauth2": [ "users:write" ] } ] } } }, "components": { "schemas": { "Client": { "properties": { "id": { "type": "string", "format": "uuid" }, "name": { "type": "string", "example": "Mi app Angular" }, "grant_types": { "type": "array", "items": { "type": "string" }, "example": [ "authorization_code", "refresh_token" ] }, "redirect_uris": { "type": "array", "items": { "type": "string" }, "example": [ "https://mi-app.com/callback" ] }, "revoked": { "type": "boolean" } }, "type": "object" }, "User": { "properties": { "id": { "type": "integer", "example": 1 }, "name": { "type": "string", "example": "Ada Lovelace" }, "email": { "type": "string", "format": "email", "example": "ada@example.com" }, "is_active": { "type": "boolean", "example": true }, "roles": { "type": "array", "items": { "type": "string" }, "example": [ "user" ] }, "app_roles": { "description": "Roles del usuario específicos de la app que llama (el client_id del token usado).", "type": "array", "items": { "type": "string" }, "example": [ "editor" ] }, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "description": "Solo presente para usuarios en la papelera (soft-deleted).", "type": "string", "format": "date-time", "nullable": true }, "approved_at": { "description": "Null = todavía no lo aprobó ningún admin (registro pendiente).", "type": "string", "format": "date-time", "nullable": true } }, "type": "object" } }, "securitySchemes": { "oauth2": { "type": "oauth2", "description": "Servidor de autorización OAuth2 (Laravel Passport). Soporta Authorization Code + PKCE, Client Credentials y Password Grant.", "flows": { "authorizationCode": { "authorizationUrl": "/oauth/authorize", "tokenUrl": "/oauth/token", "refreshUrl": "/oauth/token", "scopes": { "users:read": "Leer usuarios", "users:write": "Crear, editar y borrar usuarios", "account:read": "Leer tus clientes OAuth, tokens y apps autorizadas", "account:write": "Gestionar tus clientes OAuth, tokens y apps autorizadas" } }, "clientCredentials": { "tokenUrl": "/oauth/token", "scopes": { "users:read": "Leer usuarios", "users:write": "Crear, editar y borrar usuarios", "account:read": "Leer tus clientes OAuth, tokens y apps autorizadas", "account:write": "Gestionar tus clientes OAuth, tokens y apps autorizadas" } }, "password": { "tokenUrl": "/oauth/token", "scopes": { "users:read": "Leer usuarios", "users:write": "Crear, editar y borrar usuarios", "account:read": "Leer tus clientes OAuth, tokens y apps autorizadas", "account:write": "Gestionar tus clientes OAuth, tokens y apps autorizadas" } } } } } }, "tags": [ { "name": "Analytics", "description": "Analytics" }, { "name": "Users", "description": "Users" }, { "name": "Account", "description": "Account" } ] }