diff --git a/app/Http/Helpers/function_helper.php b/app/Http/Helpers/function_helper.php
index 28c5ac9..b44d324 100644
--- a/app/Http/Helpers/function_helper.php
+++ b/app/Http/Helpers/function_helper.php
@@ -65,6 +65,13 @@ if (!function_exists('customer')) {
}
}
+if (!function_exists('user')) {
+ function user()
+ {
+ return Auth::guard('users')->user();
+ }
+}
+
if (!function_exists('generate_order_number')) {
/**
* Generate a unique order number with given prefix
diff --git a/config/sanctum.php b/config/sanctum.php
index ec13d9f..0d07a41 100644
--- a/config/sanctum.php
+++ b/config/sanctum.php
@@ -33,7 +33,7 @@ return [
|
*/
- 'guard' => ['admins'],
+ 'guard' => ['admins', 'users'],
/*
|--------------------------------------------------------------------------
diff --git a/resources/views/frontend/layouts/partials/account.blade.php b/resources/views/frontend/layouts/partials/account.blade.php
index e4c9209..30d32ef 100644
--- a/resources/views/frontend/layouts/partials/account.blade.php
+++ b/resources/views/frontend/layouts/partials/account.blade.php
@@ -2,7 +2,7 @@
diff --git a/resources/views/frontend/main.blade.php b/resources/views/frontend/main.blade.php
index 554799a..9790b7b 100644
--- a/resources/views/frontend/main.blade.php
+++ b/resources/views/frontend/main.blade.php
@@ -79,7 +79,6 @@
@include("frontend.sidebar")
{{ $title }}
- @include("alerts")
@yield("content")
@include("frontend.footer")
diff --git a/resources/views/frontend/service/console.blade.php b/resources/views/frontend/service/console.blade.php
index eb139e6..1f98eab 100644
--- a/resources/views/frontend/service/console.blade.php
+++ b/resources/views/frontend/service/console.blade.php
@@ -112,10 +112,9 @@
const getTicket = new Promise((resolve, reject) => {
$.ajax({
- url: '{{ route('api.GetConsoleTicket') }}',
+ url: '{{ route('api.user.GetConsoleTicket') }}',
type: 'get',
headers: {
- 'X-CSRF-TOKEN': '{{ csrf_token() }}',
'Accept': 'application/json',
'Authorization': 'Bearer {{ request()->cookie('aut_accessToken') }}'
},
@@ -128,6 +127,10 @@
} else {
reject(response.message)
}
+ },
+ error: function(xhr, status, error) {
+ console.error('API Error:', xhr.responseText);
+ reject('API request failed: ' + error);
}
})
});
diff --git a/routes/api.php b/routes/api.php
index da9dc03..b5f354a 100644
--- a/routes/api.php
+++ b/routes/api.php
@@ -458,7 +458,7 @@ Route::prefix('v1')
})
/* Api for customer */
->group(function () {
- Route::middleware('auth:sanctum')
+ Route::middleware(['auth:sanctum'])
->group(function () {
Route::post('get-status-virtual-machine', function (Request $request, ServiceVCenter $serviceVCenter) {
$vmware_id = $request->vmware_id;
@@ -899,6 +899,24 @@ Route::prefix('v1')
return response()->json(['error' => true, 'message' => "Can't find product"]);
}
+ // Validate that the product belongs to the authenticated user
+ if ($product->customer_id != user()->id) {
+ return response()->json([
+ 'error' => true,
+ 'message' => 'Không có quyền truy cập máy ảo này'
+ ]);
+ }
+
+ // Check if service is expired
+ if ($product->status == 4) {
+ return response()->json(['error' => true, 'message' => 'Dịch vụ đã hết hạn']);
+ }
+
+ // Check if VM is still initializing
+ if ($product->status == 3) {
+ return response()->json(['error' => true, 'message' => 'Máy ảo đang khởi tạo']);
+ }
+
$vcenter = null;
if ($product->ipAddress && $product->ipAddress->host && $product->ipAddress->host->datacenter && $product->ipAddress->host->datacenter->vCenter) {
$vcenter = $product->ipAddress->host->datacenter->vCenter;
@@ -1149,7 +1167,7 @@ Route::prefix('v1')
$validator = Validator::make($request->all(), [
'vm_id' => 'required|string|max:255',
]);
-
+
if ($validator->fails()) {
return response()->json([
'error' => true,
@@ -1157,63 +1175,63 @@ Route::prefix('v1')
'errors' => $validator->errors()
], 422);
}
-
+
$vmId = $request->input('vm_id');
$vm = ModuleVmware::where('vmware_id', $vmId)
->orWhere('id', $vmId)
->first();
-
+
if (!$vm) {
return response()->json([
'error' => true,
'message' => 'Không tìm thấy thông tin máy ảo'
], 404);
}
-
+
if ($vm->status == 4) {
return response()->json([
'error' => true,
'message' => 'Dịch vụ đã hết hạn'
], 400);
}
-
+
if ($vm->status == 3) {
return response()->json([
'error' => true,
'message' => 'Máy ảo đang khởi tạo'
], 400);
}
-
+
$vcenter = $vm->ipAddress->host->datacenter->vCenter ?? null;
-
+
if (!$vcenter) {
return response()->json([
'error' => true,
'message' => 'Không tìm thấy thông tin vCenter'
], 500);
}
-
+
if (!$serviceVCenter->loginServer($vcenter)) {
return response()->json([
'error' => true,
'message' => 'Không thể đăng nhập vào vCenter'
], 500);
}
-
+
// Gọi 2 endpoint
$identity = Http::withoutVerifying()
->withHeaders(['vmware-api-session-id' => $serviceVCenter->token])
->get("https://{$serviceVCenter->apiUri}/rest/vcenter/vm/{$vm->vmware_id}/guest/identity")
->json();
-
+
$networking = Http::withoutVerifying()
->withHeaders(['vmware-api-session-id' => $serviceVCenter->token])
->get("https://{$serviceVCenter->apiUri}/rest/vcenter/vm/{$vm->vmware_id}/guest/networking")
->json();
-
+
// Parse IP
$ipAddresses = [];
-
+
// (1) Từ networking
if (isset($networking['value']['interfaces'])) {
foreach ($networking['value']['interfaces'] as $interface) {
@@ -1228,7 +1246,7 @@ Route::prefix('v1')
}
}
}
-
+
// (2) Nếu networking rỗng, fallback từ identity
if (empty($ipAddresses) && isset($identity['value']['ip_address'])) {
$ip = $identity['value']['ip_address'];
@@ -1240,12 +1258,12 @@ Route::prefix('v1')
];
}
}
-
+
// Update trạng thái
if (!empty($ipAddresses)) {
$vm->update(['status' => 1]);
}
-
+
return response()->json([
'error' => false,
'message' => 'Lấy IP address thành công',
@@ -1261,27 +1279,27 @@ Route::prefix('v1')
]
]
]);
-
+
} catch (\Exception $e) {
Log::error('❌ Lỗi khi lấy IP address của VM', [
'vm_id' => $request->input('vm_id'),
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
-
+
return response()->json([
'error' => true,
'message' => 'Lỗi hệ thống: ' . $e->getMessage()
], 500);
}
})->name('api.user.GetIPAddress');
-
+
Route::get('get-vm-info', function (Request $request, ServiceVCenter $serviceVCenter) {
try {
$validator = Validator::make($request->all(), [
'vm_id' => 'required|string|max:255',
]);
-
+
if ($validator->fails()) {
return response()->json([
'error' => true,
@@ -1289,29 +1307,29 @@ Route::prefix('v1')
'errors' => $validator->errors()
], 422);
}
-
+
$vmId = $request->input('vm_id');
-
+
$vcenter = vCenter::first();
-
+
if (!$vcenter) {
return response()->json([
'error' => true,
'message' => 'Không tìm thấy thông tin vCenter'
], 500);
}
-
+
// Sử dụng token có sẵn nếu có
$serviceVCenter->apiUri = $vcenter->host;
$serviceVCenter->token = $vcenter->token;
-
+
// Gọi API với timeout 5s
$vmInfo = Http::withoutVerifying()
->timeout(5)
->withHeaders(['vmware-api-session-id' => $serviceVCenter->token])
->get("https://{$serviceVCenter->apiUri}/rest/vcenter/vm/{$vmId}")
->json();
-
+
// Nếu token hết hạn, login lại 1 lần duy nhất
if (isset($vmInfo['type']) && str_contains($vmInfo['value']['messages'][0]['default_message'] ?? '', 'session')) {
if (!$serviceVCenter->loginServer($vcenter)) {
@@ -1320,7 +1338,7 @@ Route::prefix('v1')
'message' => 'Không thể đăng nhập vào vCenter'
], 500);
}
-
+
// Thử lại với token mới
$vmInfo = Http::withoutVerifying()
->timeout(5)
@@ -1328,14 +1346,14 @@ Route::prefix('v1')
->get("https://{$serviceVCenter->apiUri}/rest/vcenter/vm/{$vmId}")
->json();
}
-
+
if (isset($vmInfo['type'])) {
return response()->json([
'error' => true,
'message' => 'Không thể lấy thông tin VM từ vCenter'
], 500);
}
-
+
return response()->json([
'error' => false,
'message' => 'Lấy thông tin VM thành công',
@@ -1353,7 +1371,7 @@ Route::prefix('v1')
'size_MiB' => $vmInfo['value']['memory']['size_MiB'] ?? 0,
'hot_add_enabled' => $vmInfo['value']['memory']['hot_add_enabled'] ?? false,
],
- 'disks' => array_map(function($disk) {
+ 'disks' => array_map(function ($disk) {
return [
'key' => $disk['key'] ?? '',
'label' => $disk['value']['label'] ?? '',
@@ -1361,7 +1379,7 @@ Route::prefix('v1')
'type' => $disk['value']['type'] ?? '',
];
}, $vmInfo['value']['disks'] ?? []),
- 'nics' => array_map(function($nic) {
+ 'nics' => array_map(function ($nic) {
return [
'key' => $nic['key'] ?? '',
'label' => $nic['value']['label'] ?? '',
@@ -1385,32 +1403,32 @@ Route::prefix('v1')
],
'raw_data' => $vmInfo['value'] ?? null
]);
-
+
} catch (\Exception $e) {
Log::error('❌ Lỗi khi lấy thông tin VM', [
'vm_id' => $request->input('vm_id'),
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
-
+
return response()->json([
'error' => true,
'message' => 'Lỗi hệ thống: ' . $e->getMessage()
], 500);
}
})->name('api.user.GetVMInfo');
-
+
Route::get('get-vm-info/{vm_id}/{params?}', function (Request $request, ServiceVCenter $serviceVCenter, $vm_id, $params = null) {
try {
$vcenter = vCenter::first();
-
+
if (!$vcenter) {
return response()->json([
'error' => true,
'message' => __('vCenter configuration not found')
], 500);
}
-
+
// Login to vCenter first
if (!$serviceVCenter->loginServer($vcenter)) {
return response()->json([
@@ -1418,25 +1436,25 @@ Route::prefix('v1')
'message' => __('Cannot login to vCenter')
], 500);
}
-
+
$vmInfo = $serviceVCenter->GetDetailVirtualMachine($vm_id);
-
+
if ($vmInfo['error']) {
return response()->json([
'error' => true,
'message' => __('Cannot get VM information from vCenter')
], 500);
}
-
+
$vmData = $vmInfo['data'];
-
+
// Parse các tham số được yêu cầu
$requestedParams = [];
if ($params) {
// Tách các param bằng dấu phẩy hoặc dấu +
$requestedParams = preg_split('/[,+]/', $params);
}
-
+
// Mapping dữ liệu đầy đủ
$allData = [
'vm_id' => $vm_id,
@@ -1454,7 +1472,7 @@ Route::prefix('v1')
'boot_type' => $vmData['boot']['type'] ?? '',
'efi_legacy_boot' => $vmData['boot']['efi_legacy_boot'] ?? false,
];
-
+
// Thêm thông tin disk
if (isset($vmData['disks']) && !empty($vmData['disks'])) {
$firstDisk = $vmData['disks'][0] ?? null;
@@ -1464,7 +1482,7 @@ Route::prefix('v1')
$allData['disk_type'] = $firstDisk['value']['type'] ?? '';
}
}
-
+
// Thêm thông tin network
if (isset($vmData['nics']) && !empty($vmData['nics'])) {
$firstNic = $vmData['nics'][0] ?? null;
@@ -1474,7 +1492,7 @@ Route::prefix('v1')
$allData['network_state'] = $firstNic['value']['state'] ?? '';
}
}
-
+
// Nếu không có params cụ thể, trả về tất cả
if (empty($requestedParams)) {
return response()->json([
@@ -1483,7 +1501,7 @@ Route::prefix('v1')
'data' => $allData
]);
}
-
+
// Lọc chỉ những thông tin được yêu cầu
$filteredData = [];
foreach ($requestedParams as $param) {
@@ -1494,13 +1512,13 @@ Route::prefix('v1')
$filteredData[$param] = null; // Hoặc có thể bỏ qua
}
}
-
+
return response()->json([
'error' => false,
'message' => __('Successfully retrieved VM information'),
'data' => $filteredData
]);
-
+
} catch (\Exception $e) {
Log::error('❌ Lỗi khi lấy thông tin VM với params', [
'vm_id' => $vm_id,
@@ -1508,7 +1526,7 @@ Route::prefix('v1')
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
-
+
return response()->json([
'error' => true,
'message' => __('System error: :error', ['error' => $e->getMessage()])
@@ -1516,5 +1534,5 @@ Route::prefix('v1')
}
})->name('api.user.GetVMInfoWithParams');
});
-
+
});