src/web/usercookie.lua

changeset 0
6279a7d40ae7
--- /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;
+};

mercurial