浏览代码

introduce a running login chain

Sven Czarnian 2 年之前
父节点
当前提交
914048fadf
共有 5 个文件被更改,包括 96 次插入21 次删除
  1. 15 21
      src/App.tsx
  2. 18 0
      src/components/auth.tsx
  3. 7 0
      src/components/configuration.ts
  4. 42 0
      src/components/login.tsx
  5. 14 0
      src/components/overview.tsx

+ 15 - 21
src/App.tsx

@@ -1,26 +1,20 @@
 import React from 'react';
-import logo from './logo.svg';
+import { BrowserRouter, Routes, Route } from 'react-router-dom';
+import { Auth } from './components/auth';
+import { Login } from './components/login';
 import './App.css';
+import { Overview } from './components/overview';
 
-function App() {
-  return (
-    <div className="App">
-      <header className="App-header">
-        <img src={logo} className="App-logo" alt="logo" />
-        <p>
-          Edit <code>src/App.tsx</code> and save to reload.
-        </p>
-        <a
-          className="App-link"
-          href="https://reactjs.org"
-          target="_blank"
-          rel="noopener noreferrer"
-        >
-          Learn React
-        </a>
-      </header>
-    </div>
-  );
-}
+const App: React.FC = () => (
+  <>
+    <BrowserRouter>
+      <Routes>
+        <Route index element={<Login />} />
+        <Route path='/auth' element={<Auth />} />
+        <Route path='/overview' element={<Overview />} />
+      </Routes>
+    </BrowserRouter>
+  </>
+);
 
 export default App;

+ 18 - 0
src/components/auth.tsx

@@ -0,0 +1,18 @@
+import React from 'react';
+import { useSearchParams } from 'react-router-dom';
+
+export const Auth: React.FC = () => {
+  const [searchParams] = useSearchParams();
+  const token = searchParams.get('token');
+
+  const baseUrl = `${window.location.protocol}//${window.location.host}`
+  if (token) {
+    sessionStorage.setItem('token', token);
+    window.location.href = `${baseUrl}/overview`;
+  } else {
+    sessionStorage.removeItem('token');
+    window.location.href = `${baseUrl}`;
+  }
+
+  return <></>;
+};

+ 7 - 0
src/components/configuration.ts

@@ -0,0 +1,7 @@
+export const Configuration = {
+  resourceServer: process.env.RESOURCE_SERVER || 'http://localhost:3000',
+  vatsim: {
+    authorizeUrl: process.env.VATSIM_AUTH_URL || 'https://auth-dev.vatsim.net/oauth/authorize',
+    clientId: process.env.VATSIM_CLIENT_ID || '461',
+  },
+};

+ 42 - 0
src/components/login.tsx

@@ -0,0 +1,42 @@
+import React, { useEffect } from 'react';
+import { Button } from 'primereact/button';
+import { Card } from 'primereact/card';
+import { Configuration } from './configuration';
+
+export const Login: React.FC = () => {
+  // reset every old token
+  useEffect(() => sessionStorage.removeItem('token'), []);
+
+  const redirectToVatsim = () => {
+    const url = [
+      Configuration.vatsim.authorizeUrl,
+      `?client_id=${Configuration.vatsim.clientId}`,
+      `&redirect_uri=http://localhost:3000/auth/vatsim`,
+      `&response_type=code`,
+      `&scope=full_name+vatsim_details`,
+      `&approval_prompt=auto`,
+    ].join('');
+    window.location.replace(url);
+  }
+
+  const footer = (
+    <span>
+      <Button
+        label='Login with VATSIM SSO'
+        className='p-button p-button-success'
+        onClick={redirectToVatsim}
+      />
+    </span>
+  );
+
+  return (
+    <>
+      <Card
+        title='Arrival MANager'
+        className='login-card text-center surface-200'
+        style={{ width: '25rem' }}
+        footer={footer}>
+      </Card>
+    </>
+  );
+};

+ 14 - 0
src/components/overview.tsx

@@ -0,0 +1,14 @@
+import React, { useState } from 'react';
+import axios from 'axios';
+
+export const Overview: React.FC = () => {
+  const [msg, setMsg] = useState('LOADING');
+
+  axios.get('http://localhost:3000/auth/user', {
+    headers: {
+      Authorization: `Bearer ${sessionStorage.getItem('token')}`,
+    },
+  }).then((data) => setMsg(data.data)).catch(() => setMsg('FAILED'));
+
+  return <>OVERVIEW {msg}</>;
+};