funkwhale/front/src/components/auth/Settings.vue

997 wiersze
32 KiB
Vue
Czysty Zwykły widok Historia

<template>
2021-11-26 11:01:58 +00:00
<main
v-title="labels.title"
class="main pusher"
>
<div class="ui vertical stripe segment">
<section class="ui text container">
2018-06-30 13:28:47 +00:00
<h2 class="ui header">
2021-11-26 11:01:58 +00:00
<translate translate-context="Content/Settings/Title">
Account settings
</translate>
2018-06-30 13:28:47 +00:00
</h2>
2021-11-26 11:01:58 +00:00
<form
class="ui form"
@submit.prevent="submitSettings()"
>
<div
v-if="settings.success"
class="ui positive message"
>
<h4 class="header">
2021-11-26 11:01:58 +00:00
<translate translate-context="Content/Settings/Message">
Settings updated
</translate>
</h4>
</div>
2021-11-26 11:01:58 +00:00
<div
v-if="settings.errors.length > 0"
role="alert"
class="ui negative message"
>
<h4 class="header">
<translate translate-context="Content/Settings/Error message.Title">
Your settings can't be updated
</translate>
</h4>
<ul class="list">
2021-11-26 11:01:58 +00:00
<li
v-for="(error, key) in settings.errors"
:key="key"
>
{{ error }}
</li>
</ul>
</div>
2021-11-26 11:01:58 +00:00
<div
v-for="f in orderedSettingsFields"
:key="f.id"
class="field"
>
2020-08-01 09:11:51 +00:00
<label :for="f.id">{{ sharedLabels.fields[f.id].label }}</label>
2021-11-26 11:01:58 +00:00
<p v-if="f.help">
{{ sharedLabels.fields[f.id].help }}
</p>
<select
v-if="f.type === 'dropdown'"
:id="f.id"
v-model="f.value"
class="ui dropdown"
>
<option
v-for="(c, key) in f.choices"
:key="key"
:value="c"
>
{{ sharedLabels.fields[f.id].choices[c] }}
</option>
</select>
2021-11-26 11:01:58 +00:00
<content-form
v-if="f.type === 'content'"
v-model="f.value.text"
:field-id="f.id"
/>
</div>
2021-11-26 11:01:58 +00:00
<button
:class="['ui', {'loading': isLoading}, 'button']"
type="submit"
>
<translate translate-context="Content/Settings/Button.Label/Verb">
Update settings
</translate>
2018-06-30 13:28:47 +00:00
</button>
</form>
</section>
<section class="ui text container">
2021-11-26 11:01:58 +00:00
<div class="ui hidden divider" />
2018-07-13 12:10:39 +00:00
<h2 class="ui header">
2021-11-26 11:01:58 +00:00
<translate translate-context="Content/Settings/Title">
Avatar
</translate>
2018-07-13 12:10:39 +00:00
</h2>
<div class="ui form">
2021-11-26 11:01:58 +00:00
<div
v-if="avatarErrors.length > 0"
role="alert"
class="ui negative message"
>
<h4 class="header">
<translate translate-context="Content/Settings/Error message.Title">
Your avatar cannot be saved
</translate>
</h4>
2018-07-13 12:10:39 +00:00
<ul class="list">
2021-11-26 11:01:58 +00:00
<li
v-for="(error, key) in avatarErrors"
:key="key"
>
{{ error }}
</li>
2018-07-13 12:10:39 +00:00
</ul>
</div>
2020-01-23 15:38:04 +00:00
<attachment-input
v-model="avatar.uuid"
2020-01-23 15:38:04 +00:00
:initial-value="initialAvatar"
@update:model-value="submitAvatar($event)"
2021-11-26 11:01:58 +00:00
@delete="avatar = {uuid: null}"
>
2022-05-01 14:15:57 +00:00
<translate translate-context="Content/Channel/*">
2021-11-26 11:01:58 +00:00
Avatar
</translate>
</attachment-input>
2018-07-13 12:10:39 +00:00
</div>
</section>
2019-02-14 09:49:06 +00:00
<section class="ui text container">
2021-11-26 11:01:58 +00:00
<div class="ui hidden divider" />
2018-06-30 13:28:47 +00:00
<h2 class="ui header">
2021-11-26 11:01:58 +00:00
<translate translate-context="Content/Settings/Title/Verb">
Change my password
</translate>
2018-06-30 13:28:47 +00:00
</h2>
<div class="ui message">
2021-11-26 11:01:58 +00:00
<translate translate-context="Content/Settings/Paragraph'">
Changing your password will also change your Subsonic API password if you have requested one.
</translate>&nbsp;<translate translate-context="Content/Settings/Paragraph">
You will have to update your password on your clients that use this password.
</translate>
</div>
2021-11-26 11:01:58 +00:00
<form
class="ui form"
@submit.prevent="submitPassword()"
>
<div
v-if="passwordError"
role="alert"
class="ui negative message"
>
<h4 class="header">
2021-11-26 11:01:58 +00:00
<translate translate-context="Content/Settings/Error message.Title">
Your password cannot be changed
</translate>
</h4>
<ul class="list">
2021-11-26 11:01:58 +00:00
<li v-if="passwordError == 'invalid_credentials'">
<translate translate-context="Content/Settings/Error message.List item/Call to action">
Please double-check your password is correct
</translate>
</li>
</ul>
</div>
<div class="field">
<label for="old-password-field"><translate translate-context="Content/Settings/Input.Label">Current password</translate></label>
2021-11-26 11:01:58 +00:00
<password-input
v-model="old_password"
field-id="old-password-field"
required
/>
</div>
<div class="field">
2020-08-01 09:11:51 +00:00
<label for="new-password-field"><translate translate-context="Content/Settings/Input.Label">New password</translate></label>
2021-11-26 11:01:58 +00:00
<password-input
v-model="new_password"
field-id="new-password-field"
required
/>
</div>
<dangerous-button
:class="['ui', {'loading': isLoading}, {disabled: !new_password || !old_password}, 'warning', 'button']"
2021-11-26 11:01:58 +00:00
:action="submitPassword"
>
<translate translate-context="Content/Settings/Button.Label">
Change password
</translate>
2022-05-01 14:15:57 +00:00
<template #modal-header>
2021-11-26 11:01:58 +00:00
<p>
2022-05-01 14:15:57 +00:00
<translate translate-context="Popup/Settings/Title">
Change your password?
2021-11-26 11:01:58 +00:00
</translate>
</p>
2022-05-01 14:15:57 +00:00
</template>
<template #modal-content>
<div>
<p>
<translate translate-context="Popup/Settings/Paragraph">
Changing your password will have the following consequences:
2021-11-26 11:01:58 +00:00
</translate>
2022-05-01 14:15:57 +00:00
</p>
<ul>
<li>
<translate translate-context="Popup/Settings/List item">
You will be logged out from this session and have to log in with the new one
</translate>
</li>
<li>
<translate translate-context="Popup/Settings/List item">
Your Subsonic password will be changed to a new, random one, logging you out from devices that used the old Subsonic password
</translate>
</li>
</ul>
</div>
</template>
<template #modal-confirm>
<div>
<translate translate-context="Popup/Settings/Button.Label">
Disable access
</translate>
</div>
</template>
</dangerous-button>
</form>
<div class="ui hidden divider" />
<subsonic-token-form />
</section>
2019-02-14 09:49:06 +00:00
2021-11-26 11:01:58 +00:00
<section
id="content-filters"
class="ui text container"
>
<div class="ui hidden divider" />
2019-02-14 09:49:06 +00:00
<h2 class="ui header">
2021-11-26 11:01:58 +00:00
<i class="eye slash outline icon" />
2019-02-14 09:49:06 +00:00
<div class="content">
2021-11-26 11:01:58 +00:00
<translate translate-context="Content/Settings/Title/Noun">
Content filters
</translate>
2019-02-14 09:49:06 +00:00
</div>
</h2>
2021-11-26 11:01:58 +00:00
<p>
<translate translate-context="Content/Settings/Paragraph">
Content filters help you hide content you don't want to see on the service.
</translate>
</p>
2019-02-14 09:49:06 +00:00
<button
2021-11-26 11:01:58 +00:00
class="ui icon button"
2019-02-14 09:49:06 +00:00
@click="$store.dispatch('moderation/fetchContentFilters')"
2021-11-26 11:01:58 +00:00
>
<i class="refresh icon" />&nbsp;
<translate translate-context="Content/*/Button.Label/Short, Verb">
Refresh
</translate>
2019-02-14 09:49:06 +00:00
</button>
<h3 class="ui header">
2021-11-26 11:01:58 +00:00
<translate translate-context="Content/Settings/Title">
Hidden artists
</translate>
2019-02-14 09:49:06 +00:00
</h3>
<table class="ui compact very basic unstackable table">
2019-02-14 09:49:06 +00:00
<thead>
<tr>
2021-11-26 11:01:58 +00:00
<th>
<translate translate-context="*/*/*/Noun">
Name
</translate>
</th>
<th>
<translate translate-context="Content/*/*/Noun">
Creation date
</translate>
</th>
<th />
2019-02-14 09:49:06 +00:00
</tr>
</thead>
<tbody>
2021-11-26 11:01:58 +00:00
<tr
v-for="filter in $store.getters['moderation/artistFilters']()"
:key="filter.uuid"
>
2019-02-14 09:49:06 +00:00
<td>
<router-link :to="{name: 'library.artists.detail', params: {id: filter.target.id }}">
{{ filter.target.name }}
</router-link>
</td>
<td>
2021-11-26 11:01:58 +00:00
<human-date :date="filter.creation_date" />
2019-02-14 09:49:06 +00:00
</td>
<td>
2021-11-26 11:01:58 +00:00
<button
class="ui basic tiny button"
@click="$store.dispatch('moderation/deleteContentFilter', filter.uuid)"
>
<translate translate-context="*/*/*/Verb">
Delete
</translate>
2019-02-14 09:49:06 +00:00
</button>
</td>
</tr>
</tbody>
</table>
</section>
2021-11-26 11:01:58 +00:00
<section
id="grants"
class="ui text container"
>
<div class="ui hidden divider" />
<h2 class="ui header">
2021-11-26 11:01:58 +00:00
<i class="open lock icon" />
<div class="content">
2021-11-26 11:01:58 +00:00
<translate translate-context="Content/Settings/Title/Noun">
Authorized apps
</translate>
</div>
</h2>
2021-11-26 11:01:58 +00:00
<p>
<translate translate-context="Content/Settings/Paragraph">
This is the list of applications that have access to your account data.
</translate>
</p>
<button
2021-11-26 11:01:58 +00:00
class="ui icon button"
@click="fetchApps()"
2021-11-26 11:01:58 +00:00
>
<i class="refresh icon" />&nbsp;
<translate translate-context="Content/*/Button.Label/Short, Verb">
Refresh
</translate>
</button>
2021-11-26 11:01:58 +00:00
<table
v-if="apps.length > 0"
class="ui compact very basic unstackable table"
>
<thead>
<tr>
2021-11-26 11:01:58 +00:00
<th>
<translate translate-context="*/*/*/Noun">
Application
</translate>
</th>
<th>
<translate translate-context="Content/*/*/Noun">
Permissions
</translate>
</th>
<th />
</tr>
</thead>
<tbody>
2021-11-26 11:01:58 +00:00
<tr
v-for="app in apps"
:key="app.client_id"
>
<td>
{{ app.name }}
</td>
<td>
{{ app.scopes }}
</td>
<td>
<dangerous-button
2020-08-01 09:11:51 +00:00
class="ui tiny danger button"
2021-11-26 11:01:58 +00:00
@confirm="revokeApp(app.client_id)"
>
<translate translate-context="*/*/*/Verb">
Revoke
</translate>
2022-05-01 14:15:57 +00:00
<template #modal-header>
<p
v-translate="{application: app.name}"
translate-context="Popup/Settings/Title"
>
Revoke access for application "%{ application }"?
</p>
</template>
<template #modal-content>
<p>
<translate translate-context="Popup/Settings/Paragraph">
This will prevent this application from accessing the service on your behalf.
</translate>
</p>
</template>
<template #modal-confirm>
<div>
<translate translate-context="*/Settings/Button.Label/Verb">
Revoke access
</translate>
</div>
</template>
</dangerous-button>
</td>
</tr>
</tbody>
</table>
<empty-state v-else>
2022-05-01 14:15:57 +00:00
<template #title>
<translate translate-context="Content/Applications/Paragraph">
You don't have any application connected with your account.
</translate>
</template>
<translate translate-context="Content/Applications/Paragraph">
If you authorize third-party applications to access your data, those applications will be listed here.
</translate>
</empty-state>
</section>
2021-11-26 11:01:58 +00:00
<section
id="apps"
class="ui text container"
>
<div class="ui hidden divider" />
<h2 class="ui header">
2021-11-26 11:01:58 +00:00
<i class="code icon" />
<div class="content">
2021-11-26 11:01:58 +00:00
<translate translate-context="Content/Settings/Title/Noun">
Your applications
</translate>
</div>
</h2>
2021-11-26 11:01:58 +00:00
<p>
<translate translate-context="Content/Settings/Paragraph">
This is the list of applications that you have registered.
</translate>
</p>
<router-link
class="ui success button"
:to="{name: 'settings.applications.new'}"
>
<translate translate-context="Content/Settings/Button.Label">
Register a new application
</translate>
</router-link>
2021-11-26 11:01:58 +00:00
<table
v-if="ownedApps.length > 0"
class="ui compact very basic unstackable table"
>
<thead>
<tr>
2021-11-26 11:01:58 +00:00
<th>
<translate translate-context="*/*/*/Noun">
Application
</translate>
</th>
<th>
<translate translate-context="Content/*/*/Noun">
Scopes
</translate>
</th>
<th>
<translate translate-context="Content/*/*/Noun">
Creation date
</translate>
</th>
<th />
</tr>
</thead>
<tbody>
2021-11-26 11:01:58 +00:00
<tr
v-for="app in ownedApps"
:key="app.client_id"
>
<td>
<router-link :to="{name: 'settings.applications.edit', params: {id: app.client_id}}">
{{ app.name }}
</router-link>
</td>
<td>
{{ app.scopes }}
</td>
<td>
<human-date :date="app.created" />
</td>
<td>
2021-11-26 11:01:58 +00:00
<router-link
class="ui tiny success button"
:to="{name: 'settings.applications.edit', params: {id: app.client_id}}"
>
<translate translate-context="Content/*/Button.Label/Verb">
Edit
</translate>
</router-link>
<dangerous-button
2020-08-01 09:11:51 +00:00
class="ui tiny danger button"
2021-11-26 11:01:58 +00:00
@confirm="deleteApp(app.client_id)"
>
<translate translate-context="*/*/*/Verb">
Remove
</translate>
2022-05-01 14:15:57 +00:00
<template #modal-header>
<p
v-translate="{application: app.name}"
translate-context="Popup/Settings/Title"
>
Remove application "%{ application }"?
</p>
</template>
<template #modal-content>
<p>
<translate translate-context="Popup/Settings/Paragraph">
This will permanently remove the application and all the associated tokens.
</translate>
</p>
</template>
<template #modal-confirm>
<div>
<translate translate-context="*/Settings/Button.Label/Verb">
Remove application
</translate>
</div>
</template>
</dangerous-button>
</td>
</tr>
</tbody>
</table>
<empty-state v-else>
2022-05-01 14:15:57 +00:00
<template #title>
<translate translate-context="Content/Applications/Paragraph">
You don't have registered any application yet.
</translate>
</template>
<translate translate-context="Content/Applications/Paragraph">
Register one to integrate Funkwhale with third-party applications.
</translate>
</empty-state>
</section>
2020-07-03 08:59:12 +00:00
2021-11-26 11:01:58 +00:00
<section
id="plugins"
class="ui text container"
>
<div class="ui hidden divider" />
2020-07-03 08:59:12 +00:00
<h2 class="ui header">
2021-11-26 11:01:58 +00:00
<i class="code icon" />
2020-07-03 08:59:12 +00:00
<div class="content">
2021-11-26 11:01:58 +00:00
<translate translate-context="Content/Settings/Title/Noun">
Plugins
</translate>
2020-07-03 08:59:12 +00:00
</div>
</h2>
2021-11-26 11:01:58 +00:00
<p>
<translate translate-context="Content/Settings/Paragraph">
Use plugins to extend Funkwhale and get additional features.
</translate>
</p>
<router-link
class="ui success button"
:to="{name: 'settings.plugins'}"
>
<translate translate-context="Content/Settings/Button.Label">
Manage plugins
</translate>
2020-07-03 08:59:12 +00:00
</router-link>
</section>
<section class="ui text container">
2021-11-26 11:01:58 +00:00
<div class="ui hidden divider" />
<h2 class="ui header">
2021-11-26 11:01:58 +00:00
<i class="comment icon" />
<div class="content">
2021-11-26 11:01:58 +00:00
<translate translate-context="*/*/Button.Label">
Change my e-mail address
</translate>
</div>
</h2>
<p>
2021-11-26 11:01:58 +00:00
<translate translate-context="Content/Settings/Paragraph'">
Change the e-mail address associated with your account. We will send a confirmation to the new address.
</translate>
</p>
<p>
2021-11-26 11:01:58 +00:00
<translate
:translate-params="{email: $store.state.auth.profile.email}"
translate-context="Content/Settings/Paragraph'"
>
Your current e-mail address is %{ email }.
</translate>
</p>
2021-11-26 11:01:58 +00:00
<form
class="ui form"
@submit.prevent="changeEmail"
>
<div
v-if="changeEmailErrors.length > 0"
role="alert"
class="ui negative message"
>
<h4 class="header">
<translate translate-context="Content/Settings/Error message.Title">
We cannot change your e-mail address
</translate>
</h4>
<ul class="list">
2021-11-26 11:01:58 +00:00
<li
v-for="(error, key) in changeEmailErrors"
:key="key"
>
{{ error }}
</li>
</ul>
</div>
<div class="field">
<label for="new-email"><translate translate-context="*/*/*">New e-mail address</translate></label>
2021-11-26 11:01:58 +00:00
<input
id="new-email"
v-model="newEmail"
required
type="email"
>
</div>
<div class="field">
<label for="current-password-field-email"><translate translate-context="*/*/*">Password</translate></label>
2021-11-26 11:01:58 +00:00
<password-input
v-model="emailPassword"
field-id="current-password-field-email"
required
/>
</div>
2021-11-26 11:01:58 +00:00
<button
type="submit"
class="ui button"
>
<translate translate-context="*/*/*">
Update
</translate>
</button>
</form>
</section>
<section class="ui text container">
2021-11-26 11:01:58 +00:00
<div class="ui hidden divider" />
<h2 class="ui header">
2021-11-26 11:01:58 +00:00
<i class="trash icon" />
<div class="content">
2021-11-26 11:01:58 +00:00
<translate translate-context="*/*/Button.Label">
Delete my account
</translate>
</div>
</h2>
<p>
2021-11-26 11:01:58 +00:00
<translate translate-context="Content/Settings/Paragraph'">
You can permanently and irreversibly delete your account and all the associated data using the form below. You will be asked for confirmation.
</translate>
</p>
2021-11-26 11:01:58 +00:00
<div
role="alert"
class="ui warning message"
>
<translate translate-context="Content/Settings/Paragraph'">
Your account will be deleted from our servers within a few minutes. We will also notify other servers who may have a copy of some of your data so they can proceed to deletion. Please note that some of these servers may be offline or unwilling to comply though.
</translate>
</div>
2020-05-07 16:16:30 +00:00
<div class="ui form">
2021-11-26 11:01:58 +00:00
<div
v-if="accountDeleteErrors.length > 0"
role="alert"
class="ui negative message"
>
<h4 class="header">
<translate translate-context="Content/Settings/Error message.Title">
We cannot delete your account
</translate>
</h4>
<ul class="list">
2021-11-26 11:01:58 +00:00
<li
v-for="(error, key) in accountDeleteErrors"
:key="key"
>
{{ error }}
</li>
</ul>
</div>
<div class="field">
2020-08-01 09:11:51 +00:00
<label for="current-password-field"><translate translate-context="*/*/*">Password</translate></label>
2021-11-26 11:01:58 +00:00
<password-input
v-model="password"
field-id="current-password-field"
required
/>
</div>
<dangerous-button
:class="['ui', {'loading': isDeletingAccount}, {disabled: !password}, {danger: password}, 'button']"
2021-11-26 11:01:58 +00:00
:action="deleteAccount"
>
<translate translate-context="*/*/Button.Label">
Delete my account
</translate>
2022-05-01 14:15:57 +00:00
<template #modal-header>
2021-11-26 11:01:58 +00:00
<p>
2022-05-01 14:15:57 +00:00
<translate translate-context="Popup/Settings/Title">
Do you want to delete your account?
2021-11-26 11:01:58 +00:00
</translate>
</p>
2022-05-01 14:15:57 +00:00
</template>
<template #modal-content>
<div>
<p>
<translate translate-context="Popup/Settings/Paragraph">
This is irreversible and will permanently remove your data from our servers. You will we immediatly logged out.
</translate>
</p>
</div>
</template>
<template #modal-confirm>
<div>
<translate translate-context="*/*/Button.Label">
Delete my account
</translate>
</div>
</template>
</dangerous-button>
</div>
</section>
</div>
</main>
</template>
<script>
2021-11-26 11:01:58 +00:00
import $ from 'jquery'
import axios from 'axios'
2022-04-23 07:37:43 +00:00
import PasswordInput from '~/components/forms/PasswordInput.vue'
import SubsonicTokenForm from '~/components/auth/SubsonicTokenForm.vue'
import AttachmentInput from '~/components/common/AttachmentInput.vue'
import useLogger from '~/composables/useLogger'
2022-05-02 15:06:44 +00:00
import useSharedLabels from '~/composables/locale/useSharedLabels'
const logger = useLogger()
export default {
components: {
PasswordInput,
2020-01-23 15:38:04 +00:00
SubsonicTokenForm,
AttachmentInput
},
setup () {
const sharedLabels = useSharedLabels()
return { sharedLabels }
},
2021-11-26 11:01:58 +00:00
data () {
const d = {
// We need to initialize the component with any
// properties that will be used in it
2021-11-26 11:01:58 +00:00
old_password: '',
new_password: '',
avatar: { ...(this.$store.state.auth.profile?.avatar ?? { uuid: null }) },
2021-11-26 11:01:58 +00:00
passwordError: '',
password: '',
isLoading: false,
2018-07-13 12:10:39 +00:00
isLoadingAvatar: false,
isDeletingAccount: false,
changeEmailErrors: [],
isChangingEmail: false,
newEmail: null,
emailPassword: null,
accountDeleteErrors: [],
2018-07-13 12:10:39 +00:00
avatarErrors: [],
apps: [],
ownedApps: [],
settings: {
success: false,
errors: [],
2021-11-26 11:01:58 +00:00
order: ['summary', 'privacy_level'],
fields: {
2020-02-05 14:06:07 +00:00
summary: {
2021-11-26 11:01:58 +00:00
type: 'content',
initial: this.$store.state.auth.profile.summary || { text: '', content_type: 'text/markdown' }
2020-02-05 14:06:07 +00:00
},
privacy_level: {
2021-11-26 11:01:58 +00:00
type: 'dropdown',
initial: this.$store.state.auth.profile.privacy_level,
2021-11-26 11:01:58 +00:00
choices: ['me', 'instance', 'everyone']
}
}
}
}
2020-01-23 15:38:04 +00:00
d.initialAvatar = d.avatar.uuid
d.settings.order.forEach(id => {
d.settings.fields[id].value = d.settings.fields[id].initial
d.settings.fields[id].id = id
})
return d
},
2021-11-26 11:01:58 +00:00
computed: {
labels () {
return {
title: this.$pgettext('Head/Settings/Title', 'Account Settings')
}
},
orderedSettingsFields () {
const self = this
return this.settings.order.map(id => {
return self.settings.fields[id]
})
},
settingsValues () {
const self = this
const s = {}
this.settings.order.forEach(setting => {
const conf = self.settings.fields[setting]
s[setting] = conf.value
if (setting === 'summary' && !conf.value.text) {
s[setting] = null
}
})
return s
}
},
created () {
this.fetchApps()
this.fetchOwnedApps()
},
2021-11-26 11:01:58 +00:00
mounted () {
$('select.dropdown').dropdown()
},
methods: {
2021-11-26 11:01:58 +00:00
submitSettings () {
this.settings.success = false
this.settings.errors = []
2021-11-26 11:01:58 +00:00
const self = this
const payload = this.settingsValues
const url = `users/${this.$store.state.auth.username}/`
return axios.patch(url, payload).then(
response => {
logger.info('Updated settings successfully')
self.settings.success = true
2021-11-26 11:01:58 +00:00
return axios.get('users/me/').then(response => {
self.$store.dispatch('auth/updateProfile', response.data)
})
},
error => {
logger.error('Error while updating settings')
self.isLoading = false
self.settings.errors = error.backendErrors
}
)
},
2021-11-26 11:01:58 +00:00
fetchApps () {
this.apps = []
2021-11-26 11:01:58 +00:00
const self = this
const url = 'oauth/grants/'
return axios.get(url).then(
response => {
self.apps = response.data
},
error => {
logger.error('Error while fetching Apps')
2021-11-26 11:01:58 +00:00
self.isLoading = false
self.settings.errors = error.backendErrors
}
)
},
2021-11-26 11:01:58 +00:00
fetchOwnedApps () {
this.ownedApps = []
2021-11-26 11:01:58 +00:00
const self = this
const url = 'oauth/apps/'
return axios.get(url).then(
response => {
self.ownedApps = response.data.results
},
error => {
logger.error('Error while fetching owned Apps')
2021-11-26 11:01:58 +00:00
self.isLoading = false
self.settings.errors = error.backendErrors
}
)
},
revokeApp (id) {
2021-11-26 11:01:58 +00:00
const self = this
const url = `oauth/grants/${id}/`
return axios.delete(url).then(
response => {
self.apps = self.apps.filter(a => {
2021-11-26 11:01:58 +00:00
return a.client_id !== id
})
},
error => {
logger.error('Error while revoking App')
2021-11-26 11:01:58 +00:00
self.isLoading = false
self.settings.errors = error.backendErrors
}
)
},
deleteApp (id) {
2021-11-26 11:01:58 +00:00
const self = this
const url = `oauth/apps/${id}/`
return axios.delete(url).then(
response => {
self.ownedApps = self.ownedApps.filter(a => {
2021-11-26 11:01:58 +00:00
return a.client_id !== id
})
},
error => {
logger.error('Error while deleting App')
2021-11-26 11:01:58 +00:00
self.isLoading = false
self.settings.errors = error.backendErrors
}
)
},
2021-11-26 11:01:58 +00:00
submitAvatar (uuid) {
2018-07-13 12:10:39 +00:00
this.isLoadingAvatar = true
this.avatarErrors = []
2021-11-26 11:01:58 +00:00
const self = this
axios
2021-11-26 11:01:58 +00:00
.patch(`users/${this.$store.state.auth.username}/`, { avatar: uuid })
.then(
response => {
this.isLoadingAvatar = false
2020-01-23 15:38:04 +00:00
self.avatar = response.data.avatar
2021-11-26 11:01:58 +00:00
self.$store.commit('auth/avatar', response.data.avatar)
},
error => {
self.isLoadingAvatar = false
self.avatarErrors = error.backendErrors
}
)
2018-07-13 12:10:39 +00:00
},
2021-11-26 11:01:58 +00:00
submitPassword () {
const self = this
self.isLoading = true
2021-11-26 11:01:58 +00:00
this.error = ''
const credentials = {
old_password: this.old_password,
new_password1: this.new_password,
new_password2: this.new_password
}
2021-11-26 11:01:58 +00:00
const url = 'auth/registration/change-password/'
return axios.post(url, credentials).then(
response => {
logger.info('Password successfully changed')
self.$router.push({
2021-11-26 11:01:58 +00:00
name: 'profile.overview',
params: {
username: self.$store.state.auth.username
}
})
},
error => {
if (error.response.status === 400) {
2021-11-26 11:01:58 +00:00
self.passwordError = 'invalid_credentials'
} else {
2021-11-26 11:01:58 +00:00
self.passwordError = 'unknown_error'
}
self.isLoading = false
}
)
},
2021-11-26 11:01:58 +00:00
deleteAccount () {
this.isDeletingAccount = true
this.accountDeleteErrors = []
2021-11-26 11:01:58 +00:00
const self = this
const payload = {
confirm: true,
2021-11-26 11:01:58 +00:00
password: this.password
}
2021-11-26 11:01:58 +00:00
axios.delete('users/me/', { data: payload })
.then(
response => {
self.isDeletingAccount = false
2021-11-26 11:01:58 +00:00
const msg = self.$pgettext('*/Auth/Message', 'Your deletion request was submitted, your account and content will be deleted shortly')
self.$store.commit('ui/addMessage', {
content: msg,
date: new Date()
})
self.$store.dispatch('auth/logout')
},
error => {
self.isDeletingAccount = false
self.accountDeleteErrors = error.backendErrors
}
)
},
2021-11-26 11:01:58 +00:00
changeEmail () {
this.isChangingEmail = true
this.changeEmailErrors = []
2021-11-26 11:01:58 +00:00
const self = this
const payload = {
password: this.emailPassword,
2021-11-26 11:01:58 +00:00
email: this.newEmail
}
2021-11-26 11:01:58 +00:00
axios.post('users/users/change-email/', payload)
.then(
response => {
self.isChangingEmail = false
self.newEmail = null
self.emailPassword = null
2021-11-26 11:01:58 +00:00
const msg = self.$pgettext('*/Auth/Message', 'Your e-mail address has been changed, please check your inbox for our confirmation message.')
self.$store.commit('ui/addMessage', {
content: msg,
date: new Date()
})
},
error => {
self.isChangingEmail = false
self.changeEmailErrors = error.backendErrors
}
)
}
}
}
</script>