workos 5.11.0 → 5.12.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.
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