2FA and Password reset

pull/1382/head
ShahanaFarooqui 1 month ago
parent 907b7dee31
commit 61ffa30352

@ -47,10 +47,16 @@ export const removeSecureData = (config) => {
return config; return config;
}; };
export const addSecureData = (config) => { export const addSecureData = (config) => {
config.SSO.rtlCookiePath = common.appConfig.SSO.rtlCookiePath; config.rtlConfFilePath = common.appConfig.rtlConfFilePath;
config.multiPass = common.appConfig.multiPass; config.rtlPass = common.appConfig.rtlPass;
config.multiPassHashed = common.appConfig.multiPassHashed; config.multiPassHashed = common.appConfig.multiPassHashed;
config.secret2FA = common.appConfig.secret2FA; config.SSO.rtlCookiePath = common.appConfig.SSO.rtlCookiePath;
if (common.appConfig.multiPass) {
config.multiPass = common.appConfig.multiPass;
}
if (config.secret2FA === common.appConfig.secret2FA) {
config.secret2FA = common.appConfig.secret2FA;
}
config.nodes.map((node, i) => { config.nodes.map((node, i) => {
if (common.appConfig && common.appConfig.nodes && common.appConfig.nodes.length > i && common.appConfig.nodes[i].Authentication && common.appConfig.nodes[i].Authentication.macaroonPath) { if (common.appConfig && common.appConfig.nodes && common.appConfig.nodes.length > i && common.appConfig.nodes[i].Authentication && common.appConfig.nodes[i].Authentication.macaroonPath) {
node.Authentication.macaroonPath = common.appConfig.nodes[i].Authentication.macaroonPath; node.Authentication.macaroonPath = common.appConfig.nodes[i].Authentication.macaroonPath;
@ -111,6 +117,7 @@ export const getApplicationSettings = (req, res, next) => {
appConfData.allowPasswordUpdate = common.appConfig.allowPasswordUpdate; appConfData.allowPasswordUpdate = common.appConfig.allowPasswordUpdate;
appConfData.enable2FA = common.appConfig.enable2FA; appConfData.enable2FA = common.appConfig.enable2FA;
appConfData.selectedNodeIndex = (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.selectedNode.index); appConfData.selectedNodeIndex = (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.selectedNode.index);
common.appConfig.selectedNodeIndex = appConfData.selectedNodeIndex;
const token = req.headers.authorization ? req.headers.authorization.split(' ')[1] : ''; const token = req.headers.authorization ? req.headers.authorization.split(' ')[1] : '';
jwt.verify(token, common.secret_key, (err, user) => { jwt.verify(token, common.secret_key, (err, user) => {
if (err) { if (err) {
@ -232,12 +239,16 @@ export const updateApplicationSettings = (req, res, next) => {
const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
try { try {
const config = addSecureData(req.body); const config = addSecureData(req.body);
common.appConfig = JSON.parse(JSON.stringify(config));
delete config.selectedNodeIndex; delete config.selectedNodeIndex;
delete config.enable2FA; delete config.enable2FA;
delete config.allowPasswordUpdate;
delete config.rtlConfFilePath;
delete config.rtlPass;
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8'); fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
common.appConfig = config; const newConfig = JSON.parse(JSON.stringify(common.appConfig));
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Application Settings Updated', data: maskPasswords(common.appConfig) }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Application Settings Updated', data: maskPasswords(newConfig) });
res.status(201).json(removeSecureData(config)); res.status(201).json(removeSecureData(newConfig));
} }
catch (errRes) { catch (errRes) {
const errMsg = 'Update Default Node Error'; const errMsg = 'Update Default Node Error';

@ -115,10 +115,11 @@ export class ConfigService {
} }
}; };
this.validateNodeConfig = (config) => { this.validateNodeConfig = (config) => {
config.allowPasswordUpdate = true;
if ((process?.env?.RTL_SSO && +process?.env?.RTL_SSO === 0) || (typeof process?.env?.RTL_SSO === 'undefined' && +config.SSO.rtlSSO === 0)) { if ((process?.env?.RTL_SSO && +process?.env?.RTL_SSO === 0) || (typeof process?.env?.RTL_SSO === 'undefined' && +config.SSO.rtlSSO === 0)) {
if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') { if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') {
config.rtlPass = this.hash.update(process?.env?.APP_PASSWORD).digest('hex'); config.rtlPass = this.hash.update(process?.env?.APP_PASSWORD).digest('hex');
this.common.appConfig.allowPasswordUpdate = false; config.allowPasswordUpdate = false;
} }
else if (config.multiPassHashed && config.multiPassHashed !== '') { else if (config.multiPassHashed && config.multiPassHashed !== '') {
config.rtlPass = config.multiPassHashed; config.rtlPass = config.multiPassHashed;
@ -354,13 +355,13 @@ export class ConfigService {
}; };
this.setServerConfiguration = () => { this.setServerConfiguration = () => {
try { try {
this.common.appConfig.rtlConfFilePath = (process?.env?.RTL_CONFIG_PATH) ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..'); const rtlConfFilePath = (process?.env?.RTL_CONFIG_PATH) ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..');
const confFileFullPath = this.common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; const confFileFullPath = rtlConfFilePath + sep + 'RTL-Config.json';
if (!fs.existsSync(confFileFullPath)) { if (!fs.existsSync(confFileFullPath)) {
fs.writeFileSync(confFileFullPath, JSON.stringify(this.setDefaultConfig())); fs.writeFileSync(confFileFullPath, JSON.stringify(this.setDefaultConfig()));
} }
const config = JSON.parse(fs.readFileSync(confFileFullPath, 'utf-8')); const config = JSON.parse(fs.readFileSync(confFileFullPath, 'utf-8'));
config.rtlConfFilePath = this.common.appConfig.rtlConfFilePath; config.rtlConfFilePath = rtlConfFilePath;
this.updateLogByLevel(); this.updateLogByLevel();
this.validateNodeConfig(config); this.validateNodeConfig(config);
this.setSelectedNode(config); this.setSelectedNode(config);

@ -52,10 +52,16 @@ export const removeSecureData = (config: ApplicationConfig) => {
}; };
export const addSecureData = (config: ApplicationConfig) => { export const addSecureData = (config: ApplicationConfig) => {
config.SSO.rtlCookiePath = common.appConfig.SSO.rtlCookiePath; config.rtlConfFilePath = common.appConfig.rtlConfFilePath;
config.multiPass = common.appConfig.multiPass; config.rtlPass = common.appConfig.rtlPass;
config.multiPassHashed = common.appConfig.multiPassHashed; config.multiPassHashed = common.appConfig.multiPassHashed;
config.secret2FA = common.appConfig.secret2FA; config.SSO.rtlCookiePath = common.appConfig.SSO.rtlCookiePath;
if (common.appConfig.multiPass) {
config.multiPass = common.appConfig.multiPass;
}
if (config.secret2FA === common.appConfig.secret2FA) {
config.secret2FA = common.appConfig.secret2FA;
}
config.nodes.map((node, i) => { config.nodes.map((node, i) => {
if (common.appConfig && common.appConfig.nodes && common.appConfig.nodes.length > i && common.appConfig.nodes[i].Authentication && common.appConfig.nodes[i].Authentication.macaroonPath) { if (common.appConfig && common.appConfig.nodes && common.appConfig.nodes.length > i && common.appConfig.nodes[i].Authentication && common.appConfig.nodes[i].Authentication.macaroonPath) {
node.Authentication.macaroonPath = common.appConfig.nodes[i].Authentication.macaroonPath; node.Authentication.macaroonPath = common.appConfig.nodes[i].Authentication.macaroonPath;
@ -115,6 +121,7 @@ export const getApplicationSettings = (req, res, next) => {
appConfData.allowPasswordUpdate = common.appConfig.allowPasswordUpdate; appConfData.allowPasswordUpdate = common.appConfig.allowPasswordUpdate;
appConfData.enable2FA = common.appConfig.enable2FA; appConfData.enable2FA = common.appConfig.enable2FA;
appConfData.selectedNodeIndex = (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.selectedNode.index); appConfData.selectedNodeIndex = (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.selectedNode.index);
common.appConfig.selectedNodeIndex = appConfData.selectedNodeIndex;
const token = req.headers.authorization ? req.headers.authorization.split(' ')[1] : ''; const token = req.headers.authorization ? req.headers.authorization.split(' ')[1] : '';
jwt.verify(token, common.secret_key, (err, user) => { jwt.verify(token, common.secret_key, (err, user) => {
if (err) { if (err) {
@ -237,12 +244,16 @@ export const updateApplicationSettings = (req, res, next) => {
const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
try { try {
const config = addSecureData(req.body); const config = addSecureData(req.body);
common.appConfig = JSON.parse(JSON.stringify(config));
delete config.selectedNodeIndex; delete config.selectedNodeIndex;
delete config.enable2FA; delete config.enable2FA;
delete config.allowPasswordUpdate;
delete config.rtlConfFilePath;
delete config.rtlPass;
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8'); fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
common.appConfig = config; const newConfig = JSON.parse(JSON.stringify(common.appConfig));
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Application Settings Updated', data: maskPasswords(common.appConfig) }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Application Settings Updated', data: maskPasswords(newConfig) });
res.status(201).json(removeSecureData(config)); res.status(201).json(removeSecureData(newConfig));
} catch (errRes) { } catch (errRes) {
const errMsg = 'Update Default Node Error'; const errMsg = 'Update Default Node Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);

@ -123,10 +123,11 @@ export class ConfigService {
}; };
private validateNodeConfig = (config) => { private validateNodeConfig = (config) => {
config.allowPasswordUpdate = true;
if ((process?.env?.RTL_SSO && +process?.env?.RTL_SSO === 0) || (typeof process?.env?.RTL_SSO === 'undefined' && +config.SSO.rtlSSO === 0)) { if ((process?.env?.RTL_SSO && +process?.env?.RTL_SSO === 0) || (typeof process?.env?.RTL_SSO === 'undefined' && +config.SSO.rtlSSO === 0)) {
if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') { if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') {
config.rtlPass = this.hash.update(process?.env?.APP_PASSWORD).digest('hex'); config.rtlPass = this.hash.update(process?.env?.APP_PASSWORD).digest('hex');
this.common.appConfig.allowPasswordUpdate = false; config.allowPasswordUpdate = false;
} else if (config.multiPassHashed && config.multiPassHashed !== '') { } else if (config.multiPassHashed && config.multiPassHashed !== '') {
config.rtlPass = config.multiPassHashed; config.rtlPass = config.multiPassHashed;
} else if (config.multiPass && config.multiPass !== '') { } else if (config.multiPass && config.multiPass !== '') {
@ -333,13 +334,13 @@ export class ConfigService {
public setServerConfiguration = () => { public setServerConfiguration = () => {
try { try {
this.common.appConfig.rtlConfFilePath = (process?.env?.RTL_CONFIG_PATH) ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..'); const rtlConfFilePath = (process?.env?.RTL_CONFIG_PATH) ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..');
const confFileFullPath = this.common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; const confFileFullPath = rtlConfFilePath + sep + 'RTL-Config.json';
if (!fs.existsSync(confFileFullPath)) { if (!fs.existsSync(confFileFullPath)) {
fs.writeFileSync(confFileFullPath, JSON.stringify(this.setDefaultConfig())); fs.writeFileSync(confFileFullPath, JSON.stringify(this.setDefaultConfig()));
} }
const config = JSON.parse(fs.readFileSync(confFileFullPath, 'utf-8')); const config = JSON.parse(fs.readFileSync(confFileFullPath, 'utf-8'));
config.rtlConfFilePath = this.common.appConfig.rtlConfFilePath; config.rtlConfFilePath = rtlConfFilePath;
this.updateLogByLevel(); this.updateLogByLevel();
this.validateNodeConfig(config); this.validateNodeConfig(config);
this.setSelectedNode(config); this.setSelectedNode(config);

@ -91,6 +91,7 @@ export class TwoFactorAuthComponent implements OnInit, OnDestroy {
onVerifyToken(): boolean | void { onVerifyToken(): boolean | void {
if (this.appConfig?.enable2FA) { if (this.appConfig?.enable2FA) {
this.appConfig.enable2FA = false;
this.appConfig.secret2FA = ''; this.appConfig.secret2FA = '';
this.store.dispatch(updateApplicationSettings({ payload: this.appConfig })); this.store.dispatch(updateApplicationSettings({ payload: this.appConfig }));
this.generateSecret(); this.generateSecret();
@ -104,6 +105,7 @@ export class TwoFactorAuthComponent implements OnInit, OnDestroy {
this.tokenFormGroup.controls.token.setErrors({ notValid: true }); this.tokenFormGroup.controls.token.setErrors({ notValid: true });
return true; return true;
} }
this.appConfig.enable2FA = true;
this.appConfig.secret2FA = this.secretFormGroup.controls.secret.value; this.appConfig.secret2FA = this.secretFormGroup.controls.secret.value;
this.store.dispatch(updateApplicationSettings({ payload: this.appConfig })); this.store.dispatch(updateApplicationSettings({ payload: this.appConfig }));
this.tokenFormGroup.controls.token.setValue(''); this.tokenFormGroup.controls.token.setValue('');

@ -4,7 +4,6 @@ import { takeUntil } from 'rxjs/operators';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { faWindowRestore, faPlus, faInfoCircle } from '@fortawesome/free-solid-svg-icons'; import { faWindowRestore, faPlus, faInfoCircle } from '@fortawesome/free-solid-svg-icons';
import { UI_MESSAGES } from '../../../services/consts-enums-functions';
import { RTLConfiguration } from '../../../models/RTLconfig'; import { RTLConfiguration } from '../../../models/RTLconfig';
import { LoggerService } from '../../../services/logger.service'; import { LoggerService } from '../../../services/logger.service';

@ -287,6 +287,7 @@ export class RTLEffects implements OnDestroy {
pipe(map((appConfig: RTLConfiguration) => { pipe(map((appConfig: RTLConfiguration) => {
this.store.dispatch(updateRootAPICallStatus({ payload: { action: 'updateApplicationSettings', status: APICallStatusEnum.COMPLETED } })); this.store.dispatch(updateRootAPICallStatus({ payload: { action: 'updateApplicationSettings', status: APICallStatusEnum.COMPLETED } }));
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.UPDATE_APPLICATION_SETTINGS })); this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.UPDATE_APPLICATION_SETTINGS }));
this.store.dispatch(openSnackBar({ payload: 'Application Settings Updated Successfully!' }));
return { return {
type: RTLActions.SET_APPLICATION_SETTINGS, type: RTLActions.SET_APPLICATION_SETTINGS,
payload: appConfig payload: appConfig

Loading…
Cancel
Save