Compare commits
4 Commits
1664b4aa69
...
3ef15fd9c6
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3ef15fd9c6 | ||
![]() |
7f9b4d82b5 | ||
![]() |
8b11e0c80c | ||
![]() |
c8cf1b2efd |
@ -310,7 +310,13 @@ export class RelayManager {
|
|||||||
|
|
||||||
// Relay Message Handling
|
// Relay Message Handling
|
||||||
private handleRelayMessage(relayId: string, message: any): void {
|
private handleRelayMessage(relayId: string, message: any): void {
|
||||||
console.log(`📨 Received message from relay ${relayId}:`, message);
|
console.log(`📨 Received message from relay ${relayId}:`);
|
||||||
|
|
||||||
|
if (message.flag === 'Handshake') {
|
||||||
|
console.log('🔑 Handshake message');
|
||||||
|
} else {
|
||||||
|
console.log(`🔑 ${message.flag} message: ${message.content}`);
|
||||||
|
}
|
||||||
|
|
||||||
// Handle different types of relay responses
|
// Handle different types of relay responses
|
||||||
if (message.flag) {
|
if (message.flag) {
|
||||||
|
@ -264,8 +264,6 @@ export class Service {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get relay statistics from RelayManager.
|
* Get relay statistics from RelayManager.
|
||||||
* @returns Statistics about connected relays
|
* @returns Statistics about connected relays
|
||||||
@ -703,6 +701,48 @@ export class Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getProcessesData(filteredProcesses: Record<string, Process>): Promise<Record<string, any>> {
|
||||||
|
const data: Record<string, any> = {};
|
||||||
|
// Now we decrypt all we can in the processes
|
||||||
|
for (const [processId, process] of Object.entries(filteredProcesses)) {
|
||||||
|
console.log('process roles:', this.getRoles(process));
|
||||||
|
// We also take the public data
|
||||||
|
const lastState = this.getLastCommitedState(process);
|
||||||
|
if (!lastState) {
|
||||||
|
console.error(`❌ Process ${processId} doesn't have a commited state`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const processData: Record<string, any> = {};
|
||||||
|
for (const attribute of Object.keys(lastState.public_data)) {
|
||||||
|
try {
|
||||||
|
const value = this.decodeValue(lastState.public_data[attribute]);
|
||||||
|
if (value) {
|
||||||
|
processData[attribute] = value;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`❌ Error decoding public data ${attribute} for process ${processId}:`, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = process.states.length - 2; i >= 0; i--) {
|
||||||
|
const state = process.states[i];
|
||||||
|
for (const attribute of Object.keys(state.keys)) {
|
||||||
|
if (processData[attribute] !== undefined && processData[attribute] !== null) continue;
|
||||||
|
try {
|
||||||
|
const value = await this.decryptAttribute(processId, state, attribute);
|
||||||
|
if (value) {
|
||||||
|
processData[attribute] = value;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`❌ Error decrypting attribute ${attribute} for process ${processId}:`, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data[processId] = processData;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
// Utility method: Get Process
|
// Utility method: Get Process
|
||||||
async getProcess(processId: string): Promise<any | null> {
|
async getProcess(processId: string): Promise<any | null> {
|
||||||
// First check in-memory cache
|
// First check in-memory cache
|
||||||
|
@ -3,7 +3,7 @@ import { MessageType } from './models';
|
|||||||
import { config } from './config';
|
import { config } from './config';
|
||||||
import { Service } from './service';
|
import { Service } from './service';
|
||||||
import { ApiReturn, Process } from '../pkg/sdk_client';
|
import { ApiReturn, Process } from '../pkg/sdk_client';
|
||||||
import { EMPTY32BYTES } from './utils';
|
import { EMPTY32BYTES, splitPrivateData } from './utils';
|
||||||
|
|
||||||
interface ServerMessageEvent {
|
interface ServerMessageEvent {
|
||||||
data: {
|
data: {
|
||||||
@ -42,6 +42,52 @@ class SimpleProcessHandlers {
|
|||||||
return apiKey === this.apiKey;
|
return apiKey === this.apiKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async handleCreateProcess(event: ServerMessageEvent): Promise<ServerResponse> {
|
||||||
|
if (event.data.type !== MessageType.CREATE_PROCESS) {
|
||||||
|
throw new Error('Invalid message type');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.service.isPaired()) {
|
||||||
|
throw new Error('Device not paired');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { processData, privateFields, roles, exclusionRules, apiKey } = event.data;
|
||||||
|
|
||||||
|
if (!apiKey || !this.validateApiKey(apiKey)) {
|
||||||
|
throw new Error('Invalid API key');
|
||||||
|
}
|
||||||
|
|
||||||
|
const { privateData, publicData } = splitPrivateData(processData, privateFields);
|
||||||
|
|
||||||
|
const createProcessReturn = await this.service.createProcess(privateData, publicData, roles);
|
||||||
|
if (!createProcessReturn.updated_process) {
|
||||||
|
throw new Error('Empty updated_process in createProcessReturn');
|
||||||
|
}
|
||||||
|
console.log('🚀 ~ handleCreateProcess ~ createProcessReturn:', createProcessReturn);
|
||||||
|
const processId = createProcessReturn.updated_process.process_id;
|
||||||
|
const process = createProcessReturn.updated_process.current_process;
|
||||||
|
await this.service.handleApiReturn(createProcessReturn);
|
||||||
|
|
||||||
|
const processCreated = {
|
||||||
|
processId,
|
||||||
|
process,
|
||||||
|
processData,
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: MessageType.PROCESS_CREATED,
|
||||||
|
processCreated,
|
||||||
|
messageId: event.data.messageId
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
const errorMessage = e instanceof Error ? e.message : String(e || 'Unknown error');
|
||||||
|
// Remove redundant "Error:" prefix and simplify the message
|
||||||
|
const cleanMessage = errorMessage.replace(/^Error:\s*/, '');
|
||||||
|
throw new Error(cleanMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async handleNotifyUpdate(event: ServerMessageEvent): Promise<ServerResponse> {
|
async handleNotifyUpdate(event: ServerMessageEvent): Promise<ServerResponse> {
|
||||||
if (event.data.type !== MessageType.NOTIFY_UPDATE) {
|
if (event.data.type !== MessageType.NOTIFY_UPDATE) {
|
||||||
throw new Error('Invalid message type');
|
throw new Error('Invalid message type');
|
||||||
@ -233,42 +279,7 @@ class SimpleProcessHandlers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const data: Record<string, any> = {};
|
const data = await this.service.getProcessesData(filteredProcesses);
|
||||||
// Now we decrypt all we can in the processes
|
|
||||||
for (const [processId, process] of Object.entries(filteredProcesses)) {
|
|
||||||
// We also take the public data
|
|
||||||
const lastState = this.service.getLastCommitedState(process);
|
|
||||||
if (!lastState) {
|
|
||||||
console.error(`❌ Process ${processId} doesn't have a commited state`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const processData: Record<string, any> = {};
|
|
||||||
for (const attribute of Object.keys(lastState.public_data)) {
|
|
||||||
try {
|
|
||||||
const value = this.service.decodeValue(lastState.public_data[attribute]);
|
|
||||||
if (value) {
|
|
||||||
processData[attribute] = value;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error(`❌ Error decoding public data ${attribute} for process ${processId}:`, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i = process.states.length - 2; i >= 0; i--) {
|
|
||||||
const state = process.states[i];
|
|
||||||
for (const attribute of Object.keys(state.keys)) {
|
|
||||||
if (processData[attribute] !== undefined && processData[attribute] !== null) continue;
|
|
||||||
try {
|
|
||||||
const value = await this.service.decryptAttribute(processId, state, attribute);
|
|
||||||
if (value) {
|
|
||||||
processData[attribute] = value;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error(`❌ Error decrypting attribute ${attribute} for process ${processId}:`, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data[processId] = processData;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: MessageType.PROCESSES_RETRIEVED,
|
type: MessageType.PROCESSES_RETRIEVED,
|
||||||
@ -281,6 +292,8 @@ class SimpleProcessHandlers {
|
|||||||
async handleMessage(event: ServerMessageEvent): Promise<ServerResponse> {
|
async handleMessage(event: ServerMessageEvent): Promise<ServerResponse> {
|
||||||
try {
|
try {
|
||||||
switch (event.data.type) {
|
switch (event.data.type) {
|
||||||
|
case MessageType.CREATE_PROCESS:
|
||||||
|
return await this.handleCreateProcess(event);
|
||||||
case MessageType.NOTIFY_UPDATE:
|
case MessageType.NOTIFY_UPDATE:
|
||||||
return await this.handleNotifyUpdate(event);
|
return await this.handleNotifyUpdate(event);
|
||||||
case MessageType.VALIDATE_STATE:
|
case MessageType.VALIDATE_STATE:
|
||||||
|
15
src/utils.ts
15
src/utils.ts
@ -1,6 +1,21 @@
|
|||||||
// Server-specific utility functions
|
// Server-specific utility functions
|
||||||
export const EMPTY32BYTES = String('').padStart(64, '0');
|
export const EMPTY32BYTES = String('').padStart(64, '0');
|
||||||
|
|
||||||
|
export function splitPrivateData(data: Record<string, any>, privateFields: string[]): { privateData: Record<string, any>, publicData: Record<string, any> } {
|
||||||
|
const privateData: Record<string, any> = {};
|
||||||
|
const publicData: Record<string, any> = {};
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(data)) {
|
||||||
|
if (privateFields.includes(key)) {
|
||||||
|
privateData[key] = value;
|
||||||
|
} else {
|
||||||
|
publicData[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { privateData, publicData };
|
||||||
|
}
|
||||||
|
|
||||||
export function isValid32ByteHex(value: string): boolean {
|
export function isValid32ByteHex(value: string): boolean {
|
||||||
// Check if the value is a valid 32-byte hex string (64 characters)
|
// Check if the value is a valid 32-byte hex string (64 characters)
|
||||||
const hexRegex = /^[0-9a-fA-F]{64}$/;
|
const hexRegex = /^[0-9a-fA-F]{64}$/;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user