Skip to content

Commit

Permalink
Merge branch 'main' into smart-retry-analytics
Browse files Browse the repository at this point in the history
  • Loading branch information
JeevaRamu0104 authored Oct 28, 2024
2 parents 4319213 + d910c1e commit b483647
Show file tree
Hide file tree
Showing 26 changed files with 596 additions and 129 deletions.
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,32 @@ All notable changes to this project will be documented in this file. See [conven

- - -

## 2024.10.25.0

### Bug Fixes

- Auto retry bug ([#1639](https://github.com/juspay/hyperswitch-control-center/pull/1639)) ([`46f4de6`](https://github.com/juspay/hyperswitch-control-center/commit/46f4de64f0c68e587a62c876b56e94a5e25ec26d))
- Merchant account credentials not shown in profile view ([#1626](https://github.com/juspay/hyperswitch-control-center/pull/1626)) ([`9108801`](https://github.com/juspay/hyperswitch-control-center/commit/9108801555d2e3e03908dbe33f4a52ce9c0503a3))

### Miscellaneous Tasks

- TwoFa restriction after multiple failed attempts before login ([#1594](https://github.com/juspay/hyperswitch-control-center/pull/1594)) ([`9ff488b`](https://github.com/juspay/hyperswitch-control-center/commit/9ff488b8edc99af45fc8f77ab1f56e6cef34a838))
- Add merchant specific config ([#1643](https://github.com/juspay/hyperswitch-control-center/pull/1643)) ([`aac4ada`](https://github.com/juspay/hyperswitch-control-center/commit/aac4adabf17e96ef7d02fe91048fca8b668030a8))

**Full Changelog:** [`2024.10.24.0...2024.10.25.0`](https://github.com/juspay/hyperswitch-control-center/compare/2024.10.24.0...2024.10.25.0)

- - -

## 2024.10.24.0

### Testing

- Creation of test payment using sdk cypress ([#1555](https://github.com/juspay/hyperswitch-control-center/pull/1555)) ([`1bd1e56`](https://github.com/juspay/hyperswitch-control-center/commit/1bd1e563f993ec483ef43651996b9c836e33de0d))

**Full Changelog:** [`2024.10.22.2...2024.10.24.0`](https://github.com/juspay/hyperswitch-control-center/compare/2024.10.22.2...2024.10.24.0)

- - -

## 2024.10.22.2

### Bug Fixes
Expand Down
7 changes: 6 additions & 1 deletion config/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ primary_hover_color="#005ED6"
sidebar_color="#242F48"
[default.endpoints]
api_url="http://localhost:8080"
sdk_url=""
sdk_url="http://localhost:9050/HyperLoader.js"
logo_url=""
favicon_url=""
agreement_url=""
Expand Down Expand Up @@ -49,3 +49,8 @@ down_time=false
tax_processor=true
transaction_view=false
x_feature_route=false
[default.merchant_config]
[default.merchant_config.new_analytics]
org_ids=[]
merchant_ids=[]
profile_ids=[]
1 change: 1 addition & 0 deletions cypress.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module.exports = defineConfig({
// with any changed environment variables
return config;
},
chromeWebSecurity: false,
},
env: {
CYPRESS_USERNAME: process.env.CYPRESS_USERNAME || "[email protected]",
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/auth/auth.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe("Auth Module", () => {
});

it("sets true the feature flag for magic link and forgot password,then checks auth page back button functioning", () => {
cy.intercept("GET", "merchant-config?domain=default", {
cy.intercept("GET", "/dashboard/config/feature?domain=default", {
statusCode: 200,
body: {
theme: {
Expand Down
65 changes: 55 additions & 10 deletions cypress/e2e/connector/connector.cy.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
describe("connector", () => {
const username = `cypress${Math.round(+new Date() / 1000)}@gmail.com`;
const password = "Cypress98#";
const username = `cypress${Math.round(+new Date() / 1000)}@gmail.com`;

const getIframeBody = () => {
return cy
.get("iframe")
.its("0.contentDocument.body")
.should("not.be.empty")
.then(cy.wrap);
};

// Login before each testcase
beforeEach(() => {
before(() => {
cy.visit("http://localhost:9000/dashboard/login");
cy.url().should("include", "/login");
cy.get("[data-testid=card-header]").should(
Expand All @@ -23,16 +30,27 @@ describe("connector", () => {
cy.get('button[type="submit"]').click({ force: true });
cy.get("[data-testid=skip-now]").click({ force: true });

cy.url().should("include", "/dashboard/home");
});

it("Create a dummy connector", () => {
cy.url().should("include", "/dashboard/home");

cy.get('[data-form-label="Business name"]').should("exist");
cy.get("[data-testid=merchant_name]").type("test_business");
cy.get("[data-button-for=startExploring]").click();
cy.reload(true);
});

beforeEach(function () {
if (this.currentTest.title !== "Create a dummy connector") {
cy.visit("http://localhost:9000/dashboard/login");
cy.url().should("include", "/login");
cy.get("[data-testid=card-header]").should(
"contain",
"Hey there, Welcome back!",
);
cy.get("[data-testid=email]").type(username);
cy.get("[data-testid=password]").type(password);
cy.get('button[type="submit"]').click({ force: true });
cy.get("[data-testid=skip-now]").click({ force: true });
}
});

it("Create a dummy connector", () => {
cy.get("[data-testid=connectors]").click();
cy.get("[data-testid=paymentprocessors]").click();
cy.contains("Payment Processors").should("be.visible");
Expand Down Expand Up @@ -69,4 +87,31 @@ describe("connector", () => {
.scrollIntoView()
.should("be.visible");
});
it("Use the SDK to process a payment", () => {
cy.get("[data-testid=connectors]").click();
cy.get("[data-testid=paymentprocessors]").click();
cy.contains("Payment Processors").should("be.visible");
cy.get("[data-testid=home]").click();
cy.get("[data-button-for=tryItOut]").click();
cy.get('[data-breadcrumb="Explore Demo Checkout Experience"]').should(
"exist",
);
cy.get('[data-value="unitedStates(USD)"]').click();
cy.get('[data-dropdown-value="Germany (EUR)"]').click();
cy.get("[data-testid=amount]").find("input").clear().type("77");
cy.get("[data-button-for=showPreview]").click();
getIframeBody()
.find("[data-testid=cardNoInput]", { timeout: 20000 })
.should("exist")
.type("4242424242424242");
getIframeBody()
.find("[data-testid=expiryInput]")
.should("exist")
.type("0127");
getIframeBody().find("[data-testid=cvvInput]").should("exist").type("492");
cy.get("[data-button-for=payEUR77]").should("exist").click();
cy.contains("Payment Successful").should("be.visible");
cy.get("[data-button-for=goToPayment]").should("exist").click();
cy.url().should("include", "dashboard/payments");
});
});
2 changes: 1 addition & 1 deletion cypress/start_hyperswitch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ echo "[network_tokenization_service] section removed from $toml_file."

chmod +x /usr/local/bin/docker-compose
# Start Docker Compose services in detached mode
docker-compose up -d pg redis-standalone migration_runner hyperswitch-server
docker-compose up -d pg redis-standalone migration_runner hyperswitch-server hyperswitch-web
3 changes: 3 additions & 0 deletions src/Recoils/HyperswitchAtom.res
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ let featureFlagAtom: Recoil.recoilAtom<FeatureFlagUtils.featureFlag> = Recoil.at
"featureFlag",
JSON.Encode.null->FeatureFlagUtils.featureFlagType,
)
let merchantSpecificConfigAtom: Recoil.recoilAtom<
FeatureFlagUtils.merchantSpecificConfig,
> = Recoil.atom("merchantSpecificConfig", JSON.Encode.null->FeatureFlagUtils.merchantSpecificConfig)
let paypalAccountStatusAtom: Recoil.recoilAtom<PayPalFlowTypes.setupAccountStatus> = Recoil.atom(
"paypalAccountStatusAtom",
PayPalFlowTypes.Connect_paypal_landing,
Expand Down
6 changes: 4 additions & 2 deletions src/container/MerchantAccountContainer.res
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ let make = () => {
let setUpConnectoreContainer = async () => {
try {
setScreenState(_ => PageLoaderWrapper.Loading)

let _ = await fetchMerchantAccountDetails()
if !checkUserEntity([#Profile]) {
let _ = await fetchMerchantAccountDetails()
}
if userHasAccess(~groupAccess=ConnectorsView) === Access {
if !featureFlagDetails.isLiveMode {
let _ = await fetchConnectorListResponse()
Expand Down Expand Up @@ -67,6 +68,7 @@ let make = () => {
}}
<RenderIf
condition={!featureFlagDetails.isLiveMode &&
!checkUserEntity([#Profile]) &&
userHasAccess(~groupAccess=MerchantDetailsManage) === Access &&
merchantDetailsTypedValue.merchant_name->Option.isNone}>
<SbxOnboardingSurvey showModal=surveyModal setShowModal=setSurveyModal />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ let make = () => {
| MERCHANT_SELECT
| ACCEPT_INVITE =>
<ListInvitationScreen />
| TOTP => <TotpSetup />
| TOTP => <TwoFaLanding />
| FORCE_SET_PASSWORD
| RESET_PASSWORD =>
<ResetPassword flowType />
Expand Down
34 changes: 22 additions & 12 deletions src/entryPoints/AuthModule/TwoFaAuth/TotpSetup.res
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ let p3Regular = HSwitchUtils.getTextClass((P3, Regular))

module EnterAccessCode = {
@react.component
let make = (~setTwoFaPageState, ~onClickVerifyAccessCode) => {
let make = (~setTwoFaPageState, ~onClickVerifyAccessCode, ~errorHandling) => {
let showToast = ToastState.useShowToast()
let verifyRecoveryCodeLogic = TotpHooks.useVerifyRecoveryCode()
let (recoveryCode, setRecoveryCode) = React.useState(_ => "")
let (buttonState, setButtonState) = React.useState(_ => Button.Normal)

let verifyAccessCode = async () => {
let verifyAccessCode = async _ => {
open LogicUtils
try {
open LogicUtils

setButtonState(_ => Button.Loading)

if recoveryCode->String.length > 0 {
Expand All @@ -25,7 +24,12 @@ module EnterAccessCode = {
}
setButtonState(_ => Button.Normal)
} catch {
| _ => {
| Exn.Error(e) => {
let err = Exn.message(e)->Option.getOr("Something went wrong")
let errorCode = err->safeParse->getDictFromJsonObject->getString("code", "")
if errorCode == "UR_49" {
errorHandling(errorCode)
}
setRecoveryCode(_ => "")
setButtonState(_ => Button.Normal)
}
Expand Down Expand Up @@ -105,6 +109,7 @@ module ConfigureTotpScreen = {
~twoFaStatus,
~setTwoFaPageState,
~terminateTwoFactorAuth,
~errorHandling,
) => {
open TwoFaTypes

Expand All @@ -115,9 +120,8 @@ module ConfigureTotpScreen = {
let (buttonState, setButtonState) = React.useState(_ => Button.Normal)

let verifyTOTP = async () => {
open LogicUtils
try {
open LogicUtils

setButtonState(_ => Button.Loading)

if otp->String.length > 0 {
Expand All @@ -135,7 +139,12 @@ module ConfigureTotpScreen = {
}
setButtonState(_ => Button.Normal)
} catch {
| _ => {
| Exn.Error(e) => {
let err = Exn.message(e)->Option.getOr("Something went wrong")
let errorCode = err->safeParse->getDictFromJsonObject->getString("code", "")
if errorCode == "UR_48" {
errorHandling(errorCode)
}
setOtp(_ => "")
setButtonState(_ => Button.Normal)
}
Expand Down Expand Up @@ -225,7 +234,7 @@ module ConfigureTotpScreen = {
}

@react.component
let make = () => {
let make = (~setTwoFaPageState, ~twoFaPageState, ~errorHandling) => {
open HSwitchUtils
open TwoFaTypes

Expand All @@ -238,7 +247,6 @@ let make = () => {
let (isQrVisible, setIsQrVisible) = React.useState(_ => false)
let (totpUrl, setTotpUrl) = React.useState(_ => "")
let (twoFaStatus, setTwoFaStatus) = React.useState(_ => TWO_FA_NOT_SET)
let (twoFaPageState, setTwoFaPageState) = React.useState(_ => TOTP_SHOW_QR)
let (showNewQR, setShowNewQR) = React.useState(_ => false)

let delayTimer = () => {
Expand Down Expand Up @@ -325,14 +333,16 @@ let make = () => {
{switch twoFaPageState {
| TOTP_SHOW_QR =>
<ConfigureTotpScreen
isQrVisible totpUrl twoFaStatus setTwoFaPageState terminateTwoFactorAuth
isQrVisible totpUrl twoFaStatus setTwoFaPageState terminateTwoFactorAuth errorHandling
/>
| TOTP_SHOW_RC =>
<TotpRecoveryCodes
setTwoFaPageState onClickDownload={terminateTwoFactorAuth} setShowNewQR
/>
| TOTP_INPUT_RECOVERY_CODE =>
<EnterAccessCode setTwoFaPageState onClickVerifyAccessCode={terminateTwoFactorAuth} />
<EnterAccessCode
setTwoFaPageState onClickVerifyAccessCode={terminateTwoFactorAuth} errorHandling
/>
}}
<div className="text-grey-200 flex gap-2">
{"Log in with a different account?"->React.string}
Expand Down
Loading

0 comments on commit b483647

Please sign in to comment.