// @ts-check const addUsersTableToDb = require("../../backend/addUsersTableToDb"); const addDbEntry = require("../../backend/db/addDbEntry"); const updateUsersTableSchema = require("../../backend/updateUsersTableSchema"); const varDatabaseDbHandler = require("../../backend/varDatabaseDbHandler"); const hashPassword = require("../../dsql/hashPassword"); /** @type {import("../../../types").APICreateUserFunction} */ module.exports = async function apiCreateUser({ encryptionKey, payload, database, userId, useLocal, }) { const dbFullName = database; const API_USER_ID = userId || process.env.DSQL_API_USER_ID; const finalEncryptionKey = encryptionKey || process.env.DSQL_ENCRYPTION_PASSWORD; if (!finalEncryptionKey) { return { success: false, msg: "No encryption key provided", payload: null, }; } if (!finalEncryptionKey?.match(/.{8,}/)) { return { success: false, msg: "Encryption key must be at least 8 characters long", payload: null, }; } const hashedPassword = hashPassword({ encryptionKey: finalEncryptionKey, password: String(payload.password), }); payload.password = hashedPassword; const fieldsQuery = `SHOW COLUMNS FROM users`; let fields = await varDatabaseDbHandler({ queryString: fieldsQuery, database: dbFullName, useLocal, }); if (!fields?.[0]) { const newTable = await addUsersTableToDb({ userId: Number(API_USER_ID), database: dbFullName, useLocal, payload: payload, }); fields = await varDatabaseDbHandler({ queryString: fieldsQuery, database: dbFullName, useLocal, }); } if (!fields?.[0]) { return { success: false, msg: "Could not create users table", }; } const fieldsTitles = fields.map( (/** @type {any} */ fieldObject) => fieldObject.Field ); let invalidField = null; for (let i = 0; i < Object.keys(payload).length; i++) { const key = Object.keys(payload)[i]; if (!fieldsTitles.includes(key)) { await updateUsersTableSchema({ userId: Number(API_USER_ID), database: dbFullName, newPayload: { [key]: payload[key], }, }); } } if (invalidField) { return { success: false, msg: `${invalidField} is not a valid field!`, }; } const existingUserQuery = `SELECT * FROM users WHERE email = ?${ payload.username ? " OR username = ?" : "" }`; const existingUserValues = payload.username ? [payload.email, payload.username] : [payload.email]; const existingUser = await varDatabaseDbHandler({ queryString: existingUserQuery, queryValuesArray: existingUserValues, database: dbFullName, useLocal, }); if (existingUser?.[0]) { return { success: false, msg: "User Already Exists", payload: null, }; } const addUser = await addDbEntry({ dbContext: "Dsql User", paradigm: "Full Access", dbFullName: dbFullName, tableName: "users", data: { ...payload, image: "/images/user-preset.png", image_thumbnail: "/images/user-preset-thumbnail.png", }, useLocal, }); if (addUser?.insertId) { const newlyAddedUserQuery = `SELECT id,first_name,last_name,email,username,phone,image,image_thumbnail,city,state,country,zip_code,address,verification_status,more_user_data FROM users WHERE id='${addUser.insertId}'`; const newlyAddedUser = await varDatabaseDbHandler({ queryString: newlyAddedUserQuery, database: dbFullName, useLocal, }); return { success: true, payload: newlyAddedUser[0], }; } else { return { success: false, msg: "Could not create user", sqlResult: addUser, payload: null, }; } };