Verschlüsselung korrigiert
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { sequelize } from '../../utils/sequelize.js';
|
||||
import { DataTypes } from 'sequelize';
|
||||
import bcrypt from 'bcrypt';
|
||||
import { encrypt, generateIv } from '../../utils/encryption.js';
|
||||
|
||||
const User = sequelize.define('user', {
|
||||
email: {
|
||||
@@ -8,9 +9,17 @@ const User = sequelize.define('user', {
|
||||
allowNull: false,
|
||||
unique: true,
|
||||
set(value) {
|
||||
this.setDataValue('email', bcrypt.hashSync(value, 10));
|
||||
if (value) {
|
||||
const iv = generateIv();
|
||||
this.setDataValue('iv', iv.toString('hex'));
|
||||
this.setDataValue('email', encrypt(value, iv));
|
||||
}
|
||||
}
|
||||
},
|
||||
iv: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
username: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
@@ -19,6 +28,9 @@ const User = sequelize.define('user', {
|
||||
password: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
set(value) {
|
||||
this.setDataValue('password', bcrypt.hashSync(value, 10));
|
||||
}
|
||||
},
|
||||
registrationDate: {
|
||||
type: DataTypes.DATE,
|
||||
@@ -29,7 +41,7 @@ const User = sequelize.define('user', {
|
||||
type: DataTypes.BOOLEAN,
|
||||
defaultValue: false
|
||||
},
|
||||
resetToken: {
|
||||
resetToken: {
|
||||
type: DataTypes.UUID,
|
||||
allowNull: true
|
||||
},
|
||||
@@ -40,7 +52,7 @@ const User = sequelize.define('user', {
|
||||
}, {
|
||||
tableName: 'user',
|
||||
schema: 'community',
|
||||
underscored: true,
|
||||
underscored: true
|
||||
});
|
||||
|
||||
export default User;
|
||||
|
||||
@@ -2,6 +2,7 @@ import { sequelize } from '../../utils/sequelize.js';
|
||||
import { DataTypes } from 'sequelize';
|
||||
import User from './user.js';
|
||||
import UserParamType from '../type/user_param.js';
|
||||
import { encrypt, decrypt, generateIv } from '../../utils/encryption.js';
|
||||
|
||||
const UserParam = sequelize.define('user_param', {
|
||||
userId: {
|
||||
@@ -18,20 +19,52 @@ const UserParam = sequelize.define('user_param', {
|
||||
references: {
|
||||
model: UserParamType,
|
||||
key: 'id'
|
||||
},
|
||||
|
||||
}
|
||||
},
|
||||
value: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
set(value) {
|
||||
if (value) {
|
||||
const iv = generateIv();
|
||||
this.setDataValue('iv', iv.toString('hex'));
|
||||
this.setDataValue('value', encrypt(value, iv));
|
||||
}
|
||||
}
|
||||
},
|
||||
iv: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
}
|
||||
}, {
|
||||
tableName: 'user_param',
|
||||
schema: 'community',
|
||||
underscored: true
|
||||
underscored: true,
|
||||
hooks: {
|
||||
beforeSave: (userParam) => {
|
||||
if (userParam.value && !userParam.iv) {
|
||||
const iv = generateIv();
|
||||
userParam.iv = iv.toString('hex');
|
||||
userParam.value = encrypt(userParam.value, iv);
|
||||
}
|
||||
},
|
||||
afterFind: (userParams) => {
|
||||
if (userParams) {
|
||||
if (Array.isArray(userParams)) {
|
||||
userParams.forEach((userParam) => {
|
||||
const iv = Buffer.from(userParam.iv, 'hex');
|
||||
userParam.value = decrypt(userParam.value, iv);
|
||||
});
|
||||
} else {
|
||||
const iv = Buffer.from(userParams.iv, 'hex');
|
||||
userParams.value = decrypt(userParams.value, iv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
UserParam.belongsTo(User, { foreignKey: 'userId' });
|
||||
UserParam.belongsTo(UserParamType, { foreignKey: 'param_type_id' });
|
||||
UserParam.belongsTo(UserParamType, { foreignKey: 'paramTypeId' });
|
||||
|
||||
export default UserParam;
|
||||
|
||||
@@ -8,31 +8,40 @@ import { sendAccountActivationEmail, sendPasswordResetEmail } from './emailServi
|
||||
const saltRounds = 10;
|
||||
|
||||
export const registerUser = async ({ email, username, password, language }) => {
|
||||
const [results] = await sequelize.query(
|
||||
'SELECT * FROM "community"."user" WHERE pgp_sym_decrypt("email", :key) = :email',
|
||||
{
|
||||
replacements: { key: process.env.SECRET_KEY, email },
|
||||
type: sequelize.QueryTypes.SELECT
|
||||
}
|
||||
);
|
||||
if (results.length > 0) {
|
||||
throw new Error('Email already in use');
|
||||
}
|
||||
const iv = generateIv();
|
||||
const encryptedEmail = encrypt(email, iv);
|
||||
const hashedPassword = await bcrypt.hash(password, saltRounds);
|
||||
const resetToken = uuidv4();
|
||||
const user = await User.create({
|
||||
email,
|
||||
email: encryptedEmail,
|
||||
iv: iv.toString('hex'),
|
||||
username,
|
||||
password: hashedPassword,
|
||||
resetToken: resetToken,
|
||||
active: false,
|
||||
registration_date: new Date()
|
||||
});
|
||||
|
||||
const languageType = await UserParamType.findOne({ where: { description: 'language' } });
|
||||
if (!languageType) {
|
||||
throw new Error('Language type not found');
|
||||
}
|
||||
|
||||
await UserParam.create({
|
||||
userId: user.id,
|
||||
paramTypeId: languageType.id,
|
||||
value: language
|
||||
});
|
||||
|
||||
const activationLink = `${process.env.FRONTEND_URL}/activate?token=${resetToken}`;
|
||||
await sendAccountActivationEmail(email, activationLink, username, resetToken, language);
|
||||
|
||||
return { id: user.hashedId, username: user.username, active: user.active };
|
||||
};
|
||||
|
||||
|
||||
32
backend/utils/encryption.js
Normal file
32
backend/utils/encryption.js
Normal file
@@ -0,0 +1,32 @@
|
||||
import crypto from 'crypto';
|
||||
import dotenv from 'dotenv';
|
||||
|
||||
dotenv.config(); // Laden der Umgebungsvariablen
|
||||
|
||||
const algorithm = 'aes-256-cbc';
|
||||
const secretKey = process.env.SECRET_KEY;
|
||||
|
||||
if (!secretKey || secretKey.length !== 32) {
|
||||
throw new Error('SECRET_KEY length must be 32 bytes');
|
||||
}
|
||||
|
||||
const encrypt = (text, iv) => {
|
||||
const cipher = crypto.createCipheriv(algorithm, Buffer.from(secretKey, 'utf-8'), iv);
|
||||
let encrypted = cipher.update(text);
|
||||
encrypted = Buffer.concat([encrypted, cipher.final()]);
|
||||
return encrypted.toString('hex');
|
||||
};
|
||||
|
||||
const decrypt = (encryptedText, iv) => {
|
||||
const encryptedBuffer = Buffer.from(encryptedText, 'hex');
|
||||
const decipher = crypto.createDecipheriv(algorithm, Buffer.from(secretKey, 'utf-8'), iv);
|
||||
let decrypted = decipher.update(encryptedBuffer);
|
||||
decrypted = Buffer.concat([decrypted, decipher.final()]);
|
||||
return decrypted.toString();
|
||||
};
|
||||
|
||||
const generateIv = () => {
|
||||
return crypto.randomBytes(16);
|
||||
};
|
||||
|
||||
export { encrypt, decrypt, generateIv };
|
||||
Reference in New Issue
Block a user