feat(template): support managed template repository layout#6999
feat(template): support managed template repository layout#6999mlhiter wants to merge 6 commits into
Conversation
|
|
||
| const originalPath = process.cwd(); | ||
| const jsonPath = path.resolve(originalPath, 'templates.json'); | ||
| const result = readTemplateAssetFile({ jsonPath, templateName, assetUrl: asset }); |
There was a problem hiding this comment.
This makes the new public asset endpoint a generic file reader for the cloned template repository. asset comes directly from the query string and is only constrained later to stay under templates/, so an unauthenticated caller can request files that were never declared as this template’s README/icon, for example enough ../ segments to reach templates/.git/config or /config/categories.json. In private/offline repo deployments this can leak repo config, unpublished templates, and other non-asset files. Please authorize the asset against the template’s declared spec.readme/spec.icon/i18n assets, and only serve derived README images from an explicit allowlist of safe locations/extensions.
| function assertInRepo(repoRootPath: string, targetPath: string) { | ||
| const root = path.resolve(repoRootPath); | ||
| const target = path.resolve(targetPath); | ||
| if (target !== root && !target.startsWith(`${root}${path.sep}`)) { |
There was a problem hiding this comment.
This boundary check is path-string based, so it does not protect against symlinks inside the template repository. A repo entry such as template/foo/leak.txt -> /etc/passwd still resolves under templates/ here, but fs.readFileSync() follows the symlink and returns the target outside the repo. The split-manifest reader has the same shape when reading files from manifests/. Please validate real paths before reading and reject symlinks, or use lstat plus a realpath repo-root check and only allow regular files.
| clearTemplateRuntimeCaches(); | ||
| } | ||
|
|
||
| export async function ensureRepoFresh({ force = false }: { force?: boolean } = {}) { |
There was a problem hiding this comment.
Moving repo refresh from the existing background cron into ensureRepoFresh() changes the freshness model in a problematic way. With no traffic the catalog no longer updates in the background, and every read path now has to remember to call this helper before touching templates.json; any new or existing endpoint that misses it will silently serve stale data. It also puts git pull on the user request path whenever the TTL expires. Please keep a single background refresh mechanism (or another centralized scheduler) and let read handlers only read the current catalog/cache, instead of making each API endpoint responsible for repository synchronization.
What this PR does
This PR adds Template App support for the managed template repository layout produced by Sealos Admin.
config/categories.jsonin the cloned template repository, with the existing env fallback kept server-side./api/templateAssetso private or offline stores do not depend on public raw URLs.template/<name>/index.yamlplustemplate/<name>/manifests/*.yamlwhile keeping legacy single-file templates compatible.Why this is needed
The paired Admin template-management flow writes templates, categories, README files, icons, and manifests into an internal Git/Gogs repository. Template App needs to consume that same repository format for the store and deploy flows.
Test
pnpm -C frontend/providers/template buildNote: the build completed successfully with existing React Hook lint warnings.