Skip to content
Snippets Groups Projects
Commit 897477d2 authored by Eugenij's avatar Eugenij
Browse files

Add the Security Settings modal for setting the user's email and password

parent 52932608
No related branches found
No related tags found
No related merge requests found
Pipeline #23237 passed
......@@ -71,6 +71,25 @@ export async function fetchUser(id, authHost, token) {
})
}
export async function fetchUserCredentials(nickname, authHost, token) {
return await request({
baseURL: baseName(authHost),
url: `/api/pleroma/admin/users/${nickname}/credentials`,
method: 'get',
headers: authHeaders(token)
})
}
export async function updateUserCredentials(nickname, credentials, authHost, token) {
return await request({
baseURL: baseName(authHost),
url: `/api/pleroma/admin/users/${nickname}/credentials`,
method: 'patch',
headers: authHeaders(token),
data: credentials
})
}
export async function fetchUsers(filters, authHost, token, page = 1) {
return await request({
baseURL: baseName(authHost),
......
......@@ -260,7 +260,21 @@ export default {
activeUppercase: 'Active',
active: 'active',
deactivated: 'deactivated',
noStatuses: 'No statuses to show'
noStatuses: 'No statuses to show',
securitySettings: {
email: 'Email',
password: 'Password',
securitySettings: 'Security settings',
passwordChangeWarning1: 'Setting a new password will cause the user to be signed out from any client they have used before.',
passwordChangeWarning2: 'When the user signs in with this password, they will be asked to set a new one.',
passwordLengthNotice: 'Make sure it\'s at least {minLength} characters long.',
inputNewPassword: 'Input new password',
passwordUpdated: 'The password has been updated',
emailUpdated: 'The email has been updated',
success: 'Success',
submit: 'Submit',
close: 'Close'
}
},
usersFilter: {
inputPlaceholder: 'Select filter',
......
import { fetchUser, fetchUserStatuses } from '@/api/users'
import { fetchUser, fetchUserStatuses, fetchUserCredentials, updateUserCredentials } from '@/api/users'
const userProfile = {
state: {
statuses: [],
statusesLoading: true,
user: {},
userCredentials: {},
userProfileLoading: true
},
mutations: {
......@@ -19,6 +20,9 @@ const userProfile = {
},
SET_USER_PROFILE_LOADING: (state, status) => {
state.userProfileLoading = status
},
SET_USER_CREDENTIALS: (state, userCredentials) => {
state.userCredentials = userCredentials
}
},
actions: {
......@@ -38,6 +42,14 @@ const userProfile = {
commit('SET_STATUSES', statuses.data)
commit('SET_STATUSES_LOADING', false)
},
async FetchUserCredentials({ commit, getters }, { nickname }) {
const userResponse = await fetchUserCredentials(nickname, getters.authHost, getters.token)
commit('SET_USER_CREDENTIALS', userResponse.data)
},
async UpdateUserCredentials({ dispatch, getters }, { nickname, credentials }) {
await updateUserCredentials(nickname, credentials, getters.authHost, getters.token)
dispatch('FetchUserCredentials', { nickname })
}
}
}
......
<template>
<el-dialog
:before-close="close"
:title="$t('userProfile.securitySettings.securitySettings')"
:visible="visible"
class="security-settings-modal">
<div>
<p>
<label>
{{ $t('userProfile.securitySettings.email') }}
</label>
</p>
<div>
<el-input v-model="emailForm.newEmail" />
</div>
<br>
<div>
<el-button
:loading="emailForm.isLoading"
:disabled="emailForm.newEmail === userCredentials.email"
type="primary"
@click="updateEmail()">
{{ $t('userProfile.securitySettings.submit') }}
</el-button>
</div>
</div>
<br>
<div>
<p>
<label>
{{ $t('userProfile.securitySettings.password') }}
</label>
</p>
<div>
<el-input
:placeholder="$t('userProfile.securitySettings.inputNewPassword')"
v-model="passwordForm.newPassword"
show-password />
<small class="form-text">
{{ $t('userProfile.securitySettings.passwordLengthNotice', { minLength: 8 }) }}
</small>
</div>
<br>
<el-alert
:closable="false"
type="warning"
show-icon>
<p>{{ $t('userProfile.securitySettings.passwordChangeWarning1') }}</p>
<p>{{ $t('userProfile.securitySettings.passwordChangeWarning2') }}</p>
</el-alert>
<br>
<div>
<el-button
slot="reference"
:loading="passwordForm.isLoading"
:disabled="passwordForm.newPassword.length < 8"
type="primary"
@click="updatePassword()">
{{ $t('userProfile.securitySettings.submit') }}
</el-button>
</div>
</div>
<span slot="footer">
<el-button @click="close">
{{ $t('userProfile.securitySettings.close') }}
</el-button>
</span>
</el-dialog>
</template>
<script>
export default {
name: 'SecuritySettingsModal',
props: {
visible: {
type: Boolean,
default: false
},
user: {
type: Object,
default: function() {
return {}
}
}
},
data() {
return {
emailForm: {
newEmail: '',
isLoading: false
},
passwordForm: {
newPassword: '',
isLoading: false
}
}
},
computed: {
userCredentials() {
return this.$store.state.userProfile.userCredentials
}
},
mounted: async function() {
await this.$store.dispatch('FetchUserCredentials', { nickname: this.user.nickname })
this.emailForm.newEmail = this.userCredentials.email
},
methods: {
async updateEmail() {
const credentials = { email: this.emailForm.newEmail }
this.emailForm.isLoading = true
await this.$store.dispatch('UpdateUserCredentials', { nickname: this.user.nickname, credentials })
this.emailForm.isLoading = false
this.$notify.success({
title: this.$t('userProfile.securitySettings.success'),
message: this.$t('userProfile.securitySettings.emailUpdated'),
duration: 2000
})
},
async updatePassword() {
const credentials = { password: this.newPassword }
this.passwordForm.isLoading = true
await this.$store.dispatch('UpdateUserCredentials', { nickname: this.user.nickname, credentials })
this.passwordForm.isLoading = false
this.passwordForm.newPassword = ''
this.$notify.success({
title: this.$t('userProfile.securitySettings.success'),
message: this.$t('userProfile.securitySettings.passwordUpdated'),
duration: 2000
})
},
close() {
this.$emit('close', true)
}
}
}
</script>
<style rel='stylesheet/scss' lang='scss'>
@media all and (max-width: 800px) {
.security-settings-modal {
.el-dialog {
width: 90%;
}
}
}
.security-settings-modal {
.el-alert .el-alert__description {
word-break: break-word;
font-size: 1em;
}
.form-text {
display: block;
margin-top: .25rem;
color: #909399;
}
}
</style>
......@@ -73,6 +73,18 @@
<el-tag v-if="user.deactivated" type="danger">{{ $t('userProfile.deactivated') }}</el-tag>
</td>
</tr>
<tr class="el-table__row">
<td>
<el-button icon="el-icon-lock" @click="securitySettingsModalVisible = true">
{{ $t('userProfile.securitySettings.securitySettings') }}
</el-button>
<SecuritySettingsModal
:user="user"
:visible="securitySettingsModalVisible"
@close="securitySettingsModalVisible = false" />
</td>
<td />
</tr>
</tbody>
</table>
</div>
......@@ -96,14 +108,16 @@
<script>
import Status from '@/components/Status'
import ModerationDropdown from './components/ModerationDropdown'
import SecuritySettingsModal from './components/SecuritySettingsModal'
export default {
name: 'UsersShow',
components: { ModerationDropdown, Status },
components: { ModerationDropdown, Status, SecuritySettingsModal },
data() {
return {
showPrivate: false,
resetPasswordDialogOpen: false
resetPasswordDialogOpen: false,
securitySettingsModalVisible: false
}
},
computed: {
......@@ -127,6 +141,9 @@ export default {
},
userProfileLoading() {
return this.$store.state.userProfile.userProfileLoading
},
userCredentials() {
return this.$store.state.userProfile.userCredentials
}
},
mounted: function() {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment