lib/stytch/fraud.rb



# frozen_string_literal: true

# !!!
# WARNING: This file is autogenerated
# Only modify code within MANUAL() sections
# or your changes may be overwritten later!
# !!!

require_relative 'request_helper'

module Stytch
  class Fraud
    include Stytch::RequestHelper
    attr_reader :fingerprint, :rules

    def initialize(connection)
      @connection = connection

      @fingerprint = Stytch::Fraud::Fingerprint.new(@connection)
      @rules = Stytch::Fraud::Rules.new(@connection)
    end

    class Fingerprint
      include Stytch::RequestHelper

      def initialize(connection)
        @connection = connection
      end

      # Lookup the associated fingerprint for the `telemetry_id` returned from the `GetTelemetryID` function. Learn more about the different fingerprint types and verdicts in our [DFP guide](https://stytch.com/docs/fraud/guides/device-fingerprinting/overview).
      #
      # Make a decision based on the returned `verdict`:
      # * `ALLOW` - This is a known valid device grouping or device profile that is part of the default `ALLOW` listed set of known devices by Stytch. This grouping is made up of  verified device profiles that match the characteristics of known/authentic traffic origins.
      # * `BLOCK` - This is a known bad or malicious device profile that is undesirable and should be blocked from completing the privileged action in question.
      # * `CHALLENGE` - This is an unknown or potentially malicious device that should be put through increased friction such as 2FA or other forms of extended user verification before allowing the privileged action to proceed.
      #
      # If the `telemetry_id` is not found, we will return a 404 `telemetry_id_not_found` [error](https://stytch.com/docs/fraud/api/errors/404#telemetry_id_not_found). We recommend treating 404 errors as a `BLOCK`, since it could be a sign of an attacker trying to bypass DFP protections by generating fake telemetry IDs.
      #
      # == Parameters:
      # telemetry_id::
      #   The telemetry ID associated with the fingerprint getting looked up.
      #   The type of this field is +String+.
      # external_metadata::
      #   External identifiers that you wish to associate with the given telemetry ID. You will be able to search for fingerprint results by these identifiers in the DFP analytics dashboard. External metadata fields may not exceed 65 characters. They may only contain alphanumerics and the characters `_` `-` `+` `.` or `@`.
      #   The type of this field is nilable +Metadata+ (+object+).
      #
      # == Returns:
      # An object with the following fields:
      # request_id::
      #   Globally unique UUID that is returned with every API call. This value is important to log for debugging purposes; we may ask for this value to help identify a specific API call when helping you debug an issue.
      #   The type of this field is +String+.
      # telemetry_id::
      #   The telemetry ID associated with the fingerprint getting looked up.
      #   The type of this field is +String+.
      # fingerprints::
      #   A Stytch fingerprint consists of the following identifiers:
      #   The type of this field is +Fingerprints+ (+object+).
      # verdict::
      #   The metadata associated with each fingerprint
      #   The type of this field is +Verdict+ (+object+).
      # external_metadata::
      #   External identifiers that you wish to associate with the given telemetry ID. You will be able to search for fingerprint results by these identifiers in the DFP analytics dashboard. External metadata fields may not exceed 65 characters. They may only contain alphanumerics and the characters `_` `-` `+` `.` or `@`.
      #   The type of this field is +Metadata+ (+object+).
      # created_at::
      #   The time when the fingerprint was taken. Values conform to the RFC 3339 standard and are expressed in UTC, e.g. `2021-12-29T12:33:09Z`.
      #   The type of this field is +String+.
      # expires_at::
      #   The timestamp when the fingerprint expires. Values conform to the RFC 3339 standard and are expressed in UTC, e.g. `2021-12-29T12:33:09Z`.
      #   The type of this field is +String+.
      # status_code::
      #   The HTTP status code of the response. Stytch follows standard HTTP response status code patterns, e.g. 2XX values equate to success, 3XX values are redirects, 4XX are client errors, and 5XX are server errors.
      #   The type of this field is +Integer+.
      # properties::
      #   Additional information about the user's browser and network.
      #   The type of this field is nilable +Properties+ (+object+).
      def lookup(
        telemetry_id:,
        external_metadata: nil
      )
        headers = {}
        request = {
          telemetry_id: telemetry_id
        }
        request[:external_metadata] = external_metadata unless external_metadata.nil?

        post_request('/v1/fingerprint/lookup', request, headers)
      end
    end

    class Rules
      include Stytch::RequestHelper

      def initialize(connection)
        @connection = connection
      end

      # Set a rule for a particular `visitor_id`, `browser_id`, `visitor_fingerprint`, `browser_fingerprint`, `hardware_fingerprint`, `network_fingerprint`, `cidr_block`, `asn`, or `country_code`. This is helpful in cases where you want to allow or block a specific user or fingerprint. You should be careful when setting rules for `browser_fingerprint`, `hardware_fingerprint`, or `network_fingerprint` as they can be shared across multiple users, and you could affect more users than intended.
      #
      # You may not set an `ALLOW` rule for a `country_code`.
      #
      # Rules are applied in the order specified above. For example, if an end user has an `ALLOW` rule set for their `visitor_id` but a `BLOCK` rule set for their `hardware_fingerprint`, they will receive an `ALLOW` verdict because the `visitor_id` rule takes precedence.
      #
      # If there are conflicts between multiple `cidr_block` rules (for example, if the `ip_address` of the end user overlaps with multiple CIDR blocks that have rules set), the conflicts are resolved as follows:
      # - The smallest block size takes precedence. For example, if an `ip_address` overlaps with a `cidr_block` rule of `ALLOW` for a block with a prefix of `/32` and a `cidr_block` rule of `BLOCK` with a prefix of `/24`, the rule match verdict will be `ALLOW`.
      # - Among equivalent size blocks, `BLOCK` takes precedence over `CHALLENGE`, which takes precedence over `ALLOW`. For example, if an `ip_address` overlaps with two `cidr_block` rules with blocks of the same size that return `CHALLENGE` and `ALLOW`, the rule match verdict will be `CHALLENGE`.
      #
      # == Parameters:
      # action::
      #   The action that should be returned by a fingerprint lookup for that identifier with a `RULE_MATCH` reason. The following values are valid: `ALLOW`, `BLOCK`, `CHALLENGE`, or `NONE`. For country codes, `ALLOW` actions are not allowed. If a `NONE` action is specified, it will clear the stored rule.
      #   The type of this field is +RuleAction+ (string enum).
      # visitor_id::
      #   The visitor ID we want to set a rule for. Only one identifier can be specified in the request.
      #   The type of this field is nilable +String+.
      # browser_id::
      #   The browser ID we want to set a rule for. Only one identifier can be specified in the request.
      #   The type of this field is nilable +String+.
      # visitor_fingerprint::
      #   The visitor fingerprint we want to set a rule for. Only one identifier can be specified in the request.
      #   The type of this field is nilable +String+.
      # browser_fingerprint::
      #   The browser fingerprint we want to set a rule for. Only one identifier can be specified in the request.
      #   The type of this field is nilable +String+.
      # hardware_fingerprint::
      #   The hardware fingerprint we want to set a rule for. Only one identifier can be specified in the request.
      #   The type of this field is nilable +String+.
      # network_fingerprint::
      #   The network fingerprint we want to set a rule for. Only one identifier can be specified in the request.
      #   The type of this field is nilable +String+.
      # expires_in_minutes::
      #   The number of minutes until this rule expires. If no `expires_in_minutes` is specified, then the rule is kept permanently.
      #   The type of this field is nilable +Integer+.
      # description::
      #   An optional description for the rule.
      #   The type of this field is nilable +String+.
      # cidr_block::
      #   The CIDR block we want to set a rule for. You may pass either an IP address or a CIDR block. The CIDR block prefix must be between 16 and 32, inclusive. If an end user's IP address is within this CIDR block, this rule will be applied. Only one identifier can be specified in the request.
      #   The type of this field is nilable +String+.
      # country_code::
      #   The country code we want to set a rule for. The country code must be a valid ISO 3166-1 alpha-2 code. You may not set `ALLOW` rules for country codes. Only one identifier can be specified in the request.
      #   The type of this field is nilable +String+.
      # asn::
      #   The ASN we want to set a rule for. The ASN must be the string representation of an integer between 0 and 4294967295, inclusive. Only one identifier can be specified in the request.
      #   The type of this field is nilable +String+.
      #
      # == Returns:
      # An object with the following fields:
      # request_id::
      #   Globally unique UUID that is returned with every API call. This value is important to log for debugging purposes; we may ask for this value to help identify a specific API call when helping you debug an issue.
      #   The type of this field is +String+.
      # action::
      #   The action that will be returned for the specified identifier.
      #   The type of this field is +RuleAction+ (string enum).
      # status_code::
      #   The HTTP status code of the response. Stytch follows standard HTTP response status code patterns, e.g. 2XX values equate to success, 3XX values are redirects, 4XX are client errors, and 5XX are server errors.
      #   The type of this field is +Integer+.
      # visitor_id::
      #   The visitor ID that a rule was set for.
      #   The type of this field is nilable +String+.
      # browser_id::
      #   The browser ID that a rule was set for.
      #   The type of this field is nilable +String+.
      # visitor_fingerprint::
      #   The visitor fingerprint that a rule was set for.
      #   The type of this field is nilable +String+.
      # browser_fingerprint::
      #   The browser fingerprint that a rule was set for.
      #   The type of this field is nilable +String+.
      # hardware_fingerprint::
      #   The hardware fingerprint that a rule was set for.
      #   The type of this field is nilable +String+.
      # network_fingerprint::
      #   The network fingerprint that a rule was set for.
      #   The type of this field is nilable +String+.
      # expires_at::
      #   The timestamp when the rule expires. Values conform to the RFC 3339 standard and are expressed in UTC, e.g. `2021-12-29T12:33:09Z`.
      #   The type of this field is nilable +String+.
      # cidr_block::
      #   The CIDR block that a rule was set for. If an end user's IP address is within this CIDR block, this rule will be applied.
      #   The type of this field is nilable +String+.
      # country_code::
      #   The country code that a rule was set for.
      #   The type of this field is nilable +String+.
      # asn::
      #   The ASN that a rule was set for.
      #   The type of this field is nilable +String+.
      def set(
        action:,
        visitor_id: nil,
        browser_id: nil,
        visitor_fingerprint: nil,
        browser_fingerprint: nil,
        hardware_fingerprint: nil,
        network_fingerprint: nil,
        expires_in_minutes: nil,
        description: nil,
        cidr_block: nil,
        country_code: nil,
        asn: nil
      )
        headers = {}
        request = {
          action: action
        }
        request[:visitor_id] = visitor_id unless visitor_id.nil?
        request[:browser_id] = browser_id unless browser_id.nil?
        request[:visitor_fingerprint] = visitor_fingerprint unless visitor_fingerprint.nil?
        request[:browser_fingerprint] = browser_fingerprint unless browser_fingerprint.nil?
        request[:hardware_fingerprint] = hardware_fingerprint unless hardware_fingerprint.nil?
        request[:network_fingerprint] = network_fingerprint unless network_fingerprint.nil?
        request[:expires_in_minutes] = expires_in_minutes unless expires_in_minutes.nil?
        request[:description] = description unless description.nil?
        request[:cidr_block] = cidr_block unless cidr_block.nil?
        request[:country_code] = country_code unless country_code.nil?
        request[:asn] = asn unless asn.nil?

        post_request('/v1/rules/set', request, headers)
      end
    end
  end
end