mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-07-08 22:55:41 +08:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5884573a69 | ||
|
|
123d244a51 |
14
.github/workflows/docker.yml
vendored
14
.github/workflows/docker.yml
vendored
@@ -14,18 +14,22 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
template: [claude-code, codex, gemini]
|
template: [claude-code, codex]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3
|
uses: docker/setup-qemu-action@v4
|
||||||
|
with:
|
||||||
|
platforms: arm64
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v4
|
||||||
|
with:
|
||||||
|
version: latest
|
||||||
|
|
||||||
- name: Log in to Docker Hub
|
- name: Log in to Docker Hub
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v4
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
@@ -40,7 +44,7 @@ jobs:
|
|||||||
echo "tags=$TAGS" >> "$GITHUB_OUTPUT"
|
echo "tags=$TAGS" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
- name: Build and push
|
- name: Build and push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v7
|
||||||
with:
|
with:
|
||||||
context: ./docker
|
context: ./docker
|
||||||
file: ./docker/${{ matrix.template }}/Dockerfile
|
file: ./docker/${{ matrix.template }}/Dockerfile
|
||||||
|
|||||||
@@ -5,7 +5,16 @@ COPY shared/install-cloudcli.sh /tmp/install-cloudcli.sh
|
|||||||
RUN chmod +x /tmp/install-cloudcli.sh && /tmp/install-cloudcli.sh
|
RUN chmod +x /tmp/install-cloudcli.sh && /tmp/install-cloudcli.sh
|
||||||
|
|
||||||
USER agent
|
USER agent
|
||||||
RUN npm install -g @cloudcli-ai/cloudcli && cloudcli --version
|
RUN --mount=type=cache,target=/tmp/npm-cache,sharing=locked,mode=0777 \
|
||||||
|
npm install -g @cloudcli-ai/cloudcli \
|
||||||
|
--cache=/tmp/npm-cache \
|
||||||
|
--fetch-retries=5 \
|
||||||
|
--fetch-retry-mintimeout=20000 \
|
||||||
|
--fetch-retry-maxtimeout=120000 \
|
||||||
|
--fetch-timeout=600000 \
|
||||||
|
--no-audit \
|
||||||
|
--no-fund && \
|
||||||
|
cloudcli --version
|
||||||
|
|
||||||
COPY --chown=agent:agent shared/start-cloudcli.sh /home/agent/.cloudcli-start.sh
|
COPY --chown=agent:agent shared/start-cloudcli.sh /home/agent/.cloudcli-start.sh
|
||||||
RUN echo '. ~/.cloudcli-start.sh' >> /home/agent/.bashrc
|
RUN echo '. ~/.cloudcli-start.sh' >> /home/agent/.bashrc
|
||||||
|
|||||||
@@ -5,7 +5,16 @@ COPY shared/install-cloudcli.sh /tmp/install-cloudcli.sh
|
|||||||
RUN chmod +x /tmp/install-cloudcli.sh && /tmp/install-cloudcli.sh
|
RUN chmod +x /tmp/install-cloudcli.sh && /tmp/install-cloudcli.sh
|
||||||
|
|
||||||
USER agent
|
USER agent
|
||||||
RUN npm install -g @cloudcli-ai/cloudcli && cloudcli --version
|
RUN --mount=type=cache,target=/tmp/npm-cache,sharing=locked,mode=0777 \
|
||||||
|
npm install -g @cloudcli-ai/cloudcli \
|
||||||
|
--cache=/tmp/npm-cache \
|
||||||
|
--fetch-retries=5 \
|
||||||
|
--fetch-retry-mintimeout=20000 \
|
||||||
|
--fetch-retry-maxtimeout=120000 \
|
||||||
|
--fetch-timeout=600000 \
|
||||||
|
--no-audit \
|
||||||
|
--no-fund && \
|
||||||
|
cloudcli --version
|
||||||
|
|
||||||
COPY --chown=agent:agent shared/start-cloudcli.sh /home/agent/.cloudcli-start.sh
|
COPY --chown=agent:agent shared/start-cloudcli.sh /home/agent/.cloudcli-start.sh
|
||||||
RUN echo '. ~/.cloudcli-start.sh' >> /home/agent/.bashrc
|
RUN echo '. ~/.cloudcli-start.sh' >> /home/agent/.bashrc
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import type { DragEvent } from 'react';
|
|||||||
|
|
||||||
import { IS_PLATFORM } from '../../../constants/config';
|
import { IS_PLATFORM } from '../../../constants/config';
|
||||||
import type { Project } from '../../../types/app';
|
import type { Project } from '../../../types/app';
|
||||||
|
import { isValidRefreshedToken } from '../../../utils/api';
|
||||||
import {
|
import {
|
||||||
MAX_FILE_UPLOAD_COUNT,
|
MAX_FILE_UPLOAD_COUNT,
|
||||||
MAX_FILE_UPLOAD_SIZE_BYTES,
|
MAX_FILE_UPLOAD_SIZE_BYTES,
|
||||||
@@ -131,7 +132,7 @@ const uploadFormDataWithProgress = (
|
|||||||
|
|
||||||
xhr.onload = () => {
|
xhr.onload = () => {
|
||||||
const refreshedToken = xhr.getResponseHeader('X-Refreshed-Token');
|
const refreshedToken = xhr.getResponseHeader('X-Refreshed-Token');
|
||||||
if (refreshedToken) {
|
if (isValidRefreshedToken(refreshedToken)) {
|
||||||
localStorage.setItem('auth-token', refreshedToken);
|
localStorage.setItem('auth-token', refreshedToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,16 @@
|
|||||||
import { IS_PLATFORM } from "../constants/config";
|
import { IS_PLATFORM } from "../constants/config";
|
||||||
|
|
||||||
|
// Only accept a refreshed token that has this app's issued JWT shape
|
||||||
|
// (three base64url segments). An attacker-injected/malformed header value
|
||||||
|
// must never overwrite the stored auth token.
|
||||||
|
/**
|
||||||
|
* @param {unknown} token
|
||||||
|
* @returns {token is string}
|
||||||
|
*/
|
||||||
|
export const isValidRefreshedToken = (token) =>
|
||||||
|
typeof token === 'string' &&
|
||||||
|
/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(token);
|
||||||
|
|
||||||
// Utility function for authenticated API calls
|
// Utility function for authenticated API calls
|
||||||
export const authenticatedFetch = (url, options = {}) => {
|
export const authenticatedFetch = (url, options = {}) => {
|
||||||
const token = localStorage.getItem('auth-token');
|
const token = localStorage.getItem('auth-token');
|
||||||
@@ -23,7 +34,7 @@ export const authenticatedFetch = (url, options = {}) => {
|
|||||||
},
|
},
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
const refreshedToken = response.headers.get('X-Refreshed-Token');
|
const refreshedToken = response.headers.get('X-Refreshed-Token');
|
||||||
if (refreshedToken) {
|
if (isValidRefreshedToken(refreshedToken)) {
|
||||||
localStorage.setItem('auth-token', refreshedToken);
|
localStorage.setItem('auth-token', refreshedToken);
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
|
|||||||
Reference in New Issue
Block a user