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]; - } - } -}