user() && (int) $request->session()->get('auth_version', 0) !== (int) $request->user()->auth_version) { Auth::logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); } return response()->json($this->workflow->snapshot($request))->header('Cache-Control', 'no-store'); } public function login(Request $request) { $data = $request->validate(['email' => 'required|email|max:255', 'password' => 'required|string|max:1024']); $email = mb_strtolower(trim($data['email'])); if (strlen($data['password']) > 72) { throw ValidationException::withMessages(['email' => 'Email ou palavra-passe inválidos.']); } $key = 'sgf-login:'.hash('sha256', $email.'|'.$request->ip()); $ipKey = 'sgf-login-ip:'.hash('sha256', (string) $request->ip()); abort_if(RateLimiter::tooManyAttempts($key, config('identity.login_attempts')) || RateLimiter::tooManyAttempts($ipKey, config('identity.login_ip_attempts')), 429, 'Demasiadas tentativas. Aguarde antes de tentar novamente.'); if (! Auth::attempt(['email' => $email, 'password' => $data['password']], false)) { RateLimiter::hit($key, config('identity.login_decay_seconds')); RateLimiter::hit($ipKey, config('identity.login_decay_seconds')); Audit::record('auth.failed', null); throw ValidationException::withMessages(['email' => 'Email ou palavra-passe inválidos.']); } RateLimiter::clear($key); $request->session()->regenerate(); $request->session()->forget('company_context'); $request->session()->put('auth_version', (int) $request->user()->auth_version); Audit::record('auth.login', $request->user()->id); return $this->session($request); } public function logout(Request $request) { Audit::record('auth.logout', $request->user()->id); Auth::logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); return response()->json(['csrf' => csrf_token()])->header('Cache-Control', 'no-store'); } public function select(Request $request) { return response()->json($this->workflow->select($request)); } public function company(Request $request, int $company) { $ids = app(\App\Shared\Context\CompanyContext::class)->identifiers(); abort_unless($company === $ids['company_id'], 403); return response()->json(\Illuminate\Support\Facades\DB::table('companies')->where('id', $company)->where('tenant_id', $ids['tenant_id'])->first(['id', 'name'])); } public function unit(Request $request, int $unit) { $ids = app(\App\Shared\Context\CompanyContext::class)->identifiers(); app(\App\Modules\Identity\Services\Permissions::class)->require($request->user()->id, $ids['tenant_id'], $ids['company_id'], 'unit.view', $unit); $record = \Illuminate\Support\Facades\DB::table('units')->where('id', $unit)->where('company_id', $ids['company_id'])->where('tenant_id', $ids['tenant_id'])->first(['id', 'name']); abort_unless($record, 403); return response()->json($record); } public function renameCompany(Request $request, int $company) { $this->workflow->renameCompany($request, $company); return response()->json(['ok' => true]); } public function renameUnit(Request $request, int $unit) { $this->workflow->renameUnit($request, $unit); return response()->json(['ok' => true]); } public function createUnit(Request $request) { return response()->json(['id' => $this->workflow->createUnit($request)], 201); } public function accesses(Request $request) { return response()->json($this->workflow->accessList($request)); } public function grant(Request $request) { $this->workflow->changeAccess($request, true); return response()->json(['ok' => true]); } public function revoke(Request $request) { $this->workflow->changeAccess($request, false); return response()->json(['ok' => true]); } }