Vendoo 1.43.0 – Production Update

Manifestbasierter Production-Updater 3.3, Modulnavigation, optionales Produktbild Studio, Listing-Studio-Aktionsleiste sowie plattformübergreifende Windows-/Linux-Release-Gates.
This commit was merged in pull request #26.
This commit is contained in:
Masterluke77
2026-07-10 13:16:21 +02:00
committed by GitHub
parent 6f48827f4d
commit 40071f718e
127 changed files with 9576 additions and 581 deletions
+32
View File
@@ -296,6 +296,38 @@ export function validateAuthToken(token) {
return row;
}
export function listInvitations(limit = 100) {
const safeLimit = Math.max(1, Math.min(500, Number(limit) || 100));
return db.prepare(`SELECT id, email, role, used, expires_at, created_by, created_at,
CASE
WHEN used = 1 THEN 'revoked_or_used'
WHEN expires_at <= datetime('now') THEN 'expired'
ELSE 'pending'
END AS status
FROM auth_tokens
WHERE type = 'invite'
ORDER BY created_at DESC
LIMIT ?`).all(safeLimit);
}
export function getInvitation(id) {
return db.prepare(`SELECT id, email, role, used, expires_at, created_by, created_at,
CASE
WHEN used = 1 THEN 'revoked_or_used'
WHEN expires_at <= datetime('now') THEN 'expired'
ELSE 'pending'
END AS status
FROM auth_tokens WHERE id = ? AND type = 'invite'`).get(Number(id));
}
export function revokeInvitation(id) {
const invitation = getInvitation(id);
if (!invitation) return null;
if (invitation.status === 'pending') db.prepare('UPDATE auth_tokens SET used = 1 WHERE id = ? AND type = ?').run(Number(id), 'invite');
return { ...invitation, status: invitation.status === 'pending' ? 'revoked' : invitation.status, used: 1 };
}
// --- Rate Limiting ---
const rateLimits = new Map();
+5 -1
View File
@@ -163,7 +163,11 @@ export function buildModulePackage({ manifest, runtime = { mode: 'builtin-refere
const buffer = Buffer.isBuffer(file.content) ? file.content : Buffer.from(String(file.content || ''), 'utf8');
return { path, sha256: sha256(buffer), size: buffer.length, content: buffer.toString('base64') };
});
const draft = { format: MODULE_PACKAGE_FORMAT, schemaVersion: MODULE_PACKAGE_SCHEMA, manifest, runtime, files: normalizedFiles, createdAt, integrity: { algorithm: 'sha256', digest: '' }, signature: null };
// Der Digest muss auf demselben normalisierten Manifest basieren wie die spätere
// Validierung. Sonst würden additive Manifest-Defaults (z. B. defaultEnabled)
// den Digest nachträglich verändern.
const normalizedManifest = validateModuleManifest(manifest);
const draft = { format: MODULE_PACKAGE_FORMAT, schemaVersion: MODULE_PACKAGE_SCHEMA, manifest: normalizedManifest, runtime, files: normalizedFiles, createdAt, integrity: { algorithm: 'sha256', digest: '' }, signature: null };
draft.integrity.digest = calculatePackageDigest(draft);
return validateModulePackage(draft, { allowBuiltinReference: true });
}