174 lines
6.0 KiB
JavaScript
174 lines
6.0 KiB
JavaScript
import { useState, useEffect } from 'react';
|
|
import { PublicClientApplication } from '@azure/msal-browser';
|
|
import { msalConfig, loginRequest } from '../msalConfig';
|
|
import './Login.css';
|
|
|
|
function Login({ onLoginSuccess, onSwitchToRegister }) {
|
|
const [username, setUsername] = useState('');
|
|
const [password, setPassword] = useState('');
|
|
const [error, setError] = useState('');
|
|
const [loading, setLoading] = useState(false);
|
|
const [msalInstance, setMsalInstance] = useState(null);
|
|
const [autoLoginAttempted, setAutoLoginAttempted] = useState (false);
|
|
|
|
useEffect(() => {
|
|
const initializeMasal = async () => {
|
|
const instance = new PublicClientApplication(msalConfig);
|
|
await instance.initialize();
|
|
setMsalInstance(instance);
|
|
};
|
|
|
|
initializeMasal();
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const manualLogout = localStorage.getItem('manualLogout');
|
|
if (msalInstance && !autoLoginAttempted && manualLogout !== 'true') {
|
|
setAutoLoginAttempted(true);
|
|
handleMicrosoftLogin();
|
|
}
|
|
}, [msalInstance])
|
|
|
|
const handleSubmit = async (e) => {
|
|
e.preventDefault();
|
|
setError('');
|
|
setLoading(true);
|
|
|
|
try {
|
|
const response = await fetch('http://localhost:9000/api/auth/login', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
username: username,
|
|
password: password
|
|
})
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (response.ok) {
|
|
localStorage.removeItem('manualLogout');
|
|
onLoginSuccess(data.user, data.token);
|
|
} else {
|
|
setError(data.error || 'Login failed');
|
|
}
|
|
} catch (err) {
|
|
console.error('Login error:', err);
|
|
setError('Failed to connect to server');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const handleMicrosoftLogin = async () => {
|
|
if (!msalInstance) {
|
|
setError('Microsoft login is initializing, please try again');
|
|
return;
|
|
}
|
|
|
|
setLoading(true);
|
|
setError('');
|
|
|
|
try {
|
|
// Trigger Microsoft login popup - this gets us the access token directly
|
|
const loginResponse = await msalInstance.loginPopup(loginRequest);
|
|
|
|
// Send the access token to your backend
|
|
const response = await fetch('http://localhost:9000/api/auth/microsoft', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
accessToken: loginResponse.accessToken,
|
|
idToken: loginResponse.idToken
|
|
})
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (response.ok) {
|
|
localStorage.removeItem('manualLogout');
|
|
onLoginSuccess(data.user, data.token);
|
|
} else {
|
|
setError(data.error || 'Microsoft login failed');
|
|
}
|
|
} catch (err) {
|
|
console.error('Microsoft login error:', err);
|
|
setError('Failed to login with Microsoft');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className='login-container'>
|
|
<div className='login-box'>
|
|
<h2>Login to Knowledge Base</h2>
|
|
{error && <div className='error-message'>{error}</div>}
|
|
|
|
<form onSubmit={handleSubmit}>
|
|
<div className='form-group'>
|
|
<label htmlFor='username'>Username:</label>
|
|
<input
|
|
type='text'
|
|
id='username'
|
|
value={username}
|
|
onChange={(e) => setUsername(e.target.value)}
|
|
required
|
|
disabled={loading}
|
|
/>
|
|
</div>
|
|
|
|
<div className='form-group'>
|
|
<label htmlFor='password'>Password:</label>
|
|
<input
|
|
type='password'
|
|
id='password'
|
|
value={password}
|
|
onChange={(e) => setPassword(e.target.value)}
|
|
required
|
|
disabled={loading}
|
|
/>
|
|
</div>
|
|
|
|
<button type='submit' disabled={loading}>
|
|
{loading ? 'Logging in...': 'Login'}
|
|
</button>
|
|
</form>
|
|
|
|
<div className="divider">
|
|
<span>OR</span>
|
|
</div>
|
|
|
|
<button
|
|
type="button"
|
|
className="microsoft-login-button"
|
|
onClick={handleMicrosoftLogin}
|
|
disabled={loading}
|
|
>
|
|
<svg width="21" height="21" viewBox="0 0 21 21" fill="none">
|
|
<rect x="1" y="1" width="9" height="9" fill="#f25022"/>
|
|
<rect x="1" y="11" width="9" height="9" fill="#00a4ef"/>
|
|
<rect x="11" y="1" width="9" height="9" fill="#7fba00"/>
|
|
<rect x="11" y="11" width="9" height="9" fill="#ffb900"/>
|
|
</svg>
|
|
Sign in with Microsoft
|
|
</button>
|
|
|
|
<div className='switch-auth'>
|
|
<button
|
|
type='button'
|
|
className='link-button'
|
|
onClick={onSwitchToRegister}
|
|
disabled={loading}
|
|
>Register here</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default Login; |