identisure-client 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +19 -0
- data/README.md +105 -0
- data/lib/identisure/age_verification.rb +87 -0
- data/lib/identisure/bank_id_no.rb +219 -0
- data/lib/identisure/bank_id_se.rb +338 -0
- data/lib/identisure/callback.rb +15 -0
- data/lib/identisure/client.rb +77 -0
- data/lib/identisure/document.rb +31 -0
- data/lib/identisure/environment.rb +17 -0
- data/lib/identisure/error.rb +21 -0
- data/lib/identisure/freja.rb +224 -0
- data/lib/identisure/ftn.rb +168 -0
- data/lib/identisure/mit_id.rb +205 -0
- data/lib/identisure/poll_options.rb +12 -0
- data/lib/identisure/transport.rb +90 -0
- data/lib/identisure/version.rb +5 -0
- data/lib/identisure/vipps.rb +153 -0
- metadata +75 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 82d1c302c12ff4ecf26256974dc59b2bffe3aecdfe60b2353d3f0966832a7d13
|
|
4
|
+
data.tar.gz: c3065889a77aba5439388bc6efdd0bb9eac2d11a65a194beaf767ab4c6261775
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 1a6191c000b7770c389de61ebb66b3037aed2e06078d7d16402bca6a673d740777ecb6f64635e08a2323bea5db8f53c4708b21b4b7eb37f16c0e52ad72bc3784
|
|
7
|
+
data.tar.gz: c5440e580d6521272a861e250e2f41f894aaef827989e14ba8e44d35688dcefc6aa84054a37ac485bf9fe791f10180d5b13319076bfcb96060e26a662e940858
|
data/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<img align="left" height="100" style="margin-right: 10px;" src="img/icon.png">
|
|
2
|
+
|
|
3
|
+
# Identisure Ruby Client
|
|
4
|
+
|
|
5
|
+
[![Gem version][gem-image]][gem-url]
|
|
6
|
+
[![Documentation][docs-image]][docs-url]
|
|
7
|
+
[![MIT license][license-image]][license-url]
|
|
8
|
+
|
|
9
|
+
[gem-image]: https://img.shields.io/gem/v/identisure-client?style=flat-square
|
|
10
|
+
[gem-url]: https://rubygems.org/gems/identisure-client
|
|
11
|
+
[docs-image]: https://img.shields.io/badge/github-docs-orange?logo=github&style=flat-square
|
|
12
|
+
[docs-url]: https://identisure.github.io/api-client-ruby
|
|
13
|
+
[license-image]: https://img.shields.io/badge/license-MIT-blue?style=flat-square
|
|
14
|
+
[license-url]: https://opensource.org/license/mit
|
|
15
|
+
|
|
16
|
+
API client for the [Identisure](https://developers.identisure.com) REST API.
|
|
17
|
+
|
|
18
|
+
Documentation: [identisure.github.io/api-client-ruby](https://identisure.github.io/api-client-ruby)
|
|
19
|
+
|
|
20
|
+
## Requirements
|
|
21
|
+
|
|
22
|
+
Ruby 3.2 or later.
|
|
23
|
+
|
|
24
|
+
## Supported providers
|
|
25
|
+
|
|
26
|
+
- **BankID SE**: auth, sign, phone auth and sign, QR verify, age verification
|
|
27
|
+
- **BankID NO**: auth, backchannel auth, sign, age verification
|
|
28
|
+
- **Freja eID**: auth, backchannel auth, sign, backchannel sign, age verification
|
|
29
|
+
- **MitID**: auth, backchannel auth, sign, age verification
|
|
30
|
+
- **FTN** (Finnish Trust Network): auth, age verification
|
|
31
|
+
- **Vipps MobilePay**: auth, backchannel auth
|
|
32
|
+
- **Documents**: upload and download documents for signing
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
gem install identisure-client
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Or add to your `Gemfile`:
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
gem 'identisure-client', '~> 0.1'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Usage
|
|
47
|
+
|
|
48
|
+
```ruby
|
|
49
|
+
require 'identisure/client'
|
|
50
|
+
|
|
51
|
+
client = Identisure::ClientBuilder.new('client_id', 'client_secret')
|
|
52
|
+
.environment(Identisure::Environment::STAGING)
|
|
53
|
+
.build
|
|
54
|
+
|
|
55
|
+
session = client.bank_id_se.auth(Identisure::BankIdSe::AuthRequest.new)
|
|
56
|
+
puts "Session ID: #{session.id}" if session.is_a?(Identisure::BankIdSe::Pending)
|
|
57
|
+
|
|
58
|
+
result = client.bank_id_se.wait_for_auth(session.id)
|
|
59
|
+
|
|
60
|
+
case result
|
|
61
|
+
in Identisure::BankIdSe::Completed(ssn:, name:)
|
|
62
|
+
puts "Authenticated: #{name} (#{ssn})"
|
|
63
|
+
in Identisure::BankIdSe::Failed(error:)
|
|
64
|
+
puts "Failed: #{error}"
|
|
65
|
+
end
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Verifying callbacks
|
|
69
|
+
|
|
70
|
+
Verify the `X-Signature-SHA256` header against the raw request body before parsing it:
|
|
71
|
+
|
|
72
|
+
```ruby
|
|
73
|
+
valid = Identisure.verify_callback_signature(raw_body, signature_header, 'hmac_secret')
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Development
|
|
77
|
+
|
|
78
|
+
### Prerequisites
|
|
79
|
+
|
|
80
|
+
- Ruby 3.2+
|
|
81
|
+
- Bundler
|
|
82
|
+
|
|
83
|
+
### Setup / Build / Test
|
|
84
|
+
|
|
85
|
+
The test fixtures live in a Git submodule. Clone with `--recurse-submodules`, or run `git submodule update --init` in an existing clone.
|
|
86
|
+
|
|
87
|
+
```sh
|
|
88
|
+
bundle install
|
|
89
|
+
bundle exec rake test
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Release
|
|
93
|
+
|
|
94
|
+
Set the version in `lib/identisure/version.rb` and commit. Then push a tag:
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
git tag v0.1.0
|
|
98
|
+
git push origin v0.1.0
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The release workflow checks that the tag matches the version, runs CI, publishes to RubyGems and creates a GitHub release.
|
|
102
|
+
|
|
103
|
+
## Other languages
|
|
104
|
+
|
|
105
|
+
[C#](https://github.com/identisure/api-client-csharp), [Dart](https://github.com/identisure/api-client-dart), [Go](https://github.com/identisure/api-client-go), [TypeScript/JavaScript](https://github.com/identisure/api-client-js), [Java/Kotlin](https://github.com/identisure/api-client-jvm), [PHP](https://github.com/identisure/api-client-php), [Python](https://github.com/identisure/api-client-py), [Rust](https://github.com/identisure/api-client-rust), [Swift](https://github.com/identisure/api-client-swift)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Identisure
|
|
4
|
+
module AgeVerification
|
|
5
|
+
class Request
|
|
6
|
+
attr_reader :min_age, :max_age, :ref_id, :callback_url, :redirect_url
|
|
7
|
+
|
|
8
|
+
def initialize(min_age: nil, max_age: nil, ref_id: nil, callback_url: nil, redirect_url: nil)
|
|
9
|
+
@min_age = min_age
|
|
10
|
+
@max_age = max_age
|
|
11
|
+
@ref_id = ref_id
|
|
12
|
+
@callback_url = callback_url
|
|
13
|
+
@redirect_url = redirect_url
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def to_h
|
|
17
|
+
{
|
|
18
|
+
minAge: @min_age,
|
|
19
|
+
maxAge: @max_age,
|
|
20
|
+
refId: @ref_id,
|
|
21
|
+
callbackUrl: @callback_url,
|
|
22
|
+
redirectUrl: @redirect_url,
|
|
23
|
+
}.compact
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class Pending
|
|
28
|
+
attr_reader :id, :url, :min_age, :max_age
|
|
29
|
+
|
|
30
|
+
def initialize(id:, url: nil, min_age: nil, max_age: nil)
|
|
31
|
+
@id = id; @url = url; @min_age = min_age; @max_age = max_age
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def deconstruct_keys(_) = { id: @id, url: @url, min_age: @min_age, max_age: @max_age }
|
|
35
|
+
|
|
36
|
+
def self.from_json(d)
|
|
37
|
+
new(id: d['id'], url: d['url'], min_age: d['minAge'], max_age: d['maxAge'])
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class Completed
|
|
42
|
+
attr_reader :id, :age_verified
|
|
43
|
+
|
|
44
|
+
def initialize(id:, age_verified:)
|
|
45
|
+
@id = id; @age_verified = age_verified
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def deconstruct_keys(_) = { id: @id, age_verified: @age_verified }
|
|
49
|
+
|
|
50
|
+
def self.from_json(d) = new(id: d['id'], age_verified: d['ageVerified'])
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
class Failed
|
|
54
|
+
attr_reader :id, :error
|
|
55
|
+
|
|
56
|
+
def initialize(id:, error:)
|
|
57
|
+
@id = id; @error = error
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def deconstruct_keys(_) = { id: @id, error: @error }
|
|
61
|
+
|
|
62
|
+
def self.from_json(d) = new(id: d['id'], error: d['error'])
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
class Unknown
|
|
66
|
+
attr_reader :status
|
|
67
|
+
|
|
68
|
+
def initialize(status:)
|
|
69
|
+
@status = status
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def deconstruct_keys(_) = { status: @status }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
module Status
|
|
76
|
+
def self.from_json(d)
|
|
77
|
+
case d['status']
|
|
78
|
+
when 'PENDING' then Pending.from_json(d)
|
|
79
|
+
when 'COMPLETED' then Completed.from_json(d)
|
|
80
|
+
when 'FAILED' then Failed.from_json(d)
|
|
81
|
+
when String then Unknown.new(status: d['status'])
|
|
82
|
+
else raise IdentisureError.new(0, "Invalid age verification status: #{d['status'].inspect}")
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Identisure
|
|
4
|
+
module BankIdNo
|
|
5
|
+
class AuthRequest
|
|
6
|
+
attr_reader :redirect_url, :request_ssn, :request_phone, :request_email,
|
|
7
|
+
:request_address, :ref_id, :app_callback_uri
|
|
8
|
+
|
|
9
|
+
def initialize(redirect_url: nil, request_ssn: nil, request_phone: nil,
|
|
10
|
+
request_email: nil, request_address: nil, ref_id: nil,
|
|
11
|
+
app_callback_uri: nil)
|
|
12
|
+
@redirect_url = redirect_url; @request_ssn = request_ssn
|
|
13
|
+
@request_phone = request_phone; @request_email = request_email
|
|
14
|
+
@request_address = request_address; @ref_id = ref_id
|
|
15
|
+
@app_callback_uri = app_callback_uri
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_h
|
|
19
|
+
{
|
|
20
|
+
redirectUrl: @redirect_url, requestSsn: @request_ssn,
|
|
21
|
+
requestPhone: @request_phone, requestEmail: @request_email,
|
|
22
|
+
requestAddress: @request_address, refId: @ref_id,
|
|
23
|
+
appCallbackUri: @app_callback_uri
|
|
24
|
+
}.compact
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class BackchannelAuthRequest
|
|
29
|
+
attr_reader :ssn, :callback_url, :ref_id
|
|
30
|
+
|
|
31
|
+
def initialize(ssn:, callback_url: nil, ref_id: nil)
|
|
32
|
+
@ssn = ssn; @callback_url = callback_url; @ref_id = ref_id
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def to_h
|
|
36
|
+
{ ssn: @ssn, callbackUrl: @callback_url, refId: @ref_id }.compact
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class SignRequest
|
|
41
|
+
attr_reader :redirect_url, :text, :documents, :ref_id
|
|
42
|
+
|
|
43
|
+
def initialize(redirect_url: nil, text: nil, documents: nil, ref_id: nil)
|
|
44
|
+
@redirect_url = redirect_url; @text = text; @documents = documents
|
|
45
|
+
@ref_id = ref_id
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def to_h
|
|
49
|
+
{
|
|
50
|
+
redirectUrl: @redirect_url, text: @text, documents: @documents,
|
|
51
|
+
refId: @ref_id
|
|
52
|
+
}.compact
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
class SignResult
|
|
57
|
+
attr_reader :end_user, :merchant, :document_hash
|
|
58
|
+
|
|
59
|
+
def initialize(end_user:, merchant:, document_hash:)
|
|
60
|
+
@end_user = end_user; @merchant = merchant; @document_hash = document_hash
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def deconstruct_keys(_) = { end_user: @end_user, merchant: @merchant, document_hash: @document_hash }
|
|
64
|
+
def self.from_json(d) = new(end_user: d['endUser'], merchant: d['merchant'], document_hash: d['hash'])
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
class SignedDocument
|
|
68
|
+
attr_reader :id, :document_hash
|
|
69
|
+
|
|
70
|
+
def initialize(id:, document_hash:)
|
|
71
|
+
@id = id; @document_hash = document_hash
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def deconstruct_keys(_) = { id: @id, document_hash: @document_hash }
|
|
75
|
+
def self.from_json(d) = new(id: d['id'], document_hash: d['hash'])
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
class Pending
|
|
79
|
+
attr_reader :id, :ref_id, :url, :binding_message
|
|
80
|
+
|
|
81
|
+
def initialize(id:, ref_id: nil, url: nil, binding_message: nil)
|
|
82
|
+
@id = id; @ref_id = ref_id; @url = url; @binding_message = binding_message
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def deconstruct_keys(_) = { id: @id, ref_id: @ref_id, url: @url, binding_message: @binding_message }
|
|
86
|
+
|
|
87
|
+
def self.from_json(d)
|
|
88
|
+
new(id: d['id'], ref_id: d['refId'], url: d['url'], binding_message: d['bindingMessage'])
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
class Completed
|
|
93
|
+
attr_reader :id, :ref_id, :ssn, :name, :given_name, :surname,
|
|
94
|
+
:phone, :email, :address, :birth_date, :pid, :bank_id,
|
|
95
|
+
:sign_result, :signed_documents, :authenticated_at, :signed_at
|
|
96
|
+
|
|
97
|
+
def initialize(id:, ssn:, name:, given_name:, surname:, ref_id: nil,
|
|
98
|
+
phone: nil, email: nil, address: nil, birth_date: nil,
|
|
99
|
+
pid: nil, bank_id: nil, sign_result: nil, signed_documents: nil,
|
|
100
|
+
authenticated_at: nil, signed_at: nil)
|
|
101
|
+
@id = id; @ref_id = ref_id; @ssn = ssn; @name = name
|
|
102
|
+
@given_name = given_name; @surname = surname; @phone = phone
|
|
103
|
+
@email = email; @address = address; @birth_date = birth_date
|
|
104
|
+
@pid = pid; @bank_id = bank_id; @sign_result = sign_result
|
|
105
|
+
@signed_documents = signed_documents
|
|
106
|
+
@authenticated_at = authenticated_at; @signed_at = signed_at
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def deconstruct_keys(_)
|
|
110
|
+
{ id: @id, ref_id: @ref_id, ssn: @ssn, name: @name, given_name: @given_name,
|
|
111
|
+
surname: @surname, phone: @phone, email: @email, address: @address,
|
|
112
|
+
birth_date: @birth_date, pid: @pid, bank_id: @bank_id,
|
|
113
|
+
sign_result: @sign_result, signed_documents: @signed_documents,
|
|
114
|
+
authenticated_at: @authenticated_at, signed_at: @signed_at }
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def self.from_json(d)
|
|
118
|
+
new(
|
|
119
|
+
id: d['id'], ref_id: d['refId'], ssn: d['ssn'], name: d['name'],
|
|
120
|
+
given_name: d['givenName'], surname: d['surname'], phone: d['phone'],
|
|
121
|
+
email: d['email'], address: d['address'], birth_date: d['birthDate'],
|
|
122
|
+
pid: d['pid'], bank_id: d['bankId'],
|
|
123
|
+
sign_result: d['signResult'] ? SignResult.from_json(d['signResult']) : nil,
|
|
124
|
+
signed_documents: d['signedDocuments']&.map { SignedDocument.from_json(_1) },
|
|
125
|
+
authenticated_at: d['authenticatedAt'], signed_at: d['signedAt']
|
|
126
|
+
)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
class Failed
|
|
131
|
+
attr_reader :id, :ref_id, :error
|
|
132
|
+
|
|
133
|
+
def initialize(id:, error:, ref_id: nil)
|
|
134
|
+
@id = id; @ref_id = ref_id; @error = error
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def deconstruct_keys(_) = { id: @id, ref_id: @ref_id, error: @error }
|
|
138
|
+
def self.from_json(d) = new(id: d['id'], ref_id: d['refId'], error: d['error'])
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
class Unknown
|
|
142
|
+
attr_reader :status
|
|
143
|
+
|
|
144
|
+
def initialize(status:)
|
|
145
|
+
@status = status
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def deconstruct_keys(_) = { status: @status }
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
module Status
|
|
152
|
+
def self.from_json(d)
|
|
153
|
+
case d['status']
|
|
154
|
+
when 'PENDING' then Pending.from_json(d)
|
|
155
|
+
when 'COMPLETED' then Completed.from_json(d)
|
|
156
|
+
when 'FAILED' then Failed.from_json(d)
|
|
157
|
+
when String then Unknown.new(status: d['status'])
|
|
158
|
+
else raise IdentisureError.new(0, "Invalid bankid-no status: #{d['status'].inspect}")
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
class Endpoint
|
|
164
|
+
# @api private
|
|
165
|
+
def initialize(transport)
|
|
166
|
+
@transport = transport
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def auth(req) = Status.from_json(@transport.post('/v3/bankid-no/auth', req.to_h))
|
|
170
|
+
def backchannel_auth(req) = Status.from_json(@transport.post('/v3/bankid-no/backchannel/auth', req.to_h))
|
|
171
|
+
def sign(req) = Status.from_json(@transport.post('/v3/bankid-no/sign', req.to_h))
|
|
172
|
+
def auth_status(id) = Status.from_json(@transport.get("/v3/bankid-no/auth/#{id}"))
|
|
173
|
+
def sign_status(id) = Status.from_json(@transport.get("/v3/bankid-no/sign/#{id}"))
|
|
174
|
+
def cancel_auth(id) = @transport.delete("/v3/bankid-no/auth/#{id}")
|
|
175
|
+
def cancel_sign(id) = @transport.delete("/v3/bankid-no/sign/#{id}")
|
|
176
|
+
|
|
177
|
+
def age_verification(req)
|
|
178
|
+
Identisure::AgeVerification::Status.from_json(@transport.post('/v3/bankid-no/age-verification', req.to_h))
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def age_verification_status(id)
|
|
182
|
+
Identisure::AgeVerification::Status.from_json(@transport.get("/v3/bankid-no/age-verification/#{id}"))
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def cancel_age_verification(id) = @transport.delete("/v3/bankid-no/age-verification/#{id}")
|
|
186
|
+
|
|
187
|
+
def wait_for_auth(id, opts: PollOptions.new) = poll(opts) { auth_status(id) }
|
|
188
|
+
def wait_for_sign(id, opts: PollOptions.new) = poll(opts) { sign_status(id) }
|
|
189
|
+
|
|
190
|
+
def wait_for_age_verification(id, opts: PollOptions.new)
|
|
191
|
+
poll_age(opts) { age_verification_status(id) }
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
private
|
|
195
|
+
|
|
196
|
+
def poll(opts)
|
|
197
|
+
deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + opts.timeout
|
|
198
|
+
loop do
|
|
199
|
+
status = yield
|
|
200
|
+
return status unless status.is_a?(Pending)
|
|
201
|
+
raise WaitError.new(timeout: true) if Process.clock_gettime(Process::CLOCK_MONOTONIC) >= deadline
|
|
202
|
+
|
|
203
|
+
sleep opts.interval
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def poll_age(opts)
|
|
208
|
+
deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + opts.timeout
|
|
209
|
+
loop do
|
|
210
|
+
status = yield
|
|
211
|
+
return status unless status.is_a?(Identisure::AgeVerification::Pending)
|
|
212
|
+
raise WaitError.new(timeout: true) if Process.clock_gettime(Process::CLOCK_MONOTONIC) >= deadline
|
|
213
|
+
|
|
214
|
+
sleep opts.interval
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|