All checks were successful
star-cloud-deploy-demo / deploy-demo (push) Successful in 52s
1. 強化 B000 登入接口:驗證成功後回傳 Sanctum Token 供後續初始化使用。 2. 實作 B014 (getSettings) API:整合機台、金流與發票設定,並映射至 Android App 預期欄位。 3. 強化安全性:B014 API 掛載 auth:sanctum 並執行 RBAC 權限檢查。 4. 更新 API 說明文件 (iot-spec.md, api-docs.php) 及技術規範 (SKILL.md)。
120 lines
3.9 KiB
PHP
120 lines
3.9 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\V1\App;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\JsonResponse;
|
|
use App\Models\System\User;
|
|
use App\Models\Machine\Machine;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\Log;
|
|
use App\Jobs\Machine\ProcessStateLog;
|
|
|
|
class MachineAuthController extends Controller
|
|
{
|
|
/**
|
|
* B000: 機台本機管理員/補貨員 離線同步登入驗證
|
|
* 這個 API 僅用於機台的 Java App 登入畫面驗證帳密。不必進入 Queue。
|
|
*/
|
|
public function loginB000(Request $request): JsonResponse
|
|
{
|
|
// 1. 驗證欄位 (相容舊版 Java App 發送的 JSON 格式)
|
|
$validated = $request->validate([
|
|
'machine' => 'required|string',
|
|
'Su_Account' => 'required|string',
|
|
'Su_Password' => 'required|string',
|
|
'ip' => 'nullable|string',
|
|
'type' => 'nullable|string',
|
|
]);
|
|
|
|
// 2. 取得機台物件 (需優先於帳密驗證,以便記錄日誌到正確機台)
|
|
$machine = Machine::withoutGlobalScopes()->where('serial_no', $validated['machine'])->first();
|
|
|
|
if (!$machine) {
|
|
Log::warning("B000 機台登入失敗: 伺服器找不到該機台", [
|
|
'machine_serial' => $validated['machine']
|
|
]);
|
|
return response()->json(['message' => 'Failed']);
|
|
}
|
|
|
|
// 3. 透過帳號尋找使用者 (允許使用 username 或 email)
|
|
$user = User::where('username', $validated['Su_Account'])
|
|
->orWhere('email', $validated['Su_Account'])
|
|
->first();
|
|
|
|
// 4. 驗證密碼
|
|
if (!$user || !Hash::check($validated['Su_Password'], $user->password)) {
|
|
Log::warning("B000 機台登入失敗: 帳密錯誤", [
|
|
'account' => $validated['Su_Account'],
|
|
'machine' => $validated['machine']
|
|
]);
|
|
|
|
// 寫入機台日誌
|
|
ProcessStateLog::dispatch(
|
|
$machine->id,
|
|
$machine->company_id,
|
|
__("Login failed: :account", ['account' => $validated['Su_Account']]),
|
|
'warning',
|
|
[],
|
|
'login'
|
|
);
|
|
|
|
return response()->json(['message' => 'Failed']);
|
|
}
|
|
|
|
// 5. RBAC 權限驗證 (遵循多租戶與機台授權規範)
|
|
$isAuthorized = false;
|
|
if ($user->isSystemAdmin()) {
|
|
$isAuthorized = true;
|
|
} elseif ($user->is_admin) {
|
|
if ($machine->company_id === $user->company_id) {
|
|
$isAuthorized = true;
|
|
}
|
|
} else {
|
|
if ($user->machines()->where('machine_id', $machine->id)->exists()) {
|
|
$isAuthorized = true;
|
|
}
|
|
}
|
|
|
|
if (!$isAuthorized) {
|
|
Log::warning("B000 機台登入失敗: 權限不足", [
|
|
'user_id' => $user->id,
|
|
'machine_id' => $machine->id
|
|
]);
|
|
|
|
ProcessStateLog::dispatch(
|
|
$machine->id,
|
|
$machine->company_id,
|
|
__("Unauthorized login attempt: :account", ['account' => $user->username]),
|
|
'warning',
|
|
[],
|
|
'login'
|
|
);
|
|
|
|
return response()->json(['message' => 'Forbidden']);
|
|
}
|
|
|
|
// 6. 驗證完美通過!
|
|
Log::info("B000 機台登入成功", [
|
|
'account' => $user->username,
|
|
'machine' => $machine->serial_no
|
|
]);
|
|
|
|
// 寫入成功登入日誌
|
|
ProcessStateLog::dispatch(
|
|
$machine->id,
|
|
$machine->company_id,
|
|
__("User logged in: :name", ['name' => $user->name ?? $user->username]),
|
|
'info',
|
|
[],
|
|
'login'
|
|
);
|
|
|
|
return response()->json([
|
|
'message' => 'Success',
|
|
'token' => $user->createToken('technician-setup')->plainTextToken
|
|
]);
|
|
}
|
|
}
|