query('module'); $moduleId = $request->query('moduleId'); // Missing required parts is a client error, not a server fault. if (! isset($_FILES['file']) || $module === null || $moduleId === null) { return response()->json(['status' => 'error', 'message' => 'Missing file, module or moduleId'], 400); } $module = htmlentities($module); $id = (int) $moduleId; // The legacy endpoint had no project gate: a logged-in user could attach files to // any module/moduleId by tampering with the query string. Authorize against the // target's project (admins/owners bypass; modules with no project mapping fall back // to the read-path behaviour in Files::getFileForUser()). if (! $this->fileService->userCanUploadToModule($module, $id)) { return response()->json(['status' => 'unauthorized'], 403); } $result = $this->fileService->upload($_FILES, $module, $id); if (is_string($result)) { return response()->json(['status' => 'error', 'message' => $result], 500); } return response()->json($result); } }