canManageOnboarding()) { return redirect()->route('dashboard')->with('error', 'Access denied. You do not have permission to access Onboarding & Offboarding.'); } $onboardings = Onboarding::with(['user', 'creator', 'offboarder']) ->orderBy('created_at', 'desc') ->get(); $activeUsers = User::with(['roles', 'overrides.app']) ->where('id', '!=', Auth::id()) ->orderBy('name', 'asc') ->get(); $apps = App::orderBy('name', 'asc')->get(); $roles = Role::where('name', '!=', 'Admin')->orderBy('name', 'asc')->get(); $stats = [ 'preboarding_count' => $onboardings->where('status', 'preboarding')->count(), 'active_interns_count' => $onboardings->where('type', 'intern')->where('status', 'active')->count(), 'offboarded_count' => $onboardings->where('status', 'offboarded')->count(), 'total_managed' => $onboardings->count(), ]; return view('onboarding.index', compact('onboardings', 'activeUsers', 'apps', 'roles', 'stats')); } /** * Store a new onboarding candidate or intern profile. */ public function store(Request $request) { $user = Auth::user(); if (!$user->canManageOnboarding()) { return redirect()->route('dashboard')->with('error', 'Access denied.'); } $request->validate([ 'name' => 'required|string|max:255', 'email' => 'required|email|max:255', 'type' => 'required|string|in:intern,candidate,employee', 'join_date' => 'nullable|date', 'department' => 'nullable|string|max:255', 'assigned_roles' => 'nullable|array', 'assigned_apps' => 'nullable|array', 'notes' => 'nullable|string', ]); $defaultChecklist = [ 'document_verified' => false, 'email_created' => false, 'laptop_assigned' => false, 'sso_bundle_granted' => false, 'welcome_briefing' => false, ]; Onboarding::create([ 'name' => $request->name, 'email' => strtolower(trim($request->email)), 'type' => $request->type, 'status' => 'preboarding', 'join_date' => $request->join_date, 'department' => $request->department, 'assigned_roles' => $request->assigned_roles ?? [], 'assigned_apps' => $request->assigned_apps ?? [], 'checklist' => $defaultChecklist, 'notes' => $request->notes, 'created_by' => Auth::id(), ]); return redirect()->route('onboarding.index')->with('success', 'Onboarding profile for ' . $request->name . ' created successfully.'); } /** * Activate Day-1 Candidate / Intern account & provision SSO access. */ public function activate($id) { $user = Auth::user(); if (!$user->canManageOnboarding()) { return redirect()->route('dashboard')->with('error', 'Access denied.'); } $onboarding = Onboarding::findOrFail($id); // Check if user account already exists by email $existingUser = User::where('email', $onboarding->email)->first(); if (!$existingUser) { // Create user account with randomized initial password $existingUser = User::create([ 'name' => $onboarding->name, 'email' => $onboarding->email, 'password' => Hash::make(Str::random(16)), 'role' => 'user', ]); } // Attach assigned roles if any if (!empty($onboarding->assigned_roles)) { $existingUser->roles()->syncWithoutDetaching($onboarding->assigned_roles); } else { // Default role fallback $defaultRoleName = Setting::get('default_role', 'Developer'); $defaultRole = Role::firstOrCreate(['name' => $defaultRoleName]); $existingUser->roles()->syncWithoutDetaching([$defaultRole->id]); } // Attach pre-approved service overrides if (!empty($onboarding->assigned_apps)) { foreach ($onboarding->assigned_apps as $appId) { UserAppOverride::firstOrCreate([ 'user_id' => $existingUser->id, 'app_id' => $appId, 'type' => 'allow', ]); } } // Update onboarding record $checklist = $onboarding->checklist ?? []; $checklist['sso_bundle_granted'] = true; $onboarding->update([ 'user_id' => $existingUser->id, 'status' => 'active', 'checklist' => $checklist, ]); return redirect()->route('onboarding.index')->with('success', 'Account activated for ' . $onboarding->name . '. SSO access provisioned!'); } /** * 1-Click Offboard: Instantly block account, revoke SSO apps, & log offboarding. */ public function offboard(Request $request, $id) { $user = Auth::user(); if (!$user->canManageOnboarding()) { return redirect()->route('dashboard')->with('error', 'Access denied.'); } $onboarding = Onboarding::find($id); if ($onboarding && $onboarding->user_id) { $targetUser = User::find($onboarding->user_id); } else { // Try to find user directly if $id is user_id $targetUser = User::find($id); if ($targetUser) { $onboarding = Onboarding::firstOrCreate([ 'user_id' => $targetUser->id, ], [ 'name' => $targetUser->name, 'email' => $targetUser->email, 'type' => 'employee', 'created_by' => Auth::id(), ]); } } if (!$targetUser) { return redirect()->route('onboarding.index')->with('error', 'Target user account not found.'); } // Prevent offboarding self or admins if ($targetUser->id === Auth::id() || $targetUser->isAdmin()) { return redirect()->route('onboarding.index')->with('error', 'Security alert: You cannot offboard administrator accounts.'); } // 1. Block user account $targetUser->update(['is_blocked' => true]); // 2. Clear active overrides / grants $targetUser->overrides()->delete(); // 3. Update onboarding record $checklist = $onboarding->checklist ?? []; $checklist['exit_revocation_completed'] = true; $onboarding->update([ 'status' => 'offboarded', 'exit_date' => now(), 'offboarded_by' => Auth::id(), 'offboarded_at' => now(), 'checklist' => $checklist, ]); return redirect()->route('onboarding.index')->with('success', '1-Click Offboarding completed for ' . $targetUser->name . '. Account blocked & SSO access revoked!'); } /** * Update checklist item for an onboarding / offboarding profile. */ public function updateChecklist(Request $request, $id) { $user = Auth::user(); if (!$user->canManageOnboarding()) { return response()->json(['error' => 'Access denied'], 403); } $onboarding = Onboarding::findOrFail($id); $checklist = $onboarding->checklist ?? []; $key = $request->input('key'); $val = $request->boolean('val'); if ($key) { $checklist[$key] = $val; $onboarding->update(['checklist' => $checklist]); } return response()->json(['success' => true, 'checklist' => $checklist]); } /** * Delete an onboarding profile. */ public function destroy($id) { $user = Auth::user(); if (!$user->canManageOnboarding()) { return redirect()->route('dashboard')->with('error', 'Access denied.'); } $onboarding = Onboarding::findOrFail($id); $onboarding->delete(); return redirect()->route('onboarding.index')->with('success', 'Onboarding record removed successfully.'); } }