mirror of
https://akkoma.dev/AkkomaGang/akkoma-fe
synced 2025-04-30 19:19:29 +08:00
Add extended moderation options
This commit is contained in:
parent
86f0d09276
commit
c966e10ed4
8 changed files with 127 additions and 9 deletions
|
@ -69,7 +69,7 @@
|
||||||
padding: 1rem 1rem;
|
padding: 1rem 1rem;
|
||||||
background-color: $fallback--bg;
|
background-color: $fallback--bg;
|
||||||
background-color: var(--bg, $fallback--bg);
|
background-color: var(--bg, $fallback--bg);
|
||||||
white-space: normal;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-modal-footer {
|
.dialog-modal-footer {
|
||||||
|
|
|
@ -49,7 +49,6 @@ const UsersTab = {
|
||||||
users () { return this.$store.state.users.adminUsers },
|
users () { return this.$store.state.users.adminUsers },
|
||||||
isActive () {
|
isActive () {
|
||||||
const tabSwitcher = this.$parent
|
const tabSwitcher = this.$parent
|
||||||
console.log(this.users)
|
|
||||||
return tabSwitcher ? tabSwitcher.isActive('users') : false
|
return tabSwitcher ? tabSwitcher.isActive('users') : false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -151,10 +151,6 @@
|
||||||
:class="{ 'menu-checkbox-checked': all(actorType) }"
|
:class="{ 'menu-checkbox-checked': all(actorType) }"
|
||||||
/>{{ $t('moderation.users.filter.all') }}
|
/>{{ $t('moderation.users.filter.all') }}
|
||||||
</button>
|
</button>
|
||||||
<div
|
|
||||||
role="separator"
|
|
||||||
class="dropdown-divider"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Popover>
|
</Popover>
|
||||||
|
@ -170,7 +166,11 @@
|
||||||
class="user"
|
class="user"
|
||||||
>
|
>
|
||||||
<BasicUserCard :user="user" />
|
<BasicUserCard :user="user" />
|
||||||
<ModerationTools :user="user" class="user-moderation" />
|
<ModerationTools
|
||||||
|
:user="user"
|
||||||
|
class="user-moderation"
|
||||||
|
extended="true"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -16,7 +16,8 @@ const QUARANTINE = 'mrf_tag:quarantine'
|
||||||
|
|
||||||
const ModerationTools = {
|
const ModerationTools = {
|
||||||
props: [
|
props: [
|
||||||
'user'
|
'user',
|
||||||
|
'extended'
|
||||||
],
|
],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
@ -30,7 +31,10 @@ const ModerationTools = {
|
||||||
QUARANTINE
|
QUARANTINE
|
||||||
},
|
},
|
||||||
showDeleteUserDialog: false,
|
showDeleteUserDialog: false,
|
||||||
toggled: false
|
showPasswordTokenDialog: false,
|
||||||
|
toggled: false,
|
||||||
|
passwordResetToken: {},
|
||||||
|
bot: this.user.bot
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
@ -83,6 +87,9 @@ const ModerationTools = {
|
||||||
deleteUserDialog (show) {
|
deleteUserDialog (show) {
|
||||||
this.showDeleteUserDialog = show
|
this.showDeleteUserDialog = show
|
||||||
},
|
},
|
||||||
|
passwordTokenDialog (show) {
|
||||||
|
this.showPasswordTokenDialog = show
|
||||||
|
},
|
||||||
deleteUser () {
|
deleteUser () {
|
||||||
const store = this.$store
|
const store = this.$store
|
||||||
const user = this.user
|
const user = this.user
|
||||||
|
@ -97,6 +104,29 @@ const ModerationTools = {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
getPasswordResetToken () {
|
||||||
|
this.$store.state.api.backendInteractor.getPasswordResetToken({ nickname: this.user.screen_name })
|
||||||
|
.then(data => {
|
||||||
|
this.passwordResetToken = data
|
||||||
|
this.passwordTokenDialog(true)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
forcePasswordReset () {
|
||||||
|
this.$store.state.api.backendInteractor.forcePasswordReset({ nickname: this.user.screen_name })
|
||||||
|
},
|
||||||
|
forceDisableMFA () {
|
||||||
|
this.$store.state.api.backendInteractor.forceDisableMFA({ nickname: this.user.screen_name })
|
||||||
|
},
|
||||||
|
toggleBot () {
|
||||||
|
const params = { bot: !this.bot }
|
||||||
|
|
||||||
|
this.$store.state.api.backendInteractor
|
||||||
|
.updateProfile({ params })
|
||||||
|
.then((user) => {
|
||||||
|
this.$store.commit('addNewUsers', [user])
|
||||||
|
this.bot = !this.bot
|
||||||
|
})
|
||||||
|
},
|
||||||
setToggled (value) {
|
setToggled (value) {
|
||||||
this.toggled = value
|
this.toggled = value
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,6 +120,37 @@
|
||||||
{{ $t('user_card.admin_menu.quarantine') }}
|
{{ $t('user_card.admin_menu.quarantine') }}
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
|
<div
|
||||||
|
v-if="extended && user.is_local"
|
||||||
|
role="separator"
|
||||||
|
class="dropdown-divider"
|
||||||
|
/>
|
||||||
|
<span v-if="extended && user.is_local">
|
||||||
|
<button
|
||||||
|
class="button-default dropdown-item"
|
||||||
|
@click="getPasswordResetToken"
|
||||||
|
>
|
||||||
|
{{ $t('user_card.admin_menu.get_password_reset_token') }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="button-default dropdown-item"
|
||||||
|
@click="forcePasswordReset"
|
||||||
|
>
|
||||||
|
{{ $t('user_card.admin_menu.force_password_reset') }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="button-default dropdown-item"
|
||||||
|
@click="forceDisableMFA"
|
||||||
|
>
|
||||||
|
{{ $t('user_card.admin_menu.disable_mfa') }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="button-default dropdown-item"
|
||||||
|
@click="toggleBot"
|
||||||
|
>
|
||||||
|
{{ $t('user_card.admin_menu.convert_to', { type: !!bot ? 'Person' : 'Service' }) }}
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:trigger>
|
<template v-slot:trigger>
|
||||||
|
@ -156,6 +187,26 @@
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
</DialogModal>
|
</DialogModal>
|
||||||
|
<DialogModal
|
||||||
|
v-if="showPasswordTokenDialog"
|
||||||
|
:on-cancel="passwordTokenDialog.bind(this, false)"
|
||||||
|
>
|
||||||
|
<template v-slot:header>
|
||||||
|
{{ $t('user_card.admin_menu.password_reset_token') }}
|
||||||
|
</template>
|
||||||
|
<p>
|
||||||
|
{{ $t('user_card.admin_menu.password_reset_token_content', { token: passwordResetToken.token }) }}
|
||||||
|
<a :href="passwordResetToken.link">{{ passwordResetToken.link }}</a>
|
||||||
|
</p>
|
||||||
|
<template v-slot:footer>
|
||||||
|
<button
|
||||||
|
class="btn button-default"
|
||||||
|
@click="passwordTokenDialog(false)"
|
||||||
|
>
|
||||||
|
{{ $t('general.close') }}
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
</DialogModal>
|
||||||
</teleport>
|
</teleport>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1109,17 +1109,23 @@
|
||||||
"user_card": {
|
"user_card": {
|
||||||
"admin_menu": {
|
"admin_menu": {
|
||||||
"activate_account": "Activate account",
|
"activate_account": "Activate account",
|
||||||
|
"convert_to": "Convert to { type }",
|
||||||
"deactivate_account": "Deactivate account",
|
"deactivate_account": "Deactivate account",
|
||||||
"delete_account": "Delete account",
|
"delete_account": "Delete account",
|
||||||
"delete_user": "Delete user",
|
"delete_user": "Delete user",
|
||||||
"delete_user_data_and_deactivate_confirmation": "This will permanently delete the data from this account and deactivate it. Are you absolutely sure?",
|
"delete_user_data_and_deactivate_confirmation": "This will permanently delete the data from this account and deactivate it. Are you absolutely sure?",
|
||||||
"disable_any_subscription": "Disallow following user at all",
|
"disable_any_subscription": "Disallow following user at all",
|
||||||
|
"disable_mfa": "Disable multi-factor authentication",
|
||||||
"disable_remote_subscription": "Disallow following user from remote instances",
|
"disable_remote_subscription": "Disallow following user from remote instances",
|
||||||
"force_nsfw": "Mark all posts as NSFW",
|
"force_nsfw": "Mark all posts as NSFW",
|
||||||
|
"force_password_reset": "Require password reset on next login",
|
||||||
"force_unlisted": "Force posts to be unlisted",
|
"force_unlisted": "Force posts to be unlisted",
|
||||||
|
"get_password_reset_token": "Get password reset token",
|
||||||
"grant_admin": "Grant Admin",
|
"grant_admin": "Grant Admin",
|
||||||
"grant_moderator": "Grant Moderator",
|
"grant_moderator": "Grant Moderator",
|
||||||
"moderation": "Moderation",
|
"moderation": "Moderation",
|
||||||
|
"password_reset_token": "Password reset token",
|
||||||
|
"password_reset_token_content": "Password reset token has been generated: { token }\nYou can also use this link to reset the password: ",
|
||||||
"quarantine": "Disallow user posts from federating",
|
"quarantine": "Disallow user posts from federating",
|
||||||
"revoke_admin": "Revoke Admin",
|
"revoke_admin": "Revoke Admin",
|
||||||
"revoke_moderator": "Revoke Moderator",
|
"revoke_moderator": "Revoke Moderator",
|
||||||
|
|
|
@ -23,6 +23,9 @@ const NOTIFICATION_READ_URL = '/api/v1/pleroma/notifications/read'
|
||||||
const ADMIN_REPORTS_URL = '/api/v1/pleroma/admin/reports'
|
const ADMIN_REPORTS_URL = '/api/v1/pleroma/admin/reports'
|
||||||
const ADMIN_REPORT_NOTES_URL = id => `/api/v1/pleroma/admin/reports/${id}/notes`
|
const ADMIN_REPORT_NOTES_URL = id => `/api/v1/pleroma/admin/reports/${id}/notes`
|
||||||
const ADMIN_REPORT_NOTE_URL = (report, note) => `/api/v1/pleroma/admin/reports/${report}/notes/${note}`
|
const ADMIN_REPORT_NOTE_URL = (report, note) => `/api/v1/pleroma/admin/reports/${report}/notes/${note}`
|
||||||
|
const ADMIN_PASSWORD_RESET_TOKEN_URL = nickname => `/api/v1/pleroma/admin/users/${nickname}/password_reset`
|
||||||
|
const ADMIN_FORCE_PASSWORD_RESET_URL = '/api/v1/pleroma/admin/users/force_password_reset'
|
||||||
|
const ADMIN_DISABLE_MFA_URL = '/api/v1/pleroma/admin/users/disable_mfa'
|
||||||
|
|
||||||
const MFA_SETTINGS_URL = '/api/pleroma/accounts/mfa'
|
const MFA_SETTINGS_URL = '/api/pleroma/accounts/mfa'
|
||||||
const MFA_BACKUP_CODES_URL = '/api/pleroma/accounts/mfa/backup_codes'
|
const MFA_BACKUP_CODES_URL = '/api/pleroma/accounts/mfa/backup_codes'
|
||||||
|
@ -717,6 +720,31 @@ const deleteNoteFromReport = ({ report, note, credentials }) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getPasswordResetToken = ({ nickname, credentials }) => {
|
||||||
|
const url = ADMIN_PASSWORD_RESET_TOKEN_URL(nickname)
|
||||||
|
|
||||||
|
return fetch(url, { headers: authHeaders(credentials) })
|
||||||
|
.then(data => data.json())
|
||||||
|
}
|
||||||
|
|
||||||
|
const forcePasswordReset = ({ nickname, credentials }) => {
|
||||||
|
return promisedRequest({
|
||||||
|
url: ADMIN_FORCE_PASSWORD_RESET_URL,
|
||||||
|
method: 'PATCH',
|
||||||
|
payload: { nicknames: [nickname] },
|
||||||
|
credentials
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const forceDisableMFA = ({ nickname, credentials }) => {
|
||||||
|
return promisedRequest({
|
||||||
|
url: ADMIN_DISABLE_MFA_URL,
|
||||||
|
method: 'PUT',
|
||||||
|
payload: { nickname },
|
||||||
|
credentials
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const fetchTimeline = ({
|
const fetchTimeline = ({
|
||||||
timeline,
|
timeline,
|
||||||
credentials,
|
credentials,
|
||||||
|
@ -1793,6 +1821,9 @@ const apiService = {
|
||||||
deleteRight,
|
deleteRight,
|
||||||
activateUser,
|
activateUser,
|
||||||
deactivateUser,
|
deactivateUser,
|
||||||
|
getPasswordResetToken,
|
||||||
|
forcePasswordReset,
|
||||||
|
forceDisableMFA,
|
||||||
register,
|
register,
|
||||||
getCaptcha,
|
getCaptcha,
|
||||||
updateProfileImages,
|
updateProfileImages,
|
||||||
|
|
|
@ -143,6 +143,7 @@ export const parseUser = (data) => {
|
||||||
// TODO: handle is_local
|
// TODO: handle is_local
|
||||||
output.is_local = !output.screen_name.includes('@')
|
output.is_local = !output.screen_name.includes('@')
|
||||||
} else if (admin) {
|
} else if (admin) {
|
||||||
|
output.bot = data.actor_type === 'Service'
|
||||||
output.screen_name = data.nickname
|
output.screen_name = data.nickname
|
||||||
output.name = data.display_name
|
output.name = data.display_name
|
||||||
output.profile_image_url = data.avatar
|
output.profile_image_url = data.avatar
|
||||||
|
|
Loading…
Reference in a new issue