From 481322e6ae589ddda2b9a6d4a304b4cecafaebbf Mon Sep 17 00:00:00 2001 From: Tom Arild Jakobsen Date: Mon, 8 May 2017 14:17:29 +0200 Subject: [PATCH 01/10] Deprecate 'overrideSettings' * Deprecate and log warning to console when 'overrideSettings' is used * Change confirmation dialog be 'fixed' e.g relative to viewport instead of and arbitrary relative parent element * Same for the overlay mask * Set minimum height on body element, to fit confirmation dialog * Remove the minimum height on close dialog Fixes HFP-574 --- js/h5p-confirmation-dialog.js | 12 +++++++++++- js/h5p.js | 21 +++++---------------- styles/h5p-confirmation-dialog.css | 4 ++-- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/js/h5p-confirmation-dialog.js b/js/h5p-confirmation-dialog.js index d34f620..22ca96c 100644 --- a/js/h5p-confirmation-dialog.js +++ b/js/h5p-confirmation-dialog.js @@ -315,7 +315,7 @@ H5P.ConfirmationDialog = (function (EventDispatcher) { if (resizeIFrame && options.instance) { var minHeight = parseInt(popup.offsetHeight, 10) + exitButtonOffset + (2 * shadowOffset); - wrapperElement.style.minHeight = minHeight + 'px'; + self.setViewPortMinimumHeight(minHeight); options.instance.trigger('resize'); resizeIFrame = false; } @@ -340,10 +340,20 @@ H5P.ConfirmationDialog = (function (EventDispatcher) { setTimeout(function () { popupBackground.classList.add('hidden'); wrapperElement.removeChild(popupBackground); + self.setViewPortMinimumHeight(null); }, 100); return this; }; + + /** + * Sets the minimum height of the view port + * + * @param {number|null} minHeight + */ + this.setViewPortMinimumHeight = function(minHeight) { + document.body.style.minHeight = (typeof minHeight === 'number') ? (minHeight + 'px') : minHeight; + }; } ConfirmationDialog.prototype = Object.create(EventDispatcher.prototype); diff --git a/js/h5p.js b/js/h5p.js index 36e2709..26bd5f2 100644 --- a/js/h5p.js +++ b/js/h5p.js @@ -1000,24 +1000,13 @@ H5P.findCopyrights = function (info, parameters, contentId) { continue; // Do not check } - /* - * TODO: Make parameters clean again - * Some content types adds jQuery or other objects to parameters - * in order to determine override settings for sub-content-types. - * For instance Question Set tells Multiple Choice that it should - * attach Multi Choice's confirmation dialog to a Question Set - * jQuery element, so that the confirmation dialog will not be restricted - * to the space confined by Multi Choice. - * Ideally this should not be added to parameters, we must make a better - * solution. We should likely be adding these to sub-content through - * functions/setters instead of passing them down as params. - * - * This solution is implemented as a hack that will ignore all parameters - * inside a "overrideSettings" field, this should suffice for now since - * all overridden objects are added to this field, however this is not very - * robust solution and will very likely lead to problems in the future. + /** + * @deprecated This hack should be removed after 2017-11-01 + * The code that was using this was removed by HFP-574 */ if (field === 'overrideSettings') { + console.warn("The semantics field 'overrideSettings' is DEPRECATED and should not be used."); + console.warn(parameters); continue; } diff --git a/styles/h5p-confirmation-dialog.css b/styles/h5p-confirmation-dialog.css index 5a8f597..9e5f98f 100644 --- a/styles/h5p-confirmation-dialog.css +++ b/styles/h5p-confirmation-dialog.css @@ -1,5 +1,5 @@ .h5p-confirmation-dialog-background { - position: absolute; + position: fixed; height: 100%; width: 100%; left: 0; @@ -30,7 +30,7 @@ } .h5p-confirmation-dialog-popup { - position: absolute; + position: fixed; display: flex; flex-direction: column; justify-content: center; From f277fed4d1240776921c710acc3dcca749fb861d Mon Sep 17 00:00:00 2001 From: Tom Arild Jakobsen Date: Wed, 10 May 2017 13:50:48 +0200 Subject: [PATCH 02/10] Set overlay and dialog to be 'position: absolute;' again. HFP-574 --- styles/h5p-confirmation-dialog.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/styles/h5p-confirmation-dialog.css b/styles/h5p-confirmation-dialog.css index 9e5f98f..5a8f597 100644 --- a/styles/h5p-confirmation-dialog.css +++ b/styles/h5p-confirmation-dialog.css @@ -1,5 +1,5 @@ .h5p-confirmation-dialog-background { - position: fixed; + position: absolute; height: 100%; width: 100%; left: 0; @@ -30,7 +30,7 @@ } .h5p-confirmation-dialog-popup { - position: fixed; + position: absolute; display: flex; flex-direction: column; justify-content: center; From 87bd3c7e1132854b7abe3148d1f34b266806b4ae Mon Sep 17 00:00:00 2001 From: Tom Arild Jakobsen Date: Thu, 11 May 2017 17:09:44 +0200 Subject: [PATCH 03/10] Resize h5p container instead of body by default. HFP-574 --- js/h5p-confirmation-dialog.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/h5p-confirmation-dialog.js b/js/h5p-confirmation-dialog.js index 22ca96c..a6dd998 100644 --- a/js/h5p-confirmation-dialog.js +++ b/js/h5p-confirmation-dialog.js @@ -352,7 +352,8 @@ H5P.ConfirmationDialog = (function (EventDispatcher) { * @param {number|null} minHeight */ this.setViewPortMinimumHeight = function(minHeight) { - document.body.style.minHeight = (typeof minHeight === 'number') ? (minHeight + 'px') : minHeight; + var container = document.querySelector('.h5p-container') || document.body; + container.style.minHeight = (typeof minHeight === 'number') ? (minHeight + 'px') : minHeight; }; } From d2746b18b4db1c1fb6ca9f5e15297dd1cdb1c71a Mon Sep 17 00:00:00 2001 From: thomasmars Date: Thu, 22 Jun 2017 10:56:15 +0200 Subject: [PATCH 04/10] Make fullscreen button keyboard accessible HFP-1199 --- js/h5p.js | 23 ++++++++++++++++++++--- styles/h5p.css | 9 ++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/js/h5p.js b/js/h5p.js index 9c0846b..1d9c17f 100644 --- a/js/h5p.js +++ b/js/h5p.js @@ -133,9 +133,26 @@ H5P.init = function (target) { // Check if we should add and display a fullscreen button for this H5P. if (contentData.fullScreen == 1 && H5P.fullscreenSupported) { - H5P.jQuery('
').prependTo($container).children().click(function () { - H5P.fullScreen($container, instance); - }); + H5P.jQuery( + '
' + + '
' + + '
' + + '
') + .prependTo($container) + .children() + .click(function () { + H5P.fullScreen($container, instance); + }) + .keydown(function (e) { + if (e.which === 32 || e.which === 13) { + H5P.fullScreen($container, instance); + return false; + } + }) + ; } /** diff --git a/styles/h5p.css b/styles/h5p.css index 760c916..7696348 100755 --- a/styles/h5p.css +++ b/styles/h5p.css @@ -108,13 +108,20 @@ body.h5p-semi-fullscreen { width: 1.125em; height: 0.925em; text-indent: -0.0875em; - outline: none; } .h5p-disable-fullscreen { line-height: 0.925em; width: 1.1em; height: 0.9em; } + +.h5p-enable-fullscreen:focus, +.h5p-disable-fullscreen:focus { + outline-style: solid; + outline-width: 1px; + outline-offset: 0.25em; +} + .h5p-enable-fullscreen:hover, .h5p-disable-fullscreen:hover { background: rgba(0,0,0,0.5); } From 6444c1443bb226ad20c1e80304371ed236215b83 Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Mon, 26 Jun 2017 10:43:59 +0200 Subject: [PATCH 05/10] Bump coreApi due to editor changes HFP-1174 --- h5p.classes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/h5p.classes.php b/h5p.classes.php index 32aeb38..b582ff8 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -1724,7 +1724,7 @@ class H5PCore { public static $coreApi = array( 'majorVersion' => 1, - 'minorVersion' => 13 + 'minorVersion' => 14 ); public static $styles = array( 'styles/h5p.css', From cc7caa660418e6e0e3bde38826ade340bdfea3d2 Mon Sep 17 00:00:00 2001 From: Timothy Lim Date: Fri, 7 Jul 2017 09:56:24 +0200 Subject: [PATCH 06/10] HFP-1258 Whitelist .vtt extension --- h5p.classes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/h5p.classes.php b/h5p.classes.php index 32aeb38..9c88aac 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -1746,7 +1746,7 @@ class H5PCore { 'js/h5p-utils.js', ); - public static $defaultContentWhitelist = 'json png jpg jpeg gif bmp tif tiff svg eot ttf woff woff2 otf webm mp4 ogg mp3 wav txt pdf rtf doc docx xls xlsx ppt pptx odt ods odp xml csv diff patch swf md textile'; + public static $defaultContentWhitelist = 'json png jpg jpeg gif bmp tif tiff svg eot ttf woff woff2 otf webm mp4 ogg mp3 wav txt pdf rtf doc docx xls xlsx ppt pptx odt ods odp xml csv diff patch swf md textile vtt'; public static $defaultLibraryWhitelistExtras = 'js css'; public $librariesJsonData, $contentJsonData, $mainJsonData, $h5pF, $fs, $h5pD, $disableFileCheck; From 91ff99145ad2358a6b9975842d0b43ca77e65e2c Mon Sep 17 00:00:00 2001 From: Timothy Lim Date: Fri, 7 Jul 2017 10:11:23 +0200 Subject: [PATCH 07/10] HFP-1258 Whitelist .webvtt --- h5p.classes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/h5p.classes.php b/h5p.classes.php index 9c88aac..0ab4cfd 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -1746,7 +1746,7 @@ class H5PCore { 'js/h5p-utils.js', ); - public static $defaultContentWhitelist = 'json png jpg jpeg gif bmp tif tiff svg eot ttf woff woff2 otf webm mp4 ogg mp3 wav txt pdf rtf doc docx xls xlsx ppt pptx odt ods odp xml csv diff patch swf md textile vtt'; + public static $defaultContentWhitelist = 'json png jpg jpeg gif bmp tif tiff svg eot ttf woff woff2 otf webm mp4 ogg mp3 wav txt pdf rtf doc docx xls xlsx ppt pptx odt ods odp xml csv diff patch swf md textile vtt webvtt'; public static $defaultLibraryWhitelistExtras = 'js css'; public $librariesJsonData, $contentJsonData, $mainJsonData, $h5pF, $fs, $h5pD, $disableFileCheck; From b1531bcbc09c57ff4965cd179cad7e3252b2e6ff Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Fri, 7 Jul 2017 10:51:57 +0200 Subject: [PATCH 08/10] Add support for temporary file suffix HFP-1100 --- h5p-default-storage.class.php | 12 ++++++++++++ h5p.classes.php | 5 +++++ js/h5p.js | 3 ++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/h5p-default-storage.class.php b/h5p-default-storage.class.php index 8d2daf8..38af307 100644 --- a/h5p-default-storage.class.php +++ b/h5p-default-storage.class.php @@ -426,6 +426,18 @@ class H5PDefaultStorage implements \H5PFileStorage { $path = "{$this->path}/content/{$contentId}/{$file}"; if (file_exists($path)) { unlink($path); + + // Clean up any empty parent directories to avoid cluttering the file system + $parts = explode('/', $path); + while (array_pop($parts) !== NULL) { + $dir = implode('/', $parts); + if (is_dir($dir) && count(scandir($dir)) === 2) { // empty contains '.' and '..' + rmdir($dir); // Remove empty parent + } + else { + return; // Not empty + } + } } } diff --git a/h5p.classes.php b/h5p.classes.php index 32aeb38..51fd853 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -3400,6 +3400,11 @@ class H5PContentValidator { $file->path = $matches[5]; } + // Remove temporary files suffix + if (substr($file->path, -4, 4) === '#tmp') { + $file->path = substr($file->path, 0, strlen($file->path) - 4); + } + // Make sure path and mime does not have any special chars $file->path = htmlspecialchars($file->path, ENT_QUOTES, 'UTF-8', FALSE); if (isset($file->mime)) { diff --git a/js/h5p.js b/js/h5p.js index 2ad916f..b2d13b3 100644 --- a/js/h5p.js +++ b/js/h5p.js @@ -678,7 +678,8 @@ H5P.getPath = function (path, contentId) { } var prefix; - if (contentId !== undefined) { + var isTmpFile = (path.substr(-4,4) === '#tmp'); + if (contentId !== undefined && !isTmpFile) { // Check for custom override URL if (H5PIntegration.contents !== undefined && H5PIntegration.contents['cid-' + contentId]) { From 75803f8dfb3d249241ce00512055637aa2fbcf13 Mon Sep 17 00:00:00 2001 From: Cornel Les Date: Thu, 20 Jul 2017 17:54:12 +0300 Subject: [PATCH 09/10] Fixing font-family regex pattern when validating text --- h5p.classes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/h5p.classes.php b/h5p.classes.php index 1cd94e2..f08eeb0 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -3163,7 +3163,7 @@ class H5PContentValidator { $stylePatterns[] = '/^font-size: *[0-9.]+(em|px|%) *;?$/i'; } if (isset($semantics->font->family) && $semantics->font->family) { - $stylePatterns[] = '/^font-family: *[a-z0-9," ]+;?$/i'; + $stylePatterns[] = '/^font-family: *[-a-z0-9," ]+;?$/i'; } if (isset($semantics->font->color) && $semantics->font->color) { $stylePatterns[] = '/^color: *(#[a-f0-9]{3}[a-f0-9]{3}?|rgba?\([0-9, ]+\)) *;?$/i'; From 7728243c188c813dcdafbf3466a8e95e7ef3c1d7 Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Thu, 27 Jul 2017 13:36:51 +0200 Subject: [PATCH 10/10] Improve hashing logic --- h5p.classes.php | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/h5p.classes.php b/h5p.classes.php index f08eeb0..7c0e546 100644 --- a/h5p.classes.php +++ b/h5p.classes.php @@ -2790,16 +2790,8 @@ class H5PCore { * @return string token */ public static function createToken($action) { - if (!isset($_SESSION['h5p_token'])) { - // Create an unique key which is used to create action tokens for this session. - $_SESSION['h5p_token'] = uniqid(); - } - - // Timefactor - $time_factor = self::getTimeFactor(); - // Create and return token - return substr(hash('md5', $action . $time_factor . $_SESSION['h5p_token']), -16, 13); + return self::hashToken($action, self::getTimeFactor()); } /** @@ -2810,6 +2802,31 @@ class H5PCore { return ceil(time() / (86400 / 2)); } + /** + * Generate a unique hash string based on action, time and token + * + * @param string $action + * @param int $time_factor + * @return string + */ + private static function hashToken($action, $time_factor) { + if (!isset($_SESSION['h5p_token'])) { + // Create an unique key which is used to create action tokens for this session. + if (function_exists('random_bytes')) { + $_SESSION['h5p_token'] = base64_encode(random_bytes(15)); + } + else if (function_exists('openssl_random_pseudo_bytes')) { + $_SESSION['h5p_token'] = base64_encode(openssl_random_pseudo_bytes(15)); + } + else { + $_SESSION['h5p_token'] = uniqid('', TRUE); + } + } + + // Create hash and return + return substr(hash('md5', $action . $time_factor . $_SESSION['h5p_token']), -16, 13); + } + /** * Verify if the given token is valid for the given action. * @@ -2818,9 +2835,12 @@ class H5PCore { * @return boolean valid token */ public static function validToken($action, $token) { + // Get the timefactor $time_factor = self::getTimeFactor(); - return $token === substr(hash('md5', $action . $time_factor . $_SESSION['h5p_token']), -16, 13) || // Under 12 hours - $token === substr(hash('md5', $action . ($time_factor - 1) . $_SESSION['h5p_token']), -16, 13); // Between 12-24 hours + + // Check token to see if it's valid + return $token === self::hashToken($action, $time_factor) || // Under 12 hours + $token === self::hashToken($action, $time_factor - 1); // Between 12-24 hours } /**