142 lines
4.5 KiB
JavaScript
142 lines
4.5 KiB
JavaScript
import { db, id, now, visibleClause } from '../db.js';
|
|
import { customVariableSchema } from '../forms/schemas.js';
|
|
import { fullVariableCatalog } from '../data/variableCatalog.js';
|
|
import { decryptSecret, encryptSecret } from '../services/cryptoStore.js';
|
|
import { camelCustomVariable } from './mappers.js';
|
|
|
|
function normalizeVariable(body, existing = {}) {
|
|
const parsed = customVariableSchema.parse({ ...existing, ...body });
|
|
return {
|
|
...parsed,
|
|
sensitive: Boolean(parsed.sensitive),
|
|
groupId: parsed.visibility === 'group' ? parsed.groupId || null : null
|
|
};
|
|
}
|
|
|
|
function visibleCustomVariableRows(userId) {
|
|
return db.prepare(`
|
|
SELECT v.*, g.name AS group_name
|
|
FROM custom_variables v
|
|
LEFT JOIN groups g ON g.id = v.group_id
|
|
WHERE ${visibleClause('v')}
|
|
ORDER BY v.category, v.name
|
|
`).all(userId, userId);
|
|
}
|
|
|
|
export function listVariableCatalog(userId) {
|
|
const catalog = fullVariableCatalog();
|
|
return {
|
|
...catalog,
|
|
custom: visibleCustomVariableRows(userId).map((row) => {
|
|
const includeValue = !Boolean(row.sensitive);
|
|
const value = includeValue ? decryptSecret(row) : undefined;
|
|
return camelCustomVariable({ ...row, value }, includeValue);
|
|
})
|
|
};
|
|
}
|
|
|
|
export function listCustomVariables(userId) {
|
|
return visibleCustomVariableRows(userId).map((row) => {
|
|
const includeValue = !Boolean(row.sensitive);
|
|
const value = includeValue ? decryptSecret(row) : undefined;
|
|
return camelCustomVariable({ ...row, value }, includeValue);
|
|
});
|
|
}
|
|
|
|
export function listExecutableCustomVariables(userId) {
|
|
return visibleCustomVariableRows(userId).map((row) => ({
|
|
id: row.id,
|
|
name: row.name,
|
|
value: decryptSecret(row),
|
|
valueType: row.value_type || 'string',
|
|
sensitive: Boolean(row.sensitive)
|
|
}));
|
|
}
|
|
|
|
export function createCustomVariable(body, userId) {
|
|
const payload = normalizeVariable(body);
|
|
const encrypted = encryptSecret(payload.value);
|
|
const variableId = id('var');
|
|
db.prepare(`
|
|
INSERT INTO custom_variables (
|
|
id, name, description, category, value_type, secret_cipher, secret_iv, secret_tag,
|
|
sensitive, visibility, owner_user_id, group_id, created_by, created_at, updated_at
|
|
)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
`).run(
|
|
variableId,
|
|
payload.name,
|
|
payload.description,
|
|
payload.category,
|
|
payload.valueType,
|
|
encrypted.cipher,
|
|
encrypted.iv,
|
|
encrypted.tag,
|
|
payload.sensitive ? 1 : 0,
|
|
payload.visibility,
|
|
userId,
|
|
payload.groupId,
|
|
userId,
|
|
now(),
|
|
now()
|
|
);
|
|
return loadCustomVariable(variableId, userId);
|
|
}
|
|
|
|
export function loadCustomVariable(variableId, userId) {
|
|
const row = db.prepare(`
|
|
SELECT v.*, g.name AS group_name
|
|
FROM custom_variables v
|
|
LEFT JOIN groups g ON g.id = v.group_id
|
|
WHERE v.id = ? AND ${visibleClause('v')}
|
|
`).get(variableId, userId, userId);
|
|
if (!row) return null;
|
|
const includeValue = !Boolean(row.sensitive);
|
|
const value = includeValue ? decryptSecret(row) : undefined;
|
|
return camelCustomVariable({ ...row, value }, includeValue);
|
|
}
|
|
|
|
export function updateCustomVariable(variableId, body, userId) {
|
|
const existing = db.prepare(`SELECT * FROM custom_variables WHERE id = ? AND ${visibleClause()}`).get(variableId, userId, userId);
|
|
if (!existing) return null;
|
|
const payload = normalizeVariable(body, {
|
|
name: existing.name,
|
|
description: existing.description || '',
|
|
category: existing.category || 'Custom',
|
|
value: body.value ?? decryptSecret(existing),
|
|
valueType: existing.value_type || 'string',
|
|
sensitive: Boolean(existing.sensitive),
|
|
visibility: existing.visibility,
|
|
groupId: existing.group_id
|
|
});
|
|
const encrypted = body.value === undefined ? {
|
|
cipher: existing.secret_cipher,
|
|
iv: existing.secret_iv,
|
|
tag: existing.secret_tag
|
|
} : encryptSecret(payload.value);
|
|
db.prepare(`
|
|
UPDATE custom_variables
|
|
SET name = ?, description = ?, category = ?, value_type = ?, secret_cipher = ?, secret_iv = ?,
|
|
secret_tag = ?, sensitive = ?, visibility = ?, group_id = ?, updated_at = ?
|
|
WHERE id = ?
|
|
`).run(
|
|
payload.name,
|
|
payload.description,
|
|
payload.category,
|
|
payload.valueType,
|
|
encrypted.cipher,
|
|
encrypted.iv,
|
|
encrypted.tag,
|
|
payload.sensitive ? 1 : 0,
|
|
payload.visibility,
|
|
payload.groupId,
|
|
now(),
|
|
variableId
|
|
);
|
|
return loadCustomVariable(variableId, userId);
|
|
}
|
|
|
|
export function deleteCustomVariable(variableId, userId) {
|
|
db.prepare(`DELETE FROM custom_variables WHERE id = ? AND ${visibleClause()}`).run(variableId, userId, userId);
|
|
}
|