Genesis commit
This commit is contained in:
58
lib/core/cryptoUtil.js
Normal file
58
lib/core/cryptoUtil.js
Normal file
@@ -0,0 +1,58 @@
|
||||
const crypto = require('crypto');
|
||||
const algorithm = 'aes-256-ctr';
|
||||
const bip32 = require('bip32');
|
||||
|
||||
module.exports.encrypt = (plainText, password) => {
|
||||
// TODO encrypt text
|
||||
// const cipher = crypto.createCipheriv(algorithm, password);
|
||||
|
||||
// var cipherText = cipher.update(plainText, 'utf8', 'hex');
|
||||
// cipher += cipher.final('hex');
|
||||
|
||||
// console.log("CipherText: ", cipherText);
|
||||
return plainText;
|
||||
}
|
||||
|
||||
module.exports.decrypt = (cipherText, password) => {
|
||||
// TODO decrypt cipherText
|
||||
// const decipher = crypto.createDecipheriv(algorithm, password)
|
||||
|
||||
// var plainText = decipher.update(cipherText, 'hex', 'utf8');
|
||||
// plainText += decipher.final('utf8');
|
||||
|
||||
return cipherText;
|
||||
}
|
||||
|
||||
module.exports.randomDerivationPath = function(hardenedDerivation) {
|
||||
// TODO harden derivation path
|
||||
var randomNumbers = [];
|
||||
|
||||
for(var i = 0; i < 3; i++) {
|
||||
randomNumbers.push(parseInt(crypto.randomBytes(3).toString('hex'), 16))
|
||||
}
|
||||
|
||||
return randomNumbers.join('/')
|
||||
}
|
||||
|
||||
module.exports.verifyMessage = function(base58Key, derivationPath, message, signature) {
|
||||
if(derivationPath.startsWith("a/")) {
|
||||
derivationPath = derivationPath.split("a/")[1];
|
||||
}
|
||||
|
||||
if(derivationPath.startsWith("c/")) {
|
||||
derivationPath = derivationPath.split("c/")[1];
|
||||
}
|
||||
|
||||
const verificationNode = bip32.fromBase58(base58Key).derivePath(derivationPath);
|
||||
const hash = crypto.createHash('sha256').update(message, 'utf8').digest();
|
||||
|
||||
return verificationNode.verify(hash, Buffer.from(signature, 'hex'));
|
||||
}
|
||||
|
||||
module.exports.signMessage = function(base58Key, derivationPath, message) {
|
||||
let signingNode = bip32.fromBase58(base58Key).derivePath(derivationPath);
|
||||
|
||||
var hash = crypto.createHash('sha256').update(message, 'utf8').digest();
|
||||
|
||||
return signingNode.sign(hash);
|
||||
}
|
||||
37
lib/core/persistence/models/extendedPublicKey.js
Normal file
37
lib/core/persistence/models/extendedPublicKey.js
Normal file
@@ -0,0 +1,37 @@
|
||||
module.exports = function (sequelize, DataTypes, options) {
|
||||
const model = sequelize.define("extendedPublicKey", {
|
||||
id: {
|
||||
type: DataTypes.STRING,
|
||||
defaultValue: function() {
|
||||
return options.generateUniqueId()
|
||||
},
|
||||
primaryKey: true,
|
||||
unique: true
|
||||
},
|
||||
xpub: {
|
||||
type: DataTypes.STRING,
|
||||
// TODO add validation
|
||||
allowNull: false,
|
||||
unique: true
|
||||
},
|
||||
derivationPath: {
|
||||
type: DataTypes.STRING,
|
||||
// TODO add validation...
|
||||
allowNull: false,
|
||||
unique: true
|
||||
},
|
||||
name: {
|
||||
type: DataTypes.STRING,
|
||||
unique: true
|
||||
}
|
||||
}, {
|
||||
comment: "Exteneded public keys."
|
||||
});
|
||||
|
||||
model.associate = (db) => {
|
||||
// TODO Update key to wallet...
|
||||
model.Key = model.belongsTo(db.Key);
|
||||
}
|
||||
|
||||
return model;
|
||||
};
|
||||
30
lib/core/persistence/models/key.js
Normal file
30
lib/core/persistence/models/key.js
Normal file
@@ -0,0 +1,30 @@
|
||||
module.exports = function (sequelize, DataTypes, options) {
|
||||
const model = sequelize.define("key", { // TODO: Rename to wallet
|
||||
id: {
|
||||
type: DataTypes.STRING,
|
||||
defaultValue: function() {
|
||||
return options.generateUniqueId()
|
||||
},
|
||||
primaryKey: true,
|
||||
unique: true
|
||||
},
|
||||
encryptedPrivateKey: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
name: {
|
||||
type: DataTypes.STRING,
|
||||
unique: true
|
||||
}
|
||||
// TODO: Add order to allow for user to set default keys
|
||||
}, {
|
||||
comment: "The keys we are using in our system (seedphrase)."
|
||||
});
|
||||
|
||||
model.associate = (db) => {
|
||||
model.Locks = model.hasMany(db.Lock);
|
||||
model.ExtendedPublicKeys = model.hasMany(db.ExtendedPublicKey);
|
||||
}
|
||||
|
||||
return model;
|
||||
};
|
||||
39
lib/core/persistence/models/lock.js
Normal file
39
lib/core/persistence/models/lock.js
Normal file
@@ -0,0 +1,39 @@
|
||||
module.exports = function (sequelize, DataTypes, options) {
|
||||
const model = sequelize.define("lock", {
|
||||
id: {
|
||||
type: DataTypes.STRING,
|
||||
defaultValue: function() {
|
||||
return options.generateUniqueId()
|
||||
},
|
||||
primaryKey: true,
|
||||
unique: true
|
||||
},
|
||||
userIdentifier: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
url: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
signature: {
|
||||
// Derivation from the master key...
|
||||
// TODO: Add validation...
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
unique: true
|
||||
},
|
||||
message: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
}
|
||||
}, {
|
||||
comment: "lock which our keys has access to"
|
||||
});
|
||||
|
||||
model.associate = (db) => {
|
||||
model.ExtendedPublicKey = model.belongsTo(db.ExtendedPublicKey);
|
||||
}
|
||||
|
||||
return model;
|
||||
};
|
||||
82
lib/core/persistence/persistence.js
Normal file
82
lib/core/persistence/persistence.js
Normal file
@@ -0,0 +1,82 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function () {
|
||||
var db = {};
|
||||
|
||||
const config = require('config');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const nanoid = require('nanoid');
|
||||
|
||||
var dbOptions = {
|
||||
db: db,
|
||||
generateUniqueId: (customIdSize) => {
|
||||
var idSize = customIdSize || 11;
|
||||
return nanoid(idSize); //=> "hsCc0ocrXkc"
|
||||
}
|
||||
};
|
||||
|
||||
dbOptions.Sequelize = require('sequelize');
|
||||
|
||||
dbOptions.sequelize = new dbOptions.Sequelize(config.get('database'));
|
||||
|
||||
// Load all the models...
|
||||
var modelDir = path.join(__dirname, './models/');
|
||||
fs.readdirSync(modelDir)
|
||||
.filter(file => {
|
||||
return (file.indexOf('.') !== 0) && (file !== "index.js") && (file.slice(-3) === '.js');
|
||||
})
|
||||
.forEach(file => {
|
||||
// const model = sequelize['import'](path.join(modelDir, file));
|
||||
const model = require(path.join(modelDir, file))(dbOptions.sequelize, dbOptions.Sequelize, dbOptions);
|
||||
|
||||
// Format the Model Name like we have for this project...
|
||||
var modelName = model.name;
|
||||
modelName = modelName.replace(modelName[0], modelName[0].toUpperCase());
|
||||
|
||||
// Add model to the db...
|
||||
db[modelName] = model;
|
||||
});
|
||||
|
||||
// Time for the associations...
|
||||
Object.keys(db).forEach(modelName => {
|
||||
if (db[modelName].associate) {
|
||||
db[modelName].associate(db);
|
||||
}
|
||||
});
|
||||
|
||||
db.LoadDB = () => {
|
||||
db.Sequelize = dbOptions.Sequelize;
|
||||
db.sequelize = dbOptions.sequelize;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
dbOptions.sequelize.sync()
|
||||
.then(() => {
|
||||
resolve(db);
|
||||
}).catch(error => {
|
||||
// Do the things...
|
||||
reject(error);
|
||||
console.error('Unable to connect to the database:', error);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
db.updateDatabaseFromModels = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
dbOptions.sequelize.sync({
|
||||
alter: true
|
||||
})
|
||||
.then(() => {
|
||||
resolve(true);
|
||||
console.log("DB update successful.");
|
||||
})
|
||||
.catch(error => {
|
||||
// Do the things...
|
||||
reject(error);
|
||||
console.error('Unable to connect to the database:', error);
|
||||
})
|
||||
})
|
||||
}
|
||||
return db;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user