descope 1.0.5 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yaml +2 -2
- data/.github/workflows/publish-gem.yaml +39 -7
- data/.gitignore +2 -0
- data/.ruby-version +1 -1
- data/Gemfile +7 -7
- data/Gemfile.lock +70 -65
- data/README.md +175 -52
- data/descope.gemspec +25 -20
- data/examples/ruby/.ruby-version +1 -0
- data/examples/ruby/access_key_app.rb +4 -3
- data/examples/ruby/enchantedlink_app.rb +1 -0
- data/examples/ruby/magiclink_app.rb +1 -0
- data/examples/ruby/management/.ruby-version +1 -0
- data/examples/ruby/management/Gemfile +2 -2
- data/examples/ruby/management/access_key_app.rb +2 -0
- data/examples/ruby/management/audit_app.rb +32 -8
- data/examples/ruby/management/authz_app.rb +1 -0
- data/examples/ruby/management/flow_app.rb +1 -0
- data/examples/ruby/management/permission_app.rb +3 -2
- data/examples/ruby/management/role_app.rb +3 -2
- data/examples/ruby/management/tenant_app.rb +1 -0
- data/examples/ruby/management/user_app.rb +1 -0
- data/examples/ruby/oauth_app.rb +1 -0
- data/examples/ruby/otp_app.rb +38 -12
- data/examples/ruby/password_app.rb +8 -7
- data/examples/ruby/saml_app.rb +1 -0
- data/examples/ruby/version_check.rb +17 -0
- data/examples/ruby-on-rails-api/descope/Gemfile +9 -7
- data/examples/ruby-on-rails-api/descope/Gemfile.lock +121 -90
- data/examples/ruby-on-rails-api/descope/README.md +18 -18
- data/examples/ruby-on-rails-api/descope/app/assets/builds/application.css +20092 -23
- data/examples/ruby-on-rails-api/descope/app/assets/builds/application.js +0 -1
- data/examples/ruby-on-rails-api/descope/app/assets/builds/components/index.js +0 -14
- data/examples/ruby-on-rails-api/descope/package-lock.json +1073 -19302
- data/examples/ruby-on-rails-api/descope/package.json +8 -16
- data/examples/ruby-on-rails-api/descope/yarn.lock +557 -10641
- data/lib/descope/api/v1/auth/enchantedlink.rb +3 -1
- data/lib/descope/api/v1/auth/magiclink.rb +3 -1
- data/lib/descope/api/v1/auth/otp.rb +24 -15
- data/lib/descope/api/v1/auth/password.rb +6 -2
- data/lib/descope/api/v1/auth/totp.rb +3 -1
- data/lib/descope/api/v1/auth.rb +64 -32
- data/lib/descope/api/v1/management/audit.rb +24 -0
- data/lib/descope/api/v1/management/common.rb +21 -5
- data/lib/descope/api/v1/management/sso_application.rb +236 -0
- data/lib/descope/api/v1/management/sso_settings.rb +2 -24
- data/lib/descope/api/v1/management/user.rb +151 -13
- data/lib/descope/api/v1/management.rb +2 -0
- data/lib/descope/api/v1/session.rb +37 -4
- data/lib/descope/mixins/common.rb +6 -2
- data/lib/descope/mixins/http.rb +60 -9
- data/lib/descope/mixins/initializer.rb +2 -1
- data/lib/descope/mixins/logging.rb +12 -4
- data/lib/descope/mixins/validation.rb +21 -6
- data/lib/descope/version.rb +1 -1
- data/spec/descope/api/v1/auth_spec.rb +29 -0
- data/spec/descope/api/v1/auth_token_extraction_spec.rb +126 -0
- data/spec/descope/api/v1/session_refresh_spec.rb +98 -0
- data/spec/factories/user.rb +1 -1
- data/spec/integration/lib.descope/api/v1/auth/enchantedlink_spec.rb +1 -1
- data/spec/integration/lib.descope/api/v1/auth/magiclink_spec.rb +1 -1
- data/spec/integration/lib.descope/api/v1/auth/otp_spec.rb +73 -8
- data/spec/integration/lib.descope/api/v1/auth/session_spec.rb +49 -0
- data/spec/integration/lib.descope/api/v1/auth/totp_spec.rb +1 -1
- data/spec/integration/lib.descope/api/v1/management/access_key_spec.rb +3 -0
- data/spec/integration/lib.descope/api/v1/management/audit_spec.rb +38 -0
- data/spec/integration/lib.descope/api/v1/management/authz_spec.rb +2 -0
- data/spec/integration/lib.descope/api/v1/management/flow_spec.rb +3 -1
- data/spec/integration/lib.descope/api/v1/management/permissions_spec.rb +4 -2
- data/spec/integration/lib.descope/api/v1/management/project_spec.rb +2 -0
- data/spec/integration/lib.descope/api/v1/management/roles_spec.rb +3 -1
- data/spec/integration/lib.descope/api/v1/management/user_spec.rb +55 -6
- data/spec/lib.descope/api/v1/auth/enchantedlink_spec.rb +11 -2
- data/spec/lib.descope/api/v1/auth/otp_spec.rb +176 -18
- data/spec/lib.descope/api/v1/auth/password_spec.rb +10 -1
- data/spec/lib.descope/api/v1/auth_spec.rb +168 -6
- data/spec/lib.descope/api/v1/cookie_domain_fix_integration_spec.rb +245 -0
- data/spec/lib.descope/api/v1/management/audit_spec.rb +92 -0
- data/spec/lib.descope/api/v1/management/sso_application_spec.rb +217 -0
- data/spec/lib.descope/api/v1/management/sso_settings_spec.rb +2 -2
- data/spec/lib.descope/api/v1/management/user_spec.rb +134 -46
- data/spec/lib.descope/api/v1/session_spec.rb +119 -6
- data/spec/lib.descope/mixins/http_spec.rb +218 -0
- data/spec/support/client_config.rb +0 -1
- data/spec/support/utils.rb +6 -0
- metadata +34 -137
- data/examples/ruby-on-rails-api/descope/app/assets/builds/reportWebVitals.js +0 -211
- data/examples/ruby-on-rails-api/descope/app/assets/builds/reportWebVitals.js.map +0 -7
|
@@ -12,7 +12,7 @@ describe Descope::Api::V1::Auth::TOTP do
|
|
|
12
12
|
@client.logger.info('Cleaning up test users...')
|
|
13
13
|
all_users = @client.search_all_users
|
|
14
14
|
all_users['users'].each do |user|
|
|
15
|
-
if user['middleName'] ==
|
|
15
|
+
if user['middleName'] == "#{SpecUtils.build_prefix}Ruby-SDK-User"
|
|
16
16
|
@client.logger.info("Deleting ruby spec test user #{user['loginIds'][0]}")
|
|
17
17
|
@client.delete_user(user['loginIds'][0])
|
|
18
18
|
end
|
|
@@ -4,6 +4,8 @@ require 'spec_helper'
|
|
|
4
4
|
|
|
5
5
|
describe Descope::Api::V1::Management::AccessKey do
|
|
6
6
|
before(:all) do
|
|
7
|
+
raise 'DESCOPE_MANAGEMENT_KEY is not set' if ENV['DESCOPE_MANAGEMENT_KEY'].nil?
|
|
8
|
+
|
|
7
9
|
@client = DescopeClient.new(Configuration.config)
|
|
8
10
|
end
|
|
9
11
|
|
|
@@ -28,6 +30,7 @@ describe Descope::Api::V1::Management::AccessKey do
|
|
|
28
30
|
@tenant_id = @client.create_tenant(name: 'some-new-tenant')['id']
|
|
29
31
|
@client.logger.info('creating access key')
|
|
30
32
|
@access_key = @client.create_access_key(name: @key_name, key_tenants: [{ tenant_id: @tenant_id }])
|
|
33
|
+
@client.logger.info("waiting for access key #{@access_key['key']['id']} to be active 60 seconds")
|
|
31
34
|
sleep 60
|
|
32
35
|
end
|
|
33
36
|
|
|
@@ -4,13 +4,51 @@ require 'spec_helper'
|
|
|
4
4
|
|
|
5
5
|
describe Descope::Api::V1::Management::Audit do
|
|
6
6
|
before(:all) do
|
|
7
|
+
raise 'DESCOPE_MANAGEMENT_KEY is not set' if ENV['DESCOPE_MANAGEMENT_KEY'].nil?
|
|
8
|
+
|
|
7
9
|
@client = DescopeClient.new(Configuration.config)
|
|
10
|
+
@client.logger.info('Deleting all tenants for Ruby SDK...')
|
|
11
|
+
@client.search_all_tenants(names: ['Ruby-SDK-test'])['tenants'].each do |tenant|
|
|
12
|
+
@client.logger.info("Deleting tenant: #{tenant['name']}")
|
|
13
|
+
@client.delete_tenant(tenant['id'])
|
|
14
|
+
end
|
|
15
|
+
@client.logger.info('Cleanup completed. Starting tests...')
|
|
8
16
|
end
|
|
9
17
|
|
|
18
|
+
after(:all) do
|
|
19
|
+
all_users = @client.search_all_users
|
|
20
|
+
all_users['users'].each do |user|
|
|
21
|
+
if user['middleName'] == "#{SpecUtils.build_prefix}Ruby-SDK-User"
|
|
22
|
+
puts "Deleting ruby spec test user #{user['loginIds'][0]}"
|
|
23
|
+
@client.delete_user(user['loginIds'][0])
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
10
27
|
|
|
11
28
|
it 'should search the audit trail for user operations' do
|
|
12
29
|
res = @client.audit_search(actions: ['LoginSucceed'])
|
|
13
30
|
expect(res).to be_a(Hash)
|
|
14
31
|
expect(res['audits']).to be_a(Array)
|
|
15
32
|
end
|
|
33
|
+
|
|
34
|
+
it 'should create a new audit event' do
|
|
35
|
+
# Create tenants
|
|
36
|
+
@client.logger.info('creating Ruby-SDK-test tenant')
|
|
37
|
+
tenant_id = @client.create_tenant(name: 'Ruby-SDK-test')['id']
|
|
38
|
+
|
|
39
|
+
# Create a user (actor)
|
|
40
|
+
user = build(:user)
|
|
41
|
+
created_user = @client.create_user(**user)['user']
|
|
42
|
+
|
|
43
|
+
expect do
|
|
44
|
+
@client.audit_create_event(
|
|
45
|
+
user_id: created_user['loginId'],
|
|
46
|
+
action: 'pencil.created',
|
|
47
|
+
type: 'info',
|
|
48
|
+
tenant_id:,
|
|
49
|
+
actor_id: created_user['loginIds'][0],
|
|
50
|
+
data: { 'key' => 'value' }
|
|
51
|
+
)
|
|
52
|
+
end.not_to raise_error
|
|
53
|
+
end
|
|
16
54
|
end
|
|
@@ -4,6 +4,8 @@ require 'spec_helper'
|
|
|
4
4
|
|
|
5
5
|
describe Descope::Api::V1::Management::Flow do
|
|
6
6
|
before(:all) do
|
|
7
|
+
raise 'DESCOPE_MANAGEMENT_KEY is not set' if ENV['DESCOPE_MANAGEMENT_KEY'].nil?
|
|
8
|
+
|
|
7
9
|
@client = DescopeClient.new(Configuration.config)
|
|
8
10
|
end
|
|
9
11
|
|
|
@@ -38,7 +40,7 @@ describe Descope::Api::V1::Management::Flow do
|
|
|
38
40
|
it 'should import the current project theme' do
|
|
39
41
|
export_theme = @client.export_theme
|
|
40
42
|
export_theme_current_version = export_theme['theme']['version']
|
|
41
|
-
imported_theme = @client.import_theme(export_theme)
|
|
43
|
+
imported_theme = @client.import_theme(export_theme['theme'])
|
|
42
44
|
expect(imported_theme['theme']['version']).to be(export_theme_current_version + 1)
|
|
43
45
|
end
|
|
44
46
|
end
|
|
@@ -4,9 +4,11 @@ require 'spec_helper'
|
|
|
4
4
|
|
|
5
5
|
describe Descope::Api::V1::Management::Permission do
|
|
6
6
|
before(:all) do
|
|
7
|
+
raise 'DESCOPE_MANAGEMENT_KEY is not set' if ENV['DESCOPE_MANAGEMENT_KEY'].nil?
|
|
8
|
+
|
|
7
9
|
@client = DescopeClient.new(Configuration.config)
|
|
8
10
|
@client.load_all_permissions['permissions'].each do |perm|
|
|
9
|
-
if perm['description'] ==
|
|
11
|
+
if perm['description'] == "#{SpecUtils.build_prefix} Ruby SDK"
|
|
10
12
|
puts "Deleting permission: #{perm['name']}"
|
|
11
13
|
@client.delete_permission(perm['name'])
|
|
12
14
|
end
|
|
@@ -14,7 +16,7 @@ describe Descope::Api::V1::Management::Permission do
|
|
|
14
16
|
end
|
|
15
17
|
|
|
16
18
|
it 'should create update and delete a permission' do
|
|
17
|
-
@client.create_permission(name: 'test_permission', description:
|
|
19
|
+
@client.create_permission(name: 'test_permission', description: "#{SpecUtils.build_prefix} Ruby SDK")
|
|
18
20
|
all_permissions = @client.load_all_permissions['permissions']
|
|
19
21
|
expect(all_permissions.any? { |perm| perm['name'] == 'test_permission' }).to eq(true)
|
|
20
22
|
@client.update_permission(name: 'test_permission', new_name: 'test_permission_2')
|
|
@@ -4,6 +4,8 @@ require 'spec_helper'
|
|
|
4
4
|
|
|
5
5
|
describe Descope::Api::V1::Management::Project do
|
|
6
6
|
before(:all) do
|
|
7
|
+
raise 'DESCOPE_MANAGEMENT_KEY is not set' if ENV['DESCOPE_MANAGEMENT_KEY'].nil?
|
|
8
|
+
|
|
7
9
|
@client = DescopeClient.new(Configuration.config)
|
|
8
10
|
@export_output = @client.export_project
|
|
9
11
|
end
|
|
@@ -4,6 +4,8 @@ require 'spec_helper'
|
|
|
4
4
|
|
|
5
5
|
describe Descope::Api::V1::Management::Role do
|
|
6
6
|
before(:all) do
|
|
7
|
+
raise 'DESCOPE_MANAGEMENT_KEY is not set' if ENV['DESCOPE_MANAGEMENT_KEY'].nil?
|
|
8
|
+
|
|
7
9
|
@client = DescopeClient.new(Configuration.config)
|
|
8
10
|
@client.logger.info('Staring cleanup before tests...')
|
|
9
11
|
@client.logger.info('Deleting all permissions for Ruby SDK...')
|
|
@@ -96,7 +98,7 @@ describe Descope::Api::V1::Management::Role do
|
|
|
96
98
|
expect(all_roles.map { |role| role['name'] }).to include('Ruby-SDK-test-admin')
|
|
97
99
|
|
|
98
100
|
@client.logger.info('searching for roles with tenant ids...')
|
|
99
|
-
all_roles = @client.search_roles(
|
|
101
|
+
all_roles = @client.search_roles(role_name_like: 'Ruby-SDK-test', tenant_ids: [tenant_id])['roles']
|
|
100
102
|
expect(all_roles.map { |role| role['name'] }).to include('Ruby-SDK-test-admin')
|
|
101
103
|
|
|
102
104
|
@client.logger.info('deleting permission')
|
|
@@ -4,17 +4,21 @@ require 'spec_helper'
|
|
|
4
4
|
|
|
5
5
|
describe Descope::Api::V1::Management::User do
|
|
6
6
|
before(:all) do
|
|
7
|
+
raise 'DESCOPE_MANAGEMENT_KEY is not set' if ENV['DESCOPE_MANAGEMENT_KEY'].nil?
|
|
8
|
+
|
|
9
|
+
@client = DescopeClient.new(Configuration.config)
|
|
10
|
+
|
|
7
11
|
@password = SpecUtils.generate_password
|
|
8
12
|
@new_password = SpecUtils.generate_password
|
|
9
13
|
@user = build(:user)
|
|
10
|
-
|
|
14
|
+
|
|
11
15
|
include Descope::Mixins::Common::DeliveryMethod
|
|
12
16
|
end
|
|
13
17
|
|
|
14
18
|
after(:all) do
|
|
15
19
|
all_users = @client.search_all_users
|
|
16
20
|
all_users['users'].each do |user|
|
|
17
|
-
if user['middleName'] ==
|
|
21
|
+
if user['middleName'] == "#{SpecUtils.build_prefix}Ruby-SDK-User"
|
|
18
22
|
puts "Deleting ruby spec test user #{user['loginIds'][0]}"
|
|
19
23
|
@client.delete_user(user['loginIds'][0])
|
|
20
24
|
end
|
|
@@ -58,6 +62,41 @@ describe Descope::Api::V1::Management::User do
|
|
|
58
62
|
expect(updated_user['first_name']).to eq(created_user[updated_first_name])
|
|
59
63
|
end
|
|
60
64
|
|
|
65
|
+
it 'should patch a user' do
|
|
66
|
+
user = build(:user)
|
|
67
|
+
role_name = 'some-new-role'
|
|
68
|
+
|
|
69
|
+
# ensure no roles exist with that name
|
|
70
|
+
all_roles = @client.load_all_roles
|
|
71
|
+
all_roles['roles'].each do |role|
|
|
72
|
+
@client.delete_role(name: role['name']) if role['name'] == role_name
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
@client.create_role(name: role_name)
|
|
76
|
+
@client.create_user(**user)['user']
|
|
77
|
+
updated_first_name = 'new name'
|
|
78
|
+
updated_given_name = 'new given name'
|
|
79
|
+
update_phone_number = "+1#{Faker::Number.number(digits: 10)}"
|
|
80
|
+
updated_role_names = [role_name]
|
|
81
|
+
updated_middle_name = 'new middle name'
|
|
82
|
+
updated_user = @client.patch_user(
|
|
83
|
+
**user,
|
|
84
|
+
name: updated_first_name,
|
|
85
|
+
given_name: updated_given_name,
|
|
86
|
+
phone: update_phone_number,
|
|
87
|
+
role_names: updated_role_names,
|
|
88
|
+
middle_name: updated_middle_name
|
|
89
|
+
)['user']
|
|
90
|
+
|
|
91
|
+
puts "updated_user #{updated_user}"
|
|
92
|
+
|
|
93
|
+
expect(updated_user['name']).to eq(updated_first_name)
|
|
94
|
+
expect(updated_user['givenName']).to eq(updated_given_name)
|
|
95
|
+
expect(updated_user['phone']).to eq(update_phone_number)
|
|
96
|
+
expect(updated_user['roleNames']).to eq(updated_role_names)
|
|
97
|
+
expect(updated_user['middleName']).to eq(updated_middle_name)
|
|
98
|
+
end
|
|
99
|
+
|
|
61
100
|
it 'should delete a user' do
|
|
62
101
|
user = build(:user)
|
|
63
102
|
created_user = @client.create_user(**user)['user']
|
|
@@ -77,18 +116,28 @@ describe Descope::Api::V1::Management::User do
|
|
|
77
116
|
users = FactoryBot.build_list(:user, 5)
|
|
78
117
|
@client.create_batch_users(users)
|
|
79
118
|
all_users = @client.search_all_users
|
|
80
|
-
sdk_users = all_users['users'].select { |user| user['middleName'] ==
|
|
119
|
+
sdk_users = all_users['users'].select { |user| user['middleName'] == "#{SpecUtils.build_prefix}Ruby-SDK-User" }
|
|
81
120
|
expect(sdk_users.length).to be >= 5
|
|
82
121
|
end
|
|
83
122
|
|
|
84
123
|
it 'should create a test user' do
|
|
85
124
|
@client.delete_all_test_users
|
|
125
|
+
# ensure no roles exist with that name
|
|
126
|
+
role_name = 'some-new-role'
|
|
127
|
+
all_roles = @client.load_all_roles
|
|
128
|
+
all_roles['roles'].each do |role|
|
|
129
|
+
@client.delete_role(name: role['name']) if role['name'] == role_name
|
|
130
|
+
end
|
|
86
131
|
sleep 5
|
|
132
|
+
|
|
87
133
|
user_args = build(:user)
|
|
88
134
|
test_user = @client.create_test_user(**user_args)['user']
|
|
89
|
-
|
|
135
|
+
@client.create_role(name: role_name)
|
|
136
|
+
@client.user_add_roles(login_id: test_user['loginIds'][0], role_names: [role_name])
|
|
137
|
+
test_users = @client.search_all_test_users(role_names: [role_name])['users']
|
|
90
138
|
expect(test_users.length).to be >= 1
|
|
91
139
|
expect(test_users[0]['loginIds'][0]).to eq(test_user['loginIds'][0])
|
|
140
|
+
expect(test_users[0]['roleNames']).to eq([role_name])
|
|
92
141
|
end
|
|
93
142
|
|
|
94
143
|
it 'should update user status' do
|
|
@@ -191,8 +240,8 @@ describe Descope::Api::V1::Management::User do
|
|
|
191
240
|
new_password = SpecUtils.generate_password
|
|
192
241
|
@client.set_password(login_id: user['loginIds'][0], password: new_password)
|
|
193
242
|
@client.password_sign_in(login_id: user['loginIds'][0], password:)
|
|
194
|
-
rescue Descope::
|
|
195
|
-
expect(e.message).to match(/"
|
|
243
|
+
rescue Descope::Unauthorized => e
|
|
244
|
+
expect(e.message).to match(/"Invalid signin credentials"/)
|
|
196
245
|
end
|
|
197
246
|
end
|
|
198
247
|
|
|
@@ -51,7 +51,7 @@ describe Descope::Api::V1::EnchantedLink do
|
|
|
51
51
|
|
|
52
52
|
it 'is expected to validate refresh token and not raise an error with refresh token and valid login options' do
|
|
53
53
|
expect do
|
|
54
|
-
@instance.send(:validate_refresh_token_provided, { mfa: true, stepup: true },
|
|
54
|
+
@instance.send(:validate_refresh_token_provided, { mfa: true, stepup: true }, 'some-token')
|
|
55
55
|
end.not_to raise_error
|
|
56
56
|
end
|
|
57
57
|
|
|
@@ -148,7 +148,16 @@ describe Descope::Api::V1::EnchantedLink do
|
|
|
148
148
|
end
|
|
149
149
|
|
|
150
150
|
it 'is expected to get session by pending ref with enchanted link' do
|
|
151
|
-
jwt_response = {
|
|
151
|
+
jwt_response = {
|
|
152
|
+
'sessionJwt' => 'fake_session_jwt',
|
|
153
|
+
'refreshJwt' => 'fake_refresh_jwt',
|
|
154
|
+
'cookies' => {
|
|
155
|
+
'refresh_token' => 'fake_refresh_cookie'
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
allow(@instance).to receive(:post).with(
|
|
159
|
+
GET_SESSION_ENCHANTEDLINK_AUTH_PATH, { pendingRef: 'pendingRef' }
|
|
160
|
+
).and_return(jwt_response)
|
|
152
161
|
allow(@instance).to receive(:generate_jwt_response).and_return(jwt_response)
|
|
153
162
|
|
|
154
163
|
expect do
|
|
@@ -11,14 +11,15 @@ describe Descope::Api::V1::OTP do
|
|
|
11
11
|
@instance = dummy_instance
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
+
# Sign In methods
|
|
14
15
|
context '.sign_in' do
|
|
15
16
|
it 'is expected to respond to sign in using otp' do
|
|
16
17
|
expect(@instance).to respond_to(:otp_sign_in)
|
|
17
18
|
end
|
|
18
19
|
|
|
19
|
-
it 'is expected to sign in with otp' do
|
|
20
|
+
it 'is expected to sign in with otp with email' do
|
|
20
21
|
request_params = {
|
|
21
|
-
loginId: '
|
|
22
|
+
loginId: 'dummy@dummy.com',
|
|
22
23
|
loginOptions: {
|
|
23
24
|
stepup: false,
|
|
24
25
|
customClaims: { 'abc': '123' },
|
|
@@ -38,7 +39,7 @@ describe Descope::Api::V1::OTP do
|
|
|
38
39
|
expect do
|
|
39
40
|
@instance.otp_sign_in(
|
|
40
41
|
method: DeliveryMethod::EMAIL,
|
|
41
|
-
login_id: '
|
|
42
|
+
login_id: 'dummy@dummy.com',
|
|
42
43
|
login_options: {
|
|
43
44
|
stepup: false,
|
|
44
45
|
custom_claims: { 'abc': '123' },
|
|
@@ -50,15 +51,15 @@ describe Descope::Api::V1::OTP do
|
|
|
50
51
|
end.not_to raise_error
|
|
51
52
|
end
|
|
52
53
|
|
|
53
|
-
it 'is expected to sign in with otp phone' do
|
|
54
|
+
it 'is expected to sign in with otp phone SMS' do
|
|
54
55
|
request_params = {
|
|
55
|
-
loginId: '
|
|
56
|
+
loginId: '+12122242225',
|
|
56
57
|
loginOptions: {
|
|
57
58
|
stepup: false,
|
|
58
59
|
customClaims: { 'abc': '123' },
|
|
59
60
|
mfa: false,
|
|
60
61
|
ssoAppId: 'sso-id'
|
|
61
|
-
}
|
|
62
|
+
}
|
|
62
63
|
}
|
|
63
64
|
expect(@instance).to receive(:post).with(
|
|
64
65
|
otp_compose_signin_url(DeliveryMethod::SMS),
|
|
@@ -76,7 +77,45 @@ describe Descope::Api::V1::OTP do
|
|
|
76
77
|
expect do
|
|
77
78
|
@instance.otp_sign_in(
|
|
78
79
|
method: DeliveryMethod::SMS,
|
|
79
|
-
login_id: '
|
|
80
|
+
login_id: '+12122242225',
|
|
81
|
+
login_options: {
|
|
82
|
+
stepup: false,
|
|
83
|
+
custom_claims: { 'abc': '123' },
|
|
84
|
+
mfa: false,
|
|
85
|
+
sso_app_id: 'sso-id'
|
|
86
|
+
},
|
|
87
|
+
refresh_token: 'refresh_token'
|
|
88
|
+
)
|
|
89
|
+
end.not_to raise_error
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it 'is expected to sign in with otp Voice' do
|
|
93
|
+
request_params = {
|
|
94
|
+
loginId: '+12122242225',
|
|
95
|
+
loginOptions: {
|
|
96
|
+
stepup: false,
|
|
97
|
+
customClaims: { 'abc': '123' },
|
|
98
|
+
mfa: false,
|
|
99
|
+
ssoAppId: 'sso-id'
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
expect(@instance).to receive(:post).with(
|
|
103
|
+
otp_compose_signin_url(DeliveryMethod::VOICE),
|
|
104
|
+
request_params,
|
|
105
|
+
{},
|
|
106
|
+
'refresh_token'
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
allow_any_instance_of(Descope::Api::V1::Auth::OTP).to receive(:extract_masked_address).and_return(
|
|
110
|
+
{
|
|
111
|
+
'maskedPhone' => '+1******890'
|
|
112
|
+
}
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
expect do
|
|
116
|
+
@instance.otp_sign_in(
|
|
117
|
+
method: DeliveryMethod::VOICE,
|
|
118
|
+
login_id: '+12122242225',
|
|
80
119
|
login_options: {
|
|
81
120
|
stepup: false,
|
|
82
121
|
custom_claims: { 'abc': '123' },
|
|
@@ -89,6 +128,7 @@ describe Descope::Api::V1::OTP do
|
|
|
89
128
|
end
|
|
90
129
|
end
|
|
91
130
|
|
|
131
|
+
# Sign Up methods
|
|
92
132
|
context '.sign_up' do
|
|
93
133
|
it 'is expected to respond to otp email sign up' do
|
|
94
134
|
expect(@instance).to respond_to(:otp_sign_up)
|
|
@@ -96,7 +136,7 @@ describe Descope::Api::V1::OTP do
|
|
|
96
136
|
|
|
97
137
|
it 'is expected to sign up with otp via email' do
|
|
98
138
|
request_params = {
|
|
99
|
-
loginId: '
|
|
139
|
+
loginId: 'user1',
|
|
100
140
|
user: { loginId: 'user1', email: 'dummy@dummy.com' },
|
|
101
141
|
email: 'dummy@dummy.com'
|
|
102
142
|
}
|
|
@@ -110,18 +150,18 @@ describe Descope::Api::V1::OTP do
|
|
|
110
150
|
|
|
111
151
|
expect do
|
|
112
152
|
@instance.otp_sign_up(
|
|
113
|
-
login_id: '
|
|
153
|
+
login_id: 'user1',
|
|
114
154
|
method: DeliveryMethod::EMAIL,
|
|
115
155
|
user: { login_id: 'user1', email: 'dummy@dummy.com' }
|
|
116
156
|
)
|
|
117
157
|
end.not_to raise_error
|
|
118
158
|
end
|
|
119
159
|
|
|
120
|
-
it 'is expected to sign up with otp via
|
|
160
|
+
it 'is expected to sign up with otp via SMS' do
|
|
121
161
|
request_params = {
|
|
122
|
-
loginId: '
|
|
123
|
-
user: { loginId: '
|
|
124
|
-
phone: '
|
|
162
|
+
loginId: '+1234567890',
|
|
163
|
+
user: { loginId: '+1234567890' },
|
|
164
|
+
phone: ''
|
|
125
165
|
}
|
|
126
166
|
|
|
127
167
|
expect(@instance).to receive(:post).with(
|
|
@@ -133,22 +173,46 @@ describe Descope::Api::V1::OTP do
|
|
|
133
173
|
|
|
134
174
|
expect do
|
|
135
175
|
@instance.otp_sign_up(
|
|
136
|
-
login_id: '
|
|
176
|
+
login_id: '+1234567890',
|
|
137
177
|
method: DeliveryMethod::SMS,
|
|
138
|
-
user: { login_id: '
|
|
178
|
+
user: { login_id: '+1234567890' }
|
|
179
|
+
)
|
|
180
|
+
end.not_to raise_error
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
it 'is expected to sign up with otp via Voice' do
|
|
184
|
+
request_params = {
|
|
185
|
+
loginId: '+1234567890',
|
|
186
|
+
user: { loginId: '+1234567890', phone: '+1234567890' },
|
|
187
|
+
phone: '+1234567890'
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
expect(@instance).to receive(:post).with(
|
|
191
|
+
otp_compose_signup_url(DeliveryMethod::VOICE),
|
|
192
|
+
request_params
|
|
193
|
+
).and_return({ 'maskedPhone' => '+1******890' })
|
|
194
|
+
|
|
195
|
+
allow_any_instance_of(Descope::Api::V1::Auth).to receive(:extract_masked_address).and_return({})
|
|
196
|
+
|
|
197
|
+
expect do
|
|
198
|
+
@instance.otp_sign_up(
|
|
199
|
+
login_id: '+1234567890',
|
|
200
|
+
method: DeliveryMethod::VOICE,
|
|
201
|
+
user: { login_id: '+1234567890', phone: '+1234567890' }
|
|
139
202
|
)
|
|
140
203
|
end.not_to raise_error
|
|
141
204
|
end
|
|
142
205
|
end
|
|
143
206
|
|
|
207
|
+
# Sign Up or In methods
|
|
144
208
|
context '.sign_up_or_in' do
|
|
145
209
|
it 'is expected to respond to sign up' do
|
|
146
210
|
expect(@instance).to respond_to(:otp_sign_up_or_in)
|
|
147
211
|
end
|
|
148
212
|
|
|
149
|
-
it 'is expected to sign up or in with otp' do
|
|
213
|
+
it 'is expected to sign up or in with otp via email' do
|
|
150
214
|
request_params = {
|
|
151
|
-
loginId: '
|
|
215
|
+
loginId: 'dummy@dummy.com',
|
|
152
216
|
loginOptions: {
|
|
153
217
|
stepup: false,
|
|
154
218
|
customClaims: { 'abc': '123' },
|
|
@@ -168,7 +232,79 @@ describe Descope::Api::V1::OTP do
|
|
|
168
232
|
expect do
|
|
169
233
|
@instance.otp_sign_up_or_in(
|
|
170
234
|
method: DeliveryMethod::EMAIL,
|
|
171
|
-
login_id: '
|
|
235
|
+
login_id: 'dummy@dummy.com',
|
|
236
|
+
login_options: {
|
|
237
|
+
stepup: false,
|
|
238
|
+
custom_claims: { 'abc': '123' },
|
|
239
|
+
mfa: false,
|
|
240
|
+
sso_app_id: 'sso-id'
|
|
241
|
+
},
|
|
242
|
+
provider_id: 'provider-id',
|
|
243
|
+
template_id: 'template-id',
|
|
244
|
+
sso_app_id: 'sso-id'
|
|
245
|
+
)
|
|
246
|
+
end.not_to raise_error
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
it 'is expected to sign up or in with otp via SMS' do
|
|
250
|
+
request_params = {
|
|
251
|
+
loginId: '+12122242225',
|
|
252
|
+
loginOptions: {
|
|
253
|
+
stepup: false,
|
|
254
|
+
customClaims: { 'abc': '123' },
|
|
255
|
+
mfa: false,
|
|
256
|
+
ssoAppId: 'sso-id'
|
|
257
|
+
},
|
|
258
|
+
providerId: 'provider-id',
|
|
259
|
+
templateId: 'template-id',
|
|
260
|
+
ssoAppId: 'sso-id'
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
expect(@instance).to receive(:post).with(
|
|
264
|
+
otp_compose_sign_up_or_in_url(DeliveryMethod::SMS),
|
|
265
|
+
request_params
|
|
266
|
+
).and_return({ 'maskedPhone' => '+1******890' })
|
|
267
|
+
|
|
268
|
+
expect do
|
|
269
|
+
@instance.otp_sign_up_or_in(
|
|
270
|
+
method: DeliveryMethod::SMS,
|
|
271
|
+
login_id: '+12122242225',
|
|
272
|
+
login_options: {
|
|
273
|
+
stepup: false,
|
|
274
|
+
custom_claims: { 'abc': '123' },
|
|
275
|
+
mfa: false,
|
|
276
|
+
sso_app_id: 'sso-id'
|
|
277
|
+
},
|
|
278
|
+
provider_id: 'provider-id',
|
|
279
|
+
template_id: 'template-id',
|
|
280
|
+
sso_app_id: 'sso-id'
|
|
281
|
+
)
|
|
282
|
+
end.not_to raise_error
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
it 'is expected to sign up or in with otp via Voice' do
|
|
286
|
+
request_params = {
|
|
287
|
+
loginId: '+12122242225',
|
|
288
|
+
loginOptions: {
|
|
289
|
+
stepup: false,
|
|
290
|
+
customClaims: { 'abc': '123' },
|
|
291
|
+
mfa: false,
|
|
292
|
+
ssoAppId: 'sso-id'
|
|
293
|
+
},
|
|
294
|
+
providerId: 'provider-id',
|
|
295
|
+
templateId: 'template-id',
|
|
296
|
+
ssoAppId: 'sso-id'
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
expect(@instance).to receive(:post).with(
|
|
300
|
+
otp_compose_sign_up_or_in_url(DeliveryMethod::VOICE),
|
|
301
|
+
request_params
|
|
302
|
+
).and_return({ 'maskedPhone' => '+1******890' })
|
|
303
|
+
|
|
304
|
+
expect do
|
|
305
|
+
@instance.otp_sign_up_or_in(
|
|
306
|
+
method: DeliveryMethod::VOICE,
|
|
307
|
+
login_id: '+12122242225',
|
|
172
308
|
login_options: {
|
|
173
309
|
stepup: false,
|
|
174
310
|
custom_claims: { 'abc': '123' },
|
|
@@ -215,6 +351,28 @@ describe Descope::Api::V1::OTP do
|
|
|
215
351
|
expect(@instance).to respond_to(:otp_update_user_email)
|
|
216
352
|
end
|
|
217
353
|
|
|
354
|
+
it 'raises a validation error' do
|
|
355
|
+
expect { OTP.otp_update_user_phone(login_id: nil) }
|
|
356
|
+
.to raise_error('login_id cannot be empty')
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
it 'raises a validation error' do
|
|
360
|
+
expect { OTP.otp_update_user_phone(login_id: 'someone', phone: nil) }
|
|
361
|
+
.to raise_error('Phone number cannot be empty')
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
it 'raises a delivery method error with invalid method' do
|
|
365
|
+
expect do
|
|
366
|
+
OTP.otp_update_user_phone(login_id: 'abc', phone: '+12124332222', method: 0)
|
|
367
|
+
end.to raise_error(Descope::AuthException, /Delivery method should be one of the following/)
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
it 'raises a validation error when phone number doesnt match pattern' do
|
|
371
|
+
expect do
|
|
372
|
+
OTP.otp_update_user_phone(login_id: 'abc', phone: '-1212a$', method: DeliveryMethod::SMS)
|
|
373
|
+
end.to raise_error(Descope::AuthException, /Invalid pattern for phone number/)
|
|
374
|
+
end
|
|
375
|
+
|
|
218
376
|
it 'is expected to update email with otp' do
|
|
219
377
|
request_params = {
|
|
220
378
|
loginId: 'test',
|
|
@@ -43,9 +43,18 @@ describe Descope::Api::V1::Password do
|
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
it 'is expected to sign in with password' do
|
|
46
|
+
response_body = {
|
|
47
|
+
'sessionJwt' => 'fake_session_jwt',
|
|
48
|
+
'refreshJwt' => 'fake_refresh_jwt',
|
|
49
|
+
'cookies' => {
|
|
50
|
+
'refresh_token' => 'fake_refresh_cookie'
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
46
54
|
expect(@instance).to receive(:post).with(
|
|
47
55
|
SIGN_IN_PASSWORD_PATH, { loginId: 'test', password: 's3cr3t', ssoAppId: nil }
|
|
48
|
-
)
|
|
56
|
+
).and_return(response_body)
|
|
57
|
+
|
|
49
58
|
# stub the jwt_get_unverified_header method to return the kid of the public key created above
|
|
50
59
|
allow(@instance).to receive(:generate_jwt_response).and_return({})
|
|
51
60
|
expect { @instance.password_sign_in(login_id: 'test', password: 's3cr3t') }.not_to raise_error
|