-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1355306
commit e08499f
Showing
17 changed files
with
3,449 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
module.exports = { | ||
root: true, | ||
env: { browser: true, es2020: true }, | ||
extends: [ | ||
'eslint:recommended', | ||
'plugin:react/recommended', | ||
'plugin:react/jsx-runtime', | ||
'plugin:react-hooks/recommended', | ||
], | ||
ignorePatterns: ['dist', '.eslintrc.cjs'], | ||
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, | ||
settings: { react: { version: '18.2' } }, | ||
plugins: ['react-refresh'], | ||
rules: { | ||
'react/jsx-no-target-blank': 'off', | ||
'react-refresh/only-export-components': [ | ||
'warn', | ||
{ allowConstantExport: true }, | ||
], | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
pnpm-debug.log* | ||
lerna-debug.log* | ||
|
||
node_modules | ||
dist | ||
dist-ssr | ||
*.local | ||
|
||
# Editor directories and files | ||
.vscode/* | ||
!.vscode/extensions.json | ||
.idea | ||
.DS_Store | ||
*.suo | ||
*.ntvs* | ||
*.njsproj | ||
*.sln | ||
*.sw? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Veda React App | ||
|
||
This project provides a minimal setup to integrate veda auth in a React app. | ||
|
||
### Steps to run the project | ||
After cloning the project, you need to update the config in `auth.js` file with your Veda app's client id and client secret. | ||
|
||
**Note**: The client secret must never be exposed in the frontend code in a real-world scenario. | ||
|
||
<br>After the config is updated, you can run the following commands to start the project: | ||
``` | ||
yarn install | ||
yarn run dev | ||
``` | ||
|
||
* After running the above commands, go to `http://localhost:5173` or `http://localhost:5173/login` to see the login page. | ||
* Click on the Institution Login button to start the login flow. | ||
* You'll be redirected to the Veda login page. | ||
* After successful login, you'll be redirected back to the app on the user-info page. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Veda Auth React Demo</title> | ||
</head> | ||
<body> | ||
<div id="root"></div> | ||
<script type="module" src="/src/main.jsx"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"name": "veda-auth-demo", | ||
"private": true, | ||
"version": "0.0.0", | ||
"type": "module", | ||
"scripts": { | ||
"dev": "vite", | ||
"build": "vite build", | ||
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", | ||
"preview": "vite preview" | ||
}, | ||
"dependencies": { | ||
"axios": "^1.7.2", | ||
"bootstrap": "^5.3.3", | ||
"buffer": "^6.0.3", | ||
"dotenv": "^16.4.5", | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0", | ||
"react-router-dom": "^6.23.1", | ||
"vite-plugin-node-polyfills": "^0.22.0" | ||
}, | ||
"devDependencies": { | ||
"@types/react": "^18.2.66", | ||
"@types/react-dom": "^18.2.22", | ||
"@vitejs/plugin-react": "^4.2.1", | ||
"eslint": "^8.57.0", | ||
"eslint-plugin-react": "^7.34.1", | ||
"eslint-plugin-react-hooks": "^4.6.0", | ||
"eslint-plugin-react-refresh": "^0.4.6", | ||
"vite": "^5.2.0" | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#root { | ||
max-width: 1280px; | ||
margin: 0 auto; | ||
padding: 2rem; | ||
text-align: center; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import './App.css'; | ||
import {Route, BrowserRouter, Routes} from "react-router-dom"; | ||
import CallbackPage from "./pages/callback/CallbackPage.jsx"; | ||
import LoginPage from "./pages/login/LoginPage.jsx"; | ||
import UserInfoPage from "./pages/userInfo/UserInfoPage.jsx"; | ||
|
||
function App() { | ||
return (<BrowserRouter> | ||
<Routes> | ||
<Route path="/" element={<LoginPage />} /> | ||
<Route path="/login" element={<LoginPage />} /> | ||
<Route path="/callback" element={<CallbackPage />} /> | ||
<Route path="/user-info" element={<UserInfoPage />} /> | ||
</Routes> | ||
</BrowserRouter>); | ||
} | ||
|
||
export default App |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import axios from "axios"; | ||
import { Buffer } from 'buffer/'; | ||
|
||
/*This config object is just for this demo project. | ||
In a real-world scenario, you should store client id and client secret securely as per React best practices. | ||
Client secret must never be stored on the frontend. | ||
The base url and redirect uri should be loaded from .env file.*/ | ||
const config = { | ||
clientId: "_your_client_id_", | ||
clientSecret: "_your_client_secret_", | ||
|
||
vedaAuthBaseUrl: "http://localhost:8081/api/v1", | ||
redirectUri: "http://localhost:5173/callback/", | ||
} | ||
|
||
const axiosInstance = axios.create({ | ||
baseURL: config.vedaAuthBaseUrl, | ||
withCredentials: false, | ||
headers: { | ||
'Accept': '*/*', | ||
'Content-Type': 'application/json' | ||
} | ||
}); | ||
|
||
const getClientSecret = async (clientId) => { | ||
const {data: {custos_client_secret}} = await axiosInstance.get( | ||
`/identity-management/credentials`, | ||
{ | ||
headers: { | ||
'Authorization': `Bearer ${sessionStorage.getItem('access_token')}` | ||
}, | ||
params: { | ||
'client_id': clientId | ||
} | ||
} | ||
); | ||
return custos_client_secret; | ||
} | ||
|
||
const getClientAuthBase64 = async (clientId = null, clientSec = null) => { | ||
if (clientId === null && clientSec === null) { | ||
clientId = config.clientId; | ||
clientSec = config.clientSecret; | ||
} else if (clientId !== null && clientSec === null) { | ||
clientSec = await getClientSecret(clientId); | ||
} | ||
|
||
let clientAuthBase64 = `${clientId}:${clientSec}`; | ||
clientAuthBase64 = Buffer.from(clientAuthBase64).toString('base64'); | ||
clientAuthBase64 = `Bearer ${clientAuthBase64}` | ||
return clientAuthBase64; | ||
} | ||
|
||
const fetchAuthorizationEndpoint = async () => { | ||
const openIdConfigEndpoint = "/identity-management/.well-known/openid-configuration"; | ||
const redirectUri = config.redirectUri; | ||
const {data: {authorization_endpoint}} = await axiosInstance.get(openIdConfigEndpoint, | ||
{params: {'client_id': config.clientId,}}); | ||
window.location.href = `${authorization_endpoint}?response_type=code&client_id=${config.clientId}&redirect_uri=${redirectUri}&scope=openid&kc_idp_hint=oidc`; | ||
} | ||
|
||
const fetchToken = async ({code}) => { | ||
const clientAuthBase64 = await getClientAuthBase64(); | ||
|
||
const {data} = await axiosInstance.post("/identity-management/token", { | ||
code: code, | ||
redirect_uri: config.redirectUri, | ||
grant_type: 'authorization_code' | ||
}, { | ||
headers: { | ||
'Authorization': clientAuthBase64 | ||
} | ||
}); | ||
return data; | ||
} | ||
|
||
const fetchUserInfo = async () => { | ||
const clientAuthBase64 = await getClientAuthBase64(); | ||
const {data} = await axiosInstance.get("/user-management/userinfo", { | ||
params: { | ||
'access_token': sessionStorage.getItem('access_token') | ||
}, | ||
headers: { | ||
'Authorization': clientAuthBase64 | ||
} | ||
}); | ||
return data; | ||
} | ||
|
||
export {fetchAuthorizationEndpoint, fetchToken, fetchUserInfo} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import React from 'react' | ||
import ReactDOM from 'react-dom/client' | ||
import App from './App.jsx' | ||
import 'bootstrap/dist/css/bootstrap.min.css'; | ||
|
||
ReactDOM.createRoot(document.getElementById('root')).render( | ||
<React.StrictMode> | ||
<App /> | ||
</React.StrictMode>, | ||
) |
27 changes: 27 additions & 0 deletions
27
veda-app-samples/veda-react-app/src/pages/callback/CallbackPage.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import {fetchToken} from "../../api/auth.js"; | ||
import {useEffect} from "react"; | ||
import {useNavigate} from "react-router-dom"; | ||
|
||
const CallbackPage = () => { | ||
const navigate = useNavigate(); | ||
useEffect(() => { | ||
const urlParams = new URLSearchParams(window.location.search); | ||
const code = urlParams.get('code'); | ||
console.log("CODE: " + code); | ||
if (code !== null && code !== "") { | ||
fetchToken({code}).then((tokenResponse) => { | ||
console.log("TOKEN DATA: ", JSON.stringify(tokenResponse)); | ||
sessionStorage.setItem("access_token", tokenResponse.access_token); | ||
navigate('/user-info'); | ||
}); | ||
} | ||
}, [navigate]); | ||
|
||
return ( | ||
<div> | ||
<h1>Redirecting</h1> | ||
</div> | ||
); | ||
} | ||
|
||
export default CallbackPage; |
13 changes: 13 additions & 0 deletions
13
veda-app-samples/veda-react-app/src/pages/login/LoginPage.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
h2 { | ||
font-size: 35px; | ||
font-weight: 900; | ||
color: #203a43; | ||
text-align: center; | ||
} | ||
|
||
.h2-sub { | ||
font-size: 22px; | ||
color: #203a43; | ||
text-align: center; | ||
} | ||
|
31 changes: 31 additions & 0 deletions
31
veda-app-samples/veda-react-app/src/pages/login/LoginPage.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import {useEffect} from 'react'; | ||
import 'bootstrap/dist/css/bootstrap.min.css'; | ||
import './LoginPage.css'; | ||
import custos_home from '../../assets/custos_home.png'; | ||
import {fetchAuthorizationEndpoint} from "../../api/auth.js"; | ||
|
||
function LoginPage() { | ||
useEffect(() => { | ||
const urlParams = new URLSearchParams(window.location.search); | ||
for(let key of urlParams.keys()) { | ||
console.log(key, urlParams.get(key)); | ||
} | ||
}, []); | ||
|
||
return ( | ||
<div className="container"> | ||
<div className="row align-items-start justify-content-center"> | ||
<div className="col justify-content-center align-items-center"> | ||
<h2>Welcome to VEDA Auth Central</h2> | ||
<p className="h2-sub">Sign up and start authenticating</p> | ||
<img style={{width: "60%"}} src={custos_home} alt="Custos Home"/> | ||
<div className="p-2 text-center"> | ||
<button className="btn btn-primary mt-3" onClick={fetchAuthorizationEndpoint}>Institution Login</button> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
export default LoginPage; |
17 changes: 17 additions & 0 deletions
17
veda-app-samples/veda-react-app/src/pages/userInfo/UserInfoPage.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import {useEffect, useState} from "react"; | ||
import {fetchUserInfo} from "../../api/auth.js"; | ||
|
||
const UserInfoPage = () => { | ||
const [userInfo, setUserInfo] = useState(null); | ||
|
||
useEffect(() => { | ||
fetchUserInfo().then((userInfo) => {setUserInfo(userInfo)}); | ||
}, []); | ||
return ( | ||
<div> | ||
<h1>Logged in User Info</h1> | ||
<pre>{JSON.stringify(userInfo, null, 2)}</pre> | ||
</div>); | ||
}; | ||
|
||
export default UserInfoPage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { defineConfig } from 'vite' | ||
import react from '@vitejs/plugin-react' | ||
import {nodePolyfills} from "vite-plugin-node-polyfills"; | ||
|
||
// https://vitejs.dev/config/ | ||
export default defineConfig({ | ||
plugins: [react(), nodePolyfills()], | ||
}) |
Oops, something went wrong.