File

util/datetime.lua @ 12953:ebe3b2f96cad

mod_tokenauth: Switch to new token format (invalidates existing tokens!) The new format has the following properties: - 5 bytes longer than the previous format - The token now has separate 'id' and 'secret' parts - the token itself is no longer stored in the DB, and the secret part is hashed - The only variable length field (JID) has been moved to the end - The 'secret-token:' prefix (RFC 8959) is now included Compatibility with the old token format was not maintained, and all previously issued tokens are invalid after this commit (they will be removed from the DB if used).
author Matthew Wild <mwild1@gmail.com>
date Tue, 21 Mar 2023 14:33:29 +0000
parent 12633:5d8b0e0b9d48
line wrap: on
line source

-- Prosody IM
-- Copyright (C) 2008-2010 Matthew Wild
-- Copyright (C) 2008-2010 Waqas Hussain
--
-- This project is MIT/X11 licensed. Please see the
-- COPYING file in the source package for more information.
--


-- XEP-0082: XMPP Date and Time Profiles

local os_date = os.date;
local os_time = os.time;
local os_difftime = os.difftime;
local floor = math.floor;
local tonumber = tonumber;

local _ENV = nil;
-- luacheck: std none

local function date(t)
	return os_date("!%Y-%m-%d", t and floor(t) or nil);
end

local function datetime(t)
	if t == nil or t % 1 == 0 then
		return os_date("!%Y-%m-%dT%H:%M:%SZ", t);
	end
	local m = t % 1;
	local s = floor(t);
	return os_date("!%Y-%m-%dT%H:%M:%S.%%06dZ", s):format(floor(m * 1000000));
end

local function time(t)
	if t == nil or t % 1 == 0 then
		return os_date("!%H:%M:%S", t);
	end
	local m = t % 1;
	local s = floor(t);
	return os_date("!%H:%M:%S.%%06d", s):format(floor(m * 1000000));
end

local function legacy(t)
	return os_date("!%Y%m%dT%H:%M:%S", t and floor(t) or nil);
end

local function parse(s)
	if s then
		local year, month, day, hour, min, sec, tzd = s:match("^(%d%d%d%d)%-?(%d%d)%-?(%d%d)T(%d%d):(%d%d):(%d%d%.?%d*)([Z+%-]?.*)$");
		if year then
			local now = os_time();
			local time_offset = os_difftime(os_time(os_date("*t", now)), os_time(os_date("!*t", now))); -- to deal with local timezone
			local tzd_offset = 0;
			if tzd ~= "" and tzd ~= "Z" then
				local sign, h, m = tzd:match("([+%-])(%d%d):?(%d*)");
				if not sign then return; end
				if #m ~= 2 then m = "0"; end
				h, m = tonumber(h), tonumber(m);
				tzd_offset = h * 60 * 60 + m * 60;
				if sign == "-" then tzd_offset = -tzd_offset; end
			end
			local prec = sec%1;
			sec = floor(sec + time_offset) - tzd_offset;
			return os_time({year=year, month=month, day=day, hour=hour, min=min, sec=sec, isdst=false})+prec;
		end
	end
end

return {
	date     = date;
	datetime = datetime;
	time     = time;
	legacy   = legacy;
	parse    = parse;
};