diff --git a/src/locales/en.json b/src/locales/en.json index 7a3acb86c..bb2472d47 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -117,9 +117,17 @@ }, "companyServer": { "title": "Login", - "body": "To log in and access your Twake, please enter its URL", + "body": { + "byUrl": "To log in and access your Twake, please enter its URL", + "byEmail": "To log in and access your Twake, please enter your company email address" + }, + "toggle": { + "url": "Enter my Twake URL", + "email": "Enter my company email address" + }, "textFieldLabel": "Url", - "buttonLogin": "Next" + "buttonLogin": "Next", + "companyServerNotFound": "Company server not found" } }, "services": { diff --git a/src/locales/es.json b/src/locales/es.json index 6fdcb48d8..c2db2bc20 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -117,9 +117,17 @@ }, "companyServer": { "title": "Acceso", - "body": "Para conectarse y acceder a su Twake, introduzca su URL", + "body": { + "byUrl": "Para conectarse y acceder a su Twake, introduzca su URL", + "byEmail": "Para conectarse y acceder a su Twake, introduzca la dirección de correo electrónico corporativa" + }, + "toggle": { + "url": "Introduce mi URL de Twake", + "email": "Introduzca la dirección de correo electrónico corporativa" + }, "textFieldLabel": "Url", - "buttonLogin": "Siguiente" + "buttonLogin": "Siguiente", + "companyServerNotFound": "No se ha encontrado el servidor de la corporativa" } }, "services": { diff --git a/src/locales/fr.json b/src/locales/fr.json index b46487cb6..83aeed889 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -117,9 +117,17 @@ }, "companyServer": { "title": "Se connecter", - "body": "Pour vous connecter et accéder à votre Twake, veuillez saisir son URL", + "body": { + "byUrl": "Pour vous connecter et accéder à votre Twake, veuillez saisir son URL", + "byEmail": "Pour vous connecter et accéder à votre Twake, veuillez saisir votre adresse email d'entreprise" + }, + "toggle": { + "url": "Entrer l'URL de mon Twake", + "email": "Entrer mon adresse email d'entreprise" + }, "textFieldLabel": "Serveur", - "buttonLogin": "Suivant" + "buttonLogin": "Suivant", + "companyServerNotFound": "Serveur d'entreprise introuvable" } }, "services": { diff --git a/src/screens/login/components/TwakeCustomServerView.tsx b/src/screens/login/components/TwakeCustomServerView.tsx index 1f3904ff6..5d9cae31e 100644 --- a/src/screens/login/components/TwakeCustomServerView.tsx +++ b/src/screens/login/components/TwakeCustomServerView.tsx @@ -21,6 +21,13 @@ import { Left } from '/ui/Icons/Left' import { Link } from '/ui/Link' import { TextField } from '/ui/TextField' import { Typography } from '/ui/Typography' +import { useHomeStateContext } from '/screens/home/HomeStateProvider' +import { + isOidcOnboardingStartCallback, + processOIDC +} from '/screens/login/components/functions/oidc' +import { useLoadingOverlay } from '/app/view/Loading/LoadingOverlayProvider' +import { getLoginUri } from '/screens/login/components/functions/autodiscovery' const log = Minilog('TwakeCustomServerView') @@ -38,16 +45,24 @@ interface TwakeCustomServerViewProps { close: () => void setInstanceData: setInstanceData startOidcOauthNoCode: startOidcOauthNoCode + startOidcOAuth: startOidcOAuth + startOidcOnboarding: startOidcOnboarding } export const TwakeCustomServerView = ({ openTos, close, setInstanceData, - startOidcOauthNoCode + startOidcOauthNoCode, + startOidcOAuth, + startOidcOnboarding }: TwakeCustomServerViewProps): JSX.Element => { - const [input, setInput] = useState('') + const [isLoginByEmail, setIsLoginByEmail] = useState(true) + const [urlInput, setUrlInput] = useState('') + const [emailInput, setEmailInput] = useState('') const [error, setError] = useState() + const { setOnboardedRedirection } = useHomeStateContext() + const { showOverlay, hideOverlay } = useLoadingOverlay() const version = useMemo(() => getVersion(), []) @@ -63,14 +78,23 @@ export const TwakeCustomServerView = ({ BackHandler.removeEventListener('hardwareBackPress', handleBackPress) }, [handleBackPress]) - const handleInput = (input: string): void => { - setInput(input) + const toggleLoginByEmail = (): void => { + setIsLoginByEmail(!isLoginByEmail) + setError(undefined) + } + + const handleUrlInput = (input: string): void => { + setUrlInput(input) } - const handleLogin = async (): Promise => { + const handleEmailInput = (input: string): void => { + setEmailInput(input) + } + + const handleLoginByUrl = async (): Promise => { setError(undefined) try { - const sanitizedInput = sanitizeUrlInput(input) + const sanitizedInput = sanitizeUrlInput(urlInput) const details = await fetchRegistrationDetails(new URL(sanitizedInput)) @@ -99,6 +123,34 @@ export const TwakeCustomServerView = ({ } } + const handleLoginByEmail = async (): Promise => { + setError(undefined) + try { + const loginUri = await getLoginUri(emailInput) + + if (!loginUri) { + setError(t('screens.companyServer.companyServerNotFound')) + return + } + + showOverlay() + const oidcResult = await processOIDC({ url: loginUri.toString() }, true) + + if (isOidcOnboardingStartCallback(oidcResult)) { + void startOidcOnboarding(oidcResult.onboardUrl, oidcResult.code) + } else { + setOnboardedRedirection(oidcResult.defaultRedirection ?? '') + void startOidcOAuth(oidcResult.fqdn, oidcResult.code) + } + } catch (error: unknown) { + hideOverlay() + if (error !== 'USER_CANCELED') { + // @ts-expect-error error is always a valid type here + setError(getErrorMessage(error), error) + } + } + } + return ( @@ -112,29 +164,68 @@ export const TwakeCustomServerView = ({ {t('screens.companyServer.title')} - - {t('screens.companyServer.body')} - - + {isLoginByEmail ? ( + <> + + {t('screens.companyServer.body.byEmail')} + + + + ) : ( + <> + + {t('screens.companyServer.body.byUrl')} + + + + )} + + + + {isLoginByEmail + ? t('screens.companyServer.toggle.url') + : t('screens.companyServer.toggle.email')} + + + {error && ( {error} @@ -146,7 +237,7 @@ export const TwakeCustomServerView = ({