diff --git a/core/js/js.js b/core/js/js.js index f9a5f2b338129f58bec871fd71b81013fa4db044..872761c02bbe2044c612d238bf2ebdcb8fe95bd3 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -1675,13 +1675,16 @@ function initCore() { OC.PasswordConfirmation = { callback: null, - + pageLoadTime: null, init: function() { $('.password-confirm-required').on('click', _.bind(this.requirePasswordConfirmation, this)); + this.pageLoadTime = moment.now(); }, requiresPasswordConfirmation: function() { - var timeSinceLogin = moment.now() - (nc_lastLogin * 1000); + var serverTimeDiff = this.pageLoadTime - (nc_pageLoad * 1000); + var timeSinceLogin = moment.now() - (serverTimeDiff + (nc_lastLogin * 1000)); + // if timeSinceLogin > 30 minutes and user backend allows password confirmation return (backendAllowsPasswordConfirmation && timeSinceLogin > 30 * 60 * 1000); }, diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js index b6c617303cfc6aa682d69a10f779b21b58597dd5..616e7509f7cbff78cf5b0ac59e015c2d8a1f5b65 100644 --- a/core/js/tests/specs/coreSpec.js +++ b/core/js/tests/specs/coreSpec.js @@ -1539,4 +1539,65 @@ describe('Core base tests', function() { expect(snapperStub.close.calledTwice).toBe(true); }); }); + describe('Requires password confirmation', function () { + var stubMomentNow; + var stubJsPageLoadTime; + + afterEach(function () { + delete window.nc_pageLoad; + delete window.nc_lastLogin; + delete window.backendAllowsPasswordConfirmation; + + stubMomentNow.restore(); + stubJsPageLoadTime.restore(); + }); + + it('should not show the password confirmation dialog when server time is earlier than local time', function () { + // add server variables + window.nc_pageLoad = parseInt(new Date(2018, 0, 3, 1, 15, 0).getTime() / 1000); + window.nc_lastLogin = parseInt(new Date(2018, 0, 3, 1, 0, 0).getTime() / 1000); + window.backendAllowsPasswordConfirmation = true; + + stubJsPageLoadTime = sinon.stub(OC.PasswordConfirmation, 'pageLoadTime').value(new Date(2018, 0, 3, 12, 15, 0).getTime()); + stubMomentNow = sinon.stub(moment, 'now').returns(new Date(2018, 0, 3, 12, 20, 0).getTime()); + + expect(OC.PasswordConfirmation.requiresPasswordConfirmation()).toBeFalsy(); + }); + + it('should show the password confirmation dialog when server time is earlier than local time', function () { + // add server variables + window.nc_pageLoad = parseInt(new Date(2018, 0, 3, 1, 15, 0).getTime() / 1000); + window.nc_lastLogin = parseInt(new Date(2018, 0, 3, 1, 0, 0).getTime() / 1000); + window.backendAllowsPasswordConfirmation = true; + + stubJsPageLoadTime = sinon.stub(OC.PasswordConfirmation, 'pageLoadTime').value(new Date(2018, 0, 3, 12, 15, 0).getTime()); + stubMomentNow = sinon.stub(moment, 'now').returns(new Date(2018, 0, 3, 12, 31, 0).getTime()); + + expect(OC.PasswordConfirmation.requiresPasswordConfirmation()).toBeTruthy(); + }); + + it('should not show the password confirmation dialog when server time is later than local time', function () { + // add server variables + window.nc_pageLoad = parseInt(new Date(2018, 0, 3, 23, 15, 0).getTime() / 1000); + window.nc_lastLogin = parseInt(new Date(2018, 0, 3, 23, 0, 0).getTime() / 1000); + window.backendAllowsPasswordConfirmation = true; + + stubJsPageLoadTime = sinon.stub(OC.PasswordConfirmation, 'pageLoadTime').value(new Date(2018, 0, 3, 12, 15, 0).getTime()); + stubMomentNow = sinon.stub(moment, 'now').returns(new Date(2018, 0, 3, 12, 20, 0).getTime()); + + expect(OC.PasswordConfirmation.requiresPasswordConfirmation()).toBeFalsy(); + }); + + it('should show the password confirmation dialog when server time is later than local time', function () { + // add server variables + window.nc_pageLoad = parseInt(new Date(2018, 0, 3, 23, 15, 0).getTime() / 1000); + window.nc_lastLogin = parseInt(new Date(2018, 0, 3, 23, 0, 0).getTime() / 1000); + window.backendAllowsPasswordConfirmation = true; + + stubJsPageLoadTime = sinon.stub(OC.PasswordConfirmation, 'pageLoadTime').value(new Date(2018, 0, 3, 12, 15, 0).getTime()); + stubMomentNow = sinon.stub(moment, 'now').returns(new Date(2018, 0, 3, 12, 31, 0).getTime()); + + expect(OC.PasswordConfirmation.requiresPasswordConfirmation()).toBeTruthy(); + }); + }); }); diff --git a/lib/private/Template/JSConfigHelper.php b/lib/private/Template/JSConfigHelper.php index bdb747e1c9f81c84adb37d56d2ce5d3789c3d296..9f93ef784bc6750c440ccc5338b6e3b3bfb0ec7b 100644 --- a/lib/private/Template/JSConfigHelper.php +++ b/lib/private/Template/JSConfigHelper.php @@ -155,6 +155,7 @@ class JSConfigHelper { "oc_appswebroots" => str_replace('\\/', '/', json_encode($apps_paths)), // Ugly unescape slashes waiting for better solution "datepickerFormatDate" => json_encode($this->l->l('jsdate', null)), 'nc_lastLogin' => $lastConfirmTimestamp, + 'nc_pageLoad' => time(), "dayNames" => json_encode([ (string)$this->l->t('Sunday'), (string)$this->l->t('Monday'),