You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
313 lines
11 KiB
TypeScript
313 lines
11 KiB
TypeScript
import { Injectable, OnDestroy } from '@angular/core';
|
|
import { HttpClient } from '@angular/common/http';
|
|
import { Router } from '@angular/router';
|
|
import { Store } from '@ngrx/store';
|
|
import { Actions, Effect, ofType } from '@ngrx/effects';
|
|
import { of, Subject } from 'rxjs';
|
|
import { map, mergeMap, catchError, take, withLatestFrom } from 'rxjs/operators';
|
|
|
|
import { MatDialog } from '@angular/material';
|
|
|
|
import { environment, API_URL } from '../../environments/environment';
|
|
import { LoggerService } from '../shared/services/logger.service';
|
|
import { Settings, RTLConfiguration } from '../shared/models/RTLconfig';
|
|
|
|
import { SpinnerDialogComponent } from '../shared/components/spinner-dialog/spinner-dialog.component';
|
|
import { AlertMessageComponent } from '../shared/components/alert-message/alert-message.component';
|
|
import { ConfirmationMessageComponent } from '../shared/components/confirmation-message/confirmation-message.component';
|
|
|
|
import * as RTLActions from './rtl.actions';
|
|
import * as fromRTLReducer from './rtl.reducers';
|
|
|
|
@Injectable()
|
|
export class RTLEffects implements OnDestroy {
|
|
dialogRef: any;
|
|
CHILD_API_URL = API_URL + '/lnd';
|
|
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
|
|
|
|
constructor(
|
|
private actions$: Actions,
|
|
private httpClient: HttpClient,
|
|
private store: Store<fromRTLReducer.RTLState>,
|
|
private logger: LoggerService,
|
|
public dialog: MatDialog,
|
|
private router: Router) { }
|
|
|
|
@Effect({ dispatch: false })
|
|
openSpinner = this.actions$.pipe(
|
|
ofType(RTLActions.OPEN_SPINNER),
|
|
map((action: RTLActions.OpenSpinner) => {
|
|
this.dialogRef = this.dialog.open(SpinnerDialogComponent, { data: { titleMessage: action.payload}});
|
|
}
|
|
));
|
|
|
|
@Effect({ dispatch: false })
|
|
closeSpinner = this.actions$.pipe(
|
|
ofType(RTLActions.CLOSE_SPINNER),
|
|
map((action: RTLActions.CloseSpinner) => {
|
|
if (this.dialogRef) { this.dialogRef.close(); }
|
|
}
|
|
));
|
|
|
|
@Effect({ dispatch: false })
|
|
openAlert = this.actions$.pipe(
|
|
ofType(RTLActions.OPEN_ALERT),
|
|
map((action: RTLActions.OpenAlert) => {
|
|
this.dialogRef = this.dialog.open(AlertMessageComponent, action.payload);
|
|
}
|
|
));
|
|
|
|
@Effect({ dispatch: false })
|
|
closeAlert = this.actions$.pipe(
|
|
ofType(RTLActions.CLOSE_ALERT),
|
|
map((action: RTLActions.CloseAlert) => {
|
|
if (this.dialogRef) { this.dialogRef.close(); }
|
|
}
|
|
));
|
|
|
|
@Effect({ dispatch: false })
|
|
openConfirm = this.actions$.pipe(
|
|
ofType(RTLActions.OPEN_CONFIRMATION),
|
|
map((action: RTLActions.OpenConfirmation) => {
|
|
this.dialogRef = this.dialog.open(ConfirmationMessageComponent, action.payload);
|
|
})
|
|
);
|
|
|
|
@Effect({ dispatch: false })
|
|
closeConfirm = this.actions$.pipe(
|
|
ofType(RTLActions.CLOSE_CONFIRMATION),
|
|
take(1),
|
|
map((action: RTLActions.CloseConfirmation) => {
|
|
this.dialogRef.close();
|
|
this.logger.info(action.payload);
|
|
return action.payload;
|
|
}
|
|
));
|
|
|
|
@Effect()
|
|
appConfigFetch = this.actions$.pipe(
|
|
ofType(RTLActions.FETCH_RTL_CONFIG),
|
|
mergeMap((action: RTLActions.FetchRTLConfig) => {
|
|
this.store.dispatch(new RTLActions.ClearEffectErrorRoot('FetchRTLConfig'));
|
|
return this.httpClient.get(environment.CONF_API + '/rtlconf');
|
|
}),
|
|
map((rtlConfig: RTLConfiguration) => {
|
|
this.logger.info(rtlConfig);
|
|
if (+rtlConfig.sso.rtlSSO) { this.store.dispatch(new RTLActions.Signout()); }
|
|
this.store.dispatch(new RTLActions.SetSelelectedNode({lnNode: rtlConfig.nodes.find(node => +node.index === rtlConfig.selectedNodeIndex), isInitialSetup: true}))
|
|
return {
|
|
type: RTLActions.SET_RTL_CONFIG,
|
|
payload: rtlConfig
|
|
};
|
|
},
|
|
catchError((err) => {
|
|
this.logger.error(err);
|
|
this.store.dispatch(new RTLActions.EffectErrorRoot({ action: 'FetchRTLConfig', code: err.status, message: err.error.error }));
|
|
return of();
|
|
})
|
|
));
|
|
|
|
@Effect({ dispatch: false })
|
|
settingSave = this.actions$.pipe(
|
|
ofType(RTLActions.SAVE_SETTINGS),
|
|
mergeMap((action: RTLActions.SaveSettings) => {
|
|
return this.httpClient.post<Settings>(environment.CONF_API, { updatedSettings: action.payload });
|
|
}
|
|
));
|
|
|
|
@Effect()
|
|
configFetch = this.actions$.pipe(
|
|
ofType(RTLActions.FETCH_CONFIG),
|
|
mergeMap((action: RTLActions.FetchConfig) => {
|
|
this.store.dispatch(new RTLActions.ClearEffectErrorRoot('fetchConfig'));
|
|
return this.httpClient.get(environment.CONF_API + '/config/' + action.payload)
|
|
.pipe(
|
|
map((configFile: any) => {
|
|
this.store.dispatch(new RTLActions.CloseSpinner());
|
|
return {
|
|
type: RTLActions.SHOW_CONFIG,
|
|
payload: configFile
|
|
};
|
|
}),
|
|
catchError((err: any) => {
|
|
this.store.dispatch(new RTLActions.CloseSpinner());
|
|
this.logger.error(err);
|
|
this.store.dispatch(new RTLActions.EffectErrorRoot({ action: 'fetchConfig', code: err.status, message: err.error.error }));
|
|
return of(
|
|
{
|
|
type: RTLActions.OPEN_ALERT,
|
|
payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Fetch Config Failed!',
|
|
message: JSON.stringify({Code: err.status, Message: err.error.error})}}
|
|
}
|
|
);
|
|
}
|
|
));
|
|
})
|
|
);
|
|
|
|
@Effect({ dispatch: false })
|
|
showLnConfig = this.actions$.pipe(
|
|
ofType(RTLActions.SHOW_CONFIG),
|
|
map((action: RTLActions.ShowConfig) => {
|
|
return action.payload;
|
|
})
|
|
);
|
|
|
|
@Effect()
|
|
isAuthorized = this.actions$.pipe(
|
|
ofType(RTLActions.IS_AUTHORIZED),
|
|
withLatestFrom(this.store.select('root')),
|
|
mergeMap(([action, store]: [RTLActions.IsAuthorized, any]) => {
|
|
this.store.dispatch(new RTLActions.ClearEffectErrorRoot('IsAuthorized'));
|
|
return this.httpClient.post(environment.AUTHENTICATE_API, { password: action.payload })
|
|
.pipe(
|
|
map((postRes: any) => {
|
|
this.logger.info(postRes);
|
|
this.logger.info('Successfully Authorized!');
|
|
return {
|
|
type: RTLActions.IS_AUTHORIZED_RES,
|
|
payload: postRes
|
|
};
|
|
}),
|
|
catchError((err) => {
|
|
this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: {type: 'ERROR', titleMessage: 'Authorization Failed',
|
|
message: JSON.stringify({Code: err.status, Message: err.error.error})}}));
|
|
this.store.dispatch(new RTLActions.EffectErrorRoot({ action: 'IsAuthorized', code: err.status, message: err.error.message }));
|
|
this.logger.error(err.error);
|
|
return of({
|
|
type: RTLActions.IS_AUTHORIZED_RES,
|
|
payload: 'ERROR'
|
|
});
|
|
})
|
|
);
|
|
}));
|
|
|
|
@Effect({ dispatch: false })
|
|
isAuthorizedRes = this.actions$.pipe(
|
|
ofType(RTLActions.IS_AUTHORIZED_RES),
|
|
map((action: RTLActions.IsAuthorizedRes) => {
|
|
return action.payload;
|
|
})
|
|
);
|
|
|
|
@Effect({ dispatch: false })
|
|
authSignin = this.actions$.pipe(
|
|
ofType(RTLActions.SIGNIN),
|
|
withLatestFrom(this.store.select('root')),
|
|
mergeMap(([action, rootStore]: [RTLActions.Signin, fromRTLReducer.RootState]) => {
|
|
this.store.dispatch(new RTLActions.ClearEffectErrorRoot('Signin'));
|
|
return this.httpClient.post(environment.AUTHENTICATE_API, { password: action.payload })
|
|
.pipe(
|
|
map((postRes: any) => {
|
|
this.logger.info(postRes);
|
|
this.logger.info('Successfully Authorized!');
|
|
this.SetToken(postRes.token);
|
|
if(rootStore.selNode.lnImplementation.toLowerCase() === 'clightning') {
|
|
this.router.navigate(['/cl/home']);
|
|
} else {
|
|
this.router.navigate(['/lnd/home']);
|
|
}
|
|
}),
|
|
catchError((err) => {
|
|
this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: {type: 'ERROR', message: JSON.stringify(err.error)}}));
|
|
this.store.dispatch(new RTLActions.EffectErrorRoot({ action: 'Signin', code: err.status, message: err.error.message }));
|
|
this.logger.error(err.error);
|
|
this.logger.info('Redirecting to Signin Error Page');
|
|
if (+rootStore.appConfig.sso.rtlSSO) {
|
|
this.router.navigate(['/ssoerror']);
|
|
} else {
|
|
this.router.navigate([rootStore.appConfig.sso.logoutRedirectLink]);
|
|
}
|
|
return of();
|
|
})
|
|
);
|
|
}));
|
|
|
|
@Effect({ dispatch: false })
|
|
signOut = this.actions$.pipe(
|
|
ofType(RTLActions.SIGNOUT),
|
|
withLatestFrom(this.store.select('root')),
|
|
mergeMap(([action, store]) => {
|
|
if (+store.appConfig.sso.rtlSSO) {
|
|
window.location.href = store.appConfig.sso.logoutRedirectLink;
|
|
} else {
|
|
this.router.navigate([store.appConfig.sso.logoutRedirectLink]);
|
|
}
|
|
sessionStorage.removeItem('lndUnlocked');
|
|
sessionStorage.removeItem('token');
|
|
this.logger.warn('LOGGED OUT');
|
|
return of();
|
|
}));
|
|
|
|
@Effect()
|
|
setSelectedNode = this.actions$.pipe(
|
|
ofType(RTLActions.SET_SELECTED_NODE),
|
|
mergeMap((action: RTLActions.SetSelelectedNode) => {
|
|
this.store.dispatch(new RTLActions.ClearEffectErrorRoot('UpdateSelNode'));
|
|
return this.httpClient.post(environment.CONF_API + '/updateSelNode', { selNodeIndex: action.payload.lnNode.index })
|
|
.pipe(
|
|
map((postRes: any) => {
|
|
this.logger.info(postRes);
|
|
this.store.dispatch(new RTLActions.CloseSpinner());
|
|
if (sessionStorage.getItem('token')) {
|
|
let selNode = { channelBackupPath: action.payload.lnNode.settings.channelBackupPath, satsToBTC: action.payload.lnNode.settings.satsToBTC };
|
|
this.store.dispatch(new RTLActions.ResetRootStore(action.payload.lnNode));
|
|
this.store.dispatch(new RTLActions.ResetLNDStore(selNode));
|
|
this.store.dispatch(new RTLActions.ResetCLStore(selNode));
|
|
if(action.payload.lnNode.lnImplementation.toLowerCase() === 'clightning') {
|
|
this.router.navigate(['/cl/home']);
|
|
this.CHILD_API_URL = API_URL + '/cl';
|
|
return { type: RTLActions.VOID };
|
|
} else {
|
|
this.router.navigate(['/lnd/home']);
|
|
this.CHILD_API_URL = API_URL + '/lnd';
|
|
return { type: RTLActions.VOID };
|
|
}
|
|
} else {
|
|
if (!action.payload.isInitialSetup) {
|
|
return {
|
|
type: RTLActions.OPEN_ALERT,
|
|
payload: { width: '70%', data: {type: 'WARN', titleMessage: 'Authorization required to get the data from the node!' }}
|
|
};
|
|
} else {
|
|
return { type: RTLActions.VOID };
|
|
}
|
|
}
|
|
}),
|
|
catchError((err: any) => {
|
|
this.store.dispatch(new RTLActions.CloseSpinner());
|
|
this.store.dispatch(new RTLActions.EffectErrorRoot({ action: 'UpdateSelNode', code: err.status, message: err.error.message }));
|
|
this.logger.error(err);
|
|
return of(
|
|
{
|
|
type: RTLActions.OPEN_ALERT,
|
|
payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Update Selected Node Failed!',
|
|
message: JSON.stringify({code: err.status, Message: err.error.error})
|
|
}}
|
|
}
|
|
);
|
|
})
|
|
);
|
|
}
|
|
));
|
|
|
|
SetToken(token: string) {
|
|
if (token) {
|
|
sessionStorage.setItem('lndUnlocked', 'true');
|
|
sessionStorage.setItem('token', token);
|
|
this.store.dispatch(new RTLActions.InitAppData());
|
|
} else {
|
|
sessionStorage.removeItem('lndUnlocked');
|
|
sessionStorage.removeItem('token');
|
|
}
|
|
}
|
|
|
|
ngOnDestroy() {
|
|
this.unSubs.forEach(completeSub => {
|
|
completeSub.next();
|
|
completeSub.complete();
|
|
});
|
|
}
|
|
|
|
}
|