From fc23fc9e87768e0fc5f5f57235261c18b4518f54 Mon Sep 17 00:00:00 2001 From: joseji Date: Sun, 20 Nov 2022 18:14:43 +0100 Subject: [PATCH] fixes done --- .../src/graphql/resolver/UserResolver.test.ts | 6 ++-- backend/src/graphql/resolver/UserResolver.ts | 4 ++- backend/src/password/EncryptorUtils.ts | 27 ++++++++++-------- backend/src/password/PasswordEncryptor.ts | 17 +++++++++++ backend/src/password/PasswordEncryptr.ts | 28 ------------------- .../0053-change_password_encryption/User.ts | 2 +- .../0053-change_password_encryption.ts | 22 ++------------- 7 files changed, 42 insertions(+), 64 deletions(-) create mode 100644 backend/src/password/PasswordEncryptor.ts delete mode 100644 backend/src/password/PasswordEncryptr.ts diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 03aabfbb4..a3e2dbe21 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -36,7 +36,7 @@ import { UserContact } from '@entity/UserContact' import { OptInType } from '../enum/OptInType' import { UserContactType } from '../enum/UserContactType' import { bobBaumeister } from '@/seeds/users/bob-baumeister' -import { encryptPassword } from '@/password/PasswordEncryptr' +import { encryptPassword } from '@/password/PasswordEncryptor' import { PasswordEncryptionType } from '../enum/PasswordEncryptionType' import { SecretKeyCryptographyCreateKey } from '@/password/EncryptorUtils' @@ -149,7 +149,7 @@ describe('UserResolver', () => { publisherId: 1234, referrerId: null, contributionLinkId: null, - passwordEncryptionType: 1, + passwordEncryptionType: PasswordEncryptionType.NO_PASSWORD, }, ]) const valUUID = validateUUID(user[0].gradidoID) @@ -1168,7 +1168,7 @@ describe('UserResolver', () => { describe('user just registered', () => { let bibi: User - it('password type should be gradido id', async () => { + it('has password type gradido id', async () => { const users = await User.find() bibi = users[1] diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index ef5edd747..a9006bbb6 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -40,7 +40,7 @@ import Paginated from '@arg/Paginated' import { Order } from '@enum/Order' import { v4 as uuidv4 } from 'uuid' import { isValidPassword, SecretKeyCryptographyCreateKey } from '@/password/EncryptorUtils' -import { encryptPassword, verifyPassword } from '@/password/PasswordEncryptr' +import { encryptPassword, verifyPassword } from '@/password/PasswordEncryptor' import { PasswordEncryptionType } from '../enum/PasswordEncryptionType' // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -432,6 +432,7 @@ export class UserResolver { dbUser.lastName = lastName dbUser.language = language dbUser.publisherId = publisherId + dbUser.passwordEncryptionType = PasswordEncryptionType.NO_PASSWORD dbUser.passphrase = passphrase.join(' ') logger.debug('new dbUser=' + dbUser) if (redeemCode) { @@ -780,6 +781,7 @@ export class UserResolver { logger.debug('PrivateKey encrypted...') // Save new password hash and newly encrypted private key + userEntity.passwordEncryptionType = PasswordEncryptionType.GRADIDO_ID userEntity.password = encryptPassword(userEntity, passwordNew) userEntity.privKey = encryptedPrivkey } diff --git a/backend/src/password/EncryptorUtils.ts b/backend/src/password/EncryptorUtils.ts index 5f6f4b416..2ca47109d 100644 --- a/backend/src/password/EncryptorUtils.ts +++ b/backend/src/password/EncryptorUtils.ts @@ -47,20 +47,23 @@ export const SecretKeyCryptographyCreateKey = (salt: string, password: string): const encryptionKeyHash = Buffer.alloc(sodium.crypto_shorthash_BYTES) sodium.crypto_shorthash(encryptionKeyHash, encryptionKey, configLoginServerKey) - logger.debug( - `SecretKeyCryptographyCreateKey...successful: encryptionKeyHash= ${encryptionKeyHash}, encryptionKey= ${encryptionKey}`, - ) return [encryptionKeyHash, encryptionKey] } -export const getBasicCryptographicKey = (dbUser: User): string | null => { - if (dbUser.passwordEncryptionType === PasswordEncryptionType.NO_PASSWORD) { - return null - } else if (dbUser.passwordEncryptionType === PasswordEncryptionType.EMAIL) { - return dbUser.emailContact.email - } else if (dbUser.passwordEncryptionType === PasswordEncryptionType.GRADIDO_ID) { - return dbUser.gradidoID +export const getUserCryptographicSalt = (dbUser: User): string => { + switch (dbUser.passwordEncryptionType) { + case PasswordEncryptionType.NO_PASSWORD: { + throw new Error('Password not set for user ' + dbUser.id) // user has no password + } + case PasswordEncryptionType.EMAIL: { + return dbUser.emailContact.email + break + } + case PasswordEncryptionType.GRADIDO_ID: { + return dbUser.gradidoID + break + } + default: + throw new Error(`Unknown password encryption type: ${dbUser.passwordEncryptionType}`) } - - throw new Error(`Unknown password encryption type: ${dbUser.passwordEncryptionType}`) } diff --git a/backend/src/password/PasswordEncryptor.ts b/backend/src/password/PasswordEncryptor.ts new file mode 100644 index 000000000..2c6ebfb0f --- /dev/null +++ b/backend/src/password/PasswordEncryptor.ts @@ -0,0 +1,17 @@ +import { User } from '@entity/User' +// import { logger } from '@test/testSetup' getting error "jest is not defined" +import { getUserCryptographicSalt, SecretKeyCryptographyCreateKey } from './EncryptorUtils' + +export const encryptPassword = (dbUser: User, password: string): bigint => { + const basicKey = getUserCryptographicSalt(dbUser) + const keyBuffer = SecretKeyCryptographyCreateKey(basicKey, password) // return short and long hash + const passwordHash = keyBuffer[0].readBigUInt64LE() + return passwordHash +} + +export const verifyPassword = (dbUser: User, password: string): boolean => { + if (dbUser.password.toString() !== encryptPassword(dbUser, password).toString()) { + return false + } + return true +} diff --git a/backend/src/password/PasswordEncryptr.ts b/backend/src/password/PasswordEncryptr.ts deleted file mode 100644 index b8ef2de31..000000000 --- a/backend/src/password/PasswordEncryptr.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { User } from '@entity/User' -// import { logger } from '@test/testSetup' getting error "jest is not defined" -import { getBasicCryptographicKey, SecretKeyCryptographyCreateKey } from './EncryptorUtils' - -export const encryptPassword = (dbUser: User, password: string): bigint => { - const basicKey = getBasicCryptographicKey(dbUser) - if (!basicKey) { - // logger.error('Password not set for user ' + dbUser.id) - throw new Error('Password not set for user ' + dbUser.id) // user has no password - } else { - const keyBuffer = SecretKeyCryptographyCreateKey(basicKey, password) // return short and long hash - const passwordHash = keyBuffer[0].readBigUInt64LE() - return passwordHash - } -} - -export const verifyPassword = (dbUser: User, password: string): boolean => { - const basicKey = getBasicCryptographicKey(dbUser) - if (!basicKey) { - // logger.error('Password not set for user ' + dbUser.id) - throw new Error('Password not set for user ' + dbUser.id) // user has no password - } else { - if (dbUser.password.toString() !== encryptPassword(dbUser, password).toString()) { - return false - } - return true - } -} diff --git a/database/entity/0053-change_password_encryption/User.ts b/database/entity/0053-change_password_encryption/User.ts index fac4e1031..2a3332925 100644 --- a/database/entity/0053-change_password_encryption/User.ts +++ b/database/entity/0053-change_password_encryption/User.ts @@ -88,7 +88,7 @@ export class User extends BaseEntity { type: 'int', unsigned: true, nullable: false, - default: 1, + default: 0, }) passwordEncryptionType: number diff --git a/database/migrations/0053-change_password_encryption.ts b/database/migrations/0053-change_password_encryption.ts index 5d880689f..0c8632186 100644 --- a/database/migrations/0053-change_password_encryption.ts +++ b/database/migrations/0053-change_password_encryption.ts @@ -1,6 +1,6 @@ -/* MIGRATION TO ADD ENCRYPTION TO PASSWORDS +/* MIGRATION TO ADD ENCRYPTION TYPE TO PASSWORDS * - * This migration adds and renames columns to and in the table `users` + * This migration adds and renames columns in the table `users` */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ @@ -11,28 +11,12 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis await queryFn('ALTER TABLE users RENAME COLUMN deletedAt TO deleted_at;') // alter table emp rename column emp_name to name await queryFn( - 'ALTER TABLE users ADD COLUMN password_encryption_type int(10) NOT NULL DEFAULT 1 AFTER password;', + 'ALTER TABLE users ADD COLUMN password_encryption_type int(10) NOT NULL DEFAULT 0 AFTER password;', ) - - // TODO these steps comes after verification and test - /* - await queryFn('ALTER TABLE users DROP COLUMN public_key;') - await queryFn('ALTER TABLE users DROP COLUMN privkey;') - await queryFn('ALTER TABLE users DROP COLUMN email_hash;') - await queryFn('ALTER TABLE users DROP COLUMN passphrase;') - */ } export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { await queryFn('ALTER TABLE users RENAME COLUMN created_at TO created;') await queryFn('ALTER TABLE users RENAME COLUMN deleted_at TO deletedAt;') await queryFn('ALTER TABLE users DROP COLUMN password_encryption_type;') - - // TODO these steps comes after verification and test - /* - await queryFn('ALTER TABLE users ADD COLUMN public_key binary(32) DEFAULT NULL;') - await queryFn('ALTER TABLE users ADD COLUMN privkey binary(80) DEFAULT NULL;') - await queryFn('ALTER TABLE users ADD COLUMN email_hash binary(32) DEFAULT NULL;') - await queryFn('ALTER TABLE users ADD COLUMN passphrase text DEFAULT NULL;') - */ }