import { editObject } from './database/database.js'; import { hostModel } from './database/schemas/management/host.schema.js'; import crypto from 'crypto'; import { nanoid } from 'nanoid'; import canonicalize from 'canonical-json'; import { models } from './database/schemas/models.js'; import { loadConfig } from './config.js'; const config = loadConfig(); const authCodeLength = 64; const modelList = Object.values(models) .map(model => model.model) .filter(model => model != null); export async function generateHostOTP(id) { const otp = crypto.randomInt(0, 1000000).toString().padStart(6, '0'); // 0 to 999999 const expiresAt = new Date( Date.now() + (config.otpExpiryMins || 2) * 60 * 1000 ); // 2 minutes in ms const otpHost = await editObject({ model: hostModel, id: id, updateData: { otp: otp, otpExpiresAt: expiresAt } }); return otpHost; } export function generateAuthCode() { return nanoid(authCodeLength); } export function generateEtcId() { return nanoid(24); } export function getChangedValues(oldObj, newObj, old = false) { const changes = {}; // Check all keys in the new object for (const key in newObj) { // Skip if the key is _id or timestamps if (key === '_id' || key === 'createdAt' || key === 'updatedAt') continue; const oldVal = oldObj ? oldObj[key] : undefined; const newVal = newObj[key]; // If both values are objects (but not arrays or null), recurse if ( oldVal && newVal && typeof oldVal === 'object' && typeof newVal === 'object' && !Array.isArray(oldVal) && !Array.isArray(newVal) && oldVal !== null && newVal !== null ) { const nestedChanges = this.getChangedValues(oldVal, newVal, old); if (Object.keys(nestedChanges).length > 0) { changes[key] = nestedChanges; } } else if (JSON.stringify(oldVal) !== JSON.stringify(newVal)) { // If the old value is different from the new value, include it changes[key] = old ? oldVal : newVal; } } return changes; } export function getModelByName(modelName) { return modelList.filter(model => model.modelName == modelName)[0]; } export function getQueryToCacheKey({ model, id, populate }) { const populateKey = []; for (const pop of populate) { if (typeof pop === 'string') { populateKey.push(pop); } else if (typeof pop === 'object') { populateKey.push(pop.path); } } return `${model}:${id?.toString()}-${populateKey.join(',')}`; }