Skip to content

Commit e40fd76

Browse files
Add resend block duration to email otp
1 parent dcc6363 commit e40fd76

File tree

6 files changed

+202
-65
lines changed

6 files changed

+202
-65
lines changed

features/admin.connections.v1/constants/connection-ui-constants.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ export class ConnectionUIConstants {
109109
OTP_LENGTH_MAX_VALUE: number;
110110
OTP_LENGTH_MIN_LENGTH: number;
111111
OTP_LENGTH_MIN_VALUE: number;
112+
RESEND_BLOCK_DURATION_MIN_VALUE: number;
113+
RESEND_BLOCK_DURATION_MAX_VALUE: number;
114+
RESEND_BLOCK_DURATION_MIN_LENGTH: number;
115+
RESEND_BLOCK_DURATION_MAX_LENGTH: number;
112116

113117
} = {
114118
ALLOWED_RESEND_ATTEMPT_COUNT_MAX_LENGTH: 10000,
@@ -122,7 +126,11 @@ export class ConnectionUIConstants {
122126
OTP_LENGTH_MAX_LENGTH: 2,
123127
OTP_LENGTH_MAX_VALUE: 10,
124128
OTP_LENGTH_MIN_LENGTH: 1,
125-
OTP_LENGTH_MIN_VALUE: 4
129+
OTP_LENGTH_MIN_VALUE: 4,
130+
RESEND_BLOCK_DURATION_MAX_LENGTH: 10000,
131+
RESEND_BLOCK_DURATION_MAX_VALUE: 10000,
132+
RESEND_BLOCK_DURATION_MIN_LENGTH: 0,
133+
RESEND_BLOCK_DURATION_MIN_VALUE: 0
126134
};
127135

128136
/**

features/admin.identity-providers.v1/components/forms/authenticators/email-otp-authenticator-form.tsx

Lines changed: 149 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ interface EmailOTPAuthenticatorFormInitialValuesInterface {
103103
* Number of Email OTP resend attempts
104104
*/
105105
EmailOTP_ResendAttemptsCount: number;
106+
/**
107+
* Time duration to block resend attempts
108+
*/
109+
EmailOTP_ResendBlockDuration: number;
106110
}
107111

108112
/**
@@ -125,6 +129,10 @@ interface EmailOTPAuthenticatorFormFieldsInterface {
125129
* Number of Email OTP resend attempts
126130
*/
127131
EmailOTP_ResendAttemptsCount: CommonAuthenticatorFormFieldInterface;
132+
/**
133+
* Time duration to block resend attempts
134+
*/
135+
EmailOTP_ResendBlockDuration: CommonAuthenticatorFormFieldInterface;
128136
}
129137

130138
/**
@@ -147,6 +155,11 @@ export interface EmailOTPAuthenticatorFormErrorValidationsInterface {
147155
* Number of Email OTP resend attempts
148156
*/
149157
EmailOTP_ResendAttemptsCount: string;
158+
/**
159+
* Time duration to block resend attempts
160+
*/
161+
EmailOTP_ResendBlockDuration: string;
162+
150163
}
151164

152165
const FORM_ID: string = "email-otp-authenticator-form";
@@ -290,8 +303,9 @@ export const EmailOTPAuthenticatorForm: FunctionComponent<EmailOTPAuthenticatorF
290303
const errors: EmailOTPAuthenticatorFormErrorValidationsInterface = {
291304
EmailOTP_ExpiryTime: undefined,
292305
EmailOTP_OTPLength: undefined,
293-
EmailOTP_UseAlphanumericChars: undefined,
294-
EmailOTP_ResendAttemptsCount: undefined
306+
EmailOTP_ResendAttemptsCount: undefined,
307+
EmailOTP_ResendBlockDuration: undefined,
308+
EmailOTP_UseAlphanumericChars: undefined
295309
};
296310

297311
if (!values.EmailOTP_ExpiryTime) {
@@ -329,24 +343,42 @@ export const EmailOTPAuthenticatorForm: FunctionComponent<EmailOTPAuthenticatorF
329343
`.authenticatorSettings.emailOTP.tokenLength.validations.range.${
330344
isOTPAlphanumeric ? "characters" : "digits"
331345
}`);
332-
}
346+
}
347+
333348
if (!values.EmailOTP_ResendAttemptsCount) {
334-
// Check for required error.
335-
errors.EmailOTP_ResendAttemptsCount = t("authenticationProvider:forms" +
349+
// Check for required error.
350+
errors.EmailOTP_ResendAttemptsCount = t("authenticationProvider:forms" +
336351
".authenticatorSettings.emailOTP.allowedResendAttemptCount.validations.required");
337-
} else if (!FormValidation.isInteger(values.EmailOTP_ResendAttemptsCount as unknown as number)) {
338-
// Check for invalid input.
339-
errors.EmailOTP_ResendAttemptsCount = t("authenticationProvider:forms" +
352+
} else if (!FormValidation.isInteger(values.EmailOTP_ResendAttemptsCount as unknown as number)) {
353+
// Check for invalid input.
354+
errors.EmailOTP_ResendAttemptsCount = t("authenticationProvider:forms" +
340355
".authenticatorSettings.emailOTP.allowedResendAttemptCount.validations.invalid");
341-
} else if (values.EmailOTP_ResendAttemptsCount < ConnectionUIConstants
342-
.EMAIL_OTP_AUTHENTICATOR_SETTINGS_FORM_FIELD_CONSTRAINTS.ALLOWED_RESEND_ATTEMPT_COUNT_MIN_VALUE
356+
} else if (values.EmailOTP_ResendAttemptsCount < ConnectionUIConstants
357+
.EMAIL_OTP_AUTHENTICATOR_SETTINGS_FORM_FIELD_CONSTRAINTS.ALLOWED_RESEND_ATTEMPT_COUNT_MIN_VALUE
343358
|| (values.EmailOTP_ResendAttemptsCount > ConnectionUIConstants
344-
.EMAIL_OTP_AUTHENTICATOR_SETTINGS_FORM_FIELD_CONSTRAINTS.ALLOWED_RESEND_ATTEMPT_COUNT_MAX_VALUE)) {
345-
// Check for invalid range.
346-
errors.EmailOTP_ResendAttemptsCount = t("authenticationProvider:forms" +
359+
.EMAIL_OTP_AUTHENTICATOR_SETTINGS_FORM_FIELD_CONSTRAINTS
360+
.ALLOWED_RESEND_ATTEMPT_COUNT_MAX_VALUE)) {
361+
// Check for invalid range.
362+
errors.EmailOTP_ResendAttemptsCount = t("authenticationProvider:forms" +
347363
".authenticatorSettings.emailOTP.allowedResendAttemptCount.validations.range");
348-
}
349-
364+
}
365+
366+
if (!values.EmailOTP_ResendBlockDuration) {
367+
// Check for required error.
368+
errors.EmailOTP_ResendBlockDuration = t("authenticationProvider:forms" +
369+
".authenticatorSettings.emailOTP.resendBlockDuration.validations.required");
370+
} else if (!FormValidation.isInteger(values.EmailOTP_ResendBlockDuration as unknown as number)) {
371+
// Check for invalid input.
372+
errors.EmailOTP_ResendBlockDuration = t("authenticationProvider:forms" +
373+
".authenticatorSettings.emailOTP.resendBlockDuration.validations.invalid");
374+
} else if (values.EmailOTP_ResendBlockDuration < ConnectionUIConstants
375+
.EMAIL_OTP_AUTHENTICATOR_SETTINGS_FORM_FIELD_CONSTRAINTS.RESEND_BLOCK_DURATION_MIN_VALUE
376+
|| (values.EmailOTP_ResendBlockDuration > ConnectionUIConstants
377+
.EMAIL_OTP_AUTHENTICATOR_SETTINGS_FORM_FIELD_CONSTRAINTS.RESEND_BLOCK_DURATION_MAX_VALUE)) {
378+
// Check for invalid range.
379+
errors.EmailOTP_ResendBlockDuration = t("authenticationProvider:forms" +
380+
".authenticatorSettings.emailOTP.resendBlockDuration.validations.range");
381+
}
350382

351383
return errors;
352384
};
@@ -477,59 +509,112 @@ export const EmailOTPAuthenticatorForm: FunctionComponent<EmailOTPAuthenticatorF
477509
}
478510
</Label>
479511
</Field.Input>
480-
<Field.Input
481-
ariaLabel="Allowed Resend Attempts"
482-
inputType="number"
483-
name="EmailOTP_ResendAttemptsCount"
484-
labelPosition="right"
485-
label={
486-
t("authenticationProvider:forms.authenticatorSettings" +
512+
<Field.Input
513+
ariaLabel="Allowed Resend Attempts"
514+
inputType="number"
515+
name="EmailOTP_ResendAttemptsCount"
516+
labelPosition="right"
517+
label={
518+
t("authenticationProvider:forms.authenticatorSettings" +
487519
".emailOTP.allowedResendAttemptCount.label")
488-
}
489-
placeholder={
490-
t("authenticationProvider:forms.authenticatorSettings" +
520+
}
521+
placeholder={
522+
t("authenticationProvider:forms.authenticatorSettings" +
491523
".emailOTP.allowedResendAttemptCount.placeholder")
492-
}
493-
hint={
494-
(<Trans
495-
i18nKey={
496-
"authenticationProvider:forms.authenticatorSettings" +
524+
}
525+
hint={
526+
(<Trans
527+
i18nKey={
528+
"authenticationProvider:forms.authenticatorSettings" +
497529
".emailOTP.allowedResendAttemptCount.hint"
498-
}
499-
>
500-
Users will be limited to the specified resend attempt count when trying to resend the Email OTP
501-
code.
502-
</Trans>)
503-
}
504-
required={ true }
505-
readOnly={ readOnly }
506-
max={
507-
ConnectionUIConstants
508-
.EMAIL_OTP_AUTHENTICATOR_SETTINGS_FORM_FIELD_CONSTRAINTS.ALLOWED_RESEND_ATTEMPT_COUNT_MAX_VALUE
509-
}
510-
min={
511-
ConnectionUIConstants
512-
.EMAIL_OTP_AUTHENTICATOR_SETTINGS_FORM_FIELD_CONSTRAINTS.ALLOWED_RESEND_ATTEMPT_COUNT_MIN_VALUE
513-
}
514-
maxLength={
515-
ConnectionUIConstants
516-
.EMAIL_OTP_AUTHENTICATOR_SETTINGS_FORM_FIELD_CONSTRAINTS.ALLOWED_RESEND_ATTEMPT_COUNT_MAX_LENGTH
517-
}
518-
minLength={
519-
ConnectionUIConstants
520-
.EMAIL_OTP_AUTHENTICATOR_SETTINGS_FORM_FIELD_CONSTRAINTS.ALLOWED_RESEND_ATTEMPT_COUNT_MIN_LENGTH
521-
}
522-
width={ 12 }
523-
data-testid={ `${ testId }-allowed-resend-attempt-count` }
524-
>
525-
<input />
526-
<Label>
527-
{
528-
t("authenticationProvider:forms.authenticatorSettings" +
530+
}
531+
>
532+
Users will be limited to the specified resend attempt count when trying to resend the Email OTP
533+
code.
534+
</Trans>)
535+
}
536+
required={ true }
537+
readOnly={ readOnly }
538+
max={
539+
ConnectionUIConstants
540+
.EMAIL_OTP_AUTHENTICATOR_SETTINGS_FORM_FIELD_CONSTRAINTS.ALLOWED_RESEND_ATTEMPT_COUNT_MAX_VALUE
541+
}
542+
min={
543+
ConnectionUIConstants
544+
.EMAIL_OTP_AUTHENTICATOR_SETTINGS_FORM_FIELD_CONSTRAINTS.ALLOWED_RESEND_ATTEMPT_COUNT_MIN_VALUE
545+
}
546+
maxLength={
547+
ConnectionUIConstants
548+
.EMAIL_OTP_AUTHENTICATOR_SETTINGS_FORM_FIELD_CONSTRAINTS.ALLOWED_RESEND_ATTEMPT_COUNT_MAX_LENGTH
549+
}
550+
minLength={
551+
ConnectionUIConstants
552+
.EMAIL_OTP_AUTHENTICATOR_SETTINGS_FORM_FIELD_CONSTRAINTS.ALLOWED_RESEND_ATTEMPT_COUNT_MIN_LENGTH
553+
}
554+
width={ 12 }
555+
data-testid={ `${ testId }-allowed-resend-attempt-count` }
556+
>
557+
<input />
558+
<Label>
559+
{
560+
t("authenticationProvider:forms.authenticatorSettings" +
529561
".emailOTP.allowedResendAttemptCount.unit")
530-
}
531-
</Label>
532-
</Field.Input>
562+
}
563+
</Label>
564+
</Field.Input>
565+
<Field.Input
566+
ariaLabel="Time duration to block resend attempts"
567+
inputType="number"
568+
name="EmailOTP_ResendBlockDuration"
569+
labelPosition="right"
570+
label={
571+
t("authenticationProvider:forms.authenticatorSettings" +
572+
".emailOTP.resendBlockDuration.label")
573+
}
574+
placeholder={
575+
t("authenticationProvider:forms.authenticatorSettings" +
576+
".emailOTP.resendBlockDuration.placeholder")
577+
}
578+
hint={
579+
(<Trans
580+
i18nKey={
581+
"authenticationProvider:forms.authenticatorSettings" +
582+
".emailOTP.resendBlockDuration.hint"
583+
}
584+
>
585+
Users will be blocked from resending the OTP for the specified duration upon exceeding
586+
the allowed resend attempts.
587+
</Trans>)
588+
}
589+
required={ true }
590+
readOnly={ readOnly }
591+
max={
592+
ConnectionUIConstants
593+
.EMAIL_OTP_AUTHENTICATOR_SETTINGS_FORM_FIELD_CONSTRAINTS.RESEND_BLOCK_DURATION_MAX_VALUE
594+
}
595+
min={
596+
ConnectionUIConstants
597+
.EMAIL_OTP_AUTHENTICATOR_SETTINGS_FORM_FIELD_CONSTRAINTS.RESEND_BLOCK_DURATION_MIN_VALUE
598+
}
599+
maxLength={
600+
ConnectionUIConstants
601+
.EMAIL_OTP_AUTHENTICATOR_SETTINGS_FORM_FIELD_CONSTRAINTS.RESEND_BLOCK_DURATION_MAX_LENGTH
602+
}
603+
minLength={
604+
ConnectionUIConstants
605+
.EMAIL_OTP_AUTHENTICATOR_SETTINGS_FORM_FIELD_CONSTRAINTS.RESEND_BLOCK_DURATION_MIN_LENGTH
606+
}
607+
width={ 12 }
608+
data-testid={ `${ testId }-resend-block-duration` }
609+
>
610+
<input />
611+
<Label>
612+
{
613+
t("authenticationProvider:forms.authenticatorSettings" +
614+
".emailOTP.resendBlockDuration.unit")
615+
}
616+
</Label>
617+
</Field.Input>
533618
<Field.Button
534619
form={ FORM_ID }
535620
size="small"

modules/i18n/src/models/namespaces/authentication-provider-ns.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,17 @@ export interface AuthenticationProviderNS {
296296
range: string;
297297
};
298298
};
299+
resendBlockDuration: {
300+
hint: string;
301+
label: string;
302+
placeholder: string;
303+
unit: string;
304+
validations: {
305+
required: string;
306+
invalid: string;
307+
range: string;
308+
};
309+
};
299310
useAlphanumericChars: {
300311
hint: string;
301312
label: string;

modules/i18n/src/models/namespaces/console-ns.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,16 @@ export interface ConsoleNS {
611611
range: string;
612612
};
613613
};
614+
resendBlockDuration: {
615+
hint: string;
616+
label: string;
617+
placeholder: string;
618+
validations: {
619+
required: string;
620+
invalid: string;
621+
range: string;
622+
};
623+
};
614624
useAlphanumericChars: {
615625
hint: string;
616626
label: string;

modules/i18n/src/translations/en-US/portals/authentication-provider.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,18 @@ export const authenticationProvider:AuthenticationProviderNS = {
314314
required: "Allowed OTP resend attempt count is a required field."
315315
}
316316
},
317+
resendBlockDuration: {
318+
hint: "The duration for which OTP resend is blocked after " +
319+
"exceeding the allowed resend attempt count.",
320+
label: "Resend block duration",
321+
placeholder: "Enter resend block duration.",
322+
unit: "minutes",
323+
validations: {
324+
invalid: "Resend block duration should be an integer.",
325+
range: "Resend block duration should be between 0 & 10000 minutes.",
326+
required: "Resend block duration is a required field."
327+
}
328+
},
317329
useAlphanumericChars: {
318330
hint: "Please check this checkbox to enable alphanumeric "+
319331
"characters. Otherwise numeric characters will be used.",

modules/i18n/src/translations/en-US/portals/console.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,17 @@ export const console: ConsoleNS = {
689689
range: "Allowed OTP resend attempt count should be between 0 & 100."
690690
}
691691
},
692+
resendBlockDuration: {
693+
hint: "The duration for which the user will be blocked from requesting a new OTP " +
694+
"after reaching the maximum allowed resend attempts.",
695+
label: "OTP resend block duration",
696+
placeholder: "Enter OTP resend block duration.",
697+
validations: {
698+
required: "OTP resend block duration is a required field.",
699+
invalid: "OTP resend block duration should be an integer.",
700+
range: "OTP resend block duration should be between 0 & 10000 minutes."
701+
}
702+
},
692703
useAlphanumericChars: {
693704
hint: "Please check this checkbox to enable alphanumeric characters. Otherwise numeric characters will be used.",
694705
label: "Use alphanumeric characters for OTP",

0 commit comments

Comments
 (0)