Fix language and redirection issues when connecting from 3rd-party

Closes #626

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2021-08-09 19:29:15 +02:00
parent c46d8eac3a
commit 0cb43515bc
No known key found for this signature in database
GPG key ID: A061B9DDE0CA0773
7 changed files with 48 additions and 17 deletions

View file

@ -88,6 +88,7 @@ export default class Footer extends Vue {
// eslint-disable-next-line class-methods-use-this // eslint-disable-next-line class-methods-use-this
async updateLocale(locale: string): Promise<void> { async updateLocale(locale: string): Promise<void> {
if (locale) { if (locale) {
console.debug("Setting locale from footer");
await loadLanguageAsync(locale); await loadLanguageAsync(locale);
saveLocaleData(locale); saveLocaleData(locale);
} }

View file

@ -258,13 +258,17 @@ export default class NavBar extends Vue {
// If we don't have any identities, the user has validated their account, // If we don't have any identities, the user has validated their account,
// is logging for the first time but didn't create an identity somehow // is logging for the first time but didn't create an identity somehow
if (this.identities.length === 0) { if (this.identities.length === 0) {
await this.$router.push({ try {
name: RouteName.REGISTER_PROFILE, await this.$router.push({
params: { name: RouteName.REGISTER_PROFILE,
email: this.currentUser.email, params: {
userAlreadyActivated: "true", email: this.currentUser.email,
}, userAlreadyActivated: "true",
}); },
});
} catch (err) {
return undefined;
}
} }
} }
} }
@ -272,6 +276,7 @@ export default class NavBar extends Vue {
@Watch("loggedUser") @Watch("loggedUser")
setSavedLanguage(): void { setSavedLanguage(): void {
if (this.loggedUser?.locale) { if (this.loggedUser?.locale) {
console.debug("Setting locale from navbar");
loadLanguageAsync(this.loggedUser.locale); loadLanguageAsync(this.loggedUser.locale);
} }
} }

View file

@ -8,8 +8,18 @@ import pluralizationRules from "../i18n/pluralRules";
const DEFAULT_LOCALE = "en_US"; const DEFAULT_LOCALE = "en_US";
const localeInLocalStorage = getLocaleData();
console.debug("localeInLocalStorage", localeInLocalStorage);
let language = let language =
getLocaleData() || (document.documentElement.getAttribute("lang") as string); localeInLocalStorage ||
(document.documentElement.getAttribute("lang") as string);
console.debug(
"localeInLocalStorage or fallback to lang html attribute",
language
);
language = language =
language || language ||
@ -18,11 +28,15 @@ language =
"_" "_"
); );
console.debug("language or fallback to window.navigator language", language);
export const locale = export const locale =
language && Object.prototype.hasOwnProperty.call(langs, language) language && Object.prototype.hasOwnProperty.call(langs, language)
? language ? language
: language.split("-")[0]; : language.split("-")[0];
console.debug("chosen locale", locale);
Vue.use(VueI18n); Vue.use(VueI18n);
export const i18n = new VueI18n({ export const i18n = new VueI18n({
@ -35,9 +49,12 @@ export const i18n = new VueI18n({
pluralizationRules, pluralizationRules,
}); });
console.debug("set VueI18n with default locale", DEFAULT_LOCALE);
const loadedLanguages = [DEFAULT_LOCALE]; const loadedLanguages = [DEFAULT_LOCALE];
function setI18nLanguage(lang: string): string { function setI18nLanguage(lang: string): string {
console.debug("setting i18n locale to", lang);
i18n.locale = lang; i18n.locale = lang;
setLanguageInDOM(lang); setLanguageInDOM(lang);
return lang; return lang;
@ -80,14 +97,17 @@ Vue.use(DateFnsPlugin, { locale: dateFnsfileForLanguage(locale) });
export async function loadLanguageAsync(lang: string): Promise<string> { export async function loadLanguageAsync(lang: string): Promise<string> {
// If the same language // If the same language
if (i18n.locale === lang) { if (i18n.locale === lang) {
console.debug("already using language", lang);
return Promise.resolve(setI18nLanguage(lang)); return Promise.resolve(setI18nLanguage(lang));
} }
// If the language was already loaded // If the language was already loaded
if (loadedLanguages.includes(lang)) { if (loadedLanguages.includes(lang)) {
console.debug("language already loaded", lang);
return Promise.resolve(setI18nLanguage(lang)); return Promise.resolve(setI18nLanguage(lang));
} }
// If the language hasn't been loaded yet // If the language hasn't been loaded yet
console.debug("loading language", lang);
const newMessages = await import( const newMessages = await import(
/* webpackChunkName: "lang-[request]" */ `@/i18n/${vueI18NfileForLanguage( /* webpackChunkName: "lang-[request]" */ `@/i18n/${vueI18NfileForLanguage(
lang lang
@ -98,7 +118,9 @@ export async function loadLanguageAsync(lang: string): Promise<string> {
return setI18nLanguage(lang); return setI18nLanguage(lang);
} }
console.debug("loading async locale", locale);
loadLanguageAsync(locale); loadLanguageAsync(locale);
console.debug("loaded async locale", locale);
export function formatList(list: string[]): string { export function formatList(list: string[]): string {
if (window.Intl && Intl.ListFormat) { if (window.Intl && Intl.ListFormat) {

View file

@ -1,3 +1,6 @@
<template>
<p>{{ $t("Redirecting in progress…") }}</p>
</template>
<script lang="ts"> <script lang="ts">
import { Component, Vue } from "vue-property-decorator"; import { Component, Vue } from "vue-property-decorator";
import { ICurrentUserRole } from "@/types/enums"; import { ICurrentUserRole } from "@/types/enums";
@ -52,11 +55,7 @@ export default class ProviderValidate extends Vue {
); );
await this.$router.push({ name: RouteName.HOME }); await this.$router.push({ name: RouteName.HOME });
} else { } else {
// If the user didn't register any profile yet, let's create one for them // No need to push to REGISTER_PROFILE, the navbar will do it for us
await this.$router.push({
name: RouteName.REGISTER_PROFILE,
params: { email: loggedUser.email, userAlreadyActivated: "true" },
});
} }
} }
} }

View file

@ -111,6 +111,9 @@ defmodule Mobilizon.Config do
instance_config()[:languages] instance_config()[:languages]
) )
@spec default_language :: String.t()
def default_language, do: instance_config()[:default_language]
@spec instance_registrations_allowlist :: list(String.t()) @spec instance_registrations_allowlist :: list(String.t())
def instance_registrations_allowlist, do: instance_config()[:registration_email_allowlist] def instance_registrations_allowlist, do: instance_config()[:registration_email_allowlist]

View file

@ -8,7 +8,7 @@ defmodule Mobilizon.Users.User do
import Ecto.Changeset import Ecto.Changeset
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Crypto alias Mobilizon.{Config, Crypto}
alias Mobilizon.Events.FeedToken alias Mobilizon.Events.FeedToken
alias Mobilizon.Users.{ActivitySetting, Setting, UserRole} alias Mobilizon.Users.{ActivitySetting, Setting, UserRole}
alias Mobilizon.Web.Email.Checker alias Mobilizon.Web.Email.Checker
@ -78,7 +78,7 @@ defmodule Mobilizon.Users.User do
field(:reset_password_sent_at, :utc_datetime) field(:reset_password_sent_at, :utc_datetime)
field(:reset_password_token, :string) field(:reset_password_token, :string)
field(:unconfirmed_email, :string) field(:unconfirmed_email, :string)
field(:locale, :string, default: "en") field(:locale, :string, default: Config.default_language())
field(:disabled, :boolean, default: false) field(:disabled, :boolean, default: false)
field(:provider, :string) field(:provider, :string)
field(:last_sign_in_at, :utc_datetime) field(:last_sign_in_at, :utc_datetime)

View file

@ -30,7 +30,8 @@ defmodule Mobilizon.Web.AuthController do
end end
def callback( def callback(
%{assigns: %{ueberauth_auth: %Ueberauth.Auth{strategy: strategy} = auth}} = conn, %{assigns: %{ueberauth_auth: %Ueberauth.Auth{strategy: strategy} = auth, locale: locale}} =
conn,
_params _params
) do ) do
email = email_from_ueberauth(auth) email = email_from_ueberauth(auth)
@ -40,7 +41,7 @@ defmodule Mobilizon.Web.AuthController do
user = user =
with {:valid_email, false} <- {:valid_email, is_nil(email) or email == ""}, with {:valid_email, false} <- {:valid_email, is_nil(email) or email == ""},
{:error, :user_not_found} <- Users.get_user_by_email(email), {:error, :user_not_found} <- Users.get_user_by_email(email),
{:ok, %User{} = user} <- Users.create_external(email, strategy) do {:ok, %User{} = user} <- Users.create_external(email, strategy, %{locale: locale}) do
user user
else else
{:ok, %User{} = user} -> {:ok, %User{} = user} ->