fixed port mappings
Some checks failed
Build and Push Docker Image / Build image (push) Has been cancelled

This commit is contained in:
ACoolName 2025-04-09 20:26:58 +03:00
parent f8647c50ae
commit 1d6bc8736e
2 changed files with 145 additions and 132 deletions

View File

@ -1,56 +1,62 @@
import { JSONSchema6, JSONSchema7 } from "json-schema"
export interface Port {
Number: number
Protocol: 'tcp' | 'udp'
Number: number
Protocol: 'tcp' | 'udp'
}
export interface PortMapping {
ContainerPort: number
HostPort: number
Protocol: 'tcp' | 'udp'
}
export interface ImageInfo {
Id: string
Name: string
Version: string
Ports: Port[]
Id: string
Name: string
Version: string
Ports: Port[]
}
export interface ServerInfo {
Id: string
Name: string
On: boolean
OwnerId: string
Image: ImageInfo
Ports: Port[] | null
Domain: string
Nickname?: string
Id: string
Name: string
On: boolean
OwnerId: string
Image: ImageInfo
Ports: PortMapping[] | null
Domain: string
Nickname?: string
}
export interface User {
Username: string
Email: string
Permissions: number
Username: string
Email: string
Permissions: number
}
export interface Browser {
Id: string
Domain: string
Url: string
OwnerId: string
ConnectedTo: ServerInfo
Id: string
Domain: string
Url: string
OwnerId: string
ConnectedTo: ServerInfo
}
export interface OpenApiMethodSchema {
summary: string
requestBody: {content: Record<string, {schema: JSONSchema7}>}
api_response: 'Ignore' | 'Browse' | 'Terminal'
permissions: number
summary: string
requestBody: { content: Record<string, { schema: JSONSchema7 }> }
api_response: 'Ignore' | 'Browse' | 'Terminal'
permissions: number
}
export interface OpenAPISchema {
paths: Record<string, {get?: OpenApiMethodSchema, post?: OpenApiMethodSchema, delete?: OpenApiMethodSchema}>
components: {schema: Record<string, JSONSchema7>}
paths: Record<string, { get?: OpenApiMethodSchema, post?: OpenApiMethodSchema, delete?: OpenApiMethodSchema }>
components: { schema: Record<string, JSONSchema7> }
}

View File

@ -1,131 +1,138 @@
import { AxiosInstance } from "axios"
import { ActionGroup, ActionInfo, DataTable, UserInfoContext, actionIdentifierContext, api, apiAuthenticatedContext} from "./common"
import React, { Context, Dispatch, createContext, useContext, useEffect, useState } from "react"
import { ActionGroup, ActionInfo, DataTable, UserInfoContext, actionIdentifierContext, api, apiAuthenticatedContext } from "./common"
import { Context, Dispatch, createContext, useContext, useEffect, useState } from "react"
import { TableRow, TableCell, Chip } from "@mui/material"
import { ImageInfo, ServerInfo } from "./interfaces"
import { JSONSchema7 } from "json-schema"
import { PortMapping, ServerInfo } from "./interfaces"
import { CREATE_SERVER_ACTION, Permission, SERVER_ACTIONS } from "./actions"
import ContentCopyIcon from '@mui/icons-material/ContentCopy'
export async function loadServers(api: AxiosInstance): Promise<{ status: number, data: ServerInfo[] }> {
let response = await api.get('/servers')
return {
status: response.status,
data: response.data
}
let response = await api.get('/servers')
return {
status: response.status,
data: response.data
}
}
const serverActionsContext: Context<ActionInfo[]> = createContext([] as ActionInfo[])
function generateChipHandler(domain: string, port: PortMapping) {
return () => {
navigator.clipboard.writeText(`${domain}:${port.HostPort}`)
}
}
function ServerItem(props: { server_info: ServerInfo }) {
const actions = useContext(serverActionsContext)
const [serverPermissions, setServerPermissions] = useState(null as null|number)
const user = useContext(UserInfoContext)
let permissions = 0
console.log(user)
if (props.server_info.OwnerId === user?.Username){
permissions |= Permission.Admin
}else{
if (serverPermissions === null){
api.get(`/servers/${props.server_info.Id}/permissions`).then((event)=>{setServerPermissions(event.data)})
}else{
permissions |= serverPermissions
}
if (user){
permissions |= user.Permissions
}
const actions = useContext(serverActionsContext)
const [serverPermissions, setServerPermissions] = useState(null as null | number)
const user = useContext(UserInfoContext)
let permissions = 0
console.log(user)
if (props.server_info.OwnerId === user?.Username) {
permissions |= Permission.Admin
} else {
if (serverPermissions === null) {
api.get(`/servers/${props.server_info.Id}/permissions`).then((event) => { setServerPermissions(event.data) })
} else {
permissions |= serverPermissions
}
const name = `${props.server_info.OwnerId}'s ${props.server_info.Image.Name} ${props.server_info.Image.Version} Server`
if (props.server_info.Ports === null) {
props.server_info.Ports = []
if (user) {
permissions |= user.Permissions
}
}
return (
<UserInfoContext.Provider value={user? {Username: user.Username, Email: user.Email, Permissions: permissions}: null}>
<actionIdentifierContext.Provider value={props.server_info.Id}>
<TableRow>
<TableCell>{props.server_info.Nickname}</TableCell>
<TableCell>{props.server_info.OwnerId}</TableCell>
<TableCell>{props.server_info.Image.Name}</TableCell>
<TableCell>{props.server_info.Image.Version}</TableCell>
<TableCell>{props.server_info.Domain}</TableCell>
<TableCell>{props.server_info.Ports.map((port, index, array) => { return <Chip label={`${port.Number}/${port.Protocol}`} /> })}</TableCell>
<TableCell>
<ActionGroup actions={actions.filter((value)=>{
switch (value.ServerState){
case undefined:
return true
case "off":
return !props.server_info.On
case "on":
return props.server_info.On
}})} identifierSubstring="server_id" />
</TableCell>
</TableRow>
</actionIdentifierContext.Provider>
</UserInfoContext.Provider>
)
const name = `${props.server_info.OwnerId}'s ${props.server_info.Image.Name} ${props.server_info.Image.Version} Server`
if (props.server_info.Ports === null) {
props.server_info.Ports = []
}
return (
<UserInfoContext.Provider value={user ? { Username: user.Username, Email: user.Email, Permissions: permissions } : null}>
<actionIdentifierContext.Provider value={props.server_info.Id}>
<TableRow>
<TableCell>{props.server_info.Nickname}</TableCell>
<TableCell>{props.server_info.OwnerId}</TableCell>
<TableCell>{props.server_info.Image.Name}</TableCell>
<TableCell>{props.server_info.Image.Version}</TableCell>
<TableCell>{props.server_info.Domain}</TableCell>
<TableCell>{props.server_info.Ports.map((port, index, array) => { return <Chip onClick={generateChipHandler(props.server_info.Domain, port)} label={`${port.HostPort}:${port.ContainerPort}/${port.Protocol}`} icon={<ContentCopyIcon />} /> })}</TableCell>
<TableCell>
<ActionGroup actions={actions.filter((value) => {
switch (value.ServerState) {
case undefined:
return true
case "off":
return !props.server_info.On
case "on":
return props.server_info.On
}
})} identifierSubstring="server_id" />
</TableCell>
</TableRow>
</actionIdentifierContext.Provider>
</UserInfoContext.Provider>
)
}
export default function ServersBoard() {
const [servers, setServers]: [ServerInfo[], Dispatch<ServerInfo[]>] = useState([] as ServerInfo[]);
servers.sort()
const [apiAuthenticated, setApiAuthenticated] = useContext(apiAuthenticatedContext)
const [servers, setServers]: [ServerInfo[], Dispatch<ServerInfo[]>] = useState([] as ServerInfo[]);
servers.sort()
const [apiAuthenticated, setApiAuthenticated] = useContext(apiAuthenticatedContext)
function handleServers() {
if (!apiAuthenticated) {
return
}
let servers_promised = loadServers(api)
servers_promised.then((response) => {
setServers(response.data)
})
.catch(
(error) => {
console.log('Failed to get servers: ' + error);
if (error.response) {
if (error.response.status === 401) {
setApiAuthenticated(false)
}
else if (error.response.status === 403) {
setApiAuthenticated(false)
}
}
}
)
function handleServers() {
if (!apiAuthenticated) {
return
}
useEffect(() => {
handleServers()
const interval = setInterval(() => {
handleServers()
}, 5000
);
return () => { clearInterval(interval) }
}, [apiAuthenticated])
let servers_promised = loadServers(api)
servers_promised.then((response) => {
setServers(response.data)
})
.catch(
(error) => {
console.log('Failed to get servers: ' + error);
if (error.response) {
if (error.response.status === 401) {
setApiAuthenticated(false)
}
else if (error.response.status === 403) {
setApiAuthenticated(false)
}
}
}
)
}
return (
<DataTable headers={['Nickname', 'Owner', 'Server', 'Version', 'Domain', 'Ports', 'Actions']} actionInfo={CREATE_SERVER_ACTION}>
<serverActionsContext.Provider value={SERVER_ACTIONS}>
{
servers.sort((s1: ServerInfo, s2: ServerInfo) => { return s1.Id < s2.Id ? 0 : 1 }).map(
(value: ServerInfo, index: number, array) => {
return <ServerItem server_info={value} />
}
)
}
</serverActionsContext.Provider>
</DataTable>
useEffect(() => {
handleServers()
const interval = setInterval(() => {
handleServers()
}, 5000
);
return () => { clearInterval(interval) }
}, [apiAuthenticated])
return (
<DataTable headers={['Nickname', 'Owner', 'Server', 'Version', 'Domain', 'Ports', 'Actions']} actionInfo={CREATE_SERVER_ACTION}>
<serverActionsContext.Provider value={SERVER_ACTIONS}>
{
servers.sort((s1: ServerInfo, s2: ServerInfo) => { return s1.Id < s2.Id ? 0 : 1 }).map(
(value: ServerInfo, index: number, array) => {
return <ServerItem server_info={value} />
}
)
}
</serverActionsContext.Provider>
</DataTable>
);
}