Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b4fa679c2 | ||
|
|
c2ae95c4cc | ||
|
|
b2b7f60fd5 | ||
|
|
a465888b31 | ||
|
|
d368bdc84c | ||
|
|
cdc1150505 | ||
|
|
32d525c53c | ||
|
|
a89b40c607 | ||
|
|
b6bd9150d9 | ||
|
|
96e3e3bc86 | ||
|
|
41377f41bb | ||
|
|
fb744f81e2 | ||
|
|
750c3bcbcd | ||
|
|
d4015d7284 | ||
|
|
a9bf3fda73 | ||
|
|
7f467a4814 | ||
|
|
9f10b5e983 | ||
|
|
5291270e6a | ||
|
|
56bba381d8 |
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024-present Lejianwen and contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -39,6 +39,7 @@
|
|||||||
- 自动获取ID服务器和KEY
|
- 自动获取ID服务器和KEY
|
||||||
- 自动获取地址簿
|
- 自动获取地址簿
|
||||||
- 游客通过临时分享链接直接远程到设备
|
- 游客通过临时分享链接直接远程到设备
|
||||||
|
- v2 Preview
|
||||||
- CLI
|
- CLI
|
||||||
- 重置管理员密码
|
- 重置管理员密码
|
||||||
|
|
||||||
@@ -142,6 +143,12 @@
|
|||||||

|

|
||||||
3. 登录后,会自动同步ID服务器和KEY
|
3. 登录后,会自动同步ID服务器和KEY
|
||||||
4. 登录后,会将地址簿自动保存到web client中,方便使用
|
4. 登录后,会将地址簿自动保存到web client中,方便使用
|
||||||
|
5. 现已支持`v2 Preview`,访问路径是`/webclient2`
|
||||||
|

|
||||||
|
6. `v2 preview` 部署
|
||||||
|
- 如果是通过`443`端口的`https`部署,必须配置反向代理,可以参考[官方文档](https://rustdesk.com/docs/en/self-host/rustdesk-server-pro/faq/#8-add-websocket-secure-wss-support-for-the-id-server-and-relay-server-to-enable-secure-communication-for-the-web-client)
|
||||||
|
- 如果是`http`或者其他的`https`端口部署,则和`v1`一样,配置好`21118`,`21119`即可
|
||||||
|
- 更多参考[Web-Client-V2-Preview-Document](https://github.com/lejianwen/rustdesk-api/wiki/Web-Client-V2-Preview-Document)
|
||||||
|
|
||||||
### 自动化文档: 使用 Swag 生成 API 文档,方便开发者理解和使用 API。
|
### 自动化文档: 使用 Swag 生成 API 文档,方便开发者理解和使用 API。
|
||||||
|
|
||||||
|
|||||||
@@ -147,6 +147,13 @@ installation are `admin` `admin`, please change the password immediately.
|
|||||||

|

|
||||||
3. After logging in, the ID server and key will be automatically synced.
|
3. After logging in, the ID server and key will be automatically synced.
|
||||||
4. The address book will also be automatically saved to the web client for convenient use.
|
4. The address book will also be automatically saved to the web client for convenient use.
|
||||||
|
5. Now supports `v2 Preview`, accessible at `/webclient2`
|
||||||
|

|
||||||
|
6. `v2 preview` deployment
|
||||||
|
- If deploying via `https` on port `443`, you must configure a reverse proxy. Refer to the [official documentation](https://rustdesk.com/docs/en/self-host/rustdesk-server-pro/faq/#8-add-websocket-secure-wss-support-for-the-id-server-and-relay-server-to-enable-secure-communication-for-the-web-client)
|
||||||
|
- If deploying via `http` or other `https` ports, configure `21118` and `21119` as with `v1`
|
||||||
|
- More [Web-Client-V2-Preview-Document](https://github.com/lejianwen/rustdesk-api/wiki/Web-Client-V2-Preview-Document)
|
||||||
|
|
||||||
|
|
||||||
### Automated Documentation : API documentation is generated using Swag, making it easier for developers to understand and use the API.
|
### Automated Documentation : API documentation is generated using Swag, making it easier for developers to understand and use the API.
|
||||||
|
|
||||||
|
|||||||
@@ -3569,7 +3569,7 @@ const docTemplateadmin = `{
|
|||||||
"token": []
|
"token": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "登录凭证删除",
|
"description": "登录凭证批量删除",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
@@ -3579,7 +3579,7 @@ const docTemplateadmin = `{
|
|||||||
"tags": [
|
"tags": [
|
||||||
"登录凭证"
|
"登录凭证"
|
||||||
],
|
],
|
||||||
"summary": "登录凭证删除",
|
"summary": "登录凭证批量删除",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "登录凭证信息",
|
"description": "登录凭证信息",
|
||||||
@@ -3587,7 +3587,7 @@ const docTemplateadmin = `{
|
|||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/model.UserToken"
|
"$ref": "#/definitions/admin.UserTokenBatchDeleteForm"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -3798,12 +3798,12 @@ const docTemplateadmin = `{
|
|||||||
"properties": {
|
"properties": {
|
||||||
"new_password": {
|
"new_password": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"maxLength": 20,
|
"maxLength": 32,
|
||||||
"minLength": 4
|
"minLength": 4
|
||||||
},
|
},
|
||||||
"old_password": {
|
"old_password": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"maxLength": 20,
|
"maxLength": 32,
|
||||||
"minLength": 4
|
"minLength": 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4038,7 +4038,7 @@ const docTemplateadmin = `{
|
|||||||
},
|
},
|
||||||
"username": {
|
"username": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"maxLength": 10,
|
"maxLength": 32,
|
||||||
"minLength": 2
|
"minLength": 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4066,11 +4066,25 @@ const docTemplateadmin = `{
|
|||||||
},
|
},
|
||||||
"password": {
|
"password": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"maxLength": 20,
|
"maxLength": 32,
|
||||||
"minLength": 4
|
"minLength": 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"admin.UserTokenBatchDeleteForm": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"ids"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"ids": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"model.AddressBook": {
|
"model.AddressBook": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
@@ -3562,7 +3562,7 @@
|
|||||||
"token": []
|
"token": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "登录凭证删除",
|
"description": "登录凭证批量删除",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
@@ -3572,7 +3572,7 @@
|
|||||||
"tags": [
|
"tags": [
|
||||||
"登录凭证"
|
"登录凭证"
|
||||||
],
|
],
|
||||||
"summary": "登录凭证删除",
|
"summary": "登录凭证批量删除",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "登录凭证信息",
|
"description": "登录凭证信息",
|
||||||
@@ -3580,7 +3580,7 @@
|
|||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/model.UserToken"
|
"$ref": "#/definitions/admin.UserTokenBatchDeleteForm"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -3791,12 +3791,12 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"new_password": {
|
"new_password": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"maxLength": 20,
|
"maxLength": 32,
|
||||||
"minLength": 4
|
"minLength": 4
|
||||||
},
|
},
|
||||||
"old_password": {
|
"old_password": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"maxLength": 20,
|
"maxLength": 32,
|
||||||
"minLength": 4
|
"minLength": 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4031,7 +4031,7 @@
|
|||||||
},
|
},
|
||||||
"username": {
|
"username": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"maxLength": 10,
|
"maxLength": 32,
|
||||||
"minLength": 2
|
"minLength": 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4059,11 +4059,25 @@
|
|||||||
},
|
},
|
||||||
"password": {
|
"password": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"maxLength": 20,
|
"maxLength": 32,
|
||||||
"minLength": 4
|
"minLength": 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"admin.UserTokenBatchDeleteForm": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"ids"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"ids": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"model.AddressBook": {
|
"model.AddressBook": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
@@ -78,11 +78,11 @@ definitions:
|
|||||||
admin.ChangeCurPasswordForm:
|
admin.ChangeCurPasswordForm:
|
||||||
properties:
|
properties:
|
||||||
new_password:
|
new_password:
|
||||||
maxLength: 20
|
maxLength: 32
|
||||||
minLength: 4
|
minLength: 4
|
||||||
type: string
|
type: string
|
||||||
old_password:
|
old_password:
|
||||||
maxLength: 20
|
maxLength: 32
|
||||||
minLength: 4
|
minLength: 4
|
||||||
type: string
|
type: string
|
||||||
required:
|
required:
|
||||||
@@ -238,7 +238,7 @@ definitions:
|
|||||||
- $ref: '#/definitions/model.StatusCode'
|
- $ref: '#/definitions/model.StatusCode'
|
||||||
minimum: 0
|
minimum: 0
|
||||||
username:
|
username:
|
||||||
maxLength: 10
|
maxLength: 32
|
||||||
minLength: 2
|
minLength: 2
|
||||||
type: string
|
type: string
|
||||||
required:
|
required:
|
||||||
@@ -258,13 +258,22 @@ definitions:
|
|||||||
id:
|
id:
|
||||||
type: integer
|
type: integer
|
||||||
password:
|
password:
|
||||||
maxLength: 20
|
maxLength: 32
|
||||||
minLength: 4
|
minLength: 4
|
||||||
type: string
|
type: string
|
||||||
required:
|
required:
|
||||||
- id
|
- id
|
||||||
- password
|
- password
|
||||||
type: object
|
type: object
|
||||||
|
admin.UserTokenBatchDeleteForm:
|
||||||
|
properties:
|
||||||
|
ids:
|
||||||
|
items:
|
||||||
|
type: integer
|
||||||
|
type: array
|
||||||
|
required:
|
||||||
|
- ids
|
||||||
|
type: object
|
||||||
model.AddressBook:
|
model.AddressBook:
|
||||||
properties:
|
properties:
|
||||||
alias:
|
alias:
|
||||||
@@ -2871,14 +2880,14 @@ paths:
|
|||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
description: 登录凭证删除
|
description: 登录凭证批量删除
|
||||||
parameters:
|
parameters:
|
||||||
- description: 登录凭证信息
|
- description: 登录凭证信息
|
||||||
in: body
|
in: body
|
||||||
name: body
|
name: body
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/model.UserToken'
|
$ref: '#/definitions/admin.UserTokenBatchDeleteForm'
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
@@ -2892,7 +2901,7 @@ paths:
|
|||||||
$ref: '#/definitions/response.Response'
|
$ref: '#/definitions/response.Response'
|
||||||
security:
|
security:
|
||||||
- token: []
|
- token: []
|
||||||
summary: 登录凭证删除
|
summary: 登录凭证批量删除
|
||||||
tags:
|
tags:
|
||||||
- 登录凭证
|
- 登录凭证
|
||||||
/admin/user_token/list:
|
/admin/user_token/list:
|
||||||
|
|||||||
@@ -1056,7 +1056,7 @@ const docTemplateapi = `{
|
|||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"WEBCLIENT"
|
"WEBCLIENT_V2"
|
||||||
],
|
],
|
||||||
"summary": "服务配置",
|
"summary": "服务配置",
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -1356,7 +1356,7 @@ const docTemplateapi = `{
|
|||||||
},
|
},
|
||||||
"password": {
|
"password": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"maxLength": 20,
|
"maxLength": 32,
|
||||||
"minLength": 4
|
"minLength": 4
|
||||||
},
|
},
|
||||||
"type": {
|
"type": {
|
||||||
@@ -1364,7 +1364,7 @@ const docTemplateapi = `{
|
|||||||
},
|
},
|
||||||
"username": {
|
"username": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"maxLength": 10,
|
"maxLength": 32,
|
||||||
"minLength": 2
|
"minLength": 2
|
||||||
},
|
},
|
||||||
"uuid": {
|
"uuid": {
|
||||||
|
|||||||
@@ -1049,7 +1049,7 @@
|
|||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"WEBCLIENT"
|
"WEBCLIENT_V2"
|
||||||
],
|
],
|
||||||
"summary": "服务配置",
|
"summary": "服务配置",
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -1349,7 +1349,7 @@
|
|||||||
},
|
},
|
||||||
"password": {
|
"password": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"maxLength": 20,
|
"maxLength": 32,
|
||||||
"minLength": 4
|
"minLength": 4
|
||||||
},
|
},
|
||||||
"type": {
|
"type": {
|
||||||
@@ -1357,7 +1357,7 @@
|
|||||||
},
|
},
|
||||||
"username": {
|
"username": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"maxLength": 10,
|
"maxLength": 32,
|
||||||
"minLength": 2
|
"minLength": 2
|
||||||
},
|
},
|
||||||
"uuid": {
|
"uuid": {
|
||||||
|
|||||||
@@ -62,13 +62,13 @@ definitions:
|
|||||||
id:
|
id:
|
||||||
type: string
|
type: string
|
||||||
password:
|
password:
|
||||||
maxLength: 20
|
maxLength: 32
|
||||||
minLength: 4
|
minLength: 4
|
||||||
type: string
|
type: string
|
||||||
type:
|
type:
|
||||||
type: string
|
type: string
|
||||||
username:
|
username:
|
||||||
maxLength: 10
|
maxLength: 32
|
||||||
minLength: 2
|
minLength: 2
|
||||||
type: string
|
type: string
|
||||||
uuid:
|
uuid:
|
||||||
@@ -869,7 +869,7 @@ paths:
|
|||||||
- token: []
|
- token: []
|
||||||
summary: 服务配置
|
summary: 服务配置
|
||||||
tags:
|
tags:
|
||||||
- WEBCLIENT
|
- WEBCLIENT_V2
|
||||||
/shared-peer:
|
/shared-peer:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 19 KiB |
BIN
docs/webclientv2.png
Normal file
BIN
docs/webclientv2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
@@ -3,6 +3,7 @@ package global
|
|||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/go-playground/locales/en"
|
"github.com/go-playground/locales/en"
|
||||||
|
"github.com/go-playground/locales/es"
|
||||||
"github.com/go-playground/locales/ko"
|
"github.com/go-playground/locales/ko"
|
||||||
"github.com/go-playground/locales/ru"
|
"github.com/go-playground/locales/ru"
|
||||||
"github.com/go-playground/locales/zh_Hans_CN"
|
"github.com/go-playground/locales/zh_Hans_CN"
|
||||||
@@ -10,6 +11,7 @@ import (
|
|||||||
ut "github.com/go-playground/universal-translator"
|
ut "github.com/go-playground/universal-translator"
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
en_translations "github.com/go-playground/validator/v10/translations/en"
|
en_translations "github.com/go-playground/validator/v10/translations/en"
|
||||||
|
es_translations "github.com/go-playground/validator/v10/translations/es"
|
||||||
ru_translations "github.com/go-playground/validator/v10/translations/ru"
|
ru_translations "github.com/go-playground/validator/v10/translations/ru"
|
||||||
zh_translations "github.com/go-playground/validator/v10/translations/zh"
|
zh_translations "github.com/go-playground/validator/v10/translations/zh"
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -23,13 +25,15 @@ func ApiInitValidator() {
|
|||||||
cn := zh_Hans_CN.New()
|
cn := zh_Hans_CN.New()
|
||||||
koT := ko.New()
|
koT := ko.New()
|
||||||
ruT := ru.New()
|
ruT := ru.New()
|
||||||
|
esT := es.New()
|
||||||
|
|
||||||
uni := ut.New(enT, cn, koT, ruT)
|
uni := ut.New(enT, cn, koT, ruT, esT)
|
||||||
|
|
||||||
enTrans, _ := uni.GetTranslator("en")
|
enTrans, _ := uni.GetTranslator("en")
|
||||||
zhTrans, _ := uni.GetTranslator("zh_Hans_CN")
|
zhTrans, _ := uni.GetTranslator("zh_Hans_CN")
|
||||||
koTrans, _ := uni.GetTranslator("ko")
|
koTrans, _ := uni.GetTranslator("ko")
|
||||||
ruTrans, _ := uni.GetTranslator("ru")
|
ruTrans, _ := uni.GetTranslator("ru")
|
||||||
|
esTrans, _ := uni.GetTranslator("es")
|
||||||
|
|
||||||
err := zh_translations.RegisterDefaultTranslations(validate, zhTrans)
|
err := zh_translations.RegisterDefaultTranslations(validate, zhTrans)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -49,6 +53,10 @@ func ApiInitValidator() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
err = es_translations.RegisterDefaultTranslations(validate, esTrans)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
validate.RegisterTagNameFunc(func(field reflect.StructField) string {
|
validate.RegisterTagNameFunc(func(field reflect.StructField) string {
|
||||||
label := field.Tag.Get("label")
|
label := field.Tag.Get("label")
|
||||||
@@ -115,6 +123,9 @@ func getTranslatorForLang(lang string) ut.Translator {
|
|||||||
case "ru":
|
case "ru":
|
||||||
trans, _ := Validator.UT.GetTranslator("ru")
|
trans, _ := Validator.UT.GetTranslator("ru")
|
||||||
return trans
|
return trans
|
||||||
|
case "es":
|
||||||
|
trans, _ := Validator.UT.GetTranslator("es")
|
||||||
|
return trans
|
||||||
case "en":
|
case "en":
|
||||||
fallthrough
|
fallthrough
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"Gwen/http/response"
|
"Gwen/http/response"
|
||||||
"Gwen/model"
|
"Gwen/model"
|
||||||
"Gwen/service"
|
"Gwen/service"
|
||||||
|
"encoding/json"
|
||||||
_ "encoding/json"
|
_ "encoding/json"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@@ -327,3 +328,70 @@ func (ct *AddressBook) ShareByWebClient(c *gin.Context) {
|
|||||||
"share_token": m.ShareToken,
|
"share_token": m.ShareToken,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ct *AddressBook) BatchCreateFromPeers(c *gin.Context) {
|
||||||
|
f := &admin.BatchCreateFromPeersForm{}
|
||||||
|
if err := c.ShouldBindJSON(f); err != nil {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
u := service.AllService.UserService.CurUser(c)
|
||||||
|
|
||||||
|
if f.CollectionId != 0 {
|
||||||
|
collection := service.AllService.AddressBookService.CollectionInfoById(f.CollectionId)
|
||||||
|
if collection.Id == 0 {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if collection.UserId != u.Id {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "NoAccess"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
peers := service.AllService.PeerService.List(1, 999, func(tx *gorm.DB) {
|
||||||
|
tx.Where("row_id in ?", f.PeerIds)
|
||||||
|
tx.Where("user_id = ?", u.Id)
|
||||||
|
})
|
||||||
|
if peers.Total == 0 {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tags, _ := json.Marshal(f.Tags)
|
||||||
|
for _, peer := range peers.Peers {
|
||||||
|
ab := service.AllService.AddressBookService.FromPeer(peer)
|
||||||
|
ab.Tags = tags
|
||||||
|
ab.CollectionId = f.CollectionId
|
||||||
|
ex := service.AllService.AddressBookService.InfoByUserIdAndIdAndCid(u.Id, ab.Id, ab.CollectionId)
|
||||||
|
if ex.RowId != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
service.AllService.AddressBookService.Create(ab)
|
||||||
|
}
|
||||||
|
response.Success(c, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ct *AddressBook) BatchUpdateTags(c *gin.Context) {
|
||||||
|
f := &admin.BatchUpdateTagsForm{}
|
||||||
|
if err := c.ShouldBindJSON(f); err != nil {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
u := service.AllService.UserService.CurUser(c)
|
||||||
|
|
||||||
|
abs := service.AllService.AddressBookService.List(1, 999, func(tx *gorm.DB) {
|
||||||
|
tx.Where("row_id in ?", f.RowIds)
|
||||||
|
tx.Where("user_id = ?", u.Id)
|
||||||
|
})
|
||||||
|
if abs.Total == 0 {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := service.AllService.AddressBookService.BatchUpdateTags(abs.AddressBooks, f.Tags)
|
||||||
|
if err != nil {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.Success(c, nil)
|
||||||
|
}
|
||||||
|
|||||||
@@ -81,3 +81,33 @@ func (ct *UserToken) Delete(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BatchDelete 批量删除
|
||||||
|
// @Tags 登录凭证
|
||||||
|
// @Summary 登录凭证批量删除
|
||||||
|
// @Description 登录凭证批量删除
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param body body admin.UserTokenBatchDeleteForm true "登录凭证信息"
|
||||||
|
// @Success 200 {object} response.Response
|
||||||
|
// @Failure 500 {object} response.Response
|
||||||
|
// @Router /admin/user_token/delete [post]
|
||||||
|
// @Security token
|
||||||
|
func (ct *UserToken) BatchDelete(c *gin.Context) {
|
||||||
|
f := &admin.UserTokenBatchDeleteForm{}
|
||||||
|
if err := c.ShouldBindJSON(f); err != nil {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ids := f.Ids
|
||||||
|
if len(ids) == 0 {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := service.AllService.UserService.BatchDeleteUserToken(ids)
|
||||||
|
if err == nil {
|
||||||
|
response.Success(c, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.Fail(c, 101, err.Error())
|
||||||
|
}
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ func (i *WebClient) SharedPeer(c *gin.Context) {
|
|||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} response.Response
|
// @Success 200 {object} response.Response
|
||||||
// @Failure 500 {object} response.Response
|
// @Failure 500 {object} response.Response
|
||||||
// @Router /server-config [get]
|
// @Router /server-config-v2 [get]
|
||||||
// @Security token
|
// @Security token
|
||||||
func (i *WebClient) ServerConfigV2(c *gin.Context) {
|
func (i *WebClient) ServerConfigV2(c *gin.Context) {
|
||||||
response.Success(
|
response.Success(
|
||||||
|
|||||||
@@ -122,3 +122,13 @@ type AddressBookCollectionRuleQuery struct {
|
|||||||
IsMy int `form:"is_my"`
|
IsMy int `form:"is_my"`
|
||||||
PageQuery
|
PageQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BatchCreateFromPeersForm struct {
|
||||||
|
CollectionId uint `json:"collection_id"`
|
||||||
|
PeerIds []uint `json:"peer_ids"`
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
}
|
||||||
|
type BatchUpdateTagsForm struct {
|
||||||
|
RowIds []uint `json:"row_ids"`
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
type UserForm struct {
|
type UserForm struct {
|
||||||
Id uint `json:"id"`
|
Id uint `json:"id"`
|
||||||
Username string `json:"username" validate:"required,gte=2,lte=10"`
|
Username string `json:"username" validate:"required,gte=2,lte=32"`
|
||||||
Email string `json:"email"` //validate:"required,email" email不强制
|
Email string `json:"email"` //validate:"required,email" email不强制
|
||||||
//Password string `json:"password" validate:"required,gte=4,lte=20"`
|
//Password string `json:"password" validate:"required,gte=4,lte=20"`
|
||||||
Nickname string `json:"nickname"`
|
Nickname string `json:"nickname"`
|
||||||
@@ -51,12 +51,12 @@ type UserQuery struct {
|
|||||||
}
|
}
|
||||||
type UserPasswordForm struct {
|
type UserPasswordForm struct {
|
||||||
Id uint `json:"id" validate:"required"`
|
Id uint `json:"id" validate:"required"`
|
||||||
Password string `json:"password" validate:"required,gte=4,lte=20"`
|
Password string `json:"password" validate:"required,gte=4,lte=32"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChangeCurPasswordForm struct {
|
type ChangeCurPasswordForm struct {
|
||||||
OldPassword string `json:"old_password" validate:"required,gte=4,lte=20"`
|
OldPassword string `json:"old_password" validate:"required,gte=4,lte=32"`
|
||||||
NewPassword string `json:"new_password" validate:"required,gte=4,lte=20"`
|
NewPassword string `json:"new_password" validate:"required,gte=4,lte=32"`
|
||||||
}
|
}
|
||||||
type GroupUsersQuery struct {
|
type GroupUsersQuery struct {
|
||||||
IsMy int `json:"is_my"`
|
IsMy int `json:"is_my"`
|
||||||
@@ -64,8 +64,12 @@ type GroupUsersQuery struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RegisterForm struct {
|
type RegisterForm struct {
|
||||||
Username string `json:"username" validate:"required,gte=2,lte=10"`
|
Username string `json:"username" validate:"required,gte=2,lte=32"`
|
||||||
Email string `json:"email"` // validate:"required,email"
|
Email string `json:"email"` // validate:"required,email"
|
||||||
Password string `json:"password" validate:"required,gte=4,lte=20"`
|
Password string `json:"password" validate:"required,gte=4,lte=32"`
|
||||||
ConfirmPassword string `json:"confirm_password" validate:"required,gte=4,lte=20"`
|
ConfirmPassword string `json:"confirm_password" validate:"required,gte=4,lte=32"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserTokenBatchDeleteForm struct {
|
||||||
|
Ids []uint `json:"ids" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ type LoginForm struct {
|
|||||||
Id string `json:"id" label:"id"`
|
Id string `json:"id" label:"id"`
|
||||||
Type string `json:"type" label:"type"`
|
Type string `json:"type" label:"type"`
|
||||||
Uuid string `json:"uuid" label:"uuid"`
|
Uuid string `json:"uuid" label:"uuid"`
|
||||||
Username string `json:"username" validate:"required,gte=2,lte=10" label:"用户名"`
|
Username string `json:"username" validate:"required,gte=2,lte=32" label:"用户名"`
|
||||||
Password string `json:"password,omitempty" validate:"gte=4,lte=20" label:"密码"`
|
Password string `json:"password,omitempty" validate:"gte=4,lte=32" label:"密码"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserListQuery struct {
|
type UserListQuery struct {
|
||||||
|
|||||||
@@ -107,9 +107,12 @@ func AddressBookBind(rg *gin.RouterGroup) {
|
|||||||
aR.POST("/update", cont.Update)
|
aR.POST("/update", cont.Update)
|
||||||
aR.POST("/delete", cont.Delete)
|
aR.POST("/delete", cont.Delete)
|
||||||
aR.POST("/shareByWebClient", cont.ShareByWebClient)
|
aR.POST("/shareByWebClient", cont.ShareByWebClient)
|
||||||
|
aR.POST("/batchCreateFromPeers", cont.BatchCreateFromPeers)
|
||||||
|
aR.POST("/batchUpdateTags", cont.BatchUpdateTags)
|
||||||
|
|
||||||
arp := aR.Use(middleware.AdminPrivilege())
|
arp := aR.Use(middleware.AdminPrivilege())
|
||||||
arp.POST("/batchCreate", cont.BatchCreate)
|
arp.POST("/batchCreate", cont.BatchCreate)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func PeerBind(rg *gin.RouterGroup) {
|
func PeerBind(rg *gin.RouterGroup) {
|
||||||
@@ -195,6 +198,7 @@ func UserTokenBind(rg *gin.RouterGroup) {
|
|||||||
cont := &admin.UserToken{}
|
cont := &admin.UserToken{}
|
||||||
aR.GET("/list", cont.List)
|
aR.GET("/list", cont.List)
|
||||||
aR.POST("/delete", cont.Delete)
|
aR.POST("/delete", cont.Delete)
|
||||||
|
aR.POST("/batchDelete", cont.BatchDelete)
|
||||||
}
|
}
|
||||||
func ConfigBind(rg *gin.RouterGroup) {
|
func ConfigBind(rg *gin.RouterGroup) {
|
||||||
aR := rg.Group("/config")
|
aR := rg.Group("/config")
|
||||||
|
|||||||
134
resources/i18n/es.toml
Normal file
134
resources/i18n/es.toml
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
[Test]
|
||||||
|
description = "test"
|
||||||
|
one = "prueba1"
|
||||||
|
other = "Prueba2 {{.P0}}"
|
||||||
|
|
||||||
|
[ParamsError]
|
||||||
|
description = "Params validation failed."
|
||||||
|
one = "La validación de los parámetros falló."
|
||||||
|
other = "La validación de los parámetros falló."
|
||||||
|
|
||||||
|
[OperationFailed]
|
||||||
|
description = "OperationFailed."
|
||||||
|
one = "La operación falló."
|
||||||
|
other = "La operación falló."
|
||||||
|
|
||||||
|
[OperationSuccess]
|
||||||
|
description = "OperationSuccess."
|
||||||
|
one = "La operación fue exitosa."
|
||||||
|
other = "La operación fue exitosa."
|
||||||
|
|
||||||
|
[ItemExists]
|
||||||
|
description = "Item already exists."
|
||||||
|
one = "El elemento ya existe."
|
||||||
|
other = "El elemento ya existe."
|
||||||
|
|
||||||
|
[ItemNotFound]
|
||||||
|
description = "Item not found."
|
||||||
|
one = "El elemento no fue encontrado."
|
||||||
|
other = "El elemento no fue encontrado."
|
||||||
|
|
||||||
|
[NoAccess]
|
||||||
|
description = "No access."
|
||||||
|
one = "Sin acceso."
|
||||||
|
other = "Sin acceso."
|
||||||
|
|
||||||
|
[UsernameOrPasswordError]
|
||||||
|
description = "Username or password error."
|
||||||
|
one = "Error de usuario o contraseña."
|
||||||
|
other = "Error de usuario o contraseña."
|
||||||
|
|
||||||
|
[SystemError]
|
||||||
|
description = "System error."
|
||||||
|
one = "Error del sistema."
|
||||||
|
other = "Error del sistema."
|
||||||
|
|
||||||
|
[ConfigNotFound]
|
||||||
|
description = "Config not found."
|
||||||
|
one = "Configuración no encontrada."
|
||||||
|
other = "Configuración no encontrada."
|
||||||
|
|
||||||
|
[OauthExpired]
|
||||||
|
description = "Oauth expired."
|
||||||
|
one = "Oauth expirado, por favor intente nuevamente."
|
||||||
|
other = "Oauth expirado, por favor intente nuevamente."
|
||||||
|
|
||||||
|
[OauthFailed]
|
||||||
|
description = "Oauth failed."
|
||||||
|
one = "Oauth falló."
|
||||||
|
other = "Oauth falló."
|
||||||
|
|
||||||
|
[OauthHasBindOtherUser]
|
||||||
|
description = "Oauth has bind other user."
|
||||||
|
one = "Oauth está vinculado a otro usuario."
|
||||||
|
other = "Oauth está vinculado a otro usuario."
|
||||||
|
|
||||||
|
[ParamIsEmpty]
|
||||||
|
description = "Param is empty."
|
||||||
|
one = "{{.P0}} está vacío."
|
||||||
|
other = "{{.P0}} está vacío."
|
||||||
|
|
||||||
|
[BindFail]
|
||||||
|
description = "Bind fail."
|
||||||
|
one = "Fallo al vincular."
|
||||||
|
other = "Fallo al vincular."
|
||||||
|
|
||||||
|
[BindSuccess]
|
||||||
|
description = "Bind success."
|
||||||
|
one = "Vinculación exitosa."
|
||||||
|
other = "Vinculación exitosa."
|
||||||
|
|
||||||
|
[OauthHasBeenSuccess]
|
||||||
|
description = "Oauth has been success."
|
||||||
|
one = "Oauth fue exitoso."
|
||||||
|
other = "Oauth fue exitoso."
|
||||||
|
|
||||||
|
[OauthSuccess]
|
||||||
|
description = "Oauth success."
|
||||||
|
one = "Oauth exitoso."
|
||||||
|
other = "Oauth exitoso."
|
||||||
|
|
||||||
|
[OauthRegisterSuccess]
|
||||||
|
description = "Oauth register success."
|
||||||
|
one = "Registro de Oauth exitoso."
|
||||||
|
other = "Registro de Oauth exitoso."
|
||||||
|
|
||||||
|
[OauthRegisterFailed]
|
||||||
|
description = "Oauth register failed."
|
||||||
|
one = "Registro de Oauth falló."
|
||||||
|
other = "Registro de Oauth falló."
|
||||||
|
|
||||||
|
[GetOauthTokenError]
|
||||||
|
description = "Get oauth token error."
|
||||||
|
one = "Error al obtener el token de Oauth."
|
||||||
|
other = "Error al obtener el token de Oauth."
|
||||||
|
|
||||||
|
[GetOauthUserInfoError]
|
||||||
|
description = "Get oauth user info error."
|
||||||
|
one = "Error al obtener la información del usuario de Oauth."
|
||||||
|
other = "Error al obtener la información del usuario de Oauth."
|
||||||
|
|
||||||
|
[DecodeOauthUserInfoError]
|
||||||
|
description = "Decode oauth user info error."
|
||||||
|
one = "Error al decodificar la información del usuario de Oauth."
|
||||||
|
other = "Error al decodificar la información del usuario de Oauth."
|
||||||
|
|
||||||
|
[OldPasswordError]
|
||||||
|
description = "Old password error."
|
||||||
|
one = "Error con la contraseña anterior."
|
||||||
|
other = "Error con la contraseña anterior."
|
||||||
|
|
||||||
|
[DefaultGroup]
|
||||||
|
description = "Default group"
|
||||||
|
one = "Grupo predeterminado"
|
||||||
|
other = "Grupo predeterminado"
|
||||||
|
|
||||||
|
[ShareGroup]
|
||||||
|
description = "Share group"
|
||||||
|
one = "Grupo compartido"
|
||||||
|
other = "Grupo compartido"
|
||||||
|
|
||||||
|
[RegisterClosed]
|
||||||
|
description = "Register closed."
|
||||||
|
one = "Registro cerrado."
|
||||||
|
other = "Registro cerrado."
|
||||||
4
resources/web2/index.html
vendored
4
resources/web2/index.html
vendored
@@ -32,7 +32,7 @@
|
|||||||
<title>RustDesk</title>
|
<title>RustDesk</title>
|
||||||
<script src="/webclient-config/index.js"></script>
|
<script src="/webclient-config/index.js"></script>
|
||||||
<link rel="manifest" href="manifest.json" />
|
<link rel="manifest" href="manifest.json" />
|
||||||
<script type="module" crossorigin src="js/dist/index.js?v=3"></script>
|
<script type="module" crossorigin src="js/dist/index.js?v=893935a2"></script>
|
||||||
<link rel="modulepreload" href="js/dist/vendor.js?v=0b990c6e" />
|
<link rel="modulepreload" href="js/dist/vendor.js?v=0b990c6e" />
|
||||||
<style>
|
<style>
|
||||||
html,
|
html,
|
||||||
@@ -259,7 +259,7 @@
|
|||||||
}
|
}
|
||||||
scriptLoaded = true;
|
scriptLoaded = true;
|
||||||
var scriptTag = document.createElement("script");
|
var scriptTag = document.createElement("script");
|
||||||
scriptTag.src = "main.dart.js?v=6d46937e";
|
scriptTag.src = "main.dart.js?v=df360f45";
|
||||||
scriptTag.type = "application/javascript";
|
scriptTag.type = "application/javascript";
|
||||||
document.body.append(scriptTag);
|
document.body.append(scriptTag);
|
||||||
}
|
}
|
||||||
|
|||||||
31714
resources/web2/js/dist/index.js
vendored
31714
resources/web2/js/dist/index.js
vendored
File diff suppressed because it is too large
Load Diff
28163
resources/web2/js/dist/lang.js
vendored
Normal file
28163
resources/web2/js/dist/lang.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
36
resources/web2/js/dist/ljw.js
vendored
36
resources/web2/js/dist/ljw.js
vendored
@@ -1,6 +1,7 @@
|
|||||||
window._gwen = {}
|
window._gwen = {}
|
||||||
window._gwen.kv = {}
|
window._gwen.kv = {}
|
||||||
const apiserver = localStorage.getItem('api-server')
|
const storage_prefix = 'wc-'
|
||||||
|
const apiserver = localStorage.getItem('wc-api-server')
|
||||||
|
|
||||||
function stringToUint8Array(str) {
|
function stringToUint8Array(str) {
|
||||||
var arr = [];
|
var arr = [];
|
||||||
@@ -23,10 +24,10 @@ function getQueryVariable() {
|
|||||||
|
|
||||||
getQueryVariable()
|
getQueryVariable()
|
||||||
|
|
||||||
const id = window._gwen.kv.id || ''
|
/*const id = window._gwen.kv.id || ''
|
||||||
if (id) {
|
if (id) {
|
||||||
localStorage.setItem('remote-id', id)
|
localStorage.setItem(storage_prefix+'option:local:last_remote_id', id)
|
||||||
}
|
}*/
|
||||||
const share_token = window._gwen.kv.share_token || ''
|
const share_token = window._gwen.kv.share_token || ''
|
||||||
if (share_token) {
|
if (share_token) {
|
||||||
fetch(apiserver + "/api/shared-peer", {
|
fetch(apiserver + "/api/shared-peer", {
|
||||||
@@ -37,14 +38,15 @@ if (share_token) {
|
|||||||
body: JSON.stringify({share_token})
|
body: JSON.stringify({share_token})
|
||||||
}).then(res => res.json()).then(res => {
|
}).then(res => res.json()).then(res => {
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
localStorage.setItem('custom-rendezvous-server', res.data.id_server)
|
localStorage.setItem(storage_prefix + 'custom-rendezvous-server', res.data.id_server)
|
||||||
localStorage.setItem('key', res.data.key)
|
localStorage.setItem(storage_prefix + 'key', res.data.key)
|
||||||
const peer = res.data.peer
|
const peer = res.data.peer || {}
|
||||||
localStorage.setItem('remote-id', peer.info.id)
|
/*const s = {
|
||||||
peer.tmppwd = stringToUint8Array(window.atob(peer.tmppwd)).toString()
|
id: peer.info.id,
|
||||||
const oldPeers = JSON.parse(localStorage.getItem('peers')) || {}
|
password: peer.tmppwd,
|
||||||
oldPeers[peer.info.id] = peer
|
}*/
|
||||||
localStorage.setItem('peers', JSON.stringify(oldPeers))
|
//修改location
|
||||||
|
window.location.href = `/webclient2/#/${peer.info.id}?password=${peer.tmppwd}`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -55,8 +57,8 @@ export function getServerConf(token) {
|
|||||||
if (!token) {
|
if (!token) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const prefix = 'wc-'
|
|
||||||
console.log('getServerConf', token)
|
// console.log('getServerConf', token)
|
||||||
if (fetching) {
|
if (fetching) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -71,9 +73,9 @@ export function getServerConf(token) {
|
|||||||
).then(res => res.json()).then(res => {
|
).then(res => res.json()).then(res => {
|
||||||
fetching = false
|
fetching = false
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
if (!localStorage.getItem(prefix + 'custom-rendezvous-server') || !localStorage.getItem('key')) {
|
if (!localStorage.getItem(storage_prefix + 'custom-rendezvous-server') || !localStorage.getItem('key')) {
|
||||||
localStorage.setItem(prefix + 'custom-rendezvous-server', res.data.id_server)
|
localStorage.setItem(storage_prefix + 'custom-rendezvous-server', res.data.id_server)
|
||||||
localStorage.setItem(prefix + 'key', res.data.key)
|
localStorage.setItem(storage_prefix + 'key', res.data.key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).catch(_ => {
|
}).catch(_ => {
|
||||||
|
|||||||
224287
resources/web2/main.dart.js
vendored
224287
resources/web2/main.dart.js
vendored
File diff suppressed because one or more lines are too long
@@ -3,6 +3,7 @@ package service
|
|||||||
import (
|
import (
|
||||||
"Gwen/global"
|
"Gwen/global"
|
||||||
"Gwen/model"
|
"Gwen/model"
|
||||||
|
"encoding/json"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -116,6 +117,16 @@ func (s *AddressBookService) List(page, pageSize uint, where func(tx *gorm.DB))
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *AddressBookService) FromPeer(peer *model.Peer) (a *model.AddressBook) {
|
||||||
|
a = &model.AddressBook{}
|
||||||
|
a.Id = peer.Id
|
||||||
|
a.Username = peer.Username
|
||||||
|
a.Hostname = peer.Hostname
|
||||||
|
a.UserId = peer.UserId
|
||||||
|
a.Platform = s.PlatformFromOs(peer.Os)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
// Create 创建
|
// Create 创建
|
||||||
func (s *AddressBookService) Create(u *model.AddressBook) error {
|
func (s *AddressBookService) Create(u *model.AddressBook) error {
|
||||||
res := global.DB.Create(u).Error
|
res := global.DB.Create(u).Error
|
||||||
@@ -318,3 +329,12 @@ func (s *AddressBookService) CheckCollectionOwner(uid uint, cid uint) bool {
|
|||||||
p := s.CollectionInfoById(cid)
|
p := s.CollectionInfoById(cid)
|
||||||
return p.UserId == uid
|
return p.UserId == uid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *AddressBookService) BatchUpdateTags(abs []*model.AddressBook, tags []string) error {
|
||||||
|
ids := make([]uint, 0)
|
||||||
|
for _, ab := range abs {
|
||||||
|
ids = append(ids, ab.RowId)
|
||||||
|
}
|
||||||
|
tagsv, _ := json.Marshal(tags)
|
||||||
|
return global.DB.Model(&model.AddressBook{}).Where("row_id in ?", ids).Update("tags", tagsv).Error
|
||||||
|
}
|
||||||
|
|||||||
@@ -458,3 +458,7 @@ func (us *UserService) AutoRefreshAccessToken(ut *model.UserToken) {
|
|||||||
us.RefreshAccessToken(ut)
|
us.RefreshAccessToken(ut)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (us *UserService) BatchDeleteUserToken(ids []uint) error {
|
||||||
|
return global.DB.Where("id in ?", ids).Delete(&model.UserToken{}).Error
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user