Implement password change in basic user settings
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
f129d4137d
commit
3806295e83
|
@ -25,6 +25,14 @@ mutation ValidateUser($token: String!) {
|
|||
}
|
||||
`;
|
||||
|
||||
export const CHANGE_PASSWORD = gql`
|
||||
mutation ChangePassword($oldPassword: String!, $newPassword: String!) {
|
||||
changePassword(oldPassword: $oldPassword, newPassword: $newPassword) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const CURRENT_USER_CLIENT = gql`
|
||||
query {
|
||||
currentUser @client {
|
||||
|
|
|
@ -7,6 +7,7 @@ import SendPasswordReset from '@/views/User/SendPasswordReset.vue';
|
|||
import PasswordReset from '@/views/User/PasswordReset.vue';
|
||||
import { beforeRegisterGuard } from '@/router/guards/register-guard';
|
||||
import { RouteConfig } from 'vue-router';
|
||||
import PasswordChange from '@/views/User/PasswordChange.vue';
|
||||
|
||||
export enum UserRouteName {
|
||||
REGISTER = 'Register',
|
||||
|
@ -16,6 +17,7 @@ export enum UserRouteName {
|
|||
PASSWORD_RESET = 'PasswordReset',
|
||||
VALIDATE = 'Validate',
|
||||
LOGIN = 'Login',
|
||||
PASSWORD_CHANGE = 'PasswordChange',
|
||||
}
|
||||
|
||||
export const userRoutes: RouteConfig[] = [
|
||||
|
@ -70,4 +72,10 @@ export const userRoutes: RouteConfig[] = [
|
|||
props: true,
|
||||
meta: { requiredAuth: false },
|
||||
},
|
||||
{
|
||||
path: '/my-account/password',
|
||||
name: UserRouteName.PASSWORD_CHANGE,
|
||||
component: PasswordChange,
|
||||
meta: { requiredAuth: true },
|
||||
},
|
||||
];
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
<template>
|
||||
<section class="container">
|
||||
<nav class="breadcrumb" aria-label="breadcrumbs">
|
||||
<ul>
|
||||
<li class="is-active"><router-link :to="{ name: MyAccountRouteName.UPDATE_IDENTITY }" aria-current="page">{{ $t('My account') }}</router-link></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div v-if="currentActor">
|
||||
<div class="header">
|
||||
<figure v-if="currentActor.banner" class="image is-3by1">
|
||||
|
@ -10,6 +15,9 @@
|
|||
<div class="columns">
|
||||
<div class="identities column is-4">
|
||||
<identities v-bind:currentIdentityName="currentIdentityName"></identities>
|
||||
<div class="buttons">
|
||||
<b-button tag="router-link" type="is-secondary" :to="{ name: UserRouteName.PASSWORD_CHANGE }">{{ $t('Change password') }}</b-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-8">
|
||||
<router-view></router-view>
|
||||
|
@ -27,6 +35,10 @@
|
|||
.identities {
|
||||
padding-right: 45px;
|
||||
margin-right: 45px;
|
||||
|
||||
.buttons {
|
||||
margin-top: 1.2rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
@ -36,6 +48,8 @@ import { Component, Vue, Watch } from 'vue-property-decorator';
|
|||
import EventCard from '@/components/Event/EventCard.vue';
|
||||
import { IPerson } from '@/types/actor';
|
||||
import Identities from '@/components/Account/Identities.vue';
|
||||
import { UserRouteName } from '@/router/user';
|
||||
import { MyAccountRouteName } from '@/router/actor';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
|
@ -52,6 +66,9 @@ export default class MyAccount extends Vue {
|
|||
currentActor!: IPerson;
|
||||
currentIdentityName: string | null = null;
|
||||
|
||||
UserRouteName = UserRouteName;
|
||||
MyAccountRouteName = MyAccountRouteName;
|
||||
|
||||
@Watch('$route.params.identityName', { immediate: true })
|
||||
async onIdentityParamChanged (val: string) {
|
||||
await this.redirectIfNoIdentitySelected(val);
|
||||
|
|
94
js/src/views/User/PasswordChange.vue
Normal file
94
js/src/views/User/PasswordChange.vue
Normal file
|
@ -0,0 +1,94 @@
|
|||
<template>
|
||||
<section class="section">
|
||||
<nav class="breadcrumb" aria-label="breadcrumbs">
|
||||
<ul>
|
||||
<li><router-link :to="{ name: MyAccountRouteName.UPDATE_IDENTITY }">{{ $t('My account') }}</router-link></li>
|
||||
<li class="is-active"><router-link :to="{ name: UserRouteName.PASSWORD_CHANGE }" aria-current="page">{{ $t('Password change') }}</router-link></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<h1 class="title">{{ $t('Password') }}</h1>
|
||||
<b-notification
|
||||
type="is-danger"
|
||||
has-icon
|
||||
aria-close-label="Close notification"
|
||||
role="alert"
|
||||
:key="error"
|
||||
v-for="error in errors"
|
||||
>
|
||||
{{ error }}
|
||||
</b-notification>
|
||||
<form @submit="resetAction" class="form">
|
||||
<b-field :label="$t('Old password')">
|
||||
<b-input
|
||||
aria-required="true"
|
||||
required
|
||||
type="password"
|
||||
password-reveal
|
||||
minlength="6"
|
||||
v-model="oldPassword"
|
||||
/>
|
||||
</b-field>
|
||||
<b-field :label="$t('New password')">
|
||||
<b-input
|
||||
aria-required="true"
|
||||
required
|
||||
type="password"
|
||||
password-reveal
|
||||
minlength="6"
|
||||
v-model="newPassword"
|
||||
/>
|
||||
</b-field>
|
||||
<button class="button is-primary">
|
||||
{{ $t('Change my password') }}
|
||||
</button>
|
||||
</form>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator';
|
||||
import { CHANGE_PASSWORD } from '@/graphql/user';
|
||||
import { UserRouteName } from '@/router/user';
|
||||
import { MyAccountRouteName } from '@/router/actor';
|
||||
|
||||
@Component
|
||||
export default class PasswordChange extends Vue {
|
||||
oldPassword: string = '';
|
||||
newPassword: string = '';
|
||||
errors: string[] = [];
|
||||
|
||||
MyAccountRouteName = MyAccountRouteName;
|
||||
UserRouteName = UserRouteName;
|
||||
|
||||
async resetAction(e) {
|
||||
e.preventDefault();
|
||||
this.errors = [];
|
||||
|
||||
try {
|
||||
await this.$apollo.mutate({
|
||||
mutation: CHANGE_PASSWORD,
|
||||
variables: {
|
||||
oldPassword: this.oldPassword,
|
||||
newPassword: this.newPassword,
|
||||
},
|
||||
});
|
||||
|
||||
this.$notifier.success(this.$t('The password was successfully changed') as string);
|
||||
} catch (err) {
|
||||
this.handleError(err);
|
||||
}
|
||||
}
|
||||
|
||||
private handleError(err: any) {
|
||||
console.error(err);
|
||||
|
||||
if (err.graphQLErrors !== undefined) {
|
||||
err.graphQLErrors.forEach(({ message }) => {
|
||||
this.errors.push(message);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
</style>
|
|
@ -1,5 +1,5 @@
|
|||
# source: http://localhost:4000/api
|
||||
# timestamp: Fri Sep 20 2019 16:55:10 GMT+0200 (GMT+02:00)
|
||||
# timestamp: Tue Sep 24 2019 18:20:05 GMT+0200 (GMT+02:00)
|
||||
|
||||
schema {
|
||||
query: RootQueryType
|
||||
|
@ -184,7 +184,7 @@ enum CommentVisibility {
|
|||
"""Visible only to people members of the group or followers of the person"""
|
||||
PRIVATE
|
||||
|
||||
"""Publically listed and federated. Can be shared."""
|
||||
"""Publicly listed and federated. Can be shared."""
|
||||
PUBLIC
|
||||
|
||||
"""Visible only to people with the link - or invited"""
|
||||
|
@ -885,6 +885,9 @@ type RootMutationType {
|
|||
"""Change default actor for user"""
|
||||
changeDefaultActor(preferredUsername: String!): User
|
||||
|
||||
"""Change an user password"""
|
||||
changePassword(newPassword: String!, oldPassword: String!): User
|
||||
|
||||
"""Create a comment"""
|
||||
createComment(actorUsername: String!, text: String!): Comment
|
||||
|
||||
|
@ -911,7 +914,7 @@ type RootMutationType {
|
|||
"""The list of tags associated to the event"""
|
||||
tags: [String] = [""]
|
||||
title: String!
|
||||
visibility: EventVisibility = PRIVATE
|
||||
visibility: EventVisibility = PUBLIC
|
||||
): Event
|
||||
|
||||
"""Create a Feed Token"""
|
||||
|
@ -1044,7 +1047,7 @@ type RootMutationType {
|
|||
description: String
|
||||
endsOn: DateTime
|
||||
eventId: ID!
|
||||
joinOptions: EventJoinOptions
|
||||
joinOptions: EventJoinOptions = FREE
|
||||
onlineAddress: String
|
||||
options: EventOptionsInput
|
||||
phoneAddress: String
|
||||
|
@ -1059,7 +1062,7 @@ type RootMutationType {
|
|||
"""The list of tags associated to the event"""
|
||||
tags: [String]
|
||||
title: String
|
||||
visibility: EventVisibility
|
||||
visibility: EventVisibility = PUBLIC
|
||||
): Event
|
||||
|
||||
"""Update an identity"""
|
||||
|
|
Loading…
Reference in a new issue