2017-12-26 14:56:04 +00:00
|
|
|
<template>
|
2021-11-26 11:01:58 +00:00
|
|
|
<main
|
|
|
|
v-title="labels.title"
|
|
|
|
class="main pusher"
|
|
|
|
>
|
2017-12-26 14:56:04 +00:00
|
|
|
<div class="ui vertical stripe segment">
|
2019-03-25 16:02:51 +00:00
|
|
|
<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"
|
|
|
|
>
|
2020-07-03 12:20:47 +00:00
|
|
|
<h4 class="header">
|
2021-11-26 11:01:58 +00:00
|
|
|
<translate translate-context="Content/Settings/Message">
|
|
|
|
Settings updated
|
|
|
|
</translate>
|
2020-07-03 12:20:47 +00:00
|
|
|
</h4>
|
2018-03-03 11:40:01 +00:00
|
|
|
</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>
|
2018-03-03 11:40:01 +00:00
|
|
|
<ul class="list">
|
2021-11-26 11:01:58 +00:00
|
|
|
<li
|
|
|
|
v-for="(error, key) in settings.errors"
|
|
|
|
:key="key"
|
|
|
|
>
|
|
|
|
{{ error }}
|
|
|
|
</li>
|
2018-03-03 11:40:01 +00:00
|
|
|
</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>
|
2018-03-03 11:40:01 +00:00
|
|
|
</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"
|
|
|
|
/>
|
2018-03-03 11:40:01 +00:00
|
|
|
</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>
|
2018-03-03 11:40:01 +00:00
|
|
|
</form>
|
2018-11-19 22:33:22 +00:00
|
|
|
</section>
|
2019-03-25 16:02:51 +00:00
|
|
|
<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
|
2022-05-02 07:36:01 +00:00
|
|
|
v-model="avatar.uuid"
|
2020-01-23 15:38:04 +00:00
|
|
|
:initial-value="initialAvatar"
|
2022-05-02 07:36:01 +00:00
|
|
|
@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>
|
2018-11-19 22:33:22 +00:00
|
|
|
</section>
|
2019-02-14 09:49:06 +00:00
|
|
|
|
2019-03-25 16:02:51 +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>
|
2018-05-09 20:18:33 +00:00
|
|
|
<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> <translate translate-context="Content/Settings/Paragraph">
|
|
|
|
You will have to update your password on your clients that use this password.
|
|
|
|
</translate>
|
2018-05-09 20:18:33 +00:00
|
|
|
</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"
|
|
|
|
>
|
2020-07-03 12:20:47 +00:00
|
|
|
<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>
|
2020-07-03 12:20:47 +00:00
|
|
|
</h4>
|
2017-12-26 14:56:04 +00:00
|
|
|
<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>
|
2017-12-26 14:56:04 +00:00
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
<div class="field">
|
2021-06-17 15:55:12 +00:00
|
|
|
<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
|
|
|
|
/>
|
2017-12-26 14:56:04 +00:00
|
|
|
</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
|
|
|
|
/>
|
2017-12-26 14:56:04 +00:00
|
|
|
</div>
|
2018-05-09 20:18:33 +00:00
|
|
|
<dangerous-button
|
2021-11-11 19:05:11 +00:00
|
|
|
: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>
|
2018-05-09 20:18:33 +00:00
|
|
|
</dangerous-button>
|
2017-12-26 14:56:04 +00:00
|
|
|
</form>
|
2018-05-09 20:18:33 +00:00
|
|
|
<div class="ui hidden divider" />
|
|
|
|
<subsonic-token-form />
|
2018-11-19 22:33:22 +00:00
|
|
|
</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" />
|
|
|
|
<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>
|
2019-03-06 16:40:09 +00:00
|
|
|
<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" />
|
2019-03-25 16:02:51 +00:00
|
|
|
<h2 class="ui header">
|
2021-11-26 11:01:58 +00:00
|
|
|
<i class="open lock icon" />
|
2019-03-25 16:02:51 +00:00
|
|
|
<div class="content">
|
2021-11-26 11:01:58 +00:00
|
|
|
<translate translate-context="Content/Settings/Title/Noun">
|
|
|
|
Authorized apps
|
|
|
|
</translate>
|
2019-03-25 16:02:51 +00:00
|
|
|
</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>
|
2019-03-25 16:02:51 +00:00
|
|
|
<button
|
2021-11-26 11:01:58 +00:00
|
|
|
class="ui icon button"
|
2019-03-25 16:02:51 +00:00
|
|
|
@click="fetchApps()"
|
2021-11-26 11:01:58 +00:00
|
|
|
>
|
|
|
|
<i class="refresh icon" />
|
|
|
|
<translate translate-context="Content/*/Button.Label/Short, Verb">
|
|
|
|
Refresh
|
|
|
|
</translate>
|
2019-03-25 16:02:51 +00:00
|
|
|
</button>
|
2021-11-26 11:01:58 +00:00
|
|
|
<table
|
|
|
|
v-if="apps.length > 0"
|
|
|
|
class="ui compact very basic unstackable table"
|
|
|
|
>
|
2019-03-25 16:02:51 +00:00
|
|
|
<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 />
|
2019-03-25 16:02:51 +00:00
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
2021-11-26 11:01:58 +00:00
|
|
|
<tr
|
|
|
|
v-for="app in apps"
|
|
|
|
:key="app.client_id"
|
|
|
|
>
|
2019-03-25 16:02:51 +00:00
|
|
|
<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>
|
2019-03-25 16:02:51 +00:00
|
|
|
</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>
|
2019-03-25 16:02:51 +00:00
|
|
|
<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" />
|
2019-03-25 16:02:51 +00:00
|
|
|
<h2 class="ui header">
|
2021-11-26 11:01:58 +00:00
|
|
|
<i class="code icon" />
|
2019-03-25 16:02:51 +00:00
|
|
|
<div class="content">
|
2021-11-26 11:01:58 +00:00
|
|
|
<translate translate-context="Content/Settings/Title/Noun">
|
|
|
|
Your applications
|
|
|
|
</translate>
|
2019-03-25 16:02:51 +00:00
|
|
|
</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>
|
2019-03-25 16:02:51 +00:00
|
|
|
</router-link>
|
2021-11-26 11:01:58 +00:00
|
|
|
<table
|
|
|
|
v-if="ownedApps.length > 0"
|
|
|
|
class="ui compact very basic unstackable table"
|
|
|
|
>
|
2019-03-25 16:02:51 +00:00
|
|
|
<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 />
|
2019-03-25 16:02:51 +00:00
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
2021-11-26 11:01:58 +00:00
|
|
|
<tr
|
|
|
|
v-for="app in ownedApps"
|
|
|
|
:key="app.client_id"
|
|
|
|
>
|
2019-03-25 16:02:51 +00:00
|
|
|
<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>
|
2019-03-25 16:02:51 +00:00
|
|
|
</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>
|
2019-03-25 16:02:51 +00:00
|
|
|
</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>
|
2019-03-25 16:02:51 +00:00
|
|
|
<translate translate-context="Content/Applications/Paragraph">
|
2021-06-17 15:55:12 +00:00
|
|
|
Register one to integrate Funkwhale with third-party applications.
|
2019-03-25 16:02:51 +00:00
|
|
|
</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>
|
2020-08-02 14:29:58 +00:00
|
|
|
<section class="ui text container">
|
2021-11-26 11:01:58 +00:00
|
|
|
<div class="ui hidden divider" />
|
2020-08-02 14:29:58 +00:00
|
|
|
<h2 class="ui header">
|
2021-11-26 11:01:58 +00:00
|
|
|
<i class="comment icon" />
|
2020-08-02 14:29:58 +00:00
|
|
|
<div class="content">
|
2021-11-26 11:01:58 +00:00
|
|
|
<translate translate-context="*/*/Button.Label">
|
|
|
|
Change my e-mail address
|
|
|
|
</translate>
|
2020-08-02 14:29:58 +00:00
|
|
|
</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>
|
2020-08-02 14:29:58 +00:00
|
|
|
</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>
|
2020-08-02 14:29:58 +00:00
|
|
|
</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>
|
2020-08-02 14:29:58 +00:00
|
|
|
<ul class="list">
|
2021-11-26 11:01:58 +00:00
|
|
|
<li
|
|
|
|
v-for="(error, key) in changeEmailErrors"
|
|
|
|
:key="key"
|
|
|
|
>
|
|
|
|
{{ error }}
|
|
|
|
</li>
|
2020-08-02 14:29:58 +00:00
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
<div class="field">
|
2021-06-17 15:55:12 +00:00
|
|
|
<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"
|
|
|
|
>
|
2020-08-02 14:29:58 +00:00
|
|
|
</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
|
|
|
|
/>
|
2020-08-02 14:29:58 +00:00
|
|
|
</div>
|
2021-11-26 11:01:58 +00:00
|
|
|
<button
|
|
|
|
type="submit"
|
|
|
|
class="ui button"
|
|
|
|
>
|
|
|
|
<translate translate-context="*/*/*">
|
|
|
|
Update
|
|
|
|
</translate>
|
|
|
|
</button>
|
2020-08-02 14:29:58 +00:00
|
|
|
</form>
|
|
|
|
</section>
|
2019-09-21 14:20:49 +00:00
|
|
|
<section class="ui text container">
|
2021-11-26 11:01:58 +00:00
|
|
|
<div class="ui hidden divider" />
|
2019-09-21 14:20:49 +00:00
|
|
|
<h2 class="ui header">
|
2021-11-26 11:01:58 +00:00
|
|
|
<i class="trash icon" />
|
2019-09-21 14:20:49 +00:00
|
|
|
<div class="content">
|
2021-11-26 11:01:58 +00:00
|
|
|
<translate translate-context="*/*/Button.Label">
|
|
|
|
Delete my account
|
|
|
|
</translate>
|
2019-09-21 14:20:49 +00:00
|
|
|
</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>
|
2019-09-21 14:20:49 +00:00
|
|
|
</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>
|
2019-09-21 14:20:49 +00:00
|
|
|
</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>
|
2019-09-21 14:20:49 +00:00
|
|
|
<ul class="list">
|
2021-11-26 11:01:58 +00:00
|
|
|
<li
|
|
|
|
v-for="(error, key) in accountDeleteErrors"
|
|
|
|
:key="key"
|
|
|
|
>
|
|
|
|
{{ error }}
|
|
|
|
</li>
|
2019-09-21 14:20:49 +00:00
|
|
|
</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
|
|
|
|
/>
|
2019-09-21 14:20:49 +00:00
|
|
|
</div>
|
|
|
|
<dangerous-button
|
2021-11-11 08:54:59 +00:00
|
|
|
: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>
|
2019-09-21 14:20:49 +00:00
|
|
|
</dangerous-button>
|
|
|
|
</div>
|
|
|
|
</section>
|
2017-12-26 14:56:04 +00:00
|
|
|
</div>
|
2018-11-19 22:33:22 +00:00
|
|
|
</main>
|
2017-12-26 14:56:04 +00:00
|
|
|
</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'
|
2022-04-30 18:40:57 +00:00
|
|
|
import useLogger from '~/composables/useLogger'
|
2022-05-02 15:06:44 +00:00
|
|
|
import useSharedLabels from '~/composables/locale/useSharedLabels'
|
2022-04-30 18:40:57 +00:00
|
|
|
|
|
|
|
const logger = useLogger()
|
2017-12-26 14:56:04 +00:00
|
|
|
|
|
|
|
export default {
|
2018-05-06 09:19:20 +00:00
|
|
|
components: {
|
2018-05-09 20:18:33 +00:00
|
|
|
PasswordInput,
|
2020-01-23 15:38:04 +00:00
|
|
|
SubsonicTokenForm,
|
|
|
|
AttachmentInput
|
2018-05-06 09:19:20 +00:00
|
|
|
},
|
2022-05-01 16:46:27 +00:00
|
|
|
setup () {
|
|
|
|
const sharedLabels = useSharedLabels()
|
|
|
|
return { sharedLabels }
|
|
|
|
},
|
2021-11-26 11:01:58 +00:00
|
|
|
data () {
|
|
|
|
const d = {
|
2017-12-26 14:56:04 +00:00
|
|
|
// 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: '',
|
2022-05-02 07:36:01 +00:00
|
|
|
avatar: { ...(this.$store.state.auth.profile?.avatar ?? { uuid: null }) },
|
2021-11-26 11:01:58 +00:00
|
|
|
passwordError: '',
|
|
|
|
password: '',
|
2018-03-03 11:40:01 +00:00
|
|
|
isLoading: false,
|
2018-07-13 12:10:39 +00:00
|
|
|
isLoadingAvatar: false,
|
2019-09-21 14:20:49 +00:00
|
|
|
isDeletingAccount: false,
|
2020-08-02 14:29:58 +00:00
|
|
|
changeEmailErrors: [],
|
|
|
|
isChangingEmail: false,
|
|
|
|
newEmail: null,
|
|
|
|
emailPassword: null,
|
2019-09-21 14:20:49 +00:00
|
|
|
accountDeleteErrors: [],
|
2018-07-13 12:10:39 +00:00
|
|
|
avatarErrors: [],
|
2019-03-25 16:02:51 +00:00
|
|
|
apps: [],
|
|
|
|
ownedApps: [],
|
2018-03-03 11:40:01 +00:00
|
|
|
settings: {
|
|
|
|
success: false,
|
|
|
|
errors: [],
|
2021-11-26 11:01:58 +00:00
|
|
|
order: ['summary', 'privacy_level'],
|
2018-03-03 11:40:01 +00:00
|
|
|
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
|
|
|
},
|
2018-11-19 22:33:22 +00:00
|
|
|
privacy_level: {
|
2021-11-26 11:01:58 +00:00
|
|
|
type: 'dropdown',
|
2018-03-03 11:40:01 +00:00
|
|
|
initial: this.$store.state.auth.profile.privacy_level,
|
2021-11-26 11:01:58 +00:00
|
|
|
choices: ['me', 'instance', 'everyone']
|
2018-03-03 11:40:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-12-26 14:56:04 +00:00
|
|
|
}
|
2020-01-23 15:38:04 +00:00
|
|
|
d.initialAvatar = d.avatar.uuid
|
2018-03-03 11:40:01 +00:00
|
|
|
d.settings.order.forEach(id => {
|
|
|
|
d.settings.fields[id].value = d.settings.fields[id].initial
|
2018-10-05 17:53:28 +00:00
|
|
|
d.settings.fields[id].id = id
|
2018-03-03 11:40:01 +00:00
|
|
|
})
|
|
|
|
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
|
|
|
|
}
|
|
|
|
},
|
2019-03-25 16:02:51 +00:00
|
|
|
created () {
|
|
|
|
this.fetchApps()
|
|
|
|
this.fetchOwnedApps()
|
|
|
|
},
|
2021-11-26 11:01:58 +00:00
|
|
|
mounted () {
|
|
|
|
$('select.dropdown').dropdown()
|
2017-12-26 14:56:04 +00:00
|
|
|
},
|
|
|
|
methods: {
|
2021-11-26 11:01:58 +00:00
|
|
|
submitSettings () {
|
2018-03-03 11:40:01 +00:00
|
|
|
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}/`
|
2018-11-19 22:33:22 +00:00
|
|
|
return axios.patch(url, payload).then(
|
|
|
|
response => {
|
2022-04-30 18:40:57 +00:00
|
|
|
logger.info('Updated settings successfully')
|
2018-11-19 22:33:22 +00:00
|
|
|
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)
|
2018-11-19 22:33:22 +00:00
|
|
|
})
|
|
|
|
},
|
|
|
|
error => {
|
2022-04-30 18:40:57 +00:00
|
|
|
logger.error('Error while updating settings')
|
2018-11-19 22:33:22 +00:00
|
|
|
self.isLoading = false
|
|
|
|
self.settings.errors = error.backendErrors
|
|
|
|
}
|
|
|
|
)
|
2018-03-03 11:40:01 +00:00
|
|
|
},
|
2021-11-26 11:01:58 +00:00
|
|
|
fetchApps () {
|
2019-03-25 16:02:51 +00:00
|
|
|
this.apps = []
|
2021-11-26 11:01:58 +00:00
|
|
|
const self = this
|
|
|
|
const url = 'oauth/grants/'
|
2019-03-25 16:02:51 +00:00
|
|
|
return axios.get(url).then(
|
|
|
|
response => {
|
|
|
|
self.apps = response.data
|
|
|
|
},
|
|
|
|
error => {
|
2022-04-30 18:40:57 +00:00
|
|
|
logger.error('Error while fetching Apps')
|
2021-11-26 11:01:58 +00:00
|
|
|
self.isLoading = false
|
|
|
|
self.settings.errors = error.backendErrors
|
2019-03-25 16:02:51 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
},
|
2021-11-26 11:01:58 +00:00
|
|
|
fetchOwnedApps () {
|
2019-03-25 16:02:51 +00:00
|
|
|
this.ownedApps = []
|
2021-11-26 11:01:58 +00:00
|
|
|
const self = this
|
|
|
|
const url = 'oauth/apps/'
|
2019-03-25 16:02:51 +00:00
|
|
|
return axios.get(url).then(
|
|
|
|
response => {
|
|
|
|
self.ownedApps = response.data.results
|
|
|
|
},
|
|
|
|
error => {
|
2022-04-30 18:40:57 +00:00
|
|
|
logger.error('Error while fetching owned Apps')
|
2021-11-26 11:01:58 +00:00
|
|
|
self.isLoading = false
|
|
|
|
self.settings.errors = error.backendErrors
|
2019-03-25 16:02:51 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
},
|
|
|
|
revokeApp (id) {
|
2021-11-26 11:01:58 +00:00
|
|
|
const self = this
|
|
|
|
const url = `oauth/grants/${id}/`
|
2019-03-25 16:02:51 +00:00
|
|
|
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
|
2019-03-25 16:02:51 +00:00
|
|
|
})
|
|
|
|
},
|
|
|
|
error => {
|
2022-04-30 18:40:57 +00:00
|
|
|
logger.error('Error while revoking App')
|
2021-11-26 11:01:58 +00:00
|
|
|
self.isLoading = false
|
|
|
|
self.settings.errors = error.backendErrors
|
2019-03-25 16:02:51 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
},
|
|
|
|
deleteApp (id) {
|
2021-11-26 11:01:58 +00:00
|
|
|
const self = this
|
|
|
|
const url = `oauth/apps/${id}/`
|
2019-03-25 16:02:51 +00:00
|
|
|
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
|
2019-03-25 16:02:51 +00:00
|
|
|
})
|
|
|
|
},
|
|
|
|
error => {
|
2022-04-30 18:40:57 +00:00
|
|
|
logger.error('Error while deleting App')
|
2021-11-26 11:01:58 +00:00
|
|
|
self.isLoading = false
|
|
|
|
self.settings.errors = error.backendErrors
|
2019-03-25 16:02:51 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
},
|
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
|
2018-11-19 22:33:22 +00:00
|
|
|
axios
|
2021-11-26 11:01:58 +00:00
|
|
|
.patch(`users/${this.$store.state.auth.username}/`, { avatar: uuid })
|
2018-11-19 22:33:22 +00:00
|
|
|
.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)
|
2018-11-19 22:33:22 +00:00
|
|
|
},
|
|
|
|
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
|
2017-12-26 14:56:04 +00:00
|
|
|
self.isLoading = true
|
2021-11-26 11:01:58 +00:00
|
|
|
this.error = ''
|
|
|
|
const credentials = {
|
2017-12-26 14:56:04 +00:00
|
|
|
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/'
|
2018-11-19 22:33:22 +00:00
|
|
|
return axios.post(url, credentials).then(
|
|
|
|
response => {
|
2022-04-30 18:40:57 +00:00
|
|
|
logger.info('Password successfully changed')
|
2018-11-19 22:33:22 +00:00
|
|
|
self.$router.push({
|
2021-11-26 11:01:58 +00:00
|
|
|
name: 'profile.overview',
|
2018-11-19 22:33:22 +00:00
|
|
|
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'
|
2018-11-19 22:33:22 +00:00
|
|
|
} else {
|
2021-11-26 11:01:58 +00:00
|
|
|
self.passwordError = 'unknown_error'
|
2018-11-19 22:33:22 +00:00
|
|
|
}
|
|
|
|
self.isLoading = false
|
2017-12-26 14:56:04 +00:00
|
|
|
}
|
2018-11-19 22:33:22 +00:00
|
|
|
)
|
2019-09-21 14:20:49 +00:00
|
|
|
},
|
2021-11-26 11:01:58 +00:00
|
|
|
deleteAccount () {
|
2019-09-21 14:20:49 +00:00
|
|
|
this.isDeletingAccount = true
|
|
|
|
this.accountDeleteErrors = []
|
2021-11-26 11:01:58 +00:00
|
|
|
const self = this
|
|
|
|
const payload = {
|
2019-09-21 14:20:49 +00:00
|
|
|
confirm: true,
|
2021-11-26 11:01:58 +00:00
|
|
|
password: this.password
|
2019-09-21 14:20:49 +00:00
|
|
|
}
|
2021-11-26 11:01:58 +00:00
|
|
|
axios.delete('users/me/', { data: payload })
|
2019-09-21 14:20:49 +00:00
|
|
|
.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')
|
2019-09-21 14:20:49 +00:00
|
|
|
self.$store.commit('ui/addMessage', {
|
|
|
|
content: msg,
|
|
|
|
date: new Date()
|
|
|
|
})
|
|
|
|
self.$store.dispatch('auth/logout')
|
|
|
|
},
|
|
|
|
error => {
|
|
|
|
self.isDeletingAccount = false
|
|
|
|
self.accountDeleteErrors = error.backendErrors
|
|
|
|
}
|
|
|
|
)
|
|
|
|
},
|
2020-08-02 14:29:58 +00:00
|
|
|
|
2021-11-26 11:01:58 +00:00
|
|
|
changeEmail () {
|
2020-08-02 14:29:58 +00:00
|
|
|
this.isChangingEmail = true
|
|
|
|
this.changeEmailErrors = []
|
2021-11-26 11:01:58 +00:00
|
|
|
const self = this
|
|
|
|
const payload = {
|
2020-08-02 14:29:58 +00:00
|
|
|
password: this.emailPassword,
|
2021-11-26 11:01:58 +00:00
|
|
|
email: this.newEmail
|
2020-08-02 14:29:58 +00:00
|
|
|
}
|
2021-11-26 11:01:58 +00:00
|
|
|
axios.post('users/users/change-email/', payload)
|
2020-08-02 14:29:58 +00:00
|
|
|
.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.')
|
2020-08-02 14:29:58 +00:00
|
|
|
self.$store.commit('ui/addMessage', {
|
|
|
|
content: msg,
|
|
|
|
date: new Date()
|
|
|
|
})
|
|
|
|
},
|
|
|
|
error => {
|
|
|
|
self.isChangingEmail = false
|
|
|
|
self.changeEmailErrors = error.backendErrors
|
|
|
|
}
|
|
|
|
)
|
2018-03-03 11:40:01 +00:00
|
|
|
}
|
2017-12-26 14:56:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|