mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
Merge branch 'master' into MM-28014_Improve_Channel_Intros
This commit is contained in:
commit
c11d1e59e3
@ -433,7 +433,7 @@ func addUserToGroupSyncables(c *Context, w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
if user.AuthService != model.UserAuthServiceLdap {
|
||||
if user.AuthService != model.UserAuthServiceLdap && (user.AuthService != model.UserAuthServiceSaml || !*c.App.Config().SamlSettings.EnableSyncWithLdap) {
|
||||
c.Err = model.NewAppError("addUserToGroupSyncables", "api.user.add_user_to_group_syncables.not_ldap_user.app_error", nil, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
@ -309,4 +309,28 @@ func TestAddUserToGroupSyncables(t *testing.T) {
|
||||
resp, err = th.SystemAdminClient.AddUserToGroupSyncables(context.Background(), user.Id)
|
||||
require.NoError(t, err)
|
||||
CheckOKStatus(t, resp)
|
||||
|
||||
t.Run("should sync SAML users when SamlSettings.EnableSyncWithLdap is true", func(t *testing.T) {
|
||||
id = model.NewId()
|
||||
user = &model.User{
|
||||
Email: "test123@localhost",
|
||||
Username: model.NewId(),
|
||||
AuthData: &id,
|
||||
AuthService: model.UserAuthServiceSaml,
|
||||
}
|
||||
user, err = th.App.Srv().Store().User().Save(th.Context, user)
|
||||
require.NoError(t, err)
|
||||
|
||||
resp, err = th.Client.AddUserToGroupSyncables(context.Background(), user.Id)
|
||||
require.Error(t, err)
|
||||
CheckForbiddenStatus(t, resp)
|
||||
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.SamlSettings.EnableSyncWithLdap = true
|
||||
})
|
||||
|
||||
resp, err = th.SystemAdminClient.AddUserToGroupSyncables(context.Background(), user.Id)
|
||||
require.NoError(t, err)
|
||||
CheckOKStatus(t, resp)
|
||||
})
|
||||
}
|
||||
|
@ -164,6 +164,19 @@ describe('draft actions', () => {
|
||||
|
||||
describe('removeDraft', () => {
|
||||
it('calls setGlobalItem action correctly', async () => {
|
||||
store = mockStore({
|
||||
...initialState,
|
||||
entities: {
|
||||
...initialState.entities,
|
||||
general: {
|
||||
...initialState.entities.general,
|
||||
config: {
|
||||
...initialState.entities.general.config,
|
||||
AllowSyncedDrafts: 'false',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
await store.dispatch(removeDraft(key, channelId));
|
||||
|
||||
const testStore = mockStore(initialState);
|
||||
|
@ -105,9 +105,6 @@ export function removeDraft(key: string, channelId: string, rootId = ''): Action
|
||||
// set draft to empty to re-render the component
|
||||
await dispatch(setGlobalItem(key, {message: '', fileInfos: [], uploadsInProgress: []}));
|
||||
|
||||
// remove draft from storage
|
||||
await dispatch(removeGlobalItem(key));
|
||||
|
||||
if (syncedDraftsAreAllowedAndEnabled(state)) {
|
||||
const connectionId = getConnectionId(getState());
|
||||
|
||||
@ -119,6 +116,9 @@ export function removeDraft(key: string, channelId: string, rootId = ''): Action
|
||||
error,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// only remove draft from storage for local drafts
|
||||
await dispatch(removeGlobalItem(key));
|
||||
}
|
||||
return {data: true};
|
||||
};
|
||||
|
@ -12,7 +12,8 @@ import type {UserProfile} from '@mattermost/types/users';
|
||||
import {updateUserActive} from 'mattermost-redux/actions/users';
|
||||
import {Permissions} from 'mattermost-redux/constants';
|
||||
import General from 'mattermost-redux/constants/general';
|
||||
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
|
||||
import {getConfig} from 'mattermost-redux/selectors/entities/admin';
|
||||
import {getLicense} from 'mattermost-redux/selectors/entities/general';
|
||||
import {isSystemAdmin, isGuest} from 'mattermost-redux/utils/user_utils';
|
||||
|
||||
import {adminResetMfa} from 'actions/admin_actions';
|
||||
@ -208,7 +209,7 @@ export function SystemUsersListAction({user, currentUser, tableId, rowIndex, onE
|
||||
}}
|
||||
/>
|
||||
|
||||
{config.EnableUserAccessTokens === 'true' &&
|
||||
{config.ServiceSettings?.EnableUserAccessTokens &&
|
||||
<Menu.Item
|
||||
id={`${menuItemIdPrefix}-manageTokens`}
|
||||
labels={
|
||||
@ -244,7 +245,7 @@ export function SystemUsersListAction({user, currentUser, tableId, rowIndex, onE
|
||||
}}
|
||||
/>}
|
||||
|
||||
{user.mfa_active && config.EnableMultifactorAuthentication &&
|
||||
{user.mfa_active && config.ServiceSettings?.EnableMultifactorAuthentication &&
|
||||
<Menu.Item
|
||||
id={`${menuItemIdPrefix}-removeMFA`}
|
||||
labels={
|
||||
@ -260,7 +261,7 @@ export function SystemUsersListAction({user, currentUser, tableId, rowIndex, onE
|
||||
}}
|
||||
/>}
|
||||
|
||||
{Boolean(user.auth_service) && config.ExperimentalEnableAuthenticationTransfer === 'true' &&
|
||||
{Boolean(user.auth_service) && config.ServiceSettings?.ExperimentalEnableAuthenticationTransfer &&
|
||||
<Menu.Item
|
||||
id={`${menuItemIdPrefix}-switchToEmailPassword`}
|
||||
labels={
|
||||
@ -323,7 +324,7 @@ export function SystemUsersListAction({user, currentUser, tableId, rowIndex, onE
|
||||
}));
|
||||
}}
|
||||
/>}
|
||||
{!isGuest(user.roles) && user.id !== currentUser.id && isLicensed && config.EnableGuestAccounts === 'true' &&
|
||||
{!isGuest(user.roles) && user.id !== currentUser.id && isLicensed && config.GuestAccountsSettings?.Enable &&
|
||||
<Menu.Item
|
||||
id={`${menuItemIdPrefix}-demoteToGuest`}
|
||||
labels={
|
||||
@ -364,7 +365,7 @@ export function SystemUsersListAction({user, currentUser, tableId, rowIndex, onE
|
||||
/>}
|
||||
</SystemPermissionGate>
|
||||
<SystemPermissionGate permissions={[Permissions.SYSCONSOLE_WRITE_USERMANAGEMENT_GROUPS]}>
|
||||
{user.auth_service === Constants.LDAP_SERVICE &&
|
||||
{(user.auth_service === Constants.LDAP_SERVICE || (user.auth_service === Constants.SAML_SERVICE && config.SamlSettings?.EnableSyncWithLdap)) &&
|
||||
<Menu.Item
|
||||
id={`${menuItemIdPrefix}-resyncUserViaLdapGroups`}
|
||||
labels={
|
||||
|
@ -83,8 +83,10 @@ function ThreadViewerRow({
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id='threading.numReplies'
|
||||
defaultMessage='{replyCount, plural, =0 {Reply} =1 {# reply} other {# replies}}'
|
||||
values={{replyCount}}
|
||||
defaultMessage='{totalReplies, plural, =0 {Reply} =1 {# reply} other {# replies}}'
|
||||
values={{
|
||||
totalReplies: replyCount,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,11 +1,13 @@
|
||||
@import 'utils/module';
|
||||
|
||||
.AdminPanel {
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
border: solid 1px alpha-color($black, 0.1);
|
||||
border-radius: $border-rad;
|
||||
border: solid 1px rgba(var(--center-channel-color-rgb), 0.12);
|
||||
border-radius: var(--radius-s);
|
||||
margin: 2em 0 1em;
|
||||
box-shadow: 0 1px 2px 0 alpha-color($black, 0.5);
|
||||
background-color: var(--center-channel-bg);
|
||||
box-shadow: var(--elevation-1);
|
||||
font-size: 0.95em;
|
||||
|
||||
.AdminPanel__content {
|
||||
@ -35,6 +37,7 @@
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20px;
|
||||
border-radius: var(--radius-s) var(--radius-s) 0 0;
|
||||
background: $white;
|
||||
|
||||
h3 {
|
||||
|
@ -78,6 +78,14 @@
|
||||
--elevation-5: 0 12px 32px 0 rgba(0, 0, 0, 0.12);
|
||||
--elevation-6: 0 20px 32px 0 rgba(0, 0, 0, 0.12);
|
||||
|
||||
//Corner Radius variables
|
||||
--radius-xs: 2px;
|
||||
--radius-s: 4px;
|
||||
--radius-m: 8px;
|
||||
--radius-l: 12px;
|
||||
--radius-xl: 16px;
|
||||
--radius-full: 50%;
|
||||
|
||||
// Global Header variables
|
||||
--global-header-background: var(--sidebar-teambar-bg);
|
||||
--global-header-text: var(--sidebar-header-text-color);
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
.alert {
|
||||
padding: 8px 12px;
|
||||
border-radius: $border-rad;
|
||||
border-radius: var(--radius-s);
|
||||
|
||||
.alert-transparent {
|
||||
border-color: rgba(var(--center-channel-color-rgb), 0.12);
|
||||
|
@ -26,7 +26,7 @@ button {
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
border-radius: var(--radius-full);
|
||||
margin: 0 0 0 40px;
|
||||
background: #f74343;
|
||||
}
|
||||
@ -40,7 +40,7 @@ button {
|
||||
justify-content: center;
|
||||
padding: 0 20px;
|
||||
border: none;
|
||||
border-radius: $border-rad * 2;
|
||||
border-radius: var(--radius-s);
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
gap: 8px;
|
||||
|
@ -16,7 +16,7 @@
|
||||
.btn {
|
||||
height: 4rem;
|
||||
padding: 0 2rem;
|
||||
border-radius: $border-rad * 2;
|
||||
border-radius: var(--radius-s);
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
height: 26px;
|
||||
padding: 0 8px;
|
||||
border-color: #5b6672;
|
||||
border-radius: $border-rad * 2;
|
||||
border-radius: var(--radius-s);
|
||||
background: transparent;
|
||||
color: #5b6672;
|
||||
transition: all 0.15s ease;
|
||||
|
@ -90,8 +90,7 @@
|
||||
width: 350px;
|
||||
flex-direction: column;
|
||||
border: 1px solid;
|
||||
border-radius: $border-rad;
|
||||
border-radius: 4px;
|
||||
border-radius: var(--radius-s);
|
||||
margin-right: 3px;
|
||||
background: var(--center-channel-bg);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
|
||||
|
@ -30,7 +30,7 @@
|
||||
}
|
||||
|
||||
.form-control {
|
||||
border-radius: $border-rad;
|
||||
border-radius: var(--radius-xs);
|
||||
text-align: left;
|
||||
|
||||
&:focus {
|
||||
|
@ -3,7 +3,7 @@
|
||||
.multi-select__container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
min-height: 40px;
|
||||
justify-content: space-between;
|
||||
padding: 0 15px;
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
.popover {
|
||||
padding: 0;
|
||||
border-radius: $border-rad * 2;
|
||||
border-radius: var(--radius-s);
|
||||
background: var(--center-channel-bg);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
|
||||
color: var(--center-channel-color);
|
||||
|
@ -10,7 +10,7 @@
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: $border-rad * 2;
|
||||
border-radius: var(--radius-s);
|
||||
background: rgba(var(--center-channel-color-rgb), 0.4);
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
.modal {
|
||||
.modal-content {
|
||||
border-radius: $border-rad;
|
||||
border-radius: var(--radius-s);
|
||||
box-shadow: 0 0 10px rgba($black, 0.5);
|
||||
}
|
||||
|
||||
|
@ -491,7 +491,7 @@
|
||||
height: 34px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: $border-rad;
|
||||
border-radius: var(--radius-s);
|
||||
margin: 0 10px 0 0;
|
||||
text-decoration: none;
|
||||
transition: all 0.15s ease;
|
||||
|
@ -26,7 +26,6 @@ $announcement-bar-height: 40px;
|
||||
$backstage-bar-height: 43px;
|
||||
|
||||
// Random variables
|
||||
$border-rad: 2px;
|
||||
$emoji-per-row: 9; // needs to match variable `EMOJI_PER_ROW` in emoji_picker.jsx
|
||||
|
||||
// Transition timing defaults
|
||||
|
2
webapp/package-lock.json
generated
2
webapp/package-lock.json
generated
@ -46,7 +46,7 @@
|
||||
"webpack-dev-server": "4.13.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.10.0",
|
||||
"node": ">=18.10.0",
|
||||
"npm": "^9.0.0 || ^10.0.0"
|
||||
}
|
||||
},
|
||||
|
@ -2,7 +2,7 @@
|
||||
"name": "@mattermost/webapp",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": "^18.10.0",
|
||||
"node": ">=18.10.0",
|
||||
"npm": "^9.0.0 || ^10.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
Loading…
Reference in New Issue
Block a user