Browse Source

force login on app start

master
jeffvli 3 years ago
parent
commit
b7733e1dad
  1. 17
      src/App.tsx
  2. 124
      src/components/settings/Login.tsx

17
src/App.tsx

@ -1,21 +1,35 @@
import React from 'react'; import React from 'react';
import { HashRouter as Router, Switch, Route, Link } from 'react-router-dom'; import { HashRouter as Router, Switch, Route } from 'react-router-dom';
import { QueryClient, QueryClientProvider } from 'react-query'; import { QueryClient, QueryClientProvider } from 'react-query';
import { Helmet } from 'react-helmet-async';
import './styles/App.global.css'; import './styles/App.global.css';
import Layout from './components/layout/Layout'; import Layout from './components/layout/Layout';
import PlaylistList from './components/playlist/PlaylistList'; import PlaylistList from './components/playlist/PlaylistList';
import PlaylistView from './components/playlist/PlaylistView'; import PlaylistView from './components/playlist/PlaylistView';
import Settings from './components/settings/Settings'; import Settings from './components/settings/Settings';
import NowPlayingView from './components/player/NowPlayingView';
import Player from './components/player/Player';
import Login from './components/settings/Login';
const queryClient = new QueryClient(); const queryClient = new QueryClient();
const App = () => { const App = () => {
if (!localStorage.getItem('server')) {
return <Login />;
}
return ( return (
<QueryClientProvider client={queryClient}> <QueryClientProvider client={queryClient}>
<Helmet>
<title>sonicd</title>
</Helmet>
<Router> <Router>
<Layout> <Layout>
<Switch> <Switch>
<Route path="/nowplaying">
<NowPlayingView />
</Route>
<Route path="/settings"> <Route path="/settings">
<Settings /> <Settings />
</Route> </Route>
@ -29,6 +43,7 @@ const App = () => {
</Switch> </Switch>
</Layout> </Layout>
</Router> </Router>
<Player />
</QueryClientProvider> </QueryClientProvider>
); );
}; };

124
src/components/settings/Login.tsx

@ -0,0 +1,124 @@
import React, { useState } from 'react';
import md5 from 'md5';
import randomstring from 'randomstring';
import {
Button,
Icon,
Container,
Header,
Content,
Panel,
Form,
FormGroup,
ControlLabel,
FormControl,
ButtonToolbar,
Alert,
} from 'rsuite';
import axios from 'axios';
import '../../styles/Settings.global.css';
const Login = () => {
const [serverName, setServerName] = useState(
localStorage.getItem('server') || ''
);
const [userName, setUserName] = useState('');
const [password, setPassword] = useState('');
const handleConnect = async () => {
console.log({
serverName,
userName,
password,
});
const salt = randomstring.generate({ length: 16, charset: 'alphanumeric' });
const hash = md5(password + salt);
try {
const testConnection = await axios.get(
`${serverName}/rest/getUsers?v=1.15.0&c=sonicd&f=json&u=${userName}&s=${salt}&t=${hash}`
);
// Since a valid request will return a 200 response, we need to check that there
// are no additional failures reported by the server
if (testConnection.data['subsonic-response'].status === 'failed') {
Alert.error(testConnection.data['subsonic-response'].error.message);
return;
}
} catch (err) {
Alert.error(`Error validating server hostname: ${err.message}`);
return;
}
localStorage.setItem('server', serverName);
localStorage.setItem('username', userName);
localStorage.setItem('salt', salt);
localStorage.setItem('hash', hash);
window.location.reload();
};
const handleDisconnect = () => {
localStorage.removeItem('server');
localStorage.removeItem('username');
localStorage.removeItem('salt');
localStorage.removeItem('hash');
window.location.reload();
};
return (
<Container id="container__login" className="login__root">
<Header className="login__header" />
<Content className="login__content">
<Panel className="login__panel" header="Server configuration" bordered>
<Form className="login__form" fluid>
<FormGroup>
<ControlLabel>*sonic Server</ControlLabel>
<FormControl
name="servername"
value={serverName}
onChange={(e) => setServerName(e)}
/>
</FormGroup>
<FormGroup>
<ControlLabel>Username</ControlLabel>
<FormControl
name="name"
value={userName}
onChange={(e) => setUserName(e)}
/>
</FormGroup>
<FormGroup>
<ControlLabel>Password</ControlLabel>
<FormControl
name="password"
type="password"
value={password}
onChange={(e) => setPassword(e)}
/>
</FormGroup>
<FormGroup>
<ButtonToolbar>
<Button
appearance="primary"
type="submit"
onClick={handleConnect}
>
Connect
</Button>
<Button appearance="default" onClick={handleDisconnect}>
<Icon icon="trash" /> Delete Current Configuration
</Button>
</ButtonToolbar>
</FormGroup>
</Form>
</Panel>
</Content>
</Container>
);
};
export default Login;
Loading…
Cancel
Save