session()->get('dingtalk_identity_id'); $user = $request->user(); if (! $identityId) { if (! $user || ! in_array($user->created_from, [ 'dingtalk_roster', 'dingtalk_roster_limited', SupplierPortalAccess::CREATED_FROM, ], true)) { return $next($request); } // A password reset must not bypass HR eligibility for provisioned // accounts. Apply the same boundary after every sign-in method. $identityId = $user->dingtalkIdentity?->id; $request->session()->put('dingtalk_identity_id', $identityId); $request->session()->forget('dingtalk_roster_checked_at'); } $identity = $user ? DingTalkIdentity::query()->whereKey($identityId)->where('user_id', $user->id)->first() : null; if ($user && $user->enabled && $identity) { $checkedAt = (int) $request->session()->get('dingtalk_roster_checked_at', 0); if ($checkedAt > now()->timestamp - 300) { return $next($request); } try { $eligible = SupplierPortalAccess::isSupplierUser($user) ? app(SupplierPortalAccess::class)->revalidate($user) !== null : app(FinanceRoster::class)->findEligible((string) $identity->dingtalk_user_id); } catch (Throwable) { // Retain the session during an HR outage, but do not serve data // using an expired authorization decision. return response(trans('auth.dingtalk.roster_unavailable'), 503) ->header('Cache-Control', 'no-store'); } if ($eligible) { $request->session()->put('dingtalk_roster_checked_at', now()->timestamp); return $next($request); } } app(DingTalkClosedAccess::class)->audit('session_revoked', 'denied', $user?->id, null, $identity?->union_id, $request, [ 'reason' => ! $user?->enabled ? 'local_account_ineligible' : (! $identity ? 'binding_revoked' : (SupplierPortalAccess::isSupplierUser($user) ? 'outside_supplier_roster' : 'outside_finance_roster')), ]); auth()->logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); if ($request->expectsJson()) { return response()->json(['message' => trans('auth.dingtalk.session_expired')], 401) ->header('Cache-Control', 'no-store'); } return redirect()->route('login') ->with('dingtalk_error', trans('auth.dingtalk.session_expired')); } }