Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/fix-feedback-remove-invalid-type…
Browse files Browse the repository at this point in the history
…s' into feat-feedback-remove-deprecated-fields
  • Loading branch information
ottony committed Oct 30, 2024
2 parents 0f959bc + 99c3df6 commit 23fd128
Show file tree
Hide file tree
Showing 10 changed files with 346 additions and 219 deletions.
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
## [Unreleased]

## [2.0.0] - 2024-07-24
## [1.3.0] - 2024-10-30

- Remove support to passing timestamp on #register_feedback
- Add support for general configuration and use Incognia::Api as a static class

## [1.2.0] - 2024-08-26

- Removes the requirement to send installation id to register signup, login and payment

## [1.1.0] - 2024-07-24

Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
incognia_api (2.0.0)
incognia_api (1.3.0)
faraday (~> 1.10)
faraday_middleware (~> 1.2)

Expand Down
60 changes: 31 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,30 @@ Or install it yourself as:

### Configuration

Before using the API client, you must initialize it using credentials obtained
from the [Incognia dashboard]():
Before using the API client, you must configure it using credentials obtained
from the [Incognia dashboard](https://dash.incognia.com/):

```ruby
api = Incognia::Api.new(client_id: "your-client-id", client_secret:
"your-client-secret")
Incognia.configure(client_id: ENV['INCOGNIA_CLIENT_ID'], client_secret: ENV['INCOGNIA_CLIENT_SECRET'])

# Incognia.configure(client_id: "your-client-id", client_secret: "your-client-secret")
```

For sandbox credentials, refer to the [API testing guide]().
For sandbox credentials, refer to the [API testing guide](https://developer.incognia.com/).

:bulb: For Rails applications it's recommended to create an initializer file, for example `config/initializers/incognia.rb`.


### Registering a Signup

This method registers a new signup for the given installation and address, returning a signup assessment, containing the risk assessment and supporting evidence:
This method registers a new signup for the given request token and address, returning a signup assessment, containing the risk assessment and supporting evidence:

```ruby
address = Incognia::Address.new(line: "West 34th Street, New York City, NY 10001")
installation_id = "WlMksW+jh5GPhqWBorsV8yDihoSHHpmt+DpjJ7eYxpHhuO/5tuHTuA..."
request_token = "WlMksW+jh5GPhqWBorsV8yDihoSHHpmt+DpjJ7eYxpHhuO/5tuHTuA..."

assessment = api.register_signup(
installation_id: installation_id,
assessment = Incognia::Api.register_signup(
request_token: request_token,
address: address
)

Expand All @@ -68,11 +70,11 @@ It also supports optional parameters, for example:

```ruby
address = Incognia::Address.new(line: "West 34th Street, New York City, NY 10001")
installation_id = "WlMksW+jh5GPhqWBorsV8yDihoSHHpmt+DpjJ7eYxpHhuO/5tuHTuA..."
request_token = "WlMksW+jh5GPhqWBorsV8yDihoSHHpmt+DpjJ7eYxpHhuO/5tuHTuA..."
external_id = "7b02736a-7718-4b83-8982-f68fb6f501fa"

assessment = api.register_signup(
installation_id: installation_id,
assessment = Incognia::Api.register_signup(
request_token: request_token,
address: address,
external_id: external_id
)
Expand All @@ -82,14 +84,14 @@ assessment = api.register_signup(

### Registering a Login

This method registers a new login for the given installation and account, returning a login assessment, containing the risk assessment and supporting evidence:
This method registers a new login for the given request token and account, returning a login assessment, containing the risk assessment and supporting evidence:

```ruby
installation_id = "WlMksW+jh5GPhqWBorsV8yDihoSHHpmt+DpjJ7eYxpHhuO/5tuHTuA..."
request_token = "WlMksW+jh5GPhqWBorsV8yDihoSHHpmt+DpjJ7eYxpHhuO/5tuHTuA..."
account_id = 'account-identifier-123'

assessment = api.register_login(
installation_id: installation_id,
assessment = Incognia::Api.register_login(
request_token: request_token,
account_id: account_id,
)

Expand All @@ -100,12 +102,12 @@ assessment = api.register_login(
It also supports optional parameters, for example:

```ruby
installation_id = "WlMksW+jh5GPhqWBorsV8yDihoSHHpmt+DpjJ7eYxpHhuO/5tuHTuA..."
request_token = "WlMksW+jh5GPhqWBorsV8yDihoSHHpmt+DpjJ7eYxpHhuO/5tuHTuA..."
account_id = 'account-identifier-123'
external_id = 'some-external-identifier'

assessment = api.register_login(
installation_id: installation_id,
assessment = Incognia::Api.register_login(
request_token: request_token,
account_id: account_id,
external_id: external_id,
eval: false # can be used to register a new login without evaluating it
Expand All @@ -116,12 +118,12 @@ assessment = api.register_login(

### Registering Payment

This method registers a new payment for the given installation and account, returning a `hash`,
This method registers a new payment for the given request token and account, returning a `hash`,
containing the risk assessment and supporting evidence.

```ruby
assessment = api.register_payment(
installation_id: 'installation-id',
assessment = Incognia::Api.register_payment(
request_token: 'request-token',
account_id: 'account-id'
)

Expand Down Expand Up @@ -180,8 +182,8 @@ payment_methods = [
}
]

assessment = api.register_payment(
installation_id: 'installation-id',
assessment = Incognia::Api.register_payment(
request_token: 'request-token',
account_id: 'account-id',
external_id: 'external-id',
addresses: addresses,
Expand All @@ -202,14 +204,14 @@ The `expires_at` argument should be a _Time_, _DateTime_ or an date in **RFC 333


```ruby
installation_id = 'installation-id'
request_token = 'request-token'
account_id = 'account-id'
occurred_at = DateTime.parse('2024-07-22T15:20:00Z')

success = api.register_feedback(
success = Incognia::Api.register_feedback(
event: Incognia::Constants::FeedbackEvent::ACCOUNT_TAKEOVER,
occurred_at: occurred_at,
installation_id: installation_id,
request_token: request_token,
account_id: account_id
)

Expand All @@ -219,10 +221,10 @@ success = api.register_feedback(
For custom fraud, set the value of `event` with the corresponding code:

```ruby
success = api.register_feedback(
success = Incognia::Api.register_feedback(
event: 'custom_fraud_name',
occurred_at: occurred_at,
installation_id: installation_id,
request_token: request_token,
account_id: account_id
)

Expand Down
9 changes: 9 additions & 0 deletions lib/incognia_api.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true

require_relative "incognia_api/configuration"
require_relative "incognia_api/version"
require_relative "incognia_api/client"
require_relative "incognia_api/util"
Expand All @@ -15,6 +16,14 @@
require_relative "incognia_api/constants/feedback_event"

module Incognia
def self.configure(**args)
config.configure(**args)
end

def self.config
Configuration.instance
end

class APIError < StandardError
attr_reader :message, :errors, :status

Expand Down
111 changes: 57 additions & 54 deletions lib/incognia_api/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,74 +5,77 @@

module Incognia
class Api
# business layer: uses the Client to build domain objects
# raises missing parameters errors
attr_accessor :connection
class << self
# business layer: uses the Client.instance to build domain objects
# raises missing parameters errors

def initialize(client_id:, client_secret:)
@connection = Client.new(client_id: client_id,
client_secret: client_secret,
host: "https://api.incognia.com/api")
end
def register_signup(request_token: nil, address: nil, **opts)
params = { request_token: request_token }.compact
params.merge!(opts)
params.merge!(address&.to_hash) if address

def register_signup(installation_id:, address: nil, **opts)
params = { installation_id: installation_id }
params.merge!(opts)
params.merge!(address&.to_hash) if address
response = connection.request(
:post,
'v2/onboarding/signups',
params
)

response = connection.request(
:post,
'v2/onboarding/signups',
params
)
SignupAssessment.from_hash(response.body) if response.success?
end

SignupAssessment.from_hash(response.body) if response.success?
end
def register_login(account_id:, request_token: nil, **opts)
params = {
type: :login,
account_id: account_id,
request_token: request_token
}.compact
params.merge!(opts)

def register_login(installation_id:, account_id:, **opts)
params = {
type: :login,
installation_id: installation_id,
account_id: account_id,
}
params.merge!(opts)
response = connection.request(
:post,
'v2/authentication/transactions',
params
)

response = connection.request(
:post,
'v2/authentication/transactions',
params
)
LoginAssessment.from_hash(response.body) if response.success?
end

LoginAssessment.from_hash(response.body) if response.success?
end
def register_feedback(event:, occurred_at: nil, expires_at: nil, **ids)
occurred_at = occurred_at.to_datetime.rfc3339 if occurred_at.respond_to? :to_datetime
expires_at = expires_at.to_datetime.rfc3339 if expires_at.respond_to? :to_datetime

def register_feedback(event:, occurred_at: nil, expires_at: nil, **ids)
occurred_at = occurred_at.to_datetime.rfc3339 if occurred_at.respond_to? :to_datetime
expires_at = expires_at.to_datetime.rfc3339 if expires_at.respond_to? :to_datetime
params = { event: event, occurred_at: occurred_at, expires_at: expires_at }.compact
params.merge!(ids)

params = { event: event, occurred_at: occurred_at, expires_at: expires_at }.compact
params.merge!(ids)
response = connection.request(
:post,
'/api/v2/feedbacks',
params
)

response = connection.request(
:post,
'/api/v2/feedbacks',
params
)
response.success?
end

response.success?
end
def register_payment(account_id:, request_token: nil, **opts)
params = {
type: :payment,
account_id: account_id,
request_token: request_token
}.compact
params.merge!(opts)

def register_payment(installation_id:, account_id:, **opts)
params = { installation_id: installation_id, account_id: account_id, type: :payment }
params.merge!(opts)
response = connection.request(
:post,
'v2/authentication/transactions',
params
)

response = connection.request(
:post,
'v2/authentication/transactions',
params
)
PaymentAssessment.from_hash(response.body) if response.success?
end

PaymentAssessment.from_hash(response.body) if response.success?
def connection
Client.instance
end
end
end
end
41 changes: 20 additions & 21 deletions lib/incognia_api/client.rb
Original file line number Diff line number Diff line change
@@ -1,32 +1,14 @@
require "time"
require "singleton"

module Incognia
class Client
include Singleton
# TODO:
# (ok) http/adapter specific code
# (ok) raises network/authentication errors
# (ok) handles token refreshing ok
# future: handles retrying
attr_reader :connection

def initialize(client_id:, client_secret:, host:)
@client_id = client_id
@client_secret = client_secret
@host = host

headers = { 'User-Agent' => "incognia-ruby/#{Incognia::VERSION} " \
"({#{RbConfig::CONFIG['host']}}) " \
"{#{RbConfig::CONFIG['arch']}} " \
"Ruby/#{RbConfig::CONFIG['ruby_version']}" }

@connection = Faraday.new(host, headers: headers) do |faraday|
faraday.request :json
faraday.response :json, content_type: /\bjson$/
faraday.response :raise_error

faraday.adapter Faraday.default_adapter
end
end

def request(method, endpoint = nil, data = nil, headers = {})
json_data = JSON.generate(data) if data
Expand All @@ -48,12 +30,29 @@ def credentials
@credentials
end

def connection
return @connection if @connection

headers = { 'User-Agent' => "incognia-ruby/#{Incognia::VERSION} " \
"({#{RbConfig::CONFIG['host']}}) " \
"{#{RbConfig::CONFIG['arch']}} " \
"Ruby/#{RbConfig::CONFIG['ruby_version']}" }

@connection = Faraday.new(Incognia.config.host, headers: headers) do |faraday|
faraday.request :json
faraday.response :json, content_type: /\bjson$/
faraday.response :raise_error

faraday.adapter Faraday.default_adapter
end
end

protected

def request_credentials
basic_auth = Faraday::Request
.lookup_middleware(:basic_auth)
.header(@client_id, @client_secret)
.header(Incognia.config.client_id, Incognia.config.client_secret)

response = connection.send(:post, 'v2/token') do |r|
r.headers[Faraday::Request::Authorization::KEY] = basic_auth
Expand Down
Loading

0 comments on commit 23fd128

Please sign in to comment.