Change port start developping
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
from base64 import b64decode
|
from base64 import b64decode
|
||||||
import sqlite3, uvicorn, sys, secrets, re, os, asyncio, httpx, urllib, websockets
|
import sqlite3, uvicorn, sys, secrets, re, os, asyncio, httpx, urllib, websockets
|
||||||
|
from typing import Union
|
||||||
from fastapi import FastAPI, HTTPException, WebSocket, Depends
|
from fastapi import FastAPI, HTTPException, WebSocket, Depends
|
||||||
from pydantic import BaseModel, BaseSettings
|
from pydantic import BaseModel, BaseSettings
|
||||||
from fastapi.responses import FileResponse, StreamingResponse
|
from fastapi.responses import FileResponse, StreamingResponse
|
||||||
@@ -22,7 +23,7 @@ class Settings(BaseSettings):
|
|||||||
JWT_ALGORITHM: str = "HS256"
|
JWT_ALGORITHM: str = "HS256"
|
||||||
REACT_BUILD_DIR: str = "../frontend/build/" if not ON_DOCKER else "frontend/"
|
REACT_BUILD_DIR: str = "../frontend/build/" if not ON_DOCKER else "frontend/"
|
||||||
REACT_HTML_PATH: str = os.path.join(REACT_BUILD_DIR,"index.html")
|
REACT_HTML_PATH: str = os.path.join(REACT_BUILD_DIR,"index.html")
|
||||||
VERSION = "2.0.0"
|
VERSION = "1.3.0"
|
||||||
|
|
||||||
|
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
@@ -36,7 +37,6 @@ def JWT_SECRET(): return conf.get("secret")
|
|||||||
|
|
||||||
@app.on_event("shutdown")
|
@app.on_event("shutdown")
|
||||||
async def shutdown_event():
|
async def shutdown_event():
|
||||||
|
|
||||||
db.disconnect()
|
db.disconnect()
|
||||||
await firewall.close()
|
await firewall.close()
|
||||||
|
|
||||||
@@ -192,6 +192,31 @@ async def get_regen_port(service_id: str, auth: bool = Depends(is_loggined)):
|
|||||||
await firewall.get(service_id).update_port()
|
await firewall.get(service_id).update_port()
|
||||||
return {'status': 'ok'}
|
return {'status': 'ok'}
|
||||||
|
|
||||||
|
class ChangePortForm(BaseModel):
|
||||||
|
port: Union[int, None]
|
||||||
|
internalPort: Union[int, None]
|
||||||
|
|
||||||
|
@app.post('/api/service/{service_id}/change-ports')
|
||||||
|
async def get_regen_port(service_id: str, change_port:ChangePortForm, auth: bool = Depends(is_loggined)):
|
||||||
|
if change_port.port is None and change_port.internalPort is None:
|
||||||
|
return {'status': 'Invalid Request!'}
|
||||||
|
try:
|
||||||
|
sql_inj = ""
|
||||||
|
query = []
|
||||||
|
if not change_port.port is None:
|
||||||
|
sql_inj+=" public_port = ? "
|
||||||
|
query.append(change_port.port)
|
||||||
|
if not change_port.internalPort is None:
|
||||||
|
sql_inj+=" internal_port = ? "
|
||||||
|
query.append(change_port.internalPort)
|
||||||
|
query.append(service_id)
|
||||||
|
db.query(f'UPDATE services SET {sql_inj} WHERE service_id = ?;', *query)
|
||||||
|
except sqlite3.IntegrityError:
|
||||||
|
return {'status': 'Name or/and port of the service has been already assigned to another service'}
|
||||||
|
await firewall.get(service_id).update_port()
|
||||||
|
return {'status': 'ok'}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.get('/api/service/{service_id}/regexes')
|
@app.get('/api/service/{service_id}/regexes')
|
||||||
async def get_service_regexes(service_id: str, auth: bool = Depends(is_loggined)):
|
async def get_service_regexes(service_id: str, auth: bool = Depends(is_loggined)):
|
||||||
@@ -263,17 +288,19 @@ async def post_regexes_add(form: RegexAddForm, auth: bool = Depends(is_loggined)
|
|||||||
class ServiceAddForm(BaseModel):
|
class ServiceAddForm(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
port: int
|
port: int
|
||||||
|
internalPort: Union[int, None]
|
||||||
|
|
||||||
@app.post('/api/services/add')
|
@app.post('/api/services/add')
|
||||||
async def post_services_add(form: ServiceAddForm, auth: bool = Depends(is_loggined)):
|
async def post_services_add(form: ServiceAddForm, auth: bool = Depends(is_loggined)):
|
||||||
serv_id = gen_service_id(db)
|
serv_id = gen_service_id(db)
|
||||||
try:
|
try:
|
||||||
|
internal_port = form.internalPort if form.internalPort else gen_internal_port(db)
|
||||||
db.query("INSERT INTO services (name, service_id, internal_port, public_port, status) VALUES (?, ?, ?, ?, ?)",
|
db.query("INSERT INTO services (name, service_id, internal_port, public_port, status) VALUES (?, ?, ?, ?, ?)",
|
||||||
form.name, serv_id, gen_internal_port(db), form.port, 'stop')
|
form.name, serv_id, internal_port, form.port, 'stop')
|
||||||
await firewall.reload()
|
|
||||||
except sqlite3.IntegrityError:
|
except sqlite3.IntegrityError:
|
||||||
return {'status': 'Name or/and port of the service has been already assigned to another service'}
|
return {'status': 'Name or/and ports of the service has been already assigned to another service'}
|
||||||
|
await firewall.reload()
|
||||||
|
|
||||||
return {'status': 'ok', "id": serv_id }
|
return {'status': 'ok', "id": serv_id }
|
||||||
|
|
||||||
async def frontend_debug_proxy(path):
|
async def frontend_debug_proxy(path):
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class SQLite():
|
|||||||
'services': {
|
'services': {
|
||||||
'status': 'VARCHAR(100) NOT NULL',
|
'status': 'VARCHAR(100) NOT NULL',
|
||||||
'service_id': 'VARCHAR(100) PRIMARY KEY',
|
'service_id': 'VARCHAR(100) PRIMARY KEY',
|
||||||
'internal_port': 'INT NOT NULL CHECK(internal_port > 0 and internal_port < 65536) UNIQUE',
|
'internal_port': 'INT NOT NULL CHECK(internal_port > 0 and internal_port < 65536)',
|
||||||
'public_port': 'INT NOT NULL CHECK(internal_port > 0 and internal_port < 65536) UNIQUE',
|
'public_port': 'INT NOT NULL CHECK(internal_port > 0 and internal_port < 65536) UNIQUE',
|
||||||
'name': 'VARCHAR(100) NOT NULL'
|
'name': 'VARCHAR(100) NOT NULL'
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"files": {
|
"files": {
|
||||||
"main.css": "/static/css/main.c375ae17.css",
|
"main.css": "/static/css/main.c375ae17.css",
|
||||||
"main.js": "/static/js/main.a6ace121.js",
|
"main.js": "/static/js/main.bf062beb.js",
|
||||||
"index.html": "/index.html",
|
"index.html": "/index.html",
|
||||||
"main.c375ae17.css.map": "/static/css/main.c375ae17.css.map",
|
"main.c375ae17.css.map": "/static/css/main.c375ae17.css.map",
|
||||||
"main.a6ace121.js.map": "/static/js/main.a6ace121.js.map"
|
"main.bf062beb.js.map": "/static/js/main.bf062beb.js.map"
|
||||||
},
|
},
|
||||||
"entrypoints": [
|
"entrypoints": [
|
||||||
"static/css/main.c375ae17.css",
|
"static/css/main.c375ae17.css",
|
||||||
"static/js/main.a6ace121.js"
|
"static/js/main.bf062beb.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1 +1 @@
|
|||||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="manifest" href="/site.webmanifest"><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#FFFFFFFF"/><meta name="description" content="Firegex by Pwnzer0tt1"/><title>Firegex</title><script defer="defer" src="/static/js/main.a6ace121.js"></script><link href="/static/css/main.c375ae17.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="manifest" href="/site.webmanifest"><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#FFFFFFFF"/><meta name="description" content="Firegex by Pwnzer0tt1"/><title>Firegex</title><script defer="defer" src="/static/js/main.bf062beb.js"></script><link href="/static/css/main.c375ae17.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,70 +0,0 @@
|
|||||||
/*!
|
|
||||||
* The buffer module from node.js, for the browser.
|
|
||||||
*
|
|
||||||
* @author Feross Aboukhadijeh <https://feross.org>
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
|
||||||
|
|
||||||
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @license React
|
|
||||||
* react-dom.production.min.js
|
|
||||||
*
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @license React
|
|
||||||
* react-jsx-runtime.production.min.js
|
|
||||||
*
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @license React
|
|
||||||
* react.production.min.js
|
|
||||||
*
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @license React
|
|
||||||
* scheduler.production.min.js
|
|
||||||
*
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* React Router v6.3.0
|
|
||||||
*
|
|
||||||
* Copyright (c) Remix Software Inc.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE.md file in the root directory of this source tree.
|
|
||||||
*
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @license React v16.13.1
|
|
||||||
* react-is.production.min.js
|
|
||||||
*
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -7,7 +7,9 @@ import { ImCross } from "react-icons/im"
|
|||||||
type ServiceAddForm = {
|
type ServiceAddForm = {
|
||||||
name:string,
|
name:string,
|
||||||
port:number,
|
port:number,
|
||||||
autostart: boolean
|
autostart: boolean,
|
||||||
|
chosenInternalPort: boolean,
|
||||||
|
internalPort: number
|
||||||
}
|
}
|
||||||
|
|
||||||
function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void }) {
|
function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void }) {
|
||||||
@@ -36,9 +38,9 @@ function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void })
|
|||||||
const [submitLoading, setSubmitLoading] = useState(false)
|
const [submitLoading, setSubmitLoading] = useState(false)
|
||||||
const [error, setError] = useState<string|null>(null)
|
const [error, setError] = useState<string|null>(null)
|
||||||
|
|
||||||
const submitRequest = ({ name, port, autostart }:ServiceAddForm) =>{
|
const submitRequest = ({ name, port, autostart, chosenInternalPort, internalPort }:ServiceAddForm) =>{
|
||||||
setSubmitLoading(true)
|
setSubmitLoading(true)
|
||||||
addservice({ name, port }).then( res => {
|
addservice(chosenInternalPort?{ internalPort, name, port }:{ name, port }).then( res => {
|
||||||
if (res.status === "ok"){
|
if (res.status === "ok"){
|
||||||
setSubmitLoading(false)
|
setSubmitLoading(false)
|
||||||
close();
|
close();
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { deleteservice, errorNotify, fireUpdateRequest, okNotify, pauseservice,
|
|||||||
import { BsArrowRepeat, BsTrashFill } from 'react-icons/bs';
|
import { BsArrowRepeat, BsTrashFill } from 'react-icons/bs';
|
||||||
import { TbNumbers } from 'react-icons/tb';
|
import { TbNumbers } from 'react-icons/tb';
|
||||||
import { BiRename } from 'react-icons/bi'
|
import { BiRename } from 'react-icons/bi'
|
||||||
|
import ChangeInternalPort from './ChangeInternalPort';
|
||||||
|
|
||||||
//"status":"stop"/"wait"/"active"/"pause",
|
//"status":"stop"/"wait"/"active"/"pause",
|
||||||
function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void }) {
|
function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void }) {
|
||||||
@@ -26,6 +27,7 @@ function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void })
|
|||||||
const [tooltipStopOpened, setTooltipStopOpened] = useState(false);
|
const [tooltipStopOpened, setTooltipStopOpened] = useState(false);
|
||||||
const [deleteModal, setDeleteModal] = useState(false)
|
const [deleteModal, setDeleteModal] = useState(false)
|
||||||
const [changePortModal, setChangePortModal] = useState(false)
|
const [changePortModal, setChangePortModal] = useState(false)
|
||||||
|
const [chooseInternalPortModal, setChooseInternalPortModal] = useState(false)
|
||||||
|
|
||||||
const stopService = async () => {
|
const stopService = async () => {
|
||||||
setButtonLoading(true)
|
setButtonLoading(true)
|
||||||
@@ -149,7 +151,7 @@ function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void })
|
|||||||
<Divider />
|
<Divider />
|
||||||
<Menu.Label><b>Internal proxy port</b></Menu.Label>
|
<Menu.Label><b>Internal proxy port</b></Menu.Label>
|
||||||
<Menu.Item icon={<BsArrowRepeat size={18} />} onClick={()=>setChangePortModal(true)}>Regen port</Menu.Item>
|
<Menu.Item icon={<BsArrowRepeat size={18} />} onClick={()=>setChangePortModal(true)}>Regen port</Menu.Item>
|
||||||
<Menu.Item icon={<TbNumbers size={18} />} onClick={()=>{}}>Choose port</Menu.Item>
|
<Menu.Item icon={<TbNumbers size={18} />} onClick={()=>setChooseInternalPortModal(true)}>Choose port</Menu.Item>
|
||||||
<Divider />
|
<Divider />
|
||||||
<Menu.Label><b>Delete service</b></Menu.Label>
|
<Menu.Label><b>Delete service</b></Menu.Label>
|
||||||
<Menu.Item color="red" icon={<BsTrashFill size={18} />} onClick={()=>setDeleteModal(true)}>Delete Service</Menu.Item>
|
<Menu.Item color="red" icon={<BsTrashFill size={18} />} onClick={()=>setDeleteModal(true)}>Delete Service</Menu.Item>
|
||||||
@@ -217,6 +219,7 @@ function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void })
|
|||||||
action={changePort}
|
action={changePort}
|
||||||
opened={changePortModal}
|
opened={changePortModal}
|
||||||
/>
|
/>
|
||||||
|
<ChangeInternalPort service={service} onClose={()=> setChooseInternalPortModal(false)} opened={chooseInternalPortModal} />
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ export type Service = {
|
|||||||
|
|
||||||
export type ServiceAddForm = {
|
export type ServiceAddForm = {
|
||||||
name:string,
|
name:string,
|
||||||
port:number
|
port:number,
|
||||||
|
internalPort?:number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ServerResponse = {
|
export type ServerResponse = {
|
||||||
@@ -27,6 +28,11 @@ export type ServerResponseWithID = {
|
|||||||
id:string
|
id:string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ChangePort = {
|
||||||
|
port?: number,
|
||||||
|
internalPort?: number
|
||||||
|
}
|
||||||
|
|
||||||
export type ServerResponseToken = {
|
export type ServerResponseToken = {
|
||||||
status:string,
|
status:string,
|
||||||
access_token?:string
|
access_token?:string
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { showNotification } from "@mantine/notifications";
|
import { showNotification } from "@mantine/notifications";
|
||||||
import { ImCross } from "react-icons/im";
|
import { ImCross } from "react-icons/im";
|
||||||
import { TiTick } from "react-icons/ti"
|
import { TiTick } from "react-icons/ti"
|
||||||
import { GeneralStats, Service, ServiceAddForm, ServerResponse, RegexFilter, RegexAddForm, ServerStatusResponse, PasswordSend, ChangePassword, LoginResponse, ServerResponseToken, ServerResponseWithID } from "./models";
|
import { GeneralStats, Service, ServiceAddForm, ServerResponse, RegexFilter, RegexAddForm, ServerStatusResponse, PasswordSend, ChangePassword, LoginResponse, ServerResponseToken, ServerResponseWithID, ChangePort } from "./models";
|
||||||
|
|
||||||
var Buffer = require('buffer').Buffer
|
var Buffer = require('buffer').Buffer
|
||||||
|
|
||||||
@@ -128,6 +128,11 @@ export async function regenport(service_id:string){
|
|||||||
return status === "ok"?undefined:status
|
return status === "ok"?undefined:status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function changeports(service_id:string, data:ChangePort){
|
||||||
|
const { status } = await postapi(`service/${service_id}/change-ports`,data) as ServerResponse;
|
||||||
|
return status === "ok"?undefined:status
|
||||||
|
}
|
||||||
|
|
||||||
export async function addservice(data:ServiceAddForm) {
|
export async function addservice(data:ServiceAddForm) {
|
||||||
return await postapi("services/add",data) as ServerResponseWithID;
|
return await postapi("services/add",data) as ServerResponseWithID;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user