clowk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +365 -0
- data/clowk.gemspec +31 -0
- data/config/routes.rb +8 -0
- data/lib/clowk/authenticable.rb +112 -0
- data/lib/clowk/configuration.rb +46 -0
- data/lib/clowk/controllers/base_controller.rb +70 -0
- data/lib/clowk/controllers/callbacks_controller.rb +25 -0
- data/lib/clowk/controllers/sessions_controller.rb +23 -0
- data/lib/clowk/current.rb +47 -0
- data/lib/clowk/engine.rb +17 -0
- data/lib/clowk/helpers/url_helpers.rb +58 -0
- data/lib/clowk/http/client.rb +199 -0
- data/lib/clowk/http/logger_middleware.rb +29 -0
- data/lib/clowk/http/response.rb +43 -0
- data/lib/clowk/http/retry_middleware.rb +47 -0
- data/lib/clowk/http/timeout_middleware.rb +30 -0
- data/lib/clowk/jwt_verifier.rb +27 -0
- data/lib/clowk/middleware/token_extractor.rb +42 -0
- data/lib/clowk/sdk/client.rb +89 -0
- data/lib/clowk/sdk/resource.rb +68 -0
- data/lib/clowk/sdk/session.rb +11 -0
- data/lib/clowk/sdk/subdomain.rb +17 -0
- data/lib/clowk/sdk/token.rb +15 -0
- data/lib/clowk/sdk/user.rb +11 -0
- data/lib/clowk/subdomain.rb +120 -0
- data/lib/clowk/version.rb +5 -0
- data/lib/clowk.rb +56 -0
- metadata +136 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Clowk
|
|
4
|
+
module SDK
|
|
5
|
+
class Subdomain < Resource
|
|
6
|
+
def self.resource_path
|
|
7
|
+
'instances'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def find_by_pk(key = nil)
|
|
11
|
+
return if key.blank?
|
|
12
|
+
|
|
13
|
+
search(publishable_key: key)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'uri'
|
|
4
|
+
|
|
5
|
+
module Clowk
|
|
6
|
+
class Subdomain
|
|
7
|
+
CACHE_TTL = 60
|
|
8
|
+
DEFAULT_SUBDOMAIN_BASE = 'clowk.dev'
|
|
9
|
+
|
|
10
|
+
class << self
|
|
11
|
+
def resolve_url!(...)
|
|
12
|
+
new(...).resolve_url!
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def clear_cache!
|
|
16
|
+
@cache = {}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def read_cache(key)
|
|
20
|
+
entry = cache[key]
|
|
21
|
+
|
|
22
|
+
return unless entry
|
|
23
|
+
return entry[:value] if entry[:expires_at] > Time.now
|
|
24
|
+
|
|
25
|
+
cache.delete(key)
|
|
26
|
+
nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def write_cache(key, value, ttl:)
|
|
30
|
+
cache[key] = {
|
|
31
|
+
value: value,
|
|
32
|
+
expires_at: Time.now + ttl
|
|
33
|
+
}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def cache
|
|
39
|
+
@cache ||= {}
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def initialize(options = {})
|
|
44
|
+
@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
|
+
@subdomain_url = options.fetch(:subdomain_url, Clowk.config.subdomain_url)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def resolve_url!
|
|
50
|
+
return resolve_from_key if publishable_key.present?
|
|
51
|
+
return normalize_url(subdomain_url) if subdomain_url.present?
|
|
52
|
+
|
|
53
|
+
raise ConfigurationError, 'set publishable_key or subdomain_url to build Clowk URLs'
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
attr_reader :api_base_url, :publishable_key, :subdomain_url
|
|
59
|
+
|
|
60
|
+
def resolve_from_key
|
|
61
|
+
cached = self.class.read_cache(cache_key)
|
|
62
|
+
return cached if cached
|
|
63
|
+
|
|
64
|
+
response = client.subdomains.find_by_pk(publishable_key)
|
|
65
|
+
resolved = extract_url_from_instance(response.body_parsed)
|
|
66
|
+
|
|
67
|
+
raise ConfigurationError, 'could not resolve subdomain_url from publishable_key' if resolved.blank?
|
|
68
|
+
|
|
69
|
+
self.class.write_cache(cache_key, resolved, ttl: CACHE_TTL)
|
|
70
|
+
resolved
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def cache_key
|
|
74
|
+
"instance-url:#{publishable_key}"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def extract_url_from_instance(payload)
|
|
78
|
+
return if payload.blank?
|
|
79
|
+
|
|
80
|
+
instance = payload.is_a?(Hash) ? payload : {}
|
|
81
|
+
instance_data = instance['instance'].is_a?(Hash) ? instance['instance'] : instance
|
|
82
|
+
|
|
83
|
+
explicit_url = instance_data['url'] || instance_data['subdomain_url'] || instance_data['instance_url']
|
|
84
|
+
return normalize_url(explicit_url) if explicit_url.present?
|
|
85
|
+
|
|
86
|
+
host = instance_data['host'] || instance_data['domain'] || instance_data['hostname']
|
|
87
|
+
return normalize_url(host_to_url(host)) if host.present?
|
|
88
|
+
|
|
89
|
+
subdomain = instance_data['subdomain']
|
|
90
|
+
normalize_url("https://#{subdomain}.#{default_subdomain_base}") if subdomain.present?
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def host_to_url(host)
|
|
94
|
+
value = host.to_s
|
|
95
|
+
return value if value.start_with?('http://', 'https://')
|
|
96
|
+
|
|
97
|
+
"https://#{value}"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def default_subdomain_base
|
|
101
|
+
configured = subdomain_url.to_s.strip
|
|
102
|
+
return DEFAULT_SUBDOMAIN_BASE if configured.empty?
|
|
103
|
+
|
|
104
|
+
uri = URI.parse(configured)
|
|
105
|
+
return DEFAULT_SUBDOMAIN_BASE if uri.host.blank?
|
|
106
|
+
|
|
107
|
+
uri.host.split('.').drop(1).join('.')
|
|
108
|
+
rescue URI::InvalidURIError
|
|
109
|
+
DEFAULT_SUBDOMAIN_BASE
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def normalize_url(value)
|
|
113
|
+
value.to_s.sub(%r{/$}, '')
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def client
|
|
117
|
+
@client ||= Clowk::SDK::Client.new
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
data/lib/clowk.rb
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails'
|
|
4
|
+
require 'rails/engine'
|
|
5
|
+
require 'action_controller/railtie'
|
|
6
|
+
require 'active_support'
|
|
7
|
+
require 'active_support/core_ext/hash'
|
|
8
|
+
require 'active_support/core_ext/object/blank'
|
|
9
|
+
require 'rack'
|
|
10
|
+
|
|
11
|
+
require_relative 'clowk/version'
|
|
12
|
+
require_relative 'clowk/configuration'
|
|
13
|
+
|
|
14
|
+
module Clowk
|
|
15
|
+
class Error < StandardError; end
|
|
16
|
+
class ConfigurationError < Error; end
|
|
17
|
+
class InvalidStateError < Error; end
|
|
18
|
+
class InvalidTokenError < Error; end
|
|
19
|
+
|
|
20
|
+
class << self
|
|
21
|
+
def config
|
|
22
|
+
@config ||= Configuration.new
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def configure
|
|
26
|
+
yield(config)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def reset!
|
|
30
|
+
Subdomain.clear_cache! if defined?(Subdomain)
|
|
31
|
+
@config = Configuration.new
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
require_relative 'clowk/current'
|
|
37
|
+
require_relative 'clowk/http/response'
|
|
38
|
+
require_relative 'clowk/http/logger_middleware'
|
|
39
|
+
require_relative 'clowk/http/retry_middleware'
|
|
40
|
+
require_relative 'clowk/http/timeout_middleware'
|
|
41
|
+
require_relative 'clowk/http/client'
|
|
42
|
+
require_relative 'clowk/sdk/resource'
|
|
43
|
+
require_relative 'clowk/sdk/user'
|
|
44
|
+
require_relative 'clowk/sdk/session'
|
|
45
|
+
require_relative 'clowk/sdk/subdomain'
|
|
46
|
+
require_relative 'clowk/sdk/token'
|
|
47
|
+
require_relative 'clowk/sdk/client'
|
|
48
|
+
require_relative 'clowk/subdomain'
|
|
49
|
+
require_relative 'clowk/jwt_verifier'
|
|
50
|
+
require_relative 'clowk/helpers/url_helpers'
|
|
51
|
+
require_relative 'clowk/middleware/token_extractor'
|
|
52
|
+
require_relative 'clowk/authenticable'
|
|
53
|
+
require_relative 'clowk/controllers/base_controller'
|
|
54
|
+
require_relative 'clowk/controllers/callbacks_controller'
|
|
55
|
+
require_relative 'clowk/controllers/sessions_controller'
|
|
56
|
+
require_relative 'clowk/engine'
|
metadata
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: clowk
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Clowk
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-03-23 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: activesupport
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '7.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: jwt
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '2.7'
|
|
33
|
+
- - "<"
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
version: '3.0'
|
|
36
|
+
type: :runtime
|
|
37
|
+
prerelease: false
|
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '2.7'
|
|
43
|
+
- - "<"
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '3.0'
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: railties
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
requirements:
|
|
50
|
+
- - ">="
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: '7.0'
|
|
53
|
+
type: :runtime
|
|
54
|
+
prerelease: false
|
|
55
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
56
|
+
requirements:
|
|
57
|
+
- - ">="
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: '7.0'
|
|
60
|
+
- !ruby/object:Gem::Dependency
|
|
61
|
+
name: rspec
|
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
|
63
|
+
requirements:
|
|
64
|
+
- - ">="
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: '3.13'
|
|
67
|
+
- - "<"
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '4.0'
|
|
70
|
+
type: :development
|
|
71
|
+
prerelease: false
|
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
+
requirements:
|
|
74
|
+
- - ">="
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: '3.13'
|
|
77
|
+
- - "<"
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '4.0'
|
|
80
|
+
description: Clowk Authentication, JWT verification, and future API access
|
|
81
|
+
email:
|
|
82
|
+
- support@clowk.in
|
|
83
|
+
executables: []
|
|
84
|
+
extensions: []
|
|
85
|
+
extra_rdoc_files: []
|
|
86
|
+
files:
|
|
87
|
+
- README.md
|
|
88
|
+
- clowk.gemspec
|
|
89
|
+
- config/routes.rb
|
|
90
|
+
- lib/clowk.rb
|
|
91
|
+
- lib/clowk/authenticable.rb
|
|
92
|
+
- lib/clowk/configuration.rb
|
|
93
|
+
- lib/clowk/controllers/base_controller.rb
|
|
94
|
+
- lib/clowk/controllers/callbacks_controller.rb
|
|
95
|
+
- lib/clowk/controllers/sessions_controller.rb
|
|
96
|
+
- lib/clowk/current.rb
|
|
97
|
+
- lib/clowk/engine.rb
|
|
98
|
+
- lib/clowk/helpers/url_helpers.rb
|
|
99
|
+
- lib/clowk/http/client.rb
|
|
100
|
+
- lib/clowk/http/logger_middleware.rb
|
|
101
|
+
- lib/clowk/http/response.rb
|
|
102
|
+
- lib/clowk/http/retry_middleware.rb
|
|
103
|
+
- lib/clowk/http/timeout_middleware.rb
|
|
104
|
+
- lib/clowk/jwt_verifier.rb
|
|
105
|
+
- lib/clowk/middleware/token_extractor.rb
|
|
106
|
+
- lib/clowk/sdk/client.rb
|
|
107
|
+
- lib/clowk/sdk/resource.rb
|
|
108
|
+
- lib/clowk/sdk/session.rb
|
|
109
|
+
- lib/clowk/sdk/subdomain.rb
|
|
110
|
+
- lib/clowk/sdk/token.rb
|
|
111
|
+
- lib/clowk/sdk/user.rb
|
|
112
|
+
- lib/clowk/subdomain.rb
|
|
113
|
+
- lib/clowk/version.rb
|
|
114
|
+
homepage: https://clowk.in
|
|
115
|
+
licenses:
|
|
116
|
+
- AGPL-3.0
|
|
117
|
+
metadata:
|
|
118
|
+
rubygems_mfa_required: 'true'
|
|
119
|
+
rdoc_options: []
|
|
120
|
+
require_paths:
|
|
121
|
+
- lib
|
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
123
|
+
requirements:
|
|
124
|
+
- - ">="
|
|
125
|
+
- !ruby/object:Gem::Version
|
|
126
|
+
version: '3.3'
|
|
127
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0'
|
|
132
|
+
requirements: []
|
|
133
|
+
rubygems_version: 3.6.2
|
|
134
|
+
specification_version: 4
|
|
135
|
+
summary: Rails SDK for Clowk authentication
|
|
136
|
+
test_files: []
|