fix ban of users on open group

pull/1438/head
Audric Ackermann 4 years ago
parent e0d8d77860
commit 6a776b56f6
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -132,6 +132,7 @@
const user = { const user = {
regionCode: window.storage.get('regionCode'), regionCode: window.storage.get('regionCode'),
ourNumber: textsecure.storage.user.getNumber(), ourNumber: textsecure.storage.user.getNumber(),
ourPrimary: window.textsecure.storage.get('primaryDevicePubKey'),
isSecondaryDevice: !!textsecure.storage.get('isSecondaryDevice'), isSecondaryDevice: !!textsecure.storage.get('isSecondaryDevice'),
}; };
Whisper.events.trigger('userChanged', user); Whisper.events.trigger('userChanged', user);

@ -462,6 +462,10 @@
const regionCode = storage.get('regionCode'); const regionCode = storage.get('regionCode');
const typingKeys = Object.keys(this.contactTypingTimers || {}); const typingKeys = Object.keys(this.contactTypingTimers || {});
const groupAdmins = this.isPublic()
? this.get('moderators')
: this.get('groupAdmins');
const result = { const result = {
id: this.id, id: this.id,
isArchived: this.get('isArchived'), isArchived: this.get('isArchived'),
@ -494,6 +498,7 @@
hasNickname: !!this.getNickname(), hasNickname: !!this.getNickname(),
isKickedFromGroup: !!this.get('isKickedFromGroup'), isKickedFromGroup: !!this.get('isKickedFromGroup'),
left: !!this.get('left'), left: !!this.get('left'),
groupAdmins,
onClick: () => this.trigger('select', this), onClick: () => this.trigger('select', this),
onBlockContact: () => this.block(), onBlockContact: () => this.block(),

@ -32,9 +32,6 @@ const { UserDetailsDialog } = require('../../ts/components/UserDetailsDialog');
const { const {
DevicePairingDialog, DevicePairingDialog,
} = require('../../ts/components/DevicePairingDialog'); } = require('../../ts/components/DevicePairingDialog');
const {
SessionConversation,
} = require('../../ts/components/session/conversation/SessionConversation');
const { SessionModal } = require('../../ts/components/session/SessionModal'); const { SessionModal } = require('../../ts/components/session/SessionModal');
const { const {
SessionSeedModal, SessionSeedModal,
@ -244,7 +241,6 @@ exports.setup = (options = {}) => {
AddModeratorsDialog, AddModeratorsDialog,
RemoveModeratorsDialog, RemoveModeratorsDialog,
GroupInvitation, GroupInvitation,
SessionConversation,
SessionConfirm, SessionConfirm,
SessionModal, SessionModal,
SessionSeedModal, SessionSeedModal,

@ -53,6 +53,7 @@ export interface Props {
disableMenu?: boolean; disableMenu?: boolean;
isDeletable: boolean; isDeletable: boolean;
isModerator?: boolean; isModerator?: boolean;
weAreModerator?: boolean;
text?: string; text?: string;
bodyPending?: boolean; bodyPending?: boolean;
id: string; id: string;
@ -691,7 +692,7 @@ class MessageInner extends React.PureComponent<Props, State> {
onRetrySend, onRetrySend,
onShowDetail, onShowDetail,
isPublic, isPublic,
isModerator, weAreModerator,
onBanUser, onBanUser,
} = this.props; } = this.props;
@ -759,7 +760,7 @@ class MessageInner extends React.PureComponent<Props, State> {
</Item> </Item>
</> </>
) : null} ) : null}
{isModerator && isPublic ? ( {weAreModerator && isPublic ? (
<Item onClick={onBanUser}>{window.i18n('banUser')}</Item> <Item onClick={onBanUser}>{window.i18n('banUser')}</Item>
) : null} ) : null}
</Menu> </Menu>

@ -200,6 +200,7 @@ export class SessionInboxView extends React.Component<Props, State> {
}, },
user: { user: {
regionCode: window.storage.get('regionCode'), regionCode: window.storage.get('regionCode'),
ourPrimary: window.storage.get('primaryDevicePubKey'),
ourNumber: ourNumber:
window.storage.get('primaryDevicePubKey') || window.storage.get('primaryDevicePubKey') ||
window.textsecure.storage.user.getNumber(), window.textsecure.storage.user.getNumber(),

@ -32,6 +32,7 @@ import { getMessageById } from '../../../../js/modules/data';
import { pushUnblockToSend } from '../../../session/utils/Toast'; import { pushUnblockToSend } from '../../../session/utils/Toast';
import { MessageDetail } from '../../conversation/MessageDetail'; import { MessageDetail } from '../../conversation/MessageDetail';
import { ConversationController } from '../../../session/conversations'; import { ConversationController } from '../../../session/conversations';
import { PubKey } from '../../../session/types';
interface State { interface State {
// Message sending progress // Message sending progress
@ -70,6 +71,7 @@ interface State {
} }
interface Props { interface Props {
ourPrimary: string;
conversationKey: string; conversationKey: string;
conversation: ConversationType; conversation: ConversationType;
theme: DefaultTheme; theme: DefaultTheme;
@ -522,11 +524,12 @@ export class SessionConversation extends React.Component<Props, State> {
} }
public getMessagesListProps() { public getMessagesListProps() {
const { conversation, messages, actions } = this.props; const { conversation, ourPrimary, messages, actions } = this.props;
const { quotedMessageTimestamp, selectedMessages } = this.state; const { quotedMessageTimestamp, selectedMessages } = this.state;
return { return {
selectedMessages, selectedMessages,
ourPrimary,
conversationKey: conversation.id, conversationKey: conversation.id,
messages, messages,
resetSelection: this.resetSelection, resetSelection: this.resetSelection,

@ -18,6 +18,7 @@ import { VerificationNotification } from '../../conversation/VerificationNotific
import { ToastUtils } from '../../../session/utils'; import { ToastUtils } from '../../../session/utils';
import { TypingBubble } from '../../conversation/TypingBubble'; import { TypingBubble } from '../../conversation/TypingBubble';
import { ConversationController } from '../../../session/conversations'; import { ConversationController } from '../../../session/conversations';
import { PubKey } from '../../../session/types';
interface State { interface State {
showScrollButton: boolean; showScrollButton: boolean;
@ -29,6 +30,7 @@ interface Props {
conversationKey: string; conversationKey: string;
messages: Array<MessageModel>; messages: Array<MessageModel>;
conversation: ConversationType; conversation: ConversationType;
ourPrimary: string;
messageContainerRef: React.RefObject<any>; messageContainerRef: React.RefObject<any>;
selectMessage: (messageId: string) => void; selectMessage: (messageId: string) => void;
deleteMessage: (messageId: string) => void; deleteMessage: (messageId: string) => void;
@ -202,7 +204,8 @@ export class SessionMessagesList extends React.Component<Props, State> {
} }
private renderMessages(messages: Array<MessageModel>) { private renderMessages(messages: Array<MessageModel>) {
const multiSelectMode = Boolean(this.props.selectedMessages.length); const { conversation, ourPrimary, selectedMessages } = this.props;
const multiSelectMode = Boolean(selectedMessages.length);
let currentMessageIndex = 0; let currentMessageIndex = 0;
const displayUnreadBannerIndex = this.displayUnreadBannerIndex(messages); const displayUnreadBannerIndex = this.displayUnreadBannerIndex(messages);
@ -294,6 +297,13 @@ export class SessionMessagesList extends React.Component<Props, State> {
); );
} }
// allow moderators feature on messages (like banning a user)
if (messageProps.isPublic) {
messageProps.weAreModerator = conversation.groupAdmins?.includes(
ourPrimary
);
}
// firstMessageOfSeries tells us to render the avatar only for the first message // firstMessageOfSeries tells us to render the avatar only for the first message
// in a series of messages from the same user // in a series of messages from the same user
return ( return (

@ -79,6 +79,7 @@ export type ConversationType = {
isKickedFromGroup: boolean; isKickedFromGroup: boolean;
left: boolean; left: boolean;
avatarPath?: string; // absolute filepath to the avatar avatarPath?: string; // absolute filepath to the avatar
groupAdmins?: Array<string>; // admins for closed groups and moderators for open groups
}; };
export type ConversationLookupType = { export type ConversationLookupType = {
[key: string]: ConversationType; [key: string]: ConversationType;

@ -4,6 +4,7 @@ import { LocalizerType } from '../../types/Util';
export type UserStateType = { export type UserStateType = {
ourNumber: string; ourNumber: string;
ourPrimary: string;
regionCode: string; regionCode: string;
isSecondaryDevice: boolean; isSecondaryDevice: boolean;
i18n: LocalizerType; i18n: LocalizerType;
@ -15,6 +16,7 @@ type UserChangedActionType = {
type: 'USER_CHANGED'; type: 'USER_CHANGED';
payload: { payload: {
ourNumber: string; ourNumber: string;
ourPrimary: string;
regionCode: string; regionCode: string;
isSecondaryDevice: boolean; isSecondaryDevice: boolean;
}; };
@ -30,6 +32,7 @@ export const actions = {
function userChanged(attributes: { function userChanged(attributes: {
ourNumber: string; ourNumber: string;
ourPrimary: string;
regionCode: string; regionCode: string;
isSecondaryDevice: boolean; isSecondaryDevice: boolean;
}): UserChangedActionType { }): UserChangedActionType {
@ -44,6 +47,7 @@ function userChanged(attributes: {
function getEmptyState(): UserStateType { function getEmptyState(): UserStateType {
return { return {
ourNumber: 'missing', ourNumber: 'missing',
ourPrimary: 'missing',
regionCode: 'missing', regionCode: 'missing',
isSecondaryDevice: false, isSecondaryDevice: false,
i18n: () => 'missing', i18n: () => 'missing',

@ -8,6 +8,7 @@ import {
import { reducer as user, UserStateType } from './ducks/user'; import { reducer as user, UserStateType } from './ducks/user';
import { reducer as theme, ThemeStateType } from './ducks/theme'; import { reducer as theme, ThemeStateType } from './ducks/theme';
import { reducer as section, SectionStateType } from './ducks/section'; import { reducer as section, SectionStateType } from './ducks/section';
import { PubKey } from '../session/types';
export type StateType = { export type StateType = {
search: SearchStateType; search: SearchStateType;

@ -26,3 +26,8 @@ export const getIsSecondaryDevice = createSelector(
getUser, getUser,
(state: UserStateType): boolean => state.isSecondaryDevice (state: UserStateType): boolean => state.isSecondaryDevice
); );
export const getPrimaryPubkey = createSelector(
getUser,
(state: UserStateType): string => state.ourPrimary
);

@ -2,9 +2,11 @@ import { connect } from 'react-redux';
import { mapDispatchToProps } from '../actions'; import { mapDispatchToProps } from '../actions';
import { SessionConversation } from '../../components/session/conversation/SessionConversation'; import { SessionConversation } from '../../components/session/conversation/SessionConversation';
import { StateType } from '../reducer'; import { StateType } from '../reducer';
import { getPrimaryPubkey } from '../selectors/user';
const mapStateToProps = (state: StateType) => { const mapStateToProps = (state: StateType) => {
const conversationKey = state.conversations.selectedConversation; const conversationKey = state.conversations.selectedConversation;
const ourPrimary = getPrimaryPubkey(state);
const conversation = const conversation =
(conversationKey && (conversationKey &&
state.conversations.conversationLookup[conversationKey]) || state.conversations.conversationLookup[conversationKey]) ||
@ -14,6 +16,7 @@ const mapStateToProps = (state: StateType) => {
conversationKey, conversationKey,
theme: state.theme, theme: state.theme,
messages: state.conversations.messages, messages: state.conversations.messages,
ourPrimary,
}; };
}; };

Loading…
Cancel
Save