plutonium 0.19.11 → 0.19.13
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/app/assets/plutonium.css +1 -1
- data/app/assets/plutonium.js +21 -0
- data/app/assets/plutonium.js.map +3 -3
- data/app/assets/plutonium.min.js +30 -30
- data/app/assets/plutonium.min.js.map +4 -4
- data/app/views/rodauth/_login_form.html.erb +69 -17
- data/app/views/rodauth/_password_visibility.html.erb +19 -0
- data/app/views/rodauth/create_account.html.erb +133 -34
- data/lib/generators/pu/rodauth/admin_generator.rb +88 -0
- data/lib/generators/pu/rodauth/concerns/configuration.rb +1 -0
- data/lib/generators/pu/rodauth/install_generator.rb +2 -0
- data/lib/generators/pu/rodauth/templates/app/views/_login_form_footer.html.erb.tt +8 -0
- data/lib/generators/pu/rodauth/templates/lib/tasks/rodauth_admin.rake.tt +11 -0
- data/lib/plutonium/railtie.rb +3 -3
- data/lib/plutonium/ui/layout/header.rb +4 -4
- data/lib/plutonium/ui/layout/sidebar.rb +2 -1
- data/lib/plutonium/version.rb +1 -1
- data/lib/tasks/.keep +0 -0
- data/package-lock.json +2 -2
- data/package.json +1 -1
- data/src/js/controllers/password_visibility_controller.js +17 -0
- data/src/js/controllers/register_controllers.js +4 -0
- data/src/js/controllers/sidebar_controller.js +3 -0
- metadata +9 -3
- data/lib/tasks/create_rodauth_admin.rake +0 -16
@@ -1,30 +1,82 @@
|
|
1
|
-
<h1
|
1
|
+
<h1
|
2
|
+
class="
|
3
|
+
text-lg font-bold leading-tight tracking-tight text-gray-900 md:text-xl
|
4
|
+
dark:text-white
|
5
|
+
"
|
6
|
+
>
|
2
7
|
Sign in to your account
|
3
8
|
</h1>
|
4
|
-
<%= form_with url: rodauth.login_path, method: :post, data: { turbo: false }, class: "space-y-4" do |form| %>
|
9
|
+
<%= form_with url: rodauth.login_path, method: :post, data: { turbo: false, controller: "password-visibility" }, class: "space-y-4" do |form| %>
|
5
10
|
<div>
|
6
|
-
<%= form.label "login",
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
<%= form.label "login",
|
12
|
+
rodauth.login_label,
|
13
|
+
class:
|
14
|
+
"block mb-2 text-sm font-semibold text-gray-900 dark:text-white" %>
|
15
|
+
<%= form.email_field rodauth.login_param,
|
16
|
+
value: params[rodauth.login_param],
|
17
|
+
id: "login",
|
18
|
+
autocomplete: rodauth.login_field_autocomplete_value,
|
19
|
+
required: true,
|
20
|
+
placeholder: "jane@acme.inc",
|
21
|
+
class:
|
22
|
+
"bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 #{rodauth.field_error(rodauth.login_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400"}",
|
23
|
+
aria:
|
24
|
+
(
|
25
|
+
if rodauth.field_error(rodauth.login_param)
|
26
|
+
{ invalid: true, describedby: "login_error_message" }
|
27
|
+
end
|
28
|
+
) %>
|
12
29
|
<% unless rodauth.skip_login_field_on_login? %>
|
13
|
-
|
30
|
+
<%= if rodauth.field_error(rodauth.login_param)
|
31
|
+
content_tag(
|
32
|
+
:span,
|
33
|
+
rodauth.field_error(rodauth.login_param),
|
34
|
+
class: "block mt-1 text-red-600 text-sm dark:text-red-400",
|
35
|
+
id: "login_error_message",
|
36
|
+
)
|
37
|
+
end %>
|
14
38
|
<% end %>
|
15
39
|
</div>
|
16
40
|
|
17
41
|
<% unless rodauth.skip_password_field_on_login? %>
|
18
42
|
<div>
|
19
|
-
<%= form.label "password",
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
43
|
+
<%= form.label "password",
|
44
|
+
rodauth.password_label,
|
45
|
+
class:
|
46
|
+
"block mb-2 text-sm font-semibold text-gray-900 dark:text-white" %>
|
47
|
+
<%= form.password_field rodauth.password_param,
|
48
|
+
data: {
|
49
|
+
password_visibility_target: "password",
|
50
|
+
},
|
51
|
+
value: "",
|
52
|
+
id: "password",
|
53
|
+
autocomplete: rodauth.password_field_autocomplete_value,
|
54
|
+
required: true,
|
55
|
+
class:
|
56
|
+
"bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 #{rodauth.field_error(rodauth.password_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400"}",
|
57
|
+
aria:
|
58
|
+
(
|
59
|
+
if rodauth.field_error(rodauth.password_param)
|
60
|
+
{
|
61
|
+
invalid: true,
|
62
|
+
describedby: "password_error_message",
|
63
|
+
}
|
64
|
+
end
|
65
|
+
) %>
|
66
|
+
<%= if rodauth.field_error(rodauth.password_param)
|
67
|
+
content_tag(
|
68
|
+
:span,
|
69
|
+
rodauth.field_error(rodauth.password_param),
|
70
|
+
class: "block mt-1 text-red-600 text-sm dark:text-red-400",
|
71
|
+
id: "password_error_message",
|
72
|
+
)
|
73
|
+
end %>
|
26
74
|
</div>
|
27
75
|
<% end %>
|
28
76
|
|
29
|
-
<%=
|
77
|
+
<%= render "password_visibility" %>
|
78
|
+
|
79
|
+
<%= form.submit rodauth.login_button,
|
80
|
+
class:
|
81
|
+
"w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-semibold rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800" %>
|
30
82
|
<% end %>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<div class="flex space-x-2 items-center">
|
2
|
+
<input
|
3
|
+
type="checkbox"
|
4
|
+
name="reveal-password"
|
5
|
+
id="reveal-password"
|
6
|
+
class="
|
7
|
+
text-primary-500 rounded transition-colors duration-200 checked:bg-primary-500
|
8
|
+
hover:bg-primary-200 focus:ring-primary-500
|
9
|
+
"
|
10
|
+
data-password-visibility-target="checkbox"
|
11
|
+
data-action="password-visibility#toggle"
|
12
|
+
>
|
13
|
+
<label
|
14
|
+
for="reveal-password"
|
15
|
+
class="block text-sm font-semibold text-gray-900 dark:text-white"
|
16
|
+
>
|
17
|
+
Show Password
|
18
|
+
</label>
|
19
|
+
</div>
|
@@ -1,59 +1,158 @@
|
|
1
|
-
<h1
|
1
|
+
<h1
|
2
|
+
class="
|
3
|
+
text-lg font-bold leading-tight tracking-tight text-gray-900 md:text-xl
|
4
|
+
dark:text-white
|
5
|
+
"
|
6
|
+
>
|
2
7
|
Create an account
|
3
8
|
</h1>
|
4
|
-
<%= form_with url: rodauth.create_account_path, method: :post, data: { turbo: false }, class: "space-y-4" do |form| %>
|
9
|
+
<%= form_with url: rodauth.create_account_path, method: :post, data: { turbo: false, controller: "password-visibility" }, class: "space-y-4" do |form| %>
|
5
10
|
<div>
|
6
|
-
<%= form.label "login",
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
<%= form.label "login",
|
12
|
+
rodauth.login_label,
|
13
|
+
class:
|
14
|
+
"block mb-2 text-sm font-semibold text-gray-900 dark:text-white" %>
|
15
|
+
<%= form.email_field rodauth.login_param,
|
16
|
+
value: params[rodauth.login_param],
|
17
|
+
id: "login",
|
18
|
+
autocomplete: "email",
|
19
|
+
required: true,
|
20
|
+
placeholder: "jane@acme.inc",
|
21
|
+
class:
|
22
|
+
"bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 #{rodauth.field_error(rodauth.login_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400"}",
|
23
|
+
aria:
|
24
|
+
(
|
25
|
+
if rodauth.field_error(rodauth.login_param)
|
26
|
+
{ invalid: true, describedby: "login_error_message" }
|
27
|
+
end
|
28
|
+
) %>
|
29
|
+
<%= if rodauth.field_error(rodauth.login_param)
|
30
|
+
content_tag(
|
31
|
+
:span,
|
32
|
+
rodauth.field_error(rodauth.login_param),
|
33
|
+
class: "block mt-1 text-red-600 text-sm dark:text-red-400",
|
34
|
+
id: "login_error_message",
|
35
|
+
)
|
36
|
+
end %>
|
14
37
|
</div>
|
15
38
|
|
16
39
|
<% if rodauth.require_login_confirmation? %>
|
17
40
|
<div>
|
18
|
-
<%= form.label "login-confirm",
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
41
|
+
<%= form.label "login-confirm",
|
42
|
+
rodauth.login_confirm_label,
|
43
|
+
class:
|
44
|
+
"block mb-2 text-sm font-semibold text-gray-900 dark:text-white" %>
|
45
|
+
<%= form.email_field rodauth.login_confirm_param,
|
46
|
+
value: params[rodauth.login_confirm_param],
|
47
|
+
id: "login-confirm",
|
48
|
+
autocomplete: "email",
|
49
|
+
required: true,
|
50
|
+
placeholder: "jane@acme.inc",
|
51
|
+
class:
|
52
|
+
"bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 #{rodauth.field_error(rodauth.login_confirm_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400"}",
|
53
|
+
aria:
|
54
|
+
(
|
55
|
+
if rodauth.field_error(rodauth.login_confirm_param)
|
56
|
+
{
|
57
|
+
invalid: true,
|
58
|
+
describedby: "login-confirm_error_message",
|
59
|
+
}
|
60
|
+
end
|
61
|
+
) %>
|
62
|
+
<%= if rodauth.field_error(rodauth.login_confirm_param)
|
63
|
+
content_tag(
|
64
|
+
:span,
|
65
|
+
rodauth.field_error(rodauth.login_confirm_param),
|
66
|
+
class: "block mt-1 text-red-600 text-sm dark:text-red-400",
|
67
|
+
id: "login-confirm_error_message",
|
68
|
+
)
|
69
|
+
end %>
|
26
70
|
</div>
|
27
71
|
<% end %>
|
28
72
|
|
29
73
|
<% if rodauth.create_account_set_password? %>
|
30
74
|
<div>
|
31
|
-
<%= form.label "password",
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
75
|
+
<%= form.label "password",
|
76
|
+
rodauth.password_label,
|
77
|
+
class:
|
78
|
+
"block mb-2 text-sm font-semibold text-gray-900 dark:text-white" %>
|
79
|
+
<%= form.password_field rodauth.password_param,
|
80
|
+
data: {
|
81
|
+
password_visibility_target: "password",
|
82
|
+
},
|
83
|
+
value: "",
|
84
|
+
id: "password",
|
85
|
+
autocomplete: rodauth.password_field_autocomplete_value,
|
86
|
+
required: true,
|
87
|
+
class:
|
88
|
+
"bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 #{rodauth.field_error(rodauth.password_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400"}",
|
89
|
+
aria:
|
90
|
+
(
|
91
|
+
if rodauth.field_error(rodauth.password_param)
|
92
|
+
{
|
93
|
+
invalid: true,
|
94
|
+
describedby: "password_error_message",
|
95
|
+
}
|
96
|
+
end
|
97
|
+
) %>
|
98
|
+
<%= if rodauth.field_error(rodauth.password_param)
|
99
|
+
content_tag(
|
100
|
+
:span,
|
101
|
+
rodauth.field_error(rodauth.password_param),
|
102
|
+
class: "block mt-1 text-red-600 text-sm dark:text-red-400",
|
103
|
+
id: "password_error_message",
|
104
|
+
)
|
105
|
+
end %>
|
38
106
|
</div>
|
39
107
|
|
40
108
|
<% if rodauth.require_password_confirmation? %>
|
41
109
|
<div>
|
42
|
-
<%= form.label "password-confirm",
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
110
|
+
<%= form.label "password-confirm",
|
111
|
+
rodauth.password_confirm_label,
|
112
|
+
class:
|
113
|
+
"block mb-2 text-sm font-semibold text-gray-900 dark:text-white" %>
|
114
|
+
<%= form.password_field rodauth.password_confirm_param,
|
115
|
+
data: {
|
116
|
+
password_visibility_target: "password",
|
117
|
+
},
|
118
|
+
value: "",
|
119
|
+
id: "password-confirm",
|
120
|
+
autocomplete: "new-password",
|
121
|
+
required: true,
|
122
|
+
class:
|
123
|
+
"bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500 #{rodauth.field_error(rodauth.password_confirm_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400"}",
|
124
|
+
aria:
|
125
|
+
(
|
126
|
+
if rodauth.field_error(rodauth.password_confirm_param)
|
127
|
+
{
|
128
|
+
invalid: true,
|
129
|
+
describedby: "password-confirm_error_message",
|
130
|
+
}
|
131
|
+
end
|
132
|
+
) %>
|
133
|
+
<%= if rodauth.field_error(rodauth.password_confirm_param)
|
134
|
+
content_tag(
|
135
|
+
:span,
|
136
|
+
rodauth.field_error(rodauth.password_confirm_param),
|
137
|
+
class: "block mt-1 text-red-600 text-sm dark:text-red-400",
|
138
|
+
id: "password-confirm_error_message",
|
139
|
+
)
|
140
|
+
end %>
|
49
141
|
</div>
|
50
142
|
<% end %>
|
51
143
|
<% end %>
|
52
144
|
|
53
|
-
<%=
|
145
|
+
<%= render "password_visibility" %>
|
146
|
+
|
147
|
+
<%= form.submit rodauth.create_account_button,
|
148
|
+
class:
|
149
|
+
"w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800" %>
|
54
150
|
<% end %>
|
55
151
|
|
56
152
|
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">
|
57
153
|
Already have an account?
|
58
|
-
<%= link_to "Login",
|
154
|
+
<%= link_to "Login",
|
155
|
+
rodauth.login_path,
|
156
|
+
class:
|
157
|
+
"text-primary-600 rounded-sm text-sm hover:underline hover:text-primary-800 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-600 dark:text-primary-300 dark:hover:text-primary-400 dark:focus-visible:ring-2 dark:focus-visible:ring-primary-300" %>
|
59
158
|
</p>
|
@@ -0,0 +1,88 @@
|
|
1
|
+
return unless defined?(Rodauth::Rails)
|
2
|
+
|
3
|
+
require "rails/generators/base"
|
4
|
+
|
5
|
+
require_relative "../lib/plutonium_generators"
|
6
|
+
|
7
|
+
module Pu
|
8
|
+
module Rodauth
|
9
|
+
class AdminGenerator < ::Rails::Generators::Base
|
10
|
+
include PlutoniumGenerators::Concerns::Logger
|
11
|
+
|
12
|
+
source_root "#{__dir__}/templates"
|
13
|
+
|
14
|
+
desc "Generate a rodauth-rails account optimized for performing admin tasks"
|
15
|
+
|
16
|
+
argument :name
|
17
|
+
|
18
|
+
def start
|
19
|
+
generate_admin_account
|
20
|
+
configure_admin_account
|
21
|
+
rescue => e
|
22
|
+
exception "#{self.class} failed:", e
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def generate_admin_account
|
28
|
+
invoke "pu:rodauth:account", [name],
|
29
|
+
defaults: false,
|
30
|
+
**admin_features,
|
31
|
+
force: options[:force],
|
32
|
+
skip: options[:skip]
|
33
|
+
end
|
34
|
+
|
35
|
+
def configure_admin_account
|
36
|
+
# Prevent account creation from web
|
37
|
+
insert_into_file "app/rodauth/#{normalized_name}_rodauth_plugin.rb", indent(<<~EOT, 4), after: /# ==> Hooks\n/
|
38
|
+
|
39
|
+
# Prevent using the web to sign up.
|
40
|
+
before_create_account_route do
|
41
|
+
request.halt unless internal_request?
|
42
|
+
end
|
43
|
+
|
44
|
+
EOT
|
45
|
+
|
46
|
+
# Customize login flow
|
47
|
+
insert_into_file "app/rodauth/#{normalized_name}_rodauth_plugin.rb", indent(<<~EOT, 4), before: /\n.*# ==> Emails/
|
48
|
+
|
49
|
+
# Only ask for password after asking for the login
|
50
|
+
use_multi_phase_login? true
|
51
|
+
EOT
|
52
|
+
|
53
|
+
# Configure MFA return
|
54
|
+
gsub_file(
|
55
|
+
"app/rodauth/#{normalized_name}_rodauth_plugin.rb",
|
56
|
+
/.*two_factor_auth_return_to_requested_location?.*/,
|
57
|
+
indent("two_factor_auth_return_to_requested_location? true", 4),
|
58
|
+
verbose: false
|
59
|
+
)
|
60
|
+
|
61
|
+
# Configure MFA flash message
|
62
|
+
insert_into_file "app/rodauth/#{normalized_name}_rodauth_plugin.rb", indent(<<~EOT, 4), after: /# Override default flash messages.*\n/
|
63
|
+
two_factor_not_setup_error_flash "You need to setup two factor authentication"
|
64
|
+
EOT
|
65
|
+
|
66
|
+
template "app/views/_login_form_footer.html.erb.tt", "app/views/rodauth/#{normalized_name}/_login_form_footer.html.erb"
|
67
|
+
|
68
|
+
template "lib/tasks/rodauth_admin.rake", "lib/tasks/rodauth_#{normalized_name}.rake"
|
69
|
+
end
|
70
|
+
|
71
|
+
def admin_features
|
72
|
+
[
|
73
|
+
:login, :remember, :logout,
|
74
|
+
:create_account, :verify_account, :close_account,
|
75
|
+
:reset_password, :reset_password_notify, :change_password,
|
76
|
+
:otp, :recovery_codes,
|
77
|
+
:lockout, :active_sessions, :audit_logging,
|
78
|
+
:password_grace_period,
|
79
|
+
:internal_request
|
80
|
+
].map { |feature| [feature, true] }.to_h
|
81
|
+
end
|
82
|
+
|
83
|
+
def display_name = name.humanize.downcase
|
84
|
+
|
85
|
+
def normalized_name = name.underscore
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -41,6 +41,8 @@ module Pu
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def add_dev_config
|
44
|
+
return if Rails.version.to_f >= 8.0
|
45
|
+
|
44
46
|
insert_into_file "config/environments/development.rb",
|
45
47
|
"\n config.action_mailer.default_url_options = { host: '127.0.0.1', port: ENV.fetch('PORT', 3000) }\n",
|
46
48
|
before: /^end/
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<%% unless rodauth(:<%= normalized_name %>).login_form_footer_links.empty? %>
|
2
|
+
<ul>
|
3
|
+
<%% rodauth(:<%= normalized_name %>).login_form_footer_links.sort.each do |_, link, text| %>
|
4
|
+
<%% next if rodauth(:<%= normalized_name %>).try(:create_account_path) == link %>
|
5
|
+
<li><%%= link_to text, link, class: "text-primary-600 rounded-sm text-sm hover:underline hover:text-primary-800 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-600 dark:text-primary-300 dark:hover:text-primary-400 dark:focus-visible:ring-2 dark:focus-visible:ring-primary-300" %></li>
|
6
|
+
<%% end %>
|
7
|
+
</ul>
|
8
|
+
<%% end %>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
namespace :rodauth do
|
2
|
+
desc "Create a <%= display_name %> account"
|
3
|
+
task <%= normalized_name %>: :environment do
|
4
|
+
require "tty-prompt"
|
5
|
+
|
6
|
+
prompt = TTY::Prompt.new
|
7
|
+
email = ENV["EMAIL"] || prompt.ask("Email:", required: true)
|
8
|
+
|
9
|
+
RodauthApp.rodauth(:<%= normalized_name %>).create_account(login: email)
|
10
|
+
end
|
11
|
+
end
|
data/lib/plutonium/railtie.rb
CHANGED
@@ -47,9 +47,9 @@ module Plutonium
|
|
47
47
|
setup_phlexi_themes
|
48
48
|
end
|
49
49
|
|
50
|
-
rake_tasks do
|
51
|
-
|
52
|
-
end
|
50
|
+
# rake_tasks do
|
51
|
+
# load "tasks/create_rodauth_admin.rake"
|
52
|
+
# end
|
53
53
|
|
54
54
|
config.after_initialize do
|
55
55
|
Plutonium::Reloader.start! if Plutonium.configuration.enable_hotreload
|
@@ -44,7 +44,7 @@ module Plutonium
|
|
44
44
|
class: "bg-white border-b border-gray-200 px-4 py-2.5 dark:bg-gray-800 dark:border-gray-700 fixed left-0 right-0 top-0 z-50",
|
45
45
|
data: {
|
46
46
|
controller: "resource-header",
|
47
|
-
|
47
|
+
resource_header_sidebar_outlet: "#sidebar-navigation"
|
48
48
|
}
|
49
49
|
) do
|
50
50
|
div(class: "flex flex-wrap justify-between items-center") do
|
@@ -70,7 +70,7 @@ module Plutonium
|
|
70
70
|
# @private
|
71
71
|
def render_sidebar_toggle
|
72
72
|
button(
|
73
|
-
data_action: "header#toggleDrawer",
|
73
|
+
data_action: "resource-header#toggleDrawer",
|
74
74
|
aria_controls: "#sidebar-navigation",
|
75
75
|
class: %(p-2 mr-2 text-gray-600 rounded-lg cursor-pointer lg:hidden hover:text-gray-900
|
76
76
|
hover:bg-gray-100 focus:bg-gray-100 dark:focus:bg-gray-700 focus:ring-2
|
@@ -97,11 +97,11 @@ module Plutonium
|
|
97
97
|
# Renders the toggle icons for the sidebar button
|
98
98
|
# @private
|
99
99
|
def render_toggle_icons
|
100
|
-
span(
|
100
|
+
span(data_resource_header_target: "openIcon") do
|
101
101
|
render Phlex::TablerIcons::Menu.new(class: "w-6 h-6")
|
102
102
|
end
|
103
103
|
|
104
|
-
span(
|
104
|
+
span(data_resource_header_target: "closeIcon", class: "hidden", aria_hidden: "true") do
|
105
105
|
render Phlex::TablerIcons::X.new(class: "w-6 h-6")
|
106
106
|
end
|
107
107
|
|
@@ -24,6 +24,7 @@ module Plutonium
|
|
24
24
|
# @private
|
25
25
|
def render_sidebar_container(&)
|
26
26
|
aside(
|
27
|
+
data: {controller: "sidebar"},
|
27
28
|
id: "sidebar-navigation",
|
28
29
|
aria: {label: "Sidebar Navigation"},
|
29
30
|
class: "fixed top-0 left-0 z-40 w-64 h-screen pt-14 transition-transform -translate-x-full lg:translate-x-0",
|
@@ -43,7 +44,7 @@ module Plutonium
|
|
43
44
|
|
44
45
|
# @private
|
45
46
|
def render_color_mode_controls
|
46
|
-
div(class: "
|
47
|
+
div(class: "absolute bottom-0 left-0 justify-center p-4 space-x-4 w-full flex bg-white dark:bg-gray-800 z-20 border-r border-gray-200 dark:border-gray-700") do
|
47
48
|
render ColorModeSelector.new
|
48
49
|
end
|
49
50
|
end
|
data/lib/plutonium/version.rb
CHANGED
data/lib/tasks/.keep
ADDED
File without changes
|
data/package-lock.json
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
{
|
2
2
|
"name": "@radioactive-labs/plutonium",
|
3
|
-
"version": "0.3.
|
3
|
+
"version": "0.3.4",
|
4
4
|
"lockfileVersion": 3,
|
5
5
|
"requires": true,
|
6
6
|
"packages": {
|
7
7
|
"": {
|
8
8
|
"name": "@radioactive-labs/plutonium",
|
9
|
-
"version": "0.3.
|
9
|
+
"version": "0.3.4",
|
10
10
|
"license": "MIT",
|
11
11
|
"dependencies": {
|
12
12
|
"@hotwired/stimulus": "^3.2.2",
|
data/package.json
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
|
+
|
3
|
+
export default class extends Controller {
|
4
|
+
static targets = ["password", "checkbox"];
|
5
|
+
|
6
|
+
connect() {
|
7
|
+
this.checkboxTarget.checked = false // ensure password is hidden by default
|
8
|
+
}
|
9
|
+
|
10
|
+
toggle() {
|
11
|
+
if (this.passwordTarget.type == "password") {
|
12
|
+
this.passwordTargets.forEach((passwordTarget) => passwordTarget.type = "text")
|
13
|
+
} else {
|
14
|
+
this.passwordTargets.forEach((passwordTarget) => passwordTarget.type = "password")
|
15
|
+
}
|
16
|
+
}
|
17
|
+
}
|
@@ -16,9 +16,13 @@ import ResourceTabListController from "./resource_tab_list_controller.js"
|
|
16
16
|
import AttachmentInputController from "./attachment_input_controller.js"
|
17
17
|
import AttachmentPreviewController from "./attachment_preview_controller.js"
|
18
18
|
import AttachmentPreviewContainerController from "./attachment_preview_container_controller.js"
|
19
|
+
import SidebarController from "./sidebar_controller.js"
|
20
|
+
import PasswordVisibilityController from "./password_visibility_controller.js"
|
19
21
|
|
20
22
|
export default function (application) {
|
21
23
|
// Register controllers here
|
24
|
+
application.register("password-visibility", PasswordVisibilityController)
|
25
|
+
application.register("sidebar", SidebarController)
|
22
26
|
application.register("resource-header", ResourceHeaderController)
|
23
27
|
application.register("nested-resource-form-fields", NestedResourceFormFieldsController)
|
24
28
|
application.register("form", FormController)
|