diff --git a/packages/backend/src/db/migrations/20240822111546_add_prevent_users_from_updating_their_profiles_user_management_in_config.js b/packages/backend/src/db/migrations/20240822111546_add_prevent_users_from_updating_their_profiles_user_management_in_config.js
new file mode 100644
index 00000000..7d21d070
--- /dev/null
+++ b/packages/backend/src/db/migrations/20240822111546_add_prevent_users_from_updating_their_profiles_user_management_in_config.js
@@ -0,0 +1,12 @@
+export async function up(knex) {
+ await knex('config').insert({
+ key: 'userManagement.preventUsersFromUpdatingTheirProfile',
+ value: {
+ data: false
+ }
+ });
+};
+
+export async function down(knex) {
+ await knex('config').where({ key: 'userManagement.preventUsersFromUpdatingTheirProfile' }).delete();
+};
diff --git a/packages/web/src/components/AddAppConnection/index.jsx b/packages/web/src/components/AddAppConnection/index.jsx
index f253831b..4cbd41be 100644
--- a/packages/web/src/components/AddAppConnection/index.jsx
+++ b/packages/web/src/components/AddAppConnection/index.jsx
@@ -7,6 +7,7 @@ import DialogContentText from '@mui/material/DialogContentText';
import DialogTitle from '@mui/material/DialogTitle';
import * as React from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
+import { useQueryClient } from '@tanstack/react-query';
import { AppPropType } from 'propTypes/propTypes';
import AppAuthClientsDialog from 'components/AppAuthClientsDialog/index.ee';
@@ -17,7 +18,6 @@ import useFormatMessage from 'hooks/useFormatMessage';
import { generateExternalLink } from 'helpers/translationValues';
import { Form } from './style';
import useAppAuth from 'hooks/useAppAuth';
-import { useQueryClient } from '@tanstack/react-query';
function AddAppConnection(props) {
const { application, connectionId, onClose } = props;
diff --git a/packages/web/src/components/LoginForm/index.jsx b/packages/web/src/components/LoginForm/index.jsx
index 3611417e..bb4b3e94 100644
--- a/packages/web/src/components/LoginForm/index.jsx
+++ b/packages/web/src/components/LoginForm/index.jsx
@@ -12,6 +12,7 @@ import TextField from 'components/TextField';
import useFormatMessage from 'hooks/useFormatMessage';
import useCreateAccessToken from 'hooks/useCreateAccessToken';
import useEnqueueSnackbar from 'hooks/useEnqueueSnackbar';
+import usePreventUsersFromUpdatingTheirProfile from 'hooks/usePreventUsersFromUpdatingTheirProfile';
function LoginForm() {
const isCloud = useCloud();
@@ -19,6 +20,7 @@ function LoginForm() {
const formatMessage = useFormatMessage();
const enqueueSnackbar = useEnqueueSnackbar();
const authentication = useAuthentication();
+ const preventUsersFromUpdatingTheirProfile = usePreventUsersFromUpdatingTheirProfile();
const { mutateAsync: createAccessToken, isPending: loading } =
useCreateAccessToken();
@@ -84,7 +86,7 @@ function LoginForm() {
sx={{ mb: 1 }}
/>
- {isCloud && (
+ {isCloud && !preventUsersFromUpdatingTheirProfile && (
{
+ try {
+ await updateConfig({
+ variables: {
+ input: {
+ 'userManagement.preventUsersFromUpdatingTheirProfile': values.userManagement.preventUsersFromUpdatingTheirProfile,
+ },
+ },
+ });
+
+ await queryClient.invalidateQueries({
+ queryKey: ['automatisch', 'config'],
+ });
+
+ enqueueSnackbar(formatMessage('authenticationConfig.successfullySaved'), {
+ variant: 'success',
+ SnackbarProps: {
+ 'data-test': 'snackbar-update-role-mappings-success',
+ },
+ });
+ } catch (error) {
+ throw new Error('Failed while saving!');
+ }
+ };
+
+ if (isAutomatischConfigLoading) {
+ return null;
+ }
+
+ return (
+ <>
+
+ {formatMessage('authenticationConfig.title')}
+
+
+
+ >
+ );
+}
+
+AuthenticationConfig.propTypes = {
+};
+
+export default AuthenticationConfig;
diff --git a/packages/web/src/pages/Authentication/RoleMappings.jsx b/packages/web/src/pages/Authentication/RoleMappings.jsx
index a2605eef..812f24a0 100644
--- a/packages/web/src/pages/Authentication/RoleMappings.jsx
+++ b/packages/web/src/pages/Authentication/RoleMappings.jsx
@@ -1,7 +1,6 @@
import PropTypes from 'prop-types';
import { useMutation } from '@apollo/client';
import LoadingButton from '@mui/lab/LoadingButton';
-import Divider from '@mui/material/Divider';
import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import useEnqueueSnackbar from 'hooks/useEnqueueSnackbar';
@@ -85,7 +84,6 @@ function RoleMappings({ provider, providerLoading }) {
return (
<>
-
{formatMessage('roleMappingsForm.title')}
diff --git a/packages/web/src/pages/Authentication/SamlConfiguration.jsx b/packages/web/src/pages/Authentication/SamlConfiguration.jsx
index 6a99b6bb..bc8518bd 100644
--- a/packages/web/src/pages/Authentication/SamlConfiguration.jsx
+++ b/packages/web/src/pages/Authentication/SamlConfiguration.jsx
@@ -75,7 +75,7 @@ function SamlConfiguration({ provider, providerLoading }) {
},
});
- enqueueSnackbar(formatMessage('authenticationForm.successfullySaved'), {
+ enqueueSnackbar(formatMessage('samlAuthenticationForm.successfullySaved'), {
variant: 'success',
SnackbarProps: {
'data-test': 'snackbar-save-saml-provider-success',
@@ -98,18 +98,18 @@ function SamlConfiguration({ provider, providerLoading }) {
@@ -126,44 +126,44 @@ function SamlConfiguration({ provider, providerLoading }) {
renderInput={(params) => (
)}
/>
(
)}
loading={isRolesLoading}
@@ -187,7 +187,7 @@ function SamlConfiguration({ provider, providerLoading }) {
sx={{ boxShadow: 2 }}
loading={loading}
>
- {formatMessage('authenticationForm.save')}
+ {formatMessage('samlAuthenticationForm.save')}
diff --git a/packages/web/src/pages/Authentication/index.jsx b/packages/web/src/pages/Authentication/index.jsx
index 7b6e6826..062bb192 100644
--- a/packages/web/src/pages/Authentication/index.jsx
+++ b/packages/web/src/pages/Authentication/index.jsx
@@ -2,11 +2,14 @@ import Grid from '@mui/material/Grid';
import Stack from '@mui/material/Stack';
import PageTitle from 'components/PageTitle';
import Container from 'components/Container';
+import Divider from '@mui/material/Divider';
import useFormatMessage from 'hooks/useFormatMessage';
import useSamlAuthProvider from 'hooks/useSamlAuthProvider';
+import AuthenticationConfig from './AuthenticationConfig';
import SamlConfiguration from './SamlConfiguration';
import RoleMappings from './RoleMappings';
import useAdminSamlAuthProviders from 'hooks/useAdminSamlAuthProviders.ee';
+
function AuthenticationPage() {
const formatMessage = useFormatMessage();
@@ -16,20 +19,37 @@ function AuthenticationPage() {
const { data, isLoading: isProviderLoading } = useSamlAuthProvider({
samlAuthProviderId,
});
+
const provider = data?.data;
return (
-
+
{formatMessage('authenticationPage.title')}
+
+
+
+
+
+
+
+
+
+
+ {formatMessage('samlAuthenticationPage.title')}
+
+
+
+
+
+
diff --git a/packages/web/src/routes.jsx b/packages/web/src/routes.jsx
index 1f634275..872038a7 100644
--- a/packages/web/src/routes.jsx
+++ b/packages/web/src/routes.jsx
@@ -29,12 +29,14 @@ import adminSettingsRoutes from './adminSettingsRoutes';
import Notifications from 'pages/Notifications';
import useAutomatischConfig from 'hooks/useAutomatischConfig';
import useAuthentication from 'hooks/useAuthentication';
+import usePreventUsersFromUpdatingTheirProfile from 'hooks/usePreventUsersFromUpdatingTheirProfile';
import useAutomatischInfo from 'hooks/useAutomatischInfo';
import Installation from 'pages/Installation';
function Routes() {
const { data: automatischInfo, isSuccess } = useAutomatischInfo();
const { data: configData } = useAutomatischConfig();
+ const preventUsersFromUpdatingTheirProfile = usePreventUsersFromUpdatingTheirProfile();
const { isAuthenticated } = useAuthentication();
const config = configData?.data;
@@ -134,14 +136,14 @@ function Routes() {
}
/>
-
}
- />
+ />}