diff options
author | Robin Appelman <icewind@owncloud.com> | 2014-02-05 13:36:55 +0100 |
---|---|---|
committer | Robin Appelman <icewind@owncloud.com> | 2014-02-05 13:36:55 +0100 |
commit | 1e79369338e8435952e2eda60a2cfc49bb6c4882 (patch) | |
tree | 12d3ac88978887f16e795c54873bbd6b99bb8ee5 /core | |
parent | 3c1ab66edac1ba2f1b398c859cd933c410ea3d8d (diff) | |
parent | 3d88b10f201b7979f250b49b10360b3581030ec7 (diff) | |
download | nextcloud-server-1e79369338e8435952e2eda60a2cfc49bb6c4882.tar.gz nextcloud-server-1e79369338e8435952e2eda60a2cfc49bb6c4882.zip |
merge master into storagestatistics-reuse
Diffstat (limited to 'core')
-rw-r--r-- | core/ajax/share.php | 9 | ||||
-rw-r--r-- | core/css/icons.css | 4 | ||||
-rw-r--r-- | core/css/styles.css | 2 | ||||
-rw-r--r-- | core/img/actions/checkmark-white.png | bin | 0 -> 286 bytes | |||
-rw-r--r-- | core/img/actions/checkmark-white.svg | 4 | ||||
-rw-r--r-- | core/img/actions/toggle-filelist.png | bin | 0 -> 195 bytes | |||
-rw-r--r-- | core/img/actions/toggle-filelist.svg | 11 | ||||
-rw-r--r-- | core/img/actions/toggle-pictures.png | bin | 0 -> 193 bytes | |||
-rw-r--r-- | core/img/actions/toggle-pictures.svg | 9 | ||||
-rw-r--r-- | core/img/places/picture.png | bin | 242 -> 434 bytes | |||
-rw-r--r-- | core/img/places/picture.svg | 5 | ||||
-rw-r--r-- | core/js/config.php | 6 | ||||
-rw-r--r-- | core/js/core.json | 43 | ||||
-rw-r--r-- | core/js/js.js | 87 | ||||
-rw-r--r-- | core/js/tests/specHelper.js | 18 | ||||
-rw-r--r-- | core/js/tests/specs/coreSpec.js | 210 | ||||
-rw-r--r-- | core/setup.php | 73 | ||||
-rw-r--r-- | core/setup/controller.php | 138 | ||||
-rw-r--r-- | core/templates/installation.php | 78 | ||||
-rw-r--r-- | core/templates/layout.base.php | 2 | ||||
-rw-r--r-- | core/templates/layout.guest.php | 2 | ||||
-rw-r--r-- | core/templates/layout.user.php | 33 |
22 files changed, 533 insertions, 201 deletions
diff --git a/core/ajax/share.php b/core/ajax/share.php index 268cd4f53a7..8b48effb458 100644 --- a/core/ajax/share.php +++ b/core/ajax/share.php @@ -121,7 +121,7 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo if (isset($items[0]['expiration'])) { try { $date = new DateTime($items[0]['expiration']); - $expiration = $date->format('Y-m-d'); + $expiration = $l->l('date', $date->getTimestamp()); } catch (Exception $e) { \OCP\Util::writeLog('sharing', "Couldn't read date: " . $e->getMessage(), \OCP\Util::ERROR); } @@ -187,6 +187,8 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo break; case 'email': + // enable l10n support + $l = OC_L10N::get('core'); // read post variables $user = OCP\USER::getUser(); $displayName = OCP\User::getDisplayName(); @@ -199,16 +201,13 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo if (isset($_POST['expiration']) && $_POST['expiration'] !== '') { try { $date = new DateTime($_POST['expiration']); - $expiration = $date->format('Y-m-d'); + $expiration = $l->l('date', $date->getTimestamp()); } catch (Exception $e) { \OCP\Util::writeLog('sharing', "Couldn't read date: " . $e->getMessage(), \OCP\Util::ERROR); } } - // enable l10n support - $l = OC_L10N::get('core'); - // setup the email $subject = (string)$l->t('%s shared »%s« with you', array($displayName, $file)); diff --git a/core/css/icons.css b/core/css/icons.css index 57c37c5c51c..2dc35084122 100644 --- a/core/css/icons.css +++ b/core/css/icons.css @@ -47,6 +47,10 @@ background-image: url('../img/actions/checkmark.svg'); } +.icon-checkmark-white { + background-image: url('../img/actions/checkmark-white.svg'); +} + .icon-clock { background-image: url('../img/actions/clock.svg'); } diff --git a/core/css/styles.css b/core/css/styles.css index 03eb76ddce5..bee44785f12 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -686,7 +686,7 @@ label.infield { cursor:text !important; top:1.05em; left:.85em; } /* Apps management as sticky footer, less obtrusive in the list */ #navigation .wrapper { min-height: 100%; - margin: 0 auto -72px; + margin: 0 auto -82px 0; } #apps-management, #navigation .push { height: 72px; diff --git a/core/img/actions/checkmark-white.png b/core/img/actions/checkmark-white.png Binary files differnew file mode 100644 index 00000000000..08b8783649f --- /dev/null +++ b/core/img/actions/checkmark-white.png diff --git a/core/img/actions/checkmark-white.svg b/core/img/actions/checkmark-white.svg new file mode 100644 index 00000000000..5e8fe8abccc --- /dev/null +++ b/core/img/actions/checkmark-white.svg @@ -0,0 +1,4 @@ +<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" version="1.1" xml:space="preserve" height="16px" viewBox="-0.5 -0.5 16 16" width="16px" enable-background="new -0.5 -0.5 16 16" y="0px" x="0px" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" overflow="visible"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><defs> +</defs> +<path fill="#ffffff" d="M12.438,3.6875c-0.363,0-0.726,0.1314-1,0.4063l-4.5005,4.5-1.9687-2c-0.5498-0.5484-1.4489-0.5498-2,0l-0.5,0.5c-0.5512,0.5496-0.5512,1.4502,0,2l2.9687,2.9682c0.0063,0.007-0.0065,0.025,0,0.032l0.5,0.5c0.5497,0.55,1.4503,0.55,2,0l0.5-0.5,0.1875-0.219,5.313-5.2812c0.549-0.5498,0.549-1.4503,0-2l-0.5-0.5c-0.275-0.2749-0.638-0.4063-1-0.4063z" transform="translate(-0.5,-0.5)"/> +</svg> diff --git a/core/img/actions/toggle-filelist.png b/core/img/actions/toggle-filelist.png Binary files differnew file mode 100644 index 00000000000..45d363f1934 --- /dev/null +++ b/core/img/actions/toggle-filelist.png diff --git a/core/img/actions/toggle-filelist.svg b/core/img/actions/toggle-filelist.svg new file mode 100644 index 00000000000..940f6a49e63 --- /dev/null +++ b/core/img/actions/toggle-filelist.svg @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/"> + <g> + <rect rx=".5" ry=".5" height="4" width="4" y="1" x="1"/> + <rect rx=".5" ry=".5" height="1" width="9" y="2" x="6"/> + <rect rx=".5" ry=".5" height="4" width="4" y="6" x="1"/> + <rect rx=".5" ry=".5" height="1" width="9" y="7" x="6"/> + <rect rx=".5" ry=".5" height="4" width="4" y="11" x="1"/> + <rect rx=".5" ry=".5" height="1" width="9" y="12" x="6"/> + </g> +</svg> diff --git a/core/img/actions/toggle-pictures.png b/core/img/actions/toggle-pictures.png Binary files differnew file mode 100644 index 00000000000..8068d17e30d --- /dev/null +++ b/core/img/actions/toggle-pictures.png diff --git a/core/img/actions/toggle-pictures.svg b/core/img/actions/toggle-pictures.svg new file mode 100644 index 00000000000..5205c0226d1 --- /dev/null +++ b/core/img/actions/toggle-pictures.svg @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/"> + <g> + <rect rx=".5" ry=".5" height="6" width="6" y="1" x="1"/> + <rect rx=".5" ry=".5" height="6" width="6" y="1" x="9"/> + <rect rx=".5" ry=".5" height="6" width="6" y="9" x="9"/> + <rect rx=".5" ry=".5" height="6" width="6" y="9" x="1"/> + </g> +</svg> diff --git a/core/img/places/picture.png b/core/img/places/picture.png Binary files differindex 7b3af8c7f84..2b96ea518ce 100644 --- a/core/img/places/picture.png +++ b/core/img/places/picture.png diff --git a/core/img/places/picture.svg b/core/img/places/picture.svg index 791cbb5909a..82d457f5c7c 100644 --- a/core/img/places/picture.svg +++ b/core/img/places/picture.svg @@ -1,7 +1,4 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="32" width="32" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"> - <g transform="translate(581.71 -2.0765)"> - <path style="block-progression:tb;text-indent:0;color:#000000;text-transform:none" d="m-575.01 3.0806c-0.39495 0.0765-0.70712 0.46665-0.70001 0.87488l-0.00062 26.246c0.00001 0.45808 0.41045 0.87487 0.86155 0.87488h20.28c0.4511-0.000012 0.86154-0.4168 0.86155-0.87488l0.00061-25.921c-0.00065-0.67287-0.53099-1.2037-1.0337-1.1998h-20.27zm1.2998 19.996h18l0.00082 6h-18.001z"/> - <path style="block-progression:tb;text-indent:0;color:#000000;text-transform:none" d="m-575.01 4.0806c-0.39495 0.0765-0.70712 0.46665-0.70001 0.87488l-0.00062 26.246c0.00001 0.45808 0.41045 0.87487 0.86155 0.87488h20.28c0.4511-0.000012 0.86154-0.4168 0.86155-0.87488l0.00061-25.921c-0.00065-0.67287-0.53099-1.2037-1.0337-1.1998h-20.27zm1.2998 19.996h18l0.00082 6h-18.001z" fill="#fff"/> - </g> + <path style="block-progression:tb;color:#000000;text-transform:none;text-indent:0" fill="#fff" d="m0.6875 4c-0.39495 0.0765-0.69461 0.4668-0.6875 0.875v22.25c0.00001 0.458 0.4239 0.875 0.875 0.875h30.25c0.4511-0.000012 0.87499-0.41692 0.875-0.875v-21.906c-0.001-0.6731-0.529-1.2229-1.031-1.219zm2.3125 3h26v10l-2-2-5 7-6.625-4-9.1875 7h-3.1875zm6 3c-1.6569 0-3 1.3431-3 3s1.3431 3 3 3 3-1.3431 3-3-1.3431-3-3-3z"/> </svg> diff --git a/core/js/config.php b/core/js/config.php index dd46f7889d1..517ea1615a8 100644 --- a/core/js/config.php +++ b/core/js/config.php @@ -55,6 +55,12 @@ $array = array( ) ), "firstDay" => json_encode($l->l('firstday', 'firstday')) , + "oc_config" => json_encode( + array( + 'session_lifetime' => \OCP\Config::getSystemValue('session_lifetime', 60 * 60 * 24), + 'session_keepalive' => \OCP\Config::getSystemValue('session_keepalive', true) + ) + ) ); // Echo it diff --git a/core/js/core.json b/core/js/core.json index 79cfc42f587..4beab7cf796 100644 --- a/core/js/core.json +++ b/core/js/core.json @@ -1,28 +1,23 @@ { + "libraries": [ + "jquery-1.10.0.min.js", + "jquery-migrate-1.2.1.min.js", + "jquery-ui-1.10.0.custom.js", + "jquery-showpassword.js", + "jquery.infieldlabel.js", + "jquery.placeholder.js", + "jquery-tipsy.js" + ], "modules": [ - "jquery-1.10.0.min.js", - "jquery-migrate-1.2.1.min.js", - "jquery-ui-1.10.0.custom.js", - "jquery-showpassword.js", - "jquery.infieldlabel.js", - "jquery.placeholder.js", - "jquery-tipsy.js", - "compatibility.js", - "jquery.ocdialog.js", - "oc-dialogs.js", - "js.js", - "octemplate.js", - "eventsource.js", - "config.js", - "multiselect.js", - "search.js", - "router.js", - "oc-requesttoken.js", - "styles.js", - "apps.js", - "fixes.js", - "jquery-ui-2.10.0.custom.js", - "jquery-tipsy.js", - "jquery.ocdialog.js" + "compatibility.js", + "jquery.ocdialog.js", + "oc-dialogs.js", + "js.js", + "octemplate.js", + "eventsource.js", + "config.js", + "multiselect.js", + "router.js", + "oc-requesttoken.js" ] } diff --git a/core/js/js.js b/core/js/js.js index e84f482d672..cb177712a3a 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -11,6 +11,8 @@ var oc_webroot; var oc_current_user = document.getElementsByTagName('head')[0].getAttribute('data-user'); var oc_requesttoken = document.getElementsByTagName('head')[0].getAttribute('data-requesttoken'); +window.oc_config = window.oc_config || {}; + if (typeof oc_webroot === "undefined") { oc_webroot = location.pathname; var pos = oc_webroot.indexOf('/index.php/'); @@ -253,6 +255,12 @@ var OC={ return link; }, /** + * Redirect to the target URL, can also be used for downloads. + */ + redirect: function(targetUrl) { + window.location = targetUrl; + }, + /** * get the absolute path to an image file * @param app the app id to which the image belongs * @param file the name of the image file @@ -364,6 +372,34 @@ var OC={ } return result; }, + + /** + * Builds a URL query from a JS map. + * @param params parameter map + * @return string containing a URL query (without question) mark + */ + buildQueryString: function(params) { + var s = ''; + var first = true; + if (!params) { + return s; + } + for (var key in params) { + var value = params[key]; + if (first) { + first = false; + } + else { + s += '&'; + } + s += encodeURIComponent(key); + if (value !== null && typeof(value) !== 'undefined') { + s += '=' + encodeURIComponent(value); + } + } + return s; + }, + /** * Opens a popup with the setting for an app. * @param appid String. The ID of the app e.g. 'calendar', 'contacts' or 'files'. @@ -708,8 +744,39 @@ function fillWindow(selector) { console.warn("This function is deprecated! Use CSS instead"); } -$(document).ready(function(){ - sessionHeartBeat(); +/** + * Initializes core + */ +function initCore() { + + /** + * Calls the server periodically to ensure that session doesn't + * time out + */ + function initSessionHeartBeat(){ + // interval in seconds + var interval = 900; + if (oc_config.session_lifetime) { + interval = Math.floor(oc_config.session_lifetime / 2); + } + // minimum one minute + if (interval < 60) { + interval = 60; + } + OC.Router.registerLoadedCallback(function(){ + var url = OC.Router.generate('heartbeat'); + setInterval(function(){ + $.post(url); + }, interval * 1000); + }); + } + + // session heartbeat (defaults to enabled) + if (typeof(oc_config.session_keepalive) === 'undefined' || + !!oc_config.session_keepalive) { + + initSessionHeartBeat(); + } if(!SVGSupport()){ //replace all svg images with png images for browser that dont support svg replaceSVG(); @@ -822,7 +889,9 @@ $(document).ready(function(){ $('input[type=text]').focus(function(){ this.select(); }); -}); +} + +$(document).ready(initCore); /** * Filter Jquery selector by attribute value @@ -952,15 +1021,3 @@ jQuery.fn.exists = function(){ return this.length > 0; }; -/** - * Calls the server periodically every 15 mins to ensure that session doesnt - * time out - */ -function sessionHeartBeat(){ - OC.Router.registerLoadedCallback(function(){ - var url = OC.Router.generate('heartbeat'); - setInterval(function(){ - $.post(url); - }, 900000); - }); -} diff --git a/core/js/tests/specHelper.js b/core/js/tests/specHelper.js index 4a30878df51..1848d08354e 100644 --- a/core/js/tests/specHelper.js +++ b/core/js/tests/specHelper.js @@ -19,6 +19,8 @@ * */ +/* global OC */ + /** * Simulate the variables that are normally set by PHP code */ @@ -57,10 +59,15 @@ window.oc_webroot = location.href + '/'; window.oc_appswebroots = { "files": window.oc_webroot + '/apps/files/' }; +window.oc_config = { + session_lifetime: 600 * 1000, + session_keepalive: false +}; // global setup for all tests (function setupTests() { - var fakeServer = null; + var fakeServer = null, + routesRequestStub; beforeEach(function() { // enforce fake XHR, tests should not depend on the server and @@ -78,9 +85,18 @@ window.oc_appswebroots = { // make it globally available, so that other tests can define // custom responses window.fakeServer = fakeServer; + + OC.Router.routes = []; + OC.Router.routes_request = { + state: sinon.stub().returns('resolved'), + done: sinon.stub() + }; }); afterEach(function() { + OC.Router.routes_request.state.reset(); + OC.Router.routes_request.done.reset(); + // uncomment this to log requests // console.log(window.fakeServer.requests); fakeServer.restore(); diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js index 827669f270b..478505e9287 100644 --- a/core/js/tests/specs/coreSpec.js +++ b/core/js/tests/specs/coreSpec.js @@ -18,6 +18,8 @@ * License along with this library. If not, see <http://www.gnu.org/licenses/>. * */ + +/* global OC */ describe('Core base tests', function() { describe('Base values', function() { it('Sets webroots', function() { @@ -25,6 +27,103 @@ describe('Core base tests', function() { expect(OC.appswebroots).toBeDefined(); }); }); + describe('basename', function() { + it('Returns the nothing if no file name given', function() { + expect(OC.basename('')).toEqual(''); + }); + it('Returns the nothing if dir is root', function() { + expect(OC.basename('/')).toEqual(''); + }); + it('Returns the same name if no path given', function() { + expect(OC.basename('some name.txt')).toEqual('some name.txt'); + }); + it('Returns the base name if root path given', function() { + expect(OC.basename('/some name.txt')).toEqual('some name.txt'); + }); + it('Returns the base name if double root path given', function() { + expect(OC.basename('//some name.txt')).toEqual('some name.txt'); + }); + it('Returns the base name if subdir given without root', function() { + expect(OC.basename('subdir/some name.txt')).toEqual('some name.txt'); + }); + it('Returns the base name if subdir given with root', function() { + expect(OC.basename('/subdir/some name.txt')).toEqual('some name.txt'); + }); + it('Returns the base name if subdir given with double root', function() { + expect(OC.basename('//subdir/some name.txt')).toEqual('some name.txt'); + }); + it('Returns the base name if subdir has dot', function() { + expect(OC.basename('/subdir.dat/some name.txt')).toEqual('some name.txt'); + }); + it('Returns dot if file name is dot', function() { + expect(OC.basename('/subdir/.')).toEqual('.'); + }); + // TODO: fix the source to make it work like PHP's basename + it('Returns the dir itself if no file name given', function() { + // TODO: fix the source to make it work like PHP's dirname + // expect(OC.basename('subdir/')).toEqual('subdir'); + expect(OC.basename('subdir/')).toEqual(''); + }); + it('Returns the dir itself if no file name given with root', function() { + // TODO: fix the source to make it work like PHP's dirname + // expect(OC.basename('/subdir/')).toEqual('subdir'); + expect(OC.basename('/subdir/')).toEqual(''); + }); + }); + describe('dirname', function() { + it('Returns the nothing if no file name given', function() { + expect(OC.dirname('')).toEqual(''); + }); + it('Returns the root if dir is root', function() { + // TODO: fix the source to make it work like PHP's dirname + // expect(OC.dirname('/')).toEqual('/'); + expect(OC.dirname('/')).toEqual(''); + }); + it('Returns the root if dir is double root', function() { + // TODO: fix the source to make it work like PHP's dirname + // expect(OC.dirname('//')).toEqual('/'); + expect(OC.dirname('//')).toEqual('/'); // oh no... + }); + it('Returns dot if dir is dot', function() { + expect(OC.dirname('.')).toEqual('.'); + }); + it('Returns dot if no root given', function() { + // TODO: fix the source to make it work like PHP's dirname + // expect(OC.dirname('some dir')).toEqual('.'); + expect(OC.dirname('some dir')).toEqual('some dir'); // oh no... + }); + it('Returns the dir name if file name and root path given', function() { + // TODO: fix the source to make it work like PHP's dirname + // expect(OC.dirname('/some name.txt')).toEqual('/'); + expect(OC.dirname('/some name.txt')).toEqual(''); + }); + it('Returns the dir name if double root path given', function() { + expect(OC.dirname('//some name.txt')).toEqual('/'); // how lucky... + }); + it('Returns the dir name if subdir given without root', function() { + expect(OC.dirname('subdir/some name.txt')).toEqual('subdir'); + }); + it('Returns the dir name if subdir given with root', function() { + expect(OC.dirname('/subdir/some name.txt')).toEqual('/subdir'); + }); + it('Returns the dir name if subdir given with double root', function() { + // TODO: fix the source to make it work like PHP's dirname + // expect(OC.dirname('//subdir/some name.txt')).toEqual('/subdir'); + expect(OC.dirname('//subdir/some name.txt')).toEqual('//subdir'); // oh... + }); + it('Returns the dir name if subdir has dot', function() { + expect(OC.dirname('/subdir.dat/some name.txt')).toEqual('/subdir.dat'); + }); + it('Returns the dir name if file name is dot', function() { + expect(OC.dirname('/subdir/.')).toEqual('/subdir'); + }); + it('Returns the dir name if no file name given', function() { + expect(OC.dirname('subdir/')).toEqual('subdir'); + }); + it('Returns the dir name if no file name given with root', function() { + expect(OC.dirname('/subdir/')).toEqual('/subdir'); + }); + }); describe('Link functions', function() { var TESTAPP = 'testapp'; var TESTAPP_ROOT = OC.webroot + '/appsx/testapp'; @@ -67,4 +166,115 @@ describe('Core base tests', function() { }); }); }); + describe('Query string building', function() { + it('Returns empty string when empty params', function() { + expect(OC.buildQueryString()).toEqual(''); + expect(OC.buildQueryString({})).toEqual(''); + }); + it('Encodes regular query strings', function() { + expect(OC.buildQueryString({ + a: 'abc', + b: 'def' + })).toEqual('a=abc&b=def'); + }); + it('Encodes special characters', function() { + expect(OC.buildQueryString({ + unicode: '汉字', + })).toEqual('unicode=%E6%B1%89%E5%AD%97'); + expect(OC.buildQueryString({ + b: 'spaace value', + 'space key': 'normalvalue', + 'slash/this': 'amp&ersand' + })).toEqual('b=spaace%20value&space%20key=normalvalue&slash%2Fthis=amp%26ersand'); + }); + it('Encodes data types and empty values', function() { + expect(OC.buildQueryString({ + 'keywithemptystring': '', + 'keywithnull': null, + 'keywithundefined': null, + something: 'else' + })).toEqual('keywithemptystring=&keywithnull&keywithundefined&something=else'); + expect(OC.buildQueryString({ + 'booleanfalse': false, + 'booleantrue': true + })).toEqual('booleanfalse=false&booleantrue=true'); + expect(OC.buildQueryString({ + 'number': 123, + })).toEqual('number=123'); + }); + }); + describe('Session heartbeat', function() { + var clock, + oldConfig, + loadedStub, + routeStub, + counter; + + beforeEach(function() { + clock = sinon.useFakeTimers(); + oldConfig = window.oc_config; + loadedStub = sinon.stub(OC.Router, 'registerLoadedCallback'); + routeStub = sinon.stub(OC.Router, 'generate').returns('/heartbeat'); + counter = 0; + + fakeServer.autoRespond = true; + fakeServer.autoRespondAfter = 0; + fakeServer.respondWith(/\/heartbeat/, function(xhr) { + counter++; + xhr.respond(200, {'Content-Type': 'application/json'}, '{}'); + }); + }); + afterEach(function() { + clock.restore(); + window.oc_config = oldConfig; + loadedStub.restore(); + routeStub.restore(); + }); + it('sends heartbeat half the session lifetime when heartbeat enabled', function() { + window.oc_config = { + session_keepalive: true, + session_lifetime: 300 + }; + window.initCore(); + expect(loadedStub.calledOnce).toEqual(true); + loadedStub.yield(); + expect(routeStub.calledWith('heartbeat')).toEqual(true); + + expect(counter).toEqual(0); + + // less than half, still nothing + clock.tick(100 * 1000); + expect(counter).toEqual(0); + + // reach past half (160), one call + clock.tick(55 * 1000); + expect(counter).toEqual(1); + + // almost there to the next, still one + clock.tick(140 * 1000); + expect(counter).toEqual(1); + + // past it, second call + clock.tick(20 * 1000); + expect(counter).toEqual(2); + }); + it('does no send heartbeat when heartbeat disabled', function() { + window.oc_config = { + session_keepalive: false, + session_lifetime: 300 + }; + window.initCore(); + expect(loadedStub.notCalled).toEqual(true); + expect(routeStub.notCalled).toEqual(true); + + expect(counter).toEqual(0); + + clock.tick(1000000); + + // still nothing + expect(counter).toEqual(0); + }); + + }); }); + diff --git a/core/setup.php b/core/setup.php deleted file mode 100644 index 958376b2cce..00000000000 --- a/core/setup.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php - -// Check for autosetup: -$autosetup_file = OC::$SERVERROOT."/config/autoconfig.php"; -if( file_exists( $autosetup_file )) { - OC_Log::write('core', 'Autoconfig file found, setting up owncloud...', OC_Log::INFO); - include $autosetup_file; - $_POST = array_merge ($_POST, $AUTOCONFIG); - $_REQUEST = array_merge ($_REQUEST, $AUTOCONFIG); -} - -$dbIsSet = isset($_POST['dbtype']); -$directoryIsSet = isset($_POST['directory']); -$adminAccountIsSet = isset($_POST['adminlogin']); - -if ($dbIsSet AND $directoryIsSet AND $adminAccountIsSet) { - $_POST['install'] = 'true'; - if( file_exists( $autosetup_file )) { - unlink($autosetup_file); - } -} - -OC_Util::addScript( '3rdparty', 'strengthify/jquery.strengthify' ); -OC_Util::addStyle( '3rdparty', 'strengthify/strengthify' ); -OC_Util::addScript('setup'); - -$hasSQLite = class_exists('SQLite3'); -$hasMySQL = is_callable('mysql_connect'); -$hasPostgreSQL = is_callable('pg_connect'); -$hasOracle = is_callable('oci_connect'); -$hasMSSQL = is_callable('sqlsrv_connect'); -$datadir = OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data'); -$vulnerableToNullByte = false; -if(@file_exists(__FILE__."\0Nullbyte")) { // Check if the used PHP version is vulnerable to the NULL Byte attack (CVE-2006-7243) - $vulnerableToNullByte = true; -} - -// Protect data directory here, so we can test if the protection is working -OC_Setup::protectDataDirectory(); - -$opts = array( - 'hasSQLite' => $hasSQLite, - 'hasMySQL' => $hasMySQL, - 'hasPostgreSQL' => $hasPostgreSQL, - 'hasOracle' => $hasOracle, - 'hasMSSQL' => $hasMSSQL, - 'directory' => $datadir, - 'secureRNG' => OC_Util::secureRNGAvailable(), - 'htaccessWorking' => OC_Util::isHtAccessWorking(), - 'vulnerableToNullByte' => $vulnerableToNullByte, - 'errors' => array(), - 'dbIsSet' => $dbIsSet, - 'directoryIsSet' => $directoryIsSet, -); - -if(isset($_POST['install']) AND $_POST['install']=='true') { - // We have to launch the installation process : - $e = OC_Setup::install($_POST); - $errors = array('errors' => $e); - - if(count($e) > 0) { - //OC_Template::printGuestPage("", "error", array("errors" => $errors)); - $options = array_merge($_POST, $opts, $errors); - OC_Template::printGuestPage("", "installation", $options); - } - else { - header( 'Location: '.OC_Helper::linkToRoute( 'post_setup_check' )); - exit(); - } -} -else { - OC_Template::printGuestPage("", "installation", $opts); -} diff --git a/core/setup/controller.php b/core/setup/controller.php new file mode 100644 index 00000000000..c628bda609b --- /dev/null +++ b/core/setup/controller.php @@ -0,0 +1,138 @@ +<?php +/** + * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Core\Setup; + +class Controller { + public function run($post) { + // Check for autosetup: + $post = $this->loadAutoConfig($post); + $opts = $this->getSystemInfo(); + + if(isset($post['install']) AND $post['install']=='true') { + // We have to launch the installation process : + $e = \OC_Setup::install($post); + $errors = array('errors' => $e); + + if(count($e) > 0) { + $options = array_merge($post, $opts, $errors); + $this->display($options); + } + else { + $this->finishSetup(); + } + } + else { + $this->display($opts); + } + } + + public function display($post) { + $defaults = array( + 'adminlogin' => '', + 'adminpass' => '', + 'dbuser' => '', + 'dbpass' => '', + 'dbname' => '', + 'dbtablespace' => '', + 'dbhost' => '', + ); + $parameters = array_merge($defaults, $post); + + \OC_Util::addScript( '3rdparty', 'strengthify/jquery.strengthify' ); + \OC_Util::addStyle( '3rdparty', 'strengthify/strengthify' ); + \OC_Util::addScript('setup'); + \OC_Template::printGuestPage('', 'installation', $parameters); + } + + public function finishSetup() { + header( 'Location: '.\OC_Helper::linkToRoute( 'post_setup_check' )); + exit(); + } + + public function loadAutoConfig($post) { + $dbIsSet = isset($post['dbtype']); + $directoryIsSet = isset($post['directory']); + $adminAccountIsSet = isset($post['adminlogin']); + + $autosetup_file = \OC::$SERVERROOT.'/config/autoconfig.php'; + if( file_exists( $autosetup_file )) { + \OC_Log::write('core', 'Autoconfig file found, setting up owncloud...', \OC_Log::INFO); + include $autosetup_file; + $post = array_merge ($post, $AUTOCONFIG); + } + + if ($dbIsSet AND $directoryIsSet AND $adminAccountIsSet) { + $post['install'] = 'true'; + if( file_exists( $autosetup_file )) { + unlink($autosetup_file); + } + } + $post['dbIsSet'] = $dbIsSet; + $post['directoryIsSet'] = $directoryIsSet; + + return $post; + } + + public function getSystemInfo() { + $hasSQLite = class_exists('SQLite3'); + $hasMySQL = is_callable('mysql_connect'); + $hasPostgreSQL = is_callable('pg_connect'); + $hasOracle = is_callable('oci_connect'); + $hasMSSQL = is_callable('sqlsrv_connect'); + $databases = array(); + if ($hasSQLite) { + $databases['sqlite'] = 'SQLite'; + } + if ($hasMySQL) { + $databases['mysql'] = 'MySQL'; + } + if ($hasPostgreSQL) { + $databases['pgsql'] = 'PostgreSQL'; + } + if ($hasOracle) { + $databases['oci'] = 'Oracle'; + } + if ($hasMSSQL) { + $databases['mssql'] = 'MS SQL'; + } + $datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT.'/data'); + $vulnerableToNullByte = false; + if(@file_exists(__FILE__."\0Nullbyte")) { // Check if the used PHP version is vulnerable to the NULL Byte attack (CVE-2006-7243) + $vulnerableToNullByte = true; + } + + $errors = array(); + + // Protect data directory here, so we can test if the protection is working + \OC_Setup::protectDataDirectory(); + try { + $htaccessWorking = \OC_Util::isHtAccessWorking(); + } catch (\OC\HintException $e) { + $errors[] = array( + 'error' => $e->getMessage(), + 'hint' => $e->getHint() + ); + $htaccessWorking = false; + } + + return array( + 'hasSQLite' => $hasSQLite, + 'hasMySQL' => $hasMySQL, + 'hasPostgreSQL' => $hasPostgreSQL, + 'hasOracle' => $hasOracle, + 'hasMSSQL' => $hasMSSQL, + 'databases' => $databases, + 'directory' => $datadir, + 'secureRNG' => \OC_Util::secureRNGAvailable(), + 'htaccessWorking' => $htaccessWorking, + 'vulnerableToNullByte' => $vulnerableToNullByte, + 'errors' => $errors, + ); + } +} diff --git a/core/templates/installation.php b/core/templates/installation.php index 182fc83a4d4..9670a5e9ee5 100644 --- a/core/templates/installation.php +++ b/core/templates/installation.php @@ -48,13 +48,13 @@ <legend><?php print_unescaped($l->t( 'Create an <strong>admin account</strong>' )); ?></legend> <p class="infield grouptop"> <input type="text" name="adminlogin" id="adminlogin" placeholder="" - value="<?php p(OC_Helper::init_var('adminlogin')); ?>" autocomplete="off" autofocus required /> + value="<?php p($_['adminlogin']); ?>" autocomplete="off" autofocus required /> <label for="adminlogin" class="infield"><?php p($l->t( 'Username' )); ?></label> <img class="svg" src="<?php p(image_path('', 'actions/user.svg')); ?>" alt="" /> </p> <p class="infield groupbottom"> <input type="password" name="adminpass" data-typetoggle="#show" id="adminpass" placeholder="" - value="<?php p(OC_Helper::init_var('adminpass')); ?>" required /> + value="<?php p($_['adminpass']); ?>" required /> <label for="adminpass" class="infield"><?php p($l->t( 'Password' )); ?></label> <img class="svg" id="adminpass-icon" src="<?php print_unescaped(image_path('', 'actions/password.svg')); ?>" alt="" /> <input type="checkbox" id="show" name="show" /> @@ -75,7 +75,7 @@ <label for="directory"><?php p($l->t( 'Data folder' )); ?></label> <input type="text" name="directory" id="directory" placeholder="<?php p(OC::$SERVERROOT."/data"); ?>" - value="<?php p(OC_Helper::init_var('directory', $_['directory'])); ?>" /> + value="<?php p($_['directory']); ?>" /> </div> </fieldset> <?php endif; ?> @@ -86,62 +86,16 @@ $hasOtherDB = true; else $hasOtherDB =false; //other than SQLite ?> <legend><?php p($l->t( 'Configure the database' )); ?></legend> <div id="selectDbType"> - <?php if($_['hasSQLite']): ?> - <input type='hidden' id='hasSQLite' value="true" /> - <?php if(!$hasOtherDB): ?> - <p>SQLite <?php p($l->t( 'will be used' )); ?>.</p> - <input type="hidden" id="dbtype" name="dbtype" value="sqlite" /> + <?php foreach($_['databases'] as $type => $label): ?> + <?php if(count($_['databases']) === 1): ?> + <p class="info"><?php p($label . ' ' . $l->t( 'will be used' )); ?>.</p> + <input type="hidden" id="dbtype" name="dbtype" value="<?php p($type) ?>" /> <?php else: ?> - <input type="radio" name="dbtype" value="sqlite" id="sqlite" - <?php OC_Helper::init_radio('dbtype', 'sqlite', 'sqlite'); ?>/> - <label class="sqlite" for="sqlite">SQLite</label> - <?php endif; ?> - <?php endif; ?> - - <?php if($_['hasMySQL']): ?> - <input type='hidden' id='hasMySQL' value='true'/> - <?php if(!$_['hasSQLite'] and !$_['hasPostgreSQL'] and !$_['hasOracle'] and !$_['hasMSSQL']): ?> - <p>MySQL <?php p($l->t( 'will be used' )); ?>.</p> - <input type="hidden" id="dbtype" name="dbtype" value="mysql" /> - <?php else: ?> - <input type="radio" name="dbtype" value="mysql" id="mysql" - <?php OC_Helper::init_radio('dbtype', 'mysql', 'sqlite'); ?>/> - <label class="mysql" for="mysql">MySQL</label> - <?php endif; ?> - <?php endif; ?> - - <?php if($_['hasPostgreSQL']): ?> - <?php if(!$_['hasSQLite'] and !$_['hasMySQL'] and !$_['hasOracle'] and !$_['hasMSSQL']): ?> - <p>PostgreSQL <?php p($l->t( 'will be used' )); ?>.</p> - <input type="hidden" id="dbtype" name="dbtype" value="pgsql" /> - <?php else: ?> - <label class="pgsql" for="pgsql">PostgreSQL</label> - <input type="radio" name="dbtype" value='pgsql' id="pgsql" - <?php OC_Helper::init_radio('dbtype', 'pgsql', 'sqlite'); ?>/> - <?php endif; ?> - <?php endif; ?> - - <?php if($_['hasOracle']): ?> - <?php if(!$_['hasSQLite'] and !$_['hasMySQL'] and !$_['hasPostgreSQL'] and !$_['hasMSSQL']): ?> - <p>Oracle <?php p($l->t( 'will be used' )); ?>.</p> - <input type="hidden" id="dbtype" name="dbtype" value="oci" /> - <?php else: ?> - <label class="oci" for="oci">Oracle</label> - <input type="radio" name="dbtype" value='oci' id="oci" - <?php OC_Helper::init_radio('dbtype', 'oci', 'sqlite'); ?>/> - <?php endif; ?> - <?php endif; ?> - - <?php if($_['hasMSSQL']): ?> - <input type='hidden' id='hasMSSQL' value='true'/> - <?php if(!$_['hasSQLite'] and !$_['hasMySQL'] and !$_['hasPostgreSQL'] and !$_['hasOracle']): ?> - <p>MS SQL <?php p($l->t( 'will be used' )); ?>.</p> - <input type="hidden" id="dbtype" name="dbtype" value="mssql" /> - <?php else: ?> - <label class="mssql" for="mssql">MS SQL</label> - <input type="radio" name="dbtype" value='mssql' id="mssql" <?php OC_Helper::init_radio('dbtype', 'mssql', 'sqlite'); ?>/> - <?php endif; ?> + <input type="radio" name="dbtype" value="<?php p($type) ?>" id="<?php p($type) ?>" + <?php p($_['dbtype'] === $type ? 'checked="checked" ' : '') ?>/> + <label class="<?php p($type) ?>" for="<?php p($type) ?>"><?php p($label) ?></label> <?php endif; ?> + <?php endforeach; ?> </div> <?php if($hasOtherDB): ?> @@ -149,11 +103,11 @@ <p class="infield grouptop"> <label for="dbuser" class="infield"><?php p($l->t( 'Database user' )); ?></label> <input type="text" name="dbuser" id="dbuser" placeholder="" - value="<?php p(OC_Helper::init_var('dbuser')); ?>" autocomplete="off" /> + value="<?php p($_['dbuser']); ?>" autocomplete="off" /> </p> <p class="infield groupmiddle"> <input type="password" name="dbpass" id="dbpass" placeholder="" data-typetoggle="#dbpassword" - value="<?php p(OC_Helper::init_var('dbpass')); ?>" /> + value="<?php p($_['dbpass']); ?>" /> <label for="dbpass" class="infield"><?php p($l->t( 'Database password' )); ?></label> <input type="checkbox" id="dbpassword" name="dbpassword" /> <label for="dbpassword"></label> @@ -161,7 +115,7 @@ <p class="infield groupmiddle"> <label for="dbname" class="infield"><?php p($l->t( 'Database name' )); ?></label> <input type="text" name="dbname" id="dbname" placeholder="" - value="<?php p(OC_Helper::init_var('dbname')); ?>" + value="<?php p($_['dbname']); ?>" autocomplete="off" pattern="[0-9a-zA-Z$_-]+" /> </p> <?php if($_['hasOracle']): ?> @@ -169,14 +123,14 @@ <p class="infield groupmiddle"> <label for="dbtablespace" class="infield"><?php p($l->t( 'Database tablespace' )); ?></label> <input type="text" name="dbtablespace" id="dbtablespace" placeholder="" - value="<?php p(OC_Helper::init_var('dbtablespace')); ?>" autocomplete="off" /> + value="<?php p($_['dbtablespace']); ?>" autocomplete="off" /> </p> </div> <?php endif; ?> <p class="infield groupbottom"> <label for="dbhost" class="infield"><?php p($l->t( 'Database host' )); ?></label> <input type="text" name="dbhost" id="dbhost" placeholder="" - value="<?php p(OC_Helper::init_var('dbhost')); ?>" /> + value="<?php p($_['dbhost']); ?>" /> </p> </div> <?php endif; ?> diff --git a/core/templates/layout.base.php b/core/templates/layout.base.php index 8cd237deea1..bae52a73234 100644 --- a/core/templates/layout.base.php +++ b/core/templates/layout.base.php @@ -11,7 +11,7 @@ <?php p($theme->getTitle()); ?> </title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"> <link rel="shortcut icon" href="<?php print_unescaped(image_path('', 'favicon.png')); ?>" /> <link rel="apple-touch-icon-precomposed" href="<?php print_unescaped(image_path('', 'favicon-touch.png')); ?>" /> <?php foreach ($_['cssfiles'] as $cssfile): ?> diff --git a/core/templates/layout.guest.php b/core/templates/layout.guest.php index 47ca5903dab..6a96b17b100 100644 --- a/core/templates/layout.guest.php +++ b/core/templates/layout.guest.php @@ -11,7 +11,7 @@ <?php p($theme->getTitle()); ?> </title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"> <meta name="apple-itunes-app" content="app-id=543672169"> <link rel="shortcut icon" href="<?php print_unescaped(image_path('', 'favicon.png')); ?>" /> <link rel="apple-touch-icon-precomposed" href="<?php print_unescaped(image_path('', 'favicon-touch.png')); ?>" /> diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php index 89987625d63..bc1c700402e 100644 --- a/core/templates/layout.user.php +++ b/core/templates/layout.user.php @@ -48,15 +48,16 @@ <a href="<?php print_unescaped(link_to('', 'index.php')); ?>" title="" id="owncloud"><img class="svg" src="<?php print_unescaped(image_path('', 'logo-wide.svg')); ?>" alt="<?php p($theme->getName()); ?>" /></a> <div id="logo-claim" style="display:none;"><?php p($theme->getLogoClaim()); ?></div> - <ul id="settings" class="svg"> + <div id="settings" class="svg"> <span id="expand" tabindex="0" role="link"> <span id="expandDisplayName"><?php p(trim($_['user_displayname']) != '' ? $_['user_displayname'] : $_['user_uid']) ?></span> - <img class="svg" src="<?php print_unescaped(image_path('', 'actions/caret.svg')); ?>" /> - <?php if ($_['enableAvatars']): ?> - <div class="avatardiv"></div> - <?php endif; ?> + <img class="svg" alt="" src="<?php print_unescaped(image_path('', 'actions/caret.svg')); ?>" /> </span> + <?php if ($_['enableAvatars']): ?> + <div class="avatardiv"></div> + <?php endif; ?> <div id="expanddiv"> + <ul> <?php foreach($_['settingsnavigation'] as $entry):?> <li> <a href="<?php print_unescaped($entry['href']); ?>" title="" @@ -72,8 +73,9 @@ <?php p($l->t('Log out'));?> </a> </li> + </ul> </div> - </ul> + </div> <form class="searchbox" action="#" method="post"> <input id="searchbox" class="svg" type="search" name="query" @@ -83,37 +85,40 @@ </div></header> <nav><div id="navigation"> - <ul id="apps" class="svg"> - <div class="wrapper"><!-- for sticky footer of apps management --> + <div id="apps" class="svg"> + <ul class="wrapper"><!-- for sticky footer of apps management --> <?php foreach($_['navigation'] as $entry): ?> <li data-id="<?php p($entry['id']); ?>"> <a href="<?php print_unescaped($entry['href']); ?>" title="" <?php if( $entry['active'] ): ?> class="active"<?php endif; ?>> - <img class="icon svg" src="<?php print_unescaped($entry['icon']); ?>"/> + <img class="icon svg" alt="" src="<?php print_unescaped($entry['icon']); ?>"/> <span> <?php p($entry['name']); ?> </span> </a> </li> <?php endforeach; ?> + <?php if(OC_User::isAdminUser(OC_User::getUser())): ?> - <div class="push"></div><!-- for for sticky footer of apps management --> + <li class="push"></li><!-- for sticky footer of apps management --> <?php endif; ?> - </div> + </ul> <!-- show "More apps" link to app administration directly in app navigation, as sticky footer --> <?php if(OC_User::isAdminUser(OC_User::getUser())): ?> - <li id="apps-management"> + <ul id="apps-management"> + <li> <a href="<?php print_unescaped(OC_Helper::linkToRoute('settings_apps').'?installed'); ?>" title="" <?php if( $_['appsmanagement_active'] ): ?> class="active"<?php endif; ?>> - <img class="icon svg" src="<?php print_unescaped(OC_Helper::imagePath('settings', 'apps.svg')); ?>"/> + <img class="icon svg" alt="" src="<?php print_unescaped(OC_Helper::imagePath('settings', 'apps.svg')); ?>"/> <span> <?php p($l->t('Apps')); ?> </span> </a> </li> + </ul> <?php endif; ?> - </ul> + </div> </div></nav> <div id="content-wrapper"> |