mirror of
https://github.com/oxen-io/session-desktop.git
synced 2023-12-14 02:12:57 +01:00
move some message interactions logic to another file
This commit is contained in:
parent
3b30d13719
commit
193fb2a101
|
@ -384,6 +384,8 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
|
|||
return;
|
||||
}
|
||||
|
||||
// guess if this is an open
|
||||
|
||||
// Server URL valid?
|
||||
if (serverUrl.length === 0 || !OpenGroup.validate(serverUrl)) {
|
||||
ToastUtils.pushToastError('connectToServer', window.i18n('invalidOpenGroupUrl'));
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { OpenGroupRequestCommonType } from '../opengroup/opengroupV2/ApiUtil';
|
||||
import { isOpenGroupV2 } from '../opengroup/utils/OpenGroupUtils';
|
||||
import { channels } from './channels';
|
||||
|
||||
export type OpenGroupV2Room = {
|
||||
|
@ -35,7 +36,10 @@ export async function getAllV2OpenGroupRooms(): Promise<Map<string, OpenGroupV2R
|
|||
export async function getV2OpenGroupRoom(
|
||||
conversationId: string
|
||||
): Promise<OpenGroupV2Room | undefined> {
|
||||
const opengroupv2Rooms = await channels.getV2OpenGroupRoom(conversationId);
|
||||
if (!isOpenGroupV2(conversationId)) {
|
||||
throw new Error(`getV2OpenGroupRoom: this is not a valid v2 id: ${conversationId}`);
|
||||
}
|
||||
const opengroupv2Rooms = channels.getV2OpenGroupRoom(conversationId);
|
||||
|
||||
if (!opengroupv2Rooms) {
|
||||
return undefined;
|
||||
|
|
3
ts/interactions/index.ts
Normal file
3
ts/interactions/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import * as MessageInteraction from './message';
|
||||
|
||||
export { MessageInteraction };
|
62
ts/interactions/message.ts
Normal file
62
ts/interactions/message.ts
Normal file
|
@ -0,0 +1,62 @@
|
|||
import _ from 'lodash';
|
||||
import { getV2OpenGroupRoom } from '../data/opengroups';
|
||||
import { ConversationModel } from '../models/conversation';
|
||||
import { ApiV2 } from '../opengroup/opengroupV2';
|
||||
import { isOpenGroupV2 } from '../opengroup/utils/OpenGroupUtils';
|
||||
import { PubKey } from '../session/types';
|
||||
import { ToastUtils } from '../session/utils';
|
||||
|
||||
export function banUser(userToBan: string, conversation?: ConversationModel) {
|
||||
let pubKeyToBan: PubKey;
|
||||
try {
|
||||
pubKeyToBan = PubKey.cast(userToBan);
|
||||
} catch (e) {
|
||||
window.log.warn(e);
|
||||
ToastUtils.pushUserBanFailure();
|
||||
return;
|
||||
}
|
||||
window.confirmationDialog({
|
||||
title: window.i18n('banUser'),
|
||||
message: window.i18n('banUserConfirm'),
|
||||
resolve: async () => {
|
||||
if (!conversation) {
|
||||
window.log.info('cannot ban user, the corresponding conversation was not found.');
|
||||
return;
|
||||
}
|
||||
let success = false;
|
||||
if (isOpenGroupV2(conversation.id)) {
|
||||
const roomInfos = await getV2OpenGroupRoom(conversation.id);
|
||||
if (!roomInfos) {
|
||||
window.log.warn('banUser room not found');
|
||||
} else {
|
||||
await ApiV2.banUser(pubKeyToBan, _.pick(roomInfos, 'serverUrl', 'roomId'));
|
||||
}
|
||||
} else {
|
||||
const channelAPI = await conversation.getPublicSendData();
|
||||
if (!channelAPI) {
|
||||
window.log.info('cannot ban user, the corresponding channelAPI was not found.');
|
||||
return;
|
||||
}
|
||||
success = await channelAPI.banUser(userToBan);
|
||||
}
|
||||
if (success) {
|
||||
ToastUtils.pushUserBanSuccess();
|
||||
} else {
|
||||
ToastUtils.pushUserBanFailure();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function copyBodyToClipboard(body?: string) {
|
||||
window.clipboard.writeText(body);
|
||||
|
||||
ToastUtils.pushCopiedToClipBoard();
|
||||
}
|
||||
|
||||
export function copyPubKey(sender: string) {
|
||||
// this.getSource return out pubkey if this is an outgoing message, or the sender pubkey
|
||||
window.clipboard.writeText();
|
||||
|
||||
ToastUtils.pushCopiedToClipBoard();
|
||||
}
|
|
@ -37,11 +37,14 @@ import {
|
|||
import { GroupInvitationMessage } from '../session/messages/outgoing/visibleMessage/GroupInvitationMessage';
|
||||
import { ReadReceiptMessage } from '../session/messages/outgoing/controlMessage/receipt/ReadReceiptMessage';
|
||||
import { OpenGroup } from '../opengroup/opengroupV1/OpenGroup';
|
||||
import { openGroupPrefixRegex } from '../opengroup/utils/OpenGroupUtils';
|
||||
import {
|
||||
openGroupPrefixRegex,
|
||||
openGroupV1ConversationIdRegex,
|
||||
openGroupV2ConversationIdRegex,
|
||||
} from '../opengroup/utils/OpenGroupUtils';
|
||||
|
||||
export enum ConversationType {
|
||||
GROUP = 'group',
|
||||
OPEN_GROUP = 'opengroup',
|
||||
PRIVATE = 'private',
|
||||
}
|
||||
|
||||
|
@ -188,11 +191,11 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
|
|||
public isMe() {
|
||||
return UserUtils.isUsFromCache(this.id);
|
||||
}
|
||||
public isPublic() {
|
||||
return !!(this.id && this.id.match(openGroupPrefixRegex));
|
||||
public isPublic(): boolean {
|
||||
return Boolean(this.id && this.id.match(openGroupPrefixRegex));
|
||||
}
|
||||
public isOpenGroupV2() {
|
||||
return this.get('type') === ConversationType.OPEN_GROUP;
|
||||
public isOpenGroupV2(): boolean {
|
||||
return Boolean(this.id && this.id.match(openGroupV2ConversationIdRegex));
|
||||
}
|
||||
public isClosedGroup() {
|
||||
return this.get('type') === ConversationType.GROUP && !this.isPublic();
|
||||
|
@ -374,7 +377,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
|
|||
const groupAdmins = this.getGroupAdmins();
|
||||
|
||||
const members = this.isGroup() && !this.isPublic() ? this.get('members') : undefined;
|
||||
|
||||
// isSelected is overriden by redux
|
||||
return {
|
||||
isSelected: false,
|
||||
|
@ -1309,6 +1311,10 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
|
|||
}
|
||||
|
||||
public async deletePublicMessages(messages: Array<MessageModel>) {
|
||||
if (this.isOpenGroupV2()) {
|
||||
console.warn('FIXME deletePublicMessages');
|
||||
throw new Error('deletePublicMessages todo');
|
||||
}
|
||||
const channelAPI = await this.getPublicSendData();
|
||||
|
||||
if (!channelAPI) {
|
||||
|
|
|
@ -25,6 +25,8 @@ import { VisibleMessage } from '../session/messages/outgoing/visibleMessage/Visi
|
|||
import { buildSyncMessage } from '../session/utils/syncUtils';
|
||||
import { isOpenGroupV2 } from '../opengroup/utils/OpenGroupUtils';
|
||||
import { banUser } from '../opengroup/opengroupV2/OpenGroupAPIV2';
|
||||
import { getV2OpenGroupRoom } from '../data/opengroups';
|
||||
import { MessageInteraction } from '../interactions';
|
||||
export class MessageModel extends Backbone.Model<MessageAttributes> {
|
||||
public propsForTimerNotification: any;
|
||||
public propsForGroupNotification: any;
|
||||
|
@ -456,8 +458,6 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
|
|||
const expirationTimestamp =
|
||||
expirationLength && expireTimerStart ? expireTimerStart + expirationLength : null;
|
||||
|
||||
// TODO: investigate why conversation is undefined
|
||||
// for the public group chat
|
||||
const conversation = this.getConversation();
|
||||
|
||||
const convoId = conversation ? conversation.id : undefined;
|
||||
|
@ -697,50 +697,16 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
|
|||
}
|
||||
|
||||
public copyPubKey() {
|
||||
if (this.isIncoming()) {
|
||||
window.clipboard.writeText(this.get('source'));
|
||||
} else {
|
||||
window.clipboard.writeText(UserUtils.getOurPubKeyStrFromCache());
|
||||
}
|
||||
|
||||
ToastUtils.pushCopiedToClipBoard();
|
||||
// this.getSource return out pubkey if this is an outgoing message, or the sender pubkey
|
||||
MessageInteraction.copyPubKey(this.getSource());
|
||||
}
|
||||
|
||||
public banUser() {
|
||||
window.confirmationDialog({
|
||||
title: window.i18n('banUser'),
|
||||
message: window.i18n('banUserConfirm'),
|
||||
resolve: async () => {
|
||||
const source = this.get('source');
|
||||
const conversation = this.getConversation();
|
||||
if (!conversation) {
|
||||
window.log.info('cannot ban user, the corresponding conversation was not found.');
|
||||
return;
|
||||
}
|
||||
let success = false;
|
||||
if (isOpenGroupV2(conversation.id)) {
|
||||
await banUser();
|
||||
} else {
|
||||
const channelAPI = await conversation.getPublicSendData();
|
||||
if (!channelAPI) {
|
||||
window.log.info('cannot ban user, the corresponding channelAPI was not found.');
|
||||
return;
|
||||
}
|
||||
success = await channelAPI.banUser(source);
|
||||
}
|
||||
if (success) {
|
||||
ToastUtils.pushUserBanSuccess();
|
||||
} else {
|
||||
ToastUtils.pushUserBanFailure();
|
||||
}
|
||||
},
|
||||
});
|
||||
MessageInteraction.banUser(this.get('source'), this.getConversation());
|
||||
}
|
||||
|
||||
public copyText() {
|
||||
window.clipboard.writeText(this.get('body'));
|
||||
|
||||
ToastUtils.pushCopiedToClipBoard();
|
||||
MessageInteraction.copyBodyToClipboard(this.get('body'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,6 +2,7 @@ import _ from 'lodash';
|
|||
import { getV2OpenGroupRoomByRoomId, saveV2OpenGroupRoom } from '../../data/opengroups';
|
||||
import { ConversationController } from '../../session/conversations';
|
||||
import { sendViaOnion } from '../../session/onions/onionSend';
|
||||
import { PubKey } from '../../session/types';
|
||||
import { allowOnlyOneAtATime } from '../../session/utils/Promise';
|
||||
import {
|
||||
fromArrayBufferToBase64,
|
||||
|
@ -273,7 +274,10 @@ export async function getAuthToken({
|
|||
return null;
|
||||
}
|
||||
|
||||
export const deleteAuthToken = async ({ serverUrl, roomId }: OpenGroupRequestCommonType) => {
|
||||
export const deleteAuthToken = async ({
|
||||
serverUrl,
|
||||
roomId,
|
||||
}: OpenGroupRequestCommonType): Promise<boolean> => {
|
||||
const request: OpenGroupV2Request = {
|
||||
method: 'DELETE',
|
||||
room: roomId,
|
||||
|
@ -281,10 +285,17 @@ export const deleteAuthToken = async ({ serverUrl, roomId }: OpenGroupRequestCom
|
|||
isAuthRequired: false,
|
||||
endpoint: 'auth_token',
|
||||
};
|
||||
const result = await sendOpenGroupV2Request(request);
|
||||
const statusCode = parseStatusCodeFromOnionRequest(result);
|
||||
if (statusCode !== 200) {
|
||||
window.log.warn(`Could not deleteAuthToken, status code: ${statusCode}`);
|
||||
try {
|
||||
const result = await sendOpenGroupV2Request(request);
|
||||
const statusCode = parseStatusCodeFromOnionRequest(result);
|
||||
if (statusCode !== 200) {
|
||||
window.log.warn(`Could not deleteAuthToken, status code: ${statusCode}`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (e) {
|
||||
window.log.error('deleteAuthToken failed:', e);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -402,10 +413,10 @@ export const isUserModerator = (
|
|||
};
|
||||
|
||||
export const banUser = async (
|
||||
publicKey: string,
|
||||
userToBan: PubKey,
|
||||
roomInfos: OpenGroupRequestCommonType
|
||||
): Promise<void> => {
|
||||
const queryParams = { public_key: publicKey };
|
||||
const queryParams = { public_key: userToBan.key };
|
||||
const request: OpenGroupV2Request = {
|
||||
method: 'POST',
|
||||
room: roomInfos.roomId,
|
||||
|
@ -414,11 +425,12 @@ export const banUser = async (
|
|||
queryParams,
|
||||
endpoint: 'block_list',
|
||||
};
|
||||
await sendOpenGroupV2Request(request);
|
||||
const banResult = await sendOpenGroupV2Request(request);
|
||||
console.warn('banResult', banResult);
|
||||
};
|
||||
|
||||
export const unbanUser = async (
|
||||
publicKey: string,
|
||||
userToBan: PubKey,
|
||||
roomInfos: OpenGroupRequestCommonType
|
||||
): Promise<void> => {
|
||||
const request: OpenGroupV2Request = {
|
||||
|
@ -426,7 +438,7 @@ export const unbanUser = async (
|
|||
room: roomInfos.roomId,
|
||||
server: roomInfos.serverUrl,
|
||||
isAuthRequired: true,
|
||||
endpoint: `block_list/${publicKey}`,
|
||||
endpoint: `block_list/${userToBan.key}`,
|
||||
};
|
||||
await sendOpenGroupV2Request(request);
|
||||
};
|
||||
|
|
|
@ -62,16 +62,19 @@ async function attemptConnectionV2(
|
|||
}
|
||||
const conversation = await ConversationController.getInstance().getOrCreateAndWait(
|
||||
conversationId,
|
||||
ConversationType.OPEN_GROUP
|
||||
ConversationType.GROUP
|
||||
);
|
||||
room.imageID = roomInfos.imageId || undefined;
|
||||
room.roomName = roomInfos.name || undefined;
|
||||
await saveV2OpenGroupRoom(room);
|
||||
|
||||
console.warn('openGroupRoom info', roomInfos);
|
||||
|
||||
// mark active so it's not in the contacts list but in the conversation list
|
||||
conversation.set({
|
||||
active_at: Date.now(),
|
||||
name: room.roomName,
|
||||
avatarPath: room.roomName,
|
||||
});
|
||||
await conversation.commit();
|
||||
|
||||
|
|
3
ts/opengroup/opengroupV2/index.ts
Normal file
3
ts/opengroup/opengroupV2/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import * as ApiV2 from './OpenGroupAPIV2';
|
||||
|
||||
export { ApiV2 };
|
|
@ -28,7 +28,7 @@ export const openGroupPrefix = 'publicChat:';
|
|||
/**
|
||||
* Just a regex to match a public chat (i.e. a string starting with publicChat:)
|
||||
*/
|
||||
export const openGroupPrefixRegex = new RegExp(`/^${openGroupPrefix}/`);
|
||||
export const openGroupPrefixRegex = new RegExp(`^${openGroupPrefix}`);
|
||||
|
||||
/**
|
||||
* An open group v1 conversation id can only have the char '1' as roomId
|
||||
|
|
|
@ -14,6 +14,9 @@ import { BlockedNumberController } from '../../util';
|
|||
import { getSnodesFor } from '../snode_api/snodePool';
|
||||
import { PubKey } from '../types';
|
||||
import { actions as conversationActions } from '../../state/ducks/conversations';
|
||||
import { getV2OpenGroupRoom, removeV2OpenGroupRoom } from '../../data/opengroups';
|
||||
import { deleteAuthToken } from '../../opengroup/opengroupV2/OpenGroupAPIV2';
|
||||
import _ from 'lodash';
|
||||
|
||||
export class ConversationController {
|
||||
private static instance: ConversationController | null;
|
||||
|
@ -68,12 +71,8 @@ export class ConversationController {
|
|||
throw new TypeError("'id' must be a string");
|
||||
}
|
||||
|
||||
if (
|
||||
type !== ConversationType.PRIVATE &&
|
||||
type !== ConversationType.GROUP &&
|
||||
type !== ConversationType.OPEN_GROUP
|
||||
) {
|
||||
throw new TypeError(`'type' must be 'private' or 'group' or 'opengroup; got: '${type}'`);
|
||||
if (type !== ConversationType.PRIVATE && type !== ConversationType.GROUP) {
|
||||
throw new TypeError(`'type' must be 'private' or 'group' got: '${type}'`);
|
||||
}
|
||||
|
||||
if (!this._initialFetchComplete) {
|
||||
|
@ -178,10 +177,6 @@ export class ConversationController {
|
|||
}
|
||||
|
||||
public async deleteContact(id: string) {
|
||||
if (typeof id !== 'string') {
|
||||
throw new TypeError("'id' must be a string");
|
||||
}
|
||||
|
||||
if (!this._initialFetchComplete) {
|
||||
throw new Error('ConversationController.get() needs complete initial fetch');
|
||||
}
|
||||
|
@ -202,9 +197,17 @@ export class ConversationController {
|
|||
channelAPI.serverAPI.partChannel((channelAPI as any).channelId);
|
||||
}
|
||||
} else if (conversation.isOpenGroupV2()) {
|
||||
window.log.warn('leave open group v2 todo');
|
||||
window.log.info('leaving open group v2', conversation.id);
|
||||
const roomInfos = await getV2OpenGroupRoom(conversation.id);
|
||||
if (roomInfos) {
|
||||
// leave the group on the remote server
|
||||
await deleteAuthToken(_.pick(roomInfos, 'serverUrl', 'roomId'));
|
||||
// remove the roomInfos locally for this open group room
|
||||
await removeV2OpenGroupRoom(conversation.id);
|
||||
}
|
||||
}
|
||||
|
||||
// those are the stuff to do for all contact types
|
||||
await conversation.destroyMessages();
|
||||
|
||||
await removeConversation(id);
|
||||
|
|
|
@ -165,7 +165,7 @@ export const sendViaOnion = async (
|
|||
// port: url.port,
|
||||
};
|
||||
|
||||
console.warn('sendViaOnion payloadObj ==> ', payloadObj);
|
||||
window.log.debug('sendViaOnion payloadObj ==> ', payloadObj);
|
||||
|
||||
result = await sendOnionRequestLsrpcDest(
|
||||
0,
|
||||
|
|
|
@ -113,7 +113,6 @@ const getSslAgentForSeedNode = (seedNodeHost: string, isSsl = false) => {
|
|||
// read the cert each time. We only run this request once for each seed node nevertheless.
|
||||
const appPath = remote.app.getAppPath();
|
||||
const crt = fs.readFileSync(path.join(appPath, `/certificates/${filePrefix}.crt`), 'utf-8');
|
||||
// debugger;
|
||||
const sslOptions = {
|
||||
// as the seed nodes are using a self signed certificate, we have to provide it here.
|
||||
ca: crt,
|
||||
|
|
|
@ -227,17 +227,17 @@ describe('Message Utils', () => {
|
|||
|
||||
let convos: Array<ConversationModel>;
|
||||
const mockValidOpenGroup = new MockConversation({
|
||||
type: ConversationType.OPEN_GROUP,
|
||||
type: ConversationType.GROUP,
|
||||
id: `${openGroupPrefix}1@chat-dev.lokinet.org`,
|
||||
});
|
||||
|
||||
const mockValidOpenGroup2 = new MockConversation({
|
||||
type: ConversationType.OPEN_GROUP,
|
||||
type: ConversationType.GROUP,
|
||||
id: `${openGroupPrefix}1@chat-dev2.lokinet.org`,
|
||||
});
|
||||
|
||||
const mockValidClosedGroup = new MockConversation({
|
||||
type: ConversationType.OPEN_GROUP,
|
||||
type: ConversationType.GROUP,
|
||||
});
|
||||
|
||||
const mockValidPrivate = {
|
||||
|
|
|
@ -70,7 +70,7 @@ export class MockConversation {
|
|||
id: this.id,
|
||||
name: '',
|
||||
profileName: undefined,
|
||||
type: params.type === ConversationType.OPEN_GROUP ? 'group' : params.type,
|
||||
type: params.type === ConversationType.GROUP ? 'group' : params.type,
|
||||
members,
|
||||
left: false,
|
||||
expireTimer: 0,
|
||||
|
|
Loading…
Reference in a new issue