network chunk v12
This commit is contained in:
@@ -0,0 +1,40 @@
|
|||||||
|
export let operationCodes = {
|
||||||
|
// General Operations
|
||||||
|
HEARTBEAT: 'HEARTBEAT',
|
||||||
|
ALIVE: 'ALIVE',
|
||||||
|
SET_PUBLIC_KEY: 'SET_PUBLIC_KEY',
|
||||||
|
SET_AES_KEY: 'SET_AES_KEY',
|
||||||
|
RESET_DATABASE: 'RESET_DATABASE',
|
||||||
|
OK: 'OK',
|
||||||
|
ERR: 'ERR',
|
||||||
|
END: 'END',
|
||||||
|
UNKNOWN_COMMAND: 'UNKNOWN_COMMAND',
|
||||||
|
|
||||||
|
// Auth Operations
|
||||||
|
LOGIN: 'LOGIN',
|
||||||
|
SIGN_UP: 'SIGN_UP',
|
||||||
|
RESET_PASSWORD: 'RESET_PASSWORD',
|
||||||
|
|
||||||
|
FIND_BY_EMAIL: 'FIND_BY_EMAIL',
|
||||||
|
MODIFY_USER: 'MODIFY_USER',
|
||||||
|
|
||||||
|
GET_DEPARTMENTS: 'GET_DEPARTMENTS',
|
||||||
|
CREATE_DEPARTMENT: 'CREATE_DEPARTMENT',
|
||||||
|
MODIFY_DEPARTMENT: 'MODIFY_DEPARTMENT',
|
||||||
|
DELETE_DEPARTMENT: 'DELETE_DEPARTMENT',
|
||||||
|
|
||||||
|
GET_USERS: 'GET_USERS',
|
||||||
|
FIND_KEY_BY_USER_ID: 'FIND_KEY_BY_USER_ID',
|
||||||
|
SEND_ANNOUNCEMENT: 'SEND_ANNOUNCEMENT',
|
||||||
|
|
||||||
|
GET_USER_INFORMATION: 'GET_USER_INFORMATION',
|
||||||
|
CLEAR_BACKUP: 'CLEAR_BACKUP',
|
||||||
|
BACKUP_FILE: 'BACKUP_FILE',
|
||||||
|
SHARE_FILE: 'SHARE_FILE',
|
||||||
|
CLEAR_DEPARTMENT: 'CLEAR_DEPARTMENT',
|
||||||
|
DEPARTMENT_FILE: 'DEPARTMENT_FILE',
|
||||||
|
IS_BACKUP_CREATED: 'IS_BACKUP_CREATED',
|
||||||
|
GET_BACKUP_STRUCTURE: 'GET_BACKUP_STRUCTURE',
|
||||||
|
REQ_FILE_FROM_BACKUP: 'REQ_FILE_FROM_BACKUP',
|
||||||
|
DECRYPT_AND_SAVE_OLD_BACKUP_FILE: 'DECRYPT_AND_SAVE_OLD_BACKUP_FILE',
|
||||||
|
};
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
import { ParsedMessage } from '../message_handler';
|
|
||||||
import { OperationHandler } from './operation_handler';
|
|
||||||
import { OperationPlugin } from './operation_plugin';
|
|
||||||
|
|
||||||
export abstract class OperationBase implements OperationPlugin {
|
|
||||||
// Shared operation codes
|
|
||||||
public static readonly operationCodes = {
|
|
||||||
OK: 'OK',
|
|
||||||
ERR: 'ERR',
|
|
||||||
END: 'END',
|
|
||||||
};
|
|
||||||
|
|
||||||
// Default handler for OK operation
|
|
||||||
public static handleOk(parsedMessage: ParsedMessage): ParsedMessage {
|
|
||||||
console.log('OK operation received');
|
|
||||||
return parsedMessage; // Typically, you would just acknowledge with OK, returning as-is
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default handler for ERR operation
|
|
||||||
public static handleErr(parsedMessage: ParsedMessage): ParsedMessage {
|
|
||||||
console.log('ERR operation received: ', parsedMessage.metaInfo?.message || 'No error details provided');
|
|
||||||
return parsedMessage; // Typically, you would log the error and return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default handler for END operation
|
|
||||||
public static handleEnd(parsedMessage: ParsedMessage): ParsedMessage {
|
|
||||||
console.log('END operation received');
|
|
||||||
return {
|
|
||||||
operationCode: OperationBase.operationCodes.END,
|
|
||||||
metaInfo: { message: 'Connection ended.' },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register the common OK, ERR, and END handlers
|
|
||||||
public static registerCommonOperations(operationHandler: OperationHandler): void {
|
|
||||||
operationHandler.registerHandler(OperationBase.operationCodes.OK, OperationBase.handleOk);
|
|
||||||
operationHandler.registerHandler(OperationBase.operationCodes.ERR, OperationBase.handleErr);
|
|
||||||
operationHandler.registerHandler(OperationBase.operationCodes.END, OperationBase.handleEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Abstract register method that will be implemented by subclasses
|
|
||||||
public abstract register(operationHandler: OperationHandler): void;
|
|
||||||
}
|
|
||||||
@@ -2,14 +2,14 @@
|
|||||||
import { ParsedMessage, MessageHandler } from '../message_handler';
|
import { ParsedMessage, MessageHandler } from '../message_handler';
|
||||||
import { OperationPlugin } from './operation_plugin';
|
import { OperationPlugin } from './operation_plugin';
|
||||||
|
|
||||||
type OperationHandlerFunction = (parsedMessage: ParsedMessage) => ParsedMessage;
|
// Define handler function type to return Promise<ParsedMessage>
|
||||||
|
type OperationHandlerFunction = (parsedMessage: ParsedMessage) => Promise<ParsedMessage>;
|
||||||
|
|
||||||
export class OperationHandler {
|
export class OperationHandler {
|
||||||
private static instance: OperationHandler;
|
private static instance: OperationHandler;
|
||||||
private handlers: { [operationCode: string]: OperationHandlerFunction } = {};
|
private handlers: { [operationCode: string]: OperationHandlerFunction } = {};
|
||||||
|
|
||||||
private constructor() {
|
private constructor() {
|
||||||
// Register only the unknown command handler on initialization
|
|
||||||
this.registerHandler('UNKNOWN_COMMAND', this.handleUnknownCommand);
|
this.registerHandler('UNKNOWN_COMMAND', this.handleUnknownCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,30 +26,24 @@ export class OperationHandler {
|
|||||||
this.handlers[operationCode] = handler;
|
this.handlers[operationCode] = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle operation request
|
// Handle operation request asynchronously
|
||||||
public handleOperation(rawMessage: string): ParsedMessage {
|
public async handleOperation(rawMessage: string): Promise<ParsedMessage> {
|
||||||
// Parse and validate the message
|
|
||||||
const parsedMessage = MessageHandler.parseMessage(rawMessage);
|
const parsedMessage = MessageHandler.parseMessage(rawMessage);
|
||||||
if (!parsedMessage || !MessageHandler.validateMessage(parsedMessage)) {
|
if (!parsedMessage || !MessageHandler.validateMessage(parsedMessage)) {
|
||||||
return this.handleUnknownCommand(parsedMessage);
|
return this.handleUnknownCommand(parsedMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dispatch the handler for the given operation code
|
// Retrieve the handler for the operation code and invoke it asynchronously
|
||||||
const handler = this.handlers[parsedMessage.operationCode];
|
const handler = this.handlers[parsedMessage.operationCode];
|
||||||
if (handler) {
|
if (handler) {
|
||||||
return handler(parsedMessage);
|
return await handler(parsedMessage);
|
||||||
} else {
|
} else {
|
||||||
return this.handleUnknownCommand(parsedMessage);
|
return this.handleUnknownCommand(parsedMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all registered operation codes
|
|
||||||
public getAvailableOperationCodes(): string[] {
|
|
||||||
return Object.keys(this.handlers);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default handler for unknown commands
|
// Default handler for unknown commands
|
||||||
private handleUnknownCommand(parsedMessage?: ParsedMessage): ParsedMessage {
|
private async handleUnknownCommand(parsedMessage: ParsedMessage): Promise<ParsedMessage> {
|
||||||
return {
|
return {
|
||||||
operationCode: 'UNKNOWN_COMMAND',
|
operationCode: 'UNKNOWN_COMMAND',
|
||||||
metaInfo: { message: 'Unknown command received.' },
|
metaInfo: { message: 'Unknown command received.' },
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { ParsedMessage } from '../message_handler';
|
import { ParsedMessage } from '../message_handler';
|
||||||
import { userDatabase, departmentDatabase, keyDatabase } from '../../db_managers/db';
|
import { userDatabase, departmentDatabase, keyDatabase } from '../../db_managers/db';
|
||||||
import { OperationBase } from '../operations_base/operation_base';
|
|
||||||
import { OperationHandler } from '../operations_base/operation_handler';
|
import { OperationHandler } from '../operations_base/operation_handler';
|
||||||
|
import { OperationPlugin } from '../operations_base/operation_plugin';
|
||||||
|
import {operationCodes} from "../operation_codes";
|
||||||
|
|
||||||
export class AuthOperations extends OperationBase {
|
export class AuthOperations implements OperationPlugin {
|
||||||
public static readonly operationCodes = {
|
public static readonly operationCodes = {
|
||||||
...OperationBase.operationCodes,
|
|
||||||
LOGIN: 'LOGIN',
|
LOGIN: 'LOGIN',
|
||||||
SIGN_UP: 'SIGN_UP',
|
SIGN_UP: 'SIGN_UP',
|
||||||
RESET_PASSWORD: 'RESET_PASSWORD'
|
RESET_PASSWORD: 'RESET_PASSWORD',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Utility function to validate email format
|
// Utility function to validate email format
|
||||||
@@ -17,95 +17,82 @@ export class AuthOperations extends OperationBase {
|
|||||||
return emailRegex.test(email);
|
return emailRegex.test(email);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility function to validate password strength (min 8 chars, at least 1 number and 1 special char)
|
// Utility function to validate password strength
|
||||||
private static isStrongPassword(password: string): boolean {
|
private static isStrongPassword(password: string): boolean {
|
||||||
const passwordRegex = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,}$/;
|
const passwordRegex = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,}$/;
|
||||||
return passwordRegex.test(password);
|
return passwordRegex.test(password);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility function to check name is not empty
|
|
||||||
private static isValidName(name: string): boolean {
|
private static isValidName(name: string): boolean {
|
||||||
return name.trim().length > 0;
|
return name.trim().length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static isValidAppType(app_type: string){
|
private static isValidAppType(app_type: string): boolean {
|
||||||
const app_types = ['client', 'ceo', 'admin'];
|
const appTypes = ['client', 'ceo', 'admin'];
|
||||||
return app_types.includes(app_type);
|
return appTypes.includes(app_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle Login operation with validation
|
// Handle Login operation with validation
|
||||||
public static handleLogin(parsedMessage: ParsedMessage): ParsedMessage {
|
public static async handleLogin(parsedMessage: ParsedMessage): Promise<ParsedMessage> {
|
||||||
const { email, password, app_type } = parsedMessage.metaInfo || {};
|
const { email, password, app_type } = parsedMessage.metaInfo || {};
|
||||||
|
|
||||||
// Check if email and password are provided
|
|
||||||
if (!email || !password || !app_type) {
|
if (!email || !password || !app_type) {
|
||||||
return {
|
return {
|
||||||
operationCode: OperationBase.operationCodes.ERR,
|
operationCode: operationCodes.ERR,
|
||||||
metaInfo: { message: 'Both email and password are required.' },
|
metaInfo: { message: 'Email, password, and app_type are required.' },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify email and password with the database
|
|
||||||
const result = userDatabase.verifyCredentials(email, password, app_type);
|
const result = userDatabase.verifyCredentials(email, password, app_type);
|
||||||
|
|
||||||
// Handle the case where the credentials are incorrect
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
return {
|
return {
|
||||||
operationCode: OperationBase.operationCodes.ERR,
|
operationCode: operationCodes.ERR,
|
||||||
metaInfo: { message: result.message },
|
metaInfo: { message: result.message },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
operationCode: OperationBase.operationCodes.OK,
|
operationCode: operationCodes.OK,
|
||||||
metaInfo: { message: 'Login successful.' },
|
metaInfo: { message: 'Login successful.' },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle SignUp operation with validation
|
// Handle SignUp operation with validation
|
||||||
public static handleSignUp(parsedMessage: ParsedMessage): ParsedMessage {
|
public static async handleSignUp(parsedMessage: ParsedMessage): Promise<ParsedMessage> {
|
||||||
const { name, email, password, departmentId, app_type } = parsedMessage.metaInfo || {};
|
const { name, email, password, departmentId, app_type } = parsedMessage.metaInfo || {};
|
||||||
|
|
||||||
// Validate name
|
|
||||||
if (!AuthOperations.isValidName(name)) {
|
if (!AuthOperations.isValidName(name)) {
|
||||||
return {
|
return {
|
||||||
operationCode: OperationBase.operationCodes.ERR,
|
operationCode: operationCodes.ERR,
|
||||||
metaInfo: { message: 'Invalid name. Please provide a valid name.' },
|
metaInfo: { message: 'Invalid name.' },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate email format
|
|
||||||
if (!AuthOperations.isValidEmail(email)) {
|
if (!AuthOperations.isValidEmail(email)) {
|
||||||
return {
|
return {
|
||||||
operationCode: OperationBase.operationCodes.ERR,
|
operationCode: operationCodes.ERR,
|
||||||
metaInfo: { message: 'Invalid email format.' },
|
metaInfo: { message: 'Invalid email format.' },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate password strength
|
|
||||||
if (!AuthOperations.isStrongPassword(password)) {
|
if (!AuthOperations.isStrongPassword(password)) {
|
||||||
return {
|
return {
|
||||||
operationCode: OperationBase.operationCodes.ERR,
|
operationCode: operationCodes.ERR,
|
||||||
metaInfo: {
|
metaInfo: { message: 'Weak password.' },
|
||||||
message: 'Weak password. It must be at least 8 characters long, contain at least 1 letter, 1 number, and 1 special character.',
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AuthOperations.isValidAppType(app_type)) {
|
if (!AuthOperations.isValidAppType(app_type)) {
|
||||||
return {
|
return {
|
||||||
operationCode: OperationBase.operationCodes.ERR,
|
operationCode: operationCodes.ERR,
|
||||||
metaInfo: {
|
metaInfo: { message: 'Invalid app type.' },
|
||||||
message: 'Not valid app_type.',
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if user with this email already exists
|
|
||||||
const existingUser = userDatabase.findByEmail(email);
|
const existingUser = userDatabase.findByEmail(email);
|
||||||
if (existingUser) {
|
if (existingUser) {
|
||||||
return {
|
return {
|
||||||
operationCode: OperationBase.operationCodes.ERR,
|
operationCode: operationCodes.ERR,
|
||||||
metaInfo: { message: 'Email already in use.' },
|
metaInfo: { message: 'Email already in use.' },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -113,71 +100,57 @@ export class AuthOperations extends OperationBase {
|
|||||||
const existingUserByName = userDatabase.getAllUsers().find((user) => user.name === name);
|
const existingUserByName = userDatabase.getAllUsers().find((user) => user.name === name);
|
||||||
if (existingUserByName) {
|
if (existingUserByName) {
|
||||||
return {
|
return {
|
||||||
operationCode: OperationBase.operationCodes.ERR,
|
operationCode: operationCodes.ERR,
|
||||||
metaInfo: { message: 'Name already in use.' },
|
metaInfo: { message: 'Name already in use.' },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate department ID
|
|
||||||
const departmentEntry = departmentDatabase.findById(departmentId);
|
const departmentEntry = departmentDatabase.findById(departmentId);
|
||||||
if (!departmentEntry) {
|
if (!departmentEntry) {
|
||||||
return {
|
return {
|
||||||
operationCode: OperationBase.operationCodes.ERR,
|
operationCode: operationCodes.ERR,
|
||||||
metaInfo: { message: 'Invalid department.' },
|
metaInfo: { message: 'Invalid department.' },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new user in the database
|
|
||||||
const newUser = userDatabase.createUser(name, email, password, departmentEntry.id, app_type);
|
const newUser = userDatabase.createUser(name, email, password, departmentEntry.id, app_type);
|
||||||
|
|
||||||
// Create a key for the new user
|
|
||||||
keyDatabase.createKey(newUser.id);
|
keyDatabase.createKey(newUser.id);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
operationCode: OperationBase.operationCodes.OK,
|
operationCode: operationCodes.OK,
|
||||||
metaInfo: {
|
metaInfo: { message: 'User created successfully.', userId: newUser.id },
|
||||||
message: 'User created successfully.',
|
|
||||||
userId: newUser.id,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle Reset Password operation
|
// Handle Reset Password operation
|
||||||
public static handleResetPassword(parsedMessage: ParsedMessage): ParsedMessage {
|
public static async handleResetPassword(parsedMessage: ParsedMessage): Promise<ParsedMessage> {
|
||||||
const { email, newPassword, app_type } = parsedMessage.metaInfo || {};
|
const { email, newPassword, app_type } = parsedMessage.metaInfo || {};
|
||||||
|
|
||||||
if (!AuthOperations.isStrongPassword(newPassword)) {
|
if (!AuthOperations.isStrongPassword(newPassword)) {
|
||||||
return {
|
return {
|
||||||
operationCode: OperationBase.operationCodes.ERR,
|
operationCode: operationCodes.ERR,
|
||||||
metaInfo: {
|
metaInfo: { message: 'Weak password.' },
|
||||||
message: 'Weak password. It must be at least 8 characters long, contain at least 1 letter, 1 number, and 1 special character.',
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logic to reset password (could be sending a reset link, or generating a temp password)
|
|
||||||
const resetResult = userDatabase.resetPassword(email, newPassword, app_type);
|
const resetResult = userDatabase.resetPassword(email, newPassword, app_type);
|
||||||
|
|
||||||
if (resetResult.success) {
|
if (resetResult.success) {
|
||||||
return {
|
return {
|
||||||
operationCode: OperationBase.operationCodes.OK,
|
operationCode: operationCodes.OK,
|
||||||
metaInfo: { message: 'Password reset successfully. Please check your email for instructions.' },
|
metaInfo: { message: 'Password reset successfully.' },
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
operationCode: OperationBase.operationCodes.ERR,
|
operationCode: operationCodes.ERR,
|
||||||
metaInfo: { message: 'Failed to reset password.' },
|
metaInfo: { message: 'Failed to reset password.' },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register specific operations for AuthOperations
|
// Register operations with the OperationHandler
|
||||||
public register(operationHandler: OperationHandler): void {
|
public register(operationHandler: OperationHandler): void {
|
||||||
operationHandler.registerHandler(AuthOperations.operationCodes.LOGIN, AuthOperations.handleLogin);
|
operationHandler.registerHandler(AuthOperations.operationCodes.LOGIN, AuthOperations.handleLogin);
|
||||||
operationHandler.registerHandler(AuthOperations.operationCodes.SIGN_UP, AuthOperations.handleSignUp);
|
operationHandler.registerHandler(AuthOperations.operationCodes.SIGN_UP, AuthOperations.handleSignUp);
|
||||||
operationHandler.registerHandler(AuthOperations.operationCodes.RESET_PASSWORD, AuthOperations.handleResetPassword)
|
operationHandler.registerHandler(AuthOperations.operationCodes.RESET_PASSWORD, AuthOperations.handleResetPassword);
|
||||||
|
|
||||||
// Register common OK, ERR, and END operations from the base class
|
|
||||||
OperationBase.registerCommonOperations(operationHandler);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +1,28 @@
|
|||||||
import { ParsedMessage } from '../message_handler';
|
import { ParsedMessage } from '../message_handler';
|
||||||
import { OperationBase } from '../operations_base/operation_base';
|
import { departmentDatabase, keyDatabase, userDatabase } from '../../db_managers/db';
|
||||||
import {
|
|
||||||
departmentDatabase,
|
|
||||||
keyDatabase,
|
|
||||||
userDatabase
|
|
||||||
} from '../../db_managers/db';
|
|
||||||
import { OperationHandler } from '../operations_base/operation_handler';
|
import { OperationHandler } from '../operations_base/operation_handler';
|
||||||
|
import { OperationPlugin } from '../operations_base/operation_plugin';
|
||||||
|
import { operationCodes} from "../operation_codes";
|
||||||
|
|
||||||
export class CeoOperations extends OperationBase {
|
export class CeoOperations implements OperationPlugin {
|
||||||
public static readonly operationCodes = {
|
public static readonly operationCodes = {
|
||||||
...OperationBase.operationCodes, // Inherit common operation codes (OK, ERR, END)
|
|
||||||
RESET_DATABASE: 'RESET_DATABASE',
|
RESET_DATABASE: 'RESET_DATABASE',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle reset database operation
|
public static async handleResetDatabase(): Promise<ParsedMessage> {
|
||||||
public static handleResetDatabase(): ParsedMessage {
|
|
||||||
console.log('Resetting the database...');
|
console.log('Resetting the database...');
|
||||||
|
|
||||||
departmentDatabase.cleanTable();
|
departmentDatabase.cleanTable();
|
||||||
userDatabase.cleanTable();
|
userDatabase.cleanTable();
|
||||||
keyDatabase.cleanTable();
|
keyDatabase.cleanTable();
|
||||||
|
|
||||||
// Create the departments
|
|
||||||
departmentDatabase.createDepartment('Worker');
|
departmentDatabase.createDepartment('Worker');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
operationCode: CeoOperations.operationCodes.OK,
|
operationCode: operationCodes.OK,
|
||||||
metaInfo: {
|
metaInfo: { message: 'Database reset successfully.' },
|
||||||
message: 'Database reset successfully.',
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register general operations with the OperationHandler
|
|
||||||
public register(operationHandler: OperationHandler): void {
|
public register(operationHandler: OperationHandler): void {
|
||||||
operationHandler.registerHandler(CeoOperations.operationCodes.RESET_DATABASE, CeoOperations.handleResetDatabase);
|
operationHandler.registerHandler(CeoOperations.operationCodes.RESET_DATABASE, CeoOperations.handleResetDatabase);
|
||||||
|
|
||||||
// Register common operations inherited from the base class
|
|
||||||
OperationBase.registerCommonOperations(operationHandler);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,129 +1,54 @@
|
|||||||
import { ParsedMessage } from '../message_handler';
|
import { ParsedMessage } from '../message_handler';
|
||||||
import { departmentDatabase } from '../../db_managers/db';
|
import { departmentDatabase } from '../../db_managers/db';
|
||||||
import { OperationBase } from '../operations_base/operation_base';
|
|
||||||
import { OperationHandler } from '../operations_base/operation_handler';
|
import { OperationHandler } from '../operations_base/operation_handler';
|
||||||
|
import { OperationPlugin } from '../operations_base/operation_plugin';
|
||||||
|
import { operationCodes } from "../operation_codes";
|
||||||
|
|
||||||
export class DepartmentOperations extends OperationBase {
|
export class DepartmentOperations implements OperationPlugin {
|
||||||
public static readonly operationCodes = {
|
public static readonly operationCodes = {
|
||||||
...OperationBase.operationCodes,
|
|
||||||
GET_DEPARTMENTS: 'GET_DEPARTMENTS',
|
GET_DEPARTMENTS: 'GET_DEPARTMENTS',
|
||||||
CREATE_DEPARTMENT: 'CREATE_DEPARTMENT',
|
CREATE_DEPARTMENT: 'CREATE_DEPARTMENT',
|
||||||
MODIFY_DEPARTMENT: 'MODIFY_DEPARTMENT',
|
MODIFY_DEPARTMENT: 'MODIFY_DEPARTMENT',
|
||||||
DELETE_DEPARTMENT: 'DELETE_DEPARTMENT',
|
DELETE_DEPARTMENT: 'DELETE_DEPARTMENT',
|
||||||
FIND_DEPARTMENT_BY_ID: 'FIND_DEPARTMENT_BY_ID'
|
FIND_DEPARTMENT_BY_ID: 'FIND_DEPARTMENT_BY_ID',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get all departments
|
public static async handleGetDepartments(): Promise<ParsedMessage> {
|
||||||
public static handleGetDepartments(): ParsedMessage {
|
|
||||||
const departments = departmentDatabase.getAllDepartments();
|
const departments = departmentDatabase.getAllDepartments();
|
||||||
return {
|
return { operationCode: operationCodes.OK, metaInfo: { departments } };
|
||||||
operationCode: DepartmentOperations.operationCodes.OK,
|
|
||||||
metaInfo: { departments },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static handleGetDepartmentById(parsedMessage: ParsedMessage): ParsedMessage {
|
public static async handleGetDepartmentById(parsedMessage: ParsedMessage): Promise<ParsedMessage> {
|
||||||
const { id } = parsedMessage.metaInfo || {};
|
const { id } = parsedMessage.metaInfo || {};
|
||||||
|
const department = departmentDatabase.findById(id);
|
||||||
if(!id){
|
return department
|
||||||
return {
|
? { operationCode: operationCodes.OK, metaInfo: { department } }
|
||||||
operationCode: DepartmentOperations.operationCodes.ERR,
|
: { operationCode: operationCodes.ERR, metaInfo: { message: 'Department not found.' } };
|
||||||
metaInfo: { message: 'Id is required.' },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = departmentDatabase.findById(id);
|
public static async handleCreateDepartment(parsedMessage: ParsedMessage): Promise<ParsedMessage> {
|
||||||
return {
|
const { departmentName } = parsedMessage.metaInfo || {};
|
||||||
operationCode: user === null ? DepartmentOperations.operationCodes.ERR : DepartmentOperations.operationCodes.OK,
|
const department = departmentDatabase.createDepartment(departmentName);
|
||||||
metaInfo: user === null ? { message: 'Department not found.' } : { message: user }
|
return { operationCode: operationCodes.OK, metaInfo: { department } };
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new department
|
public static async handleModifyDepartment(parsedMessage: ParsedMessage): Promise<ParsedMessage> {
|
||||||
public static handleCreateDepartment(parsedMessage: ParsedMessage): ParsedMessage {
|
const { departmentId, newDepartmentName } = parsedMessage.metaInfo || {};
|
||||||
// @ts-ignore
|
const success = departmentDatabase.modifyDepartment(departmentId, newDepartmentName);
|
||||||
const { departmentName } = parsedMessage.metaInfo;
|
return { operationCode: success ? operationCodes.OK : operationCodes.ERR };
|
||||||
|
|
||||||
// Check if department name is provided
|
|
||||||
if (!departmentName) {
|
|
||||||
return {
|
|
||||||
operationCode: DepartmentOperations.operationCodes.ERR,
|
|
||||||
metaInfo: { message: 'Department name is required.' },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the department already exists
|
public static async handleDeleteDepartment(parsedMessage: ParsedMessage): Promise<ParsedMessage> {
|
||||||
const existingDepartment = departmentDatabase.findByName(departmentName);
|
const { departmentId } = parsedMessage.metaInfo || {};
|
||||||
if (existingDepartment) {
|
const success = departmentDatabase.deleteDepartment(departmentId);
|
||||||
return {
|
return { operationCode: success ? operationCodes.OK : operationCodes.ERR };
|
||||||
operationCode: DepartmentOperations.operationCodes.ERR,
|
|
||||||
metaInfo: { message: 'Department already exists.' },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the new department
|
|
||||||
const newDepartment = departmentDatabase.createDepartment(departmentName);
|
|
||||||
|
|
||||||
return {
|
|
||||||
operationCode: DepartmentOperations.operationCodes.OK,
|
|
||||||
metaInfo: { message: 'Department created successfully.', departmentId: newDepartment.id },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Modify an existing department
|
|
||||||
public static handleModifyDepartment(parsedMessage: ParsedMessage): ParsedMessage {
|
|
||||||
// @ts-ignore
|
|
||||||
const { departmentId, newDepartmentName } = parsedMessage.metaInfo;
|
|
||||||
|
|
||||||
// Validate input
|
|
||||||
if (!departmentId || !newDepartmentName) {
|
|
||||||
return {
|
|
||||||
operationCode: DepartmentOperations.operationCodes.ERR,
|
|
||||||
metaInfo: { message: 'Department ID and new department name are required.' },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Modify the department
|
|
||||||
const isSuccess = departmentDatabase.modifyDepartment(departmentId, newDepartmentName);
|
|
||||||
|
|
||||||
return {
|
|
||||||
operationCode: isSuccess ? DepartmentOperations.operationCodes.OK : DepartmentOperations.operationCodes.ERR,
|
|
||||||
metaInfo: { message: isSuccess ? 'Department modified successfully.' : 'Failed to modify department.' },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete an existing department
|
|
||||||
public static handleDeleteDepartment(parsedMessage: ParsedMessage): ParsedMessage {
|
|
||||||
// @ts-ignore
|
|
||||||
const { departmentId } = parsedMessage.metaInfo;
|
|
||||||
|
|
||||||
// Validate input
|
|
||||||
if (!departmentId) {
|
|
||||||
return {
|
|
||||||
operationCode: DepartmentOperations.operationCodes.ERR,
|
|
||||||
metaInfo: { message: 'Department ID is required.' },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete the department
|
|
||||||
const isSuccess = departmentDatabase.deleteDepartment(departmentId);
|
|
||||||
|
|
||||||
return {
|
|
||||||
operationCode: isSuccess ? DepartmentOperations.operationCodes.OK : DepartmentOperations.operationCodes.ERR,
|
|
||||||
metaInfo: { message: isSuccess ? 'Department deleted successfully.' : 'Failed to delete department.' },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register department operations_base with the OperationHandler
|
|
||||||
public register(operationHandler: OperationHandler): void {
|
public register(operationHandler: OperationHandler): void {
|
||||||
// Register the department operation handlers
|
|
||||||
operationHandler.registerHandler(DepartmentOperations.operationCodes.GET_DEPARTMENTS, DepartmentOperations.handleGetDepartments);
|
operationHandler.registerHandler(DepartmentOperations.operationCodes.GET_DEPARTMENTS, DepartmentOperations.handleGetDepartments);
|
||||||
operationHandler.registerHandler(DepartmentOperations.operationCodes.CREATE_DEPARTMENT, DepartmentOperations.handleCreateDepartment);
|
operationHandler.registerHandler(DepartmentOperations.operationCodes.CREATE_DEPARTMENT, DepartmentOperations.handleCreateDepartment);
|
||||||
operationHandler.registerHandler(DepartmentOperations.operationCodes.MODIFY_DEPARTMENT, DepartmentOperations.handleModifyDepartment);
|
operationHandler.registerHandler(DepartmentOperations.operationCodes.MODIFY_DEPARTMENT, DepartmentOperations.handleModifyDepartment);
|
||||||
operationHandler.registerHandler(DepartmentOperations.operationCodes.DELETE_DEPARTMENT, DepartmentOperations.handleDeleteDepartment);
|
operationHandler.registerHandler(DepartmentOperations.operationCodes.DELETE_DEPARTMENT, DepartmentOperations.handleDeleteDepartment);
|
||||||
operationHandler.registerHandler(DepartmentOperations.operationCodes.FIND_DEPARTMENT_BY_ID, DepartmentOperations.handleGetDepartmentById);
|
operationHandler.registerHandler(DepartmentOperations.operationCodes.FIND_DEPARTMENT_BY_ID, DepartmentOperations.handleGetDepartmentById);
|
||||||
|
|
||||||
// Register common operations_base inherited from the base class
|
|
||||||
OperationBase.registerCommonOperations(operationHandler);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,26 @@
|
|||||||
import { ParsedMessage } from '../message_handler';
|
import { ParsedMessage } from '../message_handler';
|
||||||
import { OperationBase } from '../operations_base/operation_base';
|
|
||||||
import { OperationHandler } from '../operations_base/operation_handler';
|
import { OperationHandler } from '../operations_base/operation_handler';
|
||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
|
import {OperationPlugin} from "../operations_base/operation_plugin";
|
||||||
|
|
||||||
export class GeneralOperations extends OperationBase {
|
export class GeneralOperations implements OperationPlugin {
|
||||||
public static readonly operationCodes = {
|
public static readonly operationCodes = {
|
||||||
...OperationBase.operationCodes, // Inherit common operation codes (OK, ERR, END)
|
OK: 'OK',
|
||||||
|
ERR: 'ERR',
|
||||||
|
END: 'END',
|
||||||
HEARTBEAT: 'HEARTBEAT',
|
HEARTBEAT: 'HEARTBEAT',
|
||||||
ALIVE: 'ALIVE',
|
ALIVE: 'ALIVE',
|
||||||
SET_PUBLIC_KEY: 'SET_PUBLIC_KEY',
|
SET_PUBLIC_KEY: 'SET_PUBLIC_KEY',
|
||||||
SET_AES_KEY: 'SET_AES_KEY', // New operation for AES key
|
SET_AES_KEY: 'SET_AES_KEY',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle heartbeat operation
|
// Handle heartbeat operation asynchronously
|
||||||
public static handleHeartbeat(): ParsedMessage {
|
public static async handleHeartbeat(): Promise<ParsedMessage> {
|
||||||
const networkInterfaces = os.networkInterfaces();
|
const networkInterfaces = os.networkInterfaces();
|
||||||
let ipAddress = 'Unknown';
|
let ipAddress = 'Unknown';
|
||||||
|
|
||||||
for (const iface of Object.values(networkInterfaces)) {
|
for (const iface of Object.values(networkInterfaces)) {
|
||||||
// @ts-ignore
|
for (const address of iface!) {
|
||||||
for (const address of iface) {
|
|
||||||
if (address.family === 'IPv4' && !address.internal) {
|
if (address.family === 'IPv4' && !address.internal) {
|
||||||
ipAddress = address.address;
|
ipAddress = address.address;
|
||||||
break;
|
break;
|
||||||
@@ -34,13 +35,13 @@ export class GeneralOperations extends OperationBase {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle public key exchange
|
// Handle public key exchange asynchronously
|
||||||
public static handlePublicKey(parsedMessage: ParsedMessage): ParsedMessage {
|
public static async handlePublicKey(parsedMessage: ParsedMessage): Promise<ParsedMessage> {
|
||||||
const clientPublicKey = parsedMessage.metaInfo?.publicKey;
|
const clientPublicKey = parsedMessage.metaInfo?.publicKey;
|
||||||
if (clientPublicKey) {
|
if (clientPublicKey) {
|
||||||
return {
|
return {
|
||||||
operationCode: GeneralOperations.operationCodes.SET_PUBLIC_KEY,
|
operationCode: GeneralOperations.operationCodes.SET_PUBLIC_KEY,
|
||||||
metaInfo: { message: clientPublicKey },
|
metaInfo: { publicKey: clientPublicKey },
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
@@ -50,13 +51,14 @@ export class GeneralOperations extends OperationBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle AES key exchange
|
// Handle AES key exchange asynchronously
|
||||||
public static handleAESKey(parsedMessage: ParsedMessage): ParsedMessage {
|
public static async handleAESKey(parsedMessage: ParsedMessage): Promise<ParsedMessage> {
|
||||||
const aesKey = parsedMessage.metaInfo?.aesKey;
|
const aesKey = parsedMessage.metaInfo?.aesKey;
|
||||||
if (aesKey) {
|
const aesIv = parsedMessage.metaInfo?.aesIv;
|
||||||
|
if (aesKey && aesIv) {
|
||||||
return {
|
return {
|
||||||
operationCode: GeneralOperations.operationCodes.SET_AES_KEY,
|
operationCode: GeneralOperations.operationCodes.SET_AES_KEY,
|
||||||
metaInfo: { message: aesKey },
|
metaInfo: { aesKey, aesIv },
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
@@ -66,14 +68,22 @@ export class GeneralOperations extends OperationBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default async handler for OK operation
|
||||||
|
public static async handleOk(parsedMessage: ParsedMessage): Promise<ParsedMessage> {
|
||||||
|
return parsedMessage; // Acknowledge with OK, returning as-is
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default async handler for ERR operation
|
||||||
|
public static async handleErr(parsedMessage: ParsedMessage): Promise<ParsedMessage> {
|
||||||
|
return parsedMessage; // Log the error and return
|
||||||
|
}
|
||||||
|
|
||||||
// Register general operations with the OperationHandler
|
// Register general operations with the OperationHandler
|
||||||
public register(operationHandler: OperationHandler): void {
|
public register(operationHandler: OperationHandler): void {
|
||||||
// Register specific handlers for the general operations
|
|
||||||
operationHandler.registerHandler(GeneralOperations.operationCodes.HEARTBEAT, GeneralOperations.handleHeartbeat);
|
operationHandler.registerHandler(GeneralOperations.operationCodes.HEARTBEAT, GeneralOperations.handleHeartbeat);
|
||||||
operationHandler.registerHandler(GeneralOperations.operationCodes.SET_PUBLIC_KEY, GeneralOperations.handlePublicKey);
|
operationHandler.registerHandler(GeneralOperations.operationCodes.SET_PUBLIC_KEY, GeneralOperations.handlePublicKey);
|
||||||
operationHandler.registerHandler(GeneralOperations.operationCodes.SET_AES_KEY, GeneralOperations.handleAESKey); // Register AES key handler
|
operationHandler.registerHandler(GeneralOperations.operationCodes.SET_AES_KEY, GeneralOperations.handleAESKey);
|
||||||
|
operationHandler.registerHandler(GeneralOperations.operationCodes.OK, GeneralOperations.handleOk);
|
||||||
// Register common operations inherited from the base class
|
operationHandler.registerHandler(GeneralOperations.operationCodes.ERR, GeneralOperations.handleErr);
|
||||||
OperationBase.registerCommonOperations(operationHandler);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,90 +1,39 @@
|
|||||||
import { ParsedMessage } from '../message_handler';
|
import { ParsedMessage } from '../message_handler';
|
||||||
import { keyDatabase } from '../../db_managers/db';
|
import { keyDatabase } from '../../db_managers/db';
|
||||||
import { OperationBase } from '../operations_base/operation_base';
|
|
||||||
import { OperationHandler } from '../operations_base/operation_handler';
|
import { OperationHandler } from '../operations_base/operation_handler';
|
||||||
|
import { OperationPlugin } from '../operations_base/operation_plugin';
|
||||||
|
import { operationCodes } from "../operation_codes";
|
||||||
|
|
||||||
export class KeyOperations extends OperationBase {
|
export class KeyOperations implements OperationPlugin {
|
||||||
public static readonly operationCodes = {
|
public static readonly operationCodes = {
|
||||||
...OperationBase.operationCodes,
|
|
||||||
GET_KEYS: 'GET_KEYS',
|
GET_KEYS: 'GET_KEYS',
|
||||||
CREATE_KEY: 'CREATE_KEY',
|
CREATE_KEY: 'CREATE_KEY',
|
||||||
DELETE_KEY: 'DELETE_KEY',
|
DELETE_KEY: 'DELETE_KEY',
|
||||||
FIND_KEY_BY_USER_ID: 'FIND_KEY_BY_USER_ID',
|
FIND_KEY_BY_USER_ID: 'FIND_KEY_BY_USER_ID',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get all keys
|
public static async handleGetKeys(): Promise<ParsedMessage> {
|
||||||
public static handleGetKeys(): ParsedMessage {
|
|
||||||
const keys = keyDatabase.getAllKeys();
|
const keys = keyDatabase.getAllKeys();
|
||||||
console.log(keys);
|
return { operationCode: operationCodes.OK, metaInfo: { keys } };
|
||||||
return {
|
|
||||||
operationCode: KeyOperations.operationCodes.OK,
|
|
||||||
metaInfo: { keys },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a key for a user
|
public static async handleCreateKey(parsedMessage: ParsedMessage): Promise<ParsedMessage> {
|
||||||
public static handleCreateKey(parsedMessage: ParsedMessage): ParsedMessage {
|
|
||||||
const { userId } = parsedMessage.metaInfo || {};
|
const { userId } = parsedMessage.metaInfo || {};
|
||||||
|
|
||||||
if (!userId) {
|
|
||||||
return {
|
|
||||||
operationCode: KeyOperations.operationCodes.ERR,
|
|
||||||
metaInfo: { message: 'User ID is required to create a key.' },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the key for the user
|
|
||||||
const key = keyDatabase.createKey(userId);
|
const key = keyDatabase.createKey(userId);
|
||||||
return {
|
return { operationCode: operationCodes.OK, metaInfo: { key } };
|
||||||
operationCode: KeyOperations.operationCodes.OK,
|
|
||||||
metaInfo: { key },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find a key by user ID
|
public static async handleFindKeyByUserId(parsedMessage: ParsedMessage): Promise<ParsedMessage> {
|
||||||
public static handleFindKeyByUserId(parsedMessage: ParsedMessage): ParsedMessage {
|
|
||||||
const { userId } = parsedMessage.metaInfo || {};
|
const { userId } = parsedMessage.metaInfo || {};
|
||||||
|
|
||||||
if (!userId) {
|
|
||||||
return {
|
|
||||||
operationCode: KeyOperations.operationCodes.ERR,
|
|
||||||
metaInfo: { message: 'User ID is required.' },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const key = keyDatabase.findByUserId(userId);
|
const key = keyDatabase.findByUserId(userId);
|
||||||
return {
|
return key
|
||||||
operationCode: key === null ? KeyOperations.operationCodes.ERR : KeyOperations.operationCodes.OK,
|
? { operationCode: operationCodes.OK, metaInfo: { key } }
|
||||||
metaInfo: key === null ? { message: 'Key not found.' } : { key },
|
: { operationCode: operationCodes.ERR, metaInfo: { message: 'Key not found.' } };
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete a key by user ID
|
|
||||||
public static handleDeleteKey(parsedMessage: ParsedMessage): ParsedMessage {
|
|
||||||
const { userId } = parsedMessage.metaInfo || {};
|
|
||||||
|
|
||||||
if (!userId) {
|
|
||||||
return {
|
|
||||||
operationCode: KeyOperations.operationCodes.ERR,
|
|
||||||
metaInfo: { message: 'User ID is required for deletion.' },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const isSuccess = keyDatabase.deleteKeysByUserId(userId);
|
|
||||||
return {
|
|
||||||
operationCode: isSuccess ? KeyOperations.operationCodes.OK : KeyOperations.operationCodes.ERR,
|
|
||||||
metaInfo: { message: isSuccess ? 'Key deleted successfully.' : 'Failed to delete key.' },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register key operations with the OperationHandler
|
|
||||||
public register(operationHandler: OperationHandler): void {
|
public register(operationHandler: OperationHandler): void {
|
||||||
operationHandler.registerHandler(KeyOperations.operationCodes.GET_KEYS, KeyOperations.handleGetKeys);
|
operationHandler.registerHandler(KeyOperations.operationCodes.GET_KEYS, KeyOperations.handleGetKeys);
|
||||||
operationHandler.registerHandler(KeyOperations.operationCodes.CREATE_KEY, KeyOperations.handleCreateKey);
|
operationHandler.registerHandler(KeyOperations.operationCodes.CREATE_KEY, KeyOperations.handleCreateKey);
|
||||||
operationHandler.registerHandler(KeyOperations.operationCodes.DELETE_KEY, KeyOperations.handleDeleteKey);
|
|
||||||
operationHandler.registerHandler(KeyOperations.operationCodes.FIND_KEY_BY_USER_ID, KeyOperations.handleFindKeyByUserId);
|
operationHandler.registerHandler(KeyOperations.operationCodes.FIND_KEY_BY_USER_ID, KeyOperations.handleFindKeyByUserId);
|
||||||
|
|
||||||
// Register common operations inherited from OperationBase
|
|
||||||
OperationBase.registerCommonOperations(operationHandler);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { ParsedMessage } from '../message_handler';
|
import { ParsedMessage } from '../message_handler';
|
||||||
import { userDatabase } from '../../db_managers/db';
|
import { userDatabase } from '../../db_managers/db';
|
||||||
import { OperationBase } from '../operations_base/operation_base';
|
|
||||||
import { OperationHandler } from '../operations_base/operation_handler';
|
import { OperationHandler } from '../operations_base/operation_handler';
|
||||||
|
import { OperationPlugin } from '../operations_base/operation_plugin';
|
||||||
|
import { operationCodes} from "../operation_codes";
|
||||||
|
|
||||||
export class UserOperations extends OperationBase {
|
export class UserOperations implements OperationPlugin {
|
||||||
public static readonly operationCodes = {
|
public static readonly operationCodes = {
|
||||||
...OperationBase.operationCodes,
|
|
||||||
GET_USERS: 'GET_USERS',
|
GET_USERS: 'GET_USERS',
|
||||||
CREATE_USER: 'CREATE_USER',
|
CREATE_USER: 'CREATE_USER',
|
||||||
MODIFY_USER: 'MODIFY_USER',
|
MODIFY_USER: 'MODIFY_USER',
|
||||||
@@ -14,123 +14,30 @@ export class UserOperations extends OperationBase {
|
|||||||
FIND_BY_EMAIL: 'FIND_BY_EMAIL',
|
FIND_BY_EMAIL: 'FIND_BY_EMAIL',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get all users
|
public static async handleGetUsers(): Promise<ParsedMessage> {
|
||||||
public static handleGetUsers(): ParsedMessage {
|
|
||||||
const users = userDatabase.getAllUsers();
|
const users = userDatabase.getAllUsers();
|
||||||
console.log(users);
|
return { operationCode: operationCodes.OK, metaInfo: { users } };
|
||||||
return {
|
|
||||||
operationCode: UserOperations.operationCodes.OK,
|
|
||||||
metaInfo: { users },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static handleGetUserById(parsedMessage: ParsedMessage): ParsedMessage {
|
public static async handleGetUserById(parsedMessage: ParsedMessage): Promise<ParsedMessage> {
|
||||||
const { id } = parsedMessage.metaInfo || {};
|
const { id } = parsedMessage.metaInfo || {};
|
||||||
|
|
||||||
if(!id){
|
|
||||||
return {
|
|
||||||
operationCode: UserOperations.operationCodes.ERR,
|
|
||||||
metaInfo: { message: 'Id is required.' },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const user = userDatabase.findById(id);
|
const user = userDatabase.findById(id);
|
||||||
return {
|
return user
|
||||||
operationCode: user === null ? UserOperations.operationCodes.ERR : UserOperations.operationCodes.OK,
|
? { operationCode: operationCodes.OK, metaInfo: { user } }
|
||||||
metaInfo: user === null ? { message: 'User not found.' } : { message: user }
|
: { operationCode: operationCodes.ERR, metaInfo: { message: 'User not found.' } };
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static handleGetUserByEmail(parsedMessage: ParsedMessage) : ParsedMessage{
|
public static async handleModifyUser(parsedMessage: ParsedMessage): Promise<ParsedMessage> {
|
||||||
const { email } = parsedMessage.metaInfo || {};
|
|
||||||
if(!email){
|
|
||||||
return {
|
|
||||||
operationCode: UserOperations.operationCodes.ERR,
|
|
||||||
metaInfo: { message: 'Email is required.' },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const user = userDatabase.findByEmail(email);
|
|
||||||
const response = {
|
|
||||||
operationCode: user === null ? UserOperations.operationCodes.ERR : UserOperations.operationCodes.OK,
|
|
||||||
metaInfo: user === null ? { message: 'User not found.' } : user
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(response);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Modify an existing user
|
|
||||||
public static handleModifyUser(parsedMessage: ParsedMessage): ParsedMessage {
|
|
||||||
const { id, name, email, password, departmentId, app_type } = parsedMessage.metaInfo || {};
|
const { id, name, email, password, departmentId, app_type } = parsedMessage.metaInfo || {};
|
||||||
|
const success = userDatabase.modifyUser(id, name, email, password, departmentId, app_type);
|
||||||
if (!id || !name || !email || !password || !departmentId || !app_type) {
|
return success
|
||||||
return {
|
? { operationCode: operationCodes.OK, metaInfo: { message: 'User modified successfully.' } }
|
||||||
operationCode: UserOperations.operationCodes.ERR,
|
: { operationCode: operationCodes.ERR, metaInfo: { message: 'Failed to modify user.' } };
|
||||||
metaInfo: { message: 'Some information are missing.' },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = userDatabase.findById(id);
|
|
||||||
if (!user) return {
|
|
||||||
operationCode: UserOperations.operationCodes.ERR,
|
|
||||||
metaInfo: { message: 'User not found in the system.' },
|
|
||||||
};
|
|
||||||
|
|
||||||
const listOfUsers = userDatabase.getAllUsers()
|
|
||||||
|
|
||||||
// Check if another user already exists with the same email or name (excluding the current user)
|
|
||||||
const existingUserByEmail = listOfUsers.find((existingUser) => existingUser.email === email && existingUser.id !== id);
|
|
||||||
const existingUserByName = listOfUsers.find((existingUser) => existingUser.name === name && existingUser.id !== id);
|
|
||||||
|
|
||||||
if (existingUserByEmail) {
|
|
||||||
return {
|
|
||||||
operationCode: UserOperations.operationCodes.ERR,
|
|
||||||
metaInfo: { message: `Email ${email} is already in use by another user.` },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (existingUserByName) {
|
|
||||||
return {
|
|
||||||
operationCode: UserOperations.operationCodes.ERR,
|
|
||||||
metaInfo: { message: `Name ${name} is already in use by another user.` },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const isSuccess = userDatabase.modifyUser(id, name, email, password, departmentId, app_type);
|
|
||||||
return {
|
|
||||||
operationCode: isSuccess ? UserOperations.operationCodes.OK : UserOperations.operationCodes.ERR,
|
|
||||||
metaInfo: { message: isSuccess ? 'User modified successfully.' : 'Failed to modify user.' },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete a user by ID
|
|
||||||
public static handleDeleteUser(parsedMessage: ParsedMessage): ParsedMessage {
|
|
||||||
const { id } = parsedMessage.metaInfo || {};
|
|
||||||
|
|
||||||
if (!id) {
|
|
||||||
return {
|
|
||||||
operationCode: UserOperations.operationCodes.ERR,
|
|
||||||
metaInfo: { message: 'User ID is required for deletion.' },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const isSuccess = userDatabase.deleteUser(id);
|
|
||||||
return {
|
|
||||||
operationCode: isSuccess ? UserOperations.operationCodes.OK : UserOperations.operationCodes.ERR,
|
|
||||||
metaInfo: { message: isSuccess ? 'User deleted successfully.' : 'Failed to delete user.' },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register user operations with the OperationHandler
|
|
||||||
public register(operationHandler: OperationHandler): void {
|
public register(operationHandler: OperationHandler): void {
|
||||||
operationHandler.registerHandler(UserOperations.operationCodes.GET_USERS, UserOperations.handleGetUsers);
|
operationHandler.registerHandler(UserOperations.operationCodes.GET_USERS, UserOperations.handleGetUsers);
|
||||||
operationHandler.registerHandler(UserOperations.operationCodes.MODIFY_USER, UserOperations.handleModifyUser);
|
operationHandler.registerHandler(UserOperations.operationCodes.MODIFY_USER, UserOperations.handleModifyUser);
|
||||||
operationHandler.registerHandler(UserOperations.operationCodes.DELETE_USER, UserOperations.handleDeleteUser);
|
|
||||||
operationHandler.registerHandler(UserOperations.operationCodes.FIND_BY_ID, UserOperations.handleGetUserById);
|
operationHandler.registerHandler(UserOperations.operationCodes.FIND_BY_ID, UserOperations.handleGetUserById);
|
||||||
operationHandler.registerHandler(UserOperations.operationCodes.FIND_BY_EMAIL, UserOperations.handleGetUserByEmail);
|
|
||||||
|
|
||||||
// Register common operations inherited from OperationBase
|
|
||||||
OperationBase.registerCommonOperations(operationHandler);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Socket } from 'net';
|
|||||||
import { MessageHandler } from '../message_handler';
|
import { MessageHandler } from '../message_handler';
|
||||||
import { SocketCommunicatorBase } from './socket_communicator_base';
|
import { SocketCommunicatorBase } from './socket_communicator_base';
|
||||||
import { OperationHandler } from '../operations_base/operation_handler';
|
import { OperationHandler } from '../operations_base/operation_handler';
|
||||||
|
import {operationCodes} from "../operation_codes";
|
||||||
|
|
||||||
export class TcpServerCommunicator extends SocketCommunicatorBase {
|
export class TcpServerCommunicator extends SocketCommunicatorBase {
|
||||||
private readonly socket: Socket;
|
private readonly socket: Socket;
|
||||||
@@ -17,7 +18,7 @@ export class TcpServerCommunicator extends SocketCommunicatorBase {
|
|||||||
throw new Error('RSA key pair is not available. Please generate RSA key pair.');
|
throw new Error('RSA key pair is not available. Please generate RSA key pair.');
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.sendMessage('SET_PUBLIC_KEY', { publicKey: this.publicKey });
|
await this.sendMessage(operationCodes.SET_PUBLIC_KEY, { publicKey: this.publicKey });
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendAesKey(): Promise<void> {
|
async sendAesKey(): Promise<void> {
|
||||||
@@ -28,7 +29,7 @@ export class TcpServerCommunicator extends SocketCommunicatorBase {
|
|||||||
|
|
||||||
const aesKeyBase64 = this.aesKey.toString('base64');
|
const aesKeyBase64 = this.aesKey.toString('base64');
|
||||||
const aesIvBase64 = this.aesIv.toString('base64');
|
const aesIvBase64 = this.aesIv.toString('base64');
|
||||||
await this.sendMessage('SET_AES_KEY', { aesKey: aesKeyBase64, aesIv: aesIvBase64 });
|
await this.sendMessage(operationCodes.SET_AES_KEY, { aesKey: aesKeyBase64, aesIv: aesIvBase64 });
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleIncomingMessage(incomingMessage: string): Promise<void> {
|
async handleIncomingMessage(incomingMessage: string): Promise<void> {
|
||||||
@@ -45,10 +46,10 @@ export class TcpServerCommunicator extends SocketCommunicatorBase {
|
|||||||
|
|
||||||
let outgoingMessage: string;
|
let outgoingMessage: string;
|
||||||
switch (operationCode) {
|
switch (operationCode) {
|
||||||
case 'SET_PUBLIC_KEY':
|
case operationCodes.SET_PUBLIC_KEY:
|
||||||
outgoingMessage = Buffer.from(message, 'utf-8').toString('base64');
|
outgoingMessage = Buffer.from(message, 'utf-8').toString('base64');
|
||||||
break;
|
break;
|
||||||
case 'SET_AES_KEY':
|
case operationCodes.SET_AES_KEY:
|
||||||
outgoingMessage = this.encryptWithRsa(message);
|
outgoingMessage = this.encryptWithRsa(message);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -22,16 +22,19 @@ export class TcpClientCommunicator extends SocketCommunicatorBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setServerPublicKey(publicKey: string): void {
|
setServerPublicKey(publicKey: string): void {
|
||||||
|
console.log('\n\nSetting server public key\n\n');
|
||||||
this.publicKey = publicKey;
|
this.publicKey = publicKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
setAesKey(aesKey: string, aesIv: string): void {
|
setAesKey(aesKey: string, aesIv: string): void {
|
||||||
|
console.log('\n\nSetting AES key\n\n');
|
||||||
this.aesKey = Buffer.from(aesKey, 'base64');
|
this.aesKey = Buffer.from(aesKey, 'base64');
|
||||||
this.aesIv = Buffer.from(aesIv, 'base64');
|
this.aesIv = Buffer.from(aesIv, 'base64');
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleIncomingMessage(incomingMessage: string): Promise<void> {
|
async handleIncomingMessage(incomingMessage: string): Promise<void> {
|
||||||
let messageToProcess;
|
let messageToProcess;
|
||||||
|
|
||||||
if (this.aesKey && this.aesIv) {
|
if (this.aesKey && this.aesIv) {
|
||||||
messageToProcess = this.decryptWithAes(incomingMessage);
|
messageToProcess = this.decryptWithAes(incomingMessage);
|
||||||
} else if (this.publicKey) {
|
} else if (this.publicKey) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Socket } from 'net';
|
|||||||
import { MessageHandler } from '../message_handler';
|
import { MessageHandler } from '../message_handler';
|
||||||
import { SocketCommunicatorBase } from './socket_communicator_base';
|
import { SocketCommunicatorBase } from './socket_communicator_base';
|
||||||
import { OperationHandler } from '../operations_base/operation_handler';
|
import { OperationHandler } from '../operations_base/operation_handler';
|
||||||
|
import {operationCodes} from "../operation_codes";
|
||||||
|
|
||||||
export class TcpServerCommunicator extends SocketCommunicatorBase {
|
export class TcpServerCommunicator extends SocketCommunicatorBase {
|
||||||
private readonly socket: Socket;
|
private readonly socket: Socket;
|
||||||
@@ -17,7 +18,7 @@ export class TcpServerCommunicator extends SocketCommunicatorBase {
|
|||||||
throw new Error('RSA key pair is not available. Please generate RSA key pair.');
|
throw new Error('RSA key pair is not available. Please generate RSA key pair.');
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.sendMessage('SET_PUBLIC_KEY', { publicKey: this.publicKey });
|
await this.sendMessage(operationCodes.SET_PUBLIC_KEY, { publicKey: this.publicKey });
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendAesKey(): Promise<void> {
|
async sendAesKey(): Promise<void> {
|
||||||
@@ -28,7 +29,7 @@ export class TcpServerCommunicator extends SocketCommunicatorBase {
|
|||||||
|
|
||||||
const aesKeyBase64 = this.aesKey.toString('base64');
|
const aesKeyBase64 = this.aesKey.toString('base64');
|
||||||
const aesIvBase64 = this.aesIv.toString('base64');
|
const aesIvBase64 = this.aesIv.toString('base64');
|
||||||
await this.sendMessage('SET_AES_KEY', { aesKey: aesKeyBase64, aesIv: aesIvBase64 });
|
await this.sendMessage(operationCodes.SET_AES_KEY, { aesKey: aesKeyBase64, aesIv: aesIvBase64 });
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleIncomingMessage(incomingMessage: string): Promise<void> {
|
async handleIncomingMessage(incomingMessage: string): Promise<void> {
|
||||||
@@ -45,10 +46,10 @@ export class TcpServerCommunicator extends SocketCommunicatorBase {
|
|||||||
|
|
||||||
let outgoingMessage: string;
|
let outgoingMessage: string;
|
||||||
switch (operationCode) {
|
switch (operationCode) {
|
||||||
case 'SET_PUBLIC_KEY':
|
case operationCodes.SET_PUBLIC_KEY:
|
||||||
outgoingMessage = Buffer.from(message, 'utf-8').toString('base64');
|
outgoingMessage = Buffer.from(message, 'utf-8').toString('base64');
|
||||||
break;
|
break;
|
||||||
case 'SET_AES_KEY':
|
case operationCodes.SET_AES_KEY:
|
||||||
outgoingMessage = this.encryptWithRsa(message);
|
outgoingMessage = this.encryptWithRsa(message);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
Reference in New Issue
Block a user