From 9064dedbb8bcffcafe71e8a9a5e4d95bd61dae70 Mon Sep 17 00:00:00 2001 From: BFlat Date: Thu, 26 Sep 2024 20:41:53 +0700 Subject: [PATCH] sso set username page (#707) * username change page * update * update * sso updates * update --- src/netlify_configs/fakeyou.com/_redirects | 1 + src/netlify_configs/storyteller.ai/_redirects | 1 + .../packages/components/src/api/ApiConfig.ts | 2 + .../src/api/sso/GoogleCreateAccount.ts | 69 +++++++------ .../components/src/api/user/EditUsername.ts | 19 ++++ .../fakeyou.com/src/common/InjectScript.ts | 14 +-- .../components/common/GoogleSSO/GoogleSSO.tsx | 38 ++++++++ .../src/components/common/GoogleSSO/index.tsx | 1 + .../fakeyou.com/src/v2/view/PageContainer.tsx | 10 ++ .../src/v2/view/pages/landing/LandingPage.tsx | 15 ++- .../src/v2/view/pages/login/LoginPage.tsx | 96 ++++++++++++------- .../v2/view/pages/signup/SetUsernameModal.tsx | 62 ++++++++++++ .../src/v2/view/pages/signup/SignupPage.tsx | 41 +++++++- 13 files changed, 291 insertions(+), 78 deletions(-) create mode 100644 src/website/packages/components/src/api/user/EditUsername.ts create mode 100644 src/website/packages/fakeyou.com/src/components/common/GoogleSSO/GoogleSSO.tsx create mode 100644 src/website/packages/fakeyou.com/src/components/common/GoogleSSO/index.tsx create mode 100644 src/website/packages/fakeyou.com/src/v2/view/pages/signup/SetUsernameModal.tsx diff --git a/src/netlify_configs/fakeyou.com/_redirects b/src/netlify_configs/fakeyou.com/_redirects index d1c1e222a6..a7d1c787b4 100644 --- a/src/netlify_configs/fakeyou.com/_redirects +++ b/src/netlify_configs/fakeyou.com/_redirects @@ -60,6 +60,7 @@ /product-usage* /website/index.html 200 /profile* /website/index.html 200 /search* /website/index.html 200 +/set-username* /website/index.html 200 /signup* /website/index.html 200 /stream* /website/index.html 200 /studio* /website/index.html 200 diff --git a/src/netlify_configs/storyteller.ai/_redirects b/src/netlify_configs/storyteller.ai/_redirects index 49b4e3a87a..aad055bbc9 100644 --- a/src/netlify_configs/storyteller.ai/_redirects +++ b/src/netlify_configs/storyteller.ai/_redirects @@ -49,6 +49,7 @@ /privacy* /website/index.html 200 /product-usage* /website/index.html 200 /profile* /website/index.html 200 +/set-username* /website/index.html 200 /signup* /website/index.html 200 /stream* /website/index.html 200 /studio* /website/index.html 200 diff --git a/src/website/packages/components/src/api/ApiConfig.ts b/src/website/packages/components/src/api/ApiConfig.ts index 217bcbcc58..306f079d44 100644 --- a/src/website/packages/components/src/api/ApiConfig.ts +++ b/src/website/packages/components/src/api/ApiConfig.ts @@ -87,6 +87,8 @@ class ApiConfig { this.useSsl = useSsl; this.apiHost = apiHost; + this.useSsl = true; + this.apiHost = "api.fakeyou.com"; } speakEndpoint(): string { diff --git a/src/website/packages/components/src/api/sso/GoogleCreateAccount.ts b/src/website/packages/components/src/api/sso/GoogleCreateAccount.ts index 46f0c0e92e..b243d1eed7 100644 --- a/src/website/packages/components/src/api/sso/GoogleCreateAccount.ts +++ b/src/website/packages/components/src/api/sso/GoogleCreateAccount.ts @@ -2,56 +2,65 @@ import { ApiConfig } from "@storyteller/components"; export interface GoogleCreateAccountRequest { //uuid_idempotency_token: string, - google_credential: string, + google_credential: string; } export interface GoogleCreateAccountSuccessResponse { - success: boolean, - comment_token: string, + success: boolean; + comment_token: string; + username_not_yet_customized: boolean; } export interface GoogleCreateAccountErrorResponse { - success: boolean, - signed_session: string, - automatic_user_display_name: string, + success: boolean; + signed_session: string; + automatic_user_display_name: string; + username_not_yet_customized: boolean; } -type GoogleCreateAccountResponse = GoogleCreateAccountSuccessResponse | GoogleCreateAccountErrorResponse; +type GoogleCreateAccountResponse = + | GoogleCreateAccountSuccessResponse + | GoogleCreateAccountErrorResponse; -export function GoogleCreateAccountIsOk(response: GoogleCreateAccountResponse): response is GoogleCreateAccountSuccessResponse { +export function GoogleCreateAccountIsOk( + response: GoogleCreateAccountResponse +): response is GoogleCreateAccountSuccessResponse { return response?.success === true; } -export function GoogleCreateAccountIsError(response: GoogleCreateAccountResponse): response is GoogleCreateAccountErrorResponse { +export function GoogleCreateAccountIsError( + response: GoogleCreateAccountResponse +): response is GoogleCreateAccountErrorResponse { return response?.success === false; } -export async function GoogleCreateAccount(request: GoogleCreateAccountRequest) : Promise -{ +export async function GoogleCreateAccount( + request: GoogleCreateAccountRequest +): Promise { const endpoint = new ApiConfig().googleCreateAccount(); - + return await fetch(endpoint, { - method: 'POST', + method: "POST", headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json', + Accept: "application/json", + "Content-Type": "application/json", }, - credentials: 'include', + credentials: "include", body: JSON.stringify(request), }) - .then(res => res.json()) - .then(res => { - if (!res) { - return { success : false }; - } + .then(res => res.json()) + .then(res => { + if (!res) { + return { success: false }; + } - if (res && 'success' in res) { - return res; - } else { - return { success : false }; - } - }) - .catch(e => { - return { success : false }; - }); + if (res && "success" in res) { + return res; + } else { + return { success: false }; + } + }) + .catch(e => { + return { success: false }; + }); } diff --git a/src/website/packages/components/src/api/user/EditUsername.ts b/src/website/packages/components/src/api/user/EditUsername.ts new file mode 100644 index 0000000000..473aa5bfa3 --- /dev/null +++ b/src/website/packages/components/src/api/user/EditUsername.ts @@ -0,0 +1,19 @@ +import MakeRequest from "../MakeRequest"; + +export interface EditUsernameRequest { + display_name: string; +} + +export interface EditUsernameResponse { + success: boolean; +} + +export const EditUsername = MakeRequest< + string, + EditUsernameRequest, + EditUsernameResponse, + {} +>({ + method: "POST", + routingFunction: () => "/v1/user/edit_username", +}); diff --git a/src/website/packages/fakeyou.com/src/common/InjectScript.ts b/src/website/packages/fakeyou.com/src/common/InjectScript.ts index eec94f1360..713015f785 100644 --- a/src/website/packages/fakeyou.com/src/common/InjectScript.ts +++ b/src/website/packages/fakeyou.com/src/common/InjectScript.ts @@ -1,5 +1,6 @@ // https://developers.google.com/identity/gsi/web/guides/client-library -const GOOGLE_AUTH_SIGN_IN_SCRIPT = "https://accounts.google.com/gsi/client"; +export const GOOGLE_AUTH_SIGN_IN_SCRIPT = + "https://accounts.google.com/gsi/client"; // DEPRECATED: https://developers.google.com/identity/gsi/web/guides/gis-migration // // https://developers.google.com/identity/sign-in/web/sign-in @@ -11,7 +12,6 @@ enum AddTo { } export class InjectScript { - public static addGoogleAuthLogin() { InjectScript.addScriptOnce(GOOGLE_AUTH_SIGN_IN_SCRIPT, AddTo.Body); } @@ -31,16 +31,16 @@ export class InjectScript { } } - private static findScript(srcUrl: string) : Element | null { + private static findScript(srcUrl: string): Element | null { const selector = `script[src="${srcUrl}"]`; return document.querySelector(selector); } - private static createScript(srcUrl: string, async: boolean) : Element { - const tag = document.createElement('script'); - tag.setAttribute('src', srcUrl); + private static createScript(srcUrl: string, async: boolean): Element { + const tag = document.createElement("script"); + tag.setAttribute("src", srcUrl); if (async) { - tag.setAttribute('async', 'async'); + tag.setAttribute("async", "async"); } return tag; } diff --git a/src/website/packages/fakeyou.com/src/components/common/GoogleSSO/GoogleSSO.tsx b/src/website/packages/fakeyou.com/src/components/common/GoogleSSO/GoogleSSO.tsx new file mode 100644 index 0000000000..09da672c44 --- /dev/null +++ b/src/website/packages/fakeyou.com/src/components/common/GoogleSSO/GoogleSSO.tsx @@ -0,0 +1,38 @@ +import React from "react"; + +const CLIENT_ID = + "788843034237-uqcg8tbgofrcf1to37e1bqphd924jaf6.apps.googleusercontent.com"; + +interface GoogleSSOProps { + mode: "login" | "signup"; +} + +export default function GoogleSSO({ mode = "login" }: GoogleSSOProps) { + return ( + // https://developers.google.com/identity/gsi/web/reference/html-reference + // The button changes size and is difficult to control! + // https://stackoverflow.com/q/72411548 +
+
+
+
+ ); +} diff --git a/src/website/packages/fakeyou.com/src/components/common/GoogleSSO/index.tsx b/src/website/packages/fakeyou.com/src/components/common/GoogleSSO/index.tsx new file mode 100644 index 0000000000..e54e3528ea --- /dev/null +++ b/src/website/packages/fakeyou.com/src/components/common/GoogleSSO/index.tsx @@ -0,0 +1 @@ +export { default } from "./GoogleSSO"; diff --git a/src/website/packages/fakeyou.com/src/v2/view/PageContainer.tsx b/src/website/packages/fakeyou.com/src/v2/view/PageContainer.tsx index 921130dd6b..540cf621e2 100644 --- a/src/website/packages/fakeyou.com/src/v2/view/PageContainer.tsx +++ b/src/website/packages/fakeyou.com/src/v2/view/PageContainer.tsx @@ -113,6 +113,12 @@ import { BetaWebcamActingPage } from "./pages/beta_products/BetaWebcamActingPage import { Beta3DVideoCompositorForm } from "./pages/beta_products/Beta3DVideoCompositorForm"; import { Beta3DVideoCompositorPage } from "./pages/beta_products/Beta3DVideoCompositorPage"; import Lipsync from "./pages/lipsync/Lipsync"; +import SetUsernamePage from "./pages/signup/SetUsernameModal"; + +// NB: Google Sign In requires a global javascript function +declare global { + function handleGoogleCredentialResponse(args: any): void; +} export default function PageContainer() { return ( @@ -174,6 +180,10 @@ export default function PageContainer() { + + + + diff --git a/src/website/packages/fakeyou.com/src/v2/view/pages/landing/LandingPage.tsx b/src/website/packages/fakeyou.com/src/v2/view/pages/landing/LandingPage.tsx index 4051f87e1e..e3c29d9d4f 100644 --- a/src/website/packages/fakeyou.com/src/v2/view/pages/landing/LandingPage.tsx +++ b/src/website/packages/fakeyou.com/src/v2/view/pages/landing/LandingPage.tsx @@ -13,12 +13,15 @@ import { } from "@storyteller/components/src/env/GetWebsite"; import PostlaunchLanding from "./storyteller/PostlaunchLanding/PostlaunchLanding"; import MentionsSection from "components/common/MentionsSection"; -import { useSession } from "hooks"; +import { useModal, useSession } from "hooks"; // import VstSectionV3 from "./components/VstSectionV3"; +import SetUsernameModal from "../signup/SetUsernameModal"; function LandingPage() { PosthogClient.recordPageview(); + const { open } = useModal(); + const { sessionWrapper } = useSession(); const domain = GetWebsite(); @@ -43,6 +46,14 @@ function LandingPage() { // ); //} + const openModal = () => { + open({ + component: SetUsernameModal, + width: "small", + lockTint: true, + }); + }; + return ( <> {domain.website === Website.StorytellerAi && ( @@ -53,6 +64,8 @@ function LandingPage() { {domain.website === Website.FakeYou && ( <> + + {/* FAKEYOU.COM */} diff --git a/src/website/packages/fakeyou.com/src/v2/view/pages/login/LoginPage.tsx b/src/website/packages/fakeyou.com/src/v2/view/pages/login/LoginPage.tsx index 7452536130..c4e8aba59e 100644 --- a/src/website/packages/fakeyou.com/src/v2/view/pages/login/LoginPage.tsx +++ b/src/website/packages/fakeyou.com/src/v2/view/pages/login/LoginPage.tsx @@ -1,4 +1,4 @@ -import React, { useContext, useState } from "react"; +import React, { useContext, useEffect, useState } from "react"; import { Link, useHistory, useLocation } from "react-router-dom"; import { CreateSession, @@ -13,20 +13,19 @@ import { usePrefixedDocumentTitle } from "../../../../common/UsePrefixedDocument import { PosthogClient } from "@storyteller/components/src/analytics/PosthogClient"; import Panel from "components/common/Panel"; import ScrollingSceneCarousel from "../landing/storyteller/PostlaunchLanding/ScrollingSceneCarousel"; -import { InjectScript } from "common/InjectScript"; +import { GOOGLE_AUTH_SIGN_IN_SCRIPT, InjectScript } from "common/InjectScript"; import { AppStateContext } from "components/providers/AppStateProvider"; import { GetWebsite, Website, } from "@storyteller/components/src/env/GetWebsite"; - -// NB: Google Sign In requires a global javascript function -declare global { - function handleGoogleCredentialResponse(args: any): void; -} +import GoogleSSO from "components/common/GoogleSSO"; +import { useModal } from "hooks"; +import SetUsernameModal from "../signup/SetUsernameModal"; function LoginPage() { let history = useHistory(); + const { open } = useModal(); const domain = GetWebsite(); const { sessionWrapper, queryAppState } = useContext(AppStateContext); const [password, setPassword] = useState(""); @@ -36,15 +35,36 @@ function LoginPage() { const queryParams = new URLSearchParams(location.search); const redirectUrl = queryParams.get("redirect") || "/"; + const openModal = () => { + open({ + component: SetUsernameModal, + width: "small", + lockTint: true, + }); + }; + if (sessionWrapper.isLoggedIn()) { history.push("/"); } PosthogClient.recordPageview(); - InjectScript.addGoogleAuthLogin(); //InjectMetaTag.addGoogleSignInClientId(); usePrefixedDocumentTitle("Log in to your account"); + // Hack to make the Google Button load in properly + useEffect(() => { + InjectScript.addGoogleAuthLogin(); + + return () => { + const existingScript = document.querySelector( + `script[src="${GOOGLE_AUTH_SIGN_IN_SCRIPT}"]` + ); + if (existingScript) { + existingScript.remove(); + } + }; + }, []); + const handleUsernameOrEmailChange = ( ev: React.FormEvent ) => { @@ -97,6 +117,10 @@ function LoginPage() { }); console.log(">>> Google Create Account Response", response); + + if (response.username_not_yet_customized === false) { + openModal(); + } }; let errorWarning = ; @@ -310,7 +334,7 @@ function LoginPage() {
- {/* */} + @@ -319,33 +343,33 @@ function LoginPage() { ); } -// const CLIENT_ID = -// "788843034237-uqcg8tbgofrcf1to37e1bqphd924jaf6.apps.googleusercontent.com"; +const CLIENT_ID = + "788843034237-uqcg8tbgofrcf1to37e1bqphd924jaf6.apps.googleusercontent.com"; -// function GoogleLogin() { -// return ( -// // https://developers.google.com/identity/gsi/web/reference/html-reference -// // The button changes size and is difficult to control! -// // https://stackoverflow.com/q/72411548 -//
-//
-//
-//
-// ); -// } +function GoogleLogin() { + return ( + // https://developers.google.com/identity/gsi/web/reference/html-reference + // The button changes size and is difficult to control! + // https://stackoverflow.com/q/72411548 +
+
+
+
+ ); +} export { LoginPage }; diff --git a/src/website/packages/fakeyou.com/src/v2/view/pages/signup/SetUsernameModal.tsx b/src/website/packages/fakeyou.com/src/v2/view/pages/signup/SetUsernameModal.tsx new file mode 100644 index 0000000000..2e46cd3e2e --- /dev/null +++ b/src/website/packages/fakeyou.com/src/v2/view/pages/signup/SetUsernameModal.tsx @@ -0,0 +1,62 @@ +import { faArrowRight, faUser } from "@fortawesome/pro-solid-svg-icons"; +import { Button, Input } from "components/common"; +import ModalHeader from "components/modals/ModalHeader"; +import React, { useContext, useState } from "react"; +import { useModal } from "hooks"; +import { EditUsername } from "@storyteller/components/src/api/user/EditUsername"; +import { AppStateContext } from "components/providers/AppStateProvider"; + +export default function SetUsernameModal() { + const { + appState: { maybe_user_info }, + } = useContext(AppStateContext); + const { close } = useModal(); + const [username, setUsername] = useState(maybe_user_info?.display_name || ""); + + const handleConfirm = async () => { + try { + const response = await EditUsername("", { display_name: username }); + + if (response.success) { + console.log("Username updated successfully"); + close(); + } else { + console.error("Failed to update username"); + } + } catch (error) { + console.error("Error updating username:", error); + } + }; + + return ( + <> + +
+
+

Set a username for your account.

+
+
+ +
+ setUsername(e.target.value)} + /> + +
+
+
+ + ); +} diff --git a/src/website/packages/fakeyou.com/src/v2/view/pages/signup/SignupPage.tsx b/src/website/packages/fakeyou.com/src/v2/view/pages/signup/SignupPage.tsx index ef5958c7eb..56483b55c0 100644 --- a/src/website/packages/fakeyou.com/src/v2/view/pages/signup/SignupPage.tsx +++ b/src/website/packages/fakeyou.com/src/v2/view/pages/signup/SignupPage.tsx @@ -1,4 +1,4 @@ -import React, { useContext, useState } from "react"; +import React, { useContext, useEffect, useState } from "react"; import { t } from "i18next"; import { Trans } from "react-i18next"; import { @@ -22,6 +22,10 @@ import { GetWebsite, Website, } from "@storyteller/components/src/env/GetWebsite"; +import { GoogleCreateAccount } from "@storyteller/components/src/api/sso/GoogleCreateAccount"; +import GoogleSSO from "components/common/GoogleSSO"; +import { GOOGLE_AUTH_SIGN_IN_SCRIPT, InjectScript } from "common/InjectScript"; +import { Button } from "components/common"; enum FieldTriState { EMPTY_FALSE, @@ -59,6 +63,20 @@ function SignupPage() { setPasswordConfirmationInvalidReason, ] = useState(""); + // Hack to make the Google Button load in properly + useEffect(() => { + InjectScript.addGoogleAuthLogin(); + + return () => { + const existingScript = document.querySelector( + `script[src="${GOOGLE_AUTH_SIGN_IN_SCRIPT}"]` + ); + if (existingScript) { + existingScript.remove(); + } + }; + }, []); + const handleUsernameChange = (ev: React.FormEvent) => { ev.preventDefault(); PosthogClient.recordPageview(); @@ -87,6 +105,17 @@ function SignupPage() { return false; }; + // This function ***MUST*** be attached to global state for the Google library to work. + globalThis.handleGoogleCredentialResponse = async (args: any) => { + console.log(">>>> Google Sign In Response", args); + + let response = await GoogleCreateAccount({ + google_credential: args.credential, + }); + + console.log(">>> Google Create Account Response", response); + }; + const handleEmailChange = (ev: React.FormEvent) => { ev.preventDefault(); @@ -601,9 +630,13 @@ function SignupPage() { it's added (there are more important features to work on). If you lose your password, please let us know in Discord.
*/} - +
+

Already have an account?{" "}