Shared link expiration backend

Redirect from sign in page when user is logged
Updated README.md
This commit is contained in:
Peter Papp
2020-08-26 07:29:28 +02:00
parent 6f300ba1d5
commit 2b08d7801b
87 changed files with 355 additions and 155 deletions

View File

@@ -1,6 +1,7 @@
<template>
<div class="action-button">
<FontAwesomeIcon class="icon" :icon="icon" />
<x-icon size="12" class="icon" v-if="icon === 'x'"></x-icon>
<edit-2-icon size="12" class="icon" v-if="icon === 'pencil-alt'"></edit-2-icon>
<span class="label">
<slot></slot>
</span>
@@ -8,9 +9,15 @@
</template>
<script>
import { Edit2Icon, XIcon } from 'vue-feather-icons'
export default {
name: 'ActionButton',
props: ['icon'],
components: {
Edit2Icon,
XIcon,
}
}
</script>
@@ -23,18 +30,17 @@
.label {
@include font-size(12);
color: $theme;
font-weight: 600;
text-decoration: underline;
}
.icon {
@include font-size(10);
vertical-align: middle;
display: inline-block;
margin-right: 2px;
path {
fill: $theme;
path, circle, line {
stroke: $theme;
}
}
}

View File

@@ -1,7 +1,7 @@
<template>
<div class="select-box">
<div class="box-item"
:class="{'selected': item.value === value}"
:class="{'selected': item.value === input}"
@click="getSelectedValue(item)"
v-for="(item, i) in data" :key="i"
>
@@ -13,21 +13,28 @@
<script>
export default {
name: 'SelectBoxInput',
props: ['data'],
props: [
'data',
'value',
],
data() {
return {
value: undefined,
input: undefined,
}
},
methods: {
getSelectedValue(item) {
if (! this.value || this.value !== item.value)
this.value = item.value
if (! this.input || this.input !== item.value)
this.input = item.value
else
this.value = undefined
this.input = undefined
this.$emit('input', this.value)
this.$emit('input', this.input)
}
},
created() {
if (this.value)
this.input = this.value
}
}
</script>
@@ -41,14 +48,21 @@
.select-box {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
flex-direction: row;
margin-bottom: 10px;
.box-item {
padding: 12px 14px;
margin-bottom: 10px;
padding: 12px 4px;
text-align: center;
background: $light_background;
border-radius: 8px;
font-weight: 700;
border: 2px solid $light_background;
cursor: pointer;
flex-direction: column;
flex-basis: 55px;
.box-value {
@include font-size(15);
@@ -65,6 +79,15 @@
}
}
@media only screen and (max-width: 960px) {
.select-box {
.box-item {
flex-basis: calc(34% - 10px);
}
}
}
@media (prefers-color-scheme: dark) {

View File

@@ -33,11 +33,17 @@
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
<!--Set expiration-->
<div class="input-wrapper">
<label class="input-label">{{ $t('shared_form.label_expiration') }}:</label>
<SelectBoxInput v-model="shareOptions.expiration" :data="expirationList" class="box"/>
<!--More options-->
<div class="more-options" v-if="isMoreOptions">
<!--Set expiration-->
<div class="input-wrapper">
<label class="input-label">{{ $t('shared_form.label_expiration') }}:</label>
<SelectBoxInput v-model="shareOptions.expiration" :data="expirationList" class="box"/>
</div>
</div>
<ActionButton @click.native="moreOptions" :icon="isMoreOptions ? 'x' : 'pencil-alt'">{{ moreOptionsTitle }}</ActionButton>
</ValidationObserver>
<!--Copy generated link-->
@@ -80,6 +86,7 @@
import SwitchInput from '@/components/Others/Forms/SwitchInput'
import SelectInput from '@/components/Others/Forms/SelectInput'
import ThumbnailItem from '@/components/Others/ThumbnailItem'
import ActionButton from '@/components/Others/ActionButton'
import CopyInput from '@/components/Others/Forms/CopyInput'
import ButtonBase from '@/components/FilesView/ButtonBase'
import {required} from 'vee-validate/dist/rules'
@@ -94,6 +101,7 @@
ValidationObserver,
SelectBoxInput,
ThumbnailItem,
ActionButton,
PopupWrapper,
PopupActions,
PopupContent,
@@ -105,7 +113,10 @@
required,
},
computed: {
...mapGetters(['permissionOptions']),
...mapGetters([
'permissionOptions',
'expirationList',
]),
itemTypeTitle() {
return this.pickedItem && this.pickedItem.type === 'folder' ? this.$t('types.folder') : this.$t('types.file')
},
@@ -114,40 +125,13 @@
},
submitButtonText() {
return this.isGeneratedShared ? this.$t('shared_form.button_done') : this.$t('shared_form.button_generate')
},
moreOptionsTitle() {
return this.isMoreOptions ? this.$t('shared_form.button_close_options') : this.$t('shared_form.button_more_options')
}
},
data() {
return {
expirationList: [
{
label: this.$t('shared_form.expiration_hour', {value: 1}),
value: '1',
},
{
label: this.$t('shared_form.expiration_hour', {value: 2}),
value: '2',
},
{
label: this.$t('shared_form.expiration_hour', {value: 6}),
value: '6',
},
{
label: this.$t('shared_form.expiration_hour', {value: 12}),
value: '12',
},
{
label: this.$t('shared_form.expiration_day', {value: 1}),
value: '24',
},
{
label: this.$t('shared_form.expiration_day', {value: 2}),
value: '48',
},
{
label: this.$t('shared_form.expiration_day', {value: 7}),
value: '168',
},
],
shareOptions: {
isPassword: false,
expiration: undefined,
@@ -160,9 +144,16 @@
shareLink: undefined,
isGeneratedShared: false,
isLoading: false,
isMoreOptions: false,
}
},
methods: {
moreOptions() {
this.isMoreOptions = ! this.isMoreOptions
if (! this.isMoreOptions)
this.shareOptions.expiration = undefined
},
async submitShareOptions() {
// If shared was generated, then close popup
@@ -224,10 +215,12 @@
permission: undefined,
password: undefined,
isPassword: false,
expiration: undefined,
type: undefined,
unique_id: undefined,
}
this.isGeneratedShared = false
this.isMoreOptions = false
this.shareLink = undefined
}, 150)
})
@@ -239,6 +232,10 @@
@import "@assets/vue-file-manager/_inapp-forms.scss";
@import '@assets/vue-file-manager/_forms';
.more-options {
margin-bottom: 10px;
}
.input-wrapper {
&.password {

View File

@@ -31,7 +31,7 @@
<label class="input-label">{{ $t('shared_form.label_password_protection') }}:</label>
<SwitchInput v-model="shareOptions.isProtected" :state="shareOptions.isProtected" class="switch"/>
</div>
<ActionButton v-if="(pickedItem.shared.protected && canChangePassword) && shareOptions.isProtected" @click.native="changePassword" icon="pencil-alt">{{ $t('popup_share_edit.change_pass') }}</ActionButton>
<ActionButton v-if="(pickedItem.shared.protected && canChangePassword) && shareOptions.isProtected" @click.native="changePassword" class="change-password">{{ $t('popup_share_edit.change_pass') }}</ActionButton>
</div>
<!--Set password-->
@@ -40,6 +40,18 @@
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
<!--More options-->
<div class="more-options" v-if="isMoreOptions">
<!--Set expiration-->
<div class="input-wrapper">
<label class="input-label">{{ $t('shared_form.label_expiration') }}:</label>
<SelectBoxInput v-model="shareOptions.expiration" :data="expirationList" :value="shareOptions.expiration" class="box"/>
</div>
</div>
<ActionButton @click.native="moreOptions" :icon="isMoreOptions || shareOptions.expiration ? 'x' : 'pencil-alt'">{{ moreOptionsTitle }}</ActionButton>
</ValidationObserver>
</PopupContent>
@@ -68,6 +80,7 @@
<script>
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import SelectBoxInput from '@/components/Others/Forms/SelectBoxInput'
import PopupWrapper from '@/components/Others/Popup/PopupWrapper'
import PopupActions from '@/components/Others/Popup/PopupActions'
import PopupContent from '@/components/Others/Popup/PopupContent'
@@ -88,6 +101,7 @@
components: {
ValidationProvider,
ValidationObserver,
SelectBoxInput,
ThumbnailItem,
ActionButton,
PopupWrapper,
@@ -101,7 +115,12 @@
required,
},
computed: {
...mapGetters(['user', 'permissionOptions', 'currentFolder']),
...mapGetters([
'permissionOptions',
'expirationList',
'currentFolder',
'user',
]),
isFolder() {
return this.pickedItem && this.pickedItem.type === 'folder'
},
@@ -114,18 +133,28 @@
isSharedLocation() {
return this.currentFolder && this.currentFolder.location === 'shared'
},
moreOptionsTitle() {
return this.isMoreOptions ? this.$t('shared_form.button_close_options') : this.$t('shared_form.button_more_options')
}
},
data() {
return {
isConfirmedDestroy: false,
canChangePassword: false,
shareOptions: undefined,
pickedItem: undefined,
isLoading: false,
isMoreOptions: false,
isDeleting: false,
canChangePassword: false,
isConfirmedDestroy: false,
isLoading: false,
}
},
methods: {
moreOptions() {
this.isMoreOptions = ! this.isMoreOptions
if (! this.isMoreOptions)
this.shareOptions.expiration = undefined
},
changePassword() {
this.canChangePassword = false
},
@@ -187,22 +216,22 @@
.post('/api/share/' + this.shareOptions.token, {
permission: this.shareOptions.permission,
protected: this.shareOptions.isProtected,
expiration: this.shareOptions.expiration,
password: this.shareOptions.password ? this.shareOptions.password : undefined,
_method: 'patch'
})
.then(response => {
// End loading
this.isLoading = false
// Update shared data
this.$store.commit('UPDATE_SHARED_ITEM', response.data.data.attributes)
events.$emit('popup:close')
})
.catch(error => {
.catch(() => {
// todo: catch errors
this.$isSomethingWrong()
})
.finally(() => {
// End loading
this.isLoading = false
@@ -222,11 +251,15 @@
// Store shared options
this.shareOptions = {
token: args.item.shared.token,
expiration: args.item.shared.expire_in,
isProtected: args.item.shared.protected,
permission: args.item.shared.permission,
password: undefined,
}
if (args.item.shared.expire_in)
this.isMoreOptions = true
this.canChangePassword = args.item.shared.protected
})
@@ -256,6 +289,11 @@
}
}
.change-password {
opacity: 0.7;
text-decoration: underline;
}
.item-thumbnail {
margin-bottom: 20px;
}

View File

@@ -52,7 +52,7 @@ const Helpers = {
}
Vue.prototype.$getImage = function (source) {
return source ? '/' + source : ''
return source ? this.$store.getters.config.host + '/' + source : ''
}
Vue.prototype.$getCreditCardBrand = function (brand) {

View File

@@ -626,6 +626,8 @@
"visitor": "仅可以查看或下载文件"
},
"shared_form": {
"button_more_options": "More Options",
"button_close_options": "Close Options",
"button_done": "太好了!",
"button_generate": "生成分享链接",
"label_password_protection": "密码保护",

View File

@@ -626,6 +626,8 @@
"visitor": "Can only view and download"
},
"shared_form": {
"button_more_options": "More Options",
"button_close_options": "Close Options",
"button_done": "Awesome, Im done!",
"button_generate": "Generate Link",
"label_password_protection": "Password Protected",

View File

@@ -626,6 +626,8 @@
"visitor": "Môže len vidieť a sťahovať súbory"
},
"shared_form": {
"button_more_options": "Viac nastavení",
"button_close_options": "Zavrieť viac možností",
"button_done": "Super, som hotový!",
"button_generate": "Vygenerovať link",
"label_password_protection": "Chrániť heslom",

View File

@@ -263,9 +263,39 @@ const defaultState = {
{label: 'Zambia', value: 'ZM'},
{label: 'Zimbabwe', value: 'ZW'}
],
expirationList: [
{
label: i18n.t('shared_form.expiration_hour', {value: 1}),
value: 1,
},
{
label: i18n.t('shared_form.expiration_hour', {value: 2}),
value: 2,
},
{
label: i18n.t('shared_form.expiration_hour', {value: 6}),
value: 6,
},
{
label: i18n.t('shared_form.expiration_hour', {value: 12}),
value: 12,
},
{
label: i18n.t('shared_form.expiration_day', {value: 1}),
value: 24,
},
{
label: i18n.t('shared_form.expiration_day', {value: 2}),
value: 48,
},
{
label: i18n.t('shared_form.expiration_day', {value: 7}),
value: 168,
},
],
}
const actions = {
changePreviewType: ({commit, dispatch, state, getters}) => {
changePreviewType: ({commit, state}) => {
// Get preview type
let previewType = state.FilePreviewType == 'grid' ? 'list' : 'grid'
@@ -320,6 +350,7 @@ const mutations = {
const getters = {
fileInfoVisible: state => state.fileInfoPanelVisible,
FilePreviewType: state => state.FilePreviewType,
expirationList: state => state.expirationList,
homeDirectory: state => state.homeDirectory,
requestedPlan: state => state.requestedPlan,
countries: state => state.countries,

View File

@@ -17,6 +17,10 @@ const actions = {
.then((response) => {
resolve(response)
// Redirect user if is logged
if (router.currentRoute.name === 'SignIn')
router.push({ name: 'Files' })
commit('RETRIEVE_USER', response.data)
}).catch((error) => {

View File

@@ -2,7 +2,7 @@
<PageTab :is-loading="isLoading" class="form-fixed-width">
<!--Personal Information-->
<PageTabGroup>
<PageTabGroup v-if="! isLoading">
<div class="form block-form">
<FormLabel>{{ $t('admin_settings.appearance.section_general') }}</FormLabel>

View File

@@ -52,11 +52,11 @@
}
.input-label {
@include font-size(12);
@include font-size(14);
color: $text;
font-weight: 700;
display: block;
margin-bottom: 5px;
margin-bottom: 8px;
}
@media (prefers-color-scheme: dark) {