refactor and tweaks

This commit is contained in:
Reinaldo Neto 2023-02-15 18:21:38 -03:00
parent 4ea8aabe6b
commit 21acdd9f2c
10 changed files with 101 additions and 36 deletions

View File

@ -149,7 +149,7 @@ export interface IMessage extends IMessageFromServer {
export type TMessageModel = IMessage & export type TMessageModel = IMessage &
Model & { Model & {
asPlain?: () => IMessage; asPlain: () => IMessage;
}; };
export type TAnyMessageModel = TMessageModel | TThreadModel | TThreadMessageModel; export type TAnyMessageModel = TMessageModel | TThreadModel | TThreadMessageModel;

View File

@ -38,4 +38,7 @@ export interface IThread extends IMessage {
draftMessage?: string; draftMessage?: string;
} }
export type TThreadModel = IThread & Model; export type TThreadModel = IThread &
Model & {
asPlain: () => IMessage;
};

View File

@ -6,4 +6,7 @@ export interface IThreadMessage extends IMessage {
tmsg?: string; tmsg?: string;
} }
export type TThreadMessageModel = IThreadMessage & Model; export type TThreadMessageModel = IThreadMessage &
Model & {
asPlain: () => IMessage;
};

View File

@ -77,4 +77,42 @@ export default class Thread extends Model {
@field('e2e') e2e; @field('e2e') e2e;
@field('draft_message') draftMessage; @field('draft_message') draftMessage;
asPlain() {
return {
id: this.id,
msg: this.msg,
t: this.t,
ts: this.ts,
u: this.u,
alias: this.alias,
parseUrls: this.parseUrls,
groupable: this.groupable,
avatar: this.avatar,
emoji: this.emoji,
attachments: this.attachments,
urls: this.urls,
_updatedAt: this._updatedAt,
status: this.status,
pinned: this.pinned,
starred: this.starred,
editedBy: this.editedBy,
reactions: this.reactions,
role: this.role,
drid: this.drid,
dcount: this.dcount,
dlm: this.dlm,
tmid: this.tmid,
tcount: this.tcount,
tlm: this.tlm,
replies: this.replies,
mentions: this.mentions,
channels: this.channels,
unread: this.unread,
autoTranslate: this.autoTranslate,
translations: this.translations,
e2e: this.e2e,
draftMessage: this.draftMessage
};
}
} }

View File

@ -77,4 +77,42 @@ export default class ThreadMessage extends Model {
@field('draft_message') draftMessage; @field('draft_message') draftMessage;
@field('e2e') e2e; @field('e2e') e2e;
asPlain() {
return {
id: this.id,
msg: this.msg,
t: this.t,
ts: this.ts,
u: this.u,
rid: this.rid,
alias: this.alias,
parseUrls: this.parseUrls,
groupable: this.groupable,
avatar: this.avatar,
emoji: this.emoji,
attachments: this.attachments,
urls: this.urls,
_updatedAt: this._updatedAt,
status: this.status,
pinned: this.pinned,
starred: this.starred,
editedBy: this.editedBy,
reactions: this.reactions,
role: this.role,
drid: this.drid,
dcount: this.dcount,
dlm: this.dlm,
tcount: this.tcount,
tlm: this.tlm,
replies: this.replies,
mentions: this.mentions,
channels: this.channels,
unread: this.unread,
autoTranslate: this.autoTranslate,
translations: this.translations,
draftMessage: this.draftMessage,
e2e: this.e2e
};
}
} }

View File

@ -1,5 +1,3 @@
import { Clause } from '@nozbe/watermelondb/QueryDescription';
import database from '..'; import database from '..';
import { TAppDatabase } from '../interfaces'; import { TAppDatabase } from '../interfaces';
import { MESSAGES_TABLE } from '../model/Message'; import { MESSAGES_TABLE } from '../model/Message';
@ -15,18 +13,7 @@ export const getMessageById = async (messageId: string | null) => {
try { try {
const result = await messageCollection.find(messageId); const result = await messageCollection.find(messageId);
return result; return result;
} catch (error) { } catch {
return null;
}
};
export const getMessageByQuery = async (...query: Clause[]) => {
const db = database.active;
const messageCollection = getCollection(db);
try {
const result = await messageCollection.query(...query).fetch();
return result;
} catch (error) {
return null; return null;
} }
}; };

View File

@ -1,2 +1,3 @@
// https://github.com/RocketChat/Rocket.Chat/blob/0226236b871d12c62338111c70b65d5d406447a3/apps/meteor/lib/getMessageUrlRegex.ts#L1-L2
export const getMessageUrlRegex = (): RegExp => export const getMessageUrlRegex = (): RegExp =>
/([A-Za-z]{3,9}):\/\/([-;:&=\+\$,\w]+@{1})?([-A-Za-z0-9\.]+)+:?(\d+)?((\/[-\+=!:~%\/\.@\,\w]*)?\??([-\+=&!:;%@\/\.\,\w]+)?(?:#([^\s\)]+))?)?/g; /([A-Za-z]{3,9}):\/\/([-;:&=\+\$,\w]+@{1})?([-A-Za-z0-9\.]+)+:?(\d+)?((\/[-\+=!:~%\/\.@\,\w]*)?\??([-\+=&!:;%@\/\.\,\w]+)?(?:#([^\s\)]+))?)?/g;

View File

@ -1,13 +1,10 @@
import { IMessage } from '../../../definitions'; import { IMessage } from '../../../definitions';
export const mapMessageFromApi = ({ attachments, tlm, ts, _updatedAt, ...message }: IMessage) => ({ export const mapMessageFromAPI = ({ attachments, tlm, ts, _updatedAt, ...message }: IMessage) => ({
...message, ...message,
ts: new Date(ts), ts: new Date(ts),
...(tlm && { tlm: new Date(tlm) }), ...(tlm && { tlm: new Date(tlm) }),
_updatedAt: new Date(_updatedAt), _updatedAt: new Date(_updatedAt),
// FIXME: webRtcCallEndTs doesn't exist in our interface IMessage, but exists on @rocket.chat/core-typings
// @ts-ignore
...(message?.webRtcCallEndTs && { webRtcCallEndTs: new Date(message.webRtcCallEndTs) }),
...(attachments && { ...(attachments && {
attachments: attachments.map(({ ts, ...attachment }) => ({ attachments: attachments.map(({ ts, ...attachment }) => ({
...(ts && { ts: new Date(ts) }), ...(ts && { ts: new Date(ts) }),

View File

@ -1,15 +1,12 @@
import { TMessageModel } from '../../../definitions'; import { TMessageModel } from '../../../definitions';
export const mapMessageFromDB = (messageModel: TMessageModel) => { export const mapMessageFromDB = (messageModel: TMessageModel) => {
const parsedMessage = messageModel.asPlain!(); const parsedMessage = messageModel.asPlain();
return { return {
...parsedMessage, ...parsedMessage,
ts: new Date(parsedMessage.ts), ts: new Date(parsedMessage.ts),
...(parsedMessage.tlm && { tlm: new Date(parsedMessage.tlm) }), ...(parsedMessage.tlm && { tlm: new Date(parsedMessage.tlm) }),
_updatedAt: new Date(parsedMessage._updatedAt), _updatedAt: new Date(parsedMessage._updatedAt),
// FIXME: webRtcCallEndTs doesn't exist in our interface IMessage, but exists on @rocket.chat/core-typings
// @ts-ignore
...(parsedMessage?.webRtcCallEndTs && { webRtcCallEndTs: new Date(parsedMessage.webRtcCallEndTs) }),
...(parsedMessage.attachments && { ...(parsedMessage.attachments && {
attachments: parsedMessage.attachments.map(({ ts, ...attachment }) => ({ attachments: parsedMessage.attachments.map(({ ts, ...attachment }) => ({
...(ts && { ts: new Date(ts) }), ...(ts && { ts: new Date(ts) }),

View File

@ -3,7 +3,6 @@ import { Base64 } from 'js-base64';
import SimpleCrypto from 'react-native-simple-crypto'; import SimpleCrypto from 'react-native-simple-crypto';
import ByteBuffer from 'bytebuffer'; import ByteBuffer from 'bytebuffer';
import parse from 'url-parse'; import parse from 'url-parse';
import { Q } from '@nozbe/watermelondb';
import getSingleMessage from '../methods/getSingleMessage'; import getSingleMessage from '../methods/getSingleMessage';
import { IMessage, IUser } from '../../definitions'; import { IMessage, IUser } from '../../definitions';
@ -25,10 +24,10 @@ import { Encryption } from './index';
import { E2E_MESSAGE_TYPE, E2E_STATUS } from '../constants'; import { E2E_MESSAGE_TYPE, E2E_STATUS } from '../constants';
import { Services } from '../services'; import { Services } from '../services';
import { getMessageUrlRegex } from './helpers/getMessageUrlRegex'; import { getMessageUrlRegex } from './helpers/getMessageUrlRegex';
import { mapMessageFromApi } from './helpers/mapMessageFromApi'; import { mapMessageFromAPI } from './helpers/mapMessageFromAPI';
import { mapMessageFromDB } from './helpers/mapMessageFromDB'; import { mapMessageFromDB } from './helpers/mapMessageFromDB';
import { createQuoteAttachment } from './helpers/createQuoteAttachment'; import { createQuoteAttachment } from './helpers/createQuoteAttachment';
import { getMessageByQuery } from '../database/services/Message'; import { getMessageById } from '../database/services/Message';
export default class EncryptionRoom { export default class EncryptionRoom {
ready: boolean; ready: boolean;
@ -283,7 +282,7 @@ export default class EncryptionRoom {
e2e: 'done' e2e: 'done'
}; };
const decryptedMessageWithQuote = await this.parseQuoteAttachment(decryptedMessage); const decryptedMessageWithQuote = await this.decryptQuoteAttachment(decryptedMessage);
return decryptedMessageWithQuote; return decryptedMessageWithQuote;
} }
} catch { } catch {
@ -293,29 +292,31 @@ export default class EncryptionRoom {
return message; return message;
}; };
async parseQuoteAttachment(message: IMessage) { async decryptQuoteAttachment(message: IMessage) {
const urls = message.msg?.match(getMessageUrlRegex()) || []; const urls = message?.msg?.match(getMessageUrlRegex()) || [];
await Promise.all( await Promise.all(
urls.map(async (url: string) => { urls.map(async (url: string) => {
const parsedUrl = parse(url, true); const parsedUrl = parse(url, true);
const messageId = parsedUrl.query?.msg; const messageId = parsedUrl.query?.msg;
if (!messageId || Array.isArray(messageId)) { if (!messageId) {
return; return;
} }
const messageFromDB = await getMessageByQuery(Q.and(Q.where('id', messageId), Q.where('e2e', E2E_STATUS.DONE))); // From local db
if (messageFromDB?.length) { const messageFromDB = await getMessageById(messageId);
const decryptedQuoteMessage = mapMessageFromDB(messageFromDB[0]); if (messageFromDB && messageFromDB.e2e === 'done') {
const decryptedQuoteMessage = mapMessageFromDB(messageFromDB);
message.attachments = message.attachments || []; message.attachments = message.attachments || [];
const quoteAttachment = createQuoteAttachment(decryptedQuoteMessage, url); const quoteAttachment = createQuoteAttachment(decryptedQuoteMessage, url);
return message.attachments.push(quoteAttachment); return message.attachments.push(quoteAttachment);
} }
// From API
const quotedMessageObject = await getSingleMessage(messageId); const quotedMessageObject = await getSingleMessage(messageId);
if (!quotedMessageObject) { if (!quotedMessageObject) {
return; return;
} }
const decryptedQuoteMessage = await this.decrypt(mapMessageFromApi(quotedMessageObject)); const decryptedQuoteMessage = await this.decrypt(mapMessageFromAPI(quotedMessageObject));
message.attachments = message.attachments || []; message.attachments = message.attachments || [];
const quoteAttachment = createQuoteAttachment(decryptedQuoteMessage, url); const quoteAttachment = createQuoteAttachment(decryptedQuoteMessage, url);
return message.attachments.push(quoteAttachment); return message.attachments.push(quoteAttachment);