mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 04:18:05 +00:00
fix: clarify docker dashboard auth setup guidance
This commit is contained in:
@@ -62,6 +62,8 @@ environment:
|
||||
CCS_DASHBOARD_PASSWORD_HASH: "<bcrypt-hash>"
|
||||
```
|
||||
|
||||
Running `ccs config auth setup` on the outer host shell updates that machine's own `~/.ccs`, not the Docker volume mounted into `ccs-cliproxy`. For the integrated stack, configure auth inside the container or provide the auth env vars in Compose.
|
||||
|
||||
Generate a bcrypt hash:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -12,6 +12,12 @@ Authentication is **disabled by default** for backward compatibility. Use the CL
|
||||
|
||||
CCS does **not** ship a default dashboard username or password. When someone opens the dashboard from a non-loopback/IP address before auth is enabled, the UI now shows a setup state instead of an ambiguous login form. The host owner must run `ccs config auth setup`, or the user should switch back to the localhost URL if they are on the same machine.
|
||||
|
||||
Docker note: the integrated `ccs docker` stack stores its config inside the running container volume, not in the outer shell's `~/.ccs`. For Docker deployments, run auth setup inside the container:
|
||||
|
||||
```bash
|
||||
docker exec -it ccs-cliproxy ccs config auth setup
|
||||
```
|
||||
|
||||
When auth stays disabled, CCS now applies a localhost-only fallback on sensitive management endpoints. Remote devices can still open the dashboard UI when you intentionally bind it beyond loopback, but write-capable routes such as AI Provider management and CLIProxy auth/status helpers reject non-loopback requests until you enable dashboard auth.
|
||||
|
||||
## Account Context Modes (Related Feature)
|
||||
@@ -193,6 +199,8 @@ dashboard_auth:
|
||||
|
||||
Run `ccs config auth setup` to configure credentials.
|
||||
|
||||
If you are using the integrated Docker stack, run that command inside `ccs-cliproxy`. Running it on the outer host shell updates a different config directory and will not unlock the running dashboard.
|
||||
|
||||
### Forgot password
|
||||
|
||||
Run `ccs config auth setup` again to set a new password.
|
||||
|
||||
@@ -41,6 +41,7 @@ All major modularization work is complete. The codebase evolved from monolithic
|
||||
|
||||
### Recent Fixes
|
||||
|
||||
- **2026-04-15**: **#1010** Remote dashboard auth guidance now explains the Docker boundary explicitly. The readonly banner, remote login/setup card, and dashboard-auth docs now tell users that integrated Docker deployments keep config inside the running `ccs-cliproxy` container volume, so `ccs config auth setup` must run there rather than in the outer host shell.
|
||||
- **2026-04-14**: **#991** CCS now auto-routes Claude-target settings profiles that use OpenAI-compatible endpoints through a local Anthropic-compatible proxy instead of sending raw Anthropic `/v1/messages` traffic directly to chat-completions backends. The `ccs proxy` command now supports `start`, `status`, `activate`, and `stop` with explicit host binding, shell-aware activation helpers, and a fuller local runtime env contract. The proxy surface now exposes `GET /`, `/health`, `/v1/models`, and `/v1/messages`, logs routing decisions into CCS structured logs, supports Anthropic image blocks plus request-time `profile:model` overrides, and adds config-driven scenario routing (`background`, `think`, `longContext`, `webSearch`) on top of the compatible-profile path. Coverage now includes request routing, rate-limit/timeout/empty-upstream failures, chunked tool-call streaming, and disconnect cleanup alongside the existing unit, integration, and e2e suites.
|
||||
- **2026-04-10**: **#765** `/providers` now includes a first-class Hugging Face preset for API Profiles. CCS exposes Hugging Face Inference Providers through the existing OpenAI-compatible profile flow with the official router endpoint `https://router.huggingface.co/v1`, a short `hf` default profile name, and `hf` preset alias support for both the dashboard chooser and `ccs api create --preset hf`.
|
||||
- **2026-04-10**: **#944** Image Analysis auth readiness no longer collapses to native Read when merged runtime-status dependency overrides include a missing initializer value. CCS now preserves default dependency functions when override entries are `undefined`, still reads token-backed auth status directly in the local readiness path, and includes regression coverage for the missing-initializer case that previously surfaced as `deps.initializeAccounts is not a function`.
|
||||
|
||||
+52
-45
@@ -51,7 +51,7 @@ const resources = {
|
||||
remoteGuardLabel: 'Remote access guard',
|
||||
loading: 'Checking dashboard access…',
|
||||
loginDescription:
|
||||
'Use the username and password configured on the host to access the dashboard.',
|
||||
'Use the username and password configured for this CCS instance to access the dashboard.',
|
||||
username: 'Username',
|
||||
password: 'Password',
|
||||
usernamePlaceholder: 'Enter username',
|
||||
@@ -63,21 +63,22 @@ const resources = {
|
||||
darkMode: 'Dark',
|
||||
noDefaultCredentials: 'No default credentials ship with CCS.',
|
||||
credentialsHint:
|
||||
'Credentials are created on the host with `ccs config auth setup`, then used here.',
|
||||
remoteSetupTitle: 'Remote access needs host setup',
|
||||
'Credentials are created with `ccs config auth setup` on the CCS host. Docker deployments must run that command inside the container.',
|
||||
remoteSetupTitle: 'Remote access needs auth setup',
|
||||
remoteSetupDescription:
|
||||
'This dashboard was opened from a non-local address, but dashboard auth is not enabled on the host yet.',
|
||||
'This dashboard was opened from a non-local address, but dashboard auth is not enabled for this CCS instance yet.',
|
||||
incompleteSetupDescription:
|
||||
'Dashboard auth is turned on, but the host setup is incomplete. Finish the host configuration before signing in.',
|
||||
'Dashboard auth is turned on, but the setup is incomplete. Finish the configuration for this CCS instance before signing in.',
|
||||
safetyNoteRemote:
|
||||
'Remote management stays locked until the host owner enables dashboard auth.',
|
||||
'Remote management stays locked until the CCS host owner enables dashboard auth.',
|
||||
safetyNoteLocal:
|
||||
'If you are on the same machine, the localhost URL remains the simplest path in.',
|
||||
safetyNoteSession:
|
||||
'Successful sign-ins create an HTTP-only session that stays scoped to this host.',
|
||||
hostStepTitle: 'On the host machine',
|
||||
'Successful sign-ins create an HTTP-only session that stays scoped to this dashboard host.',
|
||||
hostStepTitle: 'On the CCS host',
|
||||
hostStepDescription:
|
||||
'Create or re-enable dashboard credentials, then reopen this page from the remote device.',
|
||||
dockerStepDescription: 'Docker deployment? Run the setup inside the running container:',
|
||||
localStepTitle: 'If this is your machine',
|
||||
localStepDescription:
|
||||
'Open the localhost URL printed by `ccs config` instead of the LAN or Tailscale address.',
|
||||
@@ -1543,12 +1544,13 @@ const resources = {
|
||||
},
|
||||
localhostDisclaimer: {
|
||||
remoteReadonlyAuthDisabledLong:
|
||||
'Remote dashboard access is read-only because dashboard auth is currently disabled on the host. Re-enable dashboard auth on the host to unlock remote changes.',
|
||||
'Remote dashboard access is read-only because dashboard auth is currently disabled for this CCS instance. Re-enable it on the CCS host. Docker deployments must do that inside the running container.',
|
||||
remoteReadonlyAuthDisabledShort:
|
||||
'Remote dashboard is read-only until dashboard auth is re-enabled on the host.',
|
||||
'Remote dashboard is read-only until dashboard auth is re-enabled for this CCS instance.',
|
||||
remoteReadonlySetupLong:
|
||||
'Remote dashboard access is read-only until you run ccs config auth setup on the host.',
|
||||
remoteReadonlySetupShort: 'Remote dashboard is read-only until host auth is configured.',
|
||||
'Remote dashboard access is read-only until you run ccs config auth setup for this CCS instance. Docker deployments must run it inside the container.',
|
||||
remoteReadonlySetupShort:
|
||||
'Remote dashboard is read-only until auth is configured for this CCS instance.',
|
||||
localLong: 'This dashboard runs locally. All data stays on your machine.',
|
||||
localShort: 'Local dashboard - data stays on your device.',
|
||||
dismiss: 'Dismiss disclaimer',
|
||||
@@ -2530,16 +2532,18 @@ const resources = {
|
||||
lightMode: '浅色',
|
||||
darkMode: '深色',
|
||||
noDefaultCredentials: 'CCS 不提供默认用户名或密码。',
|
||||
credentialsHint: '凭据需要在主机上通过 `ccs config auth setup` 创建,然后在这里使用。',
|
||||
remoteSetupTitle: '远程访问需要在主机上完成设置',
|
||||
remoteSetupDescription: '当前通过非本机地址打开控制台,但主机尚未启用控制台认证。',
|
||||
credentialsHint:
|
||||
'凭据需要在 CCS 主机上通过 `ccs config auth setup` 创建;Docker 部署必须在容器内运行该命令。',
|
||||
remoteSetupTitle: '远程访问需要完成认证设置',
|
||||
remoteSetupDescription: '当前通过非本机地址打开控制台,但此 CCS 实例尚未启用控制台认证。',
|
||||
incompleteSetupDescription:
|
||||
'控制台认证已开启,但主机上的设置尚未完成。请先完成主机配置再登录。',
|
||||
safetyNoteRemote: '在主机所有者启用控制台认证前,远程管理会保持锁定。',
|
||||
'控制台认证已开启,但设置尚未完成。请先为此 CCS 实例完成配置再登录。',
|
||||
safetyNoteRemote: '在 CCS 主机所有者启用控制台认证前,远程管理会保持锁定。',
|
||||
safetyNoteLocal: '如果你就在这台机器上,使用 localhost 地址始终是最直接的方式。',
|
||||
safetyNoteSession: '登录成功后会创建仅限此主机的 HTTP-only 会话。',
|
||||
hostStepTitle: '在主机上操作',
|
||||
safetyNoteSession: '登录成功后会创建仅限此控制台主机的 HTTP-only 会话。',
|
||||
hostStepTitle: '在 CCS 主机上操作',
|
||||
hostStepDescription: '创建或重新启用控制台凭据,然后再从远程设备重新打开此页面。',
|
||||
dockerStepDescription: '如果是 Docker 部署,请在正在运行的容器内执行:',
|
||||
localStepTitle: '如果这就是你的机器',
|
||||
localStepDescription:
|
||||
'请使用 `ccs config` 输出的 localhost 地址,而不是局域网或 Tailscale 地址。',
|
||||
@@ -3930,10 +3934,11 @@ const resources = {
|
||||
},
|
||||
localhostDisclaimer: {
|
||||
remoteReadonlyAuthDisabledLong:
|
||||
'远程控制台当前为只读,因为主机未启用控制台认证。请在主机上重新启用控制台认证以解锁远程编辑。',
|
||||
remoteReadonlyAuthDisabledShort: '远程控制台为只读,直到主机重新启用控制台认证。',
|
||||
remoteReadonlySetupLong: '远程控制台为只读,直到在主机上运行 ccs config auth setup。',
|
||||
remoteReadonlySetupShort: '远程控制台为只读,直到完成主机认证配置。',
|
||||
'远程控制台当前为只读,因为此 CCS 实例未启用控制台认证。请在 CCS 主机上重新启用;Docker 部署需要在运行中的容器内完成。',
|
||||
remoteReadonlyAuthDisabledShort: '远程控制台为只读,直到此 CCS 实例重新启用控制台认证。',
|
||||
remoteReadonlySetupLong:
|
||||
'远程控制台为只读,直到为此 CCS 实例运行 ccs config auth setup。Docker 部署必须在容器内运行该命令。',
|
||||
remoteReadonlySetupShort: '远程控制台为只读,直到为此 CCS 实例完成认证配置。',
|
||||
localLong: '本控制台在本地运行,所有数据保留在本机。',
|
||||
localShort: '本地控制台 - 数据保留在本机。',
|
||||
dismiss: '关闭提示',
|
||||
@@ -4884,21 +4889,22 @@ const resources = {
|
||||
darkMode: 'Tối',
|
||||
noDefaultCredentials: 'CCS không có sẵn tài khoản hay mật khẩu mặc định.',
|
||||
credentialsHint:
|
||||
'Thông tin đăng nhập được tạo trên máy host bằng `ccs config auth setup`, rồi dùng tại đây.',
|
||||
remoteSetupTitle: 'Truy cập từ xa cần được thiết lập trên máy host',
|
||||
'Thông tin đăng nhập được tạo bằng `ccs config auth setup` trên máy CCS host. Với Docker, phải chạy lệnh đó bên trong container.',
|
||||
remoteSetupTitle: 'Truy cập từ xa cần thiết lập xác thực',
|
||||
remoteSetupDescription:
|
||||
'Bảng điều khiển này đang được mở từ một địa chỉ không phải localhost, nhưng máy host chưa bật dashboard auth.',
|
||||
'Bảng điều khiển này đang được mở từ một địa chỉ không phải localhost, nhưng phiên bản CCS này chưa bật dashboard auth.',
|
||||
incompleteSetupDescription:
|
||||
'Dashboard auth đã được bật nhưng cấu hình trên máy host vẫn chưa hoàn tất. Hãy hoàn thành cấu hình trước khi đăng nhập.',
|
||||
'Dashboard auth đã được bật nhưng cấu hình vẫn chưa hoàn tất. Hãy hoàn thành cấu hình cho phiên bản CCS này trước khi đăng nhập.',
|
||||
safetyNoteRemote:
|
||||
'Quản trị từ xa sẽ tiếp tục bị khóa cho tới khi chủ máy host bật dashboard auth.',
|
||||
'Quản trị từ xa sẽ tiếp tục bị khóa cho tới khi chủ máy CCS host bật dashboard auth.',
|
||||
safetyNoteLocal:
|
||||
'Nếu bạn đang ngồi ngay trên máy đó, đường localhost vẫn là cách đơn giản nhất để vào.',
|
||||
safetyNoteSession:
|
||||
'Sau khi đăng nhập thành công, phiên HTTP-only sẽ chỉ có hiệu lực trên đúng máy host này.',
|
||||
hostStepTitle: 'Trên máy host',
|
||||
'Sau khi đăng nhập thành công, phiên HTTP-only sẽ chỉ có hiệu lực trên đúng máy chủ dashboard này.',
|
||||
hostStepTitle: 'Trên máy CCS host',
|
||||
hostStepDescription:
|
||||
'Tạo hoặc bật lại thông tin đăng nhập cho dashboard, rồi mở lại trang này từ thiết bị từ xa.',
|
||||
dockerStepDescription: 'Nếu dùng Docker, hãy chạy lệnh này bên trong container đang chạy:',
|
||||
localStepTitle: 'Nếu đây là máy của bạn',
|
||||
localStepDescription:
|
||||
'Hãy mở URL localhost mà `ccs config` in ra, thay vì địa chỉ LAN hoặc Tailscale.',
|
||||
@@ -6380,13 +6386,13 @@ const resources = {
|
||||
},
|
||||
localhostDisclaimer: {
|
||||
remoteReadonlyAuthDisabledLong:
|
||||
'Dashboard từ xa ở chế độ chỉ đọc vì dashboard auth đang bị tắt trên máy host. Bật lại dashboard auth trên máy host để mở khóa thay đổi từ xa.',
|
||||
'Dashboard từ xa đang ở chế độ chỉ đọc vì dashboard auth đang bị tắt cho phiên bản CCS này. Hãy bật lại trên máy CCS host; với Docker, việc đó phải được thực hiện bên trong container đang chạy.',
|
||||
remoteReadonlyAuthDisabledShort:
|
||||
'Dashboard từ xa chỉ đọc cho đến khi dashboard auth được bật lại trên máy host.',
|
||||
'Dashboard từ xa chỉ đọc cho đến khi dashboard auth được bật lại cho phiên bản CCS này.',
|
||||
remoteReadonlySetupLong:
|
||||
'Dashboard từ xa chỉ đọc cho đến khi bạn chạy ccs config auth setup trên máy host.',
|
||||
'Dashboard từ xa chỉ đọc cho đến khi bạn chạy ccs config auth setup cho phiên bản CCS này. Với Docker, hãy chạy lệnh đó bên trong container.',
|
||||
remoteReadonlySetupShort:
|
||||
'Dashboard từ xa chỉ đọc cho đến khi auth được cấu hình trên máy host.',
|
||||
'Dashboard từ xa chỉ đọc cho đến khi auth được cấu hình cho phiên bản CCS này.',
|
||||
localLong: 'Dashboard này chạy cục bộ. Toàn bộ dữ liệu nằm trên máy của bạn.',
|
||||
localShort: 'Dashboard cục bộ - dữ liệu nằm trên thiết bị của bạn.',
|
||||
dismiss: 'Bỏ qua thông báo',
|
||||
@@ -7346,20 +7352,21 @@ const resources = {
|
||||
darkMode: 'ダーク',
|
||||
noDefaultCredentials: 'CCS にデフォルトの認証情報はありません。',
|
||||
credentialsHint:
|
||||
'認証情報はホスト側で `ccs config auth setup` を実行して作成し、ここで使用します。',
|
||||
remoteSetupTitle: 'リモートアクセスにはホスト側の設定が必要です',
|
||||
'認証情報は CCS ホスト上で `ccs config auth setup` を実行して作成します。Docker では、そのコマンドをコンテナ内で実行する必要があります。',
|
||||
remoteSetupTitle: 'リモートアクセスには認証設定が必要です',
|
||||
remoteSetupDescription:
|
||||
'このダッシュボードはローカル以外のアドレスから開かれていますが、ホストでダッシュボード認証がまだ有効になっていません。',
|
||||
'このダッシュボードはローカル以外のアドレスから開かれていますが、この CCS インスタンスではダッシュボード認証がまだ有効になっていません。',
|
||||
incompleteSetupDescription:
|
||||
'ダッシュボード認証は有効ですが、ホスト側の設定が未完了です。サインイン前に設定を完了してください。',
|
||||
'ダッシュボード認証は有効ですが、設定が未完了です。この CCS インスタンスの設定を完了してからサインインしてください。',
|
||||
safetyNoteRemote:
|
||||
'ホスト管理者がダッシュボード認証を有効にするまで、リモート管理はロックされたままです。',
|
||||
'CCS ホスト管理者がダッシュボード認証を有効にするまで、リモート管理はロックされたままです。',
|
||||
safetyNoteLocal: '同じマシン上にいる場合は、localhost の URL を使うのが最も簡単です。',
|
||||
safetyNoteSession:
|
||||
'サインインに成功すると、このホストに限定された HTTP-only セッションが作成されます。',
|
||||
hostStepTitle: 'ホスト側で行うこと',
|
||||
'サインインに成功すると、このダッシュボードホストに限定された HTTP-only セッションが作成されます。',
|
||||
hostStepTitle: 'CCS ホスト側で行うこと',
|
||||
hostStepDescription:
|
||||
'ダッシュボード認証情報を作成または再有効化してから、このページをリモート端末で開き直してください。',
|
||||
dockerStepDescription: 'Docker の場合は、実行中のコンテナ内で次を実行してください:',
|
||||
localStepTitle: 'もしこのマシンを使っているなら',
|
||||
localStepDescription:
|
||||
'`ccs config` が表示する localhost の URL を使い、LAN や Tailscale のアドレスは避けてください。',
|
||||
@@ -9254,13 +9261,13 @@ const resources = {
|
||||
},
|
||||
localhostDisclaimer: {
|
||||
remoteReadonlyAuthDisabledLong:
|
||||
'ホストでダッシュボード認証が無効になっているため、リモートダッシュボードは読み取り専用です。リモートでの変更を有効にするには、ホスト側でダッシュボード認証を再度有効にしてください。',
|
||||
'この CCS インスタンスでダッシュボード認証が無効になっているため、リモートダッシュボードは読み取り専用です。CCS ホスト側で再度有効にしてください。Docker では、実行中のコンテナ内で行う必要があります。',
|
||||
remoteReadonlyAuthDisabledShort:
|
||||
'ホストでダッシュボード認証が再有効化されるまで、リモートダッシュボードは読み取り専用です。',
|
||||
'この CCS インスタンスでダッシュボード認証が再有効化されるまで、リモートダッシュボードは読み取り専用です。',
|
||||
remoteReadonlySetupLong:
|
||||
'ホストで ccs config auth setup を実行するまで、リモートダッシュボードは読み取り専用です。',
|
||||
'この CCS インスタンスで ccs config auth setup を実行するまで、リモートダッシュボードは読み取り専用です。Docker では、そのコマンドをコンテナ内で実行してください。',
|
||||
remoteReadonlySetupShort:
|
||||
'ホストの認証が設定されるまで、リモートダッシュボードは読み取り専用です。',
|
||||
'この CCS インスタンスの認証が設定されるまで、リモートダッシュボードは読み取り専用です。',
|
||||
localLong:
|
||||
'このダッシュボードはローカルで動作しています。データはすべてお使いのマシンに残ります。',
|
||||
localShort: 'ローカルダッシュボード - データはお使いのデバイスに保存されます。',
|
||||
|
||||
@@ -207,6 +207,12 @@ export function LoginPage() {
|
||||
<code className="mt-4 block rounded-xl border border-border/70 bg-muted/60 px-3 py-2 font-mono text-[13px] text-foreground">
|
||||
ccs config auth setup
|
||||
</code>
|
||||
<p className="mt-3 text-xs leading-5 text-muted-foreground">
|
||||
{t('auth.dockerStepDescription')}
|
||||
</p>
|
||||
<code className="mt-2 block rounded-xl border border-border/70 bg-muted/60 px-3 py-2 font-mono text-[13px] text-foreground">
|
||||
docker exec -it ccs-cliproxy ccs config auth setup
|
||||
</code>
|
||||
</div>
|
||||
|
||||
<div className="rounded-2xl border border-border/70 bg-background/75 p-4">
|
||||
|
||||
@@ -42,7 +42,7 @@ describe('LocalhostDisclaimer', () => {
|
||||
|
||||
expect(
|
||||
screen.getByText(
|
||||
'Remote dashboard access is read-only until you run ccs config auth setup on the host.'
|
||||
'Remote dashboard access is read-only until you run ccs config auth setup for this CCS instance. Docker deployments must run it inside the container.'
|
||||
)
|
||||
).toBeVisible();
|
||||
expect(screen.queryByLabelText('Dismiss disclaimer')).toBeNull();
|
||||
@@ -60,7 +60,7 @@ describe('LocalhostDisclaimer', () => {
|
||||
|
||||
expect(
|
||||
screen.getByText(
|
||||
'Remote dashboard access is read-only because dashboard auth is currently disabled on the host. Re-enable dashboard auth on the host to unlock remote changes.'
|
||||
'Remote dashboard access is read-only because dashboard auth is currently disabled for this CCS instance. Re-enable it on the CCS host. Docker deployments must do that inside the running container.'
|
||||
)
|
||||
).toBeVisible();
|
||||
expect(screen.queryByLabelText('Dismiss disclaimer')).toBeNull();
|
||||
|
||||
@@ -59,7 +59,7 @@ describe('LoginPage', () => {
|
||||
await waitFor(() => {
|
||||
expect(navigateMock).toHaveBeenCalledWith('/settings', { replace: true });
|
||||
});
|
||||
expect(screen.queryByRole('heading', { name: 'Remote access needs host setup' })).toBeNull();
|
||||
expect(screen.queryByRole('heading', { name: 'Remote access needs auth setup' })).toBeNull();
|
||||
});
|
||||
|
||||
it('renders the incomplete setup copy when auth is enabled without credentials', () => {
|
||||
@@ -80,7 +80,7 @@ describe('LoginPage', () => {
|
||||
|
||||
expect(
|
||||
screen.getAllByText(
|
||||
'Dashboard auth is turned on, but the host setup is incomplete. Finish the host configuration before signing in.'
|
||||
'Dashboard auth is turned on, but the setup is incomplete. Finish the configuration for this CCS instance before signing in.'
|
||||
)
|
||||
).not.toHaveLength(0);
|
||||
expect(
|
||||
@@ -88,6 +88,10 @@ describe('LoginPage', () => {
|
||||
'Create or re-enable dashboard credentials, then reopen this page from the remote device.'
|
||||
)
|
||||
).toBeVisible();
|
||||
expect(
|
||||
screen.getByText('Docker deployment? Run the setup inside the running container:')
|
||||
).toBeVisible();
|
||||
expect(screen.getByText('docker exec -it ccs-cliproxy ccs config auth setup')).toBeVisible();
|
||||
expect(screen.queryByLabelText('Username')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user