diff --git a/ts/manager.externalregistry/classes.externalregistry.ts b/ts/manager.externalregistry/classes.externalregistry.ts index 52c4f8c..f5f95a7 100644 --- a/ts/manager.externalregistry/classes.externalregistry.ts +++ b/ts/manager.externalregistry/classes.externalregistry.ts @@ -32,11 +32,11 @@ export class ExternalRegistry extends plugins.smartdata.SmartDataDbDoc { throw new Error(`Failed to connect: ${err.message}`); }); - if (response.status === 200 || response.status === 401) { - // 200 means successful auth, 401 means registry exists but needs auth + if (response.status === 200) { + // 200 means successful (either public or authenticated) this.data.status = 'active'; this.data.lastVerified = Date.now(); this.data.lastError = undefined; await this.save(); return { success: true, message: 'Registry connection successful' }; + } else if (response.status === 401 && this.data.authType === 'none') { + // 401 with no auth means registry exists but needs auth + throw new Error('Registry requires authentication'); + } else if (response.status === 401) { + throw new Error('Authentication failed - check credentials'); } else { throw new Error(`Registry returned status ${response.status}`); } diff --git a/ts_interfaces/data/externalregistry.ts b/ts_interfaces/data/externalregistry.ts index 84eac68..4ecbbc0 100644 --- a/ts_interfaces/data/externalregistry.ts +++ b/ts_interfaces/data/externalregistry.ts @@ -19,14 +19,14 @@ export interface IExternalRegistry { url: string; /** - * Username for authentication + * Username for authentication (optional for token-based or public registries) */ - username: string; + username?: string; /** - * Password or access token for authentication + * Password, access token, or API key for authentication (optional for public registries) */ - password: string; + password?: string; /** * Optional description @@ -41,7 +41,7 @@ export interface IExternalRegistry { /** * Authentication type */ - authType?: 'basic' | 'token' | 'oauth2'; + authType?: 'none' | 'basic' | 'token' | 'oauth2'; /** * Allow insecure registry connections (HTTP or self-signed certs) diff --git a/ts_web/elements/cloudly-view-externalregistries.ts b/ts_web/elements/cloudly-view-externalregistries.ts index aced428..3203aeb 100644 --- a/ts_web/elements/cloudly-view-externalregistries.ts +++ b/ts_web/elements/cloudly-view-externalregistries.ts @@ -90,7 +90,7 @@ export class CloudlyViewExternalRegistries extends DeesElement { Name: html`${registry.data.name}${registry.data.isDefault ? html`DEFAULT` : ''}`, Type: html`${registry.data.type.toUpperCase()}`, URL: registry.data.url, - Username: registry.data.username, + Auth: registry.data.authType === 'none' ? 'Public' : (registry.data.username || 'Token Auth'), Namespace: registry.data.namespace || '-', Status: html`${(registry.data.status || 'unverified').toUpperCase()}`, 'Last Verified': registry.data.lastVerified ? new Date(registry.data.lastVerified).toLocaleString() : 'Never', @@ -130,16 +130,14 @@ export class CloudlyViewExternalRegistries extends DeesElement { + .label=${'Username (only needed for basic auth)'} + .placeholder=${'username or leave empty for token auth'}> + .label=${'Password / Token (NPM _authToken, Docker access token, etc.)'} + .placeholder=${'Token or password'} + .isPasswordBool=${true}> + .value=${'none'}> + .label=${'Username (only needed for basic auth)'} + .value=${registry.data.username || ''} + .placeholder=${'Leave empty for token auth'}> + .value=${registry.data.authType || 'none'}>