Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d9c245c81 | ||
|
|
7fa9b79f31 | ||
|
|
c7f3d13b7f | ||
|
|
46f08a89d2 | ||
|
|
0dcfedb4dc | ||
|
|
918bf85a2d | ||
|
|
99db5f7190 | ||
|
|
18eff791b2 | ||
|
|
624dcacac5 | ||
|
|
878d5fd27c | ||
|
|
4b893ce0e8 | ||
|
|
472524f836 | ||
|
|
dbf8b23b15 | ||
|
|
79a5dd53ae | ||
|
|
8a5b20685c | ||
|
|
5a9c972de0 | ||
|
|
fc0e67122d | ||
|
|
eb642f66ca | ||
|
|
8cac15f7dd | ||
|
|
5011e2b7c1 | ||
|
|
b0008143b1 | ||
|
|
a3c3ab5a72 | ||
|
|
3a16269215 | ||
|
|
151145b0c3 | ||
|
|
9c794e9d4b | ||
|
|
01f697d279 | ||
|
|
6cdc37333b | ||
|
|
ae32915565 | ||
|
|
f49457dc5b | ||
|
|
d9e2e247ea | ||
|
|
c6f2f2f150 | ||
|
|
56b9c66cb8 | ||
|
|
5d8a0d0e1f | ||
|
|
f4cb9beda5 | ||
|
|
b66fc3c06d | ||
|
|
ab2e1a9236 | ||
|
|
ab77b400a1 | ||
|
|
eb7ab63563 | ||
|
|
4cf7d01622 | ||
|
|
a876078a9c | ||
|
|
495f2ae3c6 | ||
|
|
4e6d11baf0 |
10
.github/workflows/build.yml
vendored
10
.github/workflows/build.yml
vendored
@@ -84,6 +84,15 @@ jobs:
|
||||
- name: tidy
|
||||
run: go mod tidy
|
||||
|
||||
- name: Get tag version
|
||||
run: |
|
||||
TAG_VERSION="${GITHUB_REF##*/}"
|
||||
VERSION="${TAG_VERSION#v}"
|
||||
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
||||
|
||||
- name: Write version to resources/version
|
||||
run: echo $VERSION > resources/version
|
||||
|
||||
- name: swag
|
||||
run: |
|
||||
go install github.com/swaggo/swag/cmd/swag@latest
|
||||
@@ -194,6 +203,7 @@ jobs:
|
||||
- name: Build package for ${{ matrix.job.platform }} arch
|
||||
run: |
|
||||
mv ${{ matrix.job.platform }}/release/apimain debian-build/${{ matrix.job.platform }}/bin/rustdesk-api
|
||||
mv ${{ matrix.job.platform }}/release/resources/admin resources
|
||||
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 }}/
|
||||
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,13 +1,8 @@
|
||||
.idea
|
||||
runtime/*
|
||||
!runtime
|
||||
!runtime/cache
|
||||
!runtime/cache/.gitkeep
|
||||
go.sum
|
||||
resources/*
|
||||
!resources/public/upload/.gitignore
|
||||
!resources/web
|
||||
!resources/web2
|
||||
!resources/i18n
|
||||
resources/admin
|
||||
release
|
||||
data
|
||||
166
README.md
166
README.md
@@ -9,6 +9,7 @@
|
||||
<img src="https://img.shields.io/badge/gin-v1.9.0-lightBlue"/>
|
||||
<img src="https://img.shields.io/badge/gorm-v1.25.7-green"/>
|
||||
<img src="https://img.shields.io/badge/swag-v1.16.3-yellow"/>
|
||||
<img src="https://img.shields.io/badge/i18n-7-green"/>
|
||||
<img src="https://github.com/lejianwen/rustdesk-api/actions/workflows/build.yml/badge.svg"/>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +20,10 @@
|
||||
- 登录
|
||||
- 地址簿
|
||||
- 群组
|
||||
- 授权登录,支持`github`, `google` 和 `OIDC` 登录,支持`web后台`授权登录
|
||||
- 授权登录
|
||||
- 支持`github`, `google` 和 `OIDC` 登录,
|
||||
- 支持`web后台`授权登录
|
||||
- 支持`LDAP`(AD和OpenLDAP已测试), 如果API Server配置了LDAP
|
||||
- i18n
|
||||
- Web Admin
|
||||
- 用户管理
|
||||
@@ -28,6 +32,7 @@
|
||||
- 标签管理
|
||||
- 群组管理
|
||||
- Oauth 管理
|
||||
- 配置LDAP, 配置文件或者环境变量
|
||||
- 登录日志
|
||||
- 链接日志
|
||||
- 文件传输日志
|
||||
@@ -46,45 +51,45 @@
|
||||
|
||||
## 功能
|
||||
|
||||
|
||||
### API 服务
|
||||
基本实现了PC端基础的接口。支持Personal版本接口,可以通过配置文件`rustdesk.personal`或环境变量`RUSTDESK_API_RUSTDESK_PERSONAL`来控制是否启用
|
||||
|
||||
#### 登录
|
||||
|
||||
- 添加了`github`, `google` 以及`OIDC`授权登录,需要在后台配置好就可以用了,具体可看后台OAuth配置
|
||||
- 添加了web后台授权登录,点击后直接登录后台就自动登录客户端了
|
||||
|
||||

|
||||
|
||||
#### 地址簿
|
||||
|
||||

|
||||
|
||||
#### 群组
|
||||
群组分为`共享组`和`普通组`,共享组中所有人都能看到小组成员的设备,普通组只有管理员能看到所有小组成员的设备
|
||||
|
||||

|
||||
<table>
|
||||
<tr>
|
||||
<td width="50%" align="center" colspan="2"><b>登录</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" align="center" colspan="2"><img src="docs/pc_login.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" align="center"><b>地址簿</b></td>
|
||||
<td width="50%" align="center"><b>群组</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" align="center"><img src="docs/pc_ab.png"></td>
|
||||
<td width="50%" align="center"><img src="docs/pc_gr.png"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Web Admin:
|
||||
|
||||
* 使用前后端分离,提供用户友好的管理界面,主要用来管理和展示。前端代码在[rustdesk-api-web](https://github.com/lejianwen/rustdesk-api-web)
|
||||
|
||||
* 后台访问地址是`http://<your server>[:port]/_admin/`初次安装管理员为用户名密码为`admin` `admin`,请即时更改密码
|
||||
* 后台访问地址是`http://<your server>[:port]/_admin/`
|
||||
* 初次安装管理员为用户名为`admin`,密码将在控制台打印,可以通过[命令行](#CLI)更改密码
|
||||
|
||||

|
||||
|
||||
1. 管理员界面
|
||||

|
||||
2. 普通用户界面
|
||||

|
||||
右上角可以更改密码,可以切换语言,可以切换`白天/黑夜`模式
|
||||
|
||||

|
||||
|
||||
3. 每个用户可以多个地址簿,也可以将地址簿共享给其他用户
|
||||
4. 分组可以自定义,方便管理,暂时支持两种类型: `共享组` 和 `普通组`
|
||||
5. 可以直接打开webclient,方便使用;也可以分享给游客,游客可以直接通过webclient远程到设备
|
||||

|
||||
6. Oauth,支持了`Github`, `Google` 以及 `OIDC`, 需要创建一个`OAuth App`,然后配置到后台
|
||||

|
||||
- 对于`Google` 和 `Github`, `Issuer` 和 `Scopes`不需要填写.
|
||||
- 对于`OIDC`, `Issuer`是必须的。`Scopes`是可选的,默认为 `openid,profile,email`. 确保可以获取 `sub`,`email` 和`preferred_username`
|
||||
- `github oauth app`在`Settings`->`Developer settings`->`OAuth Apps`->`New OAuth App`
|
||||
@@ -106,6 +111,7 @@
|
||||
|
||||

|
||||
|
||||
11. **LDAP 支持**, 当在API Server上设置了LDAP(已测试AD和LDAP),可以通过LDAP中的用户信息进行登录 https://github.com/lejianwen/rustdesk-api/issues/114 ,如果LDAP验证失败,返回本地用户
|
||||
|
||||
### Web Client:
|
||||
|
||||
@@ -125,6 +131,7 @@
|
||||

|
||||
|
||||
### CLI
|
||||
|
||||
```bash
|
||||
# 查看帮助
|
||||
./apimain -h
|
||||
@@ -179,47 +186,70 @@ proxy:
|
||||
jwt:
|
||||
key: ""
|
||||
expire-duration: 360000
|
||||
ldap:
|
||||
enable: false
|
||||
url: "ldap://ldap.example.com:389"
|
||||
tls: false
|
||||
tls-verify: false
|
||||
base-dn: "dc=example,dc=com"
|
||||
bind-dn: "cn=admin,dc=example,dc=com"
|
||||
bind-password: "password"
|
||||
|
||||
user:
|
||||
base-dn: "ou=users,dc=example,dc=com"
|
||||
enable-attr: "" #The attribute name of the user for enabling, in AD it is "userAccountControl", empty means no enable attribute, all users are enabled
|
||||
enable-attr-value: "" # The value of the enable attribute when the user is enabled. If you are using AD, just set random value, it will be ignored.
|
||||
filter: "(cn=*)"
|
||||
username: "uid" # The attribute name of the user for usernamem if you are using AD, it should be "sAMAccountName"
|
||||
email: "mail"
|
||||
first-name: "givenName"
|
||||
last-name: "sn"
|
||||
sync: false # If true, the user will be synchronized to the database when the user logs in. If false, the user will be synchronized to the database when the user be created.
|
||||
admin-group: "cn=admin,dc=example,dc=com" # The group name of the admin group, if the user is in this group, the user will be an admin.
|
||||
|
||||
```
|
||||
|
||||
### 环境变量
|
||||
变量名前缀是`RUSTDESK_API`,环境变量如果存在将覆盖配置文件中的配置
|
||||
环境变量和配置文件`conf/config.yaml`中的配置一一对应,变量名前缀是`RUSTDESK_API`
|
||||
下面表格并未全部列出,可以参考`conf/config.yaml`中的配置。
|
||||
|
||||
| 变量名 | 说明 | 示例 |
|
||||
|---------------------------------------------------|---------------------------------------------------------|------------------------------|
|
||||
| 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 | Rustdesk的key | 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` |
|
||||
| ----JWT配置---- | -------- | -------- |
|
||||
| RUSTDESK_API_JWT_KEY | 自定义JWT KEY,为空则不启用JWT | |
|
||||
| RUSTDESK_API_JWT_EXPIRE_DURATION | JWT有效时间 | 360000 |
|
||||
| 变量名 | 说明 | 示例 |
|
||||
|--------------------------------------------------------|--------------------------------------------------------------------------------|------------------------------|
|
||||
| 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` |
|
||||
| RUSTDESK_API_APP_TOKEN_EXPIRE | token有效时长(秒) | `3600` |
|
||||
| -----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` |
|
||||
| RUSTDESK_API_RUSTDESK_WEBCLIENT<br/>_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` |
|
||||
| ----JWT配置---- | -------- | -------- |
|
||||
| RUSTDESK_API_JWT_KEY | 自定义JWT KEY,为空则不启用JWT<br/>如果没使用`lejianwen/rustdesk-server`中的`MUST_LOGIN`,建议设置为空 | |
|
||||
| RUSTDESK_API_JWT_EXPIRE_DURATION | JWT有效时间 | 360000 |
|
||||
|
||||
|
||||
### 运行
|
||||
@@ -285,10 +315,11 @@ jwt:
|
||||
6. 打开浏览器访问`http://<your server[:port]>/_admin/`,默认用户名密码为`admin`,请及时更改密码。
|
||||
|
||||
|
||||
#### 使用我fork后的server-s6镜像运行
|
||||
#### 使用`lejianwen/server-s6`镜像运行
|
||||
|
||||
- 已解决链接超时问题
|
||||
- 可以强制登录后才能发起链接
|
||||
- github https://github.com/lejianwen/rustdesk-server
|
||||
- docker hub https://hub.docker.com/r/lejianwen/rustdesk-server-s6
|
||||
|
||||
```yaml
|
||||
networks:
|
||||
@@ -330,4 +361,15 @@ jwt:
|
||||
- [WIKI](https://github.com/lejianwen/rustdesk-api/wiki)
|
||||
- [链接超时问题](https://github.com/lejianwen/rustdesk-api/issues/92)
|
||||
- [修改客户端ID](https://github.com/abdullah-erturk/RustDesk-ID-Changer)
|
||||
- [webclient来源](https://hub.docker.com/r/keyurbhole/flutter_web_desk)
|
||||
- [webclient来源](https://hub.docker.com/r/keyurbhole/flutter_web_desk)
|
||||
|
||||
|
||||
## 鸣谢
|
||||
|
||||
感谢所有做过贡献的人!
|
||||
|
||||
<a href="https://github.com/lejianwen/rustdesk-api/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=lejianwen/rustdesk-api" />
|
||||
</a>
|
||||
|
||||
## 感谢你的支持!如果这个项目对你有帮助,请点个⭐️鼓励一下,谢谢!
|
||||
|
||||
175
README_EN.md
175
README_EN.md
@@ -8,6 +8,7 @@ desktop software that provides self-hosted solutions.
|
||||
<img src="https://img.shields.io/badge/gin-v1.9.0-lightBlue"/>
|
||||
<img src="https://img.shields.io/badge/gorm-v1.25.7-green"/>
|
||||
<img src="https://img.shields.io/badge/swag-v1.16.3-yellow"/>
|
||||
<img src="https://img.shields.io/badge/i18n-7-green"/>
|
||||
<img src="https://github.com/lejianwen/rustdesk-api/actions/workflows/build.yml/badge.svg"/>
|
||||
</div>
|
||||
|
||||
@@ -18,7 +19,10 @@ desktop software that provides self-hosted solutions.
|
||||
- Login
|
||||
- Address Book
|
||||
- Groups
|
||||
- Authorized login, supports `GitHub`, `Google` and `OIDC` login, supports `web admin` authorized login
|
||||
- Authorized login,
|
||||
- supports `GitHub`, `Google` and `OIDC` login,
|
||||
- supports `web admin` authorized login,
|
||||
- supports LDAP(test AD and openladp) if API Server config
|
||||
- i18n
|
||||
- Web Admin
|
||||
- User Management
|
||||
@@ -27,6 +31,7 @@ desktop software that provides self-hosted solutions.
|
||||
- Tag Management
|
||||
- Group Management
|
||||
- OAuth Management
|
||||
- LDAP Config by config file or ENV
|
||||
- Login Logs
|
||||
- Connection Logs
|
||||
- File Transfer Logs
|
||||
@@ -47,45 +52,44 @@ desktop software that provides self-hosted solutions.
|
||||
### API Service
|
||||
Basic implementation of the PC client's primary interfaces.Supports the Personal version api, which can be enabled by configuring the `rustdesk.personal` file or the `RUSTDESK_API_RUSTDESK_PERSONAL` environment variable.
|
||||
|
||||
#### Login
|
||||
|
||||
- Added `GitHub`, `Google` and `OIDC` login, which can be used after configuration in the admin panel. See the OAuth
|
||||
configuration section for details.
|
||||
- Added authorization login for the web admin panel.
|
||||
|
||||

|
||||
|
||||
#### Address Book
|
||||
|
||||

|
||||
|
||||
#### Groups
|
||||
Groups are divided into `shared groups` and `regular groups`. In shared groups, everyone can see the peers of all group members, while in regular groups, only administrators can see all members' peers.
|
||||
|
||||

|
||||
<table>
|
||||
<tr>
|
||||
<td width="50%" align="center" colspan="2"><b>Login</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" align="center" colspan="2"><img src="docs/en_img/pc_login.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" align="center"><b>Address Book</b></td>
|
||||
<td width="50%" align="center"><b>Groups</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" align="center"><img src="docs/en_img/pc_ab.png"></td>
|
||||
<td width="50%" align="center"><img src="docs/en_img/pc_gr.png"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Web Admin
|
||||
|
||||
* The frontend and backend are separated to provide a user-friendly management interface, primarily for managing and
|
||||
displaying data.Frontend code is available at [rustdesk-api-web](https://github.com/lejianwen/rustdesk-api-web)
|
||||
|
||||
* Admin panel URL: `http://<your server[:port]>/_admin/`. The default username and password for the initial
|
||||
installation are `admin` `admin`, please change the password immediately.
|
||||
* Admin panel URL: `http://<your server[:port]>/_admin/`
|
||||
* For the initial installation, the admin username is `admin`, and the password will be printed in the console. You can change the password via the [command line](#CLI).
|
||||
|
||||

|
||||
|
||||
|
||||
1. Admin interface:
|
||||

|
||||
2. Regular user interface:
|
||||

|
||||
In the top right corner, you can change the password, switch languages, and toggle between `day/night` mode.
|
||||
|
||||

|
||||
3. Each user can have multiple address books, which can also be shared with other users.
|
||||
4. Groups can be customized for easy management. Currently, two types are supported: `shared group` and `regular group`.
|
||||
5. You can directly launch the client or open the web client for convenience; you can also share it with guests, who can remotely access the device via the web client.
|
||||

|
||||
6. OAuth support: Currently, `GitHub`, `Google` and `OIDC` are supported. You need to create an `OAuth App` and configure it in
|
||||
the admin panel.
|
||||

|
||||
- For `Google` and `Github`, you don't need to fill the `Issuer` and `Scpoes`
|
||||
- For `OIDC`, you must set the `Issuer`. And `Scopes` is optional which default is `openid,email,profile`, please make sure this `Oauth App` can access `sub`, `email` and `preferred_username`
|
||||
- Create a `GitHub OAuth App`
|
||||
@@ -97,19 +101,18 @@ installation are `admin` `admin`, please change the password immediately.
|
||||
8. Connection logs
|
||||
9. File transfer logs
|
||||
10. Server control
|
||||
- `Simple mode`, some simple commands have been GUI-ized and can be executed directly in the backend
|
||||

|
||||
|
||||
- `Simple mode`, some simple commands have been GUI-ized and can be executed directly in the backend
|
||||

|
||||
|
||||
- `Advanced mode`, commands can be executed directly in the backend
|
||||
- `Advanced mode`, commands can be executed directly in the backend
|
||||
* Official commands can be used
|
||||
* Custom commands can be added
|
||||
* Custom commands can be executed
|
||||
|
||||

|
||||
|
||||
|
||||

|
||||
|
||||
11. **LDAP Support**, When you setup the LDAP(test for OpenLDAP and AD), you can login with the LDAP's user. https://github.com/lejianwen/rustdesk-api/issues/114 , if LDAP fail fallback local user
|
||||
|
||||
### Web Client:
|
||||
|
||||
1. If you're already logged into the admin panel, the web client will log in automatically.
|
||||
@@ -182,47 +185,70 @@ proxy:
|
||||
jwt:
|
||||
key: ""
|
||||
expire-duration: 360000
|
||||
ldap:
|
||||
enable: false
|
||||
url: "ldap://ldap.example.com:389"
|
||||
tls: false
|
||||
tls-verify: false
|
||||
base-dn: "dc=example,dc=com"
|
||||
bind-dn: "cn=admin,dc=example,dc=com"
|
||||
bind-password: "password"
|
||||
|
||||
user:
|
||||
base-dn: "ou=users,dc=example,dc=com"
|
||||
enable-attr: "" #The attribute name of the user for enabling, in AD it is "userAccountControl", empty means no enable attribute, all users are enabled
|
||||
enable-attr-value: "" # The value of the enable attribute when the user is enabled. If you are using AD, just set random value, it will be ignored.
|
||||
filter: "(cn=*)"
|
||||
username: "uid" # The attribute name of the user for usernamem if you are using AD, it should be "sAMAccountName"
|
||||
email: "mail"
|
||||
first-name: "givenName"
|
||||
last-name: "sn"
|
||||
sync: false # If true, the user will be synchronized to the database when the user logs in. If false, the user will be synchronized to the database when the user be created.
|
||||
admin-group: "cn=admin,dc=example,dc=com" # The group name of the admin group, if the user is in this group, the user will be an admin.
|
||||
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
The prefix for variable names is `RUSTDESK_API`. If environment variables exist, they will override the configurations in the configuration file.
|
||||
The environment variables correspond one-to-one with the configurations in the `conf/config.yaml` file. The prefix for variable names is `RUSTDESK_API`.
|
||||
The table below does not list all configurations. Please refer to the configurations in `conf/config.yaml`.
|
||||
|
||||
| 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` |
|
||||
| ----JWT---- | -------- | -------- |
|
||||
| RUSTDESK_API_JWT_KEY | JWT KEY. Set empty to disable jwt | |
|
||||
| RUSTDESK_API_JWT_EXPIRE_DURATION | JWT expire duration | 360000 |
|
||||
| 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` |
|
||||
| RUSTDESK_API_APP_TOKEN_EXPIRE | token expire duration(second) | `3600` |
|
||||
| ----- 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<br/>_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` |
|
||||
| ----JWT---- | -------- | -------- |
|
||||
| RUSTDESK_API_JWT_KEY | Custom JWT KEY, if empty JWT is not enabled.<br/>If `MUST_LOGIN` from `lejianwen/rustdesk-server` is not used, it is recommended to leave it empty. | |
|
||||
| RUSTDESK_API_JWT_EXPIRE_DURATION | JWT expire duration | 360000 |
|
||||
|
||||
### Installation Steps
|
||||
|
||||
@@ -293,8 +319,9 @@ Download the release from [release](https://github.com/lejianwen/rustdesk-api/re
|
||||
|
||||
#### Running with my forked server-s6 image
|
||||
|
||||
- Connection timeout issue resolved
|
||||
- Can enforce login before initiating a connection
|
||||
- github https://github.com/lejianwen/rustdesk-server
|
||||
- docker hub https://hub.docker.com/r/lejianwen/rustdesk-server-s6
|
||||
|
||||
```yaml
|
||||
networks:
|
||||
@@ -334,4 +361,14 @@ Download the release from [release](https://github.com/lejianwen/rustdesk-api/re
|
||||
- [WIKI](https://github.com/lejianwen/rustdesk-api/wiki)
|
||||
- [Connection Timeout](https://github.com/lejianwen/rustdesk-api/issues/92)
|
||||
- [Change client ID](https://github.com/abdullah-erturk/RustDesk-ID-Changer)
|
||||
- [Web client source](https://hub.docker.com/r/keyurbhole/flutter_web_desk)
|
||||
- [Web client source](https://hub.docker.com/r/keyurbhole/flutter_web_desk)
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
Thanks to everyone who contributed!
|
||||
|
||||
<a href="https://github.com/lejianwen/rustdesk-api/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=lejianwen/rustdesk-api" />
|
||||
</a>
|
||||
|
||||
## Thanks for your support! If you find this project useful, please give it a ⭐️. Thank you!
|
||||
@@ -1,19 +1,19 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"Gwen/config"
|
||||
"Gwen/global"
|
||||
"Gwen/http"
|
||||
"Gwen/lib/cache"
|
||||
"Gwen/lib/jwt"
|
||||
"Gwen/lib/lock"
|
||||
"Gwen/lib/logger"
|
||||
"Gwen/lib/orm"
|
||||
"Gwen/lib/upload"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"fmt"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"github.com/lejianwen/rustdesk-api/v2/config"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http"
|
||||
"github.com/lejianwen/rustdesk-api/v2/lib/cache"
|
||||
"github.com/lejianwen/rustdesk-api/v2/lib/jwt"
|
||||
"github.com/lejianwen/rustdesk-api/v2/lib/lock"
|
||||
"github.com/lejianwen/rustdesk-api/v2/lib/logger"
|
||||
"github.com/lejianwen/rustdesk-api/v2/lib/orm"
|
||||
"github.com/lejianwen/rustdesk-api/v2/lib/upload"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"github.com/lejianwen/rustdesk-api/v2/utils"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
@@ -39,7 +39,7 @@ var rootCmd = &cobra.Command{
|
||||
InitGlobal()
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
//gin
|
||||
global.Logger.Info("API SERVER START")
|
||||
http.ApiInit()
|
||||
},
|
||||
}
|
||||
@@ -54,10 +54,10 @@ var resetPwdCmd = &cobra.Command{
|
||||
admin := service.AllService.UserService.InfoById(1)
|
||||
err := service.AllService.UserService.UpdatePassword(admin, pwd)
|
||||
if err != nil {
|
||||
fmt.Printf("reset password fail! %v \n", err)
|
||||
global.Logger.Error("reset password fail! ", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("reset password success! \n")
|
||||
global.Logger.Info("reset password success! ")
|
||||
},
|
||||
}
|
||||
var resetUserPwdCmd = &cobra.Command{
|
||||
@@ -70,20 +70,20 @@ var resetUserPwdCmd = &cobra.Command{
|
||||
pwd := args[1]
|
||||
uid, err := strconv.Atoi(userId)
|
||||
if err != nil {
|
||||
fmt.Printf("userId must be int! \n")
|
||||
global.Logger.Warn("userId must be int!")
|
||||
return
|
||||
}
|
||||
if uid <= 0 {
|
||||
fmt.Printf("userId must be greater than 0! \n")
|
||||
global.Logger.Warn("userId must be greater than 0! ")
|
||||
return
|
||||
}
|
||||
u := service.AllService.UserService.InfoById(uint(uid))
|
||||
err = service.AllService.UserService.UpdatePassword(u, pwd)
|
||||
if err != nil {
|
||||
fmt.Printf("reset password fail! %v \n", err)
|
||||
global.Logger.Warn("reset password fail! ", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("reset password success! \n")
|
||||
global.Logger.Info("reset password success!")
|
||||
},
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ func init() {
|
||||
}
|
||||
func main() {
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
fmt.Println(err)
|
||||
global.Logger.Error(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
@@ -102,9 +102,6 @@ func InitGlobal() {
|
||||
//配置解析
|
||||
global.Viper = config.Init(&global.Config, global.ConfigPath)
|
||||
|
||||
//从配置文件中加载密钥
|
||||
config.LoadKeyFile(&global.Config.Rustdesk)
|
||||
|
||||
//日志
|
||||
global.Logger = logger.New(&logger.Config{
|
||||
Path: global.Config.Logger.Path,
|
||||
@@ -178,7 +175,6 @@ func DatabaseAutoUpdate() {
|
||||
if global.Config.Gorm.Type == config.TypeMysql {
|
||||
//检查存不存在数据库,不存在则创建
|
||||
dbName := db.Migrator().CurrentDatabase()
|
||||
fmt.Println("dbName", dbName)
|
||||
if dbName == "" {
|
||||
dbName = global.Config.Mysql.Dbname
|
||||
// 移除 DSN 中的数据库名称,以便初始连接时不指定数据库
|
||||
@@ -190,18 +186,18 @@ func DatabaseAutoUpdate() {
|
||||
// 获取底层的 *sql.DB 对象,并确保在程序退出时关闭连接
|
||||
sqlDBWithoutDB, err := dbWithoutDB.DB()
|
||||
if err != nil {
|
||||
fmt.Printf("获取底层 *sql.DB 对象失败: %v\n", err)
|
||||
global.Logger.Errorf("获取底层 *sql.DB 对象失败: %v", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err := sqlDBWithoutDB.Close(); err != nil {
|
||||
fmt.Printf("关闭连接失败: %v\n", err)
|
||||
global.Logger.Errorf("关闭连接失败: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
err = dbWithoutDB.Exec("CREATE DATABASE IF NOT EXISTS " + dbName + " DEFAULT CHARSET utf8mb4").Error
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
global.Logger.Error(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -238,7 +234,7 @@ func DatabaseAutoUpdate() {
|
||||
|
||||
}
|
||||
func Migrate(version uint) {
|
||||
fmt.Println("migrating....", version)
|
||||
global.Logger.Info("migrating....", version)
|
||||
err := global.DB.AutoMigrate(
|
||||
&model.Version{},
|
||||
&model.User{},
|
||||
@@ -258,7 +254,7 @@ func Migrate(version uint) {
|
||||
&model.ServerCmd{},
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println("migrate err :=>", err)
|
||||
global.Logger.Error("migrate err :=>", err)
|
||||
}
|
||||
global.DB.Create(&model.Version{Version: version})
|
||||
//如果是初次则创建一个默认用户
|
||||
@@ -292,7 +288,11 @@ func Migrate(version uint) {
|
||||
IsAdmin: &is_admin,
|
||||
GroupId: 1,
|
||||
}
|
||||
admin.Password = service.AllService.UserService.EncryptPassword("admin")
|
||||
|
||||
// 生成随机密码
|
||||
pwd := utils.RandomString(8)
|
||||
global.Logger.Info("Admin Password Is: ", pwd)
|
||||
admin.Password = service.AllService.UserService.EncryptPassword(pwd)
|
||||
global.DB.Create(admin)
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
### 👏👏👏 你好 ***{{username}}***, 欢迎使用 [RustDesk Api](https://github.com/lejianwen/rustdesk-api)
|
||||
### 👏👏👏 你好 ***{{username}}***, 欢迎使用 [RustDesk API](https://github.com/lejianwen/rustdesk-api)
|
||||
@@ -3,6 +3,9 @@ app:
|
||||
web-client: 1 # 1:启用 0:禁用
|
||||
register: false #是否开启注册
|
||||
show-swagger: 0 # 1:启用 0:禁用
|
||||
token-expire: 360000
|
||||
web-sso: true #web auth sso
|
||||
disable-pwd-login: false #禁用密码登录
|
||||
admin:
|
||||
title: "RustDesk Api Admin"
|
||||
hello-file: "./conf/admin/hello.html" #优先使用file
|
||||
@@ -31,7 +34,7 @@ rustdesk:
|
||||
webclient-magic-queryonline: 0
|
||||
logger:
|
||||
path: "./runtime/log.txt"
|
||||
level: "debug" #trace,debug,info,warn,error,fatal
|
||||
level: "info" #trace,debug,info,warn,error,fatal
|
||||
report-caller: true
|
||||
proxy:
|
||||
enable: false
|
||||
@@ -39,6 +42,27 @@ proxy:
|
||||
jwt:
|
||||
key: ""
|
||||
expire-duration: 360000
|
||||
ldap:
|
||||
enable: false
|
||||
url: "ldap://ldap.example.com:389"
|
||||
tls: false
|
||||
tls-verify: false
|
||||
base-dn: "dc=example,dc=com"
|
||||
bind-dn: "cn=admin,dc=example,dc=com"
|
||||
bind-password: "password"
|
||||
|
||||
user:
|
||||
base-dn: "ou=users,dc=example,dc=com"
|
||||
enable-attr: "" #The attribute name of the user for enabling, in AD it is "userAccountControl", empty means no enable attribute, all users are enabled
|
||||
enable-attr-value: "" # The value of the enable attribute when the user is enabled. If you are using AD, just set random value, it will be ignored.
|
||||
filter: "(cn=*)"
|
||||
username: "uid" # The attribute name of the user for usernamem if you are using AD, it should be "sAMAccountName"
|
||||
email: "mail"
|
||||
first-name: "givenName"
|
||||
last-name: "sn"
|
||||
sync: false # If true, the user will be synchronized to the database when the user logs in. If false, the user will be synchronized to the database when the user be created.
|
||||
admin-group: "cn=admin,dc=example,dc=com" # The group name of the admin group, if the user is in this group, the user will be an admin.
|
||||
|
||||
redis:
|
||||
addr: "127.0.0.1:6379"
|
||||
password: ""
|
||||
|
||||
@@ -2,7 +2,6 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/spf13/viper"
|
||||
"strings"
|
||||
)
|
||||
@@ -14,9 +13,12 @@ const (
|
||||
)
|
||||
|
||||
type App struct {
|
||||
WebClient int `mapstructure:"web-client"`
|
||||
Register bool `mapstructure:"register"`
|
||||
ShowSwagger int `mapstructure:"show-swagger"`
|
||||
WebClient int `mapstructure:"web-client"`
|
||||
Register bool `mapstructure:"register"`
|
||||
ShowSwagger int `mapstructure:"show-swagger"`
|
||||
TokenExpire int `mapstructure:"token-expire"`
|
||||
WebSso bool `mapstructure:"web-sso"`
|
||||
DisablePwdLogin bool `mapstructure:"disable-pwd-login"`
|
||||
}
|
||||
type Admin struct {
|
||||
Title string `mapstructure:"title"`
|
||||
@@ -37,10 +39,11 @@ type Config struct {
|
||||
Jwt Jwt
|
||||
Rustdesk Rustdesk
|
||||
Proxy Proxy
|
||||
Ldap Ldap
|
||||
}
|
||||
|
||||
// Init 初始化配置
|
||||
func Init(rowVal interface{}, path string) *viper.Viper {
|
||||
func Init(rowVal *Config, path string) *viper.Viper {
|
||||
if path == "" {
|
||||
path = DefaultConfig
|
||||
}
|
||||
@@ -54,18 +57,26 @@ func Init(rowVal interface{}, path string) *viper.Viper {
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Fatal error config file: %s \n", err))
|
||||
}
|
||||
v.WatchConfig()
|
||||
v.OnConfigChange(func(e fsnotify.Event) {
|
||||
//配置文件修改监听
|
||||
fmt.Println("config file changed:", e.Name)
|
||||
if err2 := v.Unmarshal(rowVal); err2 != nil {
|
||||
fmt.Println(err2)
|
||||
}
|
||||
})
|
||||
/*
|
||||
v.WatchConfig()
|
||||
|
||||
|
||||
//监听配置修改没什么必要
|
||||
v.OnConfigChange(func(e fsnotify.Event) {
|
||||
//配置文件修改监听
|
||||
fmt.Println("config file changed:", e.Name)
|
||||
if err2 := v.Unmarshal(rowVal); err2 != nil {
|
||||
fmt.Println(err2)
|
||||
}
|
||||
rowVal.Rustdesk.LoadKeyFile()
|
||||
rowVal.Rustdesk.ParsePort()
|
||||
})
|
||||
*/
|
||||
if err := v.Unmarshal(rowVal); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
rowVal.Rustdesk.LoadKeyFile()
|
||||
rowVal.Rustdesk.ParsePort()
|
||||
return v
|
||||
}
|
||||
|
||||
|
||||
36
config/ldap.go
Normal file
36
config/ldap.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package config
|
||||
|
||||
type LdapUser struct {
|
||||
BaseDn string `mapstructure:"base-dn"` // The base DN of the user for searching
|
||||
EnableAttr string `mapstructure:"enable-attr"` // The attribute name of the user for enabling, in AD it is "userAccountControl", empty means no enable attribute, all users are enabled
|
||||
EnableAttrValue string `mapstructure:"enable-attr-value"` // The value of the enable attribute when the user is enabled. If you are using AD, just leave it random str, it will be ignored.
|
||||
Filter string `mapstructure:"filter"`
|
||||
Username string `mapstructure:"username"`
|
||||
Email string `mapstructure:"email"`
|
||||
FirstName string `mapstructure:"first-name"`
|
||||
LastName string `mapstructure:"last-name"`
|
||||
Sync bool `mapstructure:"sync"` // Will sync the user's information to the internal database
|
||||
AdminGroup string `mapstructure:"admin-group"` // Which group is the admin group
|
||||
}
|
||||
|
||||
// type LdapGroup struct {
|
||||
// BaseDn string `mapstructure:"base-dn"` // The base DN of the group for searching
|
||||
// Name string `mapstructure:"name"` // The attribute name of the group
|
||||
// Filter string `mapstructure:"filter"`
|
||||
// Admin string `mapstructure:"admin"` // Which group is the admin group
|
||||
// Member string `mapstructure:"member"` // How to get the member of the group: member, uniqueMember, or memberOf (default: member)
|
||||
// Mode string `mapstructure:"mode"`
|
||||
// Map map[string]string `mapstructure:"map"` // If mode is "map", map the LDAP group to the internal group
|
||||
// }
|
||||
|
||||
type Ldap struct {
|
||||
Enable bool `mapstructure:"enable"`
|
||||
Url string `mapstructure:"url"`
|
||||
TLS bool `mapstructure:"tls"`
|
||||
TlsVerify bool `mapstructure:"tls-verify"`
|
||||
BaseDn string `mapstructure:"base-dn"`
|
||||
BindDn string `mapstructure:"bind-dn"`
|
||||
BindPassword string `mapstructure:"bind-password"`
|
||||
User LdapUser `mapstructure:"user"`
|
||||
// Group LdapGroup `mapstructure:"group"`
|
||||
}
|
||||
@@ -17,4 +17,4 @@ type OidcOauth struct {
|
||||
ClientId string `mapstructure:"client-id"`
|
||||
ClientSecret string `mapstructure:"client-secret"`
|
||||
RedirectUrl string `mapstructure:"redirect-url"`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,31 +2,56 @@ package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultIdServerPort = 21116
|
||||
DefaultRelayServerPort = 21117
|
||||
)
|
||||
|
||||
type Rustdesk struct {
|
||||
IdServer string `mapstructure:"id-server"`
|
||||
RelayServer string `mapstructure:"relay-server"`
|
||||
ApiServer string `mapstructure:"api-server"`
|
||||
Key string `mapstructure:"key"`
|
||||
KeyFile string `mapstructure:"key-file"`
|
||||
Personal int `mapstructure:"personal"`
|
||||
IdServer string `mapstructure:"id-server"`
|
||||
IdServerPort int `mapstructure:"-"`
|
||||
RelayServer string `mapstructure:"relay-server"`
|
||||
RelayServerPort int `mapstructure:"-"`
|
||||
ApiServer string `mapstructure:"api-server"`
|
||||
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) {
|
||||
func (rd *Rustdesk) LoadKeyFile() {
|
||||
// Load key file
|
||||
if rustdesk.Key != "" {
|
||||
if rd.Key != "" {
|
||||
return
|
||||
}
|
||||
if rustdesk.KeyFile != "" {
|
||||
if rd.KeyFile != "" {
|
||||
// Load key from file
|
||||
b, err := os.ReadFile(rustdesk.KeyFile)
|
||||
b, err := os.ReadFile(rd.KeyFile)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
rustdesk.Key = string(b)
|
||||
rd.Key = string(b)
|
||||
return
|
||||
}
|
||||
}
|
||||
func (rd *Rustdesk) ParsePort() {
|
||||
// Parse port
|
||||
idres := strings.Split(rd.IdServer, ":")
|
||||
if len(idres) == 1 {
|
||||
rd.IdServerPort = DefaultIdServerPort
|
||||
} else if len(idres) == 2 {
|
||||
rd.IdServerPort, _ = strconv.Atoi(idres[1])
|
||||
}
|
||||
|
||||
relayres := strings.Split(rd.RelayServer, ":")
|
||||
if len(relayres) == 1 {
|
||||
rd.RelayServerPort = DefaultRelayServerPort
|
||||
} else if len(relayres) == 2 {
|
||||
rd.RelayServerPort, _ = strconv.Atoi(relayres[1])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -981,40 +981,6 @@ const docTemplateadmin = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/app-config": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "APP服务配置",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"ADMIN"
|
||||
],
|
||||
"summary": "APP服务配置",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/audit_conn/batchDelete": {
|
||||
"post": {
|
||||
"security": [
|
||||
@@ -1817,7 +1783,7 @@ const docTemplateadmin = `{
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Gwen_http_request_admin.Login"
|
||||
"$ref": "#/definitions/github_com_lejianwen_rustdesk-api_http_request_admin.Login"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -1881,7 +1847,7 @@ const docTemplateadmin = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/login_log/delete": {
|
||||
"/admin/login_log/batchDelete": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
@@ -1926,6 +1892,51 @@ const docTemplateadmin = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/login_log/delete": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "登录日志删除",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"登录日志"
|
||||
],
|
||||
"summary": "登录日志删除",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "登录日志信息",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/model.LoginLog"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/login_log/detail/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -2757,6 +2768,162 @@ const docTemplateadmin = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/my/login_log/batchDelete": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "登录日志批量删除",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"我的登录日志"
|
||||
],
|
||||
"summary": "登录日志批量删除",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "登录日志",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/admin.LoginLogIds"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/my/login_log/delete": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "登录日志删除",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"我的登录日志"
|
||||
],
|
||||
"summary": "登录日志删除",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "登录日志信息",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/model.LoginLog"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/my/login_log/list": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "登录日志列表",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"我的登录日志"
|
||||
],
|
||||
"summary": "登录日志列表",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "页码",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "页大小",
|
||||
"name": "page_size",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "用户ID",
|
||||
"name": "user_id",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/response.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/model.LoginLogList"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/my/peer/list": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -3884,40 +4051,6 @@ const docTemplateadmin = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/server-config": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "服务配置,给webclient提供api-server",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"ADMIN"
|
||||
],
|
||||
"summary": "RUSTDESK服务配置",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/share_record/batchDelete": {
|
||||
"post": {
|
||||
"security": [
|
||||
@@ -4971,27 +5104,6 @@ const docTemplateadmin = `{
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"Gwen_http_request_admin.Login": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"password",
|
||||
"username"
|
||||
],
|
||||
"properties": {
|
||||
"captcha": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"platform": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"admin.AddressBookForm": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@@ -5409,6 +5521,27 @@ const docTemplateadmin = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"github_com_lejianwen_rustdesk-api_http_request_admin.Login": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"password",
|
||||
"username"
|
||||
],
|
||||
"properties": {
|
||||
"captcha": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"platform": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"model.AddressBook": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -5768,6 +5901,9 @@ const docTemplateadmin = `{
|
||||
"ip": {
|
||||
"type": "string"
|
||||
},
|
||||
"is_deleted": {
|
||||
"type": "integer"
|
||||
},
|
||||
"platform": {
|
||||
"description": "windows,linux,mac,android,ios",
|
||||
"type": "string"
|
||||
|
||||
@@ -974,40 +974,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/app-config": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "APP服务配置",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"ADMIN"
|
||||
],
|
||||
"summary": "APP服务配置",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/audit_conn/batchDelete": {
|
||||
"post": {
|
||||
"security": [
|
||||
@@ -1810,7 +1776,7 @@
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Gwen_http_request_admin.Login"
|
||||
"$ref": "#/definitions/github_com_lejianwen_rustdesk-api_http_request_admin.Login"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -1874,7 +1840,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/login_log/delete": {
|
||||
"/admin/login_log/batchDelete": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
@@ -1919,6 +1885,51 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/login_log/delete": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "登录日志删除",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"登录日志"
|
||||
],
|
||||
"summary": "登录日志删除",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "登录日志信息",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/model.LoginLog"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/login_log/detail/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -2750,6 +2761,162 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/my/login_log/batchDelete": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "登录日志批量删除",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"我的登录日志"
|
||||
],
|
||||
"summary": "登录日志批量删除",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "登录日志",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/admin.LoginLogIds"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/my/login_log/delete": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "登录日志删除",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"我的登录日志"
|
||||
],
|
||||
"summary": "登录日志删除",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "登录日志信息",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/model.LoginLog"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/my/login_log/list": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "登录日志列表",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"我的登录日志"
|
||||
],
|
||||
"summary": "登录日志列表",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "页码",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "页大小",
|
||||
"name": "page_size",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "用户ID",
|
||||
"name": "user_id",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/response.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/model.LoginLogList"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/my/peer/list": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -3877,40 +4044,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/server-config": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "服务配置,给webclient提供api-server",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"ADMIN"
|
||||
],
|
||||
"summary": "RUSTDESK服务配置",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/admin/share_record/batchDelete": {
|
||||
"post": {
|
||||
"security": [
|
||||
@@ -4964,27 +5097,6 @@
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"Gwen_http_request_admin.Login": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"password",
|
||||
"username"
|
||||
],
|
||||
"properties": {
|
||||
"captcha": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"platform": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"admin.AddressBookForm": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@@ -5402,6 +5514,27 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"github_com_lejianwen_rustdesk-api_http_request_admin.Login": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"password",
|
||||
"username"
|
||||
],
|
||||
"properties": {
|
||||
"captcha": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"platform": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"model.AddressBook": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -5761,6 +5894,9 @@
|
||||
"ip": {
|
||||
"type": "string"
|
||||
},
|
||||
"is_deleted": {
|
||||
"type": "integer"
|
||||
},
|
||||
"platform": {
|
||||
"description": "windows,linux,mac,android,ios",
|
||||
"type": "string"
|
||||
|
||||
@@ -1,19 +1,5 @@
|
||||
basePath: /api
|
||||
definitions:
|
||||
Gwen_http_request_admin.Login:
|
||||
properties:
|
||||
captcha:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
platform:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
required:
|
||||
- password
|
||||
- username
|
||||
type: object
|
||||
admin.AddressBookForm:
|
||||
properties:
|
||||
alias:
|
||||
@@ -292,6 +278,20 @@ definitions:
|
||||
required:
|
||||
- ids
|
||||
type: object
|
||||
github_com_lejianwen_rustdesk-api_http_request_admin.Login:
|
||||
properties:
|
||||
captcha:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
platform:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
required:
|
||||
- password
|
||||
- username
|
||||
type: object
|
||||
model.AddressBook:
|
||||
properties:
|
||||
alias:
|
||||
@@ -531,6 +531,8 @@ definitions:
|
||||
type: integer
|
||||
ip:
|
||||
type: string
|
||||
is_deleted:
|
||||
type: integer
|
||||
platform:
|
||||
description: windows,linux,mac,android,ios
|
||||
type: string
|
||||
@@ -1347,27 +1349,6 @@ paths:
|
||||
summary: 地址簿规则编辑
|
||||
tags:
|
||||
- 地址簿规则
|
||||
/admin/app-config:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: APP服务配置
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- token: []
|
||||
summary: APP服务配置
|
||||
tags:
|
||||
- ADMIN
|
||||
/admin/audit_conn/batchDelete:
|
||||
post:
|
||||
consumes:
|
||||
@@ -1849,7 +1830,7 @@ paths:
|
||||
name: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/Gwen_http_request_admin.Login'
|
||||
$ref: '#/definitions/github_com_lejianwen_rustdesk-api_http_request_admin.Login'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
@@ -1892,7 +1873,7 @@ paths:
|
||||
summary: 登录选项
|
||||
tags:
|
||||
- 登录
|
||||
/admin/login_log/delete:
|
||||
/admin/login_log/batchDelete:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
@@ -1920,6 +1901,34 @@ paths:
|
||||
summary: 登录日志批量删除
|
||||
tags:
|
||||
- 登录日志
|
||||
/admin/login_log/delete:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 登录日志删除
|
||||
parameters:
|
||||
- description: 登录日志信息
|
||||
in: body
|
||||
name: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/model.LoginLog'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- token: []
|
||||
summary: 登录日志删除
|
||||
tags:
|
||||
- 登录日志
|
||||
/admin/login_log/detail/{id}:
|
||||
get:
|
||||
consumes:
|
||||
@@ -2413,6 +2422,101 @@ paths:
|
||||
summary: 地址簿规则编辑
|
||||
tags:
|
||||
- 我的地址簿规则
|
||||
/admin/my/login_log/batchDelete:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 登录日志批量删除
|
||||
parameters:
|
||||
- description: 登录日志
|
||||
in: body
|
||||
name: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/admin.LoginLogIds'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- token: []
|
||||
summary: 登录日志批量删除
|
||||
tags:
|
||||
- 我的登录日志
|
||||
/admin/my/login_log/delete:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 登录日志删除
|
||||
parameters:
|
||||
- description: 登录日志信息
|
||||
in: body
|
||||
name: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/model.LoginLog'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- token: []
|
||||
summary: 登录日志删除
|
||||
tags:
|
||||
- 我的登录日志
|
||||
/admin/my/login_log/list:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 登录日志列表
|
||||
parameters:
|
||||
- description: 页码
|
||||
in: query
|
||||
name: page
|
||||
type: integer
|
||||
- description: 页大小
|
||||
in: query
|
||||
name: page_size
|
||||
type: integer
|
||||
- description: 用户ID
|
||||
in: query
|
||||
name: user_id
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/response.Response'
|
||||
- properties:
|
||||
data:
|
||||
$ref: '#/definitions/model.LoginLogList'
|
||||
type: object
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- token: []
|
||||
summary: 登录日志列表
|
||||
tags:
|
||||
- 我的登录日志
|
||||
/admin/my/peer/list:
|
||||
get:
|
||||
consumes:
|
||||
@@ -3088,27 +3192,6 @@ paths:
|
||||
summary: 设备编辑
|
||||
tags:
|
||||
- 设备
|
||||
/admin/server-config:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 服务配置,给webclient提供api-server
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- token: []
|
||||
summary: RUSTDESK服务配置
|
||||
tags:
|
||||
- ADMIN
|
||||
/admin/share_record/batchDelete:
|
||||
post:
|
||||
consumes:
|
||||
|
||||
@@ -653,40 +653,6 @@ const docTemplateapi = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "用户信息",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"用户"
|
||||
],
|
||||
"summary": "用户信息",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.UserPayload"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/audit/conn": {
|
||||
"post": {
|
||||
"description": "审计连接",
|
||||
@@ -767,6 +733,40 @@ const docTemplateapi = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/currentUser": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "用户信息",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"用户"
|
||||
],
|
||||
"summary": "用户信息",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.UserPayload"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/heartbeat": {
|
||||
"post": {
|
||||
"description": "心跳",
|
||||
@@ -1178,43 +1178,6 @@ const docTemplateapi = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/tags": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "标签",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址"
|
||||
],
|
||||
"summary": "标签",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/model.Tag"
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -1289,6 +1252,35 @@ const docTemplateapi = `{
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/version": {
|
||||
"get": {
|
||||
"description": "版本",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"首页"
|
||||
],
|
||||
"summary": "版本",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
|
||||
@@ -646,40 +646,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "用户信息",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"用户"
|
||||
],
|
||||
"summary": "用户信息",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.UserPayload"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/audit/conn": {
|
||||
"post": {
|
||||
"description": "审计连接",
|
||||
@@ -760,6 +726,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/currentUser": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"token": []
|
||||
}
|
||||
],
|
||||
"description": "用户信息",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"用户"
|
||||
],
|
||||
"summary": "用户信息",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.UserPayload"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/heartbeat": {
|
||||
"post": {
|
||||
"description": "心跳",
|
||||
@@ -1171,43 +1171,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/tags": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "标签",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"地址"
|
||||
],
|
||||
"summary": "标签",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/model.Tag"
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -1282,6 +1245,35 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/version": {
|
||||
"get": {
|
||||
"description": "版本",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"首页"
|
||||
],
|
||||
"summary": "版本",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
|
||||
@@ -598,27 +598,6 @@ paths:
|
||||
summary: 标签
|
||||
tags:
|
||||
- 地址[Personal]
|
||||
/api:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 用户信息
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/api.UserPayload'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- token: []
|
||||
summary: 用户信息
|
||||
tags:
|
||||
- 用户
|
||||
/audit/conn:
|
||||
post:
|
||||
consumes:
|
||||
@@ -671,6 +650,27 @@ paths:
|
||||
summary: 审计文件
|
||||
tags:
|
||||
- 审计
|
||||
/currentUser:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 用户信息
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/api.UserPayload'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- token: []
|
||||
summary: 用户信息
|
||||
tags:
|
||||
- 用户
|
||||
/heartbeat:
|
||||
post:
|
||||
consumes:
|
||||
@@ -936,29 +936,6 @@ paths:
|
||||
summary: 提交系统信息
|
||||
tags:
|
||||
- 地址
|
||||
/tags:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 标签
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/model.Tag'
|
||||
type: array
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.ErrorResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 标签
|
||||
tags:
|
||||
- 地址
|
||||
/users:
|
||||
get:
|
||||
consumes:
|
||||
@@ -1004,6 +981,25 @@ paths:
|
||||
summary: 用户列表
|
||||
tags:
|
||||
- 群组
|
||||
/version:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 版本
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
summary: 版本
|
||||
tags:
|
||||
- 首页
|
||||
securityDefinitions:
|
||||
BearerAuth:
|
||||
in: header
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 67 KiB |
BIN
docs/init_admin_pwd.png
Normal file
BIN
docs/init_admin_pwd.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 67 KiB |
@@ -1,4 +1,4 @@
|
||||
package Gwen
|
||||
package main
|
||||
|
||||
//go:generate swag init -g cmd/apimain.go --output docs/api --instanceName api --exclude http/controller/admin
|
||||
//go:generate swag init -g cmd/apimain.go --output docs/admin --instanceName admin --exclude http/controller/api
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
package Gwen
|
||||
package main
|
||||
|
||||
//go:generate go run cmd/apimain.go
|
||||
|
||||
@@ -4,18 +4,19 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-playground/locales/en"
|
||||
"github.com/go-playground/locales/es"
|
||||
"github.com/go-playground/locales/fr"
|
||||
"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"
|
||||
|
||||
"github.com/go-playground/locales/zh_Hant"
|
||||
ut "github.com/go-playground/universal-translator"
|
||||
"github.com/go-playground/validator/v10"
|
||||
en_translations "github.com/go-playground/validator/v10/translations/en"
|
||||
es_translations "github.com/go-playground/validator/v10/translations/es"
|
||||
fr_translations "github.com/go-playground/validator/v10/translations/fr"
|
||||
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"
|
||||
zh_tw_translations "github.com/go-playground/validator/v10/translations/zh_tw"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
@@ -29,8 +30,9 @@ func ApiInitValidator() {
|
||||
ruT := ru.New()
|
||||
esT := es.New()
|
||||
frT := fr.New()
|
||||
zhTwT := zh_Hant.New()
|
||||
|
||||
uni := ut.New(enT, cn, koT, ruT, esT, frT)
|
||||
uni := ut.New(enT, cn, koT, ruT, esT, frT, zhTwT)
|
||||
|
||||
enTrans, _ := uni.GetTranslator("en")
|
||||
zhTrans, _ := uni.GetTranslator("zh_Hans_CN")
|
||||
@@ -38,6 +40,7 @@ func ApiInitValidator() {
|
||||
ruTrans, _ := uni.GetTranslator("ru")
|
||||
esTrans, _ := uni.GetTranslator("es")
|
||||
frTrans, _ := uni.GetTranslator("fr")
|
||||
zhTwTrans, _ := uni.GetTranslator("zh_Hant")
|
||||
|
||||
err := zh_translations.RegisterDefaultTranslations(validate, zhTrans)
|
||||
if err != nil {
|
||||
@@ -65,6 +68,10 @@ func ApiInitValidator() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = zh_tw_translations.RegisterDefaultTranslations(validate, zhTwTrans)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
validate.RegisterTagNameFunc(func(field reflect.StructField) string {
|
||||
label := field.Tag.Get("label")
|
||||
@@ -125,6 +132,13 @@ func getTranslatorForLang(lang string) ut.Translator {
|
||||
case "zh":
|
||||
trans, _ := Validator.UT.GetTranslator("zh_Hans_CN")
|
||||
return trans
|
||||
case "zh_TW":
|
||||
fallthrough
|
||||
case "zh-TW":
|
||||
fallthrough
|
||||
case "zh-tw":
|
||||
trans, _ := Validator.UT.GetTranslator("zh_Hant")
|
||||
return trans
|
||||
case "ko":
|
||||
trans, _ := Validator.UT.GetTranslator("ko")
|
||||
return trans
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package global
|
||||
|
||||
import (
|
||||
"Gwen/config"
|
||||
"Gwen/lib/cache"
|
||||
"Gwen/lib/jwt"
|
||||
"Gwen/lib/lock"
|
||||
"Gwen/lib/upload"
|
||||
"github.com/gin-gonic/gin"
|
||||
ut "github.com/go-playground/universal-translator"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"github.com/lejianwen/rustdesk-api/v2/config"
|
||||
"github.com/lejianwen/rustdesk-api/v2/lib/cache"
|
||||
"github.com/lejianwen/rustdesk-api/v2/lib/jwt"
|
||||
"github.com/lejianwen/rustdesk-api/v2/lib/lock"
|
||||
"github.com/lejianwen/rustdesk-api/v2/lib/upload"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
@@ -15,7 +15,6 @@ func InitI18n() {
|
||||
fileInfos, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return
|
||||
}
|
||||
for _, fileInfo := range fileInfos {
|
||||
//如果文件名不是.toml结尾
|
||||
|
||||
15
go.mod
15
go.mod
@@ -1,4 +1,4 @@
|
||||
module Gwen
|
||||
module github.com/lejianwen/rustdesk-api/v2
|
||||
|
||||
go 1.22
|
||||
|
||||
@@ -13,7 +13,7 @@ require (
|
||||
github.com/go-playground/validator/v10 v10.11.2
|
||||
github.com/go-redis/redis/v8 v8.11.4
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
github.com/google/uuid v1.1.2
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/nicksnyder/go-i18n/v2 v2.4.0
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/spf13/cobra v1.8.1
|
||||
@@ -22,13 +22,14 @@ require (
|
||||
github.com/swaggo/gin-swagger v1.6.0
|
||||
github.com/swaggo/swag v1.16.3
|
||||
golang.org/x/oauth2 v0.23.0
|
||||
golang.org/x/text v0.18.0
|
||||
golang.org/x/text v0.21.0
|
||||
gorm.io/driver/mysql v1.5.7
|
||||
gorm.io/driver/sqlite v1.5.6
|
||||
gorm.io/gorm v1.25.7
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
@@ -37,6 +38,8 @@ require (
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect
|
||||
github.com/go-ldap/ldap/v3 v3.4.10 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||
github.com/go-openapi/spec v0.20.4 // indirect
|
||||
@@ -70,10 +73,10 @@ require (
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.9 // indirect
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
|
||||
golang.org/x/crypto v0.23.0 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/image v0.13.0 // indirect
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
golang.org/x/net v0.33.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/ini.v1 v1.63.2 // indirect
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/service"
|
||||
"encoding/json"
|
||||
_ "encoding/json"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"gorm.io/gorm"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"gorm.io/gorm"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"gorm.io/gorm"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/response"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
@@ -61,6 +61,12 @@ func (co *Config) AppConfig(c *gin.Context) {
|
||||
func (co *Config) AdminConfig(c *gin.Context) {
|
||||
|
||||
u := service.AllService.UserService.CurUser(c)
|
||||
if u == nil || u.Id == 0 {
|
||||
response.Success(c, &gin.H{
|
||||
"title": global.Config.Admin.Title,
|
||||
})
|
||||
return
|
||||
}
|
||||
hello := global.Config.Admin.Hello
|
||||
helloFile := global.Config.Admin.HelloFile
|
||||
if helloFile != "" {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/response"
|
||||
"Gwen/lib/upload"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/lib/upload"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/controller/api"
|
||||
"Gwen/http/request/admin"
|
||||
apiReq "Gwen/http/request/api"
|
||||
"Gwen/http/response"
|
||||
adResp "Gwen/http/response/admin"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/controller/api"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
apiReq "github.com/lejianwen/rustdesk-api/v2/http/request/api"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
adResp "github.com/lejianwen/rustdesk-api/v2/http/response/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"github.com/mojocn/base64Captcha"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -152,6 +152,10 @@ var loginLimiter = NewLoginLimiter(3, 5*time.Minute)
|
||||
// @Router /admin/login [post]
|
||||
// @Security token
|
||||
func (ct *Login) Login(c *gin.Context) {
|
||||
if global.Config.App.DisablePwdLogin {
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "PwdLoginDisabled"))
|
||||
return
|
||||
}
|
||||
f := &admin.Login{}
|
||||
err := c.ShouldBindJSON(f)
|
||||
clientIp := c.ClientIP()
|
||||
@@ -182,15 +186,20 @@ func (ct *Login) Login(c *gin.Context) {
|
||||
global.Logger.Warn(fmt.Sprintf("Login Fail: %s %s %s", "UsernameOrPasswordError", c.RemoteIP(), clientIp))
|
||||
loginLimiter.RecordFailure(clientIp)
|
||||
if loginLimiter.NeedsCaptcha(clientIp) {
|
||||
// 移除原验证码,重新生成
|
||||
loginLimiter.RemoveCaptcha(clientIp)
|
||||
response.Fail(c, 110, response.TranslateMsg(c, "UsernameOrPasswordError"))
|
||||
return
|
||||
}
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "UsernameOrPasswordError"))
|
||||
return
|
||||
}
|
||||
|
||||
if !service.AllService.UserService.CheckUserEnable(u) {
|
||||
if loginLimiter.NeedsCaptcha(clientIp) {
|
||||
loginLimiter.RemoveCaptcha(clientIp)
|
||||
}
|
||||
response.Fail(c, 101, response.TranslateMsg(c, "UserDisabled"))
|
||||
return
|
||||
}
|
||||
|
||||
ut := service.AllService.UserService.Login(u, &model.LoginLog{
|
||||
UserId: u.Id,
|
||||
Client: model.LoginLogClientWebAdmin,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"gorm.io/gorm"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package my
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/service"
|
||||
"encoding/json"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package my
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package my
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package my
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package my
|
||||
|
||||
import (
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"gorm.io/gorm"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package my
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package my
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
adminReq "Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
adminReq "github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"gorm.io/gorm"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
)
|
||||
|
||||
type Rustdesk struct {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"gorm.io/gorm"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
adResp "Gwen/http/response/admin"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
adResp "github.com/lejianwen/rustdesk-api/v2/http/response/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"gorm.io/gorm"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/admin"
|
||||
"Gwen/http/response"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
requstform "Gwen/http/request/api"
|
||||
"Gwen/http/response"
|
||||
"Gwen/http/response/api"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"Gwen/utils"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
requstform "github.com/lejianwen/rustdesk-api/v2/http/request/api"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response/api"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"github.com/lejianwen/rustdesk-api/v2/utils"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
request "Gwen/http/request/api"
|
||||
"Gwen/http/response"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
request "github.com/lejianwen/rustdesk-api/v2/http/request/api"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
apiReq "Gwen/http/request/api"
|
||||
"Gwen/http/response"
|
||||
apiResp "Gwen/http/response/api"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
apiReq "github.com/lejianwen/rustdesk-api/v2/http/request/api"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
apiResp "github.com/lejianwen/rustdesk-api/v2/http/response/api"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
requstform "Gwen/http/request/api"
|
||||
"Gwen/http/response"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
requstform "github.com/lejianwen/rustdesk-api/v2/http/request/api"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -61,3 +62,25 @@ func (i *Index) Heartbeat(c *gin.Context) {
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{})
|
||||
}
|
||||
|
||||
// Version 版本
|
||||
// @Tags 首页
|
||||
// @Summary 版本
|
||||
// @Description 版本
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /version [get]
|
||||
func (i *Index) Version(c *gin.Context) {
|
||||
//读取resources/version文件
|
||||
v, err := os.ReadFile("resources/version")
|
||||
if err != nil {
|
||||
response.Fail(c, 101, err.Error())
|
||||
return
|
||||
}
|
||||
response.Success(
|
||||
c,
|
||||
string(v),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/api"
|
||||
"Gwen/http/response"
|
||||
apiResp "Gwen/http/response/api"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/api"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
apiResp "github.com/lejianwen/rustdesk-api/v2/http/response/api"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
@@ -27,6 +27,10 @@ type Login struct {
|
||||
// @Failure 500 {object} response.ErrorResponse
|
||||
// @Router /login [post]
|
||||
func (l *Login) Login(c *gin.Context) {
|
||||
if global.Config.App.DisablePwdLogin {
|
||||
response.Error(c, response.TranslateMsg(c, "PwdLoginDisabled"))
|
||||
return
|
||||
}
|
||||
f := &api.LoginForm{}
|
||||
err := c.ShouldBindJSON(f)
|
||||
//fmt.Println(f)
|
||||
@@ -51,6 +55,11 @@ func (l *Login) Login(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if !service.AllService.UserService.CheckUserEnable(u) {
|
||||
response.Error(c, response.TranslateMsg(c, "UserDisabled"))
|
||||
return
|
||||
}
|
||||
|
||||
//根据refer判断是webclient还是app
|
||||
ref := c.GetHeader("referer")
|
||||
if ref != "" {
|
||||
@@ -85,7 +94,9 @@ func (l *Login) Login(c *gin.Context) {
|
||||
// @Router /login-options [get]
|
||||
func (l *Login) LoginOptions(c *gin.Context) {
|
||||
ops := service.AllService.OauthService.GetOauthProviders()
|
||||
ops = append(ops, model.OauthTypeWebauth)
|
||||
if global.Config.App.WebSso {
|
||||
ops = append(ops, model.OauthTypeWebauth)
|
||||
}
|
||||
var oidcItems []map[string]string
|
||||
for _, v := range ops {
|
||||
oidcItems = append(oidcItems, map[string]string{"name": v})
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/request/api"
|
||||
"Gwen/http/response"
|
||||
apiResp "Gwen/http/response/api"
|
||||
"Gwen/model"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/request/api"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
apiResp "github.com/lejianwen/rustdesk-api/v2/http/response/api"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
requstform "Gwen/http/request/api"
|
||||
"Gwen/http/response"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
requstform "github.com/lejianwen/rustdesk-api/v2/http/request/api"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
apiResp "Gwen/http/response/api"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
apiResp "github.com/lejianwen/rustdesk-api/v2/http/response/api"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
@@ -34,7 +34,7 @@ type User struct {
|
||||
// @Produce json
|
||||
// @Success 200 {object} apiResp.UserPayload
|
||||
// @Failure 500 {object} response.Response
|
||||
// @Router /api [get]
|
||||
// @Router /currentUser [get]
|
||||
// @Security token
|
||||
func (u *User) Info(c *gin.Context) {
|
||||
user := service.AllService.UserService.CurUser(c)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/response"
|
||||
"Gwen/http/response/api"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response/api"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/middleware"
|
||||
"Gwen/http/router"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/middleware"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/router"
|
||||
"github.com/sirupsen/logrus"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"Gwen/http/response"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
)
|
||||
|
||||
// AdminAuth 后台权限验证中间件
|
||||
func AdminAuth() gin.HandlerFunc {
|
||||
// BackendUserAuth 后台权限验证中间件
|
||||
func BackendUserAuth() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
|
||||
//测试先关闭
|
||||
@@ -24,6 +24,14 @@ func AdminAuth() gin.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
if !service.AllService.UserService.CheckUserEnable(user) {
|
||||
c.JSON(401, gin.H{
|
||||
"error": "Unauthorized",
|
||||
})
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
c.Set("curUser", user)
|
||||
c.Set("token", token)
|
||||
//如果时间小于1天,token自动续期
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"Gwen/http/response"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
)
|
||||
|
||||
// AdminPrivilege ...
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/response"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
)
|
||||
|
||||
func JwtAuth() gin.HandlerFunc {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
)
|
||||
|
||||
func RustAuth() gin.HandlerFunc {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/model"
|
||||
"encoding/json"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
)
|
||||
|
||||
type AddressBookForm struct {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package admin
|
||||
|
||||
import "Gwen/model"
|
||||
import "github.com/lejianwen/rustdesk-api/v2/model"
|
||||
|
||||
type GroupForm struct {
|
||||
Id uint `json:"id"`
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
)
|
||||
|
||||
type BindOauthForm struct {
|
||||
@@ -15,21 +15,21 @@ type UnBindOauthForm struct {
|
||||
Op string `json:"op" binding:"required"`
|
||||
}
|
||||
type OauthForm struct {
|
||||
Id uint `json:"id"`
|
||||
Op string `json:"op" validate:"omitempty"`
|
||||
OauthType string `json:"oauth_type" validate:"required"`
|
||||
Issuer string `json:"issuer" validate:"omitempty,url"`
|
||||
Scopes string `json:"scopes" validate:"omitempty"`
|
||||
ClientId string `json:"client_id" validate:"required"`
|
||||
ClientSecret string `json:"client_secret" validate:"required"`
|
||||
RedirectUrl string `json:"redirect_url" validate:"required"`
|
||||
AutoRegister *bool `json:"auto_register"`
|
||||
Id uint `json:"id"`
|
||||
Op string `json:"op" validate:"omitempty"`
|
||||
OauthType string `json:"oauth_type" validate:"required"`
|
||||
Issuer string `json:"issuer" validate:"omitempty,url"`
|
||||
Scopes string `json:"scopes" validate:"omitempty"`
|
||||
ClientId string `json:"client_id" validate:"required"`
|
||||
ClientSecret string `json:"client_secret" validate:"required"`
|
||||
RedirectUrl string `json:"redirect_url" validate:"required"`
|
||||
AutoRegister *bool `json:"auto_register"`
|
||||
}
|
||||
|
||||
func (of *OauthForm) ToOauth() *model.Oauth {
|
||||
oa := &model.Oauth{
|
||||
Op: of.Op,
|
||||
OauthType: of.OauthType,
|
||||
OauthType: of.OauthType,
|
||||
ClientId: of.ClientId,
|
||||
ClientSecret: of.ClientSecret,
|
||||
RedirectUrl: of.RedirectUrl,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package admin
|
||||
|
||||
import "Gwen/model"
|
||||
import "github.com/lejianwen/rustdesk-api/v2/model"
|
||||
|
||||
type PeerForm struct {
|
||||
RowId uint `json:"row_id" `
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package admin
|
||||
|
||||
import "Gwen/model"
|
||||
import "github.com/lejianwen/rustdesk-api/v2/model"
|
||||
|
||||
type TagForm struct {
|
||||
Id uint `json:"id"`
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"Gwen/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
)
|
||||
|
||||
type UserForm struct {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/model"
|
||||
"encoding/json"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package api
|
||||
|
||||
import "Gwen/model"
|
||||
import "github.com/lejianwen/rustdesk-api/v2/model"
|
||||
|
||||
type AddressBookFormData struct {
|
||||
Tags []string `json:"tags"`
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package admin
|
||||
|
||||
import "Gwen/model"
|
||||
import "github.com/lejianwen/rustdesk-api/v2/model"
|
||||
|
||||
type LoginPayload struct {
|
||||
Username string `json:"username"`
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package api
|
||||
|
||||
import "Gwen/model"
|
||||
import "github.com/lejianwen/rustdesk-api/v2/model"
|
||||
|
||||
type AbList struct {
|
||||
Peers []*model.AddressBook `json:"peers,omitempty"`
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package api
|
||||
|
||||
import "Gwen/model"
|
||||
import "github.com/lejianwen/rustdesk-api/v2/model"
|
||||
|
||||
/*
|
||||
GroupPeerPayload
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package api
|
||||
|
||||
import "Gwen/model"
|
||||
import "github.com/lejianwen/rustdesk-api/v2/model"
|
||||
|
||||
/*
|
||||
pub enum UserStatus {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"Gwen/model"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
_ "Gwen/docs/admin"
|
||||
"Gwen/global"
|
||||
"Gwen/http/controller/admin"
|
||||
"Gwen/http/controller/admin/my"
|
||||
"Gwen/http/middleware"
|
||||
"github.com/gin-gonic/gin"
|
||||
_ "github.com/lejianwen/rustdesk-api/v2/docs/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/controller/admin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/controller/admin/my"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/middleware"
|
||||
swaggerFiles "github.com/swaggo/files"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
)
|
||||
@@ -22,7 +22,10 @@ func Init(g *gin.Engine) {
|
||||
adg := g.Group("/api/admin")
|
||||
LoginBind(adg)
|
||||
adg.POST("/user/register", (&admin.User{}).Register)
|
||||
adg.Use(middleware.AdminAuth())
|
||||
|
||||
ConfigBind(adg)
|
||||
|
||||
adg.Use(middleware.BackendUserAuth())
|
||||
//FileBind(adg)
|
||||
UserBind(adg)
|
||||
GroupBind(adg)
|
||||
@@ -35,7 +38,6 @@ func Init(g *gin.Engine) {
|
||||
AddressBookCollectionBind(adg)
|
||||
AddressBookCollectionRuleBind(adg)
|
||||
UserTokenBind(adg)
|
||||
ConfigBind(adg)
|
||||
|
||||
//deprecated by ConfigBind
|
||||
//rs := &admin.Rustdesk{}
|
||||
@@ -221,9 +223,13 @@ func UserTokenBind(rg *gin.RouterGroup) {
|
||||
func ConfigBind(rg *gin.RouterGroup) {
|
||||
aR := rg.Group("/config")
|
||||
rs := &admin.Config{}
|
||||
|
||||
aR.GET("/admin", rs.AdminConfig)
|
||||
|
||||
aR.Use(middleware.BackendUserAuth())
|
||||
aR.GET("/server", rs.ServerConfig)
|
||||
aR.GET("/app", rs.AppConfig)
|
||||
aR.GET("/admin", rs.AdminConfig)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
_ "Gwen/docs/api"
|
||||
"Gwen/global"
|
||||
"Gwen/http/controller/api"
|
||||
"Gwen/http/middleware"
|
||||
"github.com/gin-gonic/gin"
|
||||
_ "github.com/lejianwen/rustdesk-api/v2/docs/api"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/controller/api"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/middleware"
|
||||
swaggerFiles "github.com/swaggo/files"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
"net/http"
|
||||
@@ -21,10 +21,13 @@ func ApiInit(g *gin.Engine) {
|
||||
|
||||
frg := g.Group("/api")
|
||||
|
||||
i := &api.Index{}
|
||||
frg.GET("/", i.Index)
|
||||
{
|
||||
i := &api.Index{}
|
||||
frg.GET("/", i.Index)
|
||||
frg.GET("/version", i.Version)
|
||||
|
||||
frg.POST("/heartbeat", i.Heartbeat)
|
||||
frg.POST("/heartbeat", i.Heartbeat)
|
||||
}
|
||||
|
||||
{
|
||||
l := &api.Login{}
|
||||
@@ -33,6 +36,7 @@ func ApiInit(g *gin.Engine) {
|
||||
frg.POST("/login", l.Login)
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
o := &api.Oauth{}
|
||||
// [method:POST] [uri:/api/oidc/auth]
|
||||
@@ -52,11 +56,15 @@ func ApiInit(g *gin.Engine) {
|
||||
if global.Config.App.WebClient == 1 {
|
||||
WebClientRoutes(frg)
|
||||
}
|
||||
au := &api.Audit{}
|
||||
//[method:POST] [uri:/api/audit/conn]
|
||||
frg.POST("/audit/conn", au.AuditConn)
|
||||
//[method:POST] [uri:/api/audit/file]
|
||||
frg.POST("/audit/file", au.AuditFile)
|
||||
|
||||
{
|
||||
au := &api.Audit{}
|
||||
//[method:POST] [uri:/api/audit/conn]
|
||||
frg.POST("/audit/conn", au.AuditConn)
|
||||
//[method:POST] [uri:/api/audit/file]
|
||||
frg.POST("/audit/file", au.AuditFile)
|
||||
}
|
||||
|
||||
frg.Use(middleware.RustAuth())
|
||||
{
|
||||
u := &api.User{}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"Gwen/http/controller/web"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/http/controller/web"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ type Config struct {
|
||||
func New(c *Config) *log.Logger {
|
||||
log.SetFormatter(&nested.Formatter{
|
||||
// HideKeys: true,
|
||||
TimestampFormat: "2006-01-02 15:04:05",
|
||||
TimestampFormat: "[2006-01-02 15:04:05]",
|
||||
NoColors: true,
|
||||
NoFieldsColors: true,
|
||||
//FieldsOrder: []string{"name", "age"},
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package orm
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"fmt"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package orm
|
||||
|
||||
import (
|
||||
"Gwen/global"
|
||||
"fmt"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package model
|
||||
|
||||
import "Gwen/model/custom_types"
|
||||
import "github.com/lejianwen/rustdesk-api/v2/model/custom_types"
|
||||
|
||||
// final String id;
|
||||
// String hash; // personal ab hash password
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"Gwen/model/custom_types"
|
||||
"github.com/lejianwen/rustdesk-api/v2/model/custom_types"
|
||||
)
|
||||
|
||||
type StatusCode int
|
||||
|
||||
@@ -2,11 +2,11 @@ package model
|
||||
|
||||
type UserToken struct {
|
||||
IdModel
|
||||
UserId uint `json:"user_id" gorm:"default:0;not null;index"`
|
||||
DeviceUuid string `json:"device_uuid" gorm:"default:'';omitempty;"`
|
||||
DeviceId string `json:"device_id" gorm:"default:'';omitempty;"`
|
||||
Token string `json:"token" gorm:"default:'';not null;index"`
|
||||
ExpiredAt int64 `json:"expired_at" gorm:"default:0;not null;"`
|
||||
UserId uint `json:"user_id" gorm:"default:0;not null;index"`
|
||||
DeviceUuid string `json:"device_uuid" gorm:"default:'';omitempty;"`
|
||||
DeviceId string `json:"device_id" gorm:"default:'';omitempty;"`
|
||||
Token string `json:"token" gorm:"default:'';not null;index"`
|
||||
ExpiredAt int64 `json:"expired_at" gorm:"default:0;not null;"`
|
||||
TimeModel
|
||||
}
|
||||
|
||||
|
||||
@@ -133,3 +133,8 @@ other = "Captcha required."
|
||||
description = "Captcha error."
|
||||
one = "Captcha error."
|
||||
other = "Captcha error."
|
||||
|
||||
[PwdLoginDisabled]
|
||||
description = "Password login disabled."
|
||||
one = "Password login disabled."
|
||||
other = "Password login disabled."
|
||||
@@ -141,4 +141,9 @@ other = "Captcha requerido."
|
||||
[CaptchaError]
|
||||
description = "Captcha error."
|
||||
one = "Error de captcha."
|
||||
other = "Error de captcha."
|
||||
other = "Error de captcha."
|
||||
|
||||
[PwdLoginDisabled]
|
||||
description = "Password login disabled."
|
||||
one = "Inicio de sesión con contraseña deshabilitado."
|
||||
other = "Inicio de sesión con contraseña deshabilitado."
|
||||
@@ -142,3 +142,8 @@ other = "Captcha requis."
|
||||
description = "Captcha error."
|
||||
one = "Erreur de captcha."
|
||||
other = "Erreur de captcha."
|
||||
|
||||
[PwdLoginDisabled]
|
||||
description = "Password login disabled."
|
||||
one = "Connexion par mot de passe désactivée."
|
||||
other = "Connexion par mot de passe désactivée."
|
||||
@@ -135,4 +135,9 @@ other = "Captcha가 필요합니다."
|
||||
[CaptchaError]
|
||||
description = "Captcha error."
|
||||
one = "Captcha 오류."
|
||||
other = "Captcha 오류."
|
||||
other = "Captcha 오류."
|
||||
|
||||
[PwdLoginDisabled]
|
||||
description = "Password login disabled."
|
||||
one = "비밀번호 로그인이 비활성화되었습니다."
|
||||
other = "비밀번호 로그인이 비활성화되었습니다."
|
||||
|
||||
@@ -141,4 +141,9 @@ other = "Требуется капча."
|
||||
[CaptchaError]
|
||||
description = "Captcha error."
|
||||
one = "Ошибка капчи."
|
||||
other = "Ошибка капчи."
|
||||
other = "Ошибка капчи."
|
||||
|
||||
[PwdLoginDisabled]
|
||||
description = "Password login disabled."
|
||||
one = "Вход по паролю отключен."
|
||||
other = "Вход по паролю отключен."
|
||||
@@ -134,4 +134,9 @@ other = "需要验证码。"
|
||||
[CaptchaError]
|
||||
description = "Captcha error."
|
||||
one = "验证码错误。"
|
||||
other = "验证码错误。"
|
||||
other = "验证码错误。"
|
||||
|
||||
[PwdLoginDisabled]
|
||||
description = "Password login disabled."
|
||||
one = "密码登录已禁用。"
|
||||
other = "密码登录已禁用。"
|
||||
142
resources/i18n/zh_TW.toml
Normal file
142
resources/i18n/zh_TW.toml
Normal file
@@ -0,0 +1,142 @@
|
||||
[Test]
|
||||
description = "test"
|
||||
one = "測試1 {{.P0}}"
|
||||
other = "測試2 {{.P0}}"
|
||||
|
||||
[ParamsError]
|
||||
description = "Params validation failed."
|
||||
one = "引數錯誤。"
|
||||
other = "引數錯誤。"
|
||||
|
||||
[OperationFailed]
|
||||
description = "OperationFailed."
|
||||
one = "操作失敗。"
|
||||
other = "操作失敗。"
|
||||
|
||||
[OperationSuccess]
|
||||
description = "OperationSuccess."
|
||||
one = "操作成功。"
|
||||
other = "操作成功。"
|
||||
|
||||
[ItemExists]
|
||||
description = "Item already exists."
|
||||
one = "資料已存在。"
|
||||
other = "資料已存在。"
|
||||
|
||||
[ItemNotFound]
|
||||
description = "Item not found."
|
||||
one = "資料不存在。"
|
||||
other = "資料不存在。"
|
||||
|
||||
[NoAccess]
|
||||
description = "No access."
|
||||
one = "無許可權。"
|
||||
other = "無許可權。"
|
||||
|
||||
[UsernameOrPasswordError]
|
||||
description = "Username or password error."
|
||||
one = "使用者名稱或密碼錯誤。"
|
||||
other = "使用者名稱或密碼錯誤。"
|
||||
|
||||
[SystemError]
|
||||
description = "System error."
|
||||
one = "系統錯誤。"
|
||||
other = "系統錯誤。"
|
||||
|
||||
[ConfigNotFound]
|
||||
description = "Config not found."
|
||||
one = "配置不存在。"
|
||||
other = "配置不存在。"
|
||||
|
||||
#授權過期
|
||||
[OauthExpired]
|
||||
description = "Oauth expired."
|
||||
one = "授權過期,請重新授權。"
|
||||
other = "授權過期,請重新授權。"
|
||||
|
||||
[OauthFailed]
|
||||
description = "Oauth failed."
|
||||
one = "授權失敗。"
|
||||
other = "授權失敗。"
|
||||
|
||||
[OauthHasBindOtherUser]
|
||||
description = "Oauth has bind other user."
|
||||
one = "授權已繫結其他使用者。"
|
||||
other = "授權已繫結其他使用者。"
|
||||
|
||||
[ParamIsEmpty]
|
||||
description = "Param is empty."
|
||||
one = "{{.P0}} 為空。"
|
||||
other = "{{.P0}} 為空。"
|
||||
|
||||
[BindFail]
|
||||
description = "Bind fail."
|
||||
one = "繫結失敗。"
|
||||
other = "繫結失敗。"
|
||||
[BindSuccess]
|
||||
description = "Bind success."
|
||||
one = "繫結成功。"
|
||||
other = "繫結成功。"
|
||||
[OauthHasBeenSuccess]
|
||||
description = "Oauth has been success."
|
||||
one = "授權已成功。"
|
||||
other = "授權已成功。"
|
||||
[OauthSuccess]
|
||||
description = "Oauth success."
|
||||
one = "授權成功。"
|
||||
other = "授權成功。"
|
||||
[OauthRegisterSuccess]
|
||||
description = "Oauth register success."
|
||||
one = "授權註冊成功。"
|
||||
other = "授權註冊成功。"
|
||||
[OauthRegisterFailed]
|
||||
description = "Oauth register failed."
|
||||
one = "授權註冊失敗。"
|
||||
other = "授權註冊失敗。"
|
||||
[GetOauthTokenError]
|
||||
description = "Get oauth token error."
|
||||
one = "獲取授權token失敗。"
|
||||
other = "獲取授權token失敗。"
|
||||
[GetOauthUserInfoError]
|
||||
description = "Get oauth user info error."
|
||||
one = "獲取授權使用者資訊失敗。"
|
||||
other = "獲取授權使用者資訊失敗。"
|
||||
[DecodeOauthUserInfoError]
|
||||
description = "Decode oauth user info error."
|
||||
one = "解析授權使用者資訊失敗。"
|
||||
other = "解析授權使用者資訊失敗。"
|
||||
|
||||
[OldPasswordError]
|
||||
description = "Old password error."
|
||||
one = "舊密碼錯誤。"
|
||||
other = "舊密碼錯誤。"
|
||||
|
||||
|
||||
[DefaultGroup]
|
||||
description = "Default group."
|
||||
one = "預設組"
|
||||
other = "預設組"
|
||||
|
||||
[ShareGroup]
|
||||
description = "Share group."
|
||||
one = "共享組"
|
||||
other = "共享組"
|
||||
[RegisterClosed]
|
||||
description = "Register closed."
|
||||
one = "註冊已關閉。"
|
||||
other = "註冊已關閉。"
|
||||
|
||||
[CaptchaRequired]
|
||||
description = "Captcha required."
|
||||
one = "需要驗證碼。"
|
||||
other = "需要驗證碼。"
|
||||
|
||||
[CaptchaError]
|
||||
description = "Captcha error."
|
||||
one = "驗證碼錯誤。"
|
||||
other = "驗證碼錯誤。"
|
||||
|
||||
[PwdLoginDisabled]
|
||||
description = "Password login disabled."
|
||||
one = "密碼登錄已禁用。"
|
||||
other = "密碼登錄已禁用。"
|
||||
1
resources/version
Normal file
1
resources/version
Normal file
@@ -0,0 +1 @@
|
||||
v1.0.0
|
||||
4
resources/web2/index.html
vendored
4
resources/web2/index.html
vendored
@@ -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=1bbc8b94"></script>
|
||||
<script type="module" crossorigin src="js/dist/index.js?v=cabfd933"></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=f6f842b3";
|
||||
scriptTag.src = "main.dart.js?v=060a626e";
|
||||
scriptTag.type = "application/javascript";
|
||||
document.body.append(scriptTag);
|
||||
}
|
||||
|
||||
197
resources/web2/js/dist/index.js
vendored
197
resources/web2/js/dist/index.js
vendored
@@ -18,7 +18,6 @@ var h = (u, e, i) => (ue(u, e, "read from private field"), i ? i.call(u) : e.get
|
||||
}
|
||||
}), je = (u, e, i) => (ue(u, e, "access private method"), i);
|
||||
|
||||
|
||||
const sa = function () {
|
||||
const e = document.createElement("link").relList;
|
||||
if (e && e.supports && e.supports("modulepreload")) return;
|
||||
@@ -7590,7 +7589,7 @@ class N4 {
|
||||
let i = new Uint8Array(e.data);
|
||||
this._recvDataCount += i.length;
|
||||
const o = this._secretKey;
|
||||
o && (o[2] += 1, i = Mn(i, o[2], o[0]));
|
||||
o && (o[2] += 1, i = Kn(i, o[2], o[0]));
|
||||
let a;
|
||||
i.length == 0 ? a = new Uint8Array : a = this._isRendezvous ? this.parseRendezvous(i) : this.parseMessage(i), this._buf.push(a), this._eventHandlers.message && (this._isProcessing || this.processQueue())
|
||||
}
|
||||
@@ -7817,7 +7816,7 @@ const Co = {
|
||||
RShift: "RShift",
|
||||
CTRL_ALT_DEL: "CtrlAltDel",
|
||||
LOCK_SCREEN: "LockScreen"
|
||||
}, se = "1.3.6", po = "2024-12-22 23:23";
|
||||
}, se = "1.3.7", po = "2025-01-21 01:12";
|
||||
|
||||
class A {
|
||||
static setItem(e, i) {
|
||||
@@ -8036,7 +8035,7 @@ async function zo() {
|
||||
}
|
||||
|
||||
function Z(u) {
|
||||
return Tn(u)
|
||||
return Ln(u)
|
||||
}
|
||||
|
||||
function c4(u) {
|
||||
@@ -8044,7 +8043,7 @@ function c4(u) {
|
||||
}
|
||||
|
||||
async function Po() {
|
||||
return await Jn()
|
||||
return await $n()
|
||||
}
|
||||
|
||||
function O4() {
|
||||
@@ -9176,7 +9175,7 @@ async function rn(u) {
|
||||
function xe(u, e = void 0) {
|
||||
const i = () => {
|
||||
try {
|
||||
Kn(new TextDecoder().decode(u.content)), fe(), e == null || e()
|
||||
Xn(new TextDecoder().decode(u.content)), fe(), e == null || e()
|
||||
} catch (o) {
|
||||
console.error("Failed to copy to clipboard, ", o), document.hasFocus() || (q4 = u)
|
||||
}
|
||||
@@ -9240,7 +9239,7 @@ async function Nt(u, e, i = void 0) {
|
||||
}
|
||||
|
||||
function $i() {
|
||||
In("info", "Clipboard is synchronized", 2e3)
|
||||
Un("info", "Clipboard is synchronized", 2e3)
|
||||
}
|
||||
|
||||
window.addEventListener("focus", function () {
|
||||
@@ -9650,7 +9649,7 @@ const hn = async (u, e) => {
|
||||
o = !1
|
||||
}
|
||||
return o && i.push(K4(e, "")), i
|
||||
}, Ut = 21116, Lt = "rs-ny.rustdesk.com", tt = 100, w4 = "trust-this-device";
|
||||
}, Ut = 21116, defaultIdServerPort = 21116, Lt = "rs-ny.rustdesk.com", tt = 100, w4 = "trust-this-device";
|
||||
|
||||
class Wt {
|
||||
constructor() {
|
||||
@@ -9887,7 +9886,7 @@ class Wt {
|
||||
(f4 = this._ws) == null || f4.sendMessage({public_key: T});
|
||||
return
|
||||
}
|
||||
const [E, c] = jn(), C = Nn(), D = On(C, l, E), B = K.fromPartial({asymmetric_value: c, symmetric_value: D});
|
||||
const [E, c] = Wn(), C = Vn(), D = qn(C, l, E), B = K.fromPartial({asymmetric_value: c, symmetric_value: D});
|
||||
return (x4 = this._ws) == null || x4.sendMessage({public_key: B}), (Ie = this._ws) == null || Ie.setSecretKey(C), console.log("secured"), !0
|
||||
}
|
||||
|
||||
@@ -9905,7 +9904,7 @@ class Wt {
|
||||
Re(o.colors, !1, a => {
|
||||
a && (o.colors = a, m("cursor_data", o))
|
||||
})
|
||||
} else if (e != null && e.cursor_id) m("cursor_id", {id: e == null ? void 0 : e.cursor_id}); else if (e != null && e.cursor_position) m("cursor_position", e == null ? void 0 : e.cursor_position); else if (e != null && e.misc) this.handleMisc(e == null ? void 0 : e.misc); else if (e != null && e.audio_frame) Vn(e == null ? void 0 : e.audio_frame.data); else if (e != null && e.message_box) this.handleMsgBox(e == null ? void 0 : e.message_box); else if (e != null && e.peer_info) this.handleSyncPeerInfo(e.peer_info); else if (e.file_response) await this.handleFileResponse(e.file_response); else if (e.file_action) {
|
||||
} else if (e != null && e.cursor_id) m("cursor_id", {id: e == null ? void 0 : e.cursor_id}); else if (e != null && e.cursor_position) m("cursor_position", e == null ? void 0 : e.cursor_position); else if (e != null && e.misc) this.handleMisc(e == null ? void 0 : e.misc); else if (e != null && e.audio_frame) Zn(e == null ? void 0 : e.audio_frame.data); else if (e != null && e.message_box) this.handleMsgBox(e == null ? void 0 : e.message_box); else if (e != null && e.peer_info) this.handleSyncPeerInfo(e.peer_info); else if (e.file_response) await this.handleFileResponse(e.file_response); else if (e.file_action) {
|
||||
const o = e.file_action;
|
||||
await this.handleFileAction(o)
|
||||
}
|
||||
@@ -10324,7 +10323,7 @@ class Wt {
|
||||
}
|
||||
|
||||
handleMisc(e) {
|
||||
if (e.audio_format) Wn(e.audio_format.channels, e.audio_format.sample_rate); else if (e.chat_message) m("chat_client_mode", {text: e.chat_message.text}); else if (e.permission_info) {
|
||||
if (e.audio_format) Gn(e.audio_format.channels, e.audio_format.sample_rate); else if (e.chat_message) m("chat_client_mode", {text: e.chat_message.text}); else if (e.permission_info) {
|
||||
const i = e.permission_info;
|
||||
console.info("Change permission " + i.permission + " -> " + i.enabled);
|
||||
let o;
|
||||
@@ -10494,7 +10493,7 @@ class Wt {
|
||||
|
||||
inputKey(e, i, o, a, t, s, l) {
|
||||
var c;
|
||||
const E = So(e, Rn());
|
||||
const E = So(e, Mn());
|
||||
!E || (a && (e == "VK_MENU" || e == "RAlt") && (a = !1), t && (e == "VK_CONTROL" || e == "RControl") && (t = !1), s && (e == "VK_SHIFT" || e == "RShift") && (s = !1), l && (e == "Meta" || e == "RWin") && (l = !1), E.down = i, E.press = o, E.modifiers = this.getMod(a, t, s, l), (c = this._ws) == null || c.sendMessage({key_event: E}))
|
||||
}
|
||||
|
||||
@@ -11088,25 +11087,33 @@ function R4(u = !1) {
|
||||
return I4(e || Lt, u)
|
||||
}
|
||||
|
||||
function getrUriFromRs(uri, isRelay = false, roffset = 0) {
|
||||
function getUriFromRs(uri, isRelay = false, roffset = 0) {
|
||||
const p = isHttps() ? "wss://" : "ws://"
|
||||
const [domain, uriport] = uri.split(":")
|
||||
if (isHttps() && (!uriport)) {
|
||||
return p + domain + "/ws/" + (isRelay ? "relay" : "id");
|
||||
if (!isHttps()) {
|
||||
// http 直接走端口
|
||||
if (uriport) {
|
||||
const port = parseInt(uriport)
|
||||
return p + domain + ":" + (port + (isRelay ? roffset || 3 : 2))
|
||||
}
|
||||
return p + domain + ":" + (defaultIdServerPort + (isRelay ? 3 : 2))
|
||||
}
|
||||
if (uriport) {
|
||||
const port = parseInt(uriport);
|
||||
uri = domain + ":" + (port + (isRelay ? roffset || 3 : 2))
|
||||
} else uri += ":" + (Ut + (isRelay ? 3 : 2));
|
||||
return p + uri
|
||||
// https 分情况
|
||||
if (!window.location.port) {
|
||||
// 443
|
||||
return p + domain + "/ws/" + (isRelay ? "relay" : "id")
|
||||
}
|
||||
// 非443
|
||||
return p + domain + ":" + window.location.port + "/ws/" + (isRelay ? "relay" : "id")
|
||||
}
|
||||
|
||||
|
||||
function isHttps() {
|
||||
return window.location.protocol === "https:"
|
||||
}
|
||||
|
||||
function I4(u, e = !1, i = 0) {
|
||||
return getrUriFromRs(u, e, i)
|
||||
return getUriFromRs(u, e, i)
|
||||
}
|
||||
|
||||
function wn() {
|
||||
@@ -11117,7 +11124,6 @@ function Sn(u) {
|
||||
return u.indexOf(":") > 0 ? u.split(":")[0] : u
|
||||
}
|
||||
|
||||
|
||||
const at = (u, e, i) => e && u.type == "SharedAb" ? Z(Zu([u.value, i.salt])) === Z(e) : !1,
|
||||
ot = (u, e) => e && u.type == "PersonalAb" ? Z(u.value) === Z(e) : !1;
|
||||
|
||||
@@ -11244,11 +11250,63 @@ async function Pn(u) {
|
||||
|
||||
}
|
||||
|
||||
const Rn = "rustdesk-client";
|
||||
|
||||
function In() {
|
||||
if (typeof navigator != "undefined") {
|
||||
const u = navigator.platform.toLowerCase();
|
||||
return u.includes("win") ? "windows" : u.includes("mac") ? "macos" : u.includes("linux") ? "linux" : u
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
function Tn() {
|
||||
const u = In();
|
||||
return u === "windows" ? navigator.userAgent.includes("Win64") ? "x86_64" : "x86" : u === "macos" ? navigator.userAgent.includes("Intel") ? "x86_64" : "arm64" : navigator.userAgent.includes("x64") ? "x86_64" : "x86"
|
||||
}
|
||||
|
||||
function jn() {
|
||||
const u = navigator.userAgent;
|
||||
let e = "", i = "";
|
||||
if (u.includes("Windows")) {
|
||||
e = "windows";
|
||||
const o = u.match(/Windows NT (\d+\.\d+)/);
|
||||
o && (i = o[1])
|
||||
} else if (u.includes("Mac OS X")) {
|
||||
e = "macos";
|
||||
const o = u.match(/Mac OS X (\d+[._]\d+[._]\d+)/);
|
||||
o && (i = o[1].replace(/_/g, "."))
|
||||
} else if (u.includes("Linux")) {
|
||||
e = "linux";
|
||||
const o = u.match(/Linux\s*([\d.]+)?/);
|
||||
o && o[1] && (i = o[1])
|
||||
} else e = "unknown", i = "";
|
||||
return e += "-" + navigator.userAgent, {os: e, os_version: i}
|
||||
}
|
||||
|
||||
async function Nn(u) {
|
||||
const e = "https://api.rustdesk.com/version/latest", {os: i, os_version: o} = jn(), a = Tn();
|
||||
return [{os: i, os_version: o, arch: a, device_id: [], typ: u}, e]
|
||||
}
|
||||
|
||||
async function On() {
|
||||
try {
|
||||
const [u, e] = await Nn(Rn);
|
||||
return await (await fetch(e, {
|
||||
method: "POST",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
body: JSON.stringify(u)
|
||||
})).json()
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
window.curConn = void 0;
|
||||
window.isMobile = () => /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0, 4));
|
||||
const ye = zt(), Yu = ye === Y4, H4 = ye === Be, Qu = ye === me;
|
||||
|
||||
function Rn() {
|
||||
function Mn() {
|
||||
return !isMobile()
|
||||
}
|
||||
|
||||
@@ -11267,7 +11325,7 @@ function Vt(u, e, i, o) {
|
||||
}
|
||||
}
|
||||
|
||||
function In(u, e, i) {
|
||||
function Un(u, e, i) {
|
||||
onGlobalEvent(JSON.stringify({name: "toast", type: u, text: e, dur_msec: i}))
|
||||
}
|
||||
|
||||
@@ -11340,20 +11398,20 @@ function Zt(u) {
|
||||
return q.from_base64(u, q.base64_variants.ORIGINAL)
|
||||
}
|
||||
|
||||
function Tn(u) {
|
||||
function Ln(u) {
|
||||
return q.to_base64(u, q.base64_variants.ORIGINAL)
|
||||
}
|
||||
|
||||
function jn() {
|
||||
function Wn() {
|
||||
const u = q.crypto_box_keypair(), e = u.privateKey, i = u.publicKey;
|
||||
return [e, i]
|
||||
}
|
||||
|
||||
function Nn() {
|
||||
function Vn() {
|
||||
return q.crypto_secretbox_keygen()
|
||||
}
|
||||
|
||||
function On(u, e, i) {
|
||||
function qn(u, e, i) {
|
||||
const o = Uint8Array.from(Array(24).fill(0));
|
||||
return q.crypto_box_easy(u, o, e, i)
|
||||
}
|
||||
@@ -11370,7 +11428,7 @@ function st(u, e, i) {
|
||||
return q.crypto_secretbox_easy(u, $4(e), i)
|
||||
}
|
||||
|
||||
function Mn(u, e, i) {
|
||||
function Kn(u, e, i) {
|
||||
return q.crypto_secretbox_open_easy(u, $4(e), i)
|
||||
}
|
||||
|
||||
@@ -11428,7 +11486,7 @@ window.setByName = (u, e) => {
|
||||
e = JSON.parse(e), Ho(curConn, e.usb_hid, e.down == "true", e.lock_modes);
|
||||
break;
|
||||
case"send_mouse":
|
||||
Un(e);
|
||||
Hn(e);
|
||||
break;
|
||||
case"send_2fa":
|
||||
curConn == null || curConn.send2fa(e);
|
||||
@@ -11455,7 +11513,7 @@ window.setByName = (u, e) => {
|
||||
e = JSON.parse(e), curConn.setFlutterUiOption(e.name, e.value);
|
||||
break;
|
||||
case"option:user:default":
|
||||
Gn(e);
|
||||
ur(e);
|
||||
break;
|
||||
case"option:session":
|
||||
e = JSON.parse(e), curConn.setOption(e.name, e.value);
|
||||
@@ -11473,12 +11531,12 @@ window.setByName = (u, e) => {
|
||||
curConn.inputOsPassword(e);
|
||||
break;
|
||||
case"session_add_sync":
|
||||
return Xn(e);
|
||||
return tr(e);
|
||||
case"session_start":
|
||||
Yn();
|
||||
ar();
|
||||
break;
|
||||
case"session_close":
|
||||
$n();
|
||||
or();
|
||||
break;
|
||||
case"elevate_direct":
|
||||
curConn.elevateDirect();
|
||||
@@ -11500,13 +11558,13 @@ window.setByName = (u, e) => {
|
||||
curConn.changePreferCodec(e);
|
||||
break;
|
||||
case"cursor":
|
||||
Hn(e);
|
||||
Yn(e);
|
||||
break;
|
||||
case"enter_or_leave":
|
||||
curConn == null || curConn.enterOrLeave(e);
|
||||
break;
|
||||
case"fullscreen":
|
||||
e == "Y" ? er() : ir();
|
||||
e == "Y" ? rr() : sr();
|
||||
break;
|
||||
case"send_note":
|
||||
const i = Yt("conn");
|
||||
@@ -11549,7 +11607,7 @@ window.setByName = (u, e) => {
|
||||
curConn == null || curConn.sendChat(e);
|
||||
break;
|
||||
case"load_ab":
|
||||
or();
|
||||
dr();
|
||||
break;
|
||||
case"save_ab":
|
||||
_o(e);
|
||||
@@ -11558,7 +11616,7 @@ window.setByName = (u, e) => {
|
||||
vo();
|
||||
break;
|
||||
case"load_group":
|
||||
nr();
|
||||
cr();
|
||||
break;
|
||||
case"save_group":
|
||||
ko(e);
|
||||
@@ -11575,7 +11633,7 @@ window.setByName = (u, e) => {
|
||||
}
|
||||
};
|
||||
|
||||
function Un(u) {
|
||||
function Hn(u) {
|
||||
if (!curConn) return;
|
||||
let e = 0;
|
||||
switch (u = JSON.parse(u), u.type) {
|
||||
@@ -11618,11 +11676,11 @@ function Un(u) {
|
||||
}
|
||||
|
||||
window.getByName = (u, e) => {
|
||||
let i = Ln(u, e);
|
||||
let i = Jn(u, e);
|
||||
return typeof i == "string" || i instanceof String ? i : i == null || i == null ? "" : JSON.stringify(i)
|
||||
};
|
||||
|
||||
function Ln(u, e) {
|
||||
function Jn(u, e) {
|
||||
var o, a, t, s;
|
||||
switch (u) {
|
||||
case"remember":
|
||||
@@ -11669,10 +11727,10 @@ function Ln(u, e) {
|
||||
case"version":
|
||||
return se;
|
||||
case"load_recent_peers":
|
||||
Zn();
|
||||
er();
|
||||
break;
|
||||
case"load_fav_peers":
|
||||
Qn();
|
||||
ir();
|
||||
break;
|
||||
case"fav":
|
||||
return (a = A.getItem("fav")) != null ? a : "[]";
|
||||
@@ -11726,7 +11784,7 @@ function Ln(u, e) {
|
||||
case"peer_has_password":
|
||||
return ((t = (Cu()[e] || {}).password) != null ? t : "") !== "";
|
||||
case"fullscreen":
|
||||
return tr() ? "Y" : "N";
|
||||
return lr() ? "Y" : "N";
|
||||
case"platform":
|
||||
return curConn.getPlatform();
|
||||
case"enable_trusted_devices":
|
||||
@@ -11737,11 +11795,11 @@ function Ln(u, e) {
|
||||
|
||||
let ze = new Worker("./libopus.js?v=02816afa"), Qt;
|
||||
|
||||
function Wn(u, e) {
|
||||
Qt = qn(u, e), ze.postMessage({channels: u, sampleRate: e})
|
||||
function Gn(u, e) {
|
||||
Qt = Qn(u, e), ze.postMessage({channels: u, sampleRate: e})
|
||||
}
|
||||
|
||||
function Vn(u) {
|
||||
function Zn(u) {
|
||||
ze.postMessage(u, [u.buffer])
|
||||
}
|
||||
|
||||
@@ -11749,7 +11807,7 @@ window.init = async () => {
|
||||
try {
|
||||
ze.onmessage = u => {
|
||||
Qt.feed(u.data)
|
||||
}, await Jt(), await zo(), await Pa(), await N.init(), console.log("init done"), onInitFinished()
|
||||
}, await Jt(), await zo(), await Pa(), await N.init(), console.log("init done"), onInitFinished(), await On()
|
||||
} catch (u) {
|
||||
console.error("Failed to init: " + u.message), onInitFinished()
|
||||
}
|
||||
@@ -11758,11 +11816,11 @@ window.onunload = () => {
|
||||
console.log("window close"), Ia()
|
||||
};
|
||||
|
||||
function qn(u, e) {
|
||||
function Qn(u, e) {
|
||||
return new ra({channels: u, sampleRate: e, flushingTime: 2e3})
|
||||
}
|
||||
|
||||
function Kn(u) {
|
||||
function Xn(u) {
|
||||
if (window.clipboardData && window.clipboardData.setData) return window.clipboardData.setData("Text", u);
|
||||
if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
|
||||
var e = document.createElement("textarea");
|
||||
@@ -11791,7 +11849,7 @@ function Q(u) {
|
||||
}
|
||||
}
|
||||
|
||||
function Hn(u) {
|
||||
function Yn(u) {
|
||||
let e = "auto";
|
||||
if (u != "auto") try {
|
||||
const t = JSON.parse(u);
|
||||
@@ -11807,13 +11865,13 @@ function Hn(u) {
|
||||
}
|
||||
}
|
||||
|
||||
async function Jn() {
|
||||
async function $n() {
|
||||
await T4.ready;
|
||||
const u = T4.crypto_sign_keypair();
|
||||
return {publicKey: u.publicKey, privateKey: u.privateKey}
|
||||
}
|
||||
|
||||
function Gn(u) {
|
||||
function ur(u) {
|
||||
try {
|
||||
const e = JSON.parse(u), i = JSON.parse(A.getItem("user-default-options")) || {};
|
||||
i[e.name] = e.value, A.setItem("user-default-options", JSON.stringify(i))
|
||||
@@ -11855,22 +11913,23 @@ function Pe() {
|
||||
return u.sort().reverse().map(e => e[2])
|
||||
}
|
||||
|
||||
function Zn() {
|
||||
function er() {
|
||||
const u = Pe();
|
||||
u && be("load_recent_peers", {peers: JSON.stringify(u)})
|
||||
}
|
||||
|
||||
function Qn() {
|
||||
function ir() {
|
||||
var u;
|
||||
try {
|
||||
const e = (u = A.getItem("fav")) != null ? u : "[]", i = JSON.parse(e), o = Pe().filter(a => i.includes(a.id));
|
||||
const e = (u = A.getItem("fav")) != null ? u : "[]", i = JSON.parse(e),
|
||||
o = Pe().filter(a => i.includes(a.id));
|
||||
o && be("load_fav_peers", {peers: JSON.stringify(o)})
|
||||
} catch (e) {
|
||||
console.error("Failed to load fav peers: " + e.message)
|
||||
}
|
||||
}
|
||||
|
||||
function Xn(u) {
|
||||
function tr(u) {
|
||||
var e;
|
||||
try {
|
||||
const i = JSON.parse(u), o = i.id;
|
||||
@@ -11884,7 +11943,7 @@ function Xn(u) {
|
||||
}
|
||||
}
|
||||
|
||||
function Yn(u) {
|
||||
function ar(u) {
|
||||
try {
|
||||
if (!e0()) return;
|
||||
Kt()
|
||||
@@ -11893,11 +11952,11 @@ function Yn(u) {
|
||||
}
|
||||
}
|
||||
|
||||
function $n(u) {
|
||||
function or(u) {
|
||||
Se()
|
||||
}
|
||||
|
||||
function ur(u, e) {
|
||||
function nr(u, e) {
|
||||
function i(o) {
|
||||
return /^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$/.test(o)
|
||||
}
|
||||
@@ -11925,7 +11984,7 @@ function Xt() {
|
||||
if (u) return u;
|
||||
const e = A.getItem("custom-rendezvous-server");
|
||||
if (e) {
|
||||
let i = ur(e, -2);
|
||||
let i = nr(e, -2);
|
||||
return i == e ? `http://${i}:${Ut - 2}` : `http://${i}`
|
||||
}
|
||||
return "https://admin.rustdesk.com"
|
||||
@@ -11985,28 +12044,28 @@ async function ea(u, e) {
|
||||
})
|
||||
}
|
||||
|
||||
function er() {
|
||||
function rr() {
|
||||
const u = document.documentElement;
|
||||
u.requestFullscreen ? u.requestFullscreen() : u.mozRequestFullScreen ? u.mozRequestFullScreen() : u.webkitRequestFullscreen ? u.webkitRequestFullscreen() : u.msRequestFullscreen && u.msRequestFullscreen()
|
||||
}
|
||||
|
||||
function ir() {
|
||||
function sr() {
|
||||
document.exitFullscreen ? document.exitFullscreen() : document.mozCancelFullScreen ? document.mozCancelFullScreen() : document.webkitExitFullscreen ? document.webkitExitFullscreen() : document.msExitFullscreen && document.msExitFullscreen()
|
||||
}
|
||||
|
||||
function tr() {
|
||||
function lr() {
|
||||
return document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement
|
||||
}
|
||||
|
||||
var lt = !1;
|
||||
|
||||
function ar() {
|
||||
function Er() {
|
||||
lt || (console.log("listen fullscreen"), lt = !0, document.addEventListener("fullscreenchange", () => onFullscreenChanged(!!document.fullscreenElement)), document.addEventListener("mozfullscreenchange", () => onFullscreenChanged(!!document.mozFullScreen)), document.addEventListener("webkitfullscreenchange", () => onFullscreenChanged(!!document.webkitFullscreenElement)), document.addEventListener("msfullscreenchange", () => onFullscreenChanged(!!document.msFullscreenElement)))
|
||||
}
|
||||
|
||||
ar();
|
||||
Er();
|
||||
|
||||
async function or() {
|
||||
async function dr() {
|
||||
try {
|
||||
let u = await xt();
|
||||
onLoadAbFinished(JSON.stringify(u))
|
||||
@@ -12015,7 +12074,7 @@ async function or() {
|
||||
}
|
||||
}
|
||||
|
||||
async function nr() {
|
||||
async function cr() {
|
||||
try {
|
||||
let u = await go();
|
||||
onLoadGroupFinished(JSON.stringify(u))
|
||||
@@ -12077,4 +12136,4 @@ if (Et) {
|
||||
const i = document.querySelector("input#password").value;
|
||||
i && (document.querySelector("div#password").style.display = "none", e0().login(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
36
resources/web2/js/dist/lang.js
vendored
36
resources/web2/js/dist/lang.js
vendored
@@ -4685,7 +4685,7 @@ Kui soovid juurdep\xE4\xE4su seadmele avalikus serveris, sisesta "<id>@public",
|
||||
}, sl: {
|
||||
Status: "Stanje",
|
||||
"Your Desktop": "Va\u0161e namizje",
|
||||
desk_tip: "Do va\u0161ega namizja lahko dostopate s spodnjim IDjem in geslom",
|
||||
desk_tip: "S spodnjim IDjem in geslom omogo\u010Dite oddaljeni nadzor va\u0161ega ra\u010Dunalnika",
|
||||
Password: "Geslo",
|
||||
Ready: "Pripravljen",
|
||||
Established: "Povezava vzpostavljena",
|
||||
@@ -4872,7 +4872,7 @@ Kui soovid juurdep\xE4\xE4su seadmele avalikus serveris, sisesta "<id>@public",
|
||||
"Logging in...": "Prijavljanje...",
|
||||
"Enable RDP session sharing": "Omogo\u010Di deljenje RDP seje",
|
||||
"Auto Login": "Samodejna prijava",
|
||||
"Enable direct IP access": "Omogo\u010Di neposredni dostop preko IP",
|
||||
"Enable direct IP access": "Omogo\u010Di neposredni dostop preko IP naslova",
|
||||
Rename: "Preimenuj",
|
||||
Space: "Prazno",
|
||||
"Create desktop shortcut": "Ustvari bli\u017Enjico na namizju",
|
||||
@@ -5046,7 +5046,7 @@ Kui soovid juurdep\xE4\xE4su seadmele avalikus serveris, sisesta "<id>@public",
|
||||
Recording: "Snemanje",
|
||||
Directory: "Imenik",
|
||||
"Automatically record incoming sessions": "Samodejno snemaj vhodne seje",
|
||||
"Automatically record outgoing sessions": "",
|
||||
"Automatically record outgoing sessions": "Samodejno snemaj odhodne seje",
|
||||
Change: "Spremeni",
|
||||
"Start session recording": "Za\u010Dni snemanje seje",
|
||||
"Stop session recording": "Ustavi snemanje seje",
|
||||
@@ -5094,8 +5094,8 @@ Kui soovid juurdep\xE4\xE4su seadmele avalikus serveris, sisesta "<id>@public",
|
||||
"Select local keyboard type": "Izberite lokalno vrsto tipkovnice",
|
||||
software_render_tip: "\u010Ce na Linuxu uporabljate Nvidino grafi\u010Dno kartico in se oddaljeno okno zapre takoj po vzpostavitvi povezave, lahko pomaga preklop na odprtokodni gonilnik Nouveau in uporaba programskega upodabljanja. Potreben je ponovni zagon programa.",
|
||||
"Always use software rendering": "Vedno uporabi programsko upodabljanje",
|
||||
config_input: "Za nadzor oddaljenega namizja s tipkovnico, rabi RustDesk pravico \xBBNadzor vnosa\xAB.",
|
||||
config_microphone: "Za zajem zvoka, rabi RustDesk pravico \xBBSnemanje zvoka\xAB.",
|
||||
config_input: "RustDesk potrebuje pravico \xBBNadzor vnosa\xAB za nadzor oddaljenega namizja s tipkovnico.",
|
||||
config_microphone: "RustDesk potrebuje pravico \xBBSnemanje zvoka\xAB za zajemanje zvoka.",
|
||||
request_elevation_tip: "Lahko tudi zaprosite za dvig pravic, \u010De je kdo na oddaljeni strani.",
|
||||
Wait: "\u010Cakaj",
|
||||
"Elevation Error": "Napaka pri povzdigovanju",
|
||||
@@ -5128,7 +5128,7 @@ Kui soovid juurdep\xE4\xE4su seadmele avalikus serveris, sisesta "<id>@public",
|
||||
"Voice call": "Glasovni klic",
|
||||
"Text chat": "Besedilni klepet",
|
||||
"Stop voice call": "Prekini glasovni klic",
|
||||
relay_hint_tip: "Morda neposredna povezava ni mo\u017Ena; lahko se poikusite povezati preko posrednika. \u010Ce \u017Eelite uporabiti posrednika ob prvem poizkusu vzpotavljanja povezave, lahko na konec IDja dodate \xBB/r\xAB, ali pa izberete mo\u017Enost \xBBVedno pove\u017Ei preko posrednika\xAB v kartici nedavnih sej, \u010De le-ta obstja.",
|
||||
relay_hint_tip: "Morda neposredna povezava ni mo\u017Ena; lahko se poizkusite povezati preko posrednika. \u010Ce \u017Eelite uporabiti posrednika ob prvem poizkusu vzpotavljanja povezave, lahko na konec IDja dodate \xBB/r\xAB, ali pa izberete mo\u017Enost \xBBVedno pove\u017Ei preko posrednika\xAB v kartici nedavnih sej, \u010De le-ta obstja.",
|
||||
Reconnect: "Ponovna povezava",
|
||||
Codec: "Kodek",
|
||||
Resolution: "Lo\u010Dljivost",
|
||||
@@ -5343,13 +5343,13 @@ Lahko se pove\u017Eete na druge naprave, druge naprave pa se k vam ne morejo pov
|
||||
web_id_input_tip: `Vnesete lahko ID iz istega stre\u017Enika, neposredni dostop preko IP naslova v spletnem odjemalcu ni podprt.
|
||||
\u010Ce \u017Eelite dostopati do naprave na drugem stre\u017Eniku, pripnite naslov stre\u017Enika (<id>@<naslov_stre\u017Enika>?key=<klju\u010D>), npr. 9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=.
|
||||
\u010Ce \u017Eelite dostopati do naprave na javnem stre\u017Eniku, vnesite \xBB<id>@public\xAB; klju\u010D za javni stre\u017Enik ni potreben.`,
|
||||
Download: "",
|
||||
"Upload folder": "",
|
||||
"Upload files": "",
|
||||
"Clipboard is synchronized": "",
|
||||
"Update client clipboard": "",
|
||||
Untagged: "",
|
||||
"new-version-of-{}-tip": ""
|
||||
Download: "Prenos",
|
||||
"Upload folder": "Nalo\u017Ei mapo",
|
||||
"Upload files": "Nalo\u017Ei datoteke",
|
||||
"Clipboard is synchronized": "Odlo\u017Ei\u0161\u010De je usklajeno",
|
||||
"Update client clipboard": "Osve\u017Ei odjemal\u010Devo odlo\u017Ei\u0161\u010De",
|
||||
Untagged: "Neozna\u010Deno",
|
||||
"new-version-of-{}-tip": "Na voljo je nova razli\u010Dica {}"
|
||||
}, ko: {
|
||||
Status: "\uC0C1\uD0DC",
|
||||
"Your Desktop": "\uB0B4 \uB370\uC2A4\uD06C\uD0D1",
|
||||
@@ -6683,7 +6683,7 @@ Ja v\u0113laties piek\u013C\u016Bt ier\u012Bcei publiskaj\u0101 server\u012B, l\
|
||||
"Clipboard is synchronized": "Starpliktuve ir sinhroniz\u0113ta",
|
||||
"Update client clipboard": "Atjaunin\u0101t klienta starpliktuvi",
|
||||
Untagged: "Neatz\u012Bm\u0113ts",
|
||||
"new-version-of-{}-tip": ""
|
||||
"new-version-of-{}-tip": "Ir pieejama jauna {} versija"
|
||||
}, pl: {
|
||||
Status: "Status",
|
||||
"Your Desktop": "Tw\xF3j pulpit",
|
||||
@@ -18966,7 +18966,7 @@ H\xE3y t\xECm ai \u0111\xF3 \u0111\u1EC3 k\u1EBFt n\u1ED1i c\xF9ng v\xE0 th\xEAm
|
||||
Dark: "\u9ED1\u6697",
|
||||
Light: "\u660E\u4EAE",
|
||||
"Follow System": "\u8DDF\u968F\u7CFB\u7EDF",
|
||||
"Enable hardware codec": "\u4F7F\u80FD\u786C\u4EF6\u7F16\u89E3\u7801",
|
||||
"Enable hardware codec": "\u542F\u7528\u786C\u4EF6\u7F16\u89E3\u7801",
|
||||
"Unlock Security Settings": "\u89E3\u9501\u5B89\u5168\u8BBE\u7F6E",
|
||||
"Enable audio": "\u5141\u8BB8\u4F20\u8F93\u97F3\u9891",
|
||||
"Unlock Network Settings": "\u89E3\u9501\u7F51\u7EDC\u8BBE\u7F6E",
|
||||
@@ -21967,8 +21967,8 @@ Si quieres accedder a un dispositivo en un servidor p\xFAblico, por favor, intro
|
||||
"Upload files": "Subir archivos",
|
||||
"Clipboard is synchronized": "Portapapeles sincronizado",
|
||||
"Update client clipboard": "Actualizar portapapeles del cliente",
|
||||
Untagged: "",
|
||||
"new-version-of-{}-tip": ""
|
||||
Untagged: "Sin itiquetar",
|
||||
"new-version-of-{}-tip": "Hay una nueva versi\xF3n de {} disponible"
|
||||
}, sr: {
|
||||
Status: "Status",
|
||||
"Your Desktop": "Va\u0161a radna povr\u0161ina",
|
||||
@@ -23662,7 +23662,7 @@ Ha egy nyilv\xE1nos kiszolg\xE1l\xF3n l\xE9v\u0151 eszk\xF6zh\xF6z szeretne hozz
|
||||
Recording: "\u9304\u88FD",
|
||||
Directory: "\u8DEF\u5F91",
|
||||
"Automatically record incoming sessions": "\u81EA\u52D5\u9304\u88FD\u9023\u5165\u7684\u5DE5\u4F5C\u968E\u6BB5",
|
||||
"Automatically record outgoing sessions": "",
|
||||
"Automatically record outgoing sessions": "\u81EA\u52D5\u9304\u88FD\u9023\u51FA\u7684\u5DE5\u4F5C\u968E\u6BB5",
|
||||
Change: "\u8B8A\u66F4",
|
||||
"Start session recording": "\u958B\u59CB\u9304\u5F71",
|
||||
"Stop session recording": "\u505C\u6B62\u9304\u5F71",
|
||||
|
||||
14212
resources/web2/main.dart.js
vendored
14212
resources/web2/main.dart.js
vendored
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user