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
@@ -1,101 +1,113 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "auth"
4
- require_relative "user_api"
5
- require_relative "error"
6
- require_relative "version"
7
- require "rubygems"
8
- require_relative "../openapi_client"
3
+ require 'rubygems'
4
+ require_relative 'auth'
5
+ require_relative 'user_api'
6
+ require_relative 'error'
7
+ require_relative 'version'
8
+ require_relative '../openapi_client'
9
9
 
10
10
  module Passage
11
11
  COOKIE_STRATEGY = 0
12
12
  HEADER_STRATEGY = 1
13
13
 
14
- EMAIL_CHANNEL = "email"
15
- PHONE_CHANNEL = "phone"
14
+ EMAIL_CHANNEL = 'email'
15
+ PHONE_CHANNEL = 'phone'
16
16
 
17
+ # The Passage::Client class provides methods for interacting with Passage
17
18
  class Client
18
- attr_reader :auth
19
- attr_reader :user
19
+ attr_reader :auth, :user
20
20
 
21
- def initialize(app_id:, api_key: "", auth_strategy: COOKIE_STRATEGY)
21
+ extend Gem::Deprecate
22
+
23
+ def initialize(app_id:, api_key: '', auth_strategy: COOKIE_STRATEGY)
22
24
  @app_id = app_id
23
25
  @api_key = api_key
24
26
 
25
27
  # check for valid auth strategy
26
28
  unless [COOKIE_STRATEGY, HEADER_STRATEGY].include? auth_strategy
27
- raise PassageError.new(message: "invalid auth strategy.")
29
+ raise PassageError.new(
30
+ status_code: 400,
31
+ body: {
32
+ error: 'Invalid auth strategy',
33
+ code: 'invalid_argument'
34
+ }
35
+ )
28
36
  end
37
+
29
38
  @auth_strategy = auth_strategy
30
39
 
40
+ header_params = { 'Passage-Version' => "passage-ruby #{Passage::VERSION}" }
41
+ header_params['Authorization'] = "Bearer #{@api_key}" if @api_key != ''
42
+
43
+ @req_opts = {}
44
+ @req_opts[:header_params] = header_params
45
+ @req_opts[:debug_auth_names] = ['header']
46
+
31
47
  # initialize auth class
32
- @auth = Passage::Auth.new(@app_id, @auth_strategy)
48
+ @auth = Passage::Auth.new(@app_id, @api_key, @auth_strategy)
33
49
 
34
50
  # initialize user class
35
51
  @user = Passage::UserAPI.new(@app_id, @api_key)
52
+
53
+ @magic_links_client = OpenapiClient::MagicLinksApi.new
36
54
  end
37
55
 
38
- def get_app()
39
- begin
40
- client = OpenapiClient::AppsApi.new
41
- return client.get_app(@app_id).app
42
- rescue => e
43
- raise e
44
- end
56
+ # rubocop:disable Naming/AccessorMethodName
57
+ def get_app
58
+ client = OpenapiClient::AppsApi.new
59
+ client.get_app(@app_id).app
60
+ rescue StandardError => e
61
+ raise e
45
62
  end
63
+ # rubocop:enable Naming/AccessorMethodName
46
64
 
65
+ # rubocop:disable Metrics/ParameterLists, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
47
66
  def create_magic_link(
48
- user_id: "",
49
- email: "",
50
- phone: "",
51
- channel: "",
67
+ user_id: '',
68
+ email: '',
69
+ phone: '',
70
+ channel: '',
52
71
  send: false,
53
- magic_link_path: "",
54
- redirect_url: "",
55
- language: "",
72
+ magic_link_path: '',
73
+ redirect_url: '',
74
+ language: '',
56
75
  ttl: 60,
57
- type: "login"
76
+ type: 'login'
58
77
  )
59
- magic_link_req = {}
60
- magic_link_req["user_id"] = user_id unless user_id.empty?
61
- magic_link_req["email"] = email unless email.empty?
62
- magic_link_req["phone"] = phone unless phone.empty?
78
+ args = {}
79
+ args['user_id'] = user_id unless user_id.empty?
80
+ args['email'] = email unless email.empty?
81
+ args['phone'] = phone unless phone.empty?
63
82
 
64
- # check to see if the channel specified is valid before sending it off to the server
65
83
  unless [PHONE_CHANNEL, EMAIL_CHANNEL].include? channel
66
84
  raise PassageError.new(
67
- message:
68
- "channel: must be either Passage::EMAIL_CHANNEL or Passage::PHONE_CHANNEL"
69
- )
85
+ message:
86
+ 'channel: must be either Passage::EMAIL_CHANNEL or Passage::PHONE_CHANNEL'
87
+ )
70
88
  end
71
- magic_link_req["channel"] = channel unless channel.empty?
72
- magic_link_req["send"] = send
73
- magic_link_req[
74
- "magic_link_path"
75
- ] = magic_link_path unless magic_link_path.empty?
76
- magic_link_req["redirect_url"] = redirect_url unless redirect_url.empty?
77
- magic_link_req["ttl"] = ttl unless ttl == 0
78
- magic_link_req["type"] = type
89
+
90
+ args['channel'] = channel unless channel.empty?
91
+ args['type'] = type
92
+ args['send'] = send
93
+
94
+ args['language'] = language unless language.empty?
95
+ args['magic_link_path'] = magic_link_path unless magic_link_path.empty?
96
+ args['redirect_url'] = redirect_url unless redirect_url.empty?
97
+ args['ttl'] = ttl unless ttl.zero?
79
98
 
80
99
  begin
81
- gemspec = File.join(__dir__, "../../passageidentity.gemspec")
82
- spec = Gem::Specification.load(gemspec)
83
- header_params = { "Passage-Version" => "passage-ruby #{Passage::VERSION}" }
84
- header_params["Authorization"] = "Bearer #{@api_key}" if @api_key != ""
85
-
86
- opts = {}
87
- opts[:header_params] = header_params
88
- opts[:debug_auth_names] = ["header"]
89
-
90
- client = OpenapiClient::MagicLinksApi.new
91
- return client.create_magic_link(@app_id, magic_link_req, opts).magic_link
100
+ @magic_links_client.create_magic_link(@app_id, args, @req_opts).magic_link
92
101
  rescue Faraday::Error => e
93
102
  raise PassageError.new(
94
- message: "failed to create Passage Magic Link",
95
- status_code: e.response[:status],
96
- body: e.response[:body]
97
- )
103
+ status_code: e.response[:status],
104
+ body: e.response[:body]
105
+ )
98
106
  end
99
107
  end
108
+ # rubocop:enable Metrics/ParameterLists, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
109
+
110
+ deprecate(:create_magic_link, 'Passage::Auth.create_magic_link', 2025, 1)
111
+ deprecate(:get_app, :none, 2025, 1)
100
112
  end
101
113
  end
@@ -1,24 +1,50 @@
1
- require "net/http"
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
2
4
 
3
5
  module Passage
6
+ # PassageError is a custom error class for handling errors
4
7
  class PassageError < StandardError
5
- attr_reader :status_code
6
- attr_reader :status_text
7
- attr_reader :message
8
- attr_reader :error
8
+ attr_reader :status_code, :error_code, :message, :status_text, :error
9
+
10
+ def initialize(message: nil, status_code: nil, body: {})
11
+ # Ensure body is a hash
12
+ body = {} if body.nil?
9
13
 
10
- def initialize(message:, status_code: nil, body: nil)
11
- @message = message
14
+ body = symbolize_keys(body)
12
15
  @status_code = status_code
13
- @status_text =
14
- (
15
- if status_code.nil?
16
- nil
17
- else
18
- Net::HTTPResponse::CODE_TO_OBJ[status_code.to_s]
19
- end
20
- )
21
- @error = body.nil? ? nil : body["error"]
16
+ @error_code = body[:code]
17
+ # Message precedence: explicit message > body error > default message
18
+ @message = determine_message(message, body)
19
+ # Determine status text from status code if available
20
+ @status_text = determine_status_text(status_code)
21
+ # Set error field based on message
22
+ @error = @message
23
+
24
+ super(@message)
25
+ end
26
+
27
+ private
28
+
29
+ def determine_message(message, body)
30
+ return message if message
31
+
32
+ return body[:error] if body[:error]
33
+
34
+ 'Unknown error occurred'
35
+ end
36
+
37
+ def determine_status_text(code)
38
+ return nil if code.nil?
39
+
40
+ status_code_str = code.to_s
41
+ Net::HTTPResponse::CODE_TO_OBJ[status_code_str]
42
+ rescue StandardError
43
+ nil
44
+ end
45
+
46
+ def symbolize_keys(hash)
47
+ hash.transform_keys(&:to_sym)
22
48
  end
23
49
  end
24
50
  end
@@ -1,7 +1,14 @@
1
- require_relative "client"
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubygems/deprecate'
4
+ require_relative 'client'
2
5
 
3
6
  module Passage
7
+ # The UserAPI class provides methods for interacting with Passage Users
4
8
  class UserAPI
9
+ extend Gem::Deprecate
10
+
11
+ # rubocop:disable Metrics/AbcSize
5
12
  # This class will require an API key
6
13
  def initialize(app_id, api_key)
7
14
  @app_id = app_id
@@ -9,41 +16,30 @@ module Passage
9
16
  @user_client = OpenapiClient::UsersApi.new
10
17
  @user_device_client = OpenapiClient::UserDevicesApi.new
11
18
 
12
- header_params = { "Passage-Version" => "passage-ruby #{Passage::VERSION}"}
13
- header_params["Authorization"] = "Bearer #{@api_key}" if @api_key != ""
14
-
19
+ header_params = { 'Passage-Version' => "passage-ruby #{Passage::VERSION}" }
20
+ header_params['Authorization'] = "Bearer #{@api_key}" if @api_key != ''
21
+
15
22
  @req_opts = {}
16
23
  @req_opts[:header_params] = header_params
17
- @req_opts[:debug_auth_names] = ["header"]
18
-
24
+ @req_opts[:debug_auth_names] = ['header']
19
25
  end
20
26
 
21
27
  def get(user_id:)
22
- user_exists?(user_id)
28
+ raise ArgumentError, 'user_id is required.' unless user_id && !user_id.empty?
23
29
 
24
30
  begin
25
31
  response = @user_client.get_user(@app_id, user_id, @req_opts)
26
- user = response.user
27
- return user
32
+ response.user
28
33
  rescue Faraday::Error => e
29
- if e.is_a? Faraday::ResourceNotFound
30
- raise PassageError.new(
31
- message: "Passage User with ID \"#{user_id}\" does not exist",
32
- status_code: e.response[:status],
33
- body: e.response[:body]
34
- )
35
- else
36
- raise PassageError.new(
37
- message: "failed to get Passage User.",
38
- status_code: e.response[:status],
39
- body: e.response[:body]
40
- )
41
- end
34
+ raise PassageError.new(
35
+ status_code: e.response[:status],
36
+ body: e.response[:body]
37
+ )
42
38
  end
43
39
  end
44
40
 
45
41
  def get_by_identifier(user_identifier:)
46
- identifier_exists?(user_identifier)
42
+ raise ArgumentError, 'identifier is required.' unless user_identifier && !user_identifier.empty?
47
43
 
48
44
  begin
49
45
  @req_opts[:limit] = 1
@@ -51,209 +47,172 @@ module Passage
51
47
  response = @user_client.list_paginated_users(@app_id, @req_opts)
52
48
  users = response.users
53
49
 
54
- if users.length() == 0
50
+ if users.empty?
55
51
  raise PassageError.new(
56
- message: "Passage User with identifer \"#{user_identifier}\" does not exist",
57
- status_code: 404,
58
- body: "user_not_found"
59
- )
52
+ status_code: 404,
53
+ body: {
54
+ error: 'User not found.',
55
+ code: 'user_not_found'
56
+ }
57
+ )
60
58
  end
61
- return get(user_id: users.first().id)
59
+ get(user_id: users.first.id)
62
60
  rescue Faraday::Error => e
63
- if e.is_a? Faraday::ResourceNotFound
64
- raise PassageError.new(
65
- message: "Passage User with identifer \"#{user_identifier}\" does not exist",
66
- status_code: e.response[:status],
67
- body: e.response[:body]
68
- )
69
- else
70
- raise PassageError.new(
71
- message: "failed to get Passage User.",
72
- status_code: e.response[:status],
73
- body: e.response[:body]
74
- )
75
- end
61
+ raise PassageError.new(
62
+ status_code: e.response[:status],
63
+ body: e.response[:body]
64
+ )
76
65
  end
77
66
  end
78
67
 
79
68
  def activate(user_id:)
80
- user_exists?(user_id)
69
+ raise ArgumentError, 'user_id is required.' unless user_id && !user_id.empty?
81
70
 
82
71
  begin
83
72
  response = @user_client.activate_user(@app_id, user_id, @req_opts)
84
- return response.user
73
+ response.user
85
74
  rescue Faraday::Error => e
86
- if e.is_a? Faraday::ResourceNotFound
87
- raise PassageError.new(
88
- message: "Passage User with ID \"#{user_id}\" does not exist",
89
- status_code: e.response[:status],
90
- body: e.response[:body]
91
- )
92
- else
93
- raise PassageError.new(
94
- message: "failed to activate Passage User.",
95
- status_code: e.response[:status],
96
- body: e.response[:body]
97
- )
98
- end
75
+ raise PassageError.new(
76
+ status_code: e.response[:status],
77
+ body: e.response[:body]
78
+ )
99
79
  end
100
80
  end
101
81
 
102
82
  def deactivate(user_id:)
103
- user_exists?(user_id)
83
+ raise ArgumentError, 'user_id is required.' unless user_id && !user_id.empty?
104
84
 
105
85
  begin
106
86
  response = @user_client.deactivate_user(@app_id, user_id, @req_opts)
107
- return response.user
87
+ response.user
108
88
  rescue Faraday::Error => e
109
- if e.is_a? Faraday::ResourceNotFound
110
- raise PassageError.new(
111
- message: "Passage User with ID \"#{user_id}\" does not exist",
112
- status_code: e.response[:status],
113
- body: e.response[:body]
114
- )
115
- else
116
- raise PassageError.new(
117
- message: "failed to deactivate Passage User.",
118
- status_code: e.response[:status],
119
- body: e.response[:body]
120
- )
121
- end
89
+ raise PassageError.new(
90
+ status_code: e.response[:status],
91
+ body: e.response[:body]
92
+ )
122
93
  end
123
94
  end
124
95
 
125
- def update(user_id:, email: "", phone: "", user_metadata: {})
126
- user_exists?(user_id)
96
+ def update(user_id:, email: '', phone: '', user_metadata: {})
97
+ warn '[DEPRECATED] the `update` method parameters will change to `user_id: string, ' \
98
+ 'options: UpdateUserArgs`. Parameters will change on or after 2025-1.'
127
99
 
128
100
  updates = {}
129
- updates["email"] = email unless email.empty?
130
- updates["phone"] = phone unless phone.empty?
131
- updates["user_metadata"] = user_metadata unless user_metadata.empty?
132
- begin
133
- response = @user_client.update_user(@app_id, user_id, updates, @req_opts)
134
- return response.user
135
- rescue Faraday::Error => e
136
- if e.is_a? Faraday::ResourceNotFound
137
- raise PassageError.new(
138
- message: "Passage User with ID \"#{user_id}\" does not exist",
139
- status_code: e.response[:status],
140
- body: e.response[:body]
141
- )
142
- else
143
- raise PassageError.new(
144
- "failed to update Passage User",
145
- status_code: e.response[:status],
146
- body: e.response[:body]
147
- )
148
- end
149
- end
101
+ updates['email'] = email unless email.empty?
102
+ updates['phone'] = phone unless phone.empty?
103
+ updates['user_metadata'] = user_metadata unless user_metadata.empty?
104
+
105
+ update_v2(user_id: user_id, options: updates)
150
106
  end
151
107
 
152
- def create(email: "", phone: "", user_metadata: {})
108
+ def create(email: '', phone: '', user_metadata: {})
109
+ warn '[DEPRECATED] the `create` method parameters will change to `args: CreateUserArgs`.' \
110
+ 'Parameters will change on or after 2025-1.'
111
+
153
112
  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
- begin
158
- response = @user_client.create_user(@app_id, create, @req_opts)
159
- return response.user
160
- rescue Faraday::Error => e
161
- raise PassageError.new(
162
- "failed to create Passage User",
163
- status_code: e.response[:status],
164
- body: e.response[:body]
165
- )
166
- end
113
+ create['email'] = email unless email.empty?
114
+ create['phone'] = phone unless phone.empty?
115
+ create['user_metadata'] = user_metadata unless user_metadata.empty?
116
+
117
+ create_v2(args: create)
167
118
  end
168
119
 
169
120
  def delete(user_id:)
170
- user_exists?(user_id)
121
+ raise ArgumentError, 'user_id is required.' unless user_id && !user_id.empty?
171
122
 
172
123
  begin
173
- response = @user_client.delete_user(@app_id, user_id, @req_opts)
174
- return true
124
+ @user_client.delete_user(@app_id, user_id, @req_opts)
125
+ true
175
126
  rescue Faraday::Error => e
176
- if e.is_a? Faraday::ResourceNotFound
177
- raise PassageError.new(
178
- "passage User with ID \"#{user_id}\" does not exist",
179
- status_code: e.response[:status],
180
- body: e.response[:body]
181
- )
182
- else
183
- raise PassageError.new(
184
- "failed to delete Passage User",
185
- status_code: e.response[:status],
186
- body: e.response[:body]
187
- )
188
- end
127
+ raise PassageError.new(
128
+ 'failed to delete Passage User',
129
+ status_code: e.response[:status],
130
+ body: e.response[:body]
131
+ )
189
132
  end
190
133
  end
191
134
 
192
- def delete_device(user_id:, device_id:)
193
- user_exists?(user_id)
194
- device_exists?(device_id)
135
+ def revoke_device(user_id:, device_id:)
136
+ raise ArgumentError, 'user_id is required.' unless user_id && !user_id.empty?
137
+ raise ArgumentError, 'device_id is required.' unless device_id && !device_id.empty?
195
138
 
196
139
  begin
197
- response = @user_device_client.delete_user_devices(@app_id, user_id, device_id, @req_opts)
198
- return true
140
+ @user_device_client.delete_user_devices(@app_id, user_id, device_id, @req_opts)
199
141
  rescue Faraday::Error => e
200
142
  raise PassageError.new(
201
- "failed to delete Passage User Device",
202
- status_code: e.response[:status],
203
- body: e.response[:body]
204
- )
143
+ status_code: e.response[:status],
144
+ body: e.response[:body]
145
+ )
205
146
  end
206
147
  end
207
148
 
149
+ def delete_device(user_id:, device_id:)
150
+ revoke_device(user_id: user_id, device_id: device_id)
151
+ true
152
+ end
153
+
208
154
  def list_devices(user_id:)
209
- user_exists?(user_id)
155
+ raise ArgumentError, 'user_id is required.' unless user_id && !user_id.empty?
210
156
 
211
157
  begin
212
158
  response = @user_device_client.list_user_devices(@app_id, user_id, @req_opts)
213
- return response.devices
159
+ response.devices
214
160
  rescue Faraday::Error => e
215
161
  raise PassageError.new(
216
- "failed to delete Passage User Device",
217
- status_code: e.response[:status],
218
- body: e.response[:body]
219
- )
162
+ status_code: e.response[:status],
163
+ body: e.response[:body]
164
+ )
220
165
  end
221
166
  end
222
167
 
223
168
  def signout(user_id:)
224
- warn "[DEPRECATION] `user.signout()` is deprecated. Please use `auth.revoke_user_refresh_tokens()` instead."
225
- user_exists?(user_id)
169
+ revoke_refresh_tokens(user_id: user_id)
170
+ true
171
+ end
172
+
173
+ def revoke_refresh_tokens(user_id:)
174
+ raise ArgumentError, 'user_id is required.' unless user_id && !user_id.empty?
175
+
226
176
  begin
227
177
  tokens_client = OpenapiClient::TokensApi.new
228
- response = tokens_client.revoke_user_refresh_tokens(@app_id, user_id, @req_opts)
229
- return true
178
+ tokens_client.revoke_user_refresh_tokens(@app_id, user_id, @req_opts)
230
179
  rescue Faraday::Error => e
231
180
  raise PassageError.new(
232
- "failed to revoke user's refresh tokens",
233
- status_code: e.response[:status],
234
- body: e.response[:body]
235
- )
181
+ status_code: e.response[:status],
182
+ body: e.response[:body]
183
+ )
236
184
  end
237
185
  end
238
186
 
239
187
  private
240
188
 
241
- def user_exists?(user_id)
242
- if user_id.to_s.empty?
243
- raise PassageError.new(message: "must supply a valid user_id")
244
- end
245
- end
189
+ def create_v2(args: {})
190
+ raise ArgumentError, 'At least one of args.email or args.phone is required.' unless args['phone'] || args['email']
246
191
 
247
- def identifier_exists?(identifier)
248
- if identifier.to_s.empty?
249
- raise PassageError.new(message: "must supply a valid identifier")
250
- end
192
+ response = @user_client.create_user(@app_id, args, @req_opts)
193
+ response.user
194
+ rescue Faraday::Error => e
195
+ raise PassageError.new(
196
+ status_code: e.response[:status],
197
+ body: e.response[:body]
198
+ )
251
199
  end
252
200
 
253
- def device_exists?(device_id)
254
- if device_id.to_s.empty?
255
- raise PassageError.new(message: "must supply a valid device_id")
256
- end
201
+ def update_v2(user_id:, options: {})
202
+ raise ArgumentError, 'user_id is required.' unless user_id && !user_id.empty?
203
+ raise ArgumentError, 'options are required.' if options.empty?
204
+
205
+ response = @user_client.update_user(@app_id, user_id, options, @req_opts)
206
+ response.user
207
+ rescue Faraday::Error => e
208
+ raise PassageError.new(
209
+ status_code: e.response[:status],
210
+ body: e.response[:body]
211
+ )
257
212
  end
213
+ # rubocop:enable Metrics/AbcSize
214
+
215
+ deprecate(:signout, :revoke_refresh_tokens, 2025, 1)
216
+ deprecate(:delete_device, :revoke_device, 2025, 1)
258
217
  end
259
218
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Passage
4
- VERSION = '0.6.2'
4
+ VERSION = '0.7.0'
5
5
  end
@@ -1,8 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "faraday"
3
+ require 'bundler/setup'
4
4
 
5
- require_relative "passageidentity/client"
5
+ require 'faraday'
6
6
 
7
+ require_relative 'passageidentity/client'
8
+
9
+ # This file defines the Passage module and requires necessary dependencies.
10
+ # The Passage module serves as a namespace for the Passage Identity functionality.
7
11
  module Passage
8
12
  end