Compare commits

...

22 Commits

Author SHA1 Message Date
lejianwen
1dd4df3a1c chore(buildTest): add start.bat to run on windows 2024-12-27 20:13:55 +08:00
lejianwen
c7d44cc253 fix(build): add start.bat to run on windows(#89) 2024-12-27 20:09:08 +08:00
lejianwen
5082ab1893 refactor(admin): Move Admin Web Route to user model 2024-12-27 19:27:33 +08:00
lejianwen
e8b2425222 feat(admin): Add My Login log 2024-12-27 19:25:59 +08:00
lejianwen
09d12cefd8 feat(admin): Support Markdown to welcome msg 2024-12-25 19:21:50 +08:00
lejianwen
5f1166965d fix(api): Get ab list when personal is disabled (#86) 2024-12-25 19:04:42 +08:00
lejianwen
0dbab182e9 fix(webclient): share fail when expire is 0
Closes: #88
2024-12-25 15:01:03 +08:00
lejianwen
512f3f99fd fix(build): fix build_test.yml 2024-12-25 14:06:29 +08:00
lejianwen
6fb4fad705 fix(build): up build.yml to build deb 2024-12-25 13:20:12 +08:00
lejianwen
fa92529e9b chore(build): up build.yml to build deb 2024-12-25 12:57:11 +08:00
Follow the wind
d6c6051a6c feat(build): 添加构建deb包相关基础 (#87)
* 添加构建deb包相关基础

* 补齐工作流,等待验证

* 修复构建时没有创建的data目录保障deb包构建

* 修复其余架构deb包构建中的依赖错误

* 修复:由于小改工作流导致写错架构的问题

* 修复拼写错误导致的目录错误

* 添加上传工件,和发布rel工作流,完成相关事务

---------

Co-authored-by: ymwl <ymwlpoolc@qq.com>
2024-12-25 12:28:51 +08:00
lejianwen
ce063bd3ac feat(webclient): v1.3.5 -> v1.3.6 2024-12-24 10:25:47 +08:00
lejianwen
4468894dfb chore(changelog): up build.yml to generate changelog 2024-12-22 14:14:51 +08:00
lejianwen
8b00b919ad chore(changelog): up build.yml to generate changelog 2024-12-22 14:04:23 +08:00
64f4a6dfac feat(i18n): Merge pull request #85 from jimmyGALLAND/trans-fr
add locale french
2024-12-22 13:57:56 +08:00
jimmyGALLAND
6faa5153b6 add locale french 2024-12-21 22:56:48 +01:00
lejianwen
a771b1e9b0 fix(webclient): remove console.log when query online by new 2024-12-21 21:49:03 +08:00
lejianwen
7750f9c54d chore(changelog): up build.yml to add changelog 2024-12-21 21:39:11 +08:00
lejianwen
b2d24ee67b docs(webclient): up readme 2024-12-21 21:31:54 +08:00
lejianwen
589a2a5123 feat(webclient): add new query_online function
There may be a loss of performance
Therefore, it is not enabled by default
2024-12-21 21:15:06 +08:00
lejianwen
184d3d357d optimize add ab from peer #84 2024-12-20 11:11:32 +08:00
lejianwen
50b3d85270 up docs and readme 2024-12-18 14:28:06 +08:00
46 changed files with 45324 additions and 44488 deletions

View File

@@ -55,6 +55,13 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/checkout@v4
with:
repository: lejianwen/rustdesk-api-web
path: rustdesk-api-web
ref: master
- name: Set up Go environment
uses: actions/setup-go@v4
@@ -66,14 +73,12 @@ jobs:
with:
node-version: '20'
- name: build rustdesk-api-web
working-directory: rustdesk-api-web
run: |
git clone ${{ env.WEBCLIENT_SOURCE_LOCATION }}
cd rustdesk-api-web
npm install
npm run build
mkdir ../resources/admin/ -p
mkdir -p ../resources/admin/
cp -ar dist/* ../resources/admin/
- name: tidy
@@ -96,6 +101,8 @@ jobs:
if [ "${{ matrix.job.goos }}" = "windows" ]; then
sudo apt-get install gcc-mingw-w64-x86-64 zip -y
GOOS=${{ matrix.job.goos }} GOARCH=${{ matrix.job.platform }} CC=x86_64-w64-mingw32-gcc CGO_LDFLAGS="-static" CGO_ENABLED=1 go build -ldflags "-s -w" -o ./release/apimain.exe ./cmd/apimain.go
echo @echo off > release/start.bat
echo cmd /c \"%~dp0apimain.exe\" >> release/start.bat
zip -r ${{ matrix.job.goos}}-${{ matrix.job.platform }}.${{matrix.job.file_ext}} ./release
else
if [ "${{ matrix.job.platform }}" = "arm64" ]; then
@@ -121,15 +128,92 @@ jobs:
name: rustdesk-api-${{ matrix.job.goos }}-${{ matrix.job.platform }}
path: |
${{ matrix.job.goos}}-${{ matrix.job.platform }}.${{matrix.job.file_ext}}
- name: Upload to GitHub Release
uses: softprops/action-gh-release@v2
with:
files: |
${{ matrix.job.goos}}-${{ matrix.job.platform }}.${{matrix.job.file_ext}}
# tag_name: ${{ env.LATEST_TAG }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Generate Changelog
run: npx changelogithub # or changelogithub@0.12 if ensure the stable result
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
deb-package:
name: debian package - ${{ matrix.job.platform }}
needs: build
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
job:
- { platform: "amd64", goos: "linux", debian_platform: "amd64", crossbuild_package: ""}
- { platform: "arm64", goos: "linux", debian_platform: "arm64", crossbuild_package: "crossbuild-essential-arm64" }
- { platform: "armv7l", goos: "linux", debian_platform: "armhf", crossbuild_package: "crossbuild-essential-armhf" }
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Create packaging env
run: |
sudo apt update
DEBIAN_FRONTEND=noninteractive sudo apt install -y devscripts build-essential debhelper pkg-config ${{ matrix.job.crossbuild_package }}
mkdir -p debian-build/${{ matrix.job.platform }}/bin
- name: Get tag version
id: get_tag
run: |
TAG_VERSION="${GITHUB_REF##*/}"
VERSION="${TAG_VERSION#v}"
echo "TAG_VERSION=$TAG_VERSION" >> $GITHUB_ENV
echo "VERSION=$VERSION" >> $GITHUB_ENV
- name: Update changelog
run: |
DATE=$(date -R)
sed -i "1i rustdesk-api-server (${VERSION}) stable; urgency=medium\n\n * Automatically generated release for version ${VERSION}.\n\n -- GitHub Actions <actions@github.com> ${DATE}\n" debian/changelog
- name: Download binaries
uses: actions/download-artifact@v4
with:
name: rustdesk-api-${{ matrix.job.goos }}-${{ matrix.job.platform }}
path: .
- name: Unzip binaries
run: |
mkdir -p ${{ matrix.job.platform }}
tar -xzf ${{ matrix.job.goos }}-${{ matrix.job.platform }}.tar.gz -C ${{ matrix.job.platform }}
- name: Build package for ${{ matrix.job.platform }} arch
run: |
mv ${{ matrix.job.platform }}/release/apimain debian-build/${{ matrix.job.platform }}/bin/rustdesk-api
chmod -v a+x debian-build/${{ matrix.job.platform }}/bin/*
mkdir -p data
cp -vr debian systemd conf data resources runtime debian-build/${{ matrix.job.platform }}/
cat debian/control.tpl | sed 's/{{ ARCH }}/${{ matrix.job.debian_platform }}/' > debian-build/${{ matrix.job.platform }}/debian/control
cd debian-build/${{ matrix.job.platform }}/
debuild -i -us -uc -b -a${{ matrix.job.debian_platform}}
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: rustdesk-api-${{ matrix.job.debian_platform }}
path: |
debian-build/*.deb
- name: Create Release
uses: softprops/action-gh-release@v2
with:
files: |
debian-build/rustdesk-api-server_*_${{ matrix.job.debian_platform }}.deb
docker:
name: Push Docker Image
needs: build
@@ -191,7 +275,6 @@ jobs:
run: |
mkdir -p ${{ matrix.job.platform }}
tar -xzf ${{ matrix.job.goos }}-${{ matrix.job.platform }}.tar.gz -C ${{ matrix.job.platform }}
file ${{ matrix.job.platform }}/apimain
- name: Build and push Docker image to Docker Hub ${{ matrix.job.platform }}
if: ${{ env.SKIP_DOCKER_HUB == 'false' }} # Only run this step if SKIP_DOCKER_HUB is false

View File

@@ -52,6 +52,12 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
repository: lejianwen/rustdesk-api-web
path: rustdesk-api-web
ref: master
- name: Set up Go environment
uses: actions/setup-go@v4
with:
@@ -62,14 +68,12 @@ jobs:
with:
node-version: '20'
- name: build rustdesk-api-web
working-directory: rustdesk-api-web
run: |
git clone ${{ env.WEBCLIENT_SOURCE_LOCATION }}
cd rustdesk-api-web
npm install
npm run build
mkdir ../resources/admin/ -p
mkdir -p ../resources/admin/
cp -ar dist/* ../resources/admin/
- name: tidy
@@ -92,6 +96,8 @@ jobs:
if [ "${{ matrix.job.goos }}" = "windows" ]; then
sudo apt-get install gcc-mingw-w64-x86-64 zip -y
GOOS=${{ matrix.job.goos }} GOARCH=${{ matrix.job.platform }} CC=x86_64-w64-mingw32-gcc CGO_LDFLAGS="-static" CGO_ENABLED=1 go build -ldflags "-s -w" -o ./release/apimain.exe ./cmd/apimain.go
echo @echo off > release/start.bat
echo cmd /c \"%~dp0apimain.exe\" >> release/start.bat
zip -r ${{ matrix.job.goos}}-${{ matrix.job.platform }}.${{matrix.job.file_ext}} ./release
else
if [ "${{ matrix.job.platform }}" = "arm64" ]; then
@@ -117,6 +123,7 @@ jobs:
name: rustdesk-api-${{ matrix.job.goos }}-${{ matrix.job.platform }}
path: |
${{ matrix.job.goos}}-${{ matrix.job.platform }}.${{matrix.job.file_ext}}
- name: Upload to GitHub Release
uses: softprops/action-gh-release@v2
with:
@@ -126,6 +133,66 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
deb-package:
name: debian package - ${{ matrix.job.platform }}
needs: build
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
job:
- { platform: "amd64", goos: "linux", debian_platform: "amd64", crossbuild_package: ""}
- { platform: "arm64", goos: "linux", debian_platform: "arm64", crossbuild_package: "crossbuild-essential-arm64" }
- { platform: "armv7l", goos: "linux", debian_platform: "armhf", crossbuild_package: "crossbuild-essential-armhf" }
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Create packaging env
run: |
sudo apt update
DEBIAN_FRONTEND=noninteractive sudo apt install -y devscripts build-essential debhelper pkg-config ${{ matrix.job.crossbuild_package }}
mkdir -p debian-build/${{ matrix.job.platform }}/bin
- name: Download binaries
uses: actions/download-artifact@v4
with:
name: rustdesk-api-${{ matrix.job.goos }}-${{ matrix.job.platform }}
path: .
- name: Unzip binaries
run: |
mkdir -p ${{ matrix.job.platform }}
tar -xzf ${{ matrix.job.goos }}-${{ matrix.job.platform }}.tar.gz -C ${{ matrix.job.platform }}
- name: Build package for ${{ matrix.job.platform }} arch
run: |
mv ${{ matrix.job.platform }}/release/apimain debian-build/${{ matrix.job.platform }}/bin/rustdesk-api
chmod -v a+x debian-build/${{ matrix.job.platform }}/bin/*
mkdir -p data
cp -vr debian systemd conf data resources runtime debian-build/${{ matrix.job.platform }}/
cat debian/control.tpl | sed 's/{{ ARCH }}/${{ matrix.job.debian_platform }}/' > debian-build/${{ matrix.job.platform }}/debian/control
cd debian-build/${{ matrix.job.platform }}/
debuild -i -us -uc -b -a${{ matrix.job.debian_platform}}
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: rustdesk-api-${{ matrix.job.debian_platform }}
path: |
debian-build/*.deb
- name: Upload to GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: test
files: |
debian-build/rustdesk-api-server_*_${{ matrix.job.debian_platform }}.deb
docker:
name: Push Docker Image
needs: build
@@ -187,7 +254,6 @@ jobs:
run: |
mkdir -p ${{ matrix.job.platform }}
tar -xzf ${{ matrix.job.goos }}-${{ matrix.job.platform }}.tar.gz -C ${{ matrix.job.platform }}
file ${{ matrix.job.platform }}/apimain
- name: Build and push Docker image to Docker Hub ${{ matrix.job.platform }}
if: ${{ env.SKIP_DOCKER_HUB == 'false' }} # Only run this step if SKIP_DOCKER_HUB is false

View File

@@ -140,15 +140,12 @@
1. 如果已经登录了后台web client将自动直接登录
2. 如果没登录后台点击右上角登录即可api server已经自动配置好了
![webclient_conf](docs/webclient_conf.png)
3. 登录后会自动同步ID服务器和KEY
4. 登录后会将地址簿自动保存到web client中方便使用
5. 现已支持`v2 Preview`,访问路径是`/webclient2`
![webclientv2](./docs/webclientv2.png)
6. `v2 preview` 部署
- 如果是通过`443`端口的`https`部署,必须配置反向代理,可以参考[官方文档](https://rustdesk.com/docs/en/self-host/rustdesk-server-pro/faq/#8-add-websocket-secure-wss-support-for-the-id-server-and-relay-server-to-enable-secure-communication-for-the-web-client)
- 如果是`http`或者其他的`https`端口部署,则和`v1`一样,配置好`21118`,`21119`即可
- 更多参考[Web-Client-V2-Preview-Document](https://github.com/lejianwen/rustdesk-api/wiki/Web-Client-V2-Preview-Document)
6. `v2 preview` 部署,参考[WIKI](https://github.com/lejianwen/rustdesk-api/wiki)
### 自动化文档: 使用 Swag 生成 API 文档,方便开发者理解和使用 API。
@@ -180,6 +177,7 @@ lang: "en"
app:
web-client: 1 # 1:启用 0:禁用
register: false #是否开启注册
show-swagger: 0 #是否显示swagger文档
gin:
api-addr: "0.0.0.0:21114"
mode: "release"
@@ -212,37 +210,39 @@ proxy:
### 环境变量
变量名前缀是`RUSTDESK_API`,环境变量如果存在将覆盖配置文件中的配置
| 变量名 | 说明 | 示例 |
|------------------------------------|---------------------------------------------------------|------------------------------|
| TZ | 时区 | Asia/Shanghai |
| RUSTDESK_API_LANG | 语言 | `en`,`zh-CN` |
| RUSTDESK_API_APP_WEB_CLIENT | 是否启用web-client; 1:启用,0:不启用; 默认启用 | 1 |
| RUSTDESK_API_APP_REGISTER | 是否开启注册; `true`, `false` 默认`false` | `false` |
| -----ADMIN配置----- | ---------- | ---------- |
| RUSTDESK_API_ADMIN_TITLE | 后台标题 | `RustDesk Api Admin` |
| RUSTDESK_API_ADMIN_HELLO | 后台欢迎语,可以使用`html` | |
| RUSTDESK_API_ADMIN_HELLO_FILE | 后台欢迎语文件,如果内容多,使用文件更方便。<br>会覆盖`RUSTDESK_API_ADMIN_HELLO` | `./conf/admin/hello.html` |
| -----GIN配置----- | ---------- | ---------- |
| RUSTDESK_API_GIN_TRUST_PROXY | 信任的代理IP列表以`,`分割,默认信任所有 | 192.168.1.2,192.168.1.3 |
| -----------GORM配置---------------- | ------------------------------------ | --------------------------- |
| RUSTDESK_API_GORM_TYPE | 数据库类型sqlite或者mysql默认sqlite | sqlite |
| RUSTDESK_API_GORM_MAX_IDLE_CONNS | 数据库最大空闲连接数 | 10 |
| RUSTDESK_API_GORM_MAX_OPEN_CONNS | 数据库最大打开连接数 | 100 |
| RUSTDESK_API_RUSTDESK_PERSONAL | 是否启用个人版API 1:启用,0:不启用; 默认启用 | 1 |
| -----MYSQL配置----- | ---------- | ---------- |
| RUSTDESK_API_MYSQL_USERNAME | mysql用户名 | root |
| RUSTDESK_API_MYSQL_PASSWORD | mysql密码 | 111111 |
| RUSTDESK_API_MYSQL_ADDR | mysql地址 | 192.168.1.66:3306 |
| RUSTDESK_API_MYSQL_DBNAME | mysql数据库名 | rustdesk |
| -----RUSTDESK配置----- | --------------- | ---------- |
| RUSTDESK_API_RUSTDESK_ID_SERVER | Rustdesk的id服务器地址 | 192.168.1.66:21116 |
| RUSTDESK_API_RUSTDESK_RELAY_SERVER | Rustdesk的relay服务器地址 | 192.168.1.66:21117 |
| RUSTDESK_API_RUSTDESK_API_SERVER | Rustdesk的api服务器地址 | http://192.168.1.66:21114 |
| RUSTDESK_API_RUSTDESK_KEY | Rustdesk的key | 123456789 |
| RUSTDESK_API_RUSTDESK_KEY_FILE | Rustdesk存放key的文件 | `./conf/data/id_ed25519.pub` |
| ----PROXY配置----- | --------------- | ---------- |
| RUSTDESK_API_PROXY_ENABLE | 是否启用代理:`false`, `true` | `false` |
| RUSTDESK_API_PROXY_HOST | 代理地址 | `http://127.0.0.1:1080` |
| 变量名 | 说明 | 示例 |
|---------------------------------------------------|---------------------------------------------------------|------------------------------|
| TZ | 时区 | Asia/Shanghai |
| RUSTDESK_API_LANG | 语言 | `en`,`zh-CN` |
| RUSTDESK_API_APP_WEB_CLIENT | 是否启用web-client; 1:启用,0:不启用; 默认启用 | 1 |
| RUSTDESK_API_APP_REGISTER | 是否开启注册; `true`, `false` 默认`false` | `false` |
| RUSTDESK_API_APP_SHOW_SWAGGER | 是否可见swagger文档;`1`显示,`0`不显示,默认`0`不显示 | `1` |
| -----ADMIN配置----- | ---------- | ---------- |
| RUSTDESK_API_ADMIN_TITLE | 后台标题 | `RustDesk Api Admin` |
| RUSTDESK_API_ADMIN_HELLO | 后台欢迎语,可以使用`html` | |
| RUSTDESK_API_ADMIN_HELLO_FILE | 后台欢迎语文件,如果内容多,使用文件更方便。<br>会覆盖`RUSTDESK_API_ADMIN_HELLO` | `./conf/admin/hello.html` |
| -----GIN配置----- | ---------- | ---------- |
| RUSTDESK_API_GIN_TRUST_PROXY | 信任的代理IP列表以`,`分割,默认信任所有 | 192.168.1.2,192.168.1.3 |
| -----------GORM配置---------------- | ------------------------------------ | --------------------------- |
| RUSTDESK_API_GORM_TYPE | 数据库类型sqlite或者mysql默认sqlite | sqlite |
| RUSTDESK_API_GORM_MAX_IDLE_CONNS | 数据库最大空闲连接数 | 10 |
| RUSTDESK_API_GORM_MAX_OPEN_CONNS | 数据库最大打开连接数 | 100 |
| RUSTDESK_API_RUSTDESK_PERSONAL | 是否启用个人版API 1:启用,0:不启用; 默认启用 | 1 |
| -----MYSQL配置----- | ---------- | ---------- |
| RUSTDESK_API_MYSQL_USERNAME | mysql用户名 | root |
| RUSTDESK_API_MYSQL_PASSWORD | mysql密码 | 111111 |
| RUSTDESK_API_MYSQL_ADDR | mysql地址 | 192.168.1.66:3306 |
| RUSTDESK_API_MYSQL_DBNAME | mysql数据库名 | rustdesk |
| -----RUSTDESK配置----- | --------------- | ---------- |
| RUSTDESK_API_RUSTDESK_ID_SERVER | Rustdesk的id服务器地址 | 192.168.1.66:21116 |
| RUSTDESK_API_RUSTDESK_RELAY_SERVER | Rustdesk的relay服务器地址 | 192.168.1.66:21117 |
| RUSTDESK_API_RUSTDESK_API_SERVER | Rustdesk的api服务器地址 | http://192.168.1.66:21114 |
| RUSTDESK_API_RUSTDESK_KEY | Rustdeskkey | 123456789 |
| RUSTDESK_API_RUSTDESK_KEY_FILE | Rustdesk存放key的文件 | `./conf/data/id_ed25519.pub` |
| RUSTDESK_API_RUSTDESK_WEBCLIENT_MAGIC_QUERYONLINE | Web client v2 中是否启用新的在线状态查询方法; `1`:启用,`0`:不启用,默认不启用 | `0` |
| ----PROXY配置----- | --------------- | ---------- |
| RUSTDESK_API_PROXY_ENABLE | 是否启用代理:`false`, `true` | `false` |
| RUSTDESK_API_PROXY_HOST | 代理地址 | `http://127.0.0.1:1080` |
### 运行
@@ -263,7 +263,7 @@ proxy:
lejianwen/rustdesk-api
```
2. 使用`docker compose`,参考[wiki](https://github.com/lejianwen/rustdesk-api/wiki)
2. 使用`docker compose`,参考[WIKI](https://github.com/lejianwen/rustdesk-api/wiki)
#### 下载release直接运行

View File

@@ -144,16 +144,11 @@ installation are `admin` `admin`, please change the password immediately.
1. If you're already logged into the admin panel, the web client will log in automatically.
2. If you're not logged in, simply click the login button in the top right corner, and the API server will be
pre-configured.
![webclient_conf](docs/webclient_conf.png)
3. After logging in, the ID server and key will be automatically synced.
4. The address book will also be automatically saved to the web client for convenient use.
5. Now supports `v2 Preview`, accessible at `/webclient2`
![webclientv2](./docs/webclientv2.png)
6. `v2 preview` deployment
- If deploying via `https` on port `443`, you must configure a reverse proxy. Refer to the [official documentation](https://rustdesk.com/docs/en/self-host/rustdesk-server-pro/faq/#8-add-websocket-secure-wss-support-for-the-id-server-and-relay-server-to-enable-secure-communication-for-the-web-client)
- If deploying via `http` or other `https` ports, configure `21118` and `21119` as with `v1`
- More [Web-Client-V2-Preview-Document](https://github.com/lejianwen/rustdesk-api/wiki/Web-Client-V2-Preview-Document)
6. `v2 preview` deployment, [WIKI](https://github.com/lejianwen/rustdesk-api/wiki)
### Automated Documentation : API documentation is generated using Swag, making it easier for developers to understand and use the API.
@@ -185,6 +180,7 @@ lang: "en"
app:
web-client: 1 # web client route 1:open 0:close
register: false #register enable
show-swagger: 0 #show swagger 1:open 0:close
gin:
api-addr: "0.0.0.0:21114"
mode: "release"
@@ -217,37 +213,39 @@ proxy:
### Environment Variables
The prefix for variable names is `RUSTDESK_API`. If environment variables exist, they will override the configurations in the configuration file.
| Variable Name | Description | Example |
|------------------------------------|-------------------------------------------------------------------------|-------------------------------|
| TZ | timezone | Asia/Shanghai |
| RUSTDESK_API_LANG | Language | `en`,`zh-CN` |
| RUSTDESK_API_APP_WEB_CLIENT | web client on/off; 1: on, 0 off, deault 1 | 1 |
| RUSTDESK_API_APP_REGISTER | register enable; `true`, `false`; default:`false` | `false` |
| ----- ADMIN Configuration----- | ---------- | ---------- |
| RUSTDESK_API_ADMIN_TITLE | Admin Title | `RustDesk Api Admin` |
| RUSTDESK_API_ADMIN_HELLO | Admin welcome message, you can use `html` | |
| RUSTDESK_API_ADMIN_HELLO_FILE | Admin welcome message file,<br>will override `RUSTDESK_API_ADMIN_HELLO` | `./conf/admin/hello.html` |
| ----- GIN Configuration ----- | --------------------------------------- | ----------------------------- |
| RUSTDESK_API_GIN_TRUST_PROXY | Trusted proxy IPs, separated by commas. | 192.168.1.2,192.168.1.3 |
| ----- GORM Configuration ----- | --------------------------------------- | ----------------------------- |
| RUSTDESK_API_GORM_TYPE | Database type (`sqlite` or `mysql`). Default is `sqlite`. | sqlite |
| RUSTDESK_API_GORM_MAX_IDLE_CONNS | Maximum idle connections | 10 |
| RUSTDESK_API_GORM_MAX_OPEN_CONNS | Maximum open connections | 100 |
| RUSTDESK_API_RUSTDESK_PERSONAL | Open Personal Api 1:Enable,0:Disable | 1 |
| ----- MYSQL Configuration ----- | --------------------------------------- | ----------------------------- |
| RUSTDESK_API_MYSQL_USERNAME | MySQL username | root |
| RUSTDESK_API_MYSQL_PASSWORD | MySQL password | 111111 |
| RUSTDESK_API_MYSQL_ADDR | MySQL address | 192.168.1.66:3306 |
| RUSTDESK_API_MYSQL_DBNAME | MySQL database name | rustdesk |
| ----- RUSTDESK Configuration ----- | --------------------------------------- | ----------------------------- |
| RUSTDESK_API_RUSTDESK_ID_SERVER | Rustdesk ID server address | 192.168.1.66:21116 |
| RUSTDESK_API_RUSTDESK_RELAY_SERVER | Rustdesk relay server address | 192.168.1.66:21117 |
| RUSTDESK_API_RUSTDESK_API_SERVER | Rustdesk API server address | http://192.168.1.66:21114 |
| RUSTDESK_API_RUSTDESK_KEY | Rustdesk key | 123456789 |
| RUSTDESK_API_RUSTDESK_KEY_FILE | Rustdesk存放key的文件 | `./conf/data/id_ed25519.pub` |
| ---- PROXY ----- | --------------- | ---------- |
| RUSTDESK_API_PROXY_ENABLE | proxy_enable :`false`, `true` | `false` |
| RUSTDESK_API_PROXY_HOST | proxy_host | `http://127.0.0.1:1080` |
| Variable Name | Description | Example |
|-----------------------------------------------------|--------------------------------------------------------------------------------------------------------------|-------------------------------|
| TZ | timezone | Asia/Shanghai |
| RUSTDESK_API_LANG | Language | `en`,`zh-CN` |
| RUSTDESK_API_APP_WEB_CLIENT | web client on/off; 1: on, 0 off, default: 1 | 1 |
| RUSTDESK_API_APP_REGISTER | register enable; `true`, `false`; default:`false` | `false` |
| RUSTDESK_API_APP_SHOW_SWAGGER | swagger visible; 1: yes, 0: no; default: 0 | `0` |
| ----- ADMIN Configuration----- | ---------- | ---------- |
| RUSTDESK_API_ADMIN_TITLE | Admin Title | `RustDesk Api Admin` |
| RUSTDESK_API_ADMIN_HELLO | Admin welcome message, you can use `html` | |
| RUSTDESK_API_ADMIN_HELLO_FILE | Admin welcome message file,<br>will override `RUSTDESK_API_ADMIN_HELLO` | `./conf/admin/hello.html` |
| ----- GIN Configuration ----- | --------------------------------------- | ----------------------------- |
| RUSTDESK_API_GIN_TRUST_PROXY | Trusted proxy IPs, separated by commas. | 192.168.1.2,192.168.1.3 |
| ----- GORM Configuration ----- | --------------------------------------- | ----------------------------- |
| RUSTDESK_API_GORM_TYPE | Database type (`sqlite` or `mysql`). Default is `sqlite`. | sqlite |
| RUSTDESK_API_GORM_MAX_IDLE_CONNS | Maximum idle connections | 10 |
| RUSTDESK_API_GORM_MAX_OPEN_CONNS | Maximum open connections | 100 |
| RUSTDESK_API_RUSTDESK_PERSONAL | Open Personal Api 1:Enable,0:Disable | 1 |
| ----- MYSQL Configuration ----- | --------------------------------------- | ----------------------------- |
| RUSTDESK_API_MYSQL_USERNAME | MySQL username | root |
| RUSTDESK_API_MYSQL_PASSWORD | MySQL password | 111111 |
| RUSTDESK_API_MYSQL_ADDR | MySQL address | 192.168.1.66:3306 |
| RUSTDESK_API_MYSQL_DBNAME | MySQL database name | rustdesk |
| ----- RUSTDESK Configuration ----- | --------------------------------------- | ----------------------------- |
| RUSTDESK_API_RUSTDESK_ID_SERVER | Rustdesk ID server address | 192.168.1.66:21116 |
| RUSTDESK_API_RUSTDESK_RELAY_SERVER | Rustdesk relay server address | 192.168.1.66:21117 |
| RUSTDESK_API_RUSTDESK_API_SERVER | Rustdesk API server address | http://192.168.1.66:21114 |
| RUSTDESK_API_RUSTDESK_KEY | Rustdesk key | 123456789 |
| RUSTDESK_API_RUSTDESK_KEY_FILE | Rustdesk key file | `./conf/data/id_ed25519.pub` |
| RUSTDESK_API_RUSTDESK_WEBCLIENT_MAGIC_QUERYONLINE | New online query method is enabled in the web client v2; '1': Enabled, '0': Disabled, not enabled by default | `0` |
| ---- PROXY ----- | --------------- | ---------- |
| RUSTDESK_API_PROXY_ENABLE | proxy_enable :`false`, `true` | `false` |
| RUSTDESK_API_PROXY_HOST | proxy_host | `http://127.0.0.1:1080` |
### Installation Steps
@@ -267,7 +265,7 @@ The prefix for variable names is `RUSTDESK_API`. If environment variables exist,
lejianwen/rustdesk-api
```
2. Using `docker-compose`,look [wiki](https://github.com/lejianwen/rustdesk-api/wiki)
2. Using `docker-compose`,look [WIKI](https://github.com/lejianwen/rustdesk-api/wiki)
#### Running from Release

View File

@@ -169,7 +169,7 @@ func InitGlobal() {
global.Lock = lock.NewLocal()
}
func DatabaseAutoUpdate() {
version := 246
version := 247
db := global.DB

View File

@@ -1 +1 @@
👏👏👏 你好 <strong>{{username}}</strong>, 欢迎使用 <a href='https://github.com/lejianwen/rustdesk-api' target='_blank'>RustDesk Api Admin</a>
### 👏👏👏 你好 ***{{username}}*** 欢迎使用 [RustDesk Api](https://github.com/lejianwen/rustdesk-api)

View File

@@ -28,6 +28,7 @@ rustdesk:
key: ""
key-file: "./conf/data/id_ed25519.pub"
personal: 1
webclient-magic-queryonline: 0
logger:
path: "./runtime/log.txt"
level: "warn" #trace,debug,info,warn,error,fatal

View File

@@ -11,6 +11,8 @@ type Rustdesk struct {
Key string `mapstructure:"key"`
KeyFile string `mapstructure:"key-file"`
Personal int `mapstructure:"personal"`
//webclient-magic-queryonline
WebclientMagicQueryonline int `mapstructure:"webclient-magic-queryonline"`
}
func LoadKeyFile(rustdesk *Rustdesk) {

5
debian/changelog vendored Normal file
View File

@@ -0,0 +1,5 @@
rustdesk-api-server (1.3.6) UNRELEASED; urgency=medium
* Update the version to 1.3.6 to match the client.
-- rustdesk-api <ymwlpoolc@qq.com> Tue, 24 Dec 2024 13:48:34 +0800

1
debian/compat vendored Normal file
View File

@@ -0,0 +1 @@
10

13
debian/control.tpl vendored Normal file
View File

@@ -0,0 +1,13 @@
Source: rustdesk-api-server
Section: net
Priority: optional
Maintainer: ymwl <ymwlpoolc@qq.com>
Build-Depends: debhelper (>= 10), pkg-config
Standards-Version: 4.5.0
Homepage: https://github.com/lejianwen/rustdesk-api/
Package: rustdesk-api-server
Architecture: {{ ARCH }}
Depends: systemd ${misc:Depends}
Description: RustDesk api server
RustDesk api server, it is free and open source.

21
debian/copyright vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024-present Lejianwen and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

6
debian/rules vendored Normal file
View File

@@ -0,0 +1,6 @@
#!/usr/bin/make -f
%:
dh $@
override_dh_builddeb:
dh_builddeb -- -Zgzip

6
debian/rustdesk-api-server.install vendored Normal file
View File

@@ -0,0 +1,6 @@
bin/rustdesk-api usr/bin
systemd/rustdesk-api.service lib/systemd/system
conf var/lib/rustdesk-api
data var/lib/rustdesk-api
resources var/lib/rustdesk-api
runtime var/lib/rustdesk-api

28
debian/rustdesk-api-server.postinst vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/bin/sh
set -e
SERVICE=rustdesk-api.service
if [ "$1" = "configure" ]; then
mkdir -p /var/log/rustdesk-api
fi
case "$1" in
configure|abort-upgrade|abort-deconfigure|abort-remove)
mkdir -p /var/lib/rustdesk-api/
deb-systemd-helper unmask "${SERVICE}" >/dev/null || true
if deb-systemd-helper --quiet was-enabled "${SERVICE}"; then
deb-systemd-invoke enable "${SERVICE}" >/dev/null || true
else
deb-systemd-invoke update-state "${SERVICE}" >/dev/null || true
fi
systemctl --system daemon-reload >/dev/null || true
if [ -n "$2" ]; then
deb-systemd-invoke restart "${SERVICE}" >/dev/null || true
else
deb-systemd-invoke start "${SERVICE}" >/dev/null || true
fi
;;
esac
exit 0

18
debian/rustdesk-api-server.postrm vendored Normal file
View File

@@ -0,0 +1,18 @@
#!/bin/sh
set -e
SERVICE=rustdesk-api.service
systemctl --system daemon-reload >/dev/null || true
if [ "$1" = "purge" ]; then
rm -rf /var/log/rustdesk-api/rustdesk-api.*
deb-systemd-helper purge "${SERVICE}" >/dev/null || true
deb-systemd-helper unmask "${SERVICE}" >/dev/null || true
fi
if [ "$1" = "remove" ]; then
deb-systemd-helper mask "${SERVICE}" >/dev/null || true
fi
exit 0

13
debian/rustdesk-api-server.prerm vendored Normal file
View File

@@ -0,0 +1,13 @@
#!/bin/sh
set -e
SERVICE=rustdesk-api.service
case "$1" in
remove|deconfigure)
deb-systemd-invoke stop "${SERVICE}" >/dev/null || true
deb-systemd-invoke disable "${SERVICE}" >/dev/null || true
;;
esac
exit 0

1
debian/source/format vendored Normal file
View File

@@ -0,0 +1 @@
3.0 (native)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -6,6 +6,7 @@ import (
"github.com/go-playground/locales/es"
"github.com/go-playground/locales/ko"
"github.com/go-playground/locales/ru"
"github.com/go-playground/locales/fr"
"github.com/go-playground/locales/zh_Hans_CN"
ut "github.com/go-playground/universal-translator"
@@ -14,6 +15,7 @@ import (
es_translations "github.com/go-playground/validator/v10/translations/es"
ru_translations "github.com/go-playground/validator/v10/translations/ru"
zh_translations "github.com/go-playground/validator/v10/translations/zh"
fr_translations "github.com/go-playground/validator/v10/translations/fr"
"reflect"
)
@@ -26,14 +28,16 @@ func ApiInitValidator() {
koT := ko.New()
ruT := ru.New()
esT := es.New()
frT := fr.New()
uni := ut.New(enT, cn, koT, ruT, esT)
uni := ut.New(enT, cn, koT, ruT, esT, frT)
enTrans, _ := uni.GetTranslator("en")
zhTrans, _ := uni.GetTranslator("zh_Hans_CN")
koTrans, _ := uni.GetTranslator("ko")
ruTrans, _ := uni.GetTranslator("ru")
esTrans, _ := uni.GetTranslator("es")
frTrans, _ := uni.GetTranslator("fr")
err := zh_translations.RegisterDefaultTranslations(validate, zhTrans)
if err != nil {
@@ -57,6 +61,10 @@ func ApiInitValidator() {
if err != nil {
panic(err)
}
err = fr_translations.RegisterDefaultTranslations(validate, frTrans)
if err != nil {
panic(err)
}
validate.RegisterTagNameFunc(func(field reflect.StructField) string {
label := field.Tag.Get("label")
@@ -126,6 +134,9 @@ func getTranslatorForLang(lang string) ut.Translator {
case "es":
trans, _ := Validator.UT.GetTranslator("es")
return trans
case "fr":
trans, _ := Validator.UT.GetTranslator("fr")
return trans
case "en":
fallthrough
default:

View File

@@ -4,7 +4,6 @@ import (
"Gwen/global"
"Gwen/http/request/admin"
"Gwen/http/response"
"Gwen/model"
"Gwen/service"
"encoding/json"
_ "encoding/json"
@@ -107,9 +106,21 @@ func (ct *AddressBook) BatchCreate(c *gin.Context) {
response.Fail(c, 101, errList[0])
return
}
ul := len(f.UserIds)
if ul == 0 {
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
return
}
if ul > 1 {
//多用户置空标签
f.Tags = []string{}
//多用户只能创建到默认地址簿
f.CollectionId = 0
}
//创建标签
for _, fu := range f.UserIds {
/*for _, fu := range f.UserIds {
if fu == 0 {
continue
}
@@ -122,13 +133,13 @@ func (ct *AddressBook) BatchCreate(c *gin.Context) {
})
}
}
}
}*/
ts := f.ToAddressBooks()
for _, t := range ts {
if t.UserId == 0 {
continue
}
ex := service.AllService.AddressBookService.InfoByUserIdAndId(t.UserId, t.Id)
ex := service.AllService.AddressBookService.InfoByUserIdAndIdAndCid(t.UserId, t.Id, t.CollectionId)
if ex.RowId == 0 {
service.AllService.AddressBookService.Create(t)
}

View File

@@ -56,10 +56,6 @@ func (ct *LoginLog) List(c *gin.Context) {
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
return
}
u := service.AllService.UserService.CurUser(c)
if !service.AllService.UserService.IsAdmin(u) || query.IsMy == 1 {
query.UserId = int(u.Id)
}
res := service.AllService.LoginLogService.List(query.Page, query.PageSize, func(tx *gorm.DB) {
if query.UserId > 0 {
tx.Where("user_id = ?", query.UserId)
@@ -93,21 +89,16 @@ func (ct *LoginLog) Delete(c *gin.Context) {
return
}
l := service.AllService.LoginLogService.InfoById(f.Id)
u := service.AllService.UserService.CurUser(c)
if !service.AllService.UserService.IsAdmin(u) && l.UserId != u.Id {
response.Fail(c, 101, response.TranslateMsg(c, "NoAccess"))
if l.Id == 0 {
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
return
}
if l.Id > 0 {
err := service.AllService.LoginLogService.Delete(l)
if err == nil {
response.Success(c, nil)
return
}
response.Fail(c, 101, err.Error())
err := service.AllService.LoginLogService.Delete(l)
if err == nil {
response.Success(c, nil)
return
}
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
response.Fail(c, 101, err.Error())
}
// BatchDelete 删除
@@ -119,7 +110,7 @@ func (ct *LoginLog) Delete(c *gin.Context) {
// @Param body body admin.LoginLogIds true "登录日志"
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /admin/login_log/delete [post]
// @Router /admin/login_log/batchDelete [post]
// @Security token
func (ct *LoginLog) BatchDelete(c *gin.Context) {
f := &admin.LoginLogIds{}

View File

@@ -0,0 +1,113 @@
package my
import (
"Gwen/global"
"Gwen/http/request/admin"
"Gwen/http/response"
"Gwen/model"
"Gwen/service"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
type LoginLog struct {
}
// List 列表
// @Tags 我的登录日志
// @Summary 登录日志列表
// @Description 登录日志列表
// @Accept json
// @Produce json
// @Param page query int false "页码"
// @Param page_size query int false "页大小"
// @Param user_id query int false "用户ID"
// @Success 200 {object} response.Response{data=model.LoginLogList}
// @Failure 500 {object} response.Response
// @Router /admin/my/login_log/list [get]
// @Security token
func (ct *LoginLog) List(c *gin.Context) {
query := &admin.LoginLogQuery{}
if err := c.ShouldBindQuery(query); err != nil {
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
return
}
u := service.AllService.UserService.CurUser(c)
res := service.AllService.LoginLogService.List(query.Page, query.PageSize, func(tx *gorm.DB) {
tx.Where("user_id = ? and is_deleted = ?", u.Id, model.IsDeletedNo)
tx.Order("id desc")
})
response.Success(c, res)
}
// Delete 删除
// @Tags 我的登录日志
// @Summary 登录日志删除
// @Description 登录日志删除
// @Accept json
// @Produce json
// @Param body body model.LoginLog true "登录日志信息"
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /admin/my/login_log/delete [post]
// @Security token
func (ct *LoginLog) Delete(c *gin.Context) {
f := &model.LoginLog{}
if err := c.ShouldBindJSON(f); err != nil {
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
return
}
id := f.Id
errList := global.Validator.ValidVar(c, id, "required,gt=0")
if len(errList) > 0 {
response.Fail(c, 101, errList[0])
return
}
l := service.AllService.LoginLogService.InfoById(f.Id)
if l.Id == 0 || l.IsDeleted == model.IsDeletedYes {
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
return
}
u := service.AllService.UserService.CurUser(c)
if l.UserId != u.Id {
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
return
}
err := service.AllService.LoginLogService.SoftDelete(l)
if err == nil {
response.Success(c, nil)
return
}
response.Fail(c, 101, err.Error())
}
// BatchDelete 删除
// @Tags 我的登录日志
// @Summary 登录日志批量删除
// @Description 登录日志批量删除
// @Accept json
// @Produce json
// @Param body body admin.LoginLogIds true "登录日志"
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /admin/my/login_log/batchDelete [post]
// @Security token
func (ct *LoginLog) BatchDelete(c *gin.Context) {
f := &admin.LoginLogIds{}
if err := c.ShouldBindJSON(f); err != nil {
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
return
}
if len(f.Ids) == 0 {
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
return
}
u := service.AllService.UserService.CurUser(c)
err := service.AllService.LoginLogService.BatchSoftDelete(u.Id, f.Ids)
if err == nil {
response.Success(c, nil)
return
}
response.Fail(c, 101, err.Error())
return
}

View File

@@ -32,8 +32,8 @@ type Ab struct {
func (a *Ab) Ab(c *gin.Context) {
user := service.AllService.UserService.CurUser(c)
al := service.AllService.AddressBookService.ListByUserId(user.Id, 1, 1000)
tags := service.AllService.TagService.ListByUserId(user.Id)
al := service.AllService.AddressBookService.ListByUserIdAndCollectionId(user.Id, 0, 1, 1000)
tags := service.AllService.TagService.ListByUserIdAndCollectionId(user.Id, 0)
tagColors := map[string]uint{}
//将tags中的name转成一个以逗号分割的字符串
@@ -98,23 +98,6 @@ func (a *Ab) UpAb(c *gin.Context) {
c.JSON(http.StatusOK, nil)
}
// Tags
// @Tags 地址
// @Summary 标签
// @Description 标签
// @Accept json
// @Produce json
// @Success 200 {object} []model.Tag
// @Failure 500 {object} response.ErrorResponse
// @Router /tags [post]
// @Security BearerAuth
func (a *Ab) Tags(c *gin.Context) {
user := service.AllService.UserService.CurUser(c)
tags := service.AllService.TagService.ListByUserId(user.Id)
c.JSON(http.StatusOK, tags.Tags)
}
// PTags
// @Tags 地址[Personal]
// @Summary 标签

View File

@@ -26,7 +26,7 @@ func (i *WebClient) ServerConfig(c *gin.Context) {
u := service.AllService.UserService.CurUser(c)
peers := map[string]*api.WebClientPeerPayload{}
abs := service.AllService.AddressBookService.ListByUserId(u.Id, 1, 100)
abs := service.AllService.AddressBookService.ListByUserIdAndCollectionId(u.Id, 0, 1, 100)
for _, ab := range abs.AddressBooks {
pp := &api.WebClientPeerPayload{}
pp.FromAddressBook(ab)
@@ -64,12 +64,15 @@ func (i *WebClient) SharedPeer(c *gin.Context) {
response.Fail(c, 101, "share not found")
return
}
//判断是否过期,created_at + expire > now
ca := time.Time(sr.CreatedAt)
if ca.Add(time.Second * time.Duration(sr.Expire)).Before(time.Now()) {
response.Fail(c, 101, "share expired")
return
if sr.Expire != 0 {
//判断是否过期,created_at + expire > now
ca := time.Time(sr.CreatedAt)
if ca.Add(time.Second * time.Duration(sr.Expire)).Before(time.Now()) {
response.Fail(c, 101, "share expired")
return
}
}
ab := service.AllService.AddressBookService.InfoByUserIdAndId(sr.UserId, sr.PeerId)
if ab.RowId == 0 {
response.Fail(c, 101, "peer not found")

View File

@@ -3,6 +3,7 @@ package web
import (
"Gwen/global"
"github.com/gin-gonic/gin"
"strconv"
)
type Index struct {
@@ -14,11 +15,13 @@ func (i *Index) Index(c *gin.Context) {
func (i *Index) ConfigJs(c *gin.Context) {
apiServer := global.Config.Rustdesk.ApiServer
magicQueryonline := strconv.Itoa(global.Config.Rustdesk.WebclientMagicQueryonline)
tmp := `
localStorage.setItem('api-server', "` + apiServer + `")
const ws2_prefix = 'wc-'
localStorage.setItem(ws2_prefix+'api-server', "` + apiServer + `")
`
window.webclient_magic_queryonline = ` + magicQueryonline + ``
c.String(200, tmp)
}

View File

@@ -18,11 +18,6 @@ func (lp *LoginPayload) FromUser(user *model.User) {
lp.Nickname = user.Nickname
}
var UserRouteNames = []string{
"MyTagList", "MyAddressBookList", "MyInfo", "MyAddressBookCollection", "MyPeer", "MyShareRecordList",
}
var AdminRouteNames = []string{"*"}
type UserOauthItem struct {
Op string `json:"op"`
Status int `json:"status"`

View File

@@ -160,8 +160,8 @@ func OauthBind(rg *gin.RouterGroup) {
}
func LoginLogBind(rg *gin.RouterGroup) {
aR := rg.Group("/login_log")
cont := &admin.LoginLog{}
aR := rg.Group("/login_log").Use(middleware.AdminPrivilege())
aR.GET("/list", cont.List)
aR.POST("/delete", cont.Delete)
aR.POST("/batchDelete", cont.BatchDelete)
@@ -274,6 +274,13 @@ func MyBind(rg *gin.RouterGroup) {
rg.GET("/my/peer/list", cont.List)
}
{
cont := &my.LoginLog{}
rg.GET("/my/login_log/list", cont.List)
rg.POST("/my/login_log/delete", cont.Delete)
rg.POST("/my/login_log/batchDelete", cont.BatchDelete)
}
}
func ShareRecordBind(rg *gin.RouterGroup) {

View File

@@ -4,12 +4,13 @@ type LoginLog struct {
IdModel
UserId uint `json:"user_id" gorm:"default:0;not null;"`
Client string `json:"client"` //webadmin,webclient,app,
DeviceId string `json:"device_id"`
DeviceId string `json:"device_id"`
Uuid string `json:"uuid"`
Ip string `json:"ip"`
Type string `json:"type"` //account,oauth
Platform string `json:"platform"` //windows,linux,mac,android,ios
UserTokenId uint `json:"user_token_id" gorm:"default:0;not null;"`
IsDeleted uint `json:"is_deleted" gorm:"default:0;not null;"`
TimeModel
}
@@ -24,6 +25,11 @@ const (
LoginLogTypeOauth = "oauth"
)
const (
IsDeletedNo = 0
IsDeletedYes = 1
)
type LoginLogList struct {
LoginLogs []*LoginLog `json:"list"`
Pagination

View File

@@ -27,3 +27,8 @@ type UserList struct {
Users []*User `json:"list,omitempty"`
Pagination
}
var UserRouteNames = []string{
"MyTagList", "MyAddressBookList", "MyInfo", "MyAddressBookCollection", "MyPeer", "MyShareRecordList", "MyLoginLog",
}
var AdminRouteNames = []string{"*"}

144
resources/i18n/fr.toml Normal file
View File

@@ -0,0 +1,144 @@
[Test]
description = "test"
one = "test1 "
other = "Test2 {{.P0}}"
[ParamsError]
description = "Params validation failed."
one = "La validation des paramètres a échoué."
other = "La validation des paramètres a échoué."
[OperationFailed]
description = "OperationFailed."
one = "l'opération a échoué."
other = "l'opération a échoué."
[OperationSuccess]
description = "OperationSuccess."
one = "Opération réussie"
other = "Opération réussie"
[ItemExists]
description = "Item already exists."
one = "L'élément existe déjà."
other = "L'élément existe déjà."
[ItemNotFound]
description = "Item not found."
one = "Article introuvable."
other = "Article introuvable."
[NoAccess]
description = "No access."
one = "Aucun d'access."
other = "Aucun d'access."
[UsernameOrPasswordError]
description = "Username or password error."
one = "Nom d'utilisateur ou de mot de passe incorrect."
other = "Nom d'utilisateur ou de mot de passe incorrect."
[SystemError]
description = "System error."
one = "Erreur system."
other = "Erreur system."
[ConfigNotFound]
description = "Config not found."
one = "Configuration introuvable."
other = "Configuration introuvable."
[OauthExpired]
description = "Oauth expired."
one = "Oauth a expiré, veuillez réessayer."
other = "Oauth a expiré, veuillez réessayer."
[OauthFailed]
description = "Oauth failed."
one = "Oauth a échoué."
other = "Oauth a échoué."
[OauthHasBindOtherUser]
description = "Oauth has bind other user."
one = "Oauth a lié un autre utilisateur."
other = "Oauth a lié un autre utilisateur."
[ParamIsEmpty]
description = "Param is empty."
one = "{{.P0}} est vide."
other = "{{.P0}} est vide."
[BindFail]
description = "Bind fail."
one = "Échec de la liaison."
other = "Échec de la liaison."
[BindSuccess]
description = "Bind success."
one = "Succès de la liaison."
other = "Succès de la liaison."
[OauthHasBeenSuccess]
description = "Oauth has been success."
one = "Oauth a été réussi avec Succès."
other = "Oauth a été réussi avec Succès."
[OauthSuccess]
description = "Oauth success."
one = "Oauh réussi avec succès."
other = "Oauh réussi avec succès."
[OauthRegisterSuccess]
description = "Oauth register success."
one = "Succès de l'enregistrement Oauth."
other = "Succès de l'enregistrement Oauth."
[OauthRegisterFailed]
description = "Oauth register failed."
one = "L'inscription Oauth a échoué."
other = "L'inscription Oauth a échoué."
[GetOauthTokenError]
description = "Get oauth token error."
one = "Erreur de l'obtention du jeton oauth."
other = "Erreur de l'obtention du jeton oauth."
[GetOauthUserInfoError]
description = "Get oauth user info error."
one = "Erreur d'obtention d'informations sur l'utilisateur oauth."
other = "Erreur d'obtention d'informations sur l'utilisateur oauth."
[DecodeOauthUserInfoError]
description = "Decode oauth user info error."
one = "Erreur de décodage des informations utilisateur oauth."
other = "Erreur de décodage des informations utilisateur oauth."
[OldPasswordError]
description = "Old password error."
one = "Ancien mot de passe incorrect."
other = "Ancien mot de passe incorrect."
[DefaultGroup]
description = "Default group"
one = "Groupe Défaut"
other = "Groupe Défaut"
[ShareGroup]
description = "Share group"
one = "Groupe partagé"
other = "Groupe partagé"
[RegisterClosed]
description = "Register closed."
one = "Inscription fermée."
other = "Inscription fermée."
[CaptchaRequired]
description = "Captcha required."
one = "Captcha requis."
other = "Captcha requis."
[CaptchaError]
description = "Captcha error."
one = "Erreur de captcha."
other = "Erreur de captcha."

View File

@@ -32,7 +32,7 @@
<title>RustDesk</title>
<script src="/webclient-config/index.js"></script>
<link rel="manifest" href="manifest.json" />
<script type="module" crossorigin src="js/dist/index.js?v=893935a2"></script>
<script type="module" crossorigin src="js/dist/index.js?v=1bbc8b94"></script>
<link rel="modulepreload" href="js/dist/vendor.js?v=0b990c6e" />
<style>
html,
@@ -259,7 +259,7 @@
}
scriptLoaded = true;
var scriptTag = document.createElement("script");
scriptTag.src = "main.dart.js?v=df360f45";
scriptTag.src = "main.dart.js?v=f6f842b3";
scriptTag.type = "application/javascript";
document.body.append(scriptTag);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -47,3 +47,12 @@ func (us *LoginLogService) Update(u *model.LoginLog) error {
func (us *LoginLogService) BatchDelete(ids []uint) error {
return global.DB.Where("id in (?)", ids).Delete(&model.LoginLog{}).Error
}
func (us *LoginLogService) SoftDelete(l *model.LoginLog) error {
l.IsDeleted = model.IsDeletedYes
return us.Update(l)
}
func (us *LoginLogService) BatchSoftDelete(uid uint, ids []uint) error {
return global.DB.Model(&model.LoginLog{}).Where("user_id = ? and id in (?)", uid, ids).Update("is_deleted", model.IsDeletedYes).Error
}

View File

@@ -2,7 +2,6 @@ package service
import (
"Gwen/global"
adResp "Gwen/http/response/admin"
"Gwen/model"
"Gwen/utils"
"errors"
@@ -272,9 +271,9 @@ func (us *UserService) IsAdmin(u *model.User) bool {
// RouteNames
func (us *UserService) RouteNames(u *model.User) []string {
if us.IsAdmin(u) {
return adResp.AdminRouteNames
return model.AdminRouteNames
}
return adResp.UserRouteNames
return model.UserRouteNames
}
// InfoByOauthId 根据oauth的name和openId取用户信息

View File

@@ -0,0 +1,18 @@
[Unit]
Description=Rustdesk api Server
[Service]
Type=simple
LimitNOFILE=1000000
ExecStart=/usr/bin/rustdesk-api
WorkingDirectory=/var/lib/rustdesk-api/
User=
Group=
Restart=always
StandardOutput=append:/var/log/rustdesk-api/rustdesk-api.log
StandardError=append:/var/log/rustdesk-api/rustdesk-api.error
# Restart service after 10 seconds if node service crashes
RestartSec=10
[Install]
WantedBy=multi-user.target