diff --git a/.github/workflows/docker-image-amd64.yml b/.github/workflows/docker-image-amd64.yml
index 1a77775c..43705321 100644
--- a/.github/workflows/docker-image-amd64.yml
+++ b/.github/workflows/docker-image-amd64.yml
@@ -1,54 +1,54 @@
-name: Publish Docker image (amd64)
-
-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: 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/gin-template
- ghcr.io/${{ github.repository }}
-
- - name: Build and push Docker images
- uses: docker/build-push-action@v3
- with:
- context: .
- push: true
- tags: ${{ steps.meta.outputs.tags }}
+name: Publish Docker image (amd64)
+
+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: 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: |
+ ghcr.io/rain-kl/atsflare
+ ghcr.io/${{ github.repository }}
+
+ - 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 }}
\ No newline at end of file
diff --git a/.github/workflows/docker-image-arm64.yml b/.github/workflows/docker-image-arm64.yml
index 8b57711b..91e84156 100644
--- a/.github/workflows/docker-image-arm64.yml
+++ b/.github/workflows/docker-image-arm64.yml
@@ -1,62 +1,62 @@
-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/gin-template
- 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 }}
+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: |
+ ghcr.io/rain-kl/atsflare
+ 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 }}
\ No newline at end of file
diff --git a/.github/workflows/linux-release.yml b/.github/workflows/linux-release.yml
index 31435487..50d642c6 100644
--- a/.github/workflows/linux-release.yml
+++ b/.github/workflows/linux-release.yml
@@ -1,54 +1,54 @@
-name: Linux Release
-permissions:
- contents: write
-
-on:
- push:
- tags:
- - '*'
- - '!*-alpha*'
-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
- env:
- CI: ""
- run: |
- cd web
- 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 (amd64)
- run: |
- go mod download
- go build -ldflags "-s -w -X 'gin-template/common.Version=$(git describe --tags)' -extldflags '-static'" -o gin-template
-
- - 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 'gin-template/common.Version=$(git describe --tags)' -extldflags '-static'" -o gin-template-arm64
-
- - name: Release
- uses: softprops/action-gh-release@v1
- if: startsWith(github.ref, 'refs/tags/')
- with:
- files: |
- gin-template
- gin-template-arm64
- draft: false
- generate_release_notes: true
- env:
+name: Linux Release
+permissions:
+ contents: write
+
+on:
+ push:
+ tags:
+ - '*'
+ - '!*-alpha*'
+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
+ env:
+ CI: ""
+ run: |
+ cd web
+ 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 (amd64)
+ run: |
+ go mod download
+ go build -ldflags "-s -w -X 'atsflare/common.Version=$(git describe --tags)' -extldflags '-static'" -o atsflare
+
+ - 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 'atsflare/common.Version=$(git describe --tags)' -extldflags '-static'" -o atsflare-arm64
+
+ - name: Release
+ uses: softprops/action-gh-release@v1
+ if: startsWith(github.ref, 'refs/tags/')
+ with:
+ files: |
+ atsflare
+ atsflare-arm64
+ draft: false
+ generate_release_notes: true
+ env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/.github/workflows/macos-release.yml b/.github/workflows/macos-release.yml
index fdd6eb0a..5bb0feef 100644
--- a/.github/workflows/macos-release.yml
+++ b/.github/workflows/macos-release.yml
@@ -1,45 +1,45 @@
-name: macOS Release
-permissions:
- contents: write
-
-on:
- push:
- tags:
- - '*'
- - '!*-alpha*'
-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
- env:
- CI: ""
- run: |
- cd web
- 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 "-X 'gin-template/common.Version=$(git describe --tags)'" -o gin-template-macos
- - name: Release
- uses: softprops/action-gh-release@v1
- if: startsWith(github.ref, 'refs/tags/')
- with:
- files: gin-template-macos
- draft: false
- generate_release_notes: true
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+name: macOS Release
+permissions:
+ contents: write
+
+on:
+ push:
+ tags:
+ - '*'
+ - '!*-alpha*'
+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
+ env:
+ CI: ""
+ run: |
+ cd web
+ 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 "-X 'atsflare/common.Version=$(git describe --tags)'" -o atsflare-macos
+ - name: Release
+ uses: softprops/action-gh-release@v1
+ if: startsWith(github.ref, 'refs/tags/')
+ with:
+ files: atsflare-macos
+ draft: false
+ generate_release_notes: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/windows-release.yml b/.github/workflows/windows-release.yml
index 00882d62..185c18df 100644
--- a/.github/workflows/windows-release.yml
+++ b/.github/workflows/windows-release.yml
@@ -1,48 +1,48 @@
-name: Windows Release
-permissions:
- contents: write
-
-on:
- push:
- tags:
- - '*'
- - '!*-alpha*'
-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
- env:
- CI: ""
- run: |
- cd web
- 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 'gin-template/common.Version=$(git describe --tags)'" -o gin-template.exe
- - name: Release
- uses: softprops/action-gh-release@v1
- if: startsWith(github.ref, 'refs/tags/')
- with:
- files: gin-template.exe
- draft: false
- generate_release_notes: true
- env:
+name: Windows Release
+permissions:
+ contents: write
+
+on:
+ push:
+ tags:
+ - '*'
+ - '!*-alpha*'
+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
+ env:
+ CI: ""
+ run: |
+ cd web
+ 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 'atsflare/common.Version=$(git describe --tags)'" -o atsflare.exe
+ - name: Release
+ uses: softprops/action-gh-release@v1
+ if: startsWith(github.ref, 'refs/tags/')
+ with:
+ files: atsflare.exe
+ draft: false
+ generate_release_notes: true
+ env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/README.en.md b/README.en.md
index 2060c4f5..3c4a035a 100644
--- a/README.en.md
+++ b/README.en.md
@@ -1,98 +1,93 @@
-
- 中文 | English
-
-
-
-
-
-
-
-
-# Gin Template
-
-_✨ Template for Gin & React projects ✨_
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Download
- ·
- Tutorial
- ·
- Feedback
- ·
- Demo
-
-
-## Features
-+ [x] Built-in user management.
-+ [x] Built-in file management.
-+ [x] [GitHub OAuth](https://github.com/settings/applications/new).
-+ [x] WeChat official account authorization (need [wechat-server](https://github.com/songquanpeng/wechat-server)).
-+ [x] Email verification & password reset.
-+ [x] Request rate limiting.
-+ [x] Static files caching.
-+ [x] Mobile friendly UI.
-+ [x] Token based authorization.
-+ [x] Use GitHub Actions to build releases & Docker images.
-+ [x] Cloudflare Turnstile user validation.
-
-## Deployment
-### Manual deployment
-1. Download built binary from [GitHub Releases](https://github.com/songquanpeng/gin-template/releases/latest) or build from source:
- ```shell
- git clone https://github.com/songquanpeng/gin-template.git
- go mod download
- go build -ldflags "-s -w" -o gin-template
- ````
-2. Run it:
- ```shell
- chmod u+x gin-template
- ./gin-template --port 3000 --log-dir ./logs
- ```
-3. Visit [http://localhost:3000/](http://localhost:3000/) and login. The username for the initial account is `root` and the password is `123456`.
-
-### Deploy with Docker
-Execute: `docker run -d --restart always -p 3000:3000 -v /home/ubuntu/data/gin-template:/data -v /etc/ssl/certs:/etc/ssl/certs:ro justsong/gin-template`
-
-Data will be saved in `/home/ubuntu/data/gin-template`.
-
-## Configurations
-The system works out of the box.
-
-You can configure the system by set environment variables or specify command line arguments.
-
-After the system starts, use `root` user to log in to the system and do further configuration.
-
-### Environment Variables
-1. `REDIS_CONN_STRING`: when set, Redis will be used as the storage for request rate limitation instead of memory storage.
- + Example: `REDIS_CONN_STRING=redis://default:redispw@localhost:49153`
-2. `SESSION_SECRET`: when set, a fixed session key will be used so that the logged-in users' cookie remains valid across system reboots.
- + Example: `SESSION_SECRET=random_string`
-3. `SQL_DSN`: when set, the target SQL database will be used instead of SQLite.
- + Example: `SQL_DSN=root:123456@tcp(localhost:3306)/gin-template`
-
-### Command line Arguments
-1. `--port `: specify the port number, the default value is `3000`.
- + Example: `--port 3000`
-2. `--log-dir `: specify the log dir, if not set, the log won't be saved.
- + Example: `--log-dir ./logs`
+
+ 中文 | English
+
+
+
+
+
+
+
+
+# ATSFlare
+
+_✨ Internal Nginx control plane for reverse proxy management ✨_
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Download
+ ·
+ Tutorial
+ ·
+ Feedback
+
+
+## Features
++ [x] Built-in user management.
++ [x] Built-in file management.
++ [x] [GitHub OAuth](https://github.com/settings/applications/new).
++ [x] WeChat official account authorization (need [wechat-server](https://github.com/songquanpeng/wechat-server)).
++ [x] Email verification & password reset.
++ [x] Request rate limiting.
++ [x] Static files caching.
++ [x] Mobile friendly UI.
++ [x] Token based authorization.
++ [x] Use GitHub Actions to build releases & Docker images.
++ [x] Cloudflare Turnstile user validation.
+
+## Deployment
+### Manual deployment
+1. Download built binary from [GitHub Releases](https://github.com/Rain-kl/ATSFlare/releases/latest) or build from source:
+ ```shell
+ git clone https://github.com/Rain-kl/ATSFlare.git
+ go mod download
+ go build -ldflags "-s -w" -o atsflare
+ ````
+2. Run it:
+ ```shell
+ chmod u+x atsflare
+ ./atsflare --port 3000 --log-dir ./logs
+ ```
+3. Visit [http://localhost:3000/](http://localhost:3000/) and login. The username for the initial account is `root` and the password is `123456`.
+
+### Deploy with Docker
+Execute: `docker run -d --restart always -p 3000:3000 -v /home/ubuntu/data/atsflare:/data -v /etc/ssl/certs:/etc/ssl/certs:ro ghcr.io/rain-kl/atsflare`
+
+Data will be saved in `/home/ubuntu/data/atsflare`.
+
+## Configurations
+The system works out of the box.
+
+You can configure the system by set environment variables or specify command line arguments.
+
+After the system starts, use `root` user to log in to the system and do further configuration.
+
+### Environment Variables
+1. `REDIS_CONN_STRING`: when set, Redis will be used as the storage for request rate limitation instead of memory storage.
+ + Example: `REDIS_CONN_STRING=redis://default:redispw@localhost:49153`
+2. `SESSION_SECRET`: when set, a fixed session key will be used so that the logged-in users' cookie remains valid across system reboots.
+ + Example: `SESSION_SECRET=random_string`
+3. `SQL_DSN`: when set, the target SQL database will be used instead of SQLite.
+ + Example: `SQL_DSN=root:123456@tcp(localhost:3306)/atsflare`
+
+### Command line Arguments
+1. `--port `: specify the port number, the default value is `3000`.
+ + Example: `--port 3000`
+2. `--log-dir `: specify the log dir, if not set, the log won't be saved.
+ + Example: `--log-dir ./logs`
3. `--version`: print the version and exit.
\ No newline at end of file
diff --git a/atsf_server/Dockerfile b/atsf_server/Dockerfile
index 7b2dc9ae..71efbcf4 100644
--- a/atsf_server/Dockerfile
+++ b/atsf_server/Dockerfile
@@ -1,31 +1,31 @@
-FROM node:16 as builder
-
-WORKDIR /build
-COPY ./web .
-COPY ./VERSION .
-RUN npm install
-RUN REACT_APP_VERSION=$(cat VERSION) npm run build
-
-FROM golang AS builder2
-
-ENV GO111MODULE=on \
- CGO_ENABLED=1 \
- GOOS=linux
-
-WORKDIR /build
-COPY . .
-COPY --from=builder /build/build ./web/build
-RUN go mod download
-RUN go build -ldflags "-s -w -X 'gin-template/common.Version=$(cat VERSION)' -extldflags '-static'" -o gin-template
-
-FROM alpine
-
-RUN apk update \
- && apk upgrade \
- && apk add --no-cache ca-certificates tzdata \
- && update-ca-certificates 2>/dev/null || true
-ENV PORT=3000
-COPY --from=builder2 /build/gin-template /
-EXPOSE 3000
-WORKDIR /data
-ENTRYPOINT ["/gin-template"]
+FROM node:16 as builder
+
+WORKDIR /build
+COPY ./web .
+COPY ./VERSION .
+RUN npm install
+RUN REACT_APP_VERSION=$(cat VERSION) npm run build
+
+FROM golang AS builder2
+
+ENV GO111MODULE=on \
+ CGO_ENABLED=1 \
+ GOOS=linux
+
+WORKDIR /build
+COPY . .
+COPY --from=builder /build/build ./web/build
+RUN go mod download
+RUN go build -ldflags "-s -w -X 'atsflare/common.Version=$(cat VERSION)' -extldflags '-static'" -o atsflare
+
+FROM alpine
+
+RUN apk update \
+ && apk upgrade \
+ && apk add --no-cache ca-certificates tzdata \
+ && update-ca-certificates 2>/dev/null || true
+ENV PORT=3000
+COPY --from=builder2 /build/atsflare /
+EXPOSE 3000
+WORKDIR /data
+ENTRYPOINT ["/atsflare"]
diff --git a/atsf_server/common/init.go b/atsf_server/common/init.go
index 7f926cc1..a208bdde 100644
--- a/atsf_server/common/init.go
+++ b/atsf_server/common/init.go
@@ -20,10 +20,10 @@ var (
var UploadPath = "upload"
func printHelp() {
- fmt.Println("Gin Template " + Version + " - Your next project starts from here.")
+ fmt.Println("ATSFlare " + Version + " - Internal Nginx Control Plane.")
fmt.Println("Copyright (C) 2023 JustSong. All rights reserved.")
- fmt.Println("GitHub: https://github.com/songquanpeng/gin-template")
- fmt.Println("Usage: gin-template [--port ] [--log-dir ] [--version] [--help]")
+ fmt.Println("GitHub: https://github.com/Rain-kl/ATSFlare")
+ fmt.Println("Usage: atsflare [--port ] [--log-dir ] [--version] [--help]")
}
func init() {
diff --git a/atsf_server/controller/agent.go b/atsf_server/controller/agent.go
index e446cf1f..e6417acb 100644
--- a/atsf_server/controller/agent.go
+++ b/atsf_server/controller/agent.go
@@ -1,9 +1,9 @@
package controller
import (
+ "atsflare/model"
+ "atsflare/service"
"encoding/json"
- "gin-template/model"
- "gin-template/service"
"github.com/gin-gonic/gin"
"net/http"
)
diff --git a/atsf_server/controller/config_version.go b/atsf_server/controller/config_version.go
index 7a674fc1..d4debcba 100644
--- a/atsf_server/controller/config_version.go
+++ b/atsf_server/controller/config_version.go
@@ -1,7 +1,7 @@
package controller
import (
- "gin-template/service"
+ "atsflare/service"
"github.com/gin-gonic/gin"
"net/http"
"strconv"
diff --git a/atsf_server/controller/file.go b/atsf_server/controller/file.go
index 0c1e2efb..2514890e 100644
--- a/atsf_server/controller/file.go
+++ b/atsf_server/controller/file.go
@@ -1,9 +1,9 @@
package controller
import (
+ "atsflare/common"
+ "atsflare/model"
"fmt"
- "gin-template/common"
- "gin-template/model"
"github.com/gin-gonic/gin"
"net/http"
"path/filepath"
diff --git a/atsf_server/controller/github.go b/atsf_server/controller/github.go
index 780de43b..d2930c47 100644
--- a/atsf_server/controller/github.go
+++ b/atsf_server/controller/github.go
@@ -1,12 +1,12 @@
package controller
import (
+ "atsflare/common"
+ "atsflare/model"
"bytes"
"encoding/json"
"errors"
"fmt"
- "gin-template/common"
- "gin-template/model"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"net/http"
diff --git a/atsf_server/controller/managed_domain.go b/atsf_server/controller/managed_domain.go
index 15ec4321..d9d37371 100644
--- a/atsf_server/controller/managed_domain.go
+++ b/atsf_server/controller/managed_domain.go
@@ -1,8 +1,8 @@
package controller
import (
+ "atsflare/service"
"encoding/json"
- "gin-template/service"
"github.com/gin-gonic/gin"
"net/http"
"strconv"
diff --git a/atsf_server/controller/misc.go b/atsf_server/controller/misc.go
index 6e4c15d1..d7368489 100644
--- a/atsf_server/controller/misc.go
+++ b/atsf_server/controller/misc.go
@@ -1,10 +1,10 @@
package controller
import (
+ "atsflare/common"
+ "atsflare/model"
"encoding/json"
"fmt"
- "gin-template/common"
- "gin-template/model"
"github.com/gin-gonic/gin"
"net/http"
)
diff --git a/atsf_server/controller/node.go b/atsf_server/controller/node.go
index cb48adb5..39943667 100644
--- a/atsf_server/controller/node.go
+++ b/atsf_server/controller/node.go
@@ -1,8 +1,8 @@
package controller
import (
+ "atsflare/service"
"encoding/json"
- "gin-template/service"
"github.com/gin-gonic/gin"
"net/http"
"strconv"
diff --git a/atsf_server/controller/option.go b/atsf_server/controller/option.go
index 394f2896..e627ec60 100644
--- a/atsf_server/controller/option.go
+++ b/atsf_server/controller/option.go
@@ -1,9 +1,9 @@
package controller
import (
+ "atsflare/common"
+ "atsflare/model"
"encoding/json"
- "gin-template/common"
- "gin-template/model"
"github.com/gin-gonic/gin"
"net/http"
"strings"
diff --git a/atsf_server/controller/proxy_route.go b/atsf_server/controller/proxy_route.go
index e5c273a9..7ddd2e28 100644
--- a/atsf_server/controller/proxy_route.go
+++ b/atsf_server/controller/proxy_route.go
@@ -1,8 +1,8 @@
package controller
import (
+ "atsflare/service"
"encoding/json"
- "gin-template/service"
"github.com/gin-gonic/gin"
"net/http"
"strconv"
diff --git a/atsf_server/controller/tls_certificate.go b/atsf_server/controller/tls_certificate.go
index 5dddbc1d..5b38c0ec 100644
--- a/atsf_server/controller/tls_certificate.go
+++ b/atsf_server/controller/tls_certificate.go
@@ -1,8 +1,8 @@
package controller
import (
+ "atsflare/service"
"encoding/json"
- "gin-template/service"
"github.com/gin-gonic/gin"
"net/http"
"strconv"
diff --git a/atsf_server/controller/user.go b/atsf_server/controller/user.go
index 767d3fc8..d22fb5bd 100644
--- a/atsf_server/controller/user.go
+++ b/atsf_server/controller/user.go
@@ -1,9 +1,9 @@
package controller
import (
+ "atsflare/common"
+ "atsflare/model"
"encoding/json"
- "gin-template/common"
- "gin-template/model"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
diff --git a/atsf_server/controller/wechat.go b/atsf_server/controller/wechat.go
index f7d8dfc2..04a9d17a 100644
--- a/atsf_server/controller/wechat.go
+++ b/atsf_server/controller/wechat.go
@@ -1,11 +1,11 @@
package controller
import (
+ "atsflare/common"
+ "atsflare/model"
"encoding/json"
"errors"
"fmt"
- "gin-template/common"
- "gin-template/model"
"github.com/gin-gonic/gin"
"net/http"
"strconv"
diff --git a/atsf_server/go.mod b/atsf_server/go.mod
index 7273f694..a3a40087 100644
--- a/atsf_server/go.mod
+++ b/atsf_server/go.mod
@@ -1,4 +1,4 @@
-module gin-template
+module atsflare
// +heroku goVersion go1.18
go 1.18
diff --git a/atsf_server/main.go b/atsf_server/main.go
index 056faeff..9444c350 100644
--- a/atsf_server/main.go
+++ b/atsf_server/main.go
@@ -1,85 +1,85 @@
-package main
-
-import (
- "embed"
- "fmt"
- "gin-template/common"
- "gin-template/middleware"
- "gin-template/model"
- "gin-template/router"
- "github.com/gin-contrib/sessions"
- "github.com/gin-contrib/sessions/cookie"
- "github.com/gin-contrib/sessions/redis"
- "github.com/gin-gonic/gin"
- "log"
- "os"
- "strconv"
-)
-
-//go:embed web/build
-var buildFS embed.FS
-
-//go:embed web/build/index.html
-var indexPage []byte
-
-func main() {
- common.SetupGinLog()
- common.SysLog("Gin Template " + common.Version + " started")
- if os.Getenv("GIN_MODE") != "debug" {
- gin.SetMode(gin.ReleaseMode)
- }
- // Initialize SQL Database
- err := model.InitDB()
- if err != nil {
- common.FatalLog(err)
- }
- defer func() {
- err := model.CloseDB()
- if err != nil {
- common.FatalLog(err)
- }
- }()
-
- // Initialize Redis
- err = common.InitRedisClient()
- if err != nil {
- common.FatalLog(err)
- }
-
- // Initialize options
- model.InitOptionMap()
-
- // Initialize HTTP server
- server := gin.Default()
- //server.Use(gzip.Gzip(gzip.DefaultCompression))
- server.Use(middleware.CORS())
-
- // Initialize session store
- if common.RedisEnabled {
- opt := common.ParseRedisOption()
- store, _ := redis.NewStore(opt.MinIdleConns, opt.Network, opt.Addr, opt.Password, []byte(common.SessionSecret))
- server.Use(sessions.Sessions("session", store))
- } else {
- store := cookie.NewStore([]byte(common.SessionSecret))
- server.Use(sessions.Sessions("session", store))
- }
-
- router.SetRouter(server, buildFS, indexPage)
- var port = os.Getenv("PORT")
- if port == "" {
- port = strconv.Itoa(*common.Port)
- }
- common.SysLog(fmt.Sprintf("server config: port=%s gin_mode=%s sqlite_path=%s redis_enabled=%t upload_path=%s log_dir=%s agent_token_configured=%t node_offline_threshold=%s", port, gin.Mode(), common.SQLitePath, common.RedisEnabled, common.UploadPath, valueOrDefault(*common.LogDir, "stdout"), common.AgentToken != "", common.NodeOfflineThreshold))
- common.SysLog(fmt.Sprintf("server listening on :%s", port))
- err = server.Run(":" + port)
- if err != nil {
- log.Println(err)
- }
-}
-
-func valueOrDefault(value string, fallback string) string {
- if value == "" {
- return fallback
- }
- return value
-}
+package main
+
+import (
+ "atsflare/common"
+ "atsflare/middleware"
+ "atsflare/model"
+ "atsflare/router"
+ "embed"
+ "fmt"
+ "github.com/gin-contrib/sessions"
+ "github.com/gin-contrib/sessions/cookie"
+ "github.com/gin-contrib/sessions/redis"
+ "github.com/gin-gonic/gin"
+ "log"
+ "os"
+ "strconv"
+)
+
+//go:embed web/build
+var buildFS embed.FS
+
+//go:embed web/build/index.html
+var indexPage []byte
+
+func main() {
+ common.SetupGinLog()
+ common.SysLog("ATSFlare " + common.Version + " started")
+ if os.Getenv("GIN_MODE") != "debug" {
+ gin.SetMode(gin.ReleaseMode)
+ }
+ // Initialize SQL Database
+ err := model.InitDB()
+ if err != nil {
+ common.FatalLog(err)
+ }
+ defer func() {
+ err := model.CloseDB()
+ if err != nil {
+ common.FatalLog(err)
+ }
+ }()
+
+ // Initialize Redis
+ err = common.InitRedisClient()
+ if err != nil {
+ common.FatalLog(err)
+ }
+
+ // Initialize options
+ model.InitOptionMap()
+
+ // Initialize HTTP server
+ server := gin.Default()
+ //server.Use(gzip.Gzip(gzip.DefaultCompression))
+ server.Use(middleware.CORS())
+
+ // Initialize session store
+ if common.RedisEnabled {
+ opt := common.ParseRedisOption()
+ store, _ := redis.NewStore(opt.MinIdleConns, opt.Network, opt.Addr, opt.Password, []byte(common.SessionSecret))
+ server.Use(sessions.Sessions("session", store))
+ } else {
+ store := cookie.NewStore([]byte(common.SessionSecret))
+ server.Use(sessions.Sessions("session", store))
+ }
+
+ router.SetRouter(server, buildFS, indexPage)
+ var port = os.Getenv("PORT")
+ if port == "" {
+ port = strconv.Itoa(*common.Port)
+ }
+ common.SysLog(fmt.Sprintf("server config: port=%s gin_mode=%s sqlite_path=%s redis_enabled=%t upload_path=%s log_dir=%s agent_token_configured=%t node_offline_threshold=%s", port, gin.Mode(), common.SQLitePath, common.RedisEnabled, common.UploadPath, valueOrDefault(*common.LogDir, "stdout"), common.AgentToken != "", common.NodeOfflineThreshold))
+ common.SysLog(fmt.Sprintf("server listening on :%s", port))
+ err = server.Run(":" + port)
+ if err != nil {
+ log.Println(err)
+ }
+}
+
+func valueOrDefault(value string, fallback string) string {
+ if value == "" {
+ return fallback
+ }
+ return value
+}
diff --git a/atsf_server/middleware/agent-auth.go b/atsf_server/middleware/agent-auth.go
index 5920a40b..d7827a98 100644
--- a/atsf_server/middleware/agent-auth.go
+++ b/atsf_server/middleware/agent-auth.go
@@ -1,7 +1,7 @@
package middleware
import (
- "gin-template/service"
+ "atsflare/service"
"github.com/gin-gonic/gin"
"net/http"
)
diff --git a/atsf_server/middleware/auth.go b/atsf_server/middleware/auth.go
index 07cedecd..9d387568 100644
--- a/atsf_server/middleware/auth.go
+++ b/atsf_server/middleware/auth.go
@@ -1,8 +1,8 @@
package middleware
import (
- "gin-template/common"
- "gin-template/model"
+ "atsflare/common"
+ "atsflare/model"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"net/http"
diff --git a/atsf_server/middleware/cors.go b/atsf_server/middleware/cors.go
index 170cca3e..f4737e97 100644
--- a/atsf_server/middleware/cors.go
+++ b/atsf_server/middleware/cors.go
@@ -7,6 +7,6 @@ import (
func CORS() gin.HandlerFunc {
config := cors.DefaultConfig()
- config.AllowOrigins = []string{"https://gin-template.vercel.app", "http://localhost:3000/"}
+ config.AllowOrigins = []string{"https://atsflare.vercel.app", "http://localhost:3000/"}
return cors.New(config)
}
diff --git a/atsf_server/middleware/rate-limit.go b/atsf_server/middleware/rate-limit.go
index 410ed19e..f5d04fc3 100644
--- a/atsf_server/middleware/rate-limit.go
+++ b/atsf_server/middleware/rate-limit.go
@@ -1,9 +1,9 @@
package middleware
import (
+ "atsflare/common"
"context"
"fmt"
- "gin-template/common"
"github.com/gin-gonic/gin"
"net/http"
"time"
diff --git a/atsf_server/middleware/turnstile-check.go b/atsf_server/middleware/turnstile-check.go
index b7401b79..92f570d4 100644
--- a/atsf_server/middleware/turnstile-check.go
+++ b/atsf_server/middleware/turnstile-check.go
@@ -1,8 +1,8 @@
package middleware
import (
+ "atsflare/common"
"encoding/json"
- "gin-template/common"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"net/http"
diff --git a/atsf_server/model/file.go b/atsf_server/model/file.go
index 56dceb13..0bea76be 100644
--- a/atsf_server/model/file.go
+++ b/atsf_server/model/file.go
@@ -1,50 +1,50 @@
-package model
-
-import (
- "gin-template/common"
- "gorm.io/gorm"
- "os"
- "path"
-)
-
-type File struct {
- Id int `json:"id"`
- Filename string `json:"filename" gorm:"index"`
- Description string `json:"description"`
- Uploader string `json:"uploader" gorm:"index"`
- UploaderId int `json:"uploader_id" gorm:"index"`
- Link string `json:"link" gorm:"unique;index"`
- UploadTime string `json:"upload_time"`
- DownloadCounter int `json:"download_counter"`
-}
-
-func GetAllFiles(startIdx int, num int) ([]*File, error) {
- var files []*File
- var err error
- err = DB.Order("id desc").Limit(num).Offset(startIdx).Find(&files).Error
- return files, err
-}
-
-func SearchFiles(keyword string) (files []*File, err error) {
- err = DB.Select([]string{"id", "filename", "description", "uploader", "uploader_id", "link", "upload_time", "download_counter"}).Where(
- "filename LIKE ? or uploader LIKE ? or uploader_id = ?", keyword+"%", keyword+"%", keyword).Find(&files).Error
- return files, err
-}
-
-func (file *File) Insert() error {
- var err error
- err = DB.Create(file).Error
- return err
-}
-
-// Delete Make sure link is valid! Because we will use os.Remove to delete it!
-func (file *File) Delete() error {
- var err error
- err = DB.Delete(file).Error
- err = os.Remove(path.Join(common.UploadPath, file.Link))
- return err
-}
-
-func UpdateDownloadCounter(link string) {
- DB.Model(&File{}).Where("link = ?", link).UpdateColumn("download_counter", gorm.Expr("download_counter + 1"))
-}
+package model
+
+import (
+ "atsflare/common"
+ "gorm.io/gorm"
+ "os"
+ "path"
+)
+
+type File struct {
+ Id int `json:"id"`
+ Filename string `json:"filename" gorm:"index"`
+ Description string `json:"description"`
+ Uploader string `json:"uploader" gorm:"index"`
+ UploaderId int `json:"uploader_id" gorm:"index"`
+ Link string `json:"link" gorm:"unique;index"`
+ UploadTime string `json:"upload_time"`
+ DownloadCounter int `json:"download_counter"`
+}
+
+func GetAllFiles(startIdx int, num int) ([]*File, error) {
+ var files []*File
+ var err error
+ err = DB.Order("id desc").Limit(num).Offset(startIdx).Find(&files).Error
+ return files, err
+}
+
+func SearchFiles(keyword string) (files []*File, err error) {
+ err = DB.Select([]string{"id", "filename", "description", "uploader", "uploader_id", "link", "upload_time", "download_counter"}).Where(
+ "filename LIKE ? or uploader LIKE ? or uploader_id = ?", keyword+"%", keyword+"%", keyword).Find(&files).Error
+ return files, err
+}
+
+func (file *File) Insert() error {
+ var err error
+ err = DB.Create(file).Error
+ return err
+}
+
+// Delete Make sure link is valid! Because we will use os.Remove to delete it!
+func (file *File) Delete() error {
+ var err error
+ err = DB.Delete(file).Error
+ err = os.Remove(path.Join(common.UploadPath, file.Link))
+ return err
+}
+
+func UpdateDownloadCounter(link string) {
+ DB.Model(&File{}).Where("link = ?", link).UpdateColumn("download_counter", gorm.Expr("download_counter + 1"))
+}
diff --git a/atsf_server/model/main.go b/atsf_server/model/main.go
index 335e450e..45146a5d 100644
--- a/atsf_server/model/main.go
+++ b/atsf_server/model/main.go
@@ -1,7 +1,7 @@
package model
import (
- "gin-template/common"
+ "atsflare/common"
"github.com/glebarez/sqlite"
"gorm.io/driver/mysql"
"gorm.io/gorm"
diff --git a/atsf_server/model/option.go b/atsf_server/model/option.go
index 8a89963e..20d3efb4 100644
--- a/atsf_server/model/option.go
+++ b/atsf_server/model/option.go
@@ -1,7 +1,7 @@
package model
import (
- "gin-template/common"
+ "atsflare/common"
"strconv"
"strings"
)
diff --git a/atsf_server/model/user.go b/atsf_server/model/user.go
index b5dd9900..7ce73904 100644
--- a/atsf_server/model/user.go
+++ b/atsf_server/model/user.go
@@ -1,8 +1,8 @@
package model
import (
+ "atsflare/common"
"errors"
- "gin-template/common"
"strings"
)
diff --git a/atsf_server/router/api-router.go b/atsf_server/router/api-router.go
index 8bdf7396..9022426f 100644
--- a/atsf_server/router/api-router.go
+++ b/atsf_server/router/api-router.go
@@ -1,8 +1,8 @@
package router
import (
- "gin-template/controller"
- "gin-template/middleware"
+ "atsflare/controller"
+ "atsflare/middleware"
"github.com/gin-gonic/gin"
)
diff --git a/atsf_server/router/api_phase1_test.go b/atsf_server/router/api_phase1_test.go
index d0f9d6ba..ea08fae5 100644
--- a/atsf_server/router/api_phase1_test.go
+++ b/atsf_server/router/api_phase1_test.go
@@ -1,6 +1,10 @@
package router_test
import (
+ "atsflare/common"
+ "atsflare/model"
+ "atsflare/router"
+ "atsflare/service"
"bytes"
"crypto/rand"
"crypto/rsa"
@@ -8,10 +12,6 @@ import (
"crypto/x509/pkix"
"encoding/json"
"encoding/pem"
- "gin-template/common"
- "gin-template/model"
- "gin-template/router"
- "gin-template/service"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
diff --git a/atsf_server/router/api_phase2_managed_domain_test.go b/atsf_server/router/api_phase2_managed_domain_test.go
index e8efd228..8b33bcc8 100644
--- a/atsf_server/router/api_phase2_managed_domain_test.go
+++ b/atsf_server/router/api_phase2_managed_domain_test.go
@@ -1,8 +1,8 @@
package router_test
import (
- "gin-template/common"
- "gin-template/router"
+ "atsflare/common"
+ "atsflare/router"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
diff --git a/atsf_server/router/api_phase2_test.go b/atsf_server/router/api_phase2_test.go
index aad77515..8eb4b387 100644
--- a/atsf_server/router/api_phase2_test.go
+++ b/atsf_server/router/api_phase2_test.go
@@ -1,12 +1,12 @@
package router_test
import (
+ "atsflare/common"
+ "atsflare/model"
+ "atsflare/router"
+ "atsflare/service"
"bytes"
"encoding/json"
- "gin-template/common"
- "gin-template/model"
- "gin-template/router"
- "gin-template/service"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
diff --git a/atsf_server/router/web-router.go b/atsf_server/router/web-router.go
index 1cb06633..ff836efb 100644
--- a/atsf_server/router/web-router.go
+++ b/atsf_server/router/web-router.go
@@ -1,10 +1,10 @@
package router
import (
+ "atsflare/common"
+ "atsflare/controller"
+ "atsflare/middleware"
"embed"
- "gin-template/common"
- "gin-template/controller"
- "gin-template/middleware"
"github.com/gin-contrib/static"
"github.com/gin-gonic/gin"
"net/http"
diff --git a/atsf_server/service/agent.go b/atsf_server/service/agent.go
index 3606c2a6..c21ad13b 100644
--- a/atsf_server/service/agent.go
+++ b/atsf_server/service/agent.go
@@ -1,10 +1,10 @@
package service
import (
+ "atsflare/common"
+ "atsflare/model"
"encoding/json"
"errors"
- "gin-template/common"
- "gin-template/model"
"strings"
"time"
diff --git a/atsf_server/service/config_version.go b/atsf_server/service/config_version.go
index 95dfe702..f0601a9d 100644
--- a/atsf_server/service/config_version.go
+++ b/atsf_server/service/config_version.go
@@ -1,12 +1,12 @@
package service
import (
+ "atsflare/model"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
- "gin-template/model"
"sort"
"strings"
"time"
diff --git a/atsf_server/service/https_phase1_test.go b/atsf_server/service/https_phase1_test.go
index 71f87601..4945506e 100644
--- a/atsf_server/service/https_phase1_test.go
+++ b/atsf_server/service/https_phase1_test.go
@@ -1,13 +1,13 @@
package service
import (
+ "atsflare/common"
+ "atsflare/model"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
- "gin-template/common"
- "gin-template/model"
"math/big"
"path/filepath"
"strings"
diff --git a/atsf_server/service/managed_domain.go b/atsf_server/service/managed_domain.go
index 7543d9a5..2901c525 100644
--- a/atsf_server/service/managed_domain.go
+++ b/atsf_server/service/managed_domain.go
@@ -1,9 +1,9 @@
package service
import (
+ "atsflare/model"
"errors"
"fmt"
- "gin-template/model"
"sort"
"strings"
"unicode"
diff --git a/atsf_server/service/node.go b/atsf_server/service/node.go
index d432602d..b6e8fc2e 100644
--- a/atsf_server/service/node.go
+++ b/atsf_server/service/node.go
@@ -1,11 +1,11 @@
package service
import (
+ "atsflare/common"
+ "atsflare/model"
"crypto/rand"
"encoding/hex"
"errors"
- "gin-template/common"
- "gin-template/model"
"strings"
"time"
)
diff --git a/atsf_server/service/proxy_route.go b/atsf_server/service/proxy_route.go
index 42fb6daa..2d4e2d5e 100644
--- a/atsf_server/service/proxy_route.go
+++ b/atsf_server/service/proxy_route.go
@@ -1,9 +1,9 @@
package service
import (
+ "atsflare/model"
"encoding/json"
"errors"
- "gin-template/model"
"net/url"
"regexp"
"strings"
diff --git a/atsf_server/service/tls_certificate.go b/atsf_server/service/tls_certificate.go
index 1948be73..2400c157 100644
--- a/atsf_server/service/tls_certificate.go
+++ b/atsf_server/service/tls_certificate.go
@@ -1,10 +1,10 @@
package service
import (
+ "atsflare/model"
"crypto/tls"
"errors"
"fmt"
- "gin-template/model"
"mime/multipart"
"strings"
)
diff --git a/atsf_server/web/src/App.js b/atsf_server/web/src/App.js
index 38ed8f3f..c9836599 100644
--- a/atsf_server/web/src/App.js
+++ b/atsf_server/web/src/App.js
@@ -41,9 +41,7 @@ function App() {
const res = await API.get('/api/status');
const { success, data } = res.data;
if (success) {
- console.log(
- `GitHub 仓库地址:https://github.com/songquanpeng/gin-template`
- );
+ console.log(`GitHub 仓库地址:https://github.com/Rain-kl/ATSFlare`);
localStorage.setItem('status', JSON.stringify(data));
statusDispatch({ type: 'set', payload: data });
localStorage.setItem('system_name', data.system_name);
diff --git a/atsf_server/web/src/components/Footer.js b/atsf_server/web/src/components/Footer.js
index 854211ec..a744947a 100644
--- a/atsf_server/web/src/components/Footer.js
+++ b/atsf_server/web/src/components/Footer.js
@@ -1,41 +1,38 @@
-import React from 'react';
-
-import { Container, Segment } from 'semantic-ui-react';
-import { getFooterHTML, getSystemName } from '../helpers';
-
-const Footer = () => {
- const systemName = getSystemName();
- const footer = getFooterHTML();
-
- return (
-
-
- {footer ? (
-
- ) : (
-
- )}
-
-
- );
-};
-
-export default Footer;
+import React from 'react';
+
+import { Container, Segment } from 'semantic-ui-react';
+import { getFooterHTML, getSystemName } from '../helpers';
+
+const Footer = () => {
+ const systemName = getSystemName();
+ const footer = getFooterHTML();
+
+ return (
+
+
+ {footer ? (
+
+ ) : (
+
+ )}
+
+
+ );
+};
+
+export default Footer;
diff --git a/atsf_server/web/src/components/OtherSetting.js b/atsf_server/web/src/components/OtherSetting.js
index 8d6b833a..d2c2b020 100644
--- a/atsf_server/web/src/components/OtherSetting.js
+++ b/atsf_server/web/src/components/OtherSetting.js
@@ -1,190 +1,189 @@
-import React, { useEffect, useState } from 'react';
-import { Button, Divider, Form, Grid, Header, Modal } from 'semantic-ui-react';
-import { API, showError, showSuccess } from '../helpers';
-import { marked } from 'marked';
-
-const OtherSetting = () => {
- let [inputs, setInputs] = useState({
- Footer: '',
- Notice: '',
- About: '',
- SystemName: '',
- HomePageLink: '',
- });
- let [loading, setLoading] = useState(false);
- const [showUpdateModal, setShowUpdateModal] = useState(false);
- const [updateData, setUpdateData] = useState({
- tag_name: '',
- content: '',
- });
-
- const getOptions = async () => {
- const res = await API.get('/api/option/');
- const { success, message, data } = res.data;
- if (success) {
- let newInputs = {};
- data.forEach((item) => {
- if (item.key in inputs) {
- newInputs[item.key] = item.value;
- }
- });
- setInputs(newInputs);
- } else {
- showError(message);
- }
- };
-
- useEffect(() => {
- getOptions().then();
- }, []);
-
- const updateOption = async (key, value) => {
- setLoading(true);
- const res = await API.put('/api/option', {
- key,
- value,
- });
- const { success, message } = res.data;
- if (success) {
- setInputs((inputs) => ({ ...inputs, [key]: value }));
- } else {
- showError(message);
- }
- setLoading(false);
- };
-
- const handleInputChange = async (e, { name, value }) => {
- setInputs((inputs) => ({ ...inputs, [name]: value }));
- };
-
- const submitNotice = async () => {
- await updateOption('Notice', inputs.Notice);
- };
-
- const submitFooter = async () => {
- await updateOption('Footer', inputs.Footer);
- };
-
- const submitSystemName = async () => {
- await updateOption('SystemName', inputs.SystemName);
- };
-
- const submitHomePageLink = async () => {
- await updateOption('HomePageLink', inputs.HomePageLink);
- };
-
- const submitAbout = async () => {
- await updateOption('About', inputs.About);
- };
-
- const openGitHubRelease = () => {
- window.location =
- 'https://github.com/songquanpeng/gin-template/releases/latest';
- };
-
- const checkUpdate = async () => {
- const res = await API.get(
- 'https://api.github.com/repos/songquanpeng/gin-template/releases/latest'
- );
- const { tag_name, body } = res.data;
- if (tag_name === process.env.REACT_APP_VERSION) {
- showSuccess(`已是最新版本:${tag_name}`);
- } else {
- setUpdateData({
- tag_name: tag_name,
- content: marked.parse(body),
- });
- setShowUpdateModal(true);
- }
- };
-
- return (
-
-
- 检查更新
-
-
-
- 保存公告
-
-
-
-
-
- 设置系统名称
-
-
-
- 设置首页链接
-
-
-
- 保存关于
-
-
-
- 设置页脚
-
-
- setShowUpdateModal(false)}
- onOpen={() => setShowUpdateModal(true)}
- open={showUpdateModal}
- >
- 新版本:{updateData.tag_name}
-
-
-
-
-
-
- setShowUpdateModal(false)}>关闭
- {
- setShowUpdateModal(false);
- openGitHubRelease();
- }}
- />
-
-
-
- );
-};
-
-export default OtherSetting;
+import React, { useEffect, useState } from 'react';
+import { Button, Divider, Form, Grid, Header, Modal } from 'semantic-ui-react';
+import { API, showError, showSuccess } from '../helpers';
+import { marked } from 'marked';
+
+const OtherSetting = () => {
+ let [inputs, setInputs] = useState({
+ Footer: '',
+ Notice: '',
+ About: '',
+ SystemName: '',
+ HomePageLink: '',
+ });
+ let [loading, setLoading] = useState(false);
+ const [showUpdateModal, setShowUpdateModal] = useState(false);
+ const [updateData, setUpdateData] = useState({
+ tag_name: '',
+ content: '',
+ });
+
+ const getOptions = async () => {
+ const res = await API.get('/api/option/');
+ const { success, message, data } = res.data;
+ if (success) {
+ let newInputs = {};
+ data.forEach((item) => {
+ if (item.key in inputs) {
+ newInputs[item.key] = item.value;
+ }
+ });
+ setInputs(newInputs);
+ } else {
+ showError(message);
+ }
+ };
+
+ useEffect(() => {
+ getOptions().then();
+ }, []);
+
+ const updateOption = async (key, value) => {
+ setLoading(true);
+ const res = await API.put('/api/option', {
+ key,
+ value,
+ });
+ const { success, message } = res.data;
+ if (success) {
+ setInputs((inputs) => ({ ...inputs, [key]: value }));
+ } else {
+ showError(message);
+ }
+ setLoading(false);
+ };
+
+ const handleInputChange = async (e, { name, value }) => {
+ setInputs((inputs) => ({ ...inputs, [name]: value }));
+ };
+
+ const submitNotice = async () => {
+ await updateOption('Notice', inputs.Notice);
+ };
+
+ const submitFooter = async () => {
+ await updateOption('Footer', inputs.Footer);
+ };
+
+ const submitSystemName = async () => {
+ await updateOption('SystemName', inputs.SystemName);
+ };
+
+ const submitHomePageLink = async () => {
+ await updateOption('HomePageLink', inputs.HomePageLink);
+ };
+
+ const submitAbout = async () => {
+ await updateOption('About', inputs.About);
+ };
+
+ const openGitHubRelease = () => {
+ window.location = 'https://github.com/Rain-kl/ATSFlare/releases/latest';
+ };
+
+ const checkUpdate = async () => {
+ const res = await API.get(
+ 'https://api.github.com/repos/Rain-kl/ATSFlare/releases/latest'
+ );
+ const { tag_name, body } = res.data;
+ if (tag_name === process.env.REACT_APP_VERSION) {
+ showSuccess(`已是最新版本:${tag_name}`);
+ } else {
+ setUpdateData({
+ tag_name: tag_name,
+ content: marked.parse(body),
+ });
+ setShowUpdateModal(true);
+ }
+ };
+
+ return (
+
+
+ 检查更新
+
+
+
+ 保存公告
+
+
+
+
+
+ 设置系统名称
+
+
+
+ 设置首页链接
+
+
+
+ 保存关于
+
+
+
+ 设置页脚
+
+
+ setShowUpdateModal(false)}
+ onOpen={() => setShowUpdateModal(true)}
+ open={showUpdateModal}
+ >
+ 新版本:{updateData.tag_name}
+
+
+
+
+
+
+ setShowUpdateModal(false)}>关闭
+ {
+ setShowUpdateModal(false);
+ openGitHubRelease();
+ }}
+ />
+
+
+
+ );
+};
+
+export default OtherSetting;
diff --git a/atsf_server/web/src/pages/About/index.js b/atsf_server/web/src/pages/About/index.js
index de357540..e216f37a 100644
--- a/atsf_server/web/src/pages/About/index.js
+++ b/atsf_server/web/src/pages/About/index.js
@@ -1,51 +1,51 @@
-import React, { useEffect, useState } from 'react';
-import { Header, Segment } from 'semantic-ui-react';
-import { API, showError } from '../../helpers';
-import { marked } from 'marked';
-
-const About = () => {
- const [about, setAbout] = useState('');
- const [aboutLoaded, setAboutLoaded] = useState(false);
-
- const displayAbout = async () => {
- setAbout(localStorage.getItem('about') || '');
- const res = await API.get('/api/about');
- const { success, message, data } = res.data;
- if (success) {
- let HTMLAbout = marked.parse(data);
- setAbout(HTMLAbout);
- localStorage.setItem('about', HTMLAbout);
- } else {
- showError(message);
- setAbout('加载关于内容失败...');
- }
- setAboutLoaded(true);
- };
-
- useEffect(() => {
- displayAbout().then();
- }, []);
-
- return (
- <>
-
- {aboutLoaded && about === '' ? (
- <>
-
- 可在设置页面设置关于内容,支持 HTML & Markdown
- 项目仓库地址:
-
- https://github.com/songquanpeng/gin-template
-
- >
- ) : (
- <>
-
- >
- )}
-
- >
- );
-};
-
-export default About;
+import React, { useEffect, useState } from 'react';
+import { Header, Segment } from 'semantic-ui-react';
+import { API, showError } from '../../helpers';
+import { marked } from 'marked';
+
+const About = () => {
+ const [about, setAbout] = useState('');
+ const [aboutLoaded, setAboutLoaded] = useState(false);
+
+ const displayAbout = async () => {
+ setAbout(localStorage.getItem('about') || '');
+ const res = await API.get('/api/about');
+ const { success, message, data } = res.data;
+ if (success) {
+ let HTMLAbout = marked.parse(data);
+ setAbout(HTMLAbout);
+ localStorage.setItem('about', HTMLAbout);
+ } else {
+ showError(message);
+ setAbout('加载关于内容失败...');
+ }
+ setAboutLoaded(true);
+ };
+
+ useEffect(() => {
+ displayAbout().then();
+ }, []);
+
+ return (
+ <>
+
+ {aboutLoaded && about === '' ? (
+ <>
+
+ 可在设置页面设置关于内容,支持 HTML & Markdown
+ 项目仓库地址:
+
+ https://github.com/Rain-kl/ATSFlare
+
+ >
+ ) : (
+ <>
+
+ >
+ )}
+
+ >
+ );
+};
+
+export default About;
diff --git a/atsf_server/web/src/pages/Home/index.js b/atsf_server/web/src/pages/Home/index.js
index 0abf4643..01d8eeb5 100644
--- a/atsf_server/web/src/pages/Home/index.js
+++ b/atsf_server/web/src/pages/Home/index.js
@@ -1,110 +1,110 @@
-import React, { useContext, useEffect } from 'react';
-import { Card, Grid, Header, Segment } from 'semantic-ui-react';
-import { API, showError, showNotice, timestamp2string } from '../../helpers';
-import { StatusContext } from '../../context/Status';
-
-const Home = () => {
- const [statusState, statusDispatch] = useContext(StatusContext);
- const homePageLink = localStorage.getItem('home_page_link') || '';
-
- const displayNotice = async () => {
- const res = await API.get('/api/notice');
- const { success, message, data } = res.data;
- if (success) {
- let oldNotice = localStorage.getItem('notice');
- if (data !== oldNotice && data !== '') {
- showNotice(data);
- localStorage.setItem('notice', data);
- }
- } else {
- showError(message);
- }
- };
-
- const getStartTimeString = () => {
- const timestamp = statusState?.status?.start_time;
- return timestamp2string(timestamp);
- };
-
- useEffect(() => {
- displayNotice().then();
- }, []);
- return (
- <>
- {homePageLink !== '' ? (
- <>
-
- >
- ) : (
- <>
-
-
-
-
-
-
- 系统信息
- 系统信息总览
-
- 名称:{statusState?.status?.system_name}
- 版本:{statusState?.status?.version}
-
- 源码:
-
- https://github.com/songquanpeng/gin-template
-
-
- 启动时间:{getStartTimeString()}
-
-
-
-
-
-
-
- 系统配置
- 系统配置总览
-
-
- 邮箱验证:
- {statusState?.status?.email_verification === true
- ? '已启用'
- : '未启用'}
-
-
- GitHub 身份验证:
- {statusState?.status?.github_oauth === true
- ? '已启用'
- : '未启用'}
-
-
- 微信身份验证:
- {statusState?.status?.wechat_login === true
- ? '已启用'
- : '未启用'}
-
-
- Turnstile 用户校验:
- {statusState?.status?.turnstile_check === true
- ? '已启用'
- : '未启用'}
-
-
-
-
-
-
-
- >
- )}
- >
- );
-};
-
-export default Home;
+import React, { useContext, useEffect } from 'react';
+import { Card, Grid, Header, Segment } from 'semantic-ui-react';
+import { API, showError, showNotice, timestamp2string } from '../../helpers';
+import { StatusContext } from '../../context/Status';
+
+const Home = () => {
+ const [statusState, statusDispatch] = useContext(StatusContext);
+ const homePageLink = localStorage.getItem('home_page_link') || '';
+
+ const displayNotice = async () => {
+ const res = await API.get('/api/notice');
+ const { success, message, data } = res.data;
+ if (success) {
+ let oldNotice = localStorage.getItem('notice');
+ if (data !== oldNotice && data !== '') {
+ showNotice(data);
+ localStorage.setItem('notice', data);
+ }
+ } else {
+ showError(message);
+ }
+ };
+
+ const getStartTimeString = () => {
+ const timestamp = statusState?.status?.start_time;
+ return timestamp2string(timestamp);
+ };
+
+ useEffect(() => {
+ displayNotice().then();
+ }, []);
+ return (
+ <>
+ {homePageLink !== '' ? (
+ <>
+
+ >
+ ) : (
+ <>
+
+
+
+
+
+
+ 系统信息
+ 系统信息总览
+
+ 名称:{statusState?.status?.system_name}
+ 版本:{statusState?.status?.version}
+
+ 源码:
+
+ https://github.com/Rain-kl/ATSFlare
+
+
+ 启动时间:{getStartTimeString()}
+
+
+
+
+
+
+
+ 系统配置
+ 系统配置总览
+
+
+ 邮箱验证:
+ {statusState?.status?.email_verification === true
+ ? '已启用'
+ : '未启用'}
+
+
+ GitHub 身份验证:
+ {statusState?.status?.github_oauth === true
+ ? '已启用'
+ : '未启用'}
+
+
+ 微信身份验证:
+ {statusState?.status?.wechat_login === true
+ ? '已启用'
+ : '未启用'}
+
+
+ Turnstile 用户校验:
+ {statusState?.status?.turnstile_check === true
+ ? '已启用'
+ : '未启用'}
+
+
+
+
+
+
+
+ >
+ )}
+ >
+ );
+};
+
+export default Home;
diff --git a/docs/deployment.md b/docs/deployment.md
index dc127a83..59537dd7 100644
--- a/docs/deployment.md
+++ b/docs/deployment.md
@@ -40,13 +40,13 @@ npm run build
```bash
cd atsf_server
export SESSION_SECRET='replace-with-random-string'
-export SQLITE_PATH='./gin-template.db'
+export SQLITE_PATH='./atsflare.db'
go run .
```
说明:
-- 如果未设置 `SQLITE_PATH`,默认也会落到 `atsf_server/gin-template.db`
+- 如果未设置 `SQLITE_PATH`,默认也会落到 `atsf_server/atsflare.db`
- 当前不再依赖全局 `AGENT_TOKEN` 环境变量
- 节点接入凭证改由数据库保存:节点专属 `agent_token` + 系统级 `discovery token`
- 当前默认监听端口为 `3000`
diff --git a/docs/design.md b/docs/design.md
index 40f8794a..698d72d7 100644
--- a/docs/design.md
+++ b/docs/design.md
@@ -94,12 +94,12 @@
### Server
-控制中心直接基于现有 `atsf_server` 的 `gin-template` 工程开发:
+控制中心直接基于现有 `atsf_server` 的 `ATSFlare` 工程开发:
* Web 框架:Gin
* ORM:GORM
* 前端:沿用现有 web 管理端
-* 鉴权:沿用 gin-template 登录体系
+* 鉴权:沿用 ATSFlare 登录体系
### 数据库
@@ -139,7 +139,7 @@ Agent 使用 Go 单体程序:
```text
┌────────────────────────────┐
│ ATSFlare Server │
- │ gin-template + SQLite │
+ │ ATSFlare + SQLite │
│ Admin UI + Admin API │
└──────────────┬─────────────┘
│
@@ -548,7 +548,7 @@ Agent 每次上报:
管理端:
-* 直接沿用 gin-template 的登录态
+* 直接沿用 ATSFlare 的登录态
Agent(第一版):
@@ -567,7 +567,7 @@ Agent(第二版):
### 12.1 登录页
-沿用 gin-template 现有登录。
+沿用 ATSFlare 现有登录。
### 12.2 反代规则页(第一版,已实现)
diff --git a/docs/development-guidelines.md b/docs/development-guidelines.md
index 76cff819..ce5ec3a3 100644
--- a/docs/development-guidelines.md
+++ b/docs/development-guidelines.md
@@ -41,7 +41,7 @@
* ORM:GORM
* 数据库:SQLite
* 前端:现有 `atsf_server/web`
-* 登录体系:沿用 gin-template 现有能力
+* 登录体系:沿用 ATSFlare 现有能力
约束:
@@ -126,7 +126,7 @@ Agent 放在 `atsf_agent`,使用 Go 单体程序开发。
* 所有发布都是"新版本激活",不是在线覆盖编辑。
* 第一版与第二版:所有节点默认拉同一份全量配置,不做节点分组差异化下发。
* 能用 SQLite 解决的问题,不引入额外中间件。
-* 新功能优先复用现有 gin-template 结构,不平行造第二套框架。
+* 新功能优先复用现有 ATSFlare 结构,不平行造第二套框架。
## 5. 数据模型规范
@@ -205,7 +205,7 @@ Server 代码按以下职责拆分:
管理端:
-* 继续复用 gin-template 的登录、角色和 session 体系
+* 继续复用 ATSFlare 的登录、角色和 session 体系
Agent(第一版):
diff --git a/docs/development-plan.md b/docs/development-plan.md
index b3851d32..f176be23 100644
--- a/docs/development-plan.md
+++ b/docs/development-plan.md
@@ -138,7 +138,7 @@ MVP 已于第一版完成。当前进入第二版迭代。
* 节点配置文件填写节点专属 `agent_token` 时,可直接上线;若 `agent_token` 为空且填写全局 discovery token,则会自动注册并完成 token 置换
-### V2 Phase 4: 路由自定义头
+### V2 Phase 4: 路由自定义头 ✅
目标:
@@ -155,7 +155,7 @@ MVP 已于第一版完成。当前进入第二版迭代。
* 路由配置自定义头后发布,渲染结果包含对应 `proxy_set_header` 指令
* 不配置自定义头的路由渲染行为与之前保持一致
-### V2 Phase 5: 配置预览与变更摘要
+### V2 Phase 5: 配置预览与变更摘要 ✅
目标: