#227 allow banning people without cards
This commit is contained in:
parent
b0162a61e2
commit
617cf70641
|
@ -143,7 +143,7 @@
|
|||
}
|
||||
},
|
||||
async mounted() {
|
||||
this.profiles = await this.$axios.$get(`/profile/get/${this.$user().username}`);
|
||||
this.profiles = (await this.$axios.$get(`/profile/get/${this.$user().username}`)).profiles;
|
||||
this.socialConnections = await this.$axios.$get(`/user/social-connections`);
|
||||
|
||||
if (process.client) {
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<template>
|
||||
<client-only v-if="config.profile.editorEnabled">
|
||||
<section v-if="$isGranted('users')">
|
||||
<div class="alert alert-warning">
|
||||
<textarea v-model="user.bannedReason" class="form-control" rows="3" :placeholder="$t('ban.reason') + ' ' + $t('ban.visible')" :disabled="saving"></textarea>
|
||||
<button class="btn btn-danger d-block w-100 mt-2" :disabled="saving" @click="ban">
|
||||
<Icon v="ban"/>
|
||||
{{$t('ban.action')}}
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
</client-only>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ClientOnly from 'vue-client-only'
|
||||
|
||||
export default {
|
||||
components: { ClientOnly },
|
||||
props: {
|
||||
user: { required: true },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
saving: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async ban() {
|
||||
await this.$confirm(this.$t('ban.confirm', {username: this.user.username}), 'danger');
|
||||
this.saving = true;
|
||||
try {
|
||||
await this.$post(`/admin/ban/${encodeURIComponent(this.user.username)}`, {
|
||||
reason: this.user.bannedReason,
|
||||
});
|
||||
window.location.reload();
|
||||
} finally {
|
||||
this.saving = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
|
@ -98,12 +98,14 @@
|
|||
</div>
|
||||
</div>
|
||||
<header v-else class="mb-4">
|
||||
<h1 class="text-nowrap p-4">
|
||||
<nuxt-link to="/">
|
||||
<Icon v="tags"/>
|
||||
<T>title</T>
|
||||
</nuxt-link>
|
||||
</h1>
|
||||
<div class="container">
|
||||
<h1 class="text-nowrap p-4">
|
||||
<nuxt-link to="/">
|
||||
<Icon v="tags"/>
|
||||
<T>title</T>
|
||||
</nuxt-link>
|
||||
</h1>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
<div>
|
||||
<div class="mb-3 d-flex justify-content-between flex-column flex-md-row">
|
||||
<h2 class="text-nowrap">
|
||||
<Avatar :user="profile"/>
|
||||
@{{profile.username}}
|
||||
<Avatar :user="user"/>
|
||||
@{{user.username}}
|
||||
</h2>
|
||||
<div class="flex-grow-1 text-lg-end">
|
||||
<slot></slot>
|
||||
|
@ -110,6 +110,7 @@
|
|||
|
||||
export default {
|
||||
props: {
|
||||
user: { required: true },
|
||||
profile: { required: true },
|
||||
terms: { 'default': null },
|
||||
},
|
||||
|
|
|
@ -16,3 +16,6 @@ confirm:
|
|||
|
||||
table:
|
||||
scrollUp: 'Scroll to the top'
|
||||
|
||||
profile:
|
||||
empty: 'This person hasn''t created any cards yet.'
|
||||
|
|
|
@ -407,15 +407,16 @@ profile:
|
|||
meh: 'Okay'
|
||||
no: 'Nope'
|
||||
|
||||
banner: >
|
||||
You can also use our website to create a card, {/@andrea=like this one},
|
||||
containing your names, pronouns, pride flags, liked words, etc.
|
||||
Then you can link to it in your bio or email footer.
|
||||
Just create an account {/account=here}.
|
||||
bannerButton: 'Create a card'
|
||||
card:
|
||||
link: 'Card picture'
|
||||
generating: 'Generation in progress…'
|
||||
banner: >
|
||||
You can also use our website to create a card, {/@andrea=like this one},
|
||||
containing your names, pronouns, pride flags, liked words, etc.
|
||||
Then you can link to it in your bio or email footer.
|
||||
Just create an account {/account=here}.
|
||||
bannerButton: 'Create a card'
|
||||
card:
|
||||
link: 'Card picture'
|
||||
generating: 'Generation in progress…'
|
||||
empty: 'This person hasn''t created any cards yet.'
|
||||
|
||||
share: 'Teilen'
|
||||
|
||||
|
|
|
@ -514,6 +514,7 @@ profile:
|
|||
card:
|
||||
link: 'Card picture'
|
||||
generating: 'Generation in progress…'
|
||||
empty: 'This person hasn''t created any cards yet.'
|
||||
|
||||
share: 'Share'
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ sources:
|
|||
Series: 'Series'
|
||||
Song: 'Música'
|
||||
Poetry: 'Poesía'
|
||||
Game: 'Juegos'
|
||||
Game: 'Juegos'
|
||||
Other: 'Otros'
|
||||
submit:
|
||||
header: 'Enviar un ejemplo para que sea añadido'
|
||||
|
@ -307,7 +307,7 @@ links:
|
|||
headerLong: 'Enlaces externos'
|
||||
recommended: 'Recomendamos'
|
||||
|
||||
blog: 'Blog'
|
||||
blog: 'Blog'
|
||||
media: 'Pronouns.page en los medios'
|
||||
|
||||
social: 'Redes sociales'
|
||||
|
@ -328,9 +328,9 @@ contact:
|
|||
{https://pronouns.page=Pronouns.page} and related initiatives
|
||||
are created by the “Neutral Language Council” collective.
|
||||
logo: 'Logo of the collective is a combination of the transgender symbol and a speech bubble that symbolises language.' # TODO
|
||||
members: 'Miembros actuales'
|
||||
member: 'Miembro de la cooperativa'
|
||||
upcoming: 'Próximas versiones en otras lenguas'
|
||||
members: 'Miembros actuales'
|
||||
member: 'Miembro de la cooperativa'
|
||||
upcoming: 'Próximas versiones en otras lenguas'
|
||||
|
||||
support:
|
||||
header: 'Apóyanos'
|
||||
|
@ -395,10 +395,10 @@ profile:
|
|||
birthdayInfo: 'No publicamos la fecha de tu cumpleaños, sólo la edad calculada.'
|
||||
flags: 'Banderas'
|
||||
flagsInfo: 'Arrastra tus banderas de orgullo a este marco.'
|
||||
flagsCustom: 'Sube una bandera personalizada'
|
||||
flagsCustomWarning: 'Esta bandera fue subida por un usuario. El equipo de pronouns.page no es responsable de ella.'
|
||||
flagsCustom: 'Sube una bandera personalizada'
|
||||
flagsCustomWarning: 'Esta bandera fue subida por un usuario. El equipo de pronouns.page no es responsable de ella.'
|
||||
links: 'Enlaces'
|
||||
linksCake: 'We recommend linking to'
|
||||
linksCake: 'We recommend linking to'
|
||||
column: 'Columna'
|
||||
|
||||
list: 'Tus tarjetas'
|
||||
|
@ -426,6 +426,7 @@ profile:
|
|||
card:
|
||||
link: 'Imagen de la tarjeta'
|
||||
generating: 'Generando…'
|
||||
empty: 'This person hasn''t created any cards yet.' # TODO
|
||||
|
||||
share: 'Compartir'
|
||||
|
||||
|
@ -440,7 +441,7 @@ crud:
|
|||
filterLong: 'Filtrar la lista…'
|
||||
search: 'Buscar…'
|
||||
author: 'Añadido por'
|
||||
saved: 'Los cambios se guardaron exitosamente!'
|
||||
saved: 'Los cambios se guardaron exitosamente!'
|
||||
|
||||
footer:
|
||||
# TODO source: 'El código fuente está {https://gitlab.com/Avris/Zaimki=publicado} bajo la licencia {https://mit.avris.it=MIT}.'
|
||||
|
@ -509,7 +510,7 @@ error:
|
|||
generic: 'Algo salió mal. Por favor, vuelve a intentarlo…'
|
||||
|
||||
mode:
|
||||
dark: 'Modo oscuro'
|
||||
dark: 'Modo oscuro'
|
||||
light: 'Modo claro'
|
||||
|
||||
# TODO
|
||||
|
|
|
@ -403,6 +403,17 @@ profile:
|
|||
jokingly: 'En plaisantant'
|
||||
meh: 'D''accord'
|
||||
no: 'Non'
|
||||
# TODO
|
||||
banner: >
|
||||
You can also use our website to create a card, {/@andrea=like this one},
|
||||
containing your names, pronouns, pride flags, liked words, etc.
|
||||
Then you can link to it in your bio or email footer.
|
||||
Just create an account {/account=here}.
|
||||
bannerButton: 'Create a card'
|
||||
card:
|
||||
link: 'Card picture'
|
||||
generating: 'Generation in progress…'
|
||||
empty: 'This person hasn''t created any cards yet.'
|
||||
|
||||
share: 'Partager'
|
||||
|
||||
|
|
|
@ -421,6 +421,7 @@ profile:
|
|||
card:
|
||||
link: 'Card picture'
|
||||
generating: 'Generation in progress…'
|
||||
empty: 'This person hasn''t created any cards yet.' # TODO
|
||||
|
||||
share: 'Deel'
|
||||
|
||||
|
|
|
@ -980,6 +980,7 @@ profile:
|
|||
card:
|
||||
link: 'Obrazek'
|
||||
generating: 'Trwa generowanie obrazka…'
|
||||
empty: 'Ta osoba nie stworzyła jeszcze żadnych wizytówek.'
|
||||
|
||||
census:
|
||||
header: 'Spis'
|
||||
|
|
|
@ -50,7 +50,7 @@ pronouns:
|
|||
button: 'Gerar uma ligação à formas intercambiáveis'
|
||||
header: 'Formas intercambiáveis'
|
||||
raw: 'intercambiável'
|
||||
generated: 'Estes pronomes foram criados com o gerador. A equipe do pronouns.page não é responsável por eles.'
|
||||
generated: 'Estes pronomes foram criados com o gerador. A equipe do pronouns.page não é responsável por eles.'
|
||||
any:
|
||||
header: 'Qualquer pronome'
|
||||
short: 'qualquer'
|
||||
|
@ -77,7 +77,7 @@ sources:
|
|||
Series: 'Séries'
|
||||
Song: 'Música'
|
||||
Poetry: 'Poesia'
|
||||
Game: 'Jogos'
|
||||
Game: 'Jogos'
|
||||
Other: 'Outros'
|
||||
submit:
|
||||
header: 'Enviar um exemplo para que seja adicionado'
|
||||
|
@ -97,9 +97,9 @@ sources:
|
|||
moderation: 'Os envios devem ser aprovados antes de serem publicados.'
|
||||
key: 'Key' # TODO
|
||||
keyInfo: 'Identifier for linking sources between language versions and linking with the dictionary' # TODO
|
||||
images: 'Imagens'
|
||||
otherVersions: 'Em outros idiomas'
|
||||
referenced: 'Exemplos de uso'
|
||||
images: 'Imagens'
|
||||
otherVersions: 'Em outros idiomas'
|
||||
referenced: 'Exemplos de uso'
|
||||
|
||||
nouns:
|
||||
header: 'Dicionário'
|
||||
|
@ -304,7 +304,7 @@ links:
|
|||
headerLong: 'Links externos'
|
||||
recommended: 'Recomendamos'
|
||||
|
||||
blog: 'Blog'
|
||||
blog: 'Blog'
|
||||
media: 'Pronouns.page nas mídias'
|
||||
|
||||
social: 'Redes sociais'
|
||||
|
@ -320,15 +320,15 @@ contact:
|
|||
authors: 'Autores do site'
|
||||
team:
|
||||
name: 'O coletivo "Conselho da Língua Neutra"'
|
||||
description:
|
||||
description:
|
||||
- >
|
||||
{https://pronouns.page=Pronouns.page} e iniciativas relacionadas
|
||||
são criadas pelo o coletivo “Conselho da Língua Neutra”.
|
||||
logo: 'A logo do coletivo é uma combinação do símbolo transgênero e um balão de fala que simboliza a língua.'
|
||||
members: 'Membres atuais'
|
||||
logo: 'A logo do coletivo é uma combinação do símbolo transgênero e um balão de fala que simboliza a língua.'
|
||||
members: 'Membres atuais'
|
||||
member: 'Member of the collective' # TODO
|
||||
blog: 'Blog'
|
||||
upcoming: 'Próximas versões'
|
||||
blog: 'Blog'
|
||||
upcoming: 'Próximas versões'
|
||||
|
||||
support:
|
||||
header: 'Apoie-nos'
|
||||
|
@ -353,7 +353,7 @@ user:
|
|||
Se não solicitou este código, simplesmente ignore esta mensagem.
|
||||
why: >
|
||||
Registrar-se te permite dirigir os cartões ({/@andrea=como esta}).
|
||||
passwordless: 'O site não grava qualquer senha. {https://avris.it/blog/passwords-are-passé=More info.}'
|
||||
passwordless: 'O site não grava qualquer senha. {https://avris.it/blog/passwords-are-passé=More info.}'
|
||||
code:
|
||||
action: 'Validar'
|
||||
invalid: 'Código inválido.'
|
||||
|
@ -424,6 +424,7 @@ profile:
|
|||
card:
|
||||
link: 'Imagem do cartão'
|
||||
generating: 'Gerando a imagem…'
|
||||
empty: 'This person hasn''t created any cards yet.' # TODO
|
||||
|
||||
share: 'Compartilhar'
|
||||
|
||||
|
|
|
@ -960,6 +960,7 @@ profile:
|
|||
card:
|
||||
link: 'Card picture'
|
||||
generating: 'Generation in progress…'
|
||||
empty: 'This person hasn''t created any cards yet.' # TODO
|
||||
|
||||
census:
|
||||
header: 'Spis'
|
||||
|
|
|
@ -439,6 +439,7 @@ profile:
|
|||
card:
|
||||
link: 'Card picture'
|
||||
generating: 'Generation in progress…'
|
||||
empty: 'This person hasn''t created any cards yet.' # TODO
|
||||
|
||||
share: 'Share'
|
||||
|
||||
|
|
|
@ -406,6 +406,7 @@ profile:
|
|||
card:
|
||||
link: 'Card picture'
|
||||
generating: 'Generation in progress…'
|
||||
empty: 'This person hasn''t created any cards yet.' # TODO
|
||||
|
||||
share: '這裡'
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
<template>
|
||||
<div v-if="profile">
|
||||
<section v-if="$isGranted('users') && profile.bannedReason">
|
||||
<section v-if="$isGranted('users') && user.bannedReason">
|
||||
<div class="alert alert-warning">
|
||||
<p class="h4">
|
||||
<Icon v="ban"/>
|
||||
{{$t('ban.banned')}}
|
||||
</p>
|
||||
<p class="mb-0">{{profile.bannedReason}}</p>
|
||||
<p class="mb-0">{{user.bannedReason}}</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Profile :profile="profile" :terms="terms">
|
||||
<div v-if="Object.keys(profiles).length > 1">
|
||||
<LocaleLink v-for="(options, locale) in locales" :key="locale" v-if="profiles[locale] !== undefined"
|
||||
<Profile :user="user" :profile="profile" :terms="terms">
|
||||
<div v-if="Object.keys(user.profiles).length > 1">
|
||||
<LocaleLink v-for="(options, locale) in locales" :key="locale" v-if="user.profiles[locale] !== undefined"
|
||||
:locale="locale" :link="`/@${profile.username}`"
|
||||
:class="['btn', locale === config.locale ? 'btn-primary disabled' : 'btn-outline-primary', 'btn-sm', 'mb-2 mx-1']">
|
||||
{{options.name}}
|
||||
|
@ -23,7 +23,7 @@
|
|||
<Icon v="edit"/>
|
||||
<T>profile.edit</T>
|
||||
</nuxt-link>
|
||||
<a :href="`https://pronouns.page/@${profile.username}`" v-if="Object.keys(profiles).length > 1"
|
||||
<a :href="`https://pronouns.page/@${profile.username}`" v-if="Object.keys(user.profiles).length > 1"
|
||||
class="btn btn-outline-secondary btn-sm mb-2 mx-1"
|
||||
>
|
||||
<Icon v="external-link"/>
|
||||
|
@ -51,17 +51,7 @@
|
|||
</div>
|
||||
</Profile>
|
||||
|
||||
<client-only>
|
||||
<section v-if="$isGranted('users')">
|
||||
<div class="alert alert-warning">
|
||||
<textarea v-model="profile.bannedReason" class="form-control" rows="3" :placeholder="$t('ban.reason') + ' ' + $t('ban.visible')" :disabled="saving"></textarea>
|
||||
<button class="btn btn-danger d-block w-100 mt-2" :disabled="saving" @click="ban">
|
||||
<Icon v="ban"/>
|
||||
{{$t('ban.action')}}
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
</client-only>
|
||||
<Ban :user="user"/>
|
||||
|
||||
<Separator icon="heart"/>
|
||||
<Support/>
|
||||
|
@ -69,14 +59,14 @@
|
|||
<Share/>
|
||||
</section>
|
||||
</div>
|
||||
<div v-else-if="Object.keys(profiles).length">
|
||||
<div v-else-if="user.username">
|
||||
<h2 class="text-nowrap mb-3">
|
||||
<Avatar :user="profiles[Object.keys(profiles)[0]]"/>
|
||||
<Avatar :user="user"/>
|
||||
@{{username}}
|
||||
</h2>
|
||||
|
||||
<div class="list-group">
|
||||
<LocaleLink v-for="(options, locale) in locales" :key="locale" v-if="profiles[locale] !== undefined"
|
||||
<div v-if="Object.keys(user.profiles).length" class="list-group">
|
||||
<LocaleLink v-for="(options, locale) in locales" :key="locale" v-if="user.profiles[locale] !== undefined"
|
||||
:locale="locale" :link="`/@${username}`"
|
||||
class="list-group-item list-group-item-action list-group-item-hoverable">
|
||||
<div class="h3">
|
||||
|
@ -84,6 +74,14 @@
|
|||
</div>
|
||||
</LocaleLink>
|
||||
</div>
|
||||
<div v-else class="alert alert-info">
|
||||
<p class="mb-0">
|
||||
<Icon v="info-circle"/>
|
||||
<T>profile.empty</T>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Ban :user="user"/>
|
||||
</div>
|
||||
<NotFound v-else/>
|
||||
</template>
|
||||
|
@ -96,13 +94,12 @@
|
|||
components: { ClientOnly },
|
||||
data() {
|
||||
return {
|
||||
saving: false,
|
||||
terms: [],
|
||||
}
|
||||
},
|
||||
async asyncData({ app, route }) {
|
||||
return {
|
||||
profiles: await app.$axios.$get(`/profile/get/${encodeURIComponent(route.params.pathMatch)}`),
|
||||
user: await app.$axios.$get(`/profile/get/${encodeURIComponent(route.params.pathMatch)}`),
|
||||
};
|
||||
},
|
||||
async mounted() {
|
||||
|
@ -112,9 +109,9 @@
|
|||
},
|
||||
computed: {
|
||||
profile() {
|
||||
for (let locale in this.profiles) {
|
||||
for (let locale in this.user.profiles) {
|
||||
if (locale === this.config.locale) {
|
||||
return this.profiles[locale];
|
||||
return this.user.profiles[locale];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,31 +124,17 @@
|
|||
return base;
|
||||
}
|
||||
|
||||
if (this.profile.username !== base && process.client) {
|
||||
if (this.user.username !== base && process.client) {
|
||||
history.pushState(
|
||||
'',
|
||||
document.title,
|
||||
'/@' + this.profile.username,
|
||||
'/@' + this.user.username,
|
||||
);
|
||||
}
|
||||
|
||||
return this.profile.username;
|
||||
return this.user.username;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async ban() {
|
||||
await this.$confirm(this.$t('ban.confirm', {username: this.username}), 'danger');
|
||||
this.saving = true;
|
||||
try {
|
||||
await this.$post(`/admin/ban/${encodeURIComponent(this.username)}`, {
|
||||
reason: this.profile.bannedReason,
|
||||
});
|
||||
window.location.reload();
|
||||
} finally {
|
||||
this.saving = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return head({
|
||||
title: `@${this.username}`,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<template>
|
||||
<Profile v-if="profile" :profile="profile" class="pb-3">
|
||||
<Profile v-if="profile" :user="user" :profile="profile" class="pb-3">
|
||||
<nuxt-link to="/">
|
||||
<h1 class="text-nowrap h5">
|
||||
<Icon v="tags"/>
|
||||
<T>title</T><span v-if="profile">/@{{profile.username}}</span>
|
||||
<T>title</T><span v-if="profile">/@{{user.username}}</span>
|
||||
</h1>
|
||||
</nuxt-link>
|
||||
</Profile>
|
||||
|
@ -17,14 +17,14 @@
|
|||
layout: 'basic',
|
||||
async asyncData({ app, route }) {
|
||||
return {
|
||||
profiles: await app.$axios.$get(`/profile/get/${encodeURIComponent(route.params.pathMatch)}`),
|
||||
user: await app.$axios.$get(`/profile/get/${encodeURIComponent(route.params.pathMatch)}`),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
profile() {
|
||||
for (let locale in this.profiles) {
|
||||
for (let locale in this.user.profiles) {
|
||||
if (locale === this.config.locale) {
|
||||
return this.profiles[locale];
|
||||
return this.user.profiles[locale];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -188,9 +188,9 @@
|
|||
return {};
|
||||
}
|
||||
|
||||
const profiles = await app.$axios.$get(`/profile/get/${encodeURIComponent(store.state.user.username)}`, { headers: {
|
||||
const profiles = (await app.$axios.$get(`/profile/get/${encodeURIComponent(store.state.user.username)}`, { headers: {
|
||||
authorization: 'Bearer ' + store.state.token,
|
||||
} });
|
||||
} })).profiles;
|
||||
|
||||
for (let locale in profiles) {
|
||||
if (!profiles.hasOwnProperty(locale)) {
|
||||
|
|
|
@ -27,21 +27,14 @@ const calcAge = birthday => {
|
|||
|
||||
const fetchProfiles = async (db, username, self, isAdmin) => {
|
||||
const profiles = await db.all(SQL`
|
||||
SELECT profiles.*, users.id, users.username, users.email, users.avatarSource, users.bannedReason, users.roles FROM profiles LEFT JOIN users on users.id == profiles.userId
|
||||
SELECT profiles.* FROM profiles LEFT JOIN users on users.id == profiles.userId
|
||||
WHERE usernameNorm = ${normalise(username)}
|
||||
ORDER BY profiles.locale
|
||||
`);
|
||||
|
||||
const p = {}
|
||||
for (let profile of profiles) {
|
||||
if (profile.bannedReason !== null && !isAdmin && !self) {
|
||||
return {};
|
||||
}
|
||||
p[profile.locale] = {
|
||||
id: profile.id,
|
||||
userId: profile.userId,
|
||||
username: profile.username,
|
||||
emailHash: md5(profile.email),
|
||||
names: JSON.parse(profile.names),
|
||||
pronouns: JSON.parse(profile.pronouns),
|
||||
description: profile.description,
|
||||
|
@ -50,13 +43,10 @@ const fetchProfiles = async (db, username, self, isAdmin) => {
|
|||
flags: JSON.parse(profile.flags),
|
||||
customFlags: JSON.parse(profile.customFlags),
|
||||
words: JSON.parse(profile.words),
|
||||
avatar: await avatar(db, profile),
|
||||
birthday: self ? profile.birthday : undefined,
|
||||
teamName: profile.teamName,
|
||||
footerName: profile.footerName,
|
||||
footerAreas: profile.footerAreas ? profile.footerAreas.split(',') : [],
|
||||
bannedReason: profile.bannedReason,
|
||||
team: !!profile.roles,
|
||||
card: profile.card,
|
||||
};
|
||||
}
|
||||
|
@ -66,7 +56,34 @@ const fetchProfiles = async (db, username, self, isAdmin) => {
|
|||
const router = Router();
|
||||
|
||||
router.get('/profile/get/:username', handleErrorAsync(async (req, res) => {
|
||||
return res.json(await fetchProfiles(req.db, req.params.username, req.user && req.user.username === req.params.username, req.isGranted('users')))
|
||||
const isSelf = req.user && req.user.username === req.params.username;
|
||||
const isAdmin = req.isGranted('users');
|
||||
const user = await req.db.get(SQL`
|
||||
SELECT
|
||||
users.id,
|
||||
users.username,
|
||||
users.email,
|
||||
users.avatarSource,
|
||||
users.bannedReason,
|
||||
users.roles != '' AS team
|
||||
FROM users
|
||||
WHERE users.usernameNorm = ${normalise(req.params.username)}
|
||||
`);
|
||||
|
||||
if (!user || (user.bannedReason !== null && !isAdmin && !isSelf)) {
|
||||
return res.json({
|
||||
profiles: {},
|
||||
});
|
||||
}
|
||||
|
||||
user.emailHash = md5(user.email);
|
||||
delete user.email;
|
||||
user.avatar = await avatar(req.db, user);
|
||||
|
||||
return res.json({
|
||||
...user,
|
||||
profiles: await fetchProfiles(req.db, req.params.username, isSelf),
|
||||
});
|
||||
}));
|
||||
|
||||
router.post('/profile/save', handleErrorAsync(async (req, res) => {
|
||||
|
|
Reference in New Issue