farmcontrol-ws/src/utils.js

110 lines
3.5 KiB
JavaScript

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 { loadConfig } from './config.js';
import { userModel } from './database/schemas/management/user.schema.js';
import { documentSizeModel } from './database/schemas/management/documentsize.schema.js';
import { documentJobModel } from './database/schemas/management/documentjob.schema.js';
import { documentTemplateModel } from './database/schemas/management/documenttemplate.schema.js';
import { documentPrinterModel } from './database/schemas/management/documentprinter.schema.js';
import { printerModel } from './database/schemas/production/printer.schema.js';
import { subJobModel } from './database/schemas/production/subjob.schema.js';
import { jobModel } from './database/schemas/production/job.schema.js';
import { filamentStockModel } from './database/schemas/inventory/filamentstock.schema.js';
import { fileModel } from './database/schemas/management/file.schema.js';
import { gcodeFileModel } from './database/schemas/production/gcodefile.schema.js';
import { stockEventModel } from './database/schemas/inventory/stockevent.schema.js';
import { filamentModel } from './database/schemas/management/filament.schema.js';
const config = loadConfig();
const authCodeLength = 64;
const modelList = [
hostModel,
userModel,
documentSizeModel,
documentJobModel,
documentTemplateModel,
documentPrinterModel,
printerModel,
jobModel,
subJobModel,
fileModel,
gcodeFileModel,
filamentStockModel,
stockEventModel,
filamentModel
];
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 jsonToCacheKey(obj) {
const normalized = canonicalize(obj);
const hash = crypto.createHash('sha256').update(normalized).digest('hex');
return hash;
}