workos 5.3.0 → 6.1.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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -1
  3. data/.github/workflows/ci.yml +2 -4
  4. data/.github/workflows/lint-pr-title.yml +20 -0
  5. data/.github/workflows/release-please.yml +25 -0
  6. data/.github/workflows/release.yml +22 -25
  7. data/.gitignore +1 -0
  8. data/.release-please-manifest.json +3 -0
  9. data/.rubocop.yml +11 -8
  10. data/.rubocop_todo.yml +94 -0
  11. data/.ruby-version +1 -1
  12. data/CHANGELOG.md +15 -0
  13. data/Gemfile.lock +32 -18
  14. data/Rakefile +8 -0
  15. data/context7.json +4 -0
  16. data/lib/workos/authentication_response.rb +32 -4
  17. data/lib/workos/cache.rb +94 -0
  18. data/lib/workos/client.rb +9 -1
  19. data/lib/workos/directory_sync.rb +1 -1
  20. data/lib/workos/directory_user.rb +31 -3
  21. data/lib/workos/encryptors/aes_gcm.rb +49 -0
  22. data/lib/workos/encryptors.rb +9 -0
  23. data/lib/workos/errors.rb +4 -0
  24. data/lib/workos/feature_flag.rb +34 -0
  25. data/lib/workos/mfa.rb +0 -1
  26. data/lib/workos/oauth_tokens.rb +29 -0
  27. data/lib/workos/organization.rb +14 -1
  28. data/lib/workos/organization_membership.rb +5 -1
  29. data/lib/workos/organizations.rb +87 -3
  30. data/lib/workos/profile.rb +10 -2
  31. data/lib/workos/refresh_authentication_response.rb +29 -2
  32. data/lib/workos/role.rb +38 -0
  33. data/lib/workos/session.rb +187 -0
  34. data/lib/workos/sso.rb +3 -24
  35. data/lib/workos/types/intent.rb +3 -1
  36. data/lib/workos/types/provider.rb +1 -1
  37. data/lib/workos/types/widget_scope.rb +15 -0
  38. data/lib/workos/types.rb +1 -0
  39. data/lib/workos/user.rb +7 -1
  40. data/lib/workos/user_management/session.rb +57 -0
  41. data/lib/workos/user_management.rb +213 -45
  42. data/lib/workos/version.rb +1 -1
  43. data/lib/workos/widgets.rb +46 -0
  44. data/lib/workos.rb +8 -0
  45. data/release-please-config.json +12 -0
  46. data/spec/lib/workos/cache_spec.rb +94 -0
  47. data/spec/lib/workos/directory_user_spec.rb +13 -3
  48. data/spec/lib/workos/encryptors/aes_gcm_spec.rb +41 -0
  49. data/spec/lib/workos/organizations_spec.rb +258 -1
  50. data/spec/lib/workos/portal_spec.rb +30 -0
  51. data/spec/lib/workos/role_spec.rb +142 -0
  52. data/spec/lib/workos/session_spec.rb +475 -0
  53. data/spec/lib/workos/sso_spec.rb +106 -5
  54. data/spec/lib/workos/user_management_spec.rb +496 -1
  55. data/spec/lib/workos/widgets_spec.rb +73 -0
  56. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_user.yml +1 -1
  57. data/spec/support/fixtures/vcr_cassettes/organization/create_with_external_id.yml +83 -0
  58. data/spec/support/fixtures/vcr_cassettes/organization/list_organization_feature_flags.yml +78 -0
  59. data/spec/support/fixtures/vcr_cassettes/organization/list_organization_roles.yml +82 -0
  60. data/spec/support/fixtures/vcr_cassettes/organization/update_with_external_id.yml +78 -0
  61. data/spec/support/fixtures/vcr_cassettes/organization/update_with_external_id_null.yml +78 -0
  62. data/spec/support/fixtures/vcr_cassettes/organization/update_with_stripe_customer_id.yml +78 -0
  63. data/spec/support/fixtures/vcr_cassettes/organization/update_without_name.yml +85 -0
  64. data/spec/support/fixtures/vcr_cassettes/portal/generate_link_certificate_renewal.yml +72 -0
  65. data/spec/support/fixtures/vcr_cassettes/portal/generate_link_domain_verification.yml +72 -0
  66. data/spec/support/fixtures/vcr_cassettes/sso/profile.yml +1 -1
  67. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_code/valid_with_oauth_tokens.yml +82 -0
  68. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_password/unverified.yml +82 -0
  69. data/spec/support/fixtures/vcr_cassettes/user_management/authenticate_with_refresh_token/valid.yml +79 -78
  70. data/spec/support/fixtures/vcr_cassettes/user_management/create_organization_membership/valid_multiple_roles.yml +76 -0
  71. data/spec/support/fixtures/vcr_cassettes/user_management/create_user_with_external_id.yml +77 -0
  72. data/spec/support/fixtures/vcr_cassettes/user_management/get_user.yml +1 -1
  73. data/spec/support/fixtures/vcr_cassettes/user_management/list_sessions/valid.yml +38 -0
  74. data/spec/support/fixtures/vcr_cassettes/user_management/resend_invitation/accepted.yml +83 -0
  75. data/spec/support/fixtures/vcr_cassettes/user_management/resend_invitation/expired.yml +83 -0
  76. data/spec/support/fixtures/vcr_cassettes/user_management/resend_invitation/invalid.yml +83 -0
  77. data/spec/support/fixtures/vcr_cassettes/user_management/resend_invitation/revoked.yml +83 -0
  78. data/spec/support/fixtures/vcr_cassettes/user_management/resend_invitation/valid.yml +83 -0
  79. data/spec/support/fixtures/vcr_cassettes/user_management/reset_password/valid.yml +1 -1
  80. data/spec/support/fixtures/vcr_cassettes/user_management/update_organization_membership/valid_multiple_roles.yml +76 -0
  81. data/spec/support/fixtures/vcr_cassettes/user_management/update_user/email.yml +82 -0
  82. data/spec/support/fixtures/vcr_cassettes/user_management/update_user/locale.yml +76 -0
  83. data/spec/support/fixtures/vcr_cassettes/user_management/update_user/valid.yml +2 -2
  84. data/spec/support/fixtures/vcr_cassettes/user_management/update_user_external_id_null.yml +77 -0
  85. data/spec/support/fixtures/vcr_cassettes/widgets/get_token.yml +82 -0
  86. data/spec/support/fixtures/vcr_cassettes/widgets/get_token_invalid_organization_id.yml +74 -0
  87. data/spec/support/fixtures/vcr_cassettes/widgets/get_token_invalid_user_id.yml +74 -0
  88. data/spec/support/profile.txt +1 -1
  89. data/workos.gemspec +7 -3
  90. metadata +132 -10
@@ -7,8 +7,8 @@ module WorkOS
7
7
  class DirectoryUser < DeprecatedHashWrapper
8
8
  include HashProvider
9
9
 
10
- attr_accessor :id, :idp_id, :emails, :first_name, :last_name, :job_title, :username, :state,
11
- :groups, :role, :custom_attributes, :raw_attributes, :directory_id, :organization_id,
10
+ attr_accessor :id, :idp_id, :email, :emails, :first_name, :last_name, :job_title, :username, :state,
11
+ :groups, :role, :roles, :custom_attributes, :raw_attributes, :directory_id, :organization_id,
12
12
  :created_at, :updated_at
13
13
 
14
14
  # rubocop:disable Metrics/AbcSize
@@ -19,14 +19,25 @@ module WorkOS
19
19
  @directory_id = hash[:directory_id]
20
20
  @organization_id = hash[:organization_id]
21
21
  @idp_id = hash[:idp_id]
22
+ @email = hash[:email]
23
+ # @deprecated Will be removed in a future major version.
24
+ # Enable the `emails` custom attribute in dashboard and pull from customAttributes instead.
25
+ # See https://workos.com/docs/directory-sync/attributes/custom-attributes/auto-mapped-attributes for details.
22
26
  @emails = hash[:emails]
23
27
  @first_name = hash[:first_name]
24
28
  @last_name = hash[:last_name]
29
+ # @deprecated Will be removed in a future major version.
30
+ # Enable the `job_title` custom attribute in dashboard and pull from customAttributes instead.
31
+ # See https://workos.com/docs/directory-sync/attributes/custom-attributes/auto-mapped-attributes for details.
25
32
  @job_title = hash[:job_title]
33
+ # @deprecated Will be removed in a future major version.
34
+ # Enable the `username` custom attribute in dashboard and pull from customAttributes instead.
35
+ # See https://workos.com/docs/directory-sync/attributes/custom-attributes/auto-mapped-attributes for details.
26
36
  @username = hash[:username]
27
37
  @state = hash[:state]
28
38
  @groups = hash[:groups]
29
39
  @role = hash[:role]
40
+ @roles = hash[:roles]
30
41
  @custom_attributes = hash[:custom_attributes]
31
42
  @raw_attributes = hash[:raw_attributes]
32
43
  @created_at = hash[:created_at]
@@ -37,11 +48,19 @@ module WorkOS
37
48
  # rubocop:enable Metrics/AbcSize
38
49
 
39
50
  def to_json(*)
51
+ base_attributes.
52
+ merge(authorization_attributes)
53
+ end
54
+
55
+ private
56
+
57
+ def base_attributes
40
58
  {
41
59
  id: id,
42
60
  directory_id: directory_id,
43
61
  organization_id: organization_id,
44
62
  idp_id: idp_id,
63
+ email: email,
45
64
  emails: emails,
46
65
  first_name: first_name,
47
66
  last_name: last_name,
@@ -49,7 +68,6 @@ module WorkOS
49
68
  username: username,
50
69
  state: state,
51
70
  groups: groups,
52
- role: role,
53
71
  custom_attributes: custom_attributes,
54
72
  raw_attributes: raw_attributes,
55
73
  created_at: created_at,
@@ -57,6 +75,16 @@ module WorkOS
57
75
  }
58
76
  end
59
77
 
78
+ def authorization_attributes
79
+ {
80
+ role: role,
81
+ roles: roles,
82
+ }
83
+ end
84
+
85
+ public
86
+
87
+ # @deprecated Will be removed in a future major version. Use {#email} instead.
60
88
  def primary_email
61
89
  primary_email = (emails || []).find { |email| email[:primary] }
62
90
  return primary_email[:value] if primary_email
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'encryptor'
4
+ require 'securerandom'
5
+ require 'json'
6
+ require 'base64'
7
+
8
+ module WorkOS
9
+ module Encryptors
10
+ # Default encryptor using AES-256-GCM.
11
+ # Implements the encryptor interface: #seal(data, key) and #unseal(sealed_data, key)
12
+ class AesGcm
13
+ # Encrypts and seals data using AES-256-GCM
14
+ # @param data [Hash] The data to seal
15
+ # @param key [String] The encryption key
16
+ # @return [String] Base64-encoded sealed data
17
+ def seal(data, key)
18
+ iv = SecureRandom.random_bytes(12)
19
+
20
+ encrypted_data = Encryptor.encrypt(
21
+ value: JSON.generate(data),
22
+ key: key,
23
+ iv: iv,
24
+ algorithm: 'aes-256-gcm',
25
+ )
26
+ Base64.encode64(iv + encrypted_data)
27
+ end
28
+
29
+ # Decrypts and unseals data using AES-256-GCM
30
+ # @param sealed_data [String] The sealed data to unseal
31
+ # @param key [String] The decryption key
32
+ # @return [Hash] The unsealed data with symbolized keys
33
+ def unseal(sealed_data, key)
34
+ decoded_data = Base64.decode64(sealed_data)
35
+ iv = decoded_data[0..11]
36
+ encrypted_data = decoded_data[12..]
37
+
38
+ decrypted_data = Encryptor.decrypt(
39
+ value: encrypted_data,
40
+ key: key,
41
+ iv: iv,
42
+ algorithm: 'aes-256-gcm',
43
+ )
44
+
45
+ JSON.parse(decrypted_data, symbolize_names: true)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WorkOS
4
+ # Encryptors module provides pluggable encryption implementations for session data.
5
+ # The default encryptor is AesGcm, which uses AES-256-GCM encryption.
6
+ module Encryptors
7
+ autoload :AesGcm, 'workos/encryptors/aes_gcm'
8
+ end
9
+ end
data/lib/workos/errors.rb CHANGED
@@ -64,6 +64,10 @@ module WorkOS
64
64
  # parameters.
65
65
  class InvalidRequestError < WorkOSError; end
66
66
 
67
+ # ForbiddenError is raised when a request is forbidden, likely due to missing a step
68
+ # (i.e. verifying email ownership before authenticating).
69
+ class ForbiddenRequestError < WorkOSError; end
70
+
67
71
  # SignatureVerificationError is raised when the signature verification for a
68
72
  # webhook fails
69
73
  class SignatureVerificationError < WorkOSError; end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WorkOS
4
+ # The FeatureFlag class provides a lightweight wrapper around
5
+ # a WorkOS Feature Flag resource. This class is not meant to be instantiated
6
+ # in user space, and is instantiated internally but exposed.
7
+ class FeatureFlag
8
+ include HashProvider
9
+
10
+ attr_accessor :id, :name, :slug, :description, :created_at, :updated_at
11
+
12
+ def initialize(json)
13
+ hash = JSON.parse(json, symbolize_names: true)
14
+
15
+ @id = hash[:id]
16
+ @name = hash[:name]
17
+ @slug = hash[:slug]
18
+ @description = hash[:description]
19
+ @created_at = hash[:created_at]
20
+ @updated_at = hash[:updated_at]
21
+ end
22
+
23
+ def to_json(*)
24
+ {
25
+ id: id,
26
+ name: name,
27
+ slug: slug,
28
+ description: description,
29
+ created_at: created_at,
30
+ updated_at: updated_at,
31
+ }
32
+ end
33
+ end
34
+ end
data/lib/workos/mfa.rb CHANGED
@@ -32,7 +32,6 @@ module WorkOS
32
32
  WorkOS::Factor.new(response.body)
33
33
  end
34
34
 
35
- # rubocop:disable Metrics/CyclomaticComplexity
36
35
  # rubocop:disable Metrics/PerceivedComplexity
37
36
  def validate_args(
38
37
  type:,
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WorkOS
4
+ # The OAuthTokens class represents the third party provider OAuth tokens returned in the authentication response.
5
+ # This class is not meant to be instantiated in user space, and is instantiated internally but exposed.
6
+ class OAuthTokens
7
+ include HashProvider
8
+
9
+ attr_accessor :access_token, :refresh_token, :scopes, :expires_at
10
+
11
+ def initialize(json)
12
+ hash = JSON.parse(json, symbolize_names: true)
13
+
14
+ @access_token = hash[:access_token]
15
+ @refresh_token = hash[:refresh_token]
16
+ @scopes = hash[:scopes]
17
+ @expires_at = hash[:expires_at]
18
+ end
19
+
20
+ def to_json(*)
21
+ {
22
+ access_token: access_token,
23
+ refresh_token: refresh_token,
24
+ scopes: scopes,
25
+ expires_at: expires_at,
26
+ }
27
+ end
28
+ end
29
+ end
@@ -7,15 +7,26 @@ module WorkOS
7
7
  class Organization
8
8
  include HashProvider
9
9
 
10
- attr_accessor :id, :domains, :name, :allow_profiles_outside_organization, :created_at, :updated_at
10
+ attr_accessor(
11
+ :id,
12
+ :domains,
13
+ :stripe_customer_id,
14
+ :name,
15
+ :external_id,
16
+ :allow_profiles_outside_organization,
17
+ :created_at,
18
+ :updated_at,
19
+ )
11
20
 
12
21
  def initialize(json)
13
22
  hash = JSON.parse(json, symbolize_names: true)
14
23
 
15
24
  @id = hash[:id]
16
25
  @name = hash[:name]
26
+ @external_id = hash[:external_id]
17
27
  @allow_profiles_outside_organization = hash[:allow_profiles_outside_organization]
18
28
  @domains = hash[:domains]
29
+ @stripe_customer_id = hash[:stripe_customer_id]
19
30
  @created_at = hash[:created_at]
20
31
  @updated_at = hash[:updated_at]
21
32
  end
@@ -24,8 +35,10 @@ module WorkOS
24
35
  {
25
36
  id: id,
26
37
  name: name,
38
+ external_id: external_id,
27
39
  allow_profiles_outside_organization: allow_profiles_outside_organization,
28
40
  domains: domains,
41
+ stripe_customer_id: stripe_customer_id,
29
42
  created_at: created_at,
30
43
  updated_at: updated_at,
31
44
  }
@@ -7,7 +7,7 @@ module WorkOS
7
7
  class OrganizationMembership
8
8
  include HashProvider
9
9
 
10
- attr_accessor :id, :user_id, :organization_id, :status, :role, :created_at, :updated_at
10
+ attr_accessor :id, :user_id, :organization_id, :status, :role, :roles, :custom_attributes, :created_at, :updated_at
11
11
 
12
12
  def initialize(json)
13
13
  hash = JSON.parse(json, symbolize_names: true)
@@ -17,6 +17,8 @@ module WorkOS
17
17
  @organization_id = hash[:organization_id]
18
18
  @status = hash[:status]
19
19
  @role = hash[:role]
20
+ @roles = hash[:roles]
21
+ @custom_attributes = hash[:custom_attributes]
20
22
  @created_at = hash[:created_at]
21
23
  @updated_at = hash[:updated_at]
22
24
  end
@@ -28,6 +30,8 @@ module WorkOS
28
30
  organization_id: organization_id,
29
31
  status: status,
30
32
  role: role,
33
+ roles: roles,
34
+ custom_attributes: custom_attributes,
31
35
  created_at: created_at,
32
36
  updated_at: updated_at,
33
37
  }
@@ -71,10 +71,11 @@ module WorkOS
71
71
 
72
72
  # Create an organization
73
73
  #
74
- # @param [Array<Hash>] domain_data List of domain hashes describing an orgnaization domain.
74
+ # @param [Array<Hash>] domain_data List of domain hashes describing an organization domain.
75
75
  # @option domain_data [String] domain The domain that belongs to the organization.
76
76
  # @option domain_data [String] state The state of the domain. "verified" or "pending"
77
77
  # @param [String] name A unique, descriptive name for the organization
78
+ # @param [String] external_id The organization's external ID.
78
79
  # @param [String] idempotency_key An idempotency key
79
80
  # @param [Boolean, nil] allow_profiles_outside_organization Whether Connections
80
81
  # within the Organization allow profiles that are outside of the Organization's configured User Email Domains.
@@ -85,11 +86,13 @@ module WorkOS
85
86
  domain_data: nil,
86
87
  domains: nil,
87
88
  name:,
89
+ external_id: nil,
88
90
  allow_profiles_outside_organization: nil,
89
91
  idempotency_key: nil
90
92
  )
91
93
  body = { name: name }
92
94
  body[:domain_data] = domain_data if domain_data
95
+ body[:external_id] = external_id if external_id
93
96
 
94
97
  if domains
95
98
  warn_deprecation '`domains` is deprecated. Use `domain_data` instead.'
@@ -118,24 +121,31 @@ module WorkOS
118
121
  # Update an organization
119
122
  #
120
123
  # @param [String] organization Organization unique identifier
121
- # @param [Array<Hash>] domain_data List of domain hashes describing an orgnaization domain.
124
+ # @param [Array<Hash>] domain_data List of domain hashes describing an organization domain.
122
125
  # @option domain_data [String] domain The domain that belongs to the organization.
123
126
  # @option domain_data [String] state The state of the domain. "verified" or "pending"
127
+ # @param [String] stripe_customer_id The Stripe customer ID associated with this organization.
124
128
  # @param [String] name A unique, descriptive name for the organization
129
+ # @param [String] external_id The organization's external ID.
125
130
  # @param [Boolean, nil] allow_profiles_outside_organization Whether Connections
126
131
  # within the Organization allow profiles that are outside of the Organization's configured User Email Domains.
127
132
  # Deprecated: If you need to allow sign-ins from any email domain, contact suppport@workos.com.
128
133
  # @param [Array<String>] domains List of domains that belong to the organization.
129
134
  # Deprecated: Use domain_data instead.
135
+ # rubocop:disable Metrics/ParameterLists
130
136
  def update_organization(
131
137
  organization:,
138
+ stripe_customer_id: nil,
132
139
  domain_data: nil,
133
140
  domains: nil,
134
- name:,
141
+ name: nil,
142
+ external_id: :not_set,
135
143
  allow_profiles_outside_organization: nil
136
144
  )
137
145
  body = { name: name }
138
146
  body[:domain_data] = domain_data if domain_data
147
+ body[:stripe_customer_id] = stripe_customer_id if stripe_customer_id
148
+ body[:external_id] = external_id if external_id != :not_set
139
149
 
140
150
  if domains
141
151
  warn_deprecation '`domains` is deprecated. Use `domain_data` instead.'
@@ -159,6 +169,7 @@ module WorkOS
159
169
 
160
170
  WorkOS::Organization.new(response.body)
161
171
  end
172
+ # rubocop:enable Metrics/ParameterLists
162
173
 
163
174
  # Delete an Organization
164
175
  #
@@ -180,6 +191,79 @@ module WorkOS
180
191
  response.is_a? Net::HTTPSuccess
181
192
  end
182
193
 
194
+ # Retrieve a list of roles for the given organization.
195
+ #
196
+ # @param [String] organization_id The ID of the organization to fetch roles for.
197
+ #
198
+ # @example
199
+ # WorkOS::Organizations.list_organization_roles(organization_id: 'org_01EHZNVPK3SFK441A1RGBFSHRT')
200
+ # => #<WorkOS::Types::ListStruct data=[#<WorkOS::Role id="role_123" name="Admin" slug="admin"
201
+ # permissions=["admin:all"] ...>] ...>
202
+ #
203
+ # @return [WorkOS::Types::ListStruct] - Collection of Role objects, each including permissions array
204
+ def list_organization_roles(organization_id:)
205
+ response = execute_request(
206
+ request: get_request(
207
+ path: "/organizations/#{organization_id}/roles",
208
+ auth: true,
209
+ ),
210
+ )
211
+
212
+ parsed_response = JSON.parse(response.body)
213
+
214
+ roles = parsed_response['data'].map do |role|
215
+ WorkOS::Role.new(role.to_json)
216
+ end
217
+
218
+ WorkOS::Types::ListStruct.new(
219
+ data: roles,
220
+ list_metadata: {
221
+ after: nil,
222
+ before: nil,
223
+ },
224
+ )
225
+ end
226
+
227
+ # Retrieve a list of feature flags for the given organization.
228
+ #
229
+ # @param [String] organization_id The ID of the organization to fetch feature flags for.
230
+ # @param [Hash] options
231
+ # @option options [String] before A pagination argument used to request
232
+ # feature flags before the provided FeatureFlag ID.
233
+ # @option options [String] after A pagination argument used to request
234
+ # feature flags after the provided FeatureFlag ID.
235
+ # @option options [Integer] limit A pagination argument used to limit the number
236
+ # of listed FeatureFlags that are returned.
237
+ # @option options [String] order The order in which to paginate records
238
+ #
239
+ # @example
240
+ # WorkOS::Organizations.list_organization_feature_flags(organization_id: 'org_01EHZNVPK3SFK441A1RGBFSHRT')
241
+ # => #<WorkOS::Types::ListStruct data=[#<WorkOS::FeatureFlag id="flag_123" slug="new-feature"
242
+ # enabled=true ...>] ...>
243
+ #
244
+ # @return [WorkOS::Types::ListStruct] - Collection of FeatureFlag objects
245
+ def list_organization_feature_flags(organization_id:, options: {})
246
+ options[:order] ||= 'desc'
247
+ response = execute_request(
248
+ request: get_request(
249
+ path: "/organizations/#{organization_id}/feature-flags",
250
+ auth: true,
251
+ params: options,
252
+ ),
253
+ )
254
+
255
+ parsed_response = JSON.parse(response.body)
256
+
257
+ feature_flags = parsed_response['data'].map do |feature_flag|
258
+ WorkOS::FeatureFlag.new(feature_flag.to_json)
259
+ end
260
+
261
+ WorkOS::Types::ListStruct.new(
262
+ data: feature_flags,
263
+ list_metadata: parsed_response['list_metadata']&.transform_keys(&:to_sym),
264
+ )
265
+ end
266
+
183
267
  private
184
268
 
185
269
  def check_and_raise_organization_error(response:)
@@ -9,9 +9,10 @@ module WorkOS
9
9
  class Profile
10
10
  include HashProvider
11
11
 
12
- attr_accessor :id, :email, :first_name, :last_name, :groups, :organization_id,
13
- :connection_id, :connection_type, :idp_id, :raw_attributes
12
+ attr_accessor :id, :email, :first_name, :last_name, :role, :roles, :groups, :organization_id,
13
+ :connection_id, :connection_type, :idp_id, :custom_attributes, :raw_attributes
14
14
 
15
+ # rubocop:disable Metrics/AbcSize
15
16
  def initialize(profile_json)
16
17
  hash = JSON.parse(profile_json, symbolize_names: true)
17
18
 
@@ -19,13 +20,17 @@ module WorkOS
19
20
  @email = hash[:email]
20
21
  @first_name = hash[:first_name]
21
22
  @last_name = hash[:last_name]
23
+ @role = hash[:role]
24
+ @roles = hash[:roles]
22
25
  @groups = hash[:groups]
23
26
  @organization_id = hash[:organization_id]
24
27
  @connection_id = hash[:connection_id]
25
28
  @connection_type = hash[:connection_type]
26
29
  @idp_id = hash[:idp_id]
30
+ @custom_attributes = hash[:custom_attributes]
27
31
  @raw_attributes = hash[:raw_attributes]
28
32
  end
33
+ # rubocop:enable Metrics/AbcSize
29
34
 
30
35
  def full_name
31
36
  [first_name, last_name].compact.join(' ')
@@ -37,11 +42,14 @@ module WorkOS
37
42
  email: email,
38
43
  first_name: first_name,
39
44
  last_name: last_name,
45
+ role: role,
46
+ roles: roles,
40
47
  groups: groups,
41
48
  organization_id: organization_id,
42
49
  connection_id: connection_id,
43
50
  connection_type: connection_type,
44
51
  idp_id: idp_id,
52
+ custom_attributes: custom_attributes,
45
53
  raw_attributes: raw_attributes,
46
54
  }
47
55
  end
@@ -6,18 +6,45 @@ module WorkOS
6
6
  class RefreshAuthenticationResponse
7
7
  include HashProvider
8
8
 
9
- attr_accessor :access_token, :refresh_token
9
+ attr_accessor :user, :organization_id, :impersonator, :access_token, :refresh_token, :sealed_session
10
10
 
11
- def initialize(authentication_response_json)
11
+ # rubocop:disable Metrics/AbcSize
12
+ def initialize(authentication_response_json, session = nil)
12
13
  json = JSON.parse(authentication_response_json, symbolize_names: true)
13
14
  @access_token = json[:access_token]
14
15
  @refresh_token = json[:refresh_token]
16
+ @user = WorkOS::User.new(json[:user].to_json)
17
+ @organization_id = json[:organization_id]
18
+ @impersonator =
19
+ if (impersonator_json = json[:impersonator])
20
+ Impersonator.new(email: impersonator_json[:email],
21
+ reason: impersonator_json[:reason],)
22
+ end
23
+ @sealed_session =
24
+ if session && session[:seal_session]
25
+ WorkOS::Session.seal_data(
26
+ {
27
+ access_token: access_token,
28
+ refresh_token: refresh_token,
29
+ user: user.to_json,
30
+ organization_id: organization_id,
31
+ impersonator: impersonator.to_json,
32
+ },
33
+ session[:cookie_password],
34
+ encryptor: session[:encryptor],
35
+ )
36
+ end
15
37
  end
38
+ # rubocop:enable Metrics/AbcSize
16
39
 
17
40
  def to_json(*)
18
41
  {
42
+ user: user.to_json,
43
+ organization_id: organization_id,
44
+ impersonator: impersonator.to_json,
19
45
  access_token: access_token,
20
46
  refresh_token: refresh_token,
47
+ sealed_session: sealed_session,
21
48
  }
22
49
  end
23
50
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WorkOS
4
+ # The Role class provides a lightweight wrapper around
5
+ # a WorkOS Role resource. This class is not meant to be instantiated
6
+ # in user space, and is instantiated internally but exposed.
7
+ class Role
8
+ include HashProvider
9
+
10
+ attr_accessor :id, :name, :slug, :description, :permissions, :type, :created_at, :updated_at
11
+
12
+ def initialize(json)
13
+ hash = JSON.parse(json, symbolize_names: true)
14
+
15
+ @id = hash[:id]
16
+ @name = hash[:name]
17
+ @slug = hash[:slug]
18
+ @description = hash[:description]
19
+ @permissions = hash[:permissions] || []
20
+ @type = hash[:type]
21
+ @created_at = hash[:created_at]
22
+ @updated_at = hash[:updated_at]
23
+ end
24
+
25
+ def to_json(*)
26
+ {
27
+ id: id,
28
+ name: name,
29
+ slug: slug,
30
+ description: description,
31
+ permissions: permissions,
32
+ type: type,
33
+ created_at: created_at,
34
+ updated_at: updated_at,
35
+ }
36
+ end
37
+ end
38
+ end