From 6775f25425244c587b9e10fa93ef8a7a1cb48cca Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Sat, 16 Mar 2024 07:59:42 -0600 Subject: [PATCH] Automatically infer user language when signing in via Google (#6679) --- plugins/google/server/auth/google.ts | 7 +++++++ server/commands/accountProvisioner.ts | 3 +++ server/commands/userProvisioner.ts | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/plugins/google/server/auth/google.ts b/plugins/google/server/auth/google.ts index aca999bdb..c11b901f0 100644 --- a/plugins/google/server/auth/google.ts +++ b/plugins/google/server/auth/google.ts @@ -4,6 +4,7 @@ import Router from "koa-router"; import capitalize from "lodash/capitalize"; import { Profile } from "passport"; import { Strategy as GoogleStrategy } from "passport-google-oauth2"; +import { languages } from "@shared/i18n"; import { slugifyDomain } from "@shared/utils/domains"; import accountProvisioner from "@server/commands/accountProvisioner"; import { @@ -33,6 +34,7 @@ type GoogleProfile = Profile & { picture: string; _json: { hd?: string; + locale?: string; }; }; @@ -92,6 +94,10 @@ if (env.GOOGLE_CLIENT_ID && env.GOOGLE_CLIENT_SECRET) { // Request a larger size profile picture than the default by tweaking // the query parameter. const avatarUrl = profile.picture.replace("=s96-c", "=s128-c"); + const locale = profile._json.locale; + const language = locale + ? languages.find((l) => l.startsWith(locale)) + : undefined; // if a team can be inferred, we assume the user is only interested in signing into // that team in particular; otherwise, we will do a best effort at finding their account @@ -107,6 +113,7 @@ if (env.GOOGLE_CLIENT_ID && env.GOOGLE_CLIENT_SECRET) { user: { email: profile.email, name: profile.displayName, + language, avatarUrl, }, authenticationProvider: { diff --git a/server/commands/accountProvisioner.ts b/server/commands/accountProvisioner.ts index 11d00f217..e91702fd7 100644 --- a/server/commands/accountProvisioner.ts +++ b/server/commands/accountProvisioner.ts @@ -20,6 +20,8 @@ type Props = { email: string; /** The public url of an image representing the user */ avatarUrl?: string | null; + /** The language of the user, if known */ + language?: string; }; /** Details of the team the user is logging into */ team: { @@ -129,6 +131,7 @@ async function accountProvisioner({ result = await userProvisioner({ name: userParams.name, email: userParams.email, + language: userParams.language, isAdmin: isNewTeam || undefined, avatarUrl: userParams.avatarUrl, teamId: team.id, diff --git a/server/commands/userProvisioner.ts b/server/commands/userProvisioner.ts index 7e3197e5b..801f624dd 100644 --- a/server/commands/userProvisioner.ts +++ b/server/commands/userProvisioner.ts @@ -20,6 +20,8 @@ type Props = { name: string; /** The email address of the user */ email: string; + /** The language of the user, if known */ + language?: string; /** Provision the new user as an administrator */ isAdmin?: boolean; /** The public url of an image representing the user */ @@ -51,6 +53,7 @@ export default async function userProvisioner({ name, email, isAdmin, + language, avatarUrl, teamId, authentication, @@ -233,6 +236,7 @@ export default async function userProvisioner({ { name, email, + language, isAdmin: typeof isAdmin === "boolean" && isAdmin, isViewer: isAdmin === true ? false : defaultUserRole === "viewer", teamId,