Skip to content

481 task update the display name for login methods#501

Closed
memisrose wants to merge 3 commits intodevfrom
481-task-update-the-display-name-for-login-methods
Closed

481 task update the display name for login methods#501
memisrose wants to merge 3 commits intodevfrom
481-task-update-the-display-name-for-login-methods

Conversation

@memisrose
Copy link
Copy Markdown
Contributor

Adding in loginMethodDisplayNames to properly display other login names on login buttons and mapping through list of providers to display each one.

@memisrose memisrose self-assigned this Jan 28, 2025
@memisrose memisrose requested a review from a team as a code owner January 28, 2025 15:22
@memisrose memisrose linked an issue Jan 28, 2025 that may be closed by this pull request
@github-actions
Copy link
Copy Markdown

@CodiumAI-Agent /describe

@QodoAI-Agent
Copy link
Copy Markdown

Title

481 task update the display name for login methods


User description

Adding in loginMethodDisplayNames to properly display other login names on login buttons and mapping through list of providers to display each one.


PR Type

Enhancement


Description

  • Added support for displaying login method display names.

  • Refactored login provider handling to use dynamic mapping.

  • Introduced LoginImages and loginMethodDisplayNames for extensibility.

  • Updated ConfigStore to include loginMethodDisplayNames.


Changes walkthrough 📝

Relevant files
Enhancement
LoginPage.tsx
Refactor login page for dynamic provider handling               

packages/client/src/pages/LoginPage.tsx

  • Introduced LoginImages object for mapping provider images.
  • Updated logic to dynamically render login providers using
    loginMethodDisplayNames.
  • Refactored hardcoded login provider handling to a dynamic loop.
  • Adjusted login type handling to use consistent casing.
  • +67/-68 
    config.store.ts
    Add login method display names to ConfigStore                       

    packages/client/src/stores/config/config.store.ts

  • Added loginMethodDisplayNames to the ConfigStoreInterface.
  • Updated default config object to include loginMethodDisplayNames.
  • +7/-0     

    Need help?
  • Type /help how to ... in the comments thread for any questions about PR-Agent usage.
  • Check out the documentation for more information.
  • @github-actions
    Copy link
    Copy Markdown

    @CodiumAI-Agent /review

    @QodoAI-Agent
    Copy link
    Copy Markdown

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Possible Issue

    The loginDisplayNames mapping logic in the providers.map loop should be validated to ensure it handles cases where provider keys are missing or undefined in loginDisplayNames. This could lead to unexpected behavior or UI inconsistencies.

    // get the provider display names
    const loginDisplayNames = configStore.store.config.loginMethodDisplayNames;
    
    // show the or
    const showOrDivider =
        providers.indexOf('native') > -1 &&
        (providers.indexOf('ms') || providers.indexOf('google'));
    
    return (
        <>
            <Snackbar
                open={snackbar.open}
                anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
                autoHideDuration={6000}
                onClose={() => {
                    setSnackbar({
                        open: false,
                        message: '',
                        color: 'success',
                    });
                }}
            >
                <Alert severity={snackbar.color} sx={{ width: '100%' }}>
                    {snackbar.message}
                </Alert>
            </Snackbar>
            <StyledMain>
                <StyledRow>
                    <StyledScroll>
                        <StyledContent>
                            <div>
                                <StyledLogoBox>
                                    {themeMap.isLogoUrl ? (
                                        <StyledLogo src={themeMap.logo} />
                                    ) : THEME.logo ? (
                                        <StyledLogo src={THEME.logo} />
                                    ) : null}
                                    <StyledLogoText>
                                        {themeMap.name
                                            ? themeMap.name
                                            : THEME.name}
                                    </StyledLogoText>
                                </StyledLogoBox>
                                <Typography variant="h4">Welcome!</Typography>
                                <StyledInstructions variant="body1">
                                    {register
                                        ? 'Register below'
                                        : 'Log in below'}
                                </StyledInstructions>
                            </div>
                            {!register && (
                                <StyledButtonGroup variant="outlined">
                                    {configStore.store.config.providers.includes(
                                        'native',
                                    ) && (
                                        <StyledButtonGroupItem
                                            onClick={() => {
                                                setLoginType('Native');
                                                setSuccess('');
                                                setError('');
                                            }}
                                            selected={loginType === 'Native'}
                                        >
                                            Native
                                        </StyledButtonGroupItem>
                                    )}
                                    {configStore.store.config.providers.includes(
                                        'ldap',
                                    ) && (
                                        <StyledButtonGroupItem
                                            onClick={() => {
                                                setLoginType('LDAP');
                                                setSuccess('');
                                                setError('');
                                            }}
                                            selected={loginType === 'LDAP'}
                                        >
                                            LDAP
                                        </StyledButtonGroupItem>
                                    )}
                                    {configStore.store.config.providers.includes(
                                        'linotp',
                                    ) && (
                                        <StyledButtonGroupItem
                                            onClick={() => {
                                                setLoginType('LinOTP');
                                                setSuccess('');
                                                setError('');
                                            }}
                                            selected={loginType === 'LinOTP'}
                                        >
                                            LinOTP
                                        </StyledButtonGroupItem>
                                    )}
                                </StyledButtonGroup>
                            )}
                            {error && <Alert color="error">{error}</Alert>}
                            {success && (
                                <Alert color="success">{success}</Alert>
                            )}
                            <form>
                                <Stack spacing={2}>
                                    {providers.indexOf('native') > -1 && (
                                        <>
                                            {!showOTPCodeField && register && (
                                                <>
                                                    <Controller
                                                        name={'FIRST_NAME'}
                                                        control={
                                                            registerControl
                                                        }
                                                        rules={{
                                                            required: true,
                                                        }}
                                                        render={({ field }) => {
                                                            return (
                                                                <TextField
                                                                    label="First Name"
                                                                    variant="outlined"
                                                                    size="small"
                                                                    fullWidth
                                                                    value={
                                                                        field.value
                                                                            ? field.value
                                                                            : ''
                                                                    }
                                                                    onChange={(
                                                                        e,
                                                                    ) =>
                                                                        field.onChange(
                                                                            e
                                                                                .target
                                                                                .value,
                                                                        )
                                                                    }
                                                                />
                                                            );
                                                        }}
                                                    />
                                                    <Controller
                                                        name={'LAST_NAME'}
                                                        control={
                                                            registerControl
                                                        }
                                                        rules={{
                                                            required: true,
                                                        }}
                                                        render={({ field }) => {
                                                            return (
                                                                <TextField
                                                                    label="Last Name"
                                                                    size="small"
                                                                    variant="outlined"
                                                                    fullWidth
                                                                    value={
                                                                        field.value
                                                                            ? field.value
                                                                            : ''
                                                                    }
                                                                    onChange={(
                                                                        e,
                                                                    ) =>
                                                                        field.onChange(
                                                                            e
                                                                                .target
                                                                                .value,
                                                                        )
                                                                    }
                                                                />
                                                            );
                                                        }}
                                                    />
                                                    <Controller
                                                        name={'USERNAME'}
                                                        control={
                                                            registerControl
                                                        }
                                                        rules={{
                                                            required: true,
                                                        }}
                                                        render={({ field }) => {
                                                            return (
                                                                <TextField
                                                                    label="Username"
                                                                    size="small"
                                                                    variant="outlined"
                                                                    fullWidth
                                                                    value={
                                                                        field.value
                                                                            ? field.value
                                                                            : ''
                                                                    }
                                                                    onChange={(
                                                                        e,
                                                                    ) =>
                                                                        field.onChange(
                                                                            e
                                                                                .target
                                                                                .value,
                                                                        )
                                                                    }
                                                                />
                                                            );
                                                        }}
                                                    />
                                                    <Controller
                                                        name={'EMAIL'}
                                                        control={
                                                            registerControl
                                                        }
                                                        rules={{
                                                            required: true,
                                                        }}
                                                        render={({ field }) => {
                                                            return (
                                                                <TextField
                                                                    label="Email"
                                                                    error={error.includes(
                                                                        'is not a valid email address',
                                                                    )}
                                                                    helperText={
                                                                        error.includes(
                                                                            'is not a valid email address',
                                                                        ) &&
                                                                        'Please enter a valid email'
                                                                    }
                                                                    size="small"
                                                                    variant="outlined"
                                                                    fullWidth
                                                                    value={
                                                                        field.value
                                                                            ? field.value
                                                                            : ''
                                                                    }
                                                                    onChange={(
                                                                        e,
                                                                    ) =>
                                                                        field.onChange(
                                                                            e
                                                                                .target
                                                                                .value,
                                                                        )
                                                                    }
                                                                />
                                                            );
                                                        }}
                                                    />
                                                    <Controller
                                                        name={'PHONE'}
                                                        control={
                                                            registerControl
                                                        }
                                                        rules={{
                                                            required: false,
                                                        }}
                                                        render={({ field }) => {
                                                            return (
                                                                <TextField
                                                                    label="Phone Number"
                                                                    size="small"
                                                                    variant="outlined"
                                                                    fullWidth
                                                                    value={
                                                                        field.value
                                                                            ? field.value
                                                                            : ''
                                                                    }
                                                                    onChange={(
                                                                        e,
                                                                    ) =>
                                                                        field.onChange(
                                                                            e
                                                                                .target
                                                                                .value,
                                                                        )
                                                                    }
                                                                />
                                                            );
                                                        }}
                                                    />
                                                    <Controller
                                                        name={'EXTENTION'}
                                                        control={
                                                            registerControl
                                                        }
                                                        rules={{
                                                            required: false,
                                                        }}
                                                        render={({ field }) => {
                                                            return (
                                                                <TextField
                                                                    label="Phone Extention"
                                                                    size="small"
                                                                    variant="outlined"
                                                                    fullWidth
                                                                    value={
                                                                        field.value
                                                                            ? field.value
                                                                            : ''
                                                                    }
                                                                    onChange={(
                                                                        e,
                                                                    ) =>
                                                                        field.onChange(
                                                                            e
                                                                                .target
                                                                                .value,
                                                                        )
                                                                    }
                                                                />
                                                            );
                                                        }}
                                                    />
                                                    <Controller
                                                        name={'COUNTRY_CODE'}
                                                        control={
                                                            registerControl
                                                        }
                                                        rules={{
                                                            required: false,
                                                        }}
                                                        render={({ field }) => {
                                                            return (
                                                                <TextField
                                                                    label="Country Code"
                                                                    size="small"
                                                                    variant="outlined"
                                                                    fullWidth
                                                                    value={
                                                                        field.value
                                                                            ? field.value
                                                                            : ''
                                                                    }
                                                                    onChange={(
                                                                        e,
                                                                    ) =>
                                                                        field.onChange(
                                                                            e
                                                                                .target
                                                                                .value,
                                                                        )
                                                                    }
                                                                />
                                                            );
                                                        }}
                                                    />
                                                    <Controller
                                                        name={'PASSWORD'}
                                                        control={
                                                            registerControl
                                                        }
                                                        rules={{
                                                            required: true,
                                                        }}
                                                        render={({ field }) => {
                                                            return (
                                                                <TextField
                                                                    label="Password"
                                                                    error={
                                                                        error.includes(
                                                                            'Passwords do not match',
                                                                        ) ||
                                                                        error.includes(
                                                                            'Password must be at least 8 characters in length',
                                                                        ) ||
                                                                        error.includes(
                                                                            'Password must have atleast one uppercase character',
                                                                        ) ||
                                                                        error.includes(
                                                                            'Password must have atleast one lowercase character',
                                                                        ) ||
                                                                        error.includes(
                                                                            'Password must have atleast one special character among [!,@,#,$,%,^,&,*]',
                                                                        )
                                                                    }
                                                                    helperText={
                                                                        error &&
                                                                        (error.includes(
                                                                            'Password must be at least 8 characters in length',
                                                                        ) ||
                                                                            error.includes(
                                                                                'Password must have atleast one uppercase character',
                                                                            ) ||
                                                                            error.includes(
                                                                                'Password must have atleast one lowercase character',
                                                                            ) ||
                                                                            error.includes(
                                                                                'Password must have atleast one special character among [!,@,#,$,%,^,&,*]',
                                                                            ) ||
                                                                            error.includes(
                                                                                'Password must have atleast one special character among [!,@,#,$,%,^,&,*]',
                                                                            ))
                                                                            ? error.includes(
                                                                                  'Passwords do no match',
                                                                              )
                                                                                ? 'Passwords do not match'
                                                                                : 'Passwords must be at least 8 characters in length and contain one lowercase, one uppercase, one special character.'
                                                                            : ''
                                                                    }
                                                                    size="small"
                                                                    variant="outlined"
                                                                    type="password"
                                                                    fullWidth
                                                                    value={
                                                                        field.value
                                                                            ? field.value
                                                                            : ''
                                                                    }
                                                                    onChange={(
                                                                        e,
                                                                    ) =>
                                                                        field.onChange(
                                                                            e
                                                                                .target
                                                                                .value,
                                                                        )
                                                                    }
                                                                />
                                                            );
                                                        }}
                                                    />
                                                    <Controller
                                                        name={
                                                            'PASSWORD_CONFIRMATION'
                                                        }
                                                        control={
                                                            registerControl
                                                        }
                                                        rules={{
                                                            required: true,
                                                        }}
                                                        render={({ field }) => {
                                                            return (
                                                                <TextField
                                                                    label="Password Confirmation"
                                                                    size="small"
                                                                    error={
                                                                        error.includes(
                                                                            'Passwords do not match',
                                                                        ) ||
                                                                        error.includes(
                                                                            'Password must be at least 8 characters in length',
                                                                        ) ||
                                                                        error.includes(
                                                                            'Password must have atleast one uppercase character',
                                                                        ) ||
                                                                        error.includes(
                                                                            'Password must have atleast one lowercase character',
                                                                        ) ||
                                                                        error.includes(
                                                                            'Password must have atleast one special character among [!,@,#,$,%,^,&,*]',
                                                                        )
                                                                    }
                                                                    helperText={
                                                                        error.includes(
                                                                            'Passwords do not match',
                                                                        ) &&
                                                                        'Passwords do no match'
                                                                    }
                                                                    variant="outlined"
                                                                    type="password"
                                                                    fullWidth
                                                                    value={
                                                                        field.value
                                                                            ? field.value
                                                                            : ''
                                                                    }
                                                                    onChange={(
                                                                        e,
                                                                    ) =>
                                                                        field.onChange(
                                                                            e
                                                                                .target
                                                                                .value,
                                                                        )
                                                                    }
                                                                />
                                                            );
                                                        }}
                                                    />
                                                    <StyledGoBackBox>
                                                        <Button
                                                            fullWidth
                                                            variant={'text'}
                                                            onClick={() =>
                                                                setRegister(
                                                                    false,
                                                                )
                                                            }
                                                        >
                                                            Go Back
                                                        </Button>
                                                        <Button
                                                            fullWidth
                                                            variant={
                                                                'contained'
                                                            }
                                                            onClick={
                                                                registerAccount
                                                            }
                                                        >
                                                            Register Account
                                                        </Button>
                                                    </StyledGoBackBox>
                                                </>
                                            )}
                                            {!showOTPCodeField && !register && (
                                                <>
                                                    <Controller
                                                        name={'USERNAME'}
                                                        control={control}
                                                        rules={{
                                                            required: true,
                                                        }}
                                                        render={({ field }) => {
                                                            return (
                                                                <TextField
                                                                    label="Username"
                                                                    variant="outlined"
                                                                    fullWidth
                                                                    value={
                                                                        field.value
                                                                            ? field.value
                                                                            : ''
                                                                    }
                                                                    onChange={(
                                                                        e,
                                                                    ) =>
                                                                        field.onChange(
                                                                            e
                                                                                .target
                                                                                .value,
                                                                        )
                                                                    }
                                                                />
                                                            );
                                                        }}
                                                    />
                                                    <Controller
                                                        name={'PASSWORD'}
                                                        control={control}
                                                        rules={{
                                                            required: true,
                                                        }}
                                                        render={({ field }) => {
                                                            return (
                                                                <TextField
                                                                    label="Password"
                                                                    variant="outlined"
                                                                    type="password"
                                                                    fullWidth
                                                                    value={
                                                                        field.value
                                                                            ? field.value
                                                                            : ''
                                                                    }
                                                                    onChange={(
                                                                        e,
                                                                    ) =>
                                                                        field.onChange(
                                                                            e
                                                                                .target
                                                                                .value,
                                                                        )
                                                                    }
                                                                />
                                                            );
                                                        }}
                                                    />
                                                </>
                                            )}
                                            {showOTPCodeField && (
                                                <Controller
                                                    name={'OTP_CONFIRM'}
                                                    control={control}
                                                    rules={{
                                                        required: true,
                                                    }}
                                                    render={({ field }) => {
                                                        return (
                                                            <TextField
                                                                label="OTP Confirmation Code"
                                                                variant="outlined"
                                                                fullWidth
                                                                value={
                                                                    field.value
                                                                        ? field.value
                                                                        : ''
                                                                }
                                                                onChange={(e) =>
                                                                    field.onChange(
                                                                        e.target
                                                                            .value,
                                                                    )
                                                                }
                                                            />
                                                        );
                                                    }}
                                                />
                                            )}
                                            {!register && (
                                                <>
                                                    <StyledRememberBox>
                                                        <Controller
                                                            name={
                                                                'REMEMBER_LOGIN'
                                                            }
                                                            control={control}
                                                            rules={{
                                                                required: false,
                                                            }}
                                                            render={({
                                                                field,
                                                            }) => {
                                                                return (
                                                                    <Checkbox
                                                                        label="Keep me logged in"
                                                                        checked={
                                                                            field.value
                                                                        }
                                                                        value={
                                                                            field.value
                                                                                ? field.value
                                                                                : false
                                                                        }
                                                                        onChange={(
                                                                            e: React.ChangeEvent<HTMLInputElement>,
                                                                        ) =>
                                                                            field.onChange(
                                                                                e
                                                                                    .target
                                                                                    .checked,
                                                                            )
                                                                        }
                                                                    />
                                                                );
                                                            }}
                                                        />
                                                        <StyledButtonText
                                                            variant="text"
                                                            onClick={() =>
                                                                setForgotPassword(
                                                                    true,
                                                                )
                                                            }
                                                        >
                                                            Forgot Password
                                                        </StyledButtonText>
                                                    </StyledRememberBox>
                                                    <Button
                                                        fullWidth
                                                        variant={'contained'}
                                                        onClick={login}
                                                        type="submit"
                                                    >
                                                        Login with {loginType}
                                                    </Button>
                                                    <StyledRegisterNowBox>
                                                        Don&apos;t have an
                                                        account?{' '}
                                                        <StyledButtonText
                                                            variant="text"
                                                            onClick={() =>
                                                                setRegister(
                                                                    true,
                                                                )
                                                            }
                                                        >
                                                            Register Now
                                                        </StyledButtonText>
                                                    </StyledRegisterNowBox>
                                                </>
                                            )}
                                        </>
                                    )}
                                    {!register && (
                                        <>
                                            {showOrDivider && (
                                                <>
                                                    <StyledDivider>
                                                        <StyledDividerBox>
                                                            or
                                                        </StyledDividerBox>
                                                    </StyledDivider>
                                                </>
                                            )}
                                            {providers.map((provider, idx) => {
                                                if (
                                                    provider != 'native' &&
                                                    provider !=
                                                        'registration' &&
                                                    provider != 'ldap' &&
                                                    provider != 'linotp'
                                                ) {
                                                    return (
                                                        <StyledAction
                                                            variant="outlined"
                                                            onClick={() => {
                                                                oauth(provider);
                                                            }}
                                                            fullWidth
                                                            key={idx}
                                                        >
                                                            <StyledActionBox>
                                                                <StyledActionImage
                                                                    src={
                                                                        LoginImages[
                                                                            provider
                                                                        ]
                                                                            ? LoginImages[
                                                                                  provider
                                                                              ]
                                                                            : LoginImages[
                                                                                  'other'
                                                                              ]
                                                                    }
                                                                />
                                                                <StyledActionText>
                                                                    {loginDisplayNames[
                                                                        provider
                                                                    ]
                                                                        ? loginDisplayNames[
                                                                              provider
                                                                          ]
                                                                        : provider}
                                                                </StyledActionText>
                                                            </StyledActionBox>
                                                        </StyledAction>
                                                    );
                                                }
    Code Duplication

    The repeated conditional checks for provider values like 'native', 'ldap', and 'linotp' in multiple places could be refactored to improve maintainability and reduce redundancy.

        // set initial selected login type from config.
        if (configStore.store.config.providers.includes('native')) {
            setLoginType('Native');
        } else if (configStore.store.config.providers.includes('ldap')) {
            setLoginType('LDAP');
        } else if (configStore.store.config.providers.includes('linOtp')) {
            setLoginType('LinOTP');
        }
    }, []);
    
    /**
     * Allow the user to login
     */
    const login = handleSubmit(
        async (data: TypeUserLogin): Promise<TypeUserLogin> => {
            // turn on loading
            setIsLoading(true);
    
            if (!data.USERNAME || !data.PASSWORD) {
                setError('Username and Password is Required');
                return;
            }
    
            if (!showOTPCodeField) {
                if (loginType === 'Native') {
                    await configStore
                        .login(data.USERNAME, data.PASSWORD)
                        .then(() => {
                            // noop
                        })
                        .catch((error) => {
                            setError(error.message);
                        })
                        .finally(() => {
                            // turn off loading
                            setIsLoading(false);
                        });
                }
                if (loginType === 'LDAP') {
                    await configStore
                        .loginLDAP(data.USERNAME, data.PASSWORD)
                        .then(() => {
                            // noop
                        })
                        .catch((error) => {
                            setError(error.message);
                        })
                        .finally(() => {
                            // turn off loading
                            setIsLoading(false);
                        });
                }
                if (loginType === 'LinOTP') {
                    await configStore
                        .loginOTP(data.USERNAME, data.PASSWORD)
                        .then(() => {
                            // noop
                            setShowOTPCodeField(true);
                        })
                        .catch((error) => {
                            setError(error.message);
                        })
                        .finally(() => {
                            // turn off loading
                            setIsLoading(false);
                        });
                }
            }
            if (showOTPCodeField) {
                await configStore
                    .confirmOTP(data.OTP_CONFIRM)
                    .then(() => {
                        // noop
                    })
                    .catch((error) => {
                        setError(error.message);
                    })
                    .finally(() => {
                        // turn off loading
                        setIsLoading(false);
                    });
                setShowOTPCodeField(true);
            }
        },
    );
    
    /**
     * Allow the user to login
     */
    const registerAccount = registerSubmit(
        async (data: TypeUserRegister): Promise<TypeUserRegister> => {
            // turn on loading
            setIsLoading(true);
    
            if (
                !data.USERNAME ||
                !data.PASSWORD ||
                !data.PASSWORD_CONFIRMATION ||
                !data.FIRST_NAME ||
                !data.LAST_NAME ||
                !data.EMAIL
            ) {
                setError(
                    'Username, password, password confirmation, email, first and last name are required',
                );
                setIsLoading(false);
                return;
            }
    
            if (data.PASSWORD !== data.PASSWORD_CONFIRMATION) {
                setError('Passwords do not match');
                setIsLoading(false);
                return;
            }
    
            await configStore
                .register(
                    `${data.FIRST_NAME} ${data.LAST_NAME}`,
                    data.USERNAME,
                    data.EMAIL,
                    data.PASSWORD,
                    data.PHONE,
                    data.EXTENTION,
                    data.COUNTRY_CODE,
                )
                .then((res) => {
                    if (res) {
                        setError('');
                        setRegister(false);
                        setSuccess(
                            'Account registration successful. Log in below.',
                        );
                    }
                })
                .catch((error) => {
                    setIsLoading(false);
                    setError(error.message);
                })
                .finally(() => {
                    // turn off loading
                    setIsLoading(false);
                });
        },
    );
    
    /**
     * Login with oauth
     * @param provider - provider to oauth with
     */
    const oauth = async (provider: string) => {
        // turn on loading
        setIsLoading(true);
    
        await configStore
            .oauth(provider)
            .then(() => {
                // turn off loading
                setIsLoading(false);
    
                // noop
                // (handled  by the configStore)
    
                setSnackbar({
                    open: true,
                    message: `Successfully logged in`,
                    color: 'success',
                });
            })
            .catch((error) => {
                // turn off loading
                setIsLoading(false);
    
                setError(error.message);
    
                setSnackbar({
                    open: true,
                    message: error.message,
                    color: 'error',
                });
            });
    };
    
    const themeMap = useMemo(() => {
        const theme = configStore.store.config['theme'];
    
        if (theme && theme['THEME_MAP']) {
            try {
                return JSON.parse(theme['THEME_MAP'] as string);
            } catch {
                return {};
            }
        }
    
        return {};
    }, [Object.keys(configStore.store.config).length]);
    
    // get the path the user is coming from
    const path = (location.state as { from: Location })?.from?.pathname || '/';
    
    // navigate if already logged in
    if (configStore.store.status === 'SUCCESS') {
        return <Navigate to={path} replace />;
    }
    
    // get the proviers
    const providers = [...configStore.store.config.providers];
    
    // get the provider display names
    const loginDisplayNames = configStore.store.config.loginMethodDisplayNames;
    
    // show the or
    const showOrDivider =
        providers.indexOf('native') > -1 &&
        (providers.indexOf('ms') || providers.indexOf('google'));
    
    return (
        <>
            <Snackbar
                open={snackbar.open}
                anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
                autoHideDuration={6000}
                onClose={() => {
                    setSnackbar({
                        open: false,
                        message: '',
                        color: 'success',
                    });
                }}
            >
                <Alert severity={snackbar.color} sx={{ width: '100%' }}>
                    {snackbar.message}
                </Alert>
            </Snackbar>
            <StyledMain>
                <StyledRow>
                    <StyledScroll>
                        <StyledContent>
                            <div>
                                <StyledLogoBox>
                                    {themeMap.isLogoUrl ? (
                                        <StyledLogo src={themeMap.logo} />
                                    ) : THEME.logo ? (
                                        <StyledLogo src={THEME.logo} />
                                    ) : null}
                                    <StyledLogoText>
                                        {themeMap.name
                                            ? themeMap.name
                                            : THEME.name}
                                    </StyledLogoText>
                                </StyledLogoBox>
                                <Typography variant="h4">Welcome!</Typography>
                                <StyledInstructions variant="body1">
                                    {register
                                        ? 'Register below'
                                        : 'Log in below'}
                                </StyledInstructions>
                            </div>
                            {!register && (
                                <StyledButtonGroup variant="outlined">
                                    {configStore.store.config.providers.includes(
                                        'native',
                                    ) && (
                                        <StyledButtonGroupItem
                                            onClick={() => {
                                                setLoginType('Native');
                                                setSuccess('');
                                                setError('');
                                            }}
                                            selected={loginType === 'Native'}
                                        >
                                            Native
                                        </StyledButtonGroupItem>
                                    )}
                                    {configStore.store.config.providers.includes(
                                        'ldap',
                                    ) && (
                                        <StyledButtonGroupItem
                                            onClick={() => {
                                                setLoginType('LDAP');
                                                setSuccess('');
                                                setError('');
                                            }}
                                            selected={loginType === 'LDAP'}
                                        >
                                            LDAP
                                        </StyledButtonGroupItem>
                                    )}
                                    {configStore.store.config.providers.includes(
                                        'linotp',
                                    ) && (
                                        <StyledButtonGroupItem
                                            onClick={() => {
                                                setLoginType('LinOTP');
                                                setSuccess('');
                                                setError('');
                                            }}
                                            selected={loginType === 'LinOTP'}
                                        >
                                            LinOTP
                                        </StyledButtonGroupItem>
                                    )}
                                </StyledButtonGroup>
                            )}
                            {error && <Alert color="error">{error}</Alert>}
                            {success && (
                                <Alert color="success">{success}</Alert>
                            )}
                            <form>
                                <Stack spacing={2}>
                                    {providers.indexOf('native') > -1 && (
                                        <>
                                            {!showOTPCodeField && register && (
                                                <>
                                                    <Controller
                                                        name={'FIRST_NAME'}
                                                        control={
                                                            registerControl
                                                        }
                                                        rules={{
                                                            required: true,
                                                        }}
                                                        render={({ field }) => {
                                                            return (
                                                                <TextField
                                                                    label="First Name"
                                                                    variant="outlined"
                                                                    size="small"
                                                                    fullWidth
                                                                    value={
                                                                        field.value
                                                                            ? field.value
                                                                            : ''
                                                                    }
                                                                    onChange={(
                                                                        e,
                                                                    ) =>
                                                                        field.onChange(
                                                                            e
                                                                                .target
                                                                                .value,
                                                                        )
                                                                    }
                                                                />
                                                            );
                                                        }}
                                                    />
                                                    <Controller
                                                        name={'LAST_NAME'}
                                                        control={
                                                            registerControl
                                                        }
                                                        rules={{
                                                            required: true,
                                                        }}
                                                        render={({ field }) => {
                                                            return (
                                                                <TextField
                                                                    label="Last ...

    @github-actions
    Copy link
    Copy Markdown

    @CodiumAI-Agent /improve

    @QodoAI-Agent
    Copy link
    Copy Markdown

    QodoAI-Agent commented Jan 28, 2025

    PR Code Suggestions ✨

    Latest suggestions up to 2f5b2c0

    CategorySuggestion                                                                                                                                    Impact
    General
    Initialize display names for providers

    Ensure the loginMethodDisplayNames object is initialized with all required provider
    keys to prevent undefined values during runtime.

    packages/client/src/stores/config/config.store.ts [105-107]

     loginMethodDisplayNames: {
    -    provider: '',
    +    native: 'Native',
    +    ldap: 'LDAP',
    +    linOtp: 'LinOTP',
    +    ms: 'Microsoft',
    +    google: 'Google',
    +    okta: 'Okta',
    +    github: 'GitHub',
    +    dropbox: 'Dropbox',
    +    other: 'Other',
     },
    Suggestion importance[1-10]: 9

    __

    Why: Initializing the loginMethodDisplayNames object with all required provider keys ensures that display names are always defined, preventing potential runtime issues. This is a critical improvement for maintaining consistent and error-free UI behavior.

    High
    Add error handling for oauth

    Add a fallback mechanism or error handling for the oauth(provider) function to
    ensure it gracefully handles invalid or unsupported providers.

    packages/client/src/pages/LoginPage.tsx [1207-1208]

     onClick={() => {
    -    oauth(provider);
    +    if (provider && oauth) {
    +        oauth(provider);
    +    } else {
    +        console.error('Invalid provider or oauth function');
    +    }
     }}
    Suggestion importance[1-10]: 7

    __

    Why: Adding error handling for the oauth(provider) function is a good practice to ensure the application gracefully handles invalid or unsupported providers. However, the suggestion could be improved by specifying how unsupported providers should be handled beyond logging an error.

    Medium
    Possible issue
    Add validation for missing provider keys

    Ensure that the loginDisplayNames object is properly validated to handle cases where
    a provider key might be missing or undefined, to avoid potential runtime errors.

    packages/client/src/pages/LoginPage.tsx [1228-1234]

    -{loginDisplayNames[
    -    provider
    -]
    -    ? loginDisplayNames[
    -          provider
    -      ]
    -    : provider}
    +{loginDisplayNames?.[provider] ?? provider}
    Suggestion importance[1-10]: 8

    __

    Why: The suggestion improves robustness by ensuring that missing provider keys in the loginDisplayNames object do not cause runtime errors. The use of optional chaining and nullish coalescing is a concise and effective way to handle this scenario.

    Medium
    Validate image source for providers

    Validate that the LoginImages object contains all expected provider keys to prevent
    undefined image sources during runtime.

    packages/client/src/pages/LoginPage.tsx [1214-1224]

    -LoginImages[
    -    provider
    -]
    -    ? LoginImages[
    -          provider
    -      ]
    -    : LoginImages[
    -          'other'
    -      ]
    +LoginImages?.[provider] ?? LoginImages['other']
    Suggestion importance[1-10]: 8

    __

    Why: This suggestion enhances the code by validating the LoginImages object to avoid undefined image sources, which could lead to broken UI elements. The use of optional chaining and nullish coalescing ensures a fallback image is always provided.

    Medium

    Previous suggestions

    Suggestions up to commit d73d615
    CategorySuggestion                                                                                                                                    Score
    Possible issue
    Add validation for undefined properties

    Ensure that the loginDisplayNames object is properly validated to avoid potential
    runtime errors when accessing undefined properties for providers not listed in the
    configuration.

    packages/client/src/pages/LoginPage.tsx [1228-1230]

    -{loginDisplayNames[provider] ? loginDisplayNames[provider] : provider}
    +{loginDisplayNames?.[provider] ?? provider}
    Suggestion importance[1-10]: 8

    Why: The suggestion improves robustness by using optional chaining and nullish coalescing to handle undefined properties in loginDisplayNames. This prevents potential runtime errors when accessing properties for providers not listed in the configuration.

    8
    General
    Validate provider keys in LoginImages

    Validate that the LoginImages object contains all expected provider keys to prevent
    fallback to the 'other' image for valid providers.

    packages/client/src/pages/LoginPage.tsx [1216-1224]

    -LoginImages[provider] ? LoginImages[provider] : LoginImages['other']
    +LoginImages?.[provider] ?? LoginImages['other']
    Suggestion importance[1-10]: 8

    Why: The suggestion enhances code reliability by using optional chaining and nullish coalescing to ensure that LoginImages gracefully handles missing provider keys, avoiding fallback to the 'other' image unnecessarily.

    8
    Prevent duplicate or invalid providers

    Add a check to ensure that the providers array does not contain duplicate or invalid
    entries to prevent redundant or erroneous UI elements.

    packages/client/src/pages/LoginPage.tsx [1196-1240]

    -providers.map((provider, idx) => {
    -    if (provider != 'native' && provider != 'registration' && provider != 'ldap' && provider != 'linotp') {
    -        return (
    -            ...
    -        );
    -    }
    +[...new Set(providers)].filter(provider => !['native', 'registration', 'ldap', 'linotp'].includes(provider)).map((provider, idx) => {
    +    return (
    +        ...
    +    );
     })
    Suggestion importance[1-10]: 7

    Why: This suggestion improves the UI logic by filtering out duplicate or invalid providers from the providers array. It ensures that only unique and valid providers are rendered, reducing redundancy and potential errors.

    7
    Initialize loginMethodDisplayNames with defaults

    Ensure that the loginMethodDisplayNames object is initialized with meaningful
    default values to avoid potential issues when accessed before being populated.

    packages/client/src/stores/config/config.store.ts [97-99]

     loginMethodDisplayNames: {
    -    provider: '',
    +    provider: 'Default Provider Name',
     },
    Suggestion importance[1-10]: 6

    Why: Initializing loginMethodDisplayNames with meaningful default values improves code safety by ensuring that the object has valid entries before being populated. However, the impact is moderate as it primarily addresses a potential edge case.

    6

    @memisrose memisrose deleted the 481-task-update-the-display-name-for-login-methods branch January 13, 2026 16:24
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Labels

    None yet

    Projects

    None yet

    Development

    Successfully merging this pull request may close these issues.

    [TASK] Update The Display Name for Login Methods

    4 participants