2 Commits

Author SHA1 Message Date
29dea2e0e8 v1.1.1
Some checks failed
Default (tags) / security (push) Successful in 26s
Default (tags) / test (push) Failing after 36s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-11-20 19:48:32 +00:00
52dc1c0549 fix(oci): Improve OCI manifest permission response and tag handling: include WWW-Authenticate header on unauthorized manifest GETs, accept optional headers in manifest lookup, and persist tags as a unified tags.json mapping when pushing manifests. 2025-11-20 19:48:32 +00:00
4 changed files with 20 additions and 8 deletions

View File

@@ -1,5 +1,13 @@
# Changelog
## 2025-11-20 - 1.1.1 - fix(oci)
Improve OCI manifest permission response and tag handling: include WWW-Authenticate header on unauthorized manifest GETs, accept optional headers in manifest lookup, and persist tags as a unified tags.json mapping when pushing manifests.
- getManifest now accepts an optional headers parameter for better request context handling.
- Unauthorized GET manifest responses now include a WWW-Authenticate header with realm/service/scope to comply with OCI auth expectations.
- PUT manifest logic no longer writes individual tag objects; it updates a consolidated oci/tags/{repository}/tags.json mapping using getTagsData and putObject.
- Simplified tag update flow when pushing a manifest: tags[reference] = digest and persist tags.json.
## 2025-11-20 - 1.1.0 - feat(oci)
Support monolithic OCI blob uploads; add registry cleanup/destroy hooks; update tests and docs

View File

@@ -1,6 +1,6 @@
{
"name": "@push.rocks/smartregistry",
"version": "1.1.0",
"version": "1.1.1",
"private": false,
"description": "a registry for npm modules and oci images",
"main": "dist_ts/index.js",

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@push.rocks/smartregistry',
version: '1.1.0',
version: '1.1.1',
description: 'a registry for npm modules and oci images'
}

View File

@@ -284,12 +284,15 @@ export class OciRegistry extends BaseRegistry {
private async getManifest(
repository: string,
reference: string,
token: IAuthToken | null
token: IAuthToken | null,
headers?: Record<string, string>
): Promise<IResponse> {
if (!await this.checkPermission(token, repository, 'pull')) {
return {
status: 401,
headers: {},
headers: {
'WWW-Authenticate': `Bearer realm="${this.basePath}/v2/token",service="registry",scope="repository:${repository}:pull"`,
},
body: this.createError('DENIED', 'Insufficient permissions'),
};
}
@@ -402,11 +405,12 @@ export class OciRegistry extends BaseRegistry {
// Store manifest by digest
await this.storage.putOciManifest(repository, digest, manifestData, contentType);
// If reference is a tag (not a digest), create tag reference
// If reference is a tag (not a digest), update tags mapping
if (!reference.startsWith('sha256:')) {
// Store tag -> digest mapping
const tagPath = `oci/repositories/${repository}/tags/${reference}`;
await this.storage.putObject(tagPath, Buffer.from(digest, 'utf-8'));
const tags = await this.getTagsData(repository);
tags[reference] = digest;
const tagsPath = `oci/tags/${repository}/tags.json`;
await this.storage.putObject(tagsPath, Buffer.from(JSON.stringify(tags), 'utf-8'));
}
return {