Fix user registration if username and/or password are set via environment (#13)

This commit is contained in:
Ingo Oppermann 2022-08-18 16:10:32 +03:00
parent 7ffe697939
commit 759de38c8c
No known key found for this signature in database
GPG Key ID: 2AB32426E9DD229E
3 changed files with 91 additions and 16 deletions

View File

@ -196,16 +196,24 @@ export default function RestreamerUI(props) {
});
};
const handlePasswordReset = async (username, password) => {
const [, err] = await restreamer.current.ConfigSet({
const handlePasswordReset = async (username, loginUsername, password, loginPassword) => {
const data = {
api: {
auth: {
enable: true,
username: username,
password: password,
},
},
});
};
if (username.length !== 0) {
data.api.auth.username = username;
}
if (password.length !== 0) {
data.api.auth.password = password;
}
const [, err] = await restreamer.current.ConfigSet(data);
if (err !== null) {
notify('error', 'save:settings', `There was an error resetting the password.`);
return 'ERROR';
@ -249,7 +257,7 @@ export default function RestreamerUI(props) {
if (restarted === true) {
// After the restart the API requires a login and this means the restart happened
await restreamer.current.Validate();
await restreamer.current.Login(username, password);
await restreamer.current.Login(loginUsername, loginPassword);
window.location.reload();
} else {
@ -368,7 +376,15 @@ export default function RestreamerUI(props) {
view = <Views.Incompatible type="ffmpeg" have={$state.compatibility.ffmpeg.have} want={$state.compatibility.ffmpeg.want} />;
}
} else if ($state.password === true) {
view = <Views.Password onReset={handlePasswordReset} />;
view = (
<Views.Password
onReset={handlePasswordReset}
username={restreamer.current.ConfigValue('api.auth.username')}
usernameOverride={restreamer.current.ConfigOverrides('api.auth.username')}
password={restreamer.current.ConfigValue('api.auth.password')}
passwordOverride={restreamer.current.ConfigOverrides('api.auth.password')}
/>
);
} else {
view = <Router restreamer={restreamer.current} />;
resources = handleResources;

View File

@ -722,6 +722,13 @@ class Restreamer {
password: '',
},
},
api: {
auth: {
enable: false,
username: '',
password: '',
},
},
hostname: '',
overrides: [],
};
@ -877,6 +884,14 @@ class Restreamer {
config.source.network.hls.credentials = encodeURIComponent(config.memfs.auth.username) + ':' + encodeURIComponent(config.memfs.auth.password);
}
// API Auth
config.api.auth.enable = val.config.api.auth.enable;
config.api.auth.username = val.config.api.auth.username;
config.api.auth.password = val.config.api.auth.password;
// Environment Config Overrides
config.overrides = val.overrides;
this.config = config;
@ -909,6 +924,25 @@ class Restreamer {
return this.config.overrides.includes(name);
}
ConfigValue(name) {
if (!this.config) {
return null;
}
const elms = name.split('.');
let config = this.config;
for (let e of elms) {
if (!(e in config)) {
return null;
}
config = config[e];
}
return config;
}
// Get system metadata
async GetMetadata() {
let metadata = await this._getMetadata();
@ -1355,7 +1389,9 @@ class Restreamer {
continue;
}
sessions.sessions++;
if (p !== 'ffmpeg') {
sessions.sessions++;
}
sessions.bitrate_kbit += s.bandwidth_tx_kbit;
}
}

View File

@ -6,7 +6,6 @@ import Button from '@mui/material/Button';
import Divider from '@mui/material/Divider';
import Grid from '@mui/material/Grid';
import LinearProgress from '@mui/material/LinearProgress';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import Paper from '../misc/Paper';
@ -14,6 +13,7 @@ import Password from '../misc/Password';
import PaperHeader from '../misc/PaperHeader';
import PaperContent from '../misc/PaperContent';
import PaperFooter from '../misc/PaperFooter';
import TextField from '../misc/TextField';
const generatePassword = (length) => {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
@ -28,11 +28,10 @@ const generatePassword = (length) => {
export default function ResetPassword(props) {
const [$login, setLogin] = React.useState({
username: 'admin',
password: generatePassword(6) + '-' + generatePassword(6) + '-' + generatePassword(6),
passwordConfirm: '',
showPassword: true,
memorized: false,
username: props.username.length === 0 ? 'admin' : props.username,
password: props.password.length === 0 ? generatePassword(6) + '-' + generatePassword(6) + '-' + generatePassword(6) : props.password,
passwordConfirm: props.password.length !== 0 ? props.password : '',
showPassword: props.password.length === 0 ? true : false,
});
const [$restart, setRestart] = React.useState({
restarting: false,
@ -48,7 +47,21 @@ export default function ResetPassword(props) {
timeout: false,
});
const res = await props.onReset($login.username, $login.password);
// If the username and/or password are set by an environment variable (override == true), then don't
// store that password to the config file. By setting them as empty string, the currently stored
// values won't be changed.
let username = $login.username;
if (props.usernameOverride) {
username = '';
}
let password = $login.password;
if (props.passwordOverride) {
password = '';
}
const res = await props.onReset(username, $login.username, password, $login.password);
switch (res) {
case 'ERROR':
setRestart({
@ -98,6 +111,8 @@ export default function ResetPassword(props) {
value={$login.username}
onChange={handleChange('username')}
autoComplete="username"
disabled={props.usernameOverride}
env={props.usernameOverride}
/>
</Grid>
<Grid item xs={12}>
@ -108,6 +123,8 @@ export default function ResetPassword(props) {
onChange={handleChange('password')}
show={$login.showPassword}
autoComplete="current-password"
disabled={props.passwordOverride}
env={props.passwordOverride}
/>
</Grid>
<Grid item xs={12}>
@ -117,6 +134,8 @@ export default function ResetPassword(props) {
label={<Trans>Confirm password</Trans>}
onChange={handleChange('passwordConfirm')}
show={$login.showPassword}
disabled={props.passwordOverride}
env={props.passwordOverride}
/>
</Grid>
<Grid item xs={12}>
@ -124,7 +143,7 @@ export default function ResetPassword(props) {
</Grid>
<Grid item xs={12}>
<Button variant="outlined" color="primary" fullWidth size="large" disabled={invalid} type="submit" onClick={handleReset}>
<Trans>Create user</Trans>
<Trans>Register user</Trans>
</Button>
</Grid>
</Grid>
@ -168,4 +187,8 @@ export default function ResetPassword(props) {
ResetPassword.defaultProps = {
onReset: function (username, password) {},
username: '',
usernameOverride: false,
password: '',
passwordOverride: false,
};