codecrypto-cli 1.0.21 → 1.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -127,23 +127,210 @@ export const doctorCommand = new Command('doctor')
127
127
  });
128
128
  }
129
129
 
130
- // 6. Check Docker Hub authentication (optional)
131
- const dockerAuthCheck = ora('Checking Docker Hub authentication...').start();
130
+ // 6. Check Docker authentication
131
+ const dockerAuthCheck = ora('Checking Docker authentication...').start();
132
132
  try {
133
- execSync('docker pull hello-world:latest', { encoding: 'utf-8', stdio: 'pipe' });
134
- dockerAuthCheck.succeed('Docker Hub authentication OK');
135
- checks.push({
136
- name: 'Docker Hub Auth',
137
- status: 'success',
138
- message: 'Docker Hub authentication verified'
139
- });
140
- } catch (error) {
141
- dockerAuthCheck.warn('Docker Hub authentication may be required');
133
+ // Obtener email del token.json para comparar
134
+ const tokenFilePath = path.join(os.homedir(), '.codecrypto', 'token.json');
135
+ let tokenEmail: string | null = null;
136
+ if (fs.existsSync(tokenFilePath)) {
137
+ try {
138
+ const tokenData = JSON.parse(fs.readFileSync(tokenFilePath, 'utf-8'));
139
+ tokenEmail = tokenData.email || null;
140
+ } catch {
141
+ // Ignorar errores al leer token
142
+ }
143
+ }
144
+
145
+ // Verificar si hay credenciales guardadas en Docker config
146
+ const dockerConfigPath = path.join(os.homedir(), '.docker', 'config.json');
147
+ let dockerUsername: string | null = null;
148
+ let dockerEmail: string | null = null;
149
+ let hasDockerAuth = false;
150
+ let dockerAuthInfo = '';
151
+
152
+ if (fs.existsSync(dockerConfigPath)) {
153
+ try {
154
+ const dockerConfig = JSON.parse(fs.readFileSync(dockerConfigPath, 'utf-8'));
155
+
156
+ // Verificar si hay auths configurados
157
+ if (dockerConfig.auths && Object.keys(dockerConfig.auths).length > 0) {
158
+ hasDockerAuth = true;
159
+ const registries = Object.keys(dockerConfig.auths);
160
+ dockerAuthInfo = `Authenticated to: ${registries.join(', ')}`;
161
+
162
+ // Intentar obtener el username de Docker Hub
163
+ const dockerHubKey = registries.find(reg =>
164
+ reg.includes('docker.io') ||
165
+ reg.includes('hub.docker.com') ||
166
+ reg === 'https://index.docker.io/v1/'
167
+ );
168
+
169
+ if (dockerHubKey && dockerConfig.auths[dockerHubKey]) {
170
+ // El username puede estar en auths[registry].auth (base64) o directamente
171
+ const authData = dockerConfig.auths[dockerHubKey];
172
+ if (authData && authData.username) {
173
+ dockerUsername = authData.username;
174
+ // Si el username parece un email, usarlo como email
175
+ if (dockerUsername && dockerUsername.includes('@')) {
176
+ dockerEmail = dockerUsername;
177
+ }
178
+ }
179
+ }
180
+
181
+ // Intentar obtener username de docker info como fallback
182
+ if (!dockerUsername) {
183
+ try {
184
+ const dockerInfo = execSync('docker info', { encoding: 'utf-8', stdio: 'pipe', timeout: 5000 });
185
+ const usernameMatch = dockerInfo.match(/Username:\s*(.+)/i);
186
+ if (usernameMatch) {
187
+ dockerUsername = usernameMatch[1].trim();
188
+ if (dockerUsername.includes('@')) {
189
+ dockerEmail = dockerUsername;
190
+ }
191
+ }
192
+ } catch {
193
+ // Ignorar errores
194
+ }
195
+ }
196
+
197
+ // Verificar específicamente Docker Hub
198
+ const hasDockerHub = registries.some(reg =>
199
+ reg.includes('docker.io') ||
200
+ reg.includes('hub.docker.com') ||
201
+ reg === 'https://index.docker.io/v1/'
202
+ );
203
+
204
+ // Construir mensaje con información de email/usuario
205
+ let authMessage = `Docker authentication verified: ${dockerAuthInfo}`;
206
+ if (dockerUsername || dockerEmail) {
207
+ const dockerIdentity = dockerEmail || dockerUsername;
208
+ authMessage += ` (User: ${dockerIdentity})`;
209
+
210
+ // Comparar con token.json
211
+ if (tokenEmail && dockerEmail) {
212
+ if (dockerEmail.toLowerCase() === tokenEmail.toLowerCase()) {
213
+ authMessage += ` ✓ Matches token.json email`;
214
+ } else {
215
+ authMessage += ` ⚠ Different from token.json email (${tokenEmail})`;
216
+ }
217
+ } else if (tokenEmail && dockerUsername && !dockerEmail) {
218
+ // Comparar username con email del token (parte antes del @)
219
+ const tokenUsername = tokenEmail.split('@')[0].toLowerCase();
220
+ if (dockerUsername.toLowerCase() === tokenUsername) {
221
+ authMessage += ` ✓ Username matches token.json email`;
222
+ } else {
223
+ authMessage += ` ⚠ Username differs from token.json email (${tokenEmail})`;
224
+ }
225
+ }
226
+ }
227
+
228
+ if (hasDockerHub) {
229
+ dockerAuthCheck.succeed(`Docker authentication OK (Docker Hub configured)`);
230
+ checks.push({
231
+ name: 'Docker Auth',
232
+ status: 'success',
233
+ message: authMessage
234
+ });
235
+ } else {
236
+ dockerAuthCheck.succeed(`Docker authentication OK (${registries.length} registry/registries configured)`);
237
+ checks.push({
238
+ name: 'Docker Auth',
239
+ status: 'success',
240
+ message: authMessage
241
+ });
242
+ }
243
+ } else {
244
+ // No hay auths configurados, intentar verificar con pull
245
+ try {
246
+ execSync('docker pull hello-world:latest', { encoding: 'utf-8', stdio: 'pipe', timeout: 10000 });
247
+ dockerAuthCheck.succeed('Docker authentication OK (public access)');
248
+ let message = 'Docker can access public images (authentication may not be required)';
249
+ if (tokenEmail) {
250
+ message += ` (Token email: ${tokenEmail})`;
251
+ }
252
+ checks.push({
253
+ name: 'Docker Auth',
254
+ status: 'success',
255
+ message: message
256
+ });
257
+ } catch (pullError) {
258
+ dockerAuthCheck.warn('Docker authentication not configured');
259
+ let details = 'Run "docker login" if you need to push images to Docker Hub or private registries';
260
+ if (tokenEmail) {
261
+ details += ` (Token email: ${tokenEmail})`;
262
+ }
263
+ checks.push({
264
+ name: 'Docker Auth',
265
+ status: 'warning',
266
+ message: 'Docker authentication not configured',
267
+ details: details
268
+ });
269
+ }
270
+ }
271
+ } catch (configError) {
272
+ // Error leyendo config, intentar verificar con pull
273
+ try {
274
+ execSync('docker pull hello-world:latest', { encoding: 'utf-8', stdio: 'pipe', timeout: 10000 });
275
+ dockerAuthCheck.succeed('Docker authentication OK');
276
+ let message = 'Docker can access public images';
277
+ if (tokenEmail) {
278
+ message += ` (Token email: ${tokenEmail})`;
279
+ }
280
+ checks.push({
281
+ name: 'Docker Auth',
282
+ status: 'success',
283
+ message: message
284
+ });
285
+ } catch (pullError) {
286
+ dockerAuthCheck.warn('Docker authentication may be required');
287
+ let details = 'Run "docker login" if you need to push images';
288
+ if (tokenEmail) {
289
+ details += ` (Token email: ${tokenEmail})`;
290
+ }
291
+ checks.push({
292
+ name: 'Docker Auth',
293
+ status: 'warning',
294
+ message: 'Docker authentication not verified',
295
+ details: details
296
+ });
297
+ }
298
+ }
299
+ } else {
300
+ // No existe config.json, intentar verificar con pull
301
+ try {
302
+ execSync('docker pull hello-world:latest', { encoding: 'utf-8', stdio: 'pipe', timeout: 10000 });
303
+ dockerAuthCheck.succeed('Docker authentication OK (public access)');
304
+ let message = 'Docker can access public images (authentication may not be required)';
305
+ if (tokenEmail) {
306
+ message += ` (Token email: ${tokenEmail})`;
307
+ }
308
+ checks.push({
309
+ name: 'Docker Auth',
310
+ status: 'success',
311
+ message: message
312
+ });
313
+ } catch (error) {
314
+ dockerAuthCheck.warn('Docker authentication not configured');
315
+ let details = 'Run "docker login" if you need to push images to Docker Hub or private registries';
316
+ if (tokenEmail) {
317
+ details += ` (Token email: ${tokenEmail})`;
318
+ }
319
+ checks.push({
320
+ name: 'Docker Auth',
321
+ status: 'warning',
322
+ message: 'Docker authentication not configured',
323
+ details: details
324
+ });
325
+ }
326
+ }
327
+ } catch (error: any) {
328
+ dockerAuthCheck.fail('Docker authentication check failed');
142
329
  checks.push({
143
- name: 'Docker Hub Auth',
144
- status: 'warning',
145
- message: 'Docker Hub authentication not verified',
146
- details: 'Run "docker login" if you need to push images'
330
+ name: 'Docker Auth',
331
+ status: 'error',
332
+ message: 'Docker authentication check failed',
333
+ details: `Error: ${error.message || String(error)}`
147
334
  });
148
335
  }
149
336
 
@@ -499,11 +686,11 @@ export const doctorCommand = new Command('doctor')
499
686
  }
500
687
 
501
688
  besu1Check.succeed(`Besu1 network accessible (chain-id: ${chainId}, block: ${blockNumber})`);
502
- checks.push({
503
- name: 'Besu1 Network',
504
- status: 'success',
689
+ checks.push({
690
+ name: 'Besu1 Network',
691
+ status: 'success',
505
692
  message: `Besu1 network accessible: ${rpcUrl} (chain-id: ${chainId}, block: ${blockNumber})`
506
- });
693
+ });
507
694
  }
508
695
  } catch (error: any) {
509
696
  const errorMsg = error.message || String(error);