mirror of
https://github.com/git-pkgs/proxy.git
synced 2026-07-06 14:23:20 -04:00
* Mount web UI under /ui (closes #123) The UI now lives under /ui so reverse proxies can apply different access rules to it (e.g. require auth) while leaving the package endpoints (/npm, /pypi, /v2, ...) open to build machines. - GET / redirects to /ui/ - /api/browse and /api/compare move to /ui/api/browse and /ui/api/compare since only the browser JS calls them - /health, /stats, /metrics, /openapi.json and /api/* stay at root * README: nginx example for splitting UI auth from package endpoints The /ui prefix lets a reverse proxy apply different access rules to the web UI than to the package endpoints. Adds the snippet that motivated the prefix change so deployers don't have to derive it.
128 lines
8.6 KiB
HTML
128 lines
8.6 KiB
HTML
{{define "title"}}git-pkgs proxy{{end}}
|
|
|
|
{{define "content"}}
|
|
<!-- Stats Grid -->
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-8">
|
|
<div class="bg-white dark:bg-gray-900 rounded-xl p-6 shadow-sm border border-gray-200 dark:border-gray-800">
|
|
<div class="text-sm text-gray-500 dark:text-gray-400">Cached Artifacts</div>
|
|
<div class="text-3xl font-bold mt-1">{{.Stats.CachedArtifacts}}</div>
|
|
</div>
|
|
<div class="bg-white dark:bg-gray-900 rounded-xl p-6 shadow-sm border border-gray-200 dark:border-gray-800">
|
|
<div class="text-sm text-gray-500 dark:text-gray-400">Total Size</div>
|
|
<div class="text-3xl font-bold mt-1">{{.Stats.TotalSize}}</div>
|
|
</div>
|
|
<div class="bg-white dark:bg-gray-900 rounded-xl p-6 shadow-sm border border-gray-200 dark:border-gray-800">
|
|
<div class="text-sm text-gray-500 dark:text-gray-400">Packages</div>
|
|
<div class="text-3xl font-bold mt-1">{{.Stats.TotalPackages}}</div>
|
|
</div>
|
|
<div class="bg-white dark:bg-gray-900 rounded-xl p-6 shadow-sm border border-gray-200 dark:border-gray-800">
|
|
<div class="text-sm text-gray-500 dark:text-gray-400">Versions</div>
|
|
<div class="text-3xl font-bold mt-1">{{.Stats.TotalVersions}}</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{if .EnrichmentStats.HasVulns}}
|
|
<!-- Security Overview -->
|
|
<div class="bg-white dark:bg-gray-900 rounded-xl shadow-sm border border-gray-200 dark:border-gray-800 mb-8">
|
|
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-800">
|
|
<h2 class="text-lg font-semibold">Security Overview</h2>
|
|
</div>
|
|
<div class="p-6">
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
<div class="text-center p-4 rounded-lg bg-red-50 dark:bg-red-950 border border-red-200 dark:border-red-900">
|
|
<div class="text-2xl font-bold text-red-600 dark:text-red-400">{{.EnrichmentStats.CriticalVulns}}</div>
|
|
<div class="text-xs text-red-600 dark:text-red-400 uppercase font-medium">Critical</div>
|
|
</div>
|
|
<div class="text-center p-4 rounded-lg bg-orange-50 dark:bg-orange-950 border border-orange-200 dark:border-orange-900">
|
|
<div class="text-2xl font-bold text-orange-600 dark:text-orange-400">{{.EnrichmentStats.HighVulns}}</div>
|
|
<div class="text-xs text-orange-600 dark:text-orange-400 uppercase font-medium">High</div>
|
|
</div>
|
|
<div class="text-center p-4 rounded-lg bg-yellow-50 dark:bg-yellow-950 border border-yellow-200 dark:border-yellow-900">
|
|
<div class="text-2xl font-bold text-yellow-600 dark:text-yellow-400">{{.EnrichmentStats.MediumVulns}}</div>
|
|
<div class="text-xs text-yellow-600 dark:text-yellow-400 uppercase font-medium">Medium</div>
|
|
</div>
|
|
<div class="text-center p-4 rounded-lg bg-green-50 dark:bg-green-950 border border-green-200 dark:border-green-900">
|
|
<div class="text-2xl font-bold text-green-600 dark:text-green-400">{{.EnrichmentStats.LowVulns}}</div>
|
|
<div class="text-xs text-green-600 dark:text-green-400 uppercase font-medium">Low</div>
|
|
</div>
|
|
</div>
|
|
<p class="mt-4 text-sm text-gray-500 dark:text-gray-400">
|
|
{{.EnrichmentStats.TotalVulnerabilities}} vulnerabilities tracked across {{.EnrichmentStats.VulnSyncedPackages}} packages
|
|
</p>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
<!-- Two Column Layout -->
|
|
<div class="grid md:grid-cols-2 gap-8 mb-8">
|
|
<!-- Popular Packages -->
|
|
<div class="bg-white dark:bg-gray-900 rounded-xl shadow-sm border border-gray-200 dark:border-gray-800">
|
|
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-800">
|
|
<h2 class="text-lg font-semibold">Popular Packages</h2>
|
|
</div>
|
|
<div class="divide-y divide-gray-200 dark:divide-gray-800">
|
|
{{if .PopularPackages}}
|
|
{{range .PopularPackages}}
|
|
<div class="px-6 py-4 flex items-center justify-between">
|
|
<div class="min-w-0 flex-1">
|
|
<div class="flex items-center gap-2">
|
|
{{template "ecosystem_badge" .Ecosystem}}
|
|
<a href="/ui/package/{{.Ecosystem}}/{{.Name}}" class="font-medium truncate hover:text-blue-600 dark:hover:text-blue-400">{{.Name}}</a>
|
|
</div>
|
|
<div class="flex items-center gap-2 mt-1">
|
|
{{if .License}}<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-{{if eq .LicenseCategory "permissive"}}green{{else if eq .LicenseCategory "copyleft"}}pink{{else}}gray{{end}}-100 text-{{if eq .LicenseCategory "permissive"}}green{{else if eq .LicenseCategory "copyleft"}}pink{{else}}gray{{end}}-700 dark:bg-{{if eq .LicenseCategory "permissive"}}green{{else if eq .LicenseCategory "copyleft"}}pink{{else}}gray{{end}}-900 dark:text-{{if eq .LicenseCategory "permissive"}}green{{else if eq .LicenseCategory "copyleft"}}pink{{else}}gray{{end}}-300">{{.License}}</span>{{end}}
|
|
{{if .VulnCount}}<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-700 dark:bg-red-900 dark:text-red-300">{{.VulnCount}} vulns</span>{{end}}
|
|
</div>
|
|
</div>
|
|
<div class="flex items-center gap-4 text-sm text-gray-500 dark:text-gray-400">
|
|
<span>{{.Hits}} cache hits</span>
|
|
<span>{{.Size}}</span>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
<div class="px-6 py-3 text-center border-t border-gray-200 dark:border-gray-800">
|
|
<a href="/ui/packages?sort=hits" class="text-sm text-blue-600 dark:text-blue-400 hover:underline">See all packages →</a>
|
|
</div>
|
|
{{else}}
|
|
<div class="px-6 py-12 text-center text-gray-500 dark:text-gray-400">No packages cached yet</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Recently Cached -->
|
|
<div class="bg-white dark:bg-gray-900 rounded-xl shadow-sm border border-gray-200 dark:border-gray-800">
|
|
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-800">
|
|
<h2 class="text-lg font-semibold">Recently Cached</h2>
|
|
</div>
|
|
<div class="divide-y divide-gray-200 dark:divide-gray-800">
|
|
{{if .RecentPackages}}
|
|
{{range .RecentPackages}}
|
|
<div class="px-6 py-4 flex items-center justify-between">
|
|
<div class="min-w-0 flex-1">
|
|
<div class="flex items-center gap-2">
|
|
{{template "ecosystem_badge" .Ecosystem}}
|
|
<a href="/ui/package/{{.Ecosystem}}/{{.Name}}" class="font-medium truncate hover:text-blue-600 dark:hover:text-blue-400">{{.Name}}</a>
|
|
<span class="text-gray-500 dark:text-gray-400">@{{.Version}}</span>
|
|
</div>
|
|
<div class="flex items-center gap-2 mt-1">
|
|
{{if .License}}<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-{{if eq .LicenseCategory "permissive"}}green{{else if eq .LicenseCategory "copyleft"}}pink{{else}}gray{{end}}-100 text-{{if eq .LicenseCategory "permissive"}}green{{else if eq .LicenseCategory "copyleft"}}pink{{else}}gray{{end}}-700 dark:bg-{{if eq .LicenseCategory "permissive"}}green{{else if eq .LicenseCategory "copyleft"}}pink{{else}}gray{{end}}-900 dark:text-{{if eq .LicenseCategory "permissive"}}green{{else if eq .LicenseCategory "copyleft"}}pink{{else}}gray{{end}}-300">{{.License}}</span>{{end}}
|
|
{{if .IsOutdated}}<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300">outdated</span>{{end}}
|
|
{{if .VulnCount}}<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-700 dark:bg-red-900 dark:text-red-300">{{.VulnCount}} vulns</span>{{end}}
|
|
</div>
|
|
</div>
|
|
<div class="flex items-center gap-4 text-sm text-gray-500 dark:text-gray-400">
|
|
<span>{{.CachedAt}}</span>
|
|
<span>{{.Size}}</span>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
<div class="px-6 py-3 text-center border-t border-gray-200 dark:border-gray-800">
|
|
<a href="/ui/packages?sort=cached_at" class="text-sm text-blue-600 dark:text-blue-400 hover:underline">See all packages →</a>
|
|
</div>
|
|
{{else}}
|
|
<div class="px-6 py-12 text-center text-gray-500 dark:text-gray-400">No packages cached yet</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{end}}
|