[desktop] Add workaround for back button on Stripe checkout (#4416)

Fixes: https://github.com/ente-io/ente/issues/4358
This commit is contained in:
Manav Rathi
2024-12-16 19:41:00 +05:30
committed by GitHub

View File

@@ -11,7 +11,14 @@
import { nativeImage, shell } from "electron/common";
import type { WebContents } from "electron/main";
import { BrowserWindow, Menu, Tray, app, protocol } from "electron/main";
import {
BrowserWindow,
Menu,
Tray,
app,
dialog,
protocol,
} from "electron/main";
import serveNextAt from "next-electron-server";
import { existsSync } from "node:fs";
import fs from "node:fs/promises";
@@ -131,6 +138,7 @@ const main = () => {
const webContents = mainWindow.webContents;
setDownloadPath(webContents);
allowExternalLinks(webContents);
handleBackOnStripeCheckout(mainWindow);
allowAllCORSOrigins(webContents);
// Start loading the renderer.
@@ -502,6 +510,45 @@ const allowExternalLinks = (webContents: WebContents) =>
}
});
/**
* Handle back button presses on the Stripe checkout page.
*
* For payments, we show the Stripe checkout page to the user in the app's
* window. On this page there is a back button that allows the user to get back
* to the app's contents. Since we're not showing the browser controls, this is
* the only way to get back to the app.
*
* If the user enters something in the text fields on this page (e.g. if they
* start entering their credit card number), and then press back, then the
* browser shows the user a dialog asking them to confirm if they want to
* discard their unsaved changes. However, when running in the context of an
* Electron app, this dialog is not shown, and instead the app just gets stuck
* (the back button stops working, and quitting the app also doesn't work since
* there is an invisible modal dialog).
*
* So we instead intercept these back button presses, and show the same dialog
* that the browser would've shown.
*/
const handleBackOnStripeCheckout = (window: BrowserWindow) =>
window.webContents.on("will-prevent-unload", (event) => {
const url = new URL(window.webContents.getURL());
// Only intercept on Stripe checkout pages.
if (url.host != "checkout.stripe.com") return;
// The dialog copy is similar to what Chrome would've shown.
// https://www.electronjs.org/docs/latest/api/web-contents#event-will-prevent-unload
const choice = dialog.showMessageBoxSync(window, {
type: "question",
buttons: ["Leave", "Stay"],
title: "Leave site?",
message: "Changes that you made may not be saved.",
defaultId: 0,
cancelId: 1,
});
const leave = choice === 0;
if (leave) event.preventDefault();
});
/**
* Allow uploads to arbitrary S3 buckets.
*