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

ES-715 ES-641 #44

Merged
merged 29 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
eae0e76
Version changed to 1.0.0
ase-101 Jan 23, 2024
2a1a70a
Changed to develop version
ase-101 Jan 23, 2024
6881b3a
Removed camdgc reference
ase-101 Jan 23, 2024
2af473c
Merge pull request #29 from ase-101/develop
ase-101 Jan 23, 2024
7a7bcab
ES-710
panharith-0118 Jan 24, 2024
5224751
fix: fix validation message translation
bunsyy Jan 24, 2024
7cbdb09
Forgot password feature: Displayed incorrect error message when unreg…
Jan 24, 2024
1105619
Add missing invalid_transaction
Jan 24, 2024
a74a21a
Merge pull request #30 from panharith-0118/ES-710
ase-101 Jan 24, 2024
ddf935b
Merge pull request #31 from rathanak-0080/ES-712
ase-101 Jan 24, 2024
1335cad
ES-628
ase-101 Jan 24, 2024
19e5f54
fix: remove deprecated t param
bunsyy Jan 25, 2024
6e1925c
ES-709
panharith-0118 Jan 25, 2024
556312c
Merge pull request #34 from panharith-0118/ES-709
ase-101 Jan 25, 2024
d446f5f
Fixed review comments
ase-101 Jan 25, 2024
b14727a
Merge pull request #32 from ase-101/develop
ase-101 Jan 25, 2024
e9ee4d0
Merge pull request #33 from bunsy-0900/bug/ES-713
ase-101 Jan 25, 2024
d7b190a
feat: subtract attempt on success
bunsyy Jan 26, 2024
b3f4515
fix: convert otp blocked to minutes
bunsyy Jan 26, 2024
0c3179b
feat: show retry after countdown is zero
bunsyy Jan 29, 2024
6da2669
Merge pull request #36 from bunsy-0900/feat/ES-723
ase-101 Jan 29, 2024
902effd
ES-670 ES-695 ES-379
panharith-0118 Jan 30, 2024
cdbda92
Merge pull request #42 from panharith-0118/ES-670
ase-101 Jan 30, 2024
d6a214f
Merge remote-tracking branch 'upstream/develop' into release-1.x.x
ase-101 Jan 30, 2024
e2d936a
ES-715 ES-641
ase-101 Jan 31, 2024
ffdc065
[Es-722]
pvsaidurga Jan 30, 2024
70de409
[Es-722]
pvsaidurga Jan 30, 2024
9b8514c
[ES-722]
pvsaidurga Jan 30, 2024
6cce093
Updated versions
ase-101 Jan 31, 2024
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
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
Loading