diff --git a/CHANGELOG.md b/CHANGELOG.md index 61c7d8f36..9045a3cc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [0.84.19](https://github.com/juspay/hyperswitch-web/compare/v0.84.18...v0.84.19) (2024-09-10) + +## [0.84.18](https://github.com/juspay/hyperswitch-web/compare/v0.84.17...v0.84.18) (2024-09-09) + ## [0.84.17](https://github.com/juspay/hyperswitch-web/compare/v0.84.16...v0.84.17) (2024-09-09) ## [0.84.16](https://github.com/juspay/hyperswitch-web/compare/v0.84.15...v0.84.16) (2024-09-09) diff --git a/package-lock.json b/package-lock.json index b28e41384..7a56fc0fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.84.17", + "version": "0.84.19", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.84.17", + "version": "0.84.19", "hasInstallScript": true, "dependencies": { "@glennsl/rescript-fetch": "^0.2.0", diff --git a/package.json b/package.json index 06a8832f8..1eeb8f994 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.84.17", + "version": "0.84.19", "main": "index.js", "private": true, "dependencies": { diff --git a/src/Payments/DateOfBirth.res b/src/Payments/DateOfBirth.res index d5c9272d7..bd8522e81 100644 --- a/src/Payments/DateOfBirth.res +++ b/src/Payments/DateOfBirth.res @@ -23,20 +23,25 @@ let years = Array.fromInitializer(~length=currentYear - startYear, i => currentY let make = () => { open Utils let {themeObj, localeString} = Recoil.useRecoilValueFromAtom(RecoilAtoms.configAtom) - let (selectedDate, setSelectedDate) = Recoil.useRecoilState(RecoilAtoms.dateOfBirth) let (error, setError) = React.useState(_ => false) let (isNotEligible, setIsNotEligible) = React.useState(_ => false) + let loggerState = Recoil.useRecoilValueFromAtom(RecoilAtoms.loggerAtom) + let (dateOfBirth, setDateOfBirth) = Recoil.useLoggedRecoilState( + RecoilAtoms.dateOfBirth, + "dateOfBirth", + loggerState, + ) let submitCallback = React.useCallback((ev: Window.event) => { let json = ev.data->safeParse let confirm = json->getDictFromJson->ConfirmType.itemToObjMapper if confirm.doSubmit { - switch selectedDate->Nullable.toOption { + switch dateOfBirth->Nullable.toOption { | Some(_) => setError(_ => false) | None => () } } - }, (selectedDate, isNotEligible)) + }, (dateOfBirth, isNotEligible)) useSubmitPaymentData(submitCallback) @@ -45,7 +50,7 @@ let make = () => { | Some(val) => val->checkIs18OrAbove | None => false } - setSelectedDate(_ => date) + setDateOfBirth(_ => date) setIsNotEligible(_ => !isAbove18) } @@ -67,7 +72,7 @@ let make = () => { showIcon=true icon={} className="w-full border border-gray-300 rounded p-2" - selected={selectedDate} + selected={dateOfBirth} onChange dateFormat="dd-MM-yyyy" wrapperClassName="datepicker" diff --git a/src/Utilities/DynamicFieldsUtils.res b/src/Utilities/DynamicFieldsUtils.res index e47c9350c..8c3d70b9f 100644 --- a/src/Utilities/DynamicFieldsUtils.res +++ b/src/Utilities/DynamicFieldsUtils.res @@ -294,7 +294,11 @@ let useSetInitialRequiredFields = ( let (cryptoCurrencyNetworks, setCryptoCurrencyNetworks) = Recoil.useRecoilState( cryptoCurrencyNetworks, ) - let (dateOfBirth, setDateOfBirth) = Recoil.useRecoilState(dateOfBirth) + let (dateOfBirth, setDateOfBirth) = Recoil.useLoggedRecoilState( + dateOfBirth, + "dateOfBirth", + logger, + ) React.useEffect(() => { let getNameValue = (item: PaymentMethodsRecord.required_fields) => { diff --git a/src/Utilities/PaymentHelpers.res b/src/Utilities/PaymentHelpers.res index e0c1e47fd..957f0ca11 100644 --- a/src/Utilities/PaymentHelpers.res +++ b/src/Utilities/PaymentHelpers.res @@ -338,7 +338,7 @@ let rec intentCall = ( ) let handleOpenUrl = url => { if isPaymentSession { - Window.Location.replace(url) + Window.replaceRootHref(url) } else { openUrl(url) } diff --git a/src/Window.res b/src/Window.res index 10d4907aa..6b4b754a0 100644 --- a/src/Window.res +++ b/src/Window.res @@ -14,8 +14,6 @@ type style @get external cardCVCElement: window => option = "cardCvc" @get external cardExpiryElement: window => option = "cardExpiry" @get external value: Dom.element => 'a = "value" -@val @scope(("window", "location")) -external replace: string => unit = "replace" @val @scope("document") external createElement: string => Dom.element = "createElement" @set external windowOnload: (window, unit => unit) => unit = "onload" @@ -131,6 +129,9 @@ module Location = { @val @scope(("window", "location")) external hostname: string = "hostname" + @val @scope(("window", "location")) + external href: string = "href" + @val @scope(("window", "location")) external origin: string = "origin" @@ -141,6 +142,28 @@ module Location = { external pathname: string = "pathname" } +module Top = { + module Location = { + @val @scope(("window", "top", "location")) + external replace: string => unit = "replace" + + @val @scope(("window", "top", "location")) + external hostname: string = "hostname" + + @val @scope(("window", "top", "location")) + external href: string = "href" + + @val @scope(("window", "top", "location")) + external origin: string = "origin" + + @val @scope(("window", "top", "location")) + external protocol: string = "protocol" + + @val @scope(("window", "top", "location")) + external pathname: string = "pathname" + } +} + module Element = { @get external clientWidth: Dom.element => int = "clientWidth" } @@ -155,3 +178,56 @@ let isSandbox = Location.hostname === "beta.hyperswitch.io" let isInteg = Location.hostname === "dev.hyperswitch.io" let isProd = Location.hostname === "checkout.hyperswitch.io" + +let isIframed = () => + try { + Location.href !== Top.Location.href + } catch { + | e => { + let default = true + Js.Console.error3( + "Failed to check whether or not document is within an iframe", + e, + `Using "${default->String.make}" as default (due to DOMException)`, + ) + default + } + } + +let getRootHostName = () => + switch isIframed() { + | true => + try { + Top.Location.hostname + } catch { + | e => { + let default = Location.hostname + Js.Console.error3( + "Failed to get root document's hostname", + e, + `Using "${default}" [window.location.hostname] as default`, + ) + default + } + } + | false => Location.hostname + } + +let replaceRootHref = (href: string) => { + switch isIframed() { + | true => + try { + Top.Location.replace(href) + } catch { + | e => { + Js.Console.error3( + "Failed to redirect root document", + e, + `Using [window.location.replace] for redirection`, + ) + Location.replace(href) + } + } + | false => Location.replace(href) + } +} diff --git a/src/orca-loader/Elements.res b/src/orca-loader/Elements.res index 691372db5..ed28ebfad 100644 --- a/src/orca-loader/Elements.res +++ b/src/orca-loader/Elements.res @@ -68,14 +68,13 @@ let make = ( let componentType = "preMountLoader" let iframeDivHtml = `` + + ` let iframeDiv = Window.createElement("div") iframeDiv->Window.innerHTML(iframeDivHtml) Window.body->Window.appendChild(iframeDiv) @@ -645,7 +644,7 @@ let make = ( let dict = json->getDictFromJson let status = dict->getString("status", "") let returnUrl = dict->getString("return_url", "") - Window.Location.replace( + Window.replaceRootHref( `${returnUrl}?payment_intent_client_secret=${clientSecret}&status=${status}`, ) resolve(JSON.Encode.null) @@ -660,7 +659,7 @@ let make = ( }) ->catch(err => { if redirect.contents === "always" { - Window.Location.replace(url) + Window.replaceRootHref(url) } messageCurrentWindow([ ("submitSuccessful", false->JSON.Encode.bool), diff --git a/src/orca-loader/Hyper.res b/src/orca-loader/Hyper.res index 42cb352eb..c3f5be69c 100644 --- a/src/orca-loader/Hyper.res +++ b/src/orca-loader/Hyper.res @@ -320,10 +320,10 @@ let make = (publishableKey, options: option, analyticsInfo: optionJSON.Decode.bool->Option.getOr(false)) { resolve1(json) } else { - Window.replace(returnUrl) + Window.replaceRootHref(returnUrl) } } else if val->JSON.Decode.bool->Option.getOr(false) && redirect === "always" { - Window.replace(returnUrl) + Window.replaceRootHref(returnUrl) } else if !(val->JSON.Decode.bool->Option.getOr(false)) { resolve1(json) } else { @@ -500,7 +500,7 @@ let make = (publishableKey, options: option, analyticsInfo: optiongetString("return_url", "/") if val->JSON.Decode.bool->Option.getOr(false) && url !== "/" { - Window.replace(url) + Window.replaceRootHref(url) } else { resolve(json) } diff --git a/src/orca-loader/LoaderPaymentElement.res b/src/orca-loader/LoaderPaymentElement.res index 94f7a1c33..028e50132 100644 --- a/src/orca-loader/LoaderPaymentElement.res +++ b/src/orca-loader/LoaderPaymentElement.res @@ -190,7 +190,7 @@ let make = ( switch eventDataObject->getOptionalJsonFromJson("openurl") { | Some(val) => { let url = val->getStringFromJson("") - Window.Location.replace(url) + Window.replaceRootHref(url) } | None => () }