Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.dev
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
MAIN_DB_USER=postgres
MAIN_DB_PASSWORD='p@S$w0rd!'
MAIN_DB_PASSWORD=p@S$w0rd!
MAIN_DB_VOLUME=./.data

BACK_HASH_SECRET=super-puper-mega-hash-soltt-solo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ public async Task<ErrorOr<AuthenticationResult>> Handle(RegisterCommand command,
var user = new User
{
Id = userId,
Roles = new[] { RoleType.Client },
Roles = [RoleType.Client],
FirstName = command.FirstName,
LastName = command.LastName,
Icon = string.Empty,
Login = command.Login,
HashPassword = _hashGenerator.Hash(command.Password)
};
Expand Down
1 change: 1 addition & 0 deletions frontend/src/api/enums/Role.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export enum Role {
PaymentReviewer = 'PaymentReviewer',
PageModerator = 'PageModerator',
SecurityKeeper = 'SecurityKeeper',
ServerSetuper = 'ServerSetuper',
}
57 changes: 56 additions & 1 deletion frontend/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ import PaymentConnectionInfo from './common/PaymentConnectionInfo';
import { ConnectionTicketStatus } from './enums/ConnectionTicketStatus';
import { Role } from './enums/Role';
import { VpnVersion } from './enums/VpnVersion';
import ConnectionString from './requests/ConnectionString';
import CreateConnection from './requests/CreateConnection';
import ExtendConnection from './requests/ExtendConnection';
import Page from './requests/Page';
import ProtocolInfo from './requests/ProtocolInfo';
import Register from './requests/Register';
import ServerInfo from './requests/ServerInfo';
import ApiError from './responses/ApiError';
import Auth from './responses/Auth';
import Connection from './responses/Connection';
Expand Down Expand Up @@ -118,11 +121,63 @@ const EasyVpn = {
},
},
servers: {
test: (v: VpnVersion, request: ConnectionString, token: string) => {
return api.post<void>(`/servers/test/${v}`, request, {
headers: { Authorization: `Bearer ${token}` },
});
},
getAll: (token: string) => {
return api.get<Server[]>(`/servers`, {
headers: { Authorization: `Bearer ${token}` },
});
},
get: (id: string, token: string) => {
return api.get<Server>(`/servers/${id}`, {
headers: { Authorization: `Bearer ${token}` },
});
},
create: (request: ServerInfo, token: string) => {
return api.post<void>(`/servers`, request, {
headers: { Authorization: `Bearer ${token}` },
});
},
edit: (id: string, request: ServerInfo, token: string) => {
return api.put<void>(`/servers/${id}`, request, {
headers: { Authorization: `Bearer ${token}` },
});
},
delete: (id: string, token: string) => {
return api.delete<void>(`/servers/${id}`, {
headers: { Authorization: `Bearer ${token}` },
});
},
},
protocols: {
getAll: (token: string) => {
return api.get<Protocol[]>(`/protocols`, {
headers: { Authorization: `Bearer ${token}` },
});
},
get: (id: string, token: string) => {
return api.get<Protocol>(`/protocols/${id}`, {
headers: { Authorization: `Bearer ${token}` },
});
},
create: (request: ProtocolInfo, token: string) => {
return api.post<void>(`/protocols`, request, {
headers: { Authorization: `Bearer ${token}` },
});
},
edit: (id: string, request: ProtocolInfo, token: string) => {
return api.put<void>(`/protocols/${id}`, request, {
headers: { Authorization: `Bearer ${token}` },
});
},
delete: (id: string, token: string) => {
return api.delete<void>(`/protocols/${id}`, {
headers: { Authorization: `Bearer ${token}` },
});
},
},
admin: {
connection: (connectionId: string, token: string) => {
Expand Down Expand Up @@ -183,7 +238,7 @@ const EasyVpn = {

export default EasyVpn;

export type { PaymentConnectionInfo };
export type { PaymentConnectionInfo, ProtocolInfo, ServerInfo };

export type {
ApiError,
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/api/requests/ConnectionString.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default interface ConnectionString {
auth: string;
endpoint: string;
}
4 changes: 4 additions & 0 deletions frontend/src/api/requests/ProtocolInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default interface Protocol {
name: string;
icon: string;
}
8 changes: 8 additions & 0 deletions frontend/src/api/requests/ServerInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { VpnVersion } from '../enums/VpnVersion';
import ConnectionString from './ConnectionString';

export default interface ServerInfo {
protocolId: string;
version: VpnVersion;
connection: ConnectionString;
}
2 changes: 1 addition & 1 deletion frontend/src/components/CreateButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import React, { FC, ReactNode } from 'react';
import CenterBox from '../CenterBox';

interface CreateButtonProps extends BoxProps {
description: ReactNode;
description?: ReactNode;
onClick?: () => void;
}

Expand Down
121 changes: 121 additions & 0 deletions frontend/src/modules/ConfigureServerModal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { LoadingButton } from '@mui/lab';
import { Alert, Box, Button, Divider, PaperProps } from '@mui/material';
import React, { FC, useContext, useEffect, useState } from 'react';
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';

import { Context } from '../..';
import EasyVpn, { ApiError, Server, ServerInfo, VpnVersion } from '../../api';
import CenterBox from '../../components/CenterBox';
import Modal from '../../components/Modal';
import { useRequest, useRequestHandler } from '../../hooks';
import ServerInfoForm from '../ServerForm';

interface ConfigureServerModalProps extends PaperProps {
protocolId?: string;
serverId?: string;
}

const ConfigureServerModal: FC<ConfigureServerModalProps> = (props) => {
const [searchParams] = useSearchParams();
const navigate = useNavigate();
const handleClose = () => navigate('../.');
const { Auth } = useContext(Context);

const serverId = props.serverId || useParams().serverId || '';
const [server, loading, error] = useRequest<Server, ApiError>(() =>
EasyVpn.servers.get(serverId, Auth.getToken()).then((s) => s.data),
);
useEffect(() => {
console.log(server);
setServerInfo((s) => {
s.protocolId = server?.protocol.id || '';
s.version = server?.version || VpnVersion.V1;
return s;
});
return;
}, [server]);

const [serverInfo, setServerInfo] = useState<ServerInfo>({
protocolId: searchParams.get('protocolId') || '',
version: VpnVersion.V1,
connection: { auth: '', endpoint: '' },
});

const SetServerInfo = (s: ServerInfo) => {
setServerInfo(s);
navigate(s ? `?protocolId=${s.protocolId}&version=${s.version}` : '');
};
const [editHandler, loadingEdit, errorEdit] = useRequestHandler<void, ApiError>(() =>
serverInfo
? EasyVpn.servers
.edit(serverId, serverInfo, Auth.getToken())
.then((v) => v.data)
: Promise.reject(new Error('Server information is not filled!')),
);

return (
<Modal open={true} handleClose={handleClose} loading={loading} {...props}>
{error ? (
<Alert
onClose={handleClose}
severity="error"
variant="outlined"
sx={{ width: '25ch' }}
>
{error.response?.data.title ?? error.message}
</Alert>
) : (
<CenterBox
display="flex"
flexDirection="column"
gap={2}
paddingX={3}
paddingY={1}
width="80vw"
minWidth="30ch"
>
<Divider textAlign="left">Configure server</Divider>
<ServerInfoForm server={serverInfo} onChange={SetServerInfo} />
{errorEdit && (
<Alert
onClose={handleClose}
severity="error"
variant="outlined"
sx={{ width: '25ch' }}
>
{errorEdit.response?.data.title ?? errorEdit.message}
</Alert>
)}
<Divider />
<Box
display="flex"
flexDirection="row-reverse"
flexWrap="wrap"
justifyContent="space-between"
gap={1}
>
<LoadingButton
variant="contained"
color="success"
sx={{ textTransform: 'none' }}
loading={loadingEdit}
onClick={() => editHandler(null, () => handleClose())}
>
Config server
</LoadingButton>
<Button
variant="outlined"
color="inherit"
onClick={handleClose}
sx={{ textTransform: 'none' }}
>
Close
</Button>
</Box>
</CenterBox>
)}
</Modal>
);
};

export default ConfigureServerModal;
91 changes: 91 additions & 0 deletions frontend/src/modules/CreateProtolModal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { LoadingButton } from '@mui/lab';
import { Alert, Box, Button, Divider, PaperProps } from '@mui/material';
import React, { FC, useContext, useState } from 'react';
import { useNavigate } from 'react-router-dom';

import { Context } from '../..';
import EasyVpn, { ApiError, ProtocolInfo } from '../../api';
import CenterBox from '../../components/CenterBox';
import Modal from '../../components/Modal';
import { useRequestHandler } from '../../hooks';
import ProtocolInfoForm from '../ProtocolInfoForm';

interface CreateProtocolModalProps extends PaperProps {
protocolId?: string;
}

const CreateProtocolModal: FC<CreateProtocolModalProps> = (props) => {
const navigate = useNavigate();
const handleClose = () => navigate('../.');
const { Auth } = useContext(Context);

const [protocolInfo, setProtocolInfo] = useState<ProtocolInfo>({
name: '',
icon: '',
});

const [createHandler, loading, error] = useRequestHandler<void, ApiError>(() =>
protocolInfo
? EasyVpn.protocols.create(protocolInfo, Auth.getToken()).then((v) => v.data)
: Promise.reject(new Error('Protocol information is not filled!')),
);

return (
<Modal open={true} handleClose={handleClose} {...props}>
{error ? (
<Alert
onClose={handleClose}
severity="error"
variant="outlined"
sx={{ width: '25ch' }}
>
{error.response?.data.title ?? error.message}
</Alert>
) : (
<CenterBox
display="flex"
flexDirection="column"
gap={2}
paddingX={3}
paddingY={1}
width="80vw"
minWidth="30ch"
>
<Divider textAlign="left">Create new protocol</Divider>
<ProtocolInfoForm
protocol={protocolInfo}
onChange={setProtocolInfo}
/>
<Divider />
<Box
display="flex"
flexDirection="row-reverse"
flexWrap="wrap"
justifyContent="space-between"
gap={1}
>
<LoadingButton
variant="contained"
color="success"
sx={{ textTransform: 'none' }}
loading={loading}
onClick={() => createHandler(null, () => handleClose())}
>
Create protocol
</LoadingButton>
<Button
variant="outlined"
color="inherit"
onClick={handleClose}
sx={{ textTransform: 'none' }}
>
Close
</Button>
</Box>
</CenterBox>
)}
</Modal>
);
};

export default CreateProtocolModal;
Loading