From c2d91650bd5e8e7f9e2ba005e47934292faaafb0 Mon Sep 17 00:00:00 2001 From: rxu Date: Tue, 11 Jun 2024 16:08:39 +0700 Subject: [PATCH 001/276] [ticket/17337] Fix mysqli driver is missing transaction begin statement PHPBB-17337 --- phpBB/phpbb/db/driver/mysqli.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/phpBB/phpbb/db/driver/mysqli.php b/phpBB/phpbb/db/driver/mysqli.php index e474b2584e..6182801da6 100644 --- a/phpBB/phpbb/db/driver/mysqli.php +++ b/phpBB/phpbb/db/driver/mysqli.php @@ -155,7 +155,9 @@ class mysqli extends \phpbb\db\driver\mysql_base switch ($status) { case 'begin': - return @mysqli_autocommit($this->db_connect_id, false); + @mysqli_autocommit($this->db_connect_id, false); + $result = @mysqli_begin_transaction($this->db_connect_id); + return $result; break; case 'commit': From f98f2c5896fb4594e20d4f0ee77988fddfd6319c Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 11 Jun 2024 20:12:01 +0200 Subject: [PATCH 002/276] [ticket/17301] Ensure reading invalid cache files is aborted PHPBB-17301 --- phpBB/phpbb/cache/driver/file.php | 40 +++++++-- tests/cache/file_driver_test.php | 140 +++++++++++++++++++++++++++++- 2 files changed, 170 insertions(+), 10 deletions(-) diff --git a/phpBB/phpbb/cache/driver/file.php b/phpBB/phpbb/cache/driver/file.php index a07b9a9701..768e314b18 100644 --- a/phpBB/phpbb/cache/driver/file.php +++ b/phpBB/phpbb/cache/driver/file.php @@ -330,6 +330,27 @@ class file extends \phpbb\cache\driver\base return $query_result; } + /** + * Cleanup when loading invalid data global file + * + * @param string $file Filename + * @param resource $handle + * + * @return void + */ + private function cleanup_invalid_data_global(string $file, $handle): void + { + if (is_resource($handle)) + { + fclose($handle); + } + + $this->vars = $this->var_expires = []; + $this->is_modified = false; + + $this->remove_file($file); + } + /** * Read cached data from a specified file * @@ -372,14 +393,7 @@ class file extends \phpbb\cache\driver\base if (!is_numeric($bytes) || ($bytes = (int) $bytes) === 0) { - // We cannot process the file without a valid number of bytes - // so we discard it - fclose($handle); - - $this->vars = $this->var_expires = array(); - $this->is_modified = false; - - $this->remove_file($file); + $this->cleanup_invalid_data_global($file, $handle); return false; } @@ -392,9 +406,17 @@ class file extends \phpbb\cache\driver\base } $var_name = substr(fgets($handle), 0, -1); + $data_length = $bytes - strlen($var_name); + + if ($data_length <= 0) + { + $this->cleanup_invalid_data_global($file, $handle); + + return false; + } // Read the length of bytes that consists of data. - $data = fread($handle, $bytes - strlen($var_name)); + $data = fread($handle, $data_length); $data = @unserialize($data); // Don't use the data if it was invalid diff --git a/tests/cache/file_driver_test.php b/tests/cache/file_driver_test.php index 10c9aec182..cf36cda2bb 100644 --- a/tests/cache/file_driver_test.php +++ b/tests/cache/file_driver_test.php @@ -17,6 +17,9 @@ class phpbb_cache_file_driver_test extends phpbb_cache_common_test_case { private $cache_dir; + /** @var \phpbb\cache\driver\file */ + private $cache_file; + public function getDataSet() { return $this->createXMLDataSet(__DIR__ . '/fixtures/config.xml'); @@ -36,7 +39,8 @@ class phpbb_cache_file_driver_test extends phpbb_cache_common_test_case } $this->create_cache_dir(); - $this->driver = new \phpbb\cache\driver\file($this->cache_dir); + $this->cache_file = new \phpbb\cache\driver\file($this->cache_dir); + $this->driver = $this->cache_file; } protected function tearDown(): void @@ -49,6 +53,140 @@ class phpbb_cache_file_driver_test extends phpbb_cache_common_test_case parent::tearDown(); } + public function test_read_not_readable() + { + global $phpEx; + + // Create file that is not readable + $this->assertTrue($this->cache_file->_write('unreadable', 'foo', time() + 86400)); + + $filename = "{$this->cache_dir}unreadable.$phpEx"; + @chmod($filename, 0000); + $this->assertFalse($this->cache_file->_read('unreadable')); + @chmod($filename, 0600); + $this->assertNotFalse($this->cache_file->_read('unreadable')); + } + + public function test_read_data_global_invalid() + { + global $phpEx; + + $reflectionCacheVars = new \ReflectionProperty($this->cache_file, 'vars'); + $reflectionCacheVars->setAccessible(true); + $reflectionCacheVars->setValue($this->cache_file, ['foo' => 'bar']); + + $reflectionCacheVarExpires = new \ReflectionProperty($this->cache_file, 'var_expires'); + $reflectionCacheVarExpires->setAccessible(true); + $reflectionCacheVarExpires->setValue($this->cache_file, ['foo' => time() + 86400]); + + // Create file in invalid format + $this->assertTrue($this->cache_file->_write('data_global')); + $filename = "{$this->cache_dir}data_global.$phpEx"; + $cache_data = file_get_contents($filename); + // Force negative read when retrieving data_global + $cache_data = str_replace("\n13\n", "\n1\n", $cache_data); + file_put_contents($filename, $cache_data); + + $this->assertFalse($this->cache_file->_read('data_global')); + } + + public function test_read_data_global_zero_bytes() + { + global $phpEx; + + $reflectionCacheVars = new \ReflectionProperty($this->cache_file, 'vars'); + $reflectionCacheVars->setAccessible(true); + $reflectionCacheVars->setValue($this->cache_file, ['foo' => 'bar']); + + $reflectionCacheVarExpires = new \ReflectionProperty($this->cache_file, 'var_expires'); + $reflectionCacheVarExpires->setAccessible(true); + $reflectionCacheVarExpires->setValue($this->cache_file, ['foo' => time() + 86400]); + + // Create file in invalid format + $this->assertTrue($this->cache_file->_write('data_global')); + $filename = "{$this->cache_dir}data_global.$phpEx"; + $cache_data = file_get_contents($filename); + // Force negative read when retrieving data_global + $cache_data = str_replace("\n13\n", "\n0\n", $cache_data); + file_put_contents($filename, $cache_data); + + $this->assertFalse($this->cache_file->_read('data_global')); + } + + public function test_read_data_global_hex_bytes() + { + global $phpEx; + + $reflectionCacheVars = new \ReflectionProperty($this->cache_file, 'vars'); + $reflectionCacheVars->setAccessible(true); + $reflectionCacheVars->setValue($this->cache_file, ['foo' => 'bar']); + + $reflectionCacheVarExpires = new \ReflectionProperty($this->cache_file, 'var_expires'); + $reflectionCacheVarExpires->setAccessible(true); + $reflectionCacheVarExpires->setValue($this->cache_file, ['foo' => time() + 86400]); + + // Create file in invalid format + $this->assertTrue($this->cache_file->_write('data_global')); + $filename = "{$this->cache_dir}data_global.$phpEx"; + $cache_data = file_get_contents($filename); + // Force negative read when retrieving data_global + $cache_data = str_replace("\n13\n", "\nA\n", $cache_data); + file_put_contents($filename, $cache_data); + + $this->assertFalse($this->cache_file->_read('data_global')); + } + + public function test_read_data_global_expired() + { + $reflectionCacheVars = new \ReflectionProperty($this->cache_file, 'vars'); + $reflectionCacheVars->setAccessible(true); + $reflectionCacheVars->setValue($this->cache_file, ['foo' => 'bar']); + + $reflectionCacheVarExpires = new \ReflectionProperty($this->cache_file, 'var_expires'); + $reflectionCacheVarExpires->setAccessible(true); + $reflectionCacheVarExpires->setValue($this->cache_file, ['foo' => time() - 86400]); + + // Create file in invalid format + $this->assertTrue($this->cache_file->_write('data_global')); + + // Clear data + $reflectionCacheVars->setValue($this->cache_file, []); + $reflectionCacheVarExpires->setValue($this->cache_file, []); + + $this->assertTrue($this->cache_file->_read('data_global')); + + // Check data, should be empty + $this->assertEquals([], $reflectionCacheVars->getValue($this->cache_file)); + } + + public function test_read_data_global() + { + $reflectionCacheVars = new \ReflectionProperty($this->cache_file, 'vars'); + $reflectionCacheVars->setAccessible(true); + $expectedVars = ['foo' => 'bar']; + $reflectionCacheVars->setValue($this->cache_file, $expectedVars); + + $reflectionCacheVarExpires = new \ReflectionProperty($this->cache_file, 'var_expires'); + $reflectionCacheVarExpires->setAccessible(true); + $expectedVarExpires = ['foo' => time() + 86400]; + $reflectionCacheVarExpires->setValue($this->cache_file, $expectedVarExpires); + + // Create file in invalid format + $this->assertTrue($this->cache_file->_write('data_global')); + + // Clear data + $reflectionCacheVars->setValue($this->cache_file, []); + $reflectionCacheVarExpires->setValue($this->cache_file, []); + $this->assertEquals([], $reflectionCacheVars->getValue($this->cache_file)); + $this->assertEquals([], $reflectionCacheVarExpires->getValue($this->cache_file)); + + $this->assertTrue($this->cache_file->_read('data_global')); + + // Check data, should be empty + $this->assertEquals($expectedVars, $reflectionCacheVars->getValue($this->cache_file)); + $this->assertEquals($expectedVarExpires, $reflectionCacheVarExpires->getValue($this->cache_file)); + } + private function create_cache_dir() { $this->get_test_case_helpers()->makedirs($this->cache_dir); From 9e15802805d356b02834348d74e7f65b121663b7 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 11 Jun 2024 20:29:23 +0200 Subject: [PATCH 003/276] [ticket/17301] Do not test unreadable files on windows PHPBB-17301 --- tests/cache/file_driver_test.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/cache/file_driver_test.php b/tests/cache/file_driver_test.php index cf36cda2bb..56a1b28073 100644 --- a/tests/cache/file_driver_test.php +++ b/tests/cache/file_driver_test.php @@ -55,6 +55,11 @@ class phpbb_cache_file_driver_test extends phpbb_cache_common_test_case public function test_read_not_readable() { + if (strtolower(substr(PHP_OS, 0, 3)) === 'win') + { + $this->markTestSkipped('Unable to test unreadable files on Windows'); + } + global $phpEx; // Create file that is not readable From d66d4a0c6ab5d9ac4d4dd1a37a90d8b3ea2e9889 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 12 Jun 2024 22:16:41 +0200 Subject: [PATCH 004/276] [ticket/17339] Support receiving push notifications if not logged in PHPBB-17339 --- .../migration/data/v400/add_webpush_token.php | 53 ++++++++++++ phpBB/phpbb/notification/method/webpush.php | 8 ++ phpBB/phpbb/ucp/controller/webpush.php | 80 +++++++++++++++++-- phpBB/styles/all/js/push_worker.js.twig | 8 +- 4 files changed, 143 insertions(+), 6 deletions(-) create mode 100644 phpBB/phpbb/db/migration/data/v400/add_webpush_token.php diff --git a/phpBB/phpbb/db/migration/data/v400/add_webpush_token.php b/phpBB/phpbb/db/migration/data/v400/add_webpush_token.php new file mode 100644 index 0000000000..f87dadf9e7 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v400/add_webpush_token.php @@ -0,0 +1,53 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\db\migration\data\v400; + +use phpbb\db\migration\migration; + +class add_webpush_token extends migration +{ + public static function depends_on(): array + { + return [ + '\phpbb\db\migration\data\v400\add_webpush', + ]; + } + + public function effectively_installed(): bool + { + return $this->db_tools->sql_column_exists($this->table_prefix . 'notification_push', 'push_token'); + } + + public function update_schema(): array + { + return [ + 'add_columns' => [ + $this->table_prefix . 'notification_push' => [ + 'push_token' => ['VCHAR', ''], + ], + ], + ]; + } + + public function revert_schema(): array + { + return [ + 'drop_columns' => [ + $this->table_prefix . 'notification_push' => [ + 'push_token', + ], + ], + ]; + } +} diff --git a/phpBB/phpbb/notification/method/webpush.php b/phpBB/phpbb/notification/method/webpush.php index 4d2d18bdc6..700503f97d 100644 --- a/phpBB/phpbb/notification/method/webpush.php +++ b/phpBB/phpbb/notification/method/webpush.php @@ -51,6 +51,9 @@ class webpush extends messenger_base implements extended_method_interface /** @var int Fallback size for padding if endpoint is mozilla, see https://github.com/web-push-libs/web-push-php/issues/108#issuecomment-2133477054 */ const MOZILLA_FALLBACK_PADDING = 2820; + /** @var array Map for storing push token between db insertion and sending of notifications */ + private array $push_token_map = []; + /** * Notification Method Web Push constructor * @@ -145,9 +148,11 @@ class webpush extends messenger_base implements extended_method_interface 'avatar' => $notification->get_avatar(), ]), 'notification_time' => time(), + 'push_token' => hash('sha256', random_bytes(32)) ]; $data = self::clean_data($data); $insert_buffer->insert($data); + $this->push_token_map[$notification->notification_type_id][$notification->item_id] = $data['push_token']; } $insert_buffer->flush(); @@ -221,7 +226,9 @@ class webpush extends messenger_base implements extended_method_interface $data = [ 'item_id' => $notification->item_id, 'type_id' => $notification->notification_type_id, + 'user_id' => $notification->user_id, 'version' => $this->config['assets_version'], + 'token' => hash('sha256', $user['user_form_salt'] . $this->push_token_map[$notification->notification_type_id][$notification->item_id]), ]; $json_data = json_encode($data); @@ -337,6 +344,7 @@ class webpush extends messenger_base implements extended_method_interface 'item_parent_id' => null, 'user_id' => null, 'push_data' => null, + 'push_token' => null, 'notification_time' => null, ]; diff --git a/phpBB/phpbb/ucp/controller/webpush.php b/phpBB/phpbb/ucp/controller/webpush.php index b60fa437b3..15e54956fb 100644 --- a/phpBB/phpbb/ucp/controller/webpush.php +++ b/phpBB/phpbb/ucp/controller/webpush.php @@ -100,10 +100,37 @@ class webpush * @return JsonResponse */ public function notification(): JsonResponse + { + if (!$this->request->is_ajax() || $this->user->data['is_bot'] || $this->user->data['user_type'] == USER_INACTIVE) + { + throw new http_exception(Response::HTTP_FORBIDDEN, 'Forbidden'); + } + + if ($this->user->id() !== ANONYMOUS) + { + $notification_data = $this->get_user_notifications(); + } + else + { + $notification_data = $this->get_anonymous_notifications(); + } + + // Decode and return data if everything is fine + $data = json_decode($notification_data, true); + $data['url'] = isset($data['url']) ? $this->path_helper->update_web_root_path($data['url']) : ''; + + return new JsonResponse($data); + } + + /** + * Get notification data for logged in user + * + * @return string Notification data + */ + private function get_user_notifications(): string { // Subscribe should only be available for logged-in "normal" users - if (!$this->request->is_ajax() || $this->user->id() == ANONYMOUS || $this->user->data['is_bot'] - || $this->user->data['user_type'] == USER_IGNORE || $this->user->data['user_type'] == USER_INACTIVE) + if ($this->user->data['user_type'] == USER_IGNORE) { throw new http_exception(Response::HTTP_FORBIDDEN, 'Forbidden'); } @@ -119,10 +146,53 @@ class webpush $result = $this->db->sql_query($sql); $notification_data = $this->db->sql_fetchfield('push_data'); $this->db->sql_freeresult($result); - $data = json_decode($notification_data, true); - $data['url'] = isset($data['url']) ? $this->path_helper->update_web_root_path($data['url']) : ''; - return new JsonResponse($data); + return $notification_data; + } + + /** + * Get notification data for not logged in user via token + * + * @return string + */ + private function get_anonymous_notifications(): string + { + $token = $this->request->variable('token', ''); + + if ($token) + { + $item_id = $this->request->variable('item_id', 0); + $type_id = $this->request->variable('type_id', 0); + $user_id = $this->request->variable('user_id', 0); + + $sql = 'SELECT push_data, push_token + FROM ' . $this->notification_webpush_table . ' + WHERE user_id = ' . (int) $user_id . ' + AND notification_type_id = ' . (int) $type_id . ' + AND item_id = ' . (int) $item_id; + $result = $this->db->sql_query($sql); + $notification_row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $notification_data = $notification_row['push_data']; + $push_token = $notification_row['push_token']; + + // Check if passed push token is valid + $sql = 'SELECT user_form_salt + FROM ' . USERS_TABLE . ' + WHERE user_id = ' . (int) $user_id; + $result = $this->db->sql_query($sql); + $user_form_token = $this->db->sql_fetchfield('user_form_salt'); + $this->db->sql_freeresult($result); + + $expected_push_token = hash('sha256', $user_form_token . $push_token); + if ($expected_push_token === $token) + { + return $notification_data; + } + } + + throw new http_exception(Response::HTTP_FORBIDDEN, 'Forbidden'); } /** diff --git a/phpBB/styles/all/js/push_worker.js.twig b/phpBB/styles/all/js/push_worker.js.twig index f2807cb43a..cf0ca568ac 100644 --- a/phpBB/styles/all/js/push_worker.js.twig +++ b/phpBB/styles/all/js/push_worker.js.twig @@ -23,12 +23,16 @@ self.addEventListener('push', event => { let itemId = 0; let typeId = 0; - let notificationVersion = 5; + let userId = 0; + let notificationVersion = 0; + let pushToken = ''; try { const notificationData = event.data.json(); itemId = notificationData.item_id; typeId = notificationData.type_id; + userId = notificationData.user_id; notificationVersion = parseInt(notificationData.version, 10); + pushToken = notificationData.token; } catch { self.registration.showNotification(event.data.text()); return; @@ -45,6 +49,8 @@ self.addEventListener('push', event => { const formData = new FormData(); formData.append('item_id', itemId.toString(10)); formData.append('type_id', typeId.toString(10)); + formData.append('user_id', userId.toString(10)); + formData.append('token', pushToken); fetch(getNotificationUrl, { method: 'POST', From e125f1f7094a8cd9b14e380d43e713721b6684e5 Mon Sep 17 00:00:00 2001 From: rxu Date: Thu, 13 Jun 2024 13:27:03 +0700 Subject: [PATCH 005/276] [ticket/17338] Prefer user_last_active to display user last activity info PHPBB-17338 --- phpBB/includes/acp/acp_users.php | 2 +- phpBB/includes/functions_display.php | 2 +- phpBB/memberlist.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 611e72a9b8..80089c2717 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1088,7 +1088,7 @@ class acp_users $s_action_options .= ''; } - $last_active = (!empty($user_row['session_time'])) ? $user_row['session_time'] : $user_row['user_last_active']; + $last_active = $user_row['user_last_active'] ?: ($user_row['session_time'] ?? 0); $inactive_reason = ''; if ($user_row['user_type'] == USER_INACTIVE) diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index d995676e8f..26f2d43cb5 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -1603,7 +1603,7 @@ function phpbb_show_profile($data, $user_notes_enabled = false, $warn_user_enabl if ($data['user_allow_viewonline'] || $auth->acl_get('u_viewonline')) { - $last_active = (!empty($data['session_time'])) ? $data['session_time'] : $data['user_last_active']; + $last_active = $data['user_last_active'] ?: ($data['session_time'] ?? 0); } else { diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index dbdfe80618..c846bdde05 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -1722,7 +1722,7 @@ switch ($mode) { $row['session_time'] = $session_ary[$row['user_id']]['session_time'] ?? 0; $row['session_viewonline'] = $session_ary[$row['user_id']]['session_viewonline'] ?? 0; - $row['last_visit'] = (!empty($row['session_time'])) ? $row['session_time'] : $row['user_last_active']; + $row['last_visit'] = $row['user_last_active'] ?: $row['session_time']; $id_cache[$row['user_id']] = $row; } From db9874546b95f17254ca944b050f4ea595d688b2 Mon Sep 17 00:00:00 2001 From: rxu Date: Fri, 14 Jun 2024 10:28:25 +0700 Subject: [PATCH 006/276] [ticket/17338] Add user_last_active to session_gc() PHPBB-17338 --- phpBB/phpbb/session.php | 10 ++++++---- tests/session/fixtures/sessions_garbage.xml | 3 +++ tests/session/garbage_collection_test.php | 4 ++++ tests/test_framework/phpbb_session_test_case.php | 2 +- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index af39ecf2fa..46e82d03ba 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -987,7 +987,7 @@ class session // For SQLite versions 3.8.3+ which support Common Table Expressions (CTE) $sql = "WITH s3 (session_page, session_user_id, session_time) AS ($sql_select) UPDATE " . USERS_TABLE . ' - SET (user_lastpage, user_lastvisit) = (SELECT session_page, session_time FROM s3 WHERE session_user_id = user_id) + SET (user_lastpage, user_lastvisit, user_last_active) = (SELECT session_page, session_time, session_time FROM s3 WHERE session_user_id = user_id) WHERE EXISTS (SELECT session_user_id FROM s3 WHERE session_user_id = user_id)'; $db->sql_query($sql); @@ -1000,7 +1000,9 @@ class session while ($row = $db->sql_fetchrow($result)) { $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_lastvisit = ' . (int) $row['recent_time'] . ", user_lastpage = '" . $db->sql_escape($row['session_page']) . "' + SET user_lastvisit = ' . (int) $row['recent_time'] . ', + user_last_active = ' . (int) $row['recent_time'] . ", + user_lastpage = '" . $db->sql_escape($row['session_page']) . "' WHERE user_id = " . (int) $row['session_user_id']; $db->sql_query($sql); } @@ -1010,14 +1012,14 @@ class session case 'mysqli': $sql = 'UPDATE ' . USERS_TABLE . " u, ($sql_select) s3 - SET u.user_lastvisit = s3.recent_time, u.user_lastpage = s3.session_page + SET u.user_lastvisit = s3.recent_time, u.user_last_active = s3.recent_time, u.user_lastpage = s3.session_page WHERE u.user_id = s3.session_user_id"; $db->sql_query($sql); break; default: $sql = 'UPDATE ' . USERS_TABLE . " - SET user_lastvisit = s3.recent_time, user_lastpage = s3.session_page + SET user_lastvisit = s3.recent_time, user_last_active = s3.recent_time, user_lastpage = s3.session_page FROM ($sql_select) s3 WHERE user_id = s3.session_user_id"; $db->sql_query($sql); diff --git a/tests/session/fixtures/sessions_garbage.xml b/tests/session/fixtures/sessions_garbage.xml index 59a2dc2ebe..16971428a7 100644 --- a/tests/session/fixtures/sessions_garbage.xml +++ b/tests/session/fixtures/sessions_garbage.xml @@ -7,6 +7,7 @@ user_sig user_lastpage user_lastvisit + user_last_active 4 bar @@ -14,6 +15,7 @@ oldpage_user_bar.php 1400000000 + 1300000999 5 @@ -22,6 +24,7 @@ oldpage_user_foo.php 1400000000 + 1300000998 diff --git a/tests/session/garbage_collection_test.php b/tests/session/garbage_collection_test.php index 9080478a28..32c4db3f85 100644 --- a/tests/session/garbage_collection_test.php +++ b/tests/session/garbage_collection_test.php @@ -65,11 +65,13 @@ class phpbb_session_garbage_collection_test extends phpbb_session_test_case [ 'username_clean' => 'bar', 'user_lastvisit' => 1400000000, + 'user_last_active' => 1300000999, 'user_lastpage' => 'oldpage_user_bar.php', ], [ 'username_clean' => 'foo', 'user_lastvisit' => 1400000000, + 'user_last_active' => 1300000998, 'user_lastpage' => 'oldpage_user_foo.php', ], ], @@ -89,11 +91,13 @@ class phpbb_session_garbage_collection_test extends phpbb_session_test_case [ 'username_clean' => 'bar', 'user_lastvisit' => '1500000000', + 'user_last_active' => '1500000000', 'user_lastpage' => 'newpage_user_bar.php', ], [ 'username_clean' => 'foo', 'user_lastvisit' => '1500000000', + 'user_last_active' => '1500000000', 'user_lastpage' => 'newpage_user_foo.php', ], ], diff --git a/tests/test_framework/phpbb_session_test_case.php b/tests/test_framework/phpbb_session_test_case.php index deb76d4e5e..15b5d44eb5 100644 --- a/tests/test_framework/phpbb_session_test_case.php +++ b/tests/test_framework/phpbb_session_test_case.php @@ -50,7 +50,7 @@ abstract class phpbb_session_test_case extends phpbb_database_test_case protected function check_user_session_data($expected_session_data, $message) { - $sql= 'SELECT username_clean, user_lastvisit, user_lastpage + $sql= 'SELECT username_clean, user_lastvisit, user_last_active, user_lastpage FROM ' . USERS_TABLE . ' ORDER BY user_id'; From e21a8e02cdc21c5e6c70727114eab4006014dedd Mon Sep 17 00:00:00 2001 From: rxu Date: Fri, 14 Jun 2024 15:22:20 +0700 Subject: [PATCH 007/276] [ticket/17338] Update user_last_active on session removal and login keys reset PHPBB-17338 --- phpBB/phpbb/session.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index 46e82d03ba..a1d7df511a 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -903,7 +903,8 @@ class session } $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_lastvisit = ' . (int) $this->data['session_time'] . ' + SET user_lastvisit = ' . (int) $this->data['session_time'] . ', + user_last_active = ' . (int) $this->data['session_time'] . ' WHERE user_id = ' . (int) $this->data['user_id']; $db->sql_query($sql); @@ -1652,7 +1653,9 @@ class session if ($row) { $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_lastvisit = ' . (int) $row['session_time'] . ", user_lastpage = '" . $db->sql_escape($row['session_page']) . "' + SET user_lastvisit = ' . (int) $row['session_time'] . ', + user_last_active = ' . (int) $row['session_time'] . ", + user_lastpage = '" . $db->sql_escape($row['session_page']) . "' WHERE user_id = " . (int) $user_id; $db->sql_query($sql); } From b6c2961568b6e93e21a1740f23e63e8b0bf9912b Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sun, 9 Jun 2024 12:19:47 -0700 Subject: [PATCH 008/276] [ticket/17335] Fix language var issues in the extension manager PHPBB-17335 Signed-off-by: Matt Friedman --- phpBB/adm/style/acp_ext_list.html | 39 ++++++++++++++-------------- phpBB/language/en/acp/extensions.php | 39 +++++++++++++++------------- 2 files changed, 41 insertions(+), 37 deletions(-) diff --git a/phpBB/adm/style/acp_ext_list.html b/phpBB/adm/style/acp_ext_list.html index bb22ac861c..dd006bc2cc 100644 --- a/phpBB/adm/style/acp_ext_list.html +++ b/phpBB/adm/style/acp_ext_list.html @@ -99,25 +99,26 @@
- - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + +
{L_EXTENSION_INSTALL_HEADLINE}
{L_EXTENSION_INSTALL_EXPLAIN}
{L_EXTENSION_UPDATE_HEADLINE}
{L_EXTENSION_UPDATE_EXPLAIN}
{L_EXTENSION_REMOVE_HEADLINE}
{L_EXTENSION_REMOVE_EXPLAIN}
{L_EXTENSION_INSTALLING_HEADLINE}
{L_EXTENSION_INSTALLING_EXPLAIN}
{L_EXTENSION_UPDATING_HEADLINE}
{L_EXTENSION_UPDATING_EXPLAIN}
{L_EXTENSION_REMOVING_HEADLINE}
{L_EXTENSION_REMOVING_EXPLAIN}
diff --git a/phpBB/language/en/acp/extensions.php b/phpBB/language/en/acp/extensions.php index c6eb147b86..3a8322ae0b 100644 --- a/phpBB/language/en/acp/extensions.php +++ b/phpBB/language/en/acp/extensions.php @@ -36,14 +36,15 @@ if (empty($lang) || !is_array($lang)) $lang = array_merge($lang, array( - 'EXTENSION_ALREADY_INSTALLED' => 'The “%s” extension has already been installed.', - 'EXTENSION_ALREADY_INSTALLED_MANUALLY' => 'The “%s” extension has already been installed manually.', - 'EXTENSION_ALREADY_MANAGED' => 'The “%s” extension is already managed.', - 'EXTENSION_CANNOT_MANAGE_FILESYSTEM_ERROR' => 'The “%s” extension cannot be managed because the existing files could not be removed from the filesystem.', - 'EXTENSION_CANNOT_MANAGE_INSTALL_ERROR' => 'The “%s” extension could not be installed. The prior installation of this extension has been restored.', - 'EXTENSION_MANAGED_WITH_CLEAN_ERROR' => 'The “%1$s” extension has been installed but an error occurred and the old files could not be removed. You might want to delete the “%2$s” files manually.', - 'EXTENSION_MANAGED_WITH_ENABLE_ERROR' => 'The “%s” extension has been installed but an error occurred while enabling it.', - 'EXTENSION_NOT_INSTALLED' => 'The “%s” extension is not installed.', + 'EXTENSIONS_ALREADY_INSTALLED' => 'The “%s” extension has already been installed.', + 'EXTENSIONS_ALREADY_INSTALLED_MANUALLY' => 'The “%s” extension has already been installed manually.', + 'EXTENSIONS_ALREADY_MANAGED' => 'The “%s” extension is already managed.', + 'EXTENSIONS_CANNOT_MANAGE_FILESYSTEM_ERROR' => 'The “%s” extension cannot be managed because the existing files could not be removed from the filesystem.', + 'EXTENSIONS_CANNOT_MANAGE_INSTALL_ERROR' => 'The “%s” extension could not be installed. The prior installation of this extension has been restored.', + 'EXTENSIONS_MANAGED_WITH_CLEAN_ERROR' => 'The “%1$s” extension has been installed but an error occurred and the old files could not be removed. You might want to delete the “%2$s” files manually.', + 'EXTENSIONS_MANAGED_WITH_ENABLE_ERROR' => 'The “%s” extension has been installed but an error occurred while enabling it.', + 'EXTENSIONS_NOT_INSTALLED' => 'The “%s” extension is not installed.', + 'EXTENSIONS_NOT_MANAGED' => 'The “%s” extension is not being managed.', 'ENABLING_EXTENSIONS' => 'Enabling extensions', 'DISABLING_EXTENSIONS' => 'Disabling extensions', @@ -74,6 +75,8 @@ $lang = array_merge($lang, array( 'EXTENSION_DELETE_DATA_EXPLAIN' => 'Deleting an extension’s data removes all of its data and settings. The extension files are retained so it can be enabled again.', 'EXTENSION_DISABLE_EXPLAIN' => 'Disabling an extension retains its files, data and settings but removes any functionality added by the extension.', 'EXTENSION_ENABLE_EXPLAIN' => 'Enabling an extension allows you to use it on your board.', + 'EXTENSION_REMOVE_EXPLAIN' => 'Removing an extension removes all of its files, data and settings.', + 'EXTENSION_UPDATE_EXPLAIN' => 'Updating an extension will install the latest version compatible with your board, removing old files and replacing them with new ones, and updating the database if necessary.', 'EXTENSION_DELETE_DATA_IN_PROGRESS' => 'The extension’s data is currently being deleted. Please do not leave or refresh this page until it is completed.', 'EXTENSION_DISABLE_IN_PROGRESS' => 'The extension is currently being disabled. Please do not leave or refresh this page until it is completed.', @@ -86,25 +89,25 @@ $lang = array_merge($lang, array( 'EXTENSION_NAME' => 'Extension Name', 'EXTENSION_ACTIONS' => 'Actions', 'EXTENSION_OPTIONS' => 'Options', - 'EXTENSION_INSTALL_HEADLINE'=> 'Installing an extension', - 'EXTENSION_INSTALL_EXPLAIN' => '
    + 'EXTENSION_INSTALLING_HEADLINE'=> 'Installing an extension', + 'EXTENSION_INSTALLING_EXPLAIN' => '
    1. Download an extension from phpBB’s extensions database
    2. Unzip the extension and upload it to the ext/ directory of your phpBB board
    3. Enable the extension, here in the Extensions manager
    ', - 'EXTENSION_UPDATE_HEADLINE' => 'Updating an extension', - 'EXTENSION_UPDATE_EXPLAIN' => '
      + 'EXTENSION_REMOVING_EXPLAIN' => '
        +
      1. Disable the extension
      2. +
      3. Delete the extension’s data
      4. +
      5. Delete the extension’s files from the filesystem
      6. +
      ', + 'EXTENSION_UPDATING_HEADLINE' => 'Updating an extension', + 'EXTENSION_UPDATING_EXPLAIN' => '
      1. Disable the extension
      2. Delete the extension’s files from the filesystem
      3. Upload the new files
      4. Enable the extension
      ', - 'EXTENSION_REMOVE_HEADLINE' => 'Completely removing an extension from your board', - 'EXTENSION_REMOVE_EXPLAIN' => '
        -
      1. Disable the extension
      2. -
      3. Delete the extension’s data
      4. -
      5. Delete the extension’s files from the filesystem
      6. -
      ', + 'EXTENSION_REMOVING_HEADLINE' => 'Deleting an extension from your board', 'EXTENSION_DELETE_DATA_CONFIRM' => 'Are you sure that you wish to delete the data associated with “%s”?

      This removes all of its data and settings and cannot be undone!', 'EXTENSION_DISABLE_CONFIRM' => 'Are you sure that you wish to disable the “%s” extension?', From 173e1ceeba784b8171102324a8625317225597f2 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 10 Jun 2024 20:46:58 -0700 Subject: [PATCH 009/276] [ticket/17335] Move HTML from lang to template PHPBB-17335 Signed-off-by: Matt Friedman --- phpBB/adm/style/acp_ext_list.html | 25 ++++++++++++++++--- phpBB/language/en/acp/extensions.php | 36 ++++++++++++++-------------- 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/phpBB/adm/style/acp_ext_list.html b/phpBB/adm/style/acp_ext_list.html index dd006bc2cc..b8b3d2c68a 100644 --- a/phpBB/adm/style/acp_ext_list.html +++ b/phpBB/adm/style/acp_ext_list.html @@ -104,19 +104,38 @@ {L_EXTENSION_INSTALLING_HEADLINE} - {L_EXTENSION_INSTALLING_EXPLAIN} + +
        +
      1. {{ lang(['EXTENSION_INSTALLING_EXPLAIN', 'step_1']) }}
      2. +
      3. {{ lang(['EXTENSION_INSTALLING_EXPLAIN', 'step_2']) }}
      4. +
      5. {{ lang(['EXTENSION_INSTALLING_EXPLAIN', 'step_3']) }}
      6. +
      + {L_EXTENSION_UPDATING_HEADLINE} - {L_EXTENSION_UPDATING_EXPLAIN} + +
        +
      1. {{ lang(['EXTENSION_UPDATING_EXPLAIN', 'step_1']) }}
      2. +
      3. {{ lang(['EXTENSION_UPDATING_EXPLAIN', 'step_2']) }}
      4. +
      5. {{ lang(['EXTENSION_UPDATING_EXPLAIN', 'step_3']) }}
      6. +
      7. {{ lang(['EXTENSION_UPDATING_EXPLAIN', 'step_4']) }}
      8. +
      + {L_EXTENSION_REMOVING_HEADLINE} - {L_EXTENSION_REMOVING_EXPLAIN} + +
        +
      1. {{ lang(['EXTENSION_REMOVING_EXPLAIN', 'step_1']) }}
      2. +
      3. {{ lang(['EXTENSION_REMOVING_EXPLAIN', 'step_2']) }}
      4. +
      5. {{ lang(['EXTENSION_REMOVING_EXPLAIN', 'step_3']) }}
      6. +
      + diff --git a/phpBB/language/en/acp/extensions.php b/phpBB/language/en/acp/extensions.php index 3a8322ae0b..311cfa74f3 100644 --- a/phpBB/language/en/acp/extensions.php +++ b/phpBB/language/en/acp/extensions.php @@ -89,25 +89,25 @@ $lang = array_merge($lang, array( 'EXTENSION_NAME' => 'Extension Name', 'EXTENSION_ACTIONS' => 'Actions', 'EXTENSION_OPTIONS' => 'Options', - 'EXTENSION_INSTALLING_HEADLINE'=> 'Installing an extension', - 'EXTENSION_INSTALLING_EXPLAIN' => '
        -
      1. Download an extension from phpBB’s extensions database
      2. -
      3. Unzip the extension and upload it to the ext/ directory of your phpBB board
      4. -
      5. Enable the extension, here in the Extensions manager
      6. -
      ', - 'EXTENSION_REMOVING_EXPLAIN' => '
        -
      1. Disable the extension
      2. -
      3. Delete the extension’s data
      4. -
      5. Delete the extension’s files from the filesystem
      6. -
      ', - 'EXTENSION_UPDATING_HEADLINE' => 'Updating an extension', - 'EXTENSION_UPDATING_EXPLAIN' => '
        -
      1. Disable the extension
      2. -
      3. Delete the extension’s files from the filesystem
      4. -
      5. Upload the new files
      6. -
      7. Enable the extension
      8. -
      ', + 'EXTENSION_INSTALLING_HEADLINE' => 'Installing an extension', + 'EXTENSION_INSTALLING_EXPLAIN' => [ + 'step_1' => 'Download an extension from phpBB’s extensions database', + 'step_2' => 'Unzip the extension and upload it to the ext/ directory of your phpBB board', + 'step_3' => 'Enable the extension, here in the Extensions manager', + ], 'EXTENSION_REMOVING_HEADLINE' => 'Deleting an extension from your board', + 'EXTENSION_REMOVING_EXPLAIN' => [ + 'step_1' => 'Disable the extension', + 'step_2' => 'Delete the extension’s data', + 'step_3' => 'Delete the extension‘s files from the filesystem', + ], + 'EXTENSION_UPDATING_HEADLINE' => 'Updating an extension', + 'EXTENSION_UPDATING_EXPLAIN' => [ + 'step_1' => 'Disable the extension', + 'step_2' => 'Delete the extension’s files from the filesystem', + 'step_3' => 'Upload the new files', + 'step_4' => 'Enable the extension', + ], 'EXTENSION_DELETE_DATA_CONFIRM' => 'Are you sure that you wish to delete the data associated with “%s”?

      This removes all of its data and settings and cannot be undone!', 'EXTENSION_DISABLE_CONFIRM' => 'Are you sure that you wish to disable the “%s” extension?', From 48cc96b489366641a818888ad45578c2a2948398 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Fri, 14 Jun 2024 23:10:09 +0200 Subject: [PATCH 010/276] [ticket/17335] Add lang_raw twig function for templates PHPBB-17335 --- phpBB/phpbb/template/twig/extension.php | 13 +++++++++++++ tests/template/template_test.php | 6 +++--- tests/template/templates/lang_twig.html | 4 ++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/phpBB/phpbb/template/twig/extension.php b/phpBB/phpbb/template/twig/extension.php index 2e920dbe4b..7fde9e2cac 100644 --- a/phpBB/phpbb/template/twig/extension.php +++ b/phpBB/phpbb/template/twig/extension.php @@ -93,6 +93,7 @@ class extension extends \Twig\Extension\AbstractExtension new \Twig\TwigFunction('lang', array($this, 'lang')), new \Twig\TwigFunction('lang_defined', array($this, 'lang_defined')), new \Twig\TwigFunction('lang_js', [$this, 'lang_js']), + new \Twig\TwigFunction('lang_raw', [$this, 'lang_raw']), new \Twig\TwigFunction('get_class', 'get_class'), ); } @@ -214,4 +215,16 @@ class extension extends \Twig\Extension\AbstractExtension return twig_escape_filter($this->environment, call_user_func_array([$this, 'lang'], $args), 'js'); } + + /** + * Get raw value associated with lang key + * + * @param string $key + * + * @return array|string Raw value associated with lang key + */ + public function lang_raw(string $key): array|string + { + return call_user_func_array(array($this->language, 'lang_raw'), [$key]); + } } diff --git a/tests/template/template_test.php b/tests/template/template_test.php index 8faa52d8ac..4fc9858366 100644 --- a/tests/template/template_test.php +++ b/tests/template/template_test.php @@ -365,15 +365,15 @@ class phpbb_template_template_test extends phpbb_template_template_test_case array(), array(), array(), - "VARIABLE\n1_VARIABLE\nVARIABLE\n1_VARIABLE", + "VARIABLE\n1_VARIABLE\nVARIABLE\n1_VARIABLE\nVARIABLE\n1_VARIABLE\nARY_VARIABLE", ), array( 'lang_twig.html', array(), array(), array(), - "Value'\n1 O'Clock\nValue\\u0027\n1\\u0020O\\u0027Clock", - array('VARIABLE' => "Value'", '1_VARIABLE' => "1 O'Clock"), + "Value'\n1 O'Clock\nValue\\u0027\n1\\u0020O\\u0027Clock\nValue'\n1 O'Clock\nfoo|bar", + array('VARIABLE' => "Value'", '1_VARIABLE' => "1 O'Clock", 'ARY_VARIABLE' => ['foo', 'bar']), ), array( 'loop_nested_multilevel_ref.html', diff --git a/tests/template/templates/lang_twig.html b/tests/template/templates/lang_twig.html index bf31012819..a331c7f506 100644 --- a/tests/template/templates/lang_twig.html +++ b/tests/template/templates/lang_twig.html @@ -3,3 +3,7 @@ {{ lang_js('VARIABLE') }} {{ lang_js('1_VARIABLE') }} + +{{ lang_raw('VARIABLE') }} +{{ lang_raw('1_VARIABLE') }} +{{ lang_raw('ARY_VARIABLE')|join('|') }} From 444137531ff0d6650170e4cd76e82049c8656f8c Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Fri, 14 Jun 2024 14:43:40 -0700 Subject: [PATCH 011/276] [ticket/17335] Use lang_raw PHPBB-17335 Signed-off-by: Matt Friedman --- phpBB/adm/style/acp_ext_list.html | 19 +++++++++---------- phpBB/language/en/acp/extensions.php | 20 ++++++++++---------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/phpBB/adm/style/acp_ext_list.html b/phpBB/adm/style/acp_ext_list.html index b8b3d2c68a..dc6dcf1797 100644 --- a/phpBB/adm/style/acp_ext_list.html +++ b/phpBB/adm/style/acp_ext_list.html @@ -106,9 +106,9 @@
        -
      1. {{ lang(['EXTENSION_INSTALLING_EXPLAIN', 'step_1']) }}
      2. -
      3. {{ lang(['EXTENSION_INSTALLING_EXPLAIN', 'step_2']) }}
      4. -
      5. {{ lang(['EXTENSION_INSTALLING_EXPLAIN', 'step_3']) }}
      6. + {% for step in lang_raw('EXTENSION_INSTALLING_EXPLAIN') %} +
      7. {{ step }}
      8. + {% endfor %}
      @@ -118,10 +118,9 @@
        -
      1. {{ lang(['EXTENSION_UPDATING_EXPLAIN', 'step_1']) }}
      2. -
      3. {{ lang(['EXTENSION_UPDATING_EXPLAIN', 'step_2']) }}
      4. -
      5. {{ lang(['EXTENSION_UPDATING_EXPLAIN', 'step_3']) }}
      6. -
      7. {{ lang(['EXTENSION_UPDATING_EXPLAIN', 'step_4']) }}
      8. + {% for step in lang_raw('EXTENSION_UPDATING_EXPLAIN') %} +
      9. {{ step }}
      10. + {% endfor %}
      @@ -131,9 +130,9 @@
        -
      1. {{ lang(['EXTENSION_REMOVING_EXPLAIN', 'step_1']) }}
      2. -
      3. {{ lang(['EXTENSION_REMOVING_EXPLAIN', 'step_2']) }}
      4. -
      5. {{ lang(['EXTENSION_REMOVING_EXPLAIN', 'step_3']) }}
      6. + {% for step in lang_raw('EXTENSION_REMOVING_EXPLAIN') %} +
      7. {{ step }}
      8. + {% endfor %}
      diff --git a/phpBB/language/en/acp/extensions.php b/phpBB/language/en/acp/extensions.php index 311cfa74f3..bf854cdb7b 100644 --- a/phpBB/language/en/acp/extensions.php +++ b/phpBB/language/en/acp/extensions.php @@ -91,22 +91,22 @@ $lang = array_merge($lang, array( 'EXTENSION_OPTIONS' => 'Options', 'EXTENSION_INSTALLING_HEADLINE' => 'Installing an extension', 'EXTENSION_INSTALLING_EXPLAIN' => [ - 'step_1' => 'Download an extension from phpBB’s extensions database', - 'step_2' => 'Unzip the extension and upload it to the ext/ directory of your phpBB board', - 'step_3' => 'Enable the extension, here in the Extensions manager', + 0 => 'Download an extension from phpBB’s extensions database', + 1 => 'Unzip the extension and upload it to the ext/ directory of your phpBB board', + 2 => 'Enable the extension, here in the Extensions manager', ], 'EXTENSION_REMOVING_HEADLINE' => 'Deleting an extension from your board', 'EXTENSION_REMOVING_EXPLAIN' => [ - 'step_1' => 'Disable the extension', - 'step_2' => 'Delete the extension’s data', - 'step_3' => 'Delete the extension‘s files from the filesystem', + 0 => 'Disable the extension', + 1 => 'Delete the extension’s data', + 2 => 'Delete the extension‘s files from the filesystem', ], 'EXTENSION_UPDATING_HEADLINE' => 'Updating an extension', 'EXTENSION_UPDATING_EXPLAIN' => [ - 'step_1' => 'Disable the extension', - 'step_2' => 'Delete the extension’s files from the filesystem', - 'step_3' => 'Upload the new files', - 'step_4' => 'Enable the extension', + 0 => 'Disable the extension', + 1 => 'Delete the extension’s files from the filesystem', + 2 => 'Upload the new files', + 3 => 'Enable the extension', ], 'EXTENSION_DELETE_DATA_CONFIRM' => 'Are you sure that you wish to delete the data associated with “%s”?

      This removes all of its data and settings and cannot be undone!', From d2cd8ecf6648e90fd0b4a87ff9dc4ddc48a466da Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sat, 15 Jun 2024 11:41:16 +0200 Subject: [PATCH 012/276] [ticket/17342] Add tests for PHP 8.4 to GitHub Actions PHPBB-17342 --- .github/workflows/tests.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cbf31fc288..9dd53fafa5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -137,6 +137,10 @@ jobs: db: "mysql:5.7" - php: '8.3' db: "mariadb:10.2" + - php: '8.4' + db: "mysql:8.0" + - php: '8.4' + db: "mariadb:10.3" name: PHP ${{ matrix.php }} - ${{ matrix.db_alias != '' && matrix.db_alias || matrix.db }} @@ -272,6 +276,8 @@ jobs: db: "postgres:9.5" - php: '8.3' db: "postgres:9.5" + - php: '8.4' + db: "postgres:9.5" name: PHP ${{ matrix.php }} - ${{ matrix.db }} From 0fc1a8c1f8c1d7a2781644857ebb58db489c4137 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sun, 16 Jun 2024 08:49:36 -0700 Subject: [PATCH 013/276] [ticket/17344] Show an alert when webpush subscribing is denied PHPBB-17344 --- phpBB/assets/javascript/webpush.js | 1 + phpBB/language/en/common.php | 1 + phpBB/styles/prosilver/template/notification_dropdown.html | 2 +- phpBB/styles/prosilver/template/ucp_notifications_options.html | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/phpBB/assets/javascript/webpush.js b/phpBB/assets/javascript/webpush.js index c326fe1cff..94e542d2ae 100644 --- a/phpBB/assets/javascript/webpush.js +++ b/phpBB/assets/javascript/webpush.js @@ -150,6 +150,7 @@ function PhpbbWebpush() { // Prevent the user from clicking the subscribe button multiple times. const result = await Notification.requestPermission(); if (result === 'denied') { + phpbb.alert(subscribeButton.getAttribute('data-l-err'), subscribeButton.getAttribute('data-l-msg')); return; } diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 5933cc8f5c..43269679bf 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -515,6 +515,7 @@ $lang = array_merge($lang, array( 'NOTIFY_WEB_PUSH_ENABLE' => 'Enable Web Push notifications', 'NOTIFY_WEB_PUSH_SUBSCRIBE' => 'Subscribe', 'NOTIFY_WEB_PUSH_SUBSCRIBED'=> 'Subscribed', + 'NOTIFY_WEB_PUSH_DENIED' => 'You have denied notifications from this site. To subscribe, please allow notifications in your browser settings.', 'NO_ACCESS_ATTACHMENT' => 'You are not allowed to access this file.', 'NO_ACTION' => 'No action specified.', 'NO_ADMINISTRATORS' => 'There are no administrators.', diff --git a/phpBB/styles/prosilver/template/notification_dropdown.html b/phpBB/styles/prosilver/template/notification_dropdown.html index ff52543d0a..abd5c85bfd 100644 --- a/phpBB/styles/prosilver/template/notification_dropdown.html +++ b/phpBB/styles/prosilver/template/notification_dropdown.html @@ -47,7 +47,7 @@ {% if NOTIFICATIONS_WEBPUSH_ENABLE and notification_types is not defined %} {% endif %} diff --git a/phpBB/styles/prosilver/template/ucp_notifications_options.html b/phpBB/styles/prosilver/template/ucp_notifications_options.html index b3be983f16..27981581ff 100644 --- a/phpBB/styles/prosilver/template/ucp_notifications_options.html +++ b/phpBB/styles/prosilver/template/ucp_notifications_options.html @@ -10,7 +10,7 @@

      {{ lang('NOTIFY_WEBPUSH_ENABLE_EXPLAIN') }}
      - +
      From f3ca92ffe78b832ac9f39633d5422520bb87fa6e Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sun, 16 Jun 2024 09:01:39 -0700 Subject: [PATCH 014/276] [ticket/17344] Responsive mobile friendly webpush sub button PHPBB-17344 --- phpBB/styles/prosilver/theme/common.css | 1 + phpBB/styles/prosilver/theme/responsive.css | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index 2300f9c611..f679df7c9f 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -1347,6 +1347,7 @@ ul.linklist:after, flex-wrap: nowrap; justify-content: space-between; padding: 5px 10px; + gap: 20px; } .notification-avatar, diff --git a/phpBB/styles/prosilver/theme/responsive.css b/phpBB/styles/prosilver/theme/responsive.css index 5deb7224a6..481b1a23d3 100644 --- a/phpBB/styles/prosilver/theme/responsive.css +++ b/phpBB/styles/prosilver/theme/responsive.css @@ -20,6 +20,16 @@ } } +@media (max-width: 550px) { + .dropdown-extended .notification-dropdown-footer .notification-subscribe_toggle > span { + display: none; + } + + .dropdown-extended .notification-dropdown-footer .notification-subscribe_toggle > .icon { + font-size: 24px; + } +} + @media (max-width: 430px) { .action-bar .search-box .inputbox { width: 120px; From 16743e934523078b2020b1a975f157900fc1e7ae Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sun, 16 Jun 2024 09:43:02 -0700 Subject: [PATCH 015/276] [ticket/17344] Improve webpush class names PHPBB-17344 --- .../prosilver/template/notification_dropdown.html | 6 +++--- phpBB/styles/prosilver/theme/buttons.css | 2 +- phpBB/styles/prosilver/theme/colours.css | 6 +++++- phpBB/styles/prosilver/theme/common.css | 3 +-- phpBB/styles/prosilver/theme/responsive.css | 8 +------- tests/functional/notification_webpush_test.php | 10 +++++----- 6 files changed, 16 insertions(+), 19 deletions(-) diff --git a/phpBB/styles/prosilver/template/notification_dropdown.html b/phpBB/styles/prosilver/template/notification_dropdown.html index abd5c85bfd..de5a8c79e6 100644 --- a/phpBB/styles/prosilver/template/notification_dropdown.html +++ b/phpBB/styles/prosilver/template/notification_dropdown.html @@ -45,10 +45,10 @@ {L_SEE_ALL} {% if NOTIFICATIONS_WEBPUSH_ENABLE and notification_types is not defined %} -