diff --git a/src/apps/legacy/routes/session/forgotPassword/index.tsx b/src/apps/legacy/routes/session/forgotPassword/index.tsx
index 8861a288f3..3f4f7f9b37 100644
--- a/src/apps/legacy/routes/session/forgotPassword/index.tsx
+++ b/src/apps/legacy/routes/session/forgotPassword/index.tsx
@@ -10,6 +10,8 @@ import Input from 'elements/emby-input/Input';
import globalize from 'lib/globalize';
import ServerConnections from 'lib/jellyfin-apiclient/ServerConnections';
import { getAuthenticationApi } from 'utils/sdk/authentication-api';
+import { isValidUrl } from 'utils/url';
+import shell from 'scripts/shell';
export const ForgotPasswordPage = () => {
const navigate = useNavigate();
@@ -41,13 +43,19 @@ export const ForgotPasswordPage = () => {
msg = globalize.translate('MessageForgotPasswordInNetworkRequired');
break;
case ForgotPasswordAction.PinCode:
- msg = globalize.translate('MessageForgotPasswordFileCreated');
- msg += '
';
- msg += globalize.translate('MessageForgotPasswordPinReset');
- msg += '
';
- msg += result.PinFile;
- msg += '
';
- callback = () => navigate('/forgotpasswordpin');
+ if (result.PinFile && isValidUrl(result.PinFile)) {
+ msg = globalize.translate('MessageForgotPasswordRedirect');
+ shell.openUrl(result.PinFile);
+ callback = () => navigate('/login');
+ } else {
+ msg = globalize.translate('MessageForgotPasswordFileCreated');
+ msg += '
';
+ msg += globalize.translate('MessageForgotPasswordPinReset');
+ msg += '
';
+ msg += result.PinFile;
+ msg += '
';
+ callback = () => navigate('/forgotpasswordpin');
+ }
break;
default:
return;
diff --git a/src/strings/en-us.json b/src/strings/en-us.json
index a6b093a5fd..358b318363 100755
--- a/src/strings/en-us.json
+++ b/src/strings/en-us.json
@@ -1186,6 +1186,7 @@
"MessageFileReadError": "There was an error reading the file. Please try again.",
"MessageForgotPasswordFileCreated": "The following file has been created on your server and contains instructions on how to proceed",
"MessageForgotPasswordPinReset": "Enter PIN here to finish Password reset",
+ "MessageForgotPasswordRedirect": "You have been redirected to an external provider for the password reset.",
"MessageForgotPasswordInNetworkRequired": "Please try again within your home network to initiate the password reset process.",
"MessageGetInstalledPluginsError": "An error occurred while getting the list of currently installed plugins.",
"MessageImageFileTypeAllowed": "Only JPEG and PNG files are supported.",
diff --git a/src/utils/url.ts b/src/utils/url.ts
index 7e3f4a84c6..3798122200 100644
--- a/src/utils/url.ts
+++ b/src/utils/url.ts
@@ -53,3 +53,20 @@ export const safeDecodeURIComponent = (value: string) => {
return value;
}
};
+
+/**
+ * Test if a string is a valid http or https URL.
+ * @param value The value to test.
+ * @returns Whether the value is a URL or not.
+ */
+export const isValidUrl = (value: string) => {
+ let url;
+
+ try {
+ url = new URL(value);
+ } catch {
+ return false;
+ }
+
+ return url.protocol === 'http:' || url.protocol === 'https:';
+};