[enh] Init project
This commit is contained in:
16
app.yml
Normal file
16
app.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
salt: test
|
||||
passwd: test
|
||||
ws2pServers:
|
||||
- address: ws://g1-test.cgeek.fr:20900
|
||||
expectedPubkey: 2ny7YAdmzReQxAayyJZsyVYwYhVyax2thKcGknmQy5nQ
|
||||
|
||||
mail:
|
||||
enabled: true
|
||||
host: smtp.sparkpostmail.com
|
||||
port: 587
|
||||
auth: LOGIN
|
||||
encryption: STARTTLS
|
||||
username: SMTP_Injection
|
||||
apikey: 6976eb51635b680b832dbe4914524d2c038a13b6
|
||||
from: '"DWatcher" <dwatcher@cgeek.fr>'
|
||||
to: cem.moreau@gmail.com
|
||||
21
package.json
Normal file
21
package.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "dwatcher",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"repository": "gogs@dev.cgeek.fr:cgeek/dwatcher.git",
|
||||
"author": "cgeek <cem.moreau@gmail.com>",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/minimist": "^1.2.0",
|
||||
"duniter": "^1.8.0",
|
||||
"js-yaml": "^3.12.1",
|
||||
"minimist": "^1.2.0",
|
||||
"nodemailer": "^6.2.1",
|
||||
"typescript": "^3.4.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/js-yaml": "^3.12.0",
|
||||
"@types/node": "~8.9.4",
|
||||
"@types/nodemailer": "^6.1.1"
|
||||
}
|
||||
}
|
||||
30
src/dwatcher.ts
Normal file
30
src/dwatcher.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import * as minimist from 'minimist'
|
||||
import * as path from 'path'
|
||||
import {dwatch} from './lib/dwatch'
|
||||
|
||||
process.on('uncaughtException', (err) => {
|
||||
// Dunno why this specific exception is not caught
|
||||
console.error(err.stack || err.message || err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
process.on('unhandledRejection', (err) => {
|
||||
// Dunno why this specific exception is not caught
|
||||
console.error(err.stack || err.message || err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
(async () => {
|
||||
|
||||
const argv = minimist(process.argv.slice(2))
|
||||
console.log('Starting...')
|
||||
|
||||
try {
|
||||
await dwatch(argv.conf || path.join(__dirname, '../app.yml'))
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
} finally {
|
||||
console.log('Finished')
|
||||
}
|
||||
})()
|
||||
|
||||
25
src/lib/conf.ts
Normal file
25
src/lib/conf.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
export interface Conf {
|
||||
currency: string
|
||||
salt: string
|
||||
passwd: string
|
||||
connectionTimeout: 10000
|
||||
ws2pServers: ConfServers[]
|
||||
mail: ConfMail
|
||||
}
|
||||
|
||||
export interface ConfServers {
|
||||
address: string
|
||||
expectedKey: string
|
||||
}
|
||||
|
||||
export interface ConfMail {
|
||||
enabled: boolean
|
||||
host: string
|
||||
port: number
|
||||
auth: string
|
||||
encryption: string
|
||||
username: string
|
||||
apikey: string
|
||||
from: string
|
||||
to: string
|
||||
}
|
||||
52
src/lib/dwatch.ts
Normal file
52
src/lib/dwatch.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import {Conf} from './conf'
|
||||
import * as yaml from 'js-yaml';
|
||||
import * as fs from 'fs';
|
||||
import {WS2PConnection, WS2PPubkeyLocalAuth, WS2PPubkeyRemoteAuth} from 'duniter/app/modules/ws2p/lib/WS2PConnection'
|
||||
import {MessageHandler} from './message-handler'
|
||||
import {Key} from 'duniter/app/lib/common-libs/crypto/keyring'
|
||||
import {Scrypt} from 'duniter/app/modules/keypair/lib/scrypt'
|
||||
import {sendMail} from './sendMail'
|
||||
import {moment} from 'duniter/app/lib/common-libs/moment'
|
||||
|
||||
export async function dwatch(confFile: string) {
|
||||
|
||||
const yml = fs.readFileSync(confFile, 'utf8')
|
||||
const conf = yaml.load(yml) as Conf
|
||||
const keys = await Scrypt(conf.salt, conf.passwd)
|
||||
const keypair = new Key(keys.pub, keys.sec)
|
||||
|
||||
await Promise.all(conf.ws2pServers.map(async wserver => {
|
||||
|
||||
const localAuth = new WS2PPubkeyLocalAuth(conf.currency, keypair, "", async () => true)
|
||||
const remoteAuth = new WS2PPubkeyRemoteAuth(conf.currency, keypair, async () => true)
|
||||
|
||||
const c = WS2PConnection.newConnectionToAddress(
|
||||
1,
|
||||
wserver.address,
|
||||
new MessageHandler(),
|
||||
localAuth,
|
||||
remoteAuth,
|
||||
undefined,
|
||||
{
|
||||
connectionTimeout: conf.connectionTimeout,
|
||||
requestTimeout: 0 // No request anyway
|
||||
},
|
||||
wserver.expectedKey
|
||||
)
|
||||
|
||||
await c.connectAsInitiator()
|
||||
|
||||
c.closed.then(async () => {
|
||||
console.log('Connection closed')
|
||||
await sendMail(conf.mail, '[dwatcher] Connection closed', `
|
||||
<p>
|
||||
Connection to ${c.pubkey} was lost on ${moment().format('dd-MM-YYYY HH:mm:ss')}.
|
||||
</p>
|
||||
`)
|
||||
})
|
||||
|
||||
await c.connected
|
||||
|
||||
console.log('Connected to %s', c.pubkey)
|
||||
}))
|
||||
}
|
||||
19
src/lib/message-handler.ts
Normal file
19
src/lib/message-handler.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import {WS2PMessageHandler} from 'duniter/app/modules/ws2p/lib/impl/WS2PMessageHandler'
|
||||
import {WS2PConnection} from 'duniter/app/modules/ws2p/lib/WS2PConnection'
|
||||
import {WS2PResponse} from 'duniter/app/modules/ws2p/lib/impl/WS2PResponse'
|
||||
|
||||
export class MessageHandler implements WS2PMessageHandler {
|
||||
|
||||
async answerToRequest(json: any, c: WS2PConnection): Promise<WS2PResponse> {
|
||||
console.log('Request from %s = %s', c.pubkey, JSON.stringify(json))
|
||||
return {}
|
||||
}
|
||||
|
||||
/**
|
||||
* THAT'S THE CORE OF DWATCHER: tracing push messages
|
||||
*/
|
||||
async handlePushMessage(json: any, c: WS2PConnection): Promise<void> {
|
||||
console.log('Push from %s = %s', c.pubkey, JSON.stringify(json))
|
||||
}
|
||||
|
||||
}
|
||||
27
src/lib/sendMail.ts
Normal file
27
src/lib/sendMail.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import * as nodemailer from 'nodemailer'
|
||||
import {ConfMail} from './conf'
|
||||
|
||||
export async function sendMail(conf: ConfMail, subject: string, html: string) {
|
||||
|
||||
if (conf.enabled) {
|
||||
let transporter = nodemailer.createTransport({
|
||||
host: conf.host,
|
||||
port: conf.port,
|
||||
secure: false, // true for 465, false for other ports
|
||||
auth: {
|
||||
user: conf.username, // generated ethereal user
|
||||
pass: conf.apikey // generated ethereal password
|
||||
},
|
||||
authMethod: conf.auth,
|
||||
requireTLS: true,
|
||||
});
|
||||
|
||||
// send mail with defined transport object
|
||||
let info = await transporter.sendMail({
|
||||
from: conf.from,
|
||||
to: conf.to,
|
||||
subject,
|
||||
html
|
||||
})
|
||||
}
|
||||
}
|
||||
19
tsconfig.json
Normal file
19
tsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"sourceMap": true,
|
||||
"target": "es6",
|
||||
"declaration": true,
|
||||
"moduleResolution": "node",
|
||||
"module": "commonjs",
|
||||
"strictNullChecks": true,
|
||||
"noImplicitThis": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"experimentalDecorators": true
|
||||
},
|
||||
"include": [
|
||||
"src/*",
|
||||
"../node_modules/@types/node/globals.d.ts"
|
||||
],
|
||||
"compileOnSave": true
|
||||
}
|
||||
Reference in New Issue
Block a user