Open satpugnet opened 3 weeks ago
This is my latest change to the code to try to use the Recovery key directly unsuccessfully (Getting the error shown below despite the key being the right one):
const sdk = require('matrix-js-sdk');
global.Olm = require('@matrix-org/olm');
Olm.init().then(() => {
console.log('Olm initialized successfully');
}).catch((err) => {
console.error('Failed to initialize Olm:', err);
});
const deviceId = 'REDACTED';
const matrixServerUrl = 'https://matrix.beeper.com';
const matrixUserId = 'REDACTED'; // Your user ID in Beeper
const matrixPassword = 'REDACTED'; // Your password
const beeperRecoveryKey = "REDACTED";
const matrixUsername = 'REDACTED'; // Your username
const beeperAccessToken = 'REDACTED'; // Use the access token
document.getElementById('connect').addEventListener('click', async () => {
// Setup secret storage callback
const getSecretStorageKey = async (keys, name) => {
console.log('Getting secret storage key:', keys, name);
const defaultKeyId = await client.secretStorage.getDefaultKeyId();
const keyBackupKey = client.keyBackupKeyFromRecoveryKey(beeperRecoveryKey);
return [defaultKeyId, keyBackupKey];
};
const client = sdk.createClient({
baseUrl: matrixServerUrl,
store: new sdk.MemoryStore(),
cryptoStore: new sdk.MemoryCryptoStore(),
cryptoCallbacks: { getSecretStorageKey }
});
try {
// Clear any previous stores
await client.clearStores();
// Login with username and password
// const response = await client.loginWithPassword(matrixUserId, matrixPassword);
const response = await client.login("m.login.password", {
"user": matrixUserId,
"device_id": deviceId,
"password": matrixPassword,
// "refresh_token": true,
});
console.log('Logged in successfully:', response);
// Set credentials
client.setAccessToken(response.access_token);
client.credentials.userId = response.user_id;
client.deviceId = response.device_id;
// Initialize crypto
await client.initCrypto();
// await client.initRustCrypto();
// Bootstrap cross-signing
await client.getCrypto().bootstrapCrossSigning({});
console.log('Cross-signing bootstrapped.');
// Start the client and sync
await client.startClient();
console.log('Client started.');
await client.getCrypto().crossSignDevice(deviceId);
console.log('Device cross-signed.');
const isVerified = await client.getCrypto().getDeviceVerificationStatus(matrixUserId, deviceId);
console.log('Device verification status:', isVerified);
// if (await client.getCrypto().isSecretStorageReady()) {
// console.log("Secret storage is ready.");
// }
//
// // Restore keys using recovery key
// await restoreKeysUsingRecoveryKey(client, beeperRecoveryKey);
client.on('sync', async (state) => {
console.log('Syncing...', state);
if (state === 'PREPARED') {
// Not sure if this needs to be done here or above
if (await client.getCrypto().isSecretStorageReady()) {
console.log("Secret storage is ready.");
}
// Restore keys using recovery key
await restoreKeysUsingRecoveryKey(client, beeperRecoveryKey);
console.log('Logged in and synced successfully.');
listenForMessages(client);
}
});
client.on('error', (err) => {
console.error('Error:', err);
});
} catch (err) {
console.error('Login failed or error initializing crypto:', err);
}
});
async function restoreKeysUsingRecoveryKey(client, recoveryKey) {
try {
console.log("Restoring keys using recovery key...");
// Fetch backup info from the server
// const backupInfo = (await client.getCrypto().checkKeyBackupAndEnable())?.backupInfo;
const backupInfo = await client.getKeyBackupVersion();
if (!backupInfo) {
throw new Error("No backup info found on the server.");
}
console.log("Fetched backup info:", backupInfo);
console.log("Is valid recovery key:", client.isValidRecoveryKey(recoveryKey)); // Should return "true"
// Restore the keys using the recovery key and the fetched backup info
const restoreResult = await client.restoreKeyBackupWithRecoveryKey(recoveryKey, null, null, backupInfo);
console.log("Successfully restored keys using recovery key.", restoreResult);
} catch (error) {
console.error("Failed to restore keys using recovery key:", error);
}
}
function listenForMessages(client) {
client.on('Room.timeline', async (event, room, toStartOfTimeline) => {
if (toStartOfTimeline) {
return; // Don't print paginated results
}
if (event.getType() !== 'm.room.message' && event.getType() !== 'm.room.encrypted') {
return; // Only handle messages or encrypted messages
}
// Decrypt the message if it's encrypted
if (event.isEncrypted()) {
try {
console.log('Decrypting event:', event);
await client.crypto.requestRoomKey({
room_id: event.getRoomId(),
session_id: event.getWireContent().session_id,
sender_key: event.getSenderKey(),
algorithm: event.getWireContent().algorithm
});
await client.decryptEventIfNeeded(event);
console.info('Decrypted event:', event.getContent());
} catch (err) {
console.error('Failed to decrypt event:', err);
await client.requestRoomKey(event);
return;
}
} else {
console.log('Event is not encrypted:', event);
}
const sender = event.getSender();
const content = event.getContent().body;
if (content) {
document.getElementById('messages').innerHTML += `<p><strong>${sender}:</strong> ${content}</p>`;
}
});
// Handle key requests from other devices
client.on('crypto.roomKeyRequest', (req) => {
console.log('Received room key request', req);
if (req.action === "request") {
console.log('Automatically sharing keys');
client.crypto.sendSharedHistoryKeys(req.userId, req.roomId, req.requestId, req.requestBody);
} else {
console.log(`Unhandled key request action: ${req.action}`);
}
});
}
We can't really offer support here - you could try https://matrix.to/#/#matrix-dev:matrix.org
I am trying to integrate with Beeper Homeserver for my Electron app and I have not been able to get it to work for encrypted messages. I could not find a working snippet of code on the internet. That would be immensly useful if someone could provide a working snippet of code to send and read messages through the beeper homeserver to whatsapp or another encrypted messaging app.
I have not been able to verify my client with Beeper as the "can't scan" button for verifying new apps does not seem to do anything after you enter the KEY. And I am not sure what code to put on my side to make it work with the QR code displayed by the Beeper app. This could be why I am unable to decrypt the messages but I am unsure if this is the cause.
Here is a screenshot of what my app displays. I can read messages from myself but cannot read messages from others as the key is not shared:
Here is what I see on my Beeper app as I am unable to verify the device (Not sure if that is the cause):
Thanks in advance for the help. It would be wonderful if anyone could provide. Working snippet of code. And it would probably be a huge help for the community to have a working snippet of code for this 🙂
I am using
matrix-js-sdk
withe version32.4.0
andolm
with version3.2.12
.Here is the code that I have so far, this is my
renderer.js
:Here is the main.js
Here is the index.js