mattermost-redux 10.8.0 → 10.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/lib/action_types/admin.d.ts +8 -0
  2. package/lib/action_types/admin.js +8 -0
  3. package/lib/action_types/users.d.ts +1 -0
  4. package/lib/action_types/users.js +1 -0
  5. package/lib/actions/access_control.d.ts +14 -0
  6. package/lib/actions/access_control.js +142 -0
  7. package/lib/actions/admin.d.ts +2 -0
  8. package/lib/actions/admin.js +15 -0
  9. package/lib/actions/channels.d.ts +5 -2
  10. package/lib/actions/channels.js +38 -22
  11. package/lib/actions/posts.d.ts +1 -1
  12. package/lib/actions/posts.js +25 -7
  13. package/lib/constants/general.d.ts +1 -1
  14. package/lib/constants/general.js +1 -1
  15. package/lib/constants/permissions.d.ts +2 -0
  16. package/lib/constants/permissions.js +2 -0
  17. package/lib/constants/permissions_sysconsole.d.ts +4 -0
  18. package/lib/constants/permissions_sysconsole.js +6 -0
  19. package/lib/reducers/entities/admin.d.ts +3 -0
  20. package/lib/reducers/entities/admin.js +60 -0
  21. package/lib/reducers/entities/index.d.ts +2 -0
  22. package/lib/reducers/entities/users.js +18 -0
  23. package/lib/reducers/index.d.ts +2 -0
  24. package/lib/selectors/create_selector/index.js +2 -82
  25. package/lib/selectors/entities/access_control.d.ts +8 -0
  26. package/lib/selectors/entities/access_control.js +44 -0
  27. package/lib/selectors/entities/channel_banner.d.ts +1 -0
  28. package/lib/selectors/entities/channel_banner.js +11 -4
  29. package/lib/selectors/entities/report_a_problem.d.ts +3 -0
  30. package/lib/selectors/entities/report_a_problem.js +46 -0
  31. package/lib/store/initial_state.js +2 -0
  32. package/lib/utils/browser_info.d.ts +5 -0
  33. package/lib/utils/browser_info.js +96 -0
  34. package/package.json +3 -3
@@ -47,5 +47,13 @@ declare const _default: {
47
47
  REMOVE_DATA_RETENTION_CUSTOM_POLICY_TEAMS_FAILURE: "REMOVE_DATA_RETENTION_CUSTOM_POLICY_TEAMS_FAILURE";
48
48
  REMOVE_DATA_RETENTION_CUSTOM_POLICY_CHANNELS_SUCCESS: "REMOVE_DATA_RETENTION_CUSTOM_POLICY_CHANNELS_SUCCESS";
49
49
  REMOVE_DATA_RETENTION_CUSTOM_POLICY_CHANNELS_FAILURE: "REMOVE_DATA_RETENTION_CUSTOM_POLICY_CHANNELS_FAILURE";
50
+ RECEIVED_ACCESS_CONTROL_POLICIES: "RECEIVED_ACCESS_CONTROL_POLICIES";
51
+ RECEIVED_ACCESS_CONTROL_POLICY: "RECEIVED_ACCESS_CONTROL_POLICY";
52
+ CREATE_ACCESS_CONTROL_POLICY_SUCCESS: "CREATE_ACCESS_CONTROL_POLICY_SUCCESS";
53
+ DELETE_ACCESS_CONTROL_POLICY_SUCCESS: "DELETE_ACCESS_CONTROL_POLICY_SUCCESS";
54
+ RECEIVED_ACCESS_CONTROL_CHILD_POLICIES: "RECEIVED_ACCESS_CONTROL_CHILD_POLICIES";
55
+ RECEIVED_ACCESS_CONTROL_POLICIES_SEARCH: "RECEIVED_ACCESS_CONTROL_POLICIES_SEARCH";
56
+ ASSIGN_CHANNELS_TO_ACCESS_CONTROL_POLICY_SUCCESS: "ASSIGN_CHANNELS_TO_ACCESS_CONTROL_POLICY_SUCCESS";
57
+ UNASSIGN_CHANNELS_FROM_ACCESS_CONTROL_POLICY_SUCCESS: "UNASSIGN_CHANNELS_FROM_ACCESS_CONTROL_POLICY_SUCCESS";
50
58
  };
51
59
  export default _default;
@@ -55,4 +55,12 @@ exports.default = (0, key_mirror_1.default)({
55
55
  REMOVE_DATA_RETENTION_CUSTOM_POLICY_TEAMS_FAILURE: null,
56
56
  REMOVE_DATA_RETENTION_CUSTOM_POLICY_CHANNELS_SUCCESS: null,
57
57
  REMOVE_DATA_RETENTION_CUSTOM_POLICY_CHANNELS_FAILURE: null,
58
+ RECEIVED_ACCESS_CONTROL_POLICIES: null,
59
+ RECEIVED_ACCESS_CONTROL_POLICY: null,
60
+ CREATE_ACCESS_CONTROL_POLICY_SUCCESS: null,
61
+ DELETE_ACCESS_CONTROL_POLICY_SUCCESS: null,
62
+ RECEIVED_ACCESS_CONTROL_CHILD_POLICIES: null,
63
+ RECEIVED_ACCESS_CONTROL_POLICIES_SEARCH: null,
64
+ ASSIGN_CHANNELS_TO_ACCESS_CONTROL_POLICY_SUCCESS: null,
65
+ UNASSIGN_CHANNELS_FROM_ACCESS_CONTROL_POLICY_SUCCESS: null,
58
66
  });
@@ -61,5 +61,6 @@ declare const _default: {
61
61
  RECEIVED_FILTERED_USER_STATS: "RECEIVED_FILTERED_USER_STATS";
62
62
  PROFILE_NO_LONGER_VISIBLE: "PROFILE_NO_LONGER_VISIBLE";
63
63
  LOGIN: "LOGIN";
64
+ CLEAR_CPA_VALUES: "CLEAR_CPA_VALUES";
64
65
  };
65
66
  export default _default;
@@ -69,4 +69,5 @@ exports.default = (0, key_mirror_1.default)({
69
69
  RECEIVED_FILTERED_USER_STATS: null,
70
70
  PROFILE_NO_LONGER_VISIBLE: null,
71
71
  LOGIN: null,
72
+ CLEAR_CPA_VALUES: null,
72
73
  });
@@ -0,0 +1,14 @@
1
+ import type { AccessControlPoliciesResult, AccessControlPolicy, AccessControlTestResult } from '@mattermost/types/access_control';
2
+ import type { ChannelSearchOpts, ChannelsWithTotalCount } from '@mattermost/types/channels';
3
+ import type { ActionFuncAsync } from 'mattermost-redux/types/actions';
4
+ export declare function getAccessControlPolicy(id: string): ActionFuncAsync<AccessControlPolicy, import("@mattermost/types/store").GlobalState, import("redux").AnyAction>;
5
+ export declare function createAccessControlPolicy(policy: AccessControlPolicy): ActionFuncAsync<AccessControlPolicy>;
6
+ export declare function deleteAccessControlPolicy(id: string): ActionFuncAsync<AccessControlPolicy, import("@mattermost/types/store").GlobalState, import("redux").AnyAction>;
7
+ export declare function searchAccessControlPolicies(term: string, type: string, after: string, limit: number): ActionFuncAsync<AccessControlPoliciesResult>;
8
+ export declare function searchAccessControlPolicyChannels(id: string, term: string, opts: ChannelSearchOpts): ActionFuncAsync<ChannelsWithTotalCount>;
9
+ export declare function assignChannelsToAccessControlPolicy(policyId: string, channelIds: string[]): ActionFuncAsync<import("@mattermost/types/client4").StatusOK, import("@mattermost/types/store").GlobalState, import("redux").AnyAction>;
10
+ export declare function unassignChannelsFromAccessControlPolicy(policyId: string, channelIds: string[]): ActionFuncAsync<import("@mattermost/types/client4").StatusOK, import("@mattermost/types/store").GlobalState, import("redux").AnyAction>;
11
+ export declare function getAccessControlFields(after: string, limit: number): ActionFuncAsync<import("@mattermost/types/properties").UserPropertyField[], import("@mattermost/types/store").GlobalState, import("redux").AnyAction>;
12
+ export declare function updateAccessControlPolicyActive(policyId: string, active: boolean): ActionFuncAsync<import("@mattermost/types/client4").StatusOK, import("@mattermost/types/store").GlobalState, import("redux").AnyAction>;
13
+ export declare function searchUsersForExpression(expression: string, term: string, after: string, limit: number): ActionFuncAsync<AccessControlTestResult>;
14
+ export declare function getVisualAST(expression: string): ActionFuncAsync<import("@mattermost/types/access_control").AccessControlVisualAST, import("@mattermost/types/store").GlobalState, import("redux").AnyAction>;
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
+ // See LICENSE.txt for license information.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.getAccessControlPolicy = getAccessControlPolicy;
6
+ exports.createAccessControlPolicy = createAccessControlPolicy;
7
+ exports.deleteAccessControlPolicy = deleteAccessControlPolicy;
8
+ exports.searchAccessControlPolicies = searchAccessControlPolicies;
9
+ exports.searchAccessControlPolicyChannels = searchAccessControlPolicyChannels;
10
+ exports.assignChannelsToAccessControlPolicy = assignChannelsToAccessControlPolicy;
11
+ exports.unassignChannelsFromAccessControlPolicy = unassignChannelsFromAccessControlPolicy;
12
+ exports.getAccessControlFields = getAccessControlFields;
13
+ exports.updateAccessControlPolicyActive = updateAccessControlPolicyActive;
14
+ exports.searchUsersForExpression = searchUsersForExpression;
15
+ exports.getVisualAST = getVisualAST;
16
+ const redux_batched_actions_1 = require("redux-batched-actions");
17
+ const action_types_1 = require("mattermost-redux/action_types");
18
+ const client_1 = require("mattermost-redux/client");
19
+ const helpers_1 = require("./helpers");
20
+ function getAccessControlPolicy(id) {
21
+ return (0, helpers_1.bindClientFunc)({
22
+ clientFunc: client_1.Client4.getAccessControlPolicy,
23
+ onSuccess: [action_types_1.AdminTypes.RECEIVED_ACCESS_CONTROL_POLICY],
24
+ params: [
25
+ id,
26
+ ],
27
+ });
28
+ }
29
+ function createAccessControlPolicy(policy) {
30
+ return async (dispatch, getState) => {
31
+ let data;
32
+ try {
33
+ data = await client_1.Client4.updateOrCreateAccessControlPolicy(policy);
34
+ }
35
+ catch (error) {
36
+ (0, helpers_1.forceLogoutIfNecessary)(error, dispatch, getState);
37
+ return { error };
38
+ }
39
+ dispatch({ type: action_types_1.AdminTypes.CREATE_ACCESS_CONTROL_POLICY_SUCCESS, data });
40
+ return { data };
41
+ };
42
+ }
43
+ function deleteAccessControlPolicy(id) {
44
+ return (0, helpers_1.bindClientFunc)({
45
+ clientFunc: client_1.Client4.deleteAccessControlPolicy,
46
+ onSuccess: [action_types_1.AdminTypes.DELETE_ACCESS_CONTROL_POLICY_SUCCESS],
47
+ params: [
48
+ id,
49
+ ],
50
+ });
51
+ }
52
+ function searchAccessControlPolicies(term, type, after, limit) {
53
+ return async (dispatch, getState) => {
54
+ let data;
55
+ try {
56
+ data = await client_1.Client4.searchAccessControlPolicies(term, type, after, limit);
57
+ }
58
+ catch (error) {
59
+ (0, helpers_1.forceLogoutIfNecessary)(error, dispatch, getState);
60
+ return { error };
61
+ }
62
+ dispatch({ type: action_types_1.AdminTypes.RECEIVED_ACCESS_CONTROL_POLICIES_SEARCH, data: data.policies });
63
+ return { data };
64
+ };
65
+ }
66
+ function searchAccessControlPolicyChannels(id, term, opts) {
67
+ return async (dispatch, getState) => {
68
+ let data;
69
+ try {
70
+ data = await client_1.Client4.searchChildAccessControlPolicyChannels(id, term, opts);
71
+ }
72
+ catch (error) {
73
+ (0, helpers_1.forceLogoutIfNecessary)(error, dispatch, getState);
74
+ return { error };
75
+ }
76
+ const childs = {};
77
+ childs[id] = data.channels.map((channel) => channel.id);
78
+ dispatch((0, redux_batched_actions_1.batchActions)([
79
+ { type: action_types_1.AdminTypes.RECEIVED_ACCESS_CONTROL_CHILD_POLICIES, data: childs },
80
+ { type: action_types_1.ChannelTypes.RECEIVED_CHANNELS, data: data.channels },
81
+ ]));
82
+ return { data };
83
+ };
84
+ }
85
+ function assignChannelsToAccessControlPolicy(policyId, channelIds) {
86
+ return (0, helpers_1.bindClientFunc)({
87
+ clientFunc: client_1.Client4.assignChannelsToAccessControlPolicy,
88
+ onSuccess: [action_types_1.AdminTypes.ASSIGN_CHANNELS_TO_ACCESS_CONTROL_POLICY_SUCCESS],
89
+ params: [
90
+ policyId,
91
+ channelIds,
92
+ ],
93
+ });
94
+ }
95
+ function unassignChannelsFromAccessControlPolicy(policyId, channelIds) {
96
+ return (0, helpers_1.bindClientFunc)({
97
+ clientFunc: client_1.Client4.unassignChannelsFromAccessControlPolicy,
98
+ onSuccess: [action_types_1.AdminTypes.UNASSIGN_CHANNELS_FROM_ACCESS_CONTROL_POLICY_SUCCESS],
99
+ params: [
100
+ policyId,
101
+ channelIds,
102
+ ],
103
+ });
104
+ }
105
+ function getAccessControlFields(after, limit) {
106
+ return (0, helpers_1.bindClientFunc)({
107
+ clientFunc: client_1.Client4.getAccessControlFields,
108
+ params: [
109
+ after,
110
+ limit,
111
+ ],
112
+ });
113
+ }
114
+ function updateAccessControlPolicyActive(policyId, active) {
115
+ return (0, helpers_1.bindClientFunc)({
116
+ clientFunc: client_1.Client4.updateAccessControlPolicyActive,
117
+ params: [
118
+ policyId,
119
+ active,
120
+ ],
121
+ });
122
+ }
123
+ function searchUsersForExpression(expression, term, after, limit) {
124
+ return async (dispatch, getState) => {
125
+ let data;
126
+ try {
127
+ data = await client_1.Client4.testAccessControlExpression(expression, term, after, limit);
128
+ }
129
+ catch (error) {
130
+ (0, helpers_1.forceLogoutIfNecessary)(error, dispatch, getState);
131
+ return { error };
132
+ }
133
+ dispatch({ type: action_types_1.UserTypes.RECEIVED_PROFILES, data: data.users });
134
+ return { data };
135
+ };
136
+ }
137
+ function getVisualAST(expression) {
138
+ return (0, helpers_1.bindClientFunc)({
139
+ clientFunc: client_1.Client4.expressionToVisualFormat,
140
+ params: [expression],
141
+ });
142
+ }
@@ -40,6 +40,8 @@ export declare function uploadPrivateSamlCertificate(fileData: File): ActionFunc
40
40
  export declare function uploadPublicLdapCertificate(fileData: File): ActionFuncAsync<import("@mattermost/types/client4").StatusOK, import("@mattermost/types/store").GlobalState, import("redux").AnyAction>;
41
41
  export declare function uploadPrivateLdapCertificate(fileData: File): ActionFuncAsync<import("@mattermost/types/client4").StatusOK, import("@mattermost/types/store").GlobalState, import("redux").AnyAction>;
42
42
  export declare function uploadIdpSamlCertificate(fileData: File): ActionFuncAsync<import("@mattermost/types/client4").StatusOK, import("@mattermost/types/store").GlobalState, import("redux").AnyAction>;
43
+ export declare function uploadAuditCertificate(fileData: File): ActionFuncAsync<import("@mattermost/types/client4").StatusOK, import("@mattermost/types/store").GlobalState, import("redux").AnyAction>;
44
+ export declare function removeAuditCertificate(): ActionFuncAsync<import("@mattermost/types/client4").StatusOK, import("@mattermost/types/store").GlobalState, import("redux").AnyAction>;
43
45
  export declare function removePublicSamlCertificate(): ActionFuncAsync<import("@mattermost/types/client4").StatusOK, import("@mattermost/types/store").GlobalState, import("redux").AnyAction>;
44
46
  export declare function removePrivateSamlCertificate(): ActionFuncAsync<import("@mattermost/types/client4").StatusOK, import("@mattermost/types/store").GlobalState, import("redux").AnyAction>;
45
47
  export declare function removePublicLdapCertificate(): ActionFuncAsync<import("@mattermost/types/client4").StatusOK, import("@mattermost/types/store").GlobalState, import("redux").AnyAction>;
@@ -31,6 +31,8 @@ exports.uploadPrivateSamlCertificate = uploadPrivateSamlCertificate;
31
31
  exports.uploadPublicLdapCertificate = uploadPublicLdapCertificate;
32
32
  exports.uploadPrivateLdapCertificate = uploadPrivateLdapCertificate;
33
33
  exports.uploadIdpSamlCertificate = uploadIdpSamlCertificate;
34
+ exports.uploadAuditCertificate = uploadAuditCertificate;
35
+ exports.removeAuditCertificate = removeAuditCertificate;
34
36
  exports.removePublicSamlCertificate = removePublicSamlCertificate;
35
37
  exports.removePrivateSamlCertificate = removePrivateSamlCertificate;
36
38
  exports.removePublicLdapCertificate = removePublicLdapCertificate;
@@ -334,6 +336,19 @@ function uploadIdpSamlCertificate(fileData) {
334
336
  ],
335
337
  });
336
338
  }
339
+ function uploadAuditCertificate(fileData) {
340
+ return (0, helpers_1.bindClientFunc)({
341
+ clientFunc: client_1.Client4.uploadAuditLogCertificate,
342
+ params: [
343
+ fileData,
344
+ ],
345
+ });
346
+ }
347
+ function removeAuditCertificate() {
348
+ return (0, helpers_1.bindClientFunc)({
349
+ clientFunc: client_1.Client4.removeAuditLogCertificate,
350
+ });
351
+ }
337
352
  function removePublicSamlCertificate() {
338
353
  return (0, helpers_1.bindClientFunc)({
339
354
  clientFunc: client_1.Client4.deletePublicSamlCertificate,
@@ -1,4 +1,5 @@
1
1
  import type { AnyAction } from 'redux';
2
+ import type { AccessControlAttributes } from '@mattermost/types/access_control';
2
3
  import type { Channel, ChannelNotifyProps, ChannelMembership, ChannelModerationPatch, ChannelsWithTotalCount, ChannelSearchOpts, ServerChannel, ChannelStats, ChannelWithTeamData } from '@mattermost/types/channels';
3
4
  import type { OptsSignalExt } from '@mattermost/types/client4';
4
5
  import type { GetStateFunc, ActionFunc, ActionFuncAsync } from 'mattermost-redux/types/actions';
@@ -40,8 +41,8 @@ export declare function unsetActiveChannelOnServer(): ActionFuncAsync;
40
41
  export declare function readMultipleChannels(channelIds: string[]): ActionFuncAsync;
41
42
  export declare function getChannels(teamId: string, page?: number, perPage?: number): ActionFuncAsync<Channel[]>;
42
43
  export declare function getArchivedChannels(teamId: string, page?: number, perPage?: number): ActionFuncAsync<Channel[]>;
43
- export declare function getAllChannelsWithCount(page?: number, perPage?: number, notAssociatedToGroup?: string, excludeDefaultChannels?: boolean, includeDeleted?: boolean, excludePolicyConstrained?: boolean): ActionFuncAsync<ChannelsWithTotalCount>;
44
- export declare function getAllChannels(page?: number, perPage?: number, notAssociatedToGroup?: string, excludeDefaultChannels?: boolean, excludePolicyConstrained?: boolean): ActionFuncAsync<ChannelWithTeamData[]>;
44
+ export declare function getAllChannelsWithCount(page?: number, perPage?: number, notAssociatedToGroup?: string, excludeDefaultChannels?: boolean, includeDeleted?: boolean, excludePolicyConstrained?: boolean, accessControlPolicyEnforced?: boolean, excludeAccessControlPolicyEnforced?: boolean): ActionFuncAsync<ChannelsWithTotalCount>;
45
+ export declare function getAllChannels(page?: number, perPage?: number, notAssociatedToGroup?: string, excludeDefaultChannels?: boolean, excludePolicyConstrained?: boolean, excludeAccessControlPolicyEnforced?: boolean, accessControlPolicyEnforced?: boolean): ActionFuncAsync<ChannelWithTeamData[]>;
45
46
  export declare function autocompleteChannels(teamId: string, term: string): ActionFuncAsync<Channel[]>;
46
47
  export declare function autocompleteChannelsForSearch(teamId: string, term: string): ActionFuncAsync<Channel[]>;
47
48
  export declare function searchChannels(teamId: string, term: string, archived?: boolean): ActionFuncAsync<Channel[]>;
@@ -91,6 +92,7 @@ export declare function getChannelMemberCountsByGroup(channelId: string): Action
91
92
  memberCounts: import("@mattermost/types/channels").ChannelMemberCountsByGroup;
92
93
  }, import("@mattermost/types/store").GlobalState, AnyAction>;
93
94
  export declare function fetchMissingChannels(channelIDs: string[]): ActionFuncAsync<Array<Channel['id']>>;
95
+ export declare function getChannelAccessControlAttributes(channelId: string): ActionFuncAsync<AccessControlAttributes>;
94
96
  declare const _default: {
95
97
  selectChannel: typeof selectChannel;
96
98
  createChannel: typeof createChannel;
@@ -120,5 +122,6 @@ declare const _default: {
120
122
  membersMinusGroupMembers: typeof membersMinusGroupMembers;
121
123
  getChannelModerations: typeof getChannelModerations;
122
124
  getChannelMemberCountsByGroup: typeof getChannelMemberCountsByGroup;
125
+ getChannelAccessControlAttributes: typeof getChannelAccessControlAttributes;
123
126
  };
124
127
  export default _default;
@@ -58,6 +58,7 @@ exports.getChannelModerations = getChannelModerations;
58
58
  exports.patchChannelModerations = patchChannelModerations;
59
59
  exports.getChannelMemberCountsByGroup = getChannelMemberCountsByGroup;
60
60
  exports.fetchMissingChannels = fetchMissingChannels;
61
+ exports.getChannelAccessControlAttributes = getChannelAccessControlAttributes;
61
62
  const redux_batched_actions_1 = require("redux-batched-actions");
62
63
  const action_types_1 = require("mattermost-redux/action_types");
63
64
  const client_1 = require("mattermost-redux/client");
@@ -411,8 +412,8 @@ function getChannelTimezones(channelId) {
411
412
  }
412
413
  function fetchChannelsAndMembers(teamId) {
413
414
  return async (dispatch, getState) => {
414
- let channels;
415
- let channelMembers;
415
+ let channels = [];
416
+ let channelMembers = [];
416
417
  try {
417
418
  [channels, channelMembers] = await Promise.all([
418
419
  client_1.Client4.getMyChannels(teamId),
@@ -451,32 +452,32 @@ function fetchAllMyChannelMembers() {
451
452
  return async (dispatch, getState) => {
452
453
  const state = getState();
453
454
  const { currentUserId } = state.entities.users;
454
- let channelsMembers = [];
455
- let hasMoreMembers = true;
456
- let page = 0;
455
+ let channelMembers = [];
457
456
  try {
458
- while (hasMoreMembers) {
459
- // Expected to disable since we don't have number of pages, so we can't use Promise.all
460
- // eslint-disable-next-line no-await-in-loop
461
- const data = await client_1.Client4.getAllChannelsMembers(currentUserId, page, 200);
462
- channelsMembers = [...channelsMembers, ...data];
463
- if (data.length < 200) {
464
- hasMoreMembers = false;
465
- }
466
- page++;
467
- }
457
+ // The server exposes a streaming API if page is set to -1
458
+ // We don't need to paginate through the responses, and thefore pageSize doesn't matter
459
+ channelMembers = await client_1.Client4.getAllChannelsMembers(currentUserId, -1);
468
460
  }
469
461
  catch (error) {
470
462
  (0, helpers_1.forceLogoutIfNecessary)(error, dispatch, getState);
471
463
  dispatch((0, errors_1.logError)(error));
472
464
  return { error };
473
465
  }
466
+ const roles = new Set();
467
+ for (const member of channelMembers) {
468
+ for (const role of member.roles.split(' ')) {
469
+ roles.add(role);
470
+ }
471
+ }
472
+ if (roles.size > 0) {
473
+ dispatch((0, roles_1.loadRolesIfNeeded)(roles));
474
+ }
474
475
  dispatch({
475
476
  type: action_types_1.ChannelTypes.RECEIVED_MY_CHANNEL_MEMBERS,
476
- data: channelsMembers,
477
+ data: channelMembers,
477
478
  currentUserId,
478
479
  });
479
- return { data: channelsMembers };
480
+ return { data: channelMembers };
480
481
  };
481
482
  }
482
483
  function fetchAllMyTeamsChannels() {
@@ -491,7 +492,7 @@ function fetchAllMyTeamsChannels() {
491
492
  return { error };
492
493
  }
493
494
  dispatch({
494
- type: action_types_1.ChannelTypes.RECEIVED_ALL_CHANNELS,
495
+ type: action_types_1.ChannelTypes.RECEIVED_CHANNELS,
495
496
  data: channels,
496
497
  });
497
498
  return { data: channels };
@@ -735,12 +736,12 @@ function getArchivedChannels(teamId, page = 0, perPage = constants_1.General.CHA
735
736
  return { data: channels };
736
737
  };
737
738
  }
738
- function getAllChannelsWithCount(page = 0, perPage = constants_1.General.CHANNELS_CHUNK_SIZE, notAssociatedToGroup = '', excludeDefaultChannels = false, includeDeleted = false, excludePolicyConstrained = false) {
739
+ function getAllChannelsWithCount(page = 0, perPage = constants_1.General.CHANNELS_CHUNK_SIZE, notAssociatedToGroup = '', excludeDefaultChannels = false, includeDeleted = false, excludePolicyConstrained = false, accessControlPolicyEnforced = false, excludeAccessControlPolicyEnforced = false) {
739
740
  return async (dispatch, getState) => {
740
741
  dispatch({ type: action_types_1.ChannelTypes.GET_ALL_CHANNELS_REQUEST, data: null });
741
742
  let payload;
742
743
  try {
743
- payload = await client_1.Client4.getAllChannels(page, perPage, notAssociatedToGroup, excludeDefaultChannels, true, includeDeleted, excludePolicyConstrained);
744
+ payload = await client_1.Client4.getAllChannels(page, perPage, notAssociatedToGroup, excludeDefaultChannels, true, includeDeleted, excludePolicyConstrained, accessControlPolicyEnforced, excludeAccessControlPolicyEnforced);
744
745
  }
745
746
  catch (error) {
746
747
  (0, helpers_1.forceLogoutIfNecessary)(error, dispatch, getState);
@@ -764,12 +765,12 @@ function getAllChannelsWithCount(page = 0, perPage = constants_1.General.CHANNEL
764
765
  return { data: payload };
765
766
  };
766
767
  }
767
- function getAllChannels(page = 0, perPage = constants_1.General.CHANNELS_CHUNK_SIZE, notAssociatedToGroup = '', excludeDefaultChannels = false, excludePolicyConstrained = false) {
768
+ function getAllChannels(page = 0, perPage = constants_1.General.CHANNELS_CHUNK_SIZE, notAssociatedToGroup = '', excludeDefaultChannels = false, excludePolicyConstrained = false, excludeAccessControlPolicyEnforced = false, accessControlPolicyEnforced = false) {
768
769
  return async (dispatch, getState) => {
769
770
  dispatch({ type: action_types_1.ChannelTypes.GET_ALL_CHANNELS_REQUEST, data: null });
770
771
  let channels;
771
772
  try {
772
- channels = await client_1.Client4.getAllChannels(page, perPage, notAssociatedToGroup, excludeDefaultChannels, false, false, excludePolicyConstrained);
773
+ channels = await client_1.Client4.getAllChannels(page, perPage, notAssociatedToGroup, excludeDefaultChannels, false, false, excludePolicyConstrained, accessControlPolicyEnforced, excludeAccessControlPolicyEnforced);
773
774
  }
774
775
  catch (error) {
775
776
  (0, helpers_1.forceLogoutIfNecessary)(error, dispatch, getState);
@@ -1317,6 +1318,20 @@ function fetchMissingChannels(channelIDs) {
1317
1318
  };
1318
1319
  };
1319
1320
  }
1321
+ function getChannelAccessControlAttributes(channelId) {
1322
+ return async (dispatch, getState) => {
1323
+ let data;
1324
+ try {
1325
+ data = await client_1.Client4.getChannelAccessControlAttributes(channelId);
1326
+ }
1327
+ catch (error) {
1328
+ (0, helpers_1.forceLogoutIfNecessary)(error, dispatch, getState);
1329
+ dispatch((0, errors_1.logError)(error));
1330
+ return { error };
1331
+ }
1332
+ return { data };
1333
+ };
1334
+ }
1320
1335
  exports.default = {
1321
1336
  selectChannel,
1322
1337
  createChannel,
@@ -1346,4 +1361,5 @@ exports.default = {
1346
1361
  membersMinusGroupMembers,
1347
1362
  getChannelModerations,
1348
1363
  getChannelMemberCountsByGroup,
1364
+ getChannelAccessControlAttributes,
1349
1365
  };
@@ -97,7 +97,7 @@ export declare function addReaction(postId: string, emojiName: string): ActionFu
97
97
  export declare function removeReaction(postId: string, emojiName: string): ActionFuncAsync<SubmitReactionReturnType>;
98
98
  export declare function getCustomEmojiForReaction(name: string): ActionFuncAsync;
99
99
  export declare function flagPost(postId: string): ActionFuncAsync;
100
- export declare function getPostThread(rootId: string, fetchThreads?: boolean): ActionFuncAsync<PostList>;
100
+ export declare function getPostThread(rootId: string, fetchThreads?: boolean, lastUpdateAt?: number): ActionFuncAsync<PostList>;
101
101
  export declare function getNewestPostThread(rootId: string): ActionFuncAsync;
102
102
  export declare function getPosts(channelId: string, page?: number, perPage?: number, fetchThreads?: boolean, collapsedThreadsExtended?: boolean): ActionFuncAsync<PostList>;
103
103
  export declare function getPostsUnread(channelId: string, fetchThreads?: boolean, collapsedThreadsExtended?: boolean): ActionFuncAsync<PostList>;
@@ -587,23 +587,41 @@ async function getPaginatedPostThread(rootId, options, prevList) {
587
587
  if (result.has_next) {
588
588
  const [nextPostId] = list.order.slice(-1);
589
589
  const nextPostPointer = list.posts[nextPostId];
590
- const newOptions = {
591
- ...options,
592
- fromCreateAt: nextPostPointer.create_at,
593
- fromPost: nextPostId,
594
- };
590
+ let newOptions;
591
+ if (options.updatesOnly) {
592
+ newOptions = {
593
+ ...options,
594
+ fromUpdateAt: nextPostPointer.update_at,
595
+ fromPost: nextPostId,
596
+ };
597
+ }
598
+ else {
599
+ newOptions = {
600
+ ...options,
601
+ fromCreateAt: nextPostPointer.create_at,
602
+ fromPost: nextPostId,
603
+ };
604
+ }
595
605
  return getPaginatedPostThread(rootId, newOptions, list);
596
606
  }
597
607
  return list;
598
608
  }
599
- function getPostThread(rootId, fetchThreads = true) {
609
+ function getPostThread(rootId, fetchThreads = true, lastUpdateAt = 0) {
600
610
  return async (dispatch, getState) => {
601
611
  const state = getState();
602
612
  const collapsedThreadsEnabled = (0, preferences_2.isCollapsedThreadsEnabled)(state);
603
613
  const enabledUserStatuses = (0, common_1.getIsUserStatusesConfigEnabled)(state);
604
614
  let posts;
615
+ const options = {
616
+ fetchThreads,
617
+ collapsedThreads: collapsedThreadsEnabled,
618
+ };
619
+ if (lastUpdateAt !== 0) {
620
+ options.updatesOnly = true;
621
+ options.fromUpdateAt = lastUpdateAt;
622
+ }
605
623
  try {
606
- posts = await getPaginatedPostThread(rootId, { fetchThreads, collapsedThreads: collapsedThreadsEnabled });
624
+ posts = await getPaginatedPostThread(rootId, options);
607
625
  }
608
626
  catch (error) {
609
627
  (0, helpers_1.forceLogoutIfNecessary)(error, dispatch, getState);
@@ -74,6 +74,6 @@ declare const _default: {
74
74
  CUSTOM_GROUP_USER_ROLE: string;
75
75
  MAX_GET_ROLES_BY_NAMES: number;
76
76
  SKUEnterprise: string;
77
- SKUPremium: string;
77
+ SKUEnterpriseAdvanced: string;
78
78
  };
79
79
  export default _default;
@@ -78,5 +78,5 @@ exports.default = {
78
78
  CUSTOM_GROUP_USER_ROLE: 'custom_group_user',
79
79
  MAX_GET_ROLES_BY_NAMES: 100,
80
80
  SKUEnterprise: 'enterprise',
81
- SKUPremium: 'premium',
81
+ SKUEnterpriseAdvanced: 'advanced',
82
82
  };
@@ -27,6 +27,8 @@ declare const values: {
27
27
  DELETE_PUBLIC_CHANNEL: string;
28
28
  CONVERT_PUBLIC_CHANNEL_TO_PRIVATE: string;
29
29
  CONVERT_PRIVATE_CHANNEL_TO_PUBLIC: string;
30
+ MANAGE_PUBLIC_CHANNEL_BANNER: string;
31
+ MANAGE_PRIVATE_CHANNEL_BANNER: string;
30
32
  DELETE_PRIVATE_CHANNEL: string;
31
33
  EDIT_OTHER_USERS: string;
32
34
  READ_CHANNEL: string;
@@ -31,6 +31,8 @@ const values = {
31
31
  DELETE_PUBLIC_CHANNEL: 'delete_public_channel',
32
32
  CONVERT_PUBLIC_CHANNEL_TO_PRIVATE: 'convert_public_channel_to_private',
33
33
  CONVERT_PRIVATE_CHANNEL_TO_PUBLIC: 'convert_private_channel_to_public',
34
+ MANAGE_PUBLIC_CHANNEL_BANNER: 'manage_public_channel_banner',
35
+ MANAGE_PRIVATE_CHANNEL_BANNER: 'manage_private_channel_banner',
34
36
  DELETE_PRIVATE_CHANNEL: 'delete_private_channel',
35
37
  EDIT_OTHER_USERS: 'edit_other_users',
36
38
  READ_CHANNEL: 'read_channel',
@@ -15,6 +15,10 @@ export declare const RESOURCE_KEYS: {
15
15
  PERMISSIONS: string;
16
16
  SYSTEM_ROLES: string;
17
17
  };
18
+ SYSTEM_ATTRIBUTES: {
19
+ USER_ATTRIBUTES: string;
20
+ ATTRIBUTE_BASED_ACCESS_CONTROL: string;
21
+ };
18
22
  AUTHENTICATION: {
19
23
  SIGNUP: string;
20
24
  EMAIL: string;
@@ -24,6 +24,10 @@ exports.RESOURCE_KEYS = {
24
24
  PERMISSIONS: 'user_management.permissions',
25
25
  SYSTEM_ROLES: 'user_management.system_roles',
26
26
  },
27
+ SYSTEM_ATTRIBUTES: {
28
+ USER_ATTRIBUTES: 'system_attributes.user_attributes',
29
+ ATTRIBUTE_BASED_ACCESS_CONTROL: 'system_attributes.attribute_based_access_control',
30
+ },
27
31
  AUTHENTICATION: {
28
32
  SIGNUP: 'authentication.signup',
29
33
  EMAIL: 'authentication.email',
@@ -96,6 +100,8 @@ exports.ResourceToSysConsolePermissionsTable = {
96
100
  [exports.RESOURCE_KEYS.USER_MANAGEMENT.CHANNELS]: [permissions_1.default.SYSCONSOLE_READ_USERMANAGEMENT_CHANNELS, permissions_1.default.SYSCONSOLE_WRITE_USERMANAGEMENT_CHANNELS],
97
101
  [exports.RESOURCE_KEYS.USER_MANAGEMENT.PERMISSIONS]: [permissions_1.default.SYSCONSOLE_READ_USERMANAGEMENT_PERMISSIONS, permissions_1.default.SYSCONSOLE_WRITE_USERMANAGEMENT_PERMISSIONS],
98
102
  [exports.RESOURCE_KEYS.USER_MANAGEMENT.SYSTEM_ROLES]: [permissions_1.default.SYSCONSOLE_READ_USERMANAGEMENT_SYSTEM_ROLES, permissions_1.default.SYSCONSOLE_WRITE_USERMANAGEMENT_SYSTEM_ROLES],
103
+ [exports.RESOURCE_KEYS.SYSTEM_ATTRIBUTES.USER_ATTRIBUTES]: [permissions_1.default.SYSCONSOLE_READ_USERMANAGEMENT_USERS, permissions_1.default.SYSCONSOLE_WRITE_USERMANAGEMENT_USERS],
104
+ [exports.RESOURCE_KEYS.SYSTEM_ATTRIBUTES.ATTRIBUTE_BASED_ACCESS_CONTROL]: [permissions_1.default.SYSCONSOLE_READ_USERMANAGEMENT_SYSTEM_ROLES, permissions_1.default.SYSCONSOLE_WRITE_USERMANAGEMENT_SYSTEM_ROLES],
99
105
  [exports.RESOURCE_KEYS.SITE.CUSTOMIZATION]: [permissions_1.default.SYSCONSOLE_READ_SITE_CUSTOMIZATION, permissions_1.default.SYSCONSOLE_WRITE_SITE_CUSTOMIZATION],
100
106
  [exports.RESOURCE_KEYS.SITE.LOCALIZATION]: [permissions_1.default.SYSCONSOLE_READ_SITE_LOCALIZATION, permissions_1.default.SYSCONSOLE_WRITE_SITE_LOCALIZATION],
101
107
  [exports.RESOURCE_KEYS.SITE.USERS_AND_TEAMS]: [permissions_1.default.SYSCONSOLE_READ_SITE_USERS_AND_TEAMS, permissions_1.default.SYSCONSOLE_WRITE_SITE_USERS_AND_TEAMS],
@@ -1,3 +1,4 @@
1
+ import type { AccessControlPolicy } from '@mattermost/types/access_control';
1
2
  import type { AnalyticsRow, AnalyticsState } from '@mattermost/types/admin';
2
3
  import type { Audit } from '@mattermost/types/audits';
3
4
  import type { Compliance } from '@mattermost/types/compliance';
@@ -27,5 +28,7 @@ declare const _default: import("redux").Reducer<import("redux").CombinedState<{
27
28
  dataRetentionCustomPolicies: IDMappedObjects<DataRetentionCustomPolicy>;
28
29
  dataRetentionCustomPoliciesCount: any;
29
30
  prevTrialLicense: any;
31
+ accessControlPolicies: IDMappedObjects<AccessControlPolicy>;
32
+ channelsForAccessControlPolicy: any;
30
33
  }>, import("redux").AnyAction>;
31
34
  export default _default;
@@ -572,6 +572,62 @@ function dataRetentionCustomPoliciesCount(state = 0, action) {
572
572
  return state;
573
573
  }
574
574
  }
575
+ function accessControlPolicies(state = {}, action) {
576
+ switch (action.type) {
577
+ case action_types_1.AdminTypes.CREATE_ACCESS_CONTROL_POLICY_SUCCESS:
578
+ case action_types_1.AdminTypes.RECEIVED_ACCESS_CONTROL_POLICY:
579
+ return {
580
+ ...state,
581
+ [action.data.id]: action.data,
582
+ };
583
+ case action_types_1.AdminTypes.RECEIVED_ACCESS_CONTROL_POLICIES: {
584
+ const nextState = {};
585
+ for (const policy of action.data) {
586
+ nextState[policy.id] = policy;
587
+ }
588
+ return nextState;
589
+ }
590
+ case action_types_1.AdminTypes.DELETE_ACCESS_CONTROL_POLICY_SUCCESS: {
591
+ const nextState = { ...state };
592
+ Reflect.deleteProperty(nextState, action.data.id);
593
+ return nextState;
594
+ }
595
+ case action_types_1.AdminTypes.RECEIVED_ACCESS_CONTROL_POLICIES_SEARCH: {
596
+ const nextState = { ...state };
597
+ for (const policy of action.data) {
598
+ nextState[policy.id] = policy;
599
+ }
600
+ return nextState;
601
+ }
602
+ case action_types_1.UserTypes.LOGOUT_SUCCESS:
603
+ return {};
604
+ default:
605
+ return state;
606
+ }
607
+ }
608
+ function channelsForAccessControlPolicy(state = {}, action) {
609
+ switch (action.type) {
610
+ case action_types_1.AdminTypes.RECEIVED_ACCESS_CONTROL_CHILD_POLICIES:
611
+ if (action.data) {
612
+ return { ...state, ...action.data };
613
+ }
614
+ return state;
615
+ case action_types_1.AdminTypes.ASSIGN_CHANNELS_TO_ACCESS_CONTROL_POLICY_SUCCESS:
616
+ return {
617
+ ...state,
618
+ [action.data.policyId]: action.data.channelIds,
619
+ };
620
+ case action_types_1.AdminTypes.UNASSIGN_CHANNELS_FROM_ACCESS_CONTROL_POLICY_SUCCESS:
621
+ return {
622
+ ...state,
623
+ [action.data.policyId]: action.data.channelIds,
624
+ };
625
+ case action_types_1.UserTypes.LOGOUT_SUCCESS:
626
+ return {};
627
+ default:
628
+ return state;
629
+ }
630
+ }
575
631
  exports.default = (0, redux_1.combineReducers)({
576
632
  // array of LogObjects each representing a log entry (JSON)
577
633
  logs,
@@ -614,4 +670,8 @@ exports.default = (0, redux_1.combineReducers)({
614
670
  dataRetentionCustomPoliciesCount,
615
671
  // the last trial license the server used.
616
672
  prevTrialLicense,
673
+ // object with policy ids as keys and objects representing the policies as values
674
+ accessControlPolicies,
675
+ // object with policy ids as keys and arrays of channel ids as values
676
+ channelsForAccessControlPolicy,
617
677
  });
@@ -110,6 +110,8 @@ declare const _default: import("redux").Reducer<import("redux").CombinedState<{
110
110
  dataRetentionCustomPolicies: import("@mattermost/types/utilities").IDMappedObjects<import("@mattermost/types/data_retention").DataRetentionCustomPolicy>;
111
111
  dataRetentionCustomPoliciesCount: any;
112
112
  prevTrialLicense: any;
113
+ accessControlPolicies: import("@mattermost/types/utilities").IDMappedObjects<import("@mattermost/types/access_control").AccessControlPolicy>;
114
+ channelsForAccessControlPolicy: any;
113
115
  }>;
114
116
  jobs: import("redux").CombinedState<{
115
117
  jobs: import("@mattermost/types/utilities").IDMappedObjects<import("@mattermost/types/jobs").Job>;
@@ -196,6 +196,24 @@ function profiles(state = {}, action) {
196
196
  const profileAttributes = { ...existingProfile.custom_profile_attributes, ...customAttributeValues };
197
197
  return receiveUserProfile(state, { ...existingProfile, custom_profile_attributes: profileAttributes });
198
198
  }
199
+ case action_types_1.UserTypes.CLEAR_CPA_VALUES: {
200
+ const { fieldId } = action.data;
201
+ return Object.values(state).reduce((nextState, profile) => {
202
+ // Only modify profiles that have this field value
203
+ if (profile.custom_profile_attributes && profile.custom_profile_attributes[fieldId] !== undefined) {
204
+ const newAttributes = { ...profile.custom_profile_attributes };
205
+ delete newAttributes[fieldId];
206
+ nextState[profile.id] = {
207
+ ...profile,
208
+ custom_profile_attributes: newAttributes,
209
+ };
210
+ }
211
+ else {
212
+ nextState[profile.id] = profile;
213
+ }
214
+ return nextState;
215
+ }, {});
216
+ }
199
217
  case action_types_1.UserTypes.RECEIVED_PROFILES_LIST: {
200
218
  const users = action.data;
201
219
  return users.reduce(receiveUserProfile, state);
@@ -112,6 +112,8 @@ declare const _default: {
112
112
  dataRetentionCustomPolicies: import("@mattermost/types/utilities").IDMappedObjects<import("@mattermost/types/data_retention").DataRetentionCustomPolicy>;
113
113
  dataRetentionCustomPoliciesCount: any;
114
114
  prevTrialLicense: any;
115
+ accessControlPolicies: import("@mattermost/types/utilities").IDMappedObjects<import("@mattermost/types/access_control").AccessControlPolicy>;
116
+ channelsForAccessControlPolicy: any;
115
117
  }>;
116
118
  jobs: import("redux").CombinedState<{
117
119
  jobs: import("@mattermost/types/utilities").IDMappedObjects<import("@mattermost/types/jobs").Job>;
@@ -3,30 +3,10 @@
3
3
  // See LICENSE.txt for license information.
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.createSelector = void 0;
6
- exports.generateId = generateId;
7
6
  exports.defaultMemoize = defaultMemoize;
8
7
  exports.createSelectorCreator = createSelectorCreator;
9
8
  exports.createStructuredSelector = createStructuredSelector;
10
- exports.getSortedTrackedSelectors = getSortedTrackedSelectors;
11
9
  /* eslint-disable */
12
- // Generates a RFC-4122 version 4 compliant globally unique identifier.
13
- function generateId() {
14
- // implementation taken from http://stackoverflow.com/a/2117523
15
- let id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
16
- id = id.replace(/[xy]/g, (c) => {
17
- const r = Math.floor(Math.random() * 16);
18
- let v;
19
- if (c === 'x') {
20
- v = r;
21
- }
22
- else {
23
- // eslint-disable-next-line no-mixed-operators
24
- v = r & 0x3 | 0x8;
25
- }
26
- return v.toString(16);
27
- });
28
- return id;
29
- }
30
10
  function defaultEqualityCheck(a, b) {
31
11
  return a === b;
32
12
  }
@@ -43,7 +23,7 @@ function areArgumentsShallowlyEqual(equalityCheck, prev, next) {
43
23
  }
44
24
  return true;
45
25
  }
46
- function defaultMemoize(func, measure, equalityCheck = defaultEqualityCheck) {
26
+ function defaultMemoize(func, equalityCheck = defaultEqualityCheck) {
47
27
  let lastArgs = null;
48
28
  let lastResult = null;
49
29
  // we reference arguments instead of spreading them for performance reasons
@@ -52,9 +32,6 @@ function defaultMemoize(func, measure, equalityCheck = defaultEqualityCheck) {
52
32
  // apply arguments instead of spreading for performance.
53
33
  lastResult = func.apply(null, arguments);
54
34
  }
55
- if (measure) {
56
- measure();
57
- }
58
35
  lastArgs = arguments;
59
36
  return lastResult;
60
37
  };
@@ -68,20 +45,14 @@ function getDependencies(funcs) {
68
45
  }
69
46
  return dependencies;
70
47
  }
71
- const trackedSelectors = {};
72
48
  function createSelectorCreator(memoize, ...memoizeOptions) {
73
49
  return (name, ...funcs) => {
74
- const id = generateId();
75
- let recomputations = 0;
76
- let calls = 0;
77
50
  const resultFunc = funcs.pop();
78
51
  const dependencies = getDependencies(funcs);
79
52
  const memoizedResultFunc = memoize(function () {
80
- recomputations++;
81
- trackedSelectors[id].recomputations++;
82
53
  // apply arguments instead of spreading for performance.
83
54
  return resultFunc?.apply(null, arguments);
84
- }, null, ...memoizeOptions);
55
+ }, ...memoizeOptions);
85
56
  // If a selector is called with the exact same arguments we don't need to traverse our dependencies again.
86
57
  const selector = memoize(function () {
87
58
  const params = [];
@@ -92,20 +63,9 @@ function createSelectorCreator(memoize, ...memoizeOptions) {
92
63
  }
93
64
  // apply arguments instead of spreading for performance.
94
65
  return memoizedResultFunc.apply(null, params);
95
- }, () => {
96
- calls++;
97
- trackedSelectors[id].calls++;
98
66
  });
99
67
  selector.resultFunc = resultFunc;
100
68
  selector.dependencies = dependencies;
101
- selector.recomputations = () => recomputations;
102
- selector.resetRecomputations = () => recomputations = 0;
103
- trackedSelectors[id] = {
104
- id,
105
- name,
106
- calls: 0,
107
- recomputations: 0,
108
- };
109
69
  return selector;
110
70
  };
111
71
  }
@@ -123,43 +83,3 @@ function createStructuredSelector(selectors, selectorCreator = exports.createSel
123
83
  }, {});
124
84
  });
125
85
  }
126
- // resetTrackedSelectors resets all the measurements for memoization effectiveness.
127
- function resetTrackedSelectors() {
128
- Object.values(trackedSelectors).forEach((selector) => {
129
- selector.calls = 0;
130
- selector.recomputations = 0;
131
- });
132
- }
133
- // getSortedTrackedSelectors returns an array, sorted by effectivness, containing mesaurement data on all tracked selectors.
134
- function getSortedTrackedSelectors() {
135
- let selectors = Object.values(trackedSelectors);
136
- // Filter out any selector not called
137
- selectors = selectors.filter(selector => selector.calls > 0);
138
- const selectorsData = selectors.map((selector) => ({ name: selector.name, effectiveness: effectiveness(selector), recomputations: selector.recomputations, calls: selector.calls }));
139
- selectorsData.sort((a, b) => {
140
- // Sort effectiveness ascending
141
- if (a.effectiveness !== b.effectiveness) {
142
- return a.effectiveness - b.effectiveness;
143
- }
144
- // And everything else descending
145
- if (a.recomputations !== b.recomputations) {
146
- return b.recomputations - a.recomputations;
147
- }
148
- if (a.calls !== b.calls) {
149
- return b.calls - a.calls;
150
- }
151
- return a.name.localeCompare(b.name);
152
- });
153
- return selectorsData;
154
- }
155
- function effectiveness(selector) {
156
- return 100 - ((selector.recomputations / selector.calls) * 100);
157
- }
158
- // dumpTrackedSelectorsStatistics prints to console a table containing the measurement data on all tracked selectors.
159
- function dumpTrackedSelectorsStatistics() {
160
- const selectors = getSortedTrackedSelectors();
161
- console.table(selectors); //eslint-disable-line no-console
162
- }
163
- window.dumpTrackedSelectorsStatistics = dumpTrackedSelectorsStatistics;
164
- window.resetTrackedSelectors = resetTrackedSelectors;
165
- window.getSortedTrackedSelectors = getSortedTrackedSelectors;
@@ -0,0 +1,8 @@
1
+ import type { Channel, ChannelWithTeamData, ChannelSearchOpts } from '@mattermost/types/channels';
2
+ import type { GlobalState } from '@mattermost/types/store';
3
+ export declare function getAccessControlPolicy(state: GlobalState, id: string): import("@mattermost/types/access_control").AccessControlPolicy;
4
+ export declare const getChannelIdsForAccessControlPolicy: (state: GlobalState, parentId: string) => string[];
5
+ export declare function makeGetChannelsInAccessControlPolicy(): (b: GlobalState, a: {
6
+ policyId: string;
7
+ }) => ChannelWithTeamData[];
8
+ export declare function searchChannelsInheritsPolicy(state: GlobalState, policyId: string, term: string, filters: ChannelSearchOpts): Channel[];
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
+ // See LICENSE.txt for license information.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.getChannelIdsForAccessControlPolicy = void 0;
6
+ exports.getAccessControlPolicy = getAccessControlPolicy;
7
+ exports.makeGetChannelsInAccessControlPolicy = makeGetChannelsInAccessControlPolicy;
8
+ exports.searchChannelsInheritsPolicy = searchChannelsInheritsPolicy;
9
+ const channel_utils_1 = require("mattermost-redux/utils/channel_utils");
10
+ const channels_1 = require("./channels");
11
+ const create_selector_1 = require("../create_selector");
12
+ function getAccessControlPolicy(state, id) {
13
+ return state.entities.admin.accessControlPolicies[id];
14
+ }
15
+ exports.getChannelIdsForAccessControlPolicy = (0, create_selector_1.createSelector)('getChannelIdsForAccessControlPolicy', (state, parentId) => state.entities.admin.channelsForAccessControlPolicy[parentId], (channelIds) => (Array.isArray(channelIds) ? channelIds : []));
16
+ function makeGetChannelsInAccessControlPolicy() {
17
+ return (0, create_selector_1.createSelector)('getChannelsInAccessControlPolicy', (state) => state.entities.channels.channels, (state, props) => (0, exports.getChannelIdsForAccessControlPolicy)(state, props.policyId), (state) => state.entities.teams.teams, (channels, ids, teams) => {
18
+ if (!ids) {
19
+ return [];
20
+ }
21
+ const policyChannels = [];
22
+ ids.forEach((channelId) => {
23
+ const channel = channels[channelId];
24
+ if (channel) {
25
+ const team = teams[channel.team_id] || {};
26
+ policyChannels.push({
27
+ ...channel,
28
+ team_id: channel.team_id,
29
+ team_display_name: team.display_name || '',
30
+ team_name: team.name || '',
31
+ team_update_at: team.update_at || 0,
32
+ });
33
+ }
34
+ });
35
+ return policyChannels;
36
+ });
37
+ }
38
+ function searchChannelsInheritsPolicy(state, policyId, term, filters) {
39
+ const channelsInPolicy = makeGetChannelsInAccessControlPolicy();
40
+ const channelArray = channelsInPolicy(state, { policyId });
41
+ let channels = (0, channels_1.filterChannelList)(channelArray, filters);
42
+ channels = (0, channel_utils_1.filterChannelsMatchingTerm)(channels, term);
43
+ return channels;
44
+ }
@@ -1,2 +1,3 @@
1
1
  import type { GlobalState } from '@mattermost/types/store';
2
+ export declare const selectChannelBannerEnabled: (state: GlobalState) => boolean;
2
3
  export declare const selectShowChannelBanner: (state: GlobalState, channelId: string) => boolean;
@@ -2,17 +2,24 @@
2
2
  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
3
  // See LICENSE.txt for license information.
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.selectShowChannelBanner = void 0;
5
+ exports.selectShowChannelBanner = exports.selectChannelBannerEnabled = void 0;
6
6
  const channels_1 = require("@mattermost/types/channels");
7
7
  const constants_1 = require("mattermost-redux/constants");
8
8
  const channels_2 = require("mattermost-redux/selectors/entities/channels");
9
9
  const general_1 = require("mattermost-redux/selectors/entities/general");
10
- const selectShowChannelBanner = (state, channelId) => {
10
+ const selectChannelBannerEnabled = (state) => {
11
11
  const license = (0, general_1.getLicense)(state);
12
- const isPremiumLicense = license?.SkuShortName === constants_1.General.SKUPremium;
12
+ return license?.SkuShortName === constants_1.General.SKUEnterpriseAdvanced;
13
+ };
14
+ exports.selectChannelBannerEnabled = selectChannelBannerEnabled;
15
+ const selectShowChannelBanner = (state, channelId) => {
16
+ const enabled = (0, exports.selectChannelBannerEnabled)(state);
17
+ if (!enabled) {
18
+ return false;
19
+ }
13
20
  const channelBannerInfo = (0, channels_2.getChannelBanner)(state, channelId);
14
21
  const channel = (0, channels_2.getChannel)(state, channelId);
15
22
  const isValidChannelType = Boolean(channel && (channel.type === constants_1.General.OPEN_CHANNEL || channel.type === constants_1.General.PRIVATE_CHANNEL));
16
- return isPremiumLicense && isValidChannelType && (0, channels_1.channelBannerEnabled)(channelBannerInfo);
23
+ return isValidChannelType && (0, channels_1.channelBannerEnabled)(channelBannerInfo);
17
24
  };
18
25
  exports.selectShowChannelBanner = selectShowChannelBanner;
@@ -0,0 +1,3 @@
1
+ import type { GlobalState } from '@mattermost/types/store';
2
+ export declare function getReportAProblemLink(state: GlobalState): string;
3
+ export declare const getSystemInfoMailtoLink: import("mattermost-redux/selectors/create_selector").OutputParametricSelector<GlobalState, string | undefined, string, (res1: string, res2: string, res3: string | undefined, res4: string | undefined, res5: string | undefined, res6: string | undefined) => string>;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
+ // See LICENSE.txt for license information.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.getSystemInfoMailtoLink = void 0;
6
+ exports.getReportAProblemLink = getReportAProblemLink;
7
+ const create_selector_1 = require("mattermost-redux/selectors/create_selector");
8
+ const browser_info_1 = require("mattermost-redux/utils/browser_info");
9
+ const general_1 = require("./general");
10
+ const teams_1 = require("./teams");
11
+ const users_1 = require("./users");
12
+ function getReportAProblemLink(state) {
13
+ const config = (0, general_1.getConfig)(state);
14
+ const type = config.ReportAProblemType;
15
+ switch (type) {
16
+ case 'email':
17
+ return (0, exports.getSystemInfoMailtoLink)(state, config.ReportAProblemMail);
18
+ case 'link':
19
+ if (config.ReportAProblemLink) {
20
+ return config.ReportAProblemLink;
21
+ }
22
+ // falls through
23
+ case 'default': {
24
+ const isLicensed = (0, general_1.getLicense)(state).IsLicensed === 'true';
25
+ if (isLicensed) {
26
+ return 'https://mattermost.com/pl/report_a_problem_licensed';
27
+ }
28
+ return 'https://mattermost.com/pl/report_a_problem_unlicensed';
29
+ }
30
+ }
31
+ return '';
32
+ }
33
+ exports.getSystemInfoMailtoLink = (0, create_selector_1.createSelector)('getSystemInfoMailtoLink', users_1.getCurrentUserId, teams_1.getCurrentTeamId, (state) => (0, general_1.getConfig)(state).Version, (state) => (0, general_1.getConfig)(state).BuildNumber, (state) => (0, general_1.getConfig)(state).SiteName, (state, supportEmail) => supportEmail, (currentUserId, currentTeamId, version, buildNumber, siteName, supportEmail) => {
34
+ const { browser, browserVersion } = (0, browser_info_1.getBrowserInfo)();
35
+ const platformName = (0, browser_info_1.getPlatformInfo)();
36
+ const subject = `Problem with ${siteName || 'Mattermost'} app`;
37
+ const body = `
38
+ System Information:
39
+ - User ID: ${currentUserId}
40
+ - Team ID: ${currentTeamId}
41
+ - Server Version: ${version} (${buildNumber})
42
+ - Browser: ${browser} ${browserVersion}
43
+ - Platform: ${platformName}
44
+ `.trim();
45
+ return `mailto:${supportEmail || ''}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
46
+ });
@@ -117,6 +117,8 @@ const state = {
117
117
  dataRetentionCustomPolicies: {},
118
118
  dataRetentionCustomPoliciesCount: 0,
119
119
  prevTrialLicense: {},
120
+ accessControlPolicies: {},
121
+ channelsForAccessControlPolicy: {},
120
122
  },
121
123
  jobs: {
122
124
  jobs: {},
@@ -0,0 +1,5 @@
1
+ export declare function getBrowserInfo(): {
2
+ browser: string;
3
+ browserVersion: string;
4
+ };
5
+ export declare function getPlatformInfo(): string;
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
+ // See LICENSE.txt for license information.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.getBrowserInfo = getBrowserInfo;
6
+ exports.getPlatformInfo = getPlatformInfo;
7
+ function getBrowserInfo() {
8
+ const userAgent = window.navigator.userAgent.toLowerCase();
9
+ let browser = 'Unknown';
10
+ let browserVersion = 'Unknown';
11
+ // Check if it's Mattermost Desktop App first
12
+ if (userAgent.includes('mattermost')) {
13
+ browser = 'Mattermost Desktop App';
14
+ const match = userAgent.match(/mattermost\/(\d+(\.\d+)*)/i);
15
+ if (match && match[1]) {
16
+ browserVersion = match[1];
17
+ }
18
+ return { browser, browserVersion };
19
+ }
20
+ // Simple browser detection - order matters!
21
+ if (userAgent.includes('edge/')) {
22
+ browser = 'Edge';
23
+ }
24
+ else if (userAgent.includes('edg/')) {
25
+ browser = 'Edge Chromium';
26
+ }
27
+ else if (userAgent.includes('chrome/')) {
28
+ if (userAgent.includes('opr/')) {
29
+ browser = 'Opera';
30
+ }
31
+ else {
32
+ browser = 'Chrome';
33
+ }
34
+ }
35
+ else if (userAgent.includes('safari/') && userAgent.includes('version/')) {
36
+ browser = 'Safari';
37
+ }
38
+ else if (userAgent.includes('firefox/')) {
39
+ browser = 'Firefox';
40
+ }
41
+ // Get browser version
42
+ let match;
43
+ if (browser === 'Edge') {
44
+ match = userAgent.match(/edge\/(\d+)/i);
45
+ }
46
+ else if (browser === 'Edge Chromium') {
47
+ match = userAgent.match(/edg\/(\d+)/i);
48
+ }
49
+ else if (browser === 'Opera') {
50
+ match = userAgent.match(/opr\/(\d+)/i);
51
+ }
52
+ else if (browser === 'Safari') {
53
+ match = userAgent.match(/version\/(\d+)/i);
54
+ }
55
+ else {
56
+ match = userAgent.match(/(firefox|chrome)\/(\d+)/i);
57
+ if (match) {
58
+ match[1] = match[2]; // Align with other matches where version is in group 1
59
+ }
60
+ }
61
+ if (match && match[1]) {
62
+ browserVersion = match[1];
63
+ }
64
+ return { browser, browserVersion };
65
+ }
66
+ function getPlatformInfo() {
67
+ // Casting to undefined in case it is deprecated in any browser
68
+ const platform = window.navigator.platform;
69
+ const userAgent = window.navigator.userAgent.toLowerCase();
70
+ let platformName = 'Unknown';
71
+ // First try using platform
72
+ if (platform) {
73
+ if (platform.toLowerCase().includes('win')) {
74
+ platformName = 'Windows';
75
+ }
76
+ else if (platform.toLowerCase().includes('mac')) {
77
+ platformName = 'MacOS';
78
+ }
79
+ else if (platform.toLowerCase().includes('linux')) {
80
+ platformName = 'Linux';
81
+ }
82
+ }
83
+ // Fallback to userAgent if platform didn't work
84
+ if (platformName === 'Unknown') {
85
+ if (userAgent.includes('windows')) {
86
+ platformName = 'Windows';
87
+ }
88
+ else if (userAgent.includes('mac os x')) {
89
+ platformName = 'MacOS';
90
+ }
91
+ else if (userAgent.includes('linux')) {
92
+ platformName = 'Linux';
93
+ }
94
+ }
95
+ return platformName;
96
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mattermost-redux",
3
- "version": "10.8.0",
3
+ "version": "10.9.0",
4
4
  "description": "Common code (API client, Redux stores, logic, utility functions) for building a Mattermost client",
5
5
  "keywords": [
6
6
  "mattermost"
@@ -39,8 +39,8 @@
39
39
  "directory": "webapp/platform/mattermost-redux"
40
40
  },
41
41
  "dependencies": {
42
- "@mattermost/client": "10.6.0",
43
- "@mattermost/types": "10.6.0",
42
+ "@mattermost/client": "10.9.0",
43
+ "@mattermost/types": "10.9.0",
44
44
  "@redux-devtools/extension": "^3.2.3",
45
45
  "lodash": "^4.17.21",
46
46
  "moment-timezone": "^0.5.38",