--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/web/usercookie.lua Tue Mar 09 12:16:56 2021 +0000 @@ -0,0 +1,45 @@ +local hmac_sha256 = require"util.hashes".hmac_sha256; +local base64_encode = require"util.encodings".base64.encode; +local base64_decode = require"util.encodings".base64.decode; +local datetime = require"util.datetime"; +local t_insert = table.insert; + +local function generate(user, expires, key) + local data = ("%s %s"):format(datetime.date(expires), user); + local signature = hmac_sha256(key, data); + return base64_encode(data .. signature); +end + +local function verify(cookie, key) + if not cookie then + return nil, "no value"; + end + cookie = base64_decode(cookie); + if not cookie then + return nil, "invalid armor"; + end + local data = cookie:sub(1, -33) + if cookie:sub(-32) ~= hmac_sha256(key, data) then + return nil, "invalid signature"; + end + if data < datetime.date() then + return nil, "expired"; + end + return data:sub(12); -- Strip date +end + +local function cookiedecode(s) + local r = {}; + if not s then return r; end + for k, v in s:gmatch("([%w!#$%%&'*+%-.^_`|~]+)=\"?([%w!#-+--/:<-@%]-`_]+)\"?") do + r[k] = v; + t_insert(r, { name = k, value = v }); + end + return r; +end + +return { + decode = cookiedecode; + generate = generate; + verify = verify; +};