Forum Discussion
Outlook deeplink for email compose replaces spaces with ++ when user not logged in
This is very late, but I hope this helps anyone else who goes down this rabbit hole.
If you navigate to a URL like "https://outlook.office.com/mail/deeplink/*" while signed out, that URL gets interpreted, base64 encoded, and set as the Location header of a redirect in the below format:
https://outlook.office.com/owa/?state=1&redirectTo=<BASE64_STRING>
For example, let's assume we are working with the following code:
const targetURL = new URL('https://outlook.office.com/mail/deeplink/compose/');
targetURL.searchParams.set("subject", "This is a test");
targetURL.searchParams.set("body", "This is a part of the body.");
targetURL.search = targetURL.search.replaceAll("+", "%20").replaceAll(".", "%2E");
window.open(targetURL, "_blank");
This will try to open a new tab/window to this URL (we'll call this URL A):
https://outlook.office.com/mail/deeplink/compose?subject=This%20is%20a%20test&body=This%20is%20part%20of%20the%20body%2E
Navigating to it while signed out redirects us to the following URL (URL B):
https://outlook.office.com/owa/?state=1&redirectTo=aHR0cHM6Ly9vdXRsb29rLm9mZmljZS5jb20vbWFpbC9kZWVwbGluay9jb21wb3NlLz9zdWJqZWN0PVRoaXMraXMrYSt0ZXN0JmJvZHk9VGhpcytpcytwYXJ0K29mK3RoZStib2R5Lg
Here, our URL has been Base64-URL encoded into the "redirectTo" parameter. We can confirm this by decoding the "redirectTo" parameter back to text, returning the following URL (URL C):
https://outlook.office.com/mail/deeplink/compose/?subject=This+is+a+test&body=This+is+part+of+the+body.
This shows the redirect to be why signed out users get sent to a different URL - because the URL was decoded, evaluated, re-encoded, and then Base64 encoded into the "redirectTo" parameter in a different form. This transformation causes text like "Sample%20Text" to become "Sample+Text".
Ideally, this form of the URL would be interpreted as we intend it to be interpreted.
However, what happens if we directly navigate to URL B ourselves?
- If we are logged in, we get redirected to URL C.
- If we are not logged in, we get sent to the Microsoft Auth flow, but once signed in, we get redirected to URL C.
As we can go from URL B to URL C whether we are signed in or not, if we can create URL B ourselves using our tailored copy of URL A, we can bridge the gap.
const targetURL = new URL("https://outlook.office.com/mail/deeplink/compose/");
targetURL.searchParams.set("subject", "This is a test");
targetURL.searchParams.set("body", "This is part of the body.");
targetURL.search = targetURL.search.replaceAll("+", "%20").replaceAll(".", "%2E");
const redirectURL = new URL("https://outlook.office.com/owa/?state=1");
redirectURL.searchParams.set("redirectTo", btoa(targetURL).replaceAll("=",""));
window.open(redirectURL, "_blank");
This produces and navigates to the following URL (URL D):
https://outlook.office.com/owa/?state=1&redirectTo=aHR0cHM6Ly9vdXRsb29rLm9mZmljZS5jb20vbWFpbC9kZWVwbGluay9jb21wb3NlLz9zdWJqZWN0PVRoaXMlMjBpcyUyMGElMjB0ZXN0JmJvZHk9VGhpcyUyMGlzJTIwcGFydCUyMG9mJTIwdGhlJTIwYm9keSUyRQ
Now that we have a version of URL A that uses the same format as the redirect URL, regardless of whether a user is signed in or not, we can open a new tab/window to the compose message screen.
This was very helpful thanks for sharing 👍
This is the only solution that works as a workaround to the double encoding issue, when logging in.