sls/app/Http/Controllers/OnboardingController.php
2026-07-20 20:22:03 +05:30

255 lines
8.6 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\App;
use App\Models\Onboarding;
use App\Models\Role;
use App\Models\Setting;
use App\Models\User;
use App\Models\UserAppOverride;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
class OnboardingController extends Controller
{
/**
* Display the Onboarding & Offboarding Dashboard.
*/
public function index()
{
$user = Auth::user();
if (!$user->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.');
}
}