aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/Controller/UnsupportedBrowserController.php51
-rw-r--r--core/css/apps.scss10
-rw-r--r--core/css/public.scss6
-rw-r--r--core/routes.php5
-rw-r--r--core/src/Polyfill/closest.js41
-rw-r--r--core/src/Polyfill/index.js3
-rw-r--r--core/src/components/MainMenu.js1
-rw-r--r--core/src/init.js12
-rw-r--r--core/src/main.js17
-rw-r--r--core/src/services/BrowserStorageService.js (renamed from core/src/Polyfill/console.js)24
-rw-r--r--core/src/services/BrowsersListService.js30
-rw-r--r--core/src/services/LoggerService.js (renamed from core/src/Polyfill/windows-phone.js)21
-rw-r--r--core/src/unsupported-browser.js39
-rw-r--r--core/src/utils/RedirectUnsupportedBrowsers.js54
-rw-r--r--core/src/views/UnsupportedBrowser.vue191
-rw-r--r--core/templates/unsupportedbrowser.php1
-rw-r--r--dist/core-unsupported-browser.js3
-rw-r--r--dist/core-unsupported-browser.js.map1
-rw-r--r--lib/composer/composer/autoload_classmap.php1
-rw-r--r--lib/composer/composer/autoload_static.php1
-rw-r--r--package-lock.json525
-rw-r--r--package.json4
-rw-r--r--webpack.modules.js1
23 files changed, 849 insertions, 193 deletions
diff --git a/core/Controller/UnsupportedBrowserController.php b/core/Controller/UnsupportedBrowserController.php
new file mode 100644
index 00000000000..8cdc190deea
--- /dev/null
+++ b/core/Controller/UnsupportedBrowserController.php
@@ -0,0 +1,51 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2021 John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @author John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Core\Controller;
+
+use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http\Response;
+use OCP\AppFramework\Http\TemplateResponse;
+use OCP\IRequest;
+use OCP\Util;
+
+class UnsupportedBrowserController extends Controller {
+ public function __construct(IRequest $request) {
+ parent::__construct('core', $request);
+ }
+
+ /**
+ * @PublicPage
+ * @NoCSRFRequired
+ *
+ * @return Response
+ */
+ public function index(): Response {
+ Util::addScript('core', 'unsupported-browser');
+ Util::addStyle('core', 'icons');
+ return new TemplateResponse('core', 'unsupportedbrowser', [], TemplateResponse::RENDER_AS_ERROR);
+ }
+}
diff --git a/core/css/apps.scss b/core/css/apps.scss
index dea8cbf9217..f0d96d55e9e 100644
--- a/core/css/apps.scss
+++ b/core/css/apps.scss
@@ -970,16 +970,6 @@ $popoveritem-height: 44px;
$popovericon-size: 16px;
$outter-margin: math.div($popoveritem-height - $popovericon-size, 2);
-.ie,
-.edge {
- .bubble, .bubble:after,
- .popovermenu, .popovermenu:after,
- #app-navigation .app-navigation-entry-menu,
- #app-navigation .app-navigation-entry-menu:after {
- border: 1px solid var(--color-border);
- }
-}
-
.contact .popovermenu ul,
.popover__menu {
> li > a > img {
diff --git a/core/css/public.scss b/core/css/public.scss
index 0e75a938cfa..ddeb444970d 100644
--- a/core/css/public.scss
+++ b/core/css/public.scss
@@ -47,12 +47,6 @@ $footer-height: 65px;
padding-top: 0;
}
- /* force layout to make sure the content element's height matches its contents' height */
- .ie #content {
- display: inline-block;
- }
-
-
p.info {
margin: 20px auto;
text-shadow: 0 0 2px rgba(0, 0, 0, .4);
diff --git a/core/routes.php b/core/routes.php
index 820db44bf90..02e27c9cfaf 100644
--- a/core/routes.php
+++ b/core/routes.php
@@ -58,11 +58,13 @@ $application->registerRoutes($this, [
['name' => 'login#confirmPassword', 'url' => '/login/confirm', 'verb' => 'POST'],
['name' => 'login#showLoginForm', 'url' => '/login', 'verb' => 'GET'],
['name' => 'login#logout', 'url' => '/logout', 'verb' => 'GET'],
+
// Original login flow used by all clients
['name' => 'ClientFlowLogin#showAuthPickerPage', 'url' => '/login/flow', 'verb' => 'GET'],
['name' => 'ClientFlowLogin#generateAppPassword', 'url' => '/login/flow', 'verb' => 'POST'],
['name' => 'ClientFlowLogin#grantPage', 'url' => '/login/flow/grant', 'verb' => 'GET'],
['name' => 'ClientFlowLogin#apptokenRedirect', 'url' => '/login/flow/apptoken', 'verb' => 'POST'],
+
// NG login flow used by desktop client in case of Kerberos/fancy 2fa (smart cards for example)
['name' => 'ClientFlowLoginV2#poll', 'url' => '/login/v2/poll', 'verb' => 'POST'],
['name' => 'ClientFlowLoginV2#showAuthPickerPage', 'url' => '/login/v2/flow', 'verb' => 'GET'],
@@ -97,6 +99,9 @@ $application->registerRoutes($this, [
// Well known requests https://tools.ietf.org/html/rfc5785
['name' => 'WellKnown#handle', 'url' => '.well-known/{service}'],
+
+ // Unsupported browser
+ ['name' => 'UnsupportedBrowser#index', 'url' => 'unsupported'],
],
'ocs' => [
['root' => '/cloud', 'name' => 'OCS#getCapabilities', 'url' => '/capabilities', 'verb' => 'GET'],
diff --git a/core/src/Polyfill/closest.js b/core/src/Polyfill/closest.js
deleted file mode 100644
index 68751fad38c..00000000000
--- a/core/src/Polyfill/closest.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @copyright Copyright (c) 2016 John Molakvoæ <skjnldsv@protonmail.com>
- *
- * @author John Molakvoæ <skjnldsv@protonmail.com>
- *
- * @license AGPL-3.0-or-later
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-// https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill
-
-if (!Element.prototype.matches) {
- Element.prototype.matches
- = Element.prototype.msMatchesSelector
- || Element.prototype.webkitMatchesSelector
-}
-
-if (!Element.prototype.closest) {
- Element.prototype.closest = function(s) {
- let el = this
-
- do {
- if (el.matches(s)) return el
- el = el.parentElement || el.parentNode
- } while (el !== null && el.nodeType === 1)
- return null
- }
-}
diff --git a/core/src/Polyfill/index.js b/core/src/Polyfill/index.js
index 5a190318327..610619217d2 100644
--- a/core/src/Polyfill/index.js
+++ b/core/src/Polyfill/index.js
@@ -21,7 +21,4 @@
*
*/
-import './console'
-import './closest'
-import './windows-phone'
import 'focus-visible'
diff --git a/core/src/components/MainMenu.js b/core/src/components/MainMenu.js
index 267a3d9a361..be27e752237 100644
--- a/core/src/components/MainMenu.js
+++ b/core/src/components/MainMenu.js
@@ -28,7 +28,6 @@ import Vue from 'vue'
import AppMenu from './AppMenu.vue'
export const setUp = () => {
-
Vue.mixin({
methods: {
t,
diff --git a/core/src/init.js b/core/src/init.js
index ae8db0abf49..867ba94483f 100644
--- a/core/src/init.js
+++ b/core/src/init.js
@@ -29,12 +29,12 @@ import _ from 'underscore'
import $ from 'jquery'
import moment from 'moment'
-import { initSessionHeartBeat } from './session-heartbeat'
-import OC from './OC/index'
-import { setUp as setUpContactsMenu } from './components/ContactsMenu'
-import { setUp as setUpMainMenu } from './components/MainMenu'
-import { setUp as setUpUserMenu } from './components/UserMenu'
-import PasswordConfirmation from './OC/password-confirmation'
+import { initSessionHeartBeat } from './session-heartbeat.js'
+import OC from './OC/index.js'
+import { setUp as setUpContactsMenu } from './components/ContactsMenu.js'
+import { setUp as setUpMainMenu } from './components/MainMenu.js'
+import { setUp as setUpUserMenu } from './components/UserMenu.js'
+import PasswordConfirmation from './OC/password-confirmation.js'
// keep in sync with core/css/variables.scss
const breakpointMobileWidth = 1024
diff --git a/core/src/main.js b/core/src/main.js
index f9d89327a6a..959110e86a4 100644
--- a/core/src/main.js
+++ b/core/src/main.js
@@ -26,16 +26,21 @@
import $ from 'jquery'
import 'core-js/stable'
import 'regenerator-runtime/runtime'
-import './Polyfill/index'
+import './Polyfill/index.js'
// If you remove the line below, tests won't pass
// eslint-disable-next-line no-unused-vars
-import OC from './OC/index'
+import OC from './OC/index.js'
-import './globals'
-import './jquery/index'
-import { initCore } from './init'
-import { registerAppsSlideToggle } from './OC/apps'
+import './globals.js'
+import './jquery/index.js'
+import { initCore } from './init.js'
+import { registerAppsSlideToggle } from './OC/apps.js'
+import { testSupportedBrowser } from './utils/RedirectUnsupportedBrowsers.js'
+
+if (window.TESTING === undefined) {
+ testSupportedBrowser()
+}
window.addEventListener('DOMContentLoaded', function() {
initCore()
diff --git a/core/src/Polyfill/console.js b/core/src/services/BrowserStorageService.js
index be3aca1a9b3..d383e1caaaf 100644
--- a/core/src/Polyfill/console.js
+++ b/core/src/services/BrowserStorageService.js
@@ -1,10 +1,9 @@
/**
- * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ * @copyright 2021 John Molakvoæ <skjnldsv@protonmail.com>
*
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
- * @license AGPL-3.0-or-later
+ * @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -17,18 +16,13 @@
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
-/* eslint-disable no-console */
-if (typeof console === 'undefined' || typeof console.log === 'undefined') {
- if (!window.console) {
- window.console = {}
- }
- const noOp = () => {}
- const methods = ['log', 'debug', 'warn', 'info', 'error', 'assert', 'time', 'timeEnd']
- for (let i = 0; i < methods.length; i++) {
- console[methods[i]] = noOp
- }
-}
+import { getBuilder } from '@nextcloud/browser-storage'
+
+export default getBuilder('nextcloud')
+ .clearOnLogout()
+ .persist()
+ .build()
diff --git a/core/src/services/BrowsersListService.js b/core/src/services/BrowsersListService.js
new file mode 100644
index 00000000000..c5d546665dc
--- /dev/null
+++ b/core/src/services/BrowsersListService.js
@@ -0,0 +1,30 @@
+/**
+ * @copyright 2021 John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @author John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+import { getUserAgentRegExp } from 'browserslist-useragent-regexp'
+// eslint-disable-next-line node/no-extraneous-import
+import browserslist from 'browserslist'
+import browserslistConfig from '@nextcloud/browserslist-config'
+
+// Generate a regex that matches user agents to detect incompatible browsers
+export const supportedBrowsersRegExp = getUserAgentRegExp({ allowHigherVersions: true, browsers: browserslistConfig })
+export const supportedBrowsers = browserslist(browserslistConfig)
diff --git a/core/src/Polyfill/windows-phone.js b/core/src/services/LoggerService.js
index 27b45d701c6..f0b8fc9e61d 100644
--- a/core/src/Polyfill/windows-phone.js
+++ b/core/src/services/LoggerService.js
@@ -1,10 +1,9 @@
/**
- * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
+ * @copyright 2021 John Molakvoæ <skjnldsv@protonmail.com>
*
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
- * @license AGPL-3.0-or-later
+ * @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -17,15 +16,13 @@
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
-// fix device width on windows phone
-if ('-ms-user-select' in document.documentElement.style && navigator.userAgent.match(/IEMobile\/10\.0/)) {
- const msViewportStyle = document.createElement('style')
- msViewportStyle.appendChild(
- document.createTextNode('@-ms-viewport{width:auto!important}')
- )
- document.getElementsByTagName('head')[0].appendChild(msViewportStyle)
-}
+import { getLoggerBuilder } from '@nextcloud/logger'
+
+export default getLoggerBuilder()
+ .setApp('core')
+ .detectUser()
+ .build()
diff --git a/core/src/unsupported-browser.js b/core/src/unsupported-browser.js
new file mode 100644
index 00000000000..cac5f145a7b
--- /dev/null
+++ b/core/src/unsupported-browser.js
@@ -0,0 +1,39 @@
+/**
+ * @copyright 2021 John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @author John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import { generateUrl } from '@nextcloud/router'
+import Vue from 'vue'
+
+import { browserStorageKey } from './utils/RedirectUnsupportedBrowsers.js'
+import browserStorage from './services/BrowserStorageService.js'
+import UnsupportedBrowser from './views/UnsupportedBrowser.vue'
+
+// If the ignore token is set, redirect
+if (browserStorage.getItem(browserStorageKey) === 'true') {
+ window.location = generateUrl('/')
+}
+
+export default new Vue({
+ el: '#unsupported-browser',
+ // eslint-disable-next-line vue/match-component-file-name
+ name: 'UnsupportedBrowserRoot',
+ render: h => h(UnsupportedBrowser),
+})
diff --git a/core/src/utils/RedirectUnsupportedBrowsers.js b/core/src/utils/RedirectUnsupportedBrowsers.js
new file mode 100644
index 00000000000..74074cec558
--- /dev/null
+++ b/core/src/utils/RedirectUnsupportedBrowsers.js
@@ -0,0 +1,54 @@
+/**
+ * @copyright 2021 John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @author John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import { generateUrl } from '@nextcloud/router'
+
+import { supportedBrowsersRegExp } from '../services/BrowsersListService.js'
+import browserStorage from '../services/BrowserStorageService.js'
+import logger from '../services/LoggerService.js'
+
+const redirectPath = '/unsupported'
+export const browserStorageKey = 'unsupported-browser-ignore'
+
+const isBrowserOverridden = browserStorage.getItem(browserStorageKey) === 'true'
+
+/**
+ * Test the current browser user agent against our official browserslist config
+ * and redirect if unsupported
+ */
+export const testSupportedBrowser = function() {
+ if (supportedBrowsersRegExp.test(navigator.userAgent)) {
+ logger.debug('this browser is officially supported ! 🚀')
+ return
+ }
+
+ // If incompatible BUT ignored, let's keep going
+ if (isBrowserOverridden) {
+ logger.debug('this browser is NOT supported but has been manually overridden ! ⚠️')
+ return
+ }
+
+ // If incompatible, NOT overridden AND NOT already on the warning page,
+ // redirect to the unsupported warning page
+ if (window.location.pathname.indexOf(redirectPath) === -1) {
+ window.location = generateUrl(redirectPath)
+ }
+}
diff --git a/core/src/views/UnsupportedBrowser.vue b/core/src/views/UnsupportedBrowser.vue
new file mode 100644
index 00000000000..ef2a33ca213
--- /dev/null
+++ b/core/src/views/UnsupportedBrowser.vue
@@ -0,0 +1,191 @@
+ <!--
+ - @copyright Copyright (c) 2021 John Molakvoæ <skjnldsv@protonmail.com>
+ -
+ - @author John Molakvoæ <skjnldsv@protonmail.com>
+ -
+ - @license GNU AGPL version 3 or any later version
+ -
+ - This program is free software: you can redistribute it and/or modify
+ - it under the terms of the GNU Affero General Public License as
+ - published by the Free Software Foundation, either version 3 of the
+ - License, or (at your option) any later version.
+ -
+ - This program is distributed in the hope that it will be useful,
+ - but WITHOUT ANY WARRANTY; without even the implied warranty of
+ - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ - GNU Affero General Public License for more details.
+ -
+ - You should have received a copy of the GNU Affero General Public License
+ - along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -
+ -->
+<template>
+ <div class="content-unsupported-browser guest-box">
+ <NcEmptyContent>
+ {{ t('core', 'This browser is not supported') }}
+ <template #icon>
+ <Web />
+ </template>
+ <template #action>
+ <div>
+ <h2>
+ {{ t('core', 'Please upgrade to a more recent browser') }}
+ </h2>
+ <NcButton class="content-unsupported-browser__continue" type="primary" @click="forceBrowsing">
+ {{ t('core', 'Continue with this outdated browser') }}
+ </NcButton>
+ </div>
+
+ <ul class="content-unsupported-browser__list">
+ <h3>{{ t('core', 'Supported versions') }}</h3>
+ <li v-for="browser in formattedBrowsersList" :key="browser">
+ {{ browser }}
+ </li>
+ </ul>
+ </template>
+ </NcEmptyContent>
+ </div>
+</template>
+
+<script>
+import { generateUrl } from '@nextcloud/router'
+import { translate as t, translatePlural as n } from '@nextcloud/l10n'
+import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
+import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent'
+import Web from 'vue-material-design-icons/Web'
+
+import { browserStorageKey } from '../utils/RedirectUnsupportedBrowsers.js'
+import { supportedBrowsers } from '../services/BrowsersListService.js'
+import browserStorage from '../services/BrowserStorageService.js'
+import logger from '../services/LoggerService.js'
+
+logger.debug('Supported browsers', { supportedBrowsers })
+
+export default {
+ name: 'UnsupportedBrowser',
+ components: {
+ Web,
+ NcButton,
+ NcEmptyContent,
+ },
+
+ data() {
+ return {
+ agents: {},
+ }
+ },
+
+ computed: {
+ isMobile() {
+ return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
+ },
+
+ /**
+ * Filter out or include mobile/desktop browsers depending
+ * on the current user platform/device
+ */
+ filteredSupportedBrowsers() {
+ return supportedBrowsers.filter(browser => {
+ if (!browser) {
+ return false
+ }
+
+ if (this.isMobile) {
+ return this.isMobileBrowser(browser)
+ }
+ return !this.isMobileBrowser(browser)
+ })
+ },
+
+ formattedBrowsersList() {
+ const list = {}
+
+ // supportedBrowsers is generated by webpack at compilation time
+ this.filteredSupportedBrowsers.forEach(browser => {
+ const [id, version] = browser.split(' ')
+ if (!list[id] || list[id] < parseFloat(version, 10)) {
+ list[id] = parseFloat(version, 10)
+ }
+ })
+
+ return Object.keys(list).map(id => {
+ if (!this.agents[id]?.browser) {
+ return null
+ }
+
+ const version = list[id]
+ const name = this.agents[id]?.browser
+ return this.t('core', '{name} version {version} and above', {
+ name, version,
+ })
+ }).filter(entry => entry !== null)
+ },
+ },
+
+ async beforeMount() {
+ // Dynamic load big list of user agents
+ // eslint-disable-next-line node/no-extraneous-import
+ const { agents } = await import('caniuse-lite')
+ this.agents = agents
+ },
+
+ methods: {
+ t,
+ n,
+
+ // Set the flag allowing this browser and redirect to home
+ forceBrowsing() {
+ browserStorage.setItem(browserStorageKey, true)
+ window.location = generateUrl('/')
+ },
+
+ /**
+ * Detect if the browserslist browser is a mobile one
+ * https://github.com/browserslist/browserslist#query-composition
+ *
+ * @param {string} browser a valid browserlist browser. e.g `and_chr 90`
+ */
+ isMobileBrowser(browser) {
+ browser = browser.toLowerCase()
+ return browser.includes('and_')
+ || browser.includes('android')
+ || browser.includes('ios_')
+ || browser.includes('mobile')
+ || browser.includes('_mob')
+ || browser.includes('samsung')
+ },
+ },
+}
+</script>
+
+<style lang="scss" scoped>
+.content-unsupported-browser {
+ display: flex;
+ justify-content: center;
+ width: 400px;
+ max-width: 90vw;
+ margin: auto;
+ padding: 30px;
+
+ .empty-content {
+ margin: 0;
+ &::v-deep .empty-content__icon {
+ opacity: 1;
+ }
+ }
+
+ &__continue {
+ display: block;
+ margin: 20px auto;
+ }
+
+ &__list {
+ margin-top: 60px;
+ margin-bottom: 30px;
+ li {
+ text-align: left;
+ }
+ }
+}
+
+</style>
diff --git a/core/templates/unsupportedbrowser.php b/core/templates/unsupportedbrowser.php
new file mode 100644
index 00000000000..54547e204f3
--- /dev/null
+++ b/core/templates/unsupportedbrowser.php
@@ -0,0 +1 @@
+<div id="unsupported-browser"></div>
diff --git a/dist/core-unsupported-browser.js b/dist/core-unsupported-browser.js
new file mode 100644
index 00000000000..a1a9d55e93a
--- /dev/null
+++ b/dist/core-unsupported-browser.js
@@ -0,0 +1,3 @@
+/*! For license information please see core-unsupported-browser.js.LICENSE.txt */
+!function(){var n,t,e,r={16091:function(n,t,e){"use strict";var r=e(79753),o=e(20144),i=e(81655),u=e(31e3),s=e.n(u),a=e(77727),c=e.n(a),l=((0,i.ZI)({allowHigherVersions:!0,browsers:c()}),s()(c())),d=(0,e(62556).getBuilder)("nextcloud").clearOnLogout().persist().build(),p=(0,e(17499).IY)().setApp("core").detectUser().build(),f="unsupported-browser-ignore",v=(d.getItem(f),e(9944)),b=e(10861),A=e.n(b),m=e(93455),w=e.n(m),y=e(49298);function g(n,t,e,r,o,i,u){try{var s=n[i](u),a=s.value}catch(n){return void e(n)}s.done?t(a):Promise.resolve(a).then(r,o)}function h(n,t){(null==t||t>n.length)&&(t=n.length);for(var e=0,r=new Array(t);e<t;e++)r[e]=n[e];return r}p.debug("Supported browsers",{supportedBrowsers:l});var _={name:"UnsupportedBrowser",components:{Web:y.Z,NcButton:A(),NcEmptyContent:w()},data:function(){return{agents:{}}},computed:{isMobile:function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},filteredSupportedBrowsers:function(){var n=this;return l.filter((function(t){return!!t&&(n.isMobile?n.isMobileBrowser(t):!n.isMobileBrowser(t))}))},formattedBrowsersList:function(){var n=this,t={};return this.filteredSupportedBrowsers.forEach((function(n){var e,r,o=(e=n.split(" "),r=2,function(n){if(Array.isArray(n))return n}(e)||function(n,t){var e=null==n?null:"undefined"!=typeof Symbol&&n[Symbol.iterator]||n["@@iterator"];if(null!=e){var r,o,i=[],u=!0,s=!1;try{for(e=e.call(n);!(u=(r=e.next()).done)&&(i.push(r.value),!t||i.length!==t);u=!0);}catch(n){s=!0,o=n}finally{try{u||null==e.return||e.return()}finally{if(s)throw o}}return i}}(e,r)||function(n,t){if(n){if("string"==typeof n)return h(n,t);var e=Object.prototype.toString.call(n).slice(8,-1);return"Object"===e&&n.constructor&&(e=n.constructor.name),"Map"===e||"Set"===e?Array.from(n):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?h(n,t):void 0}}(e,r)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),i=o[0],u=o[1];(!t[i]||t[i]<parseFloat(u,10))&&(t[i]=parseFloat(u,10))})),Object.keys(t).map((function(e){var r,o;if(null===(r=n.agents[e])||void 0===r||!r.browser)return null;var i=t[e],u=null===(o=n.agents[e])||void 0===o?void 0:o.browser;return n.t("core","{name} version {version} and above",{name:u,version:i})})).filter((function(n){return null!==n}))}},beforeMount:function(){var n,t=this;return(n=regeneratorRuntime.mark((function n(){var r,o;return regeneratorRuntime.wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return n.next=2,e.e(7874).then(e.t.bind(e,90614,19));case 2:r=n.sent,o=r.agents,t.agents=o;case 5:case"end":return n.stop()}}),n)})),function(){var t=this,e=arguments;return new Promise((function(r,o){var i=n.apply(t,e);function u(n){g(i,r,o,u,s,"next",n)}function s(n){g(i,r,o,u,s,"throw",n)}u(void 0)}))})()},methods:{t:v.translate,n:v.translatePlural,forceBrowsing:function(){d.setItem(f,!0),window.location=(0,r.generateUrl)("/")},isMobileBrowser:function(n){return(n=n.toLowerCase()).includes("and_")||n.includes("android")||n.includes("ios_")||n.includes("mobile")||n.includes("_mob")||n.includes("samsung")}}},C=_,x=e(93379),O=e.n(x),j=e(7795),B=e.n(j),S=e(90569),k=e.n(S),P=e(3565),M=e.n(P),I=e(19216),E=e.n(I),Z=e(44589),T=e.n(Z),U=e(73366),D={};D.styleTagTransform=T(),D.setAttributes=M(),D.insert=k().bind(null,"head"),D.domAPI=B(),D.insertStyleElement=E(),O()(U.Z,D),U.Z&&U.Z.locals&&U.Z.locals;var F=(0,e(51900).Z)(C,(function(){var n=this,t=n.$createElement,e=n._self._c||t;return e("div",{staticClass:"content-unsupported-browser guest-box"},[e("NcEmptyContent",{scopedSlots:n._u([{key:"icon",fn:function(){return[e("Web")]},proxy:!0},{key:"action",fn:function(){return[e("div",[e("h2",[n._v("\n\t\t\t\t\t"+n._s(n.t("core","Please upgrade to a more recent browser"))+"\n\t\t\t\t")]),n._v(" "),e("NcButton",{staticClass:"content-unsupported-browser__continue",attrs:{type:"primary"},on:{click:n.forceBrowsing}},[n._v("\n\t\t\t\t\t"+n._s(n.t("core","Continue with this outdated browser"))+"\n\t\t\t\t")])],1),n._v(" "),e("ul",{staticClass:"content-unsupported-browser__list"},[e("h3",[n._v(n._s(n.t("core","Supported versions")))]),n._v(" "),n._l(n.formattedBrowsersList,(function(t){return e("li",{key:t},[n._v("\n\t\t\t\t\t"+n._s(t)+"\n\t\t\t\t")])}))],2)]},proxy:!0}])},[n._v("\n\t\t"+n._s(n.t("core","This browser is not supported"))+"\n\t\t")])],1)}),[],!1,null,"6dee3851",null).exports;"true"===d.getItem(f)&&(window.location=(0,r.generateUrl)("/")),new o.ZP({el:"#unsupported-browser",name:"UnsupportedBrowserRoot",render:function(n){return n(F)}})},73366:function(n,t,e){"use strict";var r=e(87537),o=e.n(r),i=e(23645),u=e.n(i)()(o());u.push([n.id,".content-unsupported-browser[data-v-6dee3851]{display:flex;justify-content:center;width:400px;max-width:90vw;margin:auto;padding:30px}.content-unsupported-browser .empty-content[data-v-6dee3851]{margin:0}.content-unsupported-browser .empty-content[data-v-6dee3851] .empty-content__icon{opacity:1}.content-unsupported-browser__continue[data-v-6dee3851]{display:block;margin:20px auto}.content-unsupported-browser__list[data-v-6dee3851]{margin-top:60px;margin-bottom:30px}.content-unsupported-browser__list li[data-v-6dee3851]{text-align:left}","",{version:3,sources:["webpack://./core/src/views/UnsupportedBrowser.vue"],names:[],mappings:"AAiKA,8CACC,YAAA,CACA,sBAAA,CACA,WAAA,CACA,cAAA,CACA,WAAA,CACA,YAAA,CAEA,6DACC,QAAA,CACA,kFACC,SAAA,CAIF,wDACC,aAAA,CACA,gBAAA,CAGD,oDACC,eAAA,CACA,kBAAA,CACA,uDACC,eAAA",sourcesContent:["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.content-unsupported-browser {\n\tdisplay: flex;\n\tjustify-content: center;\n\twidth: 400px;\n\tmax-width: 90vw;\n\tmargin: auto;\n\tpadding: 30px;\n\n\t.empty-content {\n\t\tmargin: 0;\n\t\t&::v-deep .empty-content__icon {\n\t\t\topacity: 1;\n\t\t}\n\t}\n\n\t&__continue {\n\t\tdisplay: block;\n\t\tmargin: 20px auto;\n\t}\n\n\t&__list {\n\t\tmargin-top: 60px;\n\t\tmargin-bottom: 30px;\n\t\tli {\n\t\t\ttext-align: left;\n\t\t}\n\t}\n}\n\n"],sourceRoot:""}]),t.Z=u},72950:function(){}},o={};function i(n){var t=o[n];if(void 0!==t)return t.exports;var e=o[n]={id:n,loaded:!1,exports:{}};return r[n].call(e.exports,e,e.exports,i),e.loaded=!0,e.exports}i.m=r,i.amdD=function(){throw new Error("define cannot be used indirect")},i.amdO={},n=[],i.O=function(t,e,r,o){if(!e){var u=1/0;for(l=0;l<n.length;l++){e=n[l][0],r=n[l][1],o=n[l][2];for(var s=!0,a=0;a<e.length;a++)(!1&o||u>=o)&&Object.keys(i.O).every((function(n){return i.O[n](e[a])}))?e.splice(a--,1):(s=!1,o<u&&(u=o));if(s){n.splice(l--,1);var c=r();void 0!==c&&(t=c)}}return t}o=o||0;for(var l=n.length;l>0&&n[l-1][2]>o;l--)n[l]=n[l-1];n[l]=[e,r,o]},i.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return i.d(t,{a:t}),t},e=Object.getPrototypeOf?function(n){return Object.getPrototypeOf(n)}:function(n){return n.__proto__},i.t=function(n,r){if(1&r&&(n=this(n)),8&r)return n;if("object"==typeof n&&n){if(4&r&&n.__esModule)return n;if(16&r&&"function"==typeof n.then)return n}var o=Object.create(null);i.r(o);var u={};t=t||[null,e({}),e([]),e(e)];for(var s=2&r&&n;"object"==typeof s&&!~t.indexOf(s);s=e(s))Object.getOwnPropertyNames(s).forEach((function(t){u[t]=function(){return n[t]}}));return u.default=function(){return n},i.d(o,u),o},i.d=function(n,t){for(var e in t)i.o(t,e)&&!i.o(n,e)&&Object.defineProperty(n,e,{enumerable:!0,get:t[e]})},i.e=function(){return Promise.resolve()},i.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(n){if("object"==typeof window)return window}}(),i.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},i.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},i.nmd=function(n){return n.paths=[],n.children||(n.children=[]),n},i.j=9315,function(){i.b=document.baseURI||self.location.href;var n={9315:0};i.O.j=function(t){return 0===n[t]};var t=function(t,e){var r,o,u=e[0],s=e[1],a=e[2],c=0;if(u.some((function(t){return 0!==n[t]}))){for(r in s)i.o(s,r)&&(i.m[r]=s[r]);if(a)var l=a(i)}for(t&&t(e);c<u.length;c++)o=u[c],i.o(n,o)&&n[o]&&n[o][0](),n[o]=0;return i.O(l)},e=self.webpackChunknextcloud=self.webpackChunknextcloud||[];e.forEach(t.bind(null,0)),e.push=t.bind(null,e.push.bind(e))}(),i.nc=void 0;var u=i.O(void 0,[7874],(function(){return i(16091)}));u=i.O(u)}();
+//# sourceMappingURL=core-unsupported-browser.js.map?v=7b66cb3eeb96b0de97b8 \ No newline at end of file
diff --git a/dist/core-unsupported-browser.js.map b/dist/core-unsupported-browser.js.map
new file mode 100644
index 00000000000..10a344004d5
--- /dev/null
+++ b/dist/core-unsupported-browser.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"core-unsupported-browser.js?v=7b66cb3eeb96b0de97b8","mappings":"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","sources":["webpack:///nextcloud/webpack/runtime/chunk loaded","webpack:///nextcloud/webpack/runtime/create fake namespace object","webpack:///nextcloud/core/src/services/BrowsersListService.js","webpack:///nextcloud/core/src/services/BrowserStorageService.js","webpack:///nextcloud/core/src/services/LoggerService.js","webpack:///nextcloud/core/src/utils/RedirectUnsupportedBrowsers.js","webpack:///nextcloud/core/src/views/UnsupportedBrowser.vue","webpack:///nextcloud/core/src/views/UnsupportedBrowser.vue?vue&type=script&lang=js&","webpack://nextcloud/./core/src/views/UnsupportedBrowser.vue?ac27","webpack://nextcloud/./core/src/views/UnsupportedBrowser.vue?d53c","webpack:///nextcloud/core/src/views/UnsupportedBrowser.vue?vue&type=template&id=6dee3851&scoped=true&","webpack:///nextcloud/core/src/unsupported-browser.js","webpack:///nextcloud/core/src/views/UnsupportedBrowser.vue?vue&type=style&index=0&id=6dee3851&lang=scss&scoped=true&","webpack:///nextcloud/webpack/bootstrap","webpack:///nextcloud/webpack/runtime/amd define","webpack:///nextcloud/webpack/runtime/amd options","webpack:///nextcloud/webpack/runtime/compat get default export","webpack:///nextcloud/webpack/runtime/define property getters","webpack:///nextcloud/webpack/runtime/ensure chunk","webpack:///nextcloud/webpack/runtime/global","webpack:///nextcloud/webpack/runtime/hasOwnProperty shorthand","webpack:///nextcloud/webpack/runtime/make namespace object","webpack:///nextcloud/webpack/runtime/node module decorator","webpack:///nextcloud/webpack/runtime/runtimeId","webpack:///nextcloud/webpack/runtime/jsonp chunk loading","webpack:///nextcloud/webpack/runtime/nonce","webpack:///nextcloud/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = function(result, chunkIds, fn, priority) {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar chunkIds = deferred[i][0];\n\t\tvar fn = deferred[i][1];\n\t\tvar priority = deferred[i][2];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","var getProto = Object.getPrototypeOf ? function(obj) { return Object.getPrototypeOf(obj); } : function(obj) { return obj.__proto__; };\nvar leafPrototypes;\n// create a fake namespace object\n// mode & 1: value is a module id, require it\n// mode & 2: merge all properties of value into the ns\n// mode & 4: return value when already ns object\n// mode & 16: return value when it's Promise-like\n// mode & 8|1: behave like require\n__webpack_require__.t = function(value, mode) {\n\tif(mode & 1) value = this(value);\n\tif(mode & 8) return value;\n\tif(typeof value === 'object' && value) {\n\t\tif((mode & 4) && value.__esModule) return value;\n\t\tif((mode & 16) && typeof value.then === 'function') return value;\n\t}\n\tvar ns = Object.create(null);\n\t__webpack_require__.r(ns);\n\tvar def = {};\n\tleafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)];\n\tfor(var current = mode & 2 && value; typeof current == 'object' && !~leafPrototypes.indexOf(current); current = getProto(current)) {\n\t\tObject.getOwnPropertyNames(current).forEach(function(key) { def[key] = function() { return value[key]; }; });\n\t}\n\tdef['default'] = function() { return value; };\n\t__webpack_require__.d(ns, def);\n\treturn ns;\n};","/**\n * @copyright 2021 John Molakvoæ <skjnldsv@protonmail.com>\n *\n * @author John Molakvoæ <skjnldsv@protonmail.com>\n *\n * @license GNU AGPL version 3 or any later version\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport { getUserAgentRegExp } from 'browserslist-useragent-regexp'\n// eslint-disable-next-line node/no-extraneous-import\nimport browserslist from 'browserslist'\nimport browserslistConfig from '@nextcloud/browserslist-config'\n\n// Generate a regex that matches user agents to detect incompatible browsers\nexport const supportedBrowsersRegExp = getUserAgentRegExp({ allowHigherVersions: true, browsers: browserslistConfig })\nexport const supportedBrowsers = browserslist(browserslistConfig)\n","/**\n * @copyright 2021 John Molakvoæ <skjnldsv@protonmail.com>\n *\n * @author John Molakvoæ <skjnldsv@protonmail.com>\n *\n * @license GNU AGPL version 3 or any later version\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport { getBuilder } from '@nextcloud/browser-storage'\n\nexport default getBuilder('nextcloud')\n\t.clearOnLogout()\n\t.persist()\n\t.build()\n","/**\n * @copyright 2021 John Molakvoæ <skjnldsv@protonmail.com>\n *\n * @author John Molakvoæ <skjnldsv@protonmail.com>\n *\n * @license GNU AGPL version 3 or any later version\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport { getLoggerBuilder } from '@nextcloud/logger'\n\nexport default getLoggerBuilder()\n\t.setApp('core')\n\t.detectUser()\n\t.build()\n","/**\n * @copyright 2021 John Molakvoæ <skjnldsv@protonmail.com>\n *\n * @author John Molakvoæ <skjnldsv@protonmail.com>\n *\n * @license GNU AGPL version 3 or any later version\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { generateUrl } from '@nextcloud/router'\n\nimport { supportedBrowsersRegExp } from '../services/BrowsersListService.js'\nimport browserStorage from '../services/BrowserStorageService.js'\nimport logger from '../services/LoggerService.js'\n\nconst redirectPath = '/unsupported'\nexport const browserStorageKey = 'unsupported-browser-ignore'\n\nconst isBrowserOverridden = browserStorage.getItem(browserStorageKey) === 'true'\n\n/**\n * Test the current browser user agent against our official browserslist config\n * and redirect if unsupported\n */\nexport const testSupportedBrowser = function() {\n\tif (supportedBrowsersRegExp.test(navigator.userAgent)) {\n\t\tlogger.debug('this browser is officially supported ! 🚀')\n\t\treturn\n\t}\n\n\t// If incompatible BUT ignored, let's keep going\n\tif (isBrowserOverridden) {\n\t\tlogger.debug('this browser is NOT supported but has been manually overridden ! ⚠️')\n\t\treturn\n\t}\n\n\t// If incompatible, NOT overridden AND NOT already on the warning page,\n\t// redirect to the unsupported warning page\n\tif (window.location.pathname.indexOf(redirectPath) === -1) {\n\t\twindow.location = generateUrl(redirectPath)\n\t}\n}\n"," <!--\n - @copyright Copyright (c) 2021 John Molakvoæ <skjnldsv@protonmail.com>\n -\n - @author John Molakvoæ <skjnldsv@protonmail.com>\n -\n - @license GNU AGPL version 3 or any later version\n -\n - This program is free software: you can redistribute it and/or modify\n - it under the terms of the GNU Affero General Public License as\n - published by the Free Software Foundation, either version 3 of the\n - License, or (at your option) any later version.\n -\n - This program is distributed in the hope that it will be useful,\n - but WITHOUT ANY WARRANTY; without even the implied warranty of\n - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n - GNU Affero General Public License for more details.\n -\n - You should have received a copy of the GNU Affero General Public License\n - along with this program. If not, see <http://www.gnu.org/licenses/>.\n -\n -->\n<template>\n\t<div class=\"content-unsupported-browser guest-box\">\n\t\t<NcEmptyContent>\n\t\t\t{{ t('core', 'This browser is not supported') }}\n\t\t\t<template #icon>\n\t\t\t\t<Web />\n\t\t\t</template>\n\t\t\t<template #action>\n\t\t\t\t<div>\n\t\t\t\t\t<h2>\n\t\t\t\t\t\t{{ t('core', 'Please upgrade to a more recent browser') }}\n\t\t\t\t\t</h2>\n\t\t\t\t\t<NcButton class=\"content-unsupported-browser__continue\" type=\"primary\" @click=\"forceBrowsing\">\n\t\t\t\t\t\t{{ t('core', 'Continue with this outdated browser') }}\n\t\t\t\t\t</NcButton>\n\t\t\t\t</div>\n\n\t\t\t\t<ul class=\"content-unsupported-browser__list\">\n\t\t\t\t\t<h3>{{ t('core', 'Supported versions') }}</h3>\n\t\t\t\t\t<li v-for=\"browser in formattedBrowsersList\" :key=\"browser\">\n\t\t\t\t\t\t{{ browser }}\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t</template>\n\t\t</NcEmptyContent>\n\t</div>\n</template>\n\n<script>\nimport { generateUrl } from '@nextcloud/router'\nimport { translate as t, translatePlural as n } from '@nextcloud/l10n'\nimport NcButton from '@nextcloud/vue/dist/Components/NcButton.js'\nimport NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent'\nimport Web from 'vue-material-design-icons/Web'\n\nimport { browserStorageKey } from '../utils/RedirectUnsupportedBrowsers.js'\nimport { supportedBrowsers } from '../services/BrowsersListService.js'\nimport browserStorage from '../services/BrowserStorageService.js'\nimport logger from '../services/LoggerService.js'\n\nlogger.debug('Supported browsers', { supportedBrowsers })\n\nexport default {\n\tname: 'UnsupportedBrowser',\n\tcomponents: {\n\t\tWeb,\n\t\tNcButton,\n\t\tNcEmptyContent,\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tagents: {},\n\t\t}\n\t},\n\n\tcomputed: {\n\t\tisMobile() {\n\t\t\treturn /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)\n\t\t},\n\n\t\t/**\n\t\t * Filter out or include mobile/desktop browsers depending\n\t\t * on the current user platform/device\n\t\t */\n\t\tfilteredSupportedBrowsers() {\n\t\t\treturn supportedBrowsers.filter(browser => {\n\t\t\t\tif (!browser) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\n\t\t\t\tif (this.isMobile) {\n\t\t\t\t\treturn this.isMobileBrowser(browser)\n\t\t\t\t}\n\t\t\t\treturn !this.isMobileBrowser(browser)\n\t\t\t})\n\t\t},\n\n\t\tformattedBrowsersList() {\n\t\t\tconst list = {}\n\n\t\t\t// supportedBrowsers is generated by webpack at compilation time\n\t\t\tthis.filteredSupportedBrowsers.forEach(browser => {\n\t\t\t\tconst [id, version] = browser.split(' ')\n\t\t\t\tif (!list[id] || list[id] < parseFloat(version, 10)) {\n\t\t\t\t\tlist[id] = parseFloat(version, 10)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\treturn Object.keys(list).map(id => {\n\t\t\t\tif (!this.agents[id]?.browser) {\n\t\t\t\t\treturn null\n\t\t\t\t}\n\n\t\t\t\tconst version = list[id]\n\t\t\t\tconst name = this.agents[id]?.browser\n\t\t\t\treturn this.t('core', '{name} version {version} and above', {\n\t\t\t\t\tname, version,\n\t\t\t\t})\n\t\t\t}).filter(entry => entry !== null)\n\t\t},\n\t},\n\n\tasync beforeMount() {\n\t\t// Dynamic load big list of user agents\n\t\t// eslint-disable-next-line node/no-extraneous-import\n\t\tconst { agents } = await import('caniuse-lite')\n\t\tthis.agents = agents\n\t},\n\n\tmethods: {\n\t\tt,\n\t\tn,\n\n\t\t// Set the flag allowing this browser and redirect to home\n\t\tforceBrowsing() {\n\t\t\tbrowserStorage.setItem(browserStorageKey, true)\n\t\t\twindow.location = generateUrl('/')\n\t\t},\n\n\t\t/**\n\t\t * Detect if the browserslist browser is a mobile one\n\t\t * https://github.com/browserslist/browserslist#query-composition\n\t\t *\n\t\t * @param {string} browser a valid browserlist browser. e.g `and_chr 90`\n\t\t */\n\t\tisMobileBrowser(browser) {\n\t\t\tbrowser = browser.toLowerCase()\n\t\t\treturn browser.includes('and_')\n\t\t\t\t|| browser.includes('android')\n\t\t\t\t|| browser.includes('ios_')\n\t\t\t\t|| browser.includes('mobile')\n\t\t\t\t|| browser.includes('_mob')\n\t\t\t\t|| browser.includes('samsung')\n\t\t},\n\t},\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.content-unsupported-browser {\n\tdisplay: flex;\n\tjustify-content: center;\n\twidth: 400px;\n\tmax-width: 90vw;\n\tmargin: auto;\n\tpadding: 30px;\n\n\t.empty-content {\n\t\tmargin: 0;\n\t\t&::v-deep .empty-content__icon {\n\t\t\topacity: 1;\n\t\t}\n\t}\n\n\t&__continue {\n\t\tdisplay: block;\n\t\tmargin: 20px auto;\n\t}\n\n\t&__list {\n\t\tmargin-top: 60px;\n\t\tmargin-bottom: 30px;\n\t\tli {\n\t\t\ttext-align: left;\n\t\t}\n\t}\n}\n\n</style>\n","import mod from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./UnsupportedBrowser.vue?vue&type=script&lang=js&\"; export default mod; export * from \"-!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./UnsupportedBrowser.vue?vue&type=script&lang=js&\"","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/sass-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./UnsupportedBrowser.vue?vue&type=style&index=0&id=6dee3851&lang=scss&scoped=true&\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/sass-loader/dist/cjs.js!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./UnsupportedBrowser.vue?vue&type=style&index=0&id=6dee3851&lang=scss&scoped=true&\";\n export default content && content.locals ? content.locals : undefined;\n","import { render, staticRenderFns } from \"./UnsupportedBrowser.vue?vue&type=template&id=6dee3851&scoped=true&\"\nimport script from \"./UnsupportedBrowser.vue?vue&type=script&lang=js&\"\nexport * from \"./UnsupportedBrowser.vue?vue&type=script&lang=js&\"\nimport style0 from \"./UnsupportedBrowser.vue?vue&type=style&index=0&id=6dee3851&lang=scss&scoped=true&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"6dee3851\",\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"content-unsupported-browser guest-box\"},[_c('NcEmptyContent',{scopedSlots:_vm._u([{key:\"icon\",fn:function(){return [_c('Web')]},proxy:true},{key:\"action\",fn:function(){return [_c('div',[_c('h2',[_vm._v(\"\\n\\t\\t\\t\\t\\t\"+_vm._s(_vm.t('core', 'Please upgrade to a more recent browser'))+\"\\n\\t\\t\\t\\t\")]),_vm._v(\" \"),_c('NcButton',{staticClass:\"content-unsupported-browser__continue\",attrs:{\"type\":\"primary\"},on:{\"click\":_vm.forceBrowsing}},[_vm._v(\"\\n\\t\\t\\t\\t\\t\"+_vm._s(_vm.t('core', 'Continue with this outdated browser'))+\"\\n\\t\\t\\t\\t\")])],1),_vm._v(\" \"),_c('ul',{staticClass:\"content-unsupported-browser__list\"},[_c('h3',[_vm._v(_vm._s(_vm.t('core', 'Supported versions')))]),_vm._v(\" \"),_vm._l((_vm.formattedBrowsersList),function(browser){return _c('li',{key:browser},[_vm._v(\"\\n\\t\\t\\t\\t\\t\"+_vm._s(browser)+\"\\n\\t\\t\\t\\t\")])})],2)]},proxy:true}])},[_vm._v(\"\\n\\t\\t\"+_vm._s(_vm.t('core', 'This browser is not supported'))+\"\\n\\t\\t\")])],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","/**\n * @copyright 2021 John Molakvoæ <skjnldsv@protonmail.com>\n *\n * @author John Molakvoæ <skjnldsv@protonmail.com>\n *\n * @license GNU AGPL version 3 or any later version\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { generateUrl } from '@nextcloud/router'\nimport Vue from 'vue'\n\nimport { browserStorageKey } from './utils/RedirectUnsupportedBrowsers.js'\nimport browserStorage from './services/BrowserStorageService.js'\nimport UnsupportedBrowser from './views/UnsupportedBrowser.vue'\n\n// If the ignore token is set, redirect\nif (browserStorage.getItem(browserStorageKey) === 'true') {\n\twindow.location = generateUrl('/')\n}\n\nexport default new Vue({\n\tel: '#unsupported-browser',\n\t// eslint-disable-next-line vue/match-component-file-name\n\tname: 'UnsupportedBrowserRoot',\n\trender: h => h(UnsupportedBrowser),\n})\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".content-unsupported-browser[data-v-6dee3851]{display:flex;justify-content:center;width:400px;max-width:90vw;margin:auto;padding:30px}.content-unsupported-browser .empty-content[data-v-6dee3851]{margin:0}.content-unsupported-browser .empty-content[data-v-6dee3851] .empty-content__icon{opacity:1}.content-unsupported-browser__continue[data-v-6dee3851]{display:block;margin:20px auto}.content-unsupported-browser__list[data-v-6dee3851]{margin-top:60px;margin-bottom:30px}.content-unsupported-browser__list li[data-v-6dee3851]{text-align:left}\", \"\",{\"version\":3,\"sources\":[\"webpack://./core/src/views/UnsupportedBrowser.vue\"],\"names\":[],\"mappings\":\"AAiKA,8CACC,YAAA,CACA,sBAAA,CACA,WAAA,CACA,cAAA,CACA,WAAA,CACA,YAAA,CAEA,6DACC,QAAA,CACA,kFACC,SAAA,CAIF,wDACC,aAAA,CACA,gBAAA,CAGD,oDACC,eAAA,CACA,kBAAA,CACA,uDACC,eAAA\",\"sourcesContent\":[\"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n.content-unsupported-browser {\\n\\tdisplay: flex;\\n\\tjustify-content: center;\\n\\twidth: 400px;\\n\\tmax-width: 90vw;\\n\\tmargin: auto;\\n\\tpadding: 30px;\\n\\n\\t.empty-content {\\n\\t\\tmargin: 0;\\n\\t\\t&::v-deep .empty-content__icon {\\n\\t\\t\\topacity: 1;\\n\\t\\t}\\n\\t}\\n\\n\\t&__continue {\\n\\t\\tdisplay: block;\\n\\t\\tmargin: 20px auto;\\n\\t}\\n\\n\\t&__list {\\n\\t\\tmargin-top: 60px;\\n\\t\\tmargin-bottom: 30px;\\n\\t\\tli {\\n\\t\\t\\ttext-align: left;\\n\\t\\t}\\n\\t}\\n}\\n\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","__webpack_require__.amdD = function () {\n\tthrow new Error('define cannot be used indirect');\n};","__webpack_require__.amdO = {};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","// The chunk loading function for additional chunks\n// Since all referenced chunks are already included\n// in this file, this function is empty here.\n__webpack_require__.e = function() { return Promise.resolve(); };","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nmd = function(module) {\n\tmodule.paths = [];\n\tif (!module.children) module.children = [];\n\treturn module;\n};","__webpack_require__.j = 9315;","__webpack_require__.b = document.baseURI || self.location.href;\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t9315: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunknextcloud\"] = self[\"webpackChunknextcloud\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","__webpack_require__.nc = undefined;","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [7874], function() { return __webpack_require__(16091); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["deferred","leafPrototypes","getProto","supportedBrowsers","getUserAgentRegExp","allowHigherVersions","browsers","browserslistConfig","browserslist","getBuilder","clearOnLogout","persist","build","getLoggerBuilder","setApp","detectUser","browserStorageKey","browserStorage","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","_vm","this","_h","$createElement","_c","_self","staticClass","scopedSlots","_u","key","fn","proxy","_v","_s","t","attrs","on","forceBrowsing","_l","browser","window","location","generateUrl","Vue","el","name","render","h","UnsupportedBrowser","___CSS_LOADER_EXPORT___","push","module","id","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","loaded","__webpack_modules__","call","m","amdD","Error","amdO","O","result","chunkIds","priority","notFulfilled","Infinity","i","length","fulfilled","j","Object","keys","every","splice","r","n","getter","__esModule","d","a","getPrototypeOf","obj","__proto__","value","mode","then","ns","create","def","current","indexOf","getOwnPropertyNames","forEach","definition","o","defineProperty","enumerable","get","e","Promise","resolve","g","globalThis","Function","prop","prototype","hasOwnProperty","Symbol","toStringTag","nmd","paths","children","b","document","baseURI","self","href","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","data","moreModules","runtime","some","chunkLoadingGlobal","bind","nc","__webpack_exports__"],"sourceRoot":""} \ No newline at end of file
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 1b721a2cc33..5cb4cbf76d6 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -994,6 +994,7 @@ return array(
'OC\\Core\\Controller\\SetupController' => $baseDir . '/core/Controller/SetupController.php',
'OC\\Core\\Controller\\TwoFactorChallengeController' => $baseDir . '/core/Controller/TwoFactorChallengeController.php',
'OC\\Core\\Controller\\UnifiedSearchController' => $baseDir . '/core/Controller/UnifiedSearchController.php',
+ 'OC\\Core\\Controller\\UnsupportedBrowserController' => $baseDir . '/core/Controller/UnsupportedBrowserController.php',
'OC\\Core\\Controller\\UserController' => $baseDir . '/core/Controller/UserController.php',
'OC\\Core\\Controller\\WalledGardenController' => $baseDir . '/core/Controller/WalledGardenController.php',
'OC\\Core\\Controller\\WebAuthnController' => $baseDir . '/core/Controller/WebAuthnController.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 4539f89f206..f5d21b4d97b 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -1027,6 +1027,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Core\\Controller\\SetupController' => __DIR__ . '/../../..' . '/core/Controller/SetupController.php',
'OC\\Core\\Controller\\TwoFactorChallengeController' => __DIR__ . '/../../..' . '/core/Controller/TwoFactorChallengeController.php',
'OC\\Core\\Controller\\UnifiedSearchController' => __DIR__ . '/../../..' . '/core/Controller/UnifiedSearchController.php',
+ 'OC\\Core\\Controller\\UnsupportedBrowserController' => __DIR__ . '/../../..' . '/core/Controller/UnsupportedBrowserController.php',
'OC\\Core\\Controller\\UserController' => __DIR__ . '/../../..' . '/core/Controller/UserController.php',
'OC\\Core\\Controller\\WalledGardenController' => __DIR__ . '/../../..' . '/core/Controller/WalledGardenController.php',
'OC\\Core\\Controller\\WebAuthnController' => __DIR__ . '/../../..' . '/core/Controller/WebAuthnController.php',
diff --git a/package-lock.json b/package-lock.json
index 4a30bf6eddd..36d50089979 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,6 +12,8 @@
"@chenfengyuan/vue-qrcode": "^1.0.2",
"@nextcloud/auth": "^1.3.0",
"@nextcloud/axios": "^1.10.0",
+ "@nextcloud/browser-storage": "^0.1.1",
+ "@nextcloud/browserslist-config": "^2.3.0",
"@nextcloud/calendar-availability-vue": "^0.5.0-beta.2",
"@nextcloud/capabilities": "^1.0.4",
"@nextcloud/dialogs": "^3.1.4",
@@ -31,6 +33,7 @@
"backbone": "^1.4.1",
"blueimp-md5": "^2.19.0",
"bootstrap": "^4.6.0",
+ "browserslist-useragent-regexp": "^3.0.2",
"buffer": "^6.0.3",
"camelcase": "^6.3.0",
"clipboard": "^2.0.10",
@@ -83,7 +86,6 @@
"devDependencies": {
"@babel/node": "^7.17.10",
"@nextcloud/babel-config": "^1.0.0",
- "@nextcloud/browserslist-config": "^2.3.0",
"@nextcloud/eslint-config": "^8.0.0",
"@nextcloud/stylelint-config": "^2.1.2",
"@testing-library/jest-dom": "^5.16.4",
@@ -3414,26 +3416,53 @@
"node": ">=8"
}
},
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
+ "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
"integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
- "dev": true,
"engines": {
"node": ">=6.0.0"
}
},
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
+ "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.14",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
- "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
- "dev": true
+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.15",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz",
"integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==",
- "dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
@@ -3523,7 +3552,6 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@nextcloud/browserslist-config/-/browserslist-config-2.3.0.tgz",
"integrity": "sha512-1Tpkof2e9Q0UicHWahQnXXrubJoqyiaqsH9G52v3cjGeVeH3BCfa1FOa41eBwBSFe2/Jxj/wCH2YVLgIXpWbBg==",
- "dev": true,
"engines": {
"node": "^16.0.0",
"npm": "^7.0.0 || ^8.0.0"
@@ -5447,6 +5475,14 @@
"sprintf-js": "~1.0.2"
}
},
+ "node_modules/argue-cli": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/argue-cli/-/argue-cli-1.2.1.tgz",
+ "integrity": "sha512-Em3HDMlqiVLNOgXUCYz5NG1mx/44aijsxUOO8elmfvAN4/3ar1S3WPTua7WGhsMbeQm8clOwpDZ09sN7C2FnOg==",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"node_modules/aria-query": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz",
@@ -6132,6 +6168,94 @@
"url": "https://opencollective.com/browserslist"
}
},
+ "node_modules/browserslist-useragent-regexp": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/browserslist-useragent-regexp/-/browserslist-useragent-regexp-3.0.2.tgz",
+ "integrity": "sha512-hOvTo9ObY+2PvCLxydvam5WD9hlvWB4bFzRLxc/M5OdJfzjgfsQ9wEF7EpJJP7UJUAnKJdJK28XsSrl5d1DfoA==",
+ "dependencies": {
+ "@types/node": "^16.9.6",
+ "argue-cli": "^1.2.0",
+ "browserslist": "^4.16.3",
+ "chalk": "^4.0.0",
+ "easy-table": "^1.1.1",
+ "useragent": "^2.3.0"
+ },
+ "bin": {
+ "browserslist-useragent-regexp": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/browserslist-useragent-regexp/node_modules/@types/node": {
+ "version": "16.11.68",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.68.tgz",
+ "integrity": "sha512-JkRpuVz3xCNCWaeQ5EHLR/6woMbHZz/jZ7Kmc63AkU+1HxnoUugzSWMck7dsR4DvNYX8jp9wTi9K7WvnxOIQZQ=="
+ },
+ "node_modules/browserslist-useragent-regexp/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/browserslist-useragent-regexp/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/browserslist-useragent-regexp/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/browserslist-useragent-regexp/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "node_modules/browserslist-useragent-regexp/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist-useragent-regexp/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/bser": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
@@ -6436,6 +6560,15 @@
"wrap-ansi": "^6.2.0"
}
},
+ "node_modules/clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
+ "optional": true,
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
"node_modules/clone-deep": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
@@ -7093,6 +7226,18 @@
"node": ">=0.10.0"
}
},
+ "node_modules/defaults": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
+ "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
+ "optional": true,
+ "dependencies": {
+ "clone": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/define-properties": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@@ -7313,6 +7458,17 @@
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
+ "node_modules/easy-table": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.2.0.tgz",
+ "integrity": "sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "optionalDependencies": {
+ "wcwidth": "^1.0.1"
+ }
+ },
"node_modules/ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@@ -15512,6 +15668,14 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/p-limit": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
@@ -16110,8 +16274,7 @@
"node_modules/pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
- "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
- "dev": true
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
},
"node_modules/psl": {
"version": "1.8.0",
@@ -17049,7 +17212,7 @@
"node_modules/select2": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/select2/-/select2-3.5.1.tgz",
- "integrity": "sha1-8oGUibvGX9bTKL5yu+K5XdfofP4="
+ "integrity": "sha512-IFX3UFPpPyK1I1Kuw1R1x+upMyNAZbMlkFhiTnRCRR7ii0KU1brmJMLa3GZcrMWCHiQlm0eKqb6i4XO4pqOrGQ=="
},
"node_modules/semver": {
"version": "6.3.0",
@@ -18066,6 +18229,23 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/terser": {
+ "version": "5.15.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz",
+ "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==",
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.2",
+ "acorn": "^8.5.0",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/terser-webpack-plugin": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.0.tgz",
@@ -18099,24 +18279,6 @@
}
}
},
- "node_modules/terser-webpack-plugin/node_modules/acorn": {
- "version": "8.7.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
- "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
- "optional": true,
- "peer": true,
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/terser-webpack-plugin/node_modules/commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
- },
"node_modules/terser-webpack-plugin/node_modules/schema-utils": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
@@ -18142,37 +18304,21 @@
"node": ">=0.10.0"
}
},
- "node_modules/terser-webpack-plugin/node_modules/terser": {
- "version": "5.10.0",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz",
- "integrity": "sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==",
- "dependencies": {
- "commander": "^2.20.0",
- "source-map": "~0.7.2",
- "source-map-support": "~0.5.20"
- },
+ "node_modules/terser/node_modules/acorn": {
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
+ "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
"bin": {
- "terser": "bin/terser"
+ "acorn": "bin/acorn"
},
"engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "acorn": "^8.5.0"
- },
- "peerDependenciesMeta": {
- "acorn": {
- "optional": true
- }
+ "node": ">=0.4.0"
}
},
- "node_modules/terser-webpack-plugin/node_modules/terser/node_modules/source-map": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
- "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
- "engines": {
- "node": ">= 8"
- }
+ "node_modules/terser/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
},
"node_modules/test-exclude": {
"version": "6.0.0",
@@ -18661,6 +18807,40 @@
"resolved": "https://registry.npmjs.org/url-search-params-polyfill/-/url-search-params-polyfill-8.1.1.tgz",
"integrity": "sha512-KmkCs6SjE6t4ihrfW9JelAPQIIIFbJweaaSLTh/4AO+c58JlDcb+GbdPt8yr5lRcFg4rPswRFRRhBGpWwh0K/Q=="
},
+ "node_modules/useragent": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz",
+ "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==",
+ "dependencies": {
+ "lru-cache": "4.1.x",
+ "tmp": "0.0.x"
+ }
+ },
+ "node_modules/useragent/node_modules/lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dependencies": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "node_modules/useragent/node_modules/tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "dependencies": {
+ "os-tmpdir": "~1.0.2"
+ },
+ "engines": {
+ "node": ">=0.6.0"
+ }
+ },
+ "node_modules/useragent/node_modules/yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A=="
+ },
"node_modules/util": {
"version": "0.10.4",
"resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
@@ -19121,6 +19301,15 @@
"node": ">=10.13.0"
}
},
+ "node_modules/wcwidth": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
+ "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
+ "optional": true,
+ "dependencies": {
+ "defaults": "^1.0.3"
+ }
+ },
"node_modules/webdav": {
"version": "4.11.0",
"resolved": "https://registry.npmjs.org/webdav/-/webdav-4.11.0.tgz",
@@ -22058,23 +22247,44 @@
}
}
},
+ "@jridgewell/gen-mapping": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
+ "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+ "requires": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
"@jridgewell/resolve-uri": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
- "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
- "dev": true
+ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w=="
+ },
+ "@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw=="
+ },
+ "@jridgewell/source-map": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
+ "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
+ "requires": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
},
"@jridgewell/sourcemap-codec": {
"version": "1.4.14",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
- "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
- "dev": true
+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
},
"@jridgewell/trace-mapping": {
"version": "0.3.15",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz",
"integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==",
- "dev": true,
"requires": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
@@ -22145,8 +22355,7 @@
"@nextcloud/browserslist-config": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@nextcloud/browserslist-config/-/browserslist-config-2.3.0.tgz",
- "integrity": "sha512-1Tpkof2e9Q0UicHWahQnXXrubJoqyiaqsH9G52v3cjGeVeH3BCfa1FOa41eBwBSFe2/Jxj/wCH2YVLgIXpWbBg==",
- "dev": true
+ "integrity": "sha512-1Tpkof2e9Q0UicHWahQnXXrubJoqyiaqsH9G52v3cjGeVeH3BCfa1FOa41eBwBSFe2/Jxj/wCH2YVLgIXpWbBg=="
},
"@nextcloud/calendar-availability-vue": {
"version": "0.5.0-beta.2",
@@ -23725,6 +23934,11 @@
"sprintf-js": "~1.0.2"
}
},
+ "argue-cli": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/argue-cli/-/argue-cli-1.2.1.tgz",
+ "integrity": "sha512-Em3HDMlqiVLNOgXUCYz5NG1mx/44aijsxUOO8elmfvAN4/3ar1S3WPTua7WGhsMbeQm8clOwpDZ09sN7C2FnOg=="
+ },
"aria-query": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz",
@@ -24242,6 +24456,69 @@
"picocolors": "^1.0.0"
}
},
+ "browserslist-useragent-regexp": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/browserslist-useragent-regexp/-/browserslist-useragent-regexp-3.0.2.tgz",
+ "integrity": "sha512-hOvTo9ObY+2PvCLxydvam5WD9hlvWB4bFzRLxc/M5OdJfzjgfsQ9wEF7EpJJP7UJUAnKJdJK28XsSrl5d1DfoA==",
+ "requires": {
+ "@types/node": "^16.9.6",
+ "argue-cli": "^1.2.0",
+ "browserslist": "^4.16.3",
+ "chalk": "^4.0.0",
+ "easy-table": "^1.1.1",
+ "useragent": "^2.3.0"
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "16.11.68",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.68.tgz",
+ "integrity": "sha512-JkRpuVz3xCNCWaeQ5EHLR/6woMbHZz/jZ7Kmc63AkU+1HxnoUugzSWMck7dsR4DvNYX8jp9wTi9K7WvnxOIQZQ=="
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
"bser": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
@@ -24467,6 +24744,12 @@
"wrap-ansi": "^6.2.0"
}
},
+ "clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
+ "optional": true
+ },
"clone-deep": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
@@ -24999,6 +25282,15 @@
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
"dev": true
},
+ "defaults": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
+ "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
+ "optional": true,
+ "requires": {
+ "clone": "^1.0.2"
+ }
+ },
"define-properties": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@@ -25170,6 +25462,15 @@
"domhandler": "^4.2.0"
}
},
+ "easy-table": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.2.0.tgz",
+ "integrity": "sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==",
+ "requires": {
+ "ansi-regex": "^5.0.1",
+ "wcwidth": "^1.0.1"
+ }
+ },
"ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@@ -31396,6 +31697,11 @@
"word-wrap": "^1.2.3"
}
},
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g=="
+ },
"p-limit": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
@@ -31818,8 +32124,7 @@
"pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
- "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
- "dev": true
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
},
"psl": {
"version": "1.8.0",
@@ -32518,7 +32823,7 @@
"select2": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/select2/-/select2-3.5.1.tgz",
- "integrity": "sha1-8oGUibvGX9bTKL5yu+K5XdfofP4="
+ "integrity": "sha512-IFX3UFPpPyK1I1Kuw1R1x+upMyNAZbMlkFhiTnRCRR7ii0KU1brmJMLa3GZcrMWCHiQlm0eKqb6i4XO4pqOrGQ=="
},
"semver": {
"version": "6.3.0",
@@ -33326,6 +33631,29 @@
"supports-hyperlinks": "^2.0.0"
}
},
+ "terser": {
+ "version": "5.15.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz",
+ "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==",
+ "requires": {
+ "@jridgewell/source-map": "^0.3.2",
+ "acorn": "^8.5.0",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
+ "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w=="
+ },
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+ }
+ }
+ },
"terser-webpack-plugin": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.0.tgz",
@@ -33338,18 +33666,6 @@
"terser": "^5.7.2"
},
"dependencies": {
- "acorn": {
- "version": "8.7.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
- "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
- "optional": true,
- "peer": true
- },
- "commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
- },
"schema-utils": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
@@ -33364,23 +33680,6 @@
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
- },
- "terser": {
- "version": "5.10.0",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz",
- "integrity": "sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA==",
- "requires": {
- "commander": "^2.20.0",
- "source-map": "~0.7.2",
- "source-map-support": "~0.5.20"
- },
- "dependencies": {
- "source-map": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
- "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ=="
- }
- }
}
}
},
@@ -33766,6 +34065,39 @@
"resolved": "https://registry.npmjs.org/url-search-params-polyfill/-/url-search-params-polyfill-8.1.1.tgz",
"integrity": "sha512-KmkCs6SjE6t4ihrfW9JelAPQIIIFbJweaaSLTh/4AO+c58JlDcb+GbdPt8yr5lRcFg4rPswRFRRhBGpWwh0K/Q=="
},
+ "useragent": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz",
+ "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==",
+ "requires": {
+ "lru-cache": "4.1.x",
+ "tmp": "0.0.x"
+ },
+ "dependencies": {
+ "lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "requires": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "requires": {
+ "os-tmpdir": "~1.0.2"
+ }
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A=="
+ }
+ }
+ },
"util": {
"version": "0.10.4",
"resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
@@ -34146,6 +34478,15 @@
"graceful-fs": "^4.1.2"
}
},
+ "wcwidth": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
+ "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
+ "optional": true,
+ "requires": {
+ "defaults": "^1.0.3"
+ }
+ },
"webdav": {
"version": "4.11.0",
"resolved": "https://registry.npmjs.org/webdav/-/webdav-4.11.0.tgz",
diff --git a/package.json b/package.json
index 292464fd0f6..78ae9b0f88b 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,8 @@
"@chenfengyuan/vue-qrcode": "^1.0.2",
"@nextcloud/auth": "^1.3.0",
"@nextcloud/axios": "^1.10.0",
+ "@nextcloud/browser-storage": "^0.1.1",
+ "@nextcloud/browserslist-config": "^2.3.0",
"@nextcloud/calendar-availability-vue": "^0.5.0-beta.2",
"@nextcloud/capabilities": "^1.0.4",
"@nextcloud/dialogs": "^3.1.4",
@@ -51,6 +53,7 @@
"backbone": "^1.4.1",
"blueimp-md5": "^2.19.0",
"bootstrap": "^4.6.0",
+ "browserslist-useragent-regexp": "^3.0.2",
"buffer": "^6.0.3",
"camelcase": "^6.3.0",
"clipboard": "^2.0.10",
@@ -103,7 +106,6 @@
"devDependencies": {
"@babel/node": "^7.17.10",
"@nextcloud/babel-config": "^1.0.0",
- "@nextcloud/browserslist-config": "^2.3.0",
"@nextcloud/eslint-config": "^8.0.0",
"@nextcloud/stylelint-config": "^2.1.2",
"@testing-library/jest-dom": "^5.16.4",
diff --git a/webpack.modules.js b/webpack.modules.js
index 25982e9623d..217bbc104f4 100644
--- a/webpack.modules.js
+++ b/webpack.modules.js
@@ -38,6 +38,7 @@ module.exports = {
recommendedapps: path.join(__dirname, 'core/src', 'recommendedapps.js'),
systemtags: path.resolve(__dirname, 'core/src', 'systemtags/merged-systemtags.js'),
'unified-search': path.join(__dirname, 'core/src', 'unified-search.js'),
+ 'unsupported-browser': path.join(__dirname, 'core/src', 'unsupported-browser.js'),
},
dashboard: {
main: path.join(__dirname, 'apps/dashboard/src', 'main.js'),