1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-09 00:18:00 +01:00

feat: email will be stored hashed now for all users (#8720)

Adding email_hash column to users table.
We will update all existing users to have hashed email. 
All new users will also get the hash.

We are fine to use md5, because we just need uniqueness. We have emails
in events table stored anyways, so it is not sensitive.
This commit is contained in:
Jaanus Sellin 2024-11-12 13:28:19 +02:00 committed by GitHub
parent 42198cee83
commit c8bc40146a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 49 additions and 1 deletions

View File

@ -108,8 +108,15 @@ class UserStore implements IUserStore {
} }
async insert(user: ICreateUser): Promise<User> { async insert(user: ICreateUser): Promise<User> {
const emailHash = user.email
? this.db.raw('md5(?)', [user.email])
: null;
const rows = await this.db(TABLE) const rows = await this.db(TABLE)
.insert({ ...mapUserToColumns(user), created_at: new Date() }) .insert({
...mapUserToColumns(user),
email_hash: emailHash,
created_at: new Date(),
})
.returning(USER_COLUMNS); .returning(USER_COLUMNS);
return rowToUser(rows[0]); return rowToUser(rows[0]);
} }

View File

@ -0,0 +1,18 @@
exports.up = (db, cb) => {
db.runSql(`
ALTER TABLE users
ADD COLUMN IF NOT EXISTS email_hash VARCHAR(32);
UPDATE users
SET email_hash = md5(email::text);
`, cb);
};
exports.down = (db, cb) => {
db.runSql(`
ALTER TABLE users
DROP COLUMN IF EXISTS email_hash;
`, cb);
};

View File

@ -18,6 +18,7 @@ import { randomId } from '../../../../lib/util/random-id';
import { omitKeys } from '../../../../lib/util/omit-keys'; import { omitKeys } from '../../../../lib/util/omit-keys';
import type { ISessionStore } from '../../../../lib/types/stores/session-store'; import type { ISessionStore } from '../../../../lib/types/stores/session-store';
import type { IUnleashStores } from '../../../../lib/types'; import type { IUnleashStores } from '../../../../lib/types';
import { createHash } from 'crypto';
let stores: IUnleashStores; let stores: IUnleashStores;
let db: ITestDb; let db: ITestDb;
@ -405,3 +406,25 @@ test('Anonymises name, username and email fields if anonymiseEventLog flag is se
expect(body.users[0].name).toEqual('3a8b17647@unleash.run'); expect(body.users[0].name).toEqual('3a8b17647@unleash.run');
expect(body.users[0].username).toEqual(''); // Not set, so anonymise should return the empty string. expect(body.users[0].username).toEqual(''); // Not set, so anonymise should return the empty string.
}); });
test('creates user with email md5 hash', async () => {
await app.request
.post('/api/admin/user-admin')
.send({
email: `hasher@getunleash.ai`,
name: `Some Name Hash`,
rootRole: editorRole.id,
})
.set('Content-Type', 'application/json');
const user = await db
.rawDatabase('users')
.where({ email: 'hasher@getunleash.ai' })
.first(['email_hash']);
const expectedHash = createHash('md5')
.update('hasher@getunleash.ai')
.digest('hex');
expect(user.email_hash).toBe(expectedHash);
});