volcano-sdk 0.28.0 → 0.30.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.
@@ -3,8 +3,8 @@
3
3
  module Volcano
4
4
  # Queues auth events under the state mutex and invokes subscribers outside it.
5
5
  module AuthStateNotifications
6
- CALLBACK_FAILURES = [Exception].freeze
7
- private_constant :CALLBACK_FAILURES
6
+ CALLBACK_FAILURE = Exception
7
+ private_constant :CALLBACK_FAILURE
8
8
 
9
9
  private
10
10
 
@@ -26,12 +26,14 @@ module Volcano
26
26
  end
27
27
 
28
28
  def drain_notifications
29
+ # @type var failure: Exception?
29
30
  failure = nil
30
31
  loop do
31
32
  notification = next_notification
32
33
  break unless notification
33
34
 
34
- current_failure = notify(*notification)
35
+ callback_ids, event, session = notification
36
+ current_failure = notify(callback_ids, event, session)
35
37
  failure ||= current_failure
36
38
  end
37
39
  raise failure if failure
@@ -48,12 +50,13 @@ module Volcano
48
50
  end
49
51
 
50
52
  def notify(callback_ids, event, session)
53
+ # @type var failure: Exception?
51
54
  failure = nil
52
55
  callback_ids.each do |callback_id|
53
56
  @mutex.synchronize { @callbacks[callback_id] }&.call(event, session)
54
57
  rescue StandardError => e
55
58
  Warning.warn("Volcano auth-state callback failed (#{e.class})\n")
56
- rescue *CALLBACK_FAILURES => e
59
+ rescue CALLBACK_FAILURE => e
57
60
  unsubscribe(callback_id)
58
61
  failure ||= e
59
62
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Volcano
4
4
  # Current-user update behavior for the authentication facade.
5
- class Auth
5
+ module AuthUpdateUser
6
6
  def update_user(password: nil, metadata: nil)
7
7
  profile_request do
8
8
  request_password = password&.dup&.freeze
@@ -52,7 +52,9 @@ module Volcano
52
52
  invoke do
53
53
  apis = @api_factory.call(authorization)
54
54
  body = Generated::ProjectLockLeaseRequest.new(ttl_seconds: ttl)
55
- result = apis.locks.acquire_project_lock_with_http_info(key, token, request_id, body)
55
+ result = apis.locks.acquire_project_lock_with_http_info(
56
+ key, token, request_id, body, debug_return_type: 'Object'
57
+ )
56
58
  data, status, headers = result
57
59
  response(data, status, headers)
58
60
  end
@@ -63,7 +65,8 @@ module Volcano
63
65
  apis = @api_factory.call(authorization)
64
66
  data, status, headers = apis.locks.get_project_lock_with_http_info(
65
67
  key,
66
- request_id
68
+ request_id,
69
+ debug_return_type: 'Object'
67
70
  )
68
71
  response(data, status, headers)
69
72
  end
@@ -85,7 +88,7 @@ module Volcano
85
88
  apis = @api_factory.call(authorization)
86
89
  body = Generated::ProjectLockLeaseRequest.new(ttl_seconds: ttl)
87
90
  result = apis.locks.renew_project_lock_with_http_info(
88
- key, token, request_id, body
91
+ key, token, request_id, body, debug_return_type: 'Object'
89
92
  )
90
93
  data, status, headers = result
91
94
  response(data, status, headers)
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+
5
+ module Volcano
6
+ # Validates lock response fields before creating public records.
7
+ module LockResponse
8
+ private
9
+
10
+ def parse_time(value)
11
+ return Time.iso8601(value) if value.is_a?(String)
12
+ return value if value.nil? || value.is_a?(Time)
13
+
14
+ raise Error::TransportError, 'invalid lock expiry'
15
+ rescue ArgumentError => e
16
+ raise Error::TransportError, 'invalid lock expiry', cause: e
17
+ end
18
+
19
+ def required_time(value)
20
+ parse_time(value) || raise(Error::TransportError, 'invalid lock expiry')
21
+ end
22
+
23
+ def lock_payload(body)
24
+ raise Error::TransportError, 'invalid lock response' unless body.is_a?(Hash)
25
+
26
+ body
27
+ end
28
+
29
+ def lock_held(value)
30
+ return true if value == true
31
+ return false if value == false
32
+
33
+ raise Error::TransportError, 'invalid lock held flag'
34
+ end
35
+
36
+ def required_fencing_token(value)
37
+ raise Error::TransportError, 'invalid lock fencing token' unless value.is_a?(Integer)
38
+
39
+ value
40
+ end
41
+
42
+ def optional_fencing_token(value)
43
+ return if value.nil?
44
+
45
+ required_fencing_token(value)
46
+ end
47
+ end
48
+ end
data/lib/volcano/locks.rb CHANGED
@@ -7,6 +7,7 @@ module Volcano
7
7
  # Acquires and releases project-scoped distributed locks.
8
8
  class Locks
9
9
  include LockAutoRenewal
10
+ include LockResponse
10
11
 
11
12
  def initialize(client, transport)
12
13
  @client = client
@@ -14,80 +15,103 @@ module Volcano
14
15
  end
15
16
 
16
17
  def get(key, request_id: nil)
17
- payload = lock_request(:get_project_lock, 200, key: key, request_id: request_id)
18
- LockState.new(
19
- held: payload.fetch('held'),
20
- expires_at: parse_time(payload['expires_at']),
21
- fencing_token: payload['fencing_token']
22
- )
18
+ payload = lock_payload(perform_request(200) do
19
+ @transport.get_project_lock(
20
+ authorization: @client.service_token, key: key, request_id: request_uuid(request_id, 'request_id')
21
+ )
22
+ end)
23
+ build_state(payload)
23
24
  end
24
25
 
25
26
  def acquire(key, ttl:, token: nil, request_id: nil)
26
27
  validate_ttl(ttl)
27
- parameters = {
28
- authorization: @client.service_token.dup.freeze, key: key.dup.freeze,
29
- ttl: ttl, token: request_uuid(token, 'token'), request_id: request_uuid(request_id, 'request_id')
30
- }.freeze
31
- payload = acquire_payload(parameters)
32
- build_lease(parameters[:key], parameters[:token], payload)
28
+ authorization = @client.service_token.dup.freeze
29
+ owned_key = key.dup.freeze
30
+ owned_token = request_uuid(token, 'token')
31
+ owned_request_id = request_uuid(request_id, 'request_id')
32
+ payload = acquire_payload(
33
+ authorization: authorization, key: owned_key, ttl: ttl, token: owned_token, request_id: owned_request_id
34
+ )
35
+ build_lease(owned_key, owned_token, payload)
33
36
  end
34
37
 
35
38
  def renew(key, lease, ttl:, request_id: nil)
36
39
  validate_ttl(ttl)
37
- payload = lock_request(:renew_project_lock, 200, key: key, ttl: ttl,
38
- token: lease.token, request_id: request_id)
40
+ payload = lock_payload(perform_request(200) do
41
+ @transport.renew_project_lock(
42
+ authorization: @client.service_token, key: key, ttl: ttl,
43
+ token: lease.token, request_id: request_uuid(request_id, 'request_id')
44
+ )
45
+ end)
39
46
  build_lease(key, lease.token, payload)
40
47
  end
41
48
 
42
49
  def release(key, lease, request_id: nil)
43
- lock_request(:release_project_lock, 204, key: key, token: lease.token, request_id: request_id)
50
+ perform_request(204) do
51
+ @transport.release_project_lock(
52
+ authorization: @client.service_token, key: key, token: lease.token,
53
+ request_id: request_uuid(request_id, 'request_id')
54
+ )
55
+ end
44
56
  nil
45
57
  end
46
58
 
47
59
  def force_release(key, request_id: nil)
48
- lock_request(:force_release_project_lock, 204, key: key, request_id: request_id)
60
+ perform_request(204) do
61
+ @transport.force_release_project_lock(
62
+ authorization: @client.service_token, key: key, request_id: request_uuid(request_id, 'request_id')
63
+ )
64
+ end
49
65
  nil
50
66
  end
51
67
 
52
68
  private
53
69
 
54
- def acquire_payload(parameters)
55
- perform_request(:acquire_project_lock, 201, parameters)
70
+ def acquire_payload(authorization:, key:, ttl:, token:, request_id:)
71
+ lock_payload(perform_request(201) do
72
+ @transport.acquire_project_lock(authorization: authorization, key: key, ttl: ttl,
73
+ token: token, request_id: request_id)
74
+ end)
56
75
  rescue Error::TransportError, Error::ServerError => e
57
76
  raise unless e.status.nil? || e.status == 503
58
77
 
59
- perform_request(:acquire_project_lock, 201, parameters)
60
- end
61
-
62
- def lock_request(operation, status, **parameters)
63
- parameters[:authorization] = @client.service_token
64
- parameters[:request_id] = request_uuid(parameters[:request_id], 'request_id')
65
- perform_request(operation, status, parameters)
78
+ lock_payload(perform_request(201) do
79
+ @transport.acquire_project_lock(authorization: authorization, key: key, ttl: ttl,
80
+ token: token, request_id: request_id)
81
+ end)
66
82
  end
67
83
 
68
- def perform_request(operation, status, parameters)
69
- response = Transport.invoke { @transport.public_send(operation, **parameters) }
84
+ def perform_request(status, &)
85
+ response = Transport.invoke(&)
70
86
  Transport.body(response, status)
71
87
  end
72
88
 
73
89
  def request_uuid(value, name)
74
90
  return SecureRandom.uuid.freeze if value.nil?
75
91
 
76
- valid = value.is_a?(String) && value.match?(/\A[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}\z/i)
77
- raise ArgumentError, "#{name} must be a UUID string" unless valid
92
+ unless value.is_a?(String) && value.match?(/\A[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}\z/i)
93
+ raise ArgumentError, "#{name} must be a UUID string"
94
+ end
78
95
 
79
96
  value.dup.freeze
80
97
  end
81
98
 
82
99
  def build_lease(key, token, payload)
83
100
  LockLease.new(
84
- key: key, token: token, expires_at: parse_time(payload['expires_at']),
85
- fencing_token: payload['fencing_token']
101
+ key: key, token: token, expires_at: required_time(payload['expires_at']),
102
+ fencing_token: required_fencing_token(payload['fencing_token'])
86
103
  )
87
104
  end
88
105
 
89
- def parse_time(value)
90
- value.is_a?(String) ? Time.iso8601(value) : value
106
+ def build_state(payload)
107
+ held = lock_held(payload['held'])
108
+ expiry = held ? required_time(payload['expires_at']) : parse_time(payload['expires_at'])
109
+ fencing = if held
110
+ required_fencing_token(payload['fencing_token'])
111
+ else
112
+ optional_fencing_token(payload['fencing_token'])
113
+ end
114
+ LockState.new(held: held, expires_at: expiry, fencing_token: fencing)
91
115
  end
92
116
  end
93
117
  end
@@ -9,79 +9,6 @@ module Volcano
9
9
  end
10
10
  private_constant :SESSION_USER_CODER
11
11
 
12
- # Owns credential snapshots and preserves validated identity during refresh.
13
- module SessionCredentials
14
- def self.build(access_token, refresh_token)
15
- raise ArgumentError, 'refresh_token requires access_token' if access_token.nil? && !refresh_token.nil?
16
- return if access_token.nil?
17
-
18
- Session.new(access_token: credential(access_token, :access_token),
19
- refresh_token: credential(refresh_token, :refresh_token))
20
- end
21
-
22
- def self.credential(value, name)
23
- return if value.nil?
24
-
25
- raise ArgumentError, "#{name} must be a non-empty string" unless value.is_a?(String) && !value.strip.empty?
26
-
27
- value.dup.freeze
28
- end
29
- private_class_method :credential
30
-
31
- def self.validate_refresh_source(current, verified: false)
32
- return if verified || session_id(current.access_token)
33
-
34
- raise Error::AuthenticationError, 'Cannot refresh supplied credentials without a session identifier'
35
- end
36
-
37
- def self.validate_refresh(current, refreshed)
38
- return unless current
39
-
40
- validate_refresh_session_id(current, refreshed)
41
- return unless current.user_id && current.user_id != refreshed&.user_id
42
-
43
- raise Error::AuthenticationError, 'Refreshed session belongs to a different user'
44
- end
45
-
46
- def self.validate_refresh_session_id(current, refreshed)
47
- expected = session_id(current.access_token)
48
- return unless expected && expected != session_id(refreshed&.access_token)
49
-
50
- raise Error::AuthenticationError, 'Refreshed credentials belong to a different server session'
51
- end
52
- private_class_method :validate_refresh_session_id
53
-
54
- # Untrusted continuity constraint, never authenticated user identity.
55
- def self.session_id(access_token)
56
- payload = token_payload(access_token)
57
- return unless payload.is_a?(Hash)
58
-
59
- value = payload['session_id']
60
- value.downcase if value.is_a?(String) && value.match?(/\A[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}\z/i)
61
- end
62
-
63
- def self.token_payload(access_token)
64
- return unless access_token.is_a?(String)
65
-
66
- parts = access_token.split('.')
67
- return unless parts.length == 3
68
-
69
- encoded = parts.fetch(1).tr('-_', '+/')
70
- JSON.parse((encoded + ('=' * (-encoded.length % 4))).unpack1('m0'))
71
- rescue ArgumentError, JSON::ParserError
72
- nil
73
- end
74
- private_class_method :token_payload
75
-
76
- def self.with_user(session, user)
77
- user_id = (session.user_id || user.fetch('id')).dup.freeze
78
- raise Error::AuthenticationError, 'Profile belongs to a different user' unless user['id'] == user_id
79
-
80
- Session.new(**session.to_h, user_id: user_id, user: user)
81
- end
82
- end
83
- private_constant :SessionCredentials
84
-
85
12
  # Local credentials; refresh credentials and user identity may be unknown.
86
13
  Session = Data.define(:access_token, :refresh_token, :user_id, :user) do
87
14
  def initialize(access_token:, refresh_token: nil, user_id: nil, user: nil)
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'base64'
4
+ require 'json'
5
+ require_relative 'session'
6
+
7
+ module Volcano
8
+ # Owns credential snapshots and preserves validated identity during refresh.
9
+ module SessionCredentials
10
+ def self.build(access_token, refresh_token)
11
+ raise ArgumentError, 'refresh_token requires access_token' if access_token.nil? && !refresh_token.nil?
12
+ return if access_token.nil?
13
+
14
+ Session.new(access_token: credential(access_token, :access_token),
15
+ refresh_token: refresh_token.nil? ? nil : credential(refresh_token, :refresh_token))
16
+ end
17
+
18
+ def self.credential(value, name)
19
+ raise ArgumentError, "#{name} must be a non-empty string" unless value.is_a?(String) && !value.strip.empty?
20
+
21
+ value.dup.freeze
22
+ end
23
+ private_class_method :credential
24
+
25
+ def self.validate_refresh_source(current, verified: false)
26
+ return if verified || session_id(current.access_token)
27
+
28
+ raise Error::AuthenticationError, 'Cannot refresh supplied credentials without a session identifier'
29
+ end
30
+
31
+ def self.validate_refresh(current, refreshed)
32
+ return unless current
33
+
34
+ validate_refresh_session_id(current, refreshed)
35
+ return unless current.user_id && current.user_id != refreshed&.user_id
36
+
37
+ raise Error::AuthenticationError, 'Refreshed session belongs to a different user'
38
+ end
39
+
40
+ def self.validate_refresh_session_id(current, refreshed)
41
+ expected = session_id(current.access_token)
42
+ return unless expected && expected != session_id(refreshed&.access_token)
43
+
44
+ raise Error::AuthenticationError, 'Refreshed credentials belong to a different server session'
45
+ end
46
+ private_class_method :validate_refresh_session_id
47
+
48
+ # Untrusted continuity constraint, never authenticated user identity.
49
+ def self.session_id(access_token)
50
+ payload = token_payload(access_token)
51
+ return unless payload.is_a?(Hash)
52
+
53
+ value = payload['session_id']
54
+ value.downcase if value.is_a?(String) && value.match?(/\A[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}\z/i)
55
+ end
56
+
57
+ def self.token_payload(access_token)
58
+ return unless access_token.is_a?(String)
59
+
60
+ parts = access_token.split('.')
61
+ return unless parts.length == 3
62
+
63
+ encoded = parts.fetch(1).tr('-_', '+/')
64
+ JSON.parse(Base64.strict_decode64(encoded + ('=' * (-encoded.length % 4))))
65
+ rescue ArgumentError, JSON::ParserError
66
+ nil
67
+ end
68
+ private_class_method :token_payload
69
+
70
+ def self.with_user(session, user)
71
+ user_id = session.user_id || user.fetch('id')
72
+ raise Error::AuthenticationError, 'Profile has no valid user identifier' unless user_id.is_a?(String)
73
+
74
+ user_id = user_id.dup.freeze
75
+ raise Error::AuthenticationError, 'Profile belongs to a different user' unless user['id'] == user_id
76
+
77
+ Session.new(access_token: session.access_token, refresh_token: session.refresh_token,
78
+ user_id: user_id, user: user)
79
+ end
80
+ end
81
+ private_constant :SessionCredentials
82
+ end
@@ -42,7 +42,9 @@ module Volcano
42
42
  def refresh(&)
43
43
  operation, owner = @mutex.synchronize do
44
44
  raise Error::SessionChangedError if @sign_out || @locally_cleared
45
- next [@refresh, false] if @refresh && !@refresh.done
45
+
46
+ current = @refresh
47
+ next [current, false] if current && !current.done
46
48
 
47
49
  @refresh = Outcome.new(false)
48
50
  [@refresh, true]
@@ -51,11 +53,7 @@ module Volcano
51
53
  end
52
54
 
53
55
  def sign_out
54
- operation, owner, preceding, pending = @mutex.synchronize do
55
- first = @sign_out.nil?
56
- @sign_out ||= Outcome.new(false)
57
- [@sign_out, first, @refresh, @refresh && !@refresh.done]
58
- end
56
+ operation, owner, preceding, pending = @mutex.synchronize { claim_sign_out }
59
57
  execute(operation, owner) do
60
58
  yield(preceding, pending)
61
59
  ensure
@@ -79,10 +77,19 @@ module Volcano
79
77
 
80
78
  private
81
79
 
80
+ def claim_sign_out
81
+ first = @sign_out.nil? == true
82
+ operation = @sign_out ||= Outcome.new(false)
83
+ current = @refresh
84
+ [operation, first, current, current && !current.done]
85
+ end
86
+
82
87
  def execute(operation, owner)
83
88
  return result(operation) unless owner
84
89
 
85
90
  completed = false
91
+ # @type var value: Object?
92
+ value = nil
86
93
  begin
87
94
  value = yield
88
95
  completed = true
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Volcano
4
+ # Maps the internal wire response to immutable public session values.
5
+ module SessionPageMapping
6
+ private
7
+
8
+ def session_page(body)
9
+ raise TypeError, 'Expected a complete session page' unless body.is_a?(Hash)
10
+
11
+ sessions = body.fetch('sessions')
12
+ raise TypeError, 'Expected a complete session page' unless sessions.is_a?(Array)
13
+
14
+ SessionPage.new(
15
+ sessions: sessions.map { |attributes| auth_session(attributes) },
16
+ total: required_integer(body, 'total'), page: required_integer(body, 'page'),
17
+ limit: required_integer(body, 'limit'), total_pages: required_integer(body, 'total_pages')
18
+ )
19
+ rescue KeyError
20
+ raise TypeError, 'Expected a complete session page'
21
+ end
22
+
23
+ def auth_session(attributes)
24
+ raise TypeError, 'Expected a complete authentication session' unless attributes.is_a?(Hash)
25
+
26
+ build_auth_session(attributes)
27
+ rescue KeyError
28
+ raise TypeError, 'Expected a complete authentication session'
29
+ end
30
+
31
+ def build_auth_session(attributes)
32
+ AuthSession.new(
33
+ id: required_string(attributes, 'id'), user_id: required_string(attributes, 'user_id'),
34
+ provider: required_string(attributes, 'provider'), expires_at: required_time(attributes, 'expires_at'),
35
+ is_active: required_boolean(attributes, 'is_active'), is_current: required_boolean(attributes, 'is_current'),
36
+ user_agent: optional_string(attributes, 'user_agent'), ip_address: optional_string(attributes, 'ip_address'),
37
+ last_ip_address: optional_string(attributes, 'last_ip_address'),
38
+ last_activity_at: optional_time(attributes, 'last_activity_at'),
39
+ session_started_at: optional_time(attributes, 'session_started_at'),
40
+ created_at: optional_time(attributes, 'created_at'), updated_at: optional_time(attributes, 'updated_at')
41
+ )
42
+ end
43
+
44
+ def required_integer(body, name)
45
+ value = body.fetch(name)
46
+ raise TypeError, 'Expected a complete session page' unless value.is_a?(Integer)
47
+
48
+ value
49
+ end
50
+
51
+ def required_string(body, name)
52
+ value = body.fetch(name)
53
+ raise TypeError, 'Expected a complete authentication session' unless value.is_a?(String)
54
+
55
+ value
56
+ end
57
+
58
+ def required_time(body, name)
59
+ value = body.fetch(name)
60
+ raise TypeError, 'Expected a complete authentication session' unless value.is_a?(Time)
61
+
62
+ value
63
+ end
64
+
65
+ def required_boolean(body, name)
66
+ value = body.fetch(name)
67
+ unless value.is_a?(TrueClass) || value.is_a?(FalseClass)
68
+ raise TypeError, 'Expected a complete authentication session'
69
+ end
70
+
71
+ value
72
+ end
73
+
74
+ def optional_string(body, name)
75
+ value = body[name]
76
+ raise TypeError, 'Expected a complete authentication session' unless value.nil? || value.is_a?(String)
77
+
78
+ value
79
+ end
80
+
81
+ def optional_time(body, name)
82
+ value = body[name]
83
+ raise TypeError, 'Expected a complete authentication session' unless value.nil? || value.is_a?(Time)
84
+
85
+ value
86
+ end
87
+ end
88
+ private_constant :SessionPageMapping
89
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Volcano
4
- VERSION = '0.28.0'
4
+ VERSION = '0.30.0'
5
5
  end
data/lib/volcano.rb CHANGED
@@ -5,6 +5,7 @@ require_relative 'volcano/connection_string'
5
5
  require_relative 'volcano/models'
6
6
  require_relative 'volcano/user'
7
7
  require_relative 'volcano/session'
8
+ require_relative 'volcano/session_credentials'
8
9
  require_relative 'volcano/function_response'
9
10
  require_relative 'volcano/durable_models'
10
11
  require_relative 'volcano/log_responses'
@@ -16,16 +17,21 @@ require_relative 'volcano/errors'
16
17
  require_relative 'volcano/redaction'
17
18
  require_relative 'volcano/transport'
18
19
  require_relative 'volcano/generated_transport'
19
- require_relative 'volcano/auth'
20
+ require_relative 'volcano/auth_notification_dispatch'
21
+ require_relative 'volcano/auth_session_binding'
20
22
  require_relative 'volcano/auth_sign_out'
21
23
  require_relative 'volcano/auth_refresh'
24
+ require_relative 'volcano/auth_profile_fields'
25
+ require_relative 'volcano/auth_get_user'
26
+ require_relative 'volcano/auth_update_user'
27
+ require_relative 'volcano/auth_email_change'
28
+ require_relative 'volcano/auth_sessions'
29
+ require_relative 'volcano/auth'
22
30
  require_relative 'volcano/auth_sign_up'
23
31
  require_relative 'volcano/sign_up_result'
24
32
  require_relative 'volcano/auth_anonymous'
25
33
  require_relative 'volcano/auth_confirm_email'
26
34
  require_relative 'volcano/auth_resend_confirmation'
27
- require_relative 'volcano/auth_email_change'
28
- require_relative 'volcano/auth_sessions'
29
35
  require_relative 'volcano/auth_oauth'
30
36
  require_relative 'volcano/auth_oauth_sign_in'
31
37
  require_relative 'volcano/auth_hosted'
@@ -33,8 +39,6 @@ require_relative 'volcano/auth_oauth_token'
33
39
  require_relative 'volcano/auth_oauth_api'
34
40
  require_relative 'volcano/auth_reset_password_for_email'
35
41
  require_relative 'volcano/auth_reset_password'
36
- require_relative 'volcano/auth_get_user'
37
- require_relative 'volcano/auth_update_user'
38
42
  require_relative 'volcano/database'
39
43
  require_relative 'volcano/function_resolution'
40
44
  require_relative 'volcano/functions'
@@ -50,6 +54,7 @@ require_relative 'volcano/lock_guard'
50
54
  require_relative 'volcano/lock_renewer'
51
55
  require_relative 'volcano/lock_session'
52
56
  require_relative 'volcano/lock_auto_renewal'
57
+ require_relative 'volcano/lock_response'
53
58
  require_relative 'volcano/locks'
54
59
  require_relative 'volcano/realtime/protocol'
55
60
  require_relative 'volcano/realtime'
@@ -57,8 +62,10 @@ require_relative 'volcano/client'
57
62
 
58
63
  # Public namespace for the Volcano Ruby SDK.
59
64
  module Volcano
60
- private_constant :GeneratedTransport, :LockAutoRenewal, :LockLeaseClock, :LockRenewer, :LockSession,
61
- :Redaction, :SessionOperations
65
+ private_constant :AuthRefresh, :AuthSignOut, :AuthProfile, :AuthProfileFields, :AuthUpdateUser, :AuthEmailChange,
66
+ :AuthSessions,
67
+ :GeneratedTransport, :LockAutoRenewal, :LockLeaseClock, :LockRenewer,
68
+ :LockSession, :LockResponse, :Redaction, :SessionOperations
62
69
 
63
70
  Realtime.private_constant :Protocol, :ProtocolDispatch, :ProtocolPublicationDispatch, :ProtocolRecovery,
64
71
  :ProtocolRecoveryDispatch, :ProtocolRecoveryPosition
@@ -0,0 +1,16 @@
1
+ module Volcano
2
+ type oauth_api_input = session_input
3
+
4
+ class Auth
5
+ def list_linked_oauth_providers: () -> Array[LinkedOAuthProvider]
6
+ def link_oauth_provider: (String provider) -> String
7
+ def unlink_oauth_provider: (String provider) -> nil
8
+ def get_oauth_provider_token: (String provider) -> OAuthProviderTokenStatus
9
+ def refresh_oauth_provider_token: (String provider) -> OAuthProviderTokenStatus
10
+ def call_oauth_api: (String provider, endpoint: String, ?method: String, ?body: oauth_api_input) -> Object?
11
+ def sign_in_with_oauth: (String provider, redirect_to: String, state: String) -> String
12
+ def exchange_oauth_code: (code: String, redirect_to: String, state: String, expected_state: String) -> Session
13
+ def get_hosted_auth_url: (project_id: String, state: String, ?action: String) -> String
14
+ def adopt_hosted_auth_session: (Session session, state: String, expected_state: String) -> Session
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ module Volcano
2
+ class Auth
3
+ def user: () -> User
4
+ def get_user: () -> User
5
+ def update_user: (?password: String?, ?metadata: session_user_input?) -> User
6
+ def request_email_change: (new_email: String) -> EmailChangeResult
7
+ def cancel_email_change: () -> nil
8
+ def confirm_email_change: (token: String) -> User
9
+ end
10
+ end