mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-05-18 19:25:01 +00:00
Merge remote-tracking branch 'origin/email-verification'
# Conflicts: # composer.lock # public/mix-manifest.json # tests/TestCase.php
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<div class="select-box" :class="[isClicked ? 'bg-theme' : 'is-deactive'] ">
|
||||
<CheckIcon v-if="isClicked" class="icon" size="17" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { CheckIcon } from 'vue-feather-icons'
|
||||
|
||||
export default {
|
||||
name: 'CheckBox',
|
||||
props: [ 'isClicked' ],
|
||||
components: { CheckIcon }
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@assets/vuefilemanager/_variables';
|
||||
|
||||
.select-box {
|
||||
min-width: 20px;
|
||||
min-height: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 5px;
|
||||
|
||||
.icon {
|
||||
stroke: white;
|
||||
}
|
||||
}
|
||||
|
||||
.is-deactive {
|
||||
background-color: darken($light_background, 5%);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
.is-deactive {
|
||||
background-color: lighten($dark_mode_foreground, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -7,11 +7,7 @@
|
||||
<div class="icon-item">
|
||||
|
||||
<!-- MultiSelecting for the mobile version -->
|
||||
<div :class="{'check-select-folder' : this.item.type === 'folder', 'check-select' : this.item.type !== 'folder'}" v-if="mobileMultiSelect">
|
||||
<div class="select-box" :class="{'select-box-active' : isClicked } ">
|
||||
<CheckIcon v-if="isClicked" class="icon" size="17" />
|
||||
</div>
|
||||
</div>
|
||||
<CheckBox v-if="mobileMultiSelect" :is-clicked="isClicked" class="check-box"/>
|
||||
|
||||
<!--If is file or image, then link item-->
|
||||
<span v-if="isFile || (isImage && !item.thumbnail)" class="file-icon-text text-theme">
|
||||
@@ -65,8 +61,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {LinkIcon, UserPlusIcon, CheckIcon, MoreHorizontalIcon} from 'vue-feather-icons'
|
||||
import {LinkIcon, UserPlusIcon, MoreHorizontalIcon} from 'vue-feather-icons'
|
||||
import FolderIcon from '@/components/FilesView/FolderIcon'
|
||||
import CheckBox from '@/components/FilesView/CheckBox'
|
||||
import {debounce} from 'lodash'
|
||||
import {mapGetters} from 'vuex'
|
||||
import {events} from '@/bus'
|
||||
@@ -77,9 +74,9 @@ export default {
|
||||
components: {
|
||||
MoreHorizontalIcon,
|
||||
UserPlusIcon,
|
||||
CheckIcon,
|
||||
LinkIcon,
|
||||
FolderIcon,
|
||||
CheckBox,
|
||||
LinkIcon,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
@@ -308,7 +305,7 @@ export default {
|
||||
@import '@assets/vuefilemanager/_variables';
|
||||
@import '@assets/vuefilemanager/_mixins';
|
||||
|
||||
.check-select {
|
||||
.check-box {
|
||||
margin-right: 10px;
|
||||
margin-left: 3px;
|
||||
position: absolute;
|
||||
@@ -317,35 +314,6 @@ export default {
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
.check-select-folder {
|
||||
margin-right: 10px;
|
||||
margin-left: 3px;
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
z-index: 5;
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
.select-box {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: $light_background;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 3px 15px 2px hsla(220, 36%, 16%, 0.05);
|
||||
}
|
||||
|
||||
.select-box-active {
|
||||
background-color: $theme;
|
||||
|
||||
.icon {
|
||||
stroke: white;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.show-actions {
|
||||
cursor: pointer;
|
||||
padding: 4px 26px;
|
||||
@@ -582,18 +550,6 @@ export default {
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
.select-box {
|
||||
background-color: lighten($dark_mode_foreground, 10%);
|
||||
}
|
||||
|
||||
.select-box-active {
|
||||
background-color: lighten($theme, 5%);
|
||||
|
||||
.icon {
|
||||
stroke: white;
|
||||
}
|
||||
}
|
||||
|
||||
.file-wrapper {
|
||||
|
||||
.icon-item {
|
||||
|
||||
@@ -10,11 +10,7 @@
|
||||
>
|
||||
<!-- MultiSelecting for the mobile version -->
|
||||
<transition name="slide-from-left">
|
||||
<div class="check-select" v-if="mobileMultiSelect">
|
||||
<div class="select-box" :class="{'select-box-active' : isClicked } ">
|
||||
<CheckIcon v-if="isClicked" class="icon" size="17" />
|
||||
</div>
|
||||
</div>
|
||||
<CheckBox v-if="mobileMultiSelect" :is-clicked="isClicked" class="check-box"/>
|
||||
</transition>
|
||||
|
||||
<!--Thumbnail for item-->
|
||||
@@ -72,8 +68,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {LinkIcon, UserPlusIcon, CheckIcon, MoreVerticalIcon} from 'vue-feather-icons'
|
||||
import {LinkIcon, UserPlusIcon, MoreVerticalIcon} from 'vue-feather-icons'
|
||||
import FolderIcon from '@/components/FilesView/FolderIcon'
|
||||
import CheckBox from '@/components/FilesView/CheckBox'
|
||||
import {debounce} from 'lodash'
|
||||
import {mapGetters} from 'vuex'
|
||||
import {events} from '@/bus'
|
||||
@@ -87,7 +84,7 @@ export default {
|
||||
MoreVerticalIcon,
|
||||
UserPlusIcon,
|
||||
FolderIcon,
|
||||
CheckIcon,
|
||||
CheckBox,
|
||||
LinkIcon,
|
||||
},
|
||||
computed: {
|
||||
@@ -335,28 +332,9 @@ export default {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
|
||||
.check-select {
|
||||
.check-box {
|
||||
margin-right: 15px;
|
||||
margin-left: 6px;
|
||||
|
||||
.select-box {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: darken($light_background, 5%);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.select-box-active {
|
||||
background-color: $theme;
|
||||
|
||||
.icon {
|
||||
stroke: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.file-wrapper {
|
||||
@@ -543,20 +521,6 @@ export default {
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.check-select {
|
||||
|
||||
.select-box {
|
||||
background-color: lighten($dark_mode_foreground, 10%);
|
||||
}
|
||||
|
||||
.select-box-active {
|
||||
background-color: $theme;
|
||||
|
||||
.icon {
|
||||
stroke: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.file-wrapper {
|
||||
.icon-item {
|
||||
|
||||
Vendored
+28
@@ -334,6 +334,24 @@ const routesShared = [
|
||||
},
|
||||
]
|
||||
const routesAuth = [
|
||||
{
|
||||
name: 'SuccessfullyVerified',
|
||||
path: '/successfully-verified',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "chunks/email-verified" */ './views/Auth/SuccessfullyEmailVerified'),
|
||||
meta: {
|
||||
requiresAuth: false
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'SuccessfullySend',
|
||||
path: '/successfully-send',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "chunks/email-verified" */ './views/Auth/SuccessfullySendEmail'),
|
||||
meta: {
|
||||
requiresAuth: false
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'SignIn',
|
||||
path: '/sign-in',
|
||||
@@ -416,6 +434,16 @@ const routesUser = [
|
||||
title: 'routes_title.settings_password'
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Token',
|
||||
path: '/platform/token',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "chunks/settings-password" */ './views/User/AccessToken'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: 'routes_title.token'
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Storage',
|
||||
path: '/platform/settings/storage',
|
||||
|
||||
@@ -58,6 +58,24 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="block-wrapper">
|
||||
<div class="input-wrapper">
|
||||
<div class="inline-wrapper">
|
||||
<div class="switch-label">
|
||||
<label class="input-label">
|
||||
{{ $t('admin_settings.others.allow_user_verification') }}:
|
||||
</label>
|
||||
<small class="input-help" v-html="$t('admin_settings.others.allow_user_verification_help')"></small>
|
||||
</div>
|
||||
<SwitchInput @input="$updateText('/admin/settings', 'user_verification', app.userVerification)"
|
||||
v-model="app.userVerification"
|
||||
class="switch"
|
||||
:state="app.userVerification"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<FormLabel class="mt-70">
|
||||
{{ $t('admin_settings.others.section_others') }}
|
||||
</FormLabel>
|
||||
@@ -173,7 +191,7 @@
|
||||
mounted() {
|
||||
axios.get('/api/admin/settings', {
|
||||
params: {
|
||||
column: 'contact_email|google_analytics|storage_default|registration|storage_limitation|mimetypes_blacklist|upload_limit'
|
||||
column: 'contact_email|google_analytics|storage_default|registration|storage_limitation|mimetypes_blacklist|upload_limit|user_verification'
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
@@ -186,7 +204,8 @@
|
||||
userRegistration: parseInt(response.data.registration),
|
||||
storageLimitation: parseInt(response.data.storage_limitation),
|
||||
mimetypesBlacklist : response.data.mimetypes_blacklist,
|
||||
uploadLimit: response.data.upload_limit
|
||||
uploadLimit: response.data.upload_limit,
|
||||
userVerification: parseInt(response.data.user_verification)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -61,6 +61,19 @@
|
||||
</router-link>
|
||||
</span>
|
||||
</AuthContent>
|
||||
|
||||
<AuthContent name="not-verified" :visible="false">
|
||||
|
||||
<div class="user" v-if="checkedAccount">
|
||||
<img class="user-avatar" :src="checkedAccount.avatar" :alt="checkedAccount.name">
|
||||
<h1>{{ checkedAccount.name }}</h1>
|
||||
<h2>{{ $t('page_not_verified.subtitle') }}</h2>
|
||||
</div>
|
||||
|
||||
<span class="additional-link"> {{ $t('page_not_verified.resend_text') }}
|
||||
<a @click="resendEmail" class="text-theme">{{ $t('page_not_verified.resend_button') }} </a>
|
||||
</span>
|
||||
</AuthContent>
|
||||
</AuthContentWrapper>
|
||||
</template>
|
||||
|
||||
@@ -110,6 +123,18 @@
|
||||
}
|
||||
})
|
||||
},
|
||||
resendEmail() {
|
||||
axios.
|
||||
post('/api/user/email/resend/verify', {
|
||||
email: this.loginEmail
|
||||
})
|
||||
.then(
|
||||
this.$router.push({name: 'SuccessfullySend'})
|
||||
)
|
||||
.catch(() => {
|
||||
this.$isSomethingWrong()
|
||||
})
|
||||
},
|
||||
async logIn() {
|
||||
|
||||
// Validate fields
|
||||
@@ -164,6 +189,13 @@
|
||||
|
||||
if (!isValid) return;
|
||||
|
||||
if(!this.checkedAccount.verified) {
|
||||
|
||||
this.goToAuthPage('not-verified')
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Start loading
|
||||
this.isLoading = true
|
||||
|
||||
|
||||
@@ -132,17 +132,23 @@
|
||||
|
||||
// Send request to get user token
|
||||
axios
|
||||
.post('/register', this.register)
|
||||
.post('/api/register', this.register)
|
||||
.then(() => {
|
||||
|
||||
// End loading
|
||||
this.isLoading = false
|
||||
|
||||
// Set login state
|
||||
this.$store.commit('SET_AUTHORIZED', true)
|
||||
|
||||
// Go to files page
|
||||
this.$router.push({name: 'Files'})
|
||||
if(! this.config.userVerification) {
|
||||
// Set login state
|
||||
this.$store.commit('SET_AUTHORIZED', true)
|
||||
|
||||
// Go to files page
|
||||
this.$router.push({name: 'Files'})
|
||||
} else {
|
||||
// Go to SuccessfullySend page
|
||||
this.$router.push({name: 'SuccessfullySend'})
|
||||
}
|
||||
|
||||
})
|
||||
.catch(error => {
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<AuthContentWrapper>
|
||||
<AuthContent :visible="true">
|
||||
<img v-if="config.app_logo" class="logo" :src="$getImage(config.app_logo)" :alt="config.app_name">
|
||||
<b v-if="! config.app_logo" class="auth-logo-text">{{ config.app_name }}</b>
|
||||
|
||||
<h1>{{ $t('page_email_successfully_verified.title') }}</h1>
|
||||
<h2>{{ $t('page_email_successfully_verified.subtitle') }}</h2>
|
||||
|
||||
<a href="/sign-in">
|
||||
<AuthButton icon="chevron-right" :text="$t('page_sign_in.button_log_in')"/>
|
||||
</a>
|
||||
|
||||
</AuthContent>
|
||||
</AuthContentWrapper>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AuthContentWrapper from '@/components/Auth/AuthContentWrapper'
|
||||
import AuthContent from '@/components/Auth/AuthContent'
|
||||
import AuthButton from '@/components/Auth/AuthButton'
|
||||
import {mapGetters} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'SuccessfullyEmailVerified',
|
||||
components: {
|
||||
AuthContentWrapper,
|
||||
AuthContent,
|
||||
AuthButton,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['config']),
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '@assets/vuefilemanager/_auth-form';
|
||||
@import '@assets/vuefilemanager/_auth';
|
||||
</style>
|
||||
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<AuthContentWrapper>
|
||||
<AuthContent :visible="true">
|
||||
<img v-if="config.app_logo" class="logo" :src="$getImage(config.app_logo)" :alt="config.app_name">
|
||||
<b v-if="! config.app_logo" class="auth-logo-text">{{ config.app_name }}</b>
|
||||
|
||||
<h1>{{ $t('page_email_successfully_send.title') }}</h1>
|
||||
<h2>{{ $t('page_email_successfully_send.subtitle') }}</h2>
|
||||
|
||||
<span class="additional-link">
|
||||
<router-link :to="{name: 'Homepage'}" class="text-theme">
|
||||
{{ $t('go_home') }}
|
||||
</router-link>
|
||||
</span>
|
||||
|
||||
</AuthContent>
|
||||
</AuthContentWrapper>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AuthContentWrapper from '@/components/Auth/AuthContentWrapper'
|
||||
import AuthContent from '@/components/Auth/AuthContent'
|
||||
import AuthButton from '@/components/Auth/AuthButton'
|
||||
import {mapGetters} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'SuccessfullySendEmail',
|
||||
components: {
|
||||
AuthContentWrapper,
|
||||
AuthContent,
|
||||
AuthButton,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['config']),
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '@assets/vuefilemanager/_auth-form';
|
||||
@import '@assets/vuefilemanager/_auth';
|
||||
</style>
|
||||
@@ -32,6 +32,15 @@
|
||||
{{ $t('menu.password') }}
|
||||
</div>
|
||||
</router-link>
|
||||
|
||||
<router-link replace :to="{name: 'Token'}" class="menu-list-item link">
|
||||
<div class="icon text-theme">
|
||||
<key-icon size="17"></key-icon>
|
||||
</div>
|
||||
<div class="label text-theme">
|
||||
{{ $t('menu.token') }}
|
||||
</div>
|
||||
</router-link>
|
||||
</div>
|
||||
</ContentGroup>
|
||||
<ContentGroup title="Subscription" class="navigator" v-if="canShowSubscriptionSettings">
|
||||
@@ -142,6 +151,7 @@
|
||||
CloudIcon,
|
||||
UserIcon,
|
||||
LockIcon,
|
||||
KeyIcon,
|
||||
} from 'vue-feather-icons'
|
||||
|
||||
export default {
|
||||
@@ -162,6 +172,7 @@
|
||||
LockIcon,
|
||||
Spinner,
|
||||
InfoBox,
|
||||
KeyIcon,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['user', 'config']),
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<PageTab>
|
||||
<PageTabGroup>
|
||||
<FormLabel>{{ $t('user_token.title') }}</FormLabel>
|
||||
</PageTabGroup>
|
||||
</PageTab>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PageTabGroup from '@/components/Others/Layout/PageTabGroup'
|
||||
import FormLabel from '@/components/Others/Forms/FormLabel'
|
||||
import PageTab from '@/components/Others/Layout/PageTab'
|
||||
|
||||
export default {
|
||||
name: 'AccessToken',
|
||||
components: {
|
||||
PageTabGroup,
|
||||
FormLabel,
|
||||
PageTab
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
tokens: undefined
|
||||
}
|
||||
},
|
||||
created () {
|
||||
axios.
|
||||
get('/api/user/tokens')
|
||||
.then(response => {
|
||||
this.tokens = response.data
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@assets/vuefilemanager/_variables';
|
||||
@import '@assets/vuefilemanager/_mixins';
|
||||
|
||||
</style>
|
||||
@@ -54,6 +54,7 @@
|
||||
|
||||
allowHomepage: {{ $settings->allow_homepage ?? 1 }},
|
||||
userRegistration: {{ $settings->registration ?? 1 }},
|
||||
userVerification: {{ $settings->user_verification ?? 0 }},
|
||||
storageLimit: {{ $settings->storage_limitation ?? 1 }},
|
||||
storageDefaultSpace: {{ $settings->storage_default ?? 5 }},
|
||||
storageDefaultSpaceFormatted: '{{ isset($settings->storage_default) ? format_gigabytes($settings->storage_default) : format_gigabytes(5) }}',
|
||||
|
||||
Reference in New Issue
Block a user