clowk 0.1.0 → 0.3.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 +4 -4
- data/lib/clowk/authenticable.rb +53 -1
- data/lib/clowk/configuration.rb +4 -2
- data/lib/clowk/current.rb +4 -0
- data/lib/clowk/sdk/client.rb +8 -1
- data/lib/clowk/sdk/session.rb +13 -0
- data/lib/clowk/sdk/session_config.rb +17 -0
- data/lib/clowk/sdk/token.rb +7 -0
- data/lib/clowk/subdomain.rb +11 -5
- data/lib/clowk/version.rb +1 -1
- data/lib/clowk.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f3298d33abdf85d08387832031c8bbdb6efa36785b73c59ece84a3dec4deb064
|
|
4
|
+
data.tar.gz: b533eb6930465ea11188d0f2f8e23758575f113972d9aea81d5bdcb87a21af32
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 486ff44e3a9e781cad6c87584d40079ca43724c113432a76513078525b8df9a8d64a82c593a4be9bb7db87dc9c3bce7a6ec611c14fbefe2d7074904d8901b758
|
|
7
|
+
data.tar.gz: e06afce3a59cbb24d8c388837b51582c30d2597dec2e9e08337343040ca9cbe1041b2442c573436faa2c958adf3bd6b15ac3170d82447189ae235386a16a5fd6
|
data/lib/clowk/authenticable.rb
CHANGED
|
@@ -12,6 +12,8 @@ module Clowk
|
|
|
12
12
|
authenticate_method = :"authenticate_#{scope}!"
|
|
13
13
|
signed_in_method = :"#{scope}_signed_in?"
|
|
14
14
|
|
|
15
|
+
enforce_session_method = :"#{scope}_enforce_session!"
|
|
16
|
+
|
|
15
17
|
base.class_eval do
|
|
16
18
|
define_method(current_method) do
|
|
17
19
|
clowk_current_resource
|
|
@@ -25,6 +27,10 @@ module Clowk
|
|
|
25
27
|
clowk_current_resource.present?
|
|
26
28
|
end
|
|
27
29
|
|
|
30
|
+
define_method(enforce_session_method) do
|
|
31
|
+
clowk_enforce_session!
|
|
32
|
+
end
|
|
33
|
+
|
|
28
34
|
helper_method current_method, authenticate_method, signed_in_method, :current_token if respond_to?(:helper_method)
|
|
29
35
|
end
|
|
30
36
|
end
|
|
@@ -48,6 +54,33 @@ module Clowk
|
|
|
48
54
|
clowk_current_resource.present?
|
|
49
55
|
end
|
|
50
56
|
|
|
57
|
+
def clowk_session_status
|
|
58
|
+
@clowk_session_status ||= resolve_session_status
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def clowk_session_active?
|
|
62
|
+
clowk_session_status&.dig(:status) == 'active'
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def clowk_enforce_session!
|
|
66
|
+
return if clowk_session_active?
|
|
67
|
+
|
|
68
|
+
session_info = clowk_session_status
|
|
69
|
+
callback = Clowk.config.on_session_expired
|
|
70
|
+
|
|
71
|
+
if callback.respond_to?(:call)
|
|
72
|
+
callback.call(self, session_info)
|
|
73
|
+
|
|
74
|
+
return
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
if request.format.json?
|
|
78
|
+
render json: { error: 'Session expired or inactive' }, status: :unauthorized
|
|
79
|
+
else
|
|
80
|
+
redirect_to clowk_sign_in_path(return_to: request.fullpath)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
51
84
|
def clowk_authenticate!
|
|
52
85
|
return clowk_current_resource if clowk_signed_in?
|
|
53
86
|
|
|
@@ -96,7 +129,7 @@ module Clowk
|
|
|
96
129
|
|
|
97
130
|
def persist_clowk_session(token, payload)
|
|
98
131
|
session[Clowk.config.session_key] = {
|
|
99
|
-
token
|
|
132
|
+
token:,
|
|
100
133
|
user: payload,
|
|
101
134
|
signed_in_at: Time.now.to_i
|
|
102
135
|
}
|
|
@@ -108,5 +141,24 @@ module Clowk
|
|
|
108
141
|
secure: request.ssl?
|
|
109
142
|
}
|
|
110
143
|
end
|
|
144
|
+
|
|
145
|
+
def resolve_session_status
|
|
146
|
+
cached = stored_session&.dig('session_status') || stored_session&.dig(:session_status)
|
|
147
|
+
|
|
148
|
+
return cached&.deep_symbolize_keys if cached
|
|
149
|
+
|
|
150
|
+
resource = clowk_current_resource
|
|
151
|
+
|
|
152
|
+
return unless resource&.session_id
|
|
153
|
+
return unless Clowk.config.secret_key.present?
|
|
154
|
+
|
|
155
|
+
client = Clowk::SDK::Client.new(secret_key: Clowk.config.secret_key)
|
|
156
|
+
result = client.tokens.verify_with_session(token: current_token)
|
|
157
|
+
status = result&.dig(:session)
|
|
158
|
+
|
|
159
|
+
session[Clowk.config.session_key] = stored_session.merge('session_status' => status) if status && stored_session
|
|
160
|
+
|
|
161
|
+
status
|
|
162
|
+
end
|
|
111
163
|
end
|
|
112
164
|
end
|
data/lib/clowk/configuration.rb
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
module Clowk
|
|
4
4
|
class Configuration
|
|
5
|
-
attr_accessor :api_base_url
|
|
6
5
|
attr_accessor :app_base_url
|
|
7
6
|
attr_accessor :after_sign_in_path
|
|
8
7
|
attr_accessor :after_sign_out_path
|
|
@@ -22,9 +21,10 @@ module Clowk
|
|
|
22
21
|
attr_accessor :session_key
|
|
23
22
|
attr_accessor :subdomain_url
|
|
24
23
|
attr_accessor :token_param
|
|
24
|
+
attr_accessor :enforce_active_session
|
|
25
|
+
attr_accessor :on_session_expired
|
|
25
26
|
|
|
26
27
|
def initialize
|
|
27
|
-
@api_base_url = 'https://api.clowk.dev/client/v1'
|
|
28
28
|
@app_base_url = 'https://app.clowk.in'
|
|
29
29
|
@after_sign_in_path = '/'
|
|
30
30
|
@after_sign_out_path = '/'
|
|
@@ -41,6 +41,8 @@ module Clowk
|
|
|
41
41
|
@session_key = :clowk
|
|
42
42
|
@prefix_by = :clowk
|
|
43
43
|
@token_param = :token
|
|
44
|
+
@enforce_active_session = false
|
|
45
|
+
@on_session_expired = nil
|
|
44
46
|
end
|
|
45
47
|
end
|
|
46
48
|
end
|
data/lib/clowk/current.rb
CHANGED
data/lib/clowk/sdk/client.rb
CHANGED
|
@@ -6,7 +6,7 @@ module Clowk
|
|
|
6
6
|
module SDK
|
|
7
7
|
class Client
|
|
8
8
|
def initialize(options = {})
|
|
9
|
-
@api_base_url = options.fetch(:api_base_url,
|
|
9
|
+
@api_base_url = options.fetch(:api_base_url, nil).presence || derive_api_base_url
|
|
10
10
|
@secret_key = options.fetch(:secret_key, Clowk.config.secret_key)
|
|
11
11
|
@publishable_key = options.fetch(:publishable_key, Clowk.config.publishable_key)
|
|
12
12
|
end
|
|
@@ -65,6 +65,13 @@ module Clowk
|
|
|
65
65
|
|
|
66
66
|
attr_reader :api_base_url, :publishable_key, :secret_key
|
|
67
67
|
|
|
68
|
+
def derive_api_base_url
|
|
69
|
+
base = Clowk.config.subdomain_url.to_s.strip
|
|
70
|
+
return if base.empty?
|
|
71
|
+
|
|
72
|
+
"#{base.sub(%r{/$}, '')}/api/v1"
|
|
73
|
+
end
|
|
74
|
+
|
|
68
75
|
def http
|
|
69
76
|
@http ||= Clowk::Http.new(
|
|
70
77
|
base_url: api_base_url,
|
data/lib/clowk/sdk/session.rb
CHANGED
|
@@ -6,6 +6,19 @@ module Clowk
|
|
|
6
6
|
def self.resource_path
|
|
7
7
|
'sessions'
|
|
8
8
|
end
|
|
9
|
+
|
|
10
|
+
# @param email [String] Email to search for (ILIKE match)
|
|
11
|
+
# @return [Clowk::Http::Response]
|
|
12
|
+
def search(email:)
|
|
13
|
+
client.get("#{self.class.resource_path}/search?email=#{ERB::Util.url_encode(email)}")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Revokes a session by its session_id (clk_session_UUID)
|
|
17
|
+
# @param session_id [String]
|
|
18
|
+
# @return [Clowk::Http::Response]
|
|
19
|
+
def revoke(session_id)
|
|
20
|
+
destroy(session_id)
|
|
21
|
+
end
|
|
9
22
|
end
|
|
10
23
|
end
|
|
11
24
|
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Clowk
|
|
4
|
+
module SDK
|
|
5
|
+
class SessionConfig < Resource
|
|
6
|
+
def self.resource_path
|
|
7
|
+
'session_config'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def fetch
|
|
11
|
+
response = client.get(self.class.resource_path)
|
|
12
|
+
|
|
13
|
+
response.body_parsed&.deep_symbolize_keys
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/clowk/sdk/token.rb
CHANGED
|
@@ -10,6 +10,13 @@ module Clowk
|
|
|
10
10
|
def verify(token:)
|
|
11
11
|
client.post("#{self.class.resource_path}/verify", { token: token })
|
|
12
12
|
end
|
|
13
|
+
|
|
14
|
+
def verify_with_session(token:)
|
|
15
|
+
response = verify(token:)
|
|
16
|
+
data = response.body_parsed&.dig('data') || response.body_parsed
|
|
17
|
+
|
|
18
|
+
data&.deep_symbolize_keys
|
|
19
|
+
end
|
|
13
20
|
end
|
|
14
21
|
end
|
|
15
22
|
end
|
data/lib/clowk/subdomain.rb
CHANGED
|
@@ -4,6 +4,7 @@ require 'uri'
|
|
|
4
4
|
|
|
5
5
|
module Clowk
|
|
6
6
|
class Subdomain
|
|
7
|
+
API_BASE_URL = 'https://api.clowk.dev/api/v1'
|
|
7
8
|
CACHE_TTL = 60
|
|
8
9
|
DEFAULT_SUBDOMAIN_BASE = 'clowk.dev'
|
|
9
10
|
|
|
@@ -42,7 +43,6 @@ module Clowk
|
|
|
42
43
|
|
|
43
44
|
def initialize(options = {})
|
|
44
45
|
@publishable_key = options.fetch(:publishable_key, Clowk.config.publishable_key)
|
|
45
|
-
@api_base_url = options.fetch(:api_base_url, Clowk.config.api_base_url)
|
|
46
46
|
@subdomain_url = options.fetch(:subdomain_url, Clowk.config.subdomain_url)
|
|
47
47
|
end
|
|
48
48
|
|
|
@@ -55,7 +55,7 @@ module Clowk
|
|
|
55
55
|
|
|
56
56
|
private
|
|
57
57
|
|
|
58
|
-
attr_reader :
|
|
58
|
+
attr_reader :publishable_key, :subdomain_url
|
|
59
59
|
|
|
60
60
|
def resolve_from_key
|
|
61
61
|
cached = self.class.read_cache(cache_key)
|
|
@@ -77,8 +77,14 @@ module Clowk
|
|
|
77
77
|
def extract_url_from_instance(payload)
|
|
78
78
|
return if payload.blank?
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
instance_data =
|
|
80
|
+
root = payload.is_a?(Hash) ? payload : {}
|
|
81
|
+
instance_data = if root['instance'].is_a?(Hash)
|
|
82
|
+
root['instance']
|
|
83
|
+
elsif root['data'].is_a?(Hash)
|
|
84
|
+
root['data']
|
|
85
|
+
else
|
|
86
|
+
root
|
|
87
|
+
end
|
|
82
88
|
|
|
83
89
|
explicit_url = instance_data['url'] || instance_data['subdomain_url'] || instance_data['instance_url']
|
|
84
90
|
return normalize_url(explicit_url) if explicit_url.present?
|
|
@@ -114,7 +120,7 @@ module Clowk
|
|
|
114
120
|
end
|
|
115
121
|
|
|
116
122
|
def client
|
|
117
|
-
@client ||= Clowk::SDK::Client.new
|
|
123
|
+
@client ||= Clowk::SDK::Client.new(api_base_url: API_BASE_URL)
|
|
118
124
|
end
|
|
119
125
|
end
|
|
120
126
|
end
|
data/lib/clowk/version.rb
CHANGED
data/lib/clowk.rb
CHANGED
|
@@ -44,6 +44,7 @@ require_relative 'clowk/sdk/user'
|
|
|
44
44
|
require_relative 'clowk/sdk/session'
|
|
45
45
|
require_relative 'clowk/sdk/subdomain'
|
|
46
46
|
require_relative 'clowk/sdk/token'
|
|
47
|
+
require_relative 'clowk/sdk/session_config'
|
|
47
48
|
require_relative 'clowk/sdk/client'
|
|
48
49
|
require_relative 'clowk/subdomain'
|
|
49
50
|
require_relative 'clowk/jwt_verifier'
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: clowk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Clowk
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-03-
|
|
10
|
+
date: 2026-03-27 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: activesupport
|
|
@@ -106,6 +106,7 @@ files:
|
|
|
106
106
|
- lib/clowk/sdk/client.rb
|
|
107
107
|
- lib/clowk/sdk/resource.rb
|
|
108
108
|
- lib/clowk/sdk/session.rb
|
|
109
|
+
- lib/clowk/sdk/session_config.rb
|
|
109
110
|
- lib/clowk/sdk/subdomain.rb
|
|
110
111
|
- lib/clowk/sdk/token.rb
|
|
111
112
|
- lib/clowk/sdk/user.rb
|