Skip to content

Commit

Permalink
Add customization to login identifier
Browse files Browse the repository at this point in the history
  • Loading branch information
savindi7 committed Apr 2, 2024
1 parent cec3916 commit 856090e
Show file tree
Hide file tree
Showing 24 changed files with 207 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,25 @@
import Box from "@oxygen-ui/react/Box";
import IconButton from "@oxygen-ui/react/IconButton";
import InputAdornment from "@oxygen-ui/react/InputAdornment";
import Link from "@oxygen-ui/react/Link";
import Skeleton from "@oxygen-ui/react/Skeleton";
import Tooltip from "@oxygen-ui/react/Tooltip";
import { IdentifiableComponentInterface } from "@wso2is/core/models";
import { FinalForm, FinalFormField, FormRenderProps, FormSpy, FormState, TextFieldAdapter } from "@wso2is/form";
import { Hint } from "@wso2is/react-components";
import { GenericIcon, Hint } from "@wso2is/react-components";
import cloneDeep from "lodash-es/cloneDeep";
import orderBy from "lodash-es/orderBy";
import React, { FunctionComponent, ReactElement, SVGAttributes, useMemo } from "react";
import { useTranslation } from "react-i18next";
import { Trans, useTranslation } from "react-i18next";
import { useSelector } from "react-redux";
import { AppState } from "../../../admin.core.v1/store";

Check warning on line 33 in features/admin.branding.v1/components/custom-text/custom-text-fields.tsx

View workflow job for this annotation

GitHub Actions / ⬣ ESLint (STATIC ANALYSIS) (lts/*, 8.7.4)

`../../../admin.core.v1/store` import should occur after import of `../../../../themes/default/assets/images/icons/warning-icon.svg`
import { serverConfigurationConfig } from "../../../../extensions/configs/server-configuration";
import { ReactComponent as WarningIcon } from "../../../../themes/default/assets/images/icons/warning-icon.svg";
import { AppConstants } from "../../../core/constants";
import { history } from "../../../core/helpers/history";
import {
ServerConfigurationsConstants
} from "../../../server-configurations/constants/server-configurations-constants";
import { CustomTextPreferenceConstants } from "../../constants/custom-text-preference-constants";
import useBrandingPreference from "../../hooks/use-branding-preference";
import { CustomTextInterface } from "../../models/custom-text-preference";
Expand Down Expand Up @@ -155,6 +163,94 @@ const CustomTextFields: FunctionComponent<CustomTextFieldsProps> = (props: Custo
);
};

const handleMultiAttributeLink = (): void => {
if (serverConfigurationConfig.dynamicConnectors === true) {
history.push(
AppConstants.getPaths().get(
"GOVERNANCE_CONNECTOR_EDIT"
).replace(
":categoryId",
ServerConfigurationsConstants.
ACCOUNT_MANAGEMENT_CONNECTOR_CATEGORY_ID
).replace(
":connectorId",
ServerConfigurationsConstants.
MULTI_ATTRIBUTE_LOGIN_CONNECTOR_ID
)
);
} else {
history.push(AppConstants.getPaths().get("ALTERNATIVE_LOGIN_IDENTIFIER_EDIT"));
}
};

const getMultiAttributeLabel = (): string => {
if (serverConfigurationConfig.dynamicConnectors === true) {
return t("branding:connectors.multiAttributeLogin");
}
else {
return t("branding:connectors.alternativeLoginIdentifier");
}
};

const isMultiAttributeEnabled = (): boolean => {
if (serverConfigurationConfig.dynamicConnectors === true) {
return !serverConfigurationConfig.connectorsToHide
.includes(ServerConfigurationsConstants.MULTI_ATTRIBUTE_LOGIN_CONNECTOR_ID);
}
else {
return !serverConfigurationConfig.connectorsToHide
.includes(ServerConfigurationsConstants.ALTERNATIVE_LOGIN_IDENTIFIER);
}
};

const getHelperText = (hintKey: string, warningKey: string, fieldName: string): ReactElement => {
return i18n.exists(hintKey) || i18n.exists(warningKey)
? (
<Hint>
{ i18n.exists(hintKey) && t(hintKey, { productName }) }
{ i18n.exists(warningKey) && (
<>
<br/><br/>
<GenericIcon
icon={ WarningIcon }
key="warningIcon"
defaultIcon
colored
inline
verticalAlign="middle"
/>&nbsp;
{
isMultiAttributeEnabled() === true
&& (fieldName.replaceAll("_", ".") === CustomTextPreferenceConstants
.TEXT_BUNDLE_KEYS.LOGIN.IDENTIFIER.INPUT.LABEL
|| fieldName.replaceAll("_", ".") === CustomTextPreferenceConstants
.TEXT_BUNDLE_KEYS.PASSWORD_RECOVERY.IDENTIFIER.INPUT.PLACEHOLDER)
? (
<Trans
i18nKey={ warningKey }
values={ {
feature: getMultiAttributeLabel(),
productName: productName
} }
components={ [
<strong key="importantText">IMPORTANT</strong>,
<Link
key="configureLink"
onClick={ handleMultiAttributeLink }
>
configured
</Link>
] }
>
</Trans>
) : t(hintKey)
}
</>
) }
</Hint>
) : null;
};

return (
<div className="branding-preference-custom-text-fields">
<FinalForm
Expand Down Expand Up @@ -192,6 +288,10 @@ const CustomTextFields: FunctionComponent<CustomTextFieldsProps> = (props: Custo
fieldName.replaceAll("_", ".")
}.hint`;

const warningKey: string = `branding:brandingCustomText.form.fields.${
fieldName.replaceAll("_", ".")
}.warning`;

return (
<FinalFormField
key={ fieldName }
Expand All @@ -208,11 +308,7 @@ const CustomTextFields: FunctionComponent<CustomTextFieldsProps> = (props: Custo
placeholder={
t("branding:brandingCustomText.form.genericFieldPlaceholder")
}
helperText={ (
i18n.exists(hintKey) && (
<Hint>{ t(hintKey, { productName }) }</Hint>
)
) }
helperText={ getHelperText(hintKey, warningKey, fieldName) }
component={ TextFieldAdapter }
multiline={ customTextScreenMeta &&
customTextScreenMeta[fieldName.replaceAll("_", ".")]?.MULTI_LINE }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@ const BasicAuthFragment: FunctionComponent<BasicAuthFragmentInterface> = (
<div className="segment-form">
<div className="ui large form">
<div className="field m-0">
<label>Username</label>
<label>
{
i18n(CustomTextPreferenceConstants.TEXT_BUNDLE_KEYS.LOGIN.IDENTIFIER.INPUT.LABEL,
"Username")
}
</label>
<div className="ui fluid left icon input">
<input
type="text"
Expand Down Expand Up @@ -146,7 +151,7 @@ const BasicAuthFragment: FunctionComponent<BasicAuthFragmentInterface> = (
</div>
<div className="mt-4 mb-4">
<div className="mt-3 external-link-container text-small">
{ i18n(CustomTextPreferenceConstants.TEXT_BUNDLE_KEYS.REGISTER_TEXT.MESSAGE,
{ i18n(CustomTextPreferenceConstants.TEXT_BUNDLE_KEYS.REGISTER_TEXT.MESSAGE,
"Don't have an account? ") }
<a
target="_self"
Expand All @@ -155,7 +160,7 @@ const BasicAuthFragment: FunctionComponent<BasicAuthFragmentInterface> = (
rel="noopener noreferrer"
data-testid="login-page-create-account-button"
>
{ i18n(CustomTextPreferenceConstants.TEXT_BUNDLE_KEYS.REGISTER_TEXT.REGISTER,
{ i18n(CustomTextPreferenceConstants.TEXT_BUNDLE_KEYS.REGISTER_TEXT.REGISTER,
"Register") }
</a>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,11 @@ const PasswordRecoveryFragment: FunctionComponent<PasswordRecoveryFragmentInterf
type="text"
id="usernameUserInput"
name="usernameUserInput"
placeholder="Username"
placeholder={
i18n(CustomTextPreferenceConstants
.TEXT_BUNDLE_KEYS.PASSWORD_RECOVERY

Check warning on line 63 in features/admin.branding.v1/components/preview/sign-in-box/fragments/password-recovery-fragment.tsx

View workflow job for this annotation

GitHub Actions / ⬣ ESLint (STATIC ANALYSIS) (lts/*, 8.7.4)

Expected indentation of 44 spaces but found 40
.IDENTIFIER.INPUT.PLACEHOLDER, "Username?")

Check warning on line 64 in features/admin.branding.v1/components/preview/sign-in-box/fragments/password-recovery-fragment.tsx

View workflow job for this annotation

GitHub Actions / ⬣ ESLint (STATIC ANALYSIS) (lts/*, 8.7.4)

Expected indentation of 44 spaces but found 40
}
data-testid="login-page-username-input"
/>
<i aria-hidden="true" className="user outline icon"></i>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,20 @@ export class CustomTextPreferenceConstants {
LOGIN: {
BUTTON: string;
HEADING: string;
IDENTIFIER: {
INPUT: {
LABEL: string;
}
}
};
PASSWORD_RECOVERY: {
HEADING: string;
BODY: string;
IDENTIFIER: {
INPUT: {
PLACEHOLDER: string;
}
}
BUTTON: string;
},
PASSWORD_RESET: {
Expand Down Expand Up @@ -145,12 +155,22 @@ export class CustomTextPreferenceConstants {
},
LOGIN: {
BUTTON: "login.button",
HEADING: "login.heading"
HEADING: "login.heading",
IDENTIFIER: {
INPUT: {
LABEL: "login.identifier.input.label"
}
}
},
PASSWORD_RECOVERY: {
BODY: "password.recovery.body",
BUTTON: "password.recovery.button",
HEADING: "password.recovery.heading"
HEADING: "password.recovery.heading",
IDENTIFIER: {
INPUT: {
PLACEHOLDER: "password.recovery.identifier.input.placeholder"
}
}
},
PASSWORD_RESET: {
BUTTON: "password.reset.button",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ terms.of.service=Terms of Service
# EDITABLE=true,SCREEN="login",MULTI_LINE=false
login.heading=Sign In
# EDITABLE=true,SCREEN="login",MULTI_LINE=false
login.identifier.input.label=Username
# EDITABLE=true,SCREEN="login",MULTI_LINE=false
login.button=Sign In
# <!-- End of Login Screen Translations -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ terms.of.service=Nutzungsbedingungen

# <!-- Start of Login Screen Translations -->
login.heading=Anmelden
login.identifier.input.label=Nutzername
login.button=Anmelden
# <!-- End of Login Screen Translations -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ terms.of.service=Términos de servicio

# <!-- Start of Login Screen Translations -->
login.heading=Iniciar sesión
login.identifier.input.label=Correo electrónico
login.button=Iniciar sesión
# <!-- End of Login Screen Translations -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ terms.of.service=Conditions d'utilisation

# <!-- Start of Login Screen Translations -->
login.heading=Se connecter
login.identifier.input.label=Nom d'utilisateur
login.button=Se connecter
# <!-- End of Login Screen Translations -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ terms.of.service=利用規約

# <!-- Start of Login Screen Translations -->
login.heading=サインイン
login.identifier.input.label=ユーザー名
login.button=サインイン
# <!-- End of Login Screen Translations -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ terms.of.service=Termos de Serviço

# <!-- Start of Login Screen Translations -->
login.heading=Entrar
login.identifier.input.label=Nome de usuário
login.button=Entrar
# <!-- End of Login Screen Translations -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ terms.of.service=Termos de serviço

# <!-- Start of Login Screen Translations -->
login.heading=Entrar
login.identifier.input.label=Nome de usuário
login.button=Entrar
# <!-- End of Login Screen Translations -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ terms.of.service=服务条款

# <!-- Start of Login Screen Translations -->
login.heading=登入
login.identifier.input.label=电子邮件
login.button=登入
# <!-- End of Login Screen Translations -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -475,11 +475,21 @@
<% } %>
<% if (!isIdentifierFirstLogin(inputType) && !isLoginHintAvailable(inputType)) { %>
<div class="field m-0">
<% if (isMultiAttributeLoginEnabledInTenant) { %>
<label><%=usernameLabel %></label>
<% } else { %>
<label><%=AuthenticationEndpointUtil.i18n(resourceBundle, usernameLabel)%></label>
<% } %>
<% String loginInputLabel=i18n(resourceBundle, customText, "login.identifier.input.label" , "", false ); %>

<% if (StringUtils.isNotBlank(loginInputLabel)) { %>
<label>
<%= loginInputLabel %>
</label>
<% } else if (isMultiAttributeLoginEnabledInTenant) { %>
<label>
<%= usernameLabel %>
</label>
<% } else { %>
<label>
<%= AuthenticationEndpointUtil.i18n(resourceBundle, usernameLabel) %>
</label>
<% } %>
<div class="ui fluid left icon input">
<input
type="text"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ password.recovery.heading=Forgot Password?
# EDITABLE=true,SCREEN="password-recovery",MULTI_LINE=true
password.recovery.body=Don't worry, it happens. We will send you an email to reset your password.
# EDITABLE=true,SCREEN="password-recovery",MULTI_LINE=false
password.recovery.identifier.input.placeholder=Username
# EDITABLE=true,SCREEN="password-recovery",MULTI_LINE=false
password.recovery.button=Send Reset Link
# <!-- End of Password Recovery Translations -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ sign.up.button=Registrieren
# <!-- Start of Password Recovery Translations -->
password.recovery.heading=Passwort vergessen?
password.recovery.body=Machen Sie sich keine Sorgen, das kann passieren. Eine E-Mail zum Zurücksetzen Ihres Passwortes wird Ihnen gesendet
password.recovery.identifier.input.placeholder=Nutzername
password.recovery.button=Reset-Link senden
# <!-- End of Password Recovery Translations -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ sign.up.button=Inscribirse
# <!-- Start of Password Recovery Translations -->
password.recovery.heading=¿Has olvidado tu contraseña?
password.recovery.body=No te preocupes, sucede. Le enviaremos un correo electrónico para restablecer su contraseña.
password.recovery.identifier.input.placeholder=Correo electrónico
password.recovery.button=Enviar enlace de reinicio
# <!-- End of Password Recovery Translations -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ sign.up.button=S'inscrire
# <!-- Start of Password Recovery Translations -->
password.recovery.heading=Mot de passe oublié?
password.recovery.body=Ne vous inquiétez pas, ça arrive. Nous vous enverrons un e-mail pour réinitialiser votre mot de passe.
password.recovery.identifier.input.placeholder=Nom d'utilisateur
password.recovery.button=Envoyer le lien de réinitialisation
# <!-- End of Password Recovery Translations -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ sign.up.button=サインアップ
# <!-- Start of Password Recovery Translations -->
password.recovery.heading=パスワード
password.recovery.body=心配する必要はありません。パスワードをリセットするためのメールをお送りします。
password.recovery.identifier.input.placeholder=ユーザー名
password.recovery.button=リセットリンクの送信
# <!-- End of Password Recovery Translations -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ sign.up.button=Cadastrar
# <!-- Start of Password Recovery Translations -->
password.recovery.heading=Esqueceu a senha?
password.recovery.body=Não se preocupe, isso acontece. Enviaremos um e-mail para redefinir sua senha.
password.recovery.identifier.input.placeholder=Nome de usuário
password.recovery.button=Enviar link de redefinição
# <!-- End of Password Recovery Translations -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ sign.up.button=Inscrever-se
# <!-- Start of Password Recovery Translations -->
password.recovery.heading=Esqueceu a senha?
password.recovery.body=Não se preocupe, isso acontece. Enviaremos um e-mail para redefinir sua senha.
password.recovery.identifier.input.placeholder=Nome de usuário
password.recovery.button=Enviar link de redefinição
# <!-- End of Password Recovery Translations -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ sign.up.button=报名
# <!-- Start of Password Recovery Translations -->
password.recovery.heading=密码
password.recovery.body=不用担心,它发生了。我们将向您发送电子邮件以重置您的密码。
password.recovery.identifier.input.placeholder=用户名
password.recovery.button=发送重置链接
# <!-- End of Password Recovery Translations -->

Expand Down
Loading

0 comments on commit 856090e

Please sign in to comment.