Skip to content

Commit 43ae9fe

Browse files
authored
Merge pull request #56 from KelvinTegelaar/main
[pull] main from KelvinTegelaar:main
2 parents 595b1dd + 0bcd54b commit 43ae9fe

File tree

17 files changed

+737
-197
lines changed

17 files changed

+737
-197
lines changed

.github/workflows/cipp_dev_build.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ jobs:
3838
- name: Build Project
3939
run: npm run build
4040

41+
# Update version.json with commit hash
42+
- name: Update version.json
43+
run: |
44+
VERSION=$(jq -r '.version' public/version.json)
45+
SHORT_SHA="${GITHUB_SHA::7}"
46+
echo "{\"version\": \"${VERSION}\", \"commit\": \"${SHORT_SHA}\"}" > out/version.json
47+
4148
# Create ZIP File in a New Source Directory
4249
- name: Prepare and Zip Build Files
4350
run: |

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cipp",
3-
"version": "10.2.1",
3+
"version": "10.2.2",
44
"author": "CIPP Contributors",
55
"homepage": "https://cipp.app/",
66
"bugs": {

public/version.json

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

src/components/CippComponents/CippSponsor.jsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export const CippSponsor = () => {
7272
<Typography
7373
color="text.secondary"
7474
variant="caption"
75-
sx={{ lineHeight: 4, textAlign: "center" }}
75+
sx={{ lineHeight: 2, textAlign: "center", display: "block", mt: 2 }}
7676
>
7777
This application is sponsored by
7878
</Typography>
@@ -82,6 +82,7 @@ export const CippSponsor = () => {
8282
justifyContent: "center",
8383
alignItems: "center",
8484
height: "55px",
85+
mb: 1,
8586
}}
8687
>
8788
<Tooltip title={randomimg.tooltip} arrow>
@@ -92,7 +93,7 @@ export const CippSponsor = () => {
9293
cursor: "pointer",
9394
maxHeight: "50px",
9495
width: "auto",
95-
maxWidth: "100px",
96+
maxWidth: "150px",
9697
}}
9798
onClick={() => window.open(randomimg.link)}
9899
/>
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import { Button, Typography, Alert, Box, TextField, InputAdornment } from "@mui/material";
2+
import { Key } from "@mui/icons-material";
3+
import CippButtonCard from "../CippCards/CippButtonCard";
4+
import { ApiPostCall } from "../../api/ApiCall";
5+
import { CippCopyToClipBoard } from "../CippComponents/CippCopyToClipboard";
6+
import CippFormComponent from "../CippComponents/CippFormComponent";
7+
import { useForm } from "react-hook-form";
8+
9+
const CippSiemSettings = () => {
10+
const generateSas = ApiPostCall({
11+
datafromUrl: true,
12+
});
13+
14+
const formControl = useForm({
15+
mode: "onChange",
16+
defaultValues: {
17+
Days: { label: "365 days", value: "365" },
18+
},
19+
});
20+
21+
const handleGenerate = () => {
22+
const formData = formControl.getValues();
23+
const days = formData.Days?.value ?? "365";
24+
generateSas.mutate({
25+
url: "/api/ExecCippLogsSas",
26+
data: { Days: parseInt(days, 10) },
27+
queryKey: "ExecCippLogsSas",
28+
});
29+
};
30+
31+
return (
32+
<CippButtonCard
33+
title="CIPP Logs Table Access"
34+
cardSx={{ display: "flex", flexDirection: "column", height: "100%" }}
35+
CardButton={
36+
<Button
37+
variant="contained"
38+
size="small"
39+
onClick={handleGenerate}
40+
disabled={generateSas.isPending || !formControl.formState.isValid}
41+
startIcon={<Key style={{ width: 16, height: 16 }} />}
42+
>
43+
Generate SAS Token
44+
</Button>
45+
}
46+
>
47+
<Box sx={{ display: "flex", flexDirection: "column", gap: 2, flex: 1 }}>
48+
<Alert severity="info">
49+
Generate a read-only SAS token for the CIPP Logs table. This token can be used to query
50+
log data from external SIEM tools or scripts using the Azure Table Storage REST API. Note
51+
that generating a new URL does not invalidate previous URLs.
52+
</Alert>
53+
54+
<Box>
55+
<CippFormComponent
56+
type="autoComplete"
57+
name="Days"
58+
label="Token Validity"
59+
helperText="Select how long the SAS token should be valid for. Enter a custom value in days if needed."
60+
multiple={false}
61+
creatable={true}
62+
options={[
63+
{ label: "30 days", value: "30" },
64+
{ label: "60 days", value: "60" },
65+
{ label: "90 days", value: "90" },
66+
{ label: "180 days", value: "180" },
67+
{ label: "365 days", value: "365" },
68+
{ label: "730 days (2 years)", value: "730" },
69+
{ label: "1095 days (3 years)", value: "1095" },
70+
{ label: "1825 days (5 years)", value: "1825" },
71+
{ label: "3650 days (10 years)", value: "3650" },
72+
]}
73+
formControl={formControl}
74+
validators={{ required: "Please select a validity period" }}
75+
/>
76+
</Box>
77+
78+
{generateSas.isError && (
79+
<Alert severity="error">
80+
{generateSas.error?.response?.data?.Results ||
81+
generateSas.error?.message ||
82+
"Failed to generate SAS token"}
83+
</Alert>
84+
)}
85+
86+
{generateSas.isSuccess && generateSas.data?.data?.Results && (
87+
<>
88+
<Alert severity="success">
89+
SAS URL generated successfully. Copy this for your records, it will only be shown
90+
once.
91+
</Alert>
92+
<Box>
93+
<Typography variant="subtitle2" sx={{ mb: 0.5 }}>
94+
SAS URL
95+
</Typography>
96+
<TextField
97+
fullWidth
98+
size="small"
99+
value={generateSas.data.data.Results.SASUrl}
100+
slotProps={{
101+
input: {
102+
readOnly: true,
103+
endAdornment: (
104+
<InputAdornment position="end">
105+
<CippCopyToClipBoard text={generateSas.data.data.Results.SASUrl} />
106+
</InputAdornment>
107+
),
108+
},
109+
}}
110+
/>
111+
</Box>
112+
<Box>
113+
<Typography variant="subtitle2" sx={{ mb: 0.5 }}>
114+
Expires On
115+
</Typography>
116+
<Typography variant="body2">
117+
{new Date(generateSas.data.data.Results.ExpiresOn).toLocaleString()}
118+
</Typography>
119+
</Box>
120+
</>
121+
)}
122+
</Box>
123+
</CippButtonCard>
124+
);
125+
};
126+
127+
export default CippSiemSettings;

src/components/CippStandards/CippStandardAccordion.jsx

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ const CippStandardAccordion = ({
257257
initialConfigured[standardName] = isStandardConfigured(
258258
standardName,
259259
standard,
260-
currentValues
260+
currentValues,
261261
);
262262
}
263263
});
@@ -271,6 +271,48 @@ const CippStandardAccordion = ({
271271
}
272272
}, [watchedValues, selectedStandards, editMode]);
273273

274+
// Sync internal state when selectedStandards keys change (e.g., after re-indexing on removal)
275+
useEffect(() => {
276+
const currentKeys = Object.keys(selectedStandards);
277+
const stateKeys = Object.keys(savedValues);
278+
if (stateKeys.length === 0) return;
279+
280+
const currentSet = new Set(currentKeys);
281+
const stateSet = new Set(stateKeys);
282+
283+
const removedKeys = stateKeys.filter((k) => !currentSet.has(k));
284+
const addedKeys = currentKeys.filter((k) => !stateSet.has(k));
285+
286+
if (removedKeys.length > 0 || addedKeys.length > 0) {
287+
setSavedValues((prev) => {
288+
const updated = { ...prev };
289+
removedKeys.forEach((k) => delete updated[k]);
290+
addedKeys.forEach((k) => {
291+
const currentValues = _.get(watchedValues, k);
292+
if (currentValues) {
293+
updated[k] = _.cloneDeep(currentValues);
294+
}
295+
});
296+
return updated;
297+
});
298+
299+
setConfiguredState((prev) => {
300+
const updated = { ...prev };
301+
removedKeys.forEach((k) => delete updated[k]);
302+
addedKeys.forEach((k) => {
303+
const baseStandardName = k.split("[")[0];
304+
const standard = providedStandards.find((s) => s.name === baseStandardName);
305+
const currentValues = _.get(watchedValues, k);
306+
if (standard && currentValues) {
307+
updated[k] = isStandardConfigured(k, standard, currentValues);
308+
}
309+
});
310+
return updated;
311+
});
312+
}
313+
// eslint-disable-next-line react-hooks/exhaustive-deps
314+
}, [selectedStandards]);
315+
274316
// Save changes for a standard
275317
const handleSave = (standardName, standard, current) => {
276318
// Clone the current values to avoid reference issues
@@ -587,8 +629,8 @@ const CippStandardAccordion = ({
587629
const accordionTitle = templateDisplayName
588630
? `${standard.label} - ${templateDisplayName}`
589631
: selectedTemplateName && _.get(selectedTemplateName, "label")
590-
? `${standard.label} - ${_.get(selectedTemplateName, "label")}`
591-
: standard.label;
632+
? `${standard.label} - ${_.get(selectedTemplateName, "label")}`
633+
: standard.label;
592634

593635
// Get current values and check if they differ from saved values
594636
const current = _.get(watchedValues, standardName);
@@ -598,7 +640,7 @@ const CippStandardAccordion = ({
598640

599641
// Check if all required fields are filled
600642
const requiredFieldsFilled = current
601-
? standard.addedComponent?.every((component) => {
643+
? (standard.addedComponent?.every((component) => {
602644
// Always skip switches regardless of their required property
603645
if (component.type === "switch") return true;
604646

@@ -630,7 +672,7 @@ const CippStandardAccordion = ({
630672
switch (compareType) {
631673
case "valueEq":
632674
conditionMet = conditionValue.some(
633-
(item) => item?.[propertyName] === compareValue
675+
(item) => item?.[propertyName] === compareValue,
634676
);
635677
break;
636678
default:
@@ -658,7 +700,7 @@ const CippStandardAccordion = ({
658700

659701
// For other field types
660702
return !!fieldValue;
661-
}) ?? true
703+
}) ?? true)
662704
: false;
663705

664706
// ALWAYS require an action for all standards
@@ -668,7 +710,7 @@ const CippStandardAccordion = ({
668710
const hasRequiredComponents =
669711
standard.addedComponent &&
670712
standard.addedComponent.some(
671-
(comp) => comp.type !== "switch" && comp.required !== false
713+
(comp) => comp.type !== "switch" && comp.required !== false,
672714
);
673715

674716
// Action is always required and must be an array with at least one element
@@ -904,7 +946,7 @@ const CippStandardAccordion = ({
904946
component={component}
905947
formControl={formControl}
906948
/>
907-
)
949+
),
908950
)}
909951
</>
910952
)}
@@ -962,7 +1004,7 @@ const CippStandardAccordion = ({
9621004
component={component}
9631005
formControl={formControl}
9641006
/>
965-
)
1007+
),
9661008
)}
9671009
</Grid>
9681010
</Grid>

src/contexts/settings-context.js

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ export const SettingsProvider = (props) => {
124124
}
125125
}, []);
126126

127+
useEffect(() => {
128+
if (state.isInitialized) {
129+
storeSettings(state);
130+
}
131+
}, [state]);
132+
127133
const handleReset = useCallback(() => {
128134
deleteSettings();
129135
setState((prevState) => ({
@@ -142,11 +148,6 @@ export const SettingsProvider = (props) => {
142148
return acc;
143149
}, {});
144150

145-
storeSettings({
146-
...prevState,
147-
...filteredSettings,
148-
});
149-
150151
return {
151152
...prevState,
152153
...filteredSettings,
@@ -171,17 +172,13 @@ export const SettingsProvider = (props) => {
171172
handleUpdate,
172173
isCustom,
173174
setLastUsedFilter: (page, filter) => {
174-
setState((prevState) => {
175-
const updated = {
176-
...prevState,
177-
lastUsedFilters: {
178-
...prevState.lastUsedFilters,
179-
[page]: filter,
180-
},
181-
};
182-
storeSettings(updated);
183-
return updated;
184-
});
175+
setState((prevState) => ({
176+
...prevState,
177+
lastUsedFilters: {
178+
...prevState.lastUsedFilters,
179+
[page]: filter,
180+
},
181+
}));
185182
},
186183
}}
187184
>

src/layouts/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ export const Layout = (props) => {
236236
var bookmarkLocked = settings.bookmarkLocked;
237237
var bookmarkSortOrder = settings.bookmarkSortOrder;
238238
var bookmarksOpen = settings.bookmarksOpen;
239+
var compactNav = settings.compactNav;
239240

240241
settings.handleUpdate({
241242
...userSettingsAPI.data,
@@ -246,6 +247,7 @@ export const Layout = (props) => {
246247
bookmarkLocked,
247248
bookmarkSortOrder,
248249
bookmarksOpen,
250+
compactNav,
249251
showDevtools,
250252
});
251253

0 commit comments

Comments
 (0)