* @brief Implements apiCall(method, params?) for the JS scripting engine. */
| 443 | * @brief Implements apiCall(method, params?) for the JS scripting engine. |
| 444 | */ |
| 445 | QVariantMap DataModel::ScriptApiCallBridge::call(const QJSValue& methodVal, |
| 446 | const QJSValue& paramsVal) |
| 447 | { |
| 448 | QVariantMap out; |
| 449 | |
| 450 | if (!methodVal.isString()) { |
| 451 | out.insert(QStringLiteral("ok"), false); |
| 452 | out.insert(QStringLiteral("error"), QStringLiteral("apiCall: method must be a string")); |
| 453 | return out; |
| 454 | } |
| 455 | |
| 456 | const QString method = methodVal.toString(); |
| 457 | if (method.isEmpty()) { |
| 458 | out.insert(QStringLiteral("ok"), false); |
| 459 | out.insert(QStringLiteral("error"), QStringLiteral("apiCall: method must not be empty")); |
| 460 | return out; |
| 461 | } |
| 462 | |
| 463 | if (!API::CommandRegistry::instance().hasCommand(method)) { |
| 464 | const auto unknown = dispatchApiCall(method, QJsonObject()); |
| 465 | out.insert(QStringLiteral("ok"), false); |
| 466 | out.insert(QStringLiteral("error"), unknown.errorMessage); |
| 467 | out.insert(QStringLiteral("errorCode"), unknown.errorCode); |
| 468 | if (!unknown.errorData.isEmpty()) |
| 469 | out.insert(QStringLiteral("errorData"), unknown.errorData.toVariantMap()); |
| 470 | |
| 471 | return out; |
| 472 | } |
| 473 | |
| 474 | if (!isAllowed(method)) { |
| 475 | out.insert(QStringLiteral("ok"), false); |
| 476 | out.insert(QStringLiteral("errorCode"), QStringLiteral("METHOD_NOT_ALLOWED")); |
| 477 | out.insert(QStringLiteral("error"), |
| 478 | QStringLiteral("apiCall: method '%1' not in default allow-list " |
| 479 | "(enable apiCall.allowFullSurface in project to opt in)") |
| 480 | .arg(method)); |
| 481 | return out; |
| 482 | } |
| 483 | |
| 484 | QJsonObject params; |
| 485 | if (!paramsVal.isUndefined() && !paramsVal.isNull()) { |
| 486 | if (!paramsVal.isObject() || paramsVal.isArray() || paramsVal.isCallable()) { |
| 487 | out.insert(QStringLiteral("ok"), false); |
| 488 | out.insert(QStringLiteral("error"), QStringLiteral("apiCall: params must be an object")); |
| 489 | return out; |
| 490 | } |
| 491 | |
| 492 | const QVariant qv = paramsVal.toVariant(); |
| 493 | params = QJsonObject::fromVariantMap(qv.toMap()); |
| 494 | |
| 495 | if (approxJsonSize(params) > kMaxBodyBytes) { |
| 496 | out.insert(QStringLiteral("ok"), false); |
| 497 | out.insert(QStringLiteral("error"), |
| 498 | QStringLiteral("apiCall: params exceed %1 byte cap").arg(kMaxBodyBytes)); |
| 499 | return out; |
| 500 | } |
| 501 | } |
| 502 |
nothing calls this directly
no test coverage detected