diff --git a/src/components/CippFormPages/CippAddEditUser.jsx b/src/components/CippFormPages/CippAddEditUser.jsx index 1a6569577445..ac2b9a0262c8 100644 --- a/src/components/CippFormPages/CippAddEditUser.jsx +++ b/src/components/CippFormPages/CippAddEditUser.jsx @@ -92,7 +92,10 @@ const CippAddEditUser = (props) => { // don't trigger setValue on every keystroke const rawGivenName = watcher[0] const rawSurname = watcher[1] - const [debouncedName, setDebouncedName] = useState({ givenName: rawGivenName, surname: rawSurname }) + const [debouncedName, setDebouncedName] = useState({ + givenName: rawGivenName, + surname: rawSurname, + }) const debounceRef = useRef(null) useEffect(() => { debounceRef.current = setTimeout(() => { @@ -124,14 +127,22 @@ const CippAddEditUser = (props) => { let username = formatString - // Replace %FirstName[n]% patterns (extract first n characters) + // Replace %FirstName[n]% patterns (extract first n characters per word) username = username.replace(/%FirstName\[(\d+)\]%/gi, (match, num) => { - return firstName.substring(0, parseInt(num)) + const n = parseInt(num) + return firstName + .split(/\s+/) + .map((word) => word.substring(0, n)) + .join('') }) - // Replace %LastName[n]% patterns (extract first n characters) + // Replace %LastName[n]% patterns (extract first n characters per word) username = username.replace(/%LastName\[(\d+)\]%/gi, (match, num) => { - return lastName.substring(0, parseInt(num)) + const n = parseInt(num) + return lastName + .split(/\s+/) + .map((word) => word.substring(0, n)) + .join('') }) // Replace %FirstName% and %LastName% @@ -220,7 +231,12 @@ const CippAddEditUser = (props) => { // Reset manual flags and selected template when form is reset (fields become empty) useEffect(() => { - if (formType === 'add' && !watchedFields.givenName && !watchedFields.surname && !watchedFields.userTemplate) { + if ( + formType === 'add' && + !watchedFields.givenName && + !watchedFields.surname && + !watchedFields.userTemplate + ) { setDisplayNameManuallySet(false) setUsernameManuallySet(false) // Only clear selected template if it's not the default template @@ -228,7 +244,13 @@ const CippAddEditUser = (props) => { setSelectedTemplate(null) } } - }, [watchedFields.givenName, watchedFields.surname, watchedFields.userTemplate, formType, selectedTemplate]) + }, [ + watchedFields.givenName, + watchedFields.surname, + watchedFields.userTemplate, + formType, + selectedTemplate, + ]) // Auto-select default template for tenant useEffect(() => { diff --git a/src/data/alerts.json b/src/data/alerts.json index 33396fa152bf..6f864fbe1699 100644 --- a/src/data/alerts.json +++ b/src/data/alerts.json @@ -562,7 +562,7 @@ "inputs": [ { "inputType": "autoComplete", - "inputLabel": "Threshold type absolute number or percent", + "inputLabel": "Threshold type", "inputName": "ThresholdType", "creatable": false, "multiple": false, @@ -574,23 +574,33 @@ { "label": "Absolute", "value": "absolute" + }, + { + "label": "Drop (% decrease from previous score)", + "value": "drop" } ], "required": true }, { "inputType": "number", - "inputLabel": "Threshold Value (below this will trigger the alert)", + "inputLabel": "Threshold Value (absolute/percent: alert when below this value, drop: alert when score decreases by this percentage)", "inputName": "InputValue", "required": true } ], - "description": "Monitors Secure Score and alerts when it falls below the specified threshold (absolute or percent value). Helps identify security gaps and areas for improvement." + "description": "Monitors Secure Score and alerts when it falls below the specified threshold (absolute or percent value) or when it drops by a defined percentage compared to the previous score. Helps identify security gaps, regressions, and areas for improvement." }, { "name": "TenantAccess", "label": "Alert on tenant accessibility issues (Graph, Exchange, GDAP roles)", "recommendedRunInterval": "1d", "description": "Proactively monitors tenant accessibility by testing Graph API connectivity, GDAP role assignments, and Exchange Online access. Alerts when tenants have lost permissions, removed GDAP consent, or are missing required roles. Helps identify tenants that need a permission refresh or offboarding." + }, + { + "name": "CheckExtension", + "label": "Alert on new Check phishing extension detections", + "recommendedRunInterval": "15m", + "description": "Monitors for new phishing site detections reported by the Check browser extension. Alerts when a user visits a page that the extension flags as a potential credential phishing or AiTM attack. Requires the Check browser extension to be deployed to users." } ]