From 0800ffb16eeffab1070321b4a27a2b374b2f06d0 Mon Sep 17 00:00:00 2001 From: Konstantin Serebryakov <97249355+KonstantinSerebryakov@users.noreply.github.com> Date: Wed, 7 Oct 2026 19:47:50 +0300 Subject: [PATCH 1/2] fix(webhooks): parse simplified payload and preserve bot owners (php) --- resources/shieldlabs-api.yaml | 645 ++++++++++++++++++++++++++++--- src/Internal/Normalizer.php | 2 +- src/Model/DetectionFlags.php | 6 + src/Model/Identification.php | 9 + src/Webhook.php | 4 +- tests/ContractCurrentTest.php | 19 +- tests/data/ai-bot.json | 91 +++++ tests/data/contract-current.json | 164 +------- 8 files changed, 723 insertions(+), 217 deletions(-) create mode 100644 tests/data/ai-bot.json diff --git a/resources/shieldlabs-api.yaml b/resources/shieldlabs-api.yaml index 03edf61..9cbe011 100644 --- a/resources/shieldlabs-api.yaml +++ b/resources/shieldlabs-api.yaml @@ -466,6 +466,53 @@ paths: source: | curl "https://account.shieldlabs.ai/health" webhooks: + multi-account-changed: + post: + operationId: multiaccountChanged + tags: + - Webhooks + summary: A multi-account group changed + description: |- + Opt-in notification when a complete background detector publication detects, updates, or + resolves an exact group of accounts. Enable `multiaccount: true` on the webhook endpoint. + The default is false; existing identification.scored subscriptions are preserved. + + A repeated build with unchanged membership, level, and rules does not produce a new event. + A membership change produces resolved for the previous exact group and detected for the new + exact group. Resolved means the group is no longer supported by the current complete source + cut, including evidence expiry; it does not certify that its accounts are safe. + + Delivery is at least once, with no global ordering guarantee. Save event_id atomically with + your business operation. Within a site, publication epoch, and cluster_id, compare revision + as an integer and ignore older transitions. Verify HMAC-SHA256 over the raw received bytes; + X-Shield-Event-Id is a convenience header, and the signed body is authoritative. + + This event has no request_id or risk_score. Its source identifies the published group result; + it does not mutate an earlier identification.scored body or an already pinned Console view. + security: [] + parameters: + - $ref: '#/components/parameters/ShieldSignature' + - $ref: '#/components/parameters/ShieldEventId' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/MultiaccountChangedEvent' + examples: + detected: + $ref: '#/components/examples/MultiaccountDetected' + updated: + $ref: '#/components/examples/MultiaccountUpdated' + resolved: + $ref: '#/components/examples/MultiaccountResolved' + responses: + 2XX: + description: Durably accepted by the receiver. The response body is ignored. + 4XX: + description: Terminal delivery failure, except 429 which is retried. + 5XX: + description: Retried within the delivery attempt and age limits. identification.scored: post: operationId: identificationScored @@ -673,21 +720,6 @@ webhooks: stun_not_checked: false check_incomplete: false observed_at: '2026-10-06T00:00:00Z' - fingerprint: - outcome: new_record - record_id: sample-record - hardware_id: sample-hardware - rules_version: fp21-fixture - sharing: - level: high - devices: 4 - min_devices: 4 - takeover: - level: medium - reason: fixture - travel: - level: '' - reason: below_distance responses: 2XX: description: Delivery accepted. The response body is ignored. @@ -939,6 +971,144 @@ components: summary: Logical event identity value: 79e23184cd0b5aae43125e3b14910f13b107a54b schemas: + ClientIdentity: + type: object + additionalProperties: true + required: + - schema_version + - classification_revision + - classifier_version + - registry_revision + - availability + - observed_at + - decided_at + - claims + - verified + - assessments + - evidence + properties: + schema_version: + type: string + description: Open version identifier. Version 1 is currently emitted. + classification_revision: + type: integer + minimum: 1 + classifier_version: + type: string + registry_revision: + type: string + availability: + type: string + description: available or input_unavailable. Missing object means no stored identity data; it does not mean human. + observed_at: + type: string + format: date-time + decided_at: + type: string + format: date-time + claims: + type: array + items: + type: object + additionalProperties: true + required: + - profile_id + - provider_id + - provider_name + - agent_name + - client_kind + - purpose + - source + properties: + profile_id: + type: string + provider_id: + type: string + provider_name: + type: string + agent_name: + type: string + client_kind: + type: string + purpose: + type: string + source: + type: string + verified: + type: array + items: + type: object + additionalProperties: true + required: + - subject + - value_id + - evidence_ids + properties: + subject: + type: string + description: 'The proved attribute: provider, service or infrastructure. Proof does not extend to other attributes.' + value_id: + type: string + evidence_ids: + type: array + items: + type: string + assessments: + type: array + items: + type: object + additionalProperties: true + required: + - status + - reason + properties: + candidate_profile_id: + type: string + status: + type: string + reason: + type: string + evidence: + type: array + items: + type: object + additionalProperties: true + required: + - id + - method + - source_id + - source_revision + - checked_at + - evaluated_at + - covered_attributes + properties: + id: + type: string + method: + type: string + source_id: + type: string + source_revision: + type: string + checked_at: + type: string + format: date-time + evaluated_at: + type: string + format: date-time + covered_attributes: + type: array + items: + type: string + covered_components: + type: array + items: + type: string + request_binding: + type: string + replay_policy: + type: string + description: Stored ingest attribution, independent of risk score and browser automation. Claimed names are unverified. A verified provider does not verify the agent name, service or AI mode. Read proof scope from each attribution and its referenced evidence. Unknown string values and fields must be accepted. RequestId: type: string format: uuid @@ -1222,6 +1392,8 @@ components: - is_incognito - is_search_bot properties: + client_identity: + $ref: '#/components/schemas/ClientIdentity' request_id: $ref: '#/components/schemas/RequestId' session_id: @@ -1602,13 +1774,6 @@ components: type: string const: ok description: Always `ok` when the service answers. - SchemaVersion: - type: string - minLength: 1 - description: Webhook contract version. Current release 2026-10-06; parsers also accept legacy 2026-06-01. - examples: - - '2026-10-06' - - '2026-06-01' Rfc3339Timestamp: type: string format: date-time @@ -1617,6 +1782,187 @@ components: examples: - '2026-09-30T12:34:57.482913041Z' - '2026-09-30T12:34:56Z' + MultiaccountChangedData: + type: object + additionalProperties: false + required: + - kind + - domain + - action + - status + - detected + - level + - cluster_id + - revision + - previous_revision + - user_hids + - users_count + - members_complete + - evaluated_at + - rules_version + - source + - evidence_summary + properties: + kind: + const: multi_account + domain: + type: string + minLength: 1 + action: + type: string + enum: + - detected + - updated + - resolved + status: + const: evaluated + description: The result comes from a complete, verified detector source cut. Pending or unavailable work does not produce this event. + detected: + type: boolean + level: + type: + - string + - 'null' + enum: + - medium + - high + - null + cluster_id: + type: string + format: uuid + description: ID of the exact sorted user set within this site. A membership change resolves the old group and detects a new group. + revision: + type: string + pattern: ^[1-9][0-9]{0,19}$ + description: Publication version of this transition, as a decimal string to preserve UInt64 precision. + previous_revision: + type: + - string + - 'null' + pattern: ^(0|[1-9][0-9]{0,19})$ + description: Previous transition version while the group was active; null for a newly detected or reappearing group. + user_hids: + type: array + minItems: 3 + uniqueItems: true + description: Complete sorted group membership. Users from another site are never included. This list is not truncated. + items: + type: string + minLength: 1 + not: + enum: + - anonymous + - '-1' + - fail + - 00000000-0000-0000-0000-000000000000 + users_count: + type: integer + minimum: 3 + description: Equal to the length of user_hids. + members_complete: + const: true + evaluated_at: + $ref: '#/components/schemas/Rfc3339Timestamp' + rules_version: + type: string + minLength: 1 + source: + type: object + additionalProperties: false + required: + - publication_epoch + - publication_version + - coverage_id + properties: + publication_epoch: + const: multiaccount-v1 + publication_version: + type: string + pattern: ^[1-9][0-9]{0,19}$ + description: The exact immutable publication containing this result and event. + coverage_id: + type: string + pattern: ^[a-f0-9]{64}$ + description: Immutable binding to the trusted source completeness proof. + evidence_summary: + type: object + additionalProperties: false + required: + - basis_types + - rules + - detail_truncated + properties: + basis_types: + type: array + uniqueItems: true + items: + type: string + rules: + type: array + uniqueItems: true + items: + type: string + detail_truncated: + type: boolean + description: Whether the detector's underlying detailed evidence was truncated. Group membership remains complete. + allOf: + - if: + properties: + action: + const: resolved + required: + - action + then: + additionalProperties: true + properties: + detected: + const: false + level: + type: 'null' + else: + additionalProperties: true + properties: + detected: + const: true + level: + type: string + enum: + - medium + - high + MultiaccountChangedEvent: + type: object + description: An immutable opt-in notification of a complete multi-account group transition. + additionalProperties: false + required: + - event_id + - event_type + - schema_version + - site_id + - created_at + - data + properties: + event_id: + type: string + pattern: ^[a-f0-9]{40}$ + description: Stable logical event ID. Delivery retries preserve this ID and the signed body. + event_type: + const: hre.multi_account.changed + schema_version: + const: '2026-10-07' + site_id: + type: integer + minimum: 1 + created_at: + $ref: '#/components/schemas/Rfc3339Timestamp' + data: + $ref: '#/components/schemas/MultiaccountChangedData' + SchemaVersion: + type: string + minLength: 1 + description: Webhook contract version. Scored release 2026-10-06; multi-account group release 2026-10-07; parsers also accept legacy 2026-06-01. + examples: + - '2026-10-06' + - '2026-06-01' UserHid: type: - string @@ -1732,7 +2078,7 @@ components: for anti-detect browsers; - `port_scan_routed_via_proxy`: `proxy_routed_antidetect` carried forward from an earlier identification of the same device and IP; - - `browser_automation`: browser automation, for example a WebDriver-controlled browser; + - `browser_automation`: browser automation, for example a WebDriver-controlled browser (90 in task 204 scoring releases); - `javascript_disabled`: JavaScript or the browser APIs the checks need were unavailable; - `os_mismatch`: the operating system seen on the network differs from the one the browser reports; @@ -1758,7 +2104,7 @@ components: DetectionFlags: type: object description: |- - Stable yes/no verdicts for the identification. Legacy 19 keys are always present; the four extension flags are present in schema 2026-10-06. Branch on these flags and on + Stable yes/no verdicts for the identification. Legacy 19 keys are always present; the extension flags depend on the scoring release. Task 204 adds optional ai_bot and ai_browser flags; older payloads omit them. Branch on these flags and on the Risk Score; signal names are for display and logging. When `search_bot` is `true`, `incognito`, `check_incomplete`, `ip_mismatch` and @@ -1807,7 +2153,7 @@ components: description: The public IP has a record of abuse in IP intelligence. os_mismatch: type: boolean - description: The operating system seen on the network differs from the one the browser reports. + description: Either internal OS consistency check detected a mismatch. The public flag combines browser/network and TCP behaviour checks. os_not_detected: type: boolean description: The operating system could not be determined from the User-Agent or the network. @@ -1819,7 +2165,7 @@ components: description: An anti-detect browser was detected. browser_automation: type: boolean - description: Browser automation was detected, for example a WebDriver-controlled browser. + description: Browser automation was detected, for example a WebDriver-controlled browser. Catalogue weight is 90 for task 204 scoring releases; historical result versions may retain the earlier weight 60. ip_mismatch: type: boolean description: 'The public IP differs from the local IP found by the browser network check. Informational: it does not add to the score.' @@ -1841,14 +2187,22 @@ components: check_incomplete: type: boolean description: Part of the browser checks timed out, so the verdict rests on partial data. Informational. - os_mismatch2: - type: boolean device_spoofing: type: boolean latency_test: type: boolean banned_ip: type: boolean + ai_bot: + type: boolean + description: An accepted bot is classified as AI training or user-requested fetch. ChatGPT-User, Claude-User and Perplexity-User are AI bots, not AI browsers. Weight 0. The flag is optional on older payloads; its absence is not an evaluated negative result. Provider claims alone do not grant zero risk. + ai_browser: + type: boolean + description: A browser is identified by separate verified browser infrastructure. A generic browser User-Agent or a verified provider alone is insufficient. Weight 0. Optional on older payloads; absence is not an evaluated negative. + os_mismatch2: + type: boolean + deprecated: true + description: Legacy 2026-10-06 only; current payloads combine this check into os_mismatch. RiskEvent: type: object required: @@ -1860,6 +2214,7 @@ components: properties: code: type: string + description: Open catalogue of independent source signals. ai_bot and ai_browser carry weight 0; search_bot remains separate. browser_automation carries weight 90 in task 204 releases. UI Good bot and Bad bot groups are not risk event codes. Keep unknown codes and use the payload scoring_version/result_version for historical interpretation. detected: type: boolean description: Final scoring flag. false does not assert that every underlying probe completed. @@ -1903,6 +2258,11 @@ components: min_devices: type: integer minimum: 1 + cluster_id: + type: + - string + - 'null' + description: Authoritative cluster ID for this HRE result. Null when no cluster was published for the result, including old stored verdicts; never a device ID. Reused on retries. HRE: type: object required: @@ -1919,31 +2279,9 @@ components: impossible_travel: $ref: '#/components/schemas/HREResult' description: Three completed on-demand handler results. Technical errors block emission; no_history/skipped are explicit not_evaluated results. Anonymous checks are not_applicable. Multiaccount is separate. - Fingerprint: - type: object - required: - - outcome - - rules_version - properties: - outcome: - type: string - record_id: - type: string - hardware_id: - type: string - description: FP21 hardware identity, distinct from device_id. - rules_version: - type: string - sharing: - type: object - takeover: - type: object - travel: - type: object - description: FP21 for tracked users. Legacy sharing/takeover/travel mirrors are retained; prefer data.hre. Absent on anonymous checks. IdentificationScoredData: type: object - description: Final identification. risk_score is this scan only; no all-time entity risk. New extension fields are required by version 2026-10-06; legacy bodies remain accepted. + description: Final identification. risk_score is this scan only. Version 2026-10-07 uses signals for score contributions, detection_flags for final decisions, and hre for account results. Older bodies remain accepted. required: - request_id - visitor_id @@ -1964,6 +2302,8 @@ components: - detection_flags - observed_at properties: + client_identity: + $ref: '#/components/schemas/ClientIdentity' request_id: $ref: '#/components/schemas/RequestId' visitor_id: @@ -2016,13 +2356,26 @@ components: type: string description: Core build source revision; core:unversioned on local builds. risk_events: + deprecated: true + description: Legacy 2026-10-06 only; absent from current scored events. type: array items: $ref: '#/components/schemas/RiskEvent' hre: $ref: '#/components/schemas/HRE' - fingerprint: - $ref: '#/components/schemas/Fingerprint' + search_bot_owner: + type: string + description: Owner label from accepted search-bot detection; omitted when unknown or inactive. + examples: + - Google + ai_bot_owner: + type: string + description: Provider company label from accepted AI-bot detection; omitted when unknown or inactive. + examples: + - OpenAI + ai_browser_owner: + type: string + description: Owner label from accepted AI-browser detection; omitted when unknown or inactive. IdentificationScoredEvent: type: object description: 'Body of an `identification.scored` delivery. The signature is not part of the body: it arrives in the `X-Shield-Signature` header.' @@ -2081,6 +2434,83 @@ components: description: Logical site/request/final-result-version/type identity. Stable across retries and endpoints. type: object additionalProperties: true + - if: + type: object + required: + - schema_version + properties: + schema_version: + const: '2026-10-07' + additionalProperties: true + then: + type: object + required: + - event_id + properties: + event_id: + type: string + minLength: 1 + description: Logical site/request/final-result-version/type identity. Stable across retries and endpoints. + data: + type: object + required: + - result_version + - scoring_version + - hre + properties: + result_version: {} + scoring_version: {} + risk_events: {} + fingerprint: {} + detection_flags: + type: object + not: + type: object + required: + - os_mismatch2 + properties: + os_mismatch2: {} + additionalProperties: true + hre: + type: object + properties: + account_sharing: + type: object + required: + - cluster_id + properties: + cluster_id: {} + additionalProperties: true + account_takeover: + type: object + required: + - cluster_id + properties: + cluster_id: {} + additionalProperties: true + impossible_travel: + type: object + required: + - cluster_id + properties: + cluster_id: {} + additionalProperties: true + additionalProperties: true + not: + anyOf: + - type: object + required: + - risk_events + properties: + risk_events: {} + additionalProperties: true + - type: object + required: + - fingerprint + properties: + fingerprint: {} + additionalProperties: true + additionalProperties: true WebhookPingEvent: type: object description: Body of a `webhook.ping` delivery, sent when you verify an endpoint. It has no `data`. The keys arrive sorted alphabetically and `created_at` has second precision. @@ -2494,6 +2924,115 @@ components: description: The only successful answer. value: status: ok + MultiaccountDetected: + summary: Multi-account group detected + description: Generated by the Core event marshaler for a synthetic three-account group. + value: + event_id: ad5efdbb113f50d1207c3a3b1d03e54ee60dfb9a + site_id: 319 + event_type: hre.multi_account.changed + schema_version: '2026-10-07' + created_at: '2026-10-07T12:01:04Z' + data: + kind: multi_account + domain: example.com + action: detected + status: evaluated + detected: true + level: medium + cluster_id: 4293f02e-7cf0-5cda-9150-b5b8c4ee685d + revision: '7412' + previous_revision: null + user_hids: + - account_a + - account_b + - account_c + users_count: 3 + members_complete: true + evaluated_at: '2026-10-07T12:01:00Z' + rules_version: fp21-travel-pair-2026-10-06 + source: + publication_epoch: multiaccount-v1 + publication_version: '7412' + coverage_id: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + evidence_summary: + basis_types: + - lineage + rules: + - lineage_60m + detail_truncated: false + MultiaccountUpdated: + summary: Multi-account group updated + description: Generated by the Core event marshaler for a synthetic three-account group. + value: + event_id: 27225e88895f45c6f96562578308d3afea9d4ea2 + site_id: 319 + event_type: hre.multi_account.changed + schema_version: '2026-10-07' + created_at: '2026-10-07T12:01:04Z' + data: + kind: multi_account + domain: example.com + action: updated + status: evaluated + detected: true + level: high + cluster_id: 4293f02e-7cf0-5cda-9150-b5b8c4ee685d + revision: '7414' + previous_revision: '7412' + user_hids: + - account_a + - account_b + - account_c + users_count: 3 + members_complete: true + evaluated_at: '2026-10-07T12:01:00Z' + rules_version: fp21-travel-pair-2026-10-06 + source: + publication_epoch: multiaccount-v1 + publication_version: '7414' + coverage_id: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + evidence_summary: + basis_types: + - lineage + rules: + - lineage_60m + detail_truncated: false + MultiaccountResolved: + summary: Multi-account group resolved + description: Generated by the Core event marshaler for a synthetic three-account group. + value: + event_id: 0e703af70ff450065df0457d71789d32df4de079 + site_id: 319 + event_type: hre.multi_account.changed + schema_version: '2026-10-07' + created_at: '2026-10-07T12:01:04Z' + data: + kind: multi_account + domain: example.com + action: resolved + status: evaluated + detected: false + level: null + cluster_id: 4293f02e-7cf0-5cda-9150-b5b8c4ee685d + revision: '7415' + previous_revision: '7412' + user_hids: + - account_a + - account_b + - account_c + users_count: 3 + members_complete: true + evaluated_at: '2026-10-07T12:01:00Z' + rules_version: fp21-travel-pair-2026-10-06 + source: + publication_epoch: multiaccount-v1 + publication_version: '7415' + coverage_id: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + evidence_summary: + basis_types: [] + rules: [] + detail_truncated: false IdentificationScored: summary: Dangerous identification from a paid click description: Risk Score 80 from a proxy, a datacenter IP and an anti-detect browser, on a visit from a Google Ads click. diff --git a/src/Internal/Normalizer.php b/src/Internal/Normalizer.php index 628ee0b..ed4dba3 100644 --- a/src/Internal/Normalizer.php +++ b/src/Internal/Normalizer.php @@ -316,7 +316,7 @@ public static function fromWebhookData(array $data): array } } - foreach (['os_mismatch2', 'device_spoofing', 'latency_test', 'banned_ip'] as $key) { + foreach (['os_mismatch2', 'device_spoofing', 'latency_test', 'banned_ip', 'ai_bot', 'ai_browser'] as $key) { if (\is_bool($rawFlags[$key] ?? null)) { $flags[$key] = $rawFlags[$key]; } diff --git a/src/Model/DetectionFlags.php b/src/Model/DetectionFlags.php index 67f93c8..6b3ea49 100644 --- a/src/Model/DetectionFlags.php +++ b/src/Model/DetectionFlags.php @@ -43,6 +43,8 @@ public function __construct( public readonly ?bool $device_spoofing = null, public readonly ?bool $latency_test = null, public readonly ?bool $banned_ip = null, + public readonly ?bool $ai_bot = null, + public readonly ?bool $ai_browser = null, ) {} /** @@ -72,6 +74,8 @@ public static function fromArray(array $flags): self javascript_disabled: $value('javascript_disabled'), stun_not_checked: $value('stun_not_checked'), check_incomplete: $value('check_incomplete'), + ai_bot: \array_key_exists('ai_bot', $flags) ? $value('ai_bot') : null, + ai_browser: \array_key_exists('ai_browser', $flags) ? $value('ai_browser') : null, os_mismatch2: \array_key_exists('os_mismatch2', $flags) ? $value('os_mismatch2') : null, device_spoofing: \array_key_exists('device_spoofing', $flags) ? $value('device_spoofing') : null, latency_test: \array_key_exists('latency_test', $flags) ? $value('latency_test') : null, @@ -129,6 +133,8 @@ public function toArray(): array 'javascript_disabled' => $this->javascript_disabled, 'stun_not_checked' => $this->stun_not_checked, 'check_incomplete' => $this->check_incomplete, + ...($this->ai_bot !== null ? ['ai_bot' => $this->ai_bot] : []), + ...($this->ai_browser !== null ? ['ai_browser' => $this->ai_browser] : []), ...($this->os_mismatch2 !== null ? ['os_mismatch2' => $this->os_mismatch2] : []), ...($this->device_spoofing !== null ? ['device_spoofing' => $this->device_spoofing] : []), ...($this->latency_test !== null ? ['latency_test' => $this->latency_test] : []), diff --git a/src/Model/Identification.php b/src/Model/Identification.php index 1948d07..0eb80ba 100644 --- a/src/Model/Identification.php +++ b/src/Model/Identification.php @@ -21,6 +21,9 @@ final class Identification implements \JsonSerializable public const SOURCE_WEBHOOK = 'webhook'; public const SOURCE_HISTORY = 'history'; + public readonly ?string $search_bot_owner; + public readonly ?string $ai_bot_owner; + public readonly ?string $ai_browser_owner; public readonly ?string $result_version; public readonly ?string $scoring_version; /** @var array|null */ @@ -67,6 +70,9 @@ public function __construct( public readonly string $source, public readonly array $raw = [], ) { + $this->search_bot_owner = \is_string($raw['search_bot_owner'] ?? null) ? $raw['search_bot_owner'] : null; + $this->ai_bot_owner = \is_string($raw['ai_bot_owner'] ?? null) ? $raw['ai_bot_owner'] : null; + $this->ai_browser_owner = \is_string($raw['ai_browser_owner'] ?? null) ? $raw['ai_browser_owner'] : null; $this->result_version = \is_string($raw['result_version'] ?? null) ? $raw['result_version'] : null; $this->scoring_version = \is_string($raw['scoring_version'] ?? null) ? $raw['scoring_version'] : null; $this->risk_events = \is_array($raw['risk_events'] ?? null) ? $raw['risk_events'] : null; @@ -150,6 +156,9 @@ public function toArray(): array ...($this->result_version !== null ? ['result_version' => $this->result_version] : []), ...($this->scoring_version !== null ? ['scoring_version' => $this->scoring_version] : []), ...($this->risk_events !== null ? ['risk_events' => $this->risk_events] : []), + ...($this->search_bot_owner !== null ? ['search_bot_owner' => $this->search_bot_owner] : []), + ...($this->ai_bot_owner !== null ? ['ai_bot_owner' => $this->ai_bot_owner] : []), + ...($this->ai_browser_owner !== null ? ['ai_browser_owner' => $this->ai_browser_owner] : []), ...($this->hre !== null ? ['hre' => $this->hre] : []), ...($this->fingerprint !== null ? ['fingerprint' => $this->fingerprint] : []), ]; diff --git a/src/Webhook.php b/src/Webhook.php index d41612e..abccaaf 100644 --- a/src/Webhook.php +++ b/src/Webhook.php @@ -21,14 +21,14 @@ * request body (for example `file_get_contents('php://input')`), never JSON you * decoded and encoded again. * - * Version 2026-10-06 carries signed event_id and a convenience X-Shield-Event-Id + * Version 2026-10-07 carries signed event_id and a convenience X-Shield-Event-Id * header. Failed deliveries are retried in a bounded window. Persist before 2xx * and deduplicate by event_id (legacy: data.request_id). History is recovery/latest state. */ final class Webhook { public const SIGNATURE_HEADER = 'X-Shield-Signature'; - public const SCHEMA_VERSION = '2026-10-06'; + public const SCHEMA_VERSION = '2026-10-07'; private const SIGNATURE_PREFIX = 'sha256='; diff --git a/tests/ContractCurrentTest.php b/tests/ContractCurrentTest.php index 272e56f..8883241 100644 --- a/tests/ContractCurrentTest.php +++ b/tests/ContractCurrentTest.php @@ -19,11 +19,22 @@ public function testCurrentCoreEnvelopePreservesNewFields(): void self::assertInstanceOf(IdentificationScoredEvent::class, $event); self::assertNotEmpty($event->event_id); self::assertSame(7, $event->site_id); - self::assertCount(19, $event->data->risk_events ?? []); - self::assertSame('sample-hardware', $event->data->fingerprint['hardware_id'] ?? null); - self::assertNotSame($event->data->device_id, $event->data->fingerprint['hardware_id'] ?? null); + self::assertNull($event->data->risk_events); + self::assertNull($event->data->fingerprint); + self::assertNull($event->data->hre['account_sharing']['cluster_id']); self::assertSame('no_history', $event->data->hre['account_takeover']['reason'] ?? null); - self::assertArrayHasKey('risk_events', $event->data->toArray()); + self::assertArrayNotHasKey('risk_events', $event->data->toArray()); self::assertFalse(Webhook::verifySignature($raw . ' ', $signature, 'secret')); } + public function testAcceptedBotOwnerSurvivesNormalization(): void + { + $raw = file_get_contents(__DIR__ . '/data/ai-bot.json'); + self::assertIsString($raw); + $event = Webhook::constructEvent($raw, 'sha256=' . hash_hmac('sha256', $raw, 'secret'), 'secret'); + self::assertInstanceOf(IdentificationScoredEvent::class, $event); + self::assertSame('OpenAI', $event->data->ai_bot_owner); + self::assertTrue($event->data->detection_flags->ai_bot); + self::assertSame('OpenAI', $event->data->toArray()['ai_bot_owner']); + } + } diff --git a/tests/data/ai-bot.json b/tests/data/ai-bot.json new file mode 100644 index 0000000..30b6bc0 --- /dev/null +++ b/tests/data/ai-bot.json @@ -0,0 +1,91 @@ +{ + "event_id": "ce256c0f66536957adc5f719250f5b10ce331bd1", + "site_id": 7, + "event_type": "identification.scored", + "schema_version": "2026-10-07", + "created_at": "2026-10-06T00:00:02Z", + "data": { + "result_version": "2026-10-06T00:00:01Z", + "scoring_version": "core:fixture", + "ai_bot_owner": "OpenAI", + "hre": { + "account_sharing": { + "cluster_id": null, + "status": "not_applicable", + "level": null, + "reason": "anonymous_user" + }, + "account_takeover": { + "cluster_id": null, + "status": "not_applicable", + "level": null, + "reason": "anonymous_user" + }, + "impossible_travel": { + "cluster_id": null, + "status": "not_applicable", + "level": null, + "reason": "anonymous_user" + } + }, + "request_id": "13f84f05-7c2a-4e9b-9f1d-2a6b8c0e4d11", + "visitor_id": "161dfbad-8e7f-4a6b-9c5d-0e1f2a3b4c5d", + "device_id": "5eb7fd5c-2a1b-4c3d-9e8f-7a6b5c4d3e2f", + "session_id": "7a1b2c3d-4e5f-4789-abcd-ef0123456789", + "cookie_id": "3f2e1d0c-9b8a-4654-b210-fedcba987654", + "user_hid": "anonymous", + "domain": "example.com", + "public_ip": { + "ip": "203.0.113.1", + "country": "" + }, + "local_ip": { + "ip": "", + "country": "" + }, + "connection_type": "direct", + "os": "Windows", + "browser": "Chrome", + "device_type": "desktop", + "traffic_source": { + "channel": "", + "referrer_domain": "", + "landing_url": "", + "click_id_type": "", + "utm_source": "", + "utm_medium": "", + "utm_campaign": "", + "utm_content": "", + "utm_term": "" + }, + "risk_score": 0, + "signals": [], + "detection_flags": { + "device_spoofing": false, + "latency_test": false, + "banned_ip": false, + "vpn": false, + "privacy_relay": false, + "browser_vpn_proxy": false, + "tor": false, + "proxy": false, + "datacenter_ip": false, + "abuser": false, + "os_mismatch": false, + "os_not_detected": false, + "timezone_mismatch": false, + "anti_detect_browser": false, + "browser_automation": false, + "ip_mismatch": false, + "incognito": false, + "search_bot": false, + "ai_bot": true, + "ai_browser": false, + "suspicious_paid_click": false, + "javascript_disabled": false, + "stun_not_checked": false, + "check_incomplete": false + }, + "observed_at": "2026-10-06T00:00:00Z" + } +} diff --git a/tests/data/contract-current.json b/tests/data/contract-current.json index 4c6dcd6..f2f77c1 100644 --- a/tests/data/contract-current.json +++ b/tests/data/contract-current.json @@ -2,149 +2,15 @@ "event_id": "ce256c0f66536957adc5f719250f5b10ce331bd1", "site_id": 7, "event_type": "identification.scored", - "schema_version": "2026-10-06", + "schema_version": "2026-10-07", "created_at": "2026-10-06T00:00:02Z", "data": { "result_version": "2026-10-06T00:00:01Z", "scoring_version": "core:fixture", - "risk_events": [ - { - "code": "vpn", - "detected": false, - "weight": 30, - "contribution": 0, - "status": "evaluated" - }, - { - "code": "proxy", - "detected": false, - "weight": 30, - "contribution": 0, - "status": "evaluated" - }, - { - "code": "privacy_relay", - "detected": false, - "weight": 30, - "contribution": 0, - "status": "evaluated" - }, - { - "code": "check_incomplete", - "detected": false, - "weight": 0, - "contribution": 0, - "status": "evaluated" - }, - { - "code": "network_check_incomplete", - "detected": false, - "weight": 30, - "contribution": 0, - "status": "evaluated" - }, - { - "code": "os_not_detected", - "detected": false, - "weight": 30, - "contribution": 0, - "status": "evaluated" - }, - { - "code": "timezone_mismatch", - "detected": false, - "weight": 10, - "contribution": 0, - "status": "evaluated" - }, - { - "code": "javascript_disabled", - "detected": false, - "weight": 90, - "contribution": 0, - "status": "evaluated" - }, - { - "code": "os_mismatch", - "detected": false, - "weight": 60, - "contribution": 0, - "status": "evaluated" - }, - { - "code": "os_mismatch2", - "detected": false, - "weight": 60, - "contribution": 0, - "status": "evaluated" - }, - { - "code": "ip_mismatch", - "detected": false, - "weight": 45, - "contribution": 0, - "status": "evaluated" - }, - { - "code": "latency_test", - "detected": false, - "weight": 60, - "contribution": 0, - "status": "evaluated" - }, - { - "code": "anti_detect_browser", - "detected": false, - "weight": 60, - "contribution": 0, - "status": "evaluated" - }, - { - "code": "device_spoofing", - "detected": false, - "weight": 90, - "contribution": 0, - "status": "evaluated" - }, - { - "code": "banned_ip", - "detected": false, - "weight": 999, - "contribution": 0, - "status": "evaluated" - }, - { - "code": "incognito", - "detected": true, - "weight": 0, - "contribution": 0, - "status": "evaluated" - }, - { - "code": "search_bot", - "detected": false, - "weight": 0, - "contribution": 0, - "status": "evaluated" - }, - { - "code": "browser_automation", - "detected": false, - "weight": 60, - "contribution": 0, - "status": "evaluated" - }, - { - "code": "tor", - "detected": false, - "weight": 99, - "contribution": 0, - "status": "evaluated" - } - ], "hre": { "rules_version": "fp21-fixture", "account_sharing": { + "cluster_id": null, "status": "evaluated", "level": null, "reason": "", @@ -152,11 +18,13 @@ "min_devices": 4 }, "account_takeover": { + "cluster_id": null, "status": "not_evaluated", "level": null, "reason": "no_history" }, "impossible_travel": { + "cluster_id": null, "status": "not_evaluated", "level": null, "reason": "skipped" @@ -195,7 +63,6 @@ "risk_score": 0, "signals": [], "detection_flags": { - "os_mismatch2": false, "device_spoofing": false, "latency_test": false, "banned_ip": false, @@ -214,30 +81,13 @@ "ip_mismatch": false, "incognito": true, "search_bot": false, + "ai_bot": false, + "ai_browser": false, "suspicious_paid_click": false, "javascript_disabled": false, "stun_not_checked": false, "check_incomplete": false }, - "observed_at": "2026-10-06T00:00:00Z", - "fingerprint": { - "outcome": "new_record", - "record_id": "sample-record", - "hardware_id": "sample-hardware", - "rules_version": "fp21-fixture", - "sharing": { - "level": "", - "devices": 1, - "min_devices": 4 - }, - "takeover": { - "level": "", - "reason": "no_history" - }, - "travel": { - "level": "", - "reason": "skipped" - } - } + "observed_at": "2026-10-06T00:00:00Z" } } From 6098ba3ed649d684a88198194c4d949232a974a0 Mon Sep 17 00:00:00 2001 From: Konstantin Serebryakov <97249355+KonstantinSerebryakov@users.noreply.github.com> Date: Wed, 7 Oct 2026 20:08:03 +0300 Subject: [PATCH 2/2] fix: regenerate API models for simplified webhook schema --- generated/.openapi-generator/FILES | 10 +- generated/lib/Model/ClientIdentity.php | 793 ++++++++++++ .../Model/ClientIdentityAssessmentsInner.php | 484 +++++++ ...rint.php => ClientIdentityClaimsInner.php} | 266 ++-- .../lib/Model/ClientIdentityEvidenceInner.php | 737 +++++++++++ .../lib/Model/ClientIdentityVerifiedInner.php | 487 +++++++ generated/lib/Model/DetectionFlags.php | 156 ++- generated/lib/Model/HREResult.php | 53 +- generated/lib/Model/HistoryRow.php | 34 + .../lib/Model/IdentificationScoredData.php | 142 ++- .../lib/Model/IdentificationScoredEvent.php | 2 +- .../lib/Model/MultiaccountChangedData.php | 1129 +++++++++++++++++ ...MultiaccountChangedDataEvidenceSummary.php | 491 +++++++ .../Model/MultiaccountChangedDataSource.php | 512 ++++++++ .../lib/Model/MultiaccountChangedEvent.php | 640 ++++++++++ generated/lib/Model/RiskEvent.php | 2 +- generated/lib/Model/Signal.php | 2 +- generated/lib/Model/WebhookPingEvent.php | 2 +- 18 files changed, 5743 insertions(+), 199 deletions(-) create mode 100644 generated/lib/Model/ClientIdentity.php create mode 100644 generated/lib/Model/ClientIdentityAssessmentsInner.php rename generated/lib/Model/{Fingerprint.php => ClientIdentityClaimsInner.php} (61%) create mode 100644 generated/lib/Model/ClientIdentityEvidenceInner.php create mode 100644 generated/lib/Model/ClientIdentityVerifiedInner.php create mode 100644 generated/lib/Model/MultiaccountChangedData.php create mode 100644 generated/lib/Model/MultiaccountChangedDataEvidenceSummary.php create mode 100644 generated/lib/Model/MultiaccountChangedDataSource.php create mode 100644 generated/lib/Model/MultiaccountChangedEvent.php diff --git a/generated/.openapi-generator/FILES b/generated/.openapi-generator/FILES index aa0ffa1..73df3fc 100644 --- a/generated/.openapi-generator/FILES +++ b/generated/.openapi-generator/FILES @@ -7,10 +7,14 @@ lib/ApiException.php lib/Configuration.php lib/FormDataProcessor.php lib/HeaderSelector.php +lib/Model/ClientIdentity.php +lib/Model/ClientIdentityAssessmentsInner.php +lib/Model/ClientIdentityClaimsInner.php +lib/Model/ClientIdentityEvidenceInner.php +lib/Model/ClientIdentityVerifiedInner.php lib/Model/DetectionFlags.php lib/Model/DomainProfile.php lib/Model/ErrorBody.php -lib/Model/Fingerprint.php lib/Model/HRE.php lib/Model/HREResult.php lib/Model/HealthStatus.php @@ -21,6 +25,10 @@ lib/Model/IdentificationScoredEvent.php lib/Model/IpInfo.php lib/Model/LegacySnapshot.php lib/Model/ModelInterface.php +lib/Model/MultiaccountChangedData.php +lib/Model/MultiaccountChangedDataEvidenceSummary.php +lib/Model/MultiaccountChangedDataSource.php +lib/Model/MultiaccountChangedEvent.php lib/Model/RiskEvent.php lib/Model/ScoreDetail.php lib/Model/Signal.php diff --git a/generated/lib/Model/ClientIdentity.php b/generated/lib/Model/ClientIdentity.php new file mode 100644 index 0000000..e79d27a --- /dev/null +++ b/generated/lib/Model/ClientIdentity.php @@ -0,0 +1,793 @@ + + */ +class ClientIdentity implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'ClientIdentity'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'schema_version' => 'string', + 'classification_revision' => 'int', + 'classifier_version' => 'string', + 'registry_revision' => 'string', + 'availability' => 'string', + 'observed_at' => '\DateTime', + 'decided_at' => '\DateTime', + 'claims' => '\ShieldLabs\Generated\Model\ClientIdentityClaimsInner[]', + 'verified' => '\ShieldLabs\Generated\Model\ClientIdentityVerifiedInner[]', + 'assessments' => '\ShieldLabs\Generated\Model\ClientIdentityAssessmentsInner[]', + 'evidence' => '\ShieldLabs\Generated\Model\ClientIdentityEvidenceInner[]' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'schema_version' => null, + 'classification_revision' => null, + 'classifier_version' => null, + 'registry_revision' => null, + 'availability' => null, + 'observed_at' => 'date-time', + 'decided_at' => 'date-time', + 'claims' => null, + 'verified' => null, + 'assessments' => null, + 'evidence' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'schema_version' => false, + 'classification_revision' => false, + 'classifier_version' => false, + 'registry_revision' => false, + 'availability' => false, + 'observed_at' => false, + 'decided_at' => false, + 'claims' => false, + 'verified' => false, + 'assessments' => false, + 'evidence' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'schema_version' => 'schema_version', + 'classification_revision' => 'classification_revision', + 'classifier_version' => 'classifier_version', + 'registry_revision' => 'registry_revision', + 'availability' => 'availability', + 'observed_at' => 'observed_at', + 'decided_at' => 'decided_at', + 'claims' => 'claims', + 'verified' => 'verified', + 'assessments' => 'assessments', + 'evidence' => 'evidence' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'schema_version' => 'setSchemaVersion', + 'classification_revision' => 'setClassificationRevision', + 'classifier_version' => 'setClassifierVersion', + 'registry_revision' => 'setRegistryRevision', + 'availability' => 'setAvailability', + 'observed_at' => 'setObservedAt', + 'decided_at' => 'setDecidedAt', + 'claims' => 'setClaims', + 'verified' => 'setVerified', + 'assessments' => 'setAssessments', + 'evidence' => 'setEvidence' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'schema_version' => 'getSchemaVersion', + 'classification_revision' => 'getClassificationRevision', + 'classifier_version' => 'getClassifierVersion', + 'registry_revision' => 'getRegistryRevision', + 'availability' => 'getAvailability', + 'observed_at' => 'getObservedAt', + 'decided_at' => 'getDecidedAt', + 'claims' => 'getClaims', + 'verified' => 'getVerified', + 'assessments' => 'getAssessments', + 'evidence' => 'getEvidence' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('schema_version', $data ?? [], null); + $this->setIfExists('classification_revision', $data ?? [], null); + $this->setIfExists('classifier_version', $data ?? [], null); + $this->setIfExists('registry_revision', $data ?? [], null); + $this->setIfExists('availability', $data ?? [], null); + $this->setIfExists('observed_at', $data ?? [], null); + $this->setIfExists('decided_at', $data ?? [], null); + $this->setIfExists('claims', $data ?? [], null); + $this->setIfExists('verified', $data ?? [], null); + $this->setIfExists('assessments', $data ?? [], null); + $this->setIfExists('evidence', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['schema_version'] === null) { + $invalidProperties[] = "'schema_version' can't be null"; + } + if ($this->container['classification_revision'] === null) { + $invalidProperties[] = "'classification_revision' can't be null"; + } + if (($this->container['classification_revision'] < 1)) { + $invalidProperties[] = "invalid value for 'classification_revision', must be bigger than or equal to 1."; + } + + if ($this->container['classifier_version'] === null) { + $invalidProperties[] = "'classifier_version' can't be null"; + } + if ($this->container['registry_revision'] === null) { + $invalidProperties[] = "'registry_revision' can't be null"; + } + if ($this->container['availability'] === null) { + $invalidProperties[] = "'availability' can't be null"; + } + if ($this->container['observed_at'] === null) { + $invalidProperties[] = "'observed_at' can't be null"; + } + if ($this->container['decided_at'] === null) { + $invalidProperties[] = "'decided_at' can't be null"; + } + if ($this->container['claims'] === null) { + $invalidProperties[] = "'claims' can't be null"; + } + if ($this->container['verified'] === null) { + $invalidProperties[] = "'verified' can't be null"; + } + if ($this->container['assessments'] === null) { + $invalidProperties[] = "'assessments' can't be null"; + } + if ($this->container['evidence'] === null) { + $invalidProperties[] = "'evidence' can't be null"; + } + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets schema_version + * + * @return string + */ + public function getSchemaVersion() + { + return $this->container['schema_version']; + } + + /** + * Sets schema_version + * + * @param string $schema_version Open version identifier. Version 1 is currently emitted. + * + * @return self + */ + public function setSchemaVersion($schema_version) + { + if (is_null($schema_version)) { + throw new \InvalidArgumentException('non-nullable schema_version cannot be null'); + } + $this->container['schema_version'] = $schema_version; + + return $this; + } + + /** + * Gets classification_revision + * + * @return int + */ + public function getClassificationRevision() + { + return $this->container['classification_revision']; + } + + /** + * Sets classification_revision + * + * @param int $classification_revision classification_revision + * + * @return self + */ + public function setClassificationRevision($classification_revision) + { + if (is_null($classification_revision)) { + throw new \InvalidArgumentException('non-nullable classification_revision cannot be null'); + } + + if (($classification_revision < 1)) { + throw new \InvalidArgumentException('invalid value for $classification_revision when calling ClientIdentity., must be bigger than or equal to 1.'); + } + + $this->container['classification_revision'] = $classification_revision; + + return $this; + } + + /** + * Gets classifier_version + * + * @return string + */ + public function getClassifierVersion() + { + return $this->container['classifier_version']; + } + + /** + * Sets classifier_version + * + * @param string $classifier_version classifier_version + * + * @return self + */ + public function setClassifierVersion($classifier_version) + { + if (is_null($classifier_version)) { + throw new \InvalidArgumentException('non-nullable classifier_version cannot be null'); + } + $this->container['classifier_version'] = $classifier_version; + + return $this; + } + + /** + * Gets registry_revision + * + * @return string + */ + public function getRegistryRevision() + { + return $this->container['registry_revision']; + } + + /** + * Sets registry_revision + * + * @param string $registry_revision registry_revision + * + * @return self + */ + public function setRegistryRevision($registry_revision) + { + if (is_null($registry_revision)) { + throw new \InvalidArgumentException('non-nullable registry_revision cannot be null'); + } + $this->container['registry_revision'] = $registry_revision; + + return $this; + } + + /** + * Gets availability + * + * @return string + */ + public function getAvailability() + { + return $this->container['availability']; + } + + /** + * Sets availability + * + * @param string $availability available or input_unavailable. Missing object means no stored identity data; it does not mean human. + * + * @return self + */ + public function setAvailability($availability) + { + if (is_null($availability)) { + throw new \InvalidArgumentException('non-nullable availability cannot be null'); + } + $this->container['availability'] = $availability; + + return $this; + } + + /** + * Gets observed_at + * + * @return \DateTime + */ + public function getObservedAt() + { + return $this->container['observed_at']; + } + + /** + * Sets observed_at + * + * @param \DateTime $observed_at observed_at + * + * @return self + */ + public function setObservedAt($observed_at) + { + if (is_null($observed_at)) { + throw new \InvalidArgumentException('non-nullable observed_at cannot be null'); + } + $this->container['observed_at'] = $observed_at; + + return $this; + } + + /** + * Gets decided_at + * + * @return \DateTime + */ + public function getDecidedAt() + { + return $this->container['decided_at']; + } + + /** + * Sets decided_at + * + * @param \DateTime $decided_at decided_at + * + * @return self + */ + public function setDecidedAt($decided_at) + { + if (is_null($decided_at)) { + throw new \InvalidArgumentException('non-nullable decided_at cannot be null'); + } + $this->container['decided_at'] = $decided_at; + + return $this; + } + + /** + * Gets claims + * + * @return \ShieldLabs\Generated\Model\ClientIdentityClaimsInner[] + */ + public function getClaims() + { + return $this->container['claims']; + } + + /** + * Sets claims + * + * @param \ShieldLabs\Generated\Model\ClientIdentityClaimsInner[] $claims claims + * + * @return self + */ + public function setClaims($claims) + { + if (is_null($claims)) { + throw new \InvalidArgumentException('non-nullable claims cannot be null'); + } + $this->container['claims'] = $claims; + + return $this; + } + + /** + * Gets verified + * + * @return \ShieldLabs\Generated\Model\ClientIdentityVerifiedInner[] + */ + public function getVerified() + { + return $this->container['verified']; + } + + /** + * Sets verified + * + * @param \ShieldLabs\Generated\Model\ClientIdentityVerifiedInner[] $verified verified + * + * @return self + */ + public function setVerified($verified) + { + if (is_null($verified)) { + throw new \InvalidArgumentException('non-nullable verified cannot be null'); + } + $this->container['verified'] = $verified; + + return $this; + } + + /** + * Gets assessments + * + * @return \ShieldLabs\Generated\Model\ClientIdentityAssessmentsInner[] + */ + public function getAssessments() + { + return $this->container['assessments']; + } + + /** + * Sets assessments + * + * @param \ShieldLabs\Generated\Model\ClientIdentityAssessmentsInner[] $assessments assessments + * + * @return self + */ + public function setAssessments($assessments) + { + if (is_null($assessments)) { + throw new \InvalidArgumentException('non-nullable assessments cannot be null'); + } + $this->container['assessments'] = $assessments; + + return $this; + } + + /** + * Gets evidence + * + * @return \ShieldLabs\Generated\Model\ClientIdentityEvidenceInner[] + */ + public function getEvidence() + { + return $this->container['evidence']; + } + + /** + * Sets evidence + * + * @param \ShieldLabs\Generated\Model\ClientIdentityEvidenceInner[] $evidence evidence + * + * @return self + */ + public function setEvidence($evidence) + { + if (is_null($evidence)) { + throw new \InvalidArgumentException('non-nullable evidence cannot be null'); + } + $this->container['evidence'] = $evidence; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/ClientIdentityAssessmentsInner.php b/generated/lib/Model/ClientIdentityAssessmentsInner.php new file mode 100644 index 0000000..32ad2c4 --- /dev/null +++ b/generated/lib/Model/ClientIdentityAssessmentsInner.php @@ -0,0 +1,484 @@ + + */ +class ClientIdentityAssessmentsInner implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'ClientIdentity_assessments_inner'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'candidate_profile_id' => 'string', + 'status' => 'string', + 'reason' => 'string' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'candidate_profile_id' => null, + 'status' => null, + 'reason' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'candidate_profile_id' => false, + 'status' => false, + 'reason' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'candidate_profile_id' => 'candidate_profile_id', + 'status' => 'status', + 'reason' => 'reason' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'candidate_profile_id' => 'setCandidateProfileId', + 'status' => 'setStatus', + 'reason' => 'setReason' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'candidate_profile_id' => 'getCandidateProfileId', + 'status' => 'getStatus', + 'reason' => 'getReason' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('candidate_profile_id', $data ?? [], null); + $this->setIfExists('status', $data ?? [], null); + $this->setIfExists('reason', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['status'] === null) { + $invalidProperties[] = "'status' can't be null"; + } + if ($this->container['reason'] === null) { + $invalidProperties[] = "'reason' can't be null"; + } + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets candidate_profile_id + * + * @return string|null + */ + public function getCandidateProfileId() + { + return $this->container['candidate_profile_id']; + } + + /** + * Sets candidate_profile_id + * + * @param string|null $candidate_profile_id candidate_profile_id + * + * @return self + */ + public function setCandidateProfileId($candidate_profile_id) + { + if (is_null($candidate_profile_id)) { + throw new \InvalidArgumentException('non-nullable candidate_profile_id cannot be null'); + } + $this->container['candidate_profile_id'] = $candidate_profile_id; + + return $this; + } + + /** + * Gets status + * + * @return string + */ + public function getStatus() + { + return $this->container['status']; + } + + /** + * Sets status + * + * @param string $status status + * + * @return self + */ + public function setStatus($status) + { + if (is_null($status)) { + throw new \InvalidArgumentException('non-nullable status cannot be null'); + } + $this->container['status'] = $status; + + return $this; + } + + /** + * Gets reason + * + * @return string + */ + public function getReason() + { + return $this->container['reason']; + } + + /** + * Sets reason + * + * @param string $reason reason + * + * @return self + */ + public function setReason($reason) + { + if (is_null($reason)) { + throw new \InvalidArgumentException('non-nullable reason cannot be null'); + } + $this->container['reason'] = $reason; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/Fingerprint.php b/generated/lib/Model/ClientIdentityClaimsInner.php similarity index 61% rename from generated/lib/Model/Fingerprint.php rename to generated/lib/Model/ClientIdentityClaimsInner.php index 408c338..aa195ba 100644 --- a/generated/lib/Model/Fingerprint.php +++ b/generated/lib/Model/ClientIdentityClaimsInner.php @@ -1,6 +1,6 @@ */ -class Fingerprint implements ModelInterface, ArrayAccess, \JsonSerializable +class ClientIdentityClaimsInner implements ModelInterface, ArrayAccess, \JsonSerializable { public const DISCRIMINATOR = null; @@ -51,7 +50,7 @@ class Fingerprint implements ModelInterface, ArrayAccess, \JsonSerializable * * @var string */ - protected static $openAPIModelName = 'Fingerprint'; + protected static $openAPIModelName = 'ClientIdentity_claims_inner'; /** * Array of property to type mappings. Used for (de)serialization @@ -59,13 +58,13 @@ class Fingerprint implements ModelInterface, ArrayAccess, \JsonSerializable * @var string[] */ protected static $openAPITypes = [ - 'outcome' => 'string', - 'record_id' => 'string', - 'hardware_id' => 'string', - 'rules_version' => 'string', - 'sharing' => 'object', - 'takeover' => 'object', - 'travel' => 'object' + 'profile_id' => 'string', + 'provider_id' => 'string', + 'provider_name' => 'string', + 'agent_name' => 'string', + 'client_kind' => 'string', + 'purpose' => 'string', + 'source' => 'string' ]; /** @@ -76,13 +75,13 @@ class Fingerprint implements ModelInterface, ArrayAccess, \JsonSerializable * @psalm-var array */ protected static $openAPIFormats = [ - 'outcome' => null, - 'record_id' => null, - 'hardware_id' => null, - 'rules_version' => null, - 'sharing' => null, - 'takeover' => null, - 'travel' => null + 'profile_id' => null, + 'provider_id' => null, + 'provider_name' => null, + 'agent_name' => null, + 'client_kind' => null, + 'purpose' => null, + 'source' => null ]; /** @@ -91,13 +90,13 @@ class Fingerprint implements ModelInterface, ArrayAccess, \JsonSerializable * @var boolean[] */ protected static array $openAPINullables = [ - 'outcome' => false, - 'record_id' => false, - 'hardware_id' => false, - 'rules_version' => false, - 'sharing' => false, - 'takeover' => false, - 'travel' => false + 'profile_id' => false, + 'provider_id' => false, + 'provider_name' => false, + 'agent_name' => false, + 'client_kind' => false, + 'purpose' => false, + 'source' => false ]; /** @@ -186,13 +185,13 @@ public function isNullableSetToNull(string $property): bool * @var string[] */ protected static $attributeMap = [ - 'outcome' => 'outcome', - 'record_id' => 'record_id', - 'hardware_id' => 'hardware_id', - 'rules_version' => 'rules_version', - 'sharing' => 'sharing', - 'takeover' => 'takeover', - 'travel' => 'travel' + 'profile_id' => 'profile_id', + 'provider_id' => 'provider_id', + 'provider_name' => 'provider_name', + 'agent_name' => 'agent_name', + 'client_kind' => 'client_kind', + 'purpose' => 'purpose', + 'source' => 'source' ]; /** @@ -201,13 +200,13 @@ public function isNullableSetToNull(string $property): bool * @var string[] */ protected static $setters = [ - 'outcome' => 'setOutcome', - 'record_id' => 'setRecordId', - 'hardware_id' => 'setHardwareId', - 'rules_version' => 'setRulesVersion', - 'sharing' => 'setSharing', - 'takeover' => 'setTakeover', - 'travel' => 'setTravel' + 'profile_id' => 'setProfileId', + 'provider_id' => 'setProviderId', + 'provider_name' => 'setProviderName', + 'agent_name' => 'setAgentName', + 'client_kind' => 'setClientKind', + 'purpose' => 'setPurpose', + 'source' => 'setSource' ]; /** @@ -216,13 +215,13 @@ public function isNullableSetToNull(string $property): bool * @var string[] */ protected static $getters = [ - 'outcome' => 'getOutcome', - 'record_id' => 'getRecordId', - 'hardware_id' => 'getHardwareId', - 'rules_version' => 'getRulesVersion', - 'sharing' => 'getSharing', - 'takeover' => 'getTakeover', - 'travel' => 'getTravel' + 'profile_id' => 'getProfileId', + 'provider_id' => 'getProviderId', + 'provider_name' => 'getProviderName', + 'agent_name' => 'getAgentName', + 'client_kind' => 'getClientKind', + 'purpose' => 'getPurpose', + 'source' => 'getSource' ]; /** @@ -282,13 +281,13 @@ public function getModelName() */ public function __construct(?array $data = null) { - $this->setIfExists('outcome', $data ?? [], null); - $this->setIfExists('record_id', $data ?? [], null); - $this->setIfExists('hardware_id', $data ?? [], null); - $this->setIfExists('rules_version', $data ?? [], null); - $this->setIfExists('sharing', $data ?? [], null); - $this->setIfExists('takeover', $data ?? [], null); - $this->setIfExists('travel', $data ?? [], null); + $this->setIfExists('profile_id', $data ?? [], null); + $this->setIfExists('provider_id', $data ?? [], null); + $this->setIfExists('provider_name', $data ?? [], null); + $this->setIfExists('agent_name', $data ?? [], null); + $this->setIfExists('client_kind', $data ?? [], null); + $this->setIfExists('purpose', $data ?? [], null); + $this->setIfExists('source', $data ?? [], null); } /** @@ -318,11 +317,26 @@ public function listInvalidProperties() { $invalidProperties = []; - if ($this->container['outcome'] === null) { - $invalidProperties[] = "'outcome' can't be null"; + if ($this->container['profile_id'] === null) { + $invalidProperties[] = "'profile_id' can't be null"; } - if ($this->container['rules_version'] === null) { - $invalidProperties[] = "'rules_version' can't be null"; + if ($this->container['provider_id'] === null) { + $invalidProperties[] = "'provider_id' can't be null"; + } + if ($this->container['provider_name'] === null) { + $invalidProperties[] = "'provider_name' can't be null"; + } + if ($this->container['agent_name'] === null) { + $invalidProperties[] = "'agent_name' can't be null"; + } + if ($this->container['client_kind'] === null) { + $invalidProperties[] = "'client_kind' can't be null"; + } + if ($this->container['purpose'] === null) { + $invalidProperties[] = "'purpose' can't be null"; + } + if ($this->container['source'] === null) { + $invalidProperties[] = "'source' can't be null"; } return $invalidProperties; } @@ -340,190 +354,190 @@ public function valid() /** - * Gets outcome + * Gets profile_id * * @return string */ - public function getOutcome() + public function getProfileId() { - return $this->container['outcome']; + return $this->container['profile_id']; } /** - * Sets outcome + * Sets profile_id * - * @param string $outcome outcome + * @param string $profile_id profile_id * * @return self */ - public function setOutcome($outcome) + public function setProfileId($profile_id) { - if (is_null($outcome)) { - throw new \InvalidArgumentException('non-nullable outcome cannot be null'); + if (is_null($profile_id)) { + throw new \InvalidArgumentException('non-nullable profile_id cannot be null'); } - $this->container['outcome'] = $outcome; + $this->container['profile_id'] = $profile_id; return $this; } /** - * Gets record_id + * Gets provider_id * - * @return string|null + * @return string */ - public function getRecordId() + public function getProviderId() { - return $this->container['record_id']; + return $this->container['provider_id']; } /** - * Sets record_id + * Sets provider_id * - * @param string|null $record_id record_id + * @param string $provider_id provider_id * * @return self */ - public function setRecordId($record_id) + public function setProviderId($provider_id) { - if (is_null($record_id)) { - throw new \InvalidArgumentException('non-nullable record_id cannot be null'); + if (is_null($provider_id)) { + throw new \InvalidArgumentException('non-nullable provider_id cannot be null'); } - $this->container['record_id'] = $record_id; + $this->container['provider_id'] = $provider_id; return $this; } /** - * Gets hardware_id + * Gets provider_name * - * @return string|null + * @return string */ - public function getHardwareId() + public function getProviderName() { - return $this->container['hardware_id']; + return $this->container['provider_name']; } /** - * Sets hardware_id + * Sets provider_name * - * @param string|null $hardware_id FP21 hardware identity, distinct from device_id. + * @param string $provider_name provider_name * * @return self */ - public function setHardwareId($hardware_id) + public function setProviderName($provider_name) { - if (is_null($hardware_id)) { - throw new \InvalidArgumentException('non-nullable hardware_id cannot be null'); + if (is_null($provider_name)) { + throw new \InvalidArgumentException('non-nullable provider_name cannot be null'); } - $this->container['hardware_id'] = $hardware_id; + $this->container['provider_name'] = $provider_name; return $this; } /** - * Gets rules_version + * Gets agent_name * * @return string */ - public function getRulesVersion() + public function getAgentName() { - return $this->container['rules_version']; + return $this->container['agent_name']; } /** - * Sets rules_version + * Sets agent_name * - * @param string $rules_version rules_version + * @param string $agent_name agent_name * * @return self */ - public function setRulesVersion($rules_version) + public function setAgentName($agent_name) { - if (is_null($rules_version)) { - throw new \InvalidArgumentException('non-nullable rules_version cannot be null'); + if (is_null($agent_name)) { + throw new \InvalidArgumentException('non-nullable agent_name cannot be null'); } - $this->container['rules_version'] = $rules_version; + $this->container['agent_name'] = $agent_name; return $this; } /** - * Gets sharing + * Gets client_kind * - * @return object|null + * @return string */ - public function getSharing() + public function getClientKind() { - return $this->container['sharing']; + return $this->container['client_kind']; } /** - * Sets sharing + * Sets client_kind * - * @param object|null $sharing sharing + * @param string $client_kind client_kind * * @return self */ - public function setSharing($sharing) + public function setClientKind($client_kind) { - if (is_null($sharing)) { - throw new \InvalidArgumentException('non-nullable sharing cannot be null'); + if (is_null($client_kind)) { + throw new \InvalidArgumentException('non-nullable client_kind cannot be null'); } - $this->container['sharing'] = $sharing; + $this->container['client_kind'] = $client_kind; return $this; } /** - * Gets takeover + * Gets purpose * - * @return object|null + * @return string */ - public function getTakeover() + public function getPurpose() { - return $this->container['takeover']; + return $this->container['purpose']; } /** - * Sets takeover + * Sets purpose * - * @param object|null $takeover takeover + * @param string $purpose purpose * * @return self */ - public function setTakeover($takeover) + public function setPurpose($purpose) { - if (is_null($takeover)) { - throw new \InvalidArgumentException('non-nullable takeover cannot be null'); + if (is_null($purpose)) { + throw new \InvalidArgumentException('non-nullable purpose cannot be null'); } - $this->container['takeover'] = $takeover; + $this->container['purpose'] = $purpose; return $this; } /** - * Gets travel + * Gets source * - * @return object|null + * @return string */ - public function getTravel() + public function getSource() { - return $this->container['travel']; + return $this->container['source']; } /** - * Sets travel + * Sets source * - * @param object|null $travel travel + * @param string $source source * * @return self */ - public function setTravel($travel) + public function setSource($source) { - if (is_null($travel)) { - throw new \InvalidArgumentException('non-nullable travel cannot be null'); + if (is_null($source)) { + throw new \InvalidArgumentException('non-nullable source cannot be null'); } - $this->container['travel'] = $travel; + $this->container['source'] = $source; return $this; } diff --git a/generated/lib/Model/ClientIdentityEvidenceInner.php b/generated/lib/Model/ClientIdentityEvidenceInner.php new file mode 100644 index 0000000..3f8fad6 --- /dev/null +++ b/generated/lib/Model/ClientIdentityEvidenceInner.php @@ -0,0 +1,737 @@ + + */ +class ClientIdentityEvidenceInner implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'ClientIdentity_evidence_inner'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'id' => 'string', + 'method' => 'string', + 'source_id' => 'string', + 'source_revision' => 'string', + 'checked_at' => '\DateTime', + 'evaluated_at' => '\DateTime', + 'covered_attributes' => 'string[]', + 'covered_components' => 'string[]', + 'request_binding' => 'string', + 'replay_policy' => 'string' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'id' => null, + 'method' => null, + 'source_id' => null, + 'source_revision' => null, + 'checked_at' => 'date-time', + 'evaluated_at' => 'date-time', + 'covered_attributes' => null, + 'covered_components' => null, + 'request_binding' => null, + 'replay_policy' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'id' => false, + 'method' => false, + 'source_id' => false, + 'source_revision' => false, + 'checked_at' => false, + 'evaluated_at' => false, + 'covered_attributes' => false, + 'covered_components' => false, + 'request_binding' => false, + 'replay_policy' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'id' => 'id', + 'method' => 'method', + 'source_id' => 'source_id', + 'source_revision' => 'source_revision', + 'checked_at' => 'checked_at', + 'evaluated_at' => 'evaluated_at', + 'covered_attributes' => 'covered_attributes', + 'covered_components' => 'covered_components', + 'request_binding' => 'request_binding', + 'replay_policy' => 'replay_policy' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'id' => 'setId', + 'method' => 'setMethod', + 'source_id' => 'setSourceId', + 'source_revision' => 'setSourceRevision', + 'checked_at' => 'setCheckedAt', + 'evaluated_at' => 'setEvaluatedAt', + 'covered_attributes' => 'setCoveredAttributes', + 'covered_components' => 'setCoveredComponents', + 'request_binding' => 'setRequestBinding', + 'replay_policy' => 'setReplayPolicy' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'id' => 'getId', + 'method' => 'getMethod', + 'source_id' => 'getSourceId', + 'source_revision' => 'getSourceRevision', + 'checked_at' => 'getCheckedAt', + 'evaluated_at' => 'getEvaluatedAt', + 'covered_attributes' => 'getCoveredAttributes', + 'covered_components' => 'getCoveredComponents', + 'request_binding' => 'getRequestBinding', + 'replay_policy' => 'getReplayPolicy' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('id', $data ?? [], null); + $this->setIfExists('method', $data ?? [], null); + $this->setIfExists('source_id', $data ?? [], null); + $this->setIfExists('source_revision', $data ?? [], null); + $this->setIfExists('checked_at', $data ?? [], null); + $this->setIfExists('evaluated_at', $data ?? [], null); + $this->setIfExists('covered_attributes', $data ?? [], null); + $this->setIfExists('covered_components', $data ?? [], null); + $this->setIfExists('request_binding', $data ?? [], null); + $this->setIfExists('replay_policy', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['id'] === null) { + $invalidProperties[] = "'id' can't be null"; + } + if ($this->container['method'] === null) { + $invalidProperties[] = "'method' can't be null"; + } + if ($this->container['source_id'] === null) { + $invalidProperties[] = "'source_id' can't be null"; + } + if ($this->container['source_revision'] === null) { + $invalidProperties[] = "'source_revision' can't be null"; + } + if ($this->container['checked_at'] === null) { + $invalidProperties[] = "'checked_at' can't be null"; + } + if ($this->container['evaluated_at'] === null) { + $invalidProperties[] = "'evaluated_at' can't be null"; + } + if ($this->container['covered_attributes'] === null) { + $invalidProperties[] = "'covered_attributes' can't be null"; + } + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets id + * + * @return string + */ + public function getId() + { + return $this->container['id']; + } + + /** + * Sets id + * + * @param string $id id + * + * @return self + */ + public function setId($id) + { + if (is_null($id)) { + throw new \InvalidArgumentException('non-nullable id cannot be null'); + } + $this->container['id'] = $id; + + return $this; + } + + /** + * Gets method + * + * @return string + */ + public function getMethod() + { + return $this->container['method']; + } + + /** + * Sets method + * + * @param string $method method + * + * @return self + */ + public function setMethod($method) + { + if (is_null($method)) { + throw new \InvalidArgumentException('non-nullable method cannot be null'); + } + $this->container['method'] = $method; + + return $this; + } + + /** + * Gets source_id + * + * @return string + */ + public function getSourceId() + { + return $this->container['source_id']; + } + + /** + * Sets source_id + * + * @param string $source_id source_id + * + * @return self + */ + public function setSourceId($source_id) + { + if (is_null($source_id)) { + throw new \InvalidArgumentException('non-nullable source_id cannot be null'); + } + $this->container['source_id'] = $source_id; + + return $this; + } + + /** + * Gets source_revision + * + * @return string + */ + public function getSourceRevision() + { + return $this->container['source_revision']; + } + + /** + * Sets source_revision + * + * @param string $source_revision source_revision + * + * @return self + */ + public function setSourceRevision($source_revision) + { + if (is_null($source_revision)) { + throw new \InvalidArgumentException('non-nullable source_revision cannot be null'); + } + $this->container['source_revision'] = $source_revision; + + return $this; + } + + /** + * Gets checked_at + * + * @return \DateTime + */ + public function getCheckedAt() + { + return $this->container['checked_at']; + } + + /** + * Sets checked_at + * + * @param \DateTime $checked_at checked_at + * + * @return self + */ + public function setCheckedAt($checked_at) + { + if (is_null($checked_at)) { + throw new \InvalidArgumentException('non-nullable checked_at cannot be null'); + } + $this->container['checked_at'] = $checked_at; + + return $this; + } + + /** + * Gets evaluated_at + * + * @return \DateTime + */ + public function getEvaluatedAt() + { + return $this->container['evaluated_at']; + } + + /** + * Sets evaluated_at + * + * @param \DateTime $evaluated_at evaluated_at + * + * @return self + */ + public function setEvaluatedAt($evaluated_at) + { + if (is_null($evaluated_at)) { + throw new \InvalidArgumentException('non-nullable evaluated_at cannot be null'); + } + $this->container['evaluated_at'] = $evaluated_at; + + return $this; + } + + /** + * Gets covered_attributes + * + * @return string[] + */ + public function getCoveredAttributes() + { + return $this->container['covered_attributes']; + } + + /** + * Sets covered_attributes + * + * @param string[] $covered_attributes covered_attributes + * + * @return self + */ + public function setCoveredAttributes($covered_attributes) + { + if (is_null($covered_attributes)) { + throw new \InvalidArgumentException('non-nullable covered_attributes cannot be null'); + } + $this->container['covered_attributes'] = $covered_attributes; + + return $this; + } + + /** + * Gets covered_components + * + * @return string[]|null + */ + public function getCoveredComponents() + { + return $this->container['covered_components']; + } + + /** + * Sets covered_components + * + * @param string[]|null $covered_components covered_components + * + * @return self + */ + public function setCoveredComponents($covered_components) + { + if (is_null($covered_components)) { + throw new \InvalidArgumentException('non-nullable covered_components cannot be null'); + } + $this->container['covered_components'] = $covered_components; + + return $this; + } + + /** + * Gets request_binding + * + * @return string|null + */ + public function getRequestBinding() + { + return $this->container['request_binding']; + } + + /** + * Sets request_binding + * + * @param string|null $request_binding request_binding + * + * @return self + */ + public function setRequestBinding($request_binding) + { + if (is_null($request_binding)) { + throw new \InvalidArgumentException('non-nullable request_binding cannot be null'); + } + $this->container['request_binding'] = $request_binding; + + return $this; + } + + /** + * Gets replay_policy + * + * @return string|null + */ + public function getReplayPolicy() + { + return $this->container['replay_policy']; + } + + /** + * Sets replay_policy + * + * @param string|null $replay_policy replay_policy + * + * @return self + */ + public function setReplayPolicy($replay_policy) + { + if (is_null($replay_policy)) { + throw new \InvalidArgumentException('non-nullable replay_policy cannot be null'); + } + $this->container['replay_policy'] = $replay_policy; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/ClientIdentityVerifiedInner.php b/generated/lib/Model/ClientIdentityVerifiedInner.php new file mode 100644 index 0000000..e103ac4 --- /dev/null +++ b/generated/lib/Model/ClientIdentityVerifiedInner.php @@ -0,0 +1,487 @@ + + */ +class ClientIdentityVerifiedInner implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'ClientIdentity_verified_inner'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'subject' => 'string', + 'value_id' => 'string', + 'evidence_ids' => 'string[]' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'subject' => null, + 'value_id' => null, + 'evidence_ids' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'subject' => false, + 'value_id' => false, + 'evidence_ids' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'subject' => 'subject', + 'value_id' => 'value_id', + 'evidence_ids' => 'evidence_ids' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'subject' => 'setSubject', + 'value_id' => 'setValueId', + 'evidence_ids' => 'setEvidenceIds' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'subject' => 'getSubject', + 'value_id' => 'getValueId', + 'evidence_ids' => 'getEvidenceIds' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('subject', $data ?? [], null); + $this->setIfExists('value_id', $data ?? [], null); + $this->setIfExists('evidence_ids', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['subject'] === null) { + $invalidProperties[] = "'subject' can't be null"; + } + if ($this->container['value_id'] === null) { + $invalidProperties[] = "'value_id' can't be null"; + } + if ($this->container['evidence_ids'] === null) { + $invalidProperties[] = "'evidence_ids' can't be null"; + } + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets subject + * + * @return string + */ + public function getSubject() + { + return $this->container['subject']; + } + + /** + * Sets subject + * + * @param string $subject The proved attribute: provider, service or infrastructure. Proof does not extend to other attributes. + * + * @return self + */ + public function setSubject($subject) + { + if (is_null($subject)) { + throw new \InvalidArgumentException('non-nullable subject cannot be null'); + } + $this->container['subject'] = $subject; + + return $this; + } + + /** + * Gets value_id + * + * @return string + */ + public function getValueId() + { + return $this->container['value_id']; + } + + /** + * Sets value_id + * + * @param string $value_id value_id + * + * @return self + */ + public function setValueId($value_id) + { + if (is_null($value_id)) { + throw new \InvalidArgumentException('non-nullable value_id cannot be null'); + } + $this->container['value_id'] = $value_id; + + return $this; + } + + /** + * Gets evidence_ids + * + * @return string[] + */ + public function getEvidenceIds() + { + return $this->container['evidence_ids']; + } + + /** + * Sets evidence_ids + * + * @param string[] $evidence_ids evidence_ids + * + * @return self + */ + public function setEvidenceIds($evidence_ids) + { + if (is_null($evidence_ids)) { + throw new \InvalidArgumentException('non-nullable evidence_ids cannot be null'); + } + $this->container['evidence_ids'] = $evidence_ids; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/DetectionFlags.php b/generated/lib/Model/DetectionFlags.php index a722cbf..80d1077 100644 --- a/generated/lib/Model/DetectionFlags.php +++ b/generated/lib/Model/DetectionFlags.php @@ -36,7 +36,7 @@ * DetectionFlags Class Doc Comment * * @category Class - * @description Stable yes/no verdicts for the identification. Legacy 19 keys are always present; the four extension flags are present in schema 2026-10-06. Branch on these flags and on the Risk Score; signal names are for display and logging. When `search_bot` is `true`, `incognito`, `check_incomplete`, `ip_mismatch` and `javascript_disabled` are always `false`. + * @description Stable yes/no verdicts for the identification. Legacy 19 keys are always present; the extension flags depend on the scoring release. Task 204 adds optional ai_bot and ai_browser flags; older payloads omit them. Branch on these flags and on the Risk Score; signal names are for display and logging. When `search_bot` is `true`, `incognito`, `check_incomplete`, `ip_mismatch` and `javascript_disabled` are always `false`. * @package ShieldLabs\Generated * @author OpenAPI Generator team * @link https://openapi-generator.tech @@ -78,10 +78,12 @@ class DetectionFlags implements ModelInterface, ArrayAccess, \JsonSerializable 'javascript_disabled' => 'bool', 'stun_not_checked' => 'bool', 'check_incomplete' => 'bool', - 'os_mismatch2' => 'bool', 'device_spoofing' => 'bool', 'latency_test' => 'bool', - 'banned_ip' => 'bool' + 'banned_ip' => 'bool', + 'ai_bot' => 'bool', + 'ai_browser' => 'bool', + 'os_mismatch2' => 'bool' ]; /** @@ -111,10 +113,12 @@ class DetectionFlags implements ModelInterface, ArrayAccess, \JsonSerializable 'javascript_disabled' => null, 'stun_not_checked' => null, 'check_incomplete' => null, - 'os_mismatch2' => null, 'device_spoofing' => null, 'latency_test' => null, - 'banned_ip' => null + 'banned_ip' => null, + 'ai_bot' => null, + 'ai_browser' => null, + 'os_mismatch2' => null ]; /** @@ -142,10 +146,12 @@ class DetectionFlags implements ModelInterface, ArrayAccess, \JsonSerializable 'javascript_disabled' => false, 'stun_not_checked' => false, 'check_incomplete' => false, - 'os_mismatch2' => false, 'device_spoofing' => false, 'latency_test' => false, - 'banned_ip' => false + 'banned_ip' => false, + 'ai_bot' => false, + 'ai_browser' => false, + 'os_mismatch2' => false ]; /** @@ -253,10 +259,12 @@ public function isNullableSetToNull(string $property): bool 'javascript_disabled' => 'javascript_disabled', 'stun_not_checked' => 'stun_not_checked', 'check_incomplete' => 'check_incomplete', - 'os_mismatch2' => 'os_mismatch2', 'device_spoofing' => 'device_spoofing', 'latency_test' => 'latency_test', - 'banned_ip' => 'banned_ip' + 'banned_ip' => 'banned_ip', + 'ai_bot' => 'ai_bot', + 'ai_browser' => 'ai_browser', + 'os_mismatch2' => 'os_mismatch2' ]; /** @@ -284,10 +292,12 @@ public function isNullableSetToNull(string $property): bool 'javascript_disabled' => 'setJavascriptDisabled', 'stun_not_checked' => 'setStunNotChecked', 'check_incomplete' => 'setCheckIncomplete', - 'os_mismatch2' => 'setOsMismatch2', 'device_spoofing' => 'setDeviceSpoofing', 'latency_test' => 'setLatencyTest', - 'banned_ip' => 'setBannedIp' + 'banned_ip' => 'setBannedIp', + 'ai_bot' => 'setAiBot', + 'ai_browser' => 'setAiBrowser', + 'os_mismatch2' => 'setOsMismatch2' ]; /** @@ -315,10 +325,12 @@ public function isNullableSetToNull(string $property): bool 'javascript_disabled' => 'getJavascriptDisabled', 'stun_not_checked' => 'getStunNotChecked', 'check_incomplete' => 'getCheckIncomplete', - 'os_mismatch2' => 'getOsMismatch2', 'device_spoofing' => 'getDeviceSpoofing', 'latency_test' => 'getLatencyTest', - 'banned_ip' => 'getBannedIp' + 'banned_ip' => 'getBannedIp', + 'ai_bot' => 'getAiBot', + 'ai_browser' => 'getAiBrowser', + 'os_mismatch2' => 'getOsMismatch2' ]; /** @@ -397,10 +409,12 @@ public function __construct(?array $data = null) $this->setIfExists('javascript_disabled', $data ?? [], null); $this->setIfExists('stun_not_checked', $data ?? [], null); $this->setIfExists('check_incomplete', $data ?? [], null); - $this->setIfExists('os_mismatch2', $data ?? [], null); $this->setIfExists('device_spoofing', $data ?? [], null); $this->setIfExists('latency_test', $data ?? [], null); $this->setIfExists('banned_ip', $data ?? [], null); + $this->setIfExists('ai_bot', $data ?? [], null); + $this->setIfExists('ai_browser', $data ?? [], null); + $this->setIfExists('os_mismatch2', $data ?? [], null); } /** @@ -704,7 +718,7 @@ public function getOsMismatch() /** * Sets os_mismatch * - * @param bool $os_mismatch The operating system seen on the network differs from the one the browser reports. + * @param bool $os_mismatch Either internal OS consistency check detected a mismatch. The public flag combines browser/network and TCP behaviour checks. * * @return self */ @@ -812,7 +826,7 @@ public function getBrowserAutomation() /** * Sets browser_automation * - * @param bool $browser_automation Browser automation was detected, for example a WebDriver-controlled browser. + * @param bool $browser_automation Browser automation was detected, for example a WebDriver-controlled browser. Catalogue weight is 90 for task 204 scoring releases; historical result versions may retain the earlier weight 60. * * @return self */ @@ -1015,33 +1029,6 @@ public function setCheckIncomplete($check_incomplete) return $this; } - /** - * Gets os_mismatch2 - * - * @return bool|null - */ - public function getOsMismatch2() - { - return $this->container['os_mismatch2']; - } - - /** - * Sets os_mismatch2 - * - * @param bool|null $os_mismatch2 os_mismatch2 - * - * @return self - */ - public function setOsMismatch2($os_mismatch2) - { - if (is_null($os_mismatch2)) { - throw new \InvalidArgumentException('non-nullable os_mismatch2 cannot be null'); - } - $this->container['os_mismatch2'] = $os_mismatch2; - - return $this; - } - /** * Gets device_spoofing * @@ -1122,6 +1109,89 @@ public function setBannedIp($banned_ip) return $this; } + + /** + * Gets ai_bot + * + * @return bool|null + */ + public function getAiBot() + { + return $this->container['ai_bot']; + } + + /** + * Sets ai_bot + * + * @param bool|null $ai_bot An accepted bot is classified as AI training or user-requested fetch. ChatGPT-User, Claude-User and Perplexity-User are AI bots, not AI browsers. Weight 0. The flag is optional on older payloads; its absence is not an evaluated negative result. Provider claims alone do not grant zero risk. + * + * @return self + */ + public function setAiBot($ai_bot) + { + if (is_null($ai_bot)) { + throw new \InvalidArgumentException('non-nullable ai_bot cannot be null'); + } + $this->container['ai_bot'] = $ai_bot; + + return $this; + } + + /** + * Gets ai_browser + * + * @return bool|null + */ + public function getAiBrowser() + { + return $this->container['ai_browser']; + } + + /** + * Sets ai_browser + * + * @param bool|null $ai_browser A browser is identified by separate verified browser infrastructure. A generic browser User-Agent or a verified provider alone is insufficient. Weight 0. Optional on older payloads; absence is not an evaluated negative. + * + * @return self + */ + public function setAiBrowser($ai_browser) + { + if (is_null($ai_browser)) { + throw new \InvalidArgumentException('non-nullable ai_browser cannot be null'); + } + $this->container['ai_browser'] = $ai_browser; + + return $this; + } + + /** + * Gets os_mismatch2 + * + * @return bool|null + * @deprecated + */ + public function getOsMismatch2() + { + return $this->container['os_mismatch2']; + } + + /** + * Sets os_mismatch2 + * + * @param bool|null $os_mismatch2 Legacy 2026-10-06 only; current payloads combine this check into os_mismatch. + * + * @return self + * @deprecated + */ + public function setOsMismatch2($os_mismatch2) + { + if (is_null($os_mismatch2)) { + throw new \InvalidArgumentException('non-nullable os_mismatch2 cannot be null'); + } + $this->container['os_mismatch2'] = $os_mismatch2; + + return $this; + } /** * Returns true if offset exists. False otherwise. * diff --git a/generated/lib/Model/HREResult.php b/generated/lib/Model/HREResult.php index 030ae03..ba467ad 100644 --- a/generated/lib/Model/HREResult.php +++ b/generated/lib/Model/HREResult.php @@ -62,7 +62,8 @@ class HREResult implements ModelInterface, ArrayAccess, \JsonSerializable 'level' => 'string', 'reason' => 'string', 'devices' => 'int', - 'min_devices' => 'int' + 'min_devices' => 'int', + 'cluster_id' => 'string' ]; /** @@ -77,7 +78,8 @@ class HREResult implements ModelInterface, ArrayAccess, \JsonSerializable 'level' => null, 'reason' => null, 'devices' => null, - 'min_devices' => null + 'min_devices' => null, + 'cluster_id' => null ]; /** @@ -90,7 +92,8 @@ class HREResult implements ModelInterface, ArrayAccess, \JsonSerializable 'level' => true, 'reason' => false, 'devices' => false, - 'min_devices' => false + 'min_devices' => false, + 'cluster_id' => true ]; /** @@ -183,7 +186,8 @@ public function isNullableSetToNull(string $property): bool 'level' => 'level', 'reason' => 'reason', 'devices' => 'devices', - 'min_devices' => 'min_devices' + 'min_devices' => 'min_devices', + 'cluster_id' => 'cluster_id' ]; /** @@ -196,7 +200,8 @@ public function isNullableSetToNull(string $property): bool 'level' => 'setLevel', 'reason' => 'setReason', 'devices' => 'setDevices', - 'min_devices' => 'setMinDevices' + 'min_devices' => 'setMinDevices', + 'cluster_id' => 'setClusterId' ]; /** @@ -209,7 +214,8 @@ public function isNullableSetToNull(string $property): bool 'level' => 'getLevel', 'reason' => 'getReason', 'devices' => 'getDevices', - 'min_devices' => 'getMinDevices' + 'min_devices' => 'getMinDevices', + 'cluster_id' => 'getClusterId' ]; /** @@ -274,6 +280,7 @@ public function __construct(?array $data = null) $this->setIfExists('reason', $data ?? [], null); $this->setIfExists('devices', $data ?? [], null); $this->setIfExists('min_devices', $data ?? [], null); + $this->setIfExists('cluster_id', $data ?? [], null); } /** @@ -486,6 +493,40 @@ public function setMinDevices($min_devices) return $this; } + + /** + * Gets cluster_id + * + * @return string|null + */ + public function getClusterId() + { + return $this->container['cluster_id']; + } + + /** + * Sets cluster_id + * + * @param string|null $cluster_id Authoritative cluster ID for this HRE result. Null when no cluster was published for the result, including old stored verdicts; never a device ID. Reused on retries. + * + * @return self + */ + public function setClusterId($cluster_id) + { + if (is_null($cluster_id)) { + array_push($this->openAPINullablesSetToNull, 'cluster_id'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('cluster_id', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['cluster_id'] = $cluster_id; + + return $this; + } /** * Returns true if offset exists. False otherwise. * diff --git a/generated/lib/Model/HistoryRow.php b/generated/lib/Model/HistoryRow.php index 6938273..b784123 100644 --- a/generated/lib/Model/HistoryRow.php +++ b/generated/lib/Model/HistoryRow.php @@ -59,6 +59,7 @@ class HistoryRow implements ModelInterface, ArrayAccess, \JsonSerializable * @var string[] */ protected static $openAPITypes = [ + 'client_identity' => '\ShieldLabs\Generated\Model\ClientIdentity', 'request_id' => 'string', 'session_id' => 'string', 'cookie_id' => 'string', @@ -122,6 +123,7 @@ class HistoryRow implements ModelInterface, ArrayAccess, \JsonSerializable * @psalm-var array */ protected static $openAPIFormats = [ + 'client_identity' => null, 'request_id' => 'uuid', 'session_id' => 'uuid', 'cookie_id' => 'uuid', @@ -183,6 +185,7 @@ class HistoryRow implements ModelInterface, ArrayAccess, \JsonSerializable * @var boolean[] */ protected static array $openAPINullables = [ + 'client_identity' => false, 'request_id' => false, 'session_id' => false, 'cookie_id' => false, @@ -324,6 +327,7 @@ public function isNullableSetToNull(string $property): bool * @var string[] */ protected static $attributeMap = [ + 'client_identity' => 'client_identity', 'request_id' => 'request_id', 'session_id' => 'session_id', 'cookie_id' => 'cookie_id', @@ -385,6 +389,7 @@ public function isNullableSetToNull(string $property): bool * @var string[] */ protected static $setters = [ + 'client_identity' => 'setClientIdentity', 'request_id' => 'setRequestId', 'session_id' => 'setSessionId', 'cookie_id' => 'setCookieId', @@ -446,6 +451,7 @@ public function isNullableSetToNull(string $property): bool * @var string[] */ protected static $getters = [ + 'client_identity' => 'getClientIdentity', 'request_id' => 'getRequestId', 'session_id' => 'getSessionId', 'cookie_id' => 'getCookieId', @@ -558,6 +564,7 @@ public function getModelName() */ public function __construct(?array $data = null) { + $this->setIfExists('client_identity', $data ?? [], null); $this->setIfExists('request_id', $data ?? [], null); $this->setIfExists('session_id', $data ?? [], null); $this->setIfExists('cookie_id', $data ?? [], null); @@ -783,6 +790,33 @@ public function valid() } + /** + * Gets client_identity + * + * @return \ShieldLabs\Generated\Model\ClientIdentity|null + */ + public function getClientIdentity() + { + return $this->container['client_identity']; + } + + /** + * Sets client_identity + * + * @param \ShieldLabs\Generated\Model\ClientIdentity|null $client_identity client_identity + * + * @return self + */ + public function setClientIdentity($client_identity) + { + if (is_null($client_identity)) { + throw new \InvalidArgumentException('non-nullable client_identity cannot be null'); + } + $this->container['client_identity'] = $client_identity; + + return $this; + } + /** * Gets request_id * diff --git a/generated/lib/Model/IdentificationScoredData.php b/generated/lib/Model/IdentificationScoredData.php index 819567e..d5bc38f 100644 --- a/generated/lib/Model/IdentificationScoredData.php +++ b/generated/lib/Model/IdentificationScoredData.php @@ -36,7 +36,7 @@ * IdentificationScoredData Class Doc Comment * * @category Class - * @description Final identification. risk_score is this scan only; no all-time entity risk. New extension fields are required by version 2026-10-06; legacy bodies remain accepted. + * @description Final identification. risk_score is this scan only. Version 2026-10-07 uses signals for score contributions, detection_flags for final decisions, and hre for account results. Older bodies remain accepted. * @package ShieldLabs\Generated * @author OpenAPI Generator team * @link https://openapi-generator.tech @@ -59,6 +59,7 @@ class IdentificationScoredData implements ModelInterface, ArrayAccess, \JsonSeri * @var string[] */ protected static $openAPITypes = [ + 'client_identity' => '\ShieldLabs\Generated\Model\ClientIdentity', 'request_id' => 'string', 'visitor_id' => 'string', 'device_id' => 'string', @@ -81,7 +82,9 @@ class IdentificationScoredData implements ModelInterface, ArrayAccess, \JsonSeri 'scoring_version' => 'string', 'risk_events' => '\ShieldLabs\Generated\Model\RiskEvent[]', 'hre' => '\ShieldLabs\Generated\Model\HRE', - 'fingerprint' => '\ShieldLabs\Generated\Model\Fingerprint' + 'search_bot_owner' => 'string', + 'ai_bot_owner' => 'string', + 'ai_browser_owner' => 'string' ]; /** @@ -92,6 +95,7 @@ class IdentificationScoredData implements ModelInterface, ArrayAccess, \JsonSeri * @psalm-var array */ protected static $openAPIFormats = [ + 'client_identity' => null, 'request_id' => 'uuid', 'visitor_id' => 'uuid', 'device_id' => 'uuid', @@ -114,7 +118,9 @@ class IdentificationScoredData implements ModelInterface, ArrayAccess, \JsonSeri 'scoring_version' => null, 'risk_events' => null, 'hre' => null, - 'fingerprint' => null + 'search_bot_owner' => null, + 'ai_bot_owner' => null, + 'ai_browser_owner' => null ]; /** @@ -123,6 +129,7 @@ class IdentificationScoredData implements ModelInterface, ArrayAccess, \JsonSeri * @var boolean[] */ protected static array $openAPINullables = [ + 'client_identity' => false, 'request_id' => false, 'visitor_id' => false, 'device_id' => false, @@ -145,7 +152,9 @@ class IdentificationScoredData implements ModelInterface, ArrayAccess, \JsonSeri 'scoring_version' => false, 'risk_events' => false, 'hre' => false, - 'fingerprint' => false + 'search_bot_owner' => false, + 'ai_bot_owner' => false, + 'ai_browser_owner' => false ]; /** @@ -234,6 +243,7 @@ public function isNullableSetToNull(string $property): bool * @var string[] */ protected static $attributeMap = [ + 'client_identity' => 'client_identity', 'request_id' => 'request_id', 'visitor_id' => 'visitor_id', 'device_id' => 'device_id', @@ -256,7 +266,9 @@ public function isNullableSetToNull(string $property): bool 'scoring_version' => 'scoring_version', 'risk_events' => 'risk_events', 'hre' => 'hre', - 'fingerprint' => 'fingerprint' + 'search_bot_owner' => 'search_bot_owner', + 'ai_bot_owner' => 'ai_bot_owner', + 'ai_browser_owner' => 'ai_browser_owner' ]; /** @@ -265,6 +277,7 @@ public function isNullableSetToNull(string $property): bool * @var string[] */ protected static $setters = [ + 'client_identity' => 'setClientIdentity', 'request_id' => 'setRequestId', 'visitor_id' => 'setVisitorId', 'device_id' => 'setDeviceId', @@ -287,7 +300,9 @@ public function isNullableSetToNull(string $property): bool 'scoring_version' => 'setScoringVersion', 'risk_events' => 'setRiskEvents', 'hre' => 'setHre', - 'fingerprint' => 'setFingerprint' + 'search_bot_owner' => 'setSearchBotOwner', + 'ai_bot_owner' => 'setAiBotOwner', + 'ai_browser_owner' => 'setAiBrowserOwner' ]; /** @@ -296,6 +311,7 @@ public function isNullableSetToNull(string $property): bool * @var string[] */ protected static $getters = [ + 'client_identity' => 'getClientIdentity', 'request_id' => 'getRequestId', 'visitor_id' => 'getVisitorId', 'device_id' => 'getDeviceId', @@ -318,7 +334,9 @@ public function isNullableSetToNull(string $property): bool 'scoring_version' => 'getScoringVersion', 'risk_events' => 'getRiskEvents', 'hre' => 'getHre', - 'fingerprint' => 'getFingerprint' + 'search_bot_owner' => 'getSearchBotOwner', + 'ai_bot_owner' => 'getAiBotOwner', + 'ai_browser_owner' => 'getAiBrowserOwner' ]; /** @@ -378,6 +396,7 @@ public function getModelName() */ public function __construct(?array $data = null) { + $this->setIfExists('client_identity', $data ?? [], null); $this->setIfExists('request_id', $data ?? [], null); $this->setIfExists('visitor_id', $data ?? [], null); $this->setIfExists('device_id', $data ?? [], null); @@ -400,7 +419,9 @@ public function __construct(?array $data = null) $this->setIfExists('scoring_version', $data ?? [], null); $this->setIfExists('risk_events', $data ?? [], null); $this->setIfExists('hre', $data ?? [], null); - $this->setIfExists('fingerprint', $data ?? [], null); + $this->setIfExists('search_bot_owner', $data ?? [], null); + $this->setIfExists('ai_bot_owner', $data ?? [], null); + $this->setIfExists('ai_browser_owner', $data ?? [], null); } /** @@ -511,6 +532,33 @@ public function valid() } + /** + * Gets client_identity + * + * @return \ShieldLabs\Generated\Model\ClientIdentity|null + */ + public function getClientIdentity() + { + return $this->container['client_identity']; + } + + /** + * Sets client_identity + * + * @param \ShieldLabs\Generated\Model\ClientIdentity|null $client_identity client_identity + * + * @return self + */ + public function setClientIdentity($client_identity) + { + if (is_null($client_identity)) { + throw new \InvalidArgumentException('non-nullable client_identity cannot be null'); + } + $this->container['client_identity'] = $client_identity; + + return $this; + } + /** * Gets request_id * @@ -1077,6 +1125,7 @@ public function setScoringVersion($scoring_version) * Gets risk_events * * @return \ShieldLabs\Generated\Model\RiskEvent[]|null + * @deprecated */ public function getRiskEvents() { @@ -1086,9 +1135,10 @@ public function getRiskEvents() /** * Sets risk_events * - * @param \ShieldLabs\Generated\Model\RiskEvent[]|null $risk_events risk_events + * @param \ShieldLabs\Generated\Model\RiskEvent[]|null $risk_events Legacy 2026-10-06 only; absent from current scored events. * * @return self + * @deprecated */ public function setRiskEvents($risk_events) { @@ -1128,28 +1178,82 @@ public function setHre($hre) } /** - * Gets fingerprint + * Gets search_bot_owner + * + * @return string|null + */ + public function getSearchBotOwner() + { + return $this->container['search_bot_owner']; + } + + /** + * Sets search_bot_owner + * + * @param string|null $search_bot_owner Owner label from accepted search-bot detection; omitted when unknown or inactive. + * + * @return self + */ + public function setSearchBotOwner($search_bot_owner) + { + if (is_null($search_bot_owner)) { + throw new \InvalidArgumentException('non-nullable search_bot_owner cannot be null'); + } + $this->container['search_bot_owner'] = $search_bot_owner; + + return $this; + } + + /** + * Gets ai_bot_owner * - * @return \ShieldLabs\Generated\Model\Fingerprint|null + * @return string|null + */ + public function getAiBotOwner() + { + return $this->container['ai_bot_owner']; + } + + /** + * Sets ai_bot_owner + * + * @param string|null $ai_bot_owner Provider company label from accepted AI-bot detection; omitted when unknown or inactive. + * + * @return self + */ + public function setAiBotOwner($ai_bot_owner) + { + if (is_null($ai_bot_owner)) { + throw new \InvalidArgumentException('non-nullable ai_bot_owner cannot be null'); + } + $this->container['ai_bot_owner'] = $ai_bot_owner; + + return $this; + } + + /** + * Gets ai_browser_owner + * + * @return string|null */ - public function getFingerprint() + public function getAiBrowserOwner() { - return $this->container['fingerprint']; + return $this->container['ai_browser_owner']; } /** - * Sets fingerprint + * Sets ai_browser_owner * - * @param \ShieldLabs\Generated\Model\Fingerprint|null $fingerprint fingerprint + * @param string|null $ai_browser_owner Owner label from accepted AI-browser detection; omitted when unknown or inactive. * * @return self */ - public function setFingerprint($fingerprint) + public function setAiBrowserOwner($ai_browser_owner) { - if (is_null($fingerprint)) { - throw new \InvalidArgumentException('non-nullable fingerprint cannot be null'); + if (is_null($ai_browser_owner)) { + throw new \InvalidArgumentException('non-nullable ai_browser_owner cannot be null'); } - $this->container['fingerprint'] = $fingerprint; + $this->container['ai_browser_owner'] = $ai_browser_owner; return $this; } diff --git a/generated/lib/Model/IdentificationScoredEvent.php b/generated/lib/Model/IdentificationScoredEvent.php index 49cc5aa..885cd3e 100644 --- a/generated/lib/Model/IdentificationScoredEvent.php +++ b/generated/lib/Model/IdentificationScoredEvent.php @@ -394,7 +394,7 @@ public function getSchemaVersion() /** * Sets schema_version * - * @param string $schema_version Webhook contract version. Current release 2026-10-06; parsers also accept legacy 2026-06-01. + * @param string $schema_version Webhook contract version. Scored release 2026-10-06; multi-account group release 2026-10-07; parsers also accept legacy 2026-06-01. * * @return self */ diff --git a/generated/lib/Model/MultiaccountChangedData.php b/generated/lib/Model/MultiaccountChangedData.php new file mode 100644 index 0000000..021ca0e --- /dev/null +++ b/generated/lib/Model/MultiaccountChangedData.php @@ -0,0 +1,1129 @@ + + */ +class MultiaccountChangedData implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'MultiaccountChangedData'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'kind' => 'mixed', + 'domain' => 'string', + 'action' => 'string', + 'status' => 'mixed', + 'detected' => 'bool', + 'level' => 'string', + 'cluster_id' => 'string', + 'revision' => 'string', + 'previous_revision' => 'string', + 'user_hids' => 'string[]', + 'users_count' => 'int', + 'members_complete' => 'mixed', + 'evaluated_at' => '\DateTime', + 'rules_version' => 'string', + 'source' => '\ShieldLabs\Generated\Model\MultiaccountChangedDataSource', + 'evidence_summary' => '\ShieldLabs\Generated\Model\MultiaccountChangedDataEvidenceSummary' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'kind' => null, + 'domain' => null, + 'action' => null, + 'status' => null, + 'detected' => null, + 'level' => null, + 'cluster_id' => 'uuid', + 'revision' => null, + 'previous_revision' => null, + 'user_hids' => null, + 'users_count' => null, + 'members_complete' => null, + 'evaluated_at' => 'date-time', + 'rules_version' => null, + 'source' => null, + 'evidence_summary' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'kind' => true, + 'domain' => false, + 'action' => false, + 'status' => true, + 'detected' => false, + 'level' => true, + 'cluster_id' => false, + 'revision' => false, + 'previous_revision' => false, + 'user_hids' => false, + 'users_count' => false, + 'members_complete' => true, + 'evaluated_at' => false, + 'rules_version' => false, + 'source' => false, + 'evidence_summary' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'kind' => 'kind', + 'domain' => 'domain', + 'action' => 'action', + 'status' => 'status', + 'detected' => 'detected', + 'level' => 'level', + 'cluster_id' => 'cluster_id', + 'revision' => 'revision', + 'previous_revision' => 'previous_revision', + 'user_hids' => 'user_hids', + 'users_count' => 'users_count', + 'members_complete' => 'members_complete', + 'evaluated_at' => 'evaluated_at', + 'rules_version' => 'rules_version', + 'source' => 'source', + 'evidence_summary' => 'evidence_summary' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'kind' => 'setKind', + 'domain' => 'setDomain', + 'action' => 'setAction', + 'status' => 'setStatus', + 'detected' => 'setDetected', + 'level' => 'setLevel', + 'cluster_id' => 'setClusterId', + 'revision' => 'setRevision', + 'previous_revision' => 'setPreviousRevision', + 'user_hids' => 'setUserHids', + 'users_count' => 'setUsersCount', + 'members_complete' => 'setMembersComplete', + 'evaluated_at' => 'setEvaluatedAt', + 'rules_version' => 'setRulesVersion', + 'source' => 'setSource', + 'evidence_summary' => 'setEvidenceSummary' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'kind' => 'getKind', + 'domain' => 'getDomain', + 'action' => 'getAction', + 'status' => 'getStatus', + 'detected' => 'getDetected', + 'level' => 'getLevel', + 'cluster_id' => 'getClusterId', + 'revision' => 'getRevision', + 'previous_revision' => 'getPreviousRevision', + 'user_hids' => 'getUserHids', + 'users_count' => 'getUsersCount', + 'members_complete' => 'getMembersComplete', + 'evaluated_at' => 'getEvaluatedAt', + 'rules_version' => 'getRulesVersion', + 'source' => 'getSource', + 'evidence_summary' => 'getEvidenceSummary' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + public const ACTION_DETECTED = 'detected'; + public const ACTION_UPDATED = 'updated'; + public const ACTION_RESOLVED = 'resolved'; + public const LEVEL_MEDIUM = 'medium'; + public const LEVEL_HIGH = 'high'; + + /** + * Gets allowable values of the enum + * + * @return string[] + */ + public function getActionAllowableValues() + { + return [ + self::ACTION_DETECTED, + self::ACTION_UPDATED, + self::ACTION_RESOLVED, + ]; + } + + /** + * Gets allowable values of the enum + * + * @return string[] + */ + public function getLevelAllowableValues() + { + return [ + self::LEVEL_MEDIUM, + self::LEVEL_HIGH, + ]; + } + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('kind', $data ?? [], null); + $this->setIfExists('domain', $data ?? [], null); + $this->setIfExists('action', $data ?? [], null); + $this->setIfExists('status', $data ?? [], null); + $this->setIfExists('detected', $data ?? [], null); + $this->setIfExists('level', $data ?? [], null); + $this->setIfExists('cluster_id', $data ?? [], null); + $this->setIfExists('revision', $data ?? [], null); + $this->setIfExists('previous_revision', $data ?? [], null); + $this->setIfExists('user_hids', $data ?? [], null); + $this->setIfExists('users_count', $data ?? [], null); + $this->setIfExists('members_complete', $data ?? [], null); + $this->setIfExists('evaluated_at', $data ?? [], null); + $this->setIfExists('rules_version', $data ?? [], null); + $this->setIfExists('source', $data ?? [], null); + $this->setIfExists('evidence_summary', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['kind'] === null && !$this->isNullableSetToNull('kind')) { + $invalidProperties[] = "'kind' is required"; + } + if ($this->container['domain'] === null) { + $invalidProperties[] = "'domain' can't be null"; + } + if ((mb_strlen($this->container['domain']) < 1)) { + $invalidProperties[] = "invalid value for 'domain', the character length must be bigger than or equal to 1."; + } + + if ($this->container['action'] === null) { + $invalidProperties[] = "'action' can't be null"; + } + $allowedValues = $this->getActionAllowableValues(); + if (!is_null($this->container['action']) && !in_array($this->container['action'], $allowedValues, true)) { + $invalidProperties[] = sprintf( + "invalid value '%s' for 'action', must be one of '%s'", + $this->container['action'], + implode("', '", $allowedValues) + ); + } + + if ($this->container['status'] === null && !$this->isNullableSetToNull('status')) { + $invalidProperties[] = "'status' is required"; + } + if ($this->container['detected'] === null) { + $invalidProperties[] = "'detected' can't be null"; + } + if ($this->container['level'] === null && !$this->isNullableSetToNull('level')) { + $invalidProperties[] = "'level' is required"; + } + $allowedValues = $this->getLevelAllowableValues(); + if (!is_null($this->container['level']) && !in_array($this->container['level'], $allowedValues, true)) { + $invalidProperties[] = sprintf( + "invalid value '%s' for 'level', must be one of '%s'", + $this->container['level'], + implode("', '", $allowedValues) + ); + } + + if ($this->container['cluster_id'] === null) { + $invalidProperties[] = "'cluster_id' can't be null"; + } + if ($this->container['revision'] === null) { + $invalidProperties[] = "'revision' can't be null"; + } + if (!preg_match("/^[1-9][0-9]{0,19}$/", $this->container['revision'])) { + $invalidProperties[] = "invalid value for 'revision', must be conform to the pattern /^[1-9][0-9]{0,19}$/."; + } + + if ($this->container['previous_revision'] === null) { + $invalidProperties[] = "'previous_revision' can't be null"; + } + if (!preg_match("/^(0|[1-9][0-9]{0,19})$/", $this->container['previous_revision'])) { + $invalidProperties[] = "invalid value for 'previous_revision', must be conform to the pattern /^(0|[1-9][0-9]{0,19})$/."; + } + + if ($this->container['user_hids'] === null) { + $invalidProperties[] = "'user_hids' can't be null"; + } + if ((count($this->container['user_hids']) < 3)) { + $invalidProperties[] = "invalid value for 'user_hids', number of items must be greater than or equal to 3."; + } + + if ($this->container['users_count'] === null) { + $invalidProperties[] = "'users_count' can't be null"; + } + if (($this->container['users_count'] < 3)) { + $invalidProperties[] = "invalid value for 'users_count', must be bigger than or equal to 3."; + } + + if ($this->container['members_complete'] === null && !$this->isNullableSetToNull('members_complete')) { + $invalidProperties[] = "'members_complete' is required"; + } + if ($this->container['evaluated_at'] === null) { + $invalidProperties[] = "'evaluated_at' can't be null"; + } + if (!preg_match("/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/", $this->container['evaluated_at'])) { + $invalidProperties[] = "invalid value for 'evaluated_at', must be conform to the pattern /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/."; + } + + if ($this->container['rules_version'] === null) { + $invalidProperties[] = "'rules_version' can't be null"; + } + if ((mb_strlen($this->container['rules_version']) < 1)) { + $invalidProperties[] = "invalid value for 'rules_version', the character length must be bigger than or equal to 1."; + } + + if ($this->container['source'] === null) { + $invalidProperties[] = "'source' can't be null"; + } + if ($this->container['evidence_summary'] === null) { + $invalidProperties[] = "'evidence_summary' can't be null"; + } + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets kind + * + * @return mixed|null + */ + public function getKind() + { + return $this->container['kind']; + } + + /** + * Sets kind + * + * @param mixed|null $kind kind + * + * @return self + */ + public function setKind($kind) + { + if (is_null($kind)) { + array_push($this->openAPINullablesSetToNull, 'kind'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('kind', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['kind'] = $kind; + + return $this; + } + + /** + * Gets domain + * + * @return string + */ + public function getDomain() + { + return $this->container['domain']; + } + + /** + * Sets domain + * + * @param string $domain domain + * + * @return self + */ + public function setDomain($domain) + { + if (is_null($domain)) { + throw new \InvalidArgumentException('non-nullable domain cannot be null'); + } + + if ((mb_strlen($domain) < 1)) { + throw new \InvalidArgumentException('invalid length for $domain when calling MultiaccountChangedData., must be bigger than or equal to 1.'); + } + + $this->container['domain'] = $domain; + + return $this; + } + + /** + * Gets action + * + * @return string + */ + public function getAction() + { + return $this->container['action']; + } + + /** + * Sets action + * + * @param string $action action + * + * @return self + */ + public function setAction($action) + { + if (is_null($action)) { + throw new \InvalidArgumentException('non-nullable action cannot be null'); + } + $allowedValues = $this->getActionAllowableValues(); + if (!in_array($action, $allowedValues, true)) { + throw new \InvalidArgumentException( + sprintf( + "Invalid value '%s' for 'action', must be one of '%s'", + $action, + implode("', '", $allowedValues) + ) + ); + } + $this->container['action'] = $action; + + return $this; + } + + /** + * Gets status + * + * @return mixed|null + */ + public function getStatus() + { + return $this->container['status']; + } + + /** + * Sets status + * + * @param mixed|null $status The result comes from a complete, verified detector source cut. Pending or unavailable work does not produce this event. + * + * @return self + */ + public function setStatus($status) + { + if (is_null($status)) { + array_push($this->openAPINullablesSetToNull, 'status'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('status', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['status'] = $status; + + return $this; + } + + /** + * Gets detected + * + * @return bool + */ + public function getDetected() + { + return $this->container['detected']; + } + + /** + * Sets detected + * + * @param bool $detected detected + * + * @return self + */ + public function setDetected($detected) + { + if (is_null($detected)) { + throw new \InvalidArgumentException('non-nullable detected cannot be null'); + } + $this->container['detected'] = $detected; + + return $this; + } + + /** + * Gets level + * + * @return string|null + */ + public function getLevel() + { + return $this->container['level']; + } + + /** + * Sets level + * + * @param string|null $level level + * + * @return self + */ + public function setLevel($level) + { + if (is_null($level)) { + array_push($this->openAPINullablesSetToNull, 'level'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('level', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $allowedValues = $this->getLevelAllowableValues(); + if (!is_null($level) && !in_array($level, $allowedValues, true)) { + throw new \InvalidArgumentException( + sprintf( + "Invalid value '%s' for 'level', must be one of '%s'", + $level, + implode("', '", $allowedValues) + ) + ); + } + $this->container['level'] = $level; + + return $this; + } + + /** + * Gets cluster_id + * + * @return string + */ + public function getClusterId() + { + return $this->container['cluster_id']; + } + + /** + * Sets cluster_id + * + * @param string $cluster_id ID of the exact sorted user set within this site. A membership change resolves the old group and detects a new group. + * + * @return self + */ + public function setClusterId($cluster_id) + { + if (is_null($cluster_id)) { + throw new \InvalidArgumentException('non-nullable cluster_id cannot be null'); + } + $this->container['cluster_id'] = $cluster_id; + + return $this; + } + + /** + * Gets revision + * + * @return string + */ + public function getRevision() + { + return $this->container['revision']; + } + + /** + * Sets revision + * + * @param string $revision Publication version of this transition, as a decimal string to preserve UInt64 precision. + * + * @return self + */ + public function setRevision($revision) + { + if (is_null($revision)) { + throw new \InvalidArgumentException('non-nullable revision cannot be null'); + } + + if ((!preg_match("/^[1-9][0-9]{0,19}$/", ObjectSerializer::toString($revision)))) { + throw new \InvalidArgumentException("invalid value for \$revision when calling MultiaccountChangedData., must conform to the pattern /^[1-9][0-9]{0,19}$/."); + } + + $this->container['revision'] = $revision; + + return $this; + } + + /** + * Gets previous_revision + * + * @return string + */ + public function getPreviousRevision() + { + return $this->container['previous_revision']; + } + + /** + * Sets previous_revision + * + * @param string $previous_revision Previous transition version while the group was active; null for a newly detected or reappearing group. + * + * @return self + */ + public function setPreviousRevision($previous_revision) + { + if (is_null($previous_revision)) { + throw new \InvalidArgumentException('non-nullable previous_revision cannot be null'); + } + + if ((!preg_match("/^(0|[1-9][0-9]{0,19})$/", ObjectSerializer::toString($previous_revision)))) { + throw new \InvalidArgumentException("invalid value for \$previous_revision when calling MultiaccountChangedData., must conform to the pattern /^(0|[1-9][0-9]{0,19})$/."); + } + + $this->container['previous_revision'] = $previous_revision; + + return $this; + } + + /** + * Gets user_hids + * + * @return string[] + */ + public function getUserHids() + { + return $this->container['user_hids']; + } + + /** + * Sets user_hids + * + * @param string[] $user_hids Complete sorted group membership. Users from another site are never included. This list is not truncated. + * + * @return self + */ + public function setUserHids($user_hids) + { + if (is_null($user_hids)) { + throw new \InvalidArgumentException('non-nullable user_hids cannot be null'); + } + + + if ((count($user_hids) < 3)) { + throw new \InvalidArgumentException('invalid length for $user_hids when calling MultiaccountChangedData., number of items must be greater than or equal to 3.'); + } + $this->container['user_hids'] = $user_hids; + + return $this; + } + + /** + * Gets users_count + * + * @return int + */ + public function getUsersCount() + { + return $this->container['users_count']; + } + + /** + * Sets users_count + * + * @param int $users_count Equal to the length of user_hids. + * + * @return self + */ + public function setUsersCount($users_count) + { + if (is_null($users_count)) { + throw new \InvalidArgumentException('non-nullable users_count cannot be null'); + } + + if (($users_count < 3)) { + throw new \InvalidArgumentException('invalid value for $users_count when calling MultiaccountChangedData., must be bigger than or equal to 3.'); + } + + $this->container['users_count'] = $users_count; + + return $this; + } + + /** + * Gets members_complete + * + * @return mixed|null + */ + public function getMembersComplete() + { + return $this->container['members_complete']; + } + + /** + * Sets members_complete + * + * @param mixed|null $members_complete members_complete + * + * @return self + */ + public function setMembersComplete($members_complete) + { + if (is_null($members_complete)) { + array_push($this->openAPINullablesSetToNull, 'members_complete'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('members_complete', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['members_complete'] = $members_complete; + + return $this; + } + + /** + * Gets evaluated_at + * + * @return \DateTime + */ + public function getEvaluatedAt() + { + return $this->container['evaluated_at']; + } + + /** + * Sets evaluated_at + * + * @param \DateTime $evaluated_at RFC 3339 timestamp in UTC with up to 9 fractional digits (trailing zeros trimmed), for example `2026-09-30T12:34:57.482913041Z`. Parse it with a parser that accepts nanoseconds. + * + * @return self + */ + public function setEvaluatedAt($evaluated_at) + { + if (is_null($evaluated_at)) { + throw new \InvalidArgumentException('non-nullable evaluated_at cannot be null'); + } + + if ((!preg_match("/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/", ObjectSerializer::toString($evaluated_at)))) { + throw new \InvalidArgumentException("invalid value for \$evaluated_at when calling MultiaccountChangedData., must conform to the pattern /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/."); + } + + $this->container['evaluated_at'] = $evaluated_at; + + return $this; + } + + /** + * Gets rules_version + * + * @return string + */ + public function getRulesVersion() + { + return $this->container['rules_version']; + } + + /** + * Sets rules_version + * + * @param string $rules_version rules_version + * + * @return self + */ + public function setRulesVersion($rules_version) + { + if (is_null($rules_version)) { + throw new \InvalidArgumentException('non-nullable rules_version cannot be null'); + } + + if ((mb_strlen($rules_version) < 1)) { + throw new \InvalidArgumentException('invalid length for $rules_version when calling MultiaccountChangedData., must be bigger than or equal to 1.'); + } + + $this->container['rules_version'] = $rules_version; + + return $this; + } + + /** + * Gets source + * + * @return \ShieldLabs\Generated\Model\MultiaccountChangedDataSource + */ + public function getSource() + { + return $this->container['source']; + } + + /** + * Sets source + * + * @param \ShieldLabs\Generated\Model\MultiaccountChangedDataSource $source source + * + * @return self + */ + public function setSource($source) + { + if (is_null($source)) { + throw new \InvalidArgumentException('non-nullable source cannot be null'); + } + $this->container['source'] = $source; + + return $this; + } + + /** + * Gets evidence_summary + * + * @return \ShieldLabs\Generated\Model\MultiaccountChangedDataEvidenceSummary + */ + public function getEvidenceSummary() + { + return $this->container['evidence_summary']; + } + + /** + * Sets evidence_summary + * + * @param \ShieldLabs\Generated\Model\MultiaccountChangedDataEvidenceSummary $evidence_summary evidence_summary + * + * @return self + */ + public function setEvidenceSummary($evidence_summary) + { + if (is_null($evidence_summary)) { + throw new \InvalidArgumentException('non-nullable evidence_summary cannot be null'); + } + $this->container['evidence_summary'] = $evidence_summary; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/MultiaccountChangedDataEvidenceSummary.php b/generated/lib/Model/MultiaccountChangedDataEvidenceSummary.php new file mode 100644 index 0000000..424462a --- /dev/null +++ b/generated/lib/Model/MultiaccountChangedDataEvidenceSummary.php @@ -0,0 +1,491 @@ + + */ +class MultiaccountChangedDataEvidenceSummary implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'MultiaccountChangedData_evidence_summary'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'basis_types' => 'string[]', + 'rules' => 'string[]', + 'detail_truncated' => 'bool' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'basis_types' => null, + 'rules' => null, + 'detail_truncated' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'basis_types' => false, + 'rules' => false, + 'detail_truncated' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'basis_types' => 'basis_types', + 'rules' => 'rules', + 'detail_truncated' => 'detail_truncated' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'basis_types' => 'setBasisTypes', + 'rules' => 'setRules', + 'detail_truncated' => 'setDetailTruncated' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'basis_types' => 'getBasisTypes', + 'rules' => 'getRules', + 'detail_truncated' => 'getDetailTruncated' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('basis_types', $data ?? [], null); + $this->setIfExists('rules', $data ?? [], null); + $this->setIfExists('detail_truncated', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['basis_types'] === null) { + $invalidProperties[] = "'basis_types' can't be null"; + } + if ($this->container['rules'] === null) { + $invalidProperties[] = "'rules' can't be null"; + } + if ($this->container['detail_truncated'] === null) { + $invalidProperties[] = "'detail_truncated' can't be null"; + } + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets basis_types + * + * @return string[] + */ + public function getBasisTypes() + { + return $this->container['basis_types']; + } + + /** + * Sets basis_types + * + * @param string[] $basis_types basis_types + * + * @return self + */ + public function setBasisTypes($basis_types) + { + if (is_null($basis_types)) { + throw new \InvalidArgumentException('non-nullable basis_types cannot be null'); + } + + + $this->container['basis_types'] = $basis_types; + + return $this; + } + + /** + * Gets rules + * + * @return string[] + */ + public function getRules() + { + return $this->container['rules']; + } + + /** + * Sets rules + * + * @param string[] $rules rules + * + * @return self + */ + public function setRules($rules) + { + if (is_null($rules)) { + throw new \InvalidArgumentException('non-nullable rules cannot be null'); + } + + + $this->container['rules'] = $rules; + + return $this; + } + + /** + * Gets detail_truncated + * + * @return bool + */ + public function getDetailTruncated() + { + return $this->container['detail_truncated']; + } + + /** + * Sets detail_truncated + * + * @param bool $detail_truncated Whether the detector's underlying detailed evidence was truncated. Group membership remains complete. + * + * @return self + */ + public function setDetailTruncated($detail_truncated) + { + if (is_null($detail_truncated)) { + throw new \InvalidArgumentException('non-nullable detail_truncated cannot be null'); + } + $this->container['detail_truncated'] = $detail_truncated; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/MultiaccountChangedDataSource.php b/generated/lib/Model/MultiaccountChangedDataSource.php new file mode 100644 index 0000000..83701bd --- /dev/null +++ b/generated/lib/Model/MultiaccountChangedDataSource.php @@ -0,0 +1,512 @@ + + */ +class MultiaccountChangedDataSource implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'MultiaccountChangedData_source'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'publication_epoch' => 'mixed', + 'publication_version' => 'string', + 'coverage_id' => 'string' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'publication_epoch' => null, + 'publication_version' => null, + 'coverage_id' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'publication_epoch' => true, + 'publication_version' => false, + 'coverage_id' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'publication_epoch' => 'publication_epoch', + 'publication_version' => 'publication_version', + 'coverage_id' => 'coverage_id' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'publication_epoch' => 'setPublicationEpoch', + 'publication_version' => 'setPublicationVersion', + 'coverage_id' => 'setCoverageId' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'publication_epoch' => 'getPublicationEpoch', + 'publication_version' => 'getPublicationVersion', + 'coverage_id' => 'getCoverageId' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('publication_epoch', $data ?? [], null); + $this->setIfExists('publication_version', $data ?? [], null); + $this->setIfExists('coverage_id', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['publication_epoch'] === null && !$this->isNullableSetToNull('publication_epoch')) { + $invalidProperties[] = "'publication_epoch' is required"; + } + if ($this->container['publication_version'] === null) { + $invalidProperties[] = "'publication_version' can't be null"; + } + if (!preg_match("/^[1-9][0-9]{0,19}$/", $this->container['publication_version'])) { + $invalidProperties[] = "invalid value for 'publication_version', must be conform to the pattern /^[1-9][0-9]{0,19}$/."; + } + + if ($this->container['coverage_id'] === null) { + $invalidProperties[] = "'coverage_id' can't be null"; + } + if (!preg_match("/^[a-f0-9]{64}$/", $this->container['coverage_id'])) { + $invalidProperties[] = "invalid value for 'coverage_id', must be conform to the pattern /^[a-f0-9]{64}$/."; + } + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets publication_epoch + * + * @return mixed|null + */ + public function getPublicationEpoch() + { + return $this->container['publication_epoch']; + } + + /** + * Sets publication_epoch + * + * @param mixed|null $publication_epoch publication_epoch + * + * @return self + */ + public function setPublicationEpoch($publication_epoch) + { + if (is_null($publication_epoch)) { + array_push($this->openAPINullablesSetToNull, 'publication_epoch'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('publication_epoch', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['publication_epoch'] = $publication_epoch; + + return $this; + } + + /** + * Gets publication_version + * + * @return string + */ + public function getPublicationVersion() + { + return $this->container['publication_version']; + } + + /** + * Sets publication_version + * + * @param string $publication_version The exact immutable publication containing this result and event. + * + * @return self + */ + public function setPublicationVersion($publication_version) + { + if (is_null($publication_version)) { + throw new \InvalidArgumentException('non-nullable publication_version cannot be null'); + } + + if ((!preg_match("/^[1-9][0-9]{0,19}$/", ObjectSerializer::toString($publication_version)))) { + throw new \InvalidArgumentException("invalid value for \$publication_version when calling MultiaccountChangedDataSource., must conform to the pattern /^[1-9][0-9]{0,19}$/."); + } + + $this->container['publication_version'] = $publication_version; + + return $this; + } + + /** + * Gets coverage_id + * + * @return string + */ + public function getCoverageId() + { + return $this->container['coverage_id']; + } + + /** + * Sets coverage_id + * + * @param string $coverage_id Immutable binding to the trusted source completeness proof. + * + * @return self + */ + public function setCoverageId($coverage_id) + { + if (is_null($coverage_id)) { + throw new \InvalidArgumentException('non-nullable coverage_id cannot be null'); + } + + if ((!preg_match("/^[a-f0-9]{64}$/", ObjectSerializer::toString($coverage_id)))) { + throw new \InvalidArgumentException("invalid value for \$coverage_id when calling MultiaccountChangedDataSource., must conform to the pattern /^[a-f0-9]{64}$/."); + } + + $this->container['coverage_id'] = $coverage_id; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/MultiaccountChangedEvent.php b/generated/lib/Model/MultiaccountChangedEvent.php new file mode 100644 index 0000000..112f43e --- /dev/null +++ b/generated/lib/Model/MultiaccountChangedEvent.php @@ -0,0 +1,640 @@ + + */ +class MultiaccountChangedEvent implements ModelInterface, ArrayAccess, \JsonSerializable +{ + public const DISCRIMINATOR = null; + + /** + * The original name of the model. + * + * @var string + */ + protected static $openAPIModelName = 'MultiaccountChangedEvent'; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPITypes = [ + 'event_id' => 'string', + 'event_type' => 'mixed', + 'schema_version' => 'mixed', + 'site_id' => 'int', + 'created_at' => '\DateTime', + 'data' => '\ShieldLabs\Generated\Model\MultiaccountChangedData' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + * @phpstan-var array + * @psalm-var array + */ + protected static $openAPIFormats = [ + 'event_id' => null, + 'event_type' => null, + 'schema_version' => null, + 'site_id' => null, + 'created_at' => 'date-time', + 'data' => null + ]; + + /** + * Array of nullable properties. Used for (de)serialization + * + * @var boolean[] + */ + protected static array $openAPINullables = [ + 'event_id' => false, + 'event_type' => true, + 'schema_version' => true, + 'site_id' => false, + 'created_at' => false, + 'data' => false + ]; + + /** + * If a nullable field gets set to null, insert it here + * + * @var boolean[] + */ + protected array $openAPINullablesSetToNull = []; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of nullable properties + * + * @return array + */ + protected static function openAPINullables(): array + { + return self::$openAPINullables; + } + + /** + * Array of nullable field names deliberately set to null + * + * @return boolean[] + */ + private function getOpenAPINullablesSetToNull(): array + { + return $this->openAPINullablesSetToNull; + } + + /** + * Setter - Array of nullable field names deliberately set to null + * + * @param boolean[] $openAPINullablesSetToNull + */ + private function setOpenAPINullablesSetToNull(array $openAPINullablesSetToNull): void + { + $this->openAPINullablesSetToNull = $openAPINullablesSetToNull; + } + + /** + * Checks if a property is nullable + * + * @param string $property + * @return bool + */ + public static function isNullable(string $property): bool + { + return self::openAPINullables()[$property] ?? false; + } + + /** + * Checks if a nullable property is set to null. + * + * @param string $property + * @return bool + */ + public function isNullableSetToNull(string $property): bool + { + return in_array($property, $this->getOpenAPINullablesSetToNull(), true); + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'event_id' => 'event_id', + 'event_type' => 'event_type', + 'schema_version' => 'schema_version', + 'site_id' => 'site_id', + 'created_at' => 'created_at', + 'data' => 'data' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'event_id' => 'setEventId', + 'event_type' => 'setEventType', + 'schema_version' => 'setSchemaVersion', + 'site_id' => 'setSiteId', + 'created_at' => 'setCreatedAt', + 'data' => 'setData' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'event_id' => 'getEventId', + 'event_type' => 'getEventType', + 'schema_version' => 'getSchemaVersion', + 'site_id' => 'getSiteId', + 'created_at' => 'getCreatedAt', + 'data' => 'getData' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[]|null $data Associated array of property values + * initializing the model + */ + public function __construct(?array $data = null) + { + $this->setIfExists('event_id', $data ?? [], null); + $this->setIfExists('event_type', $data ?? [], null); + $this->setIfExists('schema_version', $data ?? [], null); + $this->setIfExists('site_id', $data ?? [], null); + $this->setIfExists('created_at', $data ?? [], null); + $this->setIfExists('data', $data ?? [], null); + } + + /** + * Sets $this->container[$variableName] to the given data or to the given default Value; if $variableName + * is nullable and its value is set to null in the $fields array, then mark it as "set to null" in the + * $this->openAPINullablesSetToNull array + * + * @param string $variableName + * @param array $fields + * @param mixed $defaultValue + */ + private function setIfExists(string $variableName, array $fields, $defaultValue): void + { + if (self::isNullable($variableName) && array_key_exists($variableName, $fields) && is_null($fields[$variableName])) { + $this->openAPINullablesSetToNull[] = $variableName; + } + + $this->container[$variableName] = $fields[$variableName] ?? $defaultValue; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + if ($this->container['event_id'] === null) { + $invalidProperties[] = "'event_id' can't be null"; + } + if (!preg_match("/^[a-f0-9]{40}$/", $this->container['event_id'])) { + $invalidProperties[] = "invalid value for 'event_id', must be conform to the pattern /^[a-f0-9]{40}$/."; + } + + if ($this->container['event_type'] === null && !$this->isNullableSetToNull('event_type')) { + $invalidProperties[] = "'event_type' is required"; + } + if ($this->container['schema_version'] === null && !$this->isNullableSetToNull('schema_version')) { + $invalidProperties[] = "'schema_version' is required"; + } + if ($this->container['site_id'] === null) { + $invalidProperties[] = "'site_id' can't be null"; + } + if (($this->container['site_id'] < 1)) { + $invalidProperties[] = "invalid value for 'site_id', must be bigger than or equal to 1."; + } + + if ($this->container['created_at'] === null) { + $invalidProperties[] = "'created_at' can't be null"; + } + if (!preg_match("/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/", $this->container['created_at'])) { + $invalidProperties[] = "invalid value for 'created_at', must be conform to the pattern /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/."; + } + + if ($this->container['data'] === null) { + $invalidProperties[] = "'data' can't be null"; + } + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets event_id + * + * @return string + */ + public function getEventId() + { + return $this->container['event_id']; + } + + /** + * Sets event_id + * + * @param string $event_id Stable logical event ID. Delivery retries preserve this ID and the signed body. + * + * @return self + */ + public function setEventId($event_id) + { + if (is_null($event_id)) { + throw new \InvalidArgumentException('non-nullable event_id cannot be null'); + } + + if ((!preg_match("/^[a-f0-9]{40}$/", ObjectSerializer::toString($event_id)))) { + throw new \InvalidArgumentException("invalid value for \$event_id when calling MultiaccountChangedEvent., must conform to the pattern /^[a-f0-9]{40}$/."); + } + + $this->container['event_id'] = $event_id; + + return $this; + } + + /** + * Gets event_type + * + * @return mixed|null + */ + public function getEventType() + { + return $this->container['event_type']; + } + + /** + * Sets event_type + * + * @param mixed|null $event_type event_type + * + * @return self + */ + public function setEventType($event_type) + { + if (is_null($event_type)) { + array_push($this->openAPINullablesSetToNull, 'event_type'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('event_type', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['event_type'] = $event_type; + + return $this; + } + + /** + * Gets schema_version + * + * @return mixed|null + */ + public function getSchemaVersion() + { + return $this->container['schema_version']; + } + + /** + * Sets schema_version + * + * @param mixed|null $schema_version schema_version + * + * @return self + */ + public function setSchemaVersion($schema_version) + { + if (is_null($schema_version)) { + array_push($this->openAPINullablesSetToNull, 'schema_version'); + } else { + $nullablesSetToNull = $this->getOpenAPINullablesSetToNull(); + $index = array_search('schema_version', $nullablesSetToNull); + if ($index !== FALSE) { + unset($nullablesSetToNull[$index]); + $this->setOpenAPINullablesSetToNull($nullablesSetToNull); + } + } + $this->container['schema_version'] = $schema_version; + + return $this; + } + + /** + * Gets site_id + * + * @return int + */ + public function getSiteId() + { + return $this->container['site_id']; + } + + /** + * Sets site_id + * + * @param int $site_id site_id + * + * @return self + */ + public function setSiteId($site_id) + { + if (is_null($site_id)) { + throw new \InvalidArgumentException('non-nullable site_id cannot be null'); + } + + if (($site_id < 1)) { + throw new \InvalidArgumentException('invalid value for $site_id when calling MultiaccountChangedEvent., must be bigger than or equal to 1.'); + } + + $this->container['site_id'] = $site_id; + + return $this; + } + + /** + * Gets created_at + * + * @return \DateTime + */ + public function getCreatedAt() + { + return $this->container['created_at']; + } + + /** + * Sets created_at + * + * @param \DateTime $created_at RFC 3339 timestamp in UTC with up to 9 fractional digits (trailing zeros trimmed), for example `2026-09-30T12:34:57.482913041Z`. Parse it with a parser that accepts nanoseconds. + * + * @return self + */ + public function setCreatedAt($created_at) + { + if (is_null($created_at)) { + throw new \InvalidArgumentException('non-nullable created_at cannot be null'); + } + + if ((!preg_match("/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/", ObjectSerializer::toString($created_at)))) { + throw new \InvalidArgumentException("invalid value for \$created_at when calling MultiaccountChangedEvent., must conform to the pattern /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$/."); + } + + $this->container['created_at'] = $created_at; + + return $this; + } + + /** + * Gets data + * + * @return \ShieldLabs\Generated\Model\MultiaccountChangedData + */ + public function getData() + { + return $this->container['data']; + } + + /** + * Sets data + * + * @param \ShieldLabs\Generated\Model\MultiaccountChangedData $data data + * + * @return self + */ + public function setData($data) + { + if (is_null($data)) { + throw new \InvalidArgumentException('non-nullable data cannot be null'); + } + $this->container['data'] = $data; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer|string $offset Offset + * + * @return boolean + */ + public function offsetExists(mixed $offset): bool + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer|string $offset Offset + * + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function offsetGet(mixed $offset) + { + return $this->container[$offset] ?? null; + } + + /** + * Sets value based on offset. + * + * @param int|null $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value): void + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer|string $offset Offset + * + * @return void + */ + public function offsetUnset(mixed $offset): void + { + unset($this->container[$offset]); + } + + /** + * Serializes the object to a value that can be serialized natively by json_encode(). + * @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php + * + * @return mixed Returns data which can be serialized by json_encode(), which is a value + * of any type other than a resource. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ObjectSerializer::sanitizeForSerialization($this); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } + + /** + * Gets a header-safe presentation of the object + * + * @return string + */ + public function toHeaderValue() + { + return json_encode(ObjectSerializer::sanitizeForSerialization($this)); + } +} + + diff --git a/generated/lib/Model/RiskEvent.php b/generated/lib/Model/RiskEvent.php index de36fda..0fc58d0 100644 --- a/generated/lib/Model/RiskEvent.php +++ b/generated/lib/Model/RiskEvent.php @@ -346,7 +346,7 @@ public function getCode() /** * Sets code * - * @param string $code code + * @param string $code Open catalogue of independent source signals. ai_bot and ai_browser carry weight 0; search_bot remains separate. browser_automation carries weight 90 in task 204 releases. UI Good bot and Bad bot groups are not risk event codes. Keep unknown codes and use the payload scoring_version/result_version for historical interpretation. * * @return self */ diff --git a/generated/lib/Model/Signal.php b/generated/lib/Model/Signal.php index 578921a..e0deea9 100644 --- a/generated/lib/Model/Signal.php +++ b/generated/lib/Model/Signal.php @@ -321,7 +321,7 @@ public function getName() /** * Sets name * - * @param string $name Signal name. The set is open: new names can appear at any time, so keep unknown names and use them for display and logging only. Known names: - `tor`: the request came through Tor; - `vpn`: a VPN was detected; - `privacy_relay`: a privacy relay such as iCloud Private Relay; - `proxy`: a proxy was detected; - `datacenter_ip`: the IP belongs to a datacenter or hosting range; - `abuser`: the IP has a record of abuse; - `browser_vpn_proxy`: a VPN or proxy inside the browser; - `antidetect_browser`: an anti-detect browser (the matching flag is `anti_detect_browser`); - `proxy_routed_antidetect`: the network check was routed through a proxy in a way typical for anti-detect browsers; - `port_scan_routed_via_proxy`: `proxy_routed_antidetect` carried forward from an earlier identification of the same device and IP; - `browser_automation`: browser automation, for example a WebDriver-controlled browser; - `javascript_disabled`: JavaScript or the browser APIs the checks need were unavailable; - `os_mismatch`: the operating system seen on the network differs from the one the browser reports; - `os_not_detected`: the operating system could not be determined; - `timezone_mismatch`: the browser timezone differs from the IP location timezone; - `stun_not_checked`: the network (STUN) check did not complete; - `stun_late_correction`: a late network result arrived; negative weight that cancels `stun_not_checked`; - `rate_limited`: the rate-limit marker, weight 999. A verdict carried forward from an earlier identification of the same device and IP (for example `antidetect_browser`) keeps a name derived from the original signal and can carry a partial weight. + * @param string $name Signal name. The set is open: new names can appear at any time, so keep unknown names and use them for display and logging only. Known names: - `tor`: the request came through Tor; - `vpn`: a VPN was detected; - `privacy_relay`: a privacy relay such as iCloud Private Relay; - `proxy`: a proxy was detected; - `datacenter_ip`: the IP belongs to a datacenter or hosting range; - `abuser`: the IP has a record of abuse; - `browser_vpn_proxy`: a VPN or proxy inside the browser; - `antidetect_browser`: an anti-detect browser (the matching flag is `anti_detect_browser`); - `proxy_routed_antidetect`: the network check was routed through a proxy in a way typical for anti-detect browsers; - `port_scan_routed_via_proxy`: `proxy_routed_antidetect` carried forward from an earlier identification of the same device and IP; - `browser_automation`: browser automation, for example a WebDriver-controlled browser (90 in task 204 scoring releases); - `javascript_disabled`: JavaScript or the browser APIs the checks need were unavailable; - `os_mismatch`: the operating system seen on the network differs from the one the browser reports; - `os_not_detected`: the operating system could not be determined; - `timezone_mismatch`: the browser timezone differs from the IP location timezone; - `stun_not_checked`: the network (STUN) check did not complete; - `stun_late_correction`: a late network result arrived; negative weight that cancels `stun_not_checked`; - `rate_limited`: the rate-limit marker, weight 999. A verdict carried forward from an earlier identification of the same device and IP (for example `antidetect_browser`) keeps a name derived from the original signal and can carry a partial weight. * * @return self */ diff --git a/generated/lib/Model/WebhookPingEvent.php b/generated/lib/Model/WebhookPingEvent.php index e289480..19902ed 100644 --- a/generated/lib/Model/WebhookPingEvent.php +++ b/generated/lib/Model/WebhookPingEvent.php @@ -405,7 +405,7 @@ public function getSchemaVersion() /** * Sets schema_version * - * @param string $schema_version Webhook contract version. Current release 2026-10-06; parsers also accept legacy 2026-06-01. + * @param string $schema_version Webhook contract version. Scored release 2026-10-06; multi-account group release 2026-10-07; parsers also accept legacy 2026-06-01. * * @return self */