import generator from "generate-password"; import noDatabaseDbHandler from "../utils/noDatabaseDbHandler"; import dbHandler from "../utils/dbHandler"; import handleGrants from "./handleGrants"; import encrypt from "../../functions/dsql/encrypt"; import decrypt from "../../functions/dsql/decrypt"; import { DSQL_DATASQUIREL_MARIADB_USERS } from "../../types/dsql"; import { MariaDBUser } from "../../types"; type Param = { userId?: number | string; mariadbUserHost?: string; mariadbUsername?: string; sqlUserID?: string | number; }; /** * # Refresh Mariadb User Grants */ export default async function refreshUsersAndGrants({ userId, mariadbUserHost, mariadbUsername, sqlUserID, }: Param) { const mariadbUsers = (await dbHandler({ query: `SELECT * FROM mariadb_users`, })) as any[] | null; if (!mariadbUsers?.[0]) { return; } const isRootUser = userId ? userId == Number(process.env.DSQL_SU_USER_ID) : false; const isWildcardHost = mariadbUserHost == "%"; if (isWildcardHost && !isRootUser) { return; } for (let i = 0; i < mariadbUsers.length; i++) { const mariadbUser = mariadbUsers[i] as | DSQL_DATASQUIREL_MARIADB_USERS | undefined; if (!mariadbUser) continue; if (userId && mariadbUser.user_id != userId) continue; if (sqlUserID && mariadbUser.id != sqlUserID) continue; try { const { username, password, host, user_id } = mariadbUser; const existingUser = await noDatabaseDbHandler( `SELECT * FROM mysql.user WHERE User = '${username}' AND Host = '${host}'` ); const isUserExisting = Boolean(existingUser?.[0]?.User); const isPrimary = String(mariadbUser.primary)?.match(/1/) ? true : false; const dsqlPassword = mariadbUser?.password ? decrypt({ encryptedString: mariadbUser.password }) : isUserExisting && password ? decrypt({ encryptedString: password }) : generator.generate({ length: 16, numbers: true, symbols: true, uppercase: true, exclude: "*#.'`\"", }); const encryptedPassword = mariadbUser?.password ? mariadbUser.password : isUserExisting ? password : encrypt({ data: dsqlPassword }); if (!isUserExisting) { if (isWildcardHost) { const _existingUsers = (await noDatabaseDbHandler( `SELECT * FROM mysql.user WHERE user='${mariadbUsername}'` )) as MariaDBUser[]; for (let i = 0; i < _existingUsers.length; i++) { const exUsr = _existingUsers[i]; await noDatabaseDbHandler( `DROP USER '${exUsr.User}'@'${exUsr.Host}'` ); } } const createNewUser = await noDatabaseDbHandler( `CREATE USER IF NOT EXISTS '${mariadbUsername}'@'${mariadbUserHost}' IDENTIFIED BY '${dsqlPassword}'` ); } if (isPrimary) { const updateUser = await dbHandler({ query: `UPDATE users SET mariadb_user = ?, mariadb_host = ?, mariadb_pass = ? WHERE id = ?`, values: [ mariadbUsername, mariadbUserHost, encryptedPassword, user_id, ], }); } const isGrantHandled = await handleGrants({ username: mariadbUser.username, host: mariadbUser.host, grants: mariadbUser.grants && typeof mariadbUser.grants == "string" ? JSON.parse(mariadbUser.grants) : [], userId: String(user_id), }); if (!isGrantHandled) { console.log( `Error in handling grants for user ${mariadbUser.username}@${mariadbUser.host}` ); } } catch (error: any) { global.ERROR_CALLBACK?.( `Error Refreshing MariaDB Users and Grants`, error as Error ); } } }