passageidentity 0.6.2 → 0.7.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.
Files changed (135) hide show
  1. checksums.yaml +4 -4
  2. data/lib/openapi_client/api/apps_api.rb +2 -2
  3. data/lib/openapi_client/api/magic_links_api.rb +4 -4
  4. data/lib/openapi_client/api/tokens_api.rb +2 -2
  5. data/lib/openapi_client/api/user_devices_api.rb +3 -3
  6. data/lib/openapi_client/api/users_api.rb +8 -8
  7. data/lib/openapi_client/api_client.rb +36 -30
  8. data/lib/openapi_client/api_error.rb +1 -1
  9. data/lib/openapi_client/configuration.rb +11 -1
  10. data/lib/openapi_client/models/app_info.rb +36 -3
  11. data/lib/openapi_client/models/app_response.rb +1 -1
  12. data/lib/openapi_client/models/apple_user_social_connection.rb +1 -1
  13. data/lib/openapi_client/models/auth_methods.rb +1 -1
  14. data/lib/openapi_client/models/create_magic_link_request.rb +2 -57
  15. data/lib/openapi_client/models/create_user_request.rb +1 -1
  16. data/lib/openapi_client/models/element_customization.rb +1 -1
  17. data/lib/openapi_client/models/font_family.rb +1 -1
  18. data/lib/openapi_client/models/github_user_social_connection.rb +1 -1
  19. data/lib/openapi_client/models/google_user_social_connection.rb +1 -1
  20. data/lib/openapi_client/models/layout_config.rb +1 -1
  21. data/lib/openapi_client/models/layouts.rb +1 -1
  22. data/lib/openapi_client/models/link.rb +1 -1
  23. data/lib/openapi_client/models/list_devices_response.rb +1 -1
  24. data/lib/openapi_client/models/list_paginated_users_item.rb +19 -2
  25. data/lib/openapi_client/models/list_paginated_users_response.rb +1 -1
  26. data/lib/openapi_client/models/magic_link.rb +1 -1
  27. data/lib/openapi_client/models/magic_link_auth_method.rb +1 -1
  28. data/lib/openapi_client/models/magic_link_channel.rb +1 -1
  29. data/lib/openapi_client/models/magic_link_response.rb +1 -1
  30. data/lib/openapi_client/models/magic_link_type.rb +1 -1
  31. data/lib/openapi_client/models/model400_error.rb +1 -1
  32. data/lib/openapi_client/models/model401_error.rb +1 -1
  33. data/lib/openapi_client/models/model403_error.rb +1 -1
  34. data/lib/openapi_client/models/model404_error.rb +3 -3
  35. data/lib/openapi_client/models/model500_error.rb +1 -1
  36. data/lib/openapi_client/models/nonce.rb +1 -1
  37. data/lib/openapi_client/models/otp_auth_method.rb +1 -1
  38. data/lib/openapi_client/models/paginated_links.rb +1 -1
  39. data/lib/openapi_client/models/passkeys_auth_method.rb +1 -1
  40. data/lib/openapi_client/models/social_connection_type.rb +41 -0
  41. data/lib/openapi_client/models/technologies.rb +1 -1
  42. data/lib/openapi_client/models/theme_type.rb +41 -0
  43. data/lib/openapi_client/models/ttl_display_unit.rb +1 -1
  44. data/lib/openapi_client/models/update_user_request.rb +1 -1
  45. data/lib/openapi_client/models/user_event_action.rb +41 -0
  46. data/lib/openapi_client/models/user_event_status.rb +1 -1
  47. data/lib/openapi_client/models/user_info.rb +19 -2
  48. data/lib/openapi_client/models/user_metadata_field.rb +1 -1
  49. data/lib/openapi_client/models/user_metadata_field_type.rb +1 -1
  50. data/lib/openapi_client/models/user_recent_event.rb +51 -5
  51. data/lib/openapi_client/models/user_response.rb +1 -1
  52. data/lib/openapi_client/models/user_social_connections.rb +1 -1
  53. data/lib/openapi_client/models/user_status.rb +1 -1
  54. data/lib/openapi_client/models/web_authn_devices.rb +1 -1
  55. data/lib/openapi_client/models/web_authn_icons.rb +1 -1
  56. data/lib/openapi_client/models/web_authn_type.rb +1 -1
  57. data/lib/openapi_client/version.rb +1 -1
  58. data/lib/openapi_client.rb +4 -4
  59. data/lib/passageidentity/auth.rb +205 -104
  60. data/lib/passageidentity/client.rb +71 -59
  61. data/lib/passageidentity/error.rb +42 -16
  62. data/lib/passageidentity/user_api.rb +120 -161
  63. data/lib/passageidentity/version.rb +1 -1
  64. data/lib/passageidentity.rb +6 -2
  65. metadata +33 -79
  66. data/.github/workflows/deploy.yml +0 -30
  67. data/.github/workflows/on-pull-request.yml +0 -33
  68. data/.gitignore +0 -58
  69. data/CHANGELOG.md +0 -57
  70. data/CONTRIBUTING.md +0 -66
  71. data/Gemfile +0 -13
  72. data/LICENSE +0 -21
  73. data/README.md +0 -84
  74. data/docs/custom/AuthApi.md +0 -141
  75. data/docs/custom/ClientApi.md +0 -107
  76. data/docs/custom/UserApi.md +0 -419
  77. data/docs/generated/AppInfo.md +0 -94
  78. data/docs/generated/AppResponse.md +0 -18
  79. data/docs/generated/AppleUserSocialConnection.md +0 -24
  80. data/docs/generated/AppsApi.md +0 -77
  81. data/docs/generated/AuthMethods.md +0 -22
  82. data/docs/generated/CreateMagicLinkRequest.md +0 -36
  83. data/docs/generated/CreateUserRequest.md +0 -22
  84. data/docs/generated/ElementCustomization.md +0 -56
  85. data/docs/generated/FontFamily.md +0 -15
  86. data/docs/generated/GithubUserSocialConnection.md +0 -24
  87. data/docs/generated/GoogleUserSocialConnection.md +0 -24
  88. data/docs/generated/LayoutConfig.md +0 -26
  89. data/docs/generated/Layouts.md +0 -20
  90. data/docs/generated/Link.md +0 -18
  91. data/docs/generated/ListDevicesResponse.md +0 -18
  92. data/docs/generated/ListPaginatedUsersItem.md +0 -38
  93. data/docs/generated/ListPaginatedUsersResponse.md +0 -28
  94. data/docs/generated/MagicLink.md +0 -36
  95. data/docs/generated/MagicLinkAuthMethod.md +0 -22
  96. data/docs/generated/MagicLinkChannel.md +0 -15
  97. data/docs/generated/MagicLinkResponse.md +0 -18
  98. data/docs/generated/MagicLinkType.md +0 -15
  99. data/docs/generated/MagicLinksApi.md +0 -79
  100. data/docs/generated/Model400Error.md +0 -20
  101. data/docs/generated/Model401Error.md +0 -20
  102. data/docs/generated/Model403Error.md +0 -20
  103. data/docs/generated/Model404Error.md +0 -20
  104. data/docs/generated/Model500Error.md +0 -20
  105. data/docs/generated/Nonce.md +0 -18
  106. data/docs/generated/OtpAuthMethod.md +0 -22
  107. data/docs/generated/PaginatedLinks.md +0 -26
  108. data/docs/generated/PasskeysAuthMethod.md +0 -18
  109. data/docs/generated/README.md +0 -158
  110. data/docs/generated/Technologies.md +0 -15
  111. data/docs/generated/TokensApi.md +0 -78
  112. data/docs/generated/TtlDisplayUnit.md +0 -15
  113. data/docs/generated/UpdateUserRequest.md +0 -22
  114. data/docs/generated/UserDevicesApi.md +0 -152
  115. data/docs/generated/UserEventStatus.md +0 -15
  116. data/docs/generated/UserInfo.md +0 -48
  117. data/docs/generated/UserMetadataField.md +0 -28
  118. data/docs/generated/UserMetadataFieldType.md +0 -15
  119. data/docs/generated/UserRecentEvent.md +0 -30
  120. data/docs/generated/UserResponse.md +0 -18
  121. data/docs/generated/UserSocialConnections.md +0 -22
  122. data/docs/generated/UserStatus.md +0 -15
  123. data/docs/generated/UsersApi.md +0 -534
  124. data/docs/generated/WebAuthnDevices.md +0 -34
  125. data/docs/generated/WebAuthnIcons.md +0 -20
  126. data/docs/generated/WebAuthnType.md +0 -15
  127. data/generate.sh +0 -31
  128. data/openapitools.json +0 -7
  129. data/passageidentity.gemspec +0 -32
  130. data/tests/all.rb +0 -3
  131. data/tests/app_test.rb +0 -15
  132. data/tests/auth_test.rb +0 -74
  133. data/tests/errors_test.rb +0 -30
  134. data/tests/magic_link_test.rb +0 -22
  135. data/tests/user_api_test.rb +0 -121
@@ -6,7 +6,7 @@
6
6
  The version of the OpenAPI document: 1
7
7
  Contact: support@passage.id
8
8
  Generated by: https://openapi-generator.tech
9
- OpenAPI Generator version: 7.1.0
9
+ Generator version: 7.11.0-SNAPSHOT
10
10
 
11
11
  =end
12
12
 
@@ -27,8 +27,16 @@ module OpenapiClient
27
27
 
28
28
  attr_accessor :type
29
29
 
30
+ # The raw user agent value from the originating device
30
31
  attr_accessor :user_agent
31
32
 
33
+ # A display-friendly version of the user agent
34
+ attr_accessor :user_agent_display
35
+
36
+ attr_accessor :action
37
+
38
+ attr_accessor :social_login_type
39
+
32
40
  class EnumAttributeValidator
33
41
  attr_reader :datatype
34
42
  attr_reader :allowable_values
@@ -60,7 +68,10 @@ module OpenapiClient
60
68
  :'ip_addr' => :'ip_addr',
61
69
  :'status' => :'status',
62
70
  :'type' => :'type',
63
- :'user_agent' => :'user_agent'
71
+ :'user_agent' => :'user_agent',
72
+ :'user_agent_display' => :'user_agent_display',
73
+ :'action' => :'action',
74
+ :'social_login_type' => :'social_login_type'
64
75
  }
65
76
  end
66
77
 
@@ -78,7 +89,10 @@ module OpenapiClient
78
89
  :'ip_addr' => :'String',
79
90
  :'status' => :'UserEventStatus',
80
91
  :'type' => :'String',
81
- :'user_agent' => :'String'
92
+ :'user_agent' => :'String',
93
+ :'user_agent_display' => :'String',
94
+ :'action' => :'UserEventAction',
95
+ :'social_login_type' => :'SocialConnectionType'
82
96
  }
83
97
  end
84
98
 
@@ -86,6 +100,7 @@ module OpenapiClient
86
100
  def self.openapi_nullable
87
101
  Set.new([
88
102
  :'completed_at',
103
+ :'social_login_type'
89
104
  ])
90
105
  end
91
106
 
@@ -145,6 +160,24 @@ module OpenapiClient
145
160
  else
146
161
  self.user_agent = nil
147
162
  end
163
+
164
+ if attributes.key?(:'user_agent_display')
165
+ self.user_agent_display = attributes[:'user_agent_display']
166
+ else
167
+ self.user_agent_display = nil
168
+ end
169
+
170
+ if attributes.key?(:'action')
171
+ self.action = attributes[:'action']
172
+ else
173
+ self.action = nil
174
+ end
175
+
176
+ if attributes.key?(:'social_login_type')
177
+ self.social_login_type = attributes[:'social_login_type']
178
+ else
179
+ self.social_login_type = nil
180
+ end
148
181
  end
149
182
 
150
183
  # Show invalid properties with the reasons. Usually used together with valid?
@@ -176,6 +209,14 @@ module OpenapiClient
176
209
  invalid_properties.push('invalid value for "user_agent", user_agent cannot be nil.')
177
210
  end
178
211
 
212
+ if @user_agent_display.nil?
213
+ invalid_properties.push('invalid value for "user_agent_display", user_agent_display cannot be nil.')
214
+ end
215
+
216
+ if @action.nil?
217
+ invalid_properties.push('invalid value for "action", action cannot be nil.')
218
+ end
219
+
179
220
  invalid_properties
180
221
  end
181
222
 
@@ -189,6 +230,8 @@ module OpenapiClient
189
230
  return false if @status.nil?
190
231
  return false if @type.nil?
191
232
  return false if @user_agent.nil?
233
+ return false if @user_agent_display.nil?
234
+ return false if @action.nil?
192
235
  true
193
236
  end
194
237
 
@@ -203,7 +246,10 @@ module OpenapiClient
203
246
  ip_addr == o.ip_addr &&
204
247
  status == o.status &&
205
248
  type == o.type &&
206
- user_agent == o.user_agent
249
+ user_agent == o.user_agent &&
250
+ user_agent_display == o.user_agent_display &&
251
+ action == o.action &&
252
+ social_login_type == o.social_login_type
207
253
  end
208
254
 
209
255
  # @see the `==` method
@@ -215,7 +261,7 @@ module OpenapiClient
215
261
  # Calculates hash code according to all attributes.
216
262
  # @return [Integer] Hash code
217
263
  def hash
218
- [created_at, completed_at, id, ip_addr, status, type, user_agent].hash
264
+ [created_at, completed_at, id, ip_addr, status, type, user_agent, user_agent_display, action, social_login_type].hash
219
265
  end
220
266
 
221
267
  # Builds the object from hash
@@ -6,7 +6,7 @@
6
6
  The version of the OpenAPI document: 1
7
7
  Contact: support@passage.id
8
8
  Generated by: https://openapi-generator.tech
9
- OpenAPI Generator version: 7.1.0
9
+ Generator version: 7.11.0-SNAPSHOT
10
10
 
11
11
  =end
12
12
 
@@ -6,7 +6,7 @@
6
6
  The version of the OpenAPI document: 1
7
7
  Contact: support@passage.id
8
8
  Generated by: https://openapi-generator.tech
9
- OpenAPI Generator version: 7.1.0
9
+ Generator version: 7.11.0-SNAPSHOT
10
10
 
11
11
  =end
12
12
 
@@ -6,7 +6,7 @@
6
6
  The version of the OpenAPI document: 1
7
7
  Contact: support@passage.id
8
8
  Generated by: https://openapi-generator.tech
9
- OpenAPI Generator version: 7.1.0
9
+ Generator version: 7.11.0-SNAPSHOT
10
10
 
11
11
  =end
12
12
 
@@ -6,7 +6,7 @@
6
6
  The version of the OpenAPI document: 1
7
7
  Contact: support@passage.id
8
8
  Generated by: https://openapi-generator.tech
9
- OpenAPI Generator version: 7.1.0
9
+ Generator version: 7.11.0-SNAPSHOT
10
10
 
11
11
  =end
12
12
 
@@ -6,7 +6,7 @@
6
6
  The version of the OpenAPI document: 1
7
7
  Contact: support@passage.id
8
8
  Generated by: https://openapi-generator.tech
9
- OpenAPI Generator version: 7.1.0
9
+ Generator version: 7.11.0-SNAPSHOT
10
10
 
11
11
  =end
12
12
 
@@ -6,7 +6,7 @@
6
6
  The version of the OpenAPI document: 1
7
7
  Contact: support@passage.id
8
8
  Generated by: https://openapi-generator.tech
9
- OpenAPI Generator version: 7.1.0
9
+ Generator version: 7.11.0-SNAPSHOT
10
10
 
11
11
  =end
12
12
 
@@ -6,7 +6,7 @@
6
6
  The version of the OpenAPI document: 1
7
7
  Contact: support@passage.id
8
8
  Generated by: https://openapi-generator.tech
9
- OpenAPI Generator version: 7.1.0
9
+ Generator version: 7.11.0-SNAPSHOT
10
10
 
11
11
  =end
12
12
 
@@ -6,7 +6,7 @@
6
6
  The version of the OpenAPI document: 1
7
7
  Contact: support@passage.id
8
8
  Generated by: https://openapi-generator.tech
9
- OpenAPI Generator version: 7.1.0
9
+ Generator version: 7.11.0-SNAPSHOT
10
10
 
11
11
  =end
12
12
 
@@ -47,12 +47,12 @@ require_relative 'openapi_client/models/nonce'
47
47
  require_relative 'openapi_client/models/otp_auth_method'
48
48
  require_relative 'openapi_client/models/paginated_links'
49
49
  require_relative 'openapi_client/models/passkeys_auth_method'
50
+ require_relative 'openapi_client/models/social_connection_type'
50
51
  require_relative 'openapi_client/models/technologies'
52
+ require_relative 'openapi_client/models/theme_type'
51
53
  require_relative 'openapi_client/models/ttl_display_unit'
52
- require_relative 'models/update_magic_link_auth_method'
53
- require_relative 'models/update_otp_auth_method'
54
- require_relative 'models/update_passkeys_auth_method'
55
54
  require_relative 'openapi_client/models/update_user_request'
55
+ require_relative 'openapi_client/models/user_event_action'
56
56
  require_relative 'openapi_client/models/user_event_status'
57
57
  require_relative 'openapi_client/models/user_info'
58
58
  require_relative 'openapi_client/models/user_metadata_field'
@@ -1,43 +1,170 @@
1
- require "openssl"
2
- require "base64"
3
- require "jwt"
4
- require_relative "client"
5
- require_relative "../openapi_client"
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+ require 'jwt'
5
+ require 'rubygems/deprecate'
6
+ require_relative 'client'
7
+ require_relative '../openapi_client'
6
8
 
7
9
  module Passage
10
+ # The Passage::Auth class provides methods for authenticating requests and tokens
8
11
  class Auth
9
- @@app_cache = {}
10
- def initialize(app_id, auth_strategy)
12
+ extend Gem::Deprecate
13
+
14
+ def initialize(app_id, api_key, auth_strategy)
15
+ @app_cache = ActiveSupport::Cache::MemoryStore.new
11
16
  @app_id = app_id
17
+ @api_key = api_key
12
18
  @auth_strategy = auth_strategy
13
19
 
14
20
  fetch_jwks
21
+
22
+ header_params = { 'Passage-Version' => "passage-ruby #{Passage::VERSION}" }
23
+ header_params['Authorization'] = "Bearer #{@api_key}" if @api_key != ''
24
+
25
+ @req_opts = {}
26
+ @req_opts[:header_params] = header_params
27
+ @req_opts[:debug_auth_names] = ['header']
28
+
29
+ @tokens_client = OpenapiClient::TokensApi.new
30
+ @magic_links_client = OpenapiClient::MagicLinksApi.new
15
31
  end
16
32
 
17
- def fetch_app()
18
- begin
19
- client = OpenapiClient::AppsApi.new
20
- response = client.get_app(@app_id)
21
-
22
- return response.app
23
- rescue Faraday::Error => e
33
+ def authenticate_request(request)
34
+ # Get the token based on the strategy
35
+ if @auth_strategy == Passage::COOKIE_STRATEGY
36
+ unless request.cookies.key?('psg_auth_token')
37
+ raise PassageError.new(
38
+ status_code: 401,
39
+ body: {
40
+ error: 'missing authentication token: expected "psg_auth_token" cookie',
41
+ code: 'invalid_access_token'
42
+ }
43
+ )
44
+ end
45
+ @token = request.cookies['psg_auth_token']
46
+ else
47
+ headers = request.headers
48
+ unless headers.key?('Authorization')
49
+ raise PassageError.new(
50
+ status_code: 401,
51
+ body: {
52
+ error: 'no authentication token in header',
53
+ code: 'invalid_access_token'
54
+ }
55
+ )
56
+ end
57
+
58
+ @token = headers['Authorization'].split(' ').last
59
+ end
60
+
61
+ validate_jwt(@token)
62
+ end
63
+
64
+ def validate_jwt(token)
65
+ raise ArgumentError, 'jwt is required.' unless token && !token.empty?
66
+
67
+ unless get_cache(@app_id)
24
68
  raise PassageError.new(
25
- message: "failed to fetch passage app",
26
- status_code: e.response[:status],
27
- body: e.response[:body]
28
- )
69
+ status_code: 401,
70
+ body: {
71
+ error: 'invalid JWKs',
72
+ code: 'invalid_access_token'
73
+ }
74
+ )
29
75
  end
76
+
77
+ audiences = [@auth_origin, @app_id]
78
+
79
+ claims =
80
+ JWT.decode(
81
+ token,
82
+ nil,
83
+ true,
84
+ {
85
+ aud: audiences,
86
+ verify_aud: true,
87
+ algorithms: ['RS256'],
88
+ jwks: @jwks
89
+ }
90
+ )
91
+
92
+ claims[0]['sub']
93
+ rescue JWT::InvalidIssuerError, JWT::InvalidAudError, JWT::ExpiredSignature, JWT::IncorrectAlgorithm,
94
+ JWT::DecodeError => e
95
+ raise PassageError.new(
96
+ status_code: 401,
97
+ body: {
98
+ error: e.message,
99
+ code: 'invalid_access_token'
100
+ }
101
+ )
30
102
  end
31
103
 
32
- def fetch_jwks()
33
- if @@app_cache[@app_id]
34
- @jwks, @auth_origin = @@app_cache[@app_id]
104
+ def revoke_user_refresh_tokens(user_id)
105
+ warn 'NOTE: Passage::Auth#revoke_user_refresh_tokens is deprecated;
106
+ use Passage::User#revoke_refresh_tokens instead. It will be removed on or after 2024-12.'
107
+ user_exists?(user_id)
108
+
109
+ @tokens_client.revoke_user_refresh_tokens(@app_id, user_id, @req_opts)
110
+ rescue Faraday::Error => e
111
+ raise PassageError.new(
112
+ status_code: e.response[:status],
113
+ body: e.response[:body]
114
+ )
115
+ end
116
+
117
+ def create_magic_link_with_email(email, type, send, opts = {})
118
+ args = {}
119
+ args['email'] = email
120
+ args['channel'] = EMAIL_CHANNEL
121
+ args['type'] = type
122
+ args['send'] = send
123
+
124
+ create_magic_link(args, opts)
125
+ end
126
+
127
+ def create_magic_link_with_phone(phone, type, send, opts = {})
128
+ args = {}
129
+ args['phone'] = phone
130
+ args['channel'] = PHONE_CHANNEL
131
+ args['type'] = type
132
+ args['send'] = send
133
+
134
+ create_magic_link(args, opts)
135
+ end
136
+
137
+ def create_magic_link_with_user(user_id, channel, type, send, opts = {})
138
+ args = {}
139
+ args['user_id'] = user_id
140
+ args['channel'] = channel
141
+ args['type'] = type
142
+ args['send'] = send
143
+
144
+ create_magic_link(args, opts)
145
+ end
146
+
147
+ def fetch_app
148
+ client = OpenapiClient::AppsApi.new
149
+ response = client.get_app(@app_id)
150
+
151
+ response.app
152
+ rescue Faraday::Error => e
153
+ raise PassageError.new(
154
+ status_code: e.response[:status],
155
+ body: e.response[:body]
156
+ )
157
+ end
158
+
159
+ def fetch_jwks
160
+ app_cache = get_cache(@app_id)
161
+
162
+ if app_cache
163
+ @jwks, @auth_origin = app_cache
35
164
  else
36
- app = fetch_app
37
165
  auth_gw_connection =
38
- Faraday.new(url: "https://auth.passage.id") do |f|
166
+ Faraday.new(url: 'https://auth.passage.id') do |f|
39
167
  f.request :json
40
- f.request :retry
41
168
  f.response :raise_error
42
169
  f.response :json
43
170
  f.adapter :net_http
@@ -49,97 +176,71 @@ module Passage
49
176
  @auth_origin = app.auth_origin
50
177
  response =
51
178
  auth_gw_connection.get("/v1/apps/#{@app_id}/.well-known/jwks.json")
52
- @jwks = response.body
53
- @@app_cache[@app_id] ||= [@jwks, @auth_origin]
179
+
180
+ if response.success?
181
+ @jwks = response.body
182
+ set_cache(key: @app_id, jwks: @jwks)
183
+ end
54
184
  end
55
185
  end
56
186
 
57
- def authenticate_request(request)
58
- warn "[DEPRECATION] `auth.authenticate_request()` is deprecated. Please use `auth.validate_jwt()` instead."
187
+ def authenticate_token(token)
188
+ validate_jwt(token)
189
+ end
59
190
 
60
- # Get the token based on the strategy
61
- if @auth_strategy === Passage::COOKIE_STRATEGY
62
- unless request.cookies.key?("psg_auth_token")
63
- raise PassageError.new(
64
- message:
65
- "missing authentication token: expected \"psg_auth_token\" cookie"
66
- )
67
- end
68
- @token = request.cookies["psg_auth_token"]
69
- else
70
- headers = request.headers
71
- unless headers.key?("Authorization")
72
- raise PassageError.new(message: "no authentication token in header")
73
- end
74
- @token = headers["Authorization"].split(" ").last
75
- end
191
+ private
76
192
 
77
- # authenticate the token
78
- if @token
79
- return authenticate_token(@token)
80
- else
81
- raise PassageError.new(message: "no authentication token")
82
- end
83
- nil
193
+ def create_magic_link(args, opts)
194
+ args['language'] = opts['language']
195
+ args['magic_link_path'] = opts['magic_link_path']
196
+ args['redirect_url'] = opts['redirect_url']
197
+ args['ttl'] = opts['ttl']
198
+
199
+ handle_magic_link_creation(args)
84
200
  end
85
201
 
86
- def validate_jwt(token)
87
- if token
88
- return authenticate_token(token)
89
- else
90
- raise PassageError.new(message: "no authentication token")
91
- end
202
+ def handle_magic_link_creation(args)
203
+ @magic_links_client.create_magic_link(@app_id, args, @req_opts).magic_link
204
+ rescue Faraday::Error => e
205
+ raise PassageError.new(
206
+ status_code: e.response[:status],
207
+ body: e.response[:body]
208
+ )
209
+ rescue OpenapiClient::ApiError => e
210
+ raise PassageError.new(
211
+ status_code: e.code,
212
+ body: try_parse_json_string(e.response_body)
213
+ )
92
214
  end
93
215
 
94
- def authenticate_token(token)
95
- begin
96
- kid = JWT.decode(token, nil, false)[1]["kid"]
97
- exists = false
98
- for jwk in @jwks["keys"]
99
- if jwk["kid"] == kid
100
- exists = true
101
- break
102
- end
103
- end
104
- fetch_jwks unless exists
105
- claims =
106
- JWT.decode(
107
- token,
108
- nil,
109
- true,
110
- {
111
- aud: @auth_origin,
112
- verify_aud: true,
113
- algorithms: ["RS256"],
114
- jwks: @jwks
115
- }
116
- )
117
- return claims[0]["sub"]
118
- rescue JWT::InvalidIssuerError => e
119
- raise PassageError.new(message: e.message)
120
- rescue JWT::InvalidAudError => e
121
- raise PassageError.new(message: e.message)
122
- rescue JWT::ExpiredSignature => e
123
- raise PassageError.new(message: e.message)
124
- rescue JWT::IncorrectAlgorithm => e
125
- raise PassageError.new(message: e.message)
126
- rescue JWT::DecodeError => e
127
- raise PassageError.new(message: e.message)
128
- end
216
+ def try_parse_json_string(string)
217
+ JSON.parse(string)
218
+ rescue JSON::ParserError
219
+ string
129
220
  end
130
221
 
131
- def revoke_user_refresh_tokens(user_id)
132
- begin
133
- client = OpenapiClient::TokensApi.new
134
- response = client.revoke_user_refresh_tokens(@app_id, user_id)
135
- return true
136
- rescue Faraday::Error => e
137
- raise PassageError.new(
138
- message: "failed to revoke user's refresh tokens",
139
- status_code: e.response[:status],
140
- body: e.response[:body]
141
- )
142
- end
222
+ def user_exists?(user_id)
223
+ return unless user_id.to_s.empty?
224
+
225
+ raise PassageError.new(
226
+ status_code: 400,
227
+ body: {
228
+ error: 'Must supply a valid user_id',
229
+ code: 'invalid_request'
230
+ }
231
+ )
232
+ end
233
+
234
+ def get_cache(key)
235
+ @app_cache.read(key)
236
+ end
237
+
238
+ def set_cache(key:, jwks:)
239
+ @app_cache.write(key, jwks, expires_in: 86_400)
143
240
  end
241
+ deprecate(:authenticate_request, :validate_jwt, 2025, 1)
242
+ deprecate(:authenticate_token, :validate_jwt, 2025, 1)
243
+ deprecate(:fetch_app, :none, 2025, 1)
244
+ deprecate(:fetch_jwks, :none, 2025, 1)
144
245
  end
145
246
  end