mirror of
https://github.com/oxen-io/session-desktop.git
synced 2023-12-14 02:12:57 +01:00
Merge pull request #2822 from Bilb/feat/prepare-blinded25-receiving
Feat/prepare blinded25 receiving
This commit is contained in:
commit
7148afa61d
|
@ -6,7 +6,7 @@ import { MessageRenderingProps } from '../../../../models/messageType';
|
|||
import { findCachedBlindedMatchOrLookItUp } from '../../../../session/apis/open_group_api/sogsv3/knownBlindedkeys';
|
||||
import { getConversationController } from '../../../../session/conversations';
|
||||
import { getSodiumRenderer } from '../../../../session/crypto';
|
||||
import { PubKey } from '../../../../session/types';
|
||||
import { KeyPrefixType, PubKey } from '../../../../session/types';
|
||||
import { openConversationWithMessages } from '../../../../state/ducks/conversations';
|
||||
import { updateUserDetailsModal } from '../../../../state/ducks/modalDialog';
|
||||
import {
|
||||
|
@ -61,7 +61,7 @@ export const MessageAvatar = (props: Props) => {
|
|||
const userName = authorName || authorProfileName || sender;
|
||||
|
||||
const onMessageAvatarClick = useCallback(async () => {
|
||||
if (isPublic && !PubKey.hasBlindedPrefix(sender)) {
|
||||
if (isPublic && !PubKey.isBlinded(sender)) {
|
||||
// public chat but session id not blinded. disable showing user details if we do not have an active convo with that user.
|
||||
// an unactive convo with that user means that we never chatted with that id directyly, but only through a sogs
|
||||
const convoWithSender = getConversationController().get(sender);
|
||||
|
@ -84,6 +84,11 @@ export const MessageAvatar = (props: Props) => {
|
|||
}
|
||||
|
||||
if (isPublic && selectedConvoKey) {
|
||||
if (sender.startsWith(KeyPrefixType.blinded25)) {
|
||||
window.log.info('onMessageAvatarClick: blinded25 convo click are disabled currently...');
|
||||
|
||||
return;
|
||||
}
|
||||
const convoOpen = getConversationController().get(selectedConvoKey);
|
||||
const room = OpenGroupData.getV2OpenGroupRoom(convoOpen.id);
|
||||
let privateConvoToOpen = sender;
|
||||
|
|
|
@ -357,7 +357,7 @@ export const CopyMenuItem = (): JSX.Element | null => {
|
|||
export const MarkAllReadMenuItem = (): JSX.Element | null => {
|
||||
const convoId = useConvoIdFromContext();
|
||||
const isIncomingRequest = useIsIncomingRequest(convoId);
|
||||
if (!isIncomingRequest && !PubKey.hasBlindedPrefix(convoId)) {
|
||||
if (!isIncomingRequest && !PubKey.isBlinded(convoId)) {
|
||||
return (
|
||||
<Item onClick={() => markAllReadByConvoId(convoId)}>{window.i18n('markAllAsRead')}</Item>
|
||||
);
|
||||
|
@ -379,7 +379,7 @@ export const BlockMenuItem = (): JSX.Element | null => {
|
|||
const isPrivate = useIsPrivate(convoId);
|
||||
const isIncomingRequest = useIsIncomingRequest(convoId);
|
||||
|
||||
if (!isMe && isPrivate && !isIncomingRequest && !PubKey.hasBlindedPrefix(convoId)) {
|
||||
if (!isMe && isPrivate && !isIncomingRequest && !PubKey.isBlinded(convoId)) {
|
||||
const blockTitle = isBlocked ? window.i18n('unblock') : window.i18n('block');
|
||||
const blockHandler = isBlocked
|
||||
? () => unblockConvoById(convoId)
|
||||
|
|
|
@ -101,7 +101,7 @@ export function useIsBlinded(convoId?: string) {
|
|||
if (!convoId) {
|
||||
return false;
|
||||
}
|
||||
return Boolean(PubKey.hasBlindedPrefix(convoId));
|
||||
return Boolean(PubKey.isBlinded(convoId));
|
||||
}
|
||||
|
||||
export function useHasNickname(convoId?: string) {
|
||||
|
|
|
@ -532,8 +532,8 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
|
|||
);
|
||||
const hasIncomingMessages = incomingMessageCount > 0;
|
||||
|
||||
if (this.id.startsWith('15')) {
|
||||
window.log.info('Sending a blinded message to this user: ', this.id);
|
||||
if (PubKey.isBlinded(this.id)) {
|
||||
window.log.info('Sending a blinded message react to this user: ', this.id);
|
||||
await this.sendBlindedMessageRequest(chatMessageParams);
|
||||
return;
|
||||
}
|
||||
|
@ -1674,7 +1674,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
|
|||
);
|
||||
const hasIncomingMessages = incomingMessageCount > 0;
|
||||
|
||||
if (this.id.startsWith('15')) {
|
||||
if (PubKey.isBlinded(this.id)) {
|
||||
window.log.info('Sending a blinded message to this user: ', this.id);
|
||||
await this.sendBlindedMessageRequest(chatMessageParams);
|
||||
return;
|
||||
|
@ -1778,7 +1778,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
|
|||
const ourSignKeyBytes = await UserUtils.getUserED25519KeyPairBytes();
|
||||
const groupUrl = this.getSogsOriginMessage();
|
||||
|
||||
if (!PubKey.hasBlindedPrefix(this.id)) {
|
||||
if (!PubKey.isBlinded(this.id)) {
|
||||
window?.log?.warn('sendBlindedMessageRequest - convo is not a blinded one');
|
||||
return;
|
||||
}
|
||||
|
@ -1826,7 +1826,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
|
|||
}
|
||||
|
||||
this.set({ active_at: Date.now(), isApproved: true });
|
||||
|
||||
// TODO we need to add support for sending blinded25 message request in addition to the legacy blinded15
|
||||
await getMessageQueue().sendToOpenGroupV2BlindedRequest({
|
||||
encryptedContent: encryptedMsg,
|
||||
roomInfos: roomInfo,
|
||||
|
|
|
@ -1279,7 +1279,7 @@ export function findAndFormatContact(pubkey: string): FindAndFormatContactType {
|
|||
|
||||
if (
|
||||
pubkey === UserUtils.getOurPubKeyStrFromCache() ||
|
||||
(pubkey && pubkey.startsWith('15') && isUsAnySogsFromCache(pubkey))
|
||||
(pubkey && PubKey.isBlinded(pubkey) && isUsAnySogsFromCache(pubkey))
|
||||
) {
|
||||
profileName = window.i18n('you');
|
||||
isMe = true;
|
||||
|
|
|
@ -1676,7 +1676,7 @@ function updateToSessionSchemaVersion31(currentVersion: number, db: BetterSqlite
|
|||
// this filter is based on the `isContactToStoreInWrapper` function. Note, blocked contacts won't be added to the wrapper at first, but will on the first start
|
||||
const contactsToWriteInWrapper = db
|
||||
.prepare(
|
||||
`SELECT * FROM ${CONVERSATIONS_TABLE} WHERE type = 'private' AND active_at > 0 AND priority <> ${CONVERSATION_PRIORITIES.hidden} AND (didApproveMe OR isApproved) AND id <> '$us' AND id NOT LIKE '15%' ;`
|
||||
`SELECT * FROM ${CONVERSATIONS_TABLE} WHERE type = 'private' AND active_at > 0 AND priority <> ${CONVERSATION_PRIORITIES.hidden} AND (didApproveMe OR isApproved) AND id <> '$us' AND id NOT LIKE '15%' AND id NOT LIKE '25%' ;`
|
||||
)
|
||||
.all({
|
||||
us: publicKeyHex,
|
||||
|
|
|
@ -145,8 +145,8 @@ export function tryMatchBlindWithStandardKey(
|
|||
throw new Error('standardKey must be a standard key (starting with 05)');
|
||||
}
|
||||
|
||||
if (!blindedSessionId.startsWith(KeyPrefixType.blinded)) {
|
||||
throw new Error('blindedKey must be a blinded key (starting with 15)');
|
||||
if (!PubKey.isBlinded(blindedSessionId)) {
|
||||
throw new Error('blindedKey must be a blinded key (starting with 15 or 25)');
|
||||
}
|
||||
|
||||
// We don't want to stop iterating even if an error happens while looking for a blind/standard match.
|
||||
|
@ -204,7 +204,7 @@ function findNotCachedBlindingMatch(
|
|||
// we iterate only over the convos private, approved, and which have an unblinded id.
|
||||
const foundConvoMatchingBlindedPubkey = getConversationController()
|
||||
.getConversations()
|
||||
.filter(m => m.isPrivate() && m.isApproved() && !PubKey.hasBlindedPrefix(m.id))
|
||||
.filter(m => m.isPrivate() && m.isApproved() && !PubKey.isBlinded(m.id))
|
||||
.find(m => {
|
||||
return tryMatchBlindWithStandardKey(m.id, blindedId, serverPublicKey, sodium);
|
||||
});
|
||||
|
@ -214,13 +214,13 @@ function findNotCachedBlindingMatch(
|
|||
|
||||
/**
|
||||
* This function returns true if the given blindedId matches our own blinded id on any pysogs.
|
||||
* If the given pubkey is not blinded, it returns true if it is our naked SessionID.
|
||||
* If the given pubkey is not blinded, it returns true if it is our naked SessionID.
|
||||
* It can be used to replace mentions with the @You syntax and for the quotes too
|
||||
*/
|
||||
export function isUsAnySogsFromCache(blindedOrNakedId: string): boolean {
|
||||
const usUnblinded = UserUtils.getOurPubKeyStrFromCache();
|
||||
|
||||
if (!PubKey.hasBlindedPrefix(blindedOrNakedId)) {
|
||||
if (!PubKey.isBlinded(blindedOrNakedId)) {
|
||||
return blindedOrNakedId === usUnblinded;
|
||||
}
|
||||
const found = assertLoaded().find(
|
||||
|
@ -268,7 +268,7 @@ function findNotCachedBlindedConvoFromUnblindedKey(
|
|||
serverPublicKey: string,
|
||||
sodium: LibSodiumWrappers
|
||||
): Array<ConversationModel> {
|
||||
if (PubKey.hasBlindedPrefix(unblindedID)) {
|
||||
if (PubKey.isBlinded(unblindedID)) {
|
||||
throw new Error(
|
||||
'findNotCachedBlindedConvoFromUnblindedKey unblindedID is supposed to be unblinded!'
|
||||
);
|
||||
|
@ -279,7 +279,7 @@ function findNotCachedBlindedConvoFromUnblindedKey(
|
|||
const foundConvosForThisServerPk =
|
||||
getConversationController()
|
||||
.getConversations()
|
||||
.filter(m => m.isPrivate() && PubKey.hasBlindedPrefix(m.id) && m.isActive())
|
||||
.filter(m => m.isPrivate() && PubKey.isBlinded(m.id) && m.isActive())
|
||||
.filter(m => {
|
||||
return tryMatchBlindWithStandardKey(unblindedID, m.id, serverPublicKey, sodium);
|
||||
}) || [];
|
||||
|
@ -302,7 +302,7 @@ export async function findCachedBlindedMatchOrLookItUp(
|
|||
serverPubKey: string,
|
||||
sodium: LibSodiumWrappers
|
||||
): Promise<string | undefined> {
|
||||
if (!PubKey.hasBlindedPrefix(blindedId)) {
|
||||
if (!PubKey.isBlinded(blindedId)) {
|
||||
return blindedId;
|
||||
}
|
||||
const found = getCachedNakedKeyFromBlinded(blindedId, serverPubKey);
|
||||
|
@ -333,7 +333,7 @@ export function findCachedBlindedIdFromUnblinded(
|
|||
unblindedId: string,
|
||||
serverPubKey: string
|
||||
): string | undefined {
|
||||
if (PubKey.hasBlindedPrefix(unblindedId)) {
|
||||
if (PubKey.isBlinded(unblindedId)) {
|
||||
throw new Error('findCachedBlindedIdFromUnblinded needs an unblindedID');
|
||||
}
|
||||
const found = assertLoaded().find(
|
||||
|
@ -351,7 +351,7 @@ export async function findCachedOurBlindedPubkeyOrLookItUp(
|
|||
): Promise<string> {
|
||||
const ourNakedSessionID = UserUtils.getOurPubKeyStrFromCache();
|
||||
|
||||
if (PubKey.hasBlindedPrefix(ourNakedSessionID)) {
|
||||
if (PubKey.isBlinded(ourNakedSessionID)) {
|
||||
throw new Error('findCachedBlindedIdFromUnblindedOrLookItUp needs a unblindedID');
|
||||
}
|
||||
let found = findCachedBlindedIdFromUnblinded(ourNakedSessionID, serverPubKey);
|
||||
|
@ -402,7 +402,7 @@ export function findCachedBlindedMatchOrLookupOnAllServers(
|
|||
unblindedId: string,
|
||||
sodium: LibSodiumWrappers
|
||||
): Array<ConversationModel> {
|
||||
if (PubKey.hasBlindedPrefix(unblindedId)) {
|
||||
if (PubKey.isBlinded(unblindedId)) {
|
||||
throw new Error('findCachedBlindedMatchOrLookupOnAllServers needs an unblindedId');
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,8 @@ async function getOpenGroupHeaders(data: {
|
|||
const blindingValues = getBlindingValues(serverPK, signingKeys, sodium);
|
||||
ka = blindingValues.secretKey;
|
||||
kA = blindingValues.publicKey;
|
||||
pubkey = `${KeyPrefixType.blinded}${toHex(kA)}`;
|
||||
// TODO we will need to add the support of blinded25 here
|
||||
pubkey = `${KeyPrefixType.blinded15}${toHex(kA)}`;
|
||||
} else {
|
||||
pubkey = `${KeyPrefixType.unblinded}${toHex(signingKeys.pubKeyBytes)}`;
|
||||
}
|
||||
|
@ -151,7 +152,8 @@ const getBlindedPubKey = (
|
|||
sodium: LibSodiumWrappers
|
||||
): string => {
|
||||
const blindedPubKeyBytes = getBlindingValues(serverPK, signingKeys, sodium);
|
||||
return `${KeyPrefixType.blinded}${to_hex(blindedPubKeyBytes.publicKey)}`;
|
||||
// TODO we will need to add the support of blinded25 here
|
||||
return `${KeyPrefixType.blinded15}${to_hex(blindedPubKeyBytes.publicKey)}`;
|
||||
};
|
||||
|
||||
const getBlindingValues = (
|
||||
|
|
|
@ -187,7 +187,7 @@ export class ConversationController {
|
|||
'getConversationController().deleteBlindedContact() needs complete initial fetch'
|
||||
);
|
||||
}
|
||||
if (!PubKey.hasBlindedPrefix(blindedId)) {
|
||||
if (!PubKey.isBlinded(blindedId)) {
|
||||
throw new Error('deleteBlindedContact allow accepts blinded id');
|
||||
}
|
||||
window.log.info(`deleteBlindedContact with ${blindedId}`);
|
||||
|
|
|
@ -139,7 +139,8 @@ export class MessageQueue {
|
|||
recipientBlindedId: string;
|
||||
}) {
|
||||
try {
|
||||
if (!PubKey.hasBlindedPrefix(recipientBlindedId)) {
|
||||
// TODO we will need to add the support for blinded25 messages requests
|
||||
if (!PubKey.isBlinded(recipientBlindedId)) {
|
||||
throw new Error('sendToOpenGroupV2BlindedRequest needs a blindedId');
|
||||
}
|
||||
const { serverTimestamp, serverId } = await MessageSender.sendToOpenGroupV2BlindedRequest(
|
||||
|
|
|
@ -10,9 +10,15 @@ export enum KeyPrefixType {
|
|||
*/
|
||||
standard = '05',
|
||||
/**
|
||||
* used for participants in open groups
|
||||
* used for participants in open groups (legacy blinding logic)
|
||||
*/
|
||||
blinded = '15',
|
||||
blinded15 = '15',
|
||||
|
||||
/**
|
||||
* used for participants in open groups (new blinding logic)
|
||||
*/
|
||||
blinded25 = '25',
|
||||
|
||||
/**
|
||||
* used for participants in open groups
|
||||
*/
|
||||
|
@ -32,7 +38,7 @@ export class PubKey {
|
|||
public static readonly PREFIX_GROUP_TEXTSECURE = '__textsecure_group__!';
|
||||
// prettier-ignore
|
||||
private static readonly regex: RegExp = new RegExp(
|
||||
`^(${PubKey.PREFIX_GROUP_TEXTSECURE})?(${KeyPrefixType.standard}|${KeyPrefixType.blinded}|${KeyPrefixType.unblinded}|${KeyPrefixType.groupV3})?(${PubKey.HEX}{64}|${PubKey.HEX}{32})$`
|
||||
`^(${PubKey.PREFIX_GROUP_TEXTSECURE})?(${KeyPrefixType.standard}|${KeyPrefixType.blinded15}|${KeyPrefixType.blinded25}|${KeyPrefixType.unblinded}|${KeyPrefixType.groupV3})?(${PubKey.HEX}{64}|${PubKey.HEX}{32})$`
|
||||
);
|
||||
/**
|
||||
* If you want to update this regex. Be sure that those are matches ;
|
||||
|
@ -146,18 +152,19 @@ export class PubKey {
|
|||
|
||||
/**
|
||||
* @param keyWithOrWithoutPrefix Key with or without prefix
|
||||
* @returns If key is the correct length and has a supported prefix 05 or 15
|
||||
* @returns If key is the correct length and has a supported prefix 05, 15, 25
|
||||
*/
|
||||
public static isValidPrefixAndLength(keyWithOrWithoutPrefix: string): boolean {
|
||||
return (
|
||||
keyWithOrWithoutPrefix.length === 66 &&
|
||||
(keyWithOrWithoutPrefix.startsWith(KeyPrefixType.blinded) ||
|
||||
(keyWithOrWithoutPrefix.startsWith(KeyPrefixType.blinded15) ||
|
||||
keyWithOrWithoutPrefix.startsWith(KeyPrefixType.blinded25) ||
|
||||
keyWithOrWithoutPrefix.startsWith(KeyPrefixType.standard))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This removes the 05 or 15 prefix from a Pubkey which have it and have a length of 66
|
||||
* This removes the 05, 15 or 25 prefix from a Pubkey which have it and have a length of 66
|
||||
* @param keyWithOrWithoutPrefix the key with or without the prefix
|
||||
*/
|
||||
public static removePrefixIfNeeded(keyWithOrWithoutPrefix: string): string {
|
||||
|
@ -230,8 +237,8 @@ export class PubKey {
|
|||
return fromHexToArray(PubKey.removePrefixIfNeeded(this.key));
|
||||
}
|
||||
|
||||
public static hasBlindedPrefix(key: string) {
|
||||
return key.startsWith(KeyPrefixType.blinded);
|
||||
public static isBlinded(key: string) {
|
||||
return key.startsWith(KeyPrefixType.blinded15) || key.startsWith(KeyPrefixType.blinded25);
|
||||
}
|
||||
|
||||
public static isClosedGroupV3(key: string) {
|
||||
|
|
|
@ -29,9 +29,7 @@ const mappedContactWrapperValues = new Map<string, ContactInfo>();
|
|||
* We want to sync the message request status so we need to allow a contact even if it's not approved, did not approve us and is not blocked.
|
||||
*/
|
||||
function isContactToStoreInWrapper(convo: ConversationModel): boolean {
|
||||
return (
|
||||
!convo.isMe() && convo.isPrivate() && convo.isActive() && !PubKey.hasBlindedPrefix(convo.id)
|
||||
);
|
||||
return !convo.isMe() && convo.isPrivate() && convo.isActive() && !PubKey.isBlinded(convo.id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -204,7 +204,7 @@ const getValidContacts = (convos: Array<ConversationModel>) => {
|
|||
c.getRealSessionUsername() &&
|
||||
c.isPrivate() &&
|
||||
c.isApproved() &&
|
||||
!PubKey.hasBlindedPrefix(c.get('id'))
|
||||
!PubKey.isBlinded(c.get('id'))
|
||||
);
|
||||
|
||||
const contacts = contactsModels.map(c => {
|
||||
|
|
|
@ -785,7 +785,7 @@ export const getMessageQuoteProps = createSelector(
|
|||
const isFromMe = isUsAnySogsFromCache(author) || false;
|
||||
|
||||
// NOTE the quote lookup map always stores our messages using the unblinded pubkey
|
||||
if (isFromMe && PubKey.hasBlindedPrefix(author)) {
|
||||
if (isFromMe && PubKey.isBlinded(author)) {
|
||||
author = UserUtils.getOurPubKeyStrFromCache();
|
||||
}
|
||||
|
||||
|
|
|
@ -418,7 +418,7 @@ describe('knownBlindedKeys', () => {
|
|||
it('throws if blindedSessionId is not standard', () => {
|
||||
expect(() => {
|
||||
tryMatchBlindWithStandardKey(realSessionId, realSessionId, serverPublicKey, sodium);
|
||||
}).to.throw('blindedKey must be a blinded key (starting with 15)');
|
||||
}).to.throw('blindedKey must be a blinded key (starting with 15 or 25)');
|
||||
});
|
||||
|
||||
it('returns true if those keys are not matching blind & naked', () => {
|
||||
|
|
|
@ -141,7 +141,8 @@ async function verifySignature(
|
|||
}
|
||||
const messageData = fromBase64ToUint8Array(messageBase64);
|
||||
const signature = fromBase64ToUint8Array(signatureBase64);
|
||||
const isBlindedSender = senderPubKey.startsWith('15');
|
||||
// blinded15 or blinded25 are the same for the verifySignature logic
|
||||
const isBlindedSender = senderPubKey.startsWith('15') || senderPubKey.startsWith('25');
|
||||
|
||||
const pubkeyWithoutPrefix = senderPubKey.slice(2);
|
||||
const pubkeyBytes = fromHexToArray(pubkeyWithoutPrefix);
|
||||
|
|
Loading…
Reference in a new issue