mirror of
https://github.com/Qortal/qortal-mobile.git
synced 2025-03-14 11:52:33 +00:00
added cancel group invite and decrypt aesgcm
This commit is contained in:
parent
d7da4329c8
commit
370e57b04d
@ -221,7 +221,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', 'SIGN_TRANSACTION', 'ADMIN_ACTION', 'OPEN_NEW_TAB', 'CREATE_AND_COPY_EMBED_LINK', 'DECRYPT_QORTAL_GROUP_DATA', 'DECRYPT_DATA_WITH_SHARING_KEY', 'DELETE_HOSTED_DATA', 'GET_HOSTED_DATA', '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', 'SIGN_TRANSACTION', 'ADMIN_ACTION', 'OPEN_NEW_TAB', 'CREATE_AND_COPY_EMBED_LINK', 'DECRYPT_QORTAL_GROUP_DATA', 'DECRYPT_DATA_WITH_SHARING_KEY', 'DELETE_HOSTED_DATA', 'GET_HOSTED_DATA', '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'
|
||||
];
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { gateways, getApiKeyFromStorage } from "./background";
|
||||
import { listOfAllQortalRequests } from "./components/Apps/useQortalMessageListener";
|
||||
import { addForeignServer, addGroupAdminRequest, addListItems, adminAction, banFromGroupRequest, cancelGroupBanRequest, cancelSellOrder, createAndCopyEmbedLink, createBuyOrder, createPoll, decryptData, decryptDataWithSharingKey, decryptQortalGroupData, deleteHostedData, deleteListItems, deployAt, encryptData, encryptDataWithSharingKey, encryptQortalGroupData, getCrossChainServerInfo, getDaySummary, getForeignFee, getHostedData, getListItems, getServerConnectionHistory, getTxActivitySummary, getUserAccount, getUserWallet, getUserWalletInfo, getWalletBalance, inviteToGroupRequest, joinGroup, kickFromGroupRequest, leaveGroupRequest, openNewTab, 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, createAndCopyEmbedLink, createBuyOrder, createPoll, 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, openNewTab, publishMultipleQDNResources, publishQDNResource, registerNameRequest, removeForeignServer, removeGroupAdminRequest, saveFile, sendChatMessage, sendCoin, setCurrentForeignServer, signTransaction, updateForeignFee, updateNameRequest, voteOnPoll } from "./qortalRequests/get";
|
||||
import { getData, storeData } from "./utils/chromeStorage";
|
||||
|
||||
|
||||
@ -1044,6 +1044,45 @@ export const isRunningGateway = async ()=> {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "CANCEL_GROUP_INVITE" : {
|
||||
try {
|
||||
const res = await cancelGroupInviteRequest(request.payload, isFromExtension)
|
||||
event.source.postMessage({
|
||||
requestId: request.requestId,
|
||||
action: request.action,
|
||||
payload: res,
|
||||
type: "backgroundMessageResponse",
|
||||
}, event.origin);
|
||||
} catch (error) {
|
||||
event.source.postMessage({
|
||||
requestId: request.requestId,
|
||||
action: request.action,
|
||||
error: error?.message,
|
||||
type: "backgroundMessageResponse",
|
||||
}, event.origin);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "DECRYPT_AESGCM" : {
|
||||
try {
|
||||
const res = await decryptAESGCMRequest(request.payload, isFromExtension)
|
||||
event.source.postMessage({
|
||||
requestId: request.requestId,
|
||||
action: request.action,
|
||||
payload: res,
|
||||
type: "backgroundMessageResponse",
|
||||
}, event.origin);
|
||||
} catch (error) {
|
||||
event.source.postMessage({
|
||||
requestId: request.requestId,
|
||||
action: request.action,
|
||||
error: error?.message,
|
||||
type: "backgroundMessageResponse",
|
||||
}, event.origin);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -25,7 +25,8 @@ import {
|
||||
kickFromGroup,
|
||||
cancelBan,
|
||||
makeAdmin,
|
||||
removeAdmin
|
||||
removeAdmin,
|
||||
cancelInvitationToGroup
|
||||
} from "../background";
|
||||
import { getNameInfo, uint8ArrayToObject } from "../backgroundFunctions/encryption";
|
||||
import { showSaveFilePicker } from "../components/Apps/useQortalMessageListener";
|
||||
@ -58,6 +59,8 @@ import { getPublishesFromAdminsAdminSpace } from "../components/Chat/AdminSpaceI
|
||||
import nacl from "../deps/nacl-fast";
|
||||
import utils from "../utils/utils";
|
||||
import { RequestQueueWithPromise } from "../utils/queue/queue";
|
||||
import ed2curve from "../deps/ed2curve";
|
||||
import { Sha256 } from "asmcrypto.js";
|
||||
|
||||
export const requestQueueGetAtAddresses = new RequestQueueWithPromise(10);
|
||||
|
||||
@ -4176,4 +4179,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.");
|
||||
}
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user