symphonia 4.1.1 → 4.2.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/.rubocop.yml +2 -0
- data/CHANGELOG.md +16 -0
- data/app/assets/javascripts/symphonia/symphonia_bootstrap_dialog.js +23 -23
- data/app/assets/stylesheets/symphonia/basic.scss +1 -3
- data/app/controllers/symphonia/accounts_controller.rb +1 -7
- data/app/views/symphonia/accounts/_form.html.erb +0 -4
- data/app/views/symphonia/accounts/register.html.erb +4 -14
- data/app/views/symphonia/login/_form.html.erb +3 -3
- data/config/locales/cs.yml +0 -5
- data/lib/generators/symphonia/setup/templates/Gemfile +1 -2
- data/lib/generators/symphonia/setup/templates/app/config/initializers/settings.rb.tt +0 -5
- data/lib/symphonia/controller_extensions.rb +39 -65
- data/lib/symphonia/engine.rb +0 -3
- data/lib/symphonia/model_attributes/attribute.rb +3 -3
- data/lib/symphonia/version.rb +1 -1
- data/spec/controllers/account_controller_spec.rb +17 -17
- metadata +8 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b1926adf23dfcc6193affda2c0eaf6edcf7729eba7ee21fde5d65d7ffe6fa64
|
4
|
+
data.tar.gz: 16cd15eb367b3f597e6fc67f60d8d8de7941010d08ec42b5b02baecf3fddf623
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c3b96b59bd3014de2cd86cbf53a5c4bfe1c30f4f1ee6d1b9a60a71c98784c33c1a8b270471dfe8a5db35f80c00f02c931e3d54c98e712000737828e805226480
|
7
|
+
data.tar.gz: 31b3f194941fb8661419af1f52a1ab9c4423f40da86443846876f9996505127903002473ec7c1923f91891858851201bb134420feb1210f7ecf061f182ae11bb
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
|
+
## [4.2.0] - 2022-04-07
|
9
|
+
### Removed
|
10
|
+
- awesome_nested_set dependency
|
11
|
+
### Changed
|
12
|
+
- start with Ruby3 support
|
13
|
+
|
14
|
+
## [4.1.3] - 2022-03-02
|
15
|
+
### Changed
|
16
|
+
- update sidekiq
|
17
|
+
## [4.1.2] - 2022-01-20
|
18
|
+
### Removed
|
19
|
+
- Recaptcha conditions
|
20
|
+
### Changed
|
21
|
+
- registration/login autocomplete
|
22
|
+
- cleanup controller extensions
|
23
|
+
|
8
24
|
## [4.1.1] - 2021-12-26
|
9
25
|
### Fixed
|
10
26
|
- user activation
|
@@ -1,42 +1,42 @@
|
|
1
1
|
/**
|
2
2
|
* Symphonia modal dialog pop-up.
|
3
3
|
* @param {String} id
|
4
|
-
* @param {Object}
|
5
|
-
* @param {String}
|
6
|
-
* @param {Boolean}
|
7
|
-
* @param {String}
|
8
|
-
* @param {String}
|
9
|
-
* @param {String}
|
10
|
-
* @param {Boolean}
|
4
|
+
* @param {Object} opts
|
5
|
+
* @param {String} opts.title - Title of dialog window.
|
6
|
+
* @param {Boolean} opts.force - If dialog element exists, will remove and replace new one.
|
7
|
+
* @param {String} opts.text - Text for body of dialog window.
|
8
|
+
* @param {String} opts.html - Content (html) for body of dialog window.
|
9
|
+
* @param {String} opts.submit - Text of submit button. If provided generate submit button.
|
10
|
+
* @param {Boolean} opts.large - Use Large modal
|
11
11
|
*/
|
12
|
-
SymphoniaDialog = function (id,
|
13
|
-
|
12
|
+
SymphoniaDialog = function (id, opts) {
|
13
|
+
const options = $.extend(opts, {});
|
14
14
|
if (options["force"] === undefined)
|
15
15
|
options["force"] = true;
|
16
16
|
|
17
17
|
this.id = id || 'ajax_modal';
|
18
|
-
|
18
|
+
const m = document.getElementById(this.id);
|
19
19
|
|
20
20
|
// var currentDialog = document.getElementById(this.id + "__symphonia_dialog");
|
21
21
|
// if (currentDialog) {
|
22
22
|
// currentDialog.remove();
|
23
23
|
// }
|
24
24
|
|
25
|
-
|
26
|
-
|
25
|
+
const dialog = document.createElement("div");
|
26
|
+
const modalDialog = document.createElement("div");
|
27
27
|
modalDialog.className = "modal-dialog";
|
28
28
|
if (options["large"]) {
|
29
29
|
modalDialog.classList.add("modal-lg")
|
30
30
|
}
|
31
31
|
dialog.setAttribute("role", "document");
|
32
32
|
|
33
|
-
|
33
|
+
const content = document.createElement("div");
|
34
34
|
content.className = "modal-content";
|
35
|
-
|
35
|
+
const heading = document.createElement("div");
|
36
36
|
heading.className = "modal-header";
|
37
|
-
|
37
|
+
const modalTitle = document.createElement("h5");
|
38
38
|
modalTitle.className = "modal-title";
|
39
|
-
|
39
|
+
const body = document.createElement("div");
|
40
40
|
|
41
41
|
body.className = "modal-body";
|
42
42
|
dialog.id = this.id;
|
@@ -46,7 +46,7 @@ SymphoniaDialog = function (id, options) {
|
|
46
46
|
// =-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-
|
47
47
|
|
48
48
|
this.appendSubmitButton = function (label) {
|
49
|
-
|
49
|
+
const submitButton = document.createElement('button');
|
50
50
|
submitButton.onclick = this.submit;
|
51
51
|
submitButton.innerText = (label === true) && 'Submit' || label;
|
52
52
|
submitButton.className = "btn btn-primary";
|
@@ -54,14 +54,14 @@ SymphoniaDialog = function (id, options) {
|
|
54
54
|
return submitButton;
|
55
55
|
};
|
56
56
|
this.submit = function () {
|
57
|
-
|
57
|
+
const form = dialog.querySelector("form");
|
58
58
|
if (form)
|
59
59
|
form.submit();
|
60
60
|
};
|
61
61
|
this.show = function () {
|
62
62
|
// dialog.find(".modal-body > .modal-content-inner-container").css({'max-height': window.innerHeight - 200});
|
63
63
|
// dialog.find(".modal-body > .modal-content-inner-container").css({'max-height': window.innerHeight - 200});
|
64
|
-
|
64
|
+
const t = dialog.querySelector(".title");
|
65
65
|
if (t && t.innerHTML === '') {
|
66
66
|
this.title = modalTitle.innerHTML;
|
67
67
|
t.remove();
|
@@ -83,7 +83,7 @@ SymphoniaDialog = function (id, options) {
|
|
83
83
|
|
84
84
|
modalTitle.innerText = options.title || '';
|
85
85
|
|
86
|
-
|
86
|
+
const closeButton = document.createElement("button");
|
87
87
|
closeButton.className = "close fa fa-times";
|
88
88
|
closeButton.dataset['dismiss'] = "modal";
|
89
89
|
heading.appendChild(modalTitle);
|
@@ -114,7 +114,7 @@ SymphoniaDialog = function (id, options) {
|
|
114
114
|
dialog.appendChild(modalDialog);
|
115
115
|
|
116
116
|
if (options.force) {
|
117
|
-
|
117
|
+
const currentDialog = document.getElementById(dialog.id);
|
118
118
|
if (currentDialog)
|
119
119
|
currentDialog.remove();
|
120
120
|
}
|
@@ -130,7 +130,7 @@ SymphoniaDialog.prototype.close = function () {
|
|
130
130
|
};
|
131
131
|
window.Symphonia.dialog = {
|
132
132
|
show: function(IDcontainer, options) {
|
133
|
-
|
133
|
+
const modal = new SymphoniaDialog(IDcontainer, options);
|
134
134
|
modal.show();
|
135
135
|
}
|
136
|
-
}
|
136
|
+
}
|
@@ -5,8 +5,6 @@ module Symphonia
|
|
5
5
|
before_action -> { menu_item(:my_account) }, only: [:show, :edit, :update]
|
6
6
|
before_action :prepare_user, only: [:register, :create]
|
7
7
|
|
8
|
-
helper Recaptcha::ClientHelper if defined? Recaptcha
|
9
|
-
|
10
8
|
def show
|
11
9
|
@user = current_account
|
12
10
|
|
@@ -159,11 +157,7 @@ module Symphonia
|
|
159
157
|
|
160
158
|
# @return [Boolean]
|
161
159
|
def verify_registration
|
162
|
-
|
163
|
-
verify_recaptcha(model: @user)
|
164
|
-
else
|
165
|
-
true
|
166
|
-
end
|
160
|
+
true
|
167
161
|
end
|
168
162
|
|
169
163
|
end
|
@@ -9,11 +9,9 @@
|
|
9
9
|
</div>
|
10
10
|
<div class="col-lg-8">
|
11
11
|
<%= f.text_field :first_name, required: true %>
|
12
|
-
|
13
12
|
</div>
|
14
13
|
<div class="col-lg-8">
|
15
14
|
<%= f.text_field :last_name, required: true %>
|
16
|
-
|
17
15
|
</div>
|
18
16
|
<div class="col-lg-8">
|
19
17
|
<% if f.object.external_id.blank? %>
|
@@ -21,5 +19,3 @@
|
|
21
19
|
<% end %>
|
22
20
|
</div>
|
23
21
|
</div>
|
24
|
-
|
25
|
-
|
@@ -8,20 +8,10 @@
|
|
8
8
|
<%= symphonia_form_for(@user, url: account_register_path) do |f| %>
|
9
9
|
<div style="width:1px;height: 1px;visibility: hidden"><%= check_box_tag :terms, true %></div>
|
10
10
|
<%= f.error_messages %>
|
11
|
-
<%= f.
|
12
|
-
<%= f.
|
13
|
-
<%= f.password_field :password, required: true, prepend: icon('key') %>
|
14
|
-
|
15
|
-
<fieldset>
|
16
|
-
<%= content_tag(:legend, t(:text_explanation_recaptcha)) %>
|
17
|
-
<div class="form-group">
|
18
|
-
<div class="col-sm-offset-4 col-sm-5">
|
19
|
-
<%#= invisible_recaptcha_tags %>
|
20
|
-
<%= recaptcha_tags(:display => { :theme => 'white' }) %>
|
21
|
-
</div>
|
22
|
-
</div>
|
23
|
-
</fieldset>
|
24
|
-
<% end %>
|
11
|
+
<%= f.text_field :name, required: true, autocomplete: "off", prepend: icon("user") %>
|
12
|
+
<%= f.email_field :mail, required: true, autocomplete: "username", prepend: "@" %>
|
13
|
+
<%= f.password_field :password, autocomplete: "new-password", required: true, prepend: icon('key') %>
|
14
|
+
|
25
15
|
<%= f.primary t(:button_register), class: 'btn btn-primary btn-block' %>
|
26
16
|
<% end %>
|
27
17
|
</div>
|
@@ -1,8 +1,8 @@
|
|
1
1
|
<%= f.error_messages %>
|
2
|
-
<%= hidden_field_tag(:back_url,
|
3
|
-
<%= f.text_field :login, required: true, autofocus: true %>
|
2
|
+
<%= hidden_field_tag(:back_url, back_url || session[:back_url]) %>
|
3
|
+
<%= f.text_field :login, required: true, autofocus: true, autocomplete: "username" %>
|
4
4
|
|
5
|
-
<%= f.password_field :password, required: true %>
|
5
|
+
<%= f.password_field :password, required: true, autocomplete: "current-password" %>
|
6
6
|
|
7
7
|
<%= f.form_group :remember_me do %>
|
8
8
|
<%= f.check_box :remember_me %>
|
data/config/locales/cs.yml
CHANGED
@@ -79,10 +79,6 @@ cs:
|
|
79
79
|
role_id: 'Role'
|
80
80
|
ssl: Používat SSL?
|
81
81
|
|
82
|
-
recaptcha:
|
83
|
-
errors:
|
84
|
-
verification_failed: 'Nesprávný text z obrázku'
|
85
|
-
|
86
82
|
helpers:
|
87
83
|
submit:
|
88
84
|
create: Vytvořit
|
@@ -144,7 +140,6 @@ cs:
|
|
144
140
|
text_user_not_found: Účet nenalezen
|
145
141
|
text_activation_resend: Aktivační odkaz odeslán
|
146
142
|
text_reset_password_resend: Informace o změně hesla odeslány
|
147
|
-
text_explanation_recaptcha: 'Opište prosím tato dvě slova:'
|
148
143
|
text_or: nebo
|
149
144
|
text_confirm_send_unlock_mail: Po aktivaci účtu bude uživateli zaslán email.
|
150
145
|
text_error_no_data_file_input: Nebyl vybrán žádný soubor
|
@@ -1,10 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
# Recaptcha.configure do |config|
|
4
|
-
# config.site_key = '6LejxOESAAAAALC3ohQCddKilokhYnTNXfYVItZe'
|
5
|
-
# config.secret_key = '6LejxOESAAAAANf-9T4nyHCDGW6Ok78Zo7GaG2GK'
|
6
|
-
# end
|
7
|
-
|
8
3
|
WillPaginate.per_page = 20
|
9
4
|
# Rails.application.config.i18n.available_locales = %i[en cs ru pl]
|
10
5
|
|
@@ -3,69 +3,39 @@ module Symphonia
|
|
3
3
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
|
+
class Unauthorized < RuntimeError
|
7
|
+
end
|
6
8
|
|
7
9
|
included do
|
8
|
-
class Unauthorized < Exception;
|
9
|
-
end
|
10
10
|
|
11
11
|
before_action :current_user, :menu_item
|
12
12
|
before_action :set_default_locale
|
13
13
|
|
14
|
-
# force_ssl if: -> {Rails.env.production? && User.current.ssl?}
|
15
|
-
|
16
14
|
add_flash_types :notice
|
17
15
|
add_flash_types :info
|
18
16
|
add_flash_types :warning
|
19
17
|
add_flash_types :error
|
20
18
|
|
21
|
-
rescue_from ::ActiveRecord::RecordNotFound
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
rescue_from Unauthorized do
|
26
|
-
render_403
|
27
|
-
end
|
28
|
-
|
29
|
-
helper_method :current_user
|
19
|
+
rescue_from ::ActiveRecord::RecordNotFound, with: :render_404
|
20
|
+
rescue_from Unauthorized, with: :render_403
|
30
21
|
|
22
|
+
helper_method :current_user, :back_url
|
31
23
|
end
|
32
24
|
|
33
25
|
def back_url
|
34
|
-
url = params[:back_url]
|
35
|
-
if url.nil? && (referer = request.env['HTTP_REFERER'])
|
26
|
+
url = params[:back_url].presence
|
27
|
+
if url.nil? && (referer = request.env['HTTP_REFERER'].presence)
|
36
28
|
url = CGI.unescape(referer.to_s)
|
37
29
|
end
|
38
30
|
url
|
39
31
|
end
|
40
32
|
|
41
|
-
# def redirect_back_or_default(default, options={})
|
42
|
-
# back_url = params[:back_url].to_s
|
43
|
-
# if back_url.present?
|
44
|
-
# begin
|
45
|
-
# uri = URI.parse(back_url)
|
46
|
-
# # do not redirect user to another host or to the login or register page
|
47
|
-
# if (uri.relative? || (uri.host == request.host)) && !uri.path.match(%r{/(login|account/register)})
|
48
|
-
# redirect_to(back_url)
|
49
|
-
# return
|
50
|
-
# end
|
51
|
-
# rescue URI::InvalidURIError
|
52
|
-
# logger.warn("Could not redirect to invalid URL #{back_url}")
|
53
|
-
# # redirect to default
|
54
|
-
# end
|
55
|
-
# elsif options[:referer]
|
56
|
-
# redirect_to_referer_or default
|
57
|
-
# return
|
58
|
-
# end
|
59
|
-
# redirect_to default, options
|
60
|
-
# false
|
61
|
-
# end
|
62
|
-
|
63
33
|
# Redirects to the request referer if present, redirects to args or call block otherwise.
|
64
34
|
def redirect_to_referer_or(*args, &block)
|
65
35
|
redirect_to :back
|
66
36
|
rescue ::ActionController::RedirectBackError
|
67
37
|
if args.any?
|
68
|
-
redirect_to
|
38
|
+
redirect_to(*args)
|
69
39
|
elsif block_given?
|
70
40
|
block.call
|
71
41
|
else
|
@@ -76,7 +46,10 @@ module Symphonia
|
|
76
46
|
# private
|
77
47
|
|
78
48
|
def set_locale
|
79
|
-
|
49
|
+
params_locale = params.fetch(:locale, nil).presence
|
50
|
+
params_locale ||= session[:locale].presence
|
51
|
+
params_locale ||= request.env['HTTP_ACCEPT_LANGUAGE'].to_s.split(',').collect { |l| l.scan(/^[a-z]{2}/) }.flatten
|
52
|
+
client_lang = Array(params_locale).compact
|
80
53
|
client_lang.unshift current_user.language if current_user.language
|
81
54
|
@client_lang = client_lang.detect { |l| I18n.available_locales.include?(l.to_sym) }
|
82
55
|
|
@@ -87,53 +60,57 @@ module Symphonia
|
|
87
60
|
end
|
88
61
|
|
89
62
|
def set_default_locale
|
90
|
-
|
91
|
-
|
92
|
-
|
63
|
+
return unless (enforce_default = Symphonia.config.default_locale)
|
64
|
+
|
65
|
+
I18n.locale = enforce_default
|
93
66
|
end
|
94
67
|
|
95
68
|
# protected
|
96
69
|
|
97
|
-
def login_require(
|
70
|
+
def login_require(_format = nil)
|
98
71
|
if current_user.nil? || !current_user.logged_in?
|
99
72
|
respond_to do |format|
|
100
73
|
format.html do
|
101
74
|
store_location
|
102
75
|
redirect_to symphonia.login_path, flash: { error: t(:text_login_require) }
|
103
76
|
end
|
104
|
-
format.json
|
105
|
-
|
77
|
+
format.json do
|
78
|
+
render json: { errors: 'You must be logged in to access this endpoint' }, status: :unauthorized
|
79
|
+
end
|
80
|
+
format.any { head :unauthorized }
|
106
81
|
end
|
107
82
|
return false
|
108
83
|
end
|
109
84
|
true
|
110
85
|
end
|
111
86
|
|
112
|
-
|
113
|
-
|
87
|
+
alias require_login login_require
|
88
|
+
alias require_user login_require
|
114
89
|
|
115
90
|
def admin_require
|
116
91
|
return unless login_require
|
117
92
|
|
118
93
|
unless current_user.admin?
|
119
94
|
render_403
|
120
|
-
|
95
|
+
false
|
121
96
|
end
|
122
97
|
end
|
123
98
|
|
124
|
-
|
99
|
+
alias require_admin admin_require
|
125
100
|
|
126
101
|
def render_403
|
127
102
|
respond_to do |format|
|
128
|
-
format.html { render template: 'common/403', message: :notice_not_authorized, status:
|
129
|
-
format.js
|
103
|
+
format.html { render template: 'common/403', message: :notice_not_authorized, status: :forbidden }
|
104
|
+
format.js do
|
105
|
+
render plain: "alert('#{t :text_access_deny}')", message: :notice_not_authorized, status: :forbidden
|
106
|
+
end
|
130
107
|
format.any { head 403, message: :notice_not_authorized }
|
131
108
|
end
|
132
109
|
end
|
133
110
|
|
134
111
|
def render_404
|
135
112
|
respond_to do |format|
|
136
|
-
format.html { render template: 'common/404', message: :notice_page_not_found, status:
|
113
|
+
format.html { render template: 'common/404', message: :notice_page_not_found, status: :not_found }
|
137
114
|
format.any { head 404, message: :not_found }
|
138
115
|
end
|
139
116
|
end
|
@@ -161,35 +138,32 @@ module Symphonia
|
|
161
138
|
def current_user
|
162
139
|
return (Symphonia::User.current ||= @current_user) if defined?(@current_user)
|
163
140
|
|
164
|
-
@current_user = current_user_session
|
141
|
+
@current_user = current_user_session&.user
|
165
142
|
Symphonia::User.current = @current_user || Symphonia::User::Anonymous.new
|
166
143
|
end
|
167
144
|
|
168
145
|
def authorize
|
169
146
|
if Symphonia::User.current.authorize?(controller_name, action_name)
|
170
147
|
return true
|
148
|
+
elsif Symphonia::User.current.logged_in?
|
149
|
+
raise Unauthorized
|
171
150
|
else
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
respond_to do |format|
|
176
|
-
format.html do
|
177
|
-
return redirect_to(symphonia.login_path(back_url: request.path), error: t(:text_error_login_required))
|
178
|
-
end
|
179
|
-
format.any { return head 401 }
|
151
|
+
respond_to do |format|
|
152
|
+
format.html do
|
153
|
+
return redirect_to(symphonia.login_path(back_url: request.path), error: t(:text_error_login_required))
|
180
154
|
end
|
155
|
+
format.any { return head 401 }
|
181
156
|
end
|
182
157
|
end
|
158
|
+
|
183
159
|
raise Unauthorized
|
184
160
|
end
|
185
161
|
|
186
162
|
def handle_unverified_request
|
187
163
|
# raise an exception
|
188
|
-
|
164
|
+
raise ActionController::InvalidAuthenticityToken
|
189
165
|
# or destroy session, redirect
|
190
|
-
|
191
|
-
current_user_session.destroy
|
192
|
-
end
|
166
|
+
current_user_session&.destroy
|
193
167
|
redirect_to main_app.root_url
|
194
168
|
end
|
195
169
|
|
data/lib/symphonia/engine.rb
CHANGED
@@ -16,9 +16,6 @@ require 'jquery-rails'
|
|
16
16
|
require 'jquery-ui-rails'
|
17
17
|
require 'rdiscount'
|
18
18
|
require 'sortable-table'
|
19
|
-
# require 'paperclip'
|
20
|
-
require 'awesome_nested_set'
|
21
|
-
# require 'acts_as_list'
|
22
19
|
require 'bootstrap_form'
|
23
20
|
require 'bootstrap-datepicker-rails'
|
24
21
|
# require 'wicked_pdf'
|
@@ -106,7 +106,7 @@ module Symphonia
|
|
106
106
|
|
107
107
|
# TODO: @klass.name || @klass.base_class.name || entity.class.name
|
108
108
|
def format_value(view, value, _entity)
|
109
|
-
view.t("#{@klass.name.underscore}.#{name.to_s.pluralize}.#{value}", format_options)
|
109
|
+
view.t("#{@klass.name.underscore}.#{name.to_s.pluralize}.#{value}", **format_options)
|
110
110
|
end
|
111
111
|
|
112
112
|
def input_field
|
@@ -179,7 +179,7 @@ module Symphonia
|
|
179
179
|
class DateAttribute < Attribute
|
180
180
|
|
181
181
|
def format_value(view, value, _entity)
|
182
|
-
value && view.l(value.to_date, format_options)
|
182
|
+
value && view.l(value.to_date, **format_options)
|
183
183
|
end
|
184
184
|
|
185
185
|
end
|
@@ -187,7 +187,7 @@ module Symphonia
|
|
187
187
|
class DateTimeAttribute < Attribute
|
188
188
|
|
189
189
|
def format_value(view, value, _entity)
|
190
|
-
value && view.l(value.localtime, format_options)
|
190
|
+
value && view.l(value.localtime, **format_options)
|
191
191
|
end
|
192
192
|
|
193
193
|
end
|
data/lib/symphonia/version.rb
CHANGED
@@ -6,8 +6,8 @@ RSpec.describe Symphonia::AccountsController do
|
|
6
6
|
|
7
7
|
let(:regular_user) { FactoryBot.create(:user) }
|
8
8
|
|
9
|
-
context 'logged', logged: true do
|
10
|
-
|
9
|
+
context 'with logged', logged: true do
|
10
|
+
describe '#update' do
|
11
11
|
|
12
12
|
it 'valid' do
|
13
13
|
put :update, params: { user: { login: Faker::Internet.user_name } }
|
@@ -22,53 +22,52 @@ RSpec.describe Symphonia::AccountsController do
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
|
25
|
+
describe '#resend_activation' do
|
26
26
|
|
27
27
|
let(:email) { Faker::Internet.email }
|
28
28
|
subject { get :resend_activation, params: { email: email } }
|
29
29
|
|
30
30
|
it 'non exist user' do
|
31
|
-
is_expected.to redirect_to :
|
31
|
+
is_expected.to redirect_to :login
|
32
32
|
expect(flash[:error]).not_to be :blank
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'active user' do
|
36
36
|
_user = FactoryBot.create(:user, email: email, status: 'active')
|
37
|
-
is_expected.to redirect_to :
|
37
|
+
is_expected.to redirect_to :login
|
38
38
|
expect(flash[:error]).not_to be :blank
|
39
39
|
end
|
40
40
|
|
41
|
+
let(:pending_user) { FactoryBot.create(:user, email: email, status: 'pending') }
|
41
42
|
it 'pending user' do
|
42
|
-
|
43
|
-
token = user.perishable_token.dup
|
43
|
+
token = pending_user.perishable_token.dup
|
44
44
|
|
45
45
|
expect { get :resend_activation, params: { email: email } }.to have_enqueued_job.on_queue('mailers')
|
46
|
-
expect(response).to have_http_status :redirect
|
47
46
|
|
48
|
-
expect
|
47
|
+
expect { pending_user.reload }.to change(pending_user, :perishable_token)
|
49
48
|
expect(flash[:error]).to be_nil
|
50
49
|
expect(flash[:notice]).not_to be :blank
|
51
50
|
end
|
52
51
|
end
|
53
52
|
|
54
|
-
|
55
|
-
let(:token) { SecureRandom.hex(3) }
|
53
|
+
describe '#activation' do
|
56
54
|
subject { get :activation, params: { activation_code: token } }
|
55
|
+
let(:token) { SecureRandom.hex(3) }
|
56
|
+
let(:pending_user) { FactoryBot.create(:user, status: 'pending') }
|
57
57
|
|
58
58
|
it 'valid token' do
|
59
|
-
|
60
|
-
user.update_columns(perishable_token: token)
|
59
|
+
pending_user.update_columns(perishable_token: token)
|
61
60
|
is_expected.to redirect_to :login
|
62
|
-
expect
|
61
|
+
expect { pending_user.reload }.to change(pending_user, :status).to "active"
|
63
62
|
end
|
64
63
|
|
65
64
|
it 'invalid token' do
|
66
|
-
is_expected.to redirect_to :
|
65
|
+
is_expected.to redirect_to :login
|
67
66
|
expect(flash[:error]).not_to be :blank
|
68
67
|
end
|
69
68
|
end
|
70
69
|
|
71
|
-
|
70
|
+
describe '#lost_password' do
|
72
71
|
|
73
72
|
it 'with mail' do
|
74
73
|
user = FactoryBot.create(:user, status: 'active')
|
@@ -84,8 +83,9 @@ RSpec.describe Symphonia::AccountsController do
|
|
84
83
|
end
|
85
84
|
end
|
86
85
|
|
87
|
-
|
86
|
+
describe "#reset_password" do
|
88
87
|
subject { FactoryBot.create :user }
|
88
|
+
|
89
89
|
it "reset" do
|
90
90
|
put :reset_password, params: { id: subject.perishable_token, password: "secret-pass-1" }
|
91
91
|
expect(response).to redirect_to /login/
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: symphonia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lukas Pokorny
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-04-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: api-pagination
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 6.4.0
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: awesome_nested_set
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 3.2.1
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 3.2.1
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: bootstrap
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -226,28 +212,28 @@ dependencies:
|
|
226
212
|
requirements:
|
227
213
|
- - "~>"
|
228
214
|
- !ruby/object:Gem::Version
|
229
|
-
version: 6.
|
215
|
+
version: 6.4.1
|
230
216
|
type: :runtime
|
231
217
|
prerelease: false
|
232
218
|
version_requirements: !ruby/object:Gem::Requirement
|
233
219
|
requirements:
|
234
220
|
- - "~>"
|
235
221
|
- !ruby/object:Gem::Version
|
236
|
-
version: 6.
|
222
|
+
version: 6.4.1
|
237
223
|
- !ruby/object:Gem::Dependency
|
238
224
|
name: sidekiq-cron
|
239
225
|
requirement: !ruby/object:Gem::Requirement
|
240
226
|
requirements:
|
241
227
|
- - "~>"
|
242
228
|
- !ruby/object:Gem::Version
|
243
|
-
version: '1.
|
229
|
+
version: '1.3'
|
244
230
|
type: :runtime
|
245
231
|
prerelease: false
|
246
232
|
version_requirements: !ruby/object:Gem::Requirement
|
247
233
|
requirements:
|
248
234
|
- - "~>"
|
249
235
|
- !ruby/object:Gem::Version
|
250
|
-
version: '1.
|
236
|
+
version: '1.3'
|
251
237
|
- !ruby/object:Gem::Dependency
|
252
238
|
name: sortable-table
|
253
239
|
requirement: !ruby/object:Gem::Requirement
|
@@ -498,7 +484,7 @@ require_paths:
|
|
498
484
|
- lib
|
499
485
|
required_ruby_version: !ruby/object:Gem::Requirement
|
500
486
|
requirements:
|
501
|
-
- - "
|
487
|
+
- - ">="
|
502
488
|
- !ruby/object:Gem::Version
|
503
489
|
version: '2.5'
|
504
490
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
@@ -507,7 +493,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
507
493
|
- !ruby/object:Gem::Version
|
508
494
|
version: '0'
|
509
495
|
requirements: []
|
510
|
-
rubygems_version: 3.
|
496
|
+
rubygems_version: 3.3.9
|
511
497
|
signing_key:
|
512
498
|
specification_version: 4
|
513
499
|
summary: My administration
|