Ability to require user's password reset

This commit is contained in:
Maxim Filippov 2019-09-24 22:55:42 +00:00
parent 21a7aa0de5
commit ada2de9733
7 changed files with 57 additions and 8 deletions

View file

@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added ### Added
- Emoji pack configuration - Emoji pack configuration
- Ability to require user's password reset
## [1.1.0] - 2019-09-15 ## [1.1.0] - 2019-09-15

View file

@ -66,6 +66,15 @@ export async function getPasswordResetToken(nickname, authHost, token) {
}) })
} }
export async function requirePasswordReset(nickname, authHost, token) {
return await request({
baseURL: baseName(authHost),
url: `/api/pleroma/admin/users/${nickname}/force_password_reset`,
method: 'patch',
headers: authHeaders(token)
})
}
export async function searchUsers(query, filters, authHost, token, page = 1) { export async function searchUsers(query, filters, authHost, token, page = 1) {
return await request({ return await request({
baseURL: baseName(authHost), baseURL: baseName(authHost),

View file

@ -200,6 +200,7 @@ export default {
disableRemoteSubscriptionForMultiple: 'Disallow following users from remote instances', disableRemoteSubscriptionForMultiple: 'Disallow following users from remote instances',
disableAnySubscription: 'Disallow following user at all', disableAnySubscription: 'Disallow following user at all',
disableAnySubscriptionForMultiple: 'Disallow following users at all', disableAnySubscriptionForMultiple: 'Disallow following users at all',
requirePasswordReset: 'Require password reset on next login',
selectUsers: 'Select users to apply actions to multiple users', selectUsers: 'Select users to apply actions to multiple users',
moderateUsers: 'Moderate multiple users', moderateUsers: 'Moderate multiple users',
createAccount: 'Create new account', createAccount: 'Create new account',
@ -212,6 +213,7 @@ export default {
deleteMultipleUsersConfirmation: 'Are you sure you want to delete accounts of all selected users?', deleteMultipleUsersConfirmation: 'Are you sure you want to delete accounts of all selected users?',
addTagForMultipleUsersConfirmation: 'Are you sure you want to apply tag to all selected users?', addTagForMultipleUsersConfirmation: 'Are you sure you want to apply tag to all selected users?',
removeTagFromMultipleUsersConfirmation: 'Are you sure you want to remove tag from all selected users?', removeTagFromMultipleUsersConfirmation: 'Are you sure you want to remove tag from all selected users?',
requirePasswordResetConfirmation: 'Are you sure you want to require password reset for all selected users?',
ok: 'Okay', ok: 'Okay',
completed: 'Completed', completed: 'Completed',
cancel: 'Cancel', cancel: 'Cancel',

View file

@ -1,4 +1,16 @@
import { addRight, createNewAccount, deleteRight, deleteUser, fetchUsers, getPasswordResetToken, searchUsers, tagUser, toggleUserActivation, untagUser } from '@/api/users' import {
addRight,
createNewAccount,
deleteRight,
deleteUser,
fetchUsers,
getPasswordResetToken,
searchUsers,
tagUser,
toggleUserActivation,
untagUser,
requirePasswordReset
} from '@/api/users'
const users = { const users = {
state: { state: {
@ -83,6 +95,9 @@ const users = {
const users = state.fetchedUsers.filter(user => user.nickname !== data) const users = state.fetchedUsers.filter(user => user.nickname !== data)
commit('SET_USERS', users) commit('SET_USERS', users)
}, },
async RequirePasswordReset({ commit, getters, state }, user) {
await requirePasswordReset(user.nickname, getters.authHost, getters.token)
},
async FetchUsers({ commit, state, getters }, { page }) { async FetchUsers({ commit, state, getters }, { page }) {
commit('SET_LOADING', true) commit('SET_LOADING', true)
const filters = Object.keys(state.filters).filter(filter => state.filters[filter]).join() const filters = Object.keys(state.filters).filter(filter => state.filters[filter]).join()

View file

@ -39,6 +39,10 @@
@click.native="deleteMultipleUsers"> @click.native="deleteMultipleUsers">
{{ $t('users.deleteAccounts') }} {{ $t('users.deleteAccounts') }}
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item
@click.native="requirePasswordReset">
{{ $t('users.requirePasswordReset') }}
</el-dropdown-item>
<el-dropdown-item divided class="no-hover"> <el-dropdown-item divided class="no-hover">
<div class="tag-container"> <div class="tag-container">
<span class="tag-text">{{ $t('users.forceNsfw') }}</span> <span class="tag-text">{{ $t('users.forceNsfw') }}</span>
@ -227,6 +231,9 @@ export default {
message: this.$t('users.completed') message: this.$t('users.completed')
}) })
this.$emit('apply-action') this.$emit('apply-action')
},
requirePasswordReset: () => {
this.selectedUsers.map(user => this.$store.dispatch('RequirePasswordReset', user))
} }
} }
}, },
@ -265,6 +272,13 @@ export default {
remove remove
) )
}, },
requirePasswordReset() {
const { requirePasswordReset } = this.mappers()
this.confirmMessage(
this.$t('users.requirePasswordResetConfirmation'),
requirePasswordReset
)
},
addTagForMultipleUsers(tag) { addTagForMultipleUsers(tag) {
const { addTag } = this.mappers() const { addTag } = this.mappers()
this.confirmMessage( this.confirmMessage(

View file

@ -133,6 +133,11 @@
@click.native="getPasswordResetToken(scope.row.nickname)"> @click.native="getPasswordResetToken(scope.row.nickname)">
{{ $t('users.getPasswordResetToken') }} {{ $t('users.getPasswordResetToken') }}
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item
v-if="scope.row.local"
@click.native="requirePasswordReset(scope.row.nickname)">
{{ $t('users.requirePasswordReset') }}
</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
</template> </template>
@ -259,6 +264,9 @@ export default {
this.resetPasswordDialogOpen = true this.resetPasswordDialogOpen = true
this.$store.dispatch('GetPasswordResetToken', nickname) this.$store.dispatch('GetPasswordResetToken', nickname)
}, },
requirePasswordReset(nickname) {
this.$store.dispatch('RequirePasswordReset', { nickname })
},
handleDeactivation({ nickname }) { handleDeactivation({ nickname }) {
this.$store.dispatch('ToggleUserActivation', nickname) this.$store.dispatch('ToggleUserActivation', nickname)
}, },

View file

@ -251,15 +251,15 @@ describe('Apply users actions to multiple users', () => {
const addTagForMultipleUsersStub = jest.fn() const addTagForMultipleUsersStub = jest.fn()
wrapper.setMethods({ addTagForMultipleUsers: addTagForMultipleUsersStub }) wrapper.setMethods({ addTagForMultipleUsers: addTagForMultipleUsersStub })
wrapper.find(`.el-dropdown-menu__item:nth-child(8) button:nth-child(1)`).trigger('click') wrapper.find(`.el-dropdown-menu__item:nth-child(9) button:nth-child(1)`).trigger('click')
expect(wrapper.vm.addTagForMultipleUsers).toHaveBeenCalled() expect(wrapper.vm.addTagForMultipleUsers).toHaveBeenCalled()
expect(wrapper.vm.addTagForMultipleUsers).toHaveBeenCalledWith('force_nsfw') expect(wrapper.vm.addTagForMultipleUsers).toHaveBeenCalledWith('force_nsfw')
wrapper.find(`.el-dropdown-menu__item:nth-child(10) button:nth-child(1)`).trigger('click') wrapper.find(`.el-dropdown-menu__item:nth-child(11) button:nth-child(1)`).trigger('click')
expect(wrapper.vm.addTagForMultipleUsers).toHaveBeenCalled() expect(wrapper.vm.addTagForMultipleUsers).toHaveBeenCalled()
expect(wrapper.vm.addTagForMultipleUsers).toHaveBeenCalledWith('force_unlisted') expect(wrapper.vm.addTagForMultipleUsers).toHaveBeenCalledWith('force_unlisted')
wrapper.find(`.el-dropdown-menu__item:nth-child(12) button:nth-child(1)`).trigger('click') wrapper.find(`.el-dropdown-menu__item:nth-child(13) button:nth-child(1)`).trigger('click')
expect(wrapper.vm.addTagForMultipleUsers).toHaveBeenCalled() expect(wrapper.vm.addTagForMultipleUsers).toHaveBeenCalled()
expect(wrapper.vm.addTagForMultipleUsers).toHaveBeenCalledWith('disable_remote_subscription') expect(wrapper.vm.addTagForMultipleUsers).toHaveBeenCalledWith('disable_remote_subscription')
@ -292,15 +292,15 @@ describe('Apply users actions to multiple users', () => {
const removeTagFromMultipleUsersStub = jest.fn() const removeTagFromMultipleUsersStub = jest.fn()
wrapper.setMethods({ removeTagFromMultipleUsers: removeTagFromMultipleUsersStub }) wrapper.setMethods({ removeTagFromMultipleUsers: removeTagFromMultipleUsersStub })
wrapper.find(`.el-dropdown-menu__item:nth-child(9) button:nth-child(2)`).trigger('click') wrapper.find(`.el-dropdown-menu__item:nth-child(10) button:nth-child(2)`).trigger('click')
expect(wrapper.vm.removeTagFromMultipleUsers).toHaveBeenCalled() expect(wrapper.vm.removeTagFromMultipleUsers).toHaveBeenCalled()
expect(wrapper.vm.removeTagFromMultipleUsers).toHaveBeenCalledWith('strip_media') expect(wrapper.vm.removeTagFromMultipleUsers).toHaveBeenCalledWith('strip_media')
wrapper.find(`.el-dropdown-menu__item:nth-child(11) button:nth-child(2)`).trigger('click') wrapper.find(`.el-dropdown-menu__item:nth-child(12) button:nth-child(2)`).trigger('click')
expect(wrapper.vm.removeTagFromMultipleUsers).toHaveBeenCalled() expect(wrapper.vm.removeTagFromMultipleUsers).toHaveBeenCalled()
expect(wrapper.vm.removeTagFromMultipleUsers).toHaveBeenCalledWith('sandbox') expect(wrapper.vm.removeTagFromMultipleUsers).toHaveBeenCalledWith('sandbox')
wrapper.find(`.el-dropdown-menu__item:nth-child(13) button:nth-child(2)`).trigger('click') wrapper.find(`.el-dropdown-menu__item:nth-child(14) button:nth-child(2)`).trigger('click')
expect(wrapper.vm.removeTagFromMultipleUsers).toHaveBeenCalled() expect(wrapper.vm.removeTagFromMultipleUsers).toHaveBeenCalled()
expect(wrapper.vm.removeTagFromMultipleUsers).toHaveBeenCalledWith('disable_any_subscription') expect(wrapper.vm.removeTagFromMultipleUsers).toHaveBeenCalledWith('disable_any_subscription')