mirror of
https://github.com/Ride-The-Lightning/RTL.git
synced 2024-11-19 09:50:36 +01:00
parent
d8835d2fcc
commit
d41e6d4a46
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -9,8 +9,8 @@
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="assets/images/favicon/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="assets/images/favicon/favicon-16x16.png">
|
||||
<link rel="manifest" href="assets/images/favicon/site.webmanifest">
|
||||
<link rel="stylesheet" href="styles.dc87b0a5f469f6ecc1b4.css"></head>
|
||||
<link rel="stylesheet" href="styles.e6b93e564e6b46dc016e.css"></head>
|
||||
<body>
|
||||
<rtl-app></rtl-app>
|
||||
<script src="runtime.987de13467a4c3a263de.js" defer></script><script src="polyfills-es5.37b2eeccc22c1df73ce7.js" nomodule defer></script><script src="polyfills.f1c3d2a0bcdfc4e93ca8.js" defer></script><script src="main.d1d565730bda0bc69787.js" defer></script></body>
|
||||
<script src="runtime.fd7f598087c4a68228d3.js" defer></script><script src="polyfills-es5.37b2eeccc22c1df73ce7.js" nomodule defer></script><script src="polyfills.f1c3d2a0bcdfc4e93ca8.js" defer></script><script src="main.ffc3e23c9362bb3a7234.js" defer></script></body>
|
||||
</html>
|
||||
|
File diff suppressed because one or more lines are too long
1
angular/main.ffc3e23c9362bb3a7234.js
Normal file
1
angular/main.ffc3e23c9362bb3a7234.js
Normal file
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
!function(e){function r(r){for(var n,a,i=r[0],c=r[1],l=r[2],p=0,s=[];p<i.length;p++)a=i[p],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,l||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++)0!==o[t[i]]&&(n=!1);n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={0:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,i=document.createElement("script");i.charset="utf-8",i.timeout=120,a.nc&&i.setAttribute("nonce",a.nc),i.src=function(e){return a.p+""+({}[e]||e)+"."+{1:"b78c4146e439be098e08",6:"1cabd441a095f3055cd4",7:"18eeb6e2c81e91aa476c"}[e]+".js"}(e);var c=new Error;u=function(r){i.onerror=i.onload=null,clearTimeout(l);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:i})}),12e4);i.onerror=i.onload=u,document.head.appendChild(i)}return Promise.all(r)},a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,(function(r){return e[r]}).bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="",a.oe=function(e){throw console.error(e),e};var i=window.webpackJsonp=window.webpackJsonp||[],c=i.push.bind(i);i.push=r,i=i.slice();for(var l=0;l<i.length;l++)r(i[l]);var f=c;t()}([]);
|
||||
!function(e){function r(r){for(var n,a,i=r[0],c=r[1],f=r[2],p=0,s=[];p<i.length;p++)a=i[p],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(l&&l(r);s.length;)s.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++)0!==o[t[i]]&&(n=!1);n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={0:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,i=document.createElement("script");i.charset="utf-8",i.timeout=120,a.nc&&i.setAttribute("nonce",a.nc),i.src=function(e){return a.p+""+({}[e]||e)+"."+{1:"b78c4146e439be098e08",6:"f485795c2defda71fe9b",7:"ee799a9ee1d85d393fd3"}[e]+".js"}(e);var c=new Error;u=function(r){i.onerror=i.onload=null,clearTimeout(f);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var f=setTimeout((function(){u({type:"timeout",target:i})}),12e4);i.onerror=i.onload=u,document.head.appendChild(i)}return Promise.all(r)},a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,(function(r){return e[r]}).bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="",a.oe=function(e){throw console.error(e),e};var i=window.webpackJsonp=window.webpackJsonp||[],c=i.push.bind(i);i.push=r,i=i.slice();for(var f=0;f<i.length;f++)r(i[f]);var l=c;t()}([]);
|
File diff suppressed because one or more lines are too long
1
angular/styles.e6b93e564e6b46dc016e.css
Normal file
1
angular/styles.e6b93e564e6b46dc016e.css
Normal file
File diff suppressed because one or more lines are too long
2
app.js
2
app.js
@ -26,6 +26,7 @@ const payReqRoutes = require("./routes/lnd/payReq");
|
||||
const paymentsRoutes = require("./routes/lnd/payments");
|
||||
const invoiceRoutes = require("./routes/lnd/invoices");
|
||||
const switchRoutes = require("./routes/lnd/switch");
|
||||
const messageRoutes = require("./routes/lnd/message");
|
||||
|
||||
const infoCLRoutes = require("./routes/c-lightning/getInfo");
|
||||
const feesCLRoutes = require("./routes/c-lightning/fees");
|
||||
@ -73,6 +74,7 @@ app.use(apiLNDRoot + "payreq", payReqRoutes);
|
||||
app.use(apiLNDRoot + "payments", paymentsRoutes);
|
||||
app.use(apiLNDRoot + "invoices", invoiceRoutes);
|
||||
app.use(apiLNDRoot + "switch", switchRoutes);
|
||||
app.use(apiLNDRoot + "message", messageRoutes);
|
||||
|
||||
app.use(apiCLRoot + "getinfo", infoCLRoutes);
|
||||
app.use(apiCLRoot + "fees", feesCLRoutes);
|
||||
|
57
controllers/lnd/message.js
Normal file
57
controllers/lnd/message.js
Normal file
@ -0,0 +1,57 @@
|
||||
var request = require('request-promise');
|
||||
var common = require('../../common');
|
||||
var logger = require('../logger');
|
||||
var options = {};
|
||||
|
||||
exports.signMessage = (req, res, next) => {
|
||||
options = common.getOptions();
|
||||
options.url = common.getSelLNServerUrl() + '/signmessage';
|
||||
options.form = JSON.stringify({
|
||||
msg: Buffer.from(req.body.message).toString('base64')
|
||||
});
|
||||
request.post(options, (error, response, body) => {
|
||||
logger.info({fileName: 'Messages', msg: 'Message Signed: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
res.status(500).json({
|
||||
message: "Sign message failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
});
|
||||
} else {
|
||||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Messages', lineNum: 24, msg: 'Sign Message Failed: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Sign Message Failed!',
|
||||
error: err.error
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.verifyMessage = (req, res, next) => {
|
||||
options = common.getOptions();
|
||||
options.url = common.getSelLNServerUrl() + '/verifymessage';
|
||||
options.form = JSON.stringify({
|
||||
msg: Buffer.from(req.body.message).toString('base64'),
|
||||
signature: req.body.signature
|
||||
});
|
||||
request.post(options, (error, response, body) => {
|
||||
logger.info({fileName: 'Messages', msg: 'Message Verified: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
res.status(500).json({
|
||||
message: "Verify message failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
});
|
||||
} else {
|
||||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Messages', lineNum: 24, msg: 'Message Verification Failed: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Verify Message Failed!',
|
||||
error: err.error
|
||||
});
|
||||
});
|
||||
};
|
9
routes/lnd/message.js
Normal file
9
routes/lnd/message.js
Normal file
@ -0,0 +1,9 @@
|
||||
const MessagesController = require("../../controllers/lnd/message");
|
||||
const express = require("express");
|
||||
const router = express.Router();
|
||||
const authCheck = require("../authCheck");
|
||||
|
||||
router.post("/sign", authCheck, MessagesController.signMessage);
|
||||
router.post("/verify", authCheck, MessagesController.verifyMessage);
|
||||
|
||||
module.exports = router;
|
@ -29,6 +29,9 @@ import { NodeLookupComponent } from './lookups/node-lookup/node-lookup.component
|
||||
import { BackupComponent } from './backup/backup.component';
|
||||
import { ChannelBackupTableComponent } from './backup/channel-backup-table/channel-backup-table.component';
|
||||
import { ChannelRestoreTableComponent } from './backup/channel-restore-table/channel-restore-table.component';
|
||||
import { SignVerifyMessageComponent } from './sign-verify-message/sign-verify-message.component';
|
||||
import { SignComponent } from './sign-verify-message/sign/sign.component';
|
||||
import { VerifyComponent } from './sign-verify-message/verify/verify.component';
|
||||
import { QueryRoutesComponent } from './transactions/query-routes/query-routes.component';
|
||||
import { ChannelOpenTableComponent } from './peers-channels/channels/channels-tables/channel-open-table/channel-open-table.component';
|
||||
import { UnlockWalletComponent } from './wallet/unlock/unlock.component';
|
||||
@ -69,8 +72,11 @@ import { LNDUnlockedGuard } from '../shared/services/auth.guard';
|
||||
NodeLookupComponent,
|
||||
BackupComponent,
|
||||
ChannelBackupTableComponent,
|
||||
QueryRoutesComponent,
|
||||
ChannelRestoreTableComponent,
|
||||
SignVerifyMessageComponent,
|
||||
SignComponent,
|
||||
VerifyComponent,
|
||||
QueryRoutesComponent,
|
||||
OnChainSendComponent,
|
||||
OnChainReceiveComponent,
|
||||
OnChainComponent,
|
||||
|
@ -10,10 +10,11 @@ import { LookupsComponent } from './lookups/lookups.component';
|
||||
import { RoutingComponent } from './routing/routing.component';
|
||||
import { OnChainComponent } from './on-chain/on-chain.component';
|
||||
import { NetworkInfoComponent } from './network-info/network-info.component';
|
||||
import { BackupComponent } from './backup/backup.component';
|
||||
import { SignVerifyMessageComponent } from './sign-verify-message/sign-verify-message.component';
|
||||
import { NotFoundComponent } from '../shared/components/not-found/not-found.component';
|
||||
|
||||
import { AuthGuard, LNDUnlockedGuard } from '../shared/services/auth.guard';
|
||||
import { NotFoundComponent } from '../shared/components/not-found/not-found.component';
|
||||
import { BackupComponent } from './backup/backup.component';
|
||||
|
||||
export const LndRoutes: Routes = [
|
||||
{ path: '', component: LNDRootComponent,
|
||||
@ -23,6 +24,7 @@ export const LndRoutes: Routes = [
|
||||
{ path: 'onchain', component: OnChainComponent, canActivate: [LNDUnlockedGuard] },
|
||||
{ path: 'peerschannels', component: PeersChannelsComponent, canActivate: [LNDUnlockedGuard] },
|
||||
{ path: 'transactions', component: TransactionsComponent, canActivate: [LNDUnlockedGuard] },
|
||||
{ path: 'signverify', component: SignVerifyMessageComponent, canActivate: [LNDUnlockedGuard] },
|
||||
{ path: 'backup', component: BackupComponent, canActivate: [LNDUnlockedGuard] },
|
||||
{ path: 'routing', component: RoutingComponent, canActivate: [LNDUnlockedGuard] },
|
||||
{ path: 'lookups', component: LookupsComponent, canActivate: [LNDUnlockedGuard] },
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
|
||||
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil, filter, take } from 'rxjs/operators';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
@ -0,0 +1,15 @@
|
||||
<div fxLayout="row" fxLayoutAlign="start center" class="padding-gap-x page-title-container">
|
||||
<fa-icon [icon]="faUserCheck" class="page-title-img mr-1"></fa-icon>
|
||||
<span class="page-title">Sign/Verify Message</span>
|
||||
</div>
|
||||
<div fxLayout="column" class="padding-gap-x">
|
||||
<mat-card>
|
||||
<mat-card-content fxLayout="column">
|
||||
<mat-tab-group>
|
||||
<mat-tab label="Sign"><rtl-sign></rtl-sign></mat-tab>
|
||||
<mat-tab label="Verify"><rtl-verify></rtl-verify></mat-tab>
|
||||
</mat-tab-group>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
|
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SignVerifyMessageComponent } from './sign-verify-message.component';
|
||||
|
||||
describe('SignVerifyMessageComponent', () => {
|
||||
let component: SignVerifyMessageComponent;
|
||||
let fixture: ComponentFixture<SignVerifyMessageComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ SignVerifyMessageComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SignVerifyMessageComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,14 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { faUserCheck } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-sign-verify-message',
|
||||
templateUrl: './sign-verify-message.component.html',
|
||||
styleUrls: ['./sign-verify-message.component.scss']
|
||||
})
|
||||
export class SignVerifyMessageComponent {
|
||||
public faUserCheck = faUserCheck;
|
||||
|
||||
constructor() {}
|
||||
|
||||
}
|
16
src/app/lnd/sign-verify-message/sign/sign.component.html
Normal file
16
src/app/lnd/sign-verify-message/sign/sign.component.html
Normal file
@ -0,0 +1,16 @@
|
||||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch">
|
||||
<form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap" #form="ngForm">
|
||||
<mat-form-field fxFlex="100" fxLayoutAlign="start end">
|
||||
<textarea autoFocus matInput [(ngModel)]="message" rows="5" (focus)="signature=''" placeholder="Message" required tabindex="1" name="message"></textarea>
|
||||
<mat-error *ngIf="!message">Message is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="start start" class="mt-1 bordered-box padding-gap-large">
|
||||
<p>{{signature}}</p>
|
||||
</div>
|
||||
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" class="mt-2">
|
||||
<button fxFlex="30" mat-stroked-button color="primary" tabindex="2" type="reset" (click)="resetData()" type="reset">Clear Field</button>
|
||||
<button fxFlex="30" mat-flat-button color="primary" (click)="onSign()" tabindex="3" type="submit">Sign</button>
|
||||
<button fxFlex="35" mat-flat-button color="primary" tabindex="4" rtlClipboard [payload]="signature" (copied)="onCopyField($event)" type="button">Copy Signature</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
6
src/app/lnd/sign-verify-message/sign/sign.component.scss
Normal file
6
src/app/lnd/sign-verify-message/sign/sign.component.scss
Normal file
@ -0,0 +1,6 @@
|
||||
.mat-column-channel_point {
|
||||
flex: 1 1 25%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
25
src/app/lnd/sign-verify-message/sign/sign.component.spec.ts
Normal file
25
src/app/lnd/sign-verify-message/sign/sign.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SignComponent } from './sign.component';
|
||||
|
||||
describe('SignComponent', () => {
|
||||
let component: SignComponent;
|
||||
let fixture: ComponentFixture<SignComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ SignComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SignComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
44
src/app/lnd/sign-verify-message/sign/sign.component.ts
Normal file
44
src/app/lnd/sign-verify-message/sign/sign.component.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { MatSnackBar } from '@angular/material';
|
||||
|
||||
import { DataService } from '../../../shared/services/data.service';
|
||||
import { LoggerService } from '../../../shared/services/logger.service';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-sign',
|
||||
templateUrl: './sign.component.html',
|
||||
styleUrls: ['./sign.component.scss']
|
||||
})
|
||||
export class SignComponent implements OnInit, OnDestroy {
|
||||
public message = '';
|
||||
public signature = '';
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
|
||||
|
||||
constructor(private dataService: DataService, private snackBar: MatSnackBar, private logger: LoggerService) {}
|
||||
|
||||
ngOnInit() {}
|
||||
|
||||
onSign() {
|
||||
if (!this.message || this.message === '') { return true; }
|
||||
this.dataService.signMessage(this.message).pipe(takeUntil(this.unSubs[0])).subscribe(res => { this.signature = res; });
|
||||
}
|
||||
|
||||
onCopyField(payload: string) {
|
||||
this.snackBar.open('Signature copied.');
|
||||
this.logger.info('Copied Text: ' + payload);
|
||||
}
|
||||
|
||||
resetData() {
|
||||
this.message = '';
|
||||
this.signature = '';
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach(completeSub => {
|
||||
completeSub.next();
|
||||
completeSub.complete();
|
||||
});
|
||||
}
|
||||
}
|
19
src/app/lnd/sign-verify-message/verify/verify.component.html
Normal file
19
src/app/lnd/sign-verify-message/verify/verify.component.html
Normal file
@ -0,0 +1,19 @@
|
||||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch">
|
||||
<form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap" #form="ngForm">
|
||||
<mat-form-field fxFlex="100" fxLayoutAlign="start end">
|
||||
<textarea autoFocus matInput [(ngModel)]="message" rows="5" (focus)="verifyRes=null" placeholder="Message" required tabindex="1" name="message"></textarea>
|
||||
<mat-error *ngIf="!message">Message is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="100" fxLayoutAlign="start end">
|
||||
<input matInput placeholder="Signature" name="signature" [(ngModel)]="signature" tabindex="2" required #sign="ngModel">
|
||||
<mat-error *ngIf="!signature">Signature is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="start start" class="mt-1 bordered-box padding-gap-large" [ngClass]="{'border-valid': verifyRes?.valid, 'border-invalid': verifyRes?.pubkey && !verifyRes?.valid}">
|
||||
<p>{{!verifyRes?.pubkey ? '' : (verifyRes?.pubkey && verifyRes?.valid) ? 'Valid: ' : 'Invalid: '}}{{verifyRes?.pubkey}}</p>
|
||||
</div>
|
||||
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" class="mt-2">
|
||||
<button fxFlex="48" mat-stroked-button color="primary" tabindex="3" type="reset" (click)="resetData()" type="reset">Clear Field</button>
|
||||
<button fxFlex="48" mat-flat-button color="primary" (click)="onVerify()" tabindex="4" type="submit">Verify</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
@ -0,0 +1,6 @@
|
||||
.mat-column-channel_point {
|
||||
flex: 1 1 25%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { VerifyComponent } from './verify.component';
|
||||
|
||||
describe('VerifyComponent', () => {
|
||||
let component: VerifyComponent;
|
||||
let fixture: ComponentFixture<VerifyComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ VerifyComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(VerifyComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
39
src/app/lnd/sign-verify-message/verify/verify.component.ts
Normal file
39
src/app/lnd/sign-verify-message/verify/verify.component.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { DataService } from '../../../shared/services/data.service';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-verify',
|
||||
templateUrl: './verify.component.html',
|
||||
styleUrls: ['./verify.component.scss']
|
||||
})
|
||||
export class VerifyComponent implements OnInit, OnDestroy {
|
||||
public message = '';
|
||||
public signature = '';
|
||||
public verifyRes = {pubkey: '', valid: null};
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
|
||||
|
||||
constructor(private dataService: DataService) {}
|
||||
|
||||
ngOnInit() {}
|
||||
|
||||
onVerify() {
|
||||
if ((!this.message || this.message === '') || (!this.signature || this.signature === '')) { return true; }
|
||||
this.dataService.verifyMessage(this.message, this.signature).pipe(takeUntil(this.unSubs[0])).subscribe(res => { this.verifyRes = res; });
|
||||
}
|
||||
|
||||
resetData() {
|
||||
this.message = '';
|
||||
this.signature = '';
|
||||
this.verifyRes = null;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach(completeSub => {
|
||||
completeSub.next();
|
||||
completeSub.complete();
|
||||
});
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@
|
||||
<mat-card-content class="mt-5px">
|
||||
<form fxLayout="column">
|
||||
<div fxLayout="column" class="bordered-box my-2 p-2">
|
||||
<p fxLayoutAlign="start center" class="pb-1">Closing channel: {{channelToClose.channel_point}}</p>
|
||||
<p fxLayoutAlign="start center" class="pb-1 word-break">Closing channel: {{channelToClose.channel_point}}</p>
|
||||
<div fxLayoutAlign="space-between center">
|
||||
<mat-form-field fxFlex.gt-sm="48">
|
||||
<mat-select [(value)]="selTransType" tabindex="1">
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { faTachometerAlt, faLink, faBolt, faExchangeAlt, faUsers, faMapSigns, faQuestion, faSearch, faTools, faProjectDiagram, faDownload, faServer, faPercentage } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faTachometerAlt, faLink, faBolt, faExchangeAlt, faUsers, faMapSigns, faQuestion, faSearch, faTools, faProjectDiagram, faDownload, faServer, faPercentage, faUserCheck } from '@fortawesome/free-solid-svg-icons';
|
||||
import { UserPersonaEnum } from '../services/consts-enums-functions';
|
||||
|
||||
export const MENU_DATA: MenuRootNode = {
|
||||
@ -10,7 +10,8 @@ export const MENU_DATA: MenuRootNode = {
|
||||
{id: 32, parentId: 3, name: 'Transactions', iconType: 'FA', icon: faExchangeAlt, link: '/lnd/transactions', userPersona: UserPersonaEnum.ALL},
|
||||
{id: 33, parentId: 3, name: 'Routing', iconType: 'FA', icon: faMapSigns, link: '/lnd/routing', userPersona: UserPersonaEnum.ALL},
|
||||
{id: 34, parentId: 3, name: 'Graph Lookup', iconType: 'FA', icon: faSearch, link: '/lnd/lookups', userPersona: UserPersonaEnum.ALL},
|
||||
{id: 35, parentId: 3, name: 'Backup', iconType: 'FA', icon: faDownload, link: '/lnd/backup', userPersona: UserPersonaEnum.ALL}
|
||||
{id: 35, parentId: 3, name: 'Sign/Verify', iconType: 'FA', icon: faUserCheck, link: '/lnd/signverify', userPersona: UserPersonaEnum.ALL},
|
||||
{id: 36, parentId: 3, name: 'Backup', iconType: 'FA', icon: faDownload, link: '/lnd/backup', userPersona: UserPersonaEnum.ALL}
|
||||
]},
|
||||
{id: 5, parentId: 0, name: 'Network', iconType: 'FA', icon: faProjectDiagram, link: '/lnd/network', userPersona: UserPersonaEnum.OPERATOR},
|
||||
{id: 6, parentId: 0, name: 'Node/Network', iconType: 'FA', icon: faServer, link: '/lnd/network', userPersona: UserPersonaEnum.MERCHANT},
|
||||
|
@ -2,14 +2,21 @@ import { Injectable, OnInit, OnDestroy } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Subject, of, Observable } from 'rxjs';
|
||||
import { take, map, takeUntil, catchError } from 'rxjs/operators';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import { LoggerService } from '../../shared/services/logger.service';
|
||||
import { environment, API_URL } from '../../../environments/environment';
|
||||
|
||||
import * as RTLActions from '../../store/rtl.actions';
|
||||
import * as fromRTLReducer from '../../store/rtl.reducers';
|
||||
import { ErrorMessageComponent } from '../components/data-modal/error-message/error-message.component';
|
||||
|
||||
@Injectable()
|
||||
export class DataService implements OnInit, OnDestroy {
|
||||
private CHILD_API_URL = API_URL + '/lnd';
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
|
||||
|
||||
constructor(private httpClient: HttpClient) {}
|
||||
constructor(private httpClient: HttpClient, private store: Store<fromRTLReducer.RTLState>, private logger: LoggerService,) {}
|
||||
|
||||
ngOnInit() {}
|
||||
|
||||
@ -29,6 +36,62 @@ export class DataService implements OnInit, OnDestroy {
|
||||
return nodes$;
|
||||
}
|
||||
|
||||
signMessage(msg: string) {
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Signing Message...'));
|
||||
return this.httpClient.post(this.CHILD_API_URL + environment.MESSAGE_API + '/sign', {message: msg})
|
||||
.pipe(takeUntil(this.unSubs[1]),
|
||||
map((res: any) => {
|
||||
this.store.dispatch(new RTLActions.CloseSpinner());
|
||||
return res.signature;
|
||||
}),
|
||||
catchError(err => {
|
||||
this.handleErrorWithAlert('ERROR', 'Sign Message Failed', this.CHILD_API_URL + environment.MESSAGE_API + '/sign', err);
|
||||
throw err;
|
||||
}));
|
||||
}
|
||||
|
||||
verifyMessage(msg: string, sign: string) {
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Verifying Message...'));
|
||||
return this.httpClient.post(this.CHILD_API_URL + environment.MESSAGE_API + '/verify', {message: msg, signature: sign})
|
||||
.pipe(takeUntil(this.unSubs[2]),
|
||||
map((res: any) => {
|
||||
this.store.dispatch(new RTLActions.CloseSpinner());
|
||||
return res;
|
||||
}),
|
||||
catchError(err => {
|
||||
this.handleErrorWithAlert('ERROR', 'Verify Message Failed', this.CHILD_API_URL + environment.MESSAGE_API + '/verify', err);
|
||||
throw err;
|
||||
}));
|
||||
}
|
||||
|
||||
handleErrorWithoutAlert(actionName: string, err: { status: number, error: any }) {
|
||||
this.logger.error('ERROR IN: ' + actionName + '\n' + JSON.stringify(err));
|
||||
if (err.status === 401) {
|
||||
this.logger.info('Redirecting to Login');
|
||||
this.store.dispatch(new RTLActions.Logout());
|
||||
} else {
|
||||
this.store.dispatch(new RTLActions.EffectErrorLnd({ action: actionName, code: err.status.toString(), message: err.error.error }));
|
||||
}
|
||||
}
|
||||
|
||||
handleErrorWithAlert(alertType: string, alertTitle: string, errURL: string, err: { status: number, error: any }) {
|
||||
this.logger.error(err);
|
||||
if (err.status === 401) {
|
||||
this.logger.info('Redirecting to Login');
|
||||
this.store.dispatch(new RTLActions.Logout());
|
||||
} else {
|
||||
this.store.dispatch(new RTLActions.CloseSpinner());
|
||||
this.store.dispatch(new RTLActions.OpenAlert({
|
||||
data: {
|
||||
type: alertType,
|
||||
alertTitle: alertTitle,
|
||||
message: { code: err.status, message: err.error.error, URL: errURL },
|
||||
component: ErrorMessageComponent
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach(completeSub => {
|
||||
completeSub.next();
|
||||
|
@ -391,6 +391,7 @@
|
||||
border: 1px solid $foreground-divider;
|
||||
border-radius: 4px;
|
||||
background: none;
|
||||
min-height: 5.5rem;
|
||||
}
|
||||
|
||||
.mat-expansion-panel {
|
||||
|
@ -961,3 +961,11 @@ table {
|
||||
overflow-y: scroll;
|
||||
max-height: 600px;
|
||||
}
|
||||
|
||||
.border-valid {
|
||||
border: 1px solid $green-color !important;
|
||||
}
|
||||
|
||||
.border-invalid {
|
||||
border: 1px solid $red-color !important;
|
||||
}
|
||||
|
@ -22,5 +22,6 @@ export const environment = {
|
||||
INVOICES_API: '/invoices',
|
||||
SWITCH_API: '/switch',
|
||||
ON_CHAIN_API: '/onchain',
|
||||
MESSAGE_API: '/message',
|
||||
VERSION: VERSION
|
||||
};
|
||||
|
@ -22,5 +22,6 @@ export const environment = {
|
||||
INVOICES_API: '/invoices',
|
||||
SWITCH_API: '/switch',
|
||||
ON_CHAIN_API: '/onchain',
|
||||
MESSAGE_API: '/message',
|
||||
VERSION: VERSION
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user