* Delete Crunch Menu Component
* Disabled Quick Note * Note crunches over when menu is open * Added a cool loader * Remomoved locked notes * Added full note encryption * Added encrypted search index * Added encrypted shared notes * Made search bar have a clear and search button * Tags only loade when clicking on the tags menu * Tweaked home page to be a little more sane * built out some gigantic test cases * simplified a lot of things to make entire app easier to maintain
This commit is contained in:
1 parent
df073b0e4d
commit
67b218329b
16 files changed
+797
-603
No files matched your search
+160
-10
@@ -1,4 +1,4 @@
|
||||
var crypto = require('crypto')
|
||||
const crypto = require('crypto')
|
||||
|
||||
const Note = require('@models/Note')
|
||||
|
||||
@@ -30,9 +30,10 @@ User.login = (username, password) => {
|
||||
})
|
||||
}
|
||||
|
||||
if(lookedUpUser && lookedUpUser.salt){
|
||||
if(rows[0].length == 1){
|
||||
//hash the password and check for a match
|
||||
const salt = new Buffer(lookedUpUser.salt, 'binary')
|
||||
// const salt = new Buffer(lookedUpUser.salt, 'binary')
|
||||
const salt = Buffer.from(lookedUpUser.salt, 'binary')
|
||||
crypto.pbkdf2(password, salt, lookedUpUser.iterations, 512, 'sha512', function(err, delivered_key){
|
||||
if(delivered_key.toString('hex') === lookedUpUser.password){
|
||||
|
||||
@@ -40,9 +41,14 @@ User.login = (username, password) => {
|
||||
.then( result => User.getMasterKey(lookedUpUser.id, password))
|
||||
.then(masterKey => {
|
||||
|
||||
//Passback a json web token
|
||||
const token = Auth.createToken(lookedUpUser.id, masterKey)
|
||||
resolve({ token: token, userId:lookedUpUser.id })
|
||||
User.generateKeypair(lookedUpUser.id, masterKey)
|
||||
.then(({publicKey, privateKey}) => {
|
||||
|
||||
//Passback a json web token
|
||||
const token = Auth.createToken(lookedUpUser.id, masterKey)
|
||||
resolve({ token: token, userId:lookedUpUser.id })
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
} else {
|
||||
@@ -80,7 +86,7 @@ User.create = (username, password) => {
|
||||
shasum.update(''+otherRandomInt) //Update Hasd
|
||||
|
||||
const saltString = shasum.digest('hex')
|
||||
const salt = new Buffer(saltString, 'binary') //Generate Salt hash
|
||||
const salt = Buffer.from(saltString, 'binary') //Generate Salt hash
|
||||
const iterations = 25000
|
||||
|
||||
crypto.pbkdf2(password, salt, iterations, 512, 'sha512', function(err, delivered_key) {
|
||||
@@ -108,8 +114,14 @@ User.create = (username, password) => {
|
||||
.then( result => User.getMasterKey(userId, password))
|
||||
.then(masterKey => {
|
||||
|
||||
const token = Auth.createToken(userId, masterKey)
|
||||
return resolve({token, userId})
|
||||
User.generateKeypair(userId, masterKey)
|
||||
.then(({publicKey, privateKey}) => {
|
||||
|
||||
const token = Auth.createToken(userId, masterKey)
|
||||
return resolve({token, userId})
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
|
||||
} else {
|
||||
@@ -202,7 +214,6 @@ User.generateMasterKey = (userId, password) => {
|
||||
} else {
|
||||
// Generate user key, its big and random
|
||||
const masterPassword = cs.createSmallSalt()
|
||||
console.log('Generating new key for user', userId)
|
||||
|
||||
//Generate a salt because it wants it
|
||||
const salt = cs.createSmallSalt()
|
||||
@@ -261,4 +272,143 @@ User.getMasterKey = (userId, password) => {
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
User.generateKeypair = (userId, masterKey) => {
|
||||
|
||||
let publicKey = null
|
||||
let privateKey = null
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
db.promise().query('SELECT * FROM user_key WHERE user_id = ?', [userId])
|
||||
.then((rows, fields) => {
|
||||
|
||||
const row = rows[0][0]
|
||||
|
||||
const salt = row['salt']
|
||||
publicKey = row['public_key']
|
||||
privateKey = row['private_key_encrypted']
|
||||
|
||||
if(row['public_key'] == null){
|
||||
const keyPair = crypto.generateKeyPairSync('rsa', {
|
||||
modulusLength: 1024,
|
||||
publicKeyEncoding: {
|
||||
type: 'spki',
|
||||
format: 'pem'
|
||||
},
|
||||
privateKeyEncoding: {
|
||||
type: 'pkcs8',
|
||||
format: 'pem'
|
||||
}
|
||||
})
|
||||
|
||||
publicKey = keyPair.publicKey
|
||||
privateKey = keyPair.privateKey
|
||||
const privateKeyEncrypted = cs.encrypt(masterKey, salt, privateKey)
|
||||
|
||||
db.promise()
|
||||
.query(
|
||||
'UPDATE user_key SET `public_key` = ?, `private_key_encrypted` = ? WHERE user_id = ?;',
|
||||
[publicKey, privateKeyEncrypted, userId]
|
||||
)
|
||||
.then((rows, fields)=>{
|
||||
|
||||
return resolve({publicKey, privateKey})
|
||||
|
||||
})
|
||||
|
||||
} else {
|
||||
|
||||
//Decrypt private key
|
||||
privateKey = cs.decrypt(masterKey, salt, privateKey)
|
||||
|
||||
return resolve({publicKey, privateKey})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
User.getPublicKey = (userId) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
db.promise().query('SELECT public_key FROM user_key WHERE user_id = ?', [userId])
|
||||
.then((rows, fields) => {
|
||||
|
||||
const row = rows[0][0]
|
||||
return resolve(row['public_key'])
|
||||
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
User.getPrivateKey = (userId, masterKey) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
db.promise().query('SELECT salt, private_key_encrypted FROM user_key WHERE user_id = ?', [userId])
|
||||
.then((rows, fields) => {
|
||||
|
||||
const row = rows[0][0]
|
||||
|
||||
const salt = row['salt']
|
||||
privateKey = row['private_key_encrypted']
|
||||
|
||||
//Decrypt private key
|
||||
privateKey = cs.decrypt(masterKey, salt, privateKey)
|
||||
|
||||
return resolve(privateKey)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
User.getByUserName = (username) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
db.promise().query('SELECT * FROM user WHERE username = ? LIMIT 1', [username.toLowerCase()])
|
||||
.then((rows, fields) => {
|
||||
resolve(rows[0][0])
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
User.deleteUser = (userId, password) => {
|
||||
|
||||
//Verify user is correct by decryptig master key with password
|
||||
|
||||
//Delete user, all notes, all keys
|
||||
}
|
||||
|
||||
User.keyPairTest = (testUserName = 'genMan', password = '1') => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
let masterKey = null
|
||||
let testUserId = null
|
||||
|
||||
User.login(testUserName, password)
|
||||
.then( ({ token, userId }) => {
|
||||
testUserId = userId
|
||||
console.log('Test: Create/Login User - Pass')
|
||||
return User.getMasterKey(testUserId, password)
|
||||
})
|
||||
.then(newMasterKey => {
|
||||
masterKey = newMasterKey
|
||||
console.log('Test: Generate/Decrypt Master Key - Pass')
|
||||
return User.generateKeypair(testUserId, masterKey)
|
||||
})
|
||||
.then(({publicKey, privateKey}) => {
|
||||
|
||||
const publicKeyMessage = 'Test: Public key decrypt - Pass'
|
||||
const privateKeyMessage = 'Test: Private key decrypt - Pass'
|
||||
|
||||
//Encrypt Message with private Key
|
||||
const privateKeyEncrypted = crypto.privateEncrypt(privateKey, Buffer.from(privateKeyMessage, 'utf8')).toString('base64')
|
||||
const decryptedPrivate = crypto.publicDecrypt(publicKey, Buffer.from(privateKeyEncrypted, 'base64'))
|
||||
//Conver back to a string
|
||||
console.log(decryptedPrivate.toString('utf8'))
|
||||
|
||||
//Encrypt with public key
|
||||
const pubEncrMsc = crypto.publicEncrypt(publicKey, Buffer.from(publicKeyMessage, 'utf8')).toString('base64')
|
||||
const publicDeccryptMessage = crypto.privateDecrypt(privateKey, Buffer.from(pubEncrMsc, 'base64') )
|
||||
//Convert it back to string
|
||||
console.log(publicDeccryptMessage.toString('utf8'))
|
||||
|
||||
resolve({testUserId, masterKey})
|
||||
})
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user