interfasys /
galleryplus
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | /* global DOMPurify, oc_requesttoken, Gallery */ |
||
| 2 | |||
| 3 | // The Utility class can also be loaded by the Files app |
||
| 4 | window.Gallery = window.Gallery || {}; |
||
| 5 | |||
| 6 | (function ($, OC, t, oc_requesttoken, Gallery) { |
||
| 7 | "use strict"; |
||
| 8 | /** |
||
| 9 | * Contains utility methods |
||
| 10 | * |
||
| 11 | * @fixme OC.generateUrl, OC.buildQueryString, OC.Notification are private APIs |
||
| 12 | * |
||
| 13 | * @constructor |
||
| 14 | */ |
||
| 15 | var Utility = function () { |
||
| 16 | }; |
||
| 17 | |||
| 18 | Utility.prototype = { |
||
| 19 | /** |
||
| 20 | * Detects if the browser is a recent or an old version of Internet Explorer |
||
| 21 | * |
||
| 22 | * @returns {string|boolean} |
||
| 23 | */ |
||
| 24 | getIeVersion: function () { |
||
| 25 | // Blocking IE8 |
||
| 26 | if ($('html').is('.ie8')) { |
||
| 27 | return 'unsupportedIe'; |
||
| 28 | } else if (navigator.userAgent.indexOf("MSIE") > 0) { |
||
| 29 | return 'oldIe'; |
||
| 30 | } else if (!!navigator.userAgent.match(/Trident.*rv[ :]*11\./)) { |
||
| 31 | return 'modernIe'; |
||
| 32 | } else if (navigator.userAgent.indexOf("Edge/") > 0) { |
||
| 33 | return 'edge'; |
||
| 34 | } |
||
| 35 | |||
| 36 | return false; |
||
| 37 | }, |
||
| 38 | |||
| 39 | /** |
||
| 40 | * Shows a notification to IE users, letting them know that they should use another browser |
||
| 41 | * in order to get the best experience |
||
| 42 | * |
||
| 43 | * @param {string} version |
||
| 44 | */ |
||
| 45 | showIeWarning: function (version) { |
||
| 46 | var line1 = t('gallery', 'This application may not work properly on your browser.'); |
||
| 47 | var line2 = t('gallery', |
||
| 48 | 'For an improved experience, please install one of the following alternatives'); |
||
| 49 | var timeout = 15; |
||
| 50 | if (version === 'unsupportedIe') { |
||
| 51 | line1 = t('gallery', 'Your browser is not supported!'); |
||
| 52 | line2 = t('gallery', 'please install one of the following alternatives'); |
||
| 53 | timeout = 60; |
||
| 54 | } |
||
| 55 | |||
| 56 | var recommendedBrowsers = '</br>' + |
||
| 57 | '<a href="http://www.getfirefox.com"><strong>Mozilla Firefox</strong></a> or ' + |
||
| 58 | '<a href="https://www.google.com/chrome/"><strong>Google Chrome</strong></a>' + |
||
| 59 | '</br>'; |
||
| 60 | |||
| 61 | var text = '<strong>' + line1 + '</strong></br>' + line2 + recommendedBrowsers; |
||
| 62 | this.showHtmlNotification(text, timeout); |
||
| 63 | }, |
||
| 64 | |||
| 65 | /** |
||
| 66 | * Shows a notification at the top of the screen |
||
| 67 | * |
||
| 68 | * @param {string} text |
||
| 69 | * @param {int} timeout |
||
| 70 | */ |
||
| 71 | showHtmlNotification: function (text, timeout) { |
||
| 72 | var options = { |
||
| 73 | timeout: timeout, |
||
| 74 | isHTML: true |
||
| 75 | }; |
||
| 76 | OC.Notification.showTemporary(text, options); |
||
| 77 | }, |
||
| 78 | |||
| 79 | /** |
||
| 80 | * Returns the token allowing access to files shared via link |
||
| 81 | * |
||
| 82 | * @returns {string} |
||
| 83 | */ |
||
| 84 | getPublicToken: function () { |
||
| 85 | var element = $('#gallery'); |
||
| 86 | var token; |
||
| 87 | |||
| 88 | if (element.data('token')) { |
||
| 89 | token = element.data('token'); |
||
| 90 | } |
||
| 91 | |||
| 92 | if (element.data('requesttoken')) { |
||
| 93 | /* jshint camelcase: false */ |
||
| 94 | oc_requesttoken = element.data('requesttoken'); |
||
| 95 | } |
||
| 96 | |||
| 97 | return token; |
||
| 98 | }, |
||
| 99 | |||
| 100 | /** |
||
| 101 | * Returns the host we can use for WebDAV |
||
| 102 | * |
||
| 103 | * On public galleries, we need to provide the token as authorization |
||
| 104 | * |
||
| 105 | * @returns {string} |
||
| 106 | */ |
||
| 107 | getWebdavHost: function () { |
||
| 108 | var host = OC.getHost(); |
||
| 109 | if (Gallery.token) { |
||
| 110 | host = Gallery.token + '@' + host; |
||
| 111 | } |
||
| 112 | |||
| 113 | return host; |
||
| 114 | }, |
||
| 115 | |||
| 116 | /** |
||
| 117 | * Returns the WebDAV endpoint we can use for files operations |
||
| 118 | * |
||
| 119 | * @returns {string} |
||
| 120 | */ |
||
| 121 | getWebdavRoot: function () { |
||
| 122 | var root = OC.linkToRemoteBase('webdav'); |
||
| 123 | if (Gallery.token) { |
||
| 124 | root = root.replace('remote.php', 'public.php'); |
||
| 125 | } |
||
| 126 | |||
| 127 | return root; |
||
| 128 | }, |
||
| 129 | |||
| 130 | /** |
||
| 131 | * Builds the URL which will retrieve a large preview of the file |
||
| 132 | * |
||
| 133 | * @fixme we cannot get rid of oc_requesttoken parameter as it's missing from the headers |
||
| 134 | * |
||
| 135 | * @param {number} fileId |
||
| 136 | * @param {number} etag |
||
| 137 | * |
||
| 138 | * @return {string} |
||
| 139 | */ |
||
| 140 | getPreviewUrl: function (fileId, etag) { |
||
| 141 | var width = Math.ceil(screen.width * window.devicePixelRatio); |
||
|
0 ignored issues
–
show
|
|||
| 142 | var height = Math.ceil(screen.height * window.devicePixelRatio); |
||
| 143 | |||
| 144 | /* Find value of longest edge. */ |
||
| 145 | var longEdge = Math.max(width, height); |
||
| 146 | |||
| 147 | /* Find the next larger image size. */ |
||
| 148 | if (longEdge % 100 !== 0) { |
||
| 149 | longEdge = ( longEdge + 100 ) - ( longEdge % 100 ); |
||
| 150 | } |
||
| 151 | |||
| 152 | /* jshint camelcase: false */ |
||
| 153 | var params = { |
||
| 154 | c: etag, |
||
| 155 | width: longEdge, |
||
| 156 | height: longEdge, |
||
| 157 | requesttoken: oc_requesttoken |
||
| 158 | }; |
||
| 159 | return this.buildGalleryUrl('preview', '/' + fileId, params); |
||
| 160 | }, |
||
| 161 | |||
| 162 | /** |
||
| 163 | * Builds a URL pointing to one of the app's controllers |
||
| 164 | * |
||
| 165 | * @param {string} endPoint |
||
| 166 | * @param {undefined|string} path |
||
| 167 | * @param params |
||
| 168 | * |
||
| 169 | * @returns {string} |
||
| 170 | */ |
||
| 171 | buildGalleryUrl: function (endPoint, path, params) { |
||
| 172 | if (path === undefined) { |
||
| 173 | path = ''; |
||
| 174 | } |
||
| 175 | var extension = ''; |
||
| 176 | if (Gallery.token) { |
||
| 177 | params.token = Gallery.token; |
||
| 178 | extension = '.public'; |
||
| 179 | } |
||
| 180 | var query = OC.buildQueryString(params); |
||
| 181 | return OC.generateUrl('apps/' + Gallery.appName + '/' + endPoint + extension + path, |
||
| 182 | null) + |
||
| 183 | '?' + |
||
| 184 | query; |
||
| 185 | }, |
||
| 186 | |||
| 187 | /** |
||
| 188 | * Builds a URL pointing to one of the files' controllers |
||
| 189 | * |
||
| 190 | * @param {string} path |
||
| 191 | * @param {string} files |
||
| 192 | * |
||
| 193 | * @returns {string} |
||
| 194 | */ |
||
| 195 | buildFilesUrl: function (path, files) { |
||
| 196 | var subUrl = ''; |
||
| 197 | var params = { |
||
| 198 | path: path, |
||
| 199 | files: files |
||
| 200 | }; |
||
| 201 | |||
| 202 | if (Gallery.token) { |
||
| 203 | params.token = Gallery.token; |
||
| 204 | subUrl = 's/{token}/download?dir={path}&files={files}'; |
||
| 205 | } else { |
||
| 206 | subUrl = 'apps/files/ajax/download.php?dir={path}&files={files}'; |
||
| 207 | } |
||
| 208 | |||
| 209 | return OC.generateUrl(subUrl, params); |
||
| 210 | }, |
||
| 211 | |||
| 212 | /** |
||
| 213 | * Sorts arrays based on name or date |
||
| 214 | * |
||
| 215 | * @param {string} sortType |
||
| 216 | * @param {string} sortOrder |
||
| 217 | * |
||
| 218 | * @returns {Function} |
||
| 219 | */ |
||
| 220 | sortBy: function (sortType, sortOrder) { |
||
| 221 | if (sortType === 'name') { |
||
| 222 | if (sortOrder === 'asc') { |
||
| 223 | //sortByNameAsc |
||
| 224 | return function (a, b) { |
||
| 225 | return OC.Util.naturalSortCompare(a.path, b.path); |
||
| 226 | }; |
||
| 227 | } |
||
| 228 | //sortByNameDes |
||
| 229 | return function (a, b) { |
||
| 230 | return -OC.Util.naturalSortCompare(a.path, b.path); |
||
| 231 | }; |
||
| 232 | } |
||
| 233 | if (sortType === 'date') { |
||
| 234 | if (sortOrder === 'asc') { |
||
| 235 | //sortByDateAsc |
||
| 236 | return function (a, b) { |
||
| 237 | return b.mTime - a.mTime; |
||
| 238 | }; |
||
| 239 | } |
||
| 240 | //sortByDateDes |
||
| 241 | return function (a, b) { |
||
| 242 | return a.mTime - b.mTime; |
||
| 243 | }; |
||
| 244 | } |
||
| 245 | }, |
||
| 246 | |||
| 247 | /** |
||
| 248 | * Adds hooks to DOMPurify |
||
| 249 | */ |
||
| 250 | addDomPurifyHooks: function () { |
||
| 251 | // allowed URI schemes |
||
| 252 | var whitelist = ['http', 'https']; |
||
| 253 | |||
| 254 | // build fitting regex |
||
| 255 | var regex = new RegExp('^(' + whitelist.join('|') + '):', 'gim'); |
||
| 256 | |||
| 257 | DOMPurify.addHook('afterSanitizeAttributes', function (node) { |
||
| 258 | // This hook enforces URI scheme whitelist |
||
| 259 | // @link |
||
| 260 | // https://github.com/cure53/DOMPurify/blob/master/demos/hooks-scheme-whitelist.html |
||
| 261 | |||
| 262 | // build an anchor to map URLs to |
||
| 263 | var anchor = document.createElement('a'); |
||
| 264 | |||
| 265 | // check all href attributes for validity |
||
| 266 | if (node.hasAttribute('href')) { |
||
| 267 | anchor.href = node.getAttribute('href'); |
||
| 268 | if (anchor.protocol && !anchor.protocol.match(regex)) { |
||
| 269 | node.removeAttribute('href'); |
||
| 270 | } |
||
| 271 | } |
||
| 272 | // check all action attributes for validity |
||
| 273 | if (node.hasAttribute('action')) { |
||
| 274 | anchor.href = node.getAttribute('action'); |
||
| 275 | if (anchor.protocol && !anchor.protocol.match(regex)) { |
||
| 276 | node.removeAttribute('action'); |
||
| 277 | } |
||
| 278 | } |
||
| 279 | // check all xlink:href attributes for validity |
||
| 280 | if (node.hasAttribute('xlink:href')) { |
||
| 281 | anchor.href = node.getAttribute('xlink:href'); |
||
| 282 | if (anchor.protocol && !anchor.protocol.match(regex)) { |
||
| 283 | node.removeAttribute('xlink:href'); |
||
| 284 | } |
||
| 285 | } |
||
| 286 | |||
| 287 | // This hook restores the proper, standard namespace in SVG files |
||
| 288 | var encodedXmlns, decodedXmlns; |
||
| 289 | |||
| 290 | // Restores namespaces which were put in the DOCTYPE by Illustrator |
||
| 291 | if (node.hasAttribute('xmlns') && node.getAttribute('xmlns') === '&ns_svg;') { |
||
| 292 | encodedXmlns = node.getAttribute('xmlns'); |
||
| 293 | decodedXmlns = encodedXmlns.replace('&ns_svg;', 'http://www.w3.org/2000/svg'); |
||
| 294 | node.setAttribute('xmlns', decodedXmlns); |
||
| 295 | } |
||
| 296 | if (node.hasAttribute('xmlns:xlink') && |
||
| 297 | node.getAttribute('xmlns:xlink') === '&ns_xlink;') { |
||
| 298 | encodedXmlns = node.getAttribute('xmlns:xlink'); |
||
| 299 | decodedXmlns = |
||
| 300 | encodedXmlns.replace('&ns_xlink;', 'http://www.w3.org/1999/xlink'); |
||
| 301 | node.setAttribute('xmlns:xlink', decodedXmlns); |
||
| 302 | } |
||
| 303 | }); |
||
| 304 | } |
||
| 305 | }; |
||
| 306 | |||
| 307 | Gallery.Utility = Utility; |
||
| 308 | })(jQuery, OC, t, oc_requesttoken, Gallery); |
||
| 309 |
This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.
To learn more about declaring variables in Javascript, see the MDN.