get('product'); if (!$productId) { return response()->json(['error' => true, 'message' => 'Please choose product']); } $vm = $this->resolveVmById($productId, $request); if ($vm instanceof JsonResponse) { return $vm; } $result = $this->getConsoleTicket($serviceVCenter, $vm); if ($result instanceof JsonResponse) { return $result; } $this->activityLogger->log( event: 'console_access', logName: 'VM', description: "Customer {$request->user()->email} truy cập console VM: {$vm->name} (ID: {$vm->vmware_id})", subject: $vm, newValues: ['product_id' => $productId, 'vm_name' => $vm->name], ); return response()->json([ 'error' => false, 'data' => $result['data'], ]); } /** * POST /v1/system/vm-change-password * * Body: { product, current_password, new_password } * Dispatches ChangeVmPasswordJob — returns immediately, runs async. */ public function changePassword(Request $request): JsonResponse { $validated = $request->validate([ 'product' => ['required'], 'current_password' => ['required', 'string'], 'new_password' => ['required', 'string', 'min:8'], ]); $vm = $this->resolveVmById($validated['product'], $request); if ($vm instanceof JsonResponse) { return $vm; } // ponytail: don't release — lock expires after 5 min while the async job runs $lock = $this->acquireVmLock($vm, 300); if (!$lock) { return $this->vmLocked(); } // Detect OS family from VM's os_id record $os = $vm->os_id ? Os::with('osGroup')->find($vm->os_id) : null; $osGroupName = strtolower($os?->osGroup?->name ?? ''); $osFamily = str_contains($osGroupName, 'windows') ? VmProvisionService::OS_WINDOWS : VmProvisionService::OS_LINUX; ChangeVmPasswordJob::dispatch( $vm->id, $vm->vmware_id, $osFamily, $validated['new_password'], $validated['current_password'], ); $this->activityLogger->log( event: 'change_password', logName: 'VM', description: "Customer {$request->user()->email} yêu cầu đổi mật khẩu VM: {$vm->name}", subject: $vm, newValues: ['os_family' => $osFamily], ); return response()->json([ 'success' => true, 'message' => 'Yêu cầu đổi mật khẩu đã được ghi nhận. Hệ thống sẽ xử lý trong vài phút.', ]); } }