diff --git a/src/App.js b/src/App.js index 3784575..a8bc1f5 100644 --- a/src/App.js +++ b/src/App.js @@ -1,25 +1,18 @@ -import logo from './logo.svg'; -import './App.css'; +import './App.css' +import LoginForm from './components/LoginForm' +import PublicHello from './components/PublicHello' +import PrivateHello from './components/PrivateHello' +import SAMLLoginForm from './components/SamlLoginForm' +import LogoutPage from './components/LogoutPage' function App() { - return ( -
-
- logo -

- Edit src/App.js and save to reload. -

- - Learn React - -
-
- ); + return
+ + + + + +
} export default App; diff --git a/src/components/LoginForm.js b/src/components/LoginForm.js new file mode 100644 index 0000000..763e38c --- /dev/null +++ b/src/components/LoginForm.js @@ -0,0 +1,84 @@ +import React, { useState } from 'react'; + +const LoginForm = () => { + const [username, setUsername] = useState(''); + const [password, setPassword] = useState(''); + // eslint-disable-next-line + const [token, setToken] = useState(''); + const [loginSuccess, setLoginSuccess] = useState(false); + + const handleUsernameChange = (event) => { + setUsername(event.target.value); + }; + + const handlePasswordChange = (event) => { + setPassword(event.target.value); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + + const requestOptions = { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + username: username, + password: password + }) + }; + + try { + const response = await fetch('http://localhost:8080/login/token', requestOptions); + const data = await response.json(); + if (data.jwt) { + setToken(data.jwt); + sessionStorage.setItem('token', data.jwt); + console.log('JWT token:', data.jwt); + // Set login success state to true + setLoginSuccess(true); + // You might want to store this token in local storage or state management (Redux, Context API) for further use. + } else { + console.error('Authentication failed'); + } + } catch (error) { + console.error('Error occurred:', error); + } + + // Reset the form fields + setUsername(''); + setPassword(''); + }; + + return ( +
+

Login

+
+
+ + +
+
+ + +
+ +
+ + {loginSuccess &&

Login successful!

} +
+ ); +}; + +export default LoginForm; diff --git a/src/components/LogoutPage.js b/src/components/LogoutPage.js new file mode 100644 index 0000000..3795790 --- /dev/null +++ b/src/components/LogoutPage.js @@ -0,0 +1,32 @@ +import React, { useState } from 'react'; + +const LogoutPage = () => { + const [message, setMessage] = useState(''); + + const handleLogout = () => { + try { + // Simulate clearing session + sessionStorage.clear(); + + // Simulate a delay before redirecting after session clearance + setTimeout(() => { + setMessage('Logged out successfully.'); + // Redirect to http://localhost:3000 after successful logout with a query parameter + window.location.href = 'http://localhost:3000?logout=true&session=cleared'; + }, 200); // You can adjust the delay time as needed + } catch (error) { + setMessage('Error occurred during logout'); + console.error(error); + } + }; + + return ( +
+

Logout Page

+ +

{message}

+
+ ); +}; + +export default LogoutPage; diff --git a/src/components/PrivateHello.js b/src/components/PrivateHello.js new file mode 100644 index 0000000..36a48a5 --- /dev/null +++ b/src/components/PrivateHello.js @@ -0,0 +1,50 @@ +import React, { useState } from 'react'; + +const PrivateHello = () => { + const [response, setResponse] = useState(''); + + const urlParams = new URLSearchParams(window.location.search); + const token = urlParams.get('token'); + + if (token) { + sessionStorage.setItem('token', token); + } + + const fetchPrivateData = async () => { + const token = sessionStorage.getItem('token'); + if (token) { + try { + const result = await fetch('http://localhost:8080/private/hello', { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}`, + }, + mode: 'cors', // Ensure CORS mode is explicitly set + credentials: 'include', // Include credentials (cookies) + }); + + if (result.ok) { + const data = await result.text(); + setResponse(data); + } else { + console.error('Error fetching private data'); + } + } catch (error) { + console.error('Error occurred:', error); + } + } else { + console.log('Token not found'); + } + }; + + return ( +
+

Private Hello

+ +

{response}

+
+ ); +}; + +export default PrivateHello; diff --git a/src/components/PublicHello.js b/src/components/PublicHello.js new file mode 100644 index 0000000..c55b4ae --- /dev/null +++ b/src/components/PublicHello.js @@ -0,0 +1,30 @@ +// PublicHello.js +import React, { useState } from 'react'; + +const PublicHello = () => { + const [response, setResponse] = useState(''); + + const fetchPublicData = async () => { + try { + const result = await fetch('http://localhost:8080/public/hello'); + if (result.ok) { + const data = await result.text(); + setResponse(data); + } else { + console.error('Error fetching public data'); + } + } catch (error) { + console.error('Error occurred:', error); + } + }; + + return ( +
+

Public Hello

+ +

{response}

+
+ ); +}; + +export default PublicHello; diff --git a/src/components/SamlLoginForm.js b/src/components/SamlLoginForm.js new file mode 100644 index 0000000..a9d9313 --- /dev/null +++ b/src/components/SamlLoginForm.js @@ -0,0 +1,16 @@ +import React from 'react'; + +const SAMLLoginForm = () => { + const handleSAMLLogin = async () => { + window.open('http://localhost:8080/saml2/authenticate/okta', '_blank'); + }; + + return ( +
+

SAML Login

+ +
+ ); +}; + +export default SAMLLoginForm; diff --git a/src/index.js b/src/index.js index d563c0f..26a2c71 100644 --- a/src/index.js +++ b/src/index.js @@ -6,9 +6,7 @@ import reportWebVitals from './reportWebVitals'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( - - ); // If you want to start measuring performance in your app, pass a function