diff --git a/packages/frontend/src/components/login/v2/ConfirmLogin.js b/packages/frontend/src/components/login/v2/ConfirmLogin.js
index e0fcccb435..afce41c1e7 100644
--- a/packages/frontend/src/components/login/v2/ConfirmLogin.js
+++ b/packages/frontend/src/components/login/v2/ConfirmLogin.js
@@ -21,7 +21,8 @@ export default ({
appReferrer,
contractId,
publicKey,
- contractIdUrl
+ contractIdUrl,
+ isValidFailureUrl
}) => {
const [loggingIn, setLoggingIn] = useState(false);
const [showGrantFullAccessModal, setShowGrantFullAccessModal] = useState(false);
@@ -81,7 +82,7 @@ export default ({
handleClickConnect();
}
}}
- disabled={loggingIn}
+ disabled={loggingIn || !isValidFailureUrl}
sending={loggingIn}
sendingString='button.connecting'
>
diff --git a/packages/frontend/src/components/login/v2/ConfirmLoginWrapper.js b/packages/frontend/src/components/login/v2/ConfirmLoginWrapper.js
index 778afa4c50..a267323279 100644
--- a/packages/frontend/src/components/login/v2/ConfirmLoginWrapper.js
+++ b/packages/frontend/src/components/login/v2/ConfirmLoginWrapper.js
@@ -15,7 +15,8 @@ export default ({
contractId,
contractIdUrl,
onClickCancel,
- publicKey
+ publicKey,
+ isValidFailureUrl
}) => {
const dispatch = useDispatch();
@@ -45,6 +46,7 @@ export default ({
);
}}
contractIdUrl={contractIdUrl}
+ isValidFailureUrl={isValidFailureUrl}
/>
);
};
\ No newline at end of file
diff --git a/packages/frontend/src/components/login/v2/SelectAccountLoginWrapper.js b/packages/frontend/src/components/login/v2/SelectAccountLoginWrapper.js
index a6d6e6b832..113da2b410 100644
--- a/packages/frontend/src/components/login/v2/SelectAccountLoginWrapper.js
+++ b/packages/frontend/src/components/login/v2/SelectAccountLoginWrapper.js
@@ -14,7 +14,6 @@ import {
selectAccountAccountsBalances
} from '../../../redux/slices/account';
import { selectAvailableAccounts } from '../../../redux/slices/availableAccounts';
-import { checkIsValidUrl } from '../../../utils/helper-api';
import SelectAccountLogin from './SelectAccountLogin';
export default ({
@@ -22,7 +21,8 @@ export default ({
contractId,
contractIdUrl,
onClickNext,
- failureUrl
+ failureUrl,
+ isValidFailureUrl
}) => {
const dispatch = useDispatch();
@@ -49,7 +49,7 @@ export default ({
contractIdUrl={contractIdUrl}
onClickCancel={() => {
Mixpanel.track("LOGIN Click deny button");
- if (failureUrl && checkIsValidUrl(failureUrl)) {
+ if (failureUrl && isValidFailureUrl) {
window.location.href = failureUrl;
} else {
dispatch(redirectToApp());
diff --git a/packages/frontend/src/components/sign/v2/SignTransactionSummary.js b/packages/frontend/src/components/sign/v2/SignTransactionSummary.js
index 5c78fb6ea5..af4360f178 100644
--- a/packages/frontend/src/components/sign/v2/SignTransactionSummary.js
+++ b/packages/frontend/src/components/sign/v2/SignTransactionSummary.js
@@ -53,7 +53,8 @@ export default ({
onClickApprove,
onClickMoreInformation,
accountUrlReferrer,
- submittingTransaction
+ submittingTransaction,
+ isValidCallbackUrl
}) => {
const insufficientBalance = availableBalance && transferAmount && new BN(availableBalance).lt(new BN(transferAmount));
return (
@@ -82,13 +83,13 @@ export default ({
diff --git a/packages/frontend/src/components/sign/v2/SignTransactionSummaryWrapper.js b/packages/frontend/src/components/sign/v2/SignTransactionSummaryWrapper.js
index b2214bfe3c..9a98d3a356 100644
--- a/packages/frontend/src/components/sign/v2/SignTransactionSummaryWrapper.js
+++ b/packages/frontend/src/components/sign/v2/SignTransactionSummaryWrapper.js
@@ -16,7 +16,8 @@ export default ({
onClickCancel,
onClickApprove,
submittingTransaction,
- signGasFee
+ signGasFee,
+ isValidCallbackUrl
}) => {
const accountLocalStorageAccountId = useSelector(selectAccountLocalStorageAccountId);
@@ -35,6 +36,7 @@ export default ({
onClickMoreInformation={onClickMoreInformation}
accountUrlReferrer={accountUrlReferrer}
submittingTransaction={submittingTransaction}
+ isValidCallbackUrl={isValidCallbackUrl}
/>
);
};
\ No newline at end of file
diff --git a/packages/frontend/src/routes/LoginWrapper.js b/packages/frontend/src/routes/LoginWrapper.js
index 590271e276..a329511d85 100644
--- a/packages/frontend/src/routes/LoginWrapper.js
+++ b/packages/frontend/src/routes/LoginWrapper.js
@@ -28,6 +28,7 @@ export function LoginWrapper() {
const contractId = URLParams.contract_id;
const publicKey = URLParams.public_key;
const failureUrl = checkIsValidUrl(URLParams.failure_url) ? URLParams.failure_url : null;
+ const isValidFailureUrl = checkIsValidUrl(failureUrl);
const invalidContractId = URLParams.invalidContractId;
const contractIdUrl = `${EXPLORER_URL}/accounts/${contractId}`;
@@ -47,7 +48,7 @@ export function LoginWrapper() {
invalidContractId={contractId}
onClickReturnToApp={() => {
Mixpanel.track("LOGIN Invalid contract id Click return to app button", { contract_id: contractId });
- if (checkIsValidUrl(failureUrl)) {
+ if (isValidFailureUrl) {
window.location.href = failureUrl;
}
}}
@@ -63,6 +64,7 @@ export function LoginWrapper() {
contractIdUrl={contractIdUrl}
onClickCancel={() => setConfirmLogin(false)}
publicKey={publicKey}
+ isValidFailureUrl={isValidFailureUrl}
/>
);
}
@@ -73,6 +75,7 @@ export function LoginWrapper() {
contractId={contractId}
contractIdUrl={contractIdUrl}
failureUrl={failureUrl}
+ isValidFailureUrl={isValidFailureUrl}
onClickNext={() => { setConfirmLogin(true); window.scrollTo(0, 0); }}
/>
);
diff --git a/packages/frontend/src/routes/SignWrapper.js b/packages/frontend/src/routes/SignWrapper.js
index 85bc45b334..23628357be 100644
--- a/packages/frontend/src/routes/SignWrapper.js
+++ b/packages/frontend/src/routes/SignWrapper.js
@@ -7,7 +7,7 @@ import SignTransferRetry from '../components/sign/SignTransferRetry';
import SignTransactionDetailsWrapper from '../components/sign/v2/SignTransactionDetailsWrapper';
import SignTransactionSummaryWrapper from '../components/sign/v2/SignTransactionSummaryWrapper';
import { Mixpanel } from '../mixpanel';
-import { switchAccount } from '../redux/actions/account';
+import { switchAccount, redirectTo } from '../redux/actions/account';
import { selectAccountId } from '../redux/slices/account';
import { selectAvailableAccounts, selectAvailableAccountsIsLoading } from '../redux/slices/availableAccounts';
import {
@@ -22,6 +22,7 @@ import {
selectSignTransactions,
selectSignTransactionsBatchIsValid
} from '../redux/slices/sign';
+import { checkIsValidUrl } from '../utils/helper-api';
export function SignWrapper() {
const dispatch = useDispatch();
@@ -45,6 +46,7 @@ export function SignWrapper() {
const transactions = useSelector(selectSignTransactions);
const accountId = useSelector(selectAccountId);
const transactionBatchisValid = useSelector(selectSignTransactionsBatchIsValid);
+ const isValidCallbackUrl = checkIsValidUrl(signCallbackUrl);
const signerId = transactions.length && transactions[0].signerId;
const signGasFee = new BN(signFeesGasLimitIncludingGasChanges).div(new BN('1000000000000')).toString();
@@ -81,11 +83,13 @@ export function SignWrapper() {
}
if (signStatus === SIGN_STATUS.SUCCESS) {
- if (signCallbackUrl && !!transactionHashes.length) {
+ if (signCallbackUrl && !!transactionHashes.length && isValidCallbackUrl) {
window.location.href = addQueryParams(signCallbackUrl, {
signMeta,
transactionHashes: transactionHashes.join(',')
});
+ } else {
+ dispatch(redirectTo('/'));
}
}
}, [signStatus]);
@@ -97,7 +101,7 @@ export function SignWrapper() {
const handleCancelTransaction = async () => {
Mixpanel.track("SIGN Deny the transaction");
- if (signCallbackUrl) {
+ if (signCallbackUrl && isValidCallbackUrl) {
if (signStatus?.success !== false) {
window.location.href = addQueryParams(signCallbackUrl, {
signMeta,
@@ -112,6 +116,8 @@ export function SignWrapper() {
errorMessage: encodeURIComponent(signStatus?.errorMessage?.substring(0, 100)) || encodeURIComponent('Unknown error')
});
return;
+ } else {
+ dispatch(redirectTo('/'));
}
};
@@ -155,6 +161,7 @@ export function SignWrapper() {
signGasFee={signGasFee}
onClickMoreInformation={() => setCurrentDisplay(DISPLAY.TRANSACTION_DETAILS)}
onClickEditAccount={() => setCurrentDisplay(DISPLAY.ACCOUNT_SELECTION)}
+ isValidCallbackUrl={isValidCallbackUrl}
/>
);
}
\ No newline at end of file
diff --git a/packages/frontend/src/utils/helper-api.js b/packages/frontend/src/utils/helper-api.js
index 7049fd4810..f002099037 100644
--- a/packages/frontend/src/utils/helper-api.js
+++ b/packages/frontend/src/utils/helper-api.js
@@ -14,8 +14,8 @@ export function checkIsValidUrl(url) {
}
const urlProtocol = new URL(url).protocol;
- if (urlProtocol !== 'http:' && urlProtocol !== 'https:') {
- console.log('Invalid URL protocol:', urlProtocol, 'Please use http or https.');
+ if (urlProtocol === 'javascript:') {
+ console.log('Invalid URL protocol:', urlProtocol, 'URL cannot execute JavaScript');
return false;
}