Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 95ff68ebec | |||
| e2a1bcef98 | |||
| ab7451d7c2 |
@@ -294,6 +294,7 @@ func (s *Store) ListSSHAccessProfiles() ([]models.SSHAccessProfile, error) {
|
|||||||
var item models.SSHAccessProfile
|
var item models.SSHAccessProfile
|
||||||
var grantIDsJSON string
|
var grantIDsJSON string
|
||||||
var serverTagsJSON string
|
var serverTagsJSON string
|
||||||
|
var groupTagsJSON string
|
||||||
|
|
||||||
rows, err = s.Query(`SELECT
|
rows, err = s.Query(`SELECT
|
||||||
p.public_id,
|
p.public_id,
|
||||||
@@ -308,6 +309,7 @@ func (s *Store) ListSSHAccessProfiles() ([]models.SSHAccessProfile, error) {
|
|||||||
COALESCE(g.created_by_subject_name, ''),
|
COALESCE(g.created_by_subject_name, ''),
|
||||||
COALESCE(g.created_at, 0),
|
COALESCE(g.created_at, 0),
|
||||||
COALESCE(g.updated_at, 0),
|
COALESCE(g.updated_at, 0),
|
||||||
|
COALESCE(g.tags_json, '[]'),
|
||||||
p.name,
|
p.name,
|
||||||
p.description,
|
p.description,
|
||||||
p.remote_username,
|
p.remote_username,
|
||||||
@@ -374,6 +376,7 @@ func (s *Store) ListSSHAccessProfiles() ([]models.SSHAccessProfile, error) {
|
|||||||
&item.ServerGroup.CreatedBySubjectName,
|
&item.ServerGroup.CreatedBySubjectName,
|
||||||
&item.ServerGroup.CreatedAt,
|
&item.ServerGroup.CreatedAt,
|
||||||
&item.ServerGroup.UpdatedAt,
|
&item.ServerGroup.UpdatedAt,
|
||||||
|
&groupTagsJSON,
|
||||||
&item.Name,
|
&item.Name,
|
||||||
&item.Description,
|
&item.Description,
|
||||||
&item.RemoteUsername,
|
&item.RemoteUsername,
|
||||||
@@ -425,6 +428,8 @@ func (s *Store) ListSSHAccessProfiles() ([]models.SSHAccessProfile, error) {
|
|||||||
|
|
||||||
item.Server.Tags, err = decodeStringList(serverTagsJSON)
|
item.Server.Tags, err = decodeStringList(serverTagsJSON)
|
||||||
if err != nil { return nil, err }
|
if err != nil { return nil, err }
|
||||||
|
item.ServerGroup.Tags, err = decodeStringList(groupTagsJSON)
|
||||||
|
if err != nil { return nil, err }
|
||||||
|
|
||||||
item.Targets, err = s.listSSHAccessProfileTargets(item.ID)
|
item.Targets, err = s.listSSHAccessProfileTargets(item.ID)
|
||||||
if err != nil { return nil, err }
|
if err != nil { return nil, err }
|
||||||
@@ -442,6 +447,7 @@ func (s *Store) GetSSHAccessProfile(id string) (models.SSHAccessProfile, error)
|
|||||||
var err error
|
var err error
|
||||||
var grantIDsJSON string
|
var grantIDsJSON string
|
||||||
var serverTagsJSON string
|
var serverTagsJSON string
|
||||||
|
var groupTagsJSON string
|
||||||
|
|
||||||
row = s.QueryRow(`SELECT
|
row = s.QueryRow(`SELECT
|
||||||
p.public_id,
|
p.public_id,
|
||||||
@@ -456,6 +462,7 @@ func (s *Store) GetSSHAccessProfile(id string) (models.SSHAccessProfile, error)
|
|||||||
COALESCE(g.created_by_subject_name, ''),
|
COALESCE(g.created_by_subject_name, ''),
|
||||||
COALESCE(g.created_at, 0),
|
COALESCE(g.created_at, 0),
|
||||||
COALESCE(g.updated_at, 0),
|
COALESCE(g.updated_at, 0),
|
||||||
|
COALESCE(g.tags_json, '[]'),
|
||||||
p.name,
|
p.name,
|
||||||
p.description,
|
p.description,
|
||||||
p.remote_username,
|
p.remote_username,
|
||||||
@@ -518,6 +525,7 @@ func (s *Store) GetSSHAccessProfile(id string) (models.SSHAccessProfile, error)
|
|||||||
&item.ServerGroup.CreatedBySubjectName,
|
&item.ServerGroup.CreatedBySubjectName,
|
||||||
&item.ServerGroup.CreatedAt,
|
&item.ServerGroup.CreatedAt,
|
||||||
&item.ServerGroup.UpdatedAt,
|
&item.ServerGroup.UpdatedAt,
|
||||||
|
&groupTagsJSON,
|
||||||
&item.Name,
|
&item.Name,
|
||||||
&item.Description,
|
&item.Description,
|
||||||
&item.RemoteUsername,
|
&item.RemoteUsername,
|
||||||
@@ -573,6 +581,10 @@ func (s *Store) GetSSHAccessProfile(id string) (models.SSHAccessProfile, error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return item, err
|
return item, err
|
||||||
}
|
}
|
||||||
|
item.ServerGroup.Tags, err = decodeStringList(groupTagsJSON)
|
||||||
|
if err != nil {
|
||||||
|
return item, err
|
||||||
|
}
|
||||||
item.Targets, err = s.listSSHAccessProfileTargets(item.ID)
|
item.Targets, err = s.listSSHAccessProfileTargets(item.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return item, err
|
return item, err
|
||||||
@@ -920,6 +932,7 @@ func (s *Store) ListSSHAccessProfilesForUser(userID string) ([]models.SSHAccessP
|
|||||||
var item models.SSHAccessProfile
|
var item models.SSHAccessProfile
|
||||||
var grantIDsJSON string
|
var grantIDsJSON string
|
||||||
var serverTagsJSON string
|
var serverTagsJSON string
|
||||||
|
var groupTagsJSON string
|
||||||
var trimmedUserID string
|
var trimmedUserID string
|
||||||
|
|
||||||
trimmedUserID = strings.TrimSpace(userID)
|
trimmedUserID = strings.TrimSpace(userID)
|
||||||
@@ -936,6 +949,7 @@ func (s *Store) ListSSHAccessProfilesForUser(userID string) ([]models.SSHAccessP
|
|||||||
COALESCE(g.created_by_subject_name, ''),
|
COALESCE(g.created_by_subject_name, ''),
|
||||||
COALESCE(g.created_at, 0),
|
COALESCE(g.created_at, 0),
|
||||||
COALESCE(g.updated_at, 0),
|
COALESCE(g.updated_at, 0),
|
||||||
|
COALESCE(g.tags_json, '[]'),
|
||||||
p.name,
|
p.name,
|
||||||
p.description,
|
p.description,
|
||||||
p.remote_username,
|
p.remote_username,
|
||||||
@@ -1025,6 +1039,7 @@ func (s *Store) ListSSHAccessProfilesForUser(userID string) ([]models.SSHAccessP
|
|||||||
&item.ServerGroup.CreatedBySubjectName,
|
&item.ServerGroup.CreatedBySubjectName,
|
||||||
&item.ServerGroup.CreatedAt,
|
&item.ServerGroup.CreatedAt,
|
||||||
&item.ServerGroup.UpdatedAt,
|
&item.ServerGroup.UpdatedAt,
|
||||||
|
&groupTagsJSON,
|
||||||
&item.Name,
|
&item.Name,
|
||||||
&item.Description,
|
&item.Description,
|
||||||
&item.RemoteUsername,
|
&item.RemoteUsername,
|
||||||
@@ -1076,6 +1091,8 @@ func (s *Store) ListSSHAccessProfilesForUser(userID string) ([]models.SSHAccessP
|
|||||||
|
|
||||||
item.Server.Tags, err = decodeStringList(serverTagsJSON)
|
item.Server.Tags, err = decodeStringList(serverTagsJSON)
|
||||||
if err != nil { return nil, err }
|
if err != nil { return nil, err }
|
||||||
|
item.ServerGroup.Tags, err = decodeStringList(groupTagsJSON)
|
||||||
|
if err != nil { return nil, err }
|
||||||
|
|
||||||
item.Targets, err = s.listSSHAccessProfileTargets(item.ID)
|
item.Targets, err = s.listSSHAccessProfileTargets(item.ID)
|
||||||
if err != nil { return nil, err }
|
if err != nil { return nil, err }
|
||||||
@@ -1094,6 +1111,7 @@ func (s *Store) GetSSHAccessProfileForUser(userID string, id string) (models.SSH
|
|||||||
var item models.SSHAccessProfile
|
var item models.SSHAccessProfile
|
||||||
var grantIDsJSON string
|
var grantIDsJSON string
|
||||||
var serverTagsJSON string
|
var serverTagsJSON string
|
||||||
|
var groupTagsJSON string
|
||||||
var trimmedUserID string
|
var trimmedUserID string
|
||||||
var trimmedID string
|
var trimmedID string
|
||||||
var err error
|
var err error
|
||||||
@@ -1116,6 +1134,7 @@ func (s *Store) GetSSHAccessProfileForUser(userID string, id string) (models.SSH
|
|||||||
COALESCE(g.created_by_subject_name, ''),
|
COALESCE(g.created_by_subject_name, ''),
|
||||||
COALESCE(g.created_at, 0),
|
COALESCE(g.created_at, 0),
|
||||||
COALESCE(g.updated_at, 0),
|
COALESCE(g.updated_at, 0),
|
||||||
|
COALESCE(g.tags_json, '[]'),
|
||||||
p.name,
|
p.name,
|
||||||
p.description,
|
p.description,
|
||||||
p.remote_username,
|
p.remote_username,
|
||||||
@@ -1200,6 +1219,7 @@ func (s *Store) GetSSHAccessProfileForUser(userID string, id string) (models.SSH
|
|||||||
&item.ServerGroup.CreatedBySubjectName,
|
&item.ServerGroup.CreatedBySubjectName,
|
||||||
&item.ServerGroup.CreatedAt,
|
&item.ServerGroup.CreatedAt,
|
||||||
&item.ServerGroup.UpdatedAt,
|
&item.ServerGroup.UpdatedAt,
|
||||||
|
&groupTagsJSON,
|
||||||
&item.Name,
|
&item.Name,
|
||||||
&item.Description,
|
&item.Description,
|
||||||
&item.RemoteUsername,
|
&item.RemoteUsername,
|
||||||
|
|||||||
@@ -85,6 +85,10 @@ erDiagram
|
|||||||
ssh_access_profiles ||--o{ ssh_sessions : starts
|
ssh_access_profiles ||--o{ ssh_sessions : starts
|
||||||
ssh_servers ||--o{ ssh_sessions : target
|
ssh_servers ||--o{ ssh_sessions : target
|
||||||
users ||--o{ ssh_sessions : opens
|
users ||--o{ ssh_sessions : opens
|
||||||
|
ssh_sessions ||..o{ ssh_file_transfers : source
|
||||||
|
ssh_sessions ||..o{ ssh_file_transfers : target
|
||||||
|
ssh_servers ||..o{ ssh_file_transfers : target_snapshot
|
||||||
|
users ||..o{ ssh_file_transfers : actor
|
||||||
```
|
```
|
||||||
|
|
||||||
### TLS And RPM Mirror State
|
### TLS And RPM Mirror State
|
||||||
@@ -576,6 +580,7 @@ Important fields:
|
|||||||
|
|
||||||
- `name`, `description`
|
- `name`, `description`
|
||||||
- `enabled`
|
- `enabled`
|
||||||
|
- `tags_json`: UI/API tags for filtering and display.
|
||||||
- `created_by_kind`, `created_by_subject_id`, `created_by_subject_name`
|
- `created_by_kind`, `created_by_subject_id`, `created_by_subject_name`
|
||||||
- `created_at`, `updated_at`
|
- `created_at`, `updated_at`
|
||||||
|
|
||||||
@@ -668,6 +673,29 @@ Important fields:
|
|||||||
|
|
||||||
Transcripts are stored on disk under the configured data directory, not in this table.
|
Transcripts are stored on disk under the configured data directory, not in this table.
|
||||||
|
|
||||||
|
### `ssh_file_transfers`
|
||||||
|
|
||||||
|
Stores SSH file transfer audit history.
|
||||||
|
|
||||||
|
Important fields:
|
||||||
|
|
||||||
|
- `session_id`: internal source session reference when available.
|
||||||
|
- `user_id`, `username`: user who initiated the transfer.
|
||||||
|
- `profile_id`, `server_id`, `server_name`: source profile/server context and server-name snapshot.
|
||||||
|
- `remote_username`: remote account used for the source session.
|
||||||
|
- `operation`: `upload`, `download`, or `copy_to_session`.
|
||||||
|
- `source_session_id`, `target_session_id`: source and destination sessions for inter-session copies.
|
||||||
|
- `target_server_id`, `target_server_name`: destination server context and server-name snapshot for inter-session copies.
|
||||||
|
- `target_dir`: destination directory for uploads/copies.
|
||||||
|
- `paths_json`: transferred source path list. Duplicate input paths are de-duplicated before execution.
|
||||||
|
- `bytes_transferred`: total successfully transferred bytes recorded by the backend.
|
||||||
|
- `status`: `running`, `success`, `partial`, `failed`, or `cancelled`.
|
||||||
|
- `error`: transfer error summary.
|
||||||
|
- `started_at`, `finished_at`, `duration_ms`: lifecycle timing.
|
||||||
|
- `remote_addr`, `user_agent`: requester metadata.
|
||||||
|
|
||||||
|
This table is audit/history data. References are nullable and intentionally tolerate deleted sessions, users, profiles, or servers by keeping string snapshots such as `username`, `server_name`, and `target_server_name`.
|
||||||
|
|
||||||
## TLS
|
## TLS
|
||||||
|
|
||||||
### `tls_listeners`
|
### `tls_listeners`
|
||||||
|
|||||||
+354
-2
@@ -4809,6 +4809,59 @@ paths:
|
|||||||
$ref: '#/components/responses/Forbidden'
|
$ref: '#/components/responses/Forbidden'
|
||||||
'404':
|
'404':
|
||||||
$ref: '#/components/responses/NotFound'
|
$ref: '#/components/responses/NotFound'
|
||||||
|
/api/admin/ssh/file-transfers:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Admin SSH
|
||||||
|
summary: List SSH file transfer audit history
|
||||||
|
operationId: ListSSHFileTransfersAdmin
|
||||||
|
x-codit-handler: ListSSHFileTransfersAdmin
|
||||||
|
parameters:
|
||||||
|
- name: limit
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
- name: offset
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
- name: q
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: status
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: session_id
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: user_id
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful response.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/SSHFileTransferListResponse'
|
||||||
|
'400':
|
||||||
|
$ref: '#/components/responses/BadRequest'
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
'403':
|
||||||
|
$ref: '#/components/responses/Forbidden'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
/api/admin/ssh/sessions/{id}/transcript:
|
/api/admin/ssh/sessions/{id}/transcript:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@@ -5685,6 +5738,70 @@ paths:
|
|||||||
$ref: '#/components/responses/Unauthorized'
|
$ref: '#/components/responses/Unauthorized'
|
||||||
'404':
|
'404':
|
||||||
$ref: '#/components/responses/NotFound'
|
$ref: '#/components/responses/NotFound'
|
||||||
|
/api/ssh/access-profiles/{id}/servers/{serverId}:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- SSH Self Service
|
||||||
|
summary: Get one SSH server available through an access profile
|
||||||
|
operationId: GetSSHAccessProfileServerForSelf
|
||||||
|
x-codit-handler: GetSSHAccessProfileServerForSelf
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: serverId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful response.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/SSHServer'
|
||||||
|
'400':
|
||||||
|
$ref: '#/components/responses/BadRequest'
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
/api/ssh/access-profiles/{id}/server-groups/{serverGroupId}/servers:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- SSH Self Service
|
||||||
|
summary: List member servers for a server group available through an access profile
|
||||||
|
operationId: ListSSHAccessProfileServerGroupMembersForSelf
|
||||||
|
x-codit-handler: ListSSHAccessProfileServerGroupMembersForSelf
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: serverGroupId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful response.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/SSHServer'
|
||||||
|
'400':
|
||||||
|
$ref: '#/components/responses/BadRequest'
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
/api/ssh/access-profiles/{id}/connect:
|
/api/ssh/access-profiles/{id}/connect:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
@@ -5783,6 +5900,52 @@ paths:
|
|||||||
$ref: '#/components/responses/Unauthorized'
|
$ref: '#/components/responses/Unauthorized'
|
||||||
'404':
|
'404':
|
||||||
$ref: '#/components/responses/NotFound'
|
$ref: '#/components/responses/NotFound'
|
||||||
|
/api/ssh/file-transfers:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- SSH Self Service
|
||||||
|
summary: List SSH file transfer audit history for the current user
|
||||||
|
operationId: ListSSHFileTransfersForSelf
|
||||||
|
x-codit-handler: ListSSHFileTransfersForSelf
|
||||||
|
parameters:
|
||||||
|
- name: limit
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
- name: offset
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
- name: q
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: status
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: session_id
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful response.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/SSHFileTransferListResponse'
|
||||||
|
'400':
|
||||||
|
$ref: '#/components/responses/BadRequest'
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
/api/ssh/stream:
|
/api/ssh/stream:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@@ -10114,6 +10277,18 @@ components:
|
|||||||
- user
|
- user
|
||||||
owner_user_id:
|
owner_user_id:
|
||||||
type: string
|
type: string
|
||||||
|
created_by_kind:
|
||||||
|
type: string
|
||||||
|
created_by_subject_id:
|
||||||
|
type: string
|
||||||
|
created_by_subject_name:
|
||||||
|
type: string
|
||||||
|
created_at:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
updated_at:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
editable:
|
editable:
|
||||||
type: boolean
|
type: boolean
|
||||||
additionalProperties: true
|
additionalProperties: true
|
||||||
@@ -10155,6 +10330,18 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
enabled:
|
enabled:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
tags:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
server_ids:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
servers:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/SSHServer'
|
||||||
created_by_kind:
|
created_by_kind:
|
||||||
type: string
|
type: string
|
||||||
created_by_subject_id:
|
created_by_subject_id:
|
||||||
@@ -10177,6 +10364,10 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
enabled:
|
enabled:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
tags:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
SSHServerGroupMemberRequest:
|
SSHServerGroupMemberRequest:
|
||||||
type: object
|
type: object
|
||||||
@@ -10262,6 +10453,8 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
server_id:
|
server_id:
|
||||||
type: string
|
type: string
|
||||||
|
server:
|
||||||
|
$ref: '#/components/schemas/SSHServer'
|
||||||
server_target_type:
|
server_target_type:
|
||||||
type: string
|
type: string
|
||||||
enum:
|
enum:
|
||||||
@@ -10269,8 +10462,8 @@ components:
|
|||||||
- group
|
- group
|
||||||
server_group_id:
|
server_group_id:
|
||||||
type: string
|
type: string
|
||||||
server_group_name:
|
server_group:
|
||||||
type: string
|
$ref: '#/components/schemas/SSHServerGroup'
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
description:
|
description:
|
||||||
@@ -10294,12 +10487,24 @@ components:
|
|||||||
enum:
|
enum:
|
||||||
- admin_shared
|
- admin_shared
|
||||||
- user
|
- user
|
||||||
|
owner_user_id:
|
||||||
|
type: string
|
||||||
|
allow_user_edit:
|
||||||
|
type: boolean
|
||||||
ssh_credential_id:
|
ssh_credential_id:
|
||||||
type: string
|
type: string
|
||||||
|
ssh_credential_name:
|
||||||
|
type: string
|
||||||
|
auth_public_key:
|
||||||
|
type: string
|
||||||
auth_public_key_fingerprint:
|
auth_public_key_fingerprint:
|
||||||
type: string
|
type: string
|
||||||
ssh_user_ca_id:
|
ssh_user_ca_id:
|
||||||
type: string
|
type: string
|
||||||
|
ssh_principal_grant_ids:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
default_cert_valid_seconds:
|
default_cert_valid_seconds:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
@@ -10314,9 +10519,45 @@ components:
|
|||||||
format: int64
|
format: int64
|
||||||
enabled:
|
enabled:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
created_by_kind:
|
||||||
|
type: string
|
||||||
|
created_by_subject_id:
|
||||||
|
type: string
|
||||||
|
created_by_subject_name:
|
||||||
|
type: string
|
||||||
|
created_at:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
updated_at:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
targets:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/SSHAccessProfileTarget'
|
||||||
editable:
|
editable:
|
||||||
type: boolean
|
type: boolean
|
||||||
additionalProperties: true
|
additionalProperties: true
|
||||||
|
SSHAccessProfileTarget:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
profile_id:
|
||||||
|
type: string
|
||||||
|
target_type:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- user
|
||||||
|
- group
|
||||||
|
target_id:
|
||||||
|
type: string
|
||||||
|
target_name:
|
||||||
|
type: string
|
||||||
|
target_active:
|
||||||
|
type: boolean
|
||||||
|
created_at:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
additionalProperties: true
|
||||||
SSHSessionFileDownloadRequest:
|
SSHSessionFileDownloadRequest:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@@ -10415,16 +10656,53 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
server_name:
|
server_name:
|
||||||
type: string
|
type: string
|
||||||
|
user_id:
|
||||||
|
type: string
|
||||||
username:
|
username:
|
||||||
type: string
|
type: string
|
||||||
remote_username:
|
remote_username:
|
||||||
type: string
|
type: string
|
||||||
auth_method:
|
auth_method:
|
||||||
type: string
|
type: string
|
||||||
|
enum:
|
||||||
|
- managed_ssh_cert
|
||||||
|
- prompted_password
|
||||||
|
- stored_password
|
||||||
|
- stored_private_key
|
||||||
|
second_factor_mode:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- none
|
||||||
|
- prompted_totp
|
||||||
|
host:
|
||||||
|
type: string
|
||||||
|
port:
|
||||||
|
type: integer
|
||||||
status:
|
status:
|
||||||
type: string
|
type: string
|
||||||
host_key_fingerprint:
|
host_key_fingerprint:
|
||||||
type: string
|
type: string
|
||||||
|
requested_term:
|
||||||
|
type: string
|
||||||
|
requested_cols:
|
||||||
|
type: integer
|
||||||
|
requested_rows:
|
||||||
|
type: integer
|
||||||
|
started_at:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
connected_at:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
ended_at:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
remote_addr:
|
||||||
|
type: string
|
||||||
|
user_agent:
|
||||||
|
type: string
|
||||||
|
error:
|
||||||
|
type: string
|
||||||
transcript_available:
|
transcript_available:
|
||||||
type: boolean
|
type: boolean
|
||||||
additionalProperties: true
|
additionalProperties: true
|
||||||
@@ -10442,3 +10720,77 @@ components:
|
|||||||
has_more:
|
has_more:
|
||||||
type: boolean
|
type: boolean
|
||||||
additionalProperties: true
|
additionalProperties: true
|
||||||
|
SSHFileTransfer:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
session_id:
|
||||||
|
type: string
|
||||||
|
user_id:
|
||||||
|
type: string
|
||||||
|
username:
|
||||||
|
type: string
|
||||||
|
profile_id:
|
||||||
|
type: string
|
||||||
|
server_id:
|
||||||
|
type: string
|
||||||
|
server_name:
|
||||||
|
type: string
|
||||||
|
remote_username:
|
||||||
|
type: string
|
||||||
|
operation:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- upload
|
||||||
|
- download
|
||||||
|
- copy_to_session
|
||||||
|
source_session_id:
|
||||||
|
type: string
|
||||||
|
target_session_id:
|
||||||
|
type: string
|
||||||
|
target_server_id:
|
||||||
|
type: string
|
||||||
|
target_server_name:
|
||||||
|
type: string
|
||||||
|
target_dir:
|
||||||
|
type: string
|
||||||
|
paths:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
bytes_transferred:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
error:
|
||||||
|
type: string
|
||||||
|
started_at:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
finished_at:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
duration_ms:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
remote_addr:
|
||||||
|
type: string
|
||||||
|
user_agent:
|
||||||
|
type: string
|
||||||
|
additionalProperties: true
|
||||||
|
SSHFileTransferListResponse:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
items:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/SSHFileTransfer'
|
||||||
|
limit:
|
||||||
|
type: integer
|
||||||
|
offset:
|
||||||
|
type: integer
|
||||||
|
has_more:
|
||||||
|
type: boolean
|
||||||
|
additionalProperties: true
|
||||||
|
|||||||
@@ -759,7 +759,7 @@ export default function SSHServersPage() {
|
|||||||
{item.name} ({item.id})
|
{item.name} ({item.id})
|
||||||
{item.enabled ? null : (<> <Chip size="small" color="error" label="Disabled" /></>)}
|
{item.enabled ? null : (<> <Chip size="small" color="error" label="Disabled" /></>)}
|
||||||
{(item.tags || []).map((tag: string) => (
|
{(item.tags || []).map((tag: string) => (
|
||||||
<Chip key={tag} label={tag} size="small" variant="outlined" sx={{ ml: 0.5 }} />
|
<Chip key={tag} label={tag} size="small" sx={{ ml: 0.5 }} />
|
||||||
))}
|
))}
|
||||||
</Typography>
|
</Typography>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -193,6 +193,7 @@ function SessionTerminalPanel(props: SessionPanelProps) {
|
|||||||
const [uploadDialogOpen, setUploadDialogOpen] = useState(false)
|
const [uploadDialogOpen, setUploadDialogOpen] = useState(false)
|
||||||
const [downloadDialogOpen, setDownloadDialogOpen] = useState(false)
|
const [downloadDialogOpen, setDownloadDialogOpen] = useState(false)
|
||||||
const [copyDialogOpen, setCopyDialogOpen] = useState(false)
|
const [copyDialogOpen, setCopyDialogOpen] = useState(false)
|
||||||
|
const [terminalFocused, setTerminalFocused] = useState(false)
|
||||||
const terminalHostRef = useRef<HTMLDivElement | null>(null)
|
const terminalHostRef = useRef<HTMLDivElement | null>(null)
|
||||||
const terminalRef = useRef<Terminal | null>(null)
|
const terminalRef = useRef<Terminal | null>(null)
|
||||||
const fitAddonRef = useRef<FitAddon | null>(null)
|
const fitAddonRef = useRef<FitAddon | null>(null)
|
||||||
@@ -341,8 +342,14 @@ function SessionTerminalPanel(props: SessionPanelProps) {
|
|||||||
term.loadAddon(unicodeAddon)
|
term.loadAddon(unicodeAddon)
|
||||||
term.unicode.activeVersion = '11'
|
term.unicode.activeVersion = '11'
|
||||||
term.open(terminalHostRef.current)
|
term.open(terminalHostRef.current)
|
||||||
|
|
||||||
|
// attach the event listeners before calling term.focus()
|
||||||
|
// otherwise, we lost the first focus.
|
||||||
|
term.textarea?.addEventListener('focus', () => { setTerminalFocused(true) })
|
||||||
|
term.textarea?.addEventListener('blur', () => { setTerminalFocused(false) })
|
||||||
fitAddon.fit()
|
fitAddon.fit()
|
||||||
term.focus()
|
term.focus()
|
||||||
|
|
||||||
term.writeln('Connecting...')
|
term.writeln('Connecting...')
|
||||||
terminalRef.current = term
|
terminalRef.current = term
|
||||||
fitAddonRef.current = fitAddon
|
fitAddonRef.current = fitAddon
|
||||||
@@ -420,6 +427,7 @@ function SessionTerminalPanel(props: SessionPanelProps) {
|
|||||||
fitAddonRef.current = null
|
fitAddonRef.current = null
|
||||||
unicodeAddonRef.current = null
|
unicodeAddonRef.current = null
|
||||||
terminalRef.current = null
|
terminalRef.current = null
|
||||||
|
setTerminalFocused(false)
|
||||||
unregisterStream(sessionID)
|
unregisterStream(sessionID)
|
||||||
term?.dispose()
|
term?.dispose()
|
||||||
}
|
}
|
||||||
@@ -628,7 +636,10 @@ function SessionTerminalPanel(props: SessionPanelProps) {
|
|||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
gap: 0.75,
|
gap: 0.75,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
minWidth: 0
|
minWidth: 0,
|
||||||
|
outline: (terminalFocused && openSessionIDs.length > 1) ? (theme) => `3px solid ${theme.palette.primary.main}` : '3px solid transparent',
|
||||||
|
outlineOffset: '-3px',
|
||||||
|
transition: 'outline-color 0.15s ease'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 1, flexWrap: 'wrap', px: 0.25 }}>
|
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 1, flexWrap: 'wrap', px: 0.25 }}>
|
||||||
|
|||||||
Reference in New Issue
Block a user