added current password to the password changing form

This commit is contained in:
Čarodej
2022-01-21 07:41:26 +01:00
parent 6b71eabfa2
commit 4fc61afc11
8 changed files with 131 additions and 67 deletions

View File

@@ -67,14 +67,14 @@
"/chunks/platform.js": "/chunks/platform.js?id=f16ebede38a3f225f480",
"/chunks/platform~chunks/shared.js": "/chunks/platform~chunks/shared.js?id=6660d58dcc0bb5030e3d",
"/chunks/platform~chunks/shared~chunks/shared-with-me~chunks/team-folders.js": "/chunks/platform~chunks/shared~chunks/shared-with-me~chunks/team-folders.js?id=ca9ca67afd5839597647",
"/chunks/profile.js": "/chunks/profile.js?id=b3ef20adb950a9e88952",
"/chunks/profile.js": "/chunks/profile.js?id=0ecdd636c92f2f1172d2",
"/chunks/profile~chunks/settings-password.js": "/chunks/profile~chunks/settings-password.js?id=a81388efd770d51f8a9c",
"/chunks/purchase-code.js": "/chunks/purchase-code.js?id=d9af0efad2af2679954b",
"/chunks/recent-uploads.js": "/chunks/recent-uploads.js?id=8577d4c771602671b38a",
"/chunks/settings.js": "/chunks/settings.js?id=5267412fac612ee9003a",
"/chunks/settings-password.js": "/chunks/settings-password.js?id=1cb5a9edc84a2fd08589",
"/chunks/settings.js": "/chunks/settings.js?id=61583d26a715225f8be1",
"/chunks/settings-password.js": "/chunks/settings-password.js?id=c4b032c249f613227d1a",
"/chunks/settings-storage.js": "/chunks/settings-storage.js?id=84f35e2124d825cc5039",
"/chunks/settings~chunks/settings-password.js": "/chunks/settings~chunks/settings-password.js?id=dd0e09a6a1dcd21820cf",
"/chunks/settings~chunks/settings-password.js": "/chunks/settings~chunks/settings-password.js?id=aafc9cd6aa47b01bc25a",
"/chunks/setup-wizard.js": "/chunks/setup-wizard.js?id=651d5accf401908724c5",
"/chunks/shared.js": "/chunks/shared.js?id=db60726012b6d246bd77",
"/chunks/shared-with-me.js": "/chunks/shared-with-me.js?id=f8da9fc2e251efc885f5",
@@ -751,5 +751,28 @@
"/chunks/profile.20f30fd47c07fc9cdd7f.hot-update.js": "/chunks/profile.20f30fd47c07fc9cdd7f.hot-update.js",
"/chunks/profile.e703ff8bfc8cd1195402.hot-update.js": "/chunks/profile.e703ff8bfc8cd1195402.hot-update.js",
"/chunks/profile.c09e61fa1d64c5882478.hot-update.js": "/chunks/profile.c09e61fa1d64c5882478.hot-update.js",
"/chunks/profile.96526d9239968c4b4cb2.hot-update.js": "/chunks/profile.96526d9239968c4b4cb2.hot-update.js"
"/chunks/profile.96526d9239968c4b4cb2.hot-update.js": "/chunks/profile.96526d9239968c4b4cb2.hot-update.js",
"/js/main.49a89a9831d562379f16.hot-update.js": "/js/main.49a89a9831d562379f16.hot-update.js",
"/chunks/profile.f41a3e0978a6d9980762.hot-update.js": "/chunks/profile.f41a3e0978a6d9980762.hot-update.js",
"/chunks/profile.26cfbd0b30b9658709ad.hot-update.js": "/chunks/profile.26cfbd0b30b9658709ad.hot-update.js",
"/chunks/profile.fe6efe6e7e3879c60805.hot-update.js": "/chunks/profile.fe6efe6e7e3879c60805.hot-update.js",
"/js/main.784b76e17de286fb9538.hot-update.js": "/js/main.784b76e17de286fb9538.hot-update.js",
"/chunks/app-appearance~chunks/app-email~chunks/app-index~chunks/app-others~chunks/payments/billings~c~dd421a96.js": "/chunks/app-appearance~chunks/app-email~chunks/app-index~chunks/app-others~chunks/payments/billings~c~dd421a96.js?id=91eea8e08d675f1a84d2",
"/chunks/app-language~chunks/page-edit~chunks/pages~chunks/plan-create/fixed~chunks/plan-create/metere~daa2a968.js": "/chunks/app-language~chunks/page-edit~chunks/pages~chunks/plan-create/fixed~chunks/plan-create/metere~daa2a968.js?id=ef8cbb733f7e82636b51",
"/chunks/settings.784b76e17de286fb9538.hot-update.js": "/chunks/settings.784b76e17de286fb9538.hot-update.js",
"/chunks/settings-password.784b76e17de286fb9538.hot-update.js": "/chunks/settings-password.784b76e17de286fb9538.hot-update.js",
"/chunks/settings-password.73ad8a756c8e15a70929.hot-update.js": "/chunks/settings-password.73ad8a756c8e15a70929.hot-update.js",
"/chunks/settings-password.baab73bd8e1d0bada2a1.hot-update.js": "/chunks/settings-password.baab73bd8e1d0bada2a1.hot-update.js",
"/chunks/settings-password.4037da0b54a57093bd2f.hot-update.js": "/chunks/settings-password.4037da0b54a57093bd2f.hot-update.js",
"/chunks/settings-password.5c4c3dc75ff1b4daaad7.hot-update.js": "/chunks/settings-password.5c4c3dc75ff1b4daaad7.hot-update.js",
"/chunks/settings-password.76d31ed911207eae7da7.hot-update.js": "/chunks/settings-password.76d31ed911207eae7da7.hot-update.js",
"/chunks/settings-password.33e722002ad7f3add9bb.hot-update.js": "/chunks/settings-password.33e722002ad7f3add9bb.hot-update.js",
"/chunks/settings-password.94ff96ea91c2a7530e34.hot-update.js": "/chunks/settings-password.94ff96ea91c2a7530e34.hot-update.js",
"/chunks/settings-password.74c1fb0f11559f76d4eb.hot-update.js": "/chunks/settings-password.74c1fb0f11559f76d4eb.hot-update.js",
"/chunks/settings-password.7945a4c2aa3c17d1ac92.hot-update.js": "/chunks/settings-password.7945a4c2aa3c17d1ac92.hot-update.js",
"/chunks/settings-password.343327efb271a21bf557.hot-update.js": "/chunks/settings-password.343327efb271a21bf557.hot-update.js",
"/chunks/settings-password.aa592f3bde5df777a170.hot-update.js": "/chunks/settings-password.aa592f3bde5df777a170.hot-update.js",
"/chunks/settings-password.3eb3f1ad1ca4e2dee8e0.hot-update.js": "/chunks/settings-password.3eb3f1ad1ca4e2dee8e0.hot-update.js",
"/chunks/settings-password.7c0ad55ca726abfb4cf1.hot-update.js": "/chunks/settings-password.7c0ad55ca726abfb4cf1.hot-update.js",
"/chunks/settings-password.ee24e2e8e1c71c29a0c3.hot-update.js": "/chunks/settings-password.ee24e2e8e1c71c29a0c3.hot-update.js"
}

View File

@@ -1,8 +1,8 @@
<template>
<PageTab>
<div v-if="user">
<!--2fa authentication-->
<div v-if="user && ! user.data.attributes.socialite_account" class="card shadow-card">
<div v-if="! user.data.attributes.socialite_account" class="card shadow-card">
<FormLabel icon="smartphone">
{{ $t('2fa.settings.title') }}
</FormLabel>
@@ -28,7 +28,7 @@
<ul class="tokens-wrapper">
<li class="token-item" v-for="token in tokens" :key="token.id">
<div class="tokens-details">
<b class="name">{{ token.name}}</b>
<b class="name">{{ token.name }}</b>
<time class="last-used">{{ $t('last_used') }}: {{ token.last_used_at ? formatDate(token.last_used_at) : $t('never') }}</time>
</div>
<div @click="confirmDeleteToken(token)" class="tokens-destroyer">
@@ -43,81 +43,82 @@
</div>
<!--Change password-->
<div class="card shadow-card">
<ValidationObserver ref="password" @submit.prevent="resetPassword" v-slot="{ invalid }" tag="form">
<FormLabel>{{ $t('user_password.title') }}</FormLabel>
<ValidationProvider tag="div" mode="passive" name="New Password" rules="required" v-slot="{ errors }">
<AppInputText :title="$t('page_create_password.label_new_pass')" :error="errors[0]">
<input v-model="newPassword" :placeholder="$t('page_create_password.label_new_pass')"
type="password"
class="focus-border-theme input-dark"
:class="{'border-red': errors[0]}"
/>
</AppInputText>
</ValidationProvider>
<ValidationProvider tag="div" mode="passive" name="Confirm Your Password" rules="required" v-slot="{ errors }">
<AppInputText :title="$t('page_create_password.label_confirm_pass')" :error="errors[0]">
<input v-model="newPasswordConfirmation"
:placeholder="$t('page_create_password.label_confirm_pass')"
type="password"
class="focus-border-theme input-dark"
:class="{'border-red': errors[0]}"
/>
</AppInputText>
</ValidationProvider>
<ButtonBase type="submit" button-style="theme" class="confirm-form">
{{ $t('profile.store_pass') }}
</ButtonBase>
</ValidationObserver>
</div>
</PageTab>
<ValidationObserver ref="password" @submit.prevent="resetPassword" v-slot="{ invalid }" tag="form" class="card shadow-card">
<FormLabel>
{{ $t('user_password.title') }}
</FormLabel>
<ValidationProvider tag="div" mode="passive" name="Current Password" rules="required" v-slot="{ errors }">
<AppInputText :title="$t('Current Password')" :error="errors[0]">
<input v-model="passwordForm.current" :placeholder="$t('Current password')" type="password" class="focus-border-theme input-dark" :class="{'border-red': errors[0]}" />
</AppInputText>
</ValidationProvider>
<ValidationProvider tag="div" mode="passive" name="New Password" rules="required" v-slot="{ errors }">
<AppInputText :title="$t('page_create_password.label_new_pass')" :error="errors[0]">
<input v-model="passwordForm.password" :placeholder="$t('page_create_password.label_new_pass')" type="password" class="focus-border-theme input-dark" :class="{'border-red': errors[0]}" />
</AppInputText>
</ValidationProvider>
<ValidationProvider tag="div" mode="passive" name="Confirm Your Password" rules="required" v-slot="{ errors }">
<AppInputText :title="$t('page_create_password.label_confirm_pass')" :error="errors[0]">
<input v-model="passwordForm.password_confirmation" :placeholder="$t('page_create_password.label_confirm_pass')" type="password" class="focus-border-theme input-dark" :class="{'border-red': errors[0]}" />
</AppInputText>
</ValidationProvider>
<ButtonBase type="submit" button-style="theme" class="confirm-form">
{{ $t('profile.store_pass') }}
</ButtonBase>
</ValidationObserver>
</div>
</template>
<script>
import AppInputText from "../../components/Admin/AppInputText";
import AppInputSwitch from "../../components/Admin/AppInputSwitch";
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import PageTabGroup from '/resources/js/components/Others/Layout/PageTabGroup'
import UserImageInput from '/resources/js/components/Others/UserImageInput'
import SwitchInput from '/resources/js/components/Others/Forms/SwitchInput'
import FormLabel from '/resources/js/components/Others/Forms/FormLabel'
import MobileHeader from '/resources/js/components/Mobile/MobileHeader'
import ButtonBase from '/resources/js/components/FilesView/ButtonBase'
import PageTab from '/resources/js/components/Others/Layout/PageTab'
import InfoBox from '/resources/js/components/Others/Forms/InfoBox'
import PageHeader from '/resources/js/components/Others/PageHeader'
import ThemeLabel from '/resources/js/components/Others/ThemeLabel'
import AppInputSwitch from "../../components/Admin/AppInputSwitch"
import AppInputText from "../../components/Admin/AppInputText"
import {required} from 'vee-validate/dist/rules'
import { XIcon } from 'vue-feather-icons'
import {mapGetters} from 'vuex'
import {XIcon} from 'vue-feather-icons'
import {events} from '/resources/js/bus'
import {mapGetters} from 'vuex'
import axios from 'axios'
export default {
name: 'Password',
components: {
AppInputText,
AppInputSwitch,
PageTabGroup,
FormLabel,
PageTab,
InfoBox,
XIcon,
ValidationProvider,
ValidationObserver,
UserImageInput,
AppInputSwitch,
AppInputText,
SwitchInput,
MobileHeader,
PageHeader,
ButtonBase,
ThemeLabel,
FormLabel,
required,
InfoBox,
XIcon,
},
computed: {
...mapGetters(['user'])
...mapGetters([
'user',
])
},
data() {
return {
passwordForm: {
current: undefined,
password: undefined,
password_confirmation: undefined,
},
newPasswordConfirmation: '',
newPassword: '',
isLoading: false,
@@ -160,20 +161,20 @@
// Send request to get user reset link
axios
.post(this.$store.getters.api + '/user/password', {
password: this.newPassword,
password_confirmation: this.newPasswordConfirmation,
})
.post(this.$store.getters.api + '/user/password', this.passwordForm)
.then(() => {
// Reset inputs
this.newPassword = ''
this.newPasswordConfirmation = ''
this.passwordForm = {
current: undefined,
password: undefined,
password_confirmation: undefined,
}
// Reset errors
this.$refs.password.reset()
// Show error message
// Show success message
events.$emit('success:open', {
title: this.$t('popup_pass_changed.title'),
message: this.$t('popup_pass_changed.message'),
@@ -181,14 +182,19 @@
})
.catch(error => {
if (error.response.status == 422) {
if (error.response.status === 422) {
if (error.response.data.errors['password']) {
this.$refs.password.setErrors({
'New Password': error.response.data.errors['password']
});
}
if (error.response.data.errors['current']) {
this.$refs.password.setErrors({
'Current Password': error.response.data.errors['current']
});
}
}
})
},

View File

@@ -6,7 +6,7 @@
{{ $t('Appearance') }}
</FormLabel>
<AppInputText :title="$t('Theme Mode')" :description="$t('Set your theme mode on dark, light or based on your system settings.')">
<AppInputText :title="$t('Theme Mode')" :description="$t('Set your theme mode on dark, light or based on your system settings.')" :is-last="! $isApple()">
<div class="flex items-center md:space-x-6 space-x-4">
<div
v-for="(theme, i) in themeSetup"
@@ -21,7 +21,7 @@
</div>
</AppInputText>
<AppInputText :title="$t('Default Emojis')" :description="$t('Set your default emojis for your folder custom icons. You can set Twemoji or default Apple emojis.')" :is-last="true">
<AppInputText v-if="$isApple()" :title="$t('Default Emojis')" :description="$t('Set your default emojis for your folder custom icons. You can set Twemoji or default Apple emojis.')" :is-last="true">
<div class="flex items-center md:space-x-6 space-x-4">
<div
v-for="(emoji, i) in emojiSetup"

View File

@@ -14,7 +14,7 @@ class UpdatePasswordController extends Controller
$user = Auth::user();
// Check if is demo
abort_if(is_demo_account($user->email), 204, 'Changed!');
abort_if(is_demo_account(), 204, 'Changed!');
// Store new password
$user->update([

View File

@@ -2,6 +2,7 @@
namespace App\Users\Requests;
use Illuminate\Foundation\Http\FormRequest;
use App\Users\Rules\PasswordMatchWithCurrent;
class UpdateUserPasswordRequest extends FormRequest
{
@@ -23,6 +24,7 @@ class UpdateUserPasswordRequest extends FormRequest
public function rules()
{
return [
'current' => ['required', 'string', new PasswordMatchWithCurrent()],
'password' => 'required|string|min:6|confirmed',
];
}

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Users\Rules;
use Auth;
use Hash;
use Illuminate\Contracts\Validation\Rule;
class PasswordMatchWithCurrent implements Rule
{
/**
* Determine if the validation rule passes.
*/
public function passes($attribute, $value): bool
{
return Hash::check($value, Auth::user()->password);
}
/**
* Get the validation error message.
*/
public function message(): string
{
return "Your current password doesn't match.";
}
}

View File

@@ -268,7 +268,7 @@ class SignFlowTest extends TestCase
public function it_login_user()
{
$user = User::factory()
->create(['email' => 'john@doe.com']);
->create();
$this->postJson('/login', [
'email' => $user->email,

View File

@@ -72,12 +72,20 @@ class UserAccountTest extends TestCase
$this
->actingAs($user)
->postJson('/api/user/password', [
'current_password' => 'secret',
'current' => 'secret',
'password' => 'VerySecretPassword',
'password_confirmation' => 'VerySecretPassword',
])->assertStatus(204);
// TODO: login s novym heslom
$this
->actingAs($user)
->postJson('/logout')
->assertStatus(204);
$this->postJson('/login', [
'email' => $user->email,
'password' => 'VerySecretPassword',
])->assertStatus(200);
}
/**