Update
This commit is contained in:
@@ -645,7 +645,7 @@ const seedPermissions = () => {
|
|||||||
label: 'Sicherheitsschlüssel',
|
label: 'Sicherheitsschlüssel',
|
||||||
sortOrder: 3,
|
sortOrder: 3,
|
||||||
defaultLevel: 'none',
|
defaultLevel: 'none',
|
||||||
levels: ['full', 'read', 'none'],
|
levels: ['full', 'none'],
|
||||||
isRequired: 0,
|
isRequired: 0,
|
||||||
dependencies: [
|
dependencies: [
|
||||||
{
|
{
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -34,8 +34,8 @@
|
|||||||
<script defer data-site="YOUR_DOMAIN_HERE" src="https://api.nepcha.com/js/nepcha-analytics.js"></script>
|
<script defer data-site="YOUR_DOMAIN_HERE" src="https://api.nepcha.com/js/nepcha-analytics.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<script type="module" crossorigin src="/assets/index-f91011a0.js"></script>
|
<script type="module" crossorigin src="/assets/index-65b35a5f.js"></script>
|
||||||
<link rel="stylesheet" href="/assets/index-f6cd1c87.css">
|
<link rel="stylesheet" href="/assets/index-328d6adf.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
@@ -119,8 +119,8 @@ export function UserDetails() {
|
|||||||
|
|
||||||
const canEditUsers = Boolean(authUser?.isSuperuser || hasPermission("users-edit", "full"));
|
const canEditUsers = Boolean(authUser?.isSuperuser || hasPermission("users-edit", "full"));
|
||||||
const canReadUsers = Boolean(authUser?.isSuperuser || hasPermission("users-edit", "read"));
|
const canReadUsers = Boolean(authUser?.isSuperuser || hasPermission("users-edit", "read"));
|
||||||
const canViewSecurityPhrase = Boolean(authUser?.isSuperuser || hasPermission("users-security-phrase", "read"));
|
const canManageSecurityPhrase = Boolean(authUser?.isSuperuser || hasPermission("users-security-phrase", "full"));
|
||||||
const canRenewSecurityPhrase = Boolean(authUser?.isSuperuser || hasPermission("users-security-phrase", "full"));
|
const canRenewSecurityPhrase = canManageSecurityPhrase;
|
||||||
|
|
||||||
if (!canReadUsers) {
|
if (!canReadUsers) {
|
||||||
return null;
|
return null;
|
||||||
@@ -393,7 +393,7 @@ export function UserDetails() {
|
|||||||
}, [canEditUsers, user, hasChanges, formValues, showToast, isSuperuserUser]);
|
}, [canEditUsers, user, hasChanges, formValues, showToast, isSuperuserUser]);
|
||||||
|
|
||||||
const fetchSecurityPhrase = useCallback(async () => {
|
const fetchSecurityPhrase = useCallback(async () => {
|
||||||
if (!canViewSecurityPhrase || !numericUserId) {
|
if (!canManageSecurityPhrase || !numericUserId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,14 +423,17 @@ export function UserDetails() {
|
|||||||
} finally {
|
} finally {
|
||||||
setSecurityPhraseLoading(false);
|
setSecurityPhraseLoading(false);
|
||||||
}
|
}
|
||||||
}, [canViewSecurityPhrase, numericUserId]);
|
}, [canManageSecurityPhrase, numericUserId]);
|
||||||
|
|
||||||
const handleReloadSecurityPhrase = useCallback(() => {
|
const handleReloadSecurityPhrase = useCallback(() => {
|
||||||
|
if (!canRenewSecurityPhrase) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (securityPhraseLoading || renewingSecurityPhrase) {
|
if (securityPhraseLoading || renewingSecurityPhrase) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fetchSecurityPhrase();
|
fetchSecurityPhrase();
|
||||||
}, [fetchSecurityPhrase, renewingSecurityPhrase, securityPhraseLoading]);
|
}, [canRenewSecurityPhrase, fetchSecurityPhrase, renewingSecurityPhrase, securityPhraseLoading]);
|
||||||
|
|
||||||
const handleRenewSecurityPhrase = useCallback(async () => {
|
const handleRenewSecurityPhrase = useCallback(async () => {
|
||||||
if (!canRenewSecurityPhrase || !numericUserId || maintenanceActive || renewingSecurityPhrase) {
|
if (!canRenewSecurityPhrase || !numericUserId || maintenanceActive || renewingSecurityPhrase) {
|
||||||
@@ -546,7 +549,7 @@ export function UserDetails() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!canViewSecurityPhrase || !numericUserId) {
|
if (!canManageSecurityPhrase || !numericUserId) {
|
||||||
setSecurityPhraseWords([]);
|
setSecurityPhraseWords([]);
|
||||||
setSecurityPhraseDownloadedAt(null);
|
setSecurityPhraseDownloadedAt(null);
|
||||||
setSecurityPhraseError("");
|
setSecurityPhraseError("");
|
||||||
@@ -555,7 +558,7 @@ export function UserDetails() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fetchSecurityPhrase();
|
fetchSecurityPhrase();
|
||||||
}, [hasLoaded, canViewSecurityPhrase, fetchSecurityPhrase, numericUserId]);
|
}, [hasLoaded, canManageSecurityPhrase, fetchSecurityPhrase, numericUserId]);
|
||||||
|
|
||||||
const inputDisabled = maintenanceActive || savingUser || !user || !canEditUsers;
|
const inputDisabled = maintenanceActive || savingUser || !user || !canEditUsers;
|
||||||
const selectDisabled = maintenanceActive || savingUser || !user || groupsLoading || !canEditUsers || isSuperuserUser;
|
const selectDisabled = maintenanceActive || savingUser || !user || groupsLoading || !canEditUsers || isSuperuserUser;
|
||||||
@@ -765,7 +768,7 @@ export function UserDetails() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{canViewSecurityPhrase && (
|
{canManageSecurityPhrase && (
|
||||||
<div className="mt-10 border-t border-blue-gray-50 pt-8">
|
<div className="mt-10 border-t border-blue-gray-50 pt-8">
|
||||||
<div className="mb-4 flex flex-wrap items-center justify-between gap-4">
|
<div className="mb-4 flex flex-wrap items-center justify-between gap-4">
|
||||||
<div>
|
<div>
|
||||||
@@ -783,27 +786,26 @@ export function UserDetails() {
|
|||||||
className="normal-case"
|
className="normal-case"
|
||||||
onClick={handleReloadSecurityPhrase}
|
onClick={handleReloadSecurityPhrase}
|
||||||
disabled={
|
disabled={
|
||||||
!canViewSecurityPhrase ||
|
!canRenewSecurityPhrase ||
|
||||||
securityPhraseLoading ||
|
securityPhraseLoading ||
|
||||||
renewingSecurityPhrase
|
renewingSecurityPhrase
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Aktualisieren
|
Aktualisieren
|
||||||
</Button>
|
</Button>
|
||||||
{canRenewSecurityPhrase && (
|
<Button
|
||||||
<Button
|
color="red"
|
||||||
color="red"
|
className="normal-case"
|
||||||
className="normal-case"
|
onClick={handleRenewSecurityPhrase}
|
||||||
onClick={handleRenewSecurityPhrase}
|
disabled={
|
||||||
disabled={
|
!canRenewSecurityPhrase ||
|
||||||
maintenanceActive ||
|
maintenanceActive ||
|
||||||
securityPhraseLoading ||
|
securityPhraseLoading ||
|
||||||
renewingSecurityPhrase
|
renewingSecurityPhrase
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{renewingSecurityPhrase ? "Erneuert ..." : "Schlüssel erneuern"}
|
{renewingSecurityPhrase ? "Erneuert ..." : "Schlüssel erneuern"}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{securityPhraseLoading ? (
|
{securityPhraseLoading ? (
|
||||||
@@ -820,7 +822,11 @@ export function UserDetails() {
|
|||||||
color="red"
|
color="red"
|
||||||
className="normal-case"
|
className="normal-case"
|
||||||
onClick={handleReloadSecurityPhrase}
|
onClick={handleReloadSecurityPhrase}
|
||||||
disabled={securityPhraseLoading || renewingSecurityPhrase}
|
disabled={
|
||||||
|
!canRenewSecurityPhrase ||
|
||||||
|
securityPhraseLoading ||
|
||||||
|
renewingSecurityPhrase
|
||||||
|
}
|
||||||
>
|
>
|
||||||
Erneut laden
|
Erneut laden
|
||||||
</Button>
|
</Button>
|
||||||
@@ -850,11 +856,9 @@ export function UserDetails() {
|
|||||||
Kein Sicherheitsschlüssel verfügbar.
|
Kein Sicherheitsschlüssel verfügbar.
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
{canRenewSecurityPhrase && (
|
<Typography className="mt-3 text-sm text-blue-gray-500">
|
||||||
<Typography className="mt-3 text-sm text-blue-gray-500">
|
Nach dem Erneuern muss der Benutzer den neuen Sicherheitsschlüssel erneut herunterladen.
|
||||||
Nach dem Erneuern muss der Benutzer den neuen Sicherheitsschlüssel erneut herunterladen.
|
</Typography>
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -126,16 +126,24 @@ export function UserGroupDetail() {
|
|||||||
if (!item || typeof item !== "object") {
|
if (!item || typeof item !== "object") {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const key = item.key || "";
|
||||||
const defaultLevel =
|
const defaultLevel =
|
||||||
typeof item.defaultLevel === "string" && item.defaultLevel ? item.defaultLevel : "none";
|
typeof item.defaultLevel === "string" && item.defaultLevel ? item.defaultLevel : "none";
|
||||||
defaults[item.key] = defaultLevel;
|
defaults[key] = defaultLevel;
|
||||||
const assigned = rawValues[item.key];
|
|
||||||
initialSelection[item.key] = typeof assigned === "string" && assigned ? assigned : defaultLevel;
|
const assigned = rawValues[key];
|
||||||
|
let normalizedAssigned =
|
||||||
|
typeof assigned === "string" && assigned ? assigned : defaultLevel;
|
||||||
|
|
||||||
const availableLevels =
|
const availableLevels =
|
||||||
Array.isArray(item.availableLevels) && item.availableLevels.length
|
Array.isArray(item.availableLevels) && item.availableLevels.length
|
||||||
? item.availableLevels
|
? item.availableLevels
|
||||||
: LEVEL_OPTIONS.map((option) => option.value);
|
: LEVEL_OPTIONS.map((option) => option.value);
|
||||||
|
if (!availableLevels.includes(normalizedAssigned)) {
|
||||||
|
normalizedAssigned = defaultLevel;
|
||||||
|
}
|
||||||
|
initialSelection[key] = normalizedAssigned;
|
||||||
|
|
||||||
const dependencies = Array.isArray(item.dependencies) ? item.dependencies : [];
|
const dependencies = Array.isArray(item.dependencies) ? item.dependencies : [];
|
||||||
|
|
||||||
@@ -359,10 +367,6 @@ export function UserGroupDetail() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (permissionsChanged && isSuperuserGroup) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (detailsChanged && !canEditGroupDetails) {
|
if (detailsChanged && !canEditGroupDetails) {
|
||||||
setSaveError("Dir fehlt die Berechtigung, diese Gruppe zu bearbeiten.");
|
setSaveError("Dir fehlt die Berechtigung, diese Gruppe zu bearbeiten.");
|
||||||
return;
|
return;
|
||||||
@@ -397,10 +401,14 @@ export function UserGroupDetail() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (permissionsChanged && !isSuperuserGroup) {
|
if (permissionsChanged) {
|
||||||
await axios.put(`/api/groups/${group.id}/permissions`, {
|
await axios.put(`/api/groups/${group.id}/permissions`, {
|
||||||
values: permissionSelection
|
values: permissionSelection
|
||||||
});
|
});
|
||||||
|
setPermissionSelection((prev) => ({
|
||||||
|
...prev,
|
||||||
|
...permissionSelection
|
||||||
|
}));
|
||||||
setInitialPermissionSelection({ ...permissionSelection });
|
setInitialPermissionSelection({ ...permissionSelection });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -577,6 +585,7 @@ export function UserGroupDetail() {
|
|||||||
? row.availableLevels
|
? row.availableLevels
|
||||||
: LEVEL_OPTIONS.map((option) => option.value)
|
: LEVEL_OPTIONS.map((option) => option.value)
|
||||||
);
|
);
|
||||||
|
const levelOptions = LEVEL_OPTIONS;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={`${ownerKey}-${row.key}`} className={rowClasses}>
|
<div key={`${ownerKey}-${row.key}`} className={rowClasses}>
|
||||||
@@ -584,7 +593,7 @@ export function UserGroupDetail() {
|
|||||||
{row.label}
|
{row.label}
|
||||||
</div>
|
</div>
|
||||||
<List className="flex-col gap-1.5 md:ml-auto md:flex-row md:flex-nowrap md:w-1/2 md:items-center md:justify-end md:gap-3">
|
<List className="flex-col gap-1.5 md:ml-auto md:flex-row md:flex-nowrap md:w-1/2 md:items-center md:justify-end md:gap-3">
|
||||||
{LEVEL_OPTIONS.map((option) => {
|
{levelOptions.map((option) => {
|
||||||
const optionId = `${rowName}-${option.value}`;
|
const optionId = `${rowName}-${option.value}`;
|
||||||
const checked = currentValue === option.value;
|
const checked = currentValue === option.value;
|
||||||
const disabled =
|
const disabled =
|
||||||
|
|||||||
Reference in New Issue
Block a user