diff --git a/src/services/encryption/data_encryption.js b/src/services/encryption/data_encryption.ts similarity index 85% rename from src/services/encryption/data_encryption.js rename to src/services/encryption/data_encryption.ts index 2b18058c5..c19008a5b 100644 --- a/src/services/encryption/data_encryption.js +++ b/src/services/encryption/data_encryption.ts @@ -1,9 +1,9 @@ "use strict"; -const crypto = require('crypto'); -const log = require('../log'); +import crypto = require('crypto'); +import log = require('../log'); -function arraysIdentical(a, b) { +function arraysIdentical(a: Buffer, b: Buffer) { let i = a.length; if (i !== b.length) return false; while (i--) { @@ -12,12 +12,12 @@ function arraysIdentical(a, b) { return true; } -function shaArray(content) { +function shaArray(content: crypto.BinaryLike) { // we use this as a simple checksum and don't rely on its security, so SHA-1 is good enough return crypto.createHash('sha1').update(content).digest(); } -function pad(data) { +function pad(data: Buffer): Buffer { if (data.length > 16) { data = data.slice(0, 16); } @@ -30,7 +30,7 @@ function pad(data) { return Buffer.from(data); } -function encrypt(key, plainText) { +function encrypt(key: Buffer, plainText: Buffer | string) { if (!key) { throw new Error("No data key!"); } @@ -51,10 +51,7 @@ function encrypt(key, plainText) { return encryptedDataWithIv.toString('base64'); } -/** - * @returns {Buffer|false|null} - */ -function decrypt(key, cipherText) { +function decrypt(key: Buffer, cipherText: string | Buffer): Buffer | false | null { if (cipherText === null) { return null; } @@ -88,12 +85,12 @@ function decrypt(key, cipherText) { return payload; } - catch (e) { + catch (e: any) { // recovery from https://github.com/zadam/trilium/issues/510 if (e.message?.includes("WRONG_FINAL_BLOCK_LENGTH") || e.message?.includes("wrong final block length")) { log.info("Caught WRONG_FINAL_BLOCK_LENGTH, returning cipherText instead"); - return cipherText; + return Buffer.from(cipherText); } else { throw e; @@ -101,7 +98,7 @@ function decrypt(key, cipherText) { } } -function decryptString(dataKey, cipherText) { +function decryptString(dataKey: Buffer, cipherText: string) { const buffer = decrypt(dataKey, cipherText); if (buffer === null) { @@ -115,7 +112,7 @@ function decryptString(dataKey, cipherText) { return buffer.toString('utf-8'); } -module.exports = { +export = { encrypt, decrypt, decryptString diff --git a/src/services/encryption/my_scrypt.js b/src/services/encryption/my_scrypt.ts similarity index 58% rename from src/services/encryption/my_scrypt.js rename to src/services/encryption/my_scrypt.ts index bc01cdde7..9c7774923 100644 --- a/src/services/encryption/my_scrypt.js +++ b/src/services/encryption/my_scrypt.ts @@ -1,28 +1,28 @@ "use strict"; -const optionService = require('../options.js'); -const crypto = require('crypto'); +import optionService = require('../options.js'); +import crypto = require('crypto'); -function getVerificationHash(password) { +function getVerificationHash(password: crypto.BinaryLike) { const salt = optionService.getOption('passwordVerificationSalt'); return getScryptHash(password, salt); } -function getPasswordDerivedKey(password) { +function getPasswordDerivedKey(password: crypto.BinaryLike) { const salt = optionService.getOption('passwordDerivedKeySalt'); return getScryptHash(password, salt); } -function getScryptHash(password, salt) { +function getScryptHash(password: crypto.BinaryLike, salt: crypto.BinaryLike) { const hashed = crypto.scryptSync(password, salt, 32, {N: 16384, r:8, p:1}); return hashed; } -module.exports = { +export = { getVerificationHash, getPasswordDerivedKey }; diff --git a/src/services/encryption/password.js b/src/services/encryption/password.ts similarity index 78% rename from src/services/encryption/password.js rename to src/services/encryption/password.ts index 95660fcf7..07b4de85b 100644 --- a/src/services/encryption/password.js +++ b/src/services/encryption/password.ts @@ -1,16 +1,16 @@ "use strict"; -const sql = require('../sql'); -const optionService = require('../options.js'); -const myScryptService = require('./my_scrypt.js'); -const utils = require('../utils'); -const passwordEncryptionService = require('./password_encryption.js'); +import sql = require('../sql'); +import optionService = require('../options.js'); +import myScryptService = require('./my_scrypt.js'); +import utils = require('../utils'); +import passwordEncryptionService = require('./password_encryption.js'); function isPasswordSet() { return !!sql.getValue("SELECT value FROM options WHERE name = 'passwordVerificationHash'"); } -function changePassword(currentPassword, newPassword) { +function changePassword(currentPassword: string, newPassword: string) { if (!isPasswordSet()) { throw new Error("Password has not been set yet, so it cannot be changed. Use 'setPassword' instead."); } @@ -29,8 +29,11 @@ function changePassword(currentPassword, newPassword) { optionService.setOption('passwordDerivedKeySalt', utils.randomSecureToken(32)); const newPasswordVerificationKey = utils.toBase64(myScryptService.getVerificationHash(newPassword)); - - passwordEncryptionService.setDataKey(newPassword, decryptedDataKey); + + if (decryptedDataKey) { + // FIXME: what should happen if the decrypted data key is null? + passwordEncryptionService.setDataKey(newPassword, decryptedDataKey); + } optionService.setOption('passwordVerificationHash', newPasswordVerificationKey); }); @@ -40,7 +43,7 @@ function changePassword(currentPassword, newPassword) { }; } -function setPassword(password) { +function setPassword(password: string) { if (isPasswordSet()) { throw new Error("Password is set already. Either change it or perform 'reset password' first."); } @@ -48,13 +51,13 @@ function setPassword(password) { optionService.createOption('passwordVerificationSalt', utils.randomSecureToken(32), true); optionService.createOption('passwordDerivedKeySalt', utils.randomSecureToken(32), true); - const passwordVerificationKey = utils.toBase64(myScryptService.getVerificationHash(password), true); + const passwordVerificationKey = utils.toBase64(myScryptService.getVerificationHash(password)); optionService.createOption('passwordVerificationHash', passwordVerificationKey, true); // passwordEncryptionService expects these options to already exist optionService.createOption('encryptedDataKey', '', true); - passwordEncryptionService.setDataKey(password, utils.randomSecureToken(16), true); + passwordEncryptionService.setDataKey(password, utils.randomSecureToken(16)); return { success: true diff --git a/src/services/encryption/password_encryption.js b/src/services/encryption/password_encryption.ts similarity index 70% rename from src/services/encryption/password_encryption.js rename to src/services/encryption/password_encryption.ts index 06ada7d98..939de5a9d 100644 --- a/src/services/encryption/password_encryption.js +++ b/src/services/encryption/password_encryption.ts @@ -1,9 +1,9 @@ -const optionService = require('../options.js'); -const myScryptService = require('./my_scrypt.js'); -const utils = require('../utils'); -const dataEncryptionService = require('./data_encryption.js'); +import optionService = require('../options.js'); +import myScryptService = require('./my_scrypt.js'); +import utils = require('../utils'); +import dataEncryptionService = require('./data_encryption.js'); -function verifyPassword(password) { +function verifyPassword(password: string) { const givenPasswordHash = utils.toBase64(myScryptService.getVerificationHash(password)); const dbPasswordHash = optionService.getOptionOrNull('passwordVerificationHash'); @@ -15,7 +15,7 @@ function verifyPassword(password) { return givenPasswordHash === dbPasswordHash; } -function setDataKey(password, plainTextDataKey) { +function setDataKey(password: string, plainTextDataKey: string | Buffer) { const passwordDerivedKey = myScryptService.getPasswordDerivedKey(password); const newEncryptedDataKey = dataEncryptionService.encrypt(passwordDerivedKey, plainTextDataKey); @@ -23,8 +23,7 @@ function setDataKey(password, plainTextDataKey) { optionService.setOption('encryptedDataKey', newEncryptedDataKey); } -/** @return {Buffer} */ -function getDataKey(password) { +function getDataKey(password: string) { const passwordDerivedKey = myScryptService.getPasswordDerivedKey(password); const encryptedDataKey = optionService.getOption('encryptedDataKey'); @@ -34,7 +33,7 @@ function getDataKey(password) { return decryptedDataKey; } -module.exports = { +export = { verifyPassword, getDataKey, setDataKey diff --git a/src/services/sql.ts b/src/services/sql.ts index f89330832..8567cafaa 100644 --- a/src/services/sql.ts +++ b/src/services/sql.ts @@ -313,7 +313,7 @@ function disableSlowQueryLogging(cb: () => T) { } } -module.exports = { +export = { dbConnection, insert, replace, diff --git a/src/services/utils.ts b/src/services/utils.ts index d31e73482..9a3397f85 100644 --- a/src/services/utils.ts +++ b/src/services/utils.ts @@ -41,7 +41,7 @@ function hashedBlobId(content: string) { return kindaBase62Hash.substr(0, 20); } -function toBase64(plainText: string) { +function toBase64(plainText: string | Buffer) { return Buffer.from(plainText).toString('base64'); } @@ -311,7 +311,7 @@ function isString(x: any) { return Object.prototype.toString.call(x) === "[object String]"; } -module.exports = { +export = { randomSecureToken, randomString, md5,