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 api = require("hooks") 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 old_authenticate = api.authenticate function api.authenticate(data) stmnt_author_acct:bind_names{name=data.user} local err = db.do_sql(stmnt_author_acct) if err ~= sql.ROW then stmnt_author_acct:reset() log(LOG_NOTICE,string.format("User %q failed to log in",data.user)) end local id, salt, passhash = unpack(stmnt_author_acct:get_values()) stmnt_author_acct:reset() local hash = sha3(salt .. data.pass) if hash == passhash then return id end 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")) local uid, err = api.authenticate({user=name,pass=pass}) if not uid then http_response(req,200,pages.login{err=err}) return end local user_session = session.start(uid) local domain_no_port = config.domain:match("(.*):.*") or config.domain local cookie_string = string.format( [[session=%s; SameSite=Lax; Path=/; Domain=%s; HttpOnly; Secure]], user_session, domain_no_port ) http_response_header(req,"set-cookie",cookie_string) local loc = string.format("https://%s.%s",name,config.domain) http_response_header(req,"Location",loc) http_response(req,303,"") end return login_post