Browse Source

invite or send group_create validated by tribe owner pubkey

feature/dockerfile-arm
Evan Feenstra 5 years ago
parent
commit
7659206580
  1. 23
      api/controllers/chats.ts
  2. 6
      api/helpers.ts
  3. 28
      api/utils/lightning.ts
  4. 18
      api/utils/tribes.ts
  5. 1
      app.ts
  6. 25
      dist/api/controllers/chats.js
  7. 2
      dist/api/controllers/chats.js.map
  8. 6
      dist/api/helpers.js
  9. 2
      dist/api/helpers.js.map
  10. 36
      dist/api/utils/lightning.js
  11. 2
      dist/api/utils/lightning.js.map
  12. 21
      dist/api/utils/tribes.js
  13. 2
      dist/api/utils/tribes.js.map
  14. 5
      dist/app.js
  15. 2
      dist/app.js.map

23
api/controllers/chats.ts

@ -256,8 +256,22 @@ async function receiveGroupJoin(payload) {
})
}
async function validateTribeOwner(chat_uuid: string, pubkey: string){
const verifiedOwnerPubkey = await tribes.verifySignedTimestamp(chat_uuid)
if(verifiedOwnerPubkey===pubkey){
return true
}
return false
}
async function receiveGroupCreateOrInvite(payload) {
const { chat_members, chat_name, chat_uuid, chat_type, chat_host, chat_key } = await helpers.parseReceiveParams(payload)
const { sender_pub_key, chat_members, chat_name, chat_uuid, chat_type, chat_host, chat_key } = await helpers.parseReceiveParams(payload)
// maybe this just needs to move to adding tribe owner ChatMember?
const isTribe = chat_type===constants.chat_types.tribe
if(isTribe){ // must be sent by tribe owner?????
const validOwner = await validateTribeOwner(chat_uuid, sender_pub_key)
if(!validOwner) return console.log('[tribes] invalid uuid signature!')
}
const contacts: any[] = []
const newContacts: any[] = []
@ -266,8 +280,8 @@ async function receiveGroupCreateOrInvite(payload) {
let addContact = false
if (chat_type===constants.chat_types.group && member && member.key) {
addContact = true
} else if(chat_type===constants.chat_types.tribe && member && member.role) {
if (member.role===constants.chat_roles.owner || member.role===constants.chat_roles.admin || member.role===constants.chat_roles.mode){
} else if(isTribe && member && member.role) {
if (member.role===constants.chat_roles.owner || member.role===constants.chat_roles.admin || member.role===constants.chat_roles.mod){
addContact = true
}
}
@ -303,8 +317,7 @@ async function receiveGroupCreateOrInvite(payload) {
...chat_key && { groupKey: chat_key },
})
// IF TRIBE, ADD TO XREF
if(chat_type===constants.chat_types.tribe){
if(isTribe){ // IF TRIBE, ADD TO XREF
contacts.forEach(c=>{
models.ChatMember.create({
contactId: c.id,

6
api/helpers.ts

@ -1,6 +1,6 @@
import { models } from './models'
import * as md5 from 'md5'
import { keysendMessage } from './utils/lightning'
import * as LND from './utils/lightning'
import {personalizeMessage} from './utils/msg'
const constants = require('../config/constants.json');
@ -103,7 +103,7 @@ const sendMessage = async (params) => {
amt: amount || 3,
}
try {
const r = await keysendMessage(opts)
const r = await LND.keysendMessage(opts)
yes = r
} catch (e) {
console.log("KEYSEND ERROR", e)
@ -124,7 +124,7 @@ const performKeysendMessage = async ({ destination_key, amount, msg, success, fa
amt: Math.max(amount, 3)
}
try {
const r = await keysendMessage(opts)
const r = await LND.keysendMessage(opts)
console.log("=> external keysend")
if (success) success(r)
} catch (e) {

28
api/utils/lightning.ts

@ -197,15 +197,6 @@ async function signAscii(ascii) {
}
}
async function verifyAscii(ascii,sig): Promise<{[k:string]:any}>{
try {
const r = await verifyMessage(ascii_to_hexa(ascii),sig)
return r
} catch(e) {
throw e
}
}
function listInvoices() {
return new Promise(async(resolve, reject)=> {
const lightning = await loadLightning()
@ -334,13 +325,21 @@ const signBuffer = (msg) => {
})
}
async function verifyBytes(msg,sig): Promise<{[k:string]:any}> {
try {
const r = await verifyMessage(msg.toString('hex'),sig)
return r
} catch(e) {
throw e
}
}
function verifyMessage(msg,sig): Promise<{[k:string]:any}> {
return new Promise(async(resolve, reject)=> {
let lightning = await loadLightning()
try {
const options = {
msg:ByteBuffer.fromHex(msg),
signature:sig,
signature:sig, // zbase32 encoded string
}
lightning.verifyMessage(options, function(err,res){
if(err || !res.pubkey) {
@ -354,6 +353,14 @@ function verifyMessage(msg,sig): Promise<{[k:string]:any}> {
}
})
}
async function verifyAscii(ascii,sig): Promise<{[k:string]:any}>{
try {
const r = await verifyMessage(ascii_to_hexa(ascii),sig)
return r
} catch(e) {
throw e
}
}
async function getInfo(): Promise<{[k:string]:any}>{
return new Promise((resolve,reject)=>{
@ -389,6 +396,7 @@ export {
signMessage,
verifyMessage,
verifyAscii,
verifyBytes,
signAscii,
signBuffer,
LND_KEYSEND_KEY,

18
api/utils/tribes.ts

@ -1,7 +1,7 @@
import * as moment from 'moment'
import * as zbase32 from './zbase32'
import {signBuffer, getInfo} from './lightning'
import * as LND from './lightning'
import * as path from 'path'
import * as mqtt from 'mqtt'
@ -10,7 +10,7 @@ const config = require(path.join(__dirname,'../../config/app.json'))[env]
export async function connect() {
const pwd = await genSignedTimestamp()
const info = await getInfo()
const info = await LND.getInfo()
const client = mqtt.connect(`tcp://${config.tribes_host}`,{
username:info.identity_pubkey,
@ -30,13 +30,25 @@ export async function connect() {
export async function genSignedTimestamp(){
const now = moment().unix()
const tsBytes = Buffer.from(now.toString(16), 'hex')
const sig = await signBuffer(tsBytes)
const sig = await LND.signBuffer(tsBytes)
const sigBytes = zbase32.decode(sig)
const totalLength = tsBytes.length + sigBytes.length
const buf = Buffer.concat([tsBytes, sigBytes], totalLength)
return urlBase64(buf)
}
export async function verifySignedTimestamp(stsBase64){
const stsBuf = Buffer.from(stsBase64, 'base64')
const sig = stsBuf.subarray(4,92)
const sigZbase32 = zbase32.encode(sig)
const r = await LND.verifyBytes(stsBuf.subarray(0,4), sigZbase32) // sig needs to be zbase32 :(
if (r.valid) {
return r.pubkey
} else {
return false
}
}
export function getHost() {
return config.tribes_host || ''
}

1
app.ts

@ -10,6 +10,7 @@ import {pingHubInterval, checkInvitesHubInterval} from './api/hub'
import {setupDatabase, setupDone} from './api/utils/setup'
import * as controllers from './api/controllers'
import * as socket from './api/utils/socket'
import * as tribes from './api/utils/tribes'
let server: any = null
const port = process.env.PORT || 3001;

25
dist/api/controllers/chats.js

@ -252,9 +252,25 @@ function receiveGroupJoin(payload) {
});
}
exports.receiveGroupJoin = receiveGroupJoin;
function validateTribeOwner(chat_uuid, pubkey) {
return __awaiter(this, void 0, void 0, function* () {
const verifiedOwnerPubkey = yield tribes.verifySignedTimestamp(chat_uuid);
if (verifiedOwnerPubkey === pubkey) {
return true;
}
return false;
});
}
function receiveGroupCreateOrInvite(payload) {
return __awaiter(this, void 0, void 0, function* () {
const { chat_members, chat_name, chat_uuid, chat_type, chat_host, chat_key } = yield helpers.parseReceiveParams(payload);
const { sender_pub_key, chat_members, chat_name, chat_uuid, chat_type, chat_host, chat_key } = yield helpers.parseReceiveParams(payload);
// maybe this just needs to move to adding tribe owner ChatMember?
const isTribe = chat_type === constants.chat_types.tribe;
if (isTribe) { // must be sent by tribe owner?????
const validOwner = yield validateTribeOwner(chat_uuid, sender_pub_key);
if (!validOwner)
return console.log('[tribes] invalid uuid signature!');
}
const contacts = [];
const newContacts = [];
for (let [pubkey, member] of Object.entries(chat_members)) {
@ -263,8 +279,8 @@ function receiveGroupCreateOrInvite(payload) {
if (chat_type === constants.chat_types.group && member && member.key) {
addContact = true;
}
else if (chat_type === constants.chat_types.tribe && member && member.role) {
if (member.role === constants.chat_roles.owner || member.role === constants.chat_roles.admin || member.role === constants.chat_roles.mode) {
else if (isTribe && member && member.role) {
if (member.role === constants.chat_roles.owner || member.role === constants.chat_roles.admin || member.role === constants.chat_roles.mod) {
addContact = true;
}
}
@ -292,8 +308,7 @@ function receiveGroupCreateOrInvite(payload) {
let date = new Date();
date.setMilliseconds(0);
const chat = yield models_1.models.Chat.create(Object.assign(Object.assign({ uuid: chat_uuid, contactIds: JSON.stringify(contactIds), createdAt: date, updatedAt: date, name: chat_name, type: chat_type || constants.chat_types.group }, chat_host && { host: chat_host }), chat_key && { groupKey: chat_key }));
// IF TRIBE, ADD TO XREF
if (chat_type === constants.chat_types.tribe) {
if (isTribe) { // IF TRIBE, ADD TO XREF
contacts.forEach(c => {
models_1.models.ChatMember.create({
contactId: c.id,

2
dist/api/controllers/chats.js.map

File diff suppressed because one or more lines are too long

6
dist/api/helpers.js

@ -11,7 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
Object.defineProperty(exports, "__esModule", { value: true });
const models_1 = require("./models");
const md5 = require("md5");
const lightning_1 = require("./utils/lightning");
const LND = require("./utils/lightning");
const msg_1 = require("./utils/msg");
const constants = require('../config/constants.json');
const findOrCreateChat = (params) => __awaiter(void 0, void 0, void 0, function* () {
@ -104,7 +104,7 @@ const sendMessage = (params) => __awaiter(void 0, void 0, void 0, function* () {
amt: amount || 3,
};
try {
const r = yield lightning_1.keysendMessage(opts);
const r = yield LND.keysendMessage(opts);
yes = r;
}
catch (e) {
@ -129,7 +129,7 @@ const performKeysendMessage = ({ destination_key, amount, msg, success, failure
amt: Math.max(amount, 3)
};
try {
const r = yield lightning_1.keysendMessage(opts);
const r = yield LND.keysendMessage(opts);
console.log("=> external keysend");
if (success)
success(r);

2
dist/api/helpers.js.map

File diff suppressed because one or more lines are too long

36
dist/api/utils/lightning.js

@ -216,18 +216,6 @@ function signAscii(ascii) {
});
}
exports.signAscii = signAscii;
function verifyAscii(ascii, sig) {
return __awaiter(this, void 0, void 0, function* () {
try {
const r = yield verifyMessage(ascii_to_hexa(ascii), sig);
return r;
}
catch (e) {
throw e;
}
});
}
exports.verifyAscii = verifyAscii;
function listInvoices() {
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
const lightning = yield loadLightning();
@ -376,6 +364,18 @@ const signBuffer = (msg) => {
}));
};
exports.signBuffer = signBuffer;
function verifyBytes(msg, sig) {
return __awaiter(this, void 0, void 0, function* () {
try {
const r = yield verifyMessage(msg.toString('hex'), sig);
return r;
}
catch (e) {
throw e;
}
});
}
exports.verifyBytes = verifyBytes;
function verifyMessage(msg, sig) {
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
let lightning = yield loadLightning();
@ -399,6 +399,18 @@ function verifyMessage(msg, sig) {
}));
}
exports.verifyMessage = verifyMessage;
function verifyAscii(ascii, sig) {
return __awaiter(this, void 0, void 0, function* () {
try {
const r = yield verifyMessage(ascii_to_hexa(ascii), sig);
return r;
}
catch (e) {
throw e;
}
});
}
exports.verifyAscii = verifyAscii;
function getInfo() {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve, reject) => {

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

File diff suppressed because one or more lines are too long

21
dist/api/utils/tribes.js

@ -11,7 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
Object.defineProperty(exports, "__esModule", { value: true });
const moment = require("moment");
const zbase32 = require("./zbase32");
const lightning_1 = require("./lightning");
const LND = require("./lightning");
const path = require("path");
const mqtt = require("mqtt");
const env = process.env.NODE_ENV || 'development';
@ -19,7 +19,7 @@ const config = require(path.join(__dirname, '../../config/app.json'))[env];
function connect() {
return __awaiter(this, void 0, void 0, function* () {
const pwd = yield genSignedTimestamp();
const info = yield lightning_1.getInfo();
const info = yield LND.getInfo();
const client = mqtt.connect(`tcp://${config.tribes_host}`, {
username: info.identity_pubkey,
password: pwd,
@ -39,7 +39,7 @@ function genSignedTimestamp() {
return __awaiter(this, void 0, void 0, function* () {
const now = moment().unix();
const tsBytes = Buffer.from(now.toString(16), 'hex');
const sig = yield lightning_1.signBuffer(tsBytes);
const sig = yield LND.signBuffer(tsBytes);
const sigBytes = zbase32.decode(sig);
const totalLength = tsBytes.length + sigBytes.length;
const buf = Buffer.concat([tsBytes, sigBytes], totalLength);
@ -47,6 +47,21 @@ function genSignedTimestamp() {
});
}
exports.genSignedTimestamp = genSignedTimestamp;
function verifySignedTimestamp(stsBase64) {
return __awaiter(this, void 0, void 0, function* () {
const stsBuf = Buffer.from(stsBase64, 'base64');
const sig = stsBuf.subarray(4, 92);
const sigZbase32 = zbase32.encode(sig);
const r = yield LND.verifyBytes(stsBuf.subarray(0, 4), sigZbase32); // sig needs to be zbase32 :(
if (r.valid) {
return r.pubkey;
}
else {
return false;
}
});
}
exports.verifySignedTimestamp = verifySignedTimestamp;
function getHost() {
return config.tribes_host || '';
}

2
dist/api/utils/tribes.js.map

@ -1 +1 @@
{"version":3,"file":"tribes.js","sourceRoot":"","sources":["../../../api/utils/tribes.ts"],"names":[],"mappings":";;;;;;;;;;;AACA,iCAAgC;AAChC,qCAAoC;AACpC,2CAA+C;AAC/C,6BAA4B;AAC5B,6BAA4B;AAE5B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAA;AACjD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAC,uBAAuB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;AAEzE,SAAsB,OAAO;;QACzB,MAAM,GAAG,GAAG,MAAM,kBAAkB,EAAE,CAAA;QACtC,MAAM,IAAI,GAAG,MAAM,mBAAO,EAAE,CAAA;QAE5B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,MAAM,CAAC,WAAW,EAAE,EAAC;YACtD,QAAQ,EAAC,IAAI,CAAC,eAAe;YAC7B,QAAQ,EAAC,GAAG;SACf,CAAC,CAAA;QAEF,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE;YACjB,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAA;YACrC,sCAAsC;YACtC,oDAAoD;QACxD,CAAC,CAAC,CAAA;QACF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE;YACf,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;QAC9B,CAAC,CAAC,CAAA;IACN,CAAC;CAAA;AAjBD,0BAiBC;AAED,SAAsB,kBAAkB;;QACpC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAA;QAC3B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAA;QACpD,MAAM,GAAG,GAAG,MAAM,sBAAU,CAAC,OAAO,CAAC,CAAA;QACrC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACpC,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAA;QACpD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,CAAA;QAC3D,OAAO,SAAS,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC;CAAA;AARD,gDAQC;AAED,SAAgB,OAAO;IACnB,OAAO,MAAM,CAAC,WAAW,IAAI,EAAE,CAAA;AACnC,CAAC;AAFD,0BAEC;AAED,SAAS,SAAS,CAAC,GAAG;IAClB,OAAO,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;AACzE,CAAC"}
{"version":3,"file":"tribes.js","sourceRoot":"","sources":["../../../api/utils/tribes.ts"],"names":[],"mappings":";;;;;;;;;;;AACA,iCAAgC;AAChC,qCAAoC;AACpC,mCAAkC;AAClC,6BAA4B;AAC5B,6BAA4B;AAE5B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAA;AACjD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAC,uBAAuB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;AAEzE,SAAsB,OAAO;;QACzB,MAAM,GAAG,GAAG,MAAM,kBAAkB,EAAE,CAAA;QACtC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,OAAO,EAAE,CAAA;QAEhC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,MAAM,CAAC,WAAW,EAAE,EAAC;YACtD,QAAQ,EAAC,IAAI,CAAC,eAAe;YAC7B,QAAQ,EAAC,GAAG;SACf,CAAC,CAAA;QAEF,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE;YACjB,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAA;YACrC,sCAAsC;YACtC,oDAAoD;QACxD,CAAC,CAAC,CAAA;QACF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE;YACf,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;QAC9B,CAAC,CAAC,CAAA;IACN,CAAC;CAAA;AAjBD,0BAiBC;AAED,SAAsB,kBAAkB;;QACpC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAA;QAC3B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAA;QACpD,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;QACzC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACpC,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAA;QACpD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,WAAW,CAAC,CAAA;QAC3D,OAAO,SAAS,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC;CAAA;AARD,gDAQC;AAED,SAAsB,qBAAqB,CAAC,SAAS;;QACjD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;QAC/C,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAC,EAAE,CAAC,CAAA;QACjC,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACtC,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA,CAAC,6BAA6B;QAC/F,IAAI,CAAC,CAAC,KAAK,EAAE;YACT,OAAO,CAAC,CAAC,MAAM,CAAA;SAClB;aAAM;YACH,OAAO,KAAK,CAAA;SACf;IACL,CAAC;CAAA;AAVD,sDAUC;AAED,SAAgB,OAAO;IACnB,OAAO,MAAM,CAAC,WAAW,IAAI,EAAE,CAAA;AACnC,CAAC;AAFD,0BAEC;AAED,SAAS,SAAS,CAAC,GAAG;IAClB,OAAO,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;AACzE,CAAC"}

5
dist/app.js

@ -21,6 +21,7 @@ const hub_1 = require("./api/hub");
const setup_1 = require("./api/utils/setup");
const controllers = require("./api/controllers");
const socket = require("./api/utils/socket");
const tribes = require("./api/utils/tribes");
let server = null;
const port = process.env.PORT || 3001;
const env = process.env.NODE_ENV || 'development';
@ -36,6 +37,10 @@ function connectToLND() {
try {
yield controllers.iniGrpcSubscriptions();
mainSetup();
const sts = yield tribes.genSignedTimestamp();
console.log("STS", sts);
tribes.verifySignedTimestamp(sts);
return;
}
catch (e) {
setTimeout(() => __awaiter(this, void 0, void 0, function* () {

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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"}
Loading…
Cancel
Save