feat: harden plugin api for separate repos, signed updates and generic external login

This commit is contained in:
LukeGus committed 2026-09-29 18:11:59 -05:00
1 parent fb9c168b6b
commit 80944301dd
310 files changed
+6577 -4927

No files matched your search

+24 -6
View File
@@ -93,12 +93,7 @@ export function describePluginFrontend(
const entry = frontendEntry(plugin);
if (!entry || !fileExists(entry.file)) return { ...none, locales };
const stat = fs.statSync(entry.file);
const assetVersion = crypto
.createHash("sha256")
.update(`${plugin.manifest.version}:${stat.size}:${stat.mtimeMs}`)
.digest("hex")
.slice(0, 12);
const assetVersion = contentVersion(entry.file, plugin.manifest.version);
return {
frontend: true,
@@ -108,6 +103,29 @@ export function describePluginFrontend(
};
}
const versionCache = new Map<string, { stamp: string; version: string }>();
/**
* A hash of the bundle's bytes, not its mtime: assets are cached as immutable
* for a year, and a rebuilt .tmxplug has a fixed mtime, so a same-size rebuild
* would otherwise keep serving the stale copy.
*/
function contentVersion(file: string, version: string): string {
const stat = fs.statSync(file);
// ctime, unlike mtime, cannot be set by tar, so an unpack always changes it.
const stamp = `${version}:${stat.size}:${stat.mtimeMs}:${stat.ctimeMs}`;
const cached = versionCache.get(file);
if (cached?.stamp === stamp) return cached.version;
const hashed = crypto
.createHash("sha256")
.update(version)
.update(fs.readFileSync(file))
.digest("hex")
.slice(0, 12);
versionCache.set(file, { stamp, version: hashed });
return hashed;
}
/**
* Maps a request path under /plugin-assets/<id>/ to a file, or null.
*