Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
97 lines
3.5 KiB
JavaScript
97 lines
3.5 KiB
JavaScript
const db = require('../db');
|
|
const { requireAuth } = require('../auth');
|
|
|
|
function normalizeVaultItem(item) {
|
|
if (!item || typeof item !== 'object') {
|
|
return null;
|
|
}
|
|
var itemType = String(item.itemType || '').trim().slice(0, 64);
|
|
var itemKey = String(item.itemKey || '').trim().slice(0, 191);
|
|
var payloadCiphertext = String(item.payloadCiphertext || '').trim();
|
|
var payloadIv = String(item.payloadIv || '').trim().slice(0, 128);
|
|
var payloadTag = String(item.payloadTag || '').trim().slice(0, 128);
|
|
var payloadHash = String(item.payloadHash || '').trim().slice(0, 64);
|
|
var keyVersion = Math.max(1, Number(item.keyVersion) || 1);
|
|
|
|
if (!itemType || !itemKey || !payloadCiphertext || !payloadIv || !payloadTag || !payloadHash) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
itemType: itemType,
|
|
itemKey: itemKey,
|
|
payloadCiphertext: payloadCiphertext,
|
|
payloadIv: payloadIv,
|
|
payloadTag: payloadTag,
|
|
payloadHash: payloadHash,
|
|
keyVersion: keyVersion
|
|
};
|
|
}
|
|
|
|
async function routes(fastify) {
|
|
fastify.addHook('preHandler', requireAuth);
|
|
|
|
fastify.post('/api/vault/push', async function (request, reply) {
|
|
var items = Array.isArray(request.body && request.body.items) ? request.body.items : [];
|
|
var normalized = items.map(normalizeVaultItem).filter(Boolean);
|
|
var index = 0;
|
|
var item = null;
|
|
if (normalized.length === 0) {
|
|
reply.code(400);
|
|
return { ok: false, error: '没有可保存的保险柜项目' };
|
|
}
|
|
|
|
for (index = 0; index < normalized.length; index++) {
|
|
item = normalized[index];
|
|
await db.execute(
|
|
'INSERT INTO vault_items (user_id, item_type, item_key, payload_ciphertext, payload_iv, payload_tag, payload_hash, key_version) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE payload_ciphertext = VALUES(payload_ciphertext), payload_iv = VALUES(payload_iv), payload_tag = VALUES(payload_tag), payload_hash = VALUES(payload_hash), key_version = VALUES(key_version), updated_at = CURRENT_TIMESTAMP',
|
|
[
|
|
request.authContext.user.id,
|
|
item.itemType,
|
|
item.itemKey,
|
|
item.payloadCiphertext,
|
|
item.payloadIv,
|
|
item.payloadTag,
|
|
item.payloadHash,
|
|
item.keyVersion
|
|
]
|
|
);
|
|
}
|
|
|
|
return { ok: true, savedCount: normalized.length };
|
|
});
|
|
|
|
fastify.post('/api/vault/pull', async function (request) {
|
|
var itemTypes = Array.isArray(request.body && request.body.itemTypes) ? request.body.itemTypes.map(function (itemType) {
|
|
return String(itemType || '').trim().slice(0, 64);
|
|
}).filter(Boolean) : [];
|
|
|
|
var sql = 'SELECT item_type, item_key, payload_ciphertext, payload_iv, payload_tag, payload_hash, key_version, updated_at FROM vault_items WHERE user_id = ?';
|
|
var params = [request.authContext.user.id];
|
|
if (itemTypes.length > 0) {
|
|
sql += ' AND item_type IN (' + itemTypes.map(function () { return '?'; }).join(',') + ')';
|
|
params = params.concat(itemTypes);
|
|
}
|
|
sql += ' ORDER BY updated_at DESC';
|
|
|
|
var rows = await db.query(sql, params);
|
|
return {
|
|
ok: true,
|
|
items: rows.map(function (row) {
|
|
return {
|
|
itemType: row.item_type,
|
|
itemKey: row.item_key,
|
|
payloadCiphertext: row.payload_ciphertext,
|
|
payloadIv: row.payload_iv,
|
|
payloadTag: row.payload_tag,
|
|
payloadHash: row.payload_hash,
|
|
keyVersion: Number(row.key_version || 1),
|
|
updatedAt: row.updated_at
|
|
};
|
|
})
|
|
};
|
|
});
|
|
}
|
|
|
|
module.exports = routes;
|