diff --git a/app/hooks/useQuery.js b/app/hooks/useQuery.js
new file mode 100644
index 000000000..cdc2478e4
--- /dev/null
+++ b/app/hooks/useQuery.js
@@ -0,0 +1,6 @@
+// @flow
+import { useLocation } from "react-router-dom";
+
+export default function useQuery() {
+ return new URLSearchParams(useLocation().search);
+}
diff --git a/app/scenes/Login/Notices.js b/app/scenes/Login/Notices.js
index d7be46d39..24ad3cd56 100644
--- a/app/scenes/Login/Notices.js
+++ b/app/scenes/Login/Notices.js
@@ -1,12 +1,13 @@
// @flow
import * as React from "react";
import NoticeAlert from "components/NoticeAlert";
+import useQuery from "hooks/useQuery";
-type Props = {
- notice?: string,
-};
+export default function Notices() {
+ const query = useQuery();
+ const notice = query.get("notice");
+ const description = query.get("description");
-export default function Notices({ notice }: Props) {
return (
<>
{notice === "google-hd" && (
@@ -39,12 +40,15 @@ export default function Notices({ notice }: Props) {
try again in a few minutes.
)}
- {notice === "auth-error" && (
-
- Authentication failed – we were unable to sign you in at this time.
- Please try again.
-
- )}
+ {notice === "auth-error" &&
+ (description ? (
+ {description}
+ ) : (
+
+ Authentication failed – we were unable to sign you in at this time.
+ Please try again.
+
+ ))}
{notice === "expired-token" && (
Sorry, it looks like that sign-in link is no longer valid, please try
diff --git a/app/scenes/Login/index.js b/app/scenes/Login/index.js
index a054162e6..0743c2981 100644
--- a/app/scenes/Login/index.js
+++ b/app/scenes/Login/index.js
@@ -5,7 +5,6 @@ import { BackIcon, EmailIcon } from "outline-icons";
import * as React from "react";
import { Redirect, Link, type Location } from "react-router-dom";
import styled from "styled-components";
-import getQueryVariable from "shared/utils/getQueryVariable";
import ButtonLarge from "components/ButtonLarge";
import Fade from "components/Fade";
import Flex from "components/Flex";
@@ -114,7 +113,7 @@ function Login({ location }: Props) {
Login to {config.name || "Outline"}
)}
-
+
{defaultProvider && (
diff --git a/app/scenes/Settings/Slack.js b/app/scenes/Settings/Slack.js
index 83eee9e82..8d2e5a4a3 100644
--- a/app/scenes/Settings/Slack.js
+++ b/app/scenes/Settings/Slack.js
@@ -5,7 +5,6 @@ import * as React from "react";
import { useTranslation, Trans } from "react-i18next";
import styled from "styled-components";
-import getQueryVariable from "shared/utils/getQueryVariable";
import Button from "components/Button";
import CollectionIcon from "components/CollectionIcon";
import Heading from "components/Heading";
@@ -18,13 +17,15 @@ import SlackIcon from "components/SlackIcon";
import SlackButton from "./components/SlackButton";
import env from "env";
import useCurrentTeam from "hooks/useCurrentTeam";
+import useQuery from "hooks/useQuery";
import useStores from "hooks/useStores";
function Slack() {
const team = useCurrentTeam();
const { collections, integrations } = useStores();
const { t } = useTranslation();
- const error = getQueryVariable("error");
+ const query = useQuery();
+ const error = query.get("error");
React.useEffect(() => {
collections.fetchPage({ limit: 100 });
diff --git a/server/middlewares/passport.js b/server/middlewares/passport.js
index bd15d7077..4a78056e4 100644
--- a/server/middlewares/passport.js
+++ b/server/middlewares/passport.js
@@ -24,6 +24,17 @@ export default function createMiddleware(providerName: string) {
return ctx.redirect(`/?notice=auth-error`);
}
+ // Handle errors from Azure which come in the format: message, Trace ID,
+ // Correlation ID, Timestamp in these two query string parameters.
+ const { error, error_description } = ctx.request.query;
+ if (error && error_description) {
+ console.error(error_description);
+
+ // Display only the descriptive message to the user, log the rest
+ const description = error_description.split("Trace ID")[0];
+ return ctx.redirect(`/?notice=auth-error&description=${description}`);
+ }
+
if (result.user.isSuspended) {
return ctx.redirect("/?notice=suspended");
}
diff --git a/shared/utils/getQueryVariable.js b/shared/utils/getQueryVariable.js
deleted file mode 100644
index 1a8f63388..000000000
--- a/shared/utils/getQueryVariable.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// @flow
-export default function getQueryVariable(variable: string) {
- const query = window.location.search.substring(1);
- const vars = query.split("&");
-
- for (var i = 0; i < vars.length; i++) {
- const pair = vars[i].split("=");
-
- if (pair[0] === variable) {
- return pair[1];
- }
- }
-}