mirror of
https://github.com/git-pkgs/proxy.git
synced 2026-11-09 15:49:16 -05:00
- GetProjectsUsingPackage no longer counts each project's components
per row; the package page only needs names and versions. The ?purl=
listing leaves component_count out accordingly.
- The delete button sends to DELETE /ui/api/projects/{project}, the same
handler as the API and still behind the token, so it sits under /ui
like the cache deletes.
- The project page answers 500 when its components can't be read,
instead of showing an empty project.
- DELETE of a path ending in /sbom that names no project answers 400
with a hint, since it's most likely the upload path.
- The upload endpoint lists JSON, XML and plain text (SPDX tag-value)
as accepted.
- The docs say that versions are compared as the SBOM spells them.
64 lines
2.4 KiB
JavaScript
64 lines
2.4 KiB
JavaScript
// Deleting a project needs the upload token: /ui has no authentication of its
|
|
// own, so the page sends the token the user enters with the request, the same
|
|
// as an upload. The token is kept for the browser session only.
|
|
(() => {
|
|
const root = document.getElementById('project-delete');
|
|
if (!root) {
|
|
return;
|
|
}
|
|
const start = document.getElementById('project-delete-start');
|
|
const form = document.getElementById('project-delete-form');
|
|
const input = document.getElementById('project-delete-token');
|
|
const cancel = document.getElementById('project-delete-cancel');
|
|
const errorBox = document.getElementById('project-delete-error');
|
|
const submit = form.querySelector('button[type="submit"]');
|
|
const storageKey = 'projects-token';
|
|
|
|
const show = (open) => {
|
|
start.classList.toggle('hidden', open);
|
|
form.classList.toggle('hidden', !open);
|
|
form.classList.toggle('flex', open);
|
|
errorBox.classList.add('hidden');
|
|
};
|
|
|
|
start.addEventListener('click', () => {
|
|
try {
|
|
input.value = sessionStorage.getItem(storageKey) || '';
|
|
} catch (e) {
|
|
input.value = '';
|
|
}
|
|
show(true);
|
|
input.focus();
|
|
});
|
|
cancel.addEventListener('click', () => show(false));
|
|
|
|
form.addEventListener('submit', async (event) => {
|
|
event.preventDefault();
|
|
const url = '/ui/api/projects/' + encodeURIComponent(root.dataset.project);
|
|
submit.disabled = true;
|
|
errorBox.classList.add('hidden');
|
|
try {
|
|
const resp = await fetch(url, {
|
|
method: 'DELETE',
|
|
headers: { Authorization: 'Bearer ' + input.value },
|
|
});
|
|
if (resp.status === 401) {
|
|
throw new Error('the token was rejected');
|
|
}
|
|
if (!resp.ok) {
|
|
const body = await resp.json().catch(() => ({}));
|
|
throw new Error(body.message || body.error || `HTTP ${resp.status}`);
|
|
}
|
|
try {
|
|
sessionStorage.setItem(storageKey, input.value);
|
|
} catch (e) {
|
|
// Without storage the token is just asked for again.
|
|
}
|
|
window.location.href = '/ui/projects';
|
|
} catch (err) {
|
|
errorBox.textContent = 'Delete failed: ' + err.message;
|
|
errorBox.classList.remove('hidden');
|
|
submit.disabled = false;
|
|
}
|
|
});
|
|
})();
|