new funcionality

This commit is contained in:
2026-07-27 17:20:02 +02:00
parent c2b5291a74
commit c5ce8a7a36
101 changed files with 6889 additions and 176 deletions

View File

@@ -2,10 +2,13 @@
use App\Http\Controllers\Api\AnalyticsController;
use App\Http\Controllers\Api\AppController;
use App\Http\Controllers\Api\AuditLogController;
use App\Http\Controllers\Api\AuthorizedAppController;
use App\Http\Controllers\Api\ClientController;
use App\Http\Controllers\Api\PersonalAccessTokenController;
use App\Http\Controllers\Api\UserController;
use App\Http\Controllers\Api\WebhookController;
use App\Http\Controllers\Api\UserSessionController;
use Illuminate\Support\Facades\Route;
// Usuario del token actual (whoami) + roles.
@@ -24,17 +27,34 @@ Route::get('/users/{user}/app-roles', [UserController::class, 'appRoles']);
Route::post('/users/{user}/app-roles', [UserController::class, 'assignAppRole']);
Route::delete('/users/{user}/app-roles/{clientId}/{role}', [UserController::class, 'revokeAppRole']);
// Sesiones (tokens OAuth activos) de un usuario.
Route::get('/users/{user}/sessions', [UserSessionController::class, 'index']);
Route::delete('/users/{user}/sessions/{tokenId}', [UserSessionController::class, 'destroy']);
Route::delete('/users/{user}/sessions', [UserSessionController::class, 'destroyAll']);
// Apps registradas en el sistema (admin, para el selector de roles-por-app).
Route::get('/apps', [AppController::class, 'index']);
// Analíticas de uso: sesiones, logins por app, actividad reciente.
Route::get('/analytics/summary', [AnalyticsController::class, 'summary']);
// Audit log: altas/bajas de usuarios, cambios de rol y de clientes OAuth.
Route::get('/audit-log', [AuditLogController::class, 'index']);
// Cuenta propia: clientes OAuth, personal access tokens y apps autorizadas.
// Todo esto es lo mismo que ofrece la SPA Vue por sesión (routes/web.php), pero
// vía Bearer token — para que cualquier cliente (Angular, Flutter, etc.) pueda
// construir su propio panel sin depender de la sesión de Laravel.
Route::apiResource('clients', ClientController::class)->except(['show'])->names('api.clients');
Route::post('/clients/{client}/rotate-secret', [ClientController::class, 'rotateSecret']);
// Webhooks salientes de un client propio (token.revoked, user.deactivated).
Route::get('/clients/{client}/webhooks', [WebhookController::class, 'index']);
Route::post('/clients/{client}/webhooks', [WebhookController::class, 'store']);
Route::put('/clients/{client}/webhooks/{webhook}', [WebhookController::class, 'update']);
Route::delete('/clients/{client}/webhooks/{webhook}', [WebhookController::class, 'destroy']);
Route::get('/clients/{client}/webhooks/{webhook}/deliveries', [WebhookController::class, 'deliveries']);
Route::post('/clients/{client}/webhooks/{webhook}/deliveries/{delivery}/retry', [WebhookController::class, 'retryDelivery']);
Route::get('/personal-access-tokens', [PersonalAccessTokenController::class, 'index']);
Route::post('/personal-access-tokens', [PersonalAccessTokenController::class, 'store']);

View File

@@ -2,11 +2,17 @@
use App\Http\Controllers\Admin\AnalyticsController;
use App\Http\Controllers\Admin\AppController;
use App\Http\Controllers\Admin\AuditLogController;
use App\Http\Controllers\Admin\UserController;
use App\Http\Controllers\Admin\UserSessionController;
use App\Http\Controllers\Auth\AuthController;
use App\Http\Controllers\Auth\PasswordResetController;
use App\Http\Controllers\Auth\TwoFactorController;
use App\Http\Controllers\OAuth\AuthorizationEventController;
use App\Http\Controllers\OAuth\AuthorizedAppController;
use App\Http\Controllers\OAuth\ClientController;
use App\Http\Controllers\OAuth\PersonalAccessTokenController;
use App\Http\Controllers\OAuth\WebhookController;
use Illuminate\Support\Facades\Route;
use Laravel\Passport\Passport;
@@ -22,15 +28,40 @@ Route::post('/web-api/locale', function () {
// administrar el servidor OAuth2 (clientes, personal access tokens, apps autorizadas).
Route::prefix('web-api')->group(function () {
Route::get('/setup-status', [AuthController::class, 'setupStatus']);
Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
Route::post('/register', [AuthController::class, 'register'])->middleware('throttle:register');
Route::post('/login', [AuthController::class, 'login'])->middleware('throttle:login');
// Segundo paso del login cuando el usuario tiene 2FA activo. Throttle
// acotado: el espacio de códigos TOTP de 6 dígitos es chico.
Route::post('/login/2fa', [AuthController::class, 'loginTwoFactor'])->middleware('throttle:6,1');
Route::post('/forgot-password', [PasswordResetController::class, 'forgotPassword'])->middleware('throttle:password-reset');
Route::post('/reset-password', [PasswordResetController::class, 'resetPassword'])->middleware('throttle:password-reset');
Route::middleware('auth')->group(function () {
Route::post('/logout', [AuthController::class, 'logout']);
Route::get('/me', [AuthController::class, 'me']);
Route::get('/scopes', fn () => response()->json(Passport::scopes()));
// 2FA propio (self-service, como clientes/tokens): setup pendiente,
// confirmación, desactivación y regeneración de códigos de recuperación.
Route::post('/2fa/setup', [TwoFactorController::class, 'setup']);
// Confirmar activación (código TOTP) y confirmar contraseña actual
// (disable/recovery-codes) son ambos espacios de adivinanza chicos —
// mismo throttle acotado que el segundo paso del login con 2FA.
Route::post('/2fa/confirm', [TwoFactorController::class, 'confirm'])->middleware('throttle:6,1');
Route::post('/2fa/disable', [TwoFactorController::class, 'disable'])->middleware('throttle:6,1');
Route::post('/2fa/recovery-codes', [TwoFactorController::class, 'regenerateRecoveryCodes'])->middleware('throttle:6,1');
Route::apiResource('clients', ClientController::class)->except(['show']);
Route::post('/clients/{client}/rotate-secret', [ClientController::class, 'rotateSecret']);
// Webhooks salientes de un client propio (token.revoked, user.deactivated).
Route::get('/clients/{client}/webhooks', [WebhookController::class, 'index']);
Route::post('/clients/{client}/webhooks', [WebhookController::class, 'store']);
Route::put('/clients/{client}/webhooks/{webhook}', [WebhookController::class, 'update']);
Route::delete('/clients/{client}/webhooks/{webhook}', [WebhookController::class, 'destroy']);
Route::get('/clients/{client}/webhooks/{webhook}/deliveries', [WebhookController::class, 'deliveries']);
Route::post('/clients/{client}/webhooks/{webhook}/deliveries/{delivery}/retry', [WebhookController::class, 'retryDelivery']);
Route::get('/personal-access-tokens', [PersonalAccessTokenController::class, 'index']);
Route::post('/personal-access-tokens', [PersonalAccessTokenController::class, 'store']);
@@ -39,6 +70,10 @@ Route::prefix('web-api')->group(function () {
Route::get('/authorized-apps', [AuthorizedAppController::class, 'index']);
Route::delete('/authorized-apps/{tokenId}', [AuthorizedAppController::class, 'destroy']);
// Analíticas del funnel de autorización OAuth (intento/aprobación/denegación),
// registrado desde la pantalla de consentimiento (Authorize.vue).
Route::post('/oauth/authorize-events', [AuthorizationEventController::class, 'store']);
// Panel de administración de usuarios (solo para roles/permisos con "users.*").
Route::prefix('admin')->group(function () {
Route::get('/users', [UserController::class, 'index'])->middleware('can:users.view');
@@ -57,8 +92,17 @@ Route::prefix('web-api')->group(function () {
Route::post('/users/{user}/app-roles', [UserController::class, 'assignAppRole'])->middleware('can:users.update');
Route::delete('/users/{user}/app-roles/{clientId}/{role}', [UserController::class, 'revokeAppRole'])->middleware('can:users.update');
// Sesiones (tokens OAuth activos) de un usuario — para incident response:
// ver qué apps/tokens tiene vigentes y cerrarlos remotamente.
Route::get('/users/{user}/sessions', [UserSessionController::class, 'index'])->middleware('can:users.view');
Route::delete('/users/{user}/sessions/{tokenId}', [UserSessionController::class, 'destroy'])->middleware('can:users.update');
Route::delete('/users/{user}/sessions', [UserSessionController::class, 'destroyAll'])->middleware('can:users.update');
// Analíticas de uso: sesiones, logins por app, actividad reciente.
Route::get('/analytics/summary', [AnalyticsController::class, 'summary'])->middleware('can:users.view');
// Audit log: altas/bajas de usuarios, cambios de rol y de clientes OAuth.
Route::get('/audit-log', [AuditLogController::class, 'index'])->middleware('can:audit.view');
});
});
});