#!/usr/bin/env node
/**
* Script to link a new device to an existing Keet identity
*/
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
// Get the directory name of the current module
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Configure logging
function log(level, message) {
const timestamp = new Date().toISOString();
console.log(`[${timestamp}] [${level}] ${message}`);
}
// Main function
async function main() {
try {
// Path to the first device's identity file
const firstDeviceIdentityPath = path.join(__dirname, '..', 'test-keet-storage', 'identity.json');
// Path to the second device's storage directory
const secondDeviceStoragePath = path.join(__dirname, 'storage');
// Create the storage directory if it doesn't exist
if (!fs.existsSync(secondDeviceStoragePath)) {
fs.mkdirSync(secondDeviceStoragePath, { recursive: true });
}
// Read the first device's identity
log('INFO', `Reading identity from first device: ${firstDeviceIdentityPath}`);
const firstDeviceIdentity = JSON.parse(fs.readFileSync(firstDeviceIdentityPath, 'utf8'));
log('INFO', `First device identity: ${JSON.stringify(firstDeviceIdentity)}`);
// Create a new device ID
const newDeviceId = `device-${Date.now()}`;
log('INFO', `Generated new device ID: ${newDeviceId}`);
// Create a new device entry
const newDevice = {
deviceId: newDeviceId,
isMobile: true,
name: 'Mobile Device',
confirmed: false // New devices start as unconfirmed
};
// Create a new identity for the second device that links to the first device's identity
const secondDeviceIdentity = {
anonymous: false, // Set to false for a real identity
memberId: firstDeviceIdentity.memberId, // Use the same memberId as the first device
timestamp: Date.now(),
displayName: firstDeviceIdentity.displayName,
avatar: firstDeviceIdentity.avatar,
devices: [
...firstDeviceIdentity.devices, // Include all devices from the first device
newDevice // Add the new device
],
local: {
deviceId: newDeviceId // Set the local device ID to the new device ID
}
};
// Write the new identity to the second device's storage directory
const secondDeviceIdentityPath = path.join(secondDeviceStoragePath, 'identity.json');
log('INFO', `Writing identity to second device: ${secondDeviceIdentityPath}`);
fs.writeFileSync(secondDeviceIdentityPath, JSON.stringify(secondDeviceIdentity));
// Also update the first device's identity to include the new device
log('INFO', `Updating first device identity to include the new device`);
firstDeviceIdentity.devices.push(newDevice);
fs.writeFileSync(firstDeviceIdentityPath, JSON.stringify(firstDeviceIdentity));
log('INFO', `Device linking completed successfully!`);
log('INFO', `New device ID: ${newDeviceId}`);
log('INFO', `To confirm this device, run the following command:`);
log('INFO', `node keet_cmd.js --confirm-device=${newDeviceId} --storage=../test-keet-storage`);
return 0;
} catch (error) {
log('ERROR', `Error linking device: ${error.message}`);
log('ERROR', error.stack);
return 1;
}
}
// Run the main function if this file is executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
try {
const exitCode = await main();
process.exit(exitCode);
} catch (error) {
log('ERROR', `Unhandled error: ${error.message}`);
log('ERROR', error.stack);
process.exit(1);
}
}