ru.Bee 1.3.2 → 1.4.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/bin/rubee +114 -88
- data/lib/app/views/app.tsx +27 -0
- data/lib/app/views/index.html +47 -0
- data/lib/app/views/layout.erb +3 -3
- data/lib/app/views/utils/redirectToBackend.tsx +9 -0
- data/lib/app/views/welcome_show.erb +1 -1
- data/lib/config/base_configuration.rb +15 -6
- data/lib/config/routes.rb +2 -1
- data/lib/db/create_accounts.rb +8 -8
- data/lib/db/create_comments.rb +7 -7
- data/lib/db/create_posts.rb +8 -8
- data/lib/db/create_users.rb +8 -8
- data/lib/db/structure.rb +42 -42
- data/lib/esbuild.config.js +33 -0
- data/lib/inits/print_colors.rb +1 -1
- data/lib/js/app.js +13 -0
- data/lib/js/app.js.map +7 -0
- data/lib/js/bundle.js +26157 -0
- data/lib/js/bundle.js.map +7 -0
- data/lib/node_modules/@types/cookie/LICENSE +21 -0
- data/lib/node_modules/@types/cookie/README.md +15 -0
- data/lib/node_modules/@types/cookie/index.d.ts +154 -0
- data/lib/node_modules/@types/cookie/package.json +30 -0
- data/lib/node_modules/cookie/LICENSE +24 -0
- data/lib/node_modules/cookie/README.md +248 -0
- data/lib/node_modules/cookie/dist/index.d.ts +114 -0
- data/lib/node_modules/cookie/dist/index.js +239 -0
- data/lib/node_modules/cookie/dist/index.js.map +1 -0
- data/lib/node_modules/cookie/package.json +42 -0
- data/lib/node_modules/js-tokens/CHANGELOG.md +151 -0
- data/lib/node_modules/js-tokens/LICENSE +21 -0
- data/lib/node_modules/js-tokens/README.md +240 -0
- data/lib/node_modules/js-tokens/index.js +23 -0
- data/lib/node_modules/js-tokens/package.json +30 -0
- data/lib/node_modules/loose-envify/LICENSE +21 -0
- data/lib/node_modules/loose-envify/README.md +45 -0
- data/lib/node_modules/loose-envify/cli.js +16 -0
- data/lib/node_modules/loose-envify/custom.js +4 -0
- data/lib/node_modules/loose-envify/index.js +3 -0
- data/lib/node_modules/loose-envify/loose-envify.js +36 -0
- data/lib/node_modules/loose-envify/package.json +36 -0
- data/lib/node_modules/loose-envify/replace.js +65 -0
- data/lib/node_modules/react/LICENSE +21 -0
- data/lib/node_modules/react/README.md +37 -0
- data/lib/node_modules/react/cjs/react-jsx-dev-runtime.development.js +1315 -0
- data/lib/node_modules/react/cjs/react-jsx-dev-runtime.production.min.js +10 -0
- data/lib/node_modules/react/cjs/react-jsx-dev-runtime.profiling.min.js +10 -0
- data/lib/node_modules/react/cjs/react-jsx-runtime.development.js +1333 -0
- data/lib/node_modules/react/cjs/react-jsx-runtime.production.min.js +11 -0
- data/lib/node_modules/react/cjs/react-jsx-runtime.profiling.min.js +11 -0
- data/lib/node_modules/react/cjs/react.development.js +2740 -0
- data/lib/node_modules/react/cjs/react.production.min.js +26 -0
- data/lib/node_modules/react/cjs/react.shared-subset.development.js +20 -0
- data/lib/node_modules/react/cjs/react.shared-subset.production.min.js +10 -0
- data/lib/node_modules/react/index.js +7 -0
- data/lib/node_modules/react/jsx-dev-runtime.js +7 -0
- data/lib/node_modules/react/jsx-runtime.js +7 -0
- data/lib/node_modules/react/package.json +47 -0
- data/lib/node_modules/react/react.shared-subset.js +7 -0
- data/lib/node_modules/react/umd/react.development.js +3343 -0
- data/lib/node_modules/react/umd/react.production.min.js +31 -0
- data/lib/node_modules/react/umd/react.profiling.min.js +31 -0
- data/lib/node_modules/react-dom/LICENSE +21 -0
- data/lib/node_modules/react-dom/README.md +60 -0
- data/lib/node_modules/react-dom/cjs/react-dom-server-legacy.browser.development.js +7029 -0
- data/lib/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.min.js +93 -0
- data/lib/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js +7093 -0
- data/lib/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.min.js +101 -0
- data/lib/node_modules/react-dom/cjs/react-dom-server.browser.development.js +7014 -0
- data/lib/node_modules/react-dom/cjs/react-dom-server.browser.production.min.js +96 -0
- data/lib/node_modules/react-dom/cjs/react-dom-server.node.development.js +7070 -0
- data/lib/node_modules/react-dom/cjs/react-dom-server.node.production.min.js +102 -0
- data/lib/node_modules/react-dom/cjs/react-dom-test-utils.development.js +1763 -0
- data/lib/node_modules/react-dom/cjs/react-dom-test-utils.production.min.js +40 -0
- data/lib/node_modules/react-dom/cjs/react-dom.development.js +29923 -0
- data/lib/node_modules/react-dom/cjs/react-dom.production.min.js +322 -0
- data/lib/node_modules/react-dom/cjs/react-dom.profiling.min.js +366 -0
- data/lib/node_modules/react-dom/client.js +25 -0
- data/lib/node_modules/react-dom/index.js +38 -0
- data/lib/node_modules/react-dom/package.json +62 -0
- data/lib/node_modules/react-dom/profiling.js +38 -0
- data/lib/node_modules/react-dom/server.browser.js +17 -0
- data/lib/node_modules/react-dom/server.js +3 -0
- data/lib/node_modules/react-dom/server.node.js +17 -0
- data/lib/node_modules/react-dom/test-utils.js +7 -0
- data/lib/node_modules/react-dom/umd/react-dom-server-legacy.browser.development.js +7026 -0
- data/lib/node_modules/react-dom/umd/react-dom-server-legacy.browser.production.min.js +75 -0
- data/lib/node_modules/react-dom/umd/react-dom-server.browser.development.js +7011 -0
- data/lib/node_modules/react-dom/umd/react-dom-server.browser.production.min.js +76 -0
- data/lib/node_modules/react-dom/umd/react-dom-test-utils.development.js +1759 -0
- data/lib/node_modules/react-dom/umd/react-dom-test-utils.production.min.js +33 -0
- data/lib/node_modules/react-dom/umd/react-dom.development.js +29924 -0
- data/lib/node_modules/react-dom/umd/react-dom.production.min.js +267 -0
- data/lib/node_modules/react-dom/umd/react-dom.profiling.min.js +285 -0
- data/lib/node_modules/react-router/CHANGELOG.md +1526 -0
- data/lib/node_modules/react-router/LICENSE.md +23 -0
- data/lib/node_modules/react-router/README.md +7 -0
- data/lib/node_modules/react-router/dist/development/chunk-KNED5TY2.mjs +10476 -0
- data/lib/node_modules/react-router/dist/development/dom-export.d.mts +23 -0
- data/lib/node_modules/react-router/dist/development/dom-export.d.ts +23 -0
- data/lib/node_modules/react-router/dist/development/dom-export.js +6111 -0
- data/lib/node_modules/react-router/dist/development/dom-export.mjs +234 -0
- data/lib/node_modules/react-router/dist/development/fog-of-war-1hWhK5ey.d.mts +1690 -0
- data/lib/node_modules/react-router/dist/development/fog-of-war-oa9CGk10.d.ts +1690 -0
- data/lib/node_modules/react-router/dist/development/future-ldDp5FKH.d.mts +21 -0
- data/lib/node_modules/react-router/dist/development/future-ldDp5FKH.d.ts +21 -0
- data/lib/node_modules/react-router/dist/development/index.d.mts +841 -0
- data/lib/node_modules/react-router/dist/development/index.d.ts +841 -0
- data/lib/node_modules/react-router/dist/development/index.js +10624 -0
- data/lib/node_modules/react-router/dist/development/index.mjs +242 -0
- data/lib/node_modules/react-router/dist/development/lib/types/route-module.d.mts +209 -0
- data/lib/node_modules/react-router/dist/development/lib/types/route-module.d.ts +209 -0
- data/lib/node_modules/react-router/dist/development/lib/types/route-module.js +28 -0
- data/lib/node_modules/react-router/dist/development/lib/types/route-module.mjs +10 -0
- data/lib/node_modules/react-router/dist/development/route-data-5OzAzQtT.d.mts +1716 -0
- data/lib/node_modules/react-router/dist/development/route-data-5OzAzQtT.d.ts +1716 -0
- data/lib/node_modules/react-router/dist/production/chunk-ZIM7OIE3.mjs +10476 -0
- data/lib/node_modules/react-router/dist/production/dom-export.d.mts +23 -0
- data/lib/node_modules/react-router/dist/production/dom-export.d.ts +23 -0
- data/lib/node_modules/react-router/dist/production/dom-export.js +6111 -0
- data/lib/node_modules/react-router/dist/production/dom-export.mjs +234 -0
- data/lib/node_modules/react-router/dist/production/fog-of-war-1hWhK5ey.d.mts +1690 -0
- data/lib/node_modules/react-router/dist/production/fog-of-war-oa9CGk10.d.ts +1690 -0
- data/lib/node_modules/react-router/dist/production/future-ldDp5FKH.d.mts +21 -0
- data/lib/node_modules/react-router/dist/production/future-ldDp5FKH.d.ts +21 -0
- data/lib/node_modules/react-router/dist/production/index.d.mts +841 -0
- data/lib/node_modules/react-router/dist/production/index.d.ts +841 -0
- data/lib/node_modules/react-router/dist/production/index.js +10624 -0
- data/lib/node_modules/react-router/dist/production/index.mjs +242 -0
- data/lib/node_modules/react-router/dist/production/lib/types/route-module.d.mts +209 -0
- data/lib/node_modules/react-router/dist/production/lib/types/route-module.d.ts +209 -0
- data/lib/node_modules/react-router/dist/production/lib/types/route-module.js +28 -0
- data/lib/node_modules/react-router/dist/production/lib/types/route-module.mjs +10 -0
- data/lib/node_modules/react-router/dist/production/route-data-5OzAzQtT.d.mts +1716 -0
- data/lib/node_modules/react-router/dist/production/route-data-5OzAzQtT.d.ts +1716 -0
- data/lib/node_modules/react-router/package.json +116 -0
- data/lib/node_modules/react-router-dom/LICENSE.md +23 -0
- data/lib/node_modules/react-router-dom/README.md +6 -0
- data/lib/node_modules/react-router-dom/dist/index.d.mts +2 -0
- data/lib/node_modules/react-router-dom/dist/index.d.ts +2 -0
- data/lib/node_modules/react-router-dom/dist/index.js +45 -0
- data/lib/node_modules/react-router-dom/dist/index.mjs +18 -0
- data/lib/node_modules/react-router-dom/package.json +82 -0
- data/lib/node_modules/scheduler/LICENSE +21 -0
- data/lib/node_modules/scheduler/README.md +9 -0
- data/lib/node_modules/scheduler/cjs/scheduler-unstable_mock.development.js +700 -0
- data/lib/node_modules/scheduler/cjs/scheduler-unstable_mock.production.min.js +20 -0
- data/lib/node_modules/scheduler/cjs/scheduler-unstable_post_task.development.js +207 -0
- data/lib/node_modules/scheduler/cjs/scheduler-unstable_post_task.production.min.js +14 -0
- data/lib/node_modules/scheduler/cjs/scheduler.development.js +634 -0
- data/lib/node_modules/scheduler/cjs/scheduler.production.min.js +19 -0
- data/lib/node_modules/scheduler/index.js +7 -0
- data/lib/node_modules/scheduler/package.json +36 -0
- data/lib/node_modules/scheduler/umd/scheduler-unstable_mock.development.js +699 -0
- data/lib/node_modules/scheduler/umd/scheduler-unstable_mock.production.min.js +19 -0
- data/lib/node_modules/scheduler/umd/scheduler.development.js +152 -0
- data/lib/node_modules/scheduler/umd/scheduler.production.min.js +146 -0
- data/lib/node_modules/scheduler/umd/scheduler.profiling.min.js +146 -0
- data/lib/node_modules/scheduler/unstable_mock.js +7 -0
- data/lib/node_modules/scheduler/unstable_post_task.js +7 -0
- data/lib/node_modules/set-cookie-parser/LICENSE +21 -0
- data/lib/node_modules/set-cookie-parser/README.md +202 -0
- data/lib/node_modules/set-cookie-parser/lib/set-cookie.js +224 -0
- data/lib/node_modules/set-cookie-parser/package.json +45 -0
- data/lib/node_modules/turbo-stream/LICENSE +7 -0
- data/lib/node_modules/turbo-stream/README.md +31 -0
- data/lib/node_modules/turbo-stream/dist/flatten.d.ts +2 -0
- data/lib/node_modules/turbo-stream/dist/flatten.js +203 -0
- data/lib/node_modules/turbo-stream/dist/turbo-stream.d.ts +13 -0
- data/lib/node_modules/turbo-stream/dist/turbo-stream.js +207 -0
- data/lib/node_modules/turbo-stream/dist/turbo-stream.mjs +673 -0
- data/lib/node_modules/turbo-stream/dist/unflatten.d.ts +2 -0
- data/lib/node_modules/turbo-stream/dist/unflatten.js +243 -0
- data/lib/node_modules/turbo-stream/dist/utils.d.ts +44 -0
- data/lib/node_modules/turbo-stream/dist/utils.js +55 -0
- data/lib/node_modules/turbo-stream/package.json +50 -0
- data/lib/package-lock.json +133 -0
- data/lib/package.json +12 -0
- data/lib/rubee/async/asyncable.rb +2 -2
- data/lib/rubee/async/sidekiq_async.rb +11 -11
- data/lib/rubee/async/thread_async.rb +1 -1
- data/lib/rubee/async/thread_pool.rb +2 -2
- data/lib/rubee/controllers/base_controller.rb +44 -21
- data/lib/rubee/controllers/extensions/auth_tokenable.rb +10 -8
- data/lib/rubee/controllers/extensions/middlewarable.rb +1 -1
- data/lib/rubee/controllers/middlewares/auth_token_middleware.rb +12 -8
- data/lib/rubee/extensions/hookable.rb +3 -6
- data/lib/rubee/extensions/serializable.rb +3 -3
- data/lib/rubee/models/database_objectable.rb +11 -12
- data/lib/rubee/models/sequel_object.rb +23 -24
- data/lib/rubee.rb +106 -55
- data/lib/tests/account_model_test.rb +4 -4
- data/lib/tests/auth_tokenable_test.rb +6 -6
- data/lib/tests/comment_model_test.rb +7 -7
- data/lib/tests/example_models/account.rb +1 -0
- data/lib/tests/example_models/comment.rb +1 -0
- data/lib/tests/example_models/post.rb +1 -0
- data/lib/tests/example_models/user.rb +1 -0
- data/lib/tests/rubeeapp_test.rb +21 -6
- data/lib/tests/test.db +0 -0
- data/lib/tests/test_helper.rb +3 -5
- data/lib/tests/user_model_test.rb +71 -54
- data/readme.md +104 -2
- metadata +170 -3
|
@@ -12,37 +12,52 @@ module Rubee
|
|
|
12
12
|
|
|
13
13
|
if File.exist?(image_path) && File.file?(image_path)
|
|
14
14
|
mime_type = Rack::Mime.mime_type(File.extname(image_path))
|
|
15
|
-
response_with
|
|
15
|
+
response_with(object: File.read(image_path), type: :image, mime_type: mime_type)
|
|
16
16
|
else
|
|
17
|
-
response_with
|
|
17
|
+
response_with(object: 'Image not found', type: :text)
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
def
|
|
21
|
+
def js
|
|
22
|
+
js_path = File.join(JS_DIR, @request.path.sub('/js/', ''))
|
|
23
|
+
|
|
24
|
+
if File.exist?(js_path) && File.file?(js_path)
|
|
25
|
+
response_with(object: File.read(js_path), type: :js)
|
|
26
|
+
else
|
|
27
|
+
response_with(object: 'Js file is not found', type: :text)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def response_with type: nil, object: nil, status: 200, mime_type: nil, render_view: nil, headers: {}, to: nil,
|
|
32
|
+
file: nil, filename: nil, **options
|
|
22
33
|
case type&.to_sym
|
|
23
34
|
in :json
|
|
24
35
|
rendered_json = object.is_a?(Array) ? object&.map(&:to_h).to_json : object.to_json
|
|
25
|
-
|
|
36
|
+
[status, headers.merge('content-type' => 'application/json'), [rendered_json]]
|
|
26
37
|
in :image
|
|
27
|
-
|
|
38
|
+
[status, headers.merge('content-type' => mime_type), [object]]
|
|
39
|
+
in :js
|
|
40
|
+
[status, headers.merge('content-type' => 'application/javascript'), [object]]
|
|
28
41
|
in :file
|
|
29
|
-
|
|
42
|
+
[
|
|
30
43
|
status,
|
|
31
44
|
headers.merge(
|
|
32
|
-
|
|
33
|
-
|
|
45
|
+
'content-disposition' => "attachment; filename=#{filename}",
|
|
46
|
+
'content-type' => 'application/octet-stream'
|
|
34
47
|
),
|
|
35
|
-
file
|
|
48
|
+
file,
|
|
36
49
|
]
|
|
37
50
|
in :text
|
|
38
|
-
|
|
51
|
+
[status, headers.merge('content-type' => 'text/plain'), [object.to_s]]
|
|
39
52
|
in :unauthentificated
|
|
40
|
-
|
|
53
|
+
[401, headers.merge('content-type' => 'text/plain'), ['Unauthentificated']]
|
|
41
54
|
in :redirect
|
|
42
|
-
|
|
55
|
+
[302, headers.merge('location' => to.to_s), ['Unauthentificated']]
|
|
56
|
+
in :not_found
|
|
57
|
+
[404, { 'content-type' => 'text/plain' }, ['Route not found']]
|
|
43
58
|
else # rendering erb view is a default behavior
|
|
44
|
-
view_file_name = self.class.name.split(
|
|
45
|
-
erb_file = render_view ?
|
|
59
|
+
view_file_name = self.class.name.split('Controller').first.downcase
|
|
60
|
+
erb_file = render_view ? render_view.to_s : "#{view_file_name}_#{@route[:action]}"
|
|
46
61
|
lib = Rubee::PROJECT_NAME == 'rubee' ? 'lib/' : ''
|
|
47
62
|
view = render_template(erb_file, { object:, **(options[:locals] || {}) })
|
|
48
63
|
|
|
@@ -55,7 +70,7 @@ module Rubee
|
|
|
55
70
|
ERB.new(view).result(binding)
|
|
56
71
|
end
|
|
57
72
|
|
|
58
|
-
|
|
73
|
+
[status, headers.merge('content-type' => 'text/html'), [whole_erb]]
|
|
59
74
|
end
|
|
60
75
|
end
|
|
61
76
|
|
|
@@ -69,25 +84,33 @@ module Rubee
|
|
|
69
84
|
|
|
70
85
|
def params
|
|
71
86
|
inputs = @request.env['rack.input'].read
|
|
72
|
-
body =
|
|
73
|
-
|
|
87
|
+
body = begin
|
|
88
|
+
JSON.parse(@request.body.read.strip)
|
|
89
|
+
rescue StandardError
|
|
90
|
+
{}
|
|
91
|
+
end
|
|
92
|
+
begin
|
|
93
|
+
body.merge!(URI.decode_www_form(inputs).to_h.transform_keys(&:to_sym))
|
|
94
|
+
rescue StandardError
|
|
95
|
+
nil
|
|
96
|
+
end
|
|
74
97
|
@params ||= extract_params(@request.path, @route[:path])
|
|
75
98
|
.merge(body)
|
|
76
99
|
.merge(@request.params)
|
|
77
100
|
.transform_keys(&:to_sym)
|
|
78
|
-
.
|
|
101
|
+
.reject { |k, _v| [:_method].include?(k.downcase.to_sym) }
|
|
79
102
|
end
|
|
80
103
|
|
|
81
104
|
def headers
|
|
82
|
-
@request.env.select {|k,
|
|
83
|
-
.collect {|key, val| [key.sub(/^HTTP_/, ''), val]}
|
|
105
|
+
@request.env.select { |k, _v| k.start_with?('HTTP_') }
|
|
106
|
+
.collect { |key, val| [key.sub(/^HTTP_/, ''), val] }
|
|
84
107
|
end
|
|
85
108
|
|
|
86
109
|
def extract_params(path, pattern)
|
|
87
110
|
regex_pattern = pattern.gsub(/\{(\w+)\}/, '(?<\1>[^/]+)')
|
|
88
111
|
regex = Regexp.new("^#{regex_pattern}$")
|
|
89
112
|
|
|
90
|
-
if match = path.match(regex)
|
|
113
|
+
if (match = path.match(regex))
|
|
91
114
|
return match.named_captures&.transform_keys(&:to_sym)
|
|
92
115
|
end
|
|
93
116
|
|
|
@@ -18,37 +18,39 @@ module Rubee
|
|
|
18
18
|
def authentificated?
|
|
19
19
|
methods = self.class._auth_methods
|
|
20
20
|
return true if methods && !methods.include?(@route[:action].to_sym)
|
|
21
|
+
|
|
21
22
|
# This is suppose to be set in the middleware, otherwise it will return false
|
|
22
23
|
valid_token?
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
def valid_token?
|
|
26
|
-
@request.env[
|
|
27
|
+
@request.env['rack.session']&.[]('authentificated')
|
|
27
28
|
end
|
|
28
29
|
|
|
29
30
|
def authentificated_user
|
|
30
31
|
# User model must be created with email and password properties at least
|
|
31
|
-
@
|
|
32
|
+
@authentificated_user ||= User.where(email: params[:email], password: params[:password]).first
|
|
32
33
|
end
|
|
33
34
|
|
|
34
35
|
def authentificate!
|
|
35
36
|
return false unless authentificated_user
|
|
37
|
+
|
|
36
38
|
# Generate token
|
|
37
39
|
payload = { username: params[:email], exp: Time.now.to_i + EXPIRE }
|
|
38
40
|
@token = JWT.encode(payload, KEY, 'HS256')
|
|
39
41
|
# Set jwt token to the browser within cookie, so next browser request will include it.
|
|
40
42
|
# make sure it passed to response_with headers options
|
|
41
|
-
@token_header = {
|
|
43
|
+
@token_header = { 'set-cookie' => "jwt=#{@token}; path=/; httponly; secure" }
|
|
42
44
|
|
|
43
45
|
true
|
|
44
46
|
end
|
|
45
47
|
|
|
46
48
|
def unauthentificate!
|
|
47
|
-
@request.env[
|
|
49
|
+
@request.env['rack.session']['authentificated'] = nil if @request.env['rack.session']&.[]('authentificated')
|
|
48
50
|
@authehtificated_user = nil if @authehtificated_user
|
|
49
51
|
@zeroed_token_header = {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
'set-cookie' => 'jwt=; path=/; httponly; secure; expires=thu, 01 jan 1970 00:00:00 gmt',
|
|
53
|
+
'content-type' => 'application/json',
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
true
|
|
@@ -58,7 +60,7 @@ module Rubee
|
|
|
58
60
|
if authentificated?
|
|
59
61
|
yield
|
|
60
62
|
else
|
|
61
|
-
response_with
|
|
63
|
+
response_with(type: :unauthentificated)
|
|
62
64
|
end
|
|
63
65
|
end
|
|
64
66
|
end
|
|
@@ -69,7 +71,7 @@ module Rubee
|
|
|
69
71
|
@auth_methods.concat(args.map(&:to_sym)).uniq!
|
|
70
72
|
|
|
71
73
|
@auth_methods.each do |method|
|
|
72
|
-
around
|
|
74
|
+
around(method, :handle_auth)
|
|
73
75
|
end
|
|
74
76
|
end
|
|
75
77
|
|
|
@@ -9,7 +9,7 @@ module Middlewarable
|
|
|
9
9
|
|
|
10
10
|
module Initializer
|
|
11
11
|
def initialize(req, route)
|
|
12
|
-
app = ->(
|
|
12
|
+
app = ->(_env) { super(req, route) }
|
|
13
13
|
self.class.middlewares.reverse_each do |middleware|
|
|
14
14
|
middleware_class = Object.const_get(middleware)
|
|
15
15
|
app = middleware_class.new(app, req)
|
|
@@ -7,13 +7,13 @@ module Rubee
|
|
|
7
7
|
|
|
8
8
|
def call(env)
|
|
9
9
|
# get token from header
|
|
10
|
-
auth_header = headers(env)[
|
|
11
|
-
token = auth_header ? auth_header[/^Bearer (.*)$/]&.gsub(
|
|
10
|
+
auth_header = headers(env)['HTTP_AUTHORIZATION']
|
|
11
|
+
token = auth_header ? auth_header[/^Bearer (.*)$/]&.gsub('Bearer ', '') : nil
|
|
12
12
|
# get token from cookies
|
|
13
|
-
token
|
|
13
|
+
token ||= @req.cookies['jwt']
|
|
14
14
|
if valid_token?(token)
|
|
15
|
-
env[
|
|
16
|
-
env[
|
|
15
|
+
env['rack.session'] ||= {}
|
|
16
|
+
env['rack.session']['authentificated'] = true
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
@app.call(env)
|
|
@@ -22,7 +22,7 @@ module Rubee
|
|
|
22
22
|
private
|
|
23
23
|
|
|
24
24
|
def headers(env)
|
|
25
|
-
env.each_with_object({}) { |(k, v), h| h[k] = v if k.start_with?(
|
|
25
|
+
env.each_with_object({}) { |(k, v), h| h[k] = v if k.start_with?('HTTP_') }
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def valid_token?(token)
|
|
@@ -35,8 +35,12 @@ module Rubee
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def decode_jwt(token)
|
|
38
|
-
decoded_array =
|
|
39
|
-
|
|
38
|
+
decoded_array = begin
|
|
39
|
+
JWT.decode(token, AuthTokenable::KEY, true, { algorithm: 'HS256' })
|
|
40
|
+
rescue StandardError
|
|
41
|
+
[]
|
|
42
|
+
end
|
|
43
|
+
decoded_array&.first&.transform_keys(&:to_sym) || {} # Extract payload
|
|
40
44
|
end
|
|
41
45
|
end
|
|
42
46
|
end
|
|
@@ -16,7 +16,7 @@ module Rubee
|
|
|
16
16
|
super(*args, &block)
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
|
-
prepend
|
|
19
|
+
prepend(hooks)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def after(method, handler, **options)
|
|
@@ -31,7 +31,7 @@ module Rubee
|
|
|
31
31
|
result
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
|
-
prepend
|
|
34
|
+
prepend(hooks)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def around(method, handler, **options)
|
|
@@ -48,7 +48,7 @@ module Rubee
|
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
50
|
end
|
|
51
|
-
prepend
|
|
51
|
+
prepend(hooks)
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
|
|
@@ -58,7 +58,6 @@ module Rubee
|
|
|
58
58
|
def conditions_met?(if_condition = nil, unless_condition = nil)
|
|
59
59
|
return true if if_condition.nil? && unless_condition.nil?
|
|
60
60
|
|
|
61
|
-
if_condition_result = true
|
|
62
61
|
if_condition_result =
|
|
63
62
|
if if_condition.nil?
|
|
64
63
|
true
|
|
@@ -67,8 +66,6 @@ module Rubee
|
|
|
67
66
|
elsif respond_to?(if_condition)
|
|
68
67
|
send(if_condition)
|
|
69
68
|
end
|
|
70
|
-
|
|
71
|
-
unless_condition_result = true
|
|
72
69
|
unless_condition_result =
|
|
73
70
|
if unless_condition.nil?
|
|
74
71
|
false
|
|
@@ -8,19 +8,19 @@ module Rubee
|
|
|
8
8
|
module Initializer
|
|
9
9
|
def initialize(attrs)
|
|
10
10
|
attrs.each do |attr, value|
|
|
11
|
-
|
|
11
|
+
send("#{attr}=", value)
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
module InstanceMethods
|
|
17
|
-
def to_json
|
|
17
|
+
def to_json(*_args)
|
|
18
18
|
to_h.to_json
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def to_h
|
|
22
22
|
instance_variables.each_with_object({}) do |var, hash|
|
|
23
|
-
hash[var.to_s.delete(
|
|
23
|
+
hash[var.to_s.delete('@')] = instance_variable_get(var)
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
end
|
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
module Rubee
|
|
2
2
|
module DatabaseObjectable
|
|
3
3
|
def self.included(base)
|
|
4
|
-
base.extend
|
|
5
|
-
base.include
|
|
6
|
-
base.prepend
|
|
4
|
+
base.extend(ClassMethods)
|
|
5
|
+
base.include(InstanceMethods)
|
|
6
|
+
base.prepend(Initializer)
|
|
7
7
|
|
|
8
|
-
base.include
|
|
9
|
-
base.include
|
|
8
|
+
base.include(Rubee::Hookable)
|
|
9
|
+
base.include(Rubee::Serializable)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
module ClassMethods
|
|
13
13
|
def pluralize_class_name
|
|
14
|
-
pluralize(
|
|
14
|
+
pluralize(name.downcase)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def pluralize(word)
|
|
18
18
|
if word.end_with?('y') && !%w[a e i o u].include?(word[-2])
|
|
19
|
-
word[0..-2]
|
|
19
|
+
"#{word[0..-2]}ies" # Replace "y" with "ies"
|
|
20
20
|
elsif word.end_with?('s', 'x', 'z', 'ch', 'sh')
|
|
21
|
-
word
|
|
21
|
+
"#{word}es" # Add "es" for certain endings
|
|
22
22
|
else
|
|
23
|
-
word
|
|
23
|
+
"#{word}s" # Default to adding "s"
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def singularize(word)
|
|
28
28
|
if word.end_with?('ies') && word.length > 3
|
|
29
|
-
word[0..-4]
|
|
29
|
+
"#{word[0..-4]}y" # Convert "ies" to "y"
|
|
30
30
|
elsif word.end_with?('es') && %w[s x z ch sh].any? { |ending| word[-(ending.length + 2)..-3] == ending }
|
|
31
31
|
word[0..-3] # Remove "es" for words like "foxes", "buses"
|
|
32
32
|
elsif word.end_with?('s') && word.length > 1
|
|
@@ -38,7 +38,7 @@ module Rubee
|
|
|
38
38
|
|
|
39
39
|
def accessor_names
|
|
40
40
|
instance_methods(false)
|
|
41
|
-
.select { |m| method_defined?("#{m}=") }
|
|
41
|
+
.select { |m| method_defined?("#{m}=") } # Check if setter exists
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
|
|
@@ -49,4 +49,3 @@ module Rubee
|
|
|
49
49
|
end
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
|
-
|
|
@@ -2,7 +2,7 @@ module Rubee
|
|
|
2
2
|
class SequelObject
|
|
3
3
|
include Rubee::DatabaseObjectable
|
|
4
4
|
|
|
5
|
-
def destroy(cascade: false, **
|
|
5
|
+
def destroy(cascade: false, **_options)
|
|
6
6
|
if cascade
|
|
7
7
|
# find all tables with foreign key
|
|
8
8
|
tables_with_fk = DB.tables.select do |table|
|
|
@@ -23,26 +23,25 @@ module Rubee
|
|
|
23
23
|
if args[:id]
|
|
24
24
|
begin
|
|
25
25
|
udpate(args)
|
|
26
|
-
rescue =>
|
|
26
|
+
rescue StandardError => _e
|
|
27
27
|
return false
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
true
|
|
31
30
|
else
|
|
32
31
|
begin
|
|
33
32
|
created_object = self.class.create(args)
|
|
34
|
-
rescue =>
|
|
33
|
+
rescue StandardError => _e
|
|
35
34
|
return false
|
|
36
35
|
end
|
|
37
36
|
self.id = created_object.id
|
|
38
37
|
|
|
39
|
-
true
|
|
40
38
|
end
|
|
39
|
+
true
|
|
41
40
|
end
|
|
42
41
|
|
|
43
|
-
def assign_attributes(args={})
|
|
44
|
-
to_h.
|
|
45
|
-
|
|
42
|
+
def assign_attributes(args = {})
|
|
43
|
+
to_h.each_key do |attr|
|
|
44
|
+
send("#{attr}=", args[attr.to_sym]) if args[attr.to_sym]
|
|
46
45
|
end
|
|
47
46
|
end
|
|
48
47
|
|
|
@@ -65,14 +64,14 @@ module Rubee
|
|
|
65
64
|
class << self
|
|
66
65
|
def last
|
|
67
66
|
found_hash = dataset.order(:id).last
|
|
68
|
-
return
|
|
67
|
+
return new(**found_hash) if found_hash
|
|
69
68
|
|
|
70
69
|
nil
|
|
71
70
|
end
|
|
72
71
|
|
|
73
72
|
def first
|
|
74
73
|
found_hash = dataset.order(:id).first
|
|
75
|
-
return
|
|
74
|
+
return new(**found_hash) if found_hash
|
|
76
75
|
|
|
77
76
|
nil
|
|
78
77
|
end
|
|
@@ -81,9 +80,9 @@ module Rubee
|
|
|
81
80
|
# owns_many :comments
|
|
82
81
|
# > user.comments
|
|
83
82
|
# > [<comment1>, <comment2>]
|
|
84
|
-
def owns_many(assoc, fk_name: nil, over: nil, **
|
|
83
|
+
def owns_many(assoc, fk_name: nil, over: nil, **_options)
|
|
85
84
|
singularized_assoc_name = singularize(assoc.to_s)
|
|
86
|
-
fk_name ||= "#{
|
|
85
|
+
fk_name ||= "#{name.to_s.downcase}_id"
|
|
87
86
|
|
|
88
87
|
define_method(assoc) do
|
|
89
88
|
klass = Object.const_get(singularized_assoc_name.capitalize)
|
|
@@ -102,9 +101,9 @@ module Rubee
|
|
|
102
101
|
# owns_one :user
|
|
103
102
|
# > comment.user
|
|
104
103
|
# > <user>
|
|
105
|
-
def owns_one(assoc, options={})
|
|
104
|
+
def owns_one(assoc, options = {})
|
|
106
105
|
Sequel::Model.one_to_one(assoc, **options)
|
|
107
|
-
fk_name ||= "#{
|
|
106
|
+
fk_name ||= "#{name.to_s.downcase}_id"
|
|
108
107
|
define_method(assoc) do
|
|
109
108
|
Object.const_get(assoc.capitalize).where(fk_name.to_sym => id)&.first
|
|
110
109
|
end
|
|
@@ -114,11 +113,11 @@ module Rubee
|
|
|
114
113
|
# holds :user
|
|
115
114
|
# > account.user
|
|
116
115
|
# > <user>
|
|
117
|
-
def holds(assoc, fk_name: nil, **
|
|
116
|
+
def holds(assoc, fk_name: nil, **_options)
|
|
118
117
|
fk_name ||= "#{assoc.to_s.downcase}_id"
|
|
119
118
|
define_method(assoc) do
|
|
120
119
|
target_klass = Object.const_get(assoc.capitalize)
|
|
121
|
-
target_klass.find(
|
|
120
|
+
target_klass.find(send(fk_name))
|
|
122
121
|
end
|
|
123
122
|
end
|
|
124
123
|
|
|
@@ -130,33 +129,33 @@ module Rubee
|
|
|
130
129
|
|
|
131
130
|
def dataset
|
|
132
131
|
@dataset ||= DB[pluralize_class_name.to_sym]
|
|
133
|
-
rescue Exception =>
|
|
132
|
+
rescue Exception => _e
|
|
134
133
|
reconnect!
|
|
135
134
|
retry
|
|
136
135
|
end
|
|
137
136
|
|
|
138
137
|
def all
|
|
139
138
|
dataset.map do |record_hash|
|
|
140
|
-
|
|
139
|
+
new(**record_hash)
|
|
141
140
|
end
|
|
142
141
|
end
|
|
143
142
|
|
|
144
143
|
def find(id)
|
|
145
144
|
found_hash = dataset.where(id:)&.first
|
|
146
|
-
return
|
|
145
|
+
return new(**found_hash) if found_hash
|
|
147
146
|
|
|
148
147
|
nil
|
|
149
148
|
end
|
|
150
149
|
|
|
151
150
|
def where(args)
|
|
152
151
|
dataset.where(**args).map do |record_hash|
|
|
153
|
-
|
|
152
|
+
new(**record_hash)
|
|
154
153
|
end
|
|
155
154
|
end
|
|
156
155
|
|
|
157
156
|
def order(*args)
|
|
158
157
|
dataset.order(*args).map do |record_hash|
|
|
159
|
-
|
|
158
|
+
new(**record_hash)
|
|
160
159
|
end
|
|
161
160
|
end
|
|
162
161
|
|
|
@@ -166,18 +165,18 @@ module Rubee
|
|
|
166
165
|
|
|
167
166
|
def create(attrs)
|
|
168
167
|
out_id = dataset.insert(**attrs)
|
|
169
|
-
|
|
168
|
+
new(**attrs.merge(id: out_id))
|
|
170
169
|
end
|
|
171
170
|
|
|
172
171
|
def destroy_all(cascade: false)
|
|
173
|
-
all.each{ |record| record.destroy(cascade:) }
|
|
172
|
+
all.each { |record| record.destroy(cascade:) }
|
|
174
173
|
end
|
|
175
174
|
|
|
176
175
|
def serialize(suquel_dataset, klass = nil)
|
|
177
176
|
klass ||= self
|
|
178
177
|
suquel_dataset.map do |record_hash|
|
|
179
178
|
target_klass_fields = DB[pluralize(klass.name.downcase).to_sym].columns
|
|
180
|
-
klass_attributes = record_hash.filter{ target_klass_fields.include?
|
|
179
|
+
klass_attributes = record_hash.filter { target_klass_fields.include?(_1) }
|
|
181
180
|
klass.new(**klass_attributes)
|
|
182
181
|
end
|
|
183
182
|
end
|