feat(external-registry): Enhance authentication handling and update UI for external registries
This commit is contained in:
		| @@ -32,11 +32,11 @@ export class ExternalRegistry extends plugins.smartdata.SmartDataDbDoc<ExternalR | ||||
|       type: registryDataArg.type || 'docker', | ||||
|       name: registryDataArg.name || '', | ||||
|       url: registryDataArg.url || '', | ||||
|       username: registryDataArg.username || '', | ||||
|       password: registryDataArg.password || '', | ||||
|       username: registryDataArg.username, | ||||
|       password: registryDataArg.password, | ||||
|       description: registryDataArg.description, | ||||
|       isDefault: registryDataArg.isDefault || false, | ||||
|       authType: registryDataArg.authType || 'basic', | ||||
|       authType: registryDataArg.authType || (registryDataArg.username || registryDataArg.password ? 'basic' : 'none'), | ||||
|       insecure: registryDataArg.insecure || false, | ||||
|       namespace: registryDataArg.namespace, | ||||
|       proxy: registryDataArg.proxy, | ||||
| @@ -123,26 +123,38 @@ export class ExternalRegistry extends plugins.smartdata.SmartDataDbDoc<ExternalR | ||||
|       // For Docker registries, try to access the v2 API | ||||
|       if (this.data.type === 'docker') { | ||||
|         const registryUrl = this.data.url.replace(/\/$/, ''); // Remove trailing slash | ||||
|         const authHeader = 'Basic ' + Buffer.from(`${this.data.username}:${this.data.password}`).toString('base64'); | ||||
|          | ||||
|         // Build headers based on auth type | ||||
|         const headers: any = {}; | ||||
|         if (this.data.authType === 'basic' && this.data.username && this.data.password) { | ||||
|           headers['Authorization'] = 'Basic ' + Buffer.from(`${this.data.username}:${this.data.password}`).toString('base64'); | ||||
|         } else if (this.data.authType === 'token' && this.data.password) { | ||||
|           // For token auth, password field contains the token | ||||
|           headers['Authorization'] = `Bearer ${this.data.password}`; | ||||
|         } | ||||
|         // For 'none' auth type or missing credentials, no auth header is added | ||||
|          | ||||
|         // Try to access the Docker Registry v2 API | ||||
|         const response = await fetch(`${registryUrl}/v2/`, { | ||||
|           headers: { | ||||
|             'Authorization': authHeader, | ||||
|           }, | ||||
|           headers, | ||||
|           // Allow insecure if configured | ||||
|           ...(this.data.insecure ? { rejectUnauthorized: false } : {}), | ||||
|         }).catch(err => { | ||||
|           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}`); | ||||
|         } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user