Browse Source

Update login/logout for jellyfin

master
jeffvli 3 years ago
committed by Jeff
parent
commit
65f9365c31
  1. 33
      src/components/settings/DisconnectButton.tsx
  2. 110
      src/components/settings/Login.tsx

33
src/components/settings/DisconnectButton.tsx

@ -2,20 +2,27 @@ import React from 'react';
import settings from 'electron-settings';
import { StyledButton } from '../shared/styled';
const DisconnectButton = () => {
const handleDisconnect = () => {
localStorage.removeItem('server');
localStorage.removeItem('username');
localStorage.removeItem('salt');
localStorage.removeItem('hash');
export const handleDisconnect = () => {
localStorage.removeItem('server');
localStorage.removeItem('username');
localStorage.removeItem('userId');
localStorage.removeItem('password');
localStorage.removeItem('salt');
localStorage.removeItem('hash');
localStorage.removeItem('token');
settings.setSync('server', '');
settings.setSync('serverBase64', '');
settings.setSync('username', '');
settings.setSync('userId', '');
settings.setSync('password', '');
settings.setSync('salt', '');
settings.setSync('hash', '');
settings.setSync('token', '');
window.location.reload();
};
settings.setSync('server', '');
settings.setSync('serverBase64', '');
settings.setSync('username', '');
settings.setSync('salt', '');
settings.setSync('hash', '');
window.location.reload();
};
const DisconnectButton = () => {
return (
<StyledButton onClick={handleDisconnect} size="sm">
Disconnect

110
src/components/settings/Login.tsx

@ -1,22 +1,29 @@
import React, { useState } from 'react';
import React, { useRef, useState } from 'react';
import md5 from 'md5';
import randomstring from 'randomstring';
import settings from 'electron-settings';
import { Button, Form, ControlLabel, Message } from 'rsuite';
import axios from 'axios';
import setDefaultSettings from '../shared/setDefaultSettings';
import { StyledCheckbox, StyledInput } from '../shared/styled';
import {
StyledCheckbox,
StyledInput,
StyledInputPicker,
StyledInputPickerContainer,
} from '../shared/styled';
import { LoginPanel } from './styled';
import GenericPage from '../layout/GenericPage';
import logo from '../../../assets/icon.png';
import { mockSettings } from '../../shared/mockSettings';
const Login = () => {
const [serverType, setServerType] = useState('subsonic');
const [serverName, setServerName] = useState('');
const [userName, setUserName] = useState('');
const [password, setPassword] = useState('');
const [legacyAuth, setLegacyAuth] = useState(false);
const [message, setMessage] = useState('');
const serverTypePickerRef = useRef(null);
const handleConnect = async () => {
setMessage('');
@ -50,6 +57,7 @@ const Login = () => {
localStorage.setItem('server', cleanServerName);
localStorage.setItem('serverBase64', btoa(cleanServerName));
localStorage.setItem('serverType', 'subsonic');
localStorage.setItem('username', userName);
localStorage.setItem('password', password);
localStorage.setItem('salt', salt);
@ -57,6 +65,7 @@ const Login = () => {
settings.setSync('server', cleanServerName);
settings.setSync('serverBase64', btoa(cleanServerName));
settings.setSync('serverType', 'subsonic');
settings.setSync('username', userName);
settings.setSync('password', password);
settings.setSync('salt', salt);
@ -64,7 +73,52 @@ const Login = () => {
// Set defaults on login
setDefaultSettings(false);
window.location.reload();
};
const handleConnectJellyfin = async () => {
setMessage('');
const cleanServerName = serverName.replace(/\/$/, '');
const deviceId = randomstring.generate({ length: 12, charset: 'alphanumeric' });
try {
const { data } = await axios.post(
`${cleanServerName}/users/authenticatebyname`,
{
Username: userName,
Pw: password,
},
{
headers: {
'X-Emby-Authorization': `MediaBrowser Client="Sonixd", Device="PC", DeviceId="${deviceId}", Version="0.1.0"`,
},
}
);
localStorage.setItem('server', cleanServerName);
localStorage.setItem('serverBase64', btoa(cleanServerName));
localStorage.setItem('serverType', 'jellyfin');
localStorage.setItem('username', data.User.Id);
localStorage.setItem('token', data.AccessToken);
localStorage.setItem('deviceId', deviceId);
settings.setSync('server', cleanServerName);
settings.setSync('serverBase64', btoa(cleanServerName));
settings.setSync('serverType', 'jellyfin');
settings.setSync('username', data.User.Id);
settings.setSync('token', data.AccessToken);
settings.setSync('deviceId', deviceId);
} catch (err) {
if (err instanceof Error) {
setMessage(`${err.message}`);
return;
}
setMessage('An unknown error occurred');
return;
}
// Set defaults on login
setDefaultSettings(false);
window.location.reload();
};
@ -78,6 +132,22 @@ const Login = () => {
<br />
{message !== '' && <Message type="error" description={message} />}
<Form id="login-form" fluid style={{ paddingTop: '20px' }}>
<StyledInputPickerContainer ref={serverTypePickerRef}>
<ControlLabel>Server type</ControlLabel>
<StyledInputPicker
container={() => serverTypePickerRef.current}
cleanable={false}
data={[
{ label: 'Subsonic', value: 'subsonic' },
{ label: 'Jellyfin', value: 'jellyfin' },
]}
defaultValue="subsonic"
valueKey="value"
labelKey="label"
onChange={(e: 'subsonic' | 'jellyfin') => setServerType(e)}
/>
</StyledInputPickerContainer>
<br />
<ControlLabel>Server</ControlLabel>
<StyledInput
id="login-servername"
@ -103,28 +173,32 @@ const Login = () => {
onChange={(e: string) => setPassword(e)}
/>
<br />
<StyledCheckbox
defaultChecked={
process.env.NODE_ENV === 'test'
? mockSettings
: Boolean(settings.getSync('legacyAuth'))
}
checked={legacyAuth}
onChange={(_v: any, e: boolean) => {
settings.setSync('legacyAuth', e);
setLegacyAuth(e);
}}
>
Legacy auth (plaintext)
</StyledCheckbox>
<br />
{serverType === 'subsonic' && (
<>
<StyledCheckbox
defaultChecked={
process.env.NODE_ENV === 'test'
? mockSettings
: Boolean(settings.getSync('legacyAuth'))
}
checked={legacyAuth}
onChange={(_v: any, e: boolean) => {
settings.setSync('legacyAuth', e);
setLegacyAuth(e);
}}
>
Legacy auth (plaintext)
</StyledCheckbox>
<br />
</>
)}
<Button
id="login-button"
appearance="primary"
type="submit"
color="green"
block
onClick={handleConnect}
onClick={serverType === 'subsonic' ? handleConnect : handleConnectJellyfin}
>
Connect
</Button>

Loading…
Cancel
Save