diff --git a/backend/app.js b/backend/app.js index e746827..9787a7a 100644 --- a/backend/app.js +++ b/backend/app.js @@ -4,19 +4,21 @@ import { fileURLToPath } from 'url'; import chatRouter from './routers/chatRouter.js'; import authRouter from './routers/authRouter.js'; import navigationRouter from './routers/navigationRouter.js' +import settingsRouter from './routers/settingsRouter.js'; import cors from 'cors'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const app = express(); - + app.use(cors()); app.use(express.json()); // To handle JSON request bodies app.use('/api/chat', chatRouter); app.use('/api/auth', authRouter); app.use('/api/navigation', navigationRouter); +app.use('/api/settings', settingsRouter); app.use('/images', express.static(path.join(__dirname, '../frontend/public/images'))); app.use((req, res) => { diff --git a/backend/controllers/authController.js b/backend/controllers/authController.js index 17174de..95cb51b 100644 --- a/backend/controllers/authController.js +++ b/backend/controllers/authController.js @@ -21,6 +21,7 @@ export const login = async (req, res) => { if (error.message === 'credentialsinvalid') { res.status(404).json({ error: error.message }) } else { + console.log(error); res.status(500).json({ error: error.message }); } } diff --git a/backend/controllers/settingsController.js b/backend/controllers/settingsController.js new file mode 100644 index 0000000..35d6b03 --- /dev/null +++ b/backend/controllers/settingsController.js @@ -0,0 +1,113 @@ +import UserParamType from '../models/type/user_param.js'; +import SettingsType from '../models/type/settings.js'; +import UserParam from '../models/community/user_param.js'; +import User from '../models/community/user.js'; +import UserParamValue from '../models/type/user_param_value.js'; + +export const filterSettings = async (req, res) => { + const { userid, type } = req.body; + console.log(userid, type); + try { + const fields = await UserParamType.findAll({ + include: [ + { + model: SettingsType, + as: 'settings_type', + where: { name: type } + }, + { + model: UserParam, + as: 'user_params', + required: false, + include: [ + { + model: User, + as: 'user', + where: { hashedId: userid } + } + ] + } + ] + }); + + const responseFields = await Promise.all(fields.map(async (field) => { + const options = ['singleselect', 'multiselect'].includes(field.datatype) ? await UserParamValue.findAll({ + where: { userParamTypeId: field.id } + }) : []; + + return { + id: field.id, + name: field.description, + minAge: field.minAge, + gender: field.gender, + datatype: field.datatype, + value: field.user_params.length > 0 ? field.user_params[0].value : null, + options: options.map(opt => ({ id: opt.id, value: opt.value })) + }; + })); + + res.status(200).json(responseFields); + } catch (error) { + console.error('Error fetching settings:', error); + res.status(500).json({ error: 'Internal server error' }); + } +}; + +export const updateSetting = async (req, res) => { + const { userid, settingId, value } = req.body; + try { + const user = await User.findOne({ where: { hashedId: userid } }); + if (!user) { + return res.status(404).json({ error: 'User not found' }); + } + + const paramType = await UserParamType.findOne({ where: { id: settingId } }); + if (!paramType) { + return res.status(404).json({ error: 'Parameter type not found' }); + } + console.log(value); + await UserParam.upsertParam(user.id, paramType.id, value); + res.status(200).json({ message: 'Setting updated successfully' }); + } catch (error) { + console.error('Error updating user setting:', error); + res.status(500).json({ error: 'Internal server error' }); + } +}; + +export const getTypeParamValueId = async(req, res) => { + const { paramValue } = req.body; + const userParamValueObject = await UserParamValue.findOne({ + where: { value: paramValue } + }); + if (!userParamValueObject) { + res.status(404).json({ error: "notfound" }); + return; + } + res.status(200).json({ paramValueId: userParamValueObject.id }); +}; + +export const getTypeParamValues = async(req, res) => { + const { type } = req.body; + const userParamValues = await UserParamValue.findAll({ + include: [ + { + model: UserParamType, + as: 'user_param_type', + where: { description: type } + } + ] + }); + res.status(200).json(userParamValues.map(type => { return { id: type.dataValues.id, name: type.dataValues.value}})); +} + +export const getTypeParamValue = async(req, res) => { + const { id } = req.param; + const userParamValueObject = await UserParamValue.findOne({ + where: { id: id } + }); + if (!userParamValueObject) { + res.status(404).json({ error: "notfound" }); + return; + } + res.status(200).json({ paramValueId: userParamValueObject.value }); +}; \ No newline at end of file diff --git a/backend/models/associations.js b/backend/models/associations.js new file mode 100644 index 0000000..c9d57f5 --- /dev/null +++ b/backend/models/associations.js @@ -0,0 +1,24 @@ +import User from './community/user.js'; +import UserParam from './community/user_param.js'; +import UserParamType from './type/user_param.js'; +import UserRightType from './type/user_right.js'; +import UserRight from './community/user_right.js'; +import SettingsType from './type/settings.js'; +import UserParamValue from './type/user_param_value.js'; + +export default function setupAssociations() { + SettingsType.hasMany(UserParamType, { foreignKey: 'settingsId', as: 'user_param_types' }); + UserParamType.belongsTo(SettingsType, { foreignKey: 'settingsId', as: 'settings_type' }); + + UserParamType.hasMany(UserParam, { foreignKey: 'paramTypeId', as: 'user_params' }); + UserParam.belongsTo(UserParamType, { foreignKey: 'paramTypeId', as: 'paramType' }); + + UserParam.belongsTo(SettingsType, { foreignKey: 'settingsId', as: 'settings' }); + UserParam.belongsTo(User, { foreignKey: 'userId', as: 'user' }); + + UserRight.belongsTo(User, { foreignKey: 'userId' }); + UserRight.belongsTo(UserRightType, { foreignKey: 'rightTypeId', as: 'rightType' }); + + UserParamType.hasMany(UserParamValue, { foreignKey: 'userParamTypeId', as: 'user_param_values' }); + UserParamValue.belongsTo(UserParamType, { foreignKey: 'userParamTypeId', as: 'user_param_type' }); +} diff --git a/backend/models/community/user.js b/backend/models/community/user.js index 2731b02..fc4043c 100644 --- a/backend/models/community/user.js +++ b/backend/models/community/user.js @@ -2,6 +2,7 @@ import { sequelize } from '../../utils/sequelize.js'; import { DataTypes } from 'sequelize'; import bcrypt from 'bcrypt'; import { encrypt, generateIv } from '../../utils/encryption.js'; +import crypto from 'crypto'; const User = sequelize.define('user', { email: { @@ -38,7 +39,7 @@ const User = sequelize.define('user', { type: DataTypes.BOOLEAN, defaultValue: false }, - resetToken: { + resetToken: { type: DataTypes.UUID, allowNull: true }, @@ -49,7 +50,14 @@ const User = sequelize.define('user', { }, { tableName: 'user', schema: 'community', - underscored: true + underscored: true, + hooks: { + afterCreate: async (user, options) => { + const hashedId = crypto.createHash('sha256').update(user.id.toString()).digest('hex'); + user.hashedId = hashedId; + await user.save(); + } + } }); export default User; diff --git a/backend/models/community/user_param.js b/backend/models/community/user_param.js index 01340fd..7bf58c8 100644 --- a/backend/models/community/user_param.js +++ b/backend/models/community/user_param.js @@ -26,9 +26,25 @@ const UserParam = sequelize.define('user_param', { allowNull: false, set(value) { if (value) { - const iv = generateIv(); - this.setDataValue('iv', iv.toString('hex')); - this.setDataValue('value', encrypt(value, iv)); + try { + const iv = generateIv(); + console.log(value); + this.setDataValue('iv', iv.toString('hex')); + this.setDataValue('value', encrypt(value, iv)); + } catch (error) { + console.log('Error setting value:', error); + this.setDataValue('value', ''); + } + } + }, + get() { + try { + const value = this.getDataValue('value'); + const iv = Buffer.from(this.getDataValue('iv'), 'hex'); + return decrypt(value, iv); + } catch (error) { + console.log('Error getting value:', error); + return ''; } } }, @@ -40,31 +56,29 @@ const UserParam = sequelize.define('user_param', { tableName: 'user_param', schema: 'community', 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); - } - } + indexes: [ + { + unique: true, + fields: ['user_id', 'param_type_id'] } - } + ] }); -UserParam.belongsTo(User, { foreignKey: 'userId' }); -UserParam.belongsTo(UserParamType, { foreignKey: 'paramTypeId' }); +UserParam.upsertParam = async function (userId, paramTypeId, value) { + try { + const [userParam, created] = await UserParam.findOrCreate({ + where: { userId, paramTypeId }, + defaults: { value } + }); + + if (!created) { + userParam.value = value; + await userParam.save(); + } + } catch (error) { + console.error('Error in upsertParam:', error); + throw error; + } +}; export default UserParam; diff --git a/backend/models/community/user_right.js b/backend/models/community/user_right.js index f699992..bf35225 100644 --- a/backend/models/community/user_right.js +++ b/backend/models/community/user_right.js @@ -26,7 +26,4 @@ const UserRight = sequelize.define('user_right', { underscored: true, }); -UserRight.belongsTo(User, { foreignKey: 'userId' }); -UserRight.belongsTo(UserRightType, { foreignKey: 'rightTypeId', as: 'rightType' }); - export default UserRight; diff --git a/backend/models/index.js b/backend/models/index.js index 9b60c5d..ee3d9b3 100644 --- a/backend/models/index.js +++ b/backend/models/index.js @@ -4,7 +4,8 @@ import UserParamType from './type/user_param.js'; import Login from './logs/login.js'; import UserRightType from './type/user_right.js'; import UserRight from './community/user_right.js'; -import SettingsType from './type/settings_type.js'; +import SettingsType from './type/settings.js'; +import UserParamValue from './type/user_param_value.js'; const models = { User, @@ -14,6 +15,7 @@ const models = { UserRightType, UserRight, SettingsType, + UserParamValue, }; export default models; diff --git a/backend/models/type/settings_type.js b/backend/models/type/settings.js similarity index 74% rename from backend/models/type/settings_type.js rename to backend/models/type/settings.js index ef0442a..d4c58cd 100644 --- a/backend/models/type/settings_type.js +++ b/backend/models/type/settings.js @@ -1,7 +1,7 @@ import { sequelize } from '../../utils/sequelize.js'; import { DataTypes } from 'sequelize'; -const SettingsType = sequelize.define('settings_type', { +const Settings = sequelize.define('settings_type', { name: { type: DataTypes.STRING, allowNull: false @@ -12,4 +12,4 @@ const SettingsType = sequelize.define('settings_type', { underscored: true }); -export default SettingsType; +export default Settings; \ No newline at end of file diff --git a/backend/models/type/user_param.js b/backend/models/type/user_param.js index dce09d3..1e1081b 100644 --- a/backend/models/type/user_param.js +++ b/backend/models/type/user_param.js @@ -1,13 +1,12 @@ import { sequelize } from '../../utils/sequelize.js'; import { DataTypes } from 'sequelize'; -import SettingsType from './settings_type.js'; const UserParamType = sequelize.define('user_param_type', { description: { type: DataTypes.STRING, allowNull: false }, - minAge: { + minAge: { type: DataTypes.INTEGER, allowNull: true }, @@ -18,22 +17,20 @@ const UserParamType = sequelize.define('user_param_type', { datatype: { type: DataTypes.STRING, allowNull: false, - defaultValue: 'string' + defaultValue: 'string' }, - settingsTypeId: { + settingsId: { type: DataTypes.INTEGER, allowNull: false, references: { - model: SettingsType, + model: 'settings', key: 'id' } - }, + } }, { tableName: 'user_param', schema: 'type', underscored: true }); -UserParamType.belongsTo(SettingsType, { foreignKey: 'settingsTypeId' }); - export default UserParamType; diff --git a/backend/models/type/user_param_value.js b/backend/models/type/user_param_value.js new file mode 100644 index 0000000..6111edd --- /dev/null +++ b/backend/models/type/user_param_value.js @@ -0,0 +1,22 @@ +import { sequelize } from '../../utils/sequelize.js'; +import { DataTypes } from 'sequelize'; +import UserParam from './user_param.js'; + +const UserParamValue = sequelize.define('user_param_value', { + userParamTypeId: { + type: DataTypes.INTEGER, + allowNull: false + }, + value: { + type: DataTypes.STRING, + allowNull: false + } +}, +{ + tableName: 'user_param_value', + schema: 'type', + underscored: true +} +); + +export default UserParamValue; diff --git a/backend/models/type/user_right.js b/backend/models/type/user_right.js index 14fa4ce..4e3b00c 100644 --- a/backend/models/type/user_right.js +++ b/backend/models/type/user_right.js @@ -7,7 +7,7 @@ const UserRightType = sequelize.define('user_right_type', { allowNull: false } }, { - tableName: 'user_right', + tableName: 'user_right', schema: 'type', underscored: true }); diff --git a/backend/routers/settingsRouter.js b/backend/routers/settingsRouter.js new file mode 100644 index 0000000..39b1e5a --- /dev/null +++ b/backend/routers/settingsRouter.js @@ -0,0 +1,11 @@ +import { Router } from 'express'; +import { filterSettings, updateSetting, getTypeParamValueId, getTypeParamValues, getTypeParamValue } from '../controllers/settingsController.js'; + +const settingsRouter = Router(); +settingsRouter.post('/filter', filterSettings); +settingsRouter.post('/update', updateSetting); +settingsRouter.post('/getparamvalueid', getTypeParamValueId); +settingsRouter.post('/getparamvalues', getTypeParamValues); +settingsRouter.post('/getparamvalue/:id', getTypeParamValue); + +export default settingsRouter; diff --git a/backend/services/authService.js b/backend/services/authService.js index a68f083..8437d0b 100644 --- a/backend/services/authService.js +++ b/backend/services/authService.js @@ -12,11 +12,11 @@ const saltRounds = 10; export const registerUser = async ({ email, username, password, language }) => { const iv = generateIv(); const encryptedEmail = encrypt(email, iv); - + console.log(email, iv, process.env.SECRET_KEY); const results = await sequelize.query( - `SELECT * FROM "community"."user" WHERE public.pgp_sym_decrypt("email"::bytea, :key::text) = :email`, + `SELECT * FROM "community"."user" WHERE "email" = :email`, { - replacements: { key: process.env.SECRET_KEY, email }, + replacements: { key: process.env.SECRET_KEY, email: encryptedEmail }, type: sequelize.QueryTypes.SELECT } ); @@ -62,7 +62,6 @@ export const loginUser = async ({ username, password }) => { throw new Error('credentialsinvalid'); } const match = await bcrypt.compare(password, user.password); - console.log(match, password, user.password, await bcrypt.hash(password, saltRounds)); if (!match) { throw new Error('credentialsinvalid'); } @@ -72,12 +71,25 @@ export const loginUser = async ({ username, password }) => { }, include: { model: UserParamType, + as: 'paramType', where: { description: ['birthdate', 'gender'] } } }); - return { id: user.hashedId, username: user.username, active: user.active, forwardDataInput: neededParams.length < 2 }; + const language = await UserParam.findOne({ + where: { + userId: user.id + }, + include: { + model: UserParamType, + as: 'paramType', + where: { + description: 'language' + } + } + }); + return { id: user.hashedId, username: user.username, active: user.active, forwardDataInput: neededParams.length < 2, language: language.value }; }; export const handleForgotPassword = async ({ email }) => { diff --git a/backend/utils/encryption.js b/backend/utils/encryption.js index 2f4f17f..5f7af4c 100644 --- a/backend/utils/encryption.js +++ b/backend/utils/encryption.js @@ -1,32 +1,23 @@ 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 = () => { +export const generateIv = () => { return crypto.randomBytes(16); }; -export { encrypt, decrypt, generateIv }; +export const encrypt = (text, iv) => { + const cipher = crypto.createCipheriv(algorithm, Buffer.from(secretKey, 'utf-8'), iv); + let encrypted = cipher.update(text, 'utf8', 'hex'); + encrypted += cipher.final('hex'); + return encrypted; +}; + +export const decrypt = (text, iv) => { + console.log(text, secretKey, iv); + const decipher = crypto.createDecipheriv(algorithm, Buffer.from(secretKey, 'utf-8'), iv); + let decrypted = decipher.update(text, 'hex', 'utf8'); + decrypted += decipher.final('utf8'); + return decrypted; +}; diff --git a/backend/utils/initializeSettings.js b/backend/utils/initializeSettings.js index 29fb485..62bd924 100644 --- a/backend/utils/initializeSettings.js +++ b/backend/utils/initializeSettings.js @@ -1,4 +1,4 @@ -import SettingsType from "../models/type/settings_type.js"; +import SettingsType from "../models/type/settings.js"; const initializeSettings = async () => { await SettingsType.findOrCreate({ diff --git a/backend/utils/initializeTypes.js b/backend/utils/initializeTypes.js index 05d98bf..212ca71 100644 --- a/backend/utils/initializeTypes.js +++ b/backend/utils/initializeTypes.js @@ -1,5 +1,6 @@ import UserParamType from '../models/type/user_param.js'; -import SettingsType from '../models/type/settings_type.js'; // Importiere SettingsType +import SettingsType from '../models/type/settings.js'; +import UserParamValue from '../models/type/user_param_value.js'; const initializeTypes = async () => { const settingsTypes = await SettingsType.findAll(); @@ -9,78 +10,141 @@ const initializeTypes = async () => { }, {}); const getSettingsTypeId = (name) => settingsTypeMap[name]; + console.log(settingsTypeMap, getSettingsTypeId('personal')); + + const getUserParamTypeId = async(name) => { + const userParamType = await UserParamType.findOne({ + where: { + description: name + } + }); + return userParamType.id; + }; await UserParamType.findOrCreate({ where: { description: 'language' }, - defaults: { description: 'language', datatype: 'string', settingsTypeId: getSettingsTypeId('personal') } + defaults: { description: 'language', datatype: 'singleselect', settingsId: getSettingsTypeId('personal') } }); await UserParamType.findOrCreate({ where: { description: 'birthdate' }, - defaults: { description: 'birthdate', datatype: 'date', settingsTypeId: getSettingsTypeId('personal') } + defaults: { description: 'birthdate', datatype: 'date', settingsId: getSettingsTypeId('personal') } }); await UserParamType.findOrCreate({ where: { description: 'zip' }, - defaults: { description: 'zip', datatype: 'string', settingsTypeId: getSettingsTypeId('personal') } + defaults: { description: 'zip', datatype: 'string', settingsId: getSettingsTypeId('personal') } }); await UserParamType.findOrCreate({ where: { description: 'town' }, - defaults: { description: 'town', datatype: 'string', settingsTypeId: getSettingsTypeId('personal') } + defaults: { description: 'town', datatype: 'string', settingsId: getSettingsTypeId('personal') } }); await UserParamType.findOrCreate({ where: { description: 'bodyheight' }, - defaults: { description: 'bodyheight', datatype: 'float', settingsTypeId: getSettingsTypeId('view') } + defaults: { description: 'bodyheight', datatype: 'float', settingsId: getSettingsTypeId('view') } }); await UserParamType.findOrCreate({ where: { description: 'weight' }, - defaults: { description: 'weight', datatype: 'float', settingsTypeId: getSettingsTypeId('view') } + defaults: { description: 'weight', datatype: 'float', settingsId: getSettingsTypeId('view') } }); await UserParamType.findOrCreate({ where: { description: 'eyecolor' }, - defaults: { description: 'eyecolor', datatype: 'string', settingsTypeId: getSettingsTypeId('view') } + defaults: { description: 'eyecolor', datatype: 'string', settingsId: getSettingsTypeId('view') } }); await UserParamType.findOrCreate({ where: { description: 'haircolor' }, - defaults: { description: 'haircolor', datatype: 'string', settingsTypeId: getSettingsTypeId('view') } + defaults: { description: 'haircolor', datatype: 'string', settingsId: getSettingsTypeId('view') } }); await UserParamType.findOrCreate({ where: { description: 'hairlength' }, - defaults: { description: 'hairlength', datatype: 'int', settingsTypeId: getSettingsTypeId('view') } + defaults: { description: 'hairlength', datatype: 'int', settingsId: getSettingsTypeId('view') } }); await UserParamType.findOrCreate({ where: { description: 'skincolor' }, - defaults: { description: 'skincolor', datatype: 'int', settingsTypeId: getSettingsTypeId('view') } + defaults: { description: 'skincolor', datatype: 'int', settingsId: getSettingsTypeId('view') } }); await UserParamType.findOrCreate({ where: { description: 'freckles' }, - defaults: { description: 'freckles', datatype: 'int', settingsTypeId: getSettingsTypeId('view') } + defaults: { description: 'freckles', datatype: 'int', settingsId: getSettingsTypeId('view') } }); await UserParamType.findOrCreate({ where: { description: 'piercings' }, - defaults: { description: 'piercings', datatype: 'bool', settingsTypeId: getSettingsTypeId('view') } + defaults: { description: 'piercings', datatype: 'bool', settingsId: getSettingsTypeId('view') } }); await UserParamType.findOrCreate({ where: { description: 'tattoos' }, - defaults: { description: 'tattoos', datatype: 'bool', settingsTypeId: getSettingsTypeId('view') } + defaults: { description: 'tattoos', datatype: 'bool', settingsId: getSettingsTypeId('view') } }); await UserParamType.findOrCreate({ where: { description: 'sexualpreference' }, - defaults: { description: 'sexualpreference', minAge: 14, datatype: 'int', settingsTypeId: getSettingsTypeId('sexuality') } + defaults: { description: 'sexualpreference', minAge: 14, datatype: 'int', settingsId: getSettingsTypeId('sexuality') } }); await UserParamType.findOrCreate({ where: { description: 'gender' }, - defaults: { description: 'gender', datatype: 'string', settingsTypeId: getSettingsTypeId('personal') } + defaults: { description: 'gender', datatype: 'singleselect', settingsId: getSettingsTypeId('personal') } }); await UserParamType.findOrCreate({ where: { description: 'pubichair' }, - defaults: { description: 'pubichair', minAge: 14, datatype: 'int', settingsTypeId: getSettingsTypeId('sexuality') } + defaults: { description: 'pubichair', minAge: 14, datatype: 'int', settingsId: getSettingsTypeId('sexuality') } }); await UserParamType.findOrCreate({ where: { description: 'penislength' }, - defaults: { description: 'penislength', minAge: 14, gender: 'm', datatype: 'int', settingsTypeId: getSettingsTypeId('sexuality') } + defaults: { description: 'penislength', minAge: 14, gender: 'm', datatype: 'int', settingsId: getSettingsTypeId('sexuality') } }); await UserParamType.findOrCreate({ where: { description: 'brasize' }, - defaults: { description: 'brasize', minAge: 14, gender: 'f', datatype: 'string', settingsTypeId: getSettingsTypeId('sexuality') } + defaults: { description: 'brasize', minAge: 14, gender: 'f', datatype: 'string', settingsId: getSettingsTypeId('sexuality') } + }); + + const genderId = await getUserParamTypeId('gender'); + await UserParamValue.findOrCreate({ + where: { + userParamTypeId: genderId, + value: 'male' + }, + defaults: { userParamTypeId: genderId, value: 'male' } + }); + await UserParamValue.findOrCreate({ + where: { + userParamTypeId: genderId, + value: 'female' + }, + defaults: { userParamTypeId: genderId, value: 'female' } + }); + await UserParamValue.findOrCreate({ + where: { + userParamTypeId: genderId, + value: 'transfemale' + }, + defaults: { userParamTypeId: genderId, value: 'transfemale' } + }); + await UserParamValue.findOrCreate({ + where: { + userParamTypeId: genderId, + value: 'transmale' + }, + defaults: { userParamTypeId: genderId, value: 'transmale' } + }); + await UserParamValue.findOrCreate({ + where: { + userParamTypeId: genderId, + value: 'nonbinary' + }, + defaults: { userParamTypeId: genderId, value: 'nonbinary' } + }); + + const languageId = await getUserParamTypeId('language'); + await UserParamValue.findOrCreate({ + where: { + userParamTypeId: languageId, + value: 'de' + }, + defaults: { userParamTypeId: languageId, value: 'de' } + }); + await UserParamValue.findOrCreate({ + where: { + userParamTypeId: languageId, + value: 'en' + }, + defaults: { userParamTypeId: languageId, value: 'en' } }); }; diff --git a/backend/utils/sequelize.js b/backend/utils/sequelize.js index 363b03c..d7fa8aa 100644 --- a/backend/utils/sequelize.js +++ b/backend/utils/sequelize.js @@ -16,7 +16,7 @@ const createSchemas = async () => { await sequelize.query('CREATE SCHEMA IF NOT EXISTS logs'); await sequelize.query('CREATE SCHEMA IF NOT EXISTS type'); }; - + const initializeDatabase = async () => { await createSchemas(); const models = await import('../models/index.js'); diff --git a/backend/utils/syncDatabase.js b/backend/utils/syncDatabase.js index b7f62f4..7a87f6b 100644 --- a/backend/utils/syncDatabase.js +++ b/backend/utils/syncDatabase.js @@ -2,10 +2,19 @@ import { initializeDatabase } from './sequelize.js'; import initializeTypes from './initializeTypes.js'; import initializeSettings from './initializeSettings.js'; import initializeUserRights from './initializeUserRights.js'; +import setupAssociations from '../models/associations.js'; +import models from '../models/index.js'; const syncDatabase = async () => { try { await initializeDatabase(); + for (const model of Object.values(models)) { + await model.sync({ alter: true }); + } + setupAssociations(); + for (const model of Object.values(models)) { + await model.sync({ alter: true }); + } await initializeSettings(); await initializeTypes(); await initializeUserRights(); diff --git a/frontend/src/components/SettingsWidget.vue b/frontend/src/components/SettingsWidget.vue new file mode 100644 index 0000000..a4f5ec7 --- /dev/null +++ b/frontend/src/components/SettingsWidget.vue @@ -0,0 +1,100 @@ + + + + + diff --git a/frontend/src/components/form/CheckboxWidget.vue b/frontend/src/components/form/CheckboxWidget.vue new file mode 100644 index 0000000..2db8504 --- /dev/null +++ b/frontend/src/components/form/CheckboxWidget.vue @@ -0,0 +1,48 @@ + + + + + + + diff --git a/frontend/src/components/form/DateInputWidget.vue b/frontend/src/components/form/DateInputWidget.vue new file mode 100644 index 0000000..b37504a --- /dev/null +++ b/frontend/src/components/form/DateInputWidget.vue @@ -0,0 +1,67 @@ + + + + + + + diff --git a/frontend/src/components/form/FloatInputWidget.vue b/frontend/src/components/form/FloatInputWidget.vue new file mode 100644 index 0000000..7fb299d --- /dev/null +++ b/frontend/src/components/form/FloatInputWidget.vue @@ -0,0 +1,67 @@ + + + + + + + diff --git a/frontend/src/components/form/InputNumberWidget.vue b/frontend/src/components/form/InputNumberWidget.vue new file mode 100644 index 0000000..e90b908 --- /dev/null +++ b/frontend/src/components/form/InputNumberWidget.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/frontend/src/components/form/InputStringWidget.vue b/frontend/src/components/form/InputStringWidget.vue new file mode 100644 index 0000000..5965e43 --- /dev/null +++ b/frontend/src/components/form/InputStringWidget.vue @@ -0,0 +1,65 @@ + + + + + + + diff --git a/frontend/src/components/form/SelectDropdownWidget.vue b/frontend/src/components/form/SelectDropdownWidget.vue new file mode 100644 index 0000000..f46c249 --- /dev/null +++ b/frontend/src/components/form/SelectDropdownWidget.vue @@ -0,0 +1,69 @@ + + + + + + + diff --git a/frontend/src/dialogues/auth/RegisterDialog.vue b/frontend/src/dialogues/auth/RegisterDialog.vue index a73b216..decbf47 100644 --- a/frontend/src/dialogues/auth/RegisterDialog.vue +++ b/frontend/src/dialogues/auth/RegisterDialog.vue @@ -15,12 +15,8 @@