GeezerVison is showing github.com — Timezone issues on password reset expiry times · Issue #2037 · textpattern/textpattern
Timezone issues on password reset expiry times #2037DescriptionNot sure if this is just a server config issue on our sites or a general core issue.
STR:
- Visit plugins.textpattern.com (for example).
- Click "Forgot Password".
- Enter your username and get it to send a reset request.
View the reset email. Note the "You have until..." date is in the past which means the token has already expired, so it's not possible to reset the password. You get an "Invalid Token" response after attempting it.
Temporary kludge: perhaps extend the RESET_EXPIRY_MINUTES value to something greater than the server timezone offset in config.php:
define('RESET_EXPIRY_MINUTES', '360'); // 6 hours
I suspect safe_strftime() is not being invoked properly to create the token datestamp, or it is working but is injecting the wrong values into the txp_token table because some conversion is taking place between client/server and database. Activitychanged the title [-]Timexone issues on password reset espiry times[/-] [+]Timezone issues on password reset expiry times[/+] on Dec 22, 2025petecooper commented on Dec 22, 2025 @Bloke I can switch the site back to PHP 8.2 to see if it's a PHP 8.5-related thing…any good? Bloke commented on Dec 22, 2025 Don't think it's 8.5. I suspect we've norked something up with the token injection / safe_strftime(). But if you could please try tweaking config.php as mentioned above to outstrip the PST -> GMT timezone differences by a couple of hours, that might fix it temporarily.
Oh the perils of developing on a system that is in the same timezone as the webserver, which means stuff like this gets overlooked. petecooper commented on Dec 22, 2025
But if you could please try tweaking config.php as mentioned above to outstrip the PST -> GMT timezone differences by a couple of hours, that might fix it temporarily.
Done. Bloke commented on Dec 22, 2025 @petecooper Nailed it, thank you.
No idea how to investigate this during debugging without spinning up some sort of remote environment in a different timezone. Will need some thought. petecooper commented on Jan 29, 2026 Cannot reproduce on third-party hosting. Hetzer shared hosting:
I make that a 90 minute window from the time of the email.
This may be an edge case with the bodge job implementation of PHP 8.5 that I've deployed temporarily. The new wave of our server build doesn't have the OP issue, I suspect it's a hold out from an ancient server config. Bloke commented on Feb 5, 2026 I wonder if this is fixed as part of 249b5ab? Or maybe it was restricted solely to the plugins.textpattern.com domain.
I'll try and do some tests. Not sure how. Maybe kludge php.ini or the system clock to fake a timezone shift? bloatware commented on Feb 5, 2026 Not sure, the modified safe_strtotime() function does not seem to be used in users management. petecooper commented on Feb 5, 2026 @Bloke Don't hate me…did you factor in the time difference with the plugins site vs UK time?:
That's the plugins site just now - PST is 8 hours behind UTC…which makes it a 6-hour window. Do you still have the reset email? Bloke commented on Feb 5, 2026 I do still have the email(s). The fact there's a timezone shift isn't factored into the expiry time. I suspect this line is at fault:
$expiryTimestamp = time() + (60 * RESET_EXPIRY_MINUTES);
That time() should probably have the server offset added to it somehow. I don't know how best to do that. Same with the activation expiry in the function above it.
My best guess is it's taking the local time, adding 90 mins to it and then generates a token by adding the timezone offset, which shoves it N hours in either direction. That means the instant you receive the email, there's a chance the link's already expired (for servers behind your local timezone).
EDIT:
Subject: [Textpattern CMS plugins] Please confirm your password reset request
Date:Monday, 22 December 2025 00:45
...
You have until 21 December 2025, 18:15 PST to respond before this link expires.
Expiry: 00:45 + 90 = 02:15 + tz (-8 hours) = 18:15 yesterday
It should be: 02:15 today petecooper commented on Feb 7, 2026 @Bloke I'm still a bit baffled by this - forgive me if I'm missing something obvious.
Your password reset email of Dec 22 2025, assuming normal send & delivery:
Timestamp: Dec 22 2025 0045UTC = Dec 21 2025 1645UTC-8 (aka PST)
Message: "You have until 21 December 2025, 18:15 PST" etc
Window: 1h 30m / 90 minutes
My password reset email of Feb 5 2026, assuming normal send & delivery:
Timestamp: Feb 5 2026 1657UTC = Feb 5 2026 0857UTC-8 (aka PST)
Message: "You have until 5 February 2026, 14:57 PST" etc
Window: 6h 0m / 360 minutes
What's changed on the plugins site server since Dec 22 2035: PHP 8.5 patch release(s), and the usual system library updates…nothing else I can think of. Config hasn't changed, as far as I know. The server timezone is UTC intentionally, and the geolocation hasn't moved.
What gives with the disparity with the two email reset windows? If you request a new reset email, do you get a 90 min or 360 min window? Or something else? Bloke commented on Feb 7, 2026 Bloke commented on Feb 7, 2026 The expiry window is 90 minutes in core but that's overridable in config.php. I was under the impression you tweaked config.php as a temporary measure so I could reset my password. If not, I'm similarly baffled why theres a 6hr window now on that site.
Either way, I'm not sure which part of the process is at fault here: token generation or token verification, and that's what is making it harder to diagnose and fix.
Maybe, when it checks the validity window, the token verification needs to use the server's timezone offset in the calculation so it doesn't think the request's already expired, less than a minute after the email has been sent.
Hmmm. petecooper commented on Feb 7, 2026
The expiry window is 90 minutes in core but that's overridable in config.php. I was under the impression you tweaked config.php as a temporary measure so I could reset my password. If not, I'm similarly baffled why theres a 6hr window now on that site.
Ah, yes - I did - that explains the longer reset window in my email, but your 90 minute window on Dec 22 still appears valid by my sums:
Timestamp: Dec 22 2025 0045UTC = Dec 21 2025 1645UTC-8 (aka PST)
Message: "You have until 21 December 2025, 18:15 PST" etc
Window: 1h 30m / 90 minutes
I'm clearly being dumb here, and I'm truly sorry for labouring a point…where am I going wrong in that calculation? Bloke commented on Feb 7, 2026
where am I going wrong in that calculation
You're not. But when I click the link and type a new password, it says the request is invalid upon submission. So either the generation of the outgoing token expiry needs fixing. Or the verification of the incoming token needs fixing. One side of that process is failing when there are timezones involved, and I don't know which side is at fault. petecooper commented on Feb 7, 2026
But when I click the link and type a new password, it says the request is invalid upon submission. So either the generation of the outgoing token expiry needs fixing. Or the verification of the incoming token needs fixing.
Penny dropped. Now I see it. Thank you. Sorry for the wasted brain cycles.
If I do a forget password on the PHP 8.5.2 site used here the reset works just fine without error, so it could be a PHP compile / config issue on the plugins site.
Let me investigate for a bit, and I'll reply. Bloke commented on Feb 7, 2026
If I do a forget password on the PHP 8.5.2 site used here the reset works just fine without error
That may be a lucky coincidence because the server is ahead of GMT so the window might actually be 2.5hrs.
EDIT: I think Txp is at fault but, if so, I'm surprised this has never come up before... there must be servers out there that are geographically West of the people using them. The constants we implemented have been in place since 4.6.0.
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|