Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/4714 update validate user registration request return type #482

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion login-workflow/docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ The `RegistrationContextProvider` manages the state of the registration workflow
- A function that is used to accept the EULA. This function will be called when the user clicks the Next button on the EULA screen.
- **requestRegistrationCode**: _`(email: string) => Promise<string>`_
- A function that is used to request a registration code. This function will be called when the user lands on the Verify Code screen as well as when a user clicks the Resend Verification Code button.
- **validateUserRegistrationRequest**: _`(validationCode: string, validationEmail?: string) => Promise<boolean>`_
- **validateUserRegistrationRequest**: _`(validationCode: string, validationEmail?: string) => Promise<{codeValid: boolean | string; accountExists?: boolean}>`_
- A function that is used to validate a registration code. This function will be called when the user clicks the Next button on the Verify Code screen screen.
- **createPassword**: _`(password: string) => Promise<boolean>`_
- A function that is used to create a password. This function will be called when the user clicks the Next button on the Create Password screen.
Expand Down
2 changes: 1 addition & 1 deletion login-workflow/docs/registration-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ For a detailed explanation of setting up routes, see the [Routing](./routing.md)
| loadEula | `(language: string) => Promise<string>` | A function that is used to load the Eula content. This function will be called when the Eula screen is loaded. | |
| acceptEula | `() => Promise<void>` | A function that is called when the user has accepted the Eula and hit the Next button. | |
| requestRegistrationCode | `(email: string) => Promise<string>` | A function that is used to request a registration code. This function will be called when the user clicks the Next button on the Create Account screen or Resend button on Verify Code screen. | |
| validateUserRegistrationRequest | `(validationCode: string, validationEmail?: string) => Promise<boolean>` | A function that is used to verify registration code. This function will be called when the user clicks the Next button on the Verify Code screen. | |
| validateUserRegistrationRequest | `(validationCode: string, validationEmail?: string) => Promise<{codeValid: boolean | string; accountExists?: boolean}>` | A function that is used to verify registration code. This function will be called when the user clicks the Next button on the Verify Code screen. | |
| createPassword | `(password: string) => Promise<boolean>` | A function that is used to create password. This function will be called when the user clicks the Next button on the Create Password screen. | |
| setAccountDetails | `(details: { firstName: string; lastName: string; extra?: { [key: string]: boolean \| string \| number }}) => Promise<boolean>` | A function that is used to set account details. This function will be called when the user clicks the Next button on the Account Details screen. | |
| completeRegistration | `(userData: any, validationCode: number \| string, validationEmail: string) => Promise<{ email: string; organizationName: string }>` | A function that is used to complete the registration workflow. This function will be called when the user clicks the Next button on the last registration workflow screen. | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,16 @@ export const ProjectRegistrationUIActions: () => RegistrationUIActions = () => (
* @returns Resolves when the code is valid. True if registration is complete, False if account information is needed.
* If the code is not valid a rejection will occur with an error message.
*/
validateUserRegistrationRequest: async (validationCode: string, validationEmail?: string): Promise<boolean> => {
validateUserRegistrationRequest: async (
validationCode: string,
validationEmail?: string
): Promise<{ codeValid: boolean | string; accountExists?: boolean }> => {
await sleep(800);

if (isRandomFailure()) {
throw new Error('Sorry, there was a problem sending your request.');
}
return isRandomFailure();
return { codeValid: true, accountExists: false };
},

completeRegistration: async (userData: object): Promise<{ email: string; organizationName: string }> => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import { parseQueryString } from '../../utils';
import { useErrorManager } from '../../contexts/ErrorContext/useErrorManager';
import ErrorManager, { ErrorManagerProps } from '../Error/ErrorManager';
import { useLanguageLocale } from '../../hooks';

/**
* Component that contain the registration workflow and index of screens.
Expand Down Expand Up @@ -56,12 +57,16 @@ export type RegistrationWorkflowProps = {
export const RegistrationWorkflow: React.FC<React.PropsWithChildren<RegistrationWorkflowProps>> = (props) => {
const [isAccountExist, setIsAccountExist] = useState(false);
const { triggerError, errorManagerConfig } = useErrorManager();
const { t } = useLanguageLocale();
const { actions, navigate } = useRegistrationContext();

const errorDisplayConfig = {
...errorManagerConfig,
...props.errorDisplayConfig,
onClose: (): void => {
if (props.errorDisplayConfig && props.errorDisplayConfig.onClose) props.errorDisplayConfig.onClose();
if (errorManagerConfig.onClose) errorManagerConfig?.onClose();
navigate(-1);
},
};
const {
Expand Down Expand Up @@ -90,7 +95,6 @@ export const RegistrationWorkflow: React.FC<React.PropsWithChildren<Registration
initialScreenIndex < 0 ? 0 : initialScreenIndex > totalScreens - 1 ? totalScreens - 1 : initialScreenIndex
);
const [showSuccessScreen, setShowSuccessScreen] = useState(false);
const { actions, navigate } = useRegistrationContext();

const [screenData, setScreenData] = useState({
Eula: {
Expand All @@ -116,7 +120,11 @@ export const RegistrationWorkflow: React.FC<React.PropsWithChildren<Registration

const updateScreenData = (data: IndividualScreenData): void => {
const { Other }: { [key: string]: any } = screenData;
const { screenId, values } = data;
const { screenId, values, isAccountExist: accountExists } = data;

setIsAccountExist(accountExists);
setShowSuccessScreen(accountExists);

if (!Object.keys(screenData).includes(screenId)) {
setScreenData((oldData) => ({
...oldData,
Expand Down Expand Up @@ -169,7 +177,21 @@ export const RegistrationWorkflow: React.FC<React.PropsWithChildren<Registration
let isAccExist;
void (async (): Promise<void> => {
try {
isAccExist = await actions.validateUserRegistrationRequest(params.code, params.email);
const { codeValid, accountExists } = await actions.validateUserRegistrationRequest(
params.code,
params.email
);
isAccExist = accountExists;

if (!isAccExist) {
if (typeof codeValid === 'string') {
triggerError(new Error(codeValid));
} else if (typeof codeValid === 'boolean' && !codeValid) {
triggerError(
new Error(t('bluiRegistration:SELF_REGISTRATION.VERIFY_EMAIL.CODE_VALIDATOR_ERROR'))
);
}
}
} catch (_error) {
triggerError(_error as Error);
} finally {
Expand Down
5 changes: 4 additions & 1 deletion login-workflow/src/contexts/RegistrationContext/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ export type RegistrationUIActions = {
* @param {string} validationEmail - the provided email address
* @returns Promise<boolean>
*/
validateUserRegistrationRequest?: (validationCode: string, validationEmail?: string) => Promise<boolean>;
validateUserRegistrationRequest?: (
validationCode: string,
validationEmail?: string
) => Promise<{ codeValid: boolean | string; accountExists?: boolean }>;

/**
* A function that is used to create a password. This function will be called when the user clicks the Next button on the Create Password screen
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const VerifyCodeScreen: React.FC<VerifyCodeScreenProps> = (props) => {
const { t } = useLanguageLocale();
const regWorkflow = useRegistrationWorkflowContext();
const { actions } = useRegistrationContext();
const { nextScreen, previousScreen, screenData, currentScreen, totalScreens } = regWorkflow;
const { nextScreen, previousScreen, screenData, currentScreen, totalScreens, updateScreenData } = regWorkflow;
const { emailAddress } = screenData.CreateAccount;
const { triggerError, errorManagerConfig } = useErrorManager();
const errorDisplayConfig = {
Expand Down Expand Up @@ -72,19 +72,34 @@ export const VerifyCodeScreen: React.FC<VerifyCodeScreenProps> = (props) => {
async (code: string) => {
try {
setIsLoading(true);
const isAccExist = await actions.validateUserRegistrationRequest(code);
void nextScreen({
screenId: 'VerifyCode',
values: { code: code },
isAccountExist: isAccExist,
});
const { codeValid, accountExists } = await actions.validateUserRegistrationRequest(code);

if (accountExists) {
updateScreenData({ screenId: 'VerifyCode', values: { code }, isAccountExist: accountExists });
} else {
if (typeof codeValid === 'boolean') {
if (codeValid)
void nextScreen({
screenId: 'VerifyCode',
values: { code },
isAccountExist: accountExists,
});
else {
triggerError(
new Error(t('bluiRegistration:SELF_REGISTRATION.VERIFY_EMAIL.CODE_VALIDATOR_ERROR'))
);
}
} else {
triggerError(new Error(codeValid));
}
}
} catch (_error) {
triggerError(_error as Error);
} finally {
setIsLoading(false);
}
},
[actions, nextScreen, triggerError]
[t, actions, nextScreen, triggerError, updateScreenData]
);

const onPrevious = (code: string): void => {
Expand Down
Loading