mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-27 23:13:01 -04:00
Merge branch 'indieauth'
This commit is contained in:
commit
cd50208c37
@ -1,16 +1,21 @@
|
||||
<template>
|
||||
<div class="d-flex flex-column flex-md-row justify-content-between align-items-center">
|
||||
<span class="my-2">
|
||||
<Icon :v="providerOptions.icon || provider" set="b"/>
|
||||
<Icon :v="providerOptions.icon || provider" set="b"
|
||||
:class="[providerOptions.icon && providerOptions.icon.endsWith('.png') ? 'mx-1 invertible' : '']"/>
|
||||
{{ providerOptions.name }}
|
||||
<button v-if="providerOptions.deprecated" class="badge bg-light text-dark border border-warning" @click="depreciationNotice(providerOptions.deprecated)">
|
||||
<Icon v="exclamation-triangle"/>
|
||||
<T>user.login.deprecated</T>
|
||||
</button>
|
||||
</span>
|
||||
<span v-if="connection === undefined">
|
||||
<template v-if="providerOptions.instanceRequired">
|
||||
<form v-if="formShown"
|
||||
:action="`${homeUrl}/api/user/social-redirect/${provider}/${config.locale}`"
|
||||
:action="providerOptions.redirectViaHome ? `${homeUrl}/api/user/social-redirect/${provider}/${config.locale}` : `/api/connect/${provider}`"
|
||||
class="input-group input-group-sm">
|
||||
<input type="text" name="instance" class="form-control" autofocus required
|
||||
:placeholder="$t('user.login.instancePlaceholder')"/>
|
||||
:placeholder="$t(providerOptions.domain ? 'user.login.domainPlaceholder' : 'user.login.instancePlaceholder')"/>
|
||||
<button type="submit" class="btn btn-outline-secondary">
|
||||
<Icon v="link"/>
|
||||
</button>
|
||||
@ -20,21 +25,21 @@
|
||||
<T>user.socialConnection.connect</T>
|
||||
</button>
|
||||
</template>
|
||||
<a v-else :href="`${homeUrl}/api/user/social-redirect/${provider}/${config.locale}`" class="badge bg-light text-dark border">
|
||||
<a v-else :href="providerOptions.redirectViaHome ? `${homeUrl}/api/user/social-redirect/${provider}/${config.locale}` : `/api/connect/${provider}`" class="badge bg-light text-dark border">
|
||||
<Icon v="link"/>
|
||||
<T>user.socialConnection.connect</T>
|
||||
</a>
|
||||
</span>
|
||||
<span v-else class="text-center">
|
||||
<span class="mr-3">
|
||||
<a href="#" @click.prevent="$emit('setAvatar', provider)">
|
||||
<span class="me-2">
|
||||
<a v-if="providerOptions.avatars && connection.avatar" href="#" @click.prevent="$emit('setAvatar', provider)">
|
||||
<Avatar :src="connection.avatar" :user="$user()" dsize="2rem"/>
|
||||
</a>
|
||||
{{connection.name}}
|
||||
</span>
|
||||
<br class="d-md-none"/>
|
||||
<a :href="`${homeUrl}/api/user/social-redirect/${provider}/${config.locale}` + (providerOptions.instanceRequired ? '?instance=' + connection.name.split('@')[1] : '')"
|
||||
class="badge bg-light text-dark border">
|
||||
<a :href="(providerOptions.redirectViaHome ? `${homeUrl}/api/user/social-redirect/${provider}/${config.locale}` : `/api/connect/${provider}`) + (providerOptions.instanceRequired ? '?instance=' + connection.name.split('@')[1] : '')"
|
||||
class="badge bg-light text-dark border">
|
||||
<Icon v="sync"/>
|
||||
<T>user.socialConnection.refresh</T>
|
||||
</a>
|
||||
@ -48,31 +53,34 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
provider: { required: true },
|
||||
providerOptions: { required: true },
|
||||
connection: {},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
disconnecting: false,
|
||||
homeUrl: process.env.HOME_URL,
|
||||
formShown: false,
|
||||
export default {
|
||||
props: {
|
||||
provider: { required: true },
|
||||
providerOptions: { required: true },
|
||||
connection: {},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
disconnecting: false,
|
||||
homeUrl: process.env.HOME_URL,
|
||||
formShown: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async disconnect() {
|
||||
await this.$confirm(this.$t('user.socialConnection.disconnectConfirm', {email: this.$user().email}), 'danger');
|
||||
|
||||
this.disconnecting = true;
|
||||
try {
|
||||
const response = await this.$post(`/user/social-connection/${this.provider}/disconnect`);
|
||||
this.$emit('disconnected', response);
|
||||
} finally {
|
||||
this.disconnecting = false;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async disconnect() {
|
||||
await this.$confirm(this.$t('user.socialConnection.disconnectConfirm', {email: this.$user().email}), 'danger');
|
||||
|
||||
this.disconnecting = true;
|
||||
try {
|
||||
const response = await this.$post(`/user/social-connection/${this.provider}/disconnect`);
|
||||
this.$emit('disconnected', response);
|
||||
} finally {
|
||||
this.disconnecting = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
async depreciationNotice(link) {
|
||||
await this.$alert(this.$t('user.login.depreciationNotice', {link}), 'warning');
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@ -3,10 +3,10 @@
|
||||
<Icon :v="options.icon || provider" set="b"/>
|
||||
{{ options.name }}
|
||||
|
||||
<form :action="`${homeUrl}/api/user/social-redirect/${provider}/${config.locale}`"
|
||||
<form :action="link"
|
||||
v-if="options.instanceRequired" class="input-group my-2">
|
||||
<input type="text" name="instance" class="form-control" autofocus required ref="instance"
|
||||
:placeholder="$t('user.login.instancePlaceholder')">
|
||||
:placeholder="$t(options.domain ? 'user.login.domainPlaceholder' : 'user.login.instancePlaceholder')"/>
|
||||
<button type="submit" class="btn btn-outline-primary">
|
||||
<Icon v="arrow-right"/>
|
||||
</button>
|
||||
@ -15,11 +15,20 @@
|
||||
<button v-else-if="options.instanceRequired && !formShown"
|
||||
class="btn btn-outline-primary"
|
||||
@click="showForm">
|
||||
<Icon :v="options.icon || provider" set="b"/>
|
||||
<Icon :v="options.icon || provider" set="b"
|
||||
:class="[options.icon && options.icon.endsWith('.png') ? 'mx-1 invertible' : '']"/>
|
||||
{{ options.name }}
|
||||
</button>
|
||||
<a v-else :href="`${homeUrl}/api/user/social-redirect/${provider}/${config.locale}`"
|
||||
class="btn btn-outline-primary">
|
||||
<a v-else-if="options.deprecated" :href="link"
|
||||
class="btn btn-outline-secondary btn-sm"
|
||||
@click.prevent="depreciationNotice(options.deprecated)"
|
||||
>
|
||||
<Icon :v="options.icon || provider" set="b"/>
|
||||
{{ options.name }}
|
||||
</a>
|
||||
<a v-else :href="link"
|
||||
class="btn btn-outline-primary"
|
||||
>
|
||||
<Icon :v="options.icon || provider" set="b"/>
|
||||
{{ options.name }}
|
||||
</a>
|
||||
@ -37,11 +46,20 @@ export default {
|
||||
formShown: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
link() {
|
||||
return this.options.redirectViaHome ? `${this.homeUrl}/api/user/social-redirect/${this.provider}/${this.config.locale}` : `/api/connect/${this.provider}`
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showForm() {
|
||||
this.formShown = true;
|
||||
this.$nextTick(() => this.$refs.instance.focus());
|
||||
}
|
||||
},
|
||||
async depreciationNotice(link) {
|
||||
await this.$confirm(this.$t('user.login.depreciationNotice', {link}), 'warning');
|
||||
window.location.href = this.link;
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -497,6 +497,12 @@ user:
|
||||
Registering lets you manage your cards ({/@example=like this one}).
|
||||
passwordless: 'The website doesn''t store any passwords. {https://avris.it/blog/passwords-are-passé=More info.}'
|
||||
instancePlaceholder: 'Instance'
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: 'Validate'
|
||||
invalid: 'Invalid code.'
|
||||
|
@ -421,6 +421,13 @@ user:
|
||||
Mit der Registrierung kannst du deine Visitenkarten verwalten ({/@example=wie diese}).
|
||||
passwordless: 'Die Website speichert keine Passwörter. {https://avris.it/blog/passwords-are-passé=Weitere Infos.}'
|
||||
instancePlaceholder: 'Instanz'
|
||||
# TODO
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: 'Validieren'
|
||||
invalid: 'Ungültiger Code.'
|
||||
|
23
locale/en/blog/facebook-login-deprecated.md
Normal file
23
locale/en/blog/facebook-login-deprecated.md
Normal file
@ -0,0 +1,23 @@
|
||||
# We don't recommend using Facebook login
|
||||
|
||||
<small>2022-04-23 | [@andrea](/@andrea)</small>
|
||||
|
||||
We all know that Meta/Facebook is a company that couldn't give a shit about morality or users' privacy.
|
||||
But did you know they're also unfriendly towards developers and try to impose their prudish, conservative views on independent websites?
|
||||
|
||||
This morning they've disabled two apps of mine whose whole purpose was simply to let people log in to a website using their Facebook account.
|
||||
Nothing more, no actual dependency on Facebook, just the “log in with” button.
|
||||
|
||||
Why? One of them, [NakedAdventure](https://naked-adventure.eu/), is a map of nude beaches and contains small amounts of non-sexual nudity.
|
||||
The other, [OurSong](https://oursong.eurovote.eu/), is a harmless game where people vote for their favourite songs
|
||||
– but it's only accessible for members, so Facebook didn't like the fact that they cannot sniff around.
|
||||
They have blocked the apps without notice, making independent websites inaccessible for some users on a whim.
|
||||
|
||||
If they think it's okay to suddenly cut people off other websites just because there was some non-sexual nudity present
|
||||
or because they weren't able to snoop around, who knows if one day they won't block Pronouns.page because of the queer content?
|
||||
After all, in countries like Russia distributing information about LGBTQ+ issues is already considered adult content.
|
||||
|
||||
Users of Pronouns.page seem to dislike Facebook anyway – only 2.76% of you has login with Facebook set up
|
||||
(compared for example to 38,95% of people using login with Twitter).
|
||||
But to those who use it as their primary login option –
|
||||
**we strongly recommend setting up a different login method and ditching Facebook**.
|
@ -521,6 +521,12 @@ user:
|
||||
Registering lets you manage your cards ({/@example=like this one}).
|
||||
passwordless: 'The website doesn''t store any passwords. {https://avris.it/blog/passwords-are-passé=More info.}'
|
||||
instancePlaceholder: 'Instance'
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: 'Validate'
|
||||
invalid: 'Invalid code.'
|
||||
|
@ -482,6 +482,13 @@ user:
|
||||
Registering lets you manage your cards ({/@example=like this one}).
|
||||
passwordless: 'The website doesn''t store any passwords. {https://avris.it/blog/passwords-are-passé=More info.}'
|
||||
instancePlaceholder: 'Instance'
|
||||
# TODO
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: 'Validate'
|
||||
invalid: 'Nevalida kodo.'
|
||||
|
@ -506,6 +506,13 @@ user:
|
||||
Registrarte te permite manejar tus tarjetas ({/@example=como esta}).
|
||||
passwordless: 'Este sitio web no guarda las contraseñas. {https://avris.it/blog/passwords-are-passé=Más información.}'
|
||||
instancePlaceholder: 'Instancia'
|
||||
# TODO
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: 'Validar'
|
||||
invalid: 'Código inválido.'
|
||||
|
@ -424,6 +424,13 @@ user:
|
||||
S’inscrire vous permet de gérer vos cartes ({/@example=comme celle-ci}).
|
||||
passwordless: 'Ce site ne stocke aucun mot de passe. {https://avris.it/blog/passwords-are-passé=Plus d’infos.}'
|
||||
instancePlaceholder: 'Instance'
|
||||
# TODO
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: 'Valider'
|
||||
invalid: 'Code invalide.'
|
||||
|
@ -405,6 +405,13 @@ user:
|
||||
Registrar-se te permite dirigir os cartões ({/@example=como esta}).
|
||||
passwordless: 'O site não grava qualquer senha. {https://avris.it/blog/passwords-are-passé=More info.}'
|
||||
instancePlaceholder: 'Instance' # TODO
|
||||
# TODO
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: 'Validar'
|
||||
invalid: 'Código inválido.'
|
||||
|
@ -498,6 +498,13 @@ user:
|
||||
Registering lets you manage your cards ({/@example=like this one}).
|
||||
passwordless: 'The website doesn''t store any passwords. {https://avris.it/blog/passwords-are-passé=More info.}'
|
||||
instancePlaceholder: 'Instance'
|
||||
# TODO
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: 'Validate'
|
||||
invalid: 'Invalid code.'
|
||||
|
@ -426,6 +426,13 @@ user:
|
||||
ご登録いただいた方は、カードの設定を行うことができます。({/@example=カードの例}).
|
||||
passwordless: 'このウェブサイトはパスワードを保存しません。 {https://avris.it/blog/passwords-are-passé=詳細はこちら。}'
|
||||
instancePlaceholder: 'サーバー'
|
||||
# TODO
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: '確認'
|
||||
invalid: '無効なコード'
|
||||
|
@ -495,6 +495,13 @@ user:
|
||||
등록하면 카드를 ({/@example=이렇게}) 관리할 수 있습니다.
|
||||
passwordless: '웹사이트는 비밀번호를 저장하지 않습니다. {https://avris.it/blog/passwords-are-passé=추가 정보.}'
|
||||
instancePlaceholder: '사례'
|
||||
# TODO
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: '확인'
|
||||
invalid: '유효하지 않은 코드'
|
||||
|
@ -402,6 +402,13 @@ user:
|
||||
Rejistrarte te permete kontentarte tus kartas ({/@example=komo esta}).
|
||||
passwordless: 'Este sitio gueb no guadra las kontrasenyas. {https://avris.it/blog/passwords-are-passé=Mas informasion.}'
|
||||
instancePlaceholder: 'Instansia'
|
||||
# TODO
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: 'Balidar'
|
||||
invalid: 'Kodiche enfirmo.'
|
||||
|
@ -424,6 +424,13 @@ user:
|
||||
Door te registreren kun je een kaart ({/@example=zoals deze}) maken.
|
||||
passwordless: 'De website slaat geen wachtwoorden op. {https://avris.it/blog/passwords-are-passé=Meer info.}'
|
||||
instancePlaceholder: 'Instantie'
|
||||
# TODO
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: 'Valideer'
|
||||
invalid: 'Ongeldige code.'
|
||||
|
@ -401,6 +401,13 @@ user:
|
||||
Å registrere seg lar deg redigere kortene dine ({/@example=sånn som denne}).
|
||||
passwordless: 'Denne nettsiden lagrer ingen passord. {https://avris.it/blog/passwords-are-passé=More info.}'
|
||||
instancePlaceholder: 'Forekomst'
|
||||
# TODO
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: 'Gyldig'
|
||||
invalid: 'Ugyldig kode.'
|
||||
|
@ -1196,6 +1196,12 @@ user:
|
||||
Założenie konta pozwala na zarządzanie swoimi wizytówkami ({/@example=takimi jak ta}).
|
||||
passwordless: 'Strona nie zapisuje żadnych haseł. {https://avris.it/blog/passwords-are-passé=Więcej info.}'
|
||||
instancePlaceholder: 'Instancja'
|
||||
domainPlaceholder: 'Domena'
|
||||
deprecated: 'Odradzane'
|
||||
depreciationNotice: >
|
||||
Ten dostawca uwierzytelniania nie jest godny zaufania.
|
||||
<a href="%link%" target="_blank" rel="noopener">Więcej szczegółów pod tym linkiem</a>.
|
||||
Mocno polecamy włączenie innej metody uwierzytelniania.
|
||||
code:
|
||||
action: 'Sprawdź'
|
||||
invalid: 'Kod nieprawidłowy.'
|
||||
|
@ -427,6 +427,13 @@ user:
|
||||
Registrar-se te permite dirigir os cartões ({/@example=como esta}).
|
||||
passwordless: 'O site não grava qualquer senha. {https://avris.it/blog/passwords-are-passé=More info.}'
|
||||
instancePlaceholder: 'Instância'
|
||||
# TODO
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: 'Validar'
|
||||
invalid: 'Código inválido.'
|
||||
|
@ -518,6 +518,13 @@ user:
|
||||
Регистрация позволяет вам управлять своими аккаунтами/карточками ({/@exemple=как, например, этой}).
|
||||
passwordless: 'Сайт не хранит пароли. {https://avris.it/blog/passwords-are-passé=Больше информации}'
|
||||
instancePlaceholder: 'инстанция'
|
||||
# TODO
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: 'Подтвердить'
|
||||
invalid: 'Неверный код.'
|
||||
|
@ -476,6 +476,13 @@ user:
|
||||
Registering låter dig hantera dina kort ({/@andrea=som det här}).
|
||||
passwordless: 'Webbplatsen lagrar inga lösenord. {https://avris.it/blog/passwords-are-passé=Mer information.}'
|
||||
instancePlaceholder: 'Instans'
|
||||
# TODO
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: 'Bekräfta'
|
||||
invalid: 'Ogiltig kod.'
|
||||
|
@ -541,6 +541,13 @@ user:
|
||||
Реєстрація дозволяє вам управляти своїми акаунтами/картками ({/@exemple=як, наприклад, цією}).
|
||||
passwordless: 'Сайт не зберігає паролі. {https://avris.it/blog/passwords-are-passé=Більше інформації}'
|
||||
instancePlaceholder: 'інстанція'
|
||||
# TODO
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: 'Підтвердити'
|
||||
invalid: 'Невірний код.'
|
||||
|
@ -395,6 +395,13 @@ user:
|
||||
Registering lets you manage your cards ({/@example=like this one}).
|
||||
passwordless: 'The website doesn''t store any passwords. {https://avris.it/blog/passwords-are-passé=More info.}'
|
||||
instancePlaceholder: 'Instance' # TODO
|
||||
# TODO
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: 'Validate'
|
||||
invalid: 'Invalid code.'
|
||||
|
@ -380,6 +380,13 @@ user:
|
||||
註冊可以讓你管理你的卡({/@example=像這個})。
|
||||
passwordless: '該網站不存儲任何密碼。 {https://avris.it/blog/passwords-are-passé=更多信息。}'
|
||||
instancePlaceholder: 'Instance' # TODO
|
||||
# TODO
|
||||
domainPlaceholder: 'Domain'
|
||||
deprecated: 'Deprecated'
|
||||
depreciationNotice: >
|
||||
This is not a reliable authentication provider.
|
||||
<a href="%link%" target="_blank" rel="noopener">Check out this link for more details</a>.
|
||||
We highly recommend making sure that you have a different login method available.
|
||||
code:
|
||||
action: '證實'
|
||||
invalid: '不對代碼'
|
||||
|
@ -42,6 +42,7 @@
|
||||
"nuxt": "^2.15.2",
|
||||
"pageres": "^6.2.3",
|
||||
"qrcode": "^1.5.0",
|
||||
"query-string": "^7.1.1",
|
||||
"rtlcss": "^3.1.2",
|
||||
"sha1": "^1.1.1",
|
||||
"speakeasy": "^2.0.0",
|
||||
|
@ -6,17 +6,25 @@ import SQL from 'sql-template-strings';
|
||||
import fetch from 'node-fetch';
|
||||
import assert from 'assert';
|
||||
import { handleErrorAsync } from "../../src/helpers";
|
||||
import queryString from 'query-string';
|
||||
|
||||
const normalizeDomainName = (domain) => {
|
||||
const url = new URL('https://' + domain);
|
||||
const url = new URL('https://' + domain.replace(/^https?:\/\//, ''));
|
||||
assert(url.port === '');
|
||||
return url.hostname;
|
||||
}
|
||||
|
||||
const baseUrl = process.env.BASE_URL || process.env.HOME_URL || 'https://pronouns.page';
|
||||
|
||||
const config = {
|
||||
mastodon: {
|
||||
scopes: ['read:accounts'],
|
||||
redirect_uri: `${process.env.HOME_URL || 'https://pronouns.page'}/api/user/social/mastodon`,
|
||||
redirect_uri: `${baseUrl}/api/user/social/mastodon`,
|
||||
},
|
||||
indieauth: {
|
||||
server_uri: 'https://indieauth.com/auth',
|
||||
client_id: baseUrl,
|
||||
redirect_uri: `${baseUrl}/api/user/social/indieauth`,
|
||||
},
|
||||
};
|
||||
|
||||
@ -52,6 +60,7 @@ const mastodonGetOAuthKeys = async (db, instance) => {
|
||||
`);
|
||||
return keys;
|
||||
};
|
||||
|
||||
router.get('/connect/mastodon', handleErrorAsync(async (req, res) => {
|
||||
assert(req.query.instance);
|
||||
const instance = normalizeDomainName(req.query.instance);
|
||||
@ -64,6 +73,7 @@ router.get('/connect/mastodon', handleErrorAsync(async (req, res) => {
|
||||
response_type: 'code',
|
||||
}));
|
||||
}));
|
||||
|
||||
router.get('/user/social/mastodon', handleErrorAsync(async (req, res, next) => {
|
||||
if (!req.session.grant || !req.session.grant.instance || !req.query.code) {
|
||||
next();
|
||||
@ -99,7 +109,47 @@ router.get('/user/social/mastodon', handleErrorAsync(async (req, res, next) => {
|
||||
response.instance = instance;
|
||||
req.session.grant.response = response;
|
||||
next();
|
||||
return;
|
||||
}));
|
||||
|
||||
router.get('/connect/indieauth', handleErrorAsync(async (req, res) => {
|
||||
assert(req.query.instance);
|
||||
const instance = normalizeDomainName(req.query.instance);
|
||||
req.session.grant = { instance };
|
||||
res.redirect(`${config.indieauth.server_uri}?` + new URLSearchParams({
|
||||
me: `https://${instance}`,
|
||||
client_id: config.indieauth.client_id,
|
||||
redirect_uri: config.indieauth.redirect_uri,
|
||||
}));
|
||||
}));
|
||||
|
||||
router.get('/user/social/indieauth', handleErrorAsync(async (req, res, next) => {
|
||||
if (!req.session.grant || !req.session.grant.instance || !req.query.code) { next(); return; }
|
||||
|
||||
const response = await fetch(config.indieauth.server_uri, {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
code: req.query.code,
|
||||
client_id: config.indieauth.client_id,
|
||||
redirect_uri: config.indieauth.redirect_uri,
|
||||
}).toString(),
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'User-Agent': 'pronouns.page',
|
||||
},
|
||||
}).then(res => res.text());
|
||||
|
||||
const profile = queryString.parse(response);
|
||||
|
||||
if (!profile || !profile.me) { next(); return; }
|
||||
|
||||
profile.domain = normalizeDomainName(profile.me);
|
||||
|
||||
req.session.grant.response = {
|
||||
profile,
|
||||
instance: req.session.grant.instance,
|
||||
access_token: true,
|
||||
};
|
||||
next();
|
||||
}));
|
||||
|
||||
export default router;
|
||||
|
@ -32,6 +32,7 @@ module.exports.config = {
|
||||
},
|
||||
// non-grant, but things break if it's not there
|
||||
mastodon: {},
|
||||
indieauth: {},
|
||||
}
|
||||
|
||||
module.exports.handlers = {
|
||||
@ -84,6 +85,15 @@ module.exports.handlers = {
|
||||
name: acct,
|
||||
avatar: r.profile.avatar,
|
||||
access_token: r.access_token,
|
||||
instance: r.instance,
|
||||
};
|
||||
},
|
||||
indieauth(r) {
|
||||
return {
|
||||
id: r.profile.me,
|
||||
email: 'indieauth@' + r.profile.domain,
|
||||
name: r.profile.domain,
|
||||
instance: r.instance,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -3,18 +3,36 @@ export const socialProviders = {
|
||||
name: 'Mastodon',
|
||||
instanceRequired: true,
|
||||
linkRegex: (p) => `^https?://(?:www.)?${p.name.split('@')[1]}/(?:(?:web/)?@|users/)?${p.name.split('@')[0]}/?$`,
|
||||
avatars: true,
|
||||
},
|
||||
indieauth: {
|
||||
name: 'IndieAuth',
|
||||
instanceRequired: true,
|
||||
domain: true,
|
||||
icon: 'indieauth.png',
|
||||
iconMargin: true,
|
||||
avatars: false,
|
||||
},
|
||||
twitter: {
|
||||
name: 'Twitter',
|
||||
linkRegex: (p) => `^https?://(?:www.)?twitter.com/${p.name}/?$`,
|
||||
redirectViaHome: true,
|
||||
avatars: true,
|
||||
},
|
||||
discord: {
|
||||
name: 'Discord',
|
||||
},
|
||||
facebook: {
|
||||
name: 'Facebook',
|
||||
redirectViaHome: true,
|
||||
avatars: true,
|
||||
},
|
||||
google: {
|
||||
name: 'Google',
|
||||
redirectViaHome: true,
|
||||
avatars: true,
|
||||
},
|
||||
facebook: {
|
||||
name: 'Facebook',
|
||||
redirectViaHome: true,
|
||||
avatars: false,
|
||||
deprecated: 'https://en.pronouns.page/blog/facebook-login-deprecated',
|
||||
},
|
||||
}
|
||||
|
BIN
static/img/indieauth-inverse.png
Normal file
BIN
static/img/indieauth-inverse.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.4 KiB |
BIN
static/img/indieauth.png
Normal file
BIN
static/img/indieauth.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.4 KiB |
10
yarn.lock
10
yarn.lock
@ -8467,6 +8467,16 @@ query-string@^6.13.8:
|
||||
split-on-first "^1.0.0"
|
||||
strict-uri-encode "^2.0.0"
|
||||
|
||||
query-string@^7.1.1:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.1.tgz#754620669db978625a90f635f12617c271a088e1"
|
||||
integrity sha512-MplouLRDHBZSG9z7fpuAAcI7aAYjDLhtsiVZsevsfaHWDS2IDdORKbSd1kWUA+V4zyva/HZoSfpwnYMMQDhb0w==
|
||||
dependencies:
|
||||
decode-uri-component "^0.2.0"
|
||||
filter-obj "^1.1.0"
|
||||
split-on-first "^1.0.0"
|
||||
strict-uri-encode "^2.0.0"
|
||||
|
||||
querystring-es3@^0.2.0:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
|
||||
|
Loading…
x
Reference in New Issue
Block a user