smr/src/lua/endpoints/login_post.lua

65 lines
1.8 KiB
Lua

local sql = require("lsqlite3")
local db = require("db")
local util = require("util")
local session = require("session")
local config = require("config")
local pages = require("pages")
local stmnt_author_acct
local oldconfigure = configure
function configure(...)
--Get the data we need to check if someone can log in
stmnt_author_acct = assert(db.conn:prepare([[
SELECT id, salt, passhash FROM authors WHERE name = :name;
]]))
return oldconfigure(...)
end
local function login_post(req)
--Try to log in
http_populate_multipart_form(req)
local name = assert(http_argument_get_string(req,"user"))
local pass = assert(http_file_get(req,"pass"))
stmnt_author_acct:bind_names{
name = name
}
local text
local err = util.do_sql(stmnt_author_acct)
if err == sql.ROW then
local id, salt, passhash = unpack(stmnt_author_acct:get_values())
stmnt_author_acct:reset()
local todigest = salt .. pass
local hash = sha3(todigest)
if hash == passhash then
local mysession = session.start(id)
local domain_no_port = config.domain:match("(.*):.*") or config.domain
http_response_header(req,"set-cookie",string.format(
[[session=%s; SameSite=Lax; Path=/; Domain=%s; HttpOnly; Secure]],mysession,domain_no_port
))
local loc = string.format("https://%s.%s",name,config.domain)
http_response_header(req,"Location",loc)
http_response(req,303,"")
return
else
text = pages.login{
err = "Incorrect username or password"
}
end
elseif err == sql.DONE then --Allows user enumeration, do we want this?
--Probably not a problem since all passwords are forced to be "good"
stmnt_author_acct:reset()
text = pages.login{
err = "Failed to find user:" .. name
}
else
stmnt_author_acct:reset()
error("Other sql error during login")
end
http_response(req,200,text)
end
return login_post