Implement monitoring of unconfirmed logins

This commit is contained in:
Rene Vergara 2021-11-09 15:00:01 -06:00
parent d05292b365
commit 648324ba5f
6 changed files with 140 additions and 45 deletions

View file

@ -8,10 +8,10 @@ const ownermodel = require('./models/owner');
const itemmodel = require('./models/item'); const itemmodel = require('./models/item');
const ordermodel = require('./models/order'); const ordermodel = require('./models/order');
const pricemodel = require('./models/price'); const pricemodel = require('./models/price');
const txmodel = require('./models/tx');
const mongoose = require('mongoose'); const mongoose = require('mongoose');
const stdrpc = require('stdrpc'); const stdrpc = require('stdrpc');
const CoinGecko = require('coingecko-api'); const CoinGecko = require('coingecko-api');
//const RequestIP = require('@supercharge/request-ip');
var db = require('./config/db'); var db = require('./config/db');
mongoose.connect('mongodb://'+db.user+':'+db.password+'@'+db.server+'/'+db.database).then(() => { mongoose.connect('mongodb://'+db.user+':'+db.password+'@'+db.server+'/'+db.database).then(() => {
@ -84,7 +84,7 @@ var blockInterval = setInterval( function() {
//console.log(docs); //console.log(docs);
//} //}
//}); //});
rpc.z_listreceivedbyaddress(fullnode.addr, 10).then(txs => { rpc.z_listreceivedbyaddress(fullnode.addr, 1).then(txs => {
var re = /.*ZGO::(.*)\sReply-To:\s(z\w+)/; var re = /.*ZGO::(.*)\sReply-To:\s(z\w+)/;
async.each (txs, function(txData, callback) { async.each (txs, function(txData, callback) {
var memo = hexToString(txData.memo); var memo = hexToString(txData.memo);
@ -96,6 +96,7 @@ var blockInterval = setInterval( function() {
var session = match[1]; var session = match[1];
var blocktime = txData.blocktime; var blocktime = txData.blocktime;
//console.log(' ', session, blocktime); //console.log(' ', session, blocktime);
if (txData.confirmations >= 10 ) {
usermodel.findOne({address: address, session: session, blocktime: blocktime}).then(function(doc){ usermodel.findOne({address: address, session: session, blocktime: blocktime}).then(function(doc){
if (doc != null) { if (doc != null) {
console.log('Found user'); console.log('Found user');
@ -136,6 +137,17 @@ var blockInterval = setInterval( function() {
}).catch((err) => { }).catch((err) => {
console.log(err); console.log(err);
}); });
txmodel.deleteMany({session: session}, function(err) {
if (err) console.log(err);
console.log('Deleted confirmed login');
});
} else {
txmodel.updateOne({address: address, session: session}, { confirmations: txData.confirmations, amount:txData.amount}, {new:true, upsert:true}, function(err,docs) {
if (err) {
console.log(err);
}
});
}
} }
} }
}, function (err) { }, function (err) {
@ -188,6 +200,26 @@ app.get('/api/users', (req, res, next) => {
}); });
}); });
app.get('/api/pending', (req, res, next) => {
console.log('Get: /api/pending');
txmodel.find({'session': req.query.session}).
then((documents) => {
if (documents.length > 0) {
//console.log('pending', documents);
res.status(200).json({
message: 'Found pending txs',
txs: documents
});
} else {
//console.log('pending not found', documents);
res.status(204).json({
message: 'No txs found',
txs: null
});
}
});
});
app.get('/api/getuser', (req, res, next) => { app.get('/api/getuser', (req, res, next) => {
console.log('Get: /api/getuser/', req.query.session); console.log('Get: /api/getuser/', req.query.session);
var today = new Date().getTime() / 1000; var today = new Date().getTime() / 1000;

10
backend/models/tx.js Normal file
View file

@ -0,0 +1,10 @@
const mongoose = require('mongoose');
const txSchema = mongoose.Schema({
address: {type: String},
session: {type: String, required:true},
confirmations: {type: Number, required:true},
amount: {type: Number, required:true}
});
module.exports = mongoose.model('Tx', txSchema);

View file

@ -31,7 +31,13 @@
</ul> </ul>
</mat-card> </mat-card>
</td> </td>
<td> <td align="center">
<mat-card *ngIf = "txs.length > 0">
<h4>Login received!</h4>
<mat-list>
<mat-list-item *ngFor="let tx of txsUpdate | async">It has {{tx.confirmations}} confirmations, needs 10.</mat-list-item>
</mat-list>
</mat-card>
<mat-card> <mat-card>
<div align="center" id="info"> <div align="center" id="info">
<p> <p>

View file

@ -2,6 +2,7 @@ import { Component, OnInit, OnDestroy, Injectable, ChangeDetectorRef } from '@an
import { CanActivate, Router, RouterStateSnapshot, ActivatedRouteSnapshot, ActivatedRoute } from '@angular/router'; import { CanActivate, Router, RouterStateSnapshot, ActivatedRouteSnapshot, ActivatedRoute } from '@angular/router';
import { UserService } from '../user.service'; import { UserService } from '../user.service';
import { FullnodeService } from '../fullnode.service'; import { FullnodeService } from '../fullnode.service';
import { Tx } from '../tx.model';
import { Subscription, Observable } from 'rxjs'; import { Subscription, Observable } from 'rxjs';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
var QRCode = require('easyqrcodejs'); var QRCode = require('easyqrcodejs');
@ -16,12 +17,14 @@ var Buffer = require('buffer/').Buffer;
}) })
export class LoginComponent implements OnInit { export class LoginComponent implements OnInit {
txs: Tx[] = [];
intervalHolder: any; intervalHolder: any;
nodeAddress: string = ''; nodeAddress: string = '';
private FullnodeSub: Subscription = new Subscription(); private FullnodeSub: Subscription = new Subscription();
private UserSub: Subscription = new Subscription(); private UserSub: Subscription = new Subscription();
public heightUpdate: Observable<number>; public heightUpdate: Observable<number>;
public uZaddrUpdate: Observable<string>; public uZaddrUpdate: Observable<string>;
public txsUpdate: Observable<Tx[]>;
constructor( constructor(
private activatedRoute: ActivatedRoute, private activatedRoute: ActivatedRoute,
public fullnodeService: FullnodeService, public fullnodeService: FullnodeService,
@ -32,6 +35,10 @@ export class LoginComponent implements OnInit {
//this.fullnodeService.getAddr(); //this.fullnodeService.getAddr();
this.heightUpdate = fullnodeService.heightUpdate; this.heightUpdate = fullnodeService.heightUpdate;
this.uZaddrUpdate = userService.uZaddrUpdate; this.uZaddrUpdate = userService.uZaddrUpdate;
this.txsUpdate = userService.txUpdate;
this.txsUpdate.subscribe((txs) => {
this.txs = txs;
});
} }
ngOnInit(){ ngOnInit(){
@ -78,6 +85,10 @@ export class LoginComponent implements OnInit {
loginCheck(){ loginCheck(){
this.userService.findUser(); this.userService.findUser();
this.userService.findPending();
this.txsUpdate.subscribe((txs) => {
this.txs = txs;
});
this.uZaddrUpdate.subscribe((userAddr: string) => { this.uZaddrUpdate.subscribe((userAddr: string) => {
if (userAddr.length != 0) { if (userAddr.length != 0) {
console.log('Log in found in blockchain!'); console.log('Log in found in blockchain!');

6
src/app/tx.model.ts Normal file
View file

@ -0,0 +1,6 @@
export interface Tx {
_id?: string;
address: string;
session: string;
confirmations: number;
}

View file

@ -3,12 +3,13 @@ import {Subject, BehaviorSubject, Observable} from 'rxjs';
import {HttpClient, HttpParams, HttpHeaders} from '@angular/common/http'; import {HttpClient, HttpParams, HttpHeaders} from '@angular/common/http';
import {User} from './user.model'; import {User} from './user.model';
import {Owner} from './owner.model'; import {Owner} from './owner.model';
import {Tx} from './tx.model';
@Injectable({providedIn: 'root'}) @Injectable({providedIn: 'root'})
export class UserService{ export class UserService{
beUrl = 'http://localhost:3000/'; beUrl = 'http://localhost:3000/';
private dataStore: { user: User, owner: Owner} = { private dataStore: { user: User, owner: Owner, txs: Tx[]} = {
user: { user: {
address: '', address: '',
session: '', session: '',
@ -17,7 +18,8 @@ export class UserService{
owner: { owner: {
address: '', address: '',
name: '' name: ''
} },
txs : []
}; };
private uZaddr = ''; private uZaddr = '';
private oZaddr = ''; private oZaddr = '';
@ -27,18 +29,21 @@ export class UserService{
private _userUpdated: BehaviorSubject<User> = new BehaviorSubject(this.dataStore.user); private _userUpdated: BehaviorSubject<User> = new BehaviorSubject(this.dataStore.user);
private uNameUpdated = new Subject<string>(); private uNameUpdated = new Subject<string>();
private _ownerUpdated: BehaviorSubject<Owner> = new BehaviorSubject(this.dataStore.owner); private _ownerUpdated: BehaviorSubject<Owner> = new BehaviorSubject(this.dataStore.owner);
private _txsUpdated: BehaviorSubject<Tx[]> = new BehaviorSubject(this.dataStore.txs);
public readonly uZaddrUpdate: Observable<string> = this._uZaddrUpdated.asObservable(); public readonly uZaddrUpdate: Observable<string> = this._uZaddrUpdated.asObservable();
public readonly ownerUpdate: Observable<Owner> = this._ownerUpdated.asObservable(); public readonly ownerUpdate: Observable<Owner> = this._ownerUpdated.asObservable();
public readonly userUpdate: Observable<User> = this._userUpdated.asObservable(); public readonly userUpdate: Observable<User> = this._userUpdated.asObservable();
public readonly txUpdate: Observable<Tx[]> = this._txsUpdated.asObservable();
private reqHeaders: HttpHeaders; private reqHeaders: HttpHeaders;
private apiKey = 'Le2adeic8Thah4Aeng4daem6i'; private apiKey = 'Le2adeic8Thah4Aeng4daem6i';
constructor(private http: HttpClient){ constructor(private http: HttpClient){
this.reqHeaders = new HttpHeaders().set('Authorization', this.apiKey); this.reqHeaders = new HttpHeaders().set('Authorization', this.apiKey);
console.log('US:', this.reqHeaders); //console.log('US:', this.reqHeaders);
this.session = localStorage.getItem('s4z_token'); this.session = localStorage.getItem('s4z_token');
if (this.session != null) { if (this.session != null) {
this.findUser(); this.findUser();
this.findPending();
} }
} }
@ -68,6 +73,31 @@ export class UserService{
} }
} }
findPending() {
this.session = localStorage.getItem('s4z_token');
if (this.session != null) {
const params = new HttpParams().append('session', this.session!);
let obs = this.http.get<{message: string, txs: any}>(this.beUrl+'api/pending', { headers: this.reqHeaders, params: params, observe: 'response'});
obs.subscribe((TxDataResponse) => {
//console.log('US Tx', TxDataResponse);
if (TxDataResponse.status == 200){
this.dataStore.txs = TxDataResponse.body!.txs;
console.log(`US: Pending logins found`);
this._txsUpdated.next(Object.assign({},this.dataStore).txs);
} else {
console.log('US: Did not find pending txs');
this.dataStore.txs = [];
this._txsUpdated.next(Object.assign({},this.dataStore).txs);
}
});
return obs;
} else {
console.log('No session loaded');
return null;
}
}
addOwner(address: string) { addOwner(address: string) {
const owner: Owner={_id: '', address: address, name: 'Zgo-'.concat(address.substring(0,5))}; const owner: Owner={_id: '', address: address, name: 'Zgo-'.concat(address.substring(0,5))};