enable authentication, disable kratos stuff

This commit is contained in:
Philipp Rothmann 2022-10-25 12:42:35 +02:00
parent 4c6b7e4414
commit d1838267ea
11 changed files with 171 additions and 46 deletions

View file

@ -1,18 +1,25 @@
import React, { useEffect } from 'react';
import { Helmet } from 'react-helmet';
import { Toaster } from 'react-hot-toast';
import { Navigate, Route, Routes } from 'react-router-dom';
import { Navigate, Outlet, Route, Routes } from 'react-router-dom';
import { Layout } from './components';
import { Dashboard } from './modules';
import { AppIframe } from './modules/dashboard/AppIframe';
import { Login } from './modules/login';
import { LoginCallback } from './modules/login/LoginCallback';
import { useApps } from './services/apps';
import { useAuth } from './services/auth';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function App() {
const host = window.location.hostname;
const splitedDomain = host.split('.');
splitedDomain.shift();
const { authToken, currentUser, isAdmin } = useAuth();
const redirectToLogin = !authToken || !currentUser?.app_roles;
const ProtectedRoute = () => {
return isAdmin ? <Outlet /> : <Navigate to="/dashboard" />;
};
const { apps, loadApps } = useApps();
useEffect(() => {
@ -33,15 +40,23 @@ function App() {
</Helmet>
<div className="app bg-gray-50 min-h-screen flex flex-col">
<Layout>
{redirectToLogin ? (
<Routes>
<Route path="/dashboard" element={<Dashboard />} />
{apps.map((app) => (
<Route key={app.name} path={app.slug} element={<AppIframe app={app} />} />
))}
<Route path="*" element={<Navigate to="/dashboard" />} />
<Route path="/login" element={<Login />} />
<Route path="/login-callback" element={<LoginCallback />} />
<Route path="*" element={<Navigate to="/login" />} />
</Routes>
</Layout>
) : (
<Layout>
<Routes>
<Route path="/dashboard" element={<Dashboard />} />
{apps.map((app) => (
<Route key={app.name} path={app.slug} element={<AppIframe app={app} />} />
))}
<Route path="*" element={<Navigate to="/dashboard" />} />
</Routes>
</Layout>
)}
{/* Place to load notifications */}
<div

View file

@ -0,0 +1,50 @@
/**
* Login page that starts the OAuth2 authentication flow.
*/
import React from 'react';
import clsx from 'clsx';
import { LockClosedIcon } from '@heroicons/react/solid';
import { performApiCall } from 'src/services/api';
import { showToast, ToastType } from 'src/common/util/show-toast';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function Login() {
const handleSubmit = async () => {
try {
const { data } = await performApiCall({
path: '/login',
method: 'POST',
});
if (data.authorizationUrl) {
window.location.href = data.authorizationUrl;
}
} catch (e: any) {
showToast('Something went wrong', ToastType.Error);
}
};
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
<div className="max-w-md w-full space-y-8">
<div className="flex justify-center">
<img className="lg:block" src="assets/logo.svg" alt="Stackspin" />
<h2 className="mt-6 text-center text-xl font-bold text-gray-900 sr-only">Sign in</h2>
</div>
<button
onClick={handleSubmit}
type="button"
className={clsx(
'group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-primary-dark hover:bg-primary-dark focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500',
)}
>
<span className="absolute left-0 inset-y-0 flex items-center pl-3">
<LockClosedIcon className="h-5 w-5 text-white group-hover:text-primary-light" aria-hidden="true" />
</span>
Sign in
</button>
</div>
</div>
);
}

View file

@ -0,0 +1,58 @@
import React, { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { showToast, ToastType } from 'src/common/util/show-toast';
import { useAuth } from 'src/services/auth';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function LoginCallback() {
const currentURL = window.location.href;
const indexOfQuestionMark = currentURL.indexOf('?');
const params = currentURL.slice(indexOfQuestionMark);
const navigate = useNavigate();
const { logIn } = useAuth();
useEffect(() => {
async function logInUser() {
if (params.length > 2) {
const res = await logIn(params);
// @ts-ignore
if (!res.ok) {
navigate('/login');
showToast('Something went wrong, please try logging in again.', ToastType.Error);
}
}
}
logInUser();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [params]);
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
<div className="max-w-md w-full space-y-8">
<div className="flex flex-col justify-center items-center">
<div className="flex justify-center items-center border border-transparent text-base font-medium rounded-md text-white transition ease-in-out duration-150">
<svg
className="animate-spin h-10 w-10 text-primary"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle className="opacity-50" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
<path
className="opacity-100"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/>
</svg>
</div>
<p className="text-lg text-primary-600 mt-2">Logging You in, just a moment.</p>
</div>
</div>
</div>
);
}

View file

@ -0,0 +1 @@
export { Login } from './Login';