added cancel group invite and decrypt aesgcm

This commit is contained in:
PhilReact 2025-02-03 20:52:08 +02:00
parent 6a1227e8dd
commit d5b2d59d0b
4 changed files with 132 additions and 4 deletions

View File

@ -2373,7 +2373,7 @@ export async function joinGroup({ groupId }) {
return res;
}
async function cancelInvitationToGroup({ groupId, qortalAddress }) {
export async function cancelInvitationToGroup({ groupId, qortalAddress }) {
const lastReference = await getLastRef();
const resKeyPair = await getKeyPair();
const parsedData = JSON.parse(resKeyPair);

View File

@ -243,7 +243,7 @@ const UIQortalRequests = [
'GET_TX_ACTIVITY_SUMMARY', 'GET_FOREIGN_FEE', 'UPDATE_FOREIGN_FEE',
'GET_SERVER_CONNECTION_HISTORY', 'SET_CURRENT_FOREIGN_SERVER',
'ADD_FOREIGN_SERVER', 'REMOVE_FOREIGN_SERVER', 'GET_DAY_SUMMARY', 'CREATE_TRADE_BUY_ORDER',
'CREATE_TRADE_SELL_ORDER', 'CANCEL_TRADE_SELL_ORDER', 'IS_USING_GATEWAY', 'ADMIN_ACTION', 'SIGN_TRANSACTION', 'DECRYPT_QORTAL_GROUP_DATA', 'DELETE_HOSTED_DATA', 'GET_HOSTED_DATA', 'DECRYPT_DATA_WITH_SHARING_KEY', 'SHOW_ACTIONS', 'REGISTER_NAME', 'UPDATE_NAME', 'LEAVE_GROUP', 'INVITE_TO_GROUP', 'KICK_FROM_GROUP', 'BAN_FROM_GROUP', 'CANCEL_GROUP_BAN', 'ADD_GROUP_ADMIN','REMOVE_GROUP_ADMIN'
'CREATE_TRADE_SELL_ORDER', 'CANCEL_TRADE_SELL_ORDER', 'IS_USING_GATEWAY', 'ADMIN_ACTION', 'SIGN_TRANSACTION', 'DECRYPT_QORTAL_GROUP_DATA', 'DELETE_HOSTED_DATA', 'GET_HOSTED_DATA', 'DECRYPT_DATA_WITH_SHARING_KEY', 'SHOW_ACTIONS', 'REGISTER_NAME', 'UPDATE_NAME', 'LEAVE_GROUP', 'INVITE_TO_GROUP', 'KICK_FROM_GROUP', 'BAN_FROM_GROUP', 'CANCEL_GROUP_BAN', 'ADD_GROUP_ADMIN','REMOVE_GROUP_ADMIN','DECRYPT_AESGCM', 'CANCEL_GROUP_INVITE'
];

View File

@ -1,5 +1,5 @@
import { banFromGroup, gateways, getApiKeyFromStorage } from "./background";
import { addForeignServer, addGroupAdminRequest, addListItems, adminAction, banFromGroupRequest, cancelGroupBanRequest, cancelSellOrder, createBuyOrder, createPoll, createSellOrder, decryptData, decryptDataWithSharingKey, decryptQortalGroupData, deleteHostedData, deleteListItems, deployAt, encryptData, encryptDataWithSharingKey, encryptQortalGroupData, getCrossChainServerInfo, getDaySummary, getForeignFee, getHostedData, getListItems, getServerConnectionHistory, getTxActivitySummary, getUserAccount, getUserWallet, getUserWalletInfo, getWalletBalance, inviteToGroupRequest, joinGroup, kickFromGroupRequest, leaveGroupRequest, publishMultipleQDNResources, publishQDNResource, registerNameRequest, removeForeignServer, removeGroupAdminRequest, saveFile, sendChatMessage, sendCoin, setCurrentForeignServer, signTransaction, updateForeignFee, updateNameRequest, voteOnPoll } from "./qortalRequests/get";
import { addForeignServer, addGroupAdminRequest, addListItems, adminAction, banFromGroupRequest, cancelGroupBanRequest, cancelGroupInviteRequest, cancelSellOrder, createBuyOrder, createPoll, createSellOrder, decryptAESGCMRequest, decryptData, decryptDataWithSharingKey, decryptQortalGroupData, deleteHostedData, deleteListItems, deployAt, encryptData, encryptDataWithSharingKey, encryptQortalGroupData, getCrossChainServerInfo, getDaySummary, getForeignFee, getHostedData, getListItems, getServerConnectionHistory, getTxActivitySummary, getUserAccount, getUserWallet, getUserWalletInfo, getWalletBalance, inviteToGroupRequest, joinGroup, kickFromGroupRequest, leaveGroupRequest, publishMultipleQDNResources, publishQDNResource, registerNameRequest, removeForeignServer, removeGroupAdminRequest, saveFile, sendChatMessage, sendCoin, setCurrentForeignServer, signTransaction, updateForeignFee, updateNameRequest, voteOnPoll } from "./qortalRequests/get";
const listOfAllQortalRequests = [
'GET_USER_ACCOUNT', 'DECRYPT_DATA', 'SEND_COIN', 'GET_LIST_ITEMS',
@ -720,6 +720,30 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
});
break;
}
case "CANCEL_GROUP_INVITE" : {
const data = request.payload;
cancelGroupInviteRequest(data, isFromExtension)
.then((res) => {
sendResponse(res);
})
.catch((error) => {
sendResponse({ error: error.message });
});
break;
}
case "DECRYPT_AESGCM" : {
const data = request.payload;
decryptAESGCMRequest(data, isFromExtension)
.then((res) => {
sendResponse(res);
})
.catch((error) => {
sendResponse({ error: error.message });
});
break;
}
}
}
return true;

View File

@ -26,7 +26,8 @@ import {
kickFromGroup,
cancelBan,
makeAdmin,
removeAdmin
removeAdmin,
cancelInvitationToGroup
} from "../background";
import { decryptGroupEncryption, getNameInfo, uint8ArrayToObject } from "../backgroundFunctions/encryption";
import { QORT_DECIMALS } from "../constants/constants";
@ -55,6 +56,8 @@ import signTradeBotTransaction from "../transactions/signTradeBotTransaction";
import nacl from "../deps/nacl-fast";
import utils from "../utils/utils";
import { RequestQueueWithPromise } from "../utils/queue/queue";
import { Sha256 } from "asmcrypto.js";
import ed2curve from "../deps/ed2curve";
export const requestQueueGetAtAddresses = new RequestQueueWithPromise(10);
@ -4231,4 +4234,105 @@ export const removeGroupAdminRequest = async (data, isFromExtension) => {
} else {
throw new Error("User declined request");
}
};
export const cancelGroupInviteRequest = async (data, isFromExtension) => {
const requiredFields = ["groupId", "qortalAddress"];
const missingFields: string[] = [];
requiredFields.forEach((field) => {
if (!data[field]) {
missingFields.push(field);
}
});
const groupId = data.groupId
const qortalAddress = data?.qortalAddress
let groupInfo = null;
try {
const url = await createEndpoint(`/groups/${groupId}`);
const response = await fetch(url);
if (!response.ok) throw new Error("Failed to fetch group");
groupInfo = await response.json();
} catch (error) {
const errorMsg = (error && error.message) || "Group not found";
throw new Error(errorMsg);
}
const displayInvitee = await getNameInfoForOthers(qortalAddress)
const fee = await getFee("CANCEL_GROUP_INVITE");
const resPermission = await getUserPermission(
{
text1: `Do you give this application permission to cancel the group invite for ${displayInvitee || qortalAddress}?`,
highlightedText: `Group: ${groupInfo.groupName}`,
fee: fee.fee,
},
isFromExtension
);
const { accepted } = resPermission;
if (accepted) {
const response = await cancelInvitationToGroup({
groupId,
qortalAddress,
})
return response
} else {
throw new Error("User declined request");
}
};
export const decryptAESGCMRequest = async (data, isFromExtension) => {
const requiredFields = ["encryptedData", "iv", "senderPublicKey"];
requiredFields.forEach((field) => {
if (!data[field]) {
throw new Error(`Missing required field: ${field}`);
}
});
const encryptedData = data.encryptedData;
const iv = data.iv;
const senderPublicKeyBase58 = data.senderPublicKey;
// Decode keys and IV
const senderPublicKey = Base58.decode(senderPublicKeyBase58);
const resKeyPair = await getKeyPair(); // Assume this retrieves the current user's keypair
const uint8PrivateKey = Base58.decode(resKeyPair.privateKey);
// Convert ed25519 keys to Curve25519
const convertedPrivateKey = ed2curve.convertSecretKey(uint8PrivateKey);
const convertedPublicKey = ed2curve.convertPublicKey(senderPublicKey);
// Generate shared secret
const sharedSecret = new Uint8Array(32);
nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey);
// Derive encryption key
const encryptionKey: Uint8Array = new Sha256().process(sharedSecret).finish().result;
// Convert IV and ciphertext from Base64
const base64ToUint8Array = (base64) => Uint8Array.from(atob(base64), c => c.charCodeAt(0));
const ivUint8Array = base64ToUint8Array(iv);
const ciphertext = base64ToUint8Array(encryptedData);
// Validate IV and key lengths
if (ivUint8Array.length !== 12) {
throw new Error("Invalid IV: AES-GCM requires a 12-byte IV.");
}
if (encryptionKey.length !== 32) {
throw new Error("Invalid key: AES-GCM requires a 256-bit key.");
}
try {
// Decrypt data
const algorithm = { name: "AES-GCM", iv: ivUint8Array };
const cryptoKey = await crypto.subtle.importKey("raw", encryptionKey, algorithm, false, ["decrypt"]);
const decryptedArrayBuffer = await crypto.subtle.decrypt(algorithm, cryptoKey, ciphertext);
// Return decrypted data as Base64
return uint8ArrayToBase64(new Uint8Array(decryptedArrayBuffer));
} catch (error) {
console.error("Decryption failed:", error);
throw new Error("Failed to decrypt the message. Ensure the data and keys are correct.");
}
};