From a779fe56ad70d4bf31f7c548be01828500a51d18 Mon Sep 17 00:00:00 2001 From: Alex Plotnick Date: Wed, 29 Jun 2022 13:31:13 -0600 Subject: [PATCH] Add client authn verification page (#929) * Add client authn verification page * Update for renamed device auth endpoints * Bump OMICRON_VERSION * prove https://github.com/oxidecomputer/omicron/pull/1303 fixes it * make typescript happy * use omicron version that's on main now that it's merged * quick polish on auth and success state Co-authored-by: David Crespo --- app/pages/DeviceAuthSuccessPage.tsx | 17 ++++++++++ app/pages/DeviceAuthVerifyPage.tsx | 48 +++++++++++++++++++++++++++++ app/routes.tsx | 7 +++++ libs/api-mocks/msw/handlers.ts | 10 ++++++ 4 files changed, 82 insertions(+) create mode 100644 app/pages/DeviceAuthSuccessPage.tsx create mode 100644 app/pages/DeviceAuthVerifyPage.tsx diff --git a/app/pages/DeviceAuthSuccessPage.tsx b/app/pages/DeviceAuthSuccessPage.tsx new file mode 100644 index 0000000000..dd90a992c0 --- /dev/null +++ b/app/pages/DeviceAuthSuccessPage.tsx @@ -0,0 +1,17 @@ +import { Success16Icon } from '@oxide/ui' + +/** + * Device authorization success page + */ +export default function DeviceAuthSuccessPage() { + return ( +
+

Device authentication

+

+ + Success! +

+

Your device is now logged in.

+
+ ) +} diff --git a/app/pages/DeviceAuthVerifyPage.tsx b/app/pages/DeviceAuthVerifyPage.tsx new file mode 100644 index 0000000000..5d01f17b17 --- /dev/null +++ b/app/pages/DeviceAuthVerifyPage.tsx @@ -0,0 +1,48 @@ +import { useNavigate, useSearchParams } from 'react-router-dom' + +import { useApiMutation } from '@oxide/api' +import { Button, Warning12Icon } from '@oxide/ui' + +import { useToast } from '../hooks' + +/** + * Device authorization verification page + */ +export default function DeviceAuthVerifyPage() { + const [searchParams] = useSearchParams() + const navigate = useNavigate() + const addToast = useToast() + const confirmPost = useApiMutation('deviceAuthConfirm', { + onSuccess: () => { + navigate('/device/success') + }, + onError: () => { + addToast({ + title: 'Token denied', + icon: , + variant: 'error', + timeout: 4000, + }) + }, + }) + const userCode = searchParams.get('user_code') + + return ( +
+

Device authentication

+

Make sure this code matches the one shown on the device you are authenticating.

+

{userCode}

+ +
+ ) +} diff --git a/app/routes.tsx b/app/routes.tsx index 733bfda426..fff239bee9 100644 --- a/app/routes.tsx +++ b/app/routes.tsx @@ -9,6 +9,8 @@ import OrgLayout from './layouts/OrgLayout' import ProjectLayout from './layouts/ProjectLayout' import RootLayout from './layouts/RootLayout' import SettingsLayout from './layouts/SettingsLayout' +import DeviceAuthSuccessPage from './pages/DeviceAuthSuccessPage' +import DeviceAuthVerifyPage from './pages/DeviceAuthVerifyPage' import LoginPage from './pages/LoginPage' import NotFound from './pages/NotFound' import { OrgAccessPage } from './pages/OrgAccessPage' @@ -44,6 +46,11 @@ export const Router = () => ( } /> + }> + } /> + } /> + + } /> }> diff --git a/libs/api-mocks/msw/handlers.ts b/libs/api-mocks/msw/handlers.ts index d2d2072bf0..0243b532dc 100644 --- a/libs/api-mocks/msw/handlers.ts +++ b/libs/api-mocks/msw/handlers.ts @@ -875,4 +875,14 @@ export const handlers = [ rest.get | GetErr>('/api/users', (req, res) => { return res(json(paginated(req.url.search, db.users))) }), + + rest.post, never, PostErr>( + '/api/device/confirm', + (req, res, ctx) => { + if (req.body.user_code === 'BADD-CODE') { + return res(ctx.status(404)) + } + return res(ctx.status(200)) + } + ), ]