diff --git a/src/api/users.js b/src/api/users.js
index fb168d6c..3755ee7c 100644
--- a/src/api/users.js
+++ b/src/api/users.js
@@ -136,4 +136,24 @@ export async function fetchUserStatuses(id, authHost, godmode, token) {
})
}
+export async function confirmUserEmail(nicknames, authHost, token) {
+ return await request({
+ baseURL: baseName(authHost),
+ url: '/api/pleroma/admin/users/confirm_email',
+ method: 'patch',
+ headers: authHeaders(token),
+ data: { nicknames }
+ })
+}
+
+export async function resendConfirmationEmail(nicknames, authHost, token) {
+ return await request({
+ baseURL: baseName(authHost),
+ url: '/api/pleroma/admin/users/resend_confirmation_email',
+ method: 'patch',
+ headers: authHeaders(token),
+ data: { nicknames }
+ })
+}
+
const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}
diff --git a/src/lang/en.js b/src/lang/en.js
index 29ba5eb3..dd3326e5 100644
--- a/src/lang/en.js
+++ b/src/lang/en.js
@@ -175,6 +175,7 @@ export default {
external: 'external',
deactivated: 'deactivated',
active: 'active',
+ unconfirmed: 'unconfirmed',
actions: 'Actions',
activate: 'Activate',
deactivate: 'Deactivate',
@@ -213,6 +214,8 @@ export default {
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?',
requirePasswordResetConfirmation: 'Are you sure you want to require password reset for all selected users?',
+ confirmAccountsConfirmation: 'Are you sure you want to confirm emails for all selected users?',
+ resendEmailConfirmation: 'Are you sure you want to resend confirmation email for all selected users?',
mailerMustBeEnabled: 'To require user\'s password reset you must enable mailer.',
ok: 'Okay',
completed: 'Completed',
@@ -230,7 +233,11 @@ export default {
invalidNicknameError: 'Username can include "a-z", "A-Z" and "0-9" characters',
getPasswordResetToken: 'Get password reset token',
passwordResetTokenCreated: 'Password reset token was created',
- accountCreated: 'New account was created!'
+ accountCreated: 'New account was created!',
+ unconfirmedEmail: 'User didn\'t confirm the email',
+ confirmAccount: 'Confirm account',
+ confirmAccounts: 'Confirm accounts',
+ resendConfirmation: 'Resend confirmation email'
},
statuses: {
statuses: 'Statuses',
diff --git a/src/store/modules/users.js b/src/store/modules/users.js
index 0290b888..160b4ff2 100644
--- a/src/store/modules/users.js
+++ b/src/store/modules/users.js
@@ -12,7 +12,9 @@ import {
searchUsers,
tagUser,
untagUser,
- requirePasswordReset
+ requirePasswordReset,
+ confirmUserEmail,
+ resendConfirmationEmail
} from '@/api/users'
const users = {
@@ -151,6 +153,31 @@ const users = {
}
dispatch('SuccessMessage')
},
+ async ConfirmUsersEmail({ commit, dispatch, getters, state }, users) {
+ const updatedUsers = users.map(user => {
+ return { ...user, confirmation_pending: false }
+ })
+ commit('SWAP_USERS', updatedUsers)
+
+ const usersNicknames = users.map(user => user.nickname)
+ try {
+ await confirmUserEmail(usersNicknames, getters.authHost, getters.token)
+ } catch (_e) {
+ return
+ } finally {
+ dispatch('SearchUsers', { query: state.searchQuery, page: state.currentPage })
+ }
+ dispatch('SuccessMessage')
+ },
+ async ResendConfirmationEmail({ dispatch, getters }, users) {
+ const usersNicknames = users.map(user => user.nickname)
+ try {
+ await resendConfirmationEmail(usersNicknames, getters.authHost, getters.token)
+ } catch (_e) {
+ return
+ }
+ dispatch('SuccessMessage')
+ },
async DeleteRight({ commit, dispatch, getters, state }, { users, right }) {
const updatedUsers = users.map(user => {
return user.local ? { ...user, roles: { ...user.roles, [right]: false }} : user
diff --git a/src/views/users/components/MultipleUsersMenu.vue b/src/views/users/components/MultipleUsersMenu.vue
index f3be52cf..1fdc029b 100644
--- a/src/views/users/components/MultipleUsersMenu.vue
+++ b/src/views/users/components/MultipleUsersMenu.vue
@@ -26,6 +26,15 @@
@click.native="revokeRightFromMultipleUsers('moderator')">
{{ $t('users.revokeModerator') }}
+
+ {{ $t('users.confirmAccounts') }}
+
+
+ {{ $t('users.resendConfirmation') }}
+
@@ -209,6 +218,18 @@ export default {
const filtered = this.selectedUsers.filter(user => user.local)
filtered.map(user => this.$store.dispatch('RequirePasswordReset', user))
this.$emit('apply-action')
+ },
+ confirmAccounts: () => {
+ const filtered = this.selectedUsers.filter(user => user.local && user.confirmation_pending)
+ const confirmAccountFn = async(users) => await this.$store.dispatch('ConfirmUsersEmail', users)
+
+ applyAction(filtered, confirmAccountFn)
+ },
+ resendConfirmation: () => {
+ const filtered = this.selectedUsers.filter(user => user.local && user.confirmation_pending)
+ const resendConfirmationFn = async(users) => await this.$store.dispatch('ResendConfirmationEmail', users)
+
+ applyAction(filtered, resendConfirmationFn)
}
}
},
@@ -276,6 +297,20 @@ export default {
removeTag(tag)
)
},
+ confirmAccountsForMultipleUsers() {
+ const { confirmAccounts } = this.mappers()
+ this.confirmMessage(
+ this.$t('users.confirmAccountsConfirmation'),
+ confirmAccounts
+ )
+ },
+ resendConfirmationForMultipleUsers() {
+ const { resendConfirmation } = this.mappers()
+ this.confirmMessage(
+ this.$t('users.resendEmailConfirmation'),
+ resendConfirmation
+ )
+ },
confirmMessage(message, applyAction) {
this.$confirm(message, {
confirmButtonText: this.$t('users.ok'),
diff --git a/src/views/users/index.vue b/src/views/users/index.vue
index f9b5e10f..93b6a7f1 100644
--- a/src/views/users/index.vue
+++ b/src/views/users/index.vue
@@ -57,6 +57,11 @@
{{ isDesktop ? $t('users.moderator') : getFirstLetter($t('users.moderator')) }}
+
+
+ {{ isDesktop ? $t('users.unconfirmed') : getFirstLetter($t('users.unconfirmed')) }}
+
+
@@ -88,6 +93,17 @@
@click.native="handleDeletion(scope.row)">
{{ $t('users.deleteAccount') }}
+
+ {{ $t('users.confirmAccount') }}
+
+
+ {{ $t('users.resendConfirmation') }}
+