workos 5.11.0 → 5.12.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b3b8df2a135ab2c2493c5d18c0435f81facd859e396671de49f5407943abfb0b
4
- data.tar.gz: 1aa8b210fffda9deece1478ef33d0cc85ac014e8c03bc308d6959ca6984563e6
3
+ metadata.gz: 6852c01440a63d103cd39a4c0aee2eeb5d1215d79a3e8eb2a3053b5aa3f3376e
4
+ data.tar.gz: 71c5c53d1f8fc5219903cfcfc23cbeb657da1db2c64980fa9d8914bd6ae92b1d
5
5
  SHA512:
6
- metadata.gz: 0ada12739dd063caf865f32aab5db4376177b6642ada12cd7d5457cdd9a000f5cd419ca39964b3f24cc73801579c4bf8e1d8832a7cc92b2aaaf09b3fb4edf9fb
7
- data.tar.gz: 395e87fa94cf398df6febdbbc65616613ad175a8ab624c40fb991509428481178e03ebba613913fd4d050ea62b05f21feeae05478c1efcb86004e127da893af3
6
+ metadata.gz: eb001da89bc0cf2866dcfd4d4c5207ddc7c960538ab413c45fcd5d5f80e4c97e205cc0e3fb51bdaaf8af984e9e30ad5c317c30e453c8e6579c1914350dfe3f2c
7
+ data.tar.gz: 5fe92a1ad40c3bced46b0597430b02ea36b20c82f109614df332695aa7d9f613a025e0f30d3afcaab978c5b3de6882a3a67886e55343de513fb508950664a5d3
@@ -17,8 +17,6 @@ jobs:
17
17
  strategy:
18
18
  matrix:
19
19
  ruby:
20
- - '2.7'
21
- - '3.0'
22
20
  - '3.1'
23
21
  - '3.2'
24
22
  steps:
data/.rubocop.yml CHANGED
@@ -1,6 +1,5 @@
1
- # Disabling due to conflict with Ruby 2.7/3.1
2
- Layout/BlockAlignment:
3
- Enabled: false
1
+ inherit_from: .rubocop_todo.yml
2
+
4
3
  Layout/DotPosition:
5
4
  EnforcedStyle: trailing
6
5
  Layout/EmptyLineAfterMagicComment:
@@ -8,11 +7,11 @@ Layout/EmptyLineAfterMagicComment:
8
7
  Layout/EmptyLines:
9
8
  Enabled: false
10
9
  Layout/LineLength:
11
- IgnoredPatterns:
10
+ AllowedPatterns:
12
11
  - 'VCR\.use_cassette'
13
12
  - '(\A|\s)/.*?/'
14
13
  Metrics/BlockLength:
15
- ExcludedMethods: ['describe', 'context', 'before', 'it']
14
+ AllowedMethods: ['describe', 'context', 'before', 'it']
16
15
  Metrics/MethodLength:
17
16
  Max: 30
18
17
  Metrics/ModuleLength:
@@ -28,4 +27,4 @@ Style/TrailingCommaInArguments:
28
27
  Style/TrailingCommaInHashLiteral:
29
28
  EnforcedStyleForMultiline: 'consistent_comma'
30
29
  AllCops:
31
- TargetRubyVersion: 2.7
30
+ TargetRubyVersion: 3.1
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,94 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2025-01-22 21:38:20 UTC using RuboCop version 1.71.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 1
10
+ # This cop supports safe autocorrection (--autocorrect).
11
+ # Configuration parameters: EnforcedStyleAlignWith.
12
+ # SupportedStylesAlignWith: either, start_of_block, start_of_line
13
+ Layout/BlockAlignment:
14
+ Exclude:
15
+ - 'spec/lib/workos/session_spec.rb'
16
+
17
+ # Offense count: 2
18
+ # This cop supports safe autocorrection (--autocorrect).
19
+ Layout/EmptyLinesAroundMethodBody:
20
+ Exclude:
21
+ - 'lib/workos/mfa.rb'
22
+ - 'lib/workos/user_management.rb'
23
+
24
+ # Offense count: 1
25
+ # This cop supports safe autocorrection (--autocorrect).
26
+ Layout/SpaceAroundMethodCallOperator:
27
+ Exclude:
28
+ - 'spec/lib/workos/directory_sync_spec.rb'
29
+
30
+ # Offense count: 1
31
+ # This cop supports unsafe autocorrection (--autocorrect-all).
32
+ Lint/DuplicateRequire:
33
+ Exclude:
34
+ - 'lib/workos/session.rb'
35
+
36
+ # Offense count: 3
37
+ # Configuration parameters: AllowedParentClasses.
38
+ Lint/MissingSuper:
39
+ Exclude:
40
+ - 'lib/workos/directory_group.rb'
41
+ - 'lib/workos/directory_user.rb'
42
+ - 'lib/workos/errors.rb'
43
+
44
+ # Offense count: 5
45
+ # Configuration parameters: CountComments, CountAsOne.
46
+ Metrics/ClassLength:
47
+ Max: 624
48
+
49
+ # Offense count: 8
50
+ # This cop supports safe autocorrection (--autocorrect).
51
+ # Configuration parameters: EnforcedStyle.
52
+ # SupportedStyles: separated, grouped
53
+ Style/AccessorGrouping:
54
+ Exclude:
55
+ - 'lib/workos/errors.rb'
56
+
57
+ # Offense count: 34
58
+ # This cop supports safe autocorrection (--autocorrect).
59
+ # Configuration parameters: EnforcedStyle.
60
+ # SupportedStyles: braces, no_braces
61
+ Style/HashAsLastArrayItem:
62
+ Exclude:
63
+ - 'spec/lib/workos/directory_sync_spec.rb'
64
+ - 'spec/lib/workos/event_spec.rb'
65
+ - 'spec/lib/workos/organizations_spec.rb'
66
+ - 'spec/lib/workos/sso_spec.rb'
67
+ - 'spec/lib/workos/user_management_spec.rb'
68
+
69
+ # Offense count: 2
70
+ # This cop supports safe autocorrection (--autocorrect).
71
+ Style/KeywordParametersOrder:
72
+ Exclude:
73
+ - 'lib/workos/organizations.rb'
74
+
75
+ # Offense count: 3
76
+ # This cop supports unsafe autocorrection (--autocorrect-all).
77
+ # Configuration parameters: SafeForConstants.
78
+ Style/RedundantFetchBlock:
79
+ Exclude:
80
+ - 'spec/lib/workos/cache_spec.rb'
81
+
82
+ # Offense count: 1
83
+ # This cop supports safe autocorrection (--autocorrect).
84
+ # Configuration parameters: AllowMultipleReturnValues.
85
+ Style/RedundantReturn:
86
+ Exclude:
87
+ - 'lib/workos/directory_user.rb'
88
+
89
+ # Offense count: 2
90
+ # This cop supports unsafe autocorrection (--autocorrect-all).
91
+ Style/SlicingWithRange:
92
+ Exclude:
93
+ - 'lib/workos/deprecated_hash_wrapper.rb'
94
+ - 'lib/workos/session.rb'
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.0.2
1
+ 3.1.4
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- workos (5.11.0)
4
+ workos (5.12.0)
5
5
  encryptor (~> 3.0)
6
6
  jwt (~> 2.8)
7
7
 
@@ -19,16 +19,18 @@ GEM
19
19
  diff-lcs (1.5.1)
20
20
  encryptor (3.0.0)
21
21
  hashdiff (1.1.0)
22
+ json (2.9.1)
22
23
  jwt (2.10.1)
23
24
  base64
24
- parallel (1.24.0)
25
- parser (3.3.0.5)
25
+ language_server-protocol (3.17.0.3)
26
+ parallel (1.26.3)
27
+ parser (3.3.7.0)
26
28
  ast (~> 2.4.1)
27
29
  racc
28
30
  public_suffix (5.0.4)
29
- racc (1.7.3)
31
+ racc (1.8.1)
30
32
  rainbow (3.1.1)
31
- regexp_parser (2.9.0)
33
+ regexp_parser (2.10.0)
32
34
  rexml (3.2.6)
33
35
  rspec (3.9.0)
34
36
  rspec-core (~> 3.9.0)
@@ -43,19 +45,22 @@ GEM
43
45
  diff-lcs (>= 1.2.0, < 2.0)
44
46
  rspec-support (~> 3.9.0)
45
47
  rspec-support (3.9.4)
46
- rubocop (0.93.1)
48
+ rubocop (1.71.0)
49
+ json (~> 2.3)
50
+ language_server-protocol (>= 3.17.0)
47
51
  parallel (~> 1.10)
48
- parser (>= 2.7.1.5)
52
+ parser (>= 3.3.0.2)
49
53
  rainbow (>= 2.2.2, < 4.0)
50
- regexp_parser (>= 1.8)
51
- rexml
52
- rubocop-ast (>= 0.6.0)
54
+ regexp_parser (>= 2.9.3, < 3.0)
55
+ rubocop-ast (>= 1.36.2, < 2.0)
53
56
  ruby-progressbar (~> 1.7)
54
- unicode-display_width (>= 1.4.0, < 2.0)
55
- rubocop-ast (1.31.2)
56
- parser (>= 3.3.0.4)
57
+ unicode-display_width (>= 2.4.0, < 4.0)
58
+ rubocop-ast (1.37.0)
59
+ parser (>= 3.3.1.0)
57
60
  ruby-progressbar (1.13.0)
58
- unicode-display_width (1.8.0)
61
+ unicode-display_width (3.1.4)
62
+ unicode-emoji (~> 4.0, >= 4.0.4)
63
+ unicode-emoji (4.0.4)
59
64
  vcr (5.0.0)
60
65
  webmock (3.23.0)
61
66
  addressable (>= 2.8.0)
@@ -68,7 +73,7 @@ PLATFORMS
68
73
  DEPENDENCIES
69
74
  bundler (>= 2.0.1)
70
75
  rspec (~> 3.9.0)
71
- rubocop (~> 0.77)
76
+ rubocop (~> 1.71)
72
77
  vcr (~> 5.0.0)
73
78
  webmock
74
79
  workos!
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WorkOS
4
+ # The Cache module provides a simple in-memory cache for storing values
5
+ # This module is not meant to be instantiated in a user space, and is used internally by the SDK
6
+ module Cache
7
+ # The Entry class represents a cache entry with a value and an expiration time
8
+ class Entry
9
+ attr_reader :value, :expires_at
10
+
11
+ # Initializes a new cache entry
12
+ # @param value [Object] The value to store in the cache
13
+ # @param expires_in_seconds [Integer, nil] The expiration time for the value in seconds, or nil for no expiration
14
+ def initialize(value, expires_in_seconds)
15
+ @value = value
16
+ @expires_at = expires_in_seconds ? Time.now + expires_in_seconds : nil
17
+ end
18
+
19
+ # Checks if the entry has expired
20
+ # @return [Boolean] True if the entry has expired, false otherwise
21
+ def expired?
22
+ return false if expires_at.nil?
23
+
24
+ Time.now > @expires_at
25
+ end
26
+ end
27
+
28
+ class << self
29
+ # Fetches a value from the cache, or calls the block to fetch the value if it is not present
30
+ # @param key [String] The key to fetch the value for
31
+ # @param expires_in [Integer] The expiration time for the value in seconds
32
+ # @param force [Boolean] If true, the value will be fetched from the block even if it is present in the cache
33
+ # @param block [Proc] The block to call to fetch the value if it is not present in the cache
34
+ # @return [Object] The value fetched from the cache or the block
35
+ def fetch(key, expires_in: nil, force: false, &block)
36
+ entry = store[key]
37
+
38
+ if force || entry.nil? || entry.expired?
39
+ value = block.call
40
+ store[key] = Entry.new(value, expires_in)
41
+ return value
42
+ end
43
+
44
+ entry.value
45
+ end
46
+
47
+ # Reads a value from the cache
48
+ # @param key [String] The key to read the value for
49
+ # @return [Object] The value read from the cache, or nil if the value is not present or has expired
50
+ def read(key)
51
+ entry = store[key]
52
+ return nil if entry.nil? || entry.expired?
53
+
54
+ entry.value
55
+ end
56
+
57
+ # Writes a value to the cache
58
+ # @param key [String] The key to write the value for
59
+ # @param value [Object] The value to write to the cache
60
+ # @param expires_in [Integer] The expiration time for the value in seconds
61
+ # @return [Object] The value written to the cache
62
+ def write(key, value, expires_in: nil)
63
+ store[key] = Entry.new(value, expires_in)
64
+ value
65
+ end
66
+
67
+ # Deletes a value from the cache
68
+ # @param key [String] The key to delete the value for
69
+ def delete(key)
70
+ store.delete(key)
71
+ end
72
+
73
+ # Clears all values from the cache
74
+ def clear
75
+ store.clear
76
+ end
77
+
78
+ # Checks if a value exists in the cache
79
+ # @param key [String] The key to check for
80
+ # @return [Boolean] True if the value exists and has not expired, false otherwise
81
+ def exist?(key)
82
+ entry = store[key]
83
+ !(entry.nil? || entry.expired?)
84
+ end
85
+
86
+ private
87
+
88
+ # The in-memory store for the cache
89
+ def store
90
+ @store ||= {}
91
+ end
92
+ end
93
+ end
94
+ end
@@ -7,7 +7,15 @@ 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
+ :allow_profiles_outside_organization,
16
+ :created_at,
17
+ :updated_at,
18
+ )
11
19
 
12
20
  def initialize(json)
13
21
  hash = JSON.parse(json, symbolize_names: true)
@@ -16,6 +24,7 @@ module WorkOS
16
24
  @name = hash[:name]
17
25
  @allow_profiles_outside_organization = hash[:allow_profiles_outside_organization]
18
26
  @domains = hash[:domains]
27
+ @stripe_customer_id = hash[:stripe_customer_id]
19
28
  @created_at = hash[:created_at]
20
29
  @updated_at = hash[:updated_at]
21
30
  end
@@ -26,6 +35,7 @@ module WorkOS
26
35
  name: name,
27
36
  allow_profiles_outside_organization: allow_profiles_outside_organization,
28
37
  domains: domains,
38
+ stripe_customer_id: stripe_customer_id,
29
39
  created_at: created_at,
30
40
  updated_at: updated_at,
31
41
  }
@@ -71,7 +71,7 @@ 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
@@ -118,9 +118,10 @@ module WorkOS
118
118
  # Update an organization
119
119
  #
120
120
  # @param [String] organization Organization unique identifier
121
- # @param [Array<Hash>] domain_data List of domain hashes describing an orgnaization domain.
121
+ # @param [Array<Hash>] domain_data List of domain hashes describing an organization domain.
122
122
  # @option domain_data [String] domain The domain that belongs to the organization.
123
123
  # @option domain_data [String] state The state of the domain. "verified" or "pending"
124
+ # @param [String] stripe_customer_id The Stripe customer ID associated with this organization.
124
125
  # @param [String] name A unique, descriptive name for the organization
125
126
  # @param [Boolean, nil] allow_profiles_outside_organization Whether Connections
126
127
  # within the Organization allow profiles that are outside of the Organization's configured User Email Domains.
@@ -129,6 +130,7 @@ module WorkOS
129
130
  # Deprecated: Use domain_data instead.
130
131
  def update_organization(
131
132
  organization:,
133
+ stripe_customer_id: nil,
132
134
  domain_data: nil,
133
135
  domains: nil,
134
136
  name: nil,
@@ -136,6 +138,7 @@ module WorkOS
136
138
  )
137
139
  body = { name: name }
138
140
  body[:domain_data] = domain_data if domain_data
141
+ body[:stripe_customer_id] = stripe_customer_id if stripe_customer_id
139
142
 
140
143
  if domains
141
144
  warn_deprecation '`domains` is deprecated. Use `domain_data` instead.'
@@ -11,7 +11,6 @@ require 'uri'
11
11
  module WorkOS
12
12
  # The Session class provides helper methods for working with WorkOS sessions
13
13
  # This class is not meant to be instantiated in a user space, and is instantiated internally but exposed.
14
- # rubocop:disable Metrics/ClassLength
15
14
  class Session
16
15
  attr_accessor :jwks, :jwks_algorithms, :user_management, :cookie_password, :session_data, :client_id
17
16
 
@@ -23,7 +22,9 @@ module WorkOS
23
22
  @session_data = session_data
24
23
  @client_id = client_id
25
24
 
26
- @jwks = create_remote_jwk_set(URI(@user_management.get_jwks_url(client_id)))
25
+ @jwks = Cache.fetch("jwks_#{client_id}", expires_in: 5 * 60) do
26
+ create_remote_jwk_set(URI(@user_management.get_jwks_url(client_id)))
27
+ end
27
28
  @jwks_algorithms = @jwks.map { |key| key[:alg] }.compact.uniq
28
29
  end
29
30
 
@@ -178,5 +179,4 @@ module WorkOS
178
179
  end
179
180
  # rubocop:enable Naming/PredicateName
180
181
  end
181
- # rubocop:enable Metrics/ClassLength
182
182
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WorkOS
4
- VERSION = '5.11.0'
4
+ VERSION = '5.12.0'
5
5
  end
data/lib/workos.rb CHANGED
@@ -45,6 +45,7 @@ module WorkOS
45
45
  autoload :AuthenticationFactorAndChallenge, 'workos/authentication_factor_and_challenge'
46
46
  autoload :AuthenticationResponse, 'workos/authentication_response'
47
47
  autoload :AuditLogs, 'workos/audit_logs'
48
+ autoload :Cache, 'workos/cache'
48
49
  autoload :Challenge, 'workos/challenge'
49
50
  autoload :Client, 'workos/client'
50
51
  autoload :Connection, 'workos/connection'
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe WorkOS::Cache do
4
+ before { described_class.clear }
5
+
6
+ describe '.write and .read' do
7
+ it 'stores and retrieves data' do
8
+ described_class.write('key', 'value')
9
+ expect(described_class.read('key')).to eq('value')
10
+ end
11
+
12
+ it 'returns nil if key does not exist' do
13
+ expect(described_class.read('missing')).to be_nil
14
+ end
15
+ end
16
+
17
+ describe '.fetch' do
18
+ it 'returns cached value when present and not expired' do
19
+ described_class.write('key', 'value')
20
+ fetch_value = described_class.fetch('key') { 'new_value' }
21
+ expect(fetch_value).to eq('value')
22
+ end
23
+
24
+ it 'executes block and caches value when not present' do
25
+ fetch_value = described_class.fetch('key') { 'new_value' }
26
+ expect(fetch_value).to eq('new_value')
27
+ end
28
+
29
+ it 'executes block and caches value when force is true' do
30
+ described_class.write('key', 'value')
31
+ fetch_value = described_class.fetch('key', force: true) { 'new_value' }
32
+ expect(fetch_value).to eq('new_value')
33
+ end
34
+ end
35
+
36
+ describe 'expiration' do
37
+ it 'expires values after specified time' do
38
+ described_class.write('key', 'value', expires_in: 0.1)
39
+ expect(described_class.read('key')).to eq('value')
40
+ sleep 0.2
41
+ expect(described_class.read('key')).to be_nil
42
+ end
43
+
44
+ it 'executes block and caches new value when expired' do
45
+ described_class.write('key', 'old_value', expires_in: 0.1)
46
+ sleep 0.2
47
+ fetch_value = described_class.fetch('key') { 'new_value' }
48
+ expect(fetch_value).to eq('new_value')
49
+ end
50
+
51
+ it 'does not expire values when expires_in is nil' do
52
+ described_class.write('key', 'value', expires_in: nil)
53
+ sleep 0.2
54
+ expect(described_class.read('key')).to eq('value')
55
+ end
56
+ end
57
+
58
+ describe '.exist?' do
59
+ it 'returns true if key exists' do
60
+ described_class.write('key', 'value')
61
+ expect(described_class.exist?('key')).to be true
62
+ end
63
+
64
+ it 'returns false if expired' do
65
+ described_class.write('key', 'value', expires_in: 0.1)
66
+ sleep 0.2
67
+ expect(described_class.exist?('key')).to be false
68
+ end
69
+
70
+ it 'returns false if key does not exist' do
71
+ expect(described_class.exist?('missing')).to be false
72
+ end
73
+ end
74
+
75
+ describe '.delete' do
76
+ it 'deletes key' do
77
+ described_class.write('key', 'value')
78
+ described_class.delete('key')
79
+ expect(described_class.read('key')).to be_nil
80
+ end
81
+ end
82
+
83
+ describe '.clear' do
84
+ it 'removes all keys from the cache' do
85
+ described_class.write('key1', 'value1')
86
+ described_class.write('key2', 'value2')
87
+
88
+ described_class.clear
89
+
90
+ expect(described_class.read('key1')).to be_nil
91
+ expect(described_class.read('key2')).to be_nil
92
+ end
93
+ end
94
+ end
@@ -295,6 +295,21 @@ describe WorkOS::Organizations do
295
295
  end
296
296
  end
297
297
  end
298
+ context 'with a stripe_customer_id' do
299
+ it 'updates the organization' do
300
+ VCR.use_cassette 'organization/update_with_stripe_customer_id' do
301
+ organization = described_class.update_organization(
302
+ organization: 'org_01JJ5H14CAA2SQ5G9HNN6TBZ05',
303
+ name: 'Test Organization',
304
+ stripe_customer_id: 'cus_123',
305
+ )
306
+
307
+ expect(organization.id).to eq('org_01JJ5H14CAA2SQ5G9HNN6TBZ05')
308
+ expect(organization.name).to eq('Test Organization')
309
+ expect(organization.stripe_customer_id).to eq('cus_123')
310
+ end
311
+ end
312
+ end
298
313
  end
299
314
 
300
315
  describe '.delete_organization' do
@@ -19,6 +19,52 @@ describe WorkOS::Session do
19
19
  allow(user_management).to receive(:get_jwks_url).with(client_id).and_return(jwks_url)
20
20
  end
21
21
 
22
+ describe 'JWKS caching' do
23
+ before do
24
+ WorkOS::Cache.clear
25
+ end
26
+
27
+ it 'caches and returns JWKS' do
28
+ expect(Net::HTTP).to receive(:get).once
29
+ session1 = WorkOS::Session.new(
30
+ user_management: user_management,
31
+ client_id: client_id,
32
+ session_data: session_data,
33
+ cookie_password: cookie_password,
34
+ )
35
+
36
+ session2 = WorkOS::Session.new(
37
+ user_management: user_management,
38
+ client_id: client_id,
39
+ session_data: session_data,
40
+ cookie_password: cookie_password,
41
+ )
42
+
43
+ expect(session1.jwks.map(&:export)).to eq(session2.jwks.map(&:export))
44
+ end
45
+
46
+ it 'fetches JWKS from remote when cache is expired' do
47
+ expect(Net::HTTP).to receive(:get).twice
48
+ session1 = WorkOS::Session.new(
49
+ user_management: user_management,
50
+ client_id: client_id,
51
+ session_data: session_data,
52
+ cookie_password: cookie_password,
53
+ )
54
+
55
+ allow(Time).to receive(:now).and_return(Time.now + 301)
56
+
57
+ session2 = WorkOS::Session.new(
58
+ user_management: user_management,
59
+ client_id: client_id,
60
+ session_data: session_data,
61
+ cookie_password: cookie_password,
62
+ )
63
+
64
+ expect(session1.jwks.map(&:export)).to eq(session2.jwks.map(&:export))
65
+ end
66
+ end
67
+
22
68
  it 'raises an error if cookie_password is nil or empty' do
23
69
  expect do
24
70
  WorkOS::Session.new(
@@ -0,0 +1,78 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: put
5
+ uri: https://api.workos.com/organizations/org_01JJ5H14CAA2SQ5G9HNN6TBZ05
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"name":"Test Organization","stripe_customer_id":"cus_123"}'
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Accept-Encoding:
13
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
14
+ Accept:
15
+ - "*/*"
16
+ User-Agent:
17
+ - WorkOS; ruby/3.1.4; arm64-darwin24; v5.11.1
18
+ Authorization:
19
+ - Bearer <API_KEY>
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Date:
26
+ - Wed, 22 Jan 2025 16:50:26 GMT
27
+ Content-Type:
28
+ - application/json; charset=utf-8
29
+ Transfer-Encoding:
30
+ - chunked
31
+ Connection:
32
+ - keep-alive
33
+ Cf-Ray:
34
+ - 90610b03f84db9f1-SEA
35
+ Cf-Cache-Status:
36
+ - DYNAMIC
37
+ Etag:
38
+ - W/"1cc-uqKwJf4L85rLspCK9lJ1ceRlbSA"
39
+ Strict-Transport-Security:
40
+ - max-age=15552000; includeSubDomains
41
+ Vary:
42
+ - Origin, Accept-Encoding
43
+ Access-Control-Allow-Credentials:
44
+ - 'true'
45
+ Content-Security-Policy:
46
+ - 'default-src ''self'';base-uri ''self'';block-all-mixed-content;font-src ''self''
47
+ https: data:;frame-ancestors ''self'';img-src ''self'' data:;object-src ''none'';script-src
48
+ ''self'';script-src-attr ''none'';style-src ''self'' https: ''unsafe-inline'';upgrade-insecure-requests'
49
+ Expect-Ct:
50
+ - max-age=0
51
+ Referrer-Policy:
52
+ - no-referrer
53
+ X-Content-Type-Options:
54
+ - nosniff
55
+ X-Dns-Prefetch-Control:
56
+ - 'off'
57
+ X-Download-Options:
58
+ - noopen
59
+ X-Frame-Options:
60
+ - SAMEORIGIN
61
+ X-Permitted-Cross-Domain-Policies:
62
+ - none
63
+ X-Request-Id:
64
+ - 7b62039f-40f4-4c2c-9ef9-7b1f63615481
65
+ X-Xss-Protection:
66
+ - '0'
67
+ Set-Cookie:
68
+ - _cfuvid=TPT.bwe9giSuDXv9bDFC8leHolKCFKy2kdsa0G89jGI-1737564626875-0.0.1.1-604800000;
69
+ path=/; domain=.workos.com; HttpOnly; Secure; SameSite=None
70
+ Server:
71
+ - cloudflare
72
+ body:
73
+ encoding: ASCII-8BIT
74
+ string: '{"object":"organization","id":"org_01JJ5H14CAA2SQ5G9HNN6TBZ05","name":"Test
75
+ Organization","allow_profiles_outside_organization":false,"created_at":"2025-01-21T22:51:46.441Z","updated_at":"2025-01-22T16:50:26.789Z","domains":[{"verification_strategy":"manual","state":"verified","object":"organization_domain","id":"org_domain_01JJ5H14CKRGAE9HVA1Y9YABSX","organization_id":"org_01JJ5H14CAA2SQ5G9HNN6TBZ05","domain":"example.me"}],"stripe_customer_id":"cus_123"}'
76
+ http_version:
77
+ recorded_at: Wed, 22 Jan 2025 16:50:26 GMT
78
+ recorded_with: VCR 5.0.0
data/workos.gemspec CHANGED
@@ -26,9 +26,9 @@ Gem::Specification.new do |spec|
26
26
 
27
27
  spec.add_development_dependency 'bundler', '>= 2.0.1'
28
28
  spec.add_development_dependency 'rspec', '~> 3.9.0'
29
- spec.add_development_dependency 'rubocop', '~> 0.77'
29
+ spec.add_development_dependency 'rubocop', '~> 1.71'
30
30
  spec.add_development_dependency 'vcr', '~> 5.0.0'
31
31
  spec.add_development_dependency 'webmock'
32
32
 
33
- spec.required_ruby_version = '>= 2.7'
33
+ spec.required_ruby_version = '>= 3.1'
34
34
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: workos
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.11.0
4
+ version: 5.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - WorkOS
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-01-15 00:00:00.000000000 Z
11
+ date: 2025-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: encryptor
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0.77'
75
+ version: '1.71'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0.77'
82
+ version: '1.71'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: vcr
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -123,6 +123,7 @@ files:
123
123
  - ".gitignore"
124
124
  - ".rspec"
125
125
  - ".rubocop.yml"
126
+ - ".rubocop_todo.yml"
126
127
  - ".ruby-version"
127
128
  - Gemfile
128
129
  - Gemfile.lock
@@ -136,6 +137,7 @@ files:
136
137
  - lib/workos/audit_logs.rb
137
138
  - lib/workos/authentication_factor_and_challenge.rb
138
139
  - lib/workos/authentication_response.rb
140
+ - lib/workos/cache.rb
139
141
  - lib/workos/challenge.rb
140
142
  - lib/workos/client.rb
141
143
  - lib/workos/configuration.rb
@@ -184,6 +186,7 @@ files:
184
186
  - lib/workos/webhooks.rb
185
187
  - lib/workos/widgets.rb
186
188
  - spec/lib/workos/audit_logs_spec.rb
189
+ - spec/lib/workos/cache_spec.rb
187
190
  - spec/lib/workos/client.rb
188
191
  - spec/lib/workos/configuration_spec.rb
189
192
  - spec/lib/workos/directory_sync_spec.rb
@@ -270,6 +273,7 @@ files:
270
273
  - spec/support/fixtures/vcr_cassettes/organization/list.yml
271
274
  - spec/support/fixtures/vcr_cassettes/organization/list_organization_roles.yml
272
275
  - spec/support/fixtures/vcr_cassettes/organization/update.yml
276
+ - spec/support/fixtures/vcr_cassettes/organization/update_with_stripe_customer_id.yml
273
277
  - spec/support/fixtures/vcr_cassettes/organization/update_without_name.yml
274
278
  - spec/support/fixtures/vcr_cassettes/passwordless/create_session.yml
275
279
  - spec/support/fixtures/vcr_cassettes/passwordless/create_session_invalid.yml
@@ -382,7 +386,7 @@ licenses:
382
386
  - MIT
383
387
  metadata:
384
388
  documentation_uri: https://docs.workos.com/sdk/ruby
385
- post_install_message:
389
+ post_install_message:
386
390
  rdoc_options: []
387
391
  require_paths:
388
392
  - lib
@@ -390,7 +394,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
390
394
  requirements:
391
395
  - - ">="
392
396
  - !ruby/object:Gem::Version
393
- version: '2.7'
397
+ version: '3.1'
394
398
  required_rubygems_version: !ruby/object:Gem::Requirement
395
399
  requirements:
396
400
  - - ">="
@@ -398,11 +402,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
398
402
  version: '0'
399
403
  requirements: []
400
404
  rubygems_version: 3.4.19
401
- signing_key:
405
+ signing_key:
402
406
  specification_version: 4
403
407
  summary: API client for WorkOS
404
408
  test_files:
405
409
  - spec/lib/workos/audit_logs_spec.rb
410
+ - spec/lib/workos/cache_spec.rb
406
411
  - spec/lib/workos/client.rb
407
412
  - spec/lib/workos/configuration_spec.rb
408
413
  - spec/lib/workos/directory_sync_spec.rb
@@ -489,6 +494,7 @@ test_files:
489
494
  - spec/support/fixtures/vcr_cassettes/organization/list.yml
490
495
  - spec/support/fixtures/vcr_cassettes/organization/list_organization_roles.yml
491
496
  - spec/support/fixtures/vcr_cassettes/organization/update.yml
497
+ - spec/support/fixtures/vcr_cassettes/organization/update_with_stripe_customer_id.yml
492
498
  - spec/support/fixtures/vcr_cassettes/organization/update_without_name.yml
493
499
  - spec/support/fixtures/vcr_cassettes/passwordless/create_session.yml
494
500
  - spec/support/fixtures/vcr_cassettes/passwordless/create_session_invalid.yml