passageidentity 0.0.3 → 0.0.6
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 +4 -4
- data/.github/workflows/deploy.yml +30 -0
- data/.github/workflows/on_pr.yml +34 -0
- data/.gitignore +1 -2
- data/CONTRIBUTING.md +12 -11
- data/lib/passageidentity/auth.rb +61 -18
- data/lib/passageidentity/client.rb +75 -52
- data/lib/passageidentity/user_api.rb +101 -101
- data/lib/passageidentity.rb +2 -2
- data/passageidentity.gemspec +2 -1
- data/tests/all.rb +3 -2
- data/tests/app_test.rb +15 -0
- data/tests/auth_test.rb +15 -0
- data/tests/magic_link_test.rb +8 -7
- data/tests/user_api_test.rb +17 -16
- metadata +24 -12
- data/lib/passage/auth.rb +0 -35
- data/lib/passage/client.rb +0 -39
- data/lib/passage/request.rb +0 -32
- data/lib/passage/user.rb +0 -0
- data/lib/passage.rb +0 -9
- data/passage-ruby +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a690a22154faaee08c7f917391722ba209f13eed6b321a71112906c45c94c4b
|
4
|
+
data.tar.gz: 33d3a29b62ef42d6239d31082a06e9fc070271e4ebbccfa612fe0b6610c6dc58
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 205210cafaa264ea5b1709c9d09a98f37d4f0c5c306a435a5b59972ed620160ad73a5bda9eb610e0df1204127d75c21b4f7138e9ffa5ea41b3a710c7d8098159
|
7
|
+
data.tar.gz: b06a3b13b4f95c3439f3acefee1872656ac151e88d0fa88e0a1b4800662114de2e25c745020ca26de21321b1c0db4f95ee03a977ed8950492e309fd134be6e0e
|
@@ -0,0 +1,30 @@
|
|
1
|
+
name: Deploy Ruby Gem
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [main]
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
build:
|
9
|
+
name: Build + Publish
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
permissions:
|
12
|
+
contents: read
|
13
|
+
packages: write
|
14
|
+
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v2
|
17
|
+
- uses: ruby/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
ruby-version: '3.0'
|
20
|
+
|
21
|
+
- name: Publish to RubyGems
|
22
|
+
run: |
|
23
|
+
mkdir -p $HOME/.gem
|
24
|
+
touch $HOME/.gem/credentials
|
25
|
+
chmod 0600 $HOME/.gem/credentials
|
26
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
27
|
+
gem build *.gemspec
|
28
|
+
gem push *.gem
|
29
|
+
env:
|
30
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
@@ -0,0 +1,34 @@
|
|
1
|
+
name: PR Checks
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request:
|
5
|
+
branches: [ main ]
|
6
|
+
|
7
|
+
env:
|
8
|
+
API_KEY: ${{ secrets.API_KEY }}
|
9
|
+
APP_ID: ${{ secrets.APP_ID }}
|
10
|
+
PSG_JWT: ${{ secrets.PSG_JWT }}
|
11
|
+
TEST_USER_ID: ${{ secrets.TEST_USER_ID }}
|
12
|
+
|
13
|
+
jobs:
|
14
|
+
build:
|
15
|
+
name: Test and Lint
|
16
|
+
runs-on: ubuntu-latest
|
17
|
+
|
18
|
+
steps:
|
19
|
+
- uses: actions/checkout@v2
|
20
|
+
- uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: '3.0'
|
23
|
+
|
24
|
+
- name: Run Tests
|
25
|
+
run: |
|
26
|
+
gem build passageidentity.gemspec -o test.gem
|
27
|
+
gem install test.gem
|
28
|
+
rm test.gem
|
29
|
+
ruby tests/all.rb
|
30
|
+
- name: Run Linting
|
31
|
+
run: |
|
32
|
+
npm install -g prettier @prettier/plugin-ruby
|
33
|
+
gem install bundler prettier_print syntax_tree syntax_tree-haml syntax_tree-rbs
|
34
|
+
prettier --check '**/*.rb'
|
data/.gitignore
CHANGED
data/CONTRIBUTING.md
CHANGED
@@ -5,8 +5,8 @@
|
|
5
5
|
Install the gem
|
6
6
|
|
7
7
|
```
|
8
|
-
gem build passageidentity.gemspec
|
9
|
-
gem install ./
|
8
|
+
gem build passageidentity.gemspec -o {$FILE_NAME}.gem
|
9
|
+
gem install ./{$FILE_NAME}.gem
|
10
10
|
```
|
11
11
|
|
12
12
|
Test it out:
|
@@ -27,6 +27,15 @@ ruby tests/all.rb
|
|
27
27
|
ruby tests/*_test.rb
|
28
28
|
```
|
29
29
|
|
30
|
+
Run Linter:
|
31
|
+
|
32
|
+
```
|
33
|
+
npm install -g prettier @prettier/plugin-ruby
|
34
|
+
gem install bundler prettier_print syntax_tree syntax_tree-haml syntax_tree-rbs
|
35
|
+
prettier --write '**/*.rb'
|
36
|
+
```
|
37
|
+
|
38
|
+
|
30
39
|
To test in the example app, change the Gemfile to include this path:
|
31
40
|
|
32
41
|
```
|
@@ -45,21 +54,13 @@ Enter host password for user '<username>':
|
|
45
54
|
```
|
46
55
|
|
47
56
|
```
|
48
|
-
<<<<<<< HEAD
|
49
57
|
gem push passage-0.0.0.gem
|
50
58
|
```
|
51
59
|
|
52
60
|
You can check for the gem here:
|
61
|
+
|
53
62
|
```
|
54
63
|
gem list -r passage
|
55
64
|
```
|
56
|
-
=======
|
57
|
-
gem push passageidentity-0.0.0.gem
|
58
|
-
```
|
59
65
|
|
60
|
-
You can check for the gem here:
|
61
|
-
|
62
|
-
```
|
63
|
-
gem list -r passageidentity
|
64
66
|
```
|
65
|
-
>>>>>>> 2d0e3f6dc3b40c621c8d16506fa6ab43b0fba673
|
data/lib/passageidentity/auth.rb
CHANGED
@@ -1,61 +1,104 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require_relative
|
1
|
+
require "openssl"
|
2
|
+
require "base64"
|
3
|
+
require "jwt"
|
4
|
+
require_relative "client"
|
5
5
|
|
6
6
|
module Passage
|
7
7
|
class Auth
|
8
|
-
|
8
|
+
@@app_cache = {}
|
9
|
+
def initialize(app_id, auth_strategy, connection)
|
9
10
|
@app_id = app_id
|
10
11
|
@auth_strategy = auth_strategy
|
11
|
-
@
|
12
|
+
@connection = connection
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
fetch_jwks
|
15
|
+
end
|
16
|
+
|
17
|
+
def fetch_app()
|
18
|
+
begin
|
19
|
+
response = @connection.get("/v1/apps/#{@app_id}")
|
20
|
+
return response.body["app"]
|
21
|
+
rescue Faraday::Error => e
|
22
|
+
raise PassageError,
|
23
|
+
"failed to get Passage App. Http Status: #{e.response[:status]}. Response: #{e.response[:body]["error"]}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def fetch_jwks()
|
28
|
+
if @@app_cache[@app_id]
|
29
|
+
@jwks, @auth_origin = @@app_cache[@app_id]
|
30
|
+
else
|
31
|
+
app = fetch_app
|
32
|
+
auth_gw_connection =
|
33
|
+
Faraday.new(url: "https://auth.passage.id") do |f|
|
34
|
+
f.request :json
|
35
|
+
f.request :retry
|
36
|
+
f.response :raise_error
|
37
|
+
f.response :json
|
38
|
+
f.adapter :net_http
|
39
|
+
end
|
40
|
+
|
41
|
+
# fetch the public key if not in cache
|
42
|
+
app = fetch_app
|
43
|
+
@auth_origin = app["auth_origin"]
|
44
|
+
response =
|
45
|
+
auth_gw_connection.get("/v1/apps/#{@app_id}/.well-known/jwks.json")
|
46
|
+
@jwks = response.body
|
47
|
+
@@app_cache[@app_id] ||= [@jwks, @auth_origin]
|
48
|
+
end
|
16
49
|
end
|
17
50
|
|
18
51
|
def authenticate_request(request)
|
19
52
|
# Get the token based on the strategy
|
20
53
|
if @auth_strategy === Passage::COOKIE_STRATEGY
|
21
|
-
unless request.cookies[
|
54
|
+
unless request.cookies["psg_auth_token"].present?
|
22
55
|
raise PassageError,
|
23
56
|
`missing authentication token: expected "psg_auth_token" cookie`
|
24
57
|
end
|
25
|
-
@token = request.cookies[
|
58
|
+
@token = request.cookies["psg_auth_token"]
|
26
59
|
else
|
27
60
|
headers = request.headers
|
28
|
-
unless headers[
|
29
|
-
raise PassageError,
|
61
|
+
unless headers["Authorization"].present?
|
62
|
+
raise PassageError, "no authentication token in header"
|
30
63
|
end
|
31
|
-
@token = headers[
|
64
|
+
@token = headers["Authorization"].split(" ").last
|
32
65
|
end
|
33
66
|
|
34
67
|
# authenticate the token
|
35
68
|
if @token
|
36
69
|
return authenticate_token(@token)
|
37
70
|
else
|
38
|
-
raise PassageError,
|
71
|
+
raise PassageError, "no authentication token"
|
39
72
|
end
|
40
73
|
nil
|
41
74
|
end
|
42
75
|
|
43
76
|
def authenticate_token(token)
|
77
|
+
kid = JWT.decode(token, nil, false)[1]["kid"]
|
78
|
+
exists = false
|
79
|
+
for jwk in @jwks["keys"]
|
80
|
+
if jwk["kid"] == kid
|
81
|
+
exists = true
|
82
|
+
break
|
83
|
+
end
|
84
|
+
end
|
85
|
+
fetch_jwks unless exists
|
44
86
|
begin
|
45
87
|
claims =
|
46
88
|
JWT.decode(
|
47
89
|
token,
|
48
|
-
|
90
|
+
nil,
|
49
91
|
true,
|
50
92
|
{
|
51
93
|
iss: @app_id,
|
52
94
|
verify_iss: true,
|
53
95
|
aud: @auth_origin,
|
54
96
|
verify_aud: true,
|
55
|
-
algorithms: [
|
97
|
+
algorithms: ["RS256"],
|
98
|
+
jwks: @jwks
|
56
99
|
}
|
57
100
|
)
|
58
|
-
return claims[0][
|
101
|
+
return claims[0]["sub"]
|
59
102
|
rescue JWT::InvalidIssuerError => e
|
60
103
|
raise Passage::PassageError, e.message
|
61
104
|
rescue JWT::InvalidAudError => e
|
@@ -1,10 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
4
|
-
require_relative
|
5
|
-
require_relative
|
3
|
+
require_relative "auth"
|
4
|
+
require_relative "user_api"
|
5
|
+
require_relative "error"
|
6
6
|
|
7
7
|
module Passage
|
8
|
+
App =
|
9
|
+
Struct.new :name,
|
10
|
+
:id,
|
11
|
+
:auth_origin,
|
12
|
+
:redirect_url,
|
13
|
+
:login_url,
|
14
|
+
:rsa_public_key,
|
15
|
+
:allowed_identifer,
|
16
|
+
:required_identifier,
|
17
|
+
:require_email_verification,
|
18
|
+
:session_timeout_length,
|
19
|
+
:user_metadata_schema,
|
20
|
+
:layouts,
|
21
|
+
keyword_init: true
|
8
22
|
User =
|
9
23
|
Struct.new :id,
|
10
24
|
:status,
|
@@ -43,40 +57,36 @@ module Passage
|
|
43
57
|
COOKIE_STRATEGY = 0
|
44
58
|
HEADER_STRATEGY = 1
|
45
59
|
|
46
|
-
EMAIL_CHANNEL =
|
47
|
-
PHONE_CHANNEL =
|
60
|
+
EMAIL_CHANNEL = "email"
|
61
|
+
PHONE_CHANNEL = "phone"
|
48
62
|
|
49
63
|
class Client
|
50
|
-
@@app_cache = {}
|
51
|
-
|
52
64
|
attr_reader :auth
|
53
65
|
attr_reader :user
|
54
66
|
|
55
|
-
def initialize(app_id:, api_key:
|
56
|
-
@api_url =
|
67
|
+
def initialize(app_id:, api_key: "", auth_strategy: COOKIE_STRATEGY)
|
68
|
+
@api_url = "https://api.passage.id"
|
57
69
|
@app_id = app_id
|
58
70
|
@api_key = api_key
|
59
71
|
|
60
72
|
# check for valid auth strategy
|
61
73
|
unless [COOKIE_STRATEGY, HEADER_STRATEGY].include? auth_strategy
|
62
|
-
raise PassageError,
|
74
|
+
raise PassageError, "invalid auth strategy."
|
63
75
|
end
|
64
76
|
@auth_strategy = auth_strategy
|
65
77
|
|
66
78
|
# setup
|
67
79
|
get_connection
|
68
|
-
fetch_public_key(@connection)
|
69
80
|
|
70
81
|
# initialize auth class
|
71
|
-
@auth =
|
72
|
-
Passage::Auth.new(@app_id, @auth_strategy, @public_key, @auth_origin)
|
82
|
+
@auth = Passage::Auth.new(@app_id, @auth_strategy, @connection)
|
73
83
|
|
74
84
|
# initialize user class
|
75
85
|
@user = Passage::UserAPI.new(@connection, @app_id, @api_key)
|
76
86
|
end
|
77
87
|
|
78
88
|
def get_connection
|
79
|
-
if @api_key ==
|
89
|
+
if @api_key == ""
|
80
90
|
@connection =
|
81
91
|
Faraday.new(url: @api_url) do |f|
|
82
92
|
f.request :json
|
@@ -90,7 +100,7 @@ module Passage
|
|
90
100
|
Faraday.new(
|
91
101
|
url: @api_url,
|
92
102
|
headers: {
|
93
|
-
|
103
|
+
"Authorization" => "Bearer #{@api_key}"
|
94
104
|
}
|
95
105
|
) do |f|
|
96
106
|
f.request :json
|
@@ -102,66 +112,79 @@ module Passage
|
|
102
112
|
end
|
103
113
|
end
|
104
114
|
|
105
|
-
def
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
115
|
+
def get_app()
|
116
|
+
begin
|
117
|
+
app_info = @auth.fetch_app()
|
118
|
+
return(
|
119
|
+
Passage::App.new(
|
120
|
+
name: app_info["name"],
|
121
|
+
id: app_info["id"],
|
122
|
+
auth_origin: app_info["auth_origin"],
|
123
|
+
redirect_url: app_info["redirect_url"],
|
124
|
+
login_url: app_info["login_url"],
|
125
|
+
rsa_public_key: app_info["rsa_public_key"],
|
126
|
+
allowed_identifer: app_info["allowed_identifer"],
|
127
|
+
required_identifier: app_info["required_identifier"],
|
128
|
+
require_email_verification: app_info["require_email_verification"],
|
129
|
+
session_timeout_length: app_info["session_timeout_length"],
|
130
|
+
user_metadata_schema: app_info["user_metadata_schema"],
|
131
|
+
layouts: app_info["layouts"]
|
132
|
+
)
|
133
|
+
)
|
134
|
+
rescue => e
|
135
|
+
raise e
|
114
136
|
end
|
115
137
|
end
|
116
138
|
|
117
139
|
def create_magic_link(
|
118
|
-
user_id:
|
119
|
-
email:
|
120
|
-
phone:
|
121
|
-
channel:
|
140
|
+
user_id: "",
|
141
|
+
email: "",
|
142
|
+
phone: "",
|
143
|
+
channel: "",
|
122
144
|
send: false,
|
123
|
-
magic_link_path:
|
124
|
-
redirect_url:
|
145
|
+
magic_link_path: "",
|
146
|
+
redirect_url: "",
|
125
147
|
ttl: 60
|
126
148
|
)
|
127
149
|
magic_link_req = {}
|
128
|
-
magic_link_req[
|
129
|
-
magic_link_req[
|
130
|
-
magic_link_req[
|
150
|
+
magic_link_req["user_id"] = user_id unless user_id.empty?
|
151
|
+
magic_link_req["email"] = email unless email.empty?
|
152
|
+
magic_link_req["phone"] = phone unless phone.empty?
|
131
153
|
|
132
154
|
# check to see if the channel specified is valid before sending it off to the server
|
133
155
|
unless [PHONE_CHANNEL, EMAIL_CHANNEL].include? channel
|
134
156
|
raise PassageError,
|
135
|
-
|
157
|
+
"channel: must be either Passage::EMAIL_CHANNEL or Passage::PHONE_CHANNEL"
|
136
158
|
end
|
137
|
-
magic_link_req[
|
138
|
-
magic_link_req[
|
139
|
-
magic_link_req[
|
140
|
-
|
141
|
-
|
142
|
-
magic_link_req[
|
159
|
+
magic_link_req["channel"] = channel unless channel.empty?
|
160
|
+
magic_link_req["send"] = send
|
161
|
+
magic_link_req[
|
162
|
+
"magic_link_path"
|
163
|
+
] = magic_link_path unless magic_link_path.empty?
|
164
|
+
magic_link_req["redirect_url"] = redirect_url unless redirect_url.empty?
|
165
|
+
magic_link_req["ttl"] = ttl unless ttl == 0
|
143
166
|
|
144
167
|
begin
|
145
168
|
response =
|
146
169
|
@connection.post("/v1/apps/#{@app_id}/magic-links", magic_link_req)
|
147
|
-
magic_link = response.body[
|
170
|
+
magic_link = response.body["magic_link"]
|
148
171
|
return(
|
149
172
|
Passage::MagicLink.new(
|
150
|
-
id: magic_link[
|
151
|
-
secret: magic_link[
|
152
|
-
activated: magic_link[
|
153
|
-
user_id: magic_link[
|
154
|
-
app_id: magic_link[
|
155
|
-
identifier: magic_link[
|
156
|
-
type: magic_link[
|
157
|
-
redirect_url: magic_link[
|
158
|
-
ttl: magic_link[
|
159
|
-
url: magic_link[
|
173
|
+
id: magic_link["id"],
|
174
|
+
secret: magic_link["secret"],
|
175
|
+
activated: magic_link["activated"],
|
176
|
+
user_id: magic_link["user_id"],
|
177
|
+
app_id: magic_link["app_id"],
|
178
|
+
identifier: magic_link["identifier"],
|
179
|
+
type: magic_link["type"],
|
180
|
+
redirect_url: magic_link["redirect_url"],
|
181
|
+
ttl: magic_link["ttl"],
|
182
|
+
url: magic_link["url"]
|
160
183
|
)
|
161
184
|
)
|
162
185
|
rescue Faraday::Error => e
|
163
186
|
raise PassageError,
|
164
|
-
"failed to create Passage Magic Link. Http Status: #{e.response[:status]}. Response: #{e.response[:body][
|
187
|
+
"failed to create Passage Magic Link. Http Status: #{e.response[:status]}. Response: #{e.response[:body]["error"]}"
|
165
188
|
end
|
166
189
|
end
|
167
190
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "client"
|
2
2
|
|
3
3
|
module Passage
|
4
4
|
class UserAPI
|
@@ -10,26 +10,26 @@ module Passage
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def get(user_id:)
|
13
|
-
raise PassageError,
|
13
|
+
raise PassageError, "must supply a valid user_id" if user_id.to_s.empty?
|
14
14
|
begin
|
15
15
|
response = @connection.get("/v1/apps/#{@app_id}/users/#{user_id}")
|
16
|
-
user = response.body[
|
16
|
+
user = response.body["user"]
|
17
17
|
user.transform_keys(&:to_sym)
|
18
18
|
return(
|
19
19
|
Passage::User.new(
|
20
|
-
id: user[
|
21
|
-
status: user[
|
22
|
-
email: user[
|
23
|
-
phone: user[
|
24
|
-
email_verified: user[
|
25
|
-
created_at: user[
|
26
|
-
updated_at: user[
|
27
|
-
last_login_at: user[
|
28
|
-
login_count: user[
|
29
|
-
webauthn: user[
|
30
|
-
webauthn_devices: user[
|
31
|
-
recent_events: user[
|
32
|
-
user_metadata: user[
|
20
|
+
id: user["id"],
|
21
|
+
status: user["status"],
|
22
|
+
email: user["email"],
|
23
|
+
phone: user["phone"],
|
24
|
+
email_verified: user["email_verified"],
|
25
|
+
created_at: user["created_at"],
|
26
|
+
updated_at: user["updated_at"],
|
27
|
+
last_login_at: user["last_login_at"],
|
28
|
+
login_count: user["login_count"],
|
29
|
+
webauthn: user["webauthn"],
|
30
|
+
webauthn_devices: user["webauthn_devices"],
|
31
|
+
recent_events: user["recent_events"],
|
32
|
+
user_metadata: user["user_metadata"]
|
33
33
|
)
|
34
34
|
)
|
35
35
|
rescue Faraday::Error => e
|
@@ -38,32 +38,32 @@ module Passage
|
|
38
38
|
"passage User with ID \"#{user_id}\" does not exist"
|
39
39
|
else
|
40
40
|
raise PassageError,
|
41
|
-
"failed to get Passage User. Http Status: #{e.response[:status]}. Response: #{e.response[:body][
|
41
|
+
"failed to get Passage User. Http Status: #{e.response[:status]}. Response: #{e.response[:body]["error"]}"
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
46
|
def activate(user_id:)
|
47
|
-
raise PassageError,
|
47
|
+
raise PassageError, "must supply a valid user_id" if user_id.to_s.empty?
|
48
48
|
begin
|
49
49
|
response =
|
50
50
|
@connection.patch("/v1/apps/#{@app_id}/users/#{user_id}/activate")
|
51
|
-
user = response.body[
|
51
|
+
user = response.body["user"]
|
52
52
|
return(
|
53
53
|
Passage::User.new(
|
54
|
-
id: user[
|
55
|
-
status: user[
|
56
|
-
email: user[
|
57
|
-
phone: user[
|
58
|
-
email_verified: user[
|
59
|
-
created_at: user[
|
60
|
-
updated_at: user[
|
61
|
-
last_login_at: user[
|
62
|
-
login_count: user[
|
63
|
-
webauthn: user[
|
64
|
-
webauthn_devices: user[
|
65
|
-
recent_events: user[
|
66
|
-
user_metadata: user[
|
54
|
+
id: user["id"],
|
55
|
+
status: user["status"],
|
56
|
+
email: user["email"],
|
57
|
+
phone: user["phone"],
|
58
|
+
email_verified: user["email_verified"],
|
59
|
+
created_at: user["created_at"],
|
60
|
+
updated_at: user["updated_at"],
|
61
|
+
last_login_at: user["last_login_at"],
|
62
|
+
login_count: user["login_count"],
|
63
|
+
webauthn: user["webauthn"],
|
64
|
+
webauthn_devices: user["webauthn_devices"],
|
65
|
+
recent_events: user["recent_events"],
|
66
|
+
user_metadata: user["user_metadata"]
|
67
67
|
)
|
68
68
|
)
|
69
69
|
rescue Faraday::Error => e
|
@@ -72,32 +72,32 @@ module Passage
|
|
72
72
|
"passage User with ID \"#{user_id}\" does not exist"
|
73
73
|
else
|
74
74
|
raise PassageError,
|
75
|
-
"failed to activate Passage User. Http Status: #{e.response[:status]}. Response: #{e.response[:body][
|
75
|
+
"failed to activate Passage User. Http Status: #{e.response[:status]}. Response: #{e.response[:body]["error"]}"
|
76
76
|
end
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
80
|
def deactivate(user_id:)
|
81
|
-
raise PassageError,
|
81
|
+
raise PassageError, "must supply a valid user_id" if user_id.to_s.empty?
|
82
82
|
begin
|
83
83
|
response =
|
84
84
|
@connection.patch("/v1/apps/#{@app_id}/users/#{user_id}/deactivate")
|
85
|
-
user = response.body[
|
85
|
+
user = response.body["user"]
|
86
86
|
return(
|
87
87
|
Passage::User.new(
|
88
|
-
id: user[
|
89
|
-
status: user[
|
90
|
-
email: user[
|
91
|
-
phone: user[
|
92
|
-
email_verified: user[
|
93
|
-
created_at: user[
|
94
|
-
updated_at: user[
|
95
|
-
last_login_at: user[
|
96
|
-
login_count: user[
|
97
|
-
webauthn: user[
|
98
|
-
webauthn_devices: user[
|
99
|
-
recent_events: user[
|
100
|
-
user_metadata: user[
|
88
|
+
id: user["id"],
|
89
|
+
status: user["status"],
|
90
|
+
email: user["email"],
|
91
|
+
phone: user["phone"],
|
92
|
+
email_verified: user["email_verified"],
|
93
|
+
created_at: user["created_at"],
|
94
|
+
updated_at: user["updated_at"],
|
95
|
+
last_login_at: user["last_login_at"],
|
96
|
+
login_count: user["login_count"],
|
97
|
+
webauthn: user["webauthn"],
|
98
|
+
webauthn_devices: user["webauthn_devices"],
|
99
|
+
recent_events: user["recent_events"],
|
100
|
+
user_metadata: user["user_metadata"]
|
101
101
|
)
|
102
102
|
)
|
103
103
|
rescue Faraday::Error => e
|
@@ -106,36 +106,36 @@ module Passage
|
|
106
106
|
"passage User with ID \"#{user_id}\" does not exist"
|
107
107
|
else
|
108
108
|
raise PassageError,
|
109
|
-
"failed to deactivate Passage User. Http Status: #{e.response[:status]}. Response: #{e.response[:body][
|
109
|
+
"failed to deactivate Passage User. Http Status: #{e.response[:status]}. Response: #{e.response[:body]["error"]}"
|
110
110
|
end
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
-
def update(user_id:, email:
|
115
|
-
raise PassageError,
|
114
|
+
def update(user_id:, email: "", phone: "", user_metadata: {})
|
115
|
+
raise PassageError, "must supply a valid user_id" if user_id.to_s.empty?
|
116
116
|
updates = {}
|
117
|
-
updates[
|
118
|
-
updates[
|
119
|
-
updates[
|
117
|
+
updates["email"] = email unless email.empty?
|
118
|
+
updates["phone"] = phone unless phone.empty?
|
119
|
+
updates["user_metadata"] = user_metadata unless user_metadata.empty?
|
120
120
|
begin
|
121
121
|
response =
|
122
122
|
@connection.patch("/v1/apps/#{@app_id}/users/#{user_id}", updates)
|
123
|
-
user = response.body[
|
123
|
+
user = response.body["user"]
|
124
124
|
return(
|
125
125
|
Passage::User.new(
|
126
|
-
id: user[
|
127
|
-
status: user[
|
128
|
-
email: user[
|
129
|
-
phone: user[
|
130
|
-
email_verified: user[
|
131
|
-
created_at: user[
|
132
|
-
updated_at: user[
|
133
|
-
last_login_at: user[
|
134
|
-
login_count: user[
|
135
|
-
webauthn: user[
|
136
|
-
webauthn_devices: user[
|
137
|
-
recent_events: user[
|
138
|
-
user_metadata: user[
|
126
|
+
id: user["id"],
|
127
|
+
status: user["status"],
|
128
|
+
email: user["email"],
|
129
|
+
phone: user["phone"],
|
130
|
+
email_verified: user["email_verified"],
|
131
|
+
created_at: user["created_at"],
|
132
|
+
updated_at: user["updated_at"],
|
133
|
+
last_login_at: user["last_login_at"],
|
134
|
+
login_count: user["login_count"],
|
135
|
+
webauthn: user["webauthn"],
|
136
|
+
webauthn_devices: user["webauthn_devices"],
|
137
|
+
recent_events: user["recent_events"],
|
138
|
+
user_metadata: user["user_metadata"]
|
139
139
|
)
|
140
140
|
)
|
141
141
|
rescue Faraday::Error => e
|
@@ -144,44 +144,44 @@ module Passage
|
|
144
144
|
"passage User with ID \"#{user_id}\" does not exist"
|
145
145
|
else
|
146
146
|
raise PassageError,
|
147
|
-
"failed to update Passage User. Http Status: #{e.response[:status]}. Response: #{e.response[:body][
|
147
|
+
"failed to update Passage User. Http Status: #{e.response[:status]}. Response: #{e.response[:body]["error"]}"
|
148
148
|
end
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
152
|
-
def create(email:
|
152
|
+
def create(email: "", phone: "", user_metadata: {})
|
153
153
|
create = {}
|
154
|
-
create[
|
155
|
-
create[
|
156
|
-
create[
|
154
|
+
create["email"] = email unless email.empty?
|
155
|
+
create["phone"] = phone unless phone.empty?
|
156
|
+
create["user_metadata"] = user_metadata unless user_metadata.empty?
|
157
157
|
begin
|
158
158
|
response = @connection.post("/v1/apps/#{@app_id}/users", create)
|
159
|
-
user = response.body[
|
159
|
+
user = response.body["user"]
|
160
160
|
return(
|
161
161
|
Passage::User.new(
|
162
|
-
id: user[
|
163
|
-
status: user[
|
164
|
-
email: user[
|
165
|
-
phone: user[
|
166
|
-
email_verified: user[
|
167
|
-
created_at: user[
|
168
|
-
updated_at: user[
|
169
|
-
last_login_at: user[
|
170
|
-
login_count: user[
|
171
|
-
webauthn: user[
|
172
|
-
webauthn_devices: user[
|
173
|
-
recent_events: user[
|
174
|
-
user_metadata: user[
|
162
|
+
id: user["id"],
|
163
|
+
status: user["status"],
|
164
|
+
email: user["email"],
|
165
|
+
phone: user["phone"],
|
166
|
+
email_verified: user["email_verified"],
|
167
|
+
created_at: user["created_at"],
|
168
|
+
updated_at: user["updated_at"],
|
169
|
+
last_login_at: user["last_login_at"],
|
170
|
+
login_count: user["login_count"],
|
171
|
+
webauthn: user["webauthn"],
|
172
|
+
webauthn_devices: user["webauthn_devices"],
|
173
|
+
recent_events: user["recent_events"],
|
174
|
+
user_metadata: user["user_metadata"]
|
175
175
|
)
|
176
176
|
)
|
177
177
|
rescue Faraday::Error => e
|
178
178
|
raise PassageError,
|
179
|
-
"failed to create Passage User. Http Status: #{e.response[:status]}. Response: #{e.response[:body][
|
179
|
+
"failed to create Passage User. Http Status: #{e.response[:status]}. Response: #{e.response[:body]["error"]}"
|
180
180
|
end
|
181
181
|
end
|
182
182
|
|
183
183
|
def delete(user_id:)
|
184
|
-
raise PassageError,
|
184
|
+
raise PassageError, "must supply a valid user_id" if user_id.to_s.empty?
|
185
185
|
begin
|
186
186
|
response = @connection.delete("/v1/apps/#{@app_id}/users/#{user_id}")
|
187
187
|
return true
|
@@ -191,15 +191,15 @@ module Passage
|
|
191
191
|
"passage User with ID \"#{user_id}\" does not exist"
|
192
192
|
else
|
193
193
|
raise PassageError,
|
194
|
-
"failed to delete Passage User. Http Status: #{e.response[:status]}. Response: #{e.response[:body][
|
194
|
+
"failed to delete Passage User. Http Status: #{e.response[:status]}. Response: #{e.response[:body]["error"]}"
|
195
195
|
end
|
196
196
|
end
|
197
197
|
end
|
198
198
|
|
199
199
|
def delete_device(user_id:, device_id:)
|
200
|
-
raise PassageError,
|
200
|
+
raise PassageError, "must supply a valid user_id" if user_id.to_s.empty?
|
201
201
|
if device_id.to_s.empty?
|
202
|
-
raise PassageError,
|
202
|
+
raise PassageError, "must supply a valid device_id"
|
203
203
|
end
|
204
204
|
begin
|
205
205
|
response =
|
@@ -209,32 +209,32 @@ module Passage
|
|
209
209
|
return true
|
210
210
|
rescue Faraday::Error => e
|
211
211
|
raise PassageError,
|
212
|
-
"failed to delete Passage User Device. Http Status: #{e.response[:status]}. Response: #{e.response[:body][
|
212
|
+
"failed to delete Passage User Device. Http Status: #{e.response[:status]}. Response: #{e.response[:body]["error"]}"
|
213
213
|
end
|
214
214
|
end
|
215
215
|
|
216
216
|
def list_devices(user_id:)
|
217
|
-
raise PassageError,
|
217
|
+
raise PassageError, "must supply a valid user_id" if user_id.to_s.empty?
|
218
218
|
begin
|
219
219
|
response =
|
220
220
|
@connection.get("/v1/apps/#{@app_id}/users/#{user_id}/devices")
|
221
|
-
devicesResp = response.body[
|
221
|
+
devicesResp = response.body["devices"]
|
222
222
|
devices = Array.new
|
223
223
|
devicesResp.each do |device|
|
224
224
|
devices.append(
|
225
225
|
Passage::Device.new(
|
226
|
-
id: device[
|
227
|
-
cred_id: device[
|
228
|
-
friendly_name: device[
|
229
|
-
usage_count: device[
|
230
|
-
last_used: device[
|
226
|
+
id: device["id"],
|
227
|
+
cred_id: device["cred_id"],
|
228
|
+
friendly_name: device["friendly_name"],
|
229
|
+
usage_count: device["usage_count"],
|
230
|
+
last_used: device["last_used"]
|
231
231
|
)
|
232
232
|
)
|
233
233
|
end
|
234
234
|
return devices
|
235
235
|
rescue Faraday::Error => e
|
236
236
|
raise PassageError,
|
237
|
-
"failed to delete Passage User Device. Http Status: #{e.response[:status]}. Response: #{e.response[:body][
|
237
|
+
"failed to delete Passage User Device. Http Status: #{e.response[:status]}. Response: #{e.response[:body]["error"]}"
|
238
238
|
end
|
239
239
|
end
|
240
240
|
end
|
data/lib/passageidentity.rb
CHANGED
data/passageidentity.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'passageidentity'
|
3
|
-
s.version = '0.0.
|
3
|
+
s.version = '0.0.6'
|
4
4
|
s.summary = 'Passage SDK for biometric authentication'
|
5
5
|
s.description =
|
6
6
|
'Enables verification of server-side authentication and user management for applications using Passage'
|
@@ -27,4 +27,5 @@ Gem::Specification.new do |s|
|
|
27
27
|
s.add_dependency 'faraday', '>= 0.17.0', '< 2.0'
|
28
28
|
s.add_dependency 'jwt', '>= 2.3.0'
|
29
29
|
s.add_dependency 'openssl', '>= 3.0.0'
|
30
|
+
s.add_dependency 'dotenv', '>= 2.7.6'
|
30
31
|
end
|
data/tests/all.rb
CHANGED
@@ -1,2 +1,3 @@
|
|
1
|
-
Dir[File.dirname(File.absolute_path(__FILE__)) +
|
2
|
-
|
1
|
+
Dir[File.dirname(File.absolute_path(__FILE__)) + "/**/*_test.rb"].each do |file|
|
2
|
+
require file
|
3
|
+
end
|
data/tests/app_test.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative "../lib/passageidentity/client"
|
2
|
+
require "dotenv"
|
3
|
+
require "faraday"
|
4
|
+
require "test/unit"
|
5
|
+
|
6
|
+
Dotenv.load(".env")
|
7
|
+
class TestAppAPI < Test::Unit::TestCase
|
8
|
+
PassageClient =
|
9
|
+
Passage::Client.new(app_id: ENV["APP_ID"], api_key: ENV["API_KEY"])
|
10
|
+
|
11
|
+
def test_get_app()
|
12
|
+
app = PassageClient.get_app()
|
13
|
+
assert_equal ENV["APP_ID"], app.id
|
14
|
+
end
|
15
|
+
end
|
data/tests/auth_test.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative "../lib/passageidentity/client"
|
2
|
+
require "dotenv"
|
3
|
+
require "faraday"
|
4
|
+
require "test/unit"
|
5
|
+
|
6
|
+
Dotenv.load(".env")
|
7
|
+
class TestUserAPI < Test::Unit::TestCase
|
8
|
+
PassageClient =
|
9
|
+
Passage::Client.new(app_id: ENV["APP_ID"], api_key: ENV["API_KEY"])
|
10
|
+
|
11
|
+
def test_authenticate_token
|
12
|
+
user_id = PassageClient.auth.authenticate_token(ENV["PSG_JWT"])
|
13
|
+
assert_equal ENV["TEST_USER_ID"], user_id
|
14
|
+
end
|
15
|
+
end
|
data/tests/magic_link_test.rb
CHANGED
@@ -1,20 +1,21 @@
|
|
1
|
-
require_relative
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require_relative "../lib/passageidentity/client"
|
2
|
+
require "dotenv"
|
3
|
+
require "faraday"
|
4
|
+
require "test/unit"
|
5
5
|
|
6
|
+
Dotenv.load(".env")
|
6
7
|
class TestUserAPI < Test::Unit::TestCase
|
7
8
|
PassageClient =
|
8
|
-
Passage::Client.new(app_id: ENV[
|
9
|
+
Passage::Client.new(app_id: ENV["APP_ID"], api_key: ENV["API_KEY"])
|
9
10
|
|
10
11
|
def test_create_magi_link()
|
11
12
|
magic_link =
|
12
13
|
PassageClient.create_magic_link(
|
13
|
-
email:
|
14
|
+
email: "chris@passage.id",
|
14
15
|
channel: Passage::EMAIL_CHANNEL,
|
15
16
|
ttl: 12
|
16
17
|
)
|
17
18
|
assert_equal 12, magic_link.ttl
|
18
|
-
assert_equal
|
19
|
+
assert_equal "chris@passage.id", magic_link.identifier
|
19
20
|
end
|
20
21
|
end
|
data/tests/user_api_test.rb
CHANGED
@@ -1,18 +1,19 @@
|
|
1
|
-
require_relative
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require_relative "../lib/passageidentity/client"
|
2
|
+
require "dotenv"
|
3
|
+
require "faraday"
|
4
|
+
require "test/unit"
|
5
5
|
|
6
|
+
Dotenv.load(".env")
|
6
7
|
class TestUserAPI < Test::Unit::TestCase
|
7
8
|
PassageClient =
|
8
|
-
Passage::Client.new(app_id: ENV[
|
9
|
+
Passage::Client.new(app_id: ENV["APP_ID"], api_key: ENV["API_KEY"])
|
9
10
|
|
10
11
|
def setup()
|
11
12
|
$global_test_user =
|
12
13
|
PassageClient.user.create(
|
13
|
-
email:
|
14
|
+
email: "chris+test-ruby@passage.id",
|
14
15
|
user_metadata: {
|
15
|
-
|
16
|
+
example1: "cool"
|
16
17
|
}
|
17
18
|
)
|
18
19
|
end
|
@@ -20,13 +21,13 @@ class TestUserAPI < Test::Unit::TestCase
|
|
20
21
|
def test_create_delete_user()
|
21
22
|
user =
|
22
23
|
PassageClient.user.create(
|
23
|
-
email:
|
24
|
+
email: "chris+test-create-delete@passage.id",
|
24
25
|
user_metadata: {
|
25
|
-
|
26
|
+
example1: "cool"
|
26
27
|
}
|
27
28
|
)
|
28
|
-
assert_equal
|
29
|
-
assert_equal
|
29
|
+
assert_equal "chris+test-create-delete@passage.id", user.email
|
30
|
+
assert_equal "cool", user.user_metadata["example1"]
|
30
31
|
deleted = PassageClient.user.delete(user_id: user.id)
|
31
32
|
assert_equal true, deleted
|
32
33
|
end
|
@@ -39,28 +40,28 @@ class TestUserAPI < Test::Unit::TestCase
|
|
39
40
|
def test_deactivate_user()
|
40
41
|
user = PassageClient.user.deactivate(user_id: $global_test_user.id)
|
41
42
|
assert_equal $global_test_user.id, user.id
|
42
|
-
assert_equal
|
43
|
+
assert_equal "inactive", user.status
|
43
44
|
end
|
44
45
|
|
45
46
|
def test_activate_user()
|
46
47
|
user = PassageClient.user.activate(user_id: $global_test_user.id)
|
47
48
|
assert_equal $global_test_user.id, user.id
|
48
|
-
assert_equal
|
49
|
+
assert_equal "active", user.status
|
49
50
|
end
|
50
51
|
|
51
52
|
def test_update_user()
|
52
|
-
new_email =
|
53
|
+
new_email = "chris+update_test-ruby@passage.id"
|
53
54
|
user =
|
54
55
|
PassageClient.user.update(
|
55
56
|
user_id: $global_test_user.id,
|
56
57
|
email: new_email,
|
57
58
|
user_metadata: {
|
58
|
-
|
59
|
+
example1: "lame"
|
59
60
|
}
|
60
61
|
)
|
61
62
|
assert_equal $global_test_user.id, user.id
|
62
63
|
assert_equal new_email, user.email
|
63
|
-
assert_equal
|
64
|
+
assert_equal "lame", user.user_metadata["example1"]
|
64
65
|
end
|
65
66
|
|
66
67
|
def test_list_devices()
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: passageidentity
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Passage Identity
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-05-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -58,6 +58,20 @@ dependencies:
|
|
58
58
|
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: 3.0.0
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: dotenv
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 2.7.6
|
68
|
+
type: :runtime
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 2.7.6
|
61
75
|
description: Enables verification of server-side authentication and user management
|
62
76
|
for applications using Passage
|
63
77
|
email: support@passage.id
|
@@ -65,23 +79,21 @@ executables: []
|
|
65
79
|
extensions: []
|
66
80
|
extra_rdoc_files: []
|
67
81
|
files:
|
82
|
+
- ".github/workflows/deploy.yml"
|
83
|
+
- ".github/workflows/on_pr.yml"
|
68
84
|
- ".gitignore"
|
69
85
|
- CONTRIBUTING.md
|
70
86
|
- LICENSE
|
71
87
|
- README.md
|
72
|
-
- lib/passage.rb
|
73
|
-
- lib/passage/auth.rb
|
74
|
-
- lib/passage/client.rb
|
75
|
-
- lib/passage/request.rb
|
76
|
-
- lib/passage/user.rb
|
77
88
|
- lib/passageidentity.rb
|
78
89
|
- lib/passageidentity/auth.rb
|
79
90
|
- lib/passageidentity/client.rb
|
80
91
|
- lib/passageidentity/error.rb
|
81
92
|
- lib/passageidentity/user_api.rb
|
82
|
-
- passage-ruby
|
83
93
|
- passageidentity.gemspec
|
84
94
|
- tests/all.rb
|
95
|
+
- tests/app_test.rb
|
96
|
+
- tests/auth_test.rb
|
85
97
|
- tests/magic_link_test.rb
|
86
98
|
- tests/user_api_test.rb
|
87
99
|
homepage: https://rubygems.org/gems/passageidentity
|
@@ -89,7 +101,7 @@ licenses:
|
|
89
101
|
- MIT
|
90
102
|
metadata:
|
91
103
|
source_code_uri: https://github.com/passage-identity/passage-ruby
|
92
|
-
post_install_message:
|
104
|
+
post_install_message:
|
93
105
|
rdoc_options: []
|
94
106
|
require_paths:
|
95
107
|
- lib
|
@@ -104,8 +116,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
116
|
- !ruby/object:Gem::Version
|
105
117
|
version: '0'
|
106
118
|
requirements: []
|
107
|
-
rubygems_version: 3.
|
108
|
-
signing_key:
|
119
|
+
rubygems_version: 3.2.33
|
120
|
+
signing_key:
|
109
121
|
specification_version: 4
|
110
122
|
summary: Passage SDK for biometric authentication
|
111
123
|
test_files: []
|
data/lib/passage/auth.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'openssl'
|
2
|
-
require 'base64'
|
3
|
-
require 'jwt'
|
4
|
-
|
5
|
-
module Passage
|
6
|
-
class Auth
|
7
|
-
|
8
|
-
def initialize(app_id, public_key, auth_origin)
|
9
|
-
|
10
|
-
@app_id = app_id
|
11
|
-
@auth_origin = auth_origin
|
12
|
-
|
13
|
-
# bas64 decode and then parse the public key
|
14
|
-
# when we have JWKS endpoint, this will get easier I think
|
15
|
-
@public_key = OpenSSL::PKey::RSA.new(Base64.decode64(public_key))
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
def authenticate(token)
|
20
|
-
|
21
|
-
begin
|
22
|
-
claims = JWT.decode(token, @public_key, true,{ iss: @app_id, verify_iss: true, aud: @auth_origin, verify_aud: true, algorithms: ["RS256"] })
|
23
|
-
return claims[0]["sub"]
|
24
|
-
rescue JWT::InvalidIssuerError
|
25
|
-
raise JWTInvalidIssuerError
|
26
|
-
rescue JWT::InvalidAudError
|
27
|
-
raise JWTInvalidAudienceError
|
28
|
-
rescue JWT::ExpiredSignature
|
29
|
-
raise JWTExpiredSignatureError
|
30
|
-
rescue JWT::IncorrectAlgorithm
|
31
|
-
raise JWTIncorrectAlgorithmError
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
data/lib/passage/client.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'request'
|
4
|
-
require_relative 'auth'
|
5
|
-
|
6
|
-
module Passage
|
7
|
-
class Client
|
8
|
-
|
9
|
-
attr_reader :auth
|
10
|
-
|
11
|
-
def initialize(app_id:)
|
12
|
-
@api_url = "https://api.passage.id"
|
13
|
-
@app_id = app_id
|
14
|
-
|
15
|
-
get_connection()
|
16
|
-
|
17
|
-
fetch_public_key(@connection)
|
18
|
-
|
19
|
-
@auth = Passage::Auth.new(@app_id, @public_key, @auth_origin)
|
20
|
-
end
|
21
|
-
|
22
|
-
def get_connection
|
23
|
-
@connection = Faraday.new(url: @api_url) do |f|
|
24
|
-
f.request :json
|
25
|
-
f.request :retry
|
26
|
-
f.response :json
|
27
|
-
f.adapter :net_http
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def fetch_public_key(conn)
|
32
|
-
response = conn.get("/v1/apps/" + @app_id)
|
33
|
-
# TODO Add error handling
|
34
|
-
@public_key = response.body["app"]["rsa_public_key"]
|
35
|
-
@auth_origin = response.body["app"]["auth_origin"]
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
end
|
data/lib/passage/request.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Passage
|
4
|
-
module Request
|
5
|
-
def get_request(path)
|
6
|
-
@connection.get(
|
7
|
-
path
|
8
|
-
).body
|
9
|
-
end
|
10
|
-
|
11
|
-
def post_request(path, data)
|
12
|
-
@connection.post(
|
13
|
-
path,
|
14
|
-
data
|
15
|
-
).body
|
16
|
-
end
|
17
|
-
|
18
|
-
def put_request(path, data)
|
19
|
-
@connection.put(
|
20
|
-
path,
|
21
|
-
data
|
22
|
-
).body
|
23
|
-
end
|
24
|
-
|
25
|
-
def delete_request(path)
|
26
|
-
@connection.delete(
|
27
|
-
path
|
28
|
-
).body
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
end
|
data/lib/passage/user.rb
DELETED
File without changes
|
data/lib/passage.rb
DELETED
data/passage-ruby
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
passage-ruby
|