Browse Source

auto-unlock, post unlock for voltage

dependabot/npm_and_yarn/ini-1.3.7
Evan Feenstra 4 years ago
parent
commit
494f7d86a8
  1. 62
      app.ts
  2. 61
      dist/app.js
  3. 2
      dist/app.js.map
  4. 129
      dist/src/auth.js
  5. 1
      dist/src/auth.js.map
  6. 2
      dist/src/grpc/index.js
  7. 2
      dist/src/grpc/index.js.map
  8. 19
      dist/src/utils/lightning.js
  9. 2
      dist/src/utils/lightning.js.map
  10. 22
      dist/src/utils/macaroon.js
  11. 1
      dist/src/utils/macaroon.js.map
  12. 45
      dist/src/utils/unlock.js
  13. 1
      dist/src/utils/unlock.js.map
  14. 5
      package-lock.json
  15. 1
      package.json
  16. 124
      src/auth.ts
  17. 2
      src/grpc/index.ts
  18. 21
      src/utils/lightning.ts
  19. 20
      src/utils/macaroon.ts
  20. 34
      src/utils/unlock.ts

62
app.ts

@ -3,17 +3,15 @@ import * as bodyParser from 'body-parser'
import * as helmet from 'helmet'
import * as cookieParser from 'cookie-parser'
import * as cors from 'cors'
import * as crypto from 'crypto'
import * as path from 'path'
import {models} from './src/models'
import logger from './src/utils/logger'
import {pingHubInterval, checkInvitesHubInterval} from './src/hub'
import {setupDatabase, setupDone} from './src/utils/setup'
import * as controllers from './src/controllers'
import * as socket from './src/utils/socket'
import * as network from './src/network'
import {authModule, unlocker} from './src/auth'
let server: any = null
const env = process.env.NODE_ENV || 'development';
const config = require(path.join(__dirname, 'config/app.json'))[env];
const port = process.env.PORT || config.node_http_port || 3001
@ -86,53 +84,17 @@ async function setupApp(){
console.log(`Node listening on ${port}.`);
});
controllers.set(app);
socket.connect(server)
}
async function authModule(req, res, next) {
if (
req.path == '/app' ||
req.path == '/' ||
req.path == '/info' ||
req.path == '/action' ||
req.path == '/contacts/tokens' ||
req.path == '/latest' ||
req.path.startsWith('/static') ||
req.path == '/contacts/set_dev'
) {
next()
return
}
if (process.env.HOSTING_PROVIDER==='true'){
// const domain = process.env.INVITE_SERVER
const host = req.headers.origin
console.log('=> host:', host)
const referer = req.headers.referer
console.log('=> referer:', referer)
if (req.path === '/invoices') {
next()
return
}
}
const token = req.headers['x-user-token'] || req.cookies['x-user-token']
if (token == null) {
res.writeHead(401, 'Access invalid for user', {'Content-Type' : 'text/plain'});
res.end('Invalid credentials');
// start all routes!
if(!config.unlock) {
controllers.set(app);
socket.connect(server)
} else {
const user = await models.Contact.findOne({ where: { isOwner: true }})
const hashedToken = crypto.createHash('sha256').update(token).digest('base64');
if (user.authToken == null || user.authToken != hashedToken) {
res.writeHead(401, 'Access invalid for user', {'Content-Type' : 'text/plain'});
res.end('Invalid credentials');
} else {
next();
}
app.post('/unlock', async function(req,res){
const ok = await unlocker(req,res)
if(ok) {
controllers.set(app);
socket.connect(server)
}
})
}
}
export default server

61
dist/app.js

@ -14,16 +14,14 @@ const bodyParser = require("body-parser");
const helmet = require("helmet");
const cookieParser = require("cookie-parser");
const cors = require("cors");
const crypto = require("crypto");
const path = require("path");
const models_1 = require("./src/models");
const logger_1 = require("./src/utils/logger");
const hub_1 = require("./src/hub");
const setup_1 = require("./src/utils/setup");
const controllers = require("./src/controllers");
const socket = require("./src/utils/socket");
const network = require("./src/network");
let server = null;
const auth_1 = require("./src/auth");
const env = process.env.NODE_ENV || 'development';
const config = require(path.join(__dirname, 'config/app.json'))[env];
const port = process.env.PORT || config.node_http_port || 3001;
@ -86,7 +84,7 @@ function setupApp() {
}));
app.use(cookieParser());
if (env != 'development') {
app.use(authModule);
app.use(auth_1.authModule);
}
app.use('/static', express.static('public'));
app.get('/app', (req, res) => res.send('INDEX'));
@ -96,51 +94,22 @@ function setupApp() {
/* eslint-disable no-console */
console.log(`Node listening on ${port}.`);
});
controllers.set(app);
socket.connect(server);
});
}
function authModule(req, res, next) {
return __awaiter(this, void 0, void 0, function* () {
if (req.path == '/app' ||
req.path == '/' ||
req.path == '/info' ||
req.path == '/action' ||
req.path == '/contacts/tokens' ||
req.path == '/latest' ||
req.path.startsWith('/static') ||
req.path == '/contacts/set_dev') {
next();
return;
}
if (process.env.HOSTING_PROVIDER === 'true') {
// const domain = process.env.INVITE_SERVER
const host = req.headers.origin;
console.log('=> host:', host);
const referer = req.headers.referer;
console.log('=> referer:', referer);
if (req.path === '/invoices') {
next();
return;
}
}
const token = req.headers['x-user-token'] || req.cookies['x-user-token'];
if (token == null) {
res.writeHead(401, 'Access invalid for user', { 'Content-Type': 'text/plain' });
res.end('Invalid credentials');
// start all routes!
if (!config.unlock) {
controllers.set(app);
socket.connect(server);
}
else {
const user = yield models_1.models.Contact.findOne({ where: { isOwner: true } });
const hashedToken = crypto.createHash('sha256').update(token).digest('base64');
if (user.authToken == null || user.authToken != hashedToken) {
res.writeHead(401, 'Access invalid for user', { 'Content-Type': 'text/plain' });
res.end('Invalid credentials');
}
else {
next();
}
app.post('/unlock', function (req, res) {
return __awaiter(this, void 0, void 0, function* () {
const ok = yield auth_1.unlocker(req, res);
if (ok) {
controllers.set(app);
socket.connect(server);
}
});
});
}
});
}
exports.default = server;
//# sourceMappingURL=app.js.map

2
dist/app.js.map

@ -1 +1 @@
{"version":3,"file":"app.js","sourceRoot":"","sources":["../app.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"app.js","sourceRoot":"","sources":["../app.ts"],"names":[],"mappings":"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"}

129
dist/src/auth.js

@ -0,0 +1,129 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const crypto = require("crypto");
const models_1 = require("./models");
const crypto_js_1 = require("crypto-js");
const path = require("path");
const res_1 = require("./utils/res");
const macaroon_1 = require("./utils/macaroon");
const fs = require('fs');
const env = process.env.NODE_ENV || 'development';
const config = require(path.join(__dirname, 'config/app.json'))[env];
function unlocker(req, res) {
return __awaiter(this, void 0, void 0, function* () {
const { password } = req.body;
if (!password) {
res_1.failure(res, 'no password');
return false;
}
const encMacPath = config.encrypted_macaroon_path;
if (!encMacPath) {
res_1.failure(res, 'no macaroon path');
return false;
}
let hexMac;
try {
var encMac = fs.readFileSync(config.encrypted_macaroon_path);
if (!encMac) {
res_1.failure(res, 'no macaroon');
return false;
}
const decMac = decryptMacaroon(password, encMac);
if (!decMac) {
res_1.failure(res, 'failed to decrypt macaroon');
return false;
}
hexMac = base64ToHex(decMac);
}
catch (e) {
res_1.failure(res, e);
return false;
}
if (hexMac) {
macaroon_1.setInMemoryMacaroon(hexMac);
res_1.success(res, 'success!');
return true;
}
else {
res_1.failure(res, 'failed to set macaroon in memory');
return false;
}
});
}
exports.unlocker = unlocker;
function authModule(req, res, next) {
return __awaiter(this, void 0, void 0, function* () {
if (req.path == '/app' ||
req.path == '/' ||
req.path == '/info' ||
req.path == '/action' ||
req.path == '/contacts/tokens' ||
req.path == '/latest' ||
req.path.startsWith('/static') ||
req.path == '/contacts/set_dev') {
next();
return;
}
if (process.env.HOSTING_PROVIDER === 'true') {
// const domain = process.env.INVITE_SERVER
const host = req.headers.origin;
console.log('=> host:', host);
const referer = req.headers.referer;
console.log('=> referer:', referer);
if (req.path === '/invoices') {
next();
return;
}
}
const token = req.headers['x-user-token'] || req.cookies['x-user-token'];
if (token == null) {
res.writeHead(401, 'Access invalid for user', { 'Content-Type': 'text/plain' });
res.end('Invalid credentials');
}
else {
const user = yield models_1.models.Contact.findOne({ where: { isOwner: true } });
const hashedToken = crypto.createHash('sha256').update(token).digest('base64');
if (user.authToken == null || user.authToken != hashedToken) {
res.writeHead(401, 'Access invalid for user', { 'Content-Type': 'text/plain' });
res.end('Invalid credentials');
}
else {
next();
}
}
});
}
exports.authModule = authModule;
function decryptMacaroon(password, macaroon) {
try {
const decrypted = crypto_js_1.default.AES.decrypt(macaroon || '', password).toString(crypto_js_1.default.enc.Base64);
const decryptResult = atob(decrypted);
return decryptResult;
}
catch (e) {
console.error('cipher mismatch, macaroon decryption failed');
console.error(e);
return '';
}
}
function base64ToHex(str) {
const raw = atob(str);
let result = '';
for (let i = 0; i < raw.length; i++) {
const hex = raw.charCodeAt(i).toString(16);
result += (hex.length === 2 ? hex : '0' + hex);
}
return result.toUpperCase();
}
exports.base64ToHex = base64ToHex;
const atob = a => Buffer.from(a, 'base64').toString('binary');
//# sourceMappingURL=auth.js.map

1
dist/src/auth.js.map

@ -0,0 +1 @@
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":"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"}

2
dist/src/grpc/index.js

@ -98,7 +98,7 @@ function subscribeInvoices(parseKeysendInvoice) {
});
});
call.on('status', function (status) {
console.log("Status", status);
console.log("Status", status.code, status);
// The server is unavailable, trying to reconnect.
if (status.code == ERR_CODE_UNAVAILABLE || status.code == ERR_CODE_STREAM_REMOVED) {
i = 0;

2
dist/src/grpc/index.js.map

File diff suppressed because one or more lines are too long

19
dist/src/utils/lightning.js

@ -17,6 +17,7 @@ const sha = require("js-sha256");
const crypto = require("crypto");
const path = require("path");
const constants_1 = require("../constants");
const macaroon_1 = require("./macaroon");
// var protoLoader = require('@grpc/proto-loader')
const env = process.env.NODE_ENV || 'development';
const config = require(path.join(__dirname, '../../config/app.json'))[env];
@ -29,8 +30,7 @@ var walletUnlocker = null;
const loadCredentials = () => {
var lndCert = fs.readFileSync(config.tls_location);
var sslCreds = grpc.credentials.createSsl(lndCert);
var m = fs.readFileSync(config.macaroon_location);
var macaroon = m.toString('hex');
var macaroon = macaroon_1.getMacaroon();
var metadata = new grpc.Metadata();
metadata.add('macaroon', macaroon);
var macaroonCreds = grpc.credentials.createFromMetadataGenerator((_args, callback) => {
@ -87,6 +87,21 @@ const loadWalletUnlocker = () => {
}
};
exports.loadWalletUnlocker = loadWalletUnlocker;
const unlockWallet = (wallet_password) => __awaiter(void 0, void 0, void 0, function* () {
return new Promise(function (resolve, reject) {
return __awaiter(this, void 0, void 0, function* () {
let wu = yield loadWalletUnlocker();
wu.unlockWallet({ wallet_password }, (err, response) => {
if (err) {
reject(err);
return;
}
resolve(response);
});
});
});
});
exports.unlockWallet = unlockWallet;
const getHeaders = (req) => {
return {
"X-User-Token": req.headers['x-user-token'],

2
dist/src/utils/lightning.js.map

File diff suppressed because one or more lines are too long

22
dist/src/utils/macaroon.js

@ -0,0 +1,22 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const path = require("path");
const env = process.env.NODE_ENV || 'development';
const config = require(path.join(__dirname, '../../config/app.json'))[env];
let inMemoryMacaroon = ''; // hex encoded
function getMacaroon() {
if (config.unlock) {
return inMemoryMacaroon;
}
else {
const m = fs.readFileSync(config.macaroon_location);
return m.toString('hex');
}
}
exports.getMacaroon = getMacaroon;
function setInMemoryMacaroon(mac) {
inMemoryMacaroon = mac;
}
exports.setInMemoryMacaroon = setInMemoryMacaroon;
//# sourceMappingURL=macaroon.js.map

1
dist/src/utils/macaroon.js.map

@ -0,0 +1 @@
{"version":3,"file":"macaroon.js","sourceRoot":"","sources":["../../../src/utils/macaroon.ts"],"names":[],"mappings":";;AAAA,yBAAwB;AACxB,6BAA4B;AAE5B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAC;AAClD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;AAE1E,IAAI,gBAAgB,GAAW,EAAE,CAAC,CAAC,cAAc;AAEjD,SAAgB,WAAW;IACzB,IAAG,MAAM,CAAC,MAAM,EAAE;QAChB,OAAO,gBAAgB,CAAA;KACxB;SAAM;QACL,MAAM,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAA;QACnD,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;KAC1B;AACH,CAAC;AAPD,kCAOC;AAED,SAAgB,mBAAmB,CAAC,GAAU;IAC5C,gBAAgB,GAAG,GAAG,CAAA;AACxB,CAAC;AAFD,kDAEC"}

45
dist/src/utils/unlock.js

@ -0,0 +1,45 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const path = require("path");
const lightning_1 = require("./lightning");
const fs = require('fs');
const readline = require('readline');
const env = process.env.NODE_ENV || 'development';
const config = require(path.join(__dirname, '../../config/app.json'))[env];
// /relay/.lnd/.lndpwd
function tryToUnlockLND() {
return __awaiter(this, void 0, void 0, function* () {
const p = config.lnd_pwd;
if (!p)
return;
var pwd = getFirstLine(config.lnd_pwd);
if (!pwd)
return;
yield lightning_1.unlockWallet(pwd);
});
}
exports.tryToUnlockLND = tryToUnlockLND;
function getFirstLine(pathToFile) {
return __awaiter(this, void 0, void 0, function* () {
const readable = fs.createReadStream(pathToFile);
const reader = readline.createInterface({ input: readable });
const line = yield new Promise((resolve) => {
reader.on('line', (line) => {
reader.close();
resolve(line);
});
});
readable.close();
return line;
});
}
//# sourceMappingURL=unlock.js.map

1
dist/src/utils/unlock.js.map

@ -0,0 +1 @@
{"version":3,"file":"unlock.js","sourceRoot":"","sources":["../../../src/utils/unlock.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,6BAA4B;AAC5B,2CAA0C;AAC1C,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;AACxB,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAErC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAC;AAClD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;AAE1E,sBAAsB;AAEtB,SAAsB,cAAc;;QAChC,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAA;QACxB,IAAI,CAAC,CAAC;YAAE,OAAM;QAEd,IAAI,GAAG,GAAG,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvC,IAAG,CAAC,GAAG;YAAE,OAAM;QAEf,MAAM,wBAAY,CAAC,GAAG,CAAC,CAAA;IAC3B,CAAC;CAAA;AARD,wCAQC;AAED,SAAe,YAAY,CAAC,UAAU;;QAClC,MAAM,QAAQ,GAAG,EAAE,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAG,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YACvC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBACvB,MAAM,CAAC,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QACH,QAAQ,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC;IAChB,CAAC;CAAA"}

5
package-lock.json

@ -1600,6 +1600,11 @@
"randomfill": "^1.0.3"
}
},
"crypto-js": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz",
"integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg=="
},
"crypto-random-string": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",

1
package.json

@ -34,6 +34,7 @@
"cron": "^1.7.2",
"cron-parser": "^2.13.0",
"crypto-browserify": "^3.12.0",
"crypto-js": "^4.0.0",
"dateformat": "^3.0.3",
"decamelize": "^3.1.1",
"express": "^4.16.4",

124
src/auth.ts

@ -0,0 +1,124 @@
import * as crypto from 'crypto'
import { models } from './models'
import cryptoJS from 'crypto-js'
import * as path from 'path'
import { success, failure } from './utils/res'
import {setInMemoryMacaroon} from './utils/macaroon'
const fs = require('fs')
const env = process.env.NODE_ENV || 'development';
const config = require(path.join(__dirname, 'config/app.json'))[env];
export async function unlocker(req, res): Promise<boolean> {
const { password } = req.body
if(!password) {
failure(res, 'no password')
return false
}
const encMacPath = config.encrypted_macaroon_path
if(!encMacPath) {
failure(res, 'no macaroon path')
return false
}
let hexMac:string
try {
var encMac = fs.readFileSync(config.encrypted_macaroon_path);
if(!encMac) {
failure(res, 'no macaroon')
return false
}
const decMac = decryptMacaroon(password, encMac)
if(!decMac) {
failure(res, 'failed to decrypt macaroon')
return false
}
hexMac = base64ToHex(decMac)
} catch(e) {
failure(res, e)
return false
}
if(hexMac) {
setInMemoryMacaroon(hexMac)
success(res, 'success!')
return true
} else {
failure(res, 'failed to set macaroon in memory')
return false
}
}
export async function authModule(req, res, next) {
if (
req.path == '/app' ||
req.path == '/' ||
req.path == '/info' ||
req.path == '/action' ||
req.path == '/contacts/tokens' ||
req.path == '/latest' ||
req.path.startsWith('/static') ||
req.path == '/contacts/set_dev'
) {
next()
return
}
if (process.env.HOSTING_PROVIDER === 'true') {
// const domain = process.env.INVITE_SERVER
const host = req.headers.origin
console.log('=> host:', host)
const referer = req.headers.referer
console.log('=> referer:', referer)
if (req.path === '/invoices') {
next()
return
}
}
const token = req.headers['x-user-token'] || req.cookies['x-user-token']
if (token == null) {
res.writeHead(401, 'Access invalid for user', { 'Content-Type': 'text/plain' });
res.end('Invalid credentials');
} else {
const user = await models.Contact.findOne({ where: { isOwner: true } })
const hashedToken = crypto.createHash('sha256').update(token).digest('base64');
if (user.authToken == null || user.authToken != hashedToken) {
res.writeHead(401, 'Access invalid for user', { 'Content-Type': 'text/plain' });
res.end('Invalid credentials');
} else {
next();
}
}
}
function decryptMacaroon(password: string, macaroon: string) {
try {
const decrypted = cryptoJS.AES.decrypt(macaroon || '', password).toString(cryptoJS.enc.Base64)
const decryptResult = atob(decrypted)
return decryptResult
} catch (e) {
console.error('cipher mismatch, macaroon decryption failed')
console.error(e)
return ''
}
}
export function base64ToHex (str) {
const raw = atob(str)
let result = ''
for (let i = 0; i < raw.length; i++) {
const hex = raw.charCodeAt(i).toString(16)
result += (hex.length === 2 ? hex : '0' + hex)
}
return result.toUpperCase()
}
const atob = a => Buffer.from(a, 'base64').toString('binary')

2
src/grpc/index.ts

@ -95,7 +95,7 @@ export function subscribeInvoices(parseKeysendInvoice) {
}
});
call.on('status', function(status) {
console.log("Status", status);
console.log("Status", status.code, status);
// The server is unavailable, trying to reconnect.
if (status.code == ERR_CODE_UNAVAILABLE || status.code == ERR_CODE_STREAM_REMOVED) {
i = 0

21
src/utils/lightning.ts

@ -6,6 +6,7 @@ import * as sha from 'js-sha256'
import * as crypto from 'crypto'
import * as path from 'path'
import constants from '../constants'
import {getMacaroon} from './macaroon'
// var protoLoader = require('@grpc/proto-loader')
const env = process.env.NODE_ENV || 'development';
@ -20,8 +21,7 @@ var walletUnlocker = <any> null;
const loadCredentials = () => {
var lndCert = fs.readFileSync(config.tls_location);
var sslCreds = grpc.credentials.createSsl(lndCert);
var m = fs.readFileSync(config.macaroon_location);
var macaroon = m.toString('hex');
var macaroon = getMacaroon()
var metadata = new grpc.Metadata()
metadata.add('macaroon', macaroon)
var macaroonCreds = grpc.credentials.createFromMetadataGenerator((_args, callback) => {
@ -76,6 +76,22 @@ const loadWalletUnlocker = () => {
}
}
const unlockWallet = async (wallet_password) => {
return new Promise(async function(resolve, reject) {
let wu = await loadWalletUnlocker()
wu.unlockWallet(
{ wallet_password },
(err, response) => {
if(err) {
reject(err)
return
}
resolve(response)
}
)
})
}
const getHeaders = (req) => {
return {
"X-User-Token": req.headers['x-user-token'],
@ -455,4 +471,5 @@ export {
queryRoute,
listChannels,
channelBalance,
unlockWallet,
}

20
src/utils/macaroon.ts

@ -0,0 +1,20 @@
import * as fs from 'fs'
import * as path from 'path'
const env = process.env.NODE_ENV || 'development';
const config = require(path.join(__dirname, '../../config/app.json'))[env]
let inMemoryMacaroon: string = ''; // hex encoded
export function getMacaroon() {
if(config.unlock) {
return inMemoryMacaroon
} else {
const m = fs.readFileSync(config.macaroon_location)
return m.toString('hex');
}
}
export function setInMemoryMacaroon(mac:string) {
inMemoryMacaroon = mac
}

34
src/utils/unlock.ts

@ -0,0 +1,34 @@
import * as path from 'path'
import { unlockWallet } from './lightning'
const fs = require('fs')
const readline = require('readline');
const env = process.env.NODE_ENV || 'development';
const config = require(path.join(__dirname, '../../config/app.json'))[env]
// /relay/.lnd/.lndpwd
export async function tryToUnlockLND() {
const p = config.lnd_pwd
if (!p) return
var pwd = getFirstLine(config.lnd_pwd);
if(!pwd) return
await unlockWallet(pwd)
}
async function getFirstLine(pathToFile) {
const readable = fs.createReadStream(pathToFile);
const reader = readline.createInterface({ input: readable });
const line = await new Promise((resolve) => {
reader.on('line', (line) => {
reader.close();
resolve(line);
});
});
readable.close();
return line;
}
Loading…
Cancel
Save