release (#150)
* 修改首页卡片间距 * 修改普通用户分享资产时只能查看到普通用户 close #133 * 修复普通用户访问非自己创建的资产无法打开原生ssh的bug * release v0.4.1 * 修复使用命令修改加密key失败的问题 * 修改初始化RDP属性「禁用字形缓存」为打开 * 增加kubernetes协议的筛选 * 修改安装文档&修复首页链接限制无效的问题 * 修改guacd版本为1.3.0 * 支持导入资产时带标签的数据 * - 修改原生安装文档中guacamole版本为1.3.0 - 修改点击名称为编辑 * release 0.5.0
This commit is contained in:
parent
969abe2202
commit
b0891a7c38
@ -12,7 +12,8 @@ RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositorie
|
|||||||
RUN apk add gcc g++
|
RUN apk add gcc g++
|
||||||
RUN go env && CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -a -ldflags '-linkmode external -extldflags "-static"' -o next-terminal main.go
|
RUN go env && CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -a -ldflags '-linkmode external -extldflags "-static"' -o next-terminal main.go
|
||||||
|
|
||||||
FROM guacamole/guacd:1.2.0
|
FROM guacamole/guacd:1.3.0
|
||||||
|
USER root
|
||||||
|
|
||||||
LABEL MAINTAINER="helloworld1024@foxmail.com"
|
LABEL MAINTAINER="helloworld1024@foxmail.com"
|
||||||
|
|
||||||
|
@ -52,6 +52,13 @@ docker rm <container-id> -f
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>ssh协议中文字体乱码怎么办?</summary>
|
||||||
|
|
||||||
|
参考[安装字体](install-naive.md)章节,给系统安装中文字体。
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>ssh协议类型的资产连接模式有什么区别?</summary>
|
<summary>ssh协议类型的资产连接模式有什么区别?</summary>
|
||||||
|
|
||||||
|
@ -22,9 +22,9 @@ sudo apt-get install libcairo2-dev libjpeg62-turbo-dev libpng-dev libtool-bin li
|
|||||||
|
|
||||||
下载&解压&configure
|
下载&解压&configure
|
||||||
```shell
|
```shell
|
||||||
wget https://mirror.bit.edu.cn/apache/guacamole/1.2.0/source/guacamole-server-1.2.0.tar.gz
|
wget https://archive.apache.org/dist/guacamole/1.3.0/source/guacamole-server-1.3.0.tar.gz
|
||||||
tar -xzf guacamole-server-1.2.0.tar.gz
|
tar -xzf guacamole-server-1.3.0.tar.gz
|
||||||
cd guacamole-server-1.2.0
|
cd guacamole-server-1.3.0
|
||||||
./configure --with-init-dir=/etc/init.d
|
./configure --with-init-dir=/etc/init.d
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ cd guacamole-server-1.2.0
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
guacamole-server version 1.2.0
|
guacamole-server version 1.3.0
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
Library status:
|
Library status:
|
||||||
@ -49,13 +49,13 @@ guacamole-server version 1.2.0
|
|||||||
libVNCServer ........ yes
|
libVNCServer ........ yes
|
||||||
libvorbis ........... yes
|
libvorbis ........... yes
|
||||||
libpulse ............ yes
|
libpulse ............ yes
|
||||||
libwebsockets ....... no
|
libwebsockets ....... yes
|
||||||
libwebp ............. yes
|
libwebp ............. yes
|
||||||
wsock32 ............. no
|
wsock32 ............. no
|
||||||
|
|
||||||
Protocol support:
|
Protocol support:
|
||||||
|
|
||||||
Kubernetes .... no
|
Kubernetes .... yes
|
||||||
RDP ........... yes
|
RDP ........... yes
|
||||||
SSH ........... yes
|
SSH ........... yes
|
||||||
Telnet ........ yes
|
Telnet ........ yes
|
||||||
@ -72,7 +72,6 @@ guacamole-server version 1.2.0
|
|||||||
Systemd units: no
|
Systemd units: no
|
||||||
|
|
||||||
Type "make" to compile guacamole-server.
|
Type "make" to compile guacamole-server.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
编译和安装
|
编译和安装
|
||||||
|
2
main.go
2
main.go
@ -13,7 +13,7 @@ import (
|
|||||||
"github.com/labstack/gommon/log"
|
"github.com/labstack/gommon/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const Version = "v0.4.1"
|
const Version = "v0.5.0"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := Run()
|
err := Run()
|
||||||
|
@ -227,7 +227,7 @@ func (r PropertyService) InitProperties() error {
|
|||||||
if len(propertyMap[guacd.DisableGlyphCaching]) == 0 {
|
if len(propertyMap[guacd.DisableGlyphCaching]) == 0 {
|
||||||
property := model.Property{
|
property := model.Property{
|
||||||
Name: guacd.DisableGlyphCaching,
|
Name: guacd.DisableGlyphCaching,
|
||||||
Value: "false",
|
Value: "true",
|
||||||
}
|
}
|
||||||
if err := r.propertyRepository.Create(&property); err != nil {
|
if err := r.propertyRepository.Create(&property); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -99,6 +99,11 @@ func AssetImportEndpoint(c echo.Context) error {
|
|||||||
Owner: account.ID,
|
Owner: account.ID,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(record) >= 10 {
|
||||||
|
tags := strings.ReplaceAll(record[9], "|", ",")
|
||||||
|
asset.Tags = tags
|
||||||
|
}
|
||||||
|
|
||||||
err := assetRepository.Create(&asset)
|
err := assetRepository.Create(&asset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorCount++
|
errorCount++
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "next-terminal",
|
"name": "next-terminal",
|
||||||
"version": "0.4.1",
|
"version": "0.5.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons": "^4.3.0",
|
"@ant-design/icons": "^4.3.0",
|
||||||
|
@ -470,11 +470,22 @@ class Asset extends Component {
|
|||||||
if (short && short.length > 20) {
|
if (short && short.length > 20) {
|
||||||
short = short.substring(0, 20) + " ...";
|
short = short.substring(0, 20) + " ...";
|
||||||
}
|
}
|
||||||
return (
|
|
||||||
<Tooltip placement="topLeft" title={name}>
|
if (hasPermission(record['owner'])) {
|
||||||
{short}
|
return (
|
||||||
</Tooltip>
|
<Button type="link" size='small' onClick={() => this.update(record.id)}>
|
||||||
);
|
<Tooltip placement="topLeft" title={name}>
|
||||||
|
{short}
|
||||||
|
</Tooltip>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<Tooltip placement="topLeft" title={name}>
|
||||||
|
{short}
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
sorter: true,
|
sorter: true,
|
||||||
}, {
|
}, {
|
||||||
@ -688,6 +699,7 @@ class Asset extends Component {
|
|||||||
<Select.Option value="ssh">ssh</Select.Option>
|
<Select.Option value="ssh">ssh</Select.Option>
|
||||||
<Select.Option value="vnc">vnc</Select.Option>
|
<Select.Option value="vnc">vnc</Select.Option>
|
||||||
<Select.Option value="telnet">telnet</Select.Option>
|
<Select.Option value="telnet">telnet</Select.Option>
|
||||||
|
<Select.Option value="kubernetes">kubernetes</Select.Option>
|
||||||
</Select>
|
</Select>
|
||||||
|
|
||||||
<Tooltip title='重置查询'>
|
<Tooltip title='重置查询'>
|
||||||
@ -876,7 +888,7 @@ class Asset extends Component {
|
|||||||
|
|
||||||
<Button type="primary" onClick={() => {
|
<Button type="primary" onClick={() => {
|
||||||
|
|
||||||
let csvString = 'name,ssh,127.0.0.1,22,username,password,privateKey,passphrase,description';
|
let csvString = 'name,ssh,127.0.0.1,22,username,password,privateKey,passphrase,description,tag1|tag2|tag3';
|
||||||
//前置的"\uFEFF"为“零宽不换行空格”,可处理中文乱码问题
|
//前置的"\uFEFF"为“零宽不换行空格”,可处理中文乱码问题
|
||||||
const blob = new Blob(["\uFEFF" + csvString], {type: 'text/csv;charset=gb2312;'});
|
const blob = new Blob(["\uFEFF" + csvString], {type: 'text/csv;charset=gb2312;'});
|
||||||
let a = document.createElement('a');
|
let a = document.createElement('a');
|
||||||
|
@ -370,11 +370,21 @@ class DynamicCommand extends Component {
|
|||||||
if (short && short.length > 20) {
|
if (short && short.length > 20) {
|
||||||
short = short.substring(0, 20) + " ...";
|
short = short.substring(0, 20) + " ...";
|
||||||
}
|
}
|
||||||
return (
|
if (hasPermission(record['owner'])) {
|
||||||
<Tooltip placement="topLeft" title={name}>
|
return (
|
||||||
{short}
|
<Button type="link" size='small' onClick={() => this.showModal('更新指令', record)}>
|
||||||
</Tooltip>
|
<Tooltip placement="topLeft" title={name}>
|
||||||
);
|
{short}
|
||||||
|
</Tooltip>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<Tooltip placement="topLeft" title={name}>
|
||||||
|
{short}
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
sorter: true,
|
sorter: true,
|
||||||
}, {
|
}, {
|
||||||
|
@ -335,16 +335,27 @@ class Credential extends Component {
|
|||||||
title: '凭证名称',
|
title: '凭证名称',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
key: 'name',
|
key: 'name',
|
||||||
render: (name, record) => {
|
render: (name, record, index) => {
|
||||||
let short = name;
|
let short = name;
|
||||||
if (short && short.length > 20) {
|
if (short && short.length > 20) {
|
||||||
short = short.substring(0, 20) + " ...";
|
short = short.substring(0, 20) + " ...";
|
||||||
}
|
}
|
||||||
return (
|
if (hasPermission(record['owner'])) {
|
||||||
<Tooltip placement="topLeft" title={name}>
|
return (
|
||||||
{short}
|
<Button type="link" size='small' loading={this.state.items[index].updateBtnLoading}
|
||||||
</Tooltip>
|
onClick={() => this.showModal('更新凭证', record.id, index)}>
|
||||||
);
|
<Tooltip placement="topLeft" title={name}>
|
||||||
|
{short}
|
||||||
|
</Tooltip>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<Tooltip placement="topLeft" title={name}>
|
||||||
|
{short}
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
sorter: true,
|
sorter: true,
|
||||||
}, {
|
}, {
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
.text-center{
|
.text-center{
|
||||||
width: 100px;
|
width: 100px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
}
|
||||||
|
.disable-link {
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
@ -5,7 +5,6 @@ import request from "../../common/request";
|
|||||||
import './Dashboard.css'
|
import './Dashboard.css'
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
import {Area} from '@ant-design/charts';
|
import {Area} from '@ant-design/charts';
|
||||||
|
|
||||||
import {isAdmin} from "../../service/permission";
|
import {isAdmin} from "../../service/permission";
|
||||||
|
|
||||||
class Dashboard extends Component {
|
class Dashboard extends Component {
|
||||||
@ -50,6 +49,12 @@ class Dashboard extends Component {
|
|||||||
}, () => this.getD())
|
}, () => this.getD())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleLinkClick = (e) => {
|
||||||
|
if (!isAdmin()) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
@ -71,7 +76,7 @@ class Dashboard extends Component {
|
|||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
<Col span={6}>
|
<Col span={6}>
|
||||||
<Card bordered={true}>
|
<Card bordered={true}>
|
||||||
<Link to={'/user'} disabled={!isAdmin()}>
|
<Link to={'/user'} onClick={this.handleLinkClick}>
|
||||||
<Statistic title="在线用户" value={this.state.counter['user']}
|
<Statistic title="在线用户" value={this.state.counter['user']}
|
||||||
prefix={<UserOutlined/>}/>
|
prefix={<UserOutlined/>}/>
|
||||||
</Link>
|
</Link>
|
||||||
@ -96,7 +101,7 @@ class Dashboard extends Component {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col span={6}>
|
<Col span={6}>
|
||||||
<Card bordered={true}>
|
<Card bordered={true}>
|
||||||
<Link to={'/online-session'} disabled={!isAdmin()}>
|
<Link to={'/online-session'} onClick={this.handleLinkClick}>
|
||||||
<Statistic title="在线会话" value={this.state.counter['onlineSession']}
|
<Statistic title="在线会话" value={this.state.counter['onlineSession']}
|
||||||
prefix={<LinkOutlined/>}/>
|
prefix={<LinkOutlined/>}/>
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -403,6 +403,7 @@ class OfflineSession extends Component {
|
|||||||
<Select.Option value="ssh">ssh</Select.Option>
|
<Select.Option value="ssh">ssh</Select.Option>
|
||||||
<Select.Option value="vnc">vnc</Select.Option>
|
<Select.Option value="vnc">vnc</Select.Option>
|
||||||
<Select.Option value="telnet">telnet</Select.Option>
|
<Select.Option value="telnet">telnet</Select.Option>
|
||||||
|
<Select.Option value="kubernetes">kubernetes</Select.Option>
|
||||||
</Select>
|
</Select>
|
||||||
|
|
||||||
<Tooltip title='重置查询'>
|
<Tooltip title='重置查询'>
|
||||||
|
@ -374,6 +374,7 @@ class OnlineSession extends Component {
|
|||||||
<Select.Option value="ssh">ssh</Select.Option>
|
<Select.Option value="ssh">ssh</Select.Option>
|
||||||
<Select.Option value="vnc">vnc</Select.Option>
|
<Select.Option value="vnc">vnc</Select.Option>
|
||||||
<Select.Option value="telnet">telnet</Select.Option>
|
<Select.Option value="telnet">telnet</Select.Option>
|
||||||
|
<Select.Option value="kubernetes">kubernetes</Select.Option>
|
||||||
</Select>
|
</Select>
|
||||||
|
|
||||||
<Tooltip title='重置查询'>
|
<Tooltip title='重置查询'>
|
||||||
|
@ -304,6 +304,19 @@ class User extends Component {
|
|||||||
dataIndex: 'username',
|
dataIndex: 'username',
|
||||||
key: 'username',
|
key: 'username',
|
||||||
sorter: true,
|
sorter: true,
|
||||||
|
render: (username, record, index) => {
|
||||||
|
return (
|
||||||
|
<Button type="link" size='small'
|
||||||
|
onClick={async () => {
|
||||||
|
let result = await request.get(`/users/${record['id']}`);
|
||||||
|
if (result['code'] !== 1) {
|
||||||
|
message.error(result['message']);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.showModal('更新用户', result['data']);
|
||||||
|
}}>{username}</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
}, {
|
}, {
|
||||||
title: '用户昵称',
|
title: '用户昵称',
|
||||||
dataIndex: 'nickname',
|
dataIndex: 'nickname',
|
||||||
|
@ -269,6 +269,13 @@ class UserGroup extends Component {
|
|||||||
title: '名称',
|
title: '名称',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
sorter: true,
|
sorter: true,
|
||||||
|
render: (name, record, index) => {
|
||||||
|
return (
|
||||||
|
<Button type="link" size='small'
|
||||||
|
loading={this.state.items[index].updateBtnLoading}
|
||||||
|
onClick={() => this.showModal('更新用户组', record['id'], index)}>{name}</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
}, {
|
}, {
|
||||||
title: '授权资产',
|
title: '授权资产',
|
||||||
dataIndex: 'assetCount',
|
dataIndex: 'assetCount',
|
||||||
|
Loading…
Reference in New Issue
Block a user