* Added theme colors to form fields

* Added some basic table styles for inserting some shitty tables
* Made popup notification styles look better and work better on mobile
* Quick note now opens a note and not some weird page
* Menu collapses when page is small, behaves like mobile menu
* Added terms and conditions to help and login forms
* Added password change functionality
* Better styles for shared page
* Added some tests for changing password
This commit is contained in:
Max G
2020-07-14 05:31:02 +00:00
parent 06b8f0ad6a
commit a8a966866c
16 changed files with 423 additions and 142 deletions

View File

@@ -7,6 +7,7 @@ let Auth = {}
const tokenSecretKey = process.env.JSON_KEY
//Creates session token
Auth.createToken = (userId, masterKey, pastId = null, pastCreatedDate = null) => {
return new Promise((resolve, reject) => {
@@ -42,6 +43,7 @@ Auth.createToken = (userId, masterKey, pastId = null, pastCreatedDate = null) =>
})
}
//Decodes session token
Auth.decodeToken = (token, request = null) => {
return new Promise((resolve, reject) => {

View File

@@ -263,7 +263,7 @@ let AuthTest = require('@helpers/Auth')
Auth.testTwoFactor()
Auth.test()
UserTest.keyPairTest('genMan16', '1', printResults)
UserTest.keyPairTest('genMan23', '1', printResults)
.then( ({testUserId, masterKey}) => NoteTest.test(testUserId, masterKey, printResults))
.then( message => {
if(printResults) console.log(message)

View File

@@ -10,19 +10,28 @@ QuickNote.get = (userId, masterKey) => {
db.promise()
.query(`
SELECT note.id FROM note WHERE quick_note = 1 AND user_id = ? LIMIT 1
`, [userId])
SELECT note.id FROM note WHERE quick_note = 1 AND user_id = ? LIMIT 1`, [userId])
.then((rows, fields) => {
//Quick Note is set, return note text
if(rows[0][0] != undefined){
let noteId = rows[0][0].id
Note.get(userId, noteId, masterKey)
.then( noteObject => {
return resolve(noteObject)
})
return resolve({'noteId':noteId})
} else {
return resolve(null)
//Or create a new note and get the id
let finalId = null
return Note.create(userId, 'Scratch Pad', '', masterKey)
.then(insertedId => {
finalId = insertedId
db.promise().query('UPDATE note SET quick_note = 1 WHERE id = ? AND user_id = ?',[insertedId, userId])
.then((rows, fields) => {
return resolve({'noteId':finalId})
})
})
}

View File

@@ -9,7 +9,7 @@ const speakeasy = require('speakeasy')
let User = module.exports = {}
const version = '3.1.3'
const version = '3.1.5'
//Login a user, if that user does not exist create them
//Issues login token
@@ -238,7 +238,7 @@ User.getCounts = (userId) => {
Object.assign(countTotals, rows[0][0]) //combine results
return db.promise().query('SELECT two_fa_enabled FROM user WHERE id = ?', [userId])
return db.promise().query('SELECT id AS quickNote FROM note WHERE quick_note = 1 AND user_id = ?', [userId])
}).then( (rows, fields) => {
@@ -432,6 +432,66 @@ User.getByUserName = (username) => {
})
}
User.changePassword = (userId, oldPass, newPass) => {
return new Promise((resolve, reject) => {
User.getMasterKey(userId, oldPass)
.then(masterKey => {
User.getPrivateKey(userId, masterKey)
.then(privateKey => {
//If success, user has correct password
// Generate new master pass, encrypt with new password
// const masterPassword = cs.createSmallSalt()
const salt = cs.createSmallSalt()
const encryptedMasterPassword = cs.encrypt(newPass, salt, masterKey)
const encryptedPrivateKey = cs.encrypt(masterKey, salt, privateKey)
db.promise()
.query(
'UPDATE user_key SET salt = ?, `key` = ?, private_key_encrypted = ? WHERE user_id = ? LIMIT 1',
[salt, encryptedMasterPassword, encryptedPrivateKey, userId]
).then((r,f) => {
//Create login using password
let shasum = crypto.createHash('sha512') //Prepare Hash
const saltString = shasum.digest('hex')
const passwordSalt = Buffer.from(saltString, 'binary') //Generate Salt hash
const iterations = 25000
crypto.pbkdf2(newPass, passwordSalt, iterations, 512, 'sha512', function(err, delivered_key) {
const deliveredPass = delivered_key.toString('hex')
db.promise().query('UPDATE user SET password = ?, salt = ? WHERE id = ? LIMIT 1', [deliveredPass, passwordSalt, userId])
.then((r,f) => {
return resolve(true)
})
})
})
})
})
.catch(error => {
resolve(false)
})
})
}
User.revokeActiveSessions = (userId, sessionId) => {
return new Promise((resolve, reject) => {
const userHash = cs.hash(String(userId)).toString('base64')
db.promise().query('DELETE FROM user_active_session WHERE user_hash = ? AND session_id != ?', [userHash, sessionId])
.then((r,f) => {
resolve(true)
})
})
}
User.deleteUser = (userId, password) => {
//Verify user is correct by decryptig master key with password
@@ -471,6 +531,7 @@ User.keyPairTest = (testUserName = 'genMan', password = '1', printResults) => {
const randomUsername = Math.random().toString(36).substring(2, 15);
const randomPassword = '1'
const secondPassword = '2'
User.register(testUserName, password)
.then( ({ token, userId }) => {
@@ -478,7 +539,7 @@ User.keyPairTest = (testUserName = 'genMan', password = '1', printResults) => {
if(printResults) console.log('Test: Register User '+testUserName+' - Pass')
return User.getMasterKey(testUserId, password)
return User.getMasterKey(testUserId, password)
})
.then(newMasterKey => {
masterKey = newMasterKey
@@ -510,6 +571,26 @@ User.keyPairTest = (testUserName = 'genMan', password = '1', printResults) => {
if(printResults) console.log('Test: Login New User - Pass')
return User.changePassword(testUserId, randomPassword, secondPassword)
})
.then(passwordChangeResults => {
if(printResults) console.log('Test: Password Change - ', passwordChangeResults?'Pass':'Fail')
return User.login(testUserName, secondPassword)
})
.then(reLogin => {
if(printResults) console.log('Test: Login With new Password - Pass')
return User.getMasterKey(testUserId, secondPassword)
})
.then(newMasterKey => {
masterKey = newMasterKey
resolve({testUserId, masterKey})
})
})

View File

@@ -6,9 +6,8 @@ let QuickNote = require('@models/QuickNote');
let userId = null
let masterKey = null
// middleware that is specific to this router
router.use(function setUserId (req, res, next) {
if(userId = req.headers.userId){
if(req.headers.userId){
userId = req.headers.userId
masterKey = req.headers.masterKey
}

View File

@@ -41,6 +41,25 @@ router.post('/register', function (req, res) {
})
})
// change password
router.post('/changepassword', function (req, res) {
User.changePassword(req.headers.userId, req.body.currentPass, req.body.newPass)
.then( returnData => {
res.send(returnData)
})
})
//Revoke all active session keys for user
router.post('/revokesessions', function(req, res) {
User.revokeActiveSessions(req.headers.userId, req.headers.sessionId)
.then( returnData => {
res.send(returnData)
})
})
// fetch counts of users notes
router.post('/totals', function (req, res) {
User.getCounts(req.headers.userId)