Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>tags/v17.0.0beta1
@@ -1,2 +1,118 @@ | |||
!function(e){var n={};function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var i in e)t.d(r,i,function(n){return e[n]}.bind(null,i));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="/js/",t(t.s=0)}([function(e,n,r){r.p=OC.linkTo("files_sharing","js/dist/"),r.nc=btoa(OC.requestToken),window.OCP.Collaboration.registerType("file",{action:function(){return new Promise(function(e,n){OC.dialogs.filepicker(t("files_sharing","Link to a file"),function(t){OC.Files.getClient().getFileInfo(t).then(function(n,t){e(t.id)},function(){n()})},!1)})},typeString:t("files_sharing","Link to a file"),typeIconClass:"icon-files-dark"})}]); | |||
/******/ (function(modules) { // webpackBootstrap | |||
/******/ // The module cache | |||
/******/ var installedModules = {}; | |||
/******/ | |||
/******/ // The require function | |||
/******/ function __webpack_require__(moduleId) { | |||
/******/ | |||
/******/ // Check if module is in cache | |||
/******/ if(installedModules[moduleId]) { | |||
/******/ return installedModules[moduleId].exports; | |||
/******/ } | |||
/******/ // Create a new module (and put it into the cache) | |||
/******/ var module = installedModules[moduleId] = { | |||
/******/ i: moduleId, | |||
/******/ l: false, | |||
/******/ exports: {} | |||
/******/ }; | |||
/******/ | |||
/******/ // Execute the module function | |||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | |||
/******/ | |||
/******/ // Flag the module as loaded | |||
/******/ module.l = true; | |||
/******/ | |||
/******/ // Return the exports of the module | |||
/******/ return module.exports; | |||
/******/ } | |||
/******/ | |||
/******/ | |||
/******/ // expose the modules object (__webpack_modules__) | |||
/******/ __webpack_require__.m = modules; | |||
/******/ | |||
/******/ // expose the module cache | |||
/******/ __webpack_require__.c = installedModules; | |||
/******/ | |||
/******/ // define getter function for harmony exports | |||
/******/ __webpack_require__.d = function(exports, name, getter) { | |||
/******/ if(!__webpack_require__.o(exports, name)) { | |||
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); | |||
/******/ } | |||
/******/ }; | |||
/******/ | |||
/******/ // define __esModule on exports | |||
/******/ __webpack_require__.r = function(exports) { | |||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { | |||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); | |||
/******/ } | |||
/******/ Object.defineProperty(exports, '__esModule', { value: true }); | |||
/******/ }; | |||
/******/ | |||
/******/ // create a fake namespace object | |||
/******/ // mode & 1: value is a module id, require it | |||
/******/ // mode & 2: merge all properties of value into the ns | |||
/******/ // mode & 4: return value when already ns object | |||
/******/ // mode & 8|1: behave like require | |||
/******/ __webpack_require__.t = function(value, mode) { | |||
/******/ if(mode & 1) value = __webpack_require__(value); | |||
/******/ if(mode & 8) return value; | |||
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; | |||
/******/ var ns = Object.create(null); | |||
/******/ __webpack_require__.r(ns); | |||
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); | |||
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); | |||
/******/ return ns; | |||
/******/ }; | |||
/******/ | |||
/******/ // getDefaultExport function for compatibility with non-harmony modules | |||
/******/ __webpack_require__.n = function(module) { | |||
/******/ var getter = module && module.__esModule ? | |||
/******/ function getDefault() { return module['default']; } : | |||
/******/ function getModuleExports() { return module; }; | |||
/******/ __webpack_require__.d(getter, 'a', getter); | |||
/******/ return getter; | |||
/******/ }; | |||
/******/ | |||
/******/ // Object.prototype.hasOwnProperty.call | |||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; | |||
/******/ | |||
/******/ // __webpack_public_path__ | |||
/******/ __webpack_require__.p = "/js/"; | |||
/******/ | |||
/******/ | |||
/******/ // Load entry module and return exports | |||
/******/ return __webpack_require__(__webpack_require__.s = "./apps/files_sharing/src/collaborationresourceshandler.js"); | |||
/******/ }) | |||
/************************************************************************/ | |||
/******/ ({ | |||
/***/ "./apps/files_sharing/src/collaborationresourceshandler.js": | |||
/*!*****************************************************************!*\ | |||
!*** ./apps/files_sharing/src/collaborationresourceshandler.js ***! | |||
\*****************************************************************/ | |||
/*! no static exports found */ | |||
/***/ (function(module, exports, __webpack_require__) { | |||
__webpack_require__.p = OC.linkTo('files_sharing', 'js/dist/'); | |||
__webpack_require__.nc = btoa(OC.requestToken); | |||
window.OCP.Collaboration.registerType('file', { | |||
action: function action() { | |||
return new Promise(function (resolve, reject) { | |||
OC.dialogs.filepicker(t('files_sharing', 'Link to a file'), function (f) { | |||
var client = OC.Files.getClient(); | |||
client.getFileInfo(f).then(function (status, fileInfo) { | |||
resolve(fileInfo.id); | |||
}, function () { | |||
reject(); | |||
}); | |||
}, false); | |||
}); | |||
}, | |||
typeString: t('files_sharing', 'Link to a file'), | |||
typeIconClass: 'icon-files-dark' | |||
}); | |||
/***/ }) | |||
/******/ }); | |||
//# sourceMappingURL=collaboration.js.map |
@@ -132,7 +132,7 @@ __webpack_require__.r(__webpack_exports__); | |||
"use strict"; | |||
__webpack_require__.r(__webpack_exports__); | |||
/* harmony import */ var nextcloud_vue_collections__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! nextcloud-vue-collections */ "./node_modules/nextcloud-vue-collections/dist/nextcloud-vue-collections.js"); | |||
!(function webpackMissingModule() { var e = new Error("Cannot find module 'nextcloud-vue-collections'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()); | |||
// | |||
// | |||
// | |||
@@ -179,7 +179,7 @@ __webpack_require__.r(__webpack_exports__); | |||
} | |||
}, | |||
components: { | |||
CollectionList: nextcloud_vue_collections__WEBPACK_IMPORTED_MODULE_0__["CollectionList"] | |||
CollectionList: !(function webpackMissingModule() { var e = new Error("Cannot find module 'nextcloud-vue-collections'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()) | |||
} | |||
}); | |||
@@ -25,26 +25,26 @@ | |||
</template> | |||
<script> | |||
import { CollectionList } from 'nextcloud-vue-collections' | |||
import { CollectionList } from 'nextcloud-vue-collections' | |||
export default { | |||
name: 'CollaborationView', | |||
computed: { | |||
fileId() { | |||
if (this.$root.model && this.$root.model.id) { | |||
return '' + this.$root.model.id; | |||
} | |||
return null; | |||
}, | |||
filename() { | |||
if (this.$root.model && this.$root.model.name) { | |||
return '' + this.$root.model.name; | |||
} | |||
return ''; | |||
export default { | |||
name: 'CollaborationView', | |||
computed: { | |||
fileId() { | |||
if (this.$root.model && this.$root.model.id) { | |||
return '' + this.$root.model.id; | |||
} | |||
return null; | |||
}, | |||
components: { | |||
CollectionList | |||
filename() { | |||
if (this.$root.model && this.$root.model.name) { | |||
return '' + this.$root.model.name; | |||
} | |||
return ''; | |||
} | |||
}, | |||
components: { | |||
CollectionList | |||
} | |||
} | |||
</script> |
@@ -31,28 +31,12 @@ module.exports = { | |||
{ | |||
test: /\.js$/, | |||
loader: 'babel-loader', | |||
exclude: /node_modules/, | |||
options: { | |||
plugins: ['@babel/plugin-syntax-dynamic-import', 'transform-es2015-arrow-functions'] | |||
} | |||
}, | |||
{ | |||
test: /\.(png|jpg|gif|svg)$/, | |||
loader: 'file-loader', | |||
options: { | |||
name: '[name].[ext]?[hash]' | |||
} | |||
exclude: /node_modules/ | |||
} | |||
] | |||
}, | |||
plugins: [new VueLoaderPlugin()], | |||
resolve: { | |||
alias: { | |||
vue$: 'vue/dist/vue.runtime.esm.js', | |||
}, | |||
extensions: ['*', '.js', '.vue', '.json'], | |||
modules: [ | |||
path.join(__dirname, '../../node_modules') | |||
] | |||
extensions: ['*', '.js', '.vue', '.json'] | |||
}, | |||
}; |
@@ -4842,9 +4842,9 @@ | |||
"integrity": "sha512-ZqnNDFNR0rCpifb29uoqyqd9IyVwNZrDePzmP6DbGiNStFrvnlOG8OTdIMSdC82bKzKAqzXU5L73kSQncG8oXA==" | |||
}, | |||
"nextcloud-vue": { | |||
"version": "0.11.1", | |||
"resolved": "https://registry.npmjs.org/nextcloud-vue/-/nextcloud-vue-0.11.1.tgz", | |||
"integrity": "sha512-gQnAyTyIjgSOPMLrTMfmVldjwP3lz+xWU6gynDj3InGl4EgjoRp+7fQfgvanPAoDJWLHYh/cmxm4O9AaVZCSSg==", | |||
"version": "0.11.3", | |||
"resolved": "https://registry.npmjs.org/nextcloud-vue/-/nextcloud-vue-0.11.3.tgz", | |||
"integrity": "sha512-lVih3gUuRZf5B82+XjLuiw3qp2tvAITF512mTyhHLtAzBWEiBfWsidMP10Nntql4zAEoLTZvLaQ1izFglMUDmw==", | |||
"requires": { | |||
"hammerjs": "^2.0.8", | |||
"md5": "^2.2.1", | |||
@@ -4858,33 +4858,26 @@ | |||
} | |||
}, | |||
"nextcloud-vue-collections": { | |||
"version": "0.4.0", | |||
"resolved": "https://registry.npmjs.org/nextcloud-vue-collections/-/nextcloud-vue-collections-0.4.0.tgz", | |||
"integrity": "sha512-UxgormIFW4CD9dUsobRzIuQt1PQXkT+EI2KCp1CoAiJiurzf5yO9BmmS3gN9lWZa1+EZvLqljapvAlyntWwX6Q==", | |||
"version": "0.5.0", | |||
"resolved": "https://registry.npmjs.org/nextcloud-vue-collections/-/nextcloud-vue-collections-0.5.0.tgz", | |||
"integrity": "sha512-YEt9k4aykFozTSjdPzjPYKfL6UErTyjeVzShLDbH13wVvO4bicV69QXmxi0r+mihUTe46jCJxp3Fh8JwKwj8nw==", | |||
"requires": { | |||
"lodash": "^4.17.11", | |||
"nextcloud-axios": "^0.1.2", | |||
"nextcloud-vue": "^0.9.0", | |||
"v-tooltip": "^2.0.0-rc.33", | |||
"nextcloud-vue": "^0.11.1", | |||
"v-tooltip": "^3.0.0-alpha.7", | |||
"vue": "^2.6.6", | |||
"vue-click-outside": "^1.0.7", | |||
"vuex": "^3.1.0" | |||
}, | |||
"dependencies": { | |||
"nextcloud-vue": { | |||
"version": "0.9.7", | |||
"resolved": "https://registry.npmjs.org/nextcloud-vue/-/nextcloud-vue-0.9.7.tgz", | |||
"integrity": "sha512-47mr8kBQfJW1oNTgKjFdktgX6+Z0c6jryd1xq+515jLef3o1DWdMmRLF5Yab3TTUdha/aG3dL0lpVQ6Z3jf9Aw==", | |||
"v-tooltip": { | |||
"version": "3.0.0-alpha.7", | |||
"resolved": "https://registry.npmjs.org/v-tooltip/-/v-tooltip-3.0.0-alpha.7.tgz", | |||
"integrity": "sha512-BJM1tYm/Idsa4xjY8nsZ/o329qEhnpAnKTI5fG2r5/aEFtmno9HJKT8+lmbHGpZhOnV8NCCg/9PuiCFPOT7/Lw==", | |||
"requires": { | |||
"hammerjs": "^2.0.8", | |||
"md5": "^2.2.1", | |||
"nextcloud-axios": "^0.1.3", | |||
"v-tooltip": "^2.0.0-rc.33", | |||
"vue": "^2.6.7", | |||
"vue-click-outside": "^1.0.7", | |||
"vue-multiselect": "^2.1.3", | |||
"vue-visible": "^1.0.2", | |||
"vue2-datepicker": "^2.10.0" | |||
"popper.js": "^1.15.0", | |||
"vue-resize": "^0.4.5" | |||
} | |||
} | |||
} | |||
@@ -7256,9 +7249,9 @@ | |||
"integrity": "sha512-yaX2its9XAJKGuQqf7LsiZHHSkxsIK8rmCOQOvEGEoF41blKRK8qr9my4qYoD6ikdLss4n8tKqYBecmaY0+WJg==" | |||
}, | |||
"vue2-datepicker": { | |||
"version": "2.10.0", | |||
"resolved": "https://registry.npmjs.org/vue2-datepicker/-/vue2-datepicker-2.10.0.tgz", | |||
"integrity": "sha512-WGL7ou0TdBiJQuHVp29BtBw3rSkLrIYwXWU/ELmaLdnAerI0EdGVAu7DvZV2iIxY4lsHyjqocApxdvXTmwLrAw==", | |||
"version": "2.11.2", | |||
"resolved": "https://registry.npmjs.org/vue2-datepicker/-/vue2-datepicker-2.11.2.tgz", | |||
"integrity": "sha512-xGyIN5pMMdaKMnndSrzqW6LDST/e7PHcFt2uIp73OOMZMDAlhEmzroNtoYBwJEEzKnCNMo+ktcykgYljrE8y8Q==", | |||
"requires": { | |||
"fecha": "^2.3.3" | |||
} |
@@ -43,8 +43,8 @@ | |||
"moment": "^2.24.0", | |||
"nextcloud-axios": "^0.1.3", | |||
"nextcloud-password-confirmation": "^0.4.1", | |||
"nextcloud-vue": "^0.11.1", | |||
"nextcloud-vue-collections": "^0.4.0", | |||
"nextcloud-vue": "^0.11.3", | |||
"nextcloud-vue-collections": "^0.5.0", | |||
"snap.js": "^2.0.9", | |||
"strengthify": "git+https://github.com/MorrisJobke/strengthify.git#0.5.8", | |||
"underscore": "^1.9.1", |
@@ -21,7 +21,7 @@ | |||
<template> | |||
<tr :data-id="token.id" | |||
:class="{wiping}"> | |||
:class="wiping"> | |||
<td class="client"> | |||
<div :class="iconName.icon"></div> | |||
</td> | |||
@@ -41,214 +41,216 @@ | |||
<span class="last-activity" v-tooltip="lastActivity">{{lastActivityRelative}}</span> | |||
</td> | |||
<td class="more"> | |||
<Action v-if="!token.current" | |||
:actions="actions" | |||
v-bind:open.sync="actionOpen" | |||
v-tooltip="{content: t('settings', 'Device settings'), container: 'body'}" | |||
tabindex="0"/> | |||
<Actions v-if="!token.current" | |||
:actions="actions" | |||
:open.sync="actionOpen" | |||
v-tooltip.auto="{ | |||
content: t('settings', 'Device settings'), | |||
container: 'body' | |||
}"> | |||
<ActionCheckbox v-if="token.type === 1" | |||
:checked="token.scope.filesystem" | |||
@change.stop.prevent="$emit('toggleScope', token, 'filesystem', !token.scope.filesystem)"> | |||
<!-- TODO: add text/longtext with some description --> | |||
{{ t('settings', 'Allow filesystem access') }} | |||
</ActionCheckbox> | |||
<ActionButton v-if="token.canRename" | |||
icon="icon-rename" | |||
@click.stop.prevent="startRename"> | |||
<!-- TODO: add text/longtext with some description --> | |||
{{ t('settings', 'Rename') }} | |||
</ActionButton> | |||
<!-- revoke & wipe --> | |||
<template v-if="token.canDelete"> | |||
<template v-if="token.type !== 2"> | |||
<ActionButton icon="icon-delete" | |||
@click.stop.prevent="revoke"> | |||
<!-- TODO: add text/longtext with some description --> | |||
{{ t('settings', 'Revoke') }} | |||
</ActionButton> | |||
<ActionButton icon="icon-delete" | |||
@click.stop.prevent="wipe"> | |||
{{ t('settings', 'Wipe device') }} | |||
</ActionButton> | |||
</template> | |||
<ActionButton v-else-if="token.type === 2" | |||
icon="icon-delete" | |||
:title="t('settings', 'Revoke')" | |||
@click.stop.prevent="revoke"> | |||
{{ t('settings', 'Revoking this token might prevent the wiping of your device if it hasn\'t started the wipe yet.') }} | |||
</ActionButton> | |||
</template> | |||
</Actions> | |||
</td> | |||
</tr> | |||
</template> | |||
<script> | |||
import {Action} from 'nextcloud-vue'; | |||
import { | |||
Actions, | |||
ActionButton, | |||
ActionCheckbox | |||
} from 'nextcloud-vue'; | |||
const userAgentMap = { | |||
ie: /(?:MSIE|Trident|Trident\/7.0; rv)[ :](\d+)/, | |||
// Microsoft Edge User Agent from https://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx | |||
edge: /^Mozilla\/5\.0 \([^)]+\) AppleWebKit\/[0-9.]+ \(KHTML, like Gecko\) Chrome\/[0-9.]+ (?:Mobile Safari|Safari)\/[0-9.]+ Edge\/[0-9.]+$/, | |||
// Firefox User Agent from https://developer.mozilla.org/en-US/docs/Web/HTTP/Gecko_user_agent_string_reference | |||
firefox: /^Mozilla\/5\.0 \([^)]*(Windows|OS X|Linux)[^)]+\) Gecko\/[0-9.]+ Firefox\/(\d+)(?:\.\d)?$/, | |||
// Chrome User Agent from https://developer.chrome.com/multidevice/user-agent | |||
chrome: /^Mozilla\/5\.0 \([^)]*(Windows|OS X|Linux)[^)]+\) AppleWebKit\/[0-9.]+ \(KHTML, like Gecko\) Chrome\/(\d+)[0-9.]+ (?:Mobile Safari|Safari)\/[0-9.]+$/, | |||
// Safari User Agent from http://www.useragentstring.com/pages/Safari/ | |||
safari: /^Mozilla\/5\.0 \([^)]*(Windows|OS X)[^)]+\) AppleWebKit\/[0-9.]+ \(KHTML, like Gecko\)(?: Version\/([0-9]+)[0-9.]+)? Safari\/[0-9.A-Z]+$/, | |||
// Android Chrome user agent: https://developers.google.com/chrome/mobile/docs/user-agent | |||
androidChrome: /Android.*(?:; (.*) Build\/).*Chrome\/(\d+)[0-9.]+/, | |||
iphone: / *CPU +iPhone +OS +([0-9]+)_(?:[0-9_])+ +like +Mac +OS +X */, | |||
ipad: /\(iPad\; *CPU +OS +([0-9]+)_(?:[0-9_])+ +like +Mac +OS +X */, | |||
iosClient: /^Mozilla\/5\.0 \(iOS\) (ownCloud|Nextcloud)\-iOS.*$/, | |||
androidClient: /^Mozilla\/5\.0 \(Android\) ownCloud\-android.*$/, | |||
iosTalkClient: /^Mozilla\/5\.0 \(iOS\) Nextcloud\-Talk.*$/, | |||
androidTalkClient: /^Mozilla\/5\.0 \(Android\) Nextcloud\-Talk.*$/, | |||
// DAVdroid/1.2 (2016/07/03; dav4android; okhttp3) Android/6.0.1 | |||
davDroid: /DAV(droid|x5)\/([0-9.]+)/, | |||
// Mozilla/5.0 (U; Linux; Maemo; Jolla; Sailfish; like Android 4.3) AppleWebKit/538.1 (KHTML, like Gecko) WebPirate/2.0 like Mobile Safari/538.1 (compatible) | |||
webPirate: /(Sailfish).*WebPirate\/(\d+)/, | |||
// Mozilla/5.0 (Maemo; Linux; U; Jolla; Sailfish; Mobile; rv:31.0) Gecko/31.0 Firefox/31.0 SailfishBrowser/1.0 | |||
sailfishBrowser: /(Sailfish).*SailfishBrowser\/(\d+)/ | |||
}; | |||
const nameMap = { | |||
ie: t('setting', 'Internet Explorer'), | |||
edge: t('setting', 'Edge'), | |||
firefox: t('setting', 'Firefox'), | |||
chrome: t('setting', 'Google Chrome'), | |||
safari: t('setting', 'Safari'), | |||
androidChrome: t('setting', 'Google Chrome for Android'), | |||
iphone: t('setting', 'iPhone'), | |||
ipad: t('setting', 'iPad'), | |||
iosClient: t('setting', 'Nextcloud iOS app'), | |||
androidClient: t('setting', 'Nextcloud Android app'), | |||
iosTalkClient: t('setting', 'Nextcloud Talk for iOS'), | |||
androidTalkClient: t('setting', 'Nextcloud Talk for Android'), | |||
davDroid: 'DAVdroid', | |||
webPirate: 'WebPirate', | |||
sailfishBrowser: 'SailfishBrowser' | |||
}; | |||
const iconMap = { | |||
ie: 'icon-desktop', | |||
edge: 'icon-desktop', | |||
firefox: 'icon-desktop', | |||
chrome: 'icon-desktop', | |||
safari: 'icon-desktop', | |||
androidChrome: 'icon-phone', | |||
iphone: 'icon-phone', | |||
ipad: 'icon-tablet', | |||
iosClient: 'icon-phone', | |||
androidClient: 'icon-phone', | |||
iosTalkClient: 'icon-phone', | |||
androidTalkClient: 'icon-phone', | |||
davDroid: 'icon-phone', | |||
webPirate: 'icon-link', | |||
sailfishBrowser: 'icon-link' | |||
}; | |||
const userAgentMap = { | |||
ie: /(?:MSIE|Trident|Trident\/7.0; rv)[ :](\d+)/, | |||
// Microsoft Edge User Agent from https://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx | |||
edge: /^Mozilla\/5\.0 \([^)]+\) AppleWebKit\/[0-9.]+ \(KHTML, like Gecko\) Chrome\/[0-9.]+ (?:Mobile Safari|Safari)\/[0-9.]+ Edge\/[0-9.]+$/, | |||
// Firefox User Agent from https://developer.mozilla.org/en-US/docs/Web/HTTP/Gecko_user_agent_string_reference | |||
firefox: /^Mozilla\/5\.0 \([^)]*(Windows|OS X|Linux)[^)]+\) Gecko\/[0-9.]+ Firefox\/(\d+)(?:\.\d)?$/, | |||
// Chrome User Agent from https://developer.chrome.com/multidevice/user-agent | |||
chrome: /^Mozilla\/5\.0 \([^)]*(Windows|OS X|Linux)[^)]+\) AppleWebKit\/[0-9.]+ \(KHTML, like Gecko\) Chrome\/(\d+)[0-9.]+ (?:Mobile Safari|Safari)\/[0-9.]+$/, | |||
// Safari User Agent from http://www.useragentstring.com/pages/Safari/ | |||
safari: /^Mozilla\/5\.0 \([^)]*(Windows|OS X)[^)]+\) AppleWebKit\/[0-9.]+ \(KHTML, like Gecko\)(?: Version\/([0-9]+)[0-9.]+)? Safari\/[0-9.A-Z]+$/, | |||
// Android Chrome user agent: https://developers.google.com/chrome/mobile/docs/user-agent | |||
androidChrome: /Android.*(?:; (.*) Build\/).*Chrome\/(\d+)[0-9.]+/, | |||
iphone: / *CPU +iPhone +OS +([0-9]+)_(?:[0-9_])+ +like +Mac +OS +X */, | |||
ipad: /\(iPad\; *CPU +OS +([0-9]+)_(?:[0-9_])+ +like +Mac +OS +X */, | |||
iosClient: /^Mozilla\/5\.0 \(iOS\) (ownCloud|Nextcloud)\-iOS.*$/, | |||
androidClient: /^Mozilla\/5\.0 \(Android\) ownCloud\-android.*$/, | |||
iosTalkClient: /^Mozilla\/5\.0 \(iOS\) Nextcloud\-Talk.*$/, | |||
androidTalkClient: /^Mozilla\/5\.0 \(Android\) Nextcloud\-Talk.*$/, | |||
// DAVdroid/1.2 (2016/07/03; dav4android; okhttp3) Android/6.0.1 | |||
davDroid: /DAV(droid|x5)\/([0-9.]+)/, | |||
// Mozilla/5.0 (U; Linux; Maemo; Jolla; Sailfish; like Android 4.3) AppleWebKit/538.1 (KHTML, like Gecko) WebPirate/2.0 like Mobile Safari/538.1 (compatible) | |||
webPirate: /(Sailfish).*WebPirate\/(\d+)/, | |||
// Mozilla/5.0 (Maemo; Linux; U; Jolla; Sailfish; Mobile; rv:31.0) Gecko/31.0 Firefox/31.0 SailfishBrowser/1.0 | |||
sailfishBrowser: /(Sailfish).*SailfishBrowser\/(\d+)/ | |||
}; | |||
const nameMap = { | |||
ie: t('setting', 'Internet Explorer'), | |||
edge: t('setting', 'Edge'), | |||
firefox: t('setting', 'Firefox'), | |||
chrome: t('setting', 'Google Chrome'), | |||
safari: t('setting', 'Safari'), | |||
androidChrome: t('setting', 'Google Chrome for Android'), | |||
iphone: t('setting', 'iPhone'), | |||
ipad: t('setting', 'iPad'), | |||
iosClient: t('setting', 'Nextcloud iOS app'), | |||
androidClient: t('setting', 'Nextcloud Android app'), | |||
iosTalkClient: t('setting', 'Nextcloud Talk for iOS'), | |||
androidTalkClient: t('setting', 'Nextcloud Talk for Android'), | |||
davDroid: 'DAVdroid', | |||
webPirate: 'WebPirate', | |||
sailfishBrowser: 'SailfishBrowser' | |||
}; | |||
const iconMap = { | |||
ie: 'icon-desktop', | |||
edge: 'icon-desktop', | |||
firefox: 'icon-desktop', | |||
chrome: 'icon-desktop', | |||
safari: 'icon-desktop', | |||
androidChrome: 'icon-phone', | |||
iphone: 'icon-phone', | |||
ipad: 'icon-tablet', | |||
iosClient: 'icon-phone', | |||
androidClient: 'icon-phone', | |||
iosTalkClient: 'icon-phone', | |||
androidTalkClient: 'icon-phone', | |||
davDroid: 'icon-phone', | |||
webPirate: 'icon-link', | |||
sailfishBrowser: 'icon-link' | |||
}; | |||
export default { | |||
name: "AuthToken", | |||
components: { | |||
Action, | |||
export default { | |||
name: "AuthToken", | |||
components: { | |||
Actions, | |||
ActionButton, | |||
ActionCheckbox | |||
}, | |||
props: { | |||
token: { | |||
type: Object, | |||
required: true, | |||
} | |||
}, | |||
computed: { | |||
lastActivityRelative () { | |||
return OC.Util.relativeModifiedDate(this.token.lastActivity * 1000); | |||
}, | |||
props: { | |||
token: { | |||
type: Object, | |||
required: true, | |||
} | |||
lastActivity () { | |||
return OC.Util.formatDate(this.token.lastActivity * 1000, 'LLL'); | |||
}, | |||
computed: { | |||
actions () { | |||
const actions = []; | |||
if (this.token.type === 1) { | |||
// TODO: add text/longtext with some description | |||
actions.push({ | |||
input: 'checkbox', | |||
action: () => this.$emit('toggleScope', this.token, 'filesystem', !this.token.scope.filesystem), | |||
model: this.token.scope.filesystem, | |||
text: t('settings', 'Allow filesystem access'), | |||
}); | |||
} | |||
if (this.token.canRename) { | |||
// TODO: add text/longtext with some description | |||
actions.push({ | |||
icon: 'icon-rename', | |||
action: () => this.startRename(), | |||
text: t('settings', 'Rename'), | |||
}); | |||
} | |||
if (this.token.canDelete && this.token.type !== 2) { | |||
// TODO: add text/longtext with some description | |||
actions.push({ | |||
icon: 'icon-delete', | |||
action: () => this.$emit('delete', this.token), | |||
text: t('settings', 'Revoke'), | |||
}); | |||
actions.push({ | |||
icon: 'icon-delete', | |||
action: this.wipe, | |||
text: t('settings', 'Wipe device'), | |||
}); | |||
} else if (this.token.canDelete && this.token.type === 2) { | |||
actions.push({ | |||
icon: 'icon-delete', | |||
action: () => this.$emit('delete', this.token), | |||
text: t('settings', 'Revoke'), | |||
longtext: t('settings', 'Revoking this token might prevent the wiping of your device if it hasn\'t started the wipe yet.'), | |||
}); | |||
} | |||
return actions; | |||
}, | |||
lastActivityRelative () { | |||
return OC.Util.relativeModifiedDate(this.token.lastActivity * 1000); | |||
}, | |||
lastActivity () { | |||
return OC.Util.formatDate(this.token.lastActivity * 1000, 'LLL'); | |||
}, | |||
iconName () { | |||
// pretty format sync client user agent | |||
let matches = this.token.name.match(/Mozilla\/5\.0 \((\w+)\) (?:mirall|csyncoC)\/(\d+\.\d+\.\d+)/); | |||
iconName () { | |||
// pretty format sync client user agent | |||
let matches = this.token.name.match(/Mozilla\/5\.0 \((\w+)\) (?:mirall|csyncoC)\/(\d+\.\d+\.\d+)/); | |||
let icon = ''; | |||
if (matches) { | |||
this.token.name = t('settings', 'Sync client - {os}', { | |||
os: matches[1], | |||
version: matches[2] | |||
}); | |||
icon = 'icon-desktop'; | |||
} | |||
// preserve title for cases where we format it further | |||
const title = this.token.name; | |||
let name = this.token.name; | |||
for (let client in userAgentMap) { | |||
if (matches = title.match(userAgentMap[client])) { | |||
if (matches[2] && matches[1]) { // version number and os | |||
name = nameMap[client] + ' ' + matches[2] + ' - ' + matches[1]; | |||
} else if (matches[1]) { // only version number | |||
name = nameMap[client] + ' ' + matches[1]; | |||
} else { | |||
name = nameMap[client]; | |||
} | |||
let icon = ''; | |||
if (matches) { | |||
this.token.name = t('settings', 'Sync client - {os}', { | |||
os: matches[1], | |||
version: matches[2] | |||
}); | |||
icon = 'icon-desktop'; | |||
} | |||
icon = iconMap[client]; | |||
// preserve title for cases where we format it further | |||
const title = this.token.name; | |||
let name = this.token.name; | |||
for (let client in userAgentMap) { | |||
if (matches = title.match(userAgentMap[client])) { | |||
if (matches[2] && matches[1]) { // version number and os | |||
name = nameMap[client] + ' ' + matches[2] + ' - ' + matches[1]; | |||
} else if (matches[1]) { // only version number | |||
name = nameMap[client] + ' ' + matches[1]; | |||
} else { | |||
name = nameMap[client]; | |||
} | |||
} | |||
if (this.token.current) { | |||
name = t('settings', 'This session'); | |||
} | |||
return { | |||
icon, | |||
name, | |||
}; | |||
}, | |||
wiping() { | |||
return this.token.type === 2; | |||
icon = iconMap[client]; | |||
} | |||
} | |||
}, | |||
data () { | |||
if (this.token.current) { | |||
name = t('settings', 'This session'); | |||
} | |||
return { | |||
showMore: this.token.canScope || this.token.canDelete, | |||
renaming: false, | |||
newName: '', | |||
actionOpen: false, | |||
icon, | |||
name, | |||
}; | |||
}, | |||
methods: { | |||
startRename () { | |||
// Close action (popover menu) | |||
this.actionOpen = false; | |||
this.newName = this.token.name; | |||
this.renaming = true; | |||
this.$nextTick(() => { | |||
this.$refs.input.select(); | |||
}); | |||
}, | |||
cancelRename () { | |||
this.renaming = false; | |||
}, | |||
rename () { | |||
this.renaming = false; | |||
this.$emit('rename', this.token, this.newName); | |||
}, | |||
wipe () { | |||
this.actionOpen = false; | |||
wiping() { | |||
return this.token.type === 2; | |||
} | |||
}, | |||
data () { | |||
return { | |||
showMore: this.token.canScope || this.token.canDelete, | |||
renaming: false, | |||
newName: '', | |||
actionOpen: false, | |||
}; | |||
}, | |||
methods: { | |||
startRename() { | |||
// Close action (popover menu) | |||
this.actionOpen = false; | |||
this.$emit('wipe', this.token); | |||
} | |||
this.newName = this.token.name; | |||
this.renaming = true; | |||
this.$nextTick(() => { | |||
this.$refs.input.select(); | |||
}); | |||
}, | |||
cancelRename() { | |||
this.renaming = false; | |||
}, | |||
revoke() { | |||
this.actionOpen = false; | |||
this.$emit('delete', this.token) | |||
}, | |||
rename() { | |||
this.renaming = false; | |||
this.$emit('rename', this.token, this.newName); | |||
}, | |||
wipe() { | |||
this.actionOpen = false; | |||
this.$emit('wipe', this.token); | |||
} | |||
} | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
@@ -266,7 +268,8 @@ | |||
&%icon { | |||
overflow: visible; | |||
position: relative; | |||
width: 16px; | |||
width: 44px; | |||
height: 44px; | |||
} | |||
&.token-name { | |||
@@ -287,6 +290,7 @@ | |||
&.more { | |||
@extend %icon; | |||
padding: 0 10px; | |||
} | |||
&.client { |
@@ -21,25 +21,31 @@ | |||
--> | |||
<template> | |||
<AppContent app-name="settings" :class="{ 'with-app-sidebar': currentApp}" | |||
<Content app-name="settings" :class="{ 'with-app-sidebar': currentApp}" | |||
:content-class="{ 'icon-loading': loadingList }" :navigation-class="{ 'icon-loading': loading }"> | |||
<template #navigation> | |||
<AppNavigation> | |||
<ul id="appscategories"> | |||
<AppNavigationItem v-for="item in menu" :key="item.key" :item="item" /> | |||
</ul> | |||
</template> | |||
<template #content class="app-settings-content" :class="{ 'icon-loading': loadingList }"> | |||
<app-list :category="category" :app="currentApp" :search="searchQuery"></app-list> | |||
</template> | |||
<template #sidebar v-if="id && currentApp" > | |||
<app-details :category="category" :app="currentApp"></app-details> | |||
</template> | |||
</AppContent> | |||
</AppNavigation> | |||
<AppContent class="app-settings-content" :class="{ 'icon-loading': loadingList }"> | |||
<AppList :category="category" :app="currentApp" :search="searchQuery" /> | |||
</AppContent> | |||
<AppSidebar v-if="id && currentApp" > | |||
<AppDetails :category="category" :app="currentApp" /> | |||
</AppSidebar> | |||
</Content> | |||
</template> | |||
<script> | |||
import { AppContent, AppNavigationItem } from 'nextcloud-vue'; | |||
import appList from '../components/appList'; | |||
import { | |||
AppContent, | |||
AppNavigation, | |||
AppNavigationItem, | |||
AppSidebar, | |||
Content | |||
} from 'nextcloud-vue'; | |||
import AppList from '../components/appList'; | |||
import Vue from 'vue'; | |||
import VueLocalStorage from 'vue-localstorage' | |||
import AppDetails from '../components/appDetails'; | |||
@@ -60,9 +66,12 @@ export default { | |||
}, | |||
components: { | |||
AppContent, | |||
AppDetails, | |||
appList, | |||
AppNavigation, | |||
AppNavigationItem, | |||
AppSidebar, | |||
Content, | |||
AppDetails, | |||
AppList | |||
}, | |||
methods: { | |||
setSearch(query) { |
@@ -21,8 +21,8 @@ | |||
--> | |||
<template> | |||
<AppContent app-name="settings" :navigation-class="{ 'icon-loading': loadingAddGroup }"> | |||
<template #navigation> | |||
<Content app-name="settings" :navigation-class="{ 'icon-loading': loadingAddGroup }"> | |||
<AppNavigation> | |||
<AppNavigationNew button-id="new-user-button" :text="t('settings','New user')" button-class="icon-add" @click="toggleNewUserMenu" /> | |||
<ul id="usergrouplist"> | |||
<AppNavigationItem v-for="item in menu" :key="item.key" :item="item" /> | |||
@@ -30,12 +30,12 @@ | |||
<AppNavigationSettings> | |||
<div> | |||
<p>{{t('settings', 'Default quota:')}}</p> | |||
<multiselect :value="defaultQuota" :options="quotaOptions" | |||
<Multiselect :value="defaultQuota" :options="quotaOptions" | |||
tag-placeholder="create" :placeholder="t('settings', 'Select default quota')" | |||
label="label" track-by="id" class="multiselect-vue" | |||
label="label" track-by="id" | |||
:allowEmpty="false" :taggable="true" | |||
@tag="validateQuota" @input="setDefaultQuota"> | |||
</multiselect> | |||
</Multiselect> | |||
</div> | |||
<div> | |||
@@ -55,22 +55,27 @@ | |||
<label for="showStoragePath">{{t('settings', 'Show storage path')}}</label> | |||
</div> | |||
</AppNavigationSettings> | |||
</template> | |||
<user-list #content :users="users" :showConfig="showConfig" :selectedGroup="selectedGroup" :externalActions="externalActions" /> | |||
</AppContent> | |||
</AppNavigation> | |||
<AppContent> | |||
<UserList #content :users="users" :showConfig="showConfig" :selectedGroup="selectedGroup" :externalActions="externalActions" /> | |||
</AppContent> | |||
</Content> | |||
</template> | |||
<script> | |||
import Vue from 'vue'; | |||
import VueLocalStorage from 'vue-localstorage' | |||
import { | |||
AppContent, | |||
AppNavigation, | |||
AppNavigationItem, | |||
AppNavigationNew, | |||
AppNavigationSettings, | |||
AppSidebar, | |||
Content, | |||
Multiselect | |||
} from 'nextcloud-vue'; | |||
import userList from '../components/userList'; | |||
import Vue from 'vue'; | |||
import VueLocalStorage from 'vue-localstorage' | |||
import Multiselect from 'vue-multiselect'; | |||
import UserList from '../components/userList'; | |||
import api from '../store/api'; | |||
Vue.use(VueLocalStorage) | |||
@@ -80,10 +85,13 @@ export default { | |||
props: ['selectedGroup'], | |||
components: { | |||
AppContent, | |||
AppNavigation, | |||
AppNavigationItem, | |||
AppNavigationNew, | |||
AppNavigationSettings, | |||
userList, | |||
AppSidebar, | |||
Content, | |||
UserList, | |||
Multiselect, | |||
}, | |||
beforeMount() { |