Skip to content

Fix for timezone change breaking session expiration#13390

Merged
danielkerr merged 1 commit intoopencart:3.0.x.xfrom
ADDCreative:patch-11
Jan 4, 2024
Merged

Fix for timezone change breaking session expiration#13390
danielkerr merged 1 commit intoopencart:3.0.x.xfrom
ADDCreative:patch-11

Conversation

@ADDCreative
Copy link
Copy Markdown
Contributor

This is the same as #9633 that was never applied to the 3.0.x.x branch. Should fix #9237 that prenvented admin login when the timezone was a negative value. However, it won't fix the issue a negative value causes with the API #9492. That would require a change in the API session code or a change in the startup order.

@danielkerr danielkerr merged commit fe02130 into opencart:3.0.x.x Jan 4, 2024
@danielkerr
Copy link
Copy Markdown
Member

thx!

@ADDCreative
Copy link
Copy Markdown
Contributor Author

May I ask why this reverted?

@mhcwebdesign
Copy link
Copy Markdown
Contributor

@ADDCreative : Just curious: How exactly is the timezone issue to be fixed? I just set up a new OC 3.0.x.x for the 'America/Denver' timezone (UTC-07), and the only way I managed to get it to work was by doing this:

System > Settings > edit Store > tab Locals > Time Zone: America/Denver (-07:00)

In the system/config/default.php replace
$_['date_timezone'] = 'UTC';
with
$_['date_timezone'] = 'America/Denver';

The latter is only used in the system/framework.php :
date_default_timezone_set($config->get('date_timezone'));

Do you have a suggestion how exactly to fix the timezone issue so it won't result in failed admin logins?

@ADDCreative
Copy link
Copy Markdown
Contributor Author

@mhcwebdesign This issue is caused as the session is started and the expiry time checked in framework.php, before the time zone is set from the value in the database in controller/startup/startup.php, but is written after the time zone is set. So the session expiry time is checked in one time zone and the written in another.

Using gmdate, which isn't affected by time zone changes, instead of date in the session class, will at least prevent the admin from being locked out.

Another way to fix all the issues it causes would be to change the startup order so the session is not started until the final time zone has been set.

This is what was eventually done in 4.0.x as well and using gmdate.

$_['action_pre_action'] = [
'startup/setting',
'startup/session',

Whereas 3.0.x does.

$_['action_pre_action'] = array(
'startup/session',
'startup/startup',

It would be more work to change the startup order in 3.0.x as the admin session is started in framework.php not a seperate controller/startup/session.php. There may also be other consequences of changing the startup order.

@mhcwebdesign
Copy link
Copy Markdown
Contributor

@ADDCreative : So the only way for OpenCart 3.0.x.x, for the admin login, would be to change the system/framework.php. E.g. if $application_config='admin' then get the 'config_timezone' from a DB query (table oc_setting.key) before dealing with the session, e.g.

....
if ($application_config=='admin') {
	$timezone =  ... get time zone from a DB query ...
	date_default_timezone_set($timezone);
}

// Session
$session = new Session($config->get('session_engine'), $registry);
.....

Just thinking aloud....

@danielkerr
Copy link
Copy Markdown
Member

please poost again

@ADDCreative
Copy link
Copy Markdown
Contributor Author

ADDCreative commented Jan 5, 2024

@mhcwebdesign I like the idea, However, it's also needed for the catalog as well. So just.

Before.

// Sync PHP and DB time zones
$db->query("SET time_zone = '" . $db->escape(date('P')) . "'");

Add something like.

$query = $db->query("SELECT * FROM " . DB_PREFIX . "setting WHERE `key` = 'config_timezone' AND store_id = '0'");

// Set time zone
if ($query->num_rows) {
	date_default_timezone_set($query->row['value']);
}

Just tested and it seems to work. Even the API seems to work.

@mhcwebdesign
Copy link
Copy Markdown
Contributor

@ADDCreative : Good point. The basic idea was that the timezone should not be hardcoded in the system/config/default.php, rather the timezone should be found from the oc_settings DB table. So do we need the line 15 in the system/framework.php at all:

date_default_timezone_set($config->get('date_timezone'));

?

@ADDCreative
Copy link
Copy Markdown
Contributor Author

@mhcwebdesign Line 15 would be used by the installer as there would be no setting in the database at that time. But as the installer doesn't auto start the database, so the PHP and database times aren't synced anyway,

It would also be used if a store had been upgraded from a version that didn't have the time zone setting, before the setting were saved again.

However, wouldn't need to set the time zone in catalog/controller/startup/startup.php or admin/controller/startup/startup.php.

@mhcwebdesign
Copy link
Copy Markdown
Contributor

@ADDCreative : So if I understand you correctly all we need is to add

$query = $db->query("SELECT * FROM " . DB_PREFIX . "setting WHERE `key` = 'config_timezone' AND store_id = '0'");

// Set time zone
if ($query->num_rows) {
	date_default_timezone_set($query->row['value']);
}

before line 83 in the system/framework.php

?

@ADDCreative
Copy link
Copy Markdown
Contributor Author

@mhcwebdesign Yes, it effectively moves the following blocks of code before the session is started. So the following blocks of code could be removed, as there is no point setting the time zone again.

// Set time zone
if ($this->config->get('config_timezone')) {
date_default_timezone_set($this->config->get('config_timezone'));
// Sync PHP and DB time zones.
$this->db->query("SET time_zone = '" . $this->db->escape(date('P')) . "'");
}

// Set time zone
if ($this->config->get('config_timezone')) {
date_default_timezone_set($this->config->get('config_timezone'));
// Sync PHP and DB time zones.
$this->db->query("SET time_zone = '" . $this->db->escape(date('P')) . "'");
}

@ADDCreative ADDCreative deleted the patch-11 branch March 3, 2024 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants