Rm some leftovers
This commit is contained in:
parent
888ca48712
commit
c07591a97a
@ -1,449 +0,0 @@
|
|||||||
import { Request, Response } from 'express';
|
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
|
||||||
import { Database } from '../database';
|
|
||||||
import { SignerImprovedService } from '../services/signer-improved';
|
|
||||||
import { SessionManager } from '../utils/session-manager';
|
|
||||||
import { authTokens } from '../utils/auth-tokens';
|
|
||||||
import { ProcessInfo, ProcessData, ProcessRoles, EOfficeStatus } from '../types';
|
|
||||||
import { config } from '../config';
|
|
||||||
import { Logger } from '../utils/logger';
|
|
||||||
import {
|
|
||||||
AppError,
|
|
||||||
ErrorCode,
|
|
||||||
NotFoundError,
|
|
||||||
ExternalServiceError,
|
|
||||||
BusinessRuleError
|
|
||||||
} from '../types/errors';
|
|
||||||
import { asyncHandler } from '../middleware/error-handler';
|
|
||||||
|
|
||||||
export class ProcessImprovedController {
|
|
||||||
static getUserProcess = asyncHandler(async (req: Request, res: Response): Promise<void> => {
|
|
||||||
const requestId = req.headers['x-request-id'] as string;
|
|
||||||
|
|
||||||
Logger.info('User process request initiated', { requestId });
|
|
||||||
|
|
||||||
// Find the full token data which should contain the original idNotUser data
|
|
||||||
const userAuth = authTokens.find(auth => auth.authToken === req.idNotUser!.authToken);
|
|
||||||
|
|
||||||
if (!userAuth || !userAuth.idNotUser) {
|
|
||||||
throw new NotFoundError('Données utilisateur non trouvées. Veuillez vous reconnecter.', requestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
const { pairingId } = req.query;
|
|
||||||
|
|
||||||
// Execute signer operations with retry logic
|
|
||||||
const processResult = await SignerImprovedService.executeWithRetry(
|
|
||||||
async (signerClient) => {
|
|
||||||
return await signerClient.getUserProcessByIdnot(userAuth.idNotUser.idNot);
|
|
||||||
},
|
|
||||||
'getUserProcessByIdnot',
|
|
||||||
3
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!processResult.success) {
|
|
||||||
throw new ExternalServiceError('Signer', processResult.error?.message || 'Failed to get user process', requestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
let process: ProcessInfo | null = processResult.data || null;
|
|
||||||
|
|
||||||
if (!process) {
|
|
||||||
Logger.info('No existing process found, creating new one', {
|
|
||||||
requestId,
|
|
||||||
userIdNot: userAuth.idNotUser.idNot
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get UUID from database
|
|
||||||
let uuid: string;
|
|
||||||
try {
|
|
||||||
const result = await Database.query('SELECT uid FROM users WHERE "idNot" = $1', [userAuth.idNotUser.idNot]);
|
|
||||||
uuid = result.rows.length > 0 ? result.rows[0].uid : null;
|
|
||||||
} catch (error) {
|
|
||||||
Logger.error('Error fetching UUID by idNot', {
|
|
||||||
requestId,
|
|
||||||
error: error instanceof Error ? error.message : 'Unknown error'
|
|
||||||
});
|
|
||||||
uuid = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!uuid) {
|
|
||||||
Logger.info('No existing UUID found in db, generating new one', { requestId });
|
|
||||||
uuid = uuidv4();
|
|
||||||
}
|
|
||||||
|
|
||||||
const processData: ProcessData = {
|
|
||||||
uid: uuid,
|
|
||||||
utype: 'collaborator',
|
|
||||||
idNot: userAuth.idNotUser.idNot,
|
|
||||||
office: {
|
|
||||||
idNot: userAuth.idNotUser.office.idNot,
|
|
||||||
},
|
|
||||||
role: userAuth.idNotUser.role,
|
|
||||||
office_role: userAuth.idNotUser.office_role,
|
|
||||||
contact: userAuth.idNotUser.contact,
|
|
||||||
};
|
|
||||||
|
|
||||||
const privateFields = Object.keys(processData);
|
|
||||||
const allFields = [...privateFields, 'roles'];
|
|
||||||
// Make those fields public
|
|
||||||
privateFields.splice(privateFields.indexOf('uid'), 1);
|
|
||||||
privateFields.splice(privateFields.indexOf('utype'), 1);
|
|
||||||
privateFields.splice(privateFields.indexOf('idNot'), 1);
|
|
||||||
|
|
||||||
// Get pairing ID with retry
|
|
||||||
const pairingResult = await SignerImprovedService.executeWithRetry(
|
|
||||||
async (signerClient) => {
|
|
||||||
return await signerClient.getPairingId();
|
|
||||||
},
|
|
||||||
'getPairingId',
|
|
||||||
3
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!pairingResult.success) {
|
|
||||||
throw new ExternalServiceError('Signer', pairingResult.error?.message || 'Failed to get pairing ID', requestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
const validatorId = pairingResult.data!.pairingId;
|
|
||||||
|
|
||||||
const roles: ProcessRoles = {
|
|
||||||
owner: {
|
|
||||||
members: [pairingId as string, validatorId],
|
|
||||||
validation_rules: [
|
|
||||||
{
|
|
||||||
quorum: 0.1,
|
|
||||||
fields: allFields,
|
|
||||||
min_sig_member: 1,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
storages: [config.defaultStorage]
|
|
||||||
},
|
|
||||||
apophis: {
|
|
||||||
members: [pairingId as string, validatorId],
|
|
||||||
validation_rules: [],
|
|
||||||
storages: []
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create process with retry
|
|
||||||
const createResult = await SignerImprovedService.executeWithRetry(
|
|
||||||
async (signerClient) => {
|
|
||||||
return await signerClient.createProcess(processData, privateFields, roles);
|
|
||||||
},
|
|
||||||
'createProcess',
|
|
||||||
3
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!createResult.success) {
|
|
||||||
throw new ExternalServiceError('Signer', createResult.error?.message || 'Failed to create process', requestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.info('Created new process', {
|
|
||||||
requestId,
|
|
||||||
processId: createResult.data!.processId
|
|
||||||
});
|
|
||||||
|
|
||||||
process = {
|
|
||||||
processId: createResult.data!.processId || '',
|
|
||||||
processData: createResult.data!.data
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
Logger.info('Using existing process', {
|
|
||||||
requestId,
|
|
||||||
processId: process.processId
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if process is committed and handle role updates
|
|
||||||
const processManagementResult = await SignerImprovedService.executeWithRetry(
|
|
||||||
async (signerClient) => {
|
|
||||||
const allProcesses = await signerClient.getOwnedProcesses();
|
|
||||||
|
|
||||||
if (allProcesses && process) {
|
|
||||||
const processStates = allProcesses.processes[process.processId].states;
|
|
||||||
const isNotCommited = processStates.length === 2
|
|
||||||
&& processStates[1].commited_in === processStates[0].commited_in;
|
|
||||||
|
|
||||||
if (isNotCommited) {
|
|
||||||
Logger.info('Process not committed, committing it', {
|
|
||||||
requestId,
|
|
||||||
processId: process.processId
|
|
||||||
});
|
|
||||||
await signerClient.validateState(process.processId, processStates[0].state_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check pairing ID in roles
|
|
||||||
let roles: ProcessRoles;
|
|
||||||
if (isNotCommited) {
|
|
||||||
const firstState = processStates[0];
|
|
||||||
roles = firstState.roles;
|
|
||||||
} else {
|
|
||||||
const tip = processStates[processStates.length - 1].commited_in;
|
|
||||||
const lastState = processStates.findLast((state: any) => state.commited_in !== tip);
|
|
||||||
roles = lastState.roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!roles) {
|
|
||||||
throw new Error('No roles found');
|
|
||||||
} else if (!roles['owner']) {
|
|
||||||
throw new Error('No owner role found');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!roles['owner'].members.includes(req.query.pairingId as string)) {
|
|
||||||
Logger.info('Adding new pairingId to owner role', {
|
|
||||||
requestId,
|
|
||||||
pairingId: req.query.pairingId,
|
|
||||||
processId: process.processId
|
|
||||||
});
|
|
||||||
|
|
||||||
roles['owner'].members.push(req.query.pairingId as string);
|
|
||||||
const updatedProcessReturn = await signerClient.updateProcess(process.processId, {}, [], roles);
|
|
||||||
const processId = updatedProcessReturn.updatedProcess.process_id;
|
|
||||||
const stateId = updatedProcessReturn.updatedProcess.diffs[0].state_id;
|
|
||||||
await signerClient.notifyUpdate(processId, stateId);
|
|
||||||
await signerClient.validateState(processId, stateId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return process;
|
|
||||||
},
|
|
||||||
'processManagement',
|
|
||||||
2
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!processManagementResult.success) {
|
|
||||||
throw new ExternalServiceError('Signer', processManagementResult.error?.message || 'Failed to manage process', requestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.info('User process request completed successfully', {
|
|
||||||
requestId,
|
|
||||||
processId: process?.processId
|
|
||||||
});
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
data: processManagementResult.data
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
static getOfficeProcess = asyncHandler(async (req: Request, res: Response): Promise<void> => {
|
|
||||||
const requestId = req.headers['x-request-id'] as string;
|
|
||||||
|
|
||||||
Logger.info('Office process request initiated', { requestId });
|
|
||||||
|
|
||||||
const userAuth = authTokens.find(auth => auth.authToken === req.idNotUser!.authToken);
|
|
||||||
|
|
||||||
if (!userAuth || !userAuth.idNotUser) {
|
|
||||||
throw new NotFoundError('Données utilisateur non trouvées. Veuillez vous reconnecter.', requestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check office status
|
|
||||||
if (userAuth.idNotUser.office.office_status !== EOfficeStatus.ACTIVATED) {
|
|
||||||
throw new BusinessRuleError('Office not activated', undefined, requestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get office process with retry
|
|
||||||
const processResult = await SignerImprovedService.executeWithRetry(
|
|
||||||
async (signerClient) => {
|
|
||||||
return await signerClient.getOfficeProcessByIdnot(userAuth.idNotUser.office.idNot);
|
|
||||||
},
|
|
||||||
'getOfficeProcessByIdnot',
|
|
||||||
3
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!processResult.success) {
|
|
||||||
throw new ExternalServiceError('Signer', processResult.error?.message || 'Failed to get office process', requestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
let process: ProcessInfo | null = processResult.data || null;
|
|
||||||
|
|
||||||
if (!process) {
|
|
||||||
Logger.info('No existing office process found, creating new one', {
|
|
||||||
requestId,
|
|
||||||
officeIdNot: userAuth.idNotUser.office.idNot
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get validator ID with retry
|
|
||||||
const pairingResult = await SignerImprovedService.executeWithRetry(
|
|
||||||
async (signerClient) => {
|
|
||||||
return await signerClient.getPairingId();
|
|
||||||
},
|
|
||||||
'getPairingId',
|
|
||||||
3
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!pairingResult.success) {
|
|
||||||
throw new ExternalServiceError('Signer', pairingResult.error?.message || 'Failed to get validator ID', requestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
const validatorId = pairingResult.data!.pairingId;
|
|
||||||
if (!validatorId) {
|
|
||||||
throw new BusinessRuleError('No validator id found', undefined, requestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get UUID from database
|
|
||||||
let uuid: string;
|
|
||||||
try {
|
|
||||||
const result = await Database.query('SELECT uid FROM offices WHERE "idNot" = $1', [userAuth.idNotUser.office.idNot]);
|
|
||||||
uuid = result.rows.length > 0 ? result.rows[0].uid : null;
|
|
||||||
} catch (error) {
|
|
||||||
Logger.error('Error fetching office UUID by idNot', {
|
|
||||||
requestId,
|
|
||||||
error: error instanceof Error ? error.message : 'Unknown error'
|
|
||||||
});
|
|
||||||
uuid = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!uuid) {
|
|
||||||
Logger.info('No existing office UUID found in db, generating new one', { requestId });
|
|
||||||
uuid = uuidv4();
|
|
||||||
}
|
|
||||||
|
|
||||||
const processData: ProcessData = {
|
|
||||||
uid: uuid,
|
|
||||||
utype: 'office',
|
|
||||||
...userAuth.idNotUser.office,
|
|
||||||
};
|
|
||||||
|
|
||||||
const privateFields = Object.keys(processData);
|
|
||||||
|
|
||||||
const roles: ProcessRoles = {
|
|
||||||
owner: {
|
|
||||||
members: [validatorId],
|
|
||||||
validation_rules: [],
|
|
||||||
storages: []
|
|
||||||
},
|
|
||||||
apophis: {
|
|
||||||
members: [validatorId],
|
|
||||||
validation_rules: [],
|
|
||||||
storages: []
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create office process with retry
|
|
||||||
const createResult = await SignerImprovedService.executeWithRetry(
|
|
||||||
async (signerClient) => {
|
|
||||||
return await signerClient.createProcess(processData, privateFields, roles);
|
|
||||||
},
|
|
||||||
'createOfficeProcess',
|
|
||||||
3
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!createResult.success) {
|
|
||||||
throw new ExternalServiceError('Signer', createResult.error?.message || 'Failed to create office process', requestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.info('Created new office process', {
|
|
||||||
requestId,
|
|
||||||
processId: createResult.data!.processId
|
|
||||||
});
|
|
||||||
|
|
||||||
process = {
|
|
||||||
processId: createResult.data!.processId || '',
|
|
||||||
processData: createResult.data!.data
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.info('Office process request completed successfully', {
|
|
||||||
requestId,
|
|
||||||
processId: process?.processId
|
|
||||||
});
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
data: process
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
static authenticateClient = asyncHandler(async (req: Request, res: Response): Promise<void> => {
|
|
||||||
const requestId = req.headers['x-request-id'] as string;
|
|
||||||
const { pairingId } = req.body;
|
|
||||||
|
|
||||||
if (!pairingId) {
|
|
||||||
throw new BusinessRuleError('Missing pairingId', undefined, requestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.info('Client authentication initiated', { requestId, pairingId });
|
|
||||||
|
|
||||||
// This should be implemented properly based on your business logic
|
|
||||||
// For now, just clean up the session
|
|
||||||
SessionManager.deleteSession(req.session!.id);
|
|
||||||
|
|
||||||
Logger.info('Client authentication completed', { requestId });
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
message: 'Client authentication successful',
|
|
||||||
data: {}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
static getPhoneNumberForEmail = asyncHandler(async (req: Request, res: Response): Promise<void> => {
|
|
||||||
const requestId = req.headers['x-request-id'] as string;
|
|
||||||
const { email } = req.body;
|
|
||||||
|
|
||||||
if (!email) {
|
|
||||||
throw new BusinessRuleError('Missing email', undefined, requestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.info('Phone number lookup initiated', { requestId, email });
|
|
||||||
|
|
||||||
const phoneResult = await SignerImprovedService.executeWithRetry(
|
|
||||||
async (signerClient) => {
|
|
||||||
return await signerClient.getPhoneNumberForEmail(email);
|
|
||||||
},
|
|
||||||
'getPhoneNumberForEmail',
|
|
||||||
3
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!phoneResult.success) {
|
|
||||||
throw new ExternalServiceError('Signer', phoneResult.error?.message || 'Failed to get phone number', requestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
const phoneNumber = phoneResult.data;
|
|
||||||
|
|
||||||
if (!phoneNumber) {
|
|
||||||
throw new NotFoundError('No phone number found for this email', requestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.info('Phone number lookup completed', { requestId, email });
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
message: 'Phone number retrieved successfully',
|
|
||||||
phoneNumber: phoneNumber
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Health check endpoint for signer service
|
|
||||||
static getSignerHealth = asyncHandler(async (req: Request, res: Response): Promise<void> => {
|
|
||||||
const healthStatus = SignerImprovedService.getHealthStatus();
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
data: {
|
|
||||||
signer: healthStatus,
|
|
||||||
timestamp: new Date().toISOString()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Force reconnection endpoint (for debugging/admin use)
|
|
||||||
static forceSignerReconnect = asyncHandler(async (req: Request, res: Response): Promise<void> => {
|
|
||||||
const requestId = req.headers['x-request-id'] as string;
|
|
||||||
|
|
||||||
Logger.info('Force signer reconnection requested', { requestId });
|
|
||||||
|
|
||||||
const reconnectResult = await SignerImprovedService.forceReconnect();
|
|
||||||
|
|
||||||
if (!reconnectResult.success) {
|
|
||||||
throw new ExternalServiceError('Signer', reconnectResult.error?.message || 'Failed to reconnect', requestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.info('Force signer reconnection completed', { requestId });
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
message: 'Signer reconnection initiated',
|
|
||||||
data: SignerImprovedService.getHealthStatus()
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
@ -1,326 +1,464 @@
|
|||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import { Database } from '../database';
|
import { Database } from '../database';
|
||||||
import { SignerService } from '../services/signer';
|
import { SignerImprovedService } from '../services/signer-improved';
|
||||||
import { SessionManager } from '../utils/session-manager';
|
import { SessionManager } from '../utils/session-manager';
|
||||||
import { authTokens } from '../utils/auth-tokens';
|
import { authTokens } from '../utils/auth-tokens';
|
||||||
import { ProcessInfo, ProcessData, ProcessRoles, EOfficeStatus } from '../types';
|
import { ProcessInfo, ProcessData, ProcessRoles, EOfficeStatus } from '../types';
|
||||||
import { config } from '../config';
|
import { config } from '../config';
|
||||||
|
import { Logger } from '../utils/logger';
|
||||||
|
import {
|
||||||
|
AppError,
|
||||||
|
ErrorCode,
|
||||||
|
NotFoundError,
|
||||||
|
ExternalServiceError,
|
||||||
|
BusinessRuleError
|
||||||
|
} from '../types/errors';
|
||||||
|
import { asyncHandler } from '../middleware/error-handler';
|
||||||
|
import { IdNotController } from './idnot.controller';
|
||||||
|
|
||||||
export class ProcessController {
|
export class ProcessController {
|
||||||
static async getUserProcess(req: Request, res: Response): Promise<any> {
|
static getUserProcess = asyncHandler(async (req: Request, res: Response): Promise<void> => {
|
||||||
console.log('Received request to get user process');
|
const requestId = req.headers['x-request-id'] as string;
|
||||||
try {
|
|
||||||
// Find the full token data which should contain the original idNotUser data
|
Logger.info('User process request initiated', { requestId });
|
||||||
const userAuth = authTokens.find(auth => auth.authToken === req.idNotUser!.authToken);
|
|
||||||
|
|
||||||
if (!userAuth || !userAuth.idNotUser) {
|
|
||||||
return res.status(404).json({
|
|
||||||
success: false,
|
|
||||||
message: 'Données utilisateur non trouvées. Veuillez vous reconnecter.'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const { pairingId } = req.query;
|
// Find the full token data which should contain the original idNotUser data
|
||||||
const signerClient = SignerService.getInstance();
|
const userAuth = authTokens.find(auth => auth.authToken === req.idNotUser!.authToken);
|
||||||
|
|
||||||
|
if (!userAuth || !userAuth.idNotUser) {
|
||||||
|
throw new NotFoundError('Données utilisateur non trouvées. Veuillez vous reconnecter.', requestId);
|
||||||
|
}
|
||||||
|
|
||||||
// Now we ask signer if he knows a process for this office
|
const { pairingId } = req.query;
|
||||||
let process: ProcessInfo | null = await signerClient.getUserProcessByIdnot(userAuth.idNotUser.idNot);
|
|
||||||
|
|
||||||
if (!process) {
|
// Execute signer operations with retry logic
|
||||||
console.log('No existing process found in signer, creating a new one');
|
const processResult = await SignerImprovedService.executeWithRetry(
|
||||||
// We can use userInfo as data for the process
|
async (signerClient) => {
|
||||||
let uuid: string;
|
return await signerClient.getUserProcessByIdnot(userAuth.idNotUser.idNot);
|
||||||
// Try to fetch existing UUID from database by idNot
|
},
|
||||||
try {
|
'getUserProcessByIdnot',
|
||||||
const result = await Database.query('SELECT uid FROM users WHERE "idNot" = $1', [userAuth.idNotUser.idNot]);
|
3
|
||||||
uuid = result.rows.length > 0 ? result.rows[0].uid : null;
|
);
|
||||||
} catch (error) {
|
|
||||||
console.error('Error fetching UUID by idNot:', error);
|
|
||||||
uuid = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no existing UUID found, generate a new one
|
|
||||||
if (!uuid) {
|
|
||||||
console.log('No existing UUID found in db, generating a new one');
|
|
||||||
uuid = uuidv4();
|
|
||||||
}
|
|
||||||
|
|
||||||
const processData: ProcessData = {
|
if (!processResult.success) {
|
||||||
uid: uuid,
|
throw new ExternalServiceError('Signer', processResult.error?.message || 'Failed to get user process', requestId);
|
||||||
utype: 'collaborator',
|
}
|
||||||
idNot: userAuth.idNotUser.idNot,
|
|
||||||
office: {
|
|
||||||
idNot: userAuth.idNotUser.office.idNot,
|
|
||||||
},
|
|
||||||
role: userAuth.idNotUser.role,
|
|
||||||
office_role: userAuth.idNotUser.office_role,
|
|
||||||
contact: userAuth.idNotUser.contact,
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log('processData', processData);
|
let process: ProcessInfo | null = processResult.data || null;
|
||||||
|
|
||||||
const privateFields = Object.keys(processData);
|
if (!process) {
|
||||||
const allFields = [...privateFields, 'roles'];
|
Logger.info('No existing process found, creating new one', {
|
||||||
// Make those fields public
|
requestId,
|
||||||
privateFields.splice(privateFields.indexOf('uid'), 1);
|
userIdNot: userAuth.idNotUser.idNot
|
||||||
privateFields.splice(privateFields.indexOf('utype'), 1);
|
|
||||||
privateFields.splice(privateFields.indexOf('idNot'), 1);
|
|
||||||
|
|
||||||
const getPairingIdResponse = await signerClient.getPairingId();
|
|
||||||
const validatorId = getPairingIdResponse.pairingId;
|
|
||||||
|
|
||||||
const roles: ProcessRoles = {
|
|
||||||
owner: {
|
|
||||||
members: [pairingId as string, validatorId],
|
|
||||||
validation_rules: [
|
|
||||||
{
|
|
||||||
quorum: 0.1,
|
|
||||||
fields: allFields,
|
|
||||||
min_sig_member: 1,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
storages: [config.defaultStorage]
|
|
||||||
},
|
|
||||||
apophis: {
|
|
||||||
members: [pairingId as string, validatorId],
|
|
||||||
validation_rules: [],
|
|
||||||
storages: []
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const newCollaboratorProcess = await signerClient.createProcess(processData, privateFields, roles);
|
|
||||||
console.log('Created new process:', newCollaboratorProcess);
|
|
||||||
// The createProcess returns a ServerResponse, we need to extract the process info
|
|
||||||
process = { processId: newCollaboratorProcess.processId, processData: newCollaboratorProcess.data };
|
|
||||||
} else {
|
|
||||||
console.log('Using process:', process.processId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We check that the process is commited, we do it if that's not the case
|
|
||||||
const allProcesses = await signerClient.getOwnedProcesses();
|
|
||||||
if (allProcesses && process) {
|
|
||||||
const processStates = allProcesses.processes[process.processId].states;
|
|
||||||
const isNotCommited = processStates.length === 2
|
|
||||||
&& processStates[1].commited_in === processStates[0].commited_in;
|
|
||||||
if (isNotCommited) {
|
|
||||||
console.log('Process is not commited, committing it');
|
|
||||||
await signerClient.validateState(process.processId, processStates[0].state_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We check that the pairingId is indeed part of the roles
|
|
||||||
let roles: ProcessRoles;
|
|
||||||
if (isNotCommited) {
|
|
||||||
// We take the first state
|
|
||||||
const firstState = processStates[0];
|
|
||||||
roles = firstState.roles;
|
|
||||||
} else {
|
|
||||||
const tip = processStates[processStates.length - 1].commited_in;
|
|
||||||
const lastState = processStates.findLast((state: any) => state.commited_in !== tip);
|
|
||||||
roles = lastState.roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!roles) {
|
|
||||||
throw new Error('No roles found');
|
|
||||||
} else if (!roles['owner']) {
|
|
||||||
throw new Error('No owner role found');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!roles['owner'].members.includes(req.query.pairingId as string)) {
|
|
||||||
// We add the new pairingId to the owner role and commit
|
|
||||||
console.log('Adding new pairingId', req.query.pairingId, 'to owner role');
|
|
||||||
roles['owner'].members.push(req.query.pairingId as string);
|
|
||||||
const updatedProcessReturn = await signerClient.updateProcess(process.processId, {}, [], roles);
|
|
||||||
const processId = updatedProcessReturn.updatedProcess.process_id;
|
|
||||||
const stateId = updatedProcessReturn.updatedProcess.diffs[0].state_id;
|
|
||||||
await signerClient.notifyUpdate(processId, stateId);
|
|
||||||
await signerClient.validateState(processId, stateId);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new Error('No processes found');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the stored idNotUser data without the authToken
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
data: process
|
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (error: any) {
|
// Get UUID from database
|
||||||
res.status(500).json({
|
let uuid: string;
|
||||||
success: false,
|
try {
|
||||||
message: 'Erreur lors de la récupération des données utilisateur',
|
const result = await Database.query('SELECT uid FROM users WHERE "idNot" = $1', [userAuth.idNotUser.idNot]);
|
||||||
error: error.message
|
uuid = result.rows.length > 0 ? result.rows[0].uid : null;
|
||||||
|
} catch (error) {
|
||||||
|
Logger.error('Error fetching UUID by idNot', {
|
||||||
|
requestId,
|
||||||
|
error: error instanceof Error ? error.message : 'Unknown error'
|
||||||
|
});
|
||||||
|
uuid = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!uuid) {
|
||||||
|
Logger.info('No existing UUID found in db, generating new one', { requestId });
|
||||||
|
uuid = uuidv4();
|
||||||
|
}
|
||||||
|
|
||||||
|
const processData: ProcessData = {
|
||||||
|
uid: uuid,
|
||||||
|
utype: 'collaborator',
|
||||||
|
idNot: userAuth.idNotUser.idNot,
|
||||||
|
office: {
|
||||||
|
idNot: userAuth.idNotUser.office.idNot,
|
||||||
|
},
|
||||||
|
role: userAuth.idNotUser.role,
|
||||||
|
office_role: userAuth.idNotUser.office_role,
|
||||||
|
contact: userAuth.idNotUser.contact,
|
||||||
|
};
|
||||||
|
|
||||||
|
const privateFields = Object.keys(processData);
|
||||||
|
const allFields = [...privateFields, 'roles'];
|
||||||
|
// Make those fields public
|
||||||
|
privateFields.splice(privateFields.indexOf('uid'), 1);
|
||||||
|
privateFields.splice(privateFields.indexOf('utype'), 1);
|
||||||
|
privateFields.splice(privateFields.indexOf('idNot'), 1);
|
||||||
|
|
||||||
|
// Get pairing ID with retry
|
||||||
|
const pairingResult = await SignerImprovedService.executeWithRetry(
|
||||||
|
async (signerClient) => {
|
||||||
|
return await signerClient.getPairingId();
|
||||||
|
},
|
||||||
|
'getPairingId',
|
||||||
|
3
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!pairingResult.success) {
|
||||||
|
throw new ExternalServiceError('Signer', pairingResult.error?.message || 'Failed to get pairing ID', requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const validatorId = pairingResult.data!.pairingId;
|
||||||
|
|
||||||
|
const roles: ProcessRoles = {
|
||||||
|
owner: {
|
||||||
|
members: [pairingId as string, validatorId],
|
||||||
|
validation_rules: [
|
||||||
|
{
|
||||||
|
quorum: 0.1,
|
||||||
|
fields: allFields,
|
||||||
|
min_sig_member: 1,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
storages: [config.defaultStorage]
|
||||||
|
},
|
||||||
|
apophis: {
|
||||||
|
members: [pairingId as string, validatorId],
|
||||||
|
validation_rules: [],
|
||||||
|
storages: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create process with retry
|
||||||
|
const createResult = await SignerImprovedService.executeWithRetry(
|
||||||
|
async (signerClient) => {
|
||||||
|
return await signerClient.createProcess(processData, privateFields, roles);
|
||||||
|
},
|
||||||
|
'createProcess',
|
||||||
|
3
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!createResult.success) {
|
||||||
|
throw new ExternalServiceError('Signer', createResult.error?.message || 'Failed to create process', requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.info('Created new process', {
|
||||||
|
requestId,
|
||||||
|
processId: createResult.data!.processId,
|
||||||
|
processData: createResult.data!.processData
|
||||||
|
});
|
||||||
|
|
||||||
|
process = {
|
||||||
|
processId: createResult.data!.processId || '',
|
||||||
|
processData: createResult.data!.data
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
Logger.info('Using existing process', {
|
||||||
|
requestId,
|
||||||
|
processId: process.processId
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static async getOfficeProcess(req: Request, res: Response): Promise<any> {
|
// Check if process is committed and handle role updates
|
||||||
console.log('Received request to get office process');
|
const processManagementResult = await SignerImprovedService.executeWithRetry(
|
||||||
try {
|
async (signerClient) => {
|
||||||
// Find the full token data which should contain the original idNotUser data
|
const allProcesses = await signerClient.getOwnedProcesses();
|
||||||
const userAuth = authTokens.find(auth => auth.authToken === req.idNotUser!.authToken);
|
|
||||||
|
if (allProcesses && process) {
|
||||||
if (!userAuth || !userAuth.idNotUser) {
|
const processStates = allProcesses.processes[process.processId].states;
|
||||||
return res.status(404).json({
|
const isNotCommited = processStates.length === 2
|
||||||
success: false,
|
&& processStates[1].commited_in === processStates[0].commited_in;
|
||||||
message: 'Données utilisateur non trouvées. Veuillez vous reconnecter.'
|
|
||||||
});
|
if (isNotCommited) {
|
||||||
}
|
Logger.info('Process not committed, committing it', {
|
||||||
|
requestId,
|
||||||
|
processId: process.processId
|
||||||
|
});
|
||||||
|
await signerClient.validateState(process.processId, processStates[0].state_id);
|
||||||
|
}
|
||||||
|
|
||||||
// If office is not ACTIVATED, we return a 404 error
|
// Check pairing ID in roles
|
||||||
if (userAuth.idNotUser.office.office_status !== EOfficeStatus.ACTIVATED) {
|
let roles: ProcessRoles;
|
||||||
return res.status(404).json({
|
if (isNotCommited) {
|
||||||
success: false,
|
const firstState = processStates[0];
|
||||||
message: 'Office not activated'
|
roles = firstState.roles;
|
||||||
});
|
} else {
|
||||||
}
|
const tip = processStates[processStates.length - 1].commited_in;
|
||||||
|
const lastState = processStates.findLast((state: any) => state.commited_in !== tip);
|
||||||
|
roles = lastState.roles;
|
||||||
|
}
|
||||||
|
|
||||||
const signerClient = SignerService.getInstance();
|
if (!roles) {
|
||||||
|
throw new Error('No roles found');
|
||||||
|
} else if (!roles['owner']) {
|
||||||
|
throw new Error('No owner role found');
|
||||||
|
}
|
||||||
|
|
||||||
// Now we ask signer if he knows a process for this office
|
if (!roles['owner'].members.includes(req.query.pairingId as string)) {
|
||||||
let process: ProcessInfo | null = await signerClient.getOfficeProcessByIdnot(userAuth.idNotUser.office.idNot);
|
Logger.info('Adding new pairingId to owner role', {
|
||||||
|
requestId,
|
||||||
if (!process) {
|
pairingId: req.query.pairingId,
|
||||||
// Let's create it
|
processId: process.processId
|
||||||
// We directly use the office info as process data
|
});
|
||||||
const getPairingIdResponse = await signerClient.getPairingId();
|
|
||||||
const validatorId = getPairingIdResponse.pairingId;
|
roles['owner'].members.push(req.query.pairingId as string);
|
||||||
if (!validatorId) {
|
const updatedProcessReturn = await signerClient.updateProcess(process.processId, {}, [], roles);
|
||||||
return res.status(400).json({
|
const processId = updatedProcessReturn.updatedProcess.process_id;
|
||||||
success: false,
|
const stateId = updatedProcessReturn.updatedProcess.diffs[0].state_id;
|
||||||
message: 'No validator id found'
|
await signerClient.notifyUpdate(processId, stateId);
|
||||||
});
|
await signerClient.validateState(processId, stateId);
|
||||||
}
|
}
|
||||||
|
|
||||||
let uuid: string;
|
|
||||||
// Try to fetch existing UUID from database by idNot
|
|
||||||
try {
|
|
||||||
const result = await Database.query('SELECT uid FROM offices WHERE "idNot" = $1', [userAuth.idNotUser.office.idNot]);
|
|
||||||
uuid = result.rows.length > 0 ? result.rows[0].uid : null;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error fetching UUID by idNot:', error);
|
|
||||||
uuid = '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no existing UUID found, generate a new one
|
return process;
|
||||||
if (!uuid) {
|
},
|
||||||
console.log('No existing UUID found in db, generating a new one');
|
'processManagement',
|
||||||
uuid = uuidv4();
|
2
|
||||||
}
|
);
|
||||||
|
|
||||||
const processData: ProcessData = {
|
if (!processManagementResult.success) {
|
||||||
uid: uuidv4(),
|
throw new ExternalServiceError('Signer', processManagementResult.error?.message || 'Failed to manage process', requestId);
|
||||||
utype: 'office',
|
|
||||||
...userAuth.idNotUser.office,
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log('processData', processData);
|
|
||||||
|
|
||||||
const privateFields = Object.keys(processData);
|
|
||||||
|
|
||||||
const roles: ProcessRoles = {
|
|
||||||
owner: {
|
|
||||||
members: [validatorId],
|
|
||||||
validation_rules: [],
|
|
||||||
storages: []
|
|
||||||
},
|
|
||||||
apophis: {
|
|
||||||
members: [validatorId],
|
|
||||||
validation_rules: [],
|
|
||||||
storages: []
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const newOfficeProcess = await signerClient.createProcess(processData, privateFields, roles);
|
|
||||||
process = { processId: newOfficeProcess.processId, processData: newOfficeProcess.data };
|
|
||||||
console.log('Created new office process:', process);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We check that the process is commited, we do it if that's not the case
|
|
||||||
const allProcesses = await signerClient.getOwnedProcesses();
|
|
||||||
if (allProcesses && process) {
|
|
||||||
const processStates = allProcesses.processes[process.processId].states;
|
|
||||||
const isNotCommited = processStates.length === 2
|
|
||||||
&& processStates[1].commited_in === processStates[0].commited_in;
|
|
||||||
if (isNotCommited) {
|
|
||||||
console.log('Process is not commited, committing it');
|
|
||||||
await signerClient.validateState(process.processId, processStates[0].state_id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new Error('No processes found');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the stored idNotUser data without the authToken
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
data: process
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (error: any) {
|
|
||||||
res.status(500).json({
|
|
||||||
success: false,
|
|
||||||
message: 'Erreur lors de la récupération des données utilisateur',
|
|
||||||
error: error.message
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static async authenticateClient(req: Request, res: Response): Promise<any> {
|
Logger.info('User process request completed successfully', {
|
||||||
|
requestId,
|
||||||
|
processId: process?.processId
|
||||||
|
});
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
data: processManagementResult.data
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
static getOfficeProcess = asyncHandler(async (req: Request, res: Response): Promise<void> => {
|
||||||
|
const requestId = req.headers['x-request-id'] as string;
|
||||||
|
|
||||||
|
Logger.info('Office process request initiated', { requestId });
|
||||||
|
|
||||||
|
const userAuth = authTokens.find(auth => auth.authToken === req.idNotUser!.authToken);
|
||||||
|
|
||||||
|
if (!userAuth || !userAuth.idNotUser) {
|
||||||
|
throw new NotFoundError('Données utilisateur non trouvées. Veuillez vous reconnecter.', requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check office status
|
||||||
|
if (userAuth.idNotUser.office.office_status !== EOfficeStatus.ACTIVATED) {
|
||||||
|
throw new BusinessRuleError('Office not activated', undefined, requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get office process with retry
|
||||||
|
const processResult = await SignerImprovedService.executeWithRetry(
|
||||||
|
async (signerClient) => {
|
||||||
|
return await signerClient.getOfficeProcessByIdnot(userAuth.idNotUser.office.idNot);
|
||||||
|
},
|
||||||
|
'getOfficeProcessByIdnot',
|
||||||
|
3
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!processResult.success) {
|
||||||
|
throw new ExternalServiceError('Signer', processResult.error?.message || 'Failed to get office process', requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
let process: ProcessInfo | null = processResult.data || null;
|
||||||
|
|
||||||
|
if (!process) {
|
||||||
|
Logger.info('No existing office process found, creating new one', {
|
||||||
|
requestId,
|
||||||
|
officeIdNot: userAuth.idNotUser.office.idNot
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get validator ID with retry
|
||||||
|
const pairingResult = await SignerImprovedService.executeWithRetry(
|
||||||
|
async (signerClient) => {
|
||||||
|
return await signerClient.getPairingId();
|
||||||
|
},
|
||||||
|
'getPairingId',
|
||||||
|
3
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!pairingResult.success) {
|
||||||
|
throw new ExternalServiceError('Signer', pairingResult.error?.message || 'Failed to get validator ID', requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const validatorId = pairingResult.data!.pairingId;
|
||||||
|
if (!validatorId) {
|
||||||
|
throw new BusinessRuleError('No validator id found', undefined, requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get UUID from database
|
||||||
|
let uuid: string;
|
||||||
|
try {
|
||||||
|
const result = await Database.query('SELECT uid FROM offices WHERE "idNot" = $1', [userAuth.idNotUser.office.idNot]);
|
||||||
|
uuid = result.rows.length > 0 ? result.rows[0].uid : null;
|
||||||
|
} catch (error) {
|
||||||
|
Logger.error('Error fetching office UUID by idNot', {
|
||||||
|
requestId,
|
||||||
|
error: error instanceof Error ? error.message : 'Unknown error'
|
||||||
|
});
|
||||||
|
uuid = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!uuid) {
|
||||||
|
Logger.info('No existing office UUID found in db, generating new one', { requestId });
|
||||||
|
uuid = uuidv4();
|
||||||
|
}
|
||||||
|
|
||||||
|
const processData: ProcessData = {
|
||||||
|
uid: uuid,
|
||||||
|
utype: 'office',
|
||||||
|
...userAuth.idNotUser.office,
|
||||||
|
};
|
||||||
|
|
||||||
|
const privateFields = Object.keys(processData);
|
||||||
|
const allFields = [...privateFields, 'roles'];
|
||||||
|
|
||||||
|
// No need for public fields?
|
||||||
|
|
||||||
|
const roles: ProcessRoles = {
|
||||||
|
owner: {
|
||||||
|
members: [validatorId],
|
||||||
|
validation_rules: [{
|
||||||
|
quorum: 0.1,
|
||||||
|
fields: allFields,
|
||||||
|
min_sig_member: 1,
|
||||||
|
}],
|
||||||
|
storages: [config.defaultStorage]
|
||||||
|
},
|
||||||
|
apophis: {
|
||||||
|
members: [validatorId],
|
||||||
|
validation_rules: [],
|
||||||
|
storages: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create office process with retry
|
||||||
|
const createResult = await SignerImprovedService.executeWithRetry(
|
||||||
|
async (signerClient) => {
|
||||||
|
return await signerClient.createProcess(processData, privateFields, roles);
|
||||||
|
},
|
||||||
|
'createOfficeProcess',
|
||||||
|
3
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!createResult.success) {
|
||||||
|
throw new ExternalServiceError('Signer', createResult.error?.message || 'Failed to create office process', requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.info('Created new office process', { process: createResult.data });
|
||||||
|
|
||||||
|
// Use the idnot number to identify all active members of the office
|
||||||
|
const officeCollaborators = await IdNotController.getOfficeRattachements(userAuth.idNotUser.office.idNot);
|
||||||
|
Logger.debug('Office collaborators', { officeCollaborators });
|
||||||
|
|
||||||
|
// Logger.info('Created new office process', {
|
||||||
|
// requestId,
|
||||||
|
// processId: createResult.data!.processId
|
||||||
|
// });
|
||||||
|
|
||||||
|
process = {
|
||||||
|
processId: createResult.data!.processCreated.processId || '',
|
||||||
|
processData: createResult.data!.processData
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.info('Office process request completed successfully', {
|
||||||
|
requestId,
|
||||||
|
processId: process?.processId
|
||||||
|
});
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
data: process
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
static authenticateClient = asyncHandler(async (req: Request, res: Response): Promise<void> => {
|
||||||
|
const requestId = req.headers['x-request-id'] as string;
|
||||||
const { pairingId } = req.body;
|
const { pairingId } = req.body;
|
||||||
|
|
||||||
if (!pairingId) {
|
if (!pairingId) {
|
||||||
return res.status(400).json({
|
throw new BusinessRuleError('Missing pairingId', undefined, requestId);
|
||||||
success: false,
|
|
||||||
message: 'Missing pairingId'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
Logger.info('Client authentication initiated', { requestId, pairingId });
|
||||||
// This should be implemented properly based on your business logic
|
|
||||||
// const result = await signerClient.updateProcess(processId, newData, privateFields || [], roles || null);
|
|
||||||
|
|
||||||
// Clean up the session after successful update
|
|
||||||
SessionManager.deleteSession(req.session!.id);
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
message: 'Client authentication successful',
|
|
||||||
data: {}
|
|
||||||
});
|
|
||||||
} catch (error: any) {
|
|
||||||
console.error('Client authentication error:', error);
|
|
||||||
res.status(500).json({
|
|
||||||
success: false,
|
|
||||||
message: 'Error during client authentication',
|
|
||||||
error: error.message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static async getPhoneNumberForEmail(req: Request, res: Response): Promise<any> {
|
// This should be implemented properly based on your business logic
|
||||||
|
// For now, just clean up the session
|
||||||
|
SessionManager.deleteSession(req.session!.id);
|
||||||
|
|
||||||
|
Logger.info('Client authentication completed', { requestId });
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
message: 'Client authentication successful',
|
||||||
|
data: {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
static getPhoneNumberForEmail = asyncHandler(async (req: Request, res: Response): Promise<void> => {
|
||||||
|
const requestId = req.headers['x-request-id'] as string;
|
||||||
const { email } = req.body;
|
const { email } = req.body;
|
||||||
|
|
||||||
if (!email) {
|
if (!email) {
|
||||||
return res.status(400).json({
|
throw new BusinessRuleError('Missing email', undefined, requestId);
|
||||||
success: false,
|
|
||||||
message: 'Missing email'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const signerClient = SignerService.getInstance();
|
Logger.info('Phone number lookup initiated', { requestId, email });
|
||||||
const phoneNumber = await signerClient.getPhoneNumberForEmail(email);
|
|
||||||
|
const phoneResult = await SignerImprovedService.executeWithRetry(
|
||||||
|
async (signerClient) => {
|
||||||
|
return await signerClient.getPhoneNumberForEmail(email);
|
||||||
|
},
|
||||||
|
'getPhoneNumberForEmail',
|
||||||
|
3
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!phoneResult.success) {
|
||||||
|
throw new ExternalServiceError('Signer', phoneResult.error?.message || 'Failed to get phone number', requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const phoneNumber = phoneResult.data;
|
||||||
|
|
||||||
if (!phoneNumber) {
|
if (!phoneNumber) {
|
||||||
return res.status(400).json({
|
throw new NotFoundError('No phone number found for this email', requestId);
|
||||||
success: false,
|
|
||||||
message: 'No phone number found for this email'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger.info('Phone number lookup completed', { requestId, email, phoneResult });
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
message: 'Phone number retrieved successfully',
|
message: 'Phone number retrieved successfully',
|
||||||
phoneNumber: phoneNumber
|
phoneNumber: phoneNumber
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
|
||||||
|
// Health check endpoint for signer service
|
||||||
|
static getSignerHealth = asyncHandler(async (req: Request, res: Response): Promise<void> => {
|
||||||
|
const healthStatus = SignerImprovedService.getHealthStatus();
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
data: {
|
||||||
|
signer: healthStatus,
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Force reconnection endpoint (for debugging/admin use)
|
||||||
|
static forceSignerReconnect = asyncHandler(async (req: Request, res: Response): Promise<void> => {
|
||||||
|
const requestId = req.headers['x-request-id'] as string;
|
||||||
|
|
||||||
|
Logger.info('Force signer reconnection requested', { requestId });
|
||||||
|
|
||||||
|
const reconnectResult = await SignerImprovedService.forceReconnect();
|
||||||
|
|
||||||
|
if (!reconnectResult.success) {
|
||||||
|
throw new ExternalServiceError('Signer', reconnectResult.error?.message || 'Failed to reconnect', requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.info('Force signer reconnection completed', { requestId });
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
message: 'Signer reconnection initiated',
|
||||||
|
data: SignerImprovedService.getHealthStatus()
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
import { Router } from 'express';
|
|
||||||
import { ProcessImprovedController } from '../controllers/process-improved.controller';
|
|
||||||
import { authenticateIdNot } from '../middleware/auth';
|
|
||||||
import { validateSession } from '../middleware/session';
|
|
||||||
|
|
||||||
const router = Router();
|
|
||||||
|
|
||||||
// Health check routes (public)
|
|
||||||
router.get('/health/signer', ProcessImprovedController.getSignerHealth);
|
|
||||||
router.post('/admin/signer/reconnect', ProcessImprovedController.forceSignerReconnect); // Should be protected in production
|
|
||||||
|
|
||||||
// IdNot protected routes
|
|
||||||
router.get('/user', authenticateIdNot, ProcessImprovedController.getUserProcess);
|
|
||||||
router.get('/office', authenticateIdNot, ProcessImprovedController.getOfficeProcess);
|
|
||||||
|
|
||||||
// Customer auth routes (session protected)
|
|
||||||
router.post('/customer/auth/client-auth', validateSession, ProcessImprovedController.authenticateClient);
|
|
||||||
router.post('/customer/auth/get-phone-number-for-email', validateSession, ProcessImprovedController.getPhoneNumberForEmail);
|
|
||||||
|
|
||||||
export { router as processImprovedRoutes };
|
|
@ -5,6 +5,10 @@ import { validateSession } from '../middleware/session';
|
|||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
|
// Health check routes (public)
|
||||||
|
router.get('/health/signer', ProcessController.getSignerHealth);
|
||||||
|
router.post('/admin/signer/reconnect', ProcessController.forceSignerReconnect); // Should be protected in production
|
||||||
|
|
||||||
// IdNot protected routes
|
// IdNot protected routes
|
||||||
router.get('/user', authenticateIdNot, ProcessController.getUserProcess);
|
router.get('/user', authenticateIdNot, ProcessController.getUserProcess);
|
||||||
router.get('/office', authenticateIdNot, ProcessController.getOfficeProcess);
|
router.get('/office', authenticateIdNot, ProcessController.getOfficeProcess);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user