Skip to content

Commit

Permalink
Merge pull request #44 from ase-101/release-1.x.x
Browse files Browse the repository at this point in the history
ES-715 ES-641
  • Loading branch information
ase-101 authored Jan 31, 2024
2 parents 9d0f84a + 6cce093 commit 77d3b81
Show file tree
Hide file tree
Showing 17 changed files with 133 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.mosip.signup;

import io.mosip.esignet.core.config.RedisCacheConfig;
import io.mosip.esignet.core.config.SimpleCacheConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
Expand All @@ -10,7 +12,8 @@
@SpringBootApplication(scanBasePackages = "io.mosip.signup.*," +
"io.mosip.esignet.core.config.RedisCacheConfig," +
"io.mosip.esignet.core.config.SimpleCacheConfig,"+
"${mosip.auth.adapter.impl.basepackage}")
"${mosip.auth.adapter.impl.basepackage}",
scanBasePackageClasses = {SimpleCacheConfig.class, RedisCacheConfig.class})
public class SignUpServiceApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ public class GenerateChallengeRequest {
private String locale;
private boolean regenerate;

@io.mosip.signup.validator.Purpose
private Purpose purpose;
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,10 @@ public class Identity implements Serializable {

@JsonInclude(JsonInclude.Include.NON_NULL)
private List<String> selectedHandles;

@JsonInclude(JsonInclude.Include.NON_NULL)
private Boolean phoneVerified;

@JsonInclude(JsonInclude.Include.NON_NULL)
private Long updatedAt;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
@Slf4j
@Service
public class CacheUtilService {

@Autowired
CacheManager cacheManager;

Expand All @@ -40,9 +41,9 @@ public RegistrationTransaction setRegisteredTransaction(String transactionId,
return registrationTransaction;
}

@Cacheable(value = SignUpConstants.BLOCKED_IDENTIFIER, key = "#identifierHash")
public String blockIdentifier(String identifierHash) {
return identifierHash;
@Cacheable(value = SignUpConstants.BLOCKED_IDENTIFIER, key = "#key")
public String blockIdentifier(String key, String value) {
return value;
}

@Cacheable(value = SignUpConstants.KEYSTORE, key = "#key")
Expand Down Expand Up @@ -71,8 +72,7 @@ public RegistrationTransaction getRegisteredTransaction(String transactionId) {
public boolean isIdentifierBlocked(String identifier) {
String identifierHash = IdentityProviderUtil.generateB64EncodedHash(IdentityProviderUtil.ALGO_SHA3_256,
identifier.toLowerCase(Locale.ROOT));
String value = cacheManager.getCache(SignUpConstants.BLOCKED_IDENTIFIER).get(identifierHash, String.class);
return value == null ? false : true;
return cacheManager.getCache(SignUpConstants.BLOCKED_IDENTIFIER).get(identifierHash, String.class) != null;
}

public String getSecretKey(String keyAlias) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@

import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -157,8 +159,8 @@ public GenerateChallengeResponse generateChallenge(GenerateChallengeRequest gene
cacheUtilService.setChallengeGeneratedTransaction(transactionId, transaction);

//Resend attempts exhausted, block the identifier for configured time.
if(transaction.getChallengeRetryAttempts() > resendAttempts + 1)
cacheUtilService.blockIdentifier(transaction.getIdentifier());
if(transaction.getChallengeRetryAttempts() > resendAttempts)
cacheUtilService.blockIdentifier(transaction.getIdentifier(), "blocked");

notificationHelper.sendSMSNotificationAsync(generateChallengeRequest.getIdentifier(), transaction.getLocale(),
SEND_OTP_SMS_NOTIFICATION_TEMPLATE_KEY, new HashMap<>(){{put("{challenge}", challenge);}})
Expand Down Expand Up @@ -274,6 +276,7 @@ public RegistrationStatusResponse updatePassword(ResetPasswordRequest resetPassw

Password password = generateSaltedHash(resetPasswordRequest.getPassword(), transactionId);
identity.setPassword(password);
identity.setUpdatedAt(LocalDateTime.now(ZoneOffset.UTC).toEpochSecond(ZoneOffset.UTC));

IdentityRequest identityRequest = new IdentityRequest();
identityRequest.setRegistrationId(transaction.getApplicationId());
Expand Down Expand Up @@ -426,6 +429,8 @@ private void saveIdentityData(RegisterRequest registerRequest, String transactio
identity.setFullName(userInfoMap.getFullName());
identity.setIDSchemaVersion(idSchemaVersion);
identity.setRegistrationType("L1");
identity.setPhoneVerified(true);
identity.setUpdatedAt(LocalDateTime.now(ZoneOffset.UTC).toEpochSecond(ZoneOffset.UTC));

String uin = getUniqueIdentifier(transactionId);
identity.setUIN(uin);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public class ErrorConstants {
public static final String INVALID_PASSWORD = "invalid_password";
public static final String INVALID_USERINFO = "invalid_username";
public static final String INVALID_CONSENT = "invalid_consent";
public static final String INVALID_PURPOSE ="invalid_purpose";
public static final String IDENTIFIER_MISMATCH = "identifier_mismatch";
public static final String CONSENT_REQUIRED = "consent_required";
public static final String INVALID_TRANSACTION="invalid_transaction";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ public class SignUpConstants {

public static final String CHALLENGE_GENERATED = "challenge_generated";
public static final String CHALLENGE_VERIFIED = "challenge_verified";
public static final String REGISTERED_CACHE = "registered";
public static final String REGISTERED_CACHE = "status_check";
public static final String BLOCKED_IDENTIFIER = "blocked_identifier";
public static final String KEYSTORE = "keystore";
public static final String KEY_ALIAS = "key_alias";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.mosip.signup.validator;

import io.mosip.signup.util.ErrorConstants;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target({FIELD, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = PurposeValidator.class)
@Documented
public @interface Purpose {
String message() default ErrorConstants.INVALID_PURPOSE;
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.mosip.signup.validator;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import io.mosip.signup.util.Purpose;

public class PurposeValidator implements ConstraintValidator<io.mosip.signup.validator.Purpose, Purpose> {
@Override
public boolean isValid(Purpose value, ConstraintValidatorContext context) {
if(value == null)
return false;
return value.equals(Purpose.REGISTRATION) || value.equals(Purpose.RESET_PASSWORD);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ mosip.signup.fullname.pattern=^[\\u1780-\\u17FF\\u19E0-\\u19FF\\u1A00-\\u1A9F\\u

## Time given to generate and verify the challenge in seconds.
## Default resend delay is 60 seconds, with 3 attempts, so 60*3=180 seconds.
## Adding 10 seconds buffer to default 180 seconds = 190 seconds.
## so 190 seconds is the Generate and verify cookie max age.
mosip.signup.unauthenticated.txn.timeout=190
## Adding 60 seconds for the default generate challenge 180+60=240
## Adding 10 seconds buffer to default 240 seconds = 250 seconds.
## so 250 seconds is the Generate and verify cookie max age.
mosip.signup.unauthenticated.txn.timeout=250
mosip.signup.challenge.resend-attempt=3
mosip.signup.challenge.resend-delay=60

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,23 @@ public void doGenerateChallenge_withRegistrationPurpose_thenPass() throws Except
.andExpect(jsonPath("$.errors").isEmpty());
}

@Test
public void doGenerateChallenge_withNullPurpose_returnErrorResponse() throws Exception {
String status = "SUCCESSFUL";
GenerateChallengeResponse generateChallengeResponse = new GenerateChallengeResponse(status);
generateChallengeRequest.setPurpose(null);
when(registrationService.generateChallenge(generateChallengeRequest, ""))
.thenReturn(generateChallengeResponse);

mockMvc.perform(post("/registration/generate-challenge")
.content(objectMapper.writeValueAsString(wrapper))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.response").isEmpty())
.andExpect(jsonPath("$.errors").isNotEmpty())
.andExpect(jsonPath("$.errors[0].errorCode").value(ErrorConstants.INVALID_PURPOSE));
}

@Test
public void doGenerateChallenge_withResetPasswordPurpose_thenPass() throws Exception {
String status = "SUCCESSFUL";
Expand Down
7 changes: 5 additions & 2 deletions signup-ui/public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@
"page_under_construction_detail": "Our experts are working hard to make this page available. Meanwhile, we request you to please visit after some time.",
"something_went_wrong": "Something went wrong!",
"something_went_wrong_detail": "Our experts are working hard to make things working again.",
"attempts_left": "{attemptLeft, plural, =0 {0 of {totalAttempt} attempts left. Please try again after {attemptRetryAfter} minutes.} other {{attemptLeft} of {totalAttempt} attempts left}}",
"attempts_left": "{attemptLeft, plural, =0 {0 of {totalAttempt} attempts left} other {{attemptLeft} of {totalAttempt} attempts left}}",
"attempts_left_and_retry": "{attemptLeft, plural, =0 {0 of {totalAttempt} attempts left. Please try again after {attemptRetryAfter} minutes.} other {{attemptLeft} of {totalAttempt} attempts left}}",
"captcha_token_validation": "Please verify that you are a human.",
"username_validation": "Enter a valid username",
"username_lead_zero_validation": "Number cannot start with zero. Enter a valid mobile number.",
Expand All @@ -83,7 +84,7 @@
"powered_by": "Powered by"
},
"error_response": {
"invalid_transaction": "Invalid Transaction or Transaction Expired",
"invalid_transaction": "The transaction has timed out. Please try again.",
"invalid_otp_channel": "Invalid OTP Channel Provided",
"invalid_captcha": "Invalid captcha found.",
"send_otp_failed": "Send OTP failed",
Expand Down Expand Up @@ -128,6 +129,8 @@
"fetch_identity_failed": "Fetch Identifier Failed",
"challenge_format_and_type_mismatch": "Challenge format and type mismatch",
"knowledgebase_mismatch": "Invalid number or name. Please enter a registered mobile number and full name.",
"identifier_blocked": "Identifier blocked for 5 minutes",
"unsupported_purpose": "Invalid Request",
"IDR-IDC-001": "Missing Input Parameter",
"IDR-IDC-002": "Invalid Input Parameter",
"IDR-IDC-003": "Invalid Request",
Expand Down
9 changes: 6 additions & 3 deletions signup-ui/public/locales/km.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"full_name_tooltip": "ជាអតិបរមា 30 តួអក្សរត្រូវបានអនុញ្ញាត និងមិនគួរមានលេខ ឬតួអក្សរពិសេសណាមួយឡើយ លើកលែងតែដកឃ្លា។",
"password": "ពាក្យសម្ងាត់",
"password_placeholder": "បញ្ចូលពាក្យសម្ងាត់",
"password_rules": "ប្រើតួអក្សរ 8 ឬច្រើនជាមួយតួអក្សរពិសេស និងយ៉ាងហោចណាស់តួលេខមួយយ៉ាងតិច។",
"password_rules": "ប្រើតួអក្សរ លាយជាមួយលេខ ឱ្យបានចំនួន8តួឬច្រើនជាងនេះ",
"confirm_password": "បញ្ជាក់ពាក្យសម្ងាត់",
"confirm_password_placeholder": "បញ្ចូលពាក្យសម្ងាត់",
"terms_and_condition": "ខ្ញុំយល់ព្រមតាម<TermsAndConditionsAnchor>លក្ខខណ្ឌ</TermsAndConditionsAnchor> និង<PrivacyPolicyAnchor>គោលការណ៍ឯកជនភាព</PrivacyPolicyAnchor>របស់ប្រទេសកម្ពុជា ដើម្បីរក្សាទុក និងដំណើរការព័ត៌មានរបស់ខ្ញុំតាមតម្រូវការ។",
Expand Down Expand Up @@ -62,7 +62,8 @@
"page_under_construction_detail": "អ្នកជំនាញកំពុងធ្វើការដើម្បីឱ្យទំព័រនេះអាចប្រើប្រាស់បាន។ សូមចូលម្ដងទៀតនៅពេលក្រោយ។",
"something_went_wrong": "មានអ្វីមួយខុសប្រក្រតី!",
"something_went_wrong_detail": "អ្នកជំនាញកំពុងធ្វើការដើម្បីឱ្យអ្វីៗដំណើរការឡើងវិញ។",
"attempts_left": "{attemptLeft, plural, =0 {ការព្យាយាមនៅសល់ 0 នៃ {totalAttempt}។ សូមព្យាយាមម្តងទៀតនៅ {attemptRetryAfter} នាទីបន្ទាប់។} other {ការព្យាយាមនៅសល់ {attemptLeft} នៃ {totalAttempt}}}",
"attempts_left": "{attemptLeft, plural, =0 {ការព្យាយាមនៅសល់ 0 នៃ {totalAttempt}} other {ការព្យាយាមនៅសល់ {attemptLeft} នៃ {totalAttempt}}}",
"attempts_left_and_retry": "{attemptLeft, plural, =0 {ការព្យាយាមនៅសល់ 0 នៃ {totalAttempt}។ សូមព្យាយាមម្តងទៀតនៅ {attemptRetryAfter} នាទីបន្ទាប់។} other {ការព្យាយាមនៅសល់ {attemptLeft} នៃ {totalAttempt}}}",
"captcha_token_validation": "សូមបញ្ជាក់ថាអ្នកជាមនុស្ស",
"username_validation": "សូមបញ្ចូលឈ្មោះអ្នកប្រើប្រាស់ត្រឹមត្រូវ",
"username_lead_zero_validation": "លេខមិនអាចចាប់ផ្តើមដោយលេខសូន្យបានទេ។បញ្ចូលលេខទូរស័ព្ទដែលត្រឹមត្រូវ។",
Expand All @@ -83,7 +84,7 @@
"powered_by": "ដំណើរការដោយ"
},
"error_response": {
"invalid_transaction": "ប្រតិបត្តិការមិនត្រឹមត្រូវ ឬប្រតិបត្តិការផុតកំណត់",
"invalid_transaction": "ប្រតិបត្តិការបានផុតកំណត់។ សូមព្យាយាមម្ដងទៀត។",
"invalid_otp_channel": "ឆានែលលេខសម្ងាត់ដែលបានផ្ដល់មិនត្រឹមត្រូវ",
"invalid_captcha": "បានរកឃើញ captcha មិនត្រឹមត្រូវ",
"send_otp_failed": "ផ្ញើលេខសម្ងាត់បរាជ័យ។ លេខសម្គាល់បុគ្គលមិនពិត/មិនស្គាល់",
Expand Down Expand Up @@ -128,6 +129,8 @@
"fetch_identity_failed": "ទាញ​យក​លេខ​សម្គាល់​បាន​បរាជ័យ",
"challenge_format_and_type_mismatch": "លេខទូរស័ព្ទ ឬឈ្មោះមិនត្រឹមត្រូវ។ សូមបញ្ចូលលេខទូរស័ព្ទនិងឈ្មោះដែលបានចុះឈ្មោះ។",
"knowledgebase_mismatch": "លេខទូរស័ព្ទ ឬឈ្មោះមិនត្រឹមត្រូវ។ សូមបញ្ចូលលេខទូរស័ព្ទនិងឈ្មោះដែលបានចុះឈ្មោះ។",
"identifier_blocked": "លេខសម្គាល់ត្រូវបានបិទចោលរយៈពេល5នាទី",
"unsupported_purpose": "សំណើមិនត្រឹមត្រូវ",
"IDR-IDC-001": "រកមិនឃើញតម្លៃដែលបានបញ្ចូល",
"IDR-IDC-002": "តម្លៃដែលបានបញ្ចូលមិនត្រឹមត្រូវ",
"IDR-IDC-003": "សំណើរមិនត្រឹមត្រូវ",
Expand Down
8 changes: 5 additions & 3 deletions signup-ui/src/components/resend-attempt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,24 @@ interface ResendAttemptProps {
currentAttempts: number;
totalAttempts: number;
attemptRetryAfter?: number;
showRetry?: boolean;
}

export const ResendAttempt = ({
currentAttempts,
totalAttempts,
attemptRetryAfter = 5,
attemptRetryAfter = 300,
showRetry = false,
}: ResendAttemptProps) => {
const { t } = useTranslation();
return (
<>
{currentAttempts < totalAttempts && (
<div className="w-max rounded-md bg-[#FFF7E5] p-2 px-8 text-center text-sm font-semibold text-[#8B6105]">
{t("attempts_left", {
{t(showRetry ? "attempts_left_and_retry" : "attempts_left", {
attemptLeft: currentAttempts,
totalAttempt: totalAttempts,
attemptRetryAfter: attemptRetryAfter,
attemptRetryAfter: attemptRetryAfter / 60,
})}
</div>
)}
Expand Down
26 changes: 15 additions & 11 deletions signup-ui/src/pages/ResetPasswordPage/Otp/Otp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ import {
Error,
GenerateChallengeRequestDto,
ResetPasswordForm,
ResetPasswordPossibleInvalid,
SettingsDto,
VerifyChallengeRequestDto,
ResetPasswordPossibleInvalid,
} from "~typings/types";

import { resetPasswordFormDefaultValues } from "../ResetPasswordPage";
Expand Down Expand Up @@ -129,22 +129,24 @@ export const Otp = ({ methods, settings }: OtpProps) => {
};

return generateChallengeMutation.mutate(generateChallengeRequestDto, {
onSuccess: ({ errors }) => {
onSuccess: ({ response, errors }) => {
pinInputRef.current?.clear();
setValue("otp", "", { shouldValidate: true });

setResendAttempts((resendAttempt) => resendAttempt - 1);
restartResendOtpTotalSecs(
getTimeoutTime(settings.response.configs["resend.delay"])
);

if (errors && errors.length > 0) {
if (errors[0].errorCode === "invalid_transaction") {
setCriticalError(errors[0]);
} else {
setChallengeVerificationError(errors[0]);
}
}

if (errors.length === 0 && response?.status === "SUCCESS") {
setResendAttempts((resendAttempt) => resendAttempt - 1);
restartResendOtpTotalSecs(
getTimeoutTime(settings.response.configs["resend.delay"])
);
}
},
});
}
Expand Down Expand Up @@ -204,9 +206,10 @@ export const Otp = ({ methods, settings }: OtpProps) => {
onSuccess: ({ errors }) => {
if (errors.length > 0) {
if (
["invalid_transaction", ...ResetPasswordPossibleInvalid].includes(
errors[0].errorCode
)
[
"invalid_transaction",
...ResetPasswordPossibleInvalid,
].includes(errors[0].errorCode)
) {
setCriticalError(errors[0]);
} else {
Expand Down Expand Up @@ -349,9 +352,10 @@ export const Otp = ({ methods, settings }: OtpProps) => {
currentAttempts={resendAttempts}
totalAttempts={settings.response.configs["resend.attempts"]}
attemptRetryAfter={settings.response.configs["otp.blocked"]}
showRetry={resendAttempts === 0 && resendOtpTotalSecs === 0}
/>
)}
{resendAttempts === 0 && (
{resendAttempts === 0 && resendOtpTotalSecs === 0 && (
<Button
variant="link"
className="m-4 h-4 px-12 text-sm"
Expand Down
Loading

0 comments on commit 77d3b81

Please sign in to comment.