Fix localhost connection issues

This commit is contained in:
LukeGus
2025-08-21 22:47:38 -05:00
parent 5f1a2d9a17
commit 7957ed06e4
2 changed files with 265 additions and 137 deletions

View File

@@ -1,10 +1,21 @@
import React, {useState, useEffect} from "react"; import React, {useState, useEffect} from "react";
import {cn} from "@/lib/utils.ts"; import {cn} from "../../lib/utils.ts";
import {Button} from "@/components/ui/button.tsx"; import {Button} from "../../components/ui/button.tsx";
import {Input} from "@/components/ui/input.tsx"; import {Input} from "../../components/ui/input.tsx";
import {Label} from "@/components/ui/label.tsx"; import {Label} from "../../components/ui/label.tsx";
import {Alert, AlertTitle, AlertDescription} from "@/components/ui/alert.tsx"; import {Alert, AlertTitle, AlertDescription} from "../../components/ui/alert.tsx";
import axios from "axios"; import {
registerUser,
loginUser,
getUserInfo,
getRegistrationAllowed,
getOIDCConfig,
getUserCount,
initiatePasswordReset,
verifyPasswordResetCode,
completePasswordReset,
getOIDCAuthorizeUrl
} from "../main-axios.ts";
function setCookie(name: string, value: string, days = 7) { function setCookie(name: string, value: string, days = 7) {
const expires = new Date(Date.now() + days * 864e5).toUTCString(); const expires = new Date(Date.now() + days * 864e5).toUTCString();
@@ -18,11 +29,7 @@ function getCookie(name: string) {
}, ""); }, "");
} }
const apiBase = import.meta.env.DEV ? "http://localhost:8081/users" : "/users";
const API = axios.create({
baseURL: apiBase,
});
interface HomepageAuthProps extends React.ComponentProps<"div"> { interface HomepageAuthProps extends React.ComponentProps<"div"> {
setLoggedIn: (loggedIn: boolean) => void; setLoggedIn: (loggedIn: boolean) => void;
@@ -74,14 +81,14 @@ export function HomepageAuth({
}, [loggedIn]); }, [loggedIn]);
useEffect(() => { useEffect(() => {
API.get("/registration-allowed").then(res => { getRegistrationAllowed().then(res => {
setRegistrationAllowed(res.data.allowed); setRegistrationAllowed(res.allowed);
}); });
}, []); }, []);
useEffect(() => { useEffect(() => {
API.get("/oidc-config").then((response) => { getOIDCConfig().then((response) => {
if (response.data) { if (response) {
setOidcConfigured(true); setOidcConfigured(true);
} else { } else {
setOidcConfigured(false); setOidcConfigured(false);
@@ -96,8 +103,8 @@ export function HomepageAuth({
}, []); }, []);
useEffect(() => { useEffect(() => {
API.get("/count").then(res => { getUserCount().then(res => {
if (res.data.count === 0) { if (res.count === 0) {
setFirstUser(true); setFirstUser(true);
setTab("signup"); setTab("signup");
} else { } else {
@@ -123,7 +130,7 @@ export function HomepageAuth({
try { try {
let res, meRes; let res, meRes;
if (tab === "login") { if (tab === "login") {
res = await API.post("/login", {username: localUsername, password}); res = await loginUser(localUsername, password);
} else { } else {
if (password !== signupConfirmPassword) { if (password !== signupConfirmPassword) {
setError("Passwords do not match"); setError("Passwords do not match");
@@ -135,31 +142,37 @@ export function HomepageAuth({
setLoading(false); setLoading(false);
return; return;
} }
await API.post("/create", {username: localUsername, password});
res = await API.post("/login", {username: localUsername, password}); await registerUser(localUsername, password);
res = await loginUser(localUsername, password);
} }
setCookie("jwt", res.data.token);
if (!res || !res.token) {
throw new Error('No token received from login');
}
setCookie("jwt", res.token);
[meRes] = await Promise.all([ [meRes] = await Promise.all([
API.get("/me", {headers: {Authorization: `Bearer ${res.data.token}`}}), getUserInfo(),
API.get("/db-health")
]); ]);
setInternalLoggedIn(true); setInternalLoggedIn(true);
setLoggedIn(true); setLoggedIn(true);
setIsAdmin(!!meRes.data.is_admin); setIsAdmin(!!meRes.is_admin);
setUsername(meRes.data.username || null); setUsername(meRes.username || null);
setUserId(meRes.data.id || null); setUserId(meRes.userId || null);
setDbError(null); setDbError(null);
onAuthSuccess({ onAuthSuccess({
isAdmin: !!meRes.data.is_admin, isAdmin: !!meRes.is_admin,
username: meRes.data.username || null, username: meRes.username || null,
userId: meRes.data.id || null userId: meRes.userId || null
}); });
setInternalLoggedIn(true); setInternalLoggedIn(true);
if (tab === "signup") { if (tab === "signup") {
setSignupConfirmPassword(""); setSignupConfirmPassword("");
} }
} catch (err: any) { } catch (err: any) {
setError(err?.response?.data?.error || "Unknown error"); setError(err?.response?.data?.error || err?.message || "Unknown error");
setInternalLoggedIn(false); setInternalLoggedIn(false);
setLoggedIn(false); setLoggedIn(false);
setIsAdmin(false); setIsAdmin(false);
@@ -176,29 +189,26 @@ export function HomepageAuth({
} }
} }
async function initiatePasswordReset() { async function handleInitiatePasswordReset() {
setError(null); setError(null);
setResetLoading(true); setResetLoading(true);
try { try {
await API.post("/initiate-reset", {username: localUsername}); const result = await initiatePasswordReset(localUsername);
setResetStep("verify"); setResetStep("verify");
setError(null); setError(null);
} catch (err: any) { } catch (err: any) {
setError(err?.response?.data?.error || "Failed to initiate password reset"); setError(err?.response?.data?.error || err?.message || "Failed to initiate password reset");
} finally { } finally {
setResetLoading(false); setResetLoading(false);
} }
} }
async function verifyResetCode() { async function handleVerifyResetCode() {
setError(null); setError(null);
setResetLoading(true); setResetLoading(true);
try { try {
const response = await API.post("/verify-reset-code", { const response = await verifyPasswordResetCode(localUsername, resetCode);
username: localUsername, setTempToken(response.tempToken);
resetCode: resetCode
});
setTempToken(response.data.tempToken);
setResetStep("newPassword"); setResetStep("newPassword");
setError(null); setError(null);
} catch (err: any) { } catch (err: any) {
@@ -208,7 +218,7 @@ export function HomepageAuth({
} }
} }
async function completePasswordReset() { async function handleCompletePasswordReset() {
setError(null); setError(null);
setResetLoading(true); setResetLoading(true);
@@ -225,11 +235,7 @@ export function HomepageAuth({
} }
try { try {
await API.post("/complete-reset", { await completePasswordReset(localUsername, tempToken, newPassword);
username: localUsername,
tempToken: tempToken,
newPassword: newPassword
});
setResetStep("initiate"); setResetStep("initiate");
setResetCode(""); setResetCode("");
@@ -267,8 +273,8 @@ export function HomepageAuth({
setError(null); setError(null);
setOidcLoading(true); setOidcLoading(true);
try { try {
const authResponse = await API.get("/oidc/authorize"); const authResponse = await getOIDCAuthorizeUrl();
const {auth_url: authUrl} = authResponse.data; const {auth_url: authUrl} = authResponse;
if (!authUrl || authUrl === 'undefined') { if (!authUrl || authUrl === 'undefined') {
throw new Error('Invalid authorization URL received from backend'); throw new Error('Invalid authorization URL received from backend');
@@ -299,18 +305,18 @@ export function HomepageAuth({
setError(null); setError(null);
setCookie("jwt", token); setCookie("jwt", token);
API.get("/me", {headers: {Authorization: `Bearer ${token}`}}) getUserInfo()
.then(meRes => { .then(meRes => {
setInternalLoggedIn(true); setInternalLoggedIn(true);
setLoggedIn(true); setLoggedIn(true);
setIsAdmin(!!meRes.data.is_admin); setIsAdmin(!!meRes.is_admin);
setUsername(meRes.data.username || null); setUsername(meRes.username || null);
setUserId(meRes.data.id || null); setUserId(meRes.id || null);
setDbError(null); setDbError(null);
onAuthSuccess({ onAuthSuccess({
isAdmin: !!meRes.data.is_admin, isAdmin: !!meRes.is_admin,
username: meRes.data.username || null, username: meRes.username || null,
userId: meRes.data.id || null userId: meRes.id || null
}); });
setInternalLoggedIn(true); setInternalLoggedIn(true);
window.history.replaceState({}, document.title, window.location.pathname); window.history.replaceState({}, document.title, window.location.pathname);
@@ -486,7 +492,7 @@ export function HomepageAuth({
type="button" type="button"
className="w-full h-11 text-base font-semibold" className="w-full h-11 text-base font-semibold"
disabled={resetLoading || !localUsername.trim()} disabled={resetLoading || !localUsername.trim()}
onClick={initiatePasswordReset} onClick={handleInitiatePasswordReset}
> >
{resetLoading ? Spinner : "Send Reset Code"} {resetLoading ? Spinner : "Send Reset Code"}
</Button> </Button>
@@ -519,7 +525,7 @@ export function HomepageAuth({
type="button" type="button"
className="w-full h-11 text-base font-semibold" className="w-full h-11 text-base font-semibold"
disabled={resetLoading || resetCode.length !== 6} disabled={resetLoading || resetCode.length !== 6}
onClick={verifyResetCode} onClick={handleVerifyResetCode}
> >
{resetLoading ? Spinner : "Verify Code"} {resetLoading ? Spinner : "Verify Code"}
</Button> </Button>
@@ -598,7 +604,7 @@ export function HomepageAuth({
type="button" type="button"
className="w-full h-11 text-base font-semibold" className="w-full h-11 text-base font-semibold"
disabled={resetLoading || !newPassword || !confirmPassword} disabled={resetLoading || !newPassword || !confirmPassword}
onClick={completePasswordReset} onClick={handleCompletePasswordReset}
> >
{resetLoading ? Spinner : "Reset Password"} {resetLoading ? Spinner : "Reset Password"}
</Button> </Button>

View File

@@ -105,35 +105,51 @@ export type ServerMetrics = {
lastChecked: string; lastChecked: string;
}; };
const isLocalhost = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'; interface AuthResponse {
token: string;
}
const sshHostApi = axios.create({ interface UserInfo {
baseURL: isLocalhost ? 'http://localhost:8081' : '', id: string;
headers: { username: string;
'Content-Type': 'application/json', is_admin: boolean;
}, }
});
const tunnelApi = axios.create({ interface RegistrationResponse {
baseURL: isLocalhost ? 'http://localhost:8083' : '', allowed: boolean;
headers: { }
'Content-Type': 'application/json',
},
});
const fileManagerApi = axios.create({ interface OIDCConfig {
baseURL: isLocalhost ? 'http://localhost:8084' : '', configured: boolean;
headers: { }
'Content-Type': 'application/json',
}
})
const statsApi = axios.create({ interface UserCount {
baseURL: isLocalhost ? 'http://localhost:8085' : '', count: number;
headers: { }
'Content-Type': 'application/json',
} interface PasswordResetInitiate {
}) username: string;
}
interface PasswordResetVerify {
username: string;
resetCode: string;
}
interface PasswordResetComplete {
username: string;
tempToken: string;
newPassword: string;
}
interface OIDCAuthorize {
auth_url: string;
}
function setCookie(name: string, value: string, days = 7) {
const expires = new Date(Date.now() + days * 864e5).toUTCString();
document.cookie = `${name}=${encodeURIComponent(value)}; expires=${expires}; path=/`;
}
function getCookie(name: string): string | undefined { function getCookie(name: string): string | undefined {
const value = `; ${document.cookie}`; const value = `; ${document.cookie}`;
@@ -141,41 +157,54 @@ function getCookie(name: string): string | undefined {
if (parts.length === 2) return parts.pop()?.split(';').shift(); if (parts.length === 2) return parts.pop()?.split(';').shift();
} }
sshHostApi.interceptors.request.use((config) => { const sshHostApi = axios.create({
const token = getCookie('jwt'); baseURL: import.meta.env.DEV ? 'http://localhost:8081/ssh' : '/ssh',
if (token) { headers: {
config.headers.Authorization = `Bearer ${token}`; 'Content-Type': 'application/json',
} },
return config;
}); });
statsApi.interceptors.request.use((config) => { const tunnelApi = axios.create({
const token = getCookie('jwt'); baseURL: import.meta.env.DEV ? 'http://localhost:8083/ssh' : '/ssh',
if (token) { headers: {
config.headers.Authorization = `Bearer ${token}`; 'Content-Type': 'application/json',
} },
return config;
}); });
tunnelApi.interceptors.request.use((config) => { const fileManagerApi = axios.create({
const token = getCookie('jwt'); baseURL: import.meta.env.DEV ? 'http://localhost:8084/ssh' : '/ssh',
if (token) { headers: {
config.headers.Authorization = `Bearer ${token}`; 'Content-Type': 'application/json',
} }
return config;
}); });
fileManagerApi.interceptors.request.use((config) => { const statsApi = axios.create({
const token = getCookie('jwt'); baseURL: import.meta.env.DEV ? 'http://localhost:8085' : '',
if (token) { headers: {
config.headers.Authorization = `Bearer ${token}`; 'Content-Type': 'application/json',
} }
return config; });
const authApi = axios.create({
baseURL: import.meta.env.DEV ? 'http://localhost:8081/users' : '/users',
headers: {
'Content-Type': 'application/json',
}
});
[sshHostApi, tunnelApi, fileManagerApi, statsApi, authApi].forEach(api => {
api.interceptors.request.use((config) => {
const token = getCookie('jwt');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
}); });
export async function getSSHHosts(): Promise<SSHHost[]> { export async function getSSHHosts(): Promise<SSHHost[]> {
try { try {
const response = await sshHostApi.get('/ssh/db/host'); const response = await sshHostApi.get('/db/host');
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@@ -220,7 +249,7 @@ export async function createSSHHost(hostData: SSHHostData): Promise<SSHHost> {
delete dataWithoutFile.key; delete dataWithoutFile.key;
formData.append('data', JSON.stringify(dataWithoutFile)); formData.append('data', JSON.stringify(dataWithoutFile));
const response = await sshHostApi.post('/ssh/db/host', formData, { const response = await sshHostApi.post('/db/host', formData, {
headers: { headers: {
'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data',
}, },
@@ -228,7 +257,7 @@ export async function createSSHHost(hostData: SSHHostData): Promise<SSHHost> {
return response.data; return response.data;
} else { } else {
const response = await sshHostApi.post('/ssh/db/host', submitData); const response = await sshHostApi.post('/db/host', submitData);
return response.data; return response.data;
} }
} catch (error) { } catch (error) {
@@ -273,7 +302,7 @@ export async function updateSSHHost(hostId: number, hostData: SSHHostData): Prom
delete dataWithoutFile.key; delete dataWithoutFile.key;
formData.append('data', JSON.stringify(dataWithoutFile)); formData.append('data', JSON.stringify(dataWithoutFile));
const response = await sshHostApi.put(`/ssh/db/host/${hostId}`, formData, { const response = await sshHostApi.put(`/db/host/${hostId}`, formData, {
headers: { headers: {
'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data',
}, },
@@ -281,7 +310,7 @@ export async function updateSSHHost(hostId: number, hostData: SSHHostData): Prom
return response.data; return response.data;
} else { } else {
const response = await sshHostApi.put(`/ssh/db/host/${hostId}`, submitData); const response = await sshHostApi.put(`/db/host/${hostId}`, submitData);
return response.data; return response.data;
} }
} catch (error) { } catch (error) {
@@ -296,7 +325,7 @@ export async function bulkImportSSHHosts(hosts: SSHHostData[]): Promise<{
errors: string[]; errors: string[];
}> { }> {
try { try {
const response = await sshHostApi.post('/ssh/bulk-import', {hosts}); const response = await sshHostApi.post('/bulk-import', {hosts});
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@@ -305,7 +334,7 @@ export async function bulkImportSSHHosts(hosts: SSHHostData[]): Promise<{
export async function deleteSSHHost(hostId: number): Promise<any> { export async function deleteSSHHost(hostId: number): Promise<any> {
try { try {
const response = await sshHostApi.delete(`/ssh/db/host/${hostId}`); const response = await sshHostApi.delete(`/db/host/${hostId}`);
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@@ -314,7 +343,7 @@ export async function deleteSSHHost(hostId: number): Promise<any> {
export async function getSSHHostById(hostId: number): Promise<SSHHost> { export async function getSSHHostById(hostId: number): Promise<SSHHost> {
try { try {
const response = await sshHostApi.get(`/ssh/db/host/${hostId}`); const response = await sshHostApi.get(`/db/host/${hostId}`);
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@@ -323,7 +352,7 @@ export async function getSSHHostById(hostId: number): Promise<SSHHost> {
export async function getTunnelStatuses(): Promise<Record<string, TunnelStatus>> { export async function getTunnelStatuses(): Promise<Record<string, TunnelStatus>> {
try { try {
const response = await tunnelApi.get('/ssh/tunnel/status'); const response = await tunnelApi.get('/tunnel/status');
return response.data || {}; return response.data || {};
} catch (error) { } catch (error) {
throw error; throw error;
@@ -337,7 +366,7 @@ export async function getTunnelStatusByName(tunnelName: string): Promise<TunnelS
export async function connectTunnel(tunnelConfig: TunnelConfig): Promise<any> { export async function connectTunnel(tunnelConfig: TunnelConfig): Promise<any> {
try { try {
const response = await tunnelApi.post('/ssh/tunnel/connect', tunnelConfig); const response = await tunnelApi.post('/tunnel/connect', tunnelConfig);
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@@ -346,7 +375,7 @@ export async function connectTunnel(tunnelConfig: TunnelConfig): Promise<any> {
export async function disconnectTunnel(tunnelName: string): Promise<any> { export async function disconnectTunnel(tunnelName: string): Promise<any> {
try { try {
const response = await tunnelApi.post('/ssh/tunnel/disconnect', {tunnelName}); const response = await tunnelApi.post('/tunnel/disconnect', {tunnelName});
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@@ -355,7 +384,7 @@ export async function disconnectTunnel(tunnelName: string): Promise<any> {
export async function cancelTunnel(tunnelName: string): Promise<any> { export async function cancelTunnel(tunnelName: string): Promise<any> {
try { try {
const response = await tunnelApi.post('/ssh/tunnel/cancel', {tunnelName}); const response = await tunnelApi.post('/tunnel/cancel', {tunnelName});
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@@ -364,7 +393,7 @@ export async function cancelTunnel(tunnelName: string): Promise<any> {
export async function getFileManagerRecent(hostId: number): Promise<FileManagerFile[]> { export async function getFileManagerRecent(hostId: number): Promise<FileManagerFile[]> {
try { try {
const response = await sshHostApi.get(`/ssh/file_manager/recent?hostId=${hostId}`); const response = await sshHostApi.get(`/file_manager/recent?hostId=${hostId}`);
return response.data || []; return response.data || [];
} catch (error) { } catch (error) {
return []; return [];
@@ -379,7 +408,7 @@ export async function addFileManagerRecent(file: {
hostId: number hostId: number
}): Promise<any> { }): Promise<any> {
try { try {
const response = await sshHostApi.post('/ssh/file_manager/recent', file); const response = await sshHostApi.post('/file_manager/recent', file);
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@@ -394,7 +423,7 @@ export async function removeFileManagerRecent(file: {
hostId: number hostId: number
}): Promise<any> { }): Promise<any> {
try { try {
const response = await sshHostApi.delete('/ssh/file_manager/recent', {data: file}); const response = await sshHostApi.delete('/file_manager/recent', {data: file});
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@@ -403,7 +432,7 @@ export async function removeFileManagerRecent(file: {
export async function getFileManagerPinned(hostId: number): Promise<FileManagerFile[]> { export async function getFileManagerPinned(hostId: number): Promise<FileManagerFile[]> {
try { try {
const response = await sshHostApi.get(`/ssh/file_manager/pinned?hostId=${hostId}`); const response = await sshHostApi.get(`/file_manager/pinned?hostId=${hostId}`);
return response.data || []; return response.data || [];
} catch (error) { } catch (error) {
return []; return [];
@@ -418,7 +447,7 @@ export async function addFileManagerPinned(file: {
hostId: number hostId: number
}): Promise<any> { }): Promise<any> {
try { try {
const response = await sshHostApi.post('/ssh/file_manager/pinned', file); const response = await sshHostApi.post('/file_manager/pinned', file);
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@@ -433,7 +462,7 @@ export async function removeFileManagerPinned(file: {
hostId: number hostId: number
}): Promise<any> { }): Promise<any> {
try { try {
const response = await sshHostApi.delete('/ssh/file_manager/pinned', {data: file}); const response = await sshHostApi.delete('/file_manager/pinned', {data: file});
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@@ -442,7 +471,7 @@ export async function removeFileManagerPinned(file: {
export async function getFileManagerShortcuts(hostId: number): Promise<FileManagerShortcut[]> { export async function getFileManagerShortcuts(hostId: number): Promise<FileManagerShortcut[]> {
try { try {
const response = await sshHostApi.get(`/ssh/file_manager/shortcuts?hostId=${hostId}`); const response = await sshHostApi.get(`/file_manager/shortcuts?hostId=${hostId}`);
return response.data || []; return response.data || [];
} catch (error) { } catch (error) {
return []; return [];
@@ -457,7 +486,7 @@ export async function addFileManagerShortcut(shortcut: {
hostId: number hostId: number
}): Promise<any> { }): Promise<any> {
try { try {
const response = await sshHostApi.post('/ssh/file_manager/shortcuts', shortcut); const response = await sshHostApi.post('/file_manager/shortcuts', shortcut);
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@@ -472,7 +501,7 @@ export async function removeFileManagerShortcut(shortcut: {
hostId: number hostId: number
}): Promise<any> { }): Promise<any> {
try { try {
const response = await sshHostApi.delete('/ssh/file_manager/shortcuts', {data: shortcut}); const response = await sshHostApi.delete('/file_manager/shortcuts', {data: shortcut});
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@@ -488,7 +517,7 @@ export async function connectSSH(sessionId: string, config: {
keyPassword?: string; keyPassword?: string;
}): Promise<any> { }): Promise<any> {
try { try {
const response = await fileManagerApi.post('/ssh/file_manager/ssh/connect', { const response = await fileManagerApi.post('/ssh/connect', {
sessionId, sessionId,
...config ...config
}); });
@@ -500,7 +529,7 @@ export async function connectSSH(sessionId: string, config: {
export async function disconnectSSH(sessionId: string): Promise<any> { export async function disconnectSSH(sessionId: string): Promise<any> {
try { try {
const response = await fileManagerApi.post('/ssh/file_manager/ssh/disconnect', {sessionId}); const response = await fileManagerApi.post('/ssh/disconnect', {sessionId});
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@@ -509,7 +538,7 @@ export async function disconnectSSH(sessionId: string): Promise<any> {
export async function getSSHStatus(sessionId: string): Promise<{ connected: boolean }> { export async function getSSHStatus(sessionId: string): Promise<{ connected: boolean }> {
try { try {
const response = await fileManagerApi.get('/ssh/file_manager/ssh/status', { const response = await fileManagerApi.get('/ssh/status', {
params: {sessionId} params: {sessionId}
}); });
return response.data; return response.data;
@@ -520,7 +549,7 @@ export async function getSSHStatus(sessionId: string): Promise<{ connected: bool
export async function listSSHFiles(sessionId: string, path: string): Promise<any[]> { export async function listSSHFiles(sessionId: string, path: string): Promise<any[]> {
try { try {
const response = await fileManagerApi.get('/ssh/file_manager/ssh/listFiles', { const response = await fileManagerApi.get('/ssh/listFiles', {
params: {sessionId, path} params: {sessionId, path}
}); });
return response.data || []; return response.data || [];
@@ -531,7 +560,7 @@ export async function listSSHFiles(sessionId: string, path: string): Promise<any
export async function readSSHFile(sessionId: string, path: string): Promise<{ content: string; path: string }> { export async function readSSHFile(sessionId: string, path: string): Promise<{ content: string; path: string }> {
try { try {
const response = await fileManagerApi.get('/ssh/file_manager/ssh/readFile', { const response = await fileManagerApi.get('/ssh/readFile', {
params: {sessionId, path} params: {sessionId, path}
}); });
return response.data; return response.data;
@@ -542,7 +571,7 @@ export async function readSSHFile(sessionId: string, path: string): Promise<{ co
export async function writeSSHFile(sessionId: string, path: string, content: string): Promise<any> { export async function writeSSHFile(sessionId: string, path: string, content: string): Promise<any> {
try { try {
const response = await fileManagerApi.post('/ssh/file_manager/ssh/writeFile', { const response = await fileManagerApi.post('/ssh/writeFile', {
sessionId, sessionId,
path, path,
content content
@@ -560,7 +589,7 @@ export async function writeSSHFile(sessionId: string, path: string, content: str
export async function uploadSSHFile(sessionId: string, path: string, fileName: string, content: string): Promise<any> { export async function uploadSSHFile(sessionId: string, path: string, fileName: string, content: string): Promise<any> {
try { try {
const response = await fileManagerApi.post('/ssh/file_manager/ssh/uploadFile', { const response = await fileManagerApi.post('/ssh/uploadFile', {
sessionId, sessionId,
path, path,
fileName, fileName,
@@ -574,7 +603,7 @@ export async function uploadSSHFile(sessionId: string, path: string, fileName: s
export async function createSSHFile(sessionId: string, path: string, fileName: string, content: string = ''): Promise<any> { export async function createSSHFile(sessionId: string, path: string, fileName: string, content: string = ''): Promise<any> {
try { try {
const response = await fileManagerApi.post('/ssh/file_manager/ssh/createFile', { const response = await fileManagerApi.post('/ssh/createFile', {
sessionId, sessionId,
path, path,
fileName, fileName,
@@ -588,7 +617,7 @@ export async function createSSHFile(sessionId: string, path: string, fileName: s
export async function createSSHFolder(sessionId: string, path: string, folderName: string): Promise<any> { export async function createSSHFolder(sessionId: string, path: string, folderName: string): Promise<any> {
try { try {
const response = await fileManagerApi.post('/ssh/file_manager/ssh/createFolder', { const response = await fileManagerApi.post('/ssh/createFolder', {
sessionId, sessionId,
path, path,
folderName folderName
@@ -601,7 +630,7 @@ export async function createSSHFolder(sessionId: string, path: string, folderNam
export async function deleteSSHItem(sessionId: string, path: string, isDirectory: boolean): Promise<any> { export async function deleteSSHItem(sessionId: string, path: string, isDirectory: boolean): Promise<any> {
try { try {
const response = await fileManagerApi.delete('/ssh/file_manager/ssh/deleteItem', { const response = await fileManagerApi.delete('/ssh/deleteItem', {
data: { data: {
sessionId, sessionId,
path, path,
@@ -616,7 +645,7 @@ export async function deleteSSHItem(sessionId: string, path: string, isDirectory
export async function renameSSHItem(sessionId: string, oldPath: string, newName: string): Promise<any> { export async function renameSSHItem(sessionId: string, oldPath: string, newName: string): Promise<any> {
try { try {
const response = await fileManagerApi.put('/ssh/file_manager/ssh/renameItem', { const response = await fileManagerApi.put('/ssh/renameItem', {
sessionId, sessionId,
oldPath, oldPath,
newName newName
@@ -627,7 +656,7 @@ export async function renameSSHItem(sessionId: string, oldPath: string, newName:
} }
} }
export {sshHostApi, tunnelApi, fileManagerApi};
export async function getAllServerStatuses(): Promise<Record<number, ServerStatus>> { export async function getAllServerStatuses(): Promise<Record<number, ServerStatus>> {
try { try {
@@ -654,4 +683,97 @@ export async function getServerMetricsById(id: number): Promise<ServerMetrics> {
} catch (error) { } catch (error) {
throw error; throw error;
} }
} }
// Auth-related functions
export async function registerUser(username: string, password: string): Promise<any> {
try {
const response = await authApi.post('/create', { username, password });
return response.data;
} catch (error) {
throw error;
}
}
export async function loginUser(username: string, password: string): Promise<AuthResponse> {
try {
const response = await authApi.post('/login', { username, password });
return response.data;
} catch (error) {
throw error;
}
}
export async function getUserInfo(): Promise<UserInfo> {
try {
const response = await authApi.get('/me');
return response.data;
} catch (error) {
throw error;
}
}
export async function getRegistrationAllowed(): Promise<{ allowed: boolean }> {
try {
const response = await authApi.get('/registration-allowed');
return response.data;
} catch (error) {
throw error;
}
}
export async function getOIDCConfig(): Promise<any> {
try {
const response = await authApi.get('/oidc-config');
return response.data;
} catch (error) {
throw error;
}
}
export async function getUserCount(): Promise<UserCount> {
try {
const response = await authApi.get('/count');
return response.data;
} catch (error) {
throw error;
}
}
export async function initiatePasswordReset(username: string): Promise<any> {
try {
const response = await authApi.post('/initiate-reset', { username });
return response.data;
} catch (error) {
throw error;
}
}
export async function verifyPasswordResetCode(username: string, resetCode: string): Promise<any> {
try {
const response = await authApi.post('/verify-reset-code', { username, resetCode });
return response.data;
} catch (error) {
throw error;
}
}
export async function completePasswordReset(username: string, tempToken: string, newPassword: string): Promise<any> {
try {
const response = await authApi.post('/complete-reset', { username, tempToken, newPassword });
return response.data;
} catch (error) {
throw error;
}
}
export async function getOIDCAuthorizeUrl(): Promise<OIDCAuthorize> {
try {
const response = await authApi.get('/oidc/authorize');
return response.data;
} catch (error) {
throw error;
}
}
export {sshHostApi, tunnelApi, fileManagerApi, authApi};