descope 1.0.4

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 (197) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yaml +54 -0
  3. data/.gitignore +59 -0
  4. data/.release-please-manifest.json +3 -0
  5. data/.rubocop.yml +10 -0
  6. data/.rubocop_todo.yml +10 -0
  7. data/.ruby-version +1 -0
  8. data/CHANGELOG.md +90 -0
  9. data/Gemfile +22 -0
  10. data/Gemfile.lock +204 -0
  11. data/LICENSE +21 -0
  12. data/README.md +1171 -0
  13. data/Rakefile +31 -0
  14. data/descope.gemspec +34 -0
  15. data/examples/ruby/Gemfile +4 -0
  16. data/examples/ruby/Gemfile.lock +41 -0
  17. data/examples/ruby/access_key_app.rb +45 -0
  18. data/examples/ruby/enchantedlink_app.rb +65 -0
  19. data/examples/ruby/magiclink_app.rb +81 -0
  20. data/examples/ruby/management/Gemfile +5 -0
  21. data/examples/ruby/management/Gemfile.lock +38 -0
  22. data/examples/ruby/management/access_key_app.rb +71 -0
  23. data/examples/ruby/management/audit_app.rb +25 -0
  24. data/examples/ruby/management/authz_app.rb +135 -0
  25. data/examples/ruby/management/authz_files.json +229 -0
  26. data/examples/ruby/management/flow_app.rb +57 -0
  27. data/examples/ruby/management/permission_app.rb +56 -0
  28. data/examples/ruby/management/role_app.rb +58 -0
  29. data/examples/ruby/management/tenant_app.rb +60 -0
  30. data/examples/ruby/management/user_app.rb +60 -0
  31. data/examples/ruby/oauth_app.rb +39 -0
  32. data/examples/ruby/otp_app.rb +50 -0
  33. data/examples/ruby/password_app.rb +76 -0
  34. data/examples/ruby/saml_app.rb +38 -0
  35. data/examples/ruby-on-rails-api/descope/.dockerignore +37 -0
  36. data/examples/ruby-on-rails-api/descope/.gitattributes +9 -0
  37. data/examples/ruby-on-rails-api/descope/.gitignore +40 -0
  38. data/examples/ruby-on-rails-api/descope/.node-version +1 -0
  39. data/examples/ruby-on-rails-api/descope/.ruby-version +1 -0
  40. data/examples/ruby-on-rails-api/descope/Dockerfile +75 -0
  41. data/examples/ruby-on-rails-api/descope/Gemfile +67 -0
  42. data/examples/ruby-on-rails-api/descope/Gemfile.lock +284 -0
  43. data/examples/ruby-on-rails-api/descope/Procfile.dev +3 -0
  44. data/examples/ruby-on-rails-api/descope/README.md +54 -0
  45. data/examples/ruby-on-rails-api/descope/Rakefile +6 -0
  46. data/examples/ruby-on-rails-api/descope/app/assets/builds/.keep +0 -0
  47. data/examples/ruby-on-rails-api/descope/app/assets/config/manifest.js +3 -0
  48. data/examples/ruby-on-rails-api/descope/app/assets/images/.keep +0 -0
  49. data/examples/ruby-on-rails-api/descope/app/assets/images/descope.jpeg +0 -0
  50. data/examples/ruby-on-rails-api/descope/app/assets/images/favicon.ico +0 -0
  51. data/examples/ruby-on-rails-api/descope/app/assets/images/logo192.png +0 -0
  52. data/examples/ruby-on-rails-api/descope/app/assets/images/logo512.png +0 -0
  53. data/examples/ruby-on-rails-api/descope/app/assets/stylesheets/application.bootstrap.scss +67 -0
  54. data/examples/ruby-on-rails-api/descope/app/channels/application_cable/channel.rb +4 -0
  55. data/examples/ruby-on-rails-api/descope/app/channels/application_cable/connection.rb +4 -0
  56. data/examples/ruby-on-rails-api/descope/app/controllers/application_controller.rb +2 -0
  57. data/examples/ruby-on-rails-api/descope/app/controllers/concerns/.keep +0 -0
  58. data/examples/ruby-on-rails-api/descope/app/controllers/homepage_controller.rb +4 -0
  59. data/examples/ruby-on-rails-api/descope/app/controllers/session_controller.rb +66 -0
  60. data/examples/ruby-on-rails-api/descope/app/helpers/application_helper.rb +2 -0
  61. data/examples/ruby-on-rails-api/descope/app/helpers/homepage_helper.rb +2 -0
  62. data/examples/ruby-on-rails-api/descope/app/helpers/session_helper.rb +2 -0
  63. data/examples/ruby-on-rails-api/descope/app/javascript/App.css +53 -0
  64. data/examples/ruby-on-rails-api/descope/app/javascript/application.js +5 -0
  65. data/examples/ruby-on-rails-api/descope/app/javascript/components/App.jsx +4 -0
  66. data/examples/ruby-on-rails-api/descope/app/javascript/components/Dashboard.jsx +60 -0
  67. data/examples/ruby-on-rails-api/descope/app/javascript/components/Home.jsx +27 -0
  68. data/examples/ruby-on-rails-api/descope/app/javascript/components/Login.jsx +45 -0
  69. data/examples/ruby-on-rails-api/descope/app/javascript/components/Profile.jsx +81 -0
  70. data/examples/ruby-on-rails-api/descope/app/javascript/components/index.html +11 -0
  71. data/examples/ruby-on-rails-api/descope/app/javascript/components/index.jsx +24 -0
  72. data/examples/ruby-on-rails-api/descope/app/javascript/controllers/application.js +9 -0
  73. data/examples/ruby-on-rails-api/descope/app/javascript/controllers/index.js +5 -0
  74. data/examples/ruby-on-rails-api/descope/app/javascript/reportWebVitals.js +13 -0
  75. data/examples/ruby-on-rails-api/descope/app/javascript/routes/index.jsx +17 -0
  76. data/examples/ruby-on-rails-api/descope/app/jobs/application_job.rb +7 -0
  77. data/examples/ruby-on-rails-api/descope/app/mailers/application_mailer.rb +4 -0
  78. data/examples/ruby-on-rails-api/descope/app/models/application_record.rb +3 -0
  79. data/examples/ruby-on-rails-api/descope/app/models/concerns/.keep +0 -0
  80. data/examples/ruby-on-rails-api/descope/app/views/homepage/index.html.erb +2 -0
  81. data/examples/ruby-on-rails-api/descope/app/views/layouts/application.html.erb +16 -0
  82. data/examples/ruby-on-rails-api/descope/app/views/layouts/mailer.html.erb +13 -0
  83. data/examples/ruby-on-rails-api/descope/app/views/layouts/mailer.text.erb +1 -0
  84. data/examples/ruby-on-rails-api/descope/app/views/session/index.html.erb +2 -0
  85. data/examples/ruby-on-rails-api/descope/bin/bundle +109 -0
  86. data/examples/ruby-on-rails-api/descope/bin/dev +11 -0
  87. data/examples/ruby-on-rails-api/descope/bin/docker-entrypoint +8 -0
  88. data/examples/ruby-on-rails-api/descope/bin/rails +4 -0
  89. data/examples/ruby-on-rails-api/descope/bin/rake +4 -0
  90. data/examples/ruby-on-rails-api/descope/bin/setup +36 -0
  91. data/examples/ruby-on-rails-api/descope/build.js +30 -0
  92. data/examples/ruby-on-rails-api/descope/config/application.rb +42 -0
  93. data/examples/ruby-on-rails-api/descope/config/boot.rb +4 -0
  94. data/examples/ruby-on-rails-api/descope/config/cable.yml +10 -0
  95. data/examples/ruby-on-rails-api/descope/config/config.yml +9 -0
  96. data/examples/ruby-on-rails-api/descope/config/credentials.yml.enc +1 -0
  97. data/examples/ruby-on-rails-api/descope/config/database.yml +25 -0
  98. data/examples/ruby-on-rails-api/descope/config/environment.rb +5 -0
  99. data/examples/ruby-on-rails-api/descope/config/environments/development.rb +76 -0
  100. data/examples/ruby-on-rails-api/descope/config/environments/production.rb +97 -0
  101. data/examples/ruby-on-rails-api/descope/config/environments/test.rb +64 -0
  102. data/examples/ruby-on-rails-api/descope/config/initializers/assets.rb +13 -0
  103. data/examples/ruby-on-rails-api/descope/config/initializers/content_security_policy.rb +25 -0
  104. data/examples/ruby-on-rails-api/descope/config/initializers/filter_parameter_logging.rb +8 -0
  105. data/examples/ruby-on-rails-api/descope/config/initializers/inflections.rb +16 -0
  106. data/examples/ruby-on-rails-api/descope/config/initializers/load_config.rb +12 -0
  107. data/examples/ruby-on-rails-api/descope/config/initializers/permissions_policy.rb +13 -0
  108. data/examples/ruby-on-rails-api/descope/config/locales/en.yml +31 -0
  109. data/examples/ruby-on-rails-api/descope/config/puma.rb +35 -0
  110. data/examples/ruby-on-rails-api/descope/config/routes.rb +18 -0
  111. data/examples/ruby-on-rails-api/descope/config/storage.yml +34 -0
  112. data/examples/ruby-on-rails-api/descope/config.ru +6 -0
  113. data/examples/ruby-on-rails-api/descope/db/seeds.rb +9 -0
  114. data/examples/ruby-on-rails-api/descope/lib/assets/.keep +0 -0
  115. data/examples/ruby-on-rails-api/descope/lib/tasks/.keep +0 -0
  116. data/examples/ruby-on-rails-api/descope/log/.keep +0 -0
  117. data/examples/ruby-on-rails-api/descope/package-lock.json +19680 -0
  118. data/examples/ruby-on-rails-api/descope/package.json +51 -0
  119. data/examples/ruby-on-rails-api/descope/public/404.html +67 -0
  120. data/examples/ruby-on-rails-api/descope/public/422.html +67 -0
  121. data/examples/ruby-on-rails-api/descope/public/500.html +66 -0
  122. data/examples/ruby-on-rails-api/descope/public/apple-touch-icon-precomposed.png +0 -0
  123. data/examples/ruby-on-rails-api/descope/public/apple-touch-icon.png +0 -0
  124. data/examples/ruby-on-rails-api/descope/public/favicon.ico +0 -0
  125. data/examples/ruby-on-rails-api/descope/public/robots.txt +1 -0
  126. data/examples/ruby-on-rails-api/descope/storage/.keep +0 -0
  127. data/examples/ruby-on-rails-api/descope/tmp/.keep +0 -0
  128. data/examples/ruby-on-rails-api/descope/tmp/pids/.keep +0 -0
  129. data/examples/ruby-on-rails-api/descope/tmp/storage/.keep +0 -0
  130. data/examples/ruby-on-rails-api/descope/vendor/.keep +0 -0
  131. data/examples/ruby-on-rails-api/descope/yarn.lock +10780 -0
  132. data/lib/descope/api/v1/auth/enchantedlink.rb +156 -0
  133. data/lib/descope/api/v1/auth/magiclink.rb +170 -0
  134. data/lib/descope/api/v1/auth/oauth.rb +72 -0
  135. data/lib/descope/api/v1/auth/otp.rb +186 -0
  136. data/lib/descope/api/v1/auth/password.rb +100 -0
  137. data/lib/descope/api/v1/auth/saml.rb +48 -0
  138. data/lib/descope/api/v1/auth/totp.rb +72 -0
  139. data/lib/descope/api/v1/auth.rb +452 -0
  140. data/lib/descope/api/v1/management/access_key.rb +81 -0
  141. data/lib/descope/api/v1/management/audit.rb +82 -0
  142. data/lib/descope/api/v1/management/authz.rb +165 -0
  143. data/lib/descope/api/v1/management/common.rb +147 -0
  144. data/lib/descope/api/v1/management/flow.rb +55 -0
  145. data/lib/descope/api/v1/management/password.rb +58 -0
  146. data/lib/descope/api/v1/management/permission.rb +48 -0
  147. data/lib/descope/api/v1/management/project.rb +53 -0
  148. data/lib/descope/api/v1/management/role.rb +48 -0
  149. data/lib/descope/api/v1/management/scim.rb +206 -0
  150. data/lib/descope/api/v1/management/sso_settings.rb +153 -0
  151. data/lib/descope/api/v1/management/tenant.rb +71 -0
  152. data/lib/descope/api/v1/management/user.rb +619 -0
  153. data/lib/descope/api/v1/management.rb +38 -0
  154. data/lib/descope/api/v1/session.rb +84 -0
  155. data/lib/descope/api/v1.rb +13 -0
  156. data/lib/descope/client.rb +6 -0
  157. data/lib/descope/exception.rb +50 -0
  158. data/lib/descope/mixins/common.rb +129 -0
  159. data/lib/descope/mixins/headers.rb +15 -0
  160. data/lib/descope/mixins/http.rb +133 -0
  161. data/lib/descope/mixins/initializer.rb +80 -0
  162. data/lib/descope/mixins/logging.rb +30 -0
  163. data/lib/descope/mixins/validation.rb +79 -0
  164. data/lib/descope/mixins.rb +22 -0
  165. data/lib/descope/version.rb +7 -0
  166. data/lib/descope.rb +9 -0
  167. data/lib/descope_client.rb +5 -0
  168. data/release-please-config.json +18 -0
  169. data/renovate.json +6 -0
  170. data/spec/factories/user.rb +16 -0
  171. data/spec/lib.descope/api/v1/auth/enchantedlink_spec.rb +159 -0
  172. data/spec/lib.descope/api/v1/auth/magiclink_spec.rb +282 -0
  173. data/spec/lib.descope/api/v1/auth/oauth_spec.rb +117 -0
  174. data/spec/lib.descope/api/v1/auth/otp_spec.rb +285 -0
  175. data/spec/lib.descope/api/v1/auth/password_spec.rb +124 -0
  176. data/spec/lib.descope/api/v1/auth/saml_spec.rb +55 -0
  177. data/spec/lib.descope/api/v1/auth/totp_spec.rb +70 -0
  178. data/spec/lib.descope/api/v1/auth_spec.rb +372 -0
  179. data/spec/lib.descope/api/v1/management/access_key_spec.rb +118 -0
  180. data/spec/lib.descope/api/v1/management/audit_spec.rb +78 -0
  181. data/spec/lib.descope/api/v1/management/authz_spec.rb +336 -0
  182. data/spec/lib.descope/api/v1/management/flow_spec.rb +78 -0
  183. data/spec/lib.descope/api/v1/management/password_spec.rb +25 -0
  184. data/spec/lib.descope/api/v1/management/permission_spec.rb +81 -0
  185. data/spec/lib.descope/api/v1/management/project_spec.rb +63 -0
  186. data/spec/lib.descope/api/v1/management/role_spec.rb +85 -0
  187. data/spec/lib.descope/api/v1/management/scim_spec.rb +312 -0
  188. data/spec/lib.descope/api/v1/management/sso_settings_spec.rb +172 -0
  189. data/spec/lib.descope/api/v1/management/tenant_spec.rb +141 -0
  190. data/spec/lib.descope/api/v1/management/user_spec.rb +667 -0
  191. data/spec/lib.descope/api/v1/session_spec.rb +117 -0
  192. data/spec/lib.descope/client_spec.rb +40 -0
  193. data/spec/spec_helper.rb +72 -0
  194. data/spec/support/client_config.rb +14 -0
  195. data/spec/support/dummy_class.rb +36 -0
  196. data/spec/support/utils.rb +32 -0
  197. metadata +420 -0
@@ -0,0 +1,285 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Descope::Api::V1::OTP do
6
+ before(:all) do
7
+ dummy_instance = DummyClass.new
8
+ dummy_instance.extend(Descope::Api::V1::Session)
9
+ dummy_instance.extend(Descope::Api::V1::Auth::OTP)
10
+ dummy_instance.extend(Descope::Api::V1::Management::User)
11
+ @instance = dummy_instance
12
+ end
13
+
14
+ context '.sign_in' do
15
+ it 'is expected to respond to sign in using otp' do
16
+ expect(@instance).to respond_to(:otp_sign_in)
17
+ end
18
+
19
+ it 'is expected to sign in with otp' do
20
+ request_params = {
21
+ loginId: 'test',
22
+ loginOptions: {
23
+ stepup: false,
24
+ customClaims: { 'abc': '123' },
25
+ mfa: false,
26
+ ssoAppId: 'sso-id'
27
+ }
28
+ }
29
+ expect(@instance).to receive(:post).with(
30
+ otp_compose_signin_url,
31
+ request_params,
32
+ {},
33
+ 'refresh_token'
34
+ )
35
+
36
+ allow_any_instance_of(Descope::Api::V1::Auth::OTP).to receive(:extract_masked_address).and_return({})
37
+
38
+ expect do
39
+ @instance.otp_sign_in(
40
+ method: DeliveryMethod::EMAIL,
41
+ login_id: 'test',
42
+ login_options: {
43
+ stepup: false,
44
+ custom_claims: { 'abc': '123' },
45
+ mfa: false,
46
+ sso_app_id: 'sso-id'
47
+ },
48
+ refresh_token: 'refresh_token'
49
+ )
50
+ end.not_to raise_error
51
+ end
52
+
53
+ it 'is expected to sign in with otp phone' do
54
+ request_params = {
55
+ loginId: 'test',
56
+ loginOptions: {
57
+ stepup: false,
58
+ customClaims: { 'abc': '123' },
59
+ mfa: false,
60
+ ssoAppId: 'sso-id'
61
+ },
62
+ }
63
+ expect(@instance).to receive(:post).with(
64
+ otp_compose_signin_url(DeliveryMethod::SMS),
65
+ request_params,
66
+ {},
67
+ 'refresh_token'
68
+ )
69
+
70
+ allow_any_instance_of(Descope::Api::V1::Auth::OTP).to receive(:extract_masked_address).and_return(
71
+ {
72
+ 'maskedPhone' => '+1******890'
73
+ }
74
+ )
75
+
76
+ expect do
77
+ @instance.otp_sign_in(
78
+ method: DeliveryMethod::SMS,
79
+ login_id: 'test',
80
+ login_options: {
81
+ stepup: false,
82
+ custom_claims: { 'abc': '123' },
83
+ mfa: false,
84
+ sso_app_id: 'sso-id'
85
+ },
86
+ refresh_token: 'refresh_token'
87
+ )
88
+ end.not_to raise_error
89
+ end
90
+ end
91
+
92
+ context '.sign_up' do
93
+ it 'is expected to respond to otp email sign up' do
94
+ expect(@instance).to respond_to(:otp_sign_up)
95
+ end
96
+
97
+ it 'is expected to sign up with otp via email' do
98
+ request_params = {
99
+ loginId: 'test',
100
+ user: { loginId: 'user1', email: 'dummy@dummy.com' },
101
+ email: 'dummy@dummy.com'
102
+ }
103
+
104
+ expect(@instance).to receive(:post).with(
105
+ otp_compose_signup_url,
106
+ request_params
107
+ ).and_return({ 'maskedEmail' => 'd****@d****.com' })
108
+
109
+ allow_any_instance_of(Descope::Api::V1::Auth).to receive(:extract_masked_address).and_return({})
110
+
111
+ expect do
112
+ @instance.otp_sign_up(
113
+ login_id: 'test',
114
+ method: DeliveryMethod::EMAIL,
115
+ user: { login_id: 'user1', email: 'dummy@dummy.com' }
116
+ )
117
+ end.not_to raise_error
118
+ end
119
+
120
+ it 'is expected to sign up with otp via phone' do
121
+ request_params = {
122
+ loginId: 'test',
123
+ user: { loginId: 'user1', phone: '+1234567890' },
124
+ phone: '+1234567890'
125
+ }
126
+
127
+ expect(@instance).to receive(:post).with(
128
+ otp_compose_signup_url(DeliveryMethod::SMS),
129
+ request_params
130
+ ).and_return({ 'maskedPhone' => '+1******890' })
131
+
132
+ allow_any_instance_of(Descope::Api::V1::Auth).to receive(:extract_masked_address).and_return({})
133
+
134
+ expect do
135
+ @instance.otp_sign_up(
136
+ login_id: 'test',
137
+ method: DeliveryMethod::SMS,
138
+ user: { login_id: 'user1', phone: '+1234567890' }
139
+ )
140
+ end.not_to raise_error
141
+ end
142
+ end
143
+
144
+ context '.sign_up_or_in' do
145
+ it 'is expected to respond to sign up' do
146
+ expect(@instance).to respond_to(:otp_sign_up_or_in)
147
+ end
148
+
149
+ it 'is expected to sign up or in with otp' do
150
+ request_params = {
151
+ loginId: 'test',
152
+ loginOptions: {
153
+ stepup: false,
154
+ customClaims: { 'abc': '123' },
155
+ mfa: false,
156
+ ssoAppId: 'sso-id'
157
+ },
158
+ providerId: 'provider-id',
159
+ templateId: 'template-id',
160
+ ssoAppId: 'sso-id'
161
+ }
162
+
163
+ expect(@instance).to receive(:post).with(
164
+ otp_compose_sign_up_or_in_url,
165
+ request_params
166
+ ).and_return({ 'maskedEmail' => 'd****@d****.com' })
167
+
168
+ expect do
169
+ @instance.otp_sign_up_or_in(
170
+ method: DeliveryMethod::EMAIL,
171
+ login_id: 'test',
172
+ login_options: {
173
+ stepup: false,
174
+ custom_claims: { 'abc': '123' },
175
+ mfa: false,
176
+ sso_app_id: 'sso-id'
177
+ },
178
+ provider_id: 'provider-id',
179
+ template_id: 'template-id',
180
+ sso_app_id: 'sso-id'
181
+ )
182
+ end.not_to raise_error
183
+ end
184
+ end
185
+
186
+ context '.otp_verify_code' do
187
+ it 'is expected to respond to otp_verify_code' do
188
+ expect(@instance).to respond_to(:otp_verify_code)
189
+ end
190
+
191
+ it 'is expected to verify OTP code' do
192
+ jwt_response = { 'fake': 'response' }
193
+ allow(@instance).to receive(:generate_jwt_response).and_return(jwt_response)
194
+
195
+ expect(@instance).to receive(:post).with(
196
+ otp_compose_verify_code_url,
197
+ {
198
+ loginId: 'test',
199
+ code: '123456'
200
+ }
201
+ ).and_return({ 'sessionJWT': 'fake-session-jwt' })
202
+
203
+ expect do
204
+ @instance.otp_verify_code(
205
+ method: DeliveryMethod::EMAIL,
206
+ login_id: 'test',
207
+ code: '123456'
208
+ )
209
+ end.not_to raise_error
210
+ end
211
+ end
212
+
213
+ context '.otp_update_email' do
214
+ it 'is expected to respond to otp_email_update_user_email' do
215
+ expect(@instance).to respond_to(:otp_update_user_email)
216
+ end
217
+
218
+ it 'is expected to update email with otp' do
219
+ request_params = {
220
+ loginId: 'test',
221
+ email: 'dummy@dummy.com',
222
+ addToLoginIDs: true,
223
+ onMergeUseExisting: true,
224
+ providerId: 'provider-id',
225
+ templateId: 'template-id'
226
+ }
227
+
228
+ expect(@instance).to receive(:post).with(
229
+ UPDATE_USER_EMAIL_OTP_PATH,
230
+ request_params,
231
+ {},
232
+ 'token'
233
+ ).and_return({ 'maskedEmail' => 'd****@d****.com' })
234
+
235
+ expect do
236
+ @instance.otp_update_user_email(
237
+ login_id: 'test',
238
+ email: 'dummy@dummy.com',
239
+ add_to_login_ids: true,
240
+ on_merge_use_existing: true,
241
+ refresh_token: 'token',
242
+ provider_id: 'provider-id',
243
+ template_id: 'template-id'
244
+ )
245
+ end.not_to raise_error
246
+ end
247
+ end
248
+
249
+ context '.otp_update_phone' do
250
+ it 'is expected to respond to otp_email_update_user_phone' do
251
+ expect(@instance).to respond_to(:otp_update_user_phone)
252
+ end
253
+
254
+ it 'is expected to update phone with otp' do
255
+ request_params = {
256
+ loginId: 'test',
257
+ phone: '+1234567890',
258
+ addToLoginIDs: true,
259
+ onMergeUseExisting: true,
260
+ providerId: 'provider-id',
261
+ templateId: 'template-id'
262
+ }
263
+
264
+ expect(@instance).to receive(:post).with(
265
+ otp_compose_update_phone_url(DeliveryMethod::SMS),
266
+ request_params,
267
+ {},
268
+ 'token'
269
+ ).and_return({ 'maskedPhone' => '+1******890' })
270
+
271
+ expect do
272
+ @instance.otp_update_user_phone(
273
+ login_id: 'test',
274
+ phone: '+1234567890',
275
+ add_to_login_ids: true,
276
+ on_merge_use_existing: true,
277
+ refresh_token: 'token',
278
+ method: DeliveryMethod::SMS,
279
+ provider_id: 'provider-id',
280
+ template_id: 'template-id'
281
+ )
282
+ end.not_to raise_error
283
+ end
284
+ end
285
+ end
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Descope::Api::V1::Password do
6
+ before(:all) do
7
+ dummy_instance = DummyClass.new
8
+ dummy_instance.extend(Descope::Api::V1::Session)
9
+ dummy_instance.extend(Descope::Api::V1::Auth::Password)
10
+ @instance = dummy_instance
11
+ end
12
+
13
+ context '.sign_up' do
14
+ it 'is expected to respond to sign up' do
15
+ expect(@instance).to respond_to(:password_sign_up)
16
+ end
17
+
18
+ it 'is expected to sign up with password' do
19
+ jwt_response = { 'fake': 'response' }
20
+ allow(@instance).to receive(:generate_jwt_response).and_return(jwt_response)
21
+
22
+ expect(@instance).to receive(:post).with(
23
+ SIGN_UP_PASSWORD_PATH, {
24
+ loginId: 'test',
25
+ password: 's3cr3t',
26
+ user: { loginId: 'admin', email: 'test@domain.com' }
27
+ }
28
+ ).and_return(jwt_response)
29
+
30
+ expect do
31
+ @instance.password_sign_up(
32
+ login_id: 'test',
33
+ password: 's3cr3t',
34
+ user: { login_id: 'admin', email: 'test@domain.com' }
35
+ )
36
+ end.not_to raise_error
37
+ end
38
+ end
39
+
40
+ context '.sign_in' do
41
+ it 'is expected to respond to sign in' do
42
+ expect(@instance).to respond_to(:password_sign_in)
43
+ end
44
+
45
+ it 'is expected to sign in with password' do
46
+ expect(@instance).to receive(:post).with(
47
+ SIGN_IN_PASSWORD_PATH, { loginId: 'test', password: 's3cr3t', ssoAppId: nil }
48
+ )
49
+ # stub the jwt_get_unverified_header method to return the kid of the public key created above
50
+ allow(@instance).to receive(:generate_jwt_response).and_return({})
51
+ expect { @instance.password_sign_in(login_id: 'test', password: 's3cr3t') }.not_to raise_error
52
+ end
53
+ end
54
+
55
+ context '.password_replace' do
56
+ it 'is expected to respond to password replace' do
57
+ expect(@instance).to respond_to(:password_replace)
58
+ end
59
+
60
+ it 'is expected to replace password' do
61
+ expect(@instance).to receive(:post).with(
62
+ REPLACE_PASSWORD_PATH, { loginId: 'test', oldPassword: 's3cr3t', newPassword: 's3cr3t1' }
63
+ )
64
+
65
+ expect do
66
+ @instance.password_replace(
67
+ login_id: 'test', old_password: 's3cr3t', new_password: 's3cr3t1'
68
+ )
69
+ end.not_to raise_error
70
+ end
71
+ end
72
+
73
+ context '.password_update' do
74
+ it 'is expected to respond to password update' do
75
+ expect(@instance).to respond_to(:password_update)
76
+ end
77
+
78
+ it 'is expected to update password' do
79
+ expect(@instance).to receive(:post).with(
80
+ UPDATE_PASSWORD_PATH, { loginId: 'test', newPassword: 's3cr3t1' }, {}, 'refresh_token'
81
+ )
82
+
83
+ expect do
84
+ @instance.password_update(
85
+ login_id: 'test', new_password: 's3cr3t1', refresh_token: 'refresh_token'
86
+ )
87
+ end.not_to raise_error
88
+ end
89
+ end
90
+
91
+ context '.get_password_policy' do
92
+ it 'is expected to respond to get password policy' do
93
+ expect(@instance).to respond_to(:get_password_policy)
94
+ end
95
+
96
+ it 'is expected to get password policy' do
97
+ expect(@instance).to receive(:get).with(
98
+ PASSWORD_POLICY_PATH, {}, {}, nil
99
+ )
100
+
101
+ expect do
102
+ @instance.get_password_policy
103
+ end.not_to raise_error
104
+ end
105
+ end
106
+
107
+ context '.password_reset' do
108
+ it 'is expected to respond to password reset' do
109
+ expect(@instance).to respond_to(:password_reset)
110
+ end
111
+
112
+ it 'is expected to reset password' do
113
+ expect(@instance).to receive(:post).with(
114
+ SEND_RESET_PASSWORD_PATH, { loginId: 'test', redirectUrl: 'https://www.google.com', providerId: 'test', templateId: 'test' }
115
+ )
116
+
117
+ expect do
118
+ @instance.password_reset(
119
+ login_id: 'test', redirect_url: 'https://www.google.com', provider_id: 'test', template_id: 'test'
120
+ )
121
+ end.not_to raise_error
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Descope::Api::V1::SAML do
6
+ before(:all) do
7
+ dummy_instance = DummyClass.new
8
+ dummy_instance.extend(Descope::Api::V1::Session)
9
+ dummy_instance.extend(Descope::Api::V1::Auth::OAuth)
10
+ @instance = dummy_instance
11
+ end
12
+
13
+ context '.saml_start' do
14
+ it 'is expected to respond to saml start' do
15
+ expect(@instance).to respond_to(:saml_sign_in)
16
+ end
17
+
18
+ it 'is expected to sign in single sign-on saml' do
19
+ request_params = {
20
+ stepup: false,
21
+ customClaims: { 'abc': '123' },
22
+ mfa: false,
23
+ ssoAppId: 'sso-id'
24
+ }
25
+ formatted_uri = '/v1/auth/saml/authorize?tenant=some-tenant&redirectUrl=https%3A%2F%2Fsome-uri%2Femail&prompt=custom+prompt+%26+needs+to+be+decoded%3A+too'
26
+ expect(@instance).to receive(:post).with(formatted_uri, request_params)
27
+
28
+ expect do
29
+ @instance.saml_sign_in(
30
+ tenant: 'some-tenant',
31
+ prompt: 'custom prompt & needs to be decoded: too',
32
+ redirect_url: 'https://some-uri/email',
33
+ stepup: false,
34
+ custom_claims: { 'abc': '123' },
35
+ mfa: false,
36
+ sso_app_id: 'sso-id'
37
+ )
38
+ end.not_to raise_error
39
+ end
40
+ end
41
+
42
+ context '.saml_exchange_token' do
43
+ it 'is expected to respond to saml exchange token' do
44
+ expect(@instance).to respond_to(:saml_exchange_token)
45
+ end
46
+
47
+ it 'is expected to exchange token' do
48
+ jwt_response = { 'fake': 'response' }
49
+ allow(@instance).to receive(:generate_jwt_response).and_return(jwt_response)
50
+
51
+ expect(@instance).to receive(:post).with(SAML_EXCHANGE_TOKEN_PATH, { code: '123456' }).and_return(jwt_response)
52
+ expect { @instance.saml_exchange_token('123456') }.not_to raise_error
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Descope::Api::V1::OTP do
6
+ before(:all) do
7
+ dummy_instance = DummyClass.new
8
+ dummy_instance.extend(Descope::Api::V1::Session)
9
+ dummy_instance.extend(Descope::Api::V1::Auth::OTP)
10
+ @instance = dummy_instance
11
+ end
12
+
13
+ context '.sign_in' do
14
+ it 'is expected to respond to sign in using otp' do
15
+ expect(@instance).to respond_to(:totp_sign_in_code)
16
+ end
17
+
18
+ it 'is expected to sign in with totp code' do
19
+ request_params = {
20
+ loginId: 'test',
21
+ loginOptions: {
22
+ stepup: false,
23
+ customClaims: { 'abc': '123' },
24
+ mfa: false,
25
+ ssoAppId: 'sso-id'
26
+ },
27
+ code: '123456'
28
+ }
29
+ jwt_response = { 'fake': 'response' }
30
+ allow(@instance).to receive(:generate_jwt_response).and_return(jwt_response)
31
+ expect(@instance).to receive(:post).with(VERIFY_TOTP_PATH, request_params, {}, nil).and_return(
32
+ jwt_response
33
+ )
34
+
35
+ expect do
36
+ @instance.totp_sign_in_code(
37
+ login_id: 'test',
38
+ login_options: {
39
+ stepup: false,
40
+ custom_claims: { 'abc': '123' },
41
+ mfa: false,
42
+ sso_app_id: 'sso-id'
43
+ },
44
+ code: '123456'
45
+ )
46
+ end.not_to raise_error
47
+ end
48
+ end
49
+
50
+ context '.totp_add_update_key' do
51
+ it 'is expected to respond to totp_add_update_key' do
52
+ expect(@instance).to respond_to(:totp_add_update_key)
53
+ end
54
+
55
+ it 'is expected to add or update totp key' do
56
+ request_params = {
57
+ loginId: 'test'
58
+ }
59
+
60
+ allow(@instance).to receive(:post).with(UPDATE_TOTP_PATH, request_params, {}, 'refresh_token')
61
+
62
+ expect do
63
+ @instance.totp_add_update_key(
64
+ login_id: 'test',
65
+ refresh_token: 'refresh_token'
66
+ )
67
+ end.not_to raise_error
68
+ end
69
+ end
70
+ end