-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle an expired admin user link #17667
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,21 +4,16 @@ | |
* See License.AGPL.txt in the project root for license information. | ||
*/ | ||
|
||
import React, { FC, Suspense, useEffect } from "react"; | ||
import { FC, Suspense, useEffect } from "react"; | ||
import { AppLoading } from "./app/AppLoading"; | ||
import { AppRoutes } from "./app/AppRoutes"; | ||
import { useCurrentOrg } from "./data/organizations/orgs-query"; | ||
import { useAnalyticsTracking } from "./hooks/use-analytics-tracking"; | ||
import { useUserLoader } from "./hooks/use-user-loader"; | ||
import { Login } from "./Login"; | ||
import { AppBlockingFlows } from "./app/AppBlockingFlows"; | ||
import { useHistory } from "react-router"; | ||
|
||
// Wrap the App in an ErrorBoundary to catch User/Org loading errors | ||
// This will also catch any errors that happen to bubble all the way up to the top | ||
const AppWithErrorBoundary: FC = () => { | ||
return <App />; | ||
}; | ||
import { Route, Switch, useHistory } from "react-router"; | ||
import { ErrorPages } from "./error-pages/ErrorPages"; | ||
|
||
export const StartWorkspaceModalKeyBinding = `${/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform) ? "⌘" : "Ctrl﹢"}O`; | ||
|
||
|
@@ -72,4 +67,13 @@ const App: FC = () => { | |
); | ||
}; | ||
|
||
export default AppWithErrorBoundary; | ||
// Routing level above main App component for any routes that don't need user/orgs loaded, such as addressable error pages | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This adds a layer above our App to let us render things like addressable error pages w/ their own routes. They won't load any external data by default. |
||
export const RootAppRouter: FC = () => { | ||
return ( | ||
<Switch> | ||
{/* Any route that starts w/ `/error` will render a specific error page if it matches a route, otherwise a generic error page */} | ||
<Route path="/error" component={ErrorPages} /> | ||
<Route path="*" component={App} /> | ||
</Switch> | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/** | ||
* Copyright (c) 2023 Gitpod GmbH. All rights reserved. | ||
* Licensed under the GNU Affero General Public License (AGPL). | ||
* See License.AGPL.txt in the project root for license information. | ||
*/ | ||
|
||
import { FC } from "react"; | ||
import { Heading1, Subheading } from "../components/typography/headings"; | ||
import { ErrorPageLayout } from "./ErrorPageLayout"; | ||
import img404 from "../images/404.webp"; | ||
import img4042x from "../images/404@2x.webp"; | ||
|
||
const DefaultError: FC = () => { | ||
return ( | ||
<ErrorPageLayout> | ||
<img | ||
className="mb-8" | ||
src={img404} | ||
srcSet={`${img404} 1x, ${img4042x} 2x`} | ||
alt="404 illustration" | ||
width="512" | ||
height="422" | ||
/> | ||
<Heading1>Oops!</Heading1> | ||
<Subheading className="mt-4">Something didn't work quite right.</Subheading> | ||
|
||
<Subheading className="mt-4">Please contact Gitpod if you continue to have this issue.</Subheading> | ||
</ErrorPageLayout> | ||
); | ||
}; | ||
|
||
export default DefaultError; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/** | ||
* Copyright (c) 2023 Gitpod GmbH. All rights reserved. | ||
* Licensed under the GNU Affero General Public License (AGPL). | ||
* See License.AGPL.txt in the project root for license information. | ||
*/ | ||
|
||
import gitpodIcon from "../images/gitpod.svg"; | ||
import gitpodDarkIcon from "../images/gitpod-dark.svg"; | ||
import { useTheme } from "../theme-context"; | ||
import { FC } from "react"; | ||
import "../dedicated-setup/styles.css"; | ||
|
||
export const ErrorPageLayout: FC = ({ children }) => { | ||
const { isDark } = useTheme(); | ||
return ( | ||
<div className="container"> | ||
<div className="app-container"> | ||
<div className="flex items-center justify-center items-center py-3"> | ||
<img src={isDark ? gitpodDarkIcon : gitpodIcon} className="h-8" alt="Gitpod's logo" /> | ||
</div> | ||
<div className={`mt-24 max-w-lg mx-auto text-center`}> | ||
<div>{children}</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/** | ||
* Copyright (c) 2023 Gitpod GmbH. All rights reserved. | ||
* Licensed under the GNU Affero General Public License (AGPL). | ||
* See License.AGPL.txt in the project root for license information. | ||
*/ | ||
|
||
import { FC, Suspense, lazy } from "react"; | ||
import { Route, Switch, useRouteMatch } from "react-router"; | ||
import { AppLoading } from "../app/AppLoading"; | ||
|
||
const ExpiredOTS = lazy(() => import("./ExpiredOTS")); | ||
const DefaultError = lazy(() => import("./DefaultError")); | ||
|
||
// Mounted under the `/error` path | ||
// Intended to handle error pages we can redirect to w/ distinct urls | ||
export const ErrorPages: FC = () => { | ||
let match = useRouteMatch(); | ||
|
||
return ( | ||
<Suspense fallback={<AppLoading />}> | ||
<Switch> | ||
{/* Matching /error/expired-ots */} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can add other addressable error pages here and use them for other cases where the api needs to redirect somewhere to show the user an error. |
||
<Route path={`${match.path}/expired-ots`} exact component={ExpiredOTS} /> | ||
{/* Matching any error/* routes */} | ||
<Route path={match.path} component={DefaultError} /> | ||
</Switch> | ||
</Suspense> | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/** | ||
* Copyright (c) 2023 Gitpod GmbH. All rights reserved. | ||
* Licensed under the GNU Affero General Public License (AGPL). | ||
* See License.AGPL.txt in the project root for license information. | ||
*/ | ||
|
||
import { FC } from "react"; | ||
import { Heading1, Subheading } from "../components/typography/headings"; | ||
import { ErrorPageLayout } from "./ErrorPageLayout"; | ||
import img404 from "../images/404.webp"; | ||
import img4042x from "../images/404@2x.webp"; | ||
|
||
const ExpiredOTS: FC = () => { | ||
return ( | ||
<ErrorPageLayout> | ||
<img | ||
className="mb-8" | ||
src={img404} | ||
srcSet={`${img404} 1x, ${img4042x} 2x`} | ||
alt="404 illustration" | ||
width="512" | ||
height="422" | ||
/> | ||
<Heading1>Oops!</Heading1> | ||
<Subheading className="mt-4">The setup link expired.</Subheading> | ||
|
||
<Subheading className="mt-4">Please contact Gitpod to receive a new link.</Subheading> | ||
</ErrorPageLayout> | ||
); | ||
}; | ||
|
||
export default ExpiredOTS; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,10 +6,10 @@ | |
|
||
import { FC } from "react"; | ||
import { Heading2, Subheading } from "../components/typography/headings"; | ||
import cubicleImg from "../images/cubicle.png"; | ||
import cubicleDarkImg from "../images/cubicle-dark.png"; | ||
import cubicleImg2x from "../images/cubicle@2x.png"; | ||
import cubicleDarkImg2x from "../images/cubicle-dark@2x.png"; | ||
import cubicleImg from "../images/cubicle.webp"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Switched all these png to webp cause they're waaaaay smaller. |
||
import cubicleDarkImg from "../images/cubicle-dark.webp"; | ||
import cubicleImg2x from "../images/cubicle@2x.webp"; | ||
import cubicleDarkImg2x from "../images/cubicle-dark@2x.webp"; | ||
import gitpodIcon from "../images/gitpod.svg"; | ||
import gitpodDarkIcon from "../images/gitpod-dark.svg"; | ||
import classNames from "classnames"; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -184,10 +184,8 @@ export class UserController { | |
} catch (e) { | ||
log.error("Failed to sign-in as admin with OTS Token", e); | ||
|
||
// Default to unauthenticated, to not leak information. | ||
// We do not send the error response to ensure we do not disclose information. | ||
const code = e.code || 401; | ||
res.sendStatus(code); | ||
// Always redirect to an expired token page if there's an error | ||
res.redirect("/error/expired-ots", 307); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unsure if we want to try and classify different errors, i.e. expired vs. invalid. If so, we can have an error route for each one. |
||
return; | ||
} | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was leftover and not needed anymore.