src/web/usercookie.lua

Tue, 09 Mar 2021 12:16:56 +0000

author
Matthew Wild <mwild1@gmail.com>
date
Tue, 09 Mar 2021 12:16:56 +0000
changeset 0
6279a7d40ae7
permissions
-rw-r--r--

Initial commit

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