Implement monitoring of unconfirmed logins
This commit is contained in:
parent
d05292b365
commit
648324ba5f
6 changed files with 140 additions and 45 deletions
114
backend/app.js
114
backend/app.js
|
@ -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,46 +96,58 @@ 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);
|
||||||
usermodel.findOne({address: address, session: session, blocktime: blocktime}).then(function(doc){
|
if (txData.confirmations >= 10 ) {
|
||||||
if (doc != null) {
|
usermodel.findOne({address: address, session: session, blocktime: blocktime}).then(function(doc){
|
||||||
console.log('Found user');
|
if (doc != null) {
|
||||||
} else {
|
console.log('Found user');
|
||||||
console.log('User not found', session, blocktime);
|
} else {
|
||||||
var user = new usermodel({
|
console.log('User not found', session, blocktime);
|
||||||
address: address,
|
var user = new usermodel({
|
||||||
session: session,
|
address: address,
|
||||||
blocktime: blocktime
|
session: session,
|
||||||
});
|
blocktime: blocktime
|
||||||
user.save(function(error) {
|
});
|
||||||
if (error) {
|
user.save(function(error) {
|
||||||
console.log(error);
|
if (error) {
|
||||||
}
|
console.log(error);
|
||||||
|
}
|
||||||
|
|
||||||
console.log('User saved');
|
console.log('User saved');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ownermodel.findOne({address: address}).then(function (oDoc) {
|
ownermodel.findOne({address: address}).then(function (oDoc) {
|
||||||
if (oDoc != null) {
|
if (oDoc != null) {
|
||||||
console.log('Found owner');
|
console.log('Found owner');
|
||||||
} else {
|
} else {
|
||||||
console.log('Owner not found', session);
|
console.log('Owner not found', session);
|
||||||
var owner = new ownermodel({
|
var owner = new ownermodel({
|
||||||
address: address,
|
address: address,
|
||||||
name: 'Z-Go-'.concat(address.substring(0,5))
|
name: 'Z-Go-'.concat(address.substring(0,5))
|
||||||
});
|
});
|
||||||
owner.save().then(function(err) {
|
owner.save().then(function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
console.log('Owner saved!');
|
console.log('Owner saved!');
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
console.log('Owner exists');
|
console.log('Owner exists');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).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
10
backend/models/tx.js
Normal 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);
|
|
@ -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>
|
||||||
|
|
|
@ -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
6
src/app/tx.model.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
export interface Tx {
|
||||||
|
_id?: string;
|
||||||
|
address: string;
|
||||||
|
session: string;
|
||||||
|
confirmations: number;
|
||||||
|
}
|
|
@ -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))};
|
||||||
|
|
Loading…
Reference in a new issue