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,18 @@
1
+ {
2
+ "packages": {
3
+ ".": {
4
+ "package-name": "descope",
5
+ "changelog-path": "CHANGELOG.md",
6
+ "release-type": "ruby",
7
+ "bump-minor-pre-major": false,
8
+ "bump-patch-for-minor-pre-major": false,
9
+ "draft": false,
10
+ "prerelease": false,
11
+ "version-file": "lib/descope/version.rb",
12
+ "versioning": "always-bump-minor",
13
+ "pull-request-title-pattern": "chore: release ${version}",
14
+ "pull-request-header": "Descope Release: Merge this PR to release ${version}"
15
+ }
16
+ },
17
+ "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
18
+ }
data/renovate.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
+ "extends": [
4
+ "local>descope/renovate-config"
5
+ ]
6
+ }
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ FactoryBot.define do
5
+ factory :user, class: Hash do
6
+ initialize_with { attributes }
7
+
8
+ login_id { Faker::Internet.username }
9
+ email { Faker::Internet.email }
10
+ phone { "+1#{Faker::Number.number(digits: 10)}" }
11
+ name { Faker::Name.name }
12
+ given_name { Faker::Name.first_name }
13
+ middle_name { 'Ruby SDK User' }
14
+ family_name { Faker::Name.last_name }
15
+ end
16
+ end
@@ -0,0 +1,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Descope::Api::V1::EnchantedLink 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::EnchantedLink)
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' do
16
+ expect(@instance).to respond_to(:enchanted_link_sign_in)
17
+ end
18
+
19
+ it 'is expected to sign in with enchanted link' do
20
+ request_params = {
21
+ loginId: 'test',
22
+ redirectUrl: 'https://some-uri/email',
23
+ loginOptions: {
24
+ stepup: false,
25
+ customClaims: { 'abc': '123' },
26
+ mfa: false,
27
+ ssoAppId: 'sso-id'
28
+ }
29
+ }
30
+ expect(@instance).to receive(:post).with(
31
+ enchanted_link_compose_signin_url,
32
+ request_params,
33
+ nil,
34
+ 'refresh_token'
35
+ )
36
+
37
+ expect do
38
+ @instance.enchanted_link_sign_in(
39
+ login_id: 'test',
40
+ uri: 'https://some-uri/email',
41
+ login_options: {
42
+ stepup: false,
43
+ custom_claims: { 'abc': '123' },
44
+ mfa: false,
45
+ sso_app_id: 'sso-id'
46
+ },
47
+ refresh_token: 'refresh_token'
48
+ )
49
+ end.not_to raise_error
50
+ end
51
+
52
+ it 'is expected to validate refresh token and not raise an error with refresh token and valid login options' do
53
+ expect do
54
+ @instance.send(:validate_refresh_token_provided, { mfa: true, stepup: true }, 'some-token')
55
+ end.not_to raise_error
56
+ end
57
+
58
+ it 'is expected to validate refresh token and raise an error with refresh token and invalid login options' do
59
+ expect do
60
+ @instance.send(:validate_refresh_token_provided, { mfa: true, stepup: true }, '')
61
+ end.to raise_error(Descope::AuthException, 'Missing refresh token for stepup/mfa')
62
+ end
63
+ end
64
+
65
+ context '.sign_up' do
66
+ it 'is expected to respond to sign up' do
67
+ expect(@instance).to respond_to(:enchanted_link_sign_up)
68
+ end
69
+
70
+ it 'is expected to sign up with enchanted link' do
71
+ request_params = {
72
+ loginId: 'test',
73
+ redirectUrl: 'https://some-uri/email',
74
+ user: { loginId: 'user1', email: 'dummy@dummy.com' },
75
+ email: 'dummy@dummy.com'
76
+ }
77
+
78
+ expect(@instance).to receive(:post).with(
79
+ enchanted_link_compose_signup_url,
80
+ request_params
81
+ )
82
+
83
+ expect do
84
+ @instance.enchanted_link_sign_up(
85
+ login_id: 'test',
86
+ uri: 'https://some-uri/email',
87
+ user: { login_id: 'user1', email: 'dummy@dummy.com' }
88
+ )
89
+ end.not_to raise_error
90
+ end
91
+ end
92
+
93
+ context '.sign_up_or_in' do
94
+ it 'is expected to respond to sign up' do
95
+ expect(@instance).to respond_to(:enchanted_link_sign_up_or_in)
96
+ end
97
+
98
+ it 'is expected to sign up with enchanted link' do
99
+ request_params = {
100
+ loginId: 'test',
101
+ redirectUrl: 'https://some-uri/email',
102
+ loginOptions: {
103
+ stepup: false,
104
+ customClaims: { 'abc': '123' },
105
+ mfa: false,
106
+ ssoAppId: 'sso-id'
107
+ }
108
+ }
109
+
110
+ expect(@instance).to receive(:post).with(
111
+ enchanted_link_compose_sign_up_or_in_url,
112
+ request_params
113
+ )
114
+
115
+ expect do
116
+ @instance.enchanted_link_sign_up_or_in(
117
+ login_id: 'test',
118
+ uri: 'https://some-uri/email',
119
+ login_options: {
120
+ stepup: false,
121
+ custom_claims: { 'abc': '123' },
122
+ mfa: false,
123
+ sso_app_id: 'sso-id'
124
+ }
125
+ )
126
+ end.not_to raise_error
127
+ end
128
+ end
129
+
130
+ context '.enchanted_link_verify_token' do
131
+ it 'is expected to respond to enchanted_link_verify_token' do
132
+ expect(@instance).to respond_to(:enchanted_link_verify_token)
133
+ end
134
+
135
+ it 'is expected to verify token with enchanted link' do
136
+ expect(@instance).to receive(:post).with(
137
+ VERIFY_ENCHANTEDLINK_AUTH_PATH,
138
+ { token: 'token' }
139
+ )
140
+
141
+ expect { @instance.enchanted_link_verify_token('token') }.not_to raise_error
142
+ end
143
+ end
144
+
145
+ context '.get_session' do
146
+ it 'is expected to respond to get_session' do
147
+ expect(@instance).to respond_to(:enchanted_link_get_session)
148
+ end
149
+
150
+ it 'is expected to get session by pending ref with enchanted link' do
151
+ jwt_response = { 'fake': 'response' }
152
+ allow(@instance).to receive(:generate_jwt_response).and_return(jwt_response)
153
+
154
+ expect do
155
+ @instance.enchanted_link_get_session('pendingRef')
156
+ end.not_to raise_error
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,282 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Descope::Api::V1::MagicLink 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::MagicLink)
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' do
16
+ expect(@instance).to respond_to(:magiclink_sign_in)
17
+ end
18
+
19
+ it 'is expected to sign in with magic link email' do
20
+ request_params = {
21
+ loginId: 'test',
22
+ redirectUrl: 'https://some-uri/email',
23
+ loginOptions: {
24
+ stepup: false,
25
+ customClaims: { 'abc': '123' },
26
+ mfa: false,
27
+ ssoAppId: 'sso-id'
28
+ }
29
+ }
30
+ expect(@instance).to receive(:post).with(
31
+ magiclink_compose_signin_url,
32
+ request_params,
33
+ {},
34
+ 'refresh_token'
35
+ )
36
+
37
+ allow_any_instance_of(Descope::Api::V1::Auth::MagicLink).to receive(:extract_masked_address).and_return({})
38
+
39
+ expect do
40
+ @instance.magiclink_sign_in(
41
+ method: DeliveryMethod::EMAIL,
42
+ login_id: 'test',
43
+ uri: 'https://some-uri/email',
44
+ login_options: {
45
+ stepup: false,
46
+ custom_claims: { 'abc': '123' },
47
+ mfa: false,
48
+ sso_app_id: 'sso-id'
49
+ },
50
+ refresh_token: 'refresh_token'
51
+ )
52
+ end.not_to raise_error
53
+ end
54
+
55
+ it 'is expected to sign in with magic link phone' do
56
+ request_params = {
57
+ loginId: 'test',
58
+ redirectUrl: 'https://some-uri/sms',
59
+ loginOptions: {
60
+ stepup: false,
61
+ customClaims: { 'abc': '123' },
62
+ mfa: false,
63
+ ssoAppId: 'sso-id'
64
+ }
65
+ }
66
+ expect(@instance).to receive(:post).with(
67
+ magiclink_compose_signin_url(DeliveryMethod::SMS),
68
+ request_params,
69
+ {},
70
+ 'refresh_token'
71
+ )
72
+
73
+ allow_any_instance_of(Descope::Api::V1::Auth::MagicLink).to receive(:extract_masked_address).and_return(
74
+ {
75
+ 'maskedPhone' => '+1******890'
76
+ }
77
+ )
78
+
79
+ expect do
80
+ @instance.magiclink_sign_in(
81
+ method: DeliveryMethod::SMS,
82
+ login_id: 'test',
83
+ uri: 'https://some-uri/sms',
84
+ login_options: {
85
+ stepup: false,
86
+ custom_claims: { 'abc': '123' },
87
+ mfa: false,
88
+ sso_app_id: 'sso-id'
89
+ },
90
+ refresh_token: 'refresh_token'
91
+ )
92
+ end.not_to raise_error
93
+ end
94
+ end
95
+
96
+ context '.sign_up' do
97
+ it 'is expected to respond to magic link email sign up' do
98
+ expect(@instance).to respond_to(:magiclink_sign_up)
99
+ end
100
+
101
+ it 'is expected to sign up with magic link via email' do
102
+ request_params = {
103
+ loginId: 'test',
104
+ redirectUrl: 'https://some-uri/email',
105
+ user: { loginId: 'user1', email: 'dummy@dummy.com' },
106
+ email: 'dummy@dummy.com'
107
+ }
108
+
109
+ expect(@instance).to receive(:post).with(
110
+ magiclink_compose_signup_url,
111
+ request_params
112
+ ).and_return({ 'maskedEmail' => 'd****@d****.com' })
113
+
114
+ expect do
115
+ @instance.magiclink_sign_up(
116
+ login_id: 'test',
117
+ method: DeliveryMethod::EMAIL,
118
+ uri: 'https://some-uri/email',
119
+ user: { login_id: 'user1', email: 'dummy@dummy.com' }
120
+ )
121
+ end.not_to raise_error
122
+ end
123
+
124
+ it 'is expected to sign up with magic link via phone' do
125
+ request_params = {
126
+ loginId: 'test',
127
+ redirectUrl: 'https://some-uri/sms',
128
+ user: { loginId: 'user1', phone: '+1234567890' },
129
+ phone: '+1234567890'
130
+ }
131
+
132
+ expect(@instance).to receive(:post).with(
133
+ magiclink_compose_signup_url(DeliveryMethod::SMS),
134
+ request_params
135
+ ).and_return({ 'maskedPhone' => '+1******890' })
136
+
137
+ expect do
138
+ @instance.magiclink_sign_up(
139
+ login_id: 'test',
140
+ method: DeliveryMethod::SMS,
141
+ uri: 'https://some-uri/sms',
142
+ user: { login_id: 'user1', phone: '+1234567890' }
143
+ )
144
+ end.not_to raise_error
145
+ end
146
+ end
147
+
148
+ context '.sign_up_or_in' do
149
+ it 'is expected to respond to sign up' do
150
+ expect(@instance).to respond_to(:magiclink_sign_up_or_in)
151
+ end
152
+
153
+ it 'is expected to sign up or in with magic link' do
154
+ request_params = {
155
+ loginId: 'test',
156
+ redirectUrl: 'https://some-uri/email',
157
+ loginOptions: {
158
+ stepup: false,
159
+ customClaims: { 'abc': '123' },
160
+ mfa: false,
161
+ ssoAppId: 'sso-id'
162
+ }
163
+ }
164
+
165
+ expect(@instance).to receive(:post).with(
166
+ magiclink_compose_sign_up_or_in_url,
167
+ request_params
168
+ ).and_return({ 'maskedEmail' => 'd****@d****.com' })
169
+
170
+ expect do
171
+ @instance.magiclink_sign_up_or_in(
172
+ method: DeliveryMethod::EMAIL,
173
+ login_id: 'test',
174
+ uri: 'https://some-uri/email',
175
+ login_options: {
176
+ stepup: false,
177
+ custom_claims: { 'abc': '123' },
178
+ mfa: false,
179
+ sso_app_id: 'sso-id'
180
+ }
181
+ )
182
+ end.not_to raise_error
183
+ end
184
+ end
185
+
186
+ context '.magiclink_verify_token' do
187
+ it 'is expected to respond to magiclink_email_verify_token' do
188
+ expect(@instance).to respond_to(:magiclink_verify_token)
189
+ end
190
+
191
+ it 'is expected to verify token with enchanted link' 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
+ VERIFY_MAGICLINK_AUTH_PATH,
197
+ { token: 'token' }
198
+ ).and_return(jwt_response)
199
+
200
+ expect { @instance.magiclink_verify_token('token') }.not_to raise_error
201
+ end
202
+ end
203
+
204
+ context '.magiclink_update_email' do
205
+ it 'is expected to respond to magiclink_email_update_user_email' do
206
+ expect(@instance).to respond_to(:magiclink_update_user_email)
207
+ end
208
+
209
+ it 'is expected to update email with enchanted link' do
210
+ request_params = {
211
+ loginId: 'test',
212
+ email: 'dummy@dummy.com',
213
+ addToLoginIDs: true,
214
+ onMergeUseExisting: true,
215
+ redirectUrl: 'https://some-uri/email'
216
+ }
217
+
218
+ expect(@instance).to receive(:post).with(
219
+ UPDATE_USER_EMAIL_MAGICLINK_PATH,
220
+ request_params,
221
+ {},
222
+ 'token'
223
+ ).and_return({ 'maskedEmail' => 'd****@d****.com' })
224
+
225
+ expect do
226
+ @instance.magiclink_update_user_email(
227
+ login_id: 'test',
228
+ email: 'dummy@dummy.com',
229
+ add_to_login_ids: true,
230
+ on_merge_use_existing: true,
231
+ refresh_token: 'token',
232
+ uri: 'https://some-uri/email'
233
+ )
234
+ end.not_to raise_error
235
+ end
236
+ end
237
+
238
+ context '.magiclink_update_phone' do
239
+ it 'is expected to respond to magiclink_email_update_user_phone' do
240
+ expect(@instance).to respond_to(:magiclink_update_user_phone)
241
+ end
242
+
243
+ it 'is expected to update phone with enchanted link' do
244
+ request_params = {
245
+ loginId: 'test',
246
+ phone: '+1234567890',
247
+ addToLoginIDs: true,
248
+ onMergeUseExisting: true,
249
+ providerId: 'provider-id',
250
+ templateId: 'template-id',
251
+ templateOptions: {
252
+ 'abc': '123'
253
+ },
254
+ redirectUrl: 'https://some-uri/sms'
255
+ }
256
+
257
+ expect(@instance).to receive(:post).with(
258
+ UPDATE_USER_PHONE_MAGICLINK_PATH,
259
+ request_params,
260
+ {},
261
+ 'token'
262
+ ).and_return({ 'maskedPhone' => '+1******890' })
263
+
264
+ expect do
265
+ @instance.magiclink_update_user_phone(
266
+ login_id: 'test',
267
+ phone: '+1234567890',
268
+ add_to_login_ids: true,
269
+ on_merge_use_existing: true,
270
+ refresh_token: 'token',
271
+ method: DeliveryMethod::SMS,
272
+ provider_id: 'provider-id',
273
+ template_id: 'template-id',
274
+ template_options: {
275
+ 'abc': '123'
276
+ },
277
+ uri: 'https://some-uri/sms'
278
+ )
279
+ end.not_to raise_error
280
+ end
281
+ end
282
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Descope::Api::V1::OAuth 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 '.oauth_start' do
14
+ it 'is expected to respond to oauth start' do
15
+ expect(@instance).to respond_to(:oauth_start)
16
+ end
17
+
18
+ it 'is expected to start oauth' do
19
+ request_params = {
20
+ stepup: false,
21
+ customClaims: { 'abc': '123' },
22
+ mfa: false,
23
+ ssoAppId: 'sso-id'
24
+ }
25
+ url = "#{OAUTH_START_PATH}?provider=github"
26
+ url += "&redirectUrl=#{CGI.escape('https://some-uri/email')}"
27
+ url += "&prompt=#{CGI.escape('hello and welcome')}"
28
+
29
+ expect(@instance).to receive(:post).with(
30
+ url,
31
+ request_params,
32
+ {},
33
+ 'refresh_token'
34
+ )
35
+
36
+ expect do
37
+ @instance.oauth_start(
38
+ provider: 'github',
39
+ return_url: 'https://some-uri/email',
40
+ prompt: 'hello and welcome',
41
+ login_options: {
42
+ stepup: false,
43
+ custom_claims: { 'abc': '123' },
44
+ mfa: false,
45
+ sso_app_id: 'sso-id'
46
+ },
47
+ refresh_token: 'refresh_token'
48
+ )
49
+ end.not_to raise_error
50
+ end
51
+ end
52
+
53
+ context '.oauth_exchange_token' do
54
+ it 'is expected to respond to oauth exchange token' do
55
+ expect(@instance).to respond_to(:oauth_exchange_token)
56
+ end
57
+
58
+ it 'is expected to exchange token' do
59
+ request_params = { code: 'some-code' }
60
+ jwt_response = { 'fake': 'response' }
61
+ expect(@instance).to receive(:post).with(OAUTH_EXCHANGE_TOKEN_PATH, request_params).and_return(jwt_response)
62
+ allow(@instance).to receive(:generate_jwt_response).and_return(jwt_response)
63
+ expect { @instance.oauth_exchange_token('some-code') }.not_to raise_error
64
+ end
65
+ end
66
+
67
+ context '.oauth_create_redirect_url_for_sign_in_request' do
68
+ it 'is expected to respond to oauth create redirect url for sign in request' do
69
+ expect(@instance).to respond_to(:oauth_create_redirect_url_for_sign_in_request)
70
+ end
71
+
72
+ it 'is expected to create redirect url for sign in request' do
73
+ request_params = {
74
+ stepup: true,
75
+ customClaims: { 'abc': '123' },
76
+ mfa: false,
77
+ ssoAppId: 'sso-id'
78
+ }
79
+ expect(@instance).to receive(:post).with(
80
+ OAUTH_CREATE_REDIRECT_URL_FOR_SIGN_IN_REQUEST_PATH,
81
+ request_params
82
+ )
83
+ expect do
84
+ @instance.oauth_create_redirect_url_for_sign_in_request(
85
+ stepup: true,
86
+ custom_claims: { 'abc': '123' },
87
+ sso_app_id: 'sso-id'
88
+ )
89
+ end.not_to raise_error
90
+ end
91
+ end
92
+
93
+ context '.oauth_create_redirect_url_for_sign_in_request' do
94
+ it 'is expected to respond to oauth create redirect url for sign in request' do
95
+ expect(@instance).to respond_to(:oauth_create_redirect_url_for_sign_in_request)
96
+ end
97
+
98
+ it 'is expected to create redirect url for sign up request' do
99
+ request_params = {
100
+ stepup: false,
101
+ customClaims: { 'abc': '123' },
102
+ mfa: false,
103
+ ssoAppId: 'sso-id'
104
+ }
105
+ expect(@instance).to receive(:post).with(
106
+ OAUTH_CREATE_REDIRECT_URL_FOR_SIGN_UP_REQUEST_PATH,
107
+ request_params
108
+ )
109
+ expect do
110
+ @instance.oauth_create_redirect_url_for_sign_up_request(
111
+ custom_claims: { 'abc': '123' },
112
+ sso_app_id: 'sso-id'
113
+ )
114
+ end.not_to raise_error
115
+ end
116
+ end
117
+ end