feat(users): add display name field for users
This commit is contained in:
@@ -127,6 +127,12 @@ module Volumen
|
|||||||
change_username
|
change_username
|
||||||
end
|
end
|
||||||
|
|
||||||
|
app.post "/admin/settings/name" do
|
||||||
|
require_login!
|
||||||
|
check_csrf!
|
||||||
|
change_name
|
||||||
|
end
|
||||||
|
|
||||||
app.post "/admin/settings/users" do
|
app.post "/admin/settings/users" do
|
||||||
require_login!
|
require_login!
|
||||||
require_admin!
|
require_admin!
|
||||||
|
|||||||
@@ -201,6 +201,10 @@ module Volumen
|
|||||||
current_user_record&.role
|
current_user_record&.role
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def current_user_name
|
||||||
|
current_user_record&.name
|
||||||
|
end
|
||||||
|
|
||||||
def admin?
|
def admin?
|
||||||
current_role == "admin"
|
current_role == "admin"
|
||||||
end
|
end
|
||||||
@@ -293,6 +297,13 @@ module Volumen
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def change_name
|
||||||
|
name = params["name"].to_s.strip
|
||||||
|
name = nil if name.empty?
|
||||||
|
users.update_name(current_user, name)
|
||||||
|
render_settings(notice: name ? "Display name updated." : "Display name cleared.")
|
||||||
|
end
|
||||||
|
|
||||||
def create_user
|
def create_user
|
||||||
name = presence(params["username"])
|
name = presence(params["username"])
|
||||||
password = presence(params["password"])
|
password = presence(params["password"])
|
||||||
|
|||||||
+15
-5
@@ -15,7 +15,7 @@ module Volumen
|
|||||||
ROLES = %w[admin author].freeze
|
ROLES = %w[admin author].freeze
|
||||||
DEFAULT_ROLE = "author"
|
DEFAULT_ROLE = "author"
|
||||||
|
|
||||||
User = Struct.new(:username, :password_hash, :role)
|
User = Struct.new(:username, :password_hash, :role, :name)
|
||||||
|
|
||||||
def initialize(path:, bootstrap_hash: nil)
|
def initialize(path:, bootstrap_hash: nil)
|
||||||
@path = path
|
@path = path
|
||||||
@@ -33,7 +33,7 @@ module Volumen
|
|||||||
elsif @bootstrap_hash.empty?
|
elsif @bootstrap_hash.empty?
|
||||||
[]
|
[]
|
||||||
else
|
else
|
||||||
[User.new("admin", @bootstrap_hash, "admin")]
|
[User.new("admin", @bootstrap_hash, "admin", nil)]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -54,11 +54,15 @@ module Volumen
|
|||||||
def add(username, password, role = DEFAULT_ROLE)
|
def add(username, password, role = DEFAULT_ROLE)
|
||||||
return nil if username.to_s.empty? || find(username)
|
return nil if username.to_s.empty? || find(username)
|
||||||
|
|
||||||
user = User.new(username, Password.hash(password), normalize_role(role))
|
user = User.new(username, Password.hash(password), normalize_role(role), nil)
|
||||||
persist(all + [user])
|
persist(all + [user])
|
||||||
user
|
user
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_name(username, name)
|
||||||
|
mutate(username) { |user| user.name = name.to_s.empty? ? nil : name.to_s }
|
||||||
|
end
|
||||||
|
|
||||||
def update_password(username, password)
|
def update_password(username, password)
|
||||||
mutate(username) { |user| user.password_hash = Password.hash(password) }
|
mutate(username) { |user| user.password_hash = Password.hash(password) }
|
||||||
end
|
end
|
||||||
@@ -121,7 +125,7 @@ module Volumen
|
|||||||
def read_file
|
def read_file
|
||||||
data = TomlRB.load_file(@path)
|
data = TomlRB.load_file(@path)
|
||||||
Array(data["users"]).map do |entry|
|
Array(data["users"]).map do |entry|
|
||||||
User.new(entry["username"], entry["password_hash"], entry["role"] || "admin")
|
User.new(entry["username"], entry["password_hash"], entry["role"] || "admin", entry["name"])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -133,7 +137,13 @@ module Volumen
|
|||||||
end
|
end
|
||||||
|
|
||||||
def user_hash(user)
|
def user_hash(user)
|
||||||
{ "username" => user.username, "password_hash" => user.password_hash, "role" => user.role }
|
hash = {
|
||||||
|
"username" => user.username,
|
||||||
|
"password_hash" => user.password_hash,
|
||||||
|
"role" => user.role
|
||||||
|
}
|
||||||
|
hash["name"] = user.name if user.name
|
||||||
|
hash
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
<div class="field-row">
|
<div class="field-row">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="author">Author</label>
|
<label for="author">Author</label>
|
||||||
<input id="author" class="input" type="text" name="author" value="<%= h(@post.author) %>" placeholder="Petr Balvín">
|
<input id="author" class="input" type="text" name="author" value="<%= h(@post.author.to_s.empty? ? current_user_name : @post.author) %>" placeholder="<%= h(current_user_name || 'Petr Balvín') %>">
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="fediverse_creator">Fediverse creator</label>
|
<label for="fediverse_creator">Fediverse creator</label>
|
||||||
|
|||||||
@@ -515,9 +515,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="sidebar-foot">
|
<div class="sidebar-foot">
|
||||||
<div class="avatar"><%= h(current_user.to_s[0].upcase) %></div>
|
<div class="avatar"><%= h((current_user_name || current_user).to_s[0].upcase) %></div>
|
||||||
<div class="user-info">
|
<div class="user-info">
|
||||||
<div class="name"><%= h(current_user) %></div>
|
<div class="name"><%= h(current_user_name || current_user) %></div>
|
||||||
<div class="role"><%= h(current_role) %></div>
|
<div class="role"><%= h(current_role) %></div>
|
||||||
</div>
|
</div>
|
||||||
<form method="post" action="<%= to("/admin/logout") %>" style="margin: 0;">
|
<form method="post" action="<%= to("/admin/logout") %>" style="margin: 0;">
|
||||||
|
|||||||
@@ -44,6 +44,19 @@
|
|||||||
|
|
||||||
<div style="border-top: 1px solid var(--border); margin: 1.5rem 0;"></div>
|
<div style="border-top: 1px solid var(--border); margin: 1.5rem 0;"></div>
|
||||||
|
|
||||||
|
<form method="post" action="<%= to("/admin/settings/name") %>">
|
||||||
|
<input type="hidden" name="_csrf" value="<%= csrf_token %>">
|
||||||
|
<h3 style="margin: 0 0 0.75rem;">Display name</h3>
|
||||||
|
<div class="field">
|
||||||
|
<label for="name">Real name</label>
|
||||||
|
<input id="name" class="input" type="text" name="name" value="<%= h(current_user_record&.name) %>" placeholder="Your real name" style="max-width: 360px;">
|
||||||
|
<p class="help">Used to pre-fill the author field for new posts. Leave empty to use your username.</p>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn">Save name</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div style="border-top: 1px solid var(--border); margin: 1.5rem 0;"></div>
|
||||||
|
|
||||||
<form method="post" action="<%= to("/admin/settings/username") %>">
|
<form method="post" action="<%= to("/admin/settings/username") %>">
|
||||||
<input type="hidden" name="_csrf" value="<%= csrf_token %>">
|
<input type="hidden" name="_csrf" value="<%= csrf_token %>">
|
||||||
<h3 style="margin: 0 0 0.75rem;">Change username</h3>
|
<h3 style="margin: 0 0 0.75rem;">Change username</h3>
|
||||||
|
|||||||
Reference in New Issue
Block a user