crystal-gauntlet/src/template_endpoints/account_settings.cr

98 lines
3.6 KiB
Crystal

require "uri"
include CrystalGauntlet
CrystalGauntlet.template_endpoints[{
name: "account_settings",
path: "/accounts/settings",
methods: ["get", "post"]
}] = ->(context : HTTP::Server::Context, params : Hash(String, String?)) {
context.response.content_type = "text/html"
account_id = nil
user_id = nil
username = nil
Templates.auth()
stars, demons, coins, user_coins, diamonds, creator_points, icon_type, color1, color2, cube, ship, ball, ufo, wave, robot, spider, glow = DATABASE.query_one("select stars, demons, coins, user_coins, diamonds, creator_points, icon_type, color1, color2, cube, ship, ball, ufo, wave, robot, spider, glow from users where id = ?", user_id, as: {Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32})
icon_value = [cube, ship, ball, ufo, wave, robot, spider][icon_type]
type_str = ["cube", "ship", "ball", "ufo", "wave", "robot", "spider"][icon_type]
unread_notifications = DATABASE.scalar("select count(*) from notifications where account_id = ? and read_at is null", account_id).as(Int64) > 0
email = DATABASE.query_one("select email from accounts where id = ?", account_id, as: {String})
result = nil
params = context.request.body.try { |b| URI::Params.parse(b.gets_to_end) }
if params
begin
if params["username"]? && params["username"] != username
# todo: dedup this and the gd register endpoint
username = Clean.clean_basic(params["username"].strip)
if username.size < 3
raise "Username must at least be 3 characters long"
end
if username.size > 16
raise "Username must at most be 16 characters long"
end
if DATABASE.scalar("select count(*) from accounts where username = ?", username).as(Int64) > 0
raise "Username already taken"
end
DATABASE.exec("update accounts set username = ? where id = ?", username, account_id)
DATABASE.exec("update users set username = ? where id = ?", username, user_id)
# refresh session
CrystalGauntlet.sessions.set(context, UserSession.new(username, account_id.not_nil!, user_id.not_nil!))
result = "Changed username successfully"
end
if params["email"]?
email = params["email"].strip
if email.size > 254
raise "Invalid email (too long)"
end
DATABASE.exec("update accounts set email = ? where id = ?", email, account_id)
end
if params["old_password"]? && params["new_password"]? && params["repeat_new_password"]?
if params["repeat_new_password"] != params["new_password"]
raise "New password and repeated password do not match"
end
new_password = params["new_password"].strip
# todo: dedup this and gd register endpoint
if new_password.size < 6
raise "New password must be at least 6 characters long"
end
old_hash = DATABASE.query_one("select password from accounts where username = ?", username, as: {String})
bcrypt = Crypto::Bcrypt::Password.new(old_hash)
if !bcrypt.verify(params["old_password"])
raise "Invalid old password"
end
password_hash = Crypto::Bcrypt::Password.create(new_password, cost: 10).to_s
gjp2 = CrystalGauntlet::GJP.hash(new_password)
DATABASE.exec("update accounts set password = ?, gjp2 = ? where id = ?", password_hash, gjp2, account_id)
result = "Changed password successfully"
end
rescue error
LOG.error {"whar.... #{error}"}
end
end
ECR.embed("./public/template/account_settings.ecr", context.response)
}