Remove all checks for minimum versions previous to 5.31 (#5572)
* Remove all checks for minimum versions previous to 5.31 * Fix tests * Fix bad merge * Address feedback * Patch flaky test
This commit is contained in:
parent
45108bde02
commit
69a65067c3
37 changed files with 186 additions and 651 deletions
|
|
@ -33,7 +33,6 @@ import {getTeamByName as selectTeamByName, getCurrentTeam, getTeamMemberships} f
|
|||
import {getCurrentUserId} from '@mm-redux/selectors/entities/users';
|
||||
import {getChannelByName as selectChannelByName, getChannelsIdForTeam} from '@mm-redux/utils/channel_utils';
|
||||
import EventEmitter from '@mm-redux/utils/event_emitter';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
import {getChannelReachable} from '@selectors/channel';
|
||||
import {getViewingGlobalThreads} from '@selectors/threads';
|
||||
import telemetry, {PERF_MARKERS} from '@telemetry';
|
||||
|
|
@ -637,11 +636,10 @@ function loadGroupData(isReconnect = false) {
|
|||
const actions = [];
|
||||
const team = getCurrentTeam(state);
|
||||
const currentUserId = getCurrentUserId(state);
|
||||
const serverVersion = state.entities.general.serverVersion;
|
||||
const license = getLicense(state);
|
||||
const hasLicense = license?.IsLicensed === 'true' && license?.LDAPGroups === 'true';
|
||||
|
||||
if (hasLicense && team && isMinimumServerVersion(serverVersion, 5, 24)) {
|
||||
if (hasLicense && team) {
|
||||
for (let i = 0; i <= MAX_RETRIES; i++) {
|
||||
try {
|
||||
if (team.group_constrained) {
|
||||
|
|
|
|||
|
|
@ -3,11 +3,9 @@
|
|||
|
||||
import moment from 'moment-timezone';
|
||||
|
||||
import {Client4} from '@client/rest';
|
||||
import PushNotifications from '@init/push_notifications';
|
||||
import {getSessions} from '@mm-redux/actions/users';
|
||||
import {getConfig} from '@mm-redux/selectors/entities/general';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
|
||||
const sortByNewest = (a, b) => {
|
||||
if (a.create_at > b.create_at) {
|
||||
|
|
@ -23,7 +21,7 @@ export function scheduleExpiredNotification(intl) {
|
|||
const {currentUserId} = state.entities.users;
|
||||
const config = getConfig(state);
|
||||
|
||||
if (isMinimumServerVersion(Client4.serverVersion, 5, 24) && config.ExtendSessionLengthWithActivity === 'true') {
|
||||
if (config.ExtendSessionLengthWithActivity === 'true') {
|
||||
PushNotifications.cancelAllLocalNotifications();
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import {GlobalState} from '@mm-redux/types/store';
|
|||
import {TeamMembership} from '@mm-redux/types/teams';
|
||||
import {WebSocketMessage} from '@mm-redux/types/websocket';
|
||||
import EventEmitter from '@mm-redux/utils/event_emitter';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
import {removeUserFromList} from '@mm-redux/utils/user_utils';
|
||||
import {getChannelSinceValue} from '@utils/channels';
|
||||
import websocketClient from '@websocket';
|
||||
|
|
@ -99,7 +98,7 @@ export function doFirstConnect(now: number) {
|
|||
const {lastDisconnectAt} = state.websocket;
|
||||
const actions: Array<GenericAction> = [wsConnected(now)];
|
||||
|
||||
if (isMinimumServerVersion(Client4.getServerVersion(), 5, 14) && lastDisconnectAt) {
|
||||
if (lastDisconnectAt) {
|
||||
const currentUserId = getCurrentUserId(state);
|
||||
const users = getUsers(state);
|
||||
const userIds = Object.keys(users);
|
||||
|
|
@ -220,7 +219,7 @@ export function doReconnect(now: number) {
|
|||
});
|
||||
}
|
||||
|
||||
if (isMinimumServerVersion(Client4.getServerVersion(), 5, 14) && lastDisconnectAt) {
|
||||
if (lastDisconnectAt) {
|
||||
const userIds = Object.keys(users);
|
||||
const userUpdates = await Client4.getProfilesByIds(userIds, {since: lastDisconnectAt});
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ describe('Websocket Post Events', () => {
|
|||
// Mock that post does not exist and check it is added
|
||||
PostSelectors.getPost.mockReturnValueOnce(false);
|
||||
mockServer.emit('message', message);
|
||||
await TestHelper.wait(100);
|
||||
await TestHelper.wait(300);
|
||||
entities = store.getState().entities;
|
||||
posts = entities.posts.posts;
|
||||
const postId = Object.keys(posts)[0];
|
||||
|
|
|
|||
|
|
@ -450,32 +450,6 @@ describe('Actions.Websocket notVisibleUsersActions', () => {
|
|||
expect(actions.length).toEqual(3);
|
||||
expect(actions).toEqual(expectedAction);
|
||||
});
|
||||
|
||||
it('should do nothing if the server version is less than 5.23', async () => {
|
||||
const profiles = {
|
||||
[me.id]: me,
|
||||
[user.id]: user,
|
||||
[user2.id]: user2,
|
||||
[user3.id]: user3,
|
||||
[user4.id]: user4,
|
||||
[user5.id]: user5,
|
||||
};
|
||||
Client4.serverVersion = '5.22.0';
|
||||
|
||||
const state = {
|
||||
entities: {
|
||||
users: {
|
||||
currentUserId: me.id,
|
||||
profiles,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
mockGetKnownUsersRequest([user.id, user3.id]);
|
||||
|
||||
const actions = await notVisibleUsersActions(state);
|
||||
expect(actions.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Actions.Websocket handleUserTypingEvent', () => {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import {analytics} from '@init/analytics';
|
||||
import {General} from '@mm-redux/constants';
|
||||
import {UserCustomStatus, UserProfile, UserStatus} from '@mm-redux/types/users';
|
||||
import {buildQueryString, isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
import {buildQueryString} from '@mm-redux/utils/helpers';
|
||||
|
||||
import {PER_PAGE_DEFAULT} from './constants';
|
||||
|
||||
|
|
@ -255,13 +255,7 @@ const ClientUsers = (superclass: any) => class extends superclass {
|
|||
getProfilesInChannel = async (channelId: string, page = 0, perPage = PER_PAGE_DEFAULT, sort = '') => {
|
||||
analytics.trackAPI('api_profiles_get_in_channel', {channel_id: channelId});
|
||||
|
||||
const serverVersion = this.getServerVersion();
|
||||
let queryStringObj;
|
||||
if (isMinimumServerVersion(serverVersion, 4, 7)) {
|
||||
queryStringObj = {in_channel: channelId, page, per_page: perPage, sort};
|
||||
} else {
|
||||
queryStringObj = {in_channel: channelId, page, per_page: perPage};
|
||||
}
|
||||
const queryStringObj = {in_channel: channelId, page, per_page: perPage, sort};
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}${buildQueryString(queryStringObj)}`,
|
||||
{method: 'get'},
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import {getAssociatedGroupsForReference, searchAssociatedGroupsForReferenceLocal
|
|||
import {getTheme} from '@mm-redux/selectors/entities/preferences';
|
||||
import {haveIChannelPermission} from '@mm-redux/selectors/entities/roles';
|
||||
import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
import {
|
||||
filterMembersInChannel,
|
||||
filterMembersNotInChannel,
|
||||
|
|
@ -28,18 +27,15 @@ function mapStateToProps(state, ownProps) {
|
|||
const currentTeamId = getCurrentTeamId(state);
|
||||
const license = getLicense(state);
|
||||
const hasLicense = license?.IsLicensed === 'true' && license?.LDAPGroups === 'true';
|
||||
let useChannelMentions = true;
|
||||
if (isMinimumServerVersion(state.entities.general.serverVersion, 5, 22)) {
|
||||
useChannelMentions = haveIChannelPermission(
|
||||
state,
|
||||
{
|
||||
channel: currentChannelId,
|
||||
team: currentTeamId,
|
||||
permission: Permissions.USE_CHANNEL_MENTIONS,
|
||||
default: true,
|
||||
},
|
||||
);
|
||||
}
|
||||
const useChannelMentions = haveIChannelPermission(
|
||||
state,
|
||||
{
|
||||
channel: currentChannelId,
|
||||
team: currentTeamId,
|
||||
permission: Permissions.USE_CHANNEL_MENTIONS,
|
||||
default: true,
|
||||
},
|
||||
);
|
||||
|
||||
const value = ownProps.value.substring(0, cursorPosition);
|
||||
const matchTerm = getMatchTermForAtMention(value, isSearch);
|
||||
|
|
@ -55,7 +51,7 @@ function mapStateToProps(state, ownProps) {
|
|||
outChannel = filterMembersNotInChannel(state, matchTerm);
|
||||
}
|
||||
|
||||
if (haveIChannelPermission(state, {channel: currentChannelId, team: currentTeamId, permission: Permissions.USE_GROUP_MENTIONS, default: true}) && hasLicense && isMinimumServerVersion(state.entities.general.serverVersion, 5, 24)) {
|
||||
if (haveIChannelPermission(state, {channel: currentChannelId, team: currentTeamId, permission: Permissions.USE_GROUP_MENTIONS, default: true}) && hasLicense) {
|
||||
if (matchTerm) {
|
||||
groups = searchAssociatedGroupsForReferenceLocal(state, matchTerm, currentTeamId, currentChannelId);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -8,11 +8,9 @@ import {
|
|||
Platform,
|
||||
} from 'react-native';
|
||||
|
||||
import {Client4} from '@client/rest';
|
||||
import {analytics} from '@init/analytics';
|
||||
import {Command, AutocompleteSuggestion, CommandArgs} from '@mm-redux/types/integrations';
|
||||
import {Theme} from '@mm-redux/types/theme';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
import {makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
import {AppCommandParser} from './app_command_parser/app_command_parser';
|
||||
|
|
@ -110,25 +108,21 @@ export default class SlashSuggestion extends PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
this.showBaseCommands(nextValue, nextCommands, this.props.channelId, this.props.currentTeamId, this.props.rootId);
|
||||
} else if (isMinimumServerVersion(Client4.getServerVersion(), 5, 24)) {
|
||||
if (nextSuggestions === prevProps.suggestions) {
|
||||
const args = {
|
||||
channel_id: prevProps.channelId,
|
||||
team_id: prevProps.currentTeamId,
|
||||
...(prevProps.rootId && {root_id: prevProps.rootId}),
|
||||
};
|
||||
this.props.actions.getCommandAutocompleteSuggestions(nextValue, nextTeamId, args);
|
||||
} else {
|
||||
const matches: AutocompleteSuggestion[] = [];
|
||||
nextSuggestions.forEach((suggestion: AutocompleteSuggestion) => {
|
||||
if (!this.contains(matches, '/' + suggestion.Complete)) {
|
||||
matches.push(suggestion);
|
||||
}
|
||||
});
|
||||
this.updateSuggestions(matches);
|
||||
}
|
||||
} else if (nextSuggestions === prevProps.suggestions) {
|
||||
const args = {
|
||||
channel_id: prevProps.channelId,
|
||||
team_id: prevProps.currentTeamId,
|
||||
...(prevProps.rootId && {root_id: prevProps.rootId}),
|
||||
};
|
||||
this.props.actions.getCommandAutocompleteSuggestions(nextValue, nextTeamId, args);
|
||||
} else {
|
||||
this.setActive(false);
|
||||
const matches: AutocompleteSuggestion[] = [];
|
||||
nextSuggestions.forEach((suggestion: AutocompleteSuggestion) => {
|
||||
if (!this.contains(matches, '/' + suggestion.Complete)) {
|
||||
matches.push(suggestion);
|
||||
}
|
||||
});
|
||||
this.updateSuggestions(matches);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,10 +5,7 @@ import {connect} from 'react-redux';
|
|||
|
||||
import {Client4} from '@client/rest';
|
||||
import {getCustomEmojisByName} from '@mm-redux/selectors/entities/emojis';
|
||||
import {getConfig} from '@mm-redux/selectors/entities/general';
|
||||
import {getCurrentUserId} from '@mm-redux/selectors/entities/users';
|
||||
import {GlobalState} from '@mm-redux/types/store';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
import {EmojiIndicesByAlias, Emojis} from '@utils/emojis';
|
||||
|
||||
import Emoji from './emoji';
|
||||
|
|
@ -18,7 +15,6 @@ type OwnProps = {
|
|||
}
|
||||
|
||||
function mapStateToProps(state: GlobalState, ownProps: OwnProps) {
|
||||
const config = getConfig(state);
|
||||
const emojiName = ownProps.emojiName;
|
||||
const customEmojis = getCustomEmojisByName(state);
|
||||
const serverUrl = Client4.getUrl();
|
||||
|
|
@ -41,11 +37,7 @@ function mapStateToProps(state: GlobalState, ownProps: OwnProps) {
|
|||
imageUrl = Client4.getCustomEmojiImageUrl(emoji!.id);
|
||||
isCustomEmoji = true;
|
||||
} else {
|
||||
displayTextOnly = state.entities.emojis.nonExistentEmoji.has(emojiName) ||
|
||||
config.EnableCustomEmoji !== 'true' ||
|
||||
config.ExperimentalEnablePostMetadata === 'true' ||
|
||||
getCurrentUserId(state) === '' ||
|
||||
isMinimumServerVersion(Client4.getServerVersion(), 5, 12);
|
||||
displayTextOnly = true;
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import {getAssociatedGroupsForReferenceMap} from '@mm-redux/selectors/entities/g
|
|||
import {getTheme} from '@mm-redux/selectors/entities/preferences';
|
||||
import {haveIChannelPermission} from '@mm-redux/selectors/entities/roles';
|
||||
import {getCurrentUserId, getStatusForUserId} from '@mm-redux/selectors/entities/users';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
import {isLandscape} from '@selectors/device';
|
||||
import {getCurrentChannelDraft, getThreadDraft} from '@selectors/views';
|
||||
|
||||
|
|
@ -43,7 +42,7 @@ export function mapStateToProps(state, ownProps) {
|
|||
const channelMemberCountsByGroup = selectChannelMemberCountsByGroup(state, channelId);
|
||||
let groupsWithAllowReference = new Map();
|
||||
|
||||
if (channel && isMinimumServerVersion(state.entities.general.serverVersion, 5, 22)) {
|
||||
if (channel) {
|
||||
useChannelMentions = haveIChannelPermission(
|
||||
state,
|
||||
{
|
||||
|
|
@ -55,7 +54,7 @@ export function mapStateToProps(state, ownProps) {
|
|||
);
|
||||
}
|
||||
|
||||
if (channel && isMinimumServerVersion(state.entities.general.serverVersion, 5, 24) && license && license.IsLicensed === 'true') {
|
||||
if (channel && license?.IsLicensed === 'true') {
|
||||
useGroupMentions = haveIChannelPermission(
|
||||
state,
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import {getCurrentChannel, getChannel, isChannelReadOnlyById} from '@mm-redux/se
|
|||
import {getTheme} from '@mm-redux/selectors/entities/preferences';
|
||||
import {haveIChannelPermission} from '@mm-redux/selectors/entities/roles';
|
||||
import {getCurrentUserId} from '@mm-redux/selectors/entities/users';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
import {getChannelMembersForDm} from '@selectors/channel';
|
||||
|
||||
import PostDraft from './post_draft';
|
||||
|
|
@ -27,7 +26,7 @@ export function mapStateToProps(state, ownProps) {
|
|||
}
|
||||
}
|
||||
|
||||
if (channel && isMinimumServerVersion(state.entities.general.serverVersion, 5, 22)) {
|
||||
if (channel) {
|
||||
canPost = haveIChannelPermission(
|
||||
state,
|
||||
{
|
||||
|
|
|
|||
|
|
@ -60,27 +60,6 @@ describe('mapStateToProps', () => {
|
|||
|
||||
const baseOwnProps = {};
|
||||
|
||||
test('haveIChannelPermission is not called when isMinimumServerVersion is not 5.22v', () => {
|
||||
const state = {...baseState};
|
||||
state.entities.general.serverVersion = '5.21';
|
||||
|
||||
mapStateToProps(state, baseOwnProps);
|
||||
expect(isMinimumServerVersion(state.entities.general.serverVersion, 5, 22)).toBe(false);
|
||||
|
||||
expect(roleSelectors.haveIChannelPermission).not.toHaveBeenCalledWith(state, {
|
||||
channel: undefined,
|
||||
team: undefined,
|
||||
permission: Permissions.CREATE_POST,
|
||||
default: true,
|
||||
});
|
||||
|
||||
expect(roleSelectors.haveIChannelPermission).not.toHaveBeenCalledWith(state, {
|
||||
channel: undefined,
|
||||
permission: Permissions.USE_CHANNEL_MENTIONS,
|
||||
default: true,
|
||||
});
|
||||
});
|
||||
|
||||
test('haveIChannelPermission is called when isMinimumServerVersion is 5.22v', () => {
|
||||
const state = {...baseState};
|
||||
state.entities.general.serverVersion = '5.22';
|
||||
|
|
|
|||
|
|
@ -11,14 +11,12 @@ import {
|
|||
getSortedUnreadChannelIds,
|
||||
getOrderedChannelIds,
|
||||
} from '@mm-redux/selectors/entities/channels';
|
||||
import {getConfig, getLicense, hasNewPermissions} from '@mm-redux/selectors/entities/general';
|
||||
import {getTheme, getFavoritesPreferences, getSidebarPreferences, isCollapsedThreadsEnabled} from '@mm-redux/selectors/entities/preferences';
|
||||
import {haveITeamPermission} from '@mm-redux/selectors/entities/roles';
|
||||
import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams';
|
||||
import {getCurrentUserId, getCurrentUserRoles} from '@mm-redux/selectors/entities/users';
|
||||
import {getCurrentUserRoles} from '@mm-redux/selectors/entities/users';
|
||||
import {showCreateOption} from '@mm-redux/utils/channel_utils';
|
||||
import {memoizeResult} from '@mm-redux/utils/helpers';
|
||||
import {isAdmin as checkIsAdmin, isSystemAdmin as checkIsSystemAdmin} from '@mm-redux/utils/user_utils';
|
||||
|
||||
import List from './list';
|
||||
|
||||
|
|
@ -32,13 +30,8 @@ const filterZeroUnreads = memoizeResult((sections) => {
|
|||
});
|
||||
|
||||
function mapStateToProps(state) {
|
||||
const config = getConfig(state);
|
||||
const collapsedThreadsEnabled = isCollapsedThreadsEnabled(state);
|
||||
const license = getLicense(state);
|
||||
const roles = getCurrentUserId(state) ? getCurrentUserRoles(state) : '';
|
||||
const currentTeamId = getCurrentTeamId(state);
|
||||
const isAdmin = checkIsAdmin(roles);
|
||||
const isSystemAdmin = checkIsSystemAdmin(roles);
|
||||
const sidebarPrefs = getSidebarPreferences(state);
|
||||
const lastUnreadChannel = DeviceTypes.IS_TABLET ? state.views.channel.keepChannelIdAsUnread : null;
|
||||
const unreadChannelIds = getSortedUnreadChannelIds(state, lastUnreadChannel);
|
||||
|
|
@ -52,15 +45,12 @@ function mapStateToProps(state) {
|
|||
sidebarPrefs.favorite_at_top === 'true' && favoriteChannelIds.length,
|
||||
));
|
||||
|
||||
let canJoinPublicChannels = true;
|
||||
if (hasNewPermissions(state)) {
|
||||
canJoinPublicChannels = haveITeamPermission(state, {
|
||||
team: currentTeamId,
|
||||
permission: Permissions.JOIN_PUBLIC_CHANNELS,
|
||||
});
|
||||
}
|
||||
const canCreatePublicChannels = showCreateOption(state, config, license, currentTeamId, General.OPEN_CHANNEL, isAdmin, isSystemAdmin);
|
||||
const canCreatePrivateChannels = showCreateOption(state, config, license, currentTeamId, General.PRIVATE_CHANNEL, isAdmin, isSystemAdmin);
|
||||
const canJoinPublicChannels = haveITeamPermission(state, {
|
||||
team: currentTeamId,
|
||||
permission: Permissions.JOIN_PUBLIC_CHANNELS,
|
||||
});
|
||||
const canCreatePublicChannels = showCreateOption(state, currentTeamId, General.OPEN_CHANNEL);
|
||||
const canCreatePrivateChannels = showCreateOption(state, currentTeamId, General.PRIVATE_CHANNEL);
|
||||
|
||||
return {
|
||||
canJoinPublicChannels,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ import {isCollapsedThreadsEnabled} from '@mm-redux/selectors/entities/preference
|
|||
import {isTimezoneEnabled} from '@mm-redux/selectors/entities/timezone';
|
||||
import {getCurrentUser, getUser} from '@mm-redux/selectors/entities/users';
|
||||
import EventEmitter from '@mm-redux/utils/event_emitter';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
import EphemeralStore from '@store/ephemeral_store';
|
||||
import initialState from '@store/initial_state';
|
||||
import Store from '@store/store';
|
||||
|
|
@ -242,7 +241,7 @@ class GlobalEventHandler {
|
|||
onServerConfigChanged = (config) => {
|
||||
this.configureAnalytics(config);
|
||||
|
||||
if (isMinimumServerVersion(Client4.serverVersion, 5, 24) && config.ExtendSessionLengthWithActivity === 'true') {
|
||||
if (config.ExtendSessionLengthWithActivity === 'true') {
|
||||
PushNotifications.cancelAllLocalNotifications();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -198,21 +198,6 @@ describe('Actions.General', () => {
|
|||
});
|
||||
|
||||
describe('getRedirectLocation', () => {
|
||||
it('old server', async () => {
|
||||
store.dispatch({type: GeneralTypes.RECEIVED_SERVER_VERSION, data: '5.0.0'});
|
||||
|
||||
const mock = nock(Client4.getBaseRoute()).
|
||||
get('/redirect_location').
|
||||
reply(404);
|
||||
|
||||
// Should return the original link
|
||||
const result = await store.dispatch(Actions.getRedirectLocation('http://examp.le'));
|
||||
assert.deepEqual(result.data, {location: 'http://examp.le'});
|
||||
|
||||
// Should not call the API on an old server
|
||||
assert.equal(mock.isDone(), false);
|
||||
});
|
||||
|
||||
it('should save the correct location', async () => {
|
||||
store.dispatch({type: GeneralTypes.RECEIVED_SERVER_VERSION, data: '5.3.0'});
|
||||
|
||||
|
|
|
|||
|
|
@ -190,12 +190,7 @@ export function setUrl(url: string) {
|
|||
|
||||
export function getRedirectLocation(url: string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
let pendingData: Promise<any>;
|
||||
if (isMinimumServerVersion(getServerVersion(getState()), 5, 3)) {
|
||||
pendingData = Client4.getRedirectLocation(url);
|
||||
} else {
|
||||
pendingData = Promise.resolve({location: url});
|
||||
}
|
||||
const pendingData = Client4.getRedirectLocation(url);
|
||||
|
||||
let data;
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import {getCurrentUserId, getUsers} from '@mm-redux/selectors/entities/users';
|
|||
import {batchActions, Action, ActionFunc, GenericAction, DispatchFunc, GetStateFunc} from '@mm-redux/types/actions';
|
||||
import {Client4Error} from '@mm-redux/types/client4';
|
||||
import {GlobalState} from '@mm-redux/types/store';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
|
||||
import {logError} from './errors';
|
||||
|
||||
|
|
@ -138,9 +137,6 @@ export function debounce(func: (...args: any) => unknown, wait: number, immediat
|
|||
}
|
||||
|
||||
export async function notVisibleUsersActions(state: GlobalState): Promise<Array<GenericAction>> {
|
||||
if (!isMinimumServerVersion(Client4.getServerVersion(), 5, 23)) {
|
||||
return [];
|
||||
}
|
||||
let knownUsers: Set<string>;
|
||||
try {
|
||||
const fetchResult = await Client4.getKnownUsers();
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import assert from 'assert';
|
|||
import nock from 'nock';
|
||||
|
||||
import {Client4} from '@client/rest';
|
||||
import {GeneralTypes} from '@mm-redux/action_types';
|
||||
import * as Actions from '@mm-redux/actions/teams';
|
||||
import {login} from '@mm-redux/actions/users';
|
||||
import TestHelper from '@test/test_helper';
|
||||
|
|
@ -261,64 +260,6 @@ describe('Actions.Teams', () => {
|
|||
assert.strictEqual(patched.description, description);
|
||||
});
|
||||
|
||||
it('Join Open Team', async () => {
|
||||
const client = TestHelper.createClient();
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users').
|
||||
query(true).
|
||||
reply(201, TestHelper.fakeUserWithId());
|
||||
const user = await client.createUser(
|
||||
TestHelper.fakeUser(),
|
||||
null,
|
||||
null,
|
||||
TestHelper.basicTeam.invite_id,
|
||||
);
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/users/login').
|
||||
reply(200, user);
|
||||
await client.login(user.email, 'password1');
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/teams').
|
||||
reply(201, {...TestHelper.fakeTeamWithId(), allow_open_invite: true});
|
||||
const team = await client.createTeam({...TestHelper.fakeTeam(), allow_open_invite: true});
|
||||
|
||||
store.dispatch({type: GeneralTypes.RECEIVED_SERVER_VERSION, data: '4.0.0'});
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
post('/teams/members/invite').
|
||||
query(true).
|
||||
reply(201, {user_id: TestHelper.basicUser.id, team_id: team.id});
|
||||
|
||||
nock(Client4.getBaseRoute()).
|
||||
get(`/teams/${team.id}`).
|
||||
reply(200, team);
|
||||
|
||||
nock(Client4.getUserRoute('me')).
|
||||
get('/teams/members').
|
||||
reply(200, [{user_id: TestHelper.basicUser.id, roles: 'team_user', team_id: team.id}]);
|
||||
|
||||
nock(Client4.getUserRoute('me')).
|
||||
get('/teams/unread').
|
||||
reply(200, [{team_id: team.id, msg_count: 0, mention_count: 0}]);
|
||||
|
||||
await Actions.joinTeam(team.invite_id, team.id)(store.dispatch, store.getState);
|
||||
|
||||
const state = store.getState();
|
||||
|
||||
const request = state.requests.teams.joinTeam;
|
||||
|
||||
if (request.status !== RequestStatus.SUCCESS) {
|
||||
throw new Error(JSON.stringify(request.error));
|
||||
}
|
||||
|
||||
const {teams, myMembers} = state.entities.teams;
|
||||
assert.ok(teams[team.id]);
|
||||
assert.ok(myMembers[team.id]);
|
||||
});
|
||||
|
||||
it('getMyTeamMembers and getMyTeamUnreads', async () => {
|
||||
nock(Client4.getUserRoute('me')).
|
||||
get('/teams/members').
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
// See LICENSE.txt for license information.
|
||||
import {Client4} from '@client/rest';
|
||||
import {ChannelTypes, RoleTypes, TeamTypes, UserTypes} from '@mm-redux/action_types';
|
||||
import {isCompatibleWithJoinViewTeamPermissions} from '@mm-redux/selectors/entities/general';
|
||||
import {getRoles} from '@mm-redux/selectors/entities/roles_helpers';
|
||||
import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams';
|
||||
import {getCurrentUserId} from '@mm-redux/selectors/entities/users';
|
||||
|
|
@ -417,18 +416,14 @@ export function removeUserFromTeam(teamId: string, userId: string): ActionFunc {
|
|||
};
|
||||
}
|
||||
|
||||
export function joinTeam(inviteId: string, teamId: string): ActionFunc {
|
||||
export function joinTeam(teamId: string): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
dispatch({type: TeamTypes.JOIN_TEAM_REQUEST, data: null});
|
||||
|
||||
const state = getState();
|
||||
try {
|
||||
if (isCompatibleWithJoinViewTeamPermissions(state)) {
|
||||
const currentUserId = state.entities.users.currentUserId;
|
||||
await Client4.addToTeam(teamId, currentUserId);
|
||||
} else {
|
||||
await Client4.joinTeam(inviteId);
|
||||
}
|
||||
const currentUserId = state.entities.users.currentUserId;
|
||||
await Client4.addToTeam(teamId, currentUserId);
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(error, dispatch, getState);
|
||||
dispatch(batchActions([
|
||||
|
|
|
|||
|
|
@ -3,19 +3,16 @@
|
|||
import {Client4} from '@client/rest';
|
||||
import {analytics} from '@init/analytics';
|
||||
import {UserTypes, TeamTypes} from '@mm-redux/action_types';
|
||||
import {getConfig, getServerVersion} from '@mm-redux/selectors/entities/general';
|
||||
import {getCurrentUserId, getUsers} from '@mm-redux/selectors/entities/users';
|
||||
import {Action, ActionFunc, ActionResult, batchActions, DispatchFunc, GetStateFunc} from '@mm-redux/types/actions';
|
||||
import {TeamMembership} from '@mm-redux/types/teams';
|
||||
import {UserProfile, UserStatus} from '@mm-redux/types/users';
|
||||
import {Dictionary} from '@mm-redux/types/utilities';
|
||||
import {getUserIdFromChannelName, isDirectChannel, isDirectChannelVisible, isGroupChannel, isGroupChannelVisible} from '@mm-redux/utils/channel_utils';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
import {removeUserFromList} from '@mm-redux/utils/user_utils';
|
||||
|
||||
import {General} from '../constants';
|
||||
|
||||
import {getAllCustomEmojis} from './emojis';
|
||||
import {logError} from './errors';
|
||||
import {getClientConfig, setServerVersion} from './general';
|
||||
import {bindClientFunc, forceLogoutIfNecessary, debounce} from './helpers';
|
||||
|
|
@ -112,7 +109,7 @@ export function loginById(id: string, password: string, mfaToken = ''): ActionFu
|
|||
}
|
||||
|
||||
function completeLogin(data: UserProfile): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
return async (dispatch: DispatchFunc) => {
|
||||
dispatch({
|
||||
type: UserTypes.RECEIVED_ME,
|
||||
data,
|
||||
|
|
@ -153,9 +150,6 @@ function completeLogin(data: UserProfile): ActionFunc {
|
|||
|
||||
const serverVersion = Client4.getServerVersion();
|
||||
dispatch(setServerVersion(serverVersion));
|
||||
if (!isMinimumServerVersion(serverVersion, 4, 7) && getConfig(getState()).EnableCustomEmoji === 'true') {
|
||||
dispatch(getAllCustomEmojis());
|
||||
}
|
||||
|
||||
try {
|
||||
await Promise.all(promises);
|
||||
|
|
@ -915,11 +909,6 @@ export function checkForModifiedUsers() {
|
|||
const state = getState();
|
||||
const users = getUsers(state);
|
||||
const lastDisconnectAt = state.websocket.lastDisconnectAt;
|
||||
const serverVersion = getServerVersion(state);
|
||||
|
||||
if (!isMinimumServerVersion(serverVersion, 5, 14)) {
|
||||
return {data: true};
|
||||
}
|
||||
|
||||
await dispatch(getProfilesByIds(Object.keys(users), {since: lastDisconnectAt}));
|
||||
return {data: true};
|
||||
|
|
|
|||
|
|
@ -1399,20 +1399,6 @@ describe('Selectors.Channels.getRedirectChannelNameForTeam', () => {
|
|||
},
|
||||
});
|
||||
|
||||
it('getRedirectChannelNameForTeam without advanced permissions', () => {
|
||||
const modifiedState = {
|
||||
...testState,
|
||||
entities: {
|
||||
...testState.entities,
|
||||
general: {
|
||||
...testState.entities.general,
|
||||
serverVersion: '4.8.0',
|
||||
},
|
||||
},
|
||||
};
|
||||
assert.equal(Selectors.getRedirectChannelNameForTeam(modifiedState, team1.id), General.DEFAULT_CHANNEL);
|
||||
});
|
||||
|
||||
it('getRedirectChannelNameForTeam with advanced permissions but without JOIN_PUBLIC_CHANNELS permission', () => {
|
||||
const modifiedState = {
|
||||
...testState,
|
||||
|
|
@ -1506,20 +1492,6 @@ describe('Selectors.Channels.getRedirectChannelNameForTeam', () => {
|
|||
assert.equal(Selectors.getRedirectChannelNameForTeam(modifiedState, team1.id), General.DEFAULT_CHANNEL);
|
||||
});
|
||||
|
||||
it('getRedirectChannelNameForTeam without advanced permissions in not current team', () => {
|
||||
const modifiedState = {
|
||||
...testState,
|
||||
entities: {
|
||||
...testState.entities,
|
||||
general: {
|
||||
...testState.entities.general,
|
||||
serverVersion: '4.8.0',
|
||||
},
|
||||
},
|
||||
};
|
||||
assert.equal(Selectors.getRedirectChannelNameForTeam(modifiedState, team2.id), General.DEFAULT_CHANNEL);
|
||||
});
|
||||
|
||||
it('getRedirectChannelNameForTeam with advanced permissions but without JOIN_PUBLIC_CHANNELS permission in not current team', () => {
|
||||
const modifiedState = {
|
||||
...testState,
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@
|
|||
import {createSelector} from 'reselect';
|
||||
|
||||
import {getCurrentChannelId, getCurrentUser, getUsers, getMyChannelMemberships, getMyCurrentChannelMembership} from '@mm-redux/selectors/entities/common';
|
||||
import {getConfig, getLicense, hasNewPermissions} from '@mm-redux/selectors/entities/general';
|
||||
import {getConfig} from '@mm-redux/selectors/entities/general';
|
||||
import {getLastPostPerChannel, getAllPosts} from '@mm-redux/selectors/entities/posts';
|
||||
import {getFavoritesPreferences, getMyPreferences, getTeammateNameDisplaySetting, getVisibleTeammate, getVisibleGroupIds, isCollapsedThreadsEnabled} from '@mm-redux/selectors/entities/preferences';
|
||||
import {haveICurrentChannelPermission, haveIChannelPermission, haveITeamPermission} from '@mm-redux/selectors/entities/roles';
|
||||
import {getCurrentTeamId, getCurrentTeamMembership, getMyTeams, getTeamMemberships} from '@mm-redux/selectors/entities/teams';
|
||||
import {getCurrentTeamId, getMyTeams, getTeamMemberships} from '@mm-redux/selectors/entities/teams';
|
||||
import {isCurrentUserSystemAdmin, getCurrentUserId} from '@mm-redux/selectors/entities/users';
|
||||
import {Channel, ChannelStats, ChannelMembership, ChannelMemberCountsByGroup} from '@mm-redux/types/channels';
|
||||
import {Config} from '@mm-redux/types/config';
|
||||
|
|
@ -18,7 +18,7 @@ import {TeamMembership, Team} from '@mm-redux/types/teams';
|
|||
import {ThreadsState} from '@mm-redux/types/threads';
|
||||
import {UsersState, UserProfile} from '@mm-redux/types/users';
|
||||
import {NameMappedObjects, UserIDMappedObjects, IDMappedObjects, RelationOneToOne, RelationOneToMany} from '@mm-redux/types/utilities';
|
||||
import {buildDisplayableChannelListWithUnreadSection, canManageMembersOldPermissions, completeDirectChannelInfo, completeDirectChannelDisplayName, getUserIdFromChannelName, getChannelByName as getChannelByNameHelper, isChannelMuted, getDirectChannelName, isAutoClosed, isDirectChannelVisible, isGroupChannelVisible, isGroupOrDirectChannelVisible, sortChannelsByDisplayName, isFavoriteChannel, isDefault, sortChannelsByRecency, getMsgCountInChannel} from '@mm-redux/utils/channel_utils';
|
||||
import {buildDisplayableChannelListWithUnreadSection, completeDirectChannelInfo, completeDirectChannelDisplayName, getUserIdFromChannelName, getChannelByName as getChannelByNameHelper, isChannelMuted, getDirectChannelName, isAutoClosed, isDirectChannelVisible, isGroupChannelVisible, isGroupOrDirectChannelVisible, sortChannelsByDisplayName, isFavoriteChannel, isDefault, sortChannelsByRecency, getMsgCountInChannel} from '@mm-redux/utils/channel_utils';
|
||||
import {createIdsSelector} from '@mm-redux/utils/helpers';
|
||||
|
||||
import {General, Permissions} from '../../constants';
|
||||
|
|
@ -471,24 +471,31 @@ export const getUnreadsInCurrentTeam: (a: GlobalState) => {
|
|||
mentionCount,
|
||||
};
|
||||
});
|
||||
export const canManageChannelMembers: (a: GlobalState) => boolean = createSelector(getCurrentChannel, getCurrentUser, getCurrentTeamMembership, getMyCurrentChannelMembership, getConfig, getLicense, hasNewPermissions, (state: GlobalState): boolean => haveICurrentChannelPermission(state, {
|
||||
permission: Permissions.MANAGE_PRIVATE_CHANNEL_MEMBERS,
|
||||
}), (state: GlobalState): boolean => haveICurrentChannelPermission(state, {
|
||||
permission: Permissions.MANAGE_PUBLIC_CHANNEL_MEMBERS,
|
||||
}), (channel: Channel, user: UserProfile, teamMembership: TeamMembership, channelMembership: ChannelMembership | undefined | null, config: Config, license: any, newPermissions: boolean, managePrivateMembers: boolean, managePublicMembers: boolean): boolean => {
|
||||
if (!channel) {
|
||||
return false;
|
||||
}
|
||||
export const canManageChannelMembers: (a: GlobalState) => boolean = createSelector(
|
||||
getCurrentChannel,
|
||||
(state: GlobalState): boolean => haveICurrentChannelPermission(state, {
|
||||
permission: Permissions.MANAGE_PRIVATE_CHANNEL_MEMBERS,
|
||||
}),
|
||||
(state: GlobalState): boolean => haveICurrentChannelPermission(state, {
|
||||
permission: Permissions.MANAGE_PUBLIC_CHANNEL_MEMBERS,
|
||||
}),
|
||||
(
|
||||
channel: Channel,
|
||||
managePrivateMembers: boolean,
|
||||
managePublicMembers: boolean,
|
||||
): boolean => {
|
||||
if (!channel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (channel.delete_at !== 0) {
|
||||
return false;
|
||||
}
|
||||
if (channel.delete_at !== 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (channel.type === General.DM_CHANNEL || channel.type === General.GM_CHANNEL || channel.name === General.DEFAULT_CHANNEL) {
|
||||
return false;
|
||||
}
|
||||
if (channel.type === General.DM_CHANNEL || channel.type === General.GM_CHANNEL || channel.name === General.DEFAULT_CHANNEL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (newPermissions) {
|
||||
if (channel.type === General.OPEN_CHANNEL) {
|
||||
return managePublicMembers;
|
||||
} else if (channel.type === General.PRIVATE_CHANNEL) {
|
||||
|
|
@ -496,14 +503,7 @@ export const canManageChannelMembers: (a: GlobalState) => boolean = createSelect
|
|||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!channelMembership) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return canManageMembersOldPermissions(channel, user, teamMembership, channelMembership, config, license);
|
||||
}); // Determine if the user has permissions to manage members in at least one channel of the current team
|
||||
}); // Determine if the user has permissions to manage members in at least one channel of the current team
|
||||
|
||||
export const canManageAnyChannelMembersInCurrentTeam: (a: GlobalState) => boolean = createSelector(getMyChannelMemberships, getCurrentTeamId, (state: GlobalState): GlobalState => state, (members: RelationOneToOne<Channel, ChannelMembership>, currentTeamId: string, state: GlobalState): boolean => {
|
||||
for (const channelId of Object.keys(members)) {
|
||||
|
|
@ -950,7 +950,7 @@ export const getMyFirstChannelForTeams: (a: GlobalState) => RelationOneToOne<Tea
|
|||
export const getRedirectChannelNameForTeam = (state: GlobalState, teamId: string): string => {
|
||||
const defaultChannelForTeam = getDefaultChannelForTeams(state)[teamId];
|
||||
const myFirstChannelForTeam = getMyFirstChannelForTeams(state)[teamId];
|
||||
const canIJoinPublicChannelsInTeam = !hasNewPermissions(state) || haveITeamPermission(state, {
|
||||
const canIJoinPublicChannelsInTeam = haveITeamPermission(state, {
|
||||
team: teamId,
|
||||
permission: Permissions.JOIN_PUBLIC_CHANNELS,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -254,31 +254,6 @@ describe('Selectors.General', () => {
|
|||
}), true);
|
||||
});
|
||||
|
||||
it('hasNewPermissions', () => {
|
||||
const state = {
|
||||
entities: {
|
||||
general: {
|
||||
serverVersion: '4.8.0',
|
||||
},
|
||||
},
|
||||
};
|
||||
assert.equal(Selectors.hasNewPermissions(state), false);
|
||||
state.entities.general.serverVersion = '4.8.0.dev.123123';
|
||||
assert.equal(Selectors.hasNewPermissions(state), true);
|
||||
state.entities.general.serverVersion = '4.8.0.4.8.1.ffffff';
|
||||
assert.equal(Selectors.hasNewPermissions(state), false);
|
||||
state.entities.general.serverVersion = '4.8.0.3607.2f31498e967dc08ed38d7a2d7a306825.true';
|
||||
assert.equal(Selectors.hasNewPermissions(state), true);
|
||||
state.entities.general.serverVersion = '4.8.1.3607.2f31498e967dc08ed38d7a2d7a306825.true';
|
||||
assert.equal(Selectors.hasNewPermissions(state), true);
|
||||
state.entities.general.serverVersion = '4.9.0';
|
||||
assert.equal(Selectors.hasNewPermissions(state), true);
|
||||
state.entities.general.serverVersion = '4.10.0';
|
||||
assert.equal(Selectors.hasNewPermissions(state), true);
|
||||
state.entities.general.serverVersion = '5.10.0.dev';
|
||||
assert.equal(Selectors.hasNewPermissions(state), true);
|
||||
});
|
||||
|
||||
describe('getAutolinkedUrlSchemes', () => {
|
||||
it('setting doesn\'t exist', () => {
|
||||
const state = {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import {createSelector} from 'reselect';
|
|||
|
||||
import {Config, FeatureFlags} from '@mm-redux/types/config';
|
||||
import {GlobalState} from '@mm-redux/types/store';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
|
||||
import {General} from '../../constants';
|
||||
|
||||
|
|
@ -31,22 +30,6 @@ export function getCurrentUrl(state: GlobalState): string {
|
|||
return state.entities.general.credentials.url;
|
||||
}
|
||||
|
||||
export function isCompatibleWithJoinViewTeamPermissions(state: GlobalState): boolean {
|
||||
const version = state.entities.general.serverVersion;
|
||||
return isMinimumServerVersion(version, 5, 10, 0) ||
|
||||
(version.indexOf('dev') !== -1 && isMinimumServerVersion(version, 5, 8, 0)) ||
|
||||
(version.match(/^5.8.\d.\d\d\d\d.*$/) !== null && isMinimumServerVersion(version, 5, 8, 0));
|
||||
}
|
||||
|
||||
export function hasNewPermissions(state: GlobalState): boolean {
|
||||
const version = state.entities.general.serverVersion;
|
||||
|
||||
// FIXME This must be changed to 4, 9, 0 before we generate the 4.9.0 release
|
||||
return isMinimumServerVersion(version, 4, 9, 0) ||
|
||||
(version.indexOf('dev') !== -1 && isMinimumServerVersion(version, 4, 8, 0)) ||
|
||||
(version.match(/^4.8.\d.\d\d\d\d.*$/) !== null && isMinimumServerVersion(version, 4, 8, 0));
|
||||
}
|
||||
|
||||
export const canUploadFilesOnMobile: (a: GlobalState) => boolean = createSelector(
|
||||
getConfig,
|
||||
getLicense,
|
||||
|
|
|
|||
|
|
@ -91,34 +91,6 @@ describe('Selectors.Teams', () => {
|
|||
assert.deepEqual(Selectors.getTeamMember(testState, team1.id, user2.id), membersInTeam[team1.id][user2.id]);
|
||||
});
|
||||
|
||||
it('getJoinableTeams', () => {
|
||||
const openTeams = [team3, team4];
|
||||
const joinableTeams = Selectors.getJoinableTeams(testState);
|
||||
assert.strictEqual(joinableTeams[0], openTeams[0]);
|
||||
assert.strictEqual(joinableTeams[1], openTeams[1]);
|
||||
});
|
||||
|
||||
it('getSortedJoinableTeams', () => {
|
||||
const openTeams = [team4, team3];
|
||||
const joinableTeams = Selectors.getSortedJoinableTeams(testState);
|
||||
assert.strictEqual(joinableTeams[0], openTeams[0]);
|
||||
assert.strictEqual(joinableTeams[1], openTeams[1]);
|
||||
});
|
||||
|
||||
it('getListableTeams', () => {
|
||||
const openTeams = [team3, team4];
|
||||
const listableTeams = Selectors.getListableTeams(testState);
|
||||
assert.strictEqual(listableTeams[0], openTeams[0]);
|
||||
assert.strictEqual(listableTeams[1], openTeams[1]);
|
||||
});
|
||||
|
||||
it('getListedJoinableTeams', () => {
|
||||
const openTeams = [team4, team3];
|
||||
const joinableTeams = Selectors.getSortedListableTeams(testState);
|
||||
assert.strictEqual(joinableTeams[0], openTeams[0]);
|
||||
assert.strictEqual(joinableTeams[1], openTeams[1]);
|
||||
});
|
||||
|
||||
it('getJoinableTeamsUsingPermissions', () => {
|
||||
const privateTeams = [team1, team2];
|
||||
const openTeams = [team3, team4];
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import * as reselect from 'reselect';
|
||||
|
||||
import {Permissions, Preferences} from '@mm-redux/constants';
|
||||
import {getConfig, getCurrentUrl, isCompatibleWithJoinViewTeamPermissions} from '@mm-redux/selectors/entities/general';
|
||||
import {getConfig, getCurrentUrl} from '@mm-redux/selectors/entities/general';
|
||||
import {get as getPreference} from '@mm-redux/selectors/entities/preferences';
|
||||
import {haveISystemPermission} from '@mm-redux/selectors/entities/roles_helpers';
|
||||
import {GlobalState} from '@mm-redux/types/store';
|
||||
|
|
@ -147,15 +147,11 @@ export const getListableTeamIds = createIdsSelector(
|
|||
getTeamMemberships,
|
||||
(state) => haveISystemPermission(state, {permission: Permissions.LIST_PUBLIC_TEAMS}),
|
||||
(state) => haveISystemPermission(state, {permission: Permissions.LIST_PRIVATE_TEAMS}),
|
||||
isCompatibleWithJoinViewTeamPermissions,
|
||||
(teams, myMembers, canListPublicTeams, canListPrivateTeams, compatibleWithJoinViewTeamPermissions) => {
|
||||
(teams, myMembers, canListPublicTeams, canListPrivateTeams) => {
|
||||
return Object.keys(teams).filter((id) => {
|
||||
const team = teams[id];
|
||||
const member = myMembers[id];
|
||||
let canList = team.allow_open_invite;
|
||||
if (compatibleWithJoinViewTeamPermissions) {
|
||||
canList = (canListPrivateTeams && !team.allow_open_invite) || (canListPublicTeams && team.allow_open_invite);
|
||||
}
|
||||
const canList = (canListPrivateTeams && !team.allow_open_invite) || (canListPublicTeams && team.allow_open_invite);
|
||||
return team.delete_at === 0 && canList && !member;
|
||||
});
|
||||
},
|
||||
|
|
@ -189,15 +185,11 @@ export const getJoinableTeamIds = createIdsSelector(
|
|||
getTeamMemberships,
|
||||
(state: GlobalState) => haveISystemPermission(state, {permission: Permissions.JOIN_PUBLIC_TEAMS}),
|
||||
(state: GlobalState) => haveISystemPermission(state, {permission: Permissions.JOIN_PRIVATE_TEAMS}),
|
||||
isCompatibleWithJoinViewTeamPermissions,
|
||||
(teams, myMembers, canJoinPublicTeams, canJoinPrivateTeams, compatibleWithJoinViewTeamPermissions) => {
|
||||
(teams, myMembers, canJoinPublicTeams, canJoinPrivateTeams) => {
|
||||
return Object.keys(teams).filter((id) => {
|
||||
const team = teams[id];
|
||||
const member = myMembers[id];
|
||||
let canJoin = team.allow_open_invite;
|
||||
if (compatibleWithJoinViewTeamPermissions) {
|
||||
canJoin = (canJoinPrivateTeams && !team.allow_open_invite) || (canJoinPublicTeams && team.allow_open_invite);
|
||||
}
|
||||
const canJoin = (canJoinPrivateTeams && !team.allow_open_invite) || (canJoinPublicTeams && team.allow_open_invite);
|
||||
return team.delete_at === 0 && canJoin && !member;
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {hasNewPermissions} from '@mm-redux/selectors/entities/general';
|
||||
import {haveITeamPermission, haveIChannelPermission} from '@mm-redux/selectors/entities/roles';
|
||||
import {Channel, ChannelMembership, ChannelType, ChannelNotifyProps} from '@mm-redux/types/channels';
|
||||
import {Post} from '@mm-redux/types/posts';
|
||||
|
|
@ -285,115 +284,30 @@ export function isGroupOrDirectChannelVisible(
|
|||
);
|
||||
}
|
||||
|
||||
export function showCreateOption(state: GlobalState, config: any, license: any, teamId: string, channelType: ChannelType, isAdmin: boolean, isSystemAdmin: boolean): boolean {
|
||||
if (hasNewPermissions(state)) {
|
||||
if (channelType === General.OPEN_CHANNEL) {
|
||||
return haveITeamPermission(state, {team: teamId, permission: Permissions.CREATE_PUBLIC_CHANNEL});
|
||||
} else if (channelType === General.PRIVATE_CHANNEL) {
|
||||
return haveITeamPermission(state, {team: teamId, permission: Permissions.CREATE_PRIVATE_CHANNEL});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (license.IsLicensed !== 'true') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Backwards compatibility with pre-advanced permissions config settings.
|
||||
export function showCreateOption(state: GlobalState, teamId: string, channelType: ChannelType): boolean {
|
||||
if (channelType === General.OPEN_CHANNEL) {
|
||||
if (config.RestrictPublicChannelCreation === General.SYSTEM_ADMIN_ROLE && !isSystemAdmin) {
|
||||
return false;
|
||||
} else if (config.RestrictPublicChannelCreation === General.TEAM_ADMIN_ROLE && !isAdmin) {
|
||||
return false;
|
||||
}
|
||||
return haveITeamPermission(state, {team: teamId, permission: Permissions.CREATE_PUBLIC_CHANNEL});
|
||||
} else if (channelType === General.PRIVATE_CHANNEL) {
|
||||
if (config.RestrictPrivateChannelCreation === General.SYSTEM_ADMIN_ROLE && !isSystemAdmin) {
|
||||
return false;
|
||||
} else if (config.RestrictPrivateChannelCreation === General.TEAM_ADMIN_ROLE && !isAdmin) {
|
||||
return false;
|
||||
}
|
||||
return haveITeamPermission(state, {team: teamId, permission: Permissions.CREATE_PRIVATE_CHANNEL});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function showManagementOptions(state: GlobalState, config: any, license: any, channel: Channel, isAdmin: boolean, isSystemAdmin: boolean, isChannelAdmin: boolean): boolean {
|
||||
if (hasNewPermissions(state)) {
|
||||
if (channel.type === General.OPEN_CHANNEL) {
|
||||
return haveIChannelPermission(state, {channel: channel.id, team: channel.team_id, permission: Permissions.MANAGE_PUBLIC_CHANNEL_PROPERTIES});
|
||||
} else if (channel.type === General.PRIVATE_CHANNEL) {
|
||||
return haveIChannelPermission(state, {channel: channel.id, team: channel.team_id, permission: Permissions.MANAGE_PRIVATE_CHANNEL_PROPERTIES});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (license.IsLicensed !== 'true') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Backwards compatibility with pre-advanced permissions config settings.
|
||||
export function showManagementOptions(state: GlobalState, channel: Channel): boolean {
|
||||
if (channel.type === General.OPEN_CHANNEL) {
|
||||
if (config.RestrictPublicChannelManagement === General.SYSTEM_ADMIN_ROLE && !isSystemAdmin) {
|
||||
return false;
|
||||
}
|
||||
if (config.RestrictPublicChannelManagement === General.TEAM_ADMIN_ROLE && !isAdmin) {
|
||||
return false;
|
||||
}
|
||||
if (config.RestrictPublicChannelManagement === General.CHANNEL_ADMIN_ROLE && !isChannelAdmin && !isAdmin) {
|
||||
return false;
|
||||
}
|
||||
return haveIChannelPermission(state, {channel: channel.id, team: channel.team_id, permission: Permissions.MANAGE_PUBLIC_CHANNEL_PROPERTIES});
|
||||
} else if (channel.type === General.PRIVATE_CHANNEL) {
|
||||
if (config.RestrictPrivateChannelManagement === General.SYSTEM_ADMIN_ROLE && !isSystemAdmin) {
|
||||
return false;
|
||||
}
|
||||
if (config.RestrictPrivateChannelManagement === General.TEAM_ADMIN_ROLE && !isAdmin) {
|
||||
return false;
|
||||
}
|
||||
if (config.RestrictPrivateChannelManagement === General.CHANNEL_ADMIN_ROLE && !isChannelAdmin && !isAdmin) {
|
||||
return false;
|
||||
}
|
||||
return haveIChannelPermission(state, {channel: channel.id, team: channel.team_id, permission: Permissions.MANAGE_PRIVATE_CHANNEL_PROPERTIES});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function showDeleteOption(state: GlobalState, config: any, license: any, channel: Channel, isAdmin: boolean, isSystemAdmin: boolean, isChannelAdmin: boolean): boolean {
|
||||
if (hasNewPermissions(state)) {
|
||||
if (channel.type === General.OPEN_CHANNEL) {
|
||||
return haveIChannelPermission(state, {channel: channel.id, team: channel.team_id, permission: Permissions.DELETE_PUBLIC_CHANNEL});
|
||||
} else if (channel.type === General.PRIVATE_CHANNEL) {
|
||||
return haveIChannelPermission(state, {channel: channel.id, team: channel.team_id, permission: Permissions.DELETE_PRIVATE_CHANNEL});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (license.IsLicensed !== 'true') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Backwards compatibility with pre-advanced permissions config settings.
|
||||
export function showDeleteOption(state: GlobalState, channel: Channel): boolean {
|
||||
if (channel.type === General.OPEN_CHANNEL) {
|
||||
if (config.RestrictPublicChannelDeletion === General.SYSTEM_ADMIN_ROLE && !isSystemAdmin) {
|
||||
return false;
|
||||
}
|
||||
if (config.RestrictPublicChannelDeletion === General.TEAM_ADMIN_ROLE && !isAdmin) {
|
||||
return false;
|
||||
}
|
||||
if (config.RestrictPublicChannelDeletion === General.CHANNEL_ADMIN_ROLE && !isChannelAdmin && !isAdmin) {
|
||||
return false;
|
||||
}
|
||||
return haveIChannelPermission(state, {channel: channel.id, team: channel.team_id, permission: Permissions.DELETE_PUBLIC_CHANNEL});
|
||||
} else if (channel.type === General.PRIVATE_CHANNEL) {
|
||||
if (config.RestrictPrivateChannelDeletion === General.SYSTEM_ADMIN_ROLE && !isSystemAdmin) {
|
||||
return false;
|
||||
}
|
||||
if (config.RestrictPrivateChannelDeletion === General.TEAM_ADMIN_ROLE && !isAdmin) {
|
||||
return false;
|
||||
}
|
||||
if (config.RestrictPrivateChannelDeletion === General.CHANNEL_ADMIN_ROLE && !isChannelAdmin && !isAdmin) {
|
||||
return false;
|
||||
}
|
||||
return haveIChannelPermission(state, {channel: channel.id, team: channel.team_id, permission: Permissions.DELETE_PRIVATE_CHANNEL});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,35 +100,46 @@ describe('PostUtils', () => {
|
|||
const channelId = 'channel-id';
|
||||
const userId = 'user-id';
|
||||
|
||||
const state = {entities: {general: {serverVersion: ''}}};
|
||||
|
||||
it('should allow to edit my post without license', () => {
|
||||
// Hasn't license
|
||||
assert.ok(canEditPost(state, {PostEditTimeLimit: -1}, notLicensed, teamId, channelId, userId, {user_id: userId, type: 'normal'}));
|
||||
assert.ok(!canEditPost(state, {PostEditTimeLimit: -1}, notLicensed, teamId, channelId, userId, {user_id: userId, type: 'system_test'}));
|
||||
assert.ok(!canEditPost(state, {PostEditTimeLimit: -1}, notLicensed, teamId, channelId, userId, {user_id: 'other', type: 'normal'}));
|
||||
assert.ok(!canEditPost(state, {PostEditTimeLimit: -1}, notLicensed, teamId, channelId, userId, {user_id: 'other', type: 'system_test'}));
|
||||
assert.ok(!canEditPost(state, {PostEditTimeLimit: -1}, notLicensed, teamId, channelId, userId, null));
|
||||
});
|
||||
|
||||
it('should work with old permissions version', () => {
|
||||
const oldVersionState = {
|
||||
const newVersionState = {
|
||||
entities: {
|
||||
general: {
|
||||
serverVersion: '4.3.0',
|
||||
serverVersion: '5.26.0',
|
||||
},
|
||||
users: {
|
||||
currentUserId: userId,
|
||||
profiles: {
|
||||
'user-id': {roles: 'system_role'},
|
||||
},
|
||||
},
|
||||
teams: {
|
||||
currentTeamId: teamId,
|
||||
myMembers: {
|
||||
'team-id': {roles: 'team_role'},
|
||||
},
|
||||
},
|
||||
channels: {
|
||||
currentChannelId: channelId,
|
||||
myMembers: {
|
||||
'channel-id': {roles: 'channel_role'},
|
||||
},
|
||||
},
|
||||
roles: {
|
||||
roles: {
|
||||
system_role: {permissions: [Permissions.EDIT_POST]},
|
||||
team_role: {permissions: []},
|
||||
channel_role: {permissions: []},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// With old permissions
|
||||
assert.ok(!canEditPost(oldVersionState, {PostEditTimeLimit: null, AllowEditPost: 'never'}, licensed, teamId, channelId, userId, {user_id: userId}));
|
||||
assert.ok(canEditPost(oldVersionState, {PostEditTimeLimit: null, AllowEditPost: 'always'}, licensed, teamId, channelId, userId, {user_id: userId}));
|
||||
assert.ok(canEditPost(oldVersionState, {PostEditTimeLimit: 300, AllowEditPost: 'time_limit'}, licensed, teamId, channelId, userId, {user_id: userId, create_at: Date.now() - 100}));
|
||||
assert.ok(!canEditPost(oldVersionState, {PostEditTimeLimit: 300, AllowEditPost: 'time_limit'}, licensed, teamId, channelId, userId, {user_id: userId, create_at: Date.now() - 600000}));
|
||||
assert.ok(!canEditPost(oldVersionState, {PostEditTimeLimit: null, AllowEditPost: 'never'}, licensed, teamId, channelId, userId, {user_id: 'other'}));
|
||||
assert.ok(!canEditPost(oldVersionState, {PostEditTimeLimit: null, AllowEditPost: 'always'}, licensed, teamId, channelId, userId, {user_id: 'other'}));
|
||||
assert.ok(!canEditPost(oldVersionState, {PostEditTimeLimit: 300, AllowEditPost: 'time_limit'}, licensed, teamId, channelId, userId, {user_id: 'other', create_at: Date.now() - 100}));
|
||||
assert.ok(!canEditPost(oldVersionState, {PostEditTimeLimit: 300, AllowEditPost: 'time_limit'}, licensed, teamId, channelId, userId, {user_id: 'other', create_at: Date.now() - 600000}));
|
||||
// Hasn't license
|
||||
assert.ok(canEditPost(newVersionState, {PostEditTimeLimit: -1}, notLicensed, teamId, channelId, userId, {user_id: userId, type: 'normal'}));
|
||||
assert.ok(!canEditPost(newVersionState, {PostEditTimeLimit: -1}, notLicensed, teamId, channelId, userId, {user_id: userId, type: 'system_test'}));
|
||||
assert.ok(!canEditPost(newVersionState, {PostEditTimeLimit: -1}, notLicensed, teamId, channelId, userId, {user_id: 'other', type: 'normal'}));
|
||||
assert.ok(!canEditPost(newVersionState, {PostEditTimeLimit: -1}, notLicensed, teamId, channelId, userId, {user_id: 'other', type: 'system_test'}));
|
||||
assert.ok(!canEditPost(newVersionState, {PostEditTimeLimit: -1}, notLicensed, teamId, channelId, userId, null));
|
||||
});
|
||||
|
||||
it('should work with new permissions version', () => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {hasNewPermissions} from '@mm-redux/selectors/entities/general';
|
||||
import {haveIChannelPermission} from '@mm-redux/selectors/entities/roles';
|
||||
import {Channel} from '@mm-redux/types/channels';
|
||||
import {Post, PostType, PostMetadata, PostEmbed} from '@mm-redux/types/posts';
|
||||
|
|
@ -9,9 +8,8 @@ import {GlobalState} from '@mm-redux/types/store';
|
|||
import {Team} from '@mm-redux/types/teams';
|
||||
import {UserProfile} from '@mm-redux/types/users';
|
||||
import {$ID} from '@mm-redux/types/utilities';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
|
||||
import {General, Posts, Preferences, Permissions} from '../constants';
|
||||
import {Posts, Preferences, Permissions} from '../constants';
|
||||
|
||||
import {getPreferenceKey} from './preference_utils';
|
||||
|
||||
|
|
@ -54,72 +52,24 @@ export function isEdited(post: Post): boolean {
|
|||
return post.edit_at > 0;
|
||||
}
|
||||
|
||||
export function canDeletePost(state: GlobalState, config: any, license: any, teamId: $ID<Team>, channelId: $ID<Channel>, userId: $ID<UserProfile>, post: Post, isAdmin: boolean, isSystemAdmin: boolean): boolean {
|
||||
if (!post) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const isOwner = isPostOwner(userId, post);
|
||||
|
||||
if (hasNewPermissions(state)) {
|
||||
let permissions = [];
|
||||
if (isOwner) {
|
||||
permissions = [Permissions.DELETE_POST];
|
||||
} else {
|
||||
const {serverVersion} = state.entities.general;
|
||||
|
||||
// prior to v5.27, the server used to require delete_own_posts and
|
||||
// delete_others_posts permissions to be able to delete a post by a
|
||||
// different author.
|
||||
permissions = isMinimumServerVersion(serverVersion, 5, 27) ? [Permissions.DELETE_OTHERS_POSTS] : [Permissions.DELETE_POST, Permissions.DELETE_OTHERS_POSTS];
|
||||
}
|
||||
return permissions.every((permission) => haveIChannelPermission(state, {team: teamId, channel: channelId, permission, default: false}));
|
||||
}
|
||||
|
||||
// Backwards compatibility with pre-advanced permissions config settings.
|
||||
if (license.IsLicensed === 'true') {
|
||||
return (config.RestrictPostDelete === General.PERMISSIONS_ALL && (isOwner || isAdmin)) ||
|
||||
(config.RestrictPostDelete === General.PERMISSIONS_TEAM_ADMIN && isAdmin) ||
|
||||
(config.RestrictPostDelete === General.PERMISSIONS_SYSTEM_ADMIN && isSystemAdmin);
|
||||
}
|
||||
return isOwner || isAdmin;
|
||||
}
|
||||
|
||||
export function canEditPost(state: GlobalState, config: any, license: any, teamId: $ID<Team>, channelId: $ID<Channel>, userId: $ID<UserProfile>, post: Post): boolean {
|
||||
if (!post || isSystemMessage(post)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const isOwner = isPostOwner(userId, post);
|
||||
let canEdit = true;
|
||||
|
||||
if (hasNewPermissions(state)) {
|
||||
let permissions = [];
|
||||
if (isOwner) {
|
||||
permissions = [Permissions.EDIT_POST];
|
||||
} else {
|
||||
const {serverVersion} = state.entities.general;
|
||||
|
||||
// prior to v5.26, the server used to require edit_own_posts and
|
||||
// edit_others_posts permissions to be able to edit a post by a
|
||||
// different author.
|
||||
permissions = isMinimumServerVersion(serverVersion, 5, 26) ? [Permissions.EDIT_OTHERS_POSTS] : [Permissions.EDIT_POST, Permissions.EDIT_OTHERS_POSTS];
|
||||
}
|
||||
canEdit = permissions.every((permission) => haveIChannelPermission(state, {team: teamId, channel: channelId, permission, default: false}));
|
||||
if (license.IsLicensed === 'true' && config.PostEditTimeLimit !== '-1' && config.PostEditTimeLimit !== -1) {
|
||||
const timeLeft = (post.create_at + (config.PostEditTimeLimit * 1000)) - Date.now();
|
||||
if (timeLeft <= 0) {
|
||||
canEdit = false;
|
||||
}
|
||||
}
|
||||
let permissions = [];
|
||||
if (isOwner) {
|
||||
permissions = [Permissions.EDIT_POST];
|
||||
} else {
|
||||
// Backwards compatibility with pre-advanced permissions config settings.
|
||||
canEdit = isOwner && config.AllowEditPost !== 'never';
|
||||
if (config.AllowEditPost === General.ALLOW_EDIT_POST_TIME_LIMIT) {
|
||||
const timeLeft = (post.create_at + (config.PostEditTimeLimit * 1000)) - Date.now();
|
||||
if (timeLeft <= 0) {
|
||||
canEdit = false;
|
||||
}
|
||||
permissions = [Permissions.EDIT_OTHERS_POSTS];
|
||||
}
|
||||
let canEdit = permissions.every((permission) => haveIChannelPermission(state, {team: teamId, channel: channelId, permission, default: false}));
|
||||
if (license.IsLicensed === 'true' && config.PostEditTimeLimit !== '-1' && config.PostEditTimeLimit !== -1) {
|
||||
const timeLeft = (post.create_at + (config.PostEditTimeLimit * 1000)) - Date.now();
|
||||
if (timeLeft <= 0) {
|
||||
canEdit = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,49 +11,38 @@ import {deleteChannel, getChannel, unarchiveChannel} from '@mm-redux/actions/cha
|
|||
import {General} from '@mm-redux/constants';
|
||||
import Permissions from '@mm-redux/constants/permissions';
|
||||
import {getCurrentChannel, isCurrentChannelReadOnly} from '@mm-redux/selectors/entities/channels';
|
||||
import {getConfig, getLicense, hasNewPermissions} from '@mm-redux/selectors/entities/general';
|
||||
import {getConfig} from '@mm-redux/selectors/entities/general';
|
||||
import {haveITeamPermission} from '@mm-redux/selectors/entities/roles';
|
||||
import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams';
|
||||
import {getCurrentUser, getCurrentUserRoles} from '@mm-redux/selectors/entities/users';
|
||||
import {getCurrentUser} from '@mm-redux/selectors/entities/users';
|
||||
import {showDeleteOption} from '@mm-redux/utils/channel_utils';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
import {isAdmin as checkIsAdmin, isChannelAdmin as checkIsChannelAdmin, isSystemAdmin as checkIsSystemAdmin} from '@mm-redux/utils/user_utils';
|
||||
import {isGuest as isUserGuest} from '@utils/users';
|
||||
|
||||
import Archive from './archive';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
const config = getConfig(state);
|
||||
const license = getLicense(state);
|
||||
const currentChannel = getCurrentChannel(state);
|
||||
const currentUser = getCurrentUser(state);
|
||||
const roles = getCurrentUserRoles(state) || '';
|
||||
const isGuest = isUserGuest(currentUser);
|
||||
const isDefaultChannel = currentChannel.name === General.DEFAULT_CHANNEL;
|
||||
const isDirectMessage = currentChannel.type === General.DM_CHANNEL;
|
||||
const isGroupMessage = currentChannel.type === General.GM_CHANNEL;
|
||||
const isAdmin = checkIsAdmin(roles);
|
||||
const isChannelAdmin = checkIsChannelAdmin(roles);
|
||||
const isSystemAdmin = checkIsSystemAdmin(roles);
|
||||
const canLeave = (!isDefaultChannel && !isDirectMessage && !isGroupMessage) || (isDefaultChannel && isGuest);
|
||||
const canDelete = showDeleteOption(state, config, license, currentChannel, isAdmin, isSystemAdmin, isChannelAdmin);
|
||||
const canDelete = showDeleteOption(state, currentChannel);
|
||||
const isArchived = currentChannel?.delete_at > 0;
|
||||
const canUnarchive = (isArchived && !isDirectMessage && !isGroupMessage);
|
||||
const viewArchivedChannels = config.ExperimentalViewArchivedChannels === 'true';
|
||||
const {serverVersion} = state.entities.general;
|
||||
|
||||
let isReadOnly = false;
|
||||
if (currentUser?.id && currentChannel?.id) {
|
||||
isReadOnly = isCurrentChannelReadOnly(state) || false;
|
||||
}
|
||||
|
||||
let canUnarchiveChannel = false;
|
||||
if (hasNewPermissions(state) && isMinimumServerVersion(serverVersion, 5, 20)) {
|
||||
canUnarchiveChannel = haveITeamPermission(state, {
|
||||
team: getCurrentTeamId(state),
|
||||
permission: Permissions.MANAGE_TEAM,
|
||||
});
|
||||
}
|
||||
const canUnarchiveChannel = haveITeamPermission(state, {
|
||||
team: getCurrentTeamId(state),
|
||||
permission: Permissions.MANAGE_TEAM,
|
||||
});
|
||||
|
||||
return {
|
||||
canArchive: (!isArchived && canLeave && canDelete && !isReadOnly),
|
||||
|
|
|
|||
|
|
@ -6,11 +6,9 @@ import {connect} from 'react-redux';
|
|||
import {convertChannelToPrivate} from '@mm-redux/actions/channels';
|
||||
import {General, Permissions} from '@mm-redux/constants';
|
||||
import {getCurrentChannel} from '@mm-redux/selectors/entities/channels';
|
||||
import {getServerVersion} from '@mm-redux/selectors/entities/general';
|
||||
import {haveIChannelPermission} from '@mm-redux/selectors/entities/roles';
|
||||
import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams';
|
||||
import {getCurrentUserRoles} from '@mm-redux/selectors/entities/users';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
import {isAdmin as checkIsAdmin} from '@mm-redux/utils/user_utils';
|
||||
|
||||
import ConvertPrivate from './convert_private';
|
||||
|
|
@ -24,18 +22,15 @@ function mapStateToProps(state) {
|
|||
const isChannelConvertible = !isDefaultChannel && isPublicChannel;
|
||||
const roles = getCurrentUserRoles(state) || '';
|
||||
const isAdmin = checkIsAdmin(roles);
|
||||
let canConvert = isChannelConvertible && isAdmin;
|
||||
if (isMinimumServerVersion(getServerVersion(state), 5, 28)) {
|
||||
canConvert = isChannelConvertible && haveIChannelPermission(
|
||||
state,
|
||||
{
|
||||
channel: channelId,
|
||||
team: currentTeamId,
|
||||
permission: Permissions.CONVERT_PUBLIC_CHANNEL_TO_PRIVATE,
|
||||
default: isAdmin,
|
||||
},
|
||||
);
|
||||
}
|
||||
const canConvert = isChannelConvertible && haveIChannelPermission(
|
||||
state,
|
||||
{
|
||||
channel: channelId,
|
||||
team: currentTeamId,
|
||||
permission: Permissions.CONVERT_PUBLIC_CHANNEL_TO_PRIVATE,
|
||||
default: isAdmin,
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
canConvert,
|
||||
|
|
|
|||
|
|
@ -4,29 +4,21 @@
|
|||
import {connect} from 'react-redux';
|
||||
|
||||
import {getCurrentChannel, isCurrentChannelReadOnly} from '@mm-redux/selectors/entities/channels';
|
||||
import {getConfig, getLicense} from '@mm-redux/selectors/entities/general';
|
||||
import {getCurrentUserId, getCurrentUserRoles} from '@mm-redux/selectors/entities/users';
|
||||
import {getCurrentUserId} from '@mm-redux/selectors/entities/users';
|
||||
import {showManagementOptions} from '@mm-redux/utils/channel_utils';
|
||||
import {isAdmin as checkIsAdmin, isChannelAdmin as checkIsChannelAdmin, isSystemAdmin as checkIsSystemAdmin} from '@mm-redux/utils/user_utils';
|
||||
|
||||
import EditChannel from './edit_channel';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
const config = getConfig(state);
|
||||
const license = getLicense(state);
|
||||
const currentChannel = getCurrentChannel(state);
|
||||
const currentUserId = getCurrentUserId(state);
|
||||
const roles = getCurrentUserRoles(state) || '';
|
||||
const isAdmin = checkIsAdmin(roles);
|
||||
const isChannelAdmin = checkIsChannelAdmin(roles);
|
||||
const isSystemAdmin = checkIsSystemAdmin(roles);
|
||||
|
||||
let channelIsReadOnly = false;
|
||||
if (currentUserId && currentChannel.id) {
|
||||
channelIsReadOnly = isCurrentChannelReadOnly(state) || false;
|
||||
}
|
||||
|
||||
const canEdit = !channelIsReadOnly && showManagementOptions(state, config, license, currentChannel, isAdmin, isSystemAdmin, isChannelAdmin);
|
||||
const canEdit = !channelIsReadOnly && showManagementOptions(state, currentChannel);
|
||||
|
||||
return {
|
||||
canEdit,
|
||||
|
|
|
|||
|
|
@ -7,14 +7,12 @@ import {bindActionCreators} from 'redux';
|
|||
import {setProfileImageUri, removeProfileImage, updateUser} from '@actions/views/edit_profile';
|
||||
import {getConfig} from '@mm-redux/selectors/entities/general';
|
||||
import {getTheme} from '@mm-redux/selectors/entities/preferences';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
import {isLandscape} from '@selectors/device';
|
||||
|
||||
import EditProfile from './edit_profile';
|
||||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
const config = getConfig(state);
|
||||
const {serverVersion} = state.entities.general;
|
||||
const {auth_service: service} = ownProps.currentUser;
|
||||
|
||||
const firstNameDisabled = (service === 'ldap' && config.LdapFirstNameAttributeSet === 'true') ||
|
||||
|
|
@ -31,10 +29,7 @@ function mapStateToProps(state, ownProps) {
|
|||
const positionDisabled = (service === 'ldap' && config.LdapPositionAttributeSet === 'true') ||
|
||||
(service === 'saml' && config.SamlPositionAttributeSet === 'true');
|
||||
|
||||
let profilePictureDisabled = false;
|
||||
if (isMinimumServerVersion(serverVersion, 5, 24)) {
|
||||
profilePictureDisabled = (service === 'ldap' || service === 'saml') && config.LdapPictureAttributeSet === 'true';
|
||||
}
|
||||
const profilePictureDisabled = (service === 'ldap' || service === 'saml') && config.LdapPictureAttributeSet === 'true';
|
||||
|
||||
return {
|
||||
firstNameDisabled,
|
||||
|
|
|
|||
|
|
@ -7,13 +7,11 @@ import {bindActionCreators} from 'redux';
|
|||
import {handleSelectChannel, setChannelDisplayName} from '@actions/views/channel';
|
||||
import {getArchivedChannels, getChannels, getSharedChannels, joinChannel, searchChannels} from '@mm-redux/actions/channels';
|
||||
import {General} from '@mm-redux/constants';
|
||||
import {getConfig, getLicense} from '@mm-redux/selectors/entities/general';
|
||||
import {getConfig} from '@mm-redux/selectors/entities/general';
|
||||
import {getTheme} from '@mm-redux/selectors/entities/preferences';
|
||||
import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams';
|
||||
import {getCurrentUserId, getCurrentUserRoles} from '@mm-redux/selectors/entities/users';
|
||||
import {getCurrentUserId} from '@mm-redux/selectors/entities/users';
|
||||
import {showCreateOption} from '@mm-redux/utils/channel_utils';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
import {isAdmin, isSystemAdmin} from '@mm-redux/utils/user_utils';
|
||||
import {teamArchivedChannels, joinablePublicChannels, joinableSharedChannels} from '@selectors/channel';
|
||||
|
||||
import MoreChannels from './more_channels';
|
||||
|
|
@ -22,18 +20,15 @@ const defaultSharedChannels = [];
|
|||
|
||||
function mapStateToProps(state) {
|
||||
const config = getConfig(state);
|
||||
const license = getLicense(state);
|
||||
const sharedChannelsEnabled = config.ExperimentalSharedChannels === 'true';
|
||||
const roles = getCurrentUserRoles(state);
|
||||
const channels = joinablePublicChannels(state);
|
||||
const sharedChannels = sharedChannelsEnabled ? joinableSharedChannels(state) : defaultSharedChannels;
|
||||
const archivedChannels = teamArchivedChannels(state);
|
||||
const currentTeamId = getCurrentTeamId(state);
|
||||
const canShowArchivedChannels = config.ExperimentalViewArchivedChannels === 'true' &&
|
||||
isMinimumServerVersion(state.entities.general.serverVersion, 5, 18);
|
||||
const canShowArchivedChannels = config.ExperimentalViewArchivedChannels === 'true';
|
||||
|
||||
return {
|
||||
canCreateChannels: showCreateOption(state, config, license, currentTeamId, General.OPEN_CHANNEL, isAdmin(roles), isSystemAdmin(roles)),
|
||||
canCreateChannels: showCreateOption(state, currentTeamId, General.OPEN_CHANNEL),
|
||||
currentUserId: getCurrentUserId(state),
|
||||
currentTeamId,
|
||||
channels,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import {getTheme} from '@mm-redux/selectors/entities/preferences';
|
|||
import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams';
|
||||
import {isTimezoneEnabled} from '@mm-redux/selectors/entities/timezone';
|
||||
import {getCurrentUser} from '@mm-redux/selectors/entities/users';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
import {getUserCurrentTimezone} from '@mm-redux/utils/timezone_utils';
|
||||
import {makePreparePostIdsForSearchPosts} from '@selectors/post_list';
|
||||
import {getDeviceUtcOffset, getUtcOffsetForTimeZone} from '@utils/timezone';
|
||||
|
|
@ -45,9 +44,6 @@ function makeMapStateToProps() {
|
|||
const userCurrentTimezone = enableTimezone ? getUserCurrentTimezone(currentUser.timezone) : '';
|
||||
const timezoneOffsetInSeconds = (userCurrentTimezone.length > 0 ? getUtcOffsetForTimeZone(userCurrentTimezone) : getDeviceUtcOffset()) * 60;
|
||||
|
||||
const serverVersion = state.entities.general.serverVersion;
|
||||
const enableDateSuggestion = isMinimumServerVersion(serverVersion, 5, 3);
|
||||
|
||||
const isSearchGettingMore = state.entities.search.isSearchGettingMore;
|
||||
|
||||
return {
|
||||
|
|
@ -58,7 +54,6 @@ function makeMapStateToProps() {
|
|||
recent: recent[currentTeamId],
|
||||
isSearchGettingMore,
|
||||
theme: getTheme(state),
|
||||
enableDateSuggestion,
|
||||
timezoneOffsetInSeconds,
|
||||
viewArchivedChannels,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ export default class Search extends PureComponent {
|
|||
recent: PropTypes.array.isRequired,
|
||||
isSearchGettingMore: PropTypes.bool.isRequired,
|
||||
theme: PropTypes.object.isRequired,
|
||||
enableDateSuggestion: PropTypes.bool,
|
||||
timezoneOffsetInSeconds: PropTypes.number.isRequired,
|
||||
viewArchivedChannels: PropTypes.bool,
|
||||
};
|
||||
|
|
@ -116,7 +115,6 @@ export default class Search extends PureComponent {
|
|||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
const {enableDateSuggestion} = this.props;
|
||||
const {recent, didFail, isLoaded, status} = this.state;
|
||||
const {status: prevStatus} = prevState;
|
||||
const shouldScroll = prevStatus !== status &&
|
||||
|
|
@ -127,7 +125,7 @@ export default class Search extends PureComponent {
|
|||
setTimeout(() => {
|
||||
const recentLabelsHeight = recent.length * RECENT_LABEL_HEIGHT;
|
||||
const recentSeparatorsHeight = (recent.length - 1) * RECENT_SEPARATOR_HEIGHT;
|
||||
const modifiersCount = enableDateSuggestion ? 5 : 2;
|
||||
const modifiersCount = 5;
|
||||
const modifiersHeight = modifiersCount * MODIFIER_LABEL_HEIGHT;
|
||||
const modifiersSeparatorHeight = (modifiersCount - 1) * RECENT_SEPARATOR_HEIGHT;
|
||||
const offset = modifiersHeight + modifiersSeparatorHeight + SECTION_HEIGHT + recentLabelsHeight + recentSeparatorsHeight;
|
||||
|
|
@ -539,36 +537,33 @@ export default class Search extends PureComponent {
|
|||
}),
|
||||
}];
|
||||
|
||||
// if search by date filters supported
|
||||
if (this.props.enableDateSuggestion) {
|
||||
sectionsData.push({
|
||||
value: 'on:',
|
||||
testID: 'search.on_section',
|
||||
modifier: 'YYYY-MM-DD',
|
||||
description: intl.formatMessage({
|
||||
id: 'mobile.search.on_modifier_description',
|
||||
defaultMessage: 'to find posts on a specific date',
|
||||
}),
|
||||
});
|
||||
sectionsData.push({
|
||||
value: 'after:',
|
||||
testID: 'search.after_section',
|
||||
modifier: 'YYYY-MM-DD',
|
||||
description: intl.formatMessage({
|
||||
id: 'mobile.search.after_modifier_description',
|
||||
defaultMessage: 'to find posts after a specific date',
|
||||
}),
|
||||
});
|
||||
sectionsData.push({
|
||||
value: 'before:',
|
||||
testID: 'search.before_section',
|
||||
modifier: 'YYYY-MM-DD',
|
||||
description: intl.formatMessage({
|
||||
id: 'mobile.search.before_modifier_description',
|
||||
defaultMessage: 'to find posts before a specific date',
|
||||
}),
|
||||
});
|
||||
}
|
||||
sectionsData.push({
|
||||
value: 'on:',
|
||||
testID: 'search.on_section',
|
||||
modifier: 'YYYY-MM-DD',
|
||||
description: intl.formatMessage({
|
||||
id: 'mobile.search.on_modifier_description',
|
||||
defaultMessage: 'to find posts on a specific date',
|
||||
}),
|
||||
});
|
||||
sectionsData.push({
|
||||
value: 'after:',
|
||||
testID: 'search.after_section',
|
||||
modifier: 'YYYY-MM-DD',
|
||||
description: intl.formatMessage({
|
||||
id: 'mobile.search.after_modifier_description',
|
||||
defaultMessage: 'to find posts after a specific date',
|
||||
}),
|
||||
});
|
||||
sectionsData.push({
|
||||
value: 'before:',
|
||||
testID: 'search.before_section',
|
||||
modifier: 'YYYY-MM-DD',
|
||||
description: intl.formatMessage({
|
||||
id: 'mobile.search.before_modifier_description',
|
||||
defaultMessage: 'to find posts before a specific date',
|
||||
}),
|
||||
});
|
||||
|
||||
const sections = [{
|
||||
data: sectionsData,
|
||||
|
|
@ -714,7 +709,7 @@ export default class Search extends PureComponent {
|
|||
onChangeText={this.handleTextChanged}
|
||||
isSearch={true}
|
||||
value={value}
|
||||
enableDateSuggestion={this.props.enableDateSuggestion}
|
||||
enableDateSuggestion={true}
|
||||
/>
|
||||
</KeyboardLayout>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import {updateMe} from '@mm-redux/actions/users';
|
|||
import {getConfig} from '@mm-redux/selectors/entities/general';
|
||||
import {getMyPreferences, getTheme, isCollapsedThreadsEnabled} from '@mm-redux/selectors/entities/preferences';
|
||||
import {getCurrentUser, getStatusForUserId} from '@mm-redux/selectors/entities/users';
|
||||
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
|
||||
import {isLandscape} from '@selectors/device';
|
||||
|
||||
import NotificationSettings from './notification_settings';
|
||||
|
|
@ -17,8 +16,7 @@ function mapStateToProps(state) {
|
|||
const config = getConfig(state);
|
||||
const currentUser = getCurrentUser(state) || {};
|
||||
const currentUserStatus = getStatusForUserId(state, currentUser.id);
|
||||
const serverVersion = state.entities.general.serverVersion;
|
||||
const enableAutoResponder = isMinimumServerVersion(serverVersion, 4, 9) && config.ExperimentalEnableAutomaticReplies === 'true';
|
||||
const enableAutoResponder = config.ExperimentalEnableAutomaticReplies === 'true';
|
||||
|
||||
return {
|
||||
config,
|
||||
|
|
|
|||
Loading…
Reference in a new issue