From 7e4934513a0ca4a5f95e8c8e4a600459911899d5 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Thu, 7 Sep 2023 12:18:46 +0200 Subject: [PATCH] feat(auth): pre-initialize registration fields with information from 3rd-party provider When using a 3rd-party auth provider, we now use the given username & display name information from the provider to fill fields from the profile RegistrationView. Partly addresses #1105 Signed-off-by: Thomas Citharel --- js/src/utils/html.ts | 8 ++++++++ js/src/views/Account/RegisterView.vue | 11 ++++++++++- js/src/views/User/ProviderValidation.vue | 9 +-------- lib/web/controllers/auth_controller.ex | 16 +++++++++++++++- lib/web/views/auth_view.ex | 8 ++++++-- 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/js/src/utils/html.ts b/js/src/utils/html.ts index ffa2dad41..e1baac0b8 100644 --- a/js/src/utils/html.ts +++ b/js/src/utils/html.ts @@ -10,3 +10,11 @@ export function htmlToText(html: string) { template.remove(); return text; } + +export const getValueFromMeta = (name: string): string | null => { + const element = document.querySelector(`meta[name="${name}"]`); + if (element && element.getAttribute("content")) { + return element.getAttribute("content"); + } + return null; +}; diff --git a/js/src/views/Account/RegisterView.vue b/js/src/views/Account/RegisterView.vue index a4191b27b..d9527246a 100644 --- a/js/src/views/Account/RegisterView.vue +++ b/js/src/views/Account/RegisterView.vue @@ -24,7 +24,7 @@ required v-model="identity.name" id="identityName" - @input="(event) => updateUsername(event.target.value)" + @input="(event: any) => updateUsername(event.target.value)" /> @@ -138,6 +138,7 @@ import { registerAccount } from "@/composition/apollo/user"; import { convertToUsername } from "@/utils/username"; import { useI18n } from "vue-i18n"; import { useHead } from "@vueuse/head"; +import { getValueFromMeta } from "@/utils/html"; const props = withDefaults( defineProps<{ @@ -174,6 +175,14 @@ onBeforeMount(() => { if (!props.email) { router.replace({ name: RouteName.PAGE_NOT_FOUND }); } + const username = getValueFromMeta("auth-user-suggested-actor-username"); + const name = getValueFromMeta("auth-user-suggested-actor-name"); + if (username) { + identity.value.preferredUsername = username; + } + if (name) { + identity.value.name = name; + } }); const updateUsername = (value: string) => { diff --git a/js/src/views/User/ProviderValidation.vue b/js/src/views/User/ProviderValidation.vue index 89cabb263..a954ae906 100644 --- a/js/src/views/User/ProviderValidation.vue +++ b/js/src/views/User/ProviderValidation.vue @@ -14,20 +14,13 @@ import { useLazyQuery, useMutation } from "@vue/apollo-composable"; import { useI18n } from "vue-i18n"; import { useHead } from "@vueuse/head"; import { computed, onMounted } from "vue"; +import { getValueFromMeta } from "@/utils/html"; const { t } = useI18n({ useScope: "global" }); useHead({ title: computed(() => t("Redirecting to Mobilizon")), }); -const getValueFromMeta = (name: string): string | null => { - const element = document.querySelector(`meta[name="${name}"]`); - if (element && element.getAttribute("content")) { - return element.getAttribute("content"); - } - return null; -}; - const accessToken = getValueFromMeta("auth-access-token"); const refreshToken = getValueFromMeta("auth-refresh-token"); const userId = getValueFromMeta("auth-user-id"); diff --git a/lib/web/controllers/auth_controller.ex b/lib/web/controllers/auth_controller.ex index 6c9c5081b..17780ff2a 100644 --- a/lib/web/controllers/auth_controller.ex +++ b/lib/web/controllers/auth_controller.ex @@ -71,7 +71,9 @@ defmodule Mobilizon.Web.AuthController do render(conn, "callback.html", %{ access_token: access_token, refresh_token: refresh_token, - user: user + user: user, + username: username_from_ueberauth(auth), + name: display_name_from_ueberauth(auth) }) else err -> @@ -114,6 +116,18 @@ defmodule Mobilizon.Web.AuthController do defp email_from_ueberauth(_), do: nil + defp username_from_ueberauth(%Ueberauth.Auth{info: %Ueberauth.Auth.Info{nickname: nickname}}) + when is_valid_string(nickname), + do: nickname + + defp username_from_ueberauth(_), do: nil + + defp display_name_from_ueberauth(%Ueberauth.Auth{info: %Ueberauth.Auth.Info{name: name}}) + when is_valid_string(name), + do: name + + defp display_name_from_ueberauth(_), do: nil + @spec provider_config(String.t()) :: {:ok, any()} | {:error, :not_supported | :unknown_error} defp provider_config(provider_name) do with ueberauth when is_list(ueberauth) <- Application.get_env(:ueberauth, Ueberauth), diff --git a/lib/web/views/auth_view.ex b/lib/web/views/auth_view.ex index 3ff847669..4e06d0c9c 100644 --- a/lib/web/views/auth_view.ex +++ b/lib/web/views/auth_view.ex @@ -20,7 +20,9 @@ defmodule Mobilizon.Web.AuthView do email: user_email, role: user_role, default_actor_id: user_actor_id - } + }, + username: username, + name: name } = assigns ) do info_tags = [ @@ -29,7 +31,9 @@ defmodule Mobilizon.Web.AuthView do Tag.tag(:meta, name: "auth-user-id", content: user_id), Tag.tag(:meta, name: "auth-user-email", content: user_email), Tag.tag(:meta, name: "auth-user-role", content: String.upcase(to_string(user_role))), - Tag.tag(:meta, name: "auth-user-actor-id", content: user_actor_id) + Tag.tag(:meta, name: "auth-user-actor-id", content: user_actor_id), + Tag.tag(:meta, name: "auth-user-suggested-actor-username", content: username), + Tag.tag(:meta, name: "auth-user-suggested-actor-name", content: name) ] with tags <- Instance.build_tags() ++ info_tags,