mirror of
				https://github.com/songquanpeng/one-api.git
				synced 2025-11-04 07:43:41 +08:00 
			
		
		
		
	Compare commits
	
		
			3 Commits
		
	
	
		
			v0.6.6-alp
			...
			v0.5.11-de
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					227e11c5ac | ||
| 
						 | 
					b0bf224bb1 | ||
| 
						 | 
					5342af9222 | 
							
								
								
									
										49
									
								
								.github/workflows/docker-image-amd64-en.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										49
									
								
								.github/workflows/docker-image-amd64-en.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,49 +0,0 @@
 | 
				
			|||||||
name: Publish Docker image (amd64, English)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
on:
 | 
					 | 
				
			||||||
  push:
 | 
					 | 
				
			||||||
    tags:
 | 
					 | 
				
			||||||
      - '*'
 | 
					 | 
				
			||||||
  workflow_dispatch:
 | 
					 | 
				
			||||||
    inputs:
 | 
					 | 
				
			||||||
      name:
 | 
					 | 
				
			||||||
        description: 'reason'
 | 
					 | 
				
			||||||
        required: false
 | 
					 | 
				
			||||||
jobs:
 | 
					 | 
				
			||||||
  push_to_registries:
 | 
					 | 
				
			||||||
    name: Push Docker image to multiple registries
 | 
					 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					 | 
				
			||||||
    permissions:
 | 
					 | 
				
			||||||
      packages: write
 | 
					 | 
				
			||||||
      contents: read
 | 
					 | 
				
			||||||
    steps:
 | 
					 | 
				
			||||||
      - name: Check out the repo
 | 
					 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Save version info
 | 
					 | 
				
			||||||
        run: |
 | 
					 | 
				
			||||||
          git describe --tags > VERSION 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Translate
 | 
					 | 
				
			||||||
        run: |
 | 
					 | 
				
			||||||
          python ./i18n/translate.py --repository_path . --json_file_path ./i18n/en.json
 | 
					 | 
				
			||||||
      - name: Log in to Docker Hub
 | 
					 | 
				
			||||||
        uses: docker/login-action@v2
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          username: ${{ secrets.DOCKERHUB_USERNAME }}
 | 
					 | 
				
			||||||
          password: ${{ secrets.DOCKERHUB_TOKEN }}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Extract metadata (tags, labels) for Docker
 | 
					 | 
				
			||||||
        id: meta
 | 
					 | 
				
			||||||
        uses: docker/metadata-action@v4
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          images: |
 | 
					 | 
				
			||||||
            justsong/one-api-en
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Build and push Docker images
 | 
					 | 
				
			||||||
        uses: docker/build-push-action@v3
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          context: .
 | 
					 | 
				
			||||||
          push: true
 | 
					 | 
				
			||||||
          tags: ${{ steps.meta.outputs.tags }}
 | 
					 | 
				
			||||||
          labels: ${{ steps.meta.outputs.labels }}
 | 
					 | 
				
			||||||
							
								
								
									
										22
									
								
								.github/workflows/docker-image-amd64.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								.github/workflows/docker-image-amd64.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,34 +1,28 @@
 | 
				
			|||||||
name: Publish Docker image (amd64)
 | 
					name: Publish Docker image (amd64)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
on:
 | 
					on:
 | 
				
			||||||
  push:
 | 
					 | 
				
			||||||
    tags:
 | 
					 | 
				
			||||||
      - '*'
 | 
					 | 
				
			||||||
  workflow_dispatch:
 | 
					  workflow_dispatch:
 | 
				
			||||||
    inputs:
 | 
					    inputs:
 | 
				
			||||||
      name:
 | 
					      name:
 | 
				
			||||||
        description: 'reason'
 | 
					        description: 'reason'
 | 
				
			||||||
        required: false
 | 
					        required: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
jobs:
 | 
					jobs:
 | 
				
			||||||
  push_to_registries:
 | 
					  build-and-push-image:
 | 
				
			||||||
    name: Push Docker image to multiple registries
 | 
					    name: Push Docker image to GitHub registry
 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
    permissions:
 | 
					    permissions:
 | 
				
			||||||
      packages: write
 | 
					      packages: write
 | 
				
			||||||
      contents: read
 | 
					      contents: read
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Check out the repo
 | 
					      - name: Check out the repo
 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					        uses: actions/checkout@v3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Save version info
 | 
					      - name: Save version info
 | 
				
			||||||
        run: |
 | 
					        run: |
 | 
				
			||||||
          git describe --tags > VERSION 
 | 
					          git describe --tags > VERSION
 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Log in to Docker Hub
 | 
					 | 
				
			||||||
        uses: docker/login-action@v2
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          username: ${{ secrets.DOCKERHUB_USERNAME }}
 | 
					 | 
				
			||||||
          password: ${{ secrets.DOCKERHUB_TOKEN }}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Log in to the Container registry
 | 
					      - name: Log in to the Container registry
 | 
				
			||||||
        uses: docker/login-action@v2
 | 
					        uses: docker/login-action@v2
 | 
				
			||||||
@@ -41,9 +35,7 @@ jobs:
 | 
				
			|||||||
        id: meta
 | 
					        id: meta
 | 
				
			||||||
        uses: docker/metadata-action@v4
 | 
					        uses: docker/metadata-action@v4
 | 
				
			||||||
        with:
 | 
					        with:
 | 
				
			||||||
          images: |
 | 
					          images: ghcr.io/${{ github.repository }}
 | 
				
			||||||
            justsong/one-api
 | 
					 | 
				
			||||||
            ghcr.io/${{ github.repository }}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Build and push Docker images
 | 
					      - name: Build and push Docker images
 | 
				
			||||||
        uses: docker/build-push-action@v3
 | 
					        uses: docker/build-push-action@v3
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										62
									
								
								.github/workflows/docker-image-arm64.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										62
									
								
								.github/workflows/docker-image-arm64.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,62 +0,0 @@
 | 
				
			|||||||
name: Publish Docker image (arm64)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
on:
 | 
					 | 
				
			||||||
  push:
 | 
					 | 
				
			||||||
    tags:
 | 
					 | 
				
			||||||
      - '*'
 | 
					 | 
				
			||||||
      - '!*-alpha*'
 | 
					 | 
				
			||||||
  workflow_dispatch:
 | 
					 | 
				
			||||||
    inputs:
 | 
					 | 
				
			||||||
      name:
 | 
					 | 
				
			||||||
        description: 'reason'
 | 
					 | 
				
			||||||
        required: false
 | 
					 | 
				
			||||||
jobs:
 | 
					 | 
				
			||||||
  push_to_registries:
 | 
					 | 
				
			||||||
    name: Push Docker image to multiple registries
 | 
					 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					 | 
				
			||||||
    permissions:
 | 
					 | 
				
			||||||
      packages: write
 | 
					 | 
				
			||||||
      contents: read
 | 
					 | 
				
			||||||
    steps:
 | 
					 | 
				
			||||||
      - name: Check out the repo
 | 
					 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Save version info
 | 
					 | 
				
			||||||
        run: |
 | 
					 | 
				
			||||||
          git describe --tags > VERSION 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Set up QEMU
 | 
					 | 
				
			||||||
        uses: docker/setup-qemu-action@v2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Set up Docker Buildx
 | 
					 | 
				
			||||||
        uses: docker/setup-buildx-action@v2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Log in to Docker Hub
 | 
					 | 
				
			||||||
        uses: docker/login-action@v2
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          username: ${{ secrets.DOCKERHUB_USERNAME }}
 | 
					 | 
				
			||||||
          password: ${{ secrets.DOCKERHUB_TOKEN }}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Log in to the Container registry
 | 
					 | 
				
			||||||
        uses: docker/login-action@v2
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          registry: ghcr.io
 | 
					 | 
				
			||||||
          username: ${{ github.actor }}
 | 
					 | 
				
			||||||
          password: ${{ secrets.GITHUB_TOKEN }}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Extract metadata (tags, labels) for Docker
 | 
					 | 
				
			||||||
        id: meta
 | 
					 | 
				
			||||||
        uses: docker/metadata-action@v4
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          images: |
 | 
					 | 
				
			||||||
            justsong/one-api
 | 
					 | 
				
			||||||
            ghcr.io/${{ github.repository }}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Build and push Docker images
 | 
					 | 
				
			||||||
        uses: docker/build-push-action@v3
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          context: .
 | 
					 | 
				
			||||||
          platforms: linux/amd64,linux/arm64
 | 
					 | 
				
			||||||
          push: true
 | 
					 | 
				
			||||||
          tags: ${{ steps.meta.outputs.tags }}
 | 
					 | 
				
			||||||
          labels: ${{ steps.meta.outputs.labels }}
 | 
					 | 
				
			||||||
							
								
								
									
										59
									
								
								.github/workflows/linux-release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										59
									
								
								.github/workflows/linux-release.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,59 +0,0 @@
 | 
				
			|||||||
name: Linux Release
 | 
					 | 
				
			||||||
permissions:
 | 
					 | 
				
			||||||
  contents: write
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
on:
 | 
					 | 
				
			||||||
  push:
 | 
					 | 
				
			||||||
    tags:
 | 
					 | 
				
			||||||
      - '*'
 | 
					 | 
				
			||||||
      - '!*-alpha*'
 | 
					 | 
				
			||||||
  workflow_dispatch:
 | 
					 | 
				
			||||||
    inputs:
 | 
					 | 
				
			||||||
      name:
 | 
					 | 
				
			||||||
        description: 'reason'
 | 
					 | 
				
			||||||
        required: false
 | 
					 | 
				
			||||||
jobs:
 | 
					 | 
				
			||||||
  release:
 | 
					 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					 | 
				
			||||||
    steps:
 | 
					 | 
				
			||||||
      - name: Checkout
 | 
					 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          fetch-depth: 0
 | 
					 | 
				
			||||||
      - uses: actions/setup-node@v3
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          node-version: 16
 | 
					 | 
				
			||||||
      - name: Build Frontend (theme default)
 | 
					 | 
				
			||||||
        env:
 | 
					 | 
				
			||||||
          CI: ""
 | 
					 | 
				
			||||||
        run: |
 | 
					 | 
				
			||||||
          cd web
 | 
					 | 
				
			||||||
          git describe --tags > VERSION
 | 
					 | 
				
			||||||
          REACT_APP_VERSION=$(git describe --tags) chmod u+x ./build.sh && ./build.sh
 | 
					 | 
				
			||||||
          cd ..
 | 
					 | 
				
			||||||
      - name: Set up Go
 | 
					 | 
				
			||||||
        uses: actions/setup-go@v3
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          go-version: '>=1.18.0'
 | 
					 | 
				
			||||||
      - name: Build Backend (amd64)
 | 
					 | 
				
			||||||
        run: |
 | 
					 | 
				
			||||||
          go mod download
 | 
					 | 
				
			||||||
          go build -ldflags "-s -w -X 'one-api/common.Version=$(git describe --tags)' -extldflags '-static'" -o one-api
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Build Backend (arm64)
 | 
					 | 
				
			||||||
        run: |
 | 
					 | 
				
			||||||
          sudo apt-get update
 | 
					 | 
				
			||||||
          sudo apt-get install gcc-aarch64-linux-gnu
 | 
					 | 
				
			||||||
          CC=aarch64-linux-gnu-gcc CGO_ENABLED=1 GOOS=linux GOARCH=arm64 go build -ldflags "-s -w -X 'one-api/common.Version=$(git describe --tags)' -extldflags '-static'" -o one-api-arm64
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Release
 | 
					 | 
				
			||||||
        uses: softprops/action-gh-release@v1
 | 
					 | 
				
			||||||
        if: startsWith(github.ref, 'refs/tags/')
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          files: |
 | 
					 | 
				
			||||||
            one-api
 | 
					 | 
				
			||||||
            one-api-arm64
 | 
					 | 
				
			||||||
          draft: true
 | 
					 | 
				
			||||||
          generate_release_notes: true
 | 
					 | 
				
			||||||
        env:
 | 
					 | 
				
			||||||
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 | 
					 | 
				
			||||||
							
								
								
									
										50
									
								
								.github/workflows/macos-release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										50
									
								
								.github/workflows/macos-release.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,50 +0,0 @@
 | 
				
			|||||||
name: macOS Release
 | 
					 | 
				
			||||||
permissions:
 | 
					 | 
				
			||||||
  contents: write
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
on:
 | 
					 | 
				
			||||||
  push:
 | 
					 | 
				
			||||||
    tags:
 | 
					 | 
				
			||||||
      - '*'
 | 
					 | 
				
			||||||
      - '!*-alpha*'
 | 
					 | 
				
			||||||
  workflow_dispatch:
 | 
					 | 
				
			||||||
    inputs:
 | 
					 | 
				
			||||||
      name:
 | 
					 | 
				
			||||||
        description: 'reason'
 | 
					 | 
				
			||||||
        required: false
 | 
					 | 
				
			||||||
jobs:
 | 
					 | 
				
			||||||
  release:
 | 
					 | 
				
			||||||
    runs-on: macos-latest
 | 
					 | 
				
			||||||
    steps:
 | 
					 | 
				
			||||||
      - name: Checkout
 | 
					 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          fetch-depth: 0
 | 
					 | 
				
			||||||
      - uses: actions/setup-node@v3
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          node-version: 16
 | 
					 | 
				
			||||||
      - name: Build Frontend (theme default)
 | 
					 | 
				
			||||||
        env:
 | 
					 | 
				
			||||||
          CI: ""
 | 
					 | 
				
			||||||
        run: |
 | 
					 | 
				
			||||||
          cd web
 | 
					 | 
				
			||||||
          git describe --tags > VERSION
 | 
					 | 
				
			||||||
          REACT_APP_VERSION=$(git describe --tags) chmod u+x ./build.sh && ./build.sh
 | 
					 | 
				
			||||||
          cd ..
 | 
					 | 
				
			||||||
      - name: Set up Go
 | 
					 | 
				
			||||||
        uses: actions/setup-go@v3
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          go-version: '>=1.18.0'
 | 
					 | 
				
			||||||
      - name: Build Backend
 | 
					 | 
				
			||||||
        run: |
 | 
					 | 
				
			||||||
          go mod download
 | 
					 | 
				
			||||||
          go build -ldflags "-X 'one-api/common.Version=$(git describe --tags)'" -o one-api-macos
 | 
					 | 
				
			||||||
      - name: Release
 | 
					 | 
				
			||||||
        uses: softprops/action-gh-release@v1
 | 
					 | 
				
			||||||
        if: startsWith(github.ref, 'refs/tags/')
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          files: one-api-macos
 | 
					 | 
				
			||||||
          draft: true
 | 
					 | 
				
			||||||
          generate_release_notes: true
 | 
					 | 
				
			||||||
        env:
 | 
					 | 
				
			||||||
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 | 
					 | 
				
			||||||
							
								
								
									
										53
									
								
								.github/workflows/windows-release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										53
									
								
								.github/workflows/windows-release.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,53 +0,0 @@
 | 
				
			|||||||
name: Windows Release
 | 
					 | 
				
			||||||
permissions:
 | 
					 | 
				
			||||||
  contents: write
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
on:
 | 
					 | 
				
			||||||
  push:
 | 
					 | 
				
			||||||
    tags:
 | 
					 | 
				
			||||||
      - '*'
 | 
					 | 
				
			||||||
      - '!*-alpha*'
 | 
					 | 
				
			||||||
  workflow_dispatch:
 | 
					 | 
				
			||||||
    inputs:
 | 
					 | 
				
			||||||
      name:
 | 
					 | 
				
			||||||
        description: 'reason'
 | 
					 | 
				
			||||||
        required: false
 | 
					 | 
				
			||||||
jobs:
 | 
					 | 
				
			||||||
  release:
 | 
					 | 
				
			||||||
    runs-on: windows-latest
 | 
					 | 
				
			||||||
    defaults:
 | 
					 | 
				
			||||||
      run:
 | 
					 | 
				
			||||||
        shell: bash
 | 
					 | 
				
			||||||
    steps:
 | 
					 | 
				
			||||||
      - name: Checkout
 | 
					 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          fetch-depth: 0
 | 
					 | 
				
			||||||
      - uses: actions/setup-node@v3
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          node-version: 16
 | 
					 | 
				
			||||||
      - name: Build Frontend (theme default)
 | 
					 | 
				
			||||||
        env:
 | 
					 | 
				
			||||||
          CI: ""
 | 
					 | 
				
			||||||
        run: |
 | 
					 | 
				
			||||||
          cd web/default
 | 
					 | 
				
			||||||
          npm install
 | 
					 | 
				
			||||||
          REACT_APP_VERSION=$(git describe --tags) npm run build
 | 
					 | 
				
			||||||
          cd ../..
 | 
					 | 
				
			||||||
      - name: Set up Go
 | 
					 | 
				
			||||||
        uses: actions/setup-go@v3
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          go-version: '>=1.18.0'
 | 
					 | 
				
			||||||
      - name: Build Backend
 | 
					 | 
				
			||||||
        run: |
 | 
					 | 
				
			||||||
          go mod download
 | 
					 | 
				
			||||||
          go build -ldflags "-s -w -X 'one-api/common.Version=$(git describe --tags)'" -o one-api.exe
 | 
					 | 
				
			||||||
      - name: Release
 | 
					 | 
				
			||||||
        uses: softprops/action-gh-release@v1
 | 
					 | 
				
			||||||
        if: startsWith(github.ref, 'refs/tags/')
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          files: one-api.exe
 | 
					 | 
				
			||||||
          draft: true
 | 
					 | 
				
			||||||
          generate_release_notes: true
 | 
					 | 
				
			||||||
        env:
 | 
					 | 
				
			||||||
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 | 
					 | 
				
			||||||
@@ -62,6 +62,7 @@ var SMTPPort = 587
 | 
				
			|||||||
var SMTPAccount = ""
 | 
					var SMTPAccount = ""
 | 
				
			||||||
var SMTPFrom = ""
 | 
					var SMTPFrom = ""
 | 
				
			||||||
var SMTPToken = ""
 | 
					var SMTPToken = ""
 | 
				
			||||||
 | 
					var SMTPAuthLoginEnabled = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var GitHubClientId = ""
 | 
					var GitHubClientId = ""
 | 
				
			||||||
var GitHubClientSecret = ""
 | 
					var GitHubClientSecret = ""
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,12 +4,39 @@ import (
 | 
				
			|||||||
	"crypto/rand"
 | 
						"crypto/rand"
 | 
				
			||||||
	"crypto/tls"
 | 
						"crypto/tls"
 | 
				
			||||||
	"encoding/base64"
 | 
						"encoding/base64"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/smtp"
 | 
						"net/smtp"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type loginAuth struct {
 | 
				
			||||||
 | 
						username, password string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func LoginAuth(username, password string) smtp.Auth {
 | 
				
			||||||
 | 
						return &loginAuth{username, password}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (a *loginAuth) Start(_ *smtp.ServerInfo) (string, []byte, error) {
 | 
				
			||||||
 | 
						return "LOGIN", []byte(a.username), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
 | 
				
			||||||
 | 
						if more {
 | 
				
			||||||
 | 
							switch string(fromServer) {
 | 
				
			||||||
 | 
							case "Username:":
 | 
				
			||||||
 | 
								return []byte(a.username), nil
 | 
				
			||||||
 | 
							case "Password:":
 | 
				
			||||||
 | 
								return []byte(a.password), nil
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								return nil, errors.New("unknown command from server during login auth")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func SendEmail(subject string, receiver string, content string) error {
 | 
					func SendEmail(subject string, receiver string, content string) error {
 | 
				
			||||||
	if SMTPFrom == "" { // for compatibility
 | 
						if SMTPFrom == "" { // for compatibility
 | 
				
			||||||
		SMTPFrom = SMTPAccount
 | 
							SMTPFrom = SMTPAccount
 | 
				
			||||||
@@ -37,7 +64,13 @@ func SendEmail(subject string, receiver string, content string) error {
 | 
				
			|||||||
		"Date: %s\r\n"+
 | 
							"Date: %s\r\n"+
 | 
				
			||||||
		"Content-Type: text/html; charset=UTF-8\r\n\r\n%s\r\n",
 | 
							"Content-Type: text/html; charset=UTF-8\r\n\r\n%s\r\n",
 | 
				
			||||||
		receiver, SystemName, SMTPFrom, encodedSubject, messageId, time.Now().Format(time.RFC1123Z), content))
 | 
							receiver, SystemName, SMTPFrom, encodedSubject, messageId, time.Now().Format(time.RFC1123Z), content))
 | 
				
			||||||
	auth := smtp.PlainAuth("", SMTPAccount, SMTPToken, SMTPServer)
 | 
					
 | 
				
			||||||
 | 
						var auth smtp.Auth
 | 
				
			||||||
 | 
						if SMTPAuthLoginEnabled {
 | 
				
			||||||
 | 
							auth = LoginAuth(SMTPAccount, SMTPToken)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							auth = smtp.PlainAuth("", SMTPAccount, SMTPToken, SMTPServer)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	addr := fmt.Sprintf("%s:%d", SMTPServer, SMTPPort)
 | 
						addr := fmt.Sprintf("%s:%d", SMTPServer, SMTPPort)
 | 
				
			||||||
	to := strings.Split(receiver, ";")
 | 
						to := strings.Split(receiver, ";")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,8 +6,23 @@ import (
 | 
				
			|||||||
	"one-api/common"
 | 
						"one-api/common"
 | 
				
			||||||
	"one-api/model"
 | 
						"one-api/model"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseIntArray(input string) []int {
 | 
				
			||||||
 | 
						values := strings.Split(input, ",")
 | 
				
			||||||
 | 
						result := make([]int, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, value := range values {
 | 
				
			||||||
 | 
							num, err := strconv.Atoi(strings.TrimSpace(value))
 | 
				
			||||||
 | 
							if err == nil {
 | 
				
			||||||
 | 
								result = append(result, num)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetAllLogs(c *gin.Context) {
 | 
					func GetAllLogs(c *gin.Context) {
 | 
				
			||||||
	p, _ := strconv.Atoi(c.Query("p"))
 | 
						p, _ := strconv.Atoi(c.Query("p"))
 | 
				
			||||||
	if p < 0 {
 | 
						if p < 0 {
 | 
				
			||||||
@@ -19,8 +34,8 @@ func GetAllLogs(c *gin.Context) {
 | 
				
			|||||||
	username := c.Query("username")
 | 
						username := c.Query("username")
 | 
				
			||||||
	tokenName := c.Query("token_name")
 | 
						tokenName := c.Query("token_name")
 | 
				
			||||||
	modelName := c.Query("model_name")
 | 
						modelName := c.Query("model_name")
 | 
				
			||||||
	channel, _ := strconv.Atoi(c.Query("channel"))
 | 
						channels := parseIntArray(c.Query("channel"))
 | 
				
			||||||
	logs, err := model.GetAllLogs(logType, startTimestamp, endTimestamp, modelName, username, tokenName, p*common.ItemsPerPage, common.ItemsPerPage, channel)
 | 
						logs, err := model.GetAllLogs(logType, startTimestamp, endTimestamp, modelName, username, tokenName, p*common.ItemsPerPage, common.ItemsPerPage, channels)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		c.JSON(http.StatusOK, gin.H{
 | 
							c.JSON(http.StatusOK, gin.H{
 | 
				
			||||||
			"success": false,
 | 
								"success": false,
 | 
				
			||||||
@@ -107,8 +122,8 @@ func GetLogsStat(c *gin.Context) {
 | 
				
			|||||||
	tokenName := c.Query("token_name")
 | 
						tokenName := c.Query("token_name")
 | 
				
			||||||
	username := c.Query("username")
 | 
						username := c.Query("username")
 | 
				
			||||||
	modelName := c.Query("model_name")
 | 
						modelName := c.Query("model_name")
 | 
				
			||||||
	channel, _ := strconv.Atoi(c.Query("channel"))
 | 
						channels := parseIntArray(c.Query("channel"))
 | 
				
			||||||
	quotaNum := model.SumUsedQuota(logType, startTimestamp, endTimestamp, modelName, username, tokenName, channel)
 | 
						quotaNum := model.SumUsedQuota(logType, startTimestamp, endTimestamp, modelName, username, tokenName, channels)
 | 
				
			||||||
	//tokenNum := model.SumUsedToken(logType, startTimestamp, endTimestamp, modelName, username, "")
 | 
						//tokenNum := model.SumUsedToken(logType, startTimestamp, endTimestamp, modelName, username, "")
 | 
				
			||||||
	c.JSON(http.StatusOK, gin.H{
 | 
						c.JSON(http.StatusOK, gin.H{
 | 
				
			||||||
		"success": true,
 | 
							"success": true,
 | 
				
			||||||
@@ -128,8 +143,8 @@ func GetLogsSelfStat(c *gin.Context) {
 | 
				
			|||||||
	endTimestamp, _ := strconv.ParseInt(c.Query("end_timestamp"), 10, 64)
 | 
						endTimestamp, _ := strconv.ParseInt(c.Query("end_timestamp"), 10, 64)
 | 
				
			||||||
	tokenName := c.Query("token_name")
 | 
						tokenName := c.Query("token_name")
 | 
				
			||||||
	modelName := c.Query("model_name")
 | 
						modelName := c.Query("model_name")
 | 
				
			||||||
	channel, _ := strconv.Atoi(c.Query("channel"))
 | 
						channels := parseIntArray(c.Query("channel"))
 | 
				
			||||||
	quotaNum := model.SumUsedQuota(logType, startTimestamp, endTimestamp, modelName, username, tokenName, channel)
 | 
						quotaNum := model.SumUsedQuota(logType, startTimestamp, endTimestamp, modelName, username, tokenName, channels)
 | 
				
			||||||
	//tokenNum := model.SumUsedToken(logType, startTimestamp, endTimestamp, modelName, username, tokenName)
 | 
						//tokenNum := model.SumUsedToken(logType, startTimestamp, endTimestamp, modelName, username, tokenName)
 | 
				
			||||||
	c.JSON(http.StatusOK, gin.H{
 | 
						c.JSON(http.StatusOK, gin.H{
 | 
				
			||||||
		"success": true,
 | 
							"success": true,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -330,6 +330,7 @@
 | 
				
			|||||||
  "通常和邮箱地址保持一致": "Usually consistent with the email address",
 | 
					  "通常和邮箱地址保持一致": "Usually consistent with the email address",
 | 
				
			||||||
  "SMTP 访问凭证": "SMTP Access Credential",
 | 
					  "SMTP 访问凭证": "SMTP Access Credential",
 | 
				
			||||||
  "敏感信息不会发送到前端显示": "Sensitive information will not be displayed in the frontend",
 | 
					  "敏感信息不会发送到前端显示": "Sensitive information will not be displayed in the frontend",
 | 
				
			||||||
 | 
					  "使用 SMTP LOGIN 认证方式": "Use LOGIN as SMTP authentication method",
 | 
				
			||||||
  "保存 SMTP 设置": "Save SMTP Settings",
 | 
					  "保存 SMTP 设置": "Save SMTP Settings",
 | 
				
			||||||
  "配置 GitHub OAuth App": "Configure GitHub OAuth App",
 | 
					  "配置 GitHub OAuth App": "Configure GitHub OAuth App",
 | 
				
			||||||
  "用以支持通过 GitHub 进行登录注册": "To support login & registration via GitHub",
 | 
					  "用以支持通过 GitHub 进行登录注册": "To support login & registration via GitHub",
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										17
									
								
								model/log.go
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								model/log.go
									
									
									
									
									
								
							@@ -72,7 +72,7 @@ func RecordConsumeLog(ctx context.Context, userId int, channelId int, promptToke
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetAllLogs(logType int, startTimestamp int64, endTimestamp int64, modelName string, username string, tokenName string, startIdx int, num int, channel int) (logs []*Log, err error) {
 | 
					func GetAllLogs(logType int, startTimestamp int64, endTimestamp int64, modelName string, username string, tokenName string, startIdx int, num int, channels []int) (logs []*Log, err error) {
 | 
				
			||||||
	var tx *gorm.DB
 | 
						var tx *gorm.DB
 | 
				
			||||||
	if logType == LogTypeUnknown {
 | 
						if logType == LogTypeUnknown {
 | 
				
			||||||
		tx = DB
 | 
							tx = DB
 | 
				
			||||||
@@ -94,9 +94,12 @@ func GetAllLogs(logType int, startTimestamp int64, endTimestamp int64, modelName
 | 
				
			|||||||
	if endTimestamp != 0 {
 | 
						if endTimestamp != 0 {
 | 
				
			||||||
		tx = tx.Where("created_at <= ?", endTimestamp)
 | 
							tx = tx.Where("created_at <= ?", endTimestamp)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if channel != 0 {
 | 
						if len(channels) > 1 {
 | 
				
			||||||
		tx = tx.Where("channel_id = ?", channel)
 | 
							tx = tx.Where("channel_id IN ?", channels)
 | 
				
			||||||
 | 
						} else if len(channels) == 1 && channels[0] != 0 {
 | 
				
			||||||
 | 
							tx = tx.Where("channel_id = ?", channels[0])
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = tx.Order("id desc").Limit(num).Offset(startIdx).Find(&logs).Error
 | 
						err = tx.Order("id desc").Limit(num).Offset(startIdx).Find(&logs).Error
 | 
				
			||||||
	return logs, err
 | 
						return logs, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -134,7 +137,7 @@ func SearchUserLogs(userId int, keyword string) (logs []*Log, err error) {
 | 
				
			|||||||
	return logs, err
 | 
						return logs, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func SumUsedQuota(logType int, startTimestamp int64, endTimestamp int64, modelName string, username string, tokenName string, channel int) (quota int) {
 | 
					func SumUsedQuota(logType int, startTimestamp int64, endTimestamp int64, modelName string, username string, tokenName string, channels []int) (quota int) {
 | 
				
			||||||
	tx := DB.Table("logs").Select("ifnull(sum(quota),0)")
 | 
						tx := DB.Table("logs").Select("ifnull(sum(quota),0)")
 | 
				
			||||||
	if username != "" {
 | 
						if username != "" {
 | 
				
			||||||
		tx = tx.Where("username = ?", username)
 | 
							tx = tx.Where("username = ?", username)
 | 
				
			||||||
@@ -151,8 +154,10 @@ func SumUsedQuota(logType int, startTimestamp int64, endTimestamp int64, modelNa
 | 
				
			|||||||
	if modelName != "" {
 | 
						if modelName != "" {
 | 
				
			||||||
		tx = tx.Where("model_name = ?", modelName)
 | 
							tx = tx.Where("model_name = ?", modelName)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if channel != 0 {
 | 
						if len(channels) > 1 {
 | 
				
			||||||
		tx = tx.Where("channel_id = ?", channel)
 | 
							tx = tx.Where("channel_id IN ?", channels)
 | 
				
			||||||
 | 
						} else if len(channels) == 1 && channels[0] != 0 {
 | 
				
			||||||
 | 
							tx = tx.Where("channel_id = ?", channels[0])
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	tx.Where("type = ?", LogTypeConsume).Scan("a)
 | 
						tx.Where("type = ?", LogTypeConsume).Scan("a)
 | 
				
			||||||
	return quota
 | 
						return quota
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -47,6 +47,7 @@ func InitOptionMap() {
 | 
				
			|||||||
	common.OptionMap["SMTPPort"] = strconv.Itoa(common.SMTPPort)
 | 
						common.OptionMap["SMTPPort"] = strconv.Itoa(common.SMTPPort)
 | 
				
			||||||
	common.OptionMap["SMTPAccount"] = ""
 | 
						common.OptionMap["SMTPAccount"] = ""
 | 
				
			||||||
	common.OptionMap["SMTPToken"] = ""
 | 
						common.OptionMap["SMTPToken"] = ""
 | 
				
			||||||
 | 
						common.OptionMap["SMTPAuthLoginEnabled"] = strconv.FormatBool(common.SMTPAuthLoginEnabled)
 | 
				
			||||||
	common.OptionMap["Notice"] = ""
 | 
						common.OptionMap["Notice"] = ""
 | 
				
			||||||
	common.OptionMap["About"] = ""
 | 
						common.OptionMap["About"] = ""
 | 
				
			||||||
	common.OptionMap["HomePageContent"] = ""
 | 
						common.OptionMap["HomePageContent"] = ""
 | 
				
			||||||
@@ -159,6 +160,8 @@ func updateOptionMap(key string, value string) (err error) {
 | 
				
			|||||||
			common.DisplayInCurrencyEnabled = boolValue
 | 
								common.DisplayInCurrencyEnabled = boolValue
 | 
				
			||||||
		case "DisplayTokenStatEnabled":
 | 
							case "DisplayTokenStatEnabled":
 | 
				
			||||||
			common.DisplayTokenStatEnabled = boolValue
 | 
								common.DisplayTokenStatEnabled = boolValue
 | 
				
			||||||
 | 
							case "SMTPAuthLoginEnabled":
 | 
				
			||||||
 | 
								common.SMTPAuthLoginEnabled = boolValue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	switch key {
 | 
						switch key {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,7 @@ const SystemSetting = () => {
 | 
				
			|||||||
    SMTPAccount: '',
 | 
					    SMTPAccount: '',
 | 
				
			||||||
    SMTPFrom: '',
 | 
					    SMTPFrom: '',
 | 
				
			||||||
    SMTPToken: '',
 | 
					    SMTPToken: '',
 | 
				
			||||||
 | 
					    SMTPAuthLoginEnabled: '',
 | 
				
			||||||
    ServerAddress: '',
 | 
					    ServerAddress: '',
 | 
				
			||||||
    Footer: '',
 | 
					    Footer: '',
 | 
				
			||||||
    WeChatAuthEnabled: '',
 | 
					    WeChatAuthEnabled: '',
 | 
				
			||||||
@@ -72,6 +73,7 @@ const SystemSetting = () => {
 | 
				
			|||||||
      case 'TurnstileCheckEnabled':
 | 
					      case 'TurnstileCheckEnabled':
 | 
				
			||||||
      case 'EmailDomainRestrictionEnabled':
 | 
					      case 'EmailDomainRestrictionEnabled':
 | 
				
			||||||
      case 'RegisterEnabled':
 | 
					      case 'RegisterEnabled':
 | 
				
			||||||
 | 
					      case 'SMTPAuthLoginEnabled':
 | 
				
			||||||
        value = inputs[key] === 'true' ? 'false' : 'true';
 | 
					        value = inputs[key] === 'true' ? 'false' : 'true';
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      default:
 | 
					      default:
 | 
				
			||||||
@@ -103,7 +105,7 @@ const SystemSetting = () => {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    if (
 | 
					    if (
 | 
				
			||||||
      name === 'Notice' ||
 | 
					      name === 'Notice' ||
 | 
				
			||||||
      name.startsWith('SMTP') ||
 | 
					      (name.startsWith('SMTP') && !name.endsWith('Enabled')) ||
 | 
				
			||||||
      name === 'ServerAddress' ||
 | 
					      name === 'ServerAddress' ||
 | 
				
			||||||
      name === 'GitHubClientId' ||
 | 
					      name === 'GitHubClientId' ||
 | 
				
			||||||
      name === 'GitHubClientSecret' ||
 | 
					      name === 'GitHubClientSecret' ||
 | 
				
			||||||
@@ -411,6 +413,12 @@ const SystemSetting = () => {
 | 
				
			|||||||
              checked={inputs.RegisterEnabled === 'true'}
 | 
					              checked={inputs.RegisterEnabled === 'true'}
 | 
				
			||||||
              placeholder='敏感信息不会发送到前端显示'
 | 
					              placeholder='敏感信息不会发送到前端显示'
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
 | 
					            <Form.Checkbox
 | 
				
			||||||
 | 
					              checked={inputs.SMTPAuthLoginEnabled === 'true'}
 | 
				
			||||||
 | 
					              label='使用 SMTP LOGIN 认证方式'
 | 
				
			||||||
 | 
					              name='SMTPAuthLoginEnabled'
 | 
				
			||||||
 | 
					              onChange={handleInputChange}
 | 
				
			||||||
 | 
					            />
 | 
				
			||||||
          </Form.Group>
 | 
					          </Form.Group>
 | 
				
			||||||
          <Form.Button onClick={submitSMTP}>保存 SMTP 设置</Form.Button>
 | 
					          <Form.Button onClick={submitSMTP}>保存 SMTP 设置</Form.Button>
 | 
				
			||||||
          <Divider />
 | 
					          <Divider />
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user