workos 2.2.1 → 2.5.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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +2 -2
  3. data/README.md +4 -1
  4. data/lib/workos/audit_trail.rb +1 -1
  5. data/lib/workos/challenge.rb +1 -1
  6. data/lib/workos/client.rb +14 -5
  7. data/lib/workos/configuration.rb +17 -0
  8. data/lib/workos/directory_group.rb +22 -1
  9. data/lib/workos/directory_sync.rb +3 -1
  10. data/lib/workos/directory_user.rb +12 -1
  11. data/lib/workos/errors.rb +3 -0
  12. data/lib/workos/factor.rb +1 -6
  13. data/lib/workos/mfa.rb +22 -7
  14. data/lib/workos/organizations.rb +1 -1
  15. data/lib/workos/passwordless.rb +0 -1
  16. data/lib/workos/portal.rb +0 -1
  17. data/lib/workos/sso.rb +2 -2
  18. data/lib/workos/types/challenge_struct.rb +1 -1
  19. data/lib/workos/types/directory_group_struct.rb +6 -0
  20. data/lib/workos/types/directory_user_struct.rb +2 -0
  21. data/lib/workos/types/factor_struct.rb +0 -1
  22. data/lib/workos/types/{verify_factor_struct.rb → verify_challenge_struct.rb} +3 -3
  23. data/lib/workos/types.rb +1 -1
  24. data/lib/workos/{verify_factor.rb → verify_challenge.rb} +5 -6
  25. data/lib/workos/version.rb +1 -1
  26. data/lib/workos.rb +17 -7
  27. data/spec/lib/workos/configuration_spec.rb +61 -0
  28. data/spec/lib/workos/directory_sync_spec.rb +26 -19
  29. data/spec/lib/workos/directory_user_spec.rb +36 -0
  30. data/spec/lib/workos/mfa_spec.rb +93 -74
  31. data/spec/lib/workos/sso_spec.rb +1 -1
  32. data/spec/spec_helper.rb +2 -2
  33. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_group.yml +47 -29
  34. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_user.yml +28 -31
  35. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_after.yml +46 -32
  36. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_before.yml +47 -31
  37. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_directory.yml +46 -34
  38. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_limit.yml +41 -31
  39. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_no_options.yml +36 -26
  40. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_user.yml +38 -28
  41. data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_generic_valid.yml +2 -2
  42. data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_sms_valid.yml +2 -2
  43. data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_totp_valid.yml +3 -3
  44. data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_generic_valid.yml +1 -1
  45. data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_sms_valid.yml +1 -1
  46. data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_totp_valid.yml +1 -1
  47. data/spec/support/fixtures/vcr_cassettes/mfa/get_factor_valid.yml +1 -1
  48. data/spec/support/fixtures/vcr_cassettes/mfa/{verify_factor_generic_expired.yml → verify_challenge_generic_expired.yml} +2 -2
  49. data/spec/support/fixtures/vcr_cassettes/mfa/{verify_factor_generic_invalid.yml → verify_challenge_generic_invalid.yml} +2 -2
  50. data/spec/support/fixtures/vcr_cassettes/mfa/{verify_factor_generic_valid.yml → verify_challenge_generic_valid.yml} +2 -2
  51. data/spec/support/fixtures/vcr_cassettes/mfa/{verify_factor_generic_valid_is_false.yml → verify_challenge_generic_valid_is_false.yml} +2 -2
  52. metadata +18 -16
  53. data/lib/workos/base.rb +0 -18
  54. data/spec/lib/workos/base_spec.rb +0 -30
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+ # typed: false
3
+
4
+ describe WorkOS do
5
+ describe '.configure' do
6
+ context 'with key and no timeout' do
7
+ before do
8
+ WorkOS.configure do |config|
9
+ config.key = 'example_api_key'
10
+ end
11
+ end
12
+
13
+ it 'sets the key and default timeout configuration' do
14
+ expect(WorkOS.config.key).to eq('example_api_key')
15
+ expect(WorkOS.config.timeout).to eq(60)
16
+ end
17
+ end
18
+
19
+ context 'with key and timeout' do
20
+ before do
21
+ WorkOS.configure do |config|
22
+ config.key = 'example_api_key'
23
+ config.timeout = 120
24
+ end
25
+ end
26
+
27
+ it 'sets the key and timeout configuration' do
28
+ expect(WorkOS.config.key).to eq('example_api_key')
29
+ expect(WorkOS.config.timeout).to eq(120)
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ describe WorkOS::Configuration do
36
+ describe '.key!' do
37
+ context 'with key set' do
38
+ before do
39
+ WorkOS.config.key = 'example_api_key'
40
+ end
41
+
42
+ it 'returns the key' do
43
+ expect(WorkOS.config.key!).to eq('example_api_key')
44
+ end
45
+ end
46
+
47
+ context 'with key not set' do
48
+ before do
49
+ WorkOS.config.key = nil
50
+ end
51
+
52
+ it 'throws an error' do
53
+ expect do
54
+ WorkOS.config.key!
55
+ end.to raise_error(
56
+ '`WorkOS.config.key` not set',
57
+ )
58
+ end
59
+ end
60
+ end
61
+ end
@@ -189,7 +189,7 @@ describe WorkOS::DirectorySync do
189
189
  context 'with directory option' do
190
190
  it 'forms the proper request to the API' do
191
191
  request_args = [
192
- '/directory_groups?directory=directory_01EK2YEMVTWGX27STRDR0N3MP9',
192
+ '/directory_groups?directory=directory_01G2Z8ADK5NPMVTWF48MVVE4HT',
193
193
  'Content-Type' => 'application/json'
194
194
  ]
195
195
 
@@ -200,7 +200,7 @@ describe WorkOS::DirectorySync do
200
200
 
201
201
  VCR.use_cassette 'directory_sync/list_groups/with_directory' do
202
202
  groups = described_class.list_groups(
203
- directory: 'directory_01EK2YEMVTWGX27STRDR0N3MP9',
203
+ directory: 'directory_01G2Z8ADK5NPMVTWF48MVVE4HT',
204
204
  )
205
205
 
206
206
  expect(groups.data.size).to eq(10)
@@ -212,7 +212,7 @@ describe WorkOS::DirectorySync do
212
212
  context 'with user option' do
213
213
  it 'forms the proper request to the API' do
214
214
  request_args = [
215
- '/directory_groups?user=directory_user_01EK2YFBC3R10MPB4W49G5QDXG',
215
+ '/directory_groups?user=directory_user_01G2Z8D4FDB28ZNSRRBVCF2E0P',
216
216
  'Content-Type' => 'application/json'
217
217
  ]
218
218
 
@@ -223,7 +223,7 @@ describe WorkOS::DirectorySync do
223
223
 
224
224
  VCR.use_cassette 'directory_sync/list_groups/with_user' do
225
225
  groups = described_class.list_groups(
226
- user: 'directory_user_01EK2YFBC3R10MPB4W49G5QDXG',
226
+ user: 'directory_user_01G2Z8D4FDB28ZNSRRBVCF2E0P',
227
227
  )
228
228
 
229
229
  expect(groups.data.size).to eq(3)
@@ -234,8 +234,8 @@ describe WorkOS::DirectorySync do
234
234
  context 'with the before option' do
235
235
  it 'forms the proper request to the API' do
236
236
  request_args = [
237
- '/directory_groups?before=before-id&' \
238
- 'directory=directory_01EK2YEMVTWGX27STRDR0N3MP9',
237
+ '/directory_groups?before=directory_group_01G2Z8D4ZR8RJ03Y1W7P9K8NMG&' \
238
+ 'directory=directory_01G2Z8ADK5NPMVTWF48MVVE4HT',
239
239
  'Content-Type' => 'application/json'
240
240
  ]
241
241
 
@@ -246,11 +246,11 @@ describe WorkOS::DirectorySync do
246
246
 
247
247
  VCR.use_cassette 'directory_sync/list_groups/with_before' do
248
248
  groups = described_class.list_groups(
249
- before: 'before-id',
250
- directory: 'directory_01EK2YEMVTWGX27STRDR0N3MP9',
249
+ before: 'directory_group_01G2Z8D4ZR8RJ03Y1W7P9K8NMG',
250
+ directory: 'directory_01G2Z8ADK5NPMVTWF48MVVE4HT',
251
251
  )
252
252
 
253
- expect(groups.data.size).to eq(2)
253
+ expect(groups.data.size).to eq(10)
254
254
  end
255
255
  end
256
256
  end
@@ -258,8 +258,8 @@ describe WorkOS::DirectorySync do
258
258
  context 'with the after option' do
259
259
  it 'forms the proper request to the API' do
260
260
  request_args = [
261
- '/directory_groups?after=after-id&' \
262
- 'directory=directory_01EK2YEMVTWGX27STRDR0N3MP9',
261
+ '/directory_groups?after=directory_group_01G2Z8D4ZR8RJ03Y1W7P9K8NMG&' \
262
+ 'directory=directory_01G2Z8ADK5NPMVTWF48MVVE4HT',
263
263
  'Content-Type' => 'application/json'
264
264
  ]
265
265
 
@@ -270,11 +270,11 @@ describe WorkOS::DirectorySync do
270
270
 
271
271
  VCR.use_cassette 'directory_sync/list_groups/with_after' do
272
272
  groups = described_class.list_groups(
273
- after: 'after-id',
274
- directory: 'directory_01EK2YEMVTWGX27STRDR0N3MP9',
273
+ after: 'directory_group_01G2Z8D4ZR8RJ03Y1W7P9K8NMG',
274
+ directory: 'directory_01G2Z8ADK5NPMVTWF48MVVE4HT',
275
275
  )
276
276
 
277
- expect(groups.data.size).to eq(10)
277
+ expect(groups.data.size).to eq(9)
278
278
  end
279
279
  end
280
280
  end
@@ -283,7 +283,7 @@ describe WorkOS::DirectorySync do
283
283
  it 'forms the proper request to the API' do
284
284
  request_args = [
285
285
  '/directory_groups?limit=2&' \
286
- 'directory=directory_01EK2YEMVTWGX27STRDR0N3MP9',
286
+ 'directory=directory_01G2Z8ADK5NPMVTWF48MVVE4HT',
287
287
  'Content-Type' => 'application/json'
288
288
  ]
289
289
 
@@ -295,7 +295,7 @@ describe WorkOS::DirectorySync do
295
295
  VCR.use_cassette 'directory_sync/list_groups/with_limit' do
296
296
  groups = described_class.list_groups(
297
297
  limit: 2,
298
- directory: 'directory_01EK2YEMVTWGX27STRDR0N3MP9',
298
+ directory: 'directory_01G2Z8ADK5NPMVTWF48MVVE4HT',
299
299
  )
300
300
 
301
301
  expect(groups.data.size).to eq(2)
@@ -438,11 +438,16 @@ describe WorkOS::DirectorySync do
438
438
  it 'returns a group' do
439
439
  VCR.use_cassette('directory_sync/get_group') do
440
440
  group = WorkOS::DirectorySync.get_group(
441
- 'directory_grp_01E64QTDNS0EGJ0FMCVY9BWGZT',
441
+ 'directory_group_01G2Z8D4ZR8RJ03Y1W7P9K8NMG',
442
442
  )
443
443
 
444
- expect(group['name']).to eq('Walrus')
445
- expect(group.name).to eq('Walrus')
444
+ expect(group['directory_id']).to eq('directory_01G2Z8ADK5NPMVTWF48MVVE4HT')
445
+ expect(group['organization_id']).to eq('org_01EGS4P7QR31EZ4YWD1Z1XA176')
446
+ expect(group['idp_id']).to eq('01jlao4614two3d')
447
+ expect(group['name']).to eq('Sales')
448
+ expect(group.name).to eq('Sales')
449
+ expect(group['created_at']).to eq('2022-05-13T17:45:31.732Z')
450
+ expect(group['updated_at']).to eq('2022-07-13T17:45:42.618Z')
446
451
  end
447
452
  end
448
453
  end
@@ -467,6 +472,8 @@ describe WorkOS::DirectorySync do
467
472
  )
468
473
 
469
474
  expect(user['first_name']).to eq('Logan')
475
+ expect(user.directory_id).to eq('directory_01FAZYMST676QMTFN1DDJZZX87')
476
+ expect(user.organization_id).to eq('org_01FAZWCWR03DVWA83NCJYKKD54')
470
477
  expect(user.first_name).to eq('Logan')
471
478
  end
472
479
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+ # typed: false
3
+
4
+ describe WorkOS::DirectoryUser do
5
+ # rubocop:disable Layout/LineLength
6
+ describe '.get_primary_email' do
7
+ context 'with one primary email' do
8
+ it 'returns the primary email' do
9
+ user = WorkOS::DirectoryUser.new('{"object":"directory_user","id":"directory_user_01FAZYNPC8M0HRYTKFP2GNX852","directory_id":"directory_01FAZYMST676QMTFN1DDJZZX87","idp_id":"6092c280a3f1e19ef6d8cef8","username":"logan@workos.com","emails":[{"primary":true,"value":"logan@workos.com"}, {"primary":false,"value":"logan@gmail.com"}],"first_name":"Logan","last_name":"Gingerich","state":"active","raw_attributes":{},"custom_attributes":{},"groups":[]}')
10
+ expect(user.primary_email).to eq('logan@workos.com')
11
+ end
12
+ end
13
+
14
+ context 'with multiple primary emails' do
15
+ it 'returns the first email marked as primary' do
16
+ user = WorkOS::DirectoryUser.new('{"object":"directory_user","id":"directory_user_01FAZYNPC8M0HRYTKFP2GNX852","directory_id":"directory_01FAZYMST676QMTFN1DDJZZX87","idp_id":"6092c280a3f1e19ef6d8cef8","username":"logan@workos.com","emails":[{"primary":true,"value":"logan@workos.com"}, {"primary":true,"value":"logan@gmail.com"}],"first_name":"Logan","last_name":"Gingerich","state":"active","raw_attributes":{},"custom_attributes":{},"groups":[]}')
17
+ expect(user.primary_email).to eq('logan@workos.com')
18
+ end
19
+ end
20
+
21
+ context 'with no primary emails' do
22
+ it 'returns nil' do
23
+ user = WorkOS::DirectoryUser.new('{"object":"directory_user","id":"directory_user_01FAZYNPC8M0HRYTKFP2GNX852","directory_id":"directory_01FAZYMST676QMTFN1DDJZZX87","idp_id":"6092c280a3f1e19ef6d8cef8","username":"logan@workos.com","emails":[{"primary":false,"value":"logan@gmail.com"}],"first_name":"Logan","last_name":"Gingerich","state":"active","raw_attributes":{},"custom_attributes":{},"groups":[]}')
24
+ expect(user.primary_email).to eq(nil)
25
+ end
26
+ end
27
+
28
+ context 'with an empty email array' do
29
+ it 'returns nil' do
30
+ user = WorkOS::DirectoryUser.new('{"object":"directory_user","id":"directory_user_01FAZYNPC8M0HRYTKFP2GNX852","directory_id":"directory_01FAZYMST676QMTFN1DDJZZX87","idp_id":"6092c280a3f1e19ef6d8cef8","username":"logan@workos.com","emails":[],"first_name":"Logan","last_name":"Gingerich","state":"active","raw_attributes":{},"custom_attributes":{},"groups":[]}')
31
+ expect(user.primary_email).to eq(nil)
32
+ end
33
+ end
34
+ end
35
+ # rubocop:enable Layout/LineLength
36
+ end
@@ -4,8 +4,8 @@
4
4
  describe WorkOS::MFA do
5
5
  it_behaves_like 'client'
6
6
 
7
- describe 'enroll_factor valid requests' do
8
- context 'enroll factor using valid generic argument' do
7
+ describe '.enroll_factor' do
8
+ context 'with valid generic argument' do
9
9
  it 'returns a valid factor object' do
10
10
  VCR.use_cassette 'mfa/enroll_factor_generic_valid' do
11
11
  factor = described_class.enroll_factor(
@@ -16,7 +16,7 @@ describe WorkOS::MFA do
16
16
  end
17
17
  end
18
18
 
19
- context 'enroll factor using valid totp arguments' do
19
+ context 'with valid totp arguments' do
20
20
  it 'returns a valid factor object' do
21
21
  VCR.use_cassette 'mfa/enroll_factor_totp_valid' do
22
22
  factor = described_class.enroll_factor(
@@ -29,7 +29,7 @@ describe WorkOS::MFA do
29
29
  end
30
30
  end
31
31
 
32
- context 'enroll factor using valid sms arguments' do
32
+ context 'with valid sms arguments' do
33
33
  it 'returns a valid factor object' do
34
34
  VCR.use_cassette 'mfa/enroll_factor_sms_valid' do
35
35
  factor = described_class.enroll_factor(
@@ -40,10 +40,8 @@ describe WorkOS::MFA do
40
40
  end
41
41
  end
42
42
  end
43
- end
44
43
 
45
- describe 'enroll_factor invalid responses' do
46
- context 'enroll factor throws error if type is not sms or totp' do
44
+ context 'when type is not sms or totp' do
47
45
  it 'returns an error' do
48
46
  expect do
49
47
  described_class.enroll_factor(
@@ -57,7 +55,7 @@ describe WorkOS::MFA do
57
55
  end
58
56
  end
59
57
 
60
- context 'enroll factor throws error if type is not sms or totp' do
58
+ context 'when type is totp but missing arguments' do
61
59
  it 'returns an error' do
62
60
  expect do
63
61
  described_class.enroll_factor(
@@ -70,7 +68,7 @@ describe WorkOS::MFA do
70
68
  )
71
69
  end
72
70
  end
73
- context 'enroll factor throws error if type sms and phone number is nil' do
71
+ context 'when type is sms and phone number is nil' do
74
72
  it 'returns an error' do
75
73
  expect do
76
74
  described_class.enroll_factor(
@@ -84,7 +82,7 @@ describe WorkOS::MFA do
84
82
  end
85
83
  end
86
84
 
87
- describe 'challenge factor with valid request arguments' do
85
+ describe '.challenge_factor' do
88
86
  context 'challenge with totp' do
89
87
  it 'returns challenge factor object for totp' do
90
88
  VCR.use_cassette 'mfa/challenge_factor_totp_valid' do
@@ -118,9 +116,7 @@ describe WorkOS::MFA do
118
116
  end
119
117
  end
120
118
  end
121
- end
122
119
 
123
- describe 'challenge factor with invalid arguments' do
124
120
  context 'challenge with totp mssing authentication_factor_id' do
125
121
  it 'returns argument error' do
126
122
  expect do
@@ -133,48 +129,58 @@ describe WorkOS::MFA do
133
129
  end
134
130
  end
135
131
 
136
- describe 'challenge factor with valid requests' do
137
- context 'verify generic otp' do
138
- it 'returns a true boolean if the challenge has not been verifed yet' do
139
- VCR.use_cassette 'mfa/verify_factor_generic_valid' do
140
- verify_factor = described_class.verify_factor(
132
+ describe '.verify_factor' do
133
+ it 'throws a warning' do
134
+ expect do
135
+ VCR.use_cassette 'mfa/verify_challenge_generic_valid' do
136
+ described_class.verify_factor(
141
137
  authentication_challenge_id: 'auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J',
142
138
  code: '897792',
143
139
  )
144
- expect(verify_factor.valid == 'true')
145
140
  end
146
- end
141
+ end.to output("[DEPRECATION] `verify_factor` is deprecated. Please use `verify_challenge` instead.\n").to_stderr
147
142
  end
148
143
 
149
- context 'verify generic otp invalid response' do
150
- it 'returns a true boolean if the challenge has not been verifed yet' do
151
- VCR.use_cassette 'mfa/verify_factor_generic_valid_is_false' do
152
- verify_factor = described_class.verify_factor(
153
- authentication_challenge_id: 'auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J',
154
- code: '897792',
155
- )
156
- expect(verify_factor.valid == 'false')
157
- end
144
+ it 'calls verify_challenge' do
145
+ VCR.use_cassette 'mfa/verify_challenge_generic_valid' do
146
+ verify_factor = described_class.verify_factor(
147
+ authentication_challenge_id: 'auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J',
148
+ code: '897792',
149
+ )
150
+ expect(verify_factor.valid == 'true')
158
151
  end
159
152
  end
153
+ end
160
154
 
161
- context 'verify generic otp' do
162
- it 'returns error that the challenge has already been verfied' do
163
- VCR.use_cassette 'mfa/verify_factor_generic_invalid' do
164
- expect do
165
- described_class.verify_factor(
155
+ describe '.verify_challenge' do
156
+ context 'with generic otp' do
157
+ context 'and the challenge has not been verified' do
158
+ it 'returns true if the code is correct' do
159
+ VCR.use_cassette 'mfa/verify_challenge_generic_valid' do
160
+ verify_challenge = described_class.verify_challenge(
166
161
  authentication_challenge_id: 'auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J',
167
162
  code: '897792',
168
163
  )
169
- end.to raise_error(WorkOS::InvalidRequestError)
164
+ expect(verify_challenge.valid == 'true')
165
+ end
166
+ end
167
+
168
+ it 'returns false if the code is incorrect' do
169
+ VCR.use_cassette 'mfa/verify_challenge_generic_valid_is_false' do
170
+ verify_challenge = described_class.verify_challenge(
171
+ authentication_challenge_id: 'auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J',
172
+ code: '897792',
173
+ )
174
+ expect(verify_challenge.valid == 'false')
175
+ end
170
176
  end
171
177
  end
172
178
 
173
- context 'verify generic otp' do
174
- it 'returns error that the challenge has expired' do
175
- VCR.use_cassette 'mfa/verify_factor_generic_expired' do
179
+ context 'and the challenge has already been verified' do
180
+ it 'returns an error' do
181
+ VCR.use_cassette 'mfa/verify_challenge_generic_invalid' do
176
182
  expect do
177
- described_class.verify_factor(
183
+ described_class.verify_challenge(
178
184
  authentication_challenge_id: 'auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J',
179
185
  code: '897792',
180
186
  )
@@ -182,51 +188,62 @@ describe WorkOS::MFA do
182
188
  end
183
189
  end
184
190
  end
185
- end
186
- end
187
191
 
188
- describe 'verify_factor with invalid argument' do
189
- context 'missing code argument' do
190
- it 'returns argument error' do
191
- expect do
192
- described_class.verify_factor(
193
- authentication_challenge_id: 'auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J',
192
+ context 'and the challenge has expired' do
193
+ it 'returns an error' do
194
+ VCR.use_cassette 'mfa/verify_challenge_generic_expired' do
195
+ expect do
196
+ described_class.verify_challenge(
197
+ authentication_challenge_id: 'auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J',
198
+ code: '897792',
199
+ )
200
+ end.to raise_error(WorkOS::InvalidRequestError)
201
+ end
202
+ end
203
+ end
204
+
205
+ context 'with missing code argument' do
206
+ it 'returns an argument error' do
207
+ expect do
208
+ described_class.verify_challenge(
209
+ authentication_challenge_id: 'auth_challenge_01FZ4YVRBMXP5ZM0A7BP4AJ12J',
210
+ )
211
+ end.to raise_error(
212
+ ArgumentError,
213
+ "Incomplete arguments: 'authentication_challenge_id' and 'code' are required arguments",
194
214
  )
195
- end.to raise_error(
196
- ArgumentError,
197
- "Incomplete arguments: 'authentication_challenge_id' and 'code' are required arguments",
198
- )
215
+ end
199
216
  end
200
- end
201
217
 
202
- context 'missing authentication_challenge_id argument' do
203
- it 'returns and error' do
204
- expect do
205
- described_class.verify_factor(
206
- code: '897792',
218
+ context 'with missing authentication_challenge_id argument' do
219
+ it 'returns an error' do
220
+ expect do
221
+ described_class.verify_challenge(
222
+ code: '897792',
223
+ )
224
+ end.to raise_error(
225
+ ArgumentError,
226
+ "Incomplete arguments: 'authentication_challenge_id' and 'code' are required arguments",
207
227
  )
208
- end.to raise_error(
209
- ArgumentError,
210
- "Incomplete arguments: 'authentication_challenge_id' and 'code' are required arguments",
211
- )
228
+ end
212
229
  end
213
- end
214
230
 
215
- context 'missing code and authentication_challenge_id arguments' do
216
- it 'returns argument error' do
217
- expect do
218
- described_class.verify_factor
219
- end.to raise_error(
220
- ArgumentError,
221
- "Incomplete arguments: 'authentication_challenge_id' and 'code' are required arguments",
222
- )
231
+ context 'with missing code and authentication_challenge_id arguments' do
232
+ it 'returns an argument error' do
233
+ expect do
234
+ described_class.verify_challenge
235
+ end.to raise_error(
236
+ ArgumentError,
237
+ "Incomplete arguments: 'authentication_challenge_id' and 'code' are required arguments",
238
+ )
239
+ end
223
240
  end
224
241
  end
225
242
  end
226
243
 
227
- describe 'tests returning and deleting a factor' do
228
- context 'returns a factor' do
229
- it 'uses get_factor to return factor' do
244
+ describe '.get_factor' do
245
+ context 'with a valid id' do
246
+ it 'returns a factor' do
230
247
  VCR.use_cassette 'mfa/get_factor_valid' do
231
248
  factor = described_class.get_factor(
232
249
  id: 'auth_factor_01FZ4WMXXA09XF6NK1XMKNWB3M',
@@ -236,8 +253,8 @@ describe WorkOS::MFA do
236
253
  end
237
254
  end
238
255
 
239
- context 'invalid factor request' do
240
- it 'uses get_factor and throws error if id is wrong' do
256
+ context 'with an invalid id' do
257
+ it 'returns an error' do
241
258
  VCR.use_cassette 'mfa/get_factor_invalid' do
242
259
  expect do
243
260
  described_class.get_factor(
@@ -247,7 +264,9 @@ describe WorkOS::MFA do
247
264
  end
248
265
  end
249
266
  end
267
+ end
250
268
 
269
+ describe '.delete_factor' do
251
270
  context 'deletes facotr' do
252
271
  it 'uses delete_factor to delete factor' do
253
272
  VCR.use_cassette 'mfa/delete_factor' do
@@ -330,7 +330,7 @@ describe WorkOS::SSO do
330
330
  let(:request_body) do
331
331
  {
332
332
  client_id: args[:client_id],
333
- client_secret: WorkOS.key,
333
+ client_secret: WorkOS.config.key,
334
334
  code: args[:code],
335
335
  grant_type: 'authorization_code',
336
336
  }
data/spec/spec_helper.rb CHANGED
@@ -25,7 +25,7 @@ SPEC_ROOT = File.dirname __FILE__
25
25
 
26
26
  VCR.configure do |config|
27
27
  config.cassette_library_dir = 'spec/support/fixtures/vcr_cassettes'
28
- config.filter_sensitive_data('<API_KEY>') { WorkOS.key }
28
+ config.filter_sensitive_data('<API_KEY>') { WorkOS.config.key }
29
29
  config.hook_into :webmock
30
30
  end
31
31
 
@@ -51,6 +51,6 @@ RSpec.configure do |config|
51
51
  end
52
52
  end)
53
53
 
54
- config.before(:all) { WorkOS.key ||= '' }
54
+ config.before(:all) { WorkOS.config.key ||= '' }
55
55
  config.before(:each) { VCR.turn_on! }
56
56
  end
@@ -2,7 +2,7 @@
2
2
  http_interactions:
3
3
  - request:
4
4
  method: get
5
- uri: https://api.workos.com/directory_groups/directory_grp_01E64QTDNS0EGJ0FMCVY9BWGZT
5
+ uri: https://api.workos.com/directory_groups/directory_group_01G2Z8D4ZR8RJ03Y1W7P9K8NMG
6
6
  body:
7
7
  encoding: US-ASCII
8
8
  string: ''
@@ -14,7 +14,7 @@ http_interactions:
14
14
  Accept:
15
15
  - "*/*"
16
16
  User-Agent:
17
- - WorkOS; ruby/2.7.1; x86_64-darwin19; v0.2.3
17
+ - WorkOS; ruby/2.7.2; arm64-darwin21; v2.3.0
18
18
  Authorization:
19
19
  - Bearer <API_KEY>
20
20
  response:
@@ -22,41 +22,59 @@ http_interactions:
22
22
  code: 200
23
23
  message: OK
24
24
  headers:
25
- Server:
26
- - Cowboy
25
+ Date:
26
+ - Thu, 14 Jul 2022 16:49:09 GMT
27
+ Content-Type:
28
+ - application/json; charset=utf-8
29
+ Transfer-Encoding:
30
+ - chunked
27
31
  Connection:
28
32
  - keep-alive
29
- Vary:
30
- - Origin, Accept-Encoding
31
33
  Access-Control-Allow-Credentials:
32
34
  - 'true'
33
- X-Dns-Prefetch-Control:
34
- - 'off'
35
- X-Frame-Options:
36
- - SAMEORIGIN
35
+ Content-Security-Policy:
36
+ - 'default-src ''self'';base-uri ''self'';block-all-mixed-content;font-src ''self''
37
+ https: data:;frame-ancestors ''self'';img-src ''self'' data:;object-src ''none'';script-src
38
+ ''self'';script-src-attr ''none'';style-src ''self'' https: ''unsafe-inline'';upgrade-insecure-requests'
39
+ Etag:
40
+ - W/"277-8j8DgAIILf/mCF7LCmvrqcqdwK4"
41
+ Expect-Ct:
42
+ - max-age=0
43
+ Referrer-Policy:
44
+ - no-referrer
37
45
  Strict-Transport-Security:
38
46
  - max-age=15552000; includeSubDomains
39
- X-Download-Options:
40
- - noopen
47
+ Vary:
48
+ - Origin, Accept-Encoding
49
+ Via:
50
+ - 1.1 spaces-router (b642bf20b975)
41
51
  X-Content-Type-Options:
42
52
  - nosniff
43
- X-Xss-Protection:
44
- - 1; mode=block
53
+ X-Dns-Prefetch-Control:
54
+ - 'off'
55
+ X-Download-Options:
56
+ - noopen
57
+ X-Frame-Options:
58
+ - SAMEORIGIN
59
+ X-Permitted-Cross-Domain-Policies:
60
+ - none
45
61
  X-Request-Id:
46
- - 4fb94ab3-ecff-4cea-b0b7-d4d1b3ffad3a
47
- Content-Type:
48
- - application/json; charset=utf-8
49
- Content-Length:
50
- - '65'
51
- Etag:
52
- - W/"41-QrnAKhorJuUwAsR1OyMpfB8q1Kc"
53
- Date:
54
- - Thu, 30 Apr 2020 04:47:49 GMT
55
- Via:
56
- - 1.1 vegur
62
+ - 0f21c2f3-e24a-e3a2-85d3-41ee9e45b3e2
63
+ X-Xss-Protection:
64
+ - '0'
65
+ Cf-Cache-Status:
66
+ - DYNAMIC
67
+ Report-To:
68
+ - '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=Hnm%2BEiBTG2ROFxqX2mdwcp0HvQ173SgQlQDCmTmBQEbLv9w2dkcl2qMqYh44OSHRABBCkRfuJ2MtnHuqb6sQ5RjHRMKSCfRqklsOrgd%2FHo0PEE6mW0u%2BlZqBMIlN1BEp"}],"group":"cf-nel","max_age":604800}'
69
+ Nel:
70
+ - '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}'
71
+ Server:
72
+ - cloudflare
73
+ Cf-Ray:
74
+ - 72abc002fbd9f039-EWR
57
75
  body:
58
- encoding: UTF-8
59
- string: '{"id":"directory_grp_01E64QTDNS0EGJ0FMCVY9BWGZT","name":"Walrus"}'
60
- http_version:
61
- recorded_at: Thu, 30 Apr 2020 04:47:49 GMT
76
+ encoding: ASCII-8BIT
77
+ string: '{"object":"directory_group","id":"directory_group_01G2Z8D4ZR8RJ03Y1W7P9K8NMG","idp_id":"01jlao4614two3d","directory_id":"directory_01G2Z8ADK5NPMVTWF48MVVE4HT","organization_id":"org_01EGS4P7QR31EZ4YWD1Z1XA176","name":"Sales","created_at":"2022-05-13T17:45:31.732Z","updated_at":"2022-07-13T17:45:42.618Z","raw_attributes":{"id":"01jlao4614two3d","etag":"\"SEQQBYC70u6XQ2UUjmjNYw6b0a5EzY0mTMShjiZga8A/uLYJ0Hrx1gXXVg9z-zGLBZET2Wo\"","kind":"admin#directory#group","name":"Sales","email":"sales@foo-corp.com","description":"","adminCreated":true,"directMembersCount":"1","nonEditableAliases":["sales@foo-corp.com.test-google-a.com"]}}'
78
+ http_version:
79
+ recorded_at: Thu, 14 Jul 2022 16:49:09 GMT
62
80
  recorded_with: VCR 5.0.0