Skip to content

Commit 6a3625a

Browse files
authored
Merge pull request KelvinTegelaar#4232 from KelvinTegelaar/dev
Dev to hotfix
2 parents db63240 + d11bc3f commit 6a3625a

File tree

13 files changed

+796
-545
lines changed

13 files changed

+796
-545
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cipp",
3-
"version": "7.1.3",
3+
"version": "8.0.2",
44
"author": "CIPP Contributors",
55
"homepage": "https://cipp.app/",
66
"bugs": {
@@ -112,4 +112,4 @@
112112
"eslint": "9.22.0",
113113
"eslint-config-next": "15.2.2"
114114
}
115-
}
115+
}

public/version.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"version": "8.0.2"
2+
"version": "8.0.3"
33
}

src/components/CippComponents/CippMailboxPermissionsDialog.jsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const CippMailboxPermissionsDialog = ({ formHook }) => {
2525
});
2626

2727
return (
28-
<Stack spacing={3} sx={{ mt: 1 }}>
28+
<Stack spacing={2} sx={{ mt: 1 }}>
2929
<Box>
3030
<CippFormComponent
3131
type="autoComplete"
@@ -40,16 +40,17 @@ const CippMailboxPermissionsDialog = ({ formHook }) => {
4040
})) || []
4141
}
4242
/>
43-
{fullAccess && (
43+
</Box>
44+
{fullAccess?.length > 0 && (
45+
<Box sx={{ pl: 0.5 }}>
4446
<CippFormComponent
4547
type="switch"
4648
label="Enable Automapping"
47-
name="permissions.AutoMapping"
49+
name="permissions.AutoMap"
4850
formControl={formHook}
49-
sx={{ mt: 0.5, ml: 0.5 }}
5051
/>
51-
)}
52-
</Box>
52+
</Box>
53+
)}
5354
<Box>
5455
<CippFormComponent
5556
type="autoComplete"

src/components/CippStandards/CippStandardAccordion.jsx

Lines changed: 45 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ const CippStandardAccordion = ({
9393
handleRemoveStandard,
9494
handleAddMultipleStandard,
9595
formControl,
96+
editMode = false,
9697
}) => {
9798
const [configuredState, setConfiguredState] = useState({});
9899
const [filter, setFilter] = useState("all");
@@ -188,46 +189,48 @@ const CippStandardAccordion = ({
188189

189190
// Initialize when watchedValues are available
190191
useEffect(() => {
191-
// Only run initialization if we have watchedValues and they contain data
192-
if (!watchedValues || Object.keys(watchedValues).length === 0) {
193-
return;
194-
}
195-
196-
// Prevent re-initialization if we already have configuration state
197-
const hasConfigState = Object.keys(configuredState).length > 0;
198-
if (hasConfigState) {
199-
return;
200-
}
201-
202-
console.log("Initializing configuration state from template values");
203-
const initial = {};
204-
const initialConfigured = {};
205-
206-
// For each standard, get its current values and determine if it's configured
207-
Object.keys(selectedStandards).forEach((standardName) => {
208-
const currentValues = _.get(watchedValues, standardName);
209-
if (!currentValues) return;
210-
211-
initial[standardName] = _.cloneDeep(currentValues);
192+
if (editMode) {
193+
// Only run initialization if we have watchedValues and they contain data
194+
if (!watchedValues || Object.keys(watchedValues).length === 0) {
195+
return;
196+
}
212197

213-
const baseStandardName = standardName.split("[")[0];
214-
const standard = providedStandards.find((s) => s.name === baseStandardName);
215-
if (standard) {
216-
initialConfigured[standardName] = isStandardConfigured(
217-
standardName,
218-
standard,
219-
currentValues
220-
);
198+
// Prevent re-initialization if we already have configuration state
199+
const hasConfigState = Object.keys(configuredState).length > 0;
200+
if (hasConfigState) {
201+
return;
221202
}
222-
});
223203

224-
// Store both the initial values and set them as current saved values
225-
setOriginalValues(initial);
226-
setSavedValues(initial);
227-
setConfiguredState(initialConfigured);
228-
// Only depend on watchedValues and selectedStandards to avoid infinite loops
229-
// eslint-disable-next-line react-hooks/exhaustive-deps
230-
}, [watchedValues, selectedStandards]);
204+
console.log("Initializing configuration state from template values");
205+
const initial = {};
206+
const initialConfigured = {};
207+
208+
// For each standard, get its current values and determine if it's configured
209+
Object.keys(selectedStandards).forEach((standardName) => {
210+
const currentValues = _.get(watchedValues, standardName);
211+
if (!currentValues) return;
212+
213+
initial[standardName] = _.cloneDeep(currentValues);
214+
215+
const baseStandardName = standardName.split("[")[0];
216+
const standard = providedStandards.find((s) => s.name === baseStandardName);
217+
if (standard) {
218+
initialConfigured[standardName] = isStandardConfigured(
219+
standardName,
220+
standard,
221+
currentValues
222+
);
223+
}
224+
});
225+
226+
// Store both the initial values and set them as current saved values
227+
setOriginalValues(initial);
228+
setSavedValues(initial);
229+
setConfiguredState(initialConfigured);
230+
// Only depend on watchedValues and selectedStandards to avoid infinite loops
231+
// eslint-disable-next-line react-hooks/exhaustive-deps
232+
}
233+
}, [watchedValues, selectedStandards, editMode]);
231234

232235
// Save changes for a standard
233236
const handleSave = (standardName, standard, current) => {
@@ -519,6 +522,9 @@ const CippStandardAccordion = ({
519522
// Get current values and check if they differ from saved values
520523
const current = _.get(watchedValues, standardName);
521524
const saved = _.get(savedValues, standardName) || {};
525+
console.log(`Current values for ${standardName}:`, current);
526+
console.log(`Saved values for ${standardName}:`, saved);
527+
522528
const hasUnsaved = !_.isEqual(current, saved);
523529

524530
// Check if all required fields are filled
@@ -609,7 +615,7 @@ const CippStandardAccordion = ({
609615
const canSave = hasAction && requiredFieldsFilled && hasUnsaved;
610616

611617
console.log(
612-
`Standard: ${standardName}, Action Required: ${actionRequired}, Has Action: ${hasAction}, Required Fields Filled: ${requiredFieldsFilled}, Can Save: ${canSave}`
618+
`Standard: ${standardName}, Action Required: ${actionRequired}, Has Action: ${hasAction}, Required Fields Filled: ${requiredFieldsFilled}, Unsaved Changes: ${hasUnsaved}, Can Save: ${canSave}`
613619
);
614620

615621
return (
@@ -760,7 +766,7 @@ const CippStandardAccordion = ({
760766
</Grid>
761767
</Box>
762768
<Divider sx={{ mt: 2 }} />
763-
<Box sx={{ px: 3 , py: 2 }}>
769+
<Box sx={{ px: 3, py: 2 }}>
764770
<Stack direction="row" justifyContent="flex-end" spacing={1}>
765771
<Button
766772
variant="outlined"

src/components/CippStandards/CippStandardsSideBar.jsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,24 @@ const CippStandardsSideBar = ({
6464
formControl,
6565
createDialog,
6666
edit,
67+
onSaveSuccess,
6768
}) => {
6869
const [currentStep, setCurrentStep] = useState(0);
6970
const [savedItem, setSavedItem] = useState(null);
7071
const dialogAfterEffect = (id) => {
7172
setSavedItem(id);
73+
74+
// Reset form's dirty state to prevent unsaved changes warning
75+
if (formControl && formControl.reset) {
76+
// Get current values and reset the form with them to clear dirty state
77+
const currentValues = formControl.getValues();
78+
formControl.reset(currentValues);
79+
}
80+
81+
// Call the onSaveSuccess callback if provided
82+
if (typeof onSaveSuccess === "function") {
83+
onSaveSuccess();
84+
}
7285
};
7386

7487
const watchForm = useWatch({ control: formControl.control });
@@ -276,6 +289,7 @@ CippStandardsSideBar.propTypes = {
276289
).isRequired,
277290
updatedAt: PropTypes.string,
278291
formControl: PropTypes.object.isRequired,
292+
onSaveSuccess: PropTypes.func,
279293
};
280294

281295
export default CippStandardsSideBar;

src/components/PrivateRoute.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ export const PrivateRoute = ({ children, routeType }) => {
1818
});
1919

2020
// Check if the session is still loading before determining authentication status
21-
if (session.isLoading || apiRoles.isLoading) {
21+
if (
22+
session.isLoading ||
23+
apiRoles.isLoading ||
24+
(apiRoles.isFetching && (apiRoles.data === null || apiRoles.data === undefined))
25+
) {
2226
return <LoadingPage />;
2327
}
2428

src/data/GDAPRoles.json

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,22 @@
6363
"Name": "Attribute Definition Reader",
6464
"ObjectId": "1d336d2c-4ae8-42ef-9711-b3604ce3fc2c"
6565
},
66+
{
67+
"ExtensionData": {},
68+
"Description": "Read audit logs and configure diagnostic settings for events related to custom security attributes.",
69+
"IsEnabled": true,
70+
"IsSystem": true,
71+
"Name": "Attribute Log Administrator",
72+
"ObjectId": "5b784334-f94b-471a-a387-e7219fc49ca2"
73+
},
74+
{
75+
"ExtensionData": {},
76+
"Description": "Read audit logs related to custom security attributes.",
77+
"IsEnabled": true,
78+
"IsSystem": true,
79+
"Name": "Attribute Log Reader",
80+
"ObjectId": "9c99539d-8186-4804-835f-fd51ef9e2dcd"
81+
},
6682
{
6783
"ExtensionData": {},
6884
"Description": "Allowed to view, set and reset authentication method information for any non-admin user.",
@@ -79,6 +95,14 @@
7995
"Name": "Authentication Policy Administrator",
8096
"ObjectId": "0526716b-113d-4c15-b2c8-68e3c22b9f80"
8197
},
98+
{
99+
"ExtensionData": {},
100+
"Description": "Customize sign in and sign up experiences for users by creating and managing custom authentication extensions.",
101+
"IsEnabled": true,
102+
"IsSystem": true,
103+
"Name": "Authentication Extensibility Administrator",
104+
"ObjectId": "25a516ed-2fa0-40ea-a2d0-12923a21473a"
105+
},
82106
{
83107
"ExtensionData": {},
84108
"Description": "Users assigned to this role are added to the local administrators group on Azure AD-joined devices.",
@@ -311,6 +335,14 @@
311335
"Name": "Global Reader",
312336
"ObjectId": "f2ef992c-3afb-46b9-b7cf-a126ee74c451"
313337
},
338+
{
339+
"ExtensionData": {},
340+
"Description": "Create and manage all aspects of Microsoft Entra Internet Access and Microsoft Entra Private Access, including managing access to public and private endpoints.",
341+
"IsEnabled": true,
342+
"IsSystem": true,
343+
"Name": "Global Secure Access Administrator",
344+
"ObjectId": "ac434307-12b9-4fa1-a708-88bf58caabc1"
345+
},
314346
{
315347
"ExtensionData": {},
316348
"Description": "Members of this role can create/manage groups, create/manage groups settings like naming and expiration policies, and view groups activity and audit reports.",
@@ -439,6 +471,30 @@
439471
"Name": "Message Center Reader",
440472
"ObjectId": "790c1fb9-7f7d-4f88-86a1-ef1f95c05c1b"
441473
},
474+
{
475+
"ExtensionData": {},
476+
"Description": "Perform all migration functionality to migrate content to Microsoft 365 using Migration Manager.",
477+
"IsEnabled": true,
478+
"IsSystem": true,
479+
"Name": "Microsoft 365 Migration Administrator",
480+
"ObjectId": "8c8b803f-96e1-4129-9349-20738d9f9652"
481+
},
482+
{
483+
"ExtensionData": {},
484+
"Description": "Create and manage all aspects warranty claims and entitlements for Microsoft manufactured hardware, like Surface and HoloLens.",
485+
"IsEnabled": true,
486+
"IsSystem": true,
487+
"Name": "Microsoft Hardware Warranty Administrator",
488+
"ObjectId": "1501b917-7653-4ff9-a4b5-203eaf33784f"
489+
},
490+
{
491+
"ExtensionData": {},
492+
"Description": "Create and read warranty claims for Microsoft manufactured hardware, like Surface and HoloLens.",
493+
"IsEnabled": true,
494+
"IsSystem": true,
495+
"Name": "Microsoft Hardware Warranty Specialist",
496+
"ObjectId": "281fe777-fb20-4fbb-b7a3-ccebce5b0d96"
497+
},
442498
{
443499
"ExtensionData": {},
444500
"Description": "Can manage network locations and review enterprise network design insights for Microsoft 365 Software as a Service applications.",
@@ -455,6 +511,14 @@
455511
"Name": "Office Apps Administrator",
456512
"ObjectId": "2b745bdf-0803-4d80-aa65-822c4493daac"
457513
},
514+
{
515+
"ExtensionData": {},
516+
"Description": "Write, publish, manage, and review the organizational messages for end-users through Microsoft product surfaces.",
517+
"IsEnabled": true,
518+
"IsSystem": true,
519+
"Name": "Organizational Messages Writer",
520+
"ObjectId": "507f53e4-4e52-4077-abd3-d2e1558b6ea2"
521+
},
458522
{
459523
"ExtensionData": {},
460524
"Description": "Can reset passwords for non-administrators and Password Administrators.",
@@ -583,6 +647,14 @@
583647
"Name": "SharePoint Administrator",
584648
"ObjectId": "f28a1f50-f6e7-4571-818b-6a12f2af6b6c"
585649
},
650+
{
651+
"ExtensionData": {},
652+
"Description": "Manage all aspects of SharePoint Embedded containers.",
653+
"IsEnabled": true,
654+
"IsSystem": true,
655+
"Name": "SharePoint Embedded Administrator",
656+
"ObjectId": "1a7d78b6-429f-476b-8eb-35fb715fffd4"
657+
},
586658
{
587659
"ExtensionData": {},
588660
"Description": "Can manage all aspects of the Skype for Business product.",
@@ -631,6 +703,22 @@
631703
"Name": "Teams Devices Administrator",
632704
"ObjectId": "3d762c5a-1b6c-493f-843e-55a3b42923d4"
633705
},
706+
{
707+
"ExtensionData": {},
708+
"Description": "Manage voice and telephony features and troubleshoot communication issues within the Microsoft Teams service.",
709+
"IsEnabled": true,
710+
"IsSystem": true,
711+
"Name": "Teams Telephony Administrator",
712+
"ObjectId": "aa38014f-0993-46e9-9b45-30501a20909d"
713+
},
714+
{
715+
"ExtensionData": {},
716+
"Description": "Create new Microsoft Entra or Azure AD B2C tenants.",
717+
"IsEnabled": true,
718+
"IsSystem": true,
719+
"Name": "Tenant Creator",
720+
"ObjectId": "112ca1a2-15ad-4102-995e-45b0bc479a6a"
721+
},
634722
{
635723
"ExtensionData": {},
636724
"Description": "Can see only tenant level aggregates in Microsoft 365 Usage Analytics and Productivity Score.",
@@ -647,6 +735,14 @@
647735
"Name": "User Administrator",
648736
"ObjectId": "fe930be7-5e62-47db-91af-98c3a49a38b1"
649737
},
738+
{
739+
"ExtensionData": {},
740+
"Description": "View product feedback, survey results, and reports to find training and communication opportunities.",
741+
"IsEnabled": true,
742+
"IsSystem": true,
743+
"Name": "User Experience Success Manager",
744+
"ObjectId": "27460883-1df1-4691-b032-3b79643e5e63"
745+
},
650746
{
651747
"ExtensionData": {},
652748
"Description": "Manage and share Virtual Visits information and metrics from admin centers or the Virtual Visits app.",

0 commit comments

Comments
 (0)