+
+
diff --git a/apps/web/src/connectors/redirect.ts b/apps/web/src/connectors/redirect.ts
new file mode 100644
index 0000000000..82bd273fad
--- /dev/null
+++ b/apps/web/src/connectors/redirect.ts
@@ -0,0 +1,17 @@
+// This redirect connector is used to redirect users to the correct URL after they have been sent here from an email link.
+// The fragment contains the information needed to redirect the user to the correct page.
+// This is required because android app links couldn't properly handle the angular hash based route we originally had in the email link.
+window.addEventListener("load", () => {
+ // ex: https://vault.bitwarden.com/redirect-connector.html#finish-signup?token=fakeToken&email=example%40example.com&fromEmail=true
+ const currentUrl = new URL(window.location.href);
+
+ // Get the fragment (everything after the #)
+ const fragment = currentUrl.hash.substring(1); // Remove the leading #
+
+ if (!fragment) {
+ throw new Error("No fragment found in URL. Cannot determine redirect.");
+ }
+
+ const newUrl = `${window.location.origin}/#/${fragment}`;
+ window.location.href = newUrl;
+});
diff --git a/apps/web/webpack.config.js b/apps/web/webpack.config.js
index ce3979f791..cec4bf044b 100644
--- a/apps/web/webpack.config.js
+++ b/apps/web/webpack.config.js
@@ -111,6 +111,11 @@ const plugins = [
filename: "sso-connector.html",
chunks: ["connectors/sso"],
}),
+ new HtmlWebpackPlugin({
+ template: "./src/connectors/redirect.html",
+ filename: "redirect-connector.html",
+ chunks: ["connectors/redirect", "styles"],
+ }),
new HtmlWebpackPlugin({
template: "./src/connectors/captcha.html",
filename: "captcha-connector.html",
@@ -325,6 +330,7 @@ const webpackConfig = {
"connectors/sso": "./src/connectors/sso.ts",
"connectors/captcha": "./src/connectors/captcha.ts",
"connectors/duo-redirect": "./src/connectors/duo-redirect.ts",
+ "connectors/redirect": "./src/connectors/redirect.ts",
styles: ["./src/scss/styles.scss", "./src/scss/tailwind.css"],
theme_head: "./src/theme.ts",
},