From 659d816a3157c2b7bce31af8fca720b549927f4f Mon Sep 17 00:00:00 2001 From: IISweetHeartII Date: Mon, 2 Feb 2026 22:33:01 +0900 Subject: [PATCH] fix: use www.clawhub.ai as default registry to prevent auth header stripping on redirect (#100) clawhub.ai redirects to www.clawhub.ai via 307, which strips the Authorization header per standard cross-origin HTTP security rules. This causes all authenticated CLI commands to fail with 'Unauthorized'. Update DEFAULT_SITE and DEFAULT_REGISTRY to https://www.clawhub.ai and align .well-known/clawhub.json discovery endpoints accordingly. Also fixes #41, #72, #99. --- e2e/clawdhub.e2e.test.ts | 4 ++-- packages/clawdhub/src/cli/commands/delete.test.ts | 8 ++++---- packages/clawdhub/src/cli/commands/inspect.test.ts | 6 +++--- packages/clawdhub/src/cli/commands/moderation.test.ts | 8 ++++---- packages/clawdhub/src/cli/commands/publish.test.ts | 8 ++++---- packages/clawdhub/src/cli/commands/skills.test.ts | 6 +++--- packages/clawdhub/src/cli/commands/sync.test.ts | 8 ++++---- packages/clawdhub/src/cli/registry.test.ts | 10 +++++----- packages/clawdhub/src/cli/registry.ts | 4 ++-- public/.well-known/clawhub.json | 6 +++--- 10 files changed, 34 insertions(+), 34 deletions(-) diff --git a/e2e/clawdhub.e2e.test.ts b/e2e/clawdhub.e2e.test.ts index d5ed667..49445b6 100644 --- a/e2e/clawdhub.e2e.test.ts +++ b/e2e/clawdhub.e2e.test.ts @@ -38,13 +38,13 @@ function getRegistry() { return ( process.env.CLAWHUB_REGISTRY?.trim() || process.env.CLAWDHUB_REGISTRY?.trim() || - 'https://clawhub.ai' + 'https://www.clawhub.ai' ) } function getSite() { return ( - process.env.CLAWHUB_SITE?.trim() || process.env.CLAWDHUB_SITE?.trim() || 'https://clawhub.ai' + process.env.CLAWHUB_SITE?.trim() || process.env.CLAWDHUB_SITE?.trim() || 'https://www.clawhub.ai' ) } diff --git a/packages/clawdhub/src/cli/commands/delete.test.ts b/packages/clawdhub/src/cli/commands/delete.test.ts index 259db5a..715b20a 100644 --- a/packages/clawdhub/src/cli/commands/delete.test.ts +++ b/packages/clawdhub/src/cli/commands/delete.test.ts @@ -4,11 +4,11 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import type { GlobalOpts } from '../types' vi.mock('../../config.js', () => ({ - readGlobalConfig: vi.fn(async () => ({ registry: 'https://clawhub.ai', token: 'tkn' })), + readGlobalConfig: vi.fn(async () => ({ registry: 'https://www.clawhub.ai', token: 'tkn' })), })) vi.mock('../registry.js', () => ({ - getRegistry: vi.fn(async () => 'https://clawhub.ai'), + getRegistry: vi.fn(async () => 'https://www.clawhub.ai'), })) const mockApiRequest = vi.fn() @@ -35,8 +35,8 @@ function makeOpts(): GlobalOpts { return { workdir: '/work', dir: '/work/skills', - site: 'https://clawhub.ai', - registry: 'https://clawhub.ai', + site: 'https://www.clawhub.ai', + registry: 'https://www.clawhub.ai', registrySource: 'default', } } diff --git a/packages/clawdhub/src/cli/commands/inspect.test.ts b/packages/clawdhub/src/cli/commands/inspect.test.ts index d0d2616..3722980 100644 --- a/packages/clawdhub/src/cli/commands/inspect.test.ts +++ b/packages/clawdhub/src/cli/commands/inspect.test.ts @@ -11,7 +11,7 @@ vi.mock('../../http.js', () => ({ fetchText: (...args: unknown[]) => mockFetchText(...args), })) -const mockGetRegistry = vi.fn(async () => 'https://clawhub.ai') +const mockGetRegistry = vi.fn(async () => 'https://www.clawhub.ai') vi.mock('../registry.js', () => ({ getRegistry: () => mockGetRegistry(), })) @@ -41,8 +41,8 @@ function makeOpts(): GlobalOpts { return { workdir: '/work', dir: '/work/skills', - site: 'https://clawhub.ai', - registry: 'https://clawhub.ai', + site: 'https://www.clawhub.ai', + registry: 'https://www.clawhub.ai', registrySource: 'default', } } diff --git a/packages/clawdhub/src/cli/commands/moderation.test.ts b/packages/clawdhub/src/cli/commands/moderation.test.ts index da32988..bc7a795 100644 --- a/packages/clawdhub/src/cli/commands/moderation.test.ts +++ b/packages/clawdhub/src/cli/commands/moderation.test.ts @@ -4,11 +4,11 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import type { GlobalOpts } from '../types' vi.mock('../../config.js', () => ({ - readGlobalConfig: vi.fn(async () => ({ registry: 'https://clawhub.ai', token: 'tkn' })), + readGlobalConfig: vi.fn(async () => ({ registry: 'https://www.clawhub.ai', token: 'tkn' })), })) vi.mock('../registry.js', () => ({ - getRegistry: vi.fn(async () => 'https://clawhub.ai'), + getRegistry: vi.fn(async () => 'https://www.clawhub.ai'), })) const mockApiRequest = vi.fn() @@ -33,8 +33,8 @@ function makeOpts(): GlobalOpts { return { workdir: '/work', dir: '/work/skills', - site: 'https://clawhub.ai', - registry: 'https://clawhub.ai', + site: 'https://www.clawhub.ai', + registry: 'https://www.clawhub.ai', registrySource: 'default', } } diff --git a/packages/clawdhub/src/cli/commands/publish.test.ts b/packages/clawdhub/src/cli/commands/publish.test.ts index a583e03..b2d2092 100644 --- a/packages/clawdhub/src/cli/commands/publish.test.ts +++ b/packages/clawdhub/src/cli/commands/publish.test.ts @@ -7,10 +7,10 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import type { GlobalOpts } from '../types' vi.mock('../../config.js', () => ({ - readGlobalConfig: vi.fn(async () => ({ registry: 'https://clawhub.ai', token: 'tkn' })), + readGlobalConfig: vi.fn(async () => ({ registry: 'https://www.clawhub.ai', token: 'tkn' })), })) -const mockGetRegistry = vi.fn(async (_opts: unknown, _params?: unknown) => 'https://clawhub.ai') +const mockGetRegistry = vi.fn(async (_opts: unknown, _params?: unknown) => 'https://www.clawhub.ai') vi.mock('../registry.js', () => ({ getRegistry: (opts: unknown, params?: unknown) => mockGetRegistry(opts, params), })) @@ -42,8 +42,8 @@ function makeOpts(workdir: string): GlobalOpts { return { workdir, dir: join(workdir, 'skills'), - site: 'https://clawhub.ai', - registry: 'https://clawhub.ai', + site: 'https://www.clawhub.ai', + registry: 'https://www.clawhub.ai', registrySource: 'default', } } diff --git a/packages/clawdhub/src/cli/commands/skills.test.ts b/packages/clawdhub/src/cli/commands/skills.test.ts index c124f2b..40a5c4a 100644 --- a/packages/clawdhub/src/cli/commands/skills.test.ts +++ b/packages/clawdhub/src/cli/commands/skills.test.ts @@ -11,7 +11,7 @@ vi.mock('../../http.js', () => ({ downloadZip: (...args: unknown[]) => mockDownloadZip(...args), })) -const mockGetRegistry = vi.fn(async () => 'https://clawhub.ai') +const mockGetRegistry = vi.fn(async () => 'https://www.clawhub.ai') vi.mock('../registry.js', () => ({ getRegistry: () => mockGetRegistry(), })) @@ -68,8 +68,8 @@ function makeOpts(): GlobalOpts { return { workdir: '/work', dir: '/work/skills', - site: 'https://clawhub.ai', - registry: 'https://clawhub.ai', + site: 'https://www.clawhub.ai', + registry: 'https://www.clawhub.ai', registrySource: 'default', } } diff --git a/packages/clawdhub/src/cli/commands/sync.test.ts b/packages/clawdhub/src/cli/commands/sync.test.ts index 745db07..fa0b50e 100644 --- a/packages/clawdhub/src/cli/commands/sync.test.ts +++ b/packages/clawdhub/src/cli/commands/sync.test.ts @@ -27,10 +27,10 @@ vi.mock('@clack/prompts', () => ({ })) vi.mock('../../config.js', () => ({ - readGlobalConfig: vi.fn(async () => ({ registry: 'https://clawhub.ai', token: 'tkn' })), + readGlobalConfig: vi.fn(async () => ({ registry: 'https://www.clawhub.ai', token: 'tkn' })), })) -const mockGetRegistry = vi.fn(async () => 'https://clawhub.ai') +const mockGetRegistry = vi.fn(async () => 'https://www.clawhub.ai') vi.mock('../registry.js', () => ({ getRegistry: () => mockGetRegistry(), })) @@ -89,8 +89,8 @@ function makeOpts(): GlobalOpts { return { workdir: '/work', dir: '/work/skills', - site: 'https://clawhub.ai', - registry: 'https://clawhub.ai', + site: 'https://www.clawhub.ai', + registry: 'https://www.clawhub.ai', registrySource: 'default', } } diff --git a/packages/clawdhub/src/cli/registry.test.ts b/packages/clawdhub/src/cli/registry.test.ts index 60f486a..4a81f6f 100644 --- a/packages/clawdhub/src/cli/registry.test.ts +++ b/packages/clawdhub/src/cli/registry.test.ts @@ -22,7 +22,7 @@ function makeOpts(overrides: Partial = {}): GlobalOpts { return { workdir: '/work', dir: '/work/skills', - site: 'https://clawhub.ai', + site: 'https://www.clawhub.ai', registry: DEFAULT_REGISTRY, registrySource: 'default', ...overrides, @@ -38,7 +38,7 @@ beforeEach(() => { describe('registry resolution', () => { it('prefers explicit registry over discovery/cache', async () => { readGlobalConfig.mockResolvedValue({ registry: 'https://auth.clawdhub.com' }) - discoverRegistryFromSite.mockResolvedValue({ apiBase: 'https://clawhub.ai' }) + discoverRegistryFromSite.mockResolvedValue({ apiBase: 'https://www.clawhub.ai' }) const registry = await resolveRegistry( makeOpts({ registry: 'https://custom.example', registrySource: 'cli' }), @@ -50,13 +50,13 @@ describe('registry resolution', () => { it('ignores legacy registry and updates cache from discovery', async () => { readGlobalConfig.mockResolvedValue({ registry: 'https://auth.clawdhub.com', token: 'tkn' }) - discoverRegistryFromSite.mockResolvedValue({ apiBase: 'https://clawhub.ai' }) + discoverRegistryFromSite.mockResolvedValue({ apiBase: 'https://www.clawhub.ai' }) const registry = await getRegistry(makeOpts(), { cache: true }) - expect(registry).toBe('https://clawhub.ai') + expect(registry).toBe('https://www.clawhub.ai') expect(writeGlobalConfig).toHaveBeenCalledWith({ - registry: 'https://clawhub.ai', + registry: 'https://www.clawhub.ai', token: 'tkn', }) }) diff --git a/packages/clawdhub/src/cli/registry.ts b/packages/clawdhub/src/cli/registry.ts index 86e2c65..49120fd 100644 --- a/packages/clawdhub/src/cli/registry.ts +++ b/packages/clawdhub/src/cli/registry.ts @@ -2,8 +2,8 @@ import { readGlobalConfig, writeGlobalConfig } from '../config.js' import { discoverRegistryFromSite } from '../discovery.js' import type { GlobalOpts } from './types.js' -export const DEFAULT_SITE = 'https://clawhub.ai' -export const DEFAULT_REGISTRY = 'https://clawhub.ai' +export const DEFAULT_SITE = 'https://www.clawhub.ai' +export const DEFAULT_REGISTRY = 'https://www.clawhub.ai' const LEGACY_REGISTRY_HOSTS = new Set(['auth.clawdhub.com', 'auth.clawhub.com', 'auth.clawhub.ai']) export async function resolveRegistry(opts: GlobalOpts) { diff --git a/public/.well-known/clawhub.json b/public/.well-known/clawhub.json index 2c66c4a..e258b68 100644 --- a/public/.well-known/clawhub.json +++ b/public/.well-known/clawhub.json @@ -1,6 +1,6 @@ { - "apiBase": "https://clawhub.ai", - "authBase": "https://clawhub.ai", + "apiBase": "https://www.clawhub.ai", + "authBase": "https://www.clawhub.ai", "minCliVersion": "0.1.0", - "registry": "https://clawhub.ai" + "registry": "https://www.clawhub.ai" }