Skip to content

Commit 54ce4a9

Browse files
Merge pull request #2174 from KelvinTegelaar/dev
Dev to hotfix
2 parents 30a5344 + 992b5b5 commit 54ce4a9

File tree

5 files changed

+146
-24
lines changed

5 files changed

+146
-24
lines changed

public/version_latest.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5.2.0
1+
5.2.1

src/components/forms/RFFComponents.jsx

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
CTooltip,
1212
} from '@coreui/react'
1313
import Select from 'react-select'
14+
import Creatable, { useCreatable } from 'react-select/creatable'
1415
import { Field } from 'react-final-form'
1516
import { FieldArray } from 'react-final-form-arrays'
1617
import React, { useState, useMemo, useRef } from 'react'
@@ -393,6 +394,7 @@ export const RFFSelectSearch = ({
393394
disabled = false,
394395
retainInput = true,
395396
isLoading = false,
397+
allowCreate = false,
396398
refreshFunction,
397399
props,
398400
}) => {
@@ -433,7 +435,7 @@ export const RFFSelectSearch = ({
433435
</CTooltip>
434436
)}
435437
</CFormLabel>
436-
{onChange && (
438+
{!allowCreate && onChange && (
437439
<Select
438440
className="react-select-container"
439441
classNamePrefix="react-select"
@@ -452,7 +454,7 @@ export const RFFSelectSearch = ({
452454
{...props}
453455
/>
454456
)}
455-
{!onChange && (
457+
{!allowCreate && !onChange && (
456458
<Select
457459
className="react-select-container"
458460
classNamePrefix="react-select"
@@ -470,6 +472,43 @@ export const RFFSelectSearch = ({
470472
{...props}
471473
/>
472474
)}
475+
{allowCreate && onChange && (
476+
<Creatable
477+
className="react-select-container"
478+
classNamePrefix="react-select"
479+
{...input}
480+
isClearable={false}
481+
name={name}
482+
id={name}
483+
disabled={disabled}
484+
options={selectSearchvalues}
485+
placeholder={placeholder}
486+
isMulti={multi}
487+
onChange={onChange}
488+
onInputChange={debounceOnInputChange}
489+
inputValue={inputText}
490+
isLoading={isLoading}
491+
{...props}
492+
/>
493+
)}
494+
{allowCreate && !onChange && (
495+
<Creatable
496+
className="react-select-container"
497+
classNamePrefix="react-select"
498+
{...input}
499+
isClearable={true}
500+
name={name}
501+
id={name}
502+
disabled={disabled}
503+
options={selectSearchvalues}
504+
placeholder={placeholder}
505+
onInputChange={setOnInputChange}
506+
isMulti={multi}
507+
inputValue={inputText}
508+
isLoading={isLoading}
509+
{...props}
510+
/>
511+
)}
473512
{meta.error && meta.touched && <span className="text-danger">{meta.error}</span>}
474513
</div>
475514
)

src/views/identity/reports/MFAReport.jsx

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,20 @@ const columns = [
2525
cell: cellBooleanFormatter({ colourless: true }),
2626
exportSelector: 'isLicensed',
2727
},
28-
{
29-
selector: (row) => row['PerUser'],
30-
name: 'Per user MFA Status',
31-
sortable: true,
32-
exportSelector: 'PerUser',
33-
},
3428
{
3529
selector: (row) => row['MFARegistration'],
3630
name: 'Registered for Conditional MFA',
3731
sortable: true,
3832
cell: cellBooleanFormatter(),
3933
exportSelector: 'MFARegistration',
4034
},
35+
{
36+
selector: (row) => row['CoveredBySD'],
37+
name: 'Enforced via Security Defaults',
38+
sortable: true,
39+
cell: cellBooleanFormatter({ colourless: true }),
40+
exportSelector: 'CoveredBySD',
41+
},
4142
{
4243
selector: (row) => row['CoveredByCA'],
4344
name: 'Enforced via Conditional Access',
@@ -46,11 +47,10 @@ const columns = [
4647
exportSelector: 'CoveredByCA',
4748
},
4849
{
49-
selector: (row) => row['CoveredBySD'],
50-
name: 'Enforced via Security Defaults',
50+
selector: (row) => row['PerUser'],
51+
name: 'Per user MFA Status',
5152
sortable: true,
52-
cell: cellBooleanFormatter({ colourless: true }),
53-
exportSelector: 'CoveredBySD',
53+
exportSelector: 'PerUser',
5454
},
5555
]
5656

@@ -134,7 +134,17 @@ const MFAList = () => {
134134
datatable={{
135135
filterlist: [
136136
{ filterName: 'Enabled users', filter: '"accountEnabled":true' },
137+
{ filterName: 'Non-guest users', filter: 'Complex: UPN notlike #EXT#' },
137138
{ filterName: 'Licensed users', filter: 'Complex: IsLicensed eq true' },
139+
{
140+
filterName: 'Enabled, licensed non-guest users missing MFA',
141+
filter:
142+
'Complex: UPN notlike #EXT#; IsLicensed eq true; accountEnabled eq true; MFARegistration eq false',
143+
},
144+
{
145+
filterName: 'No MFA methods registered',
146+
filter: 'Complex: MFARegistration eq false',
147+
},
138148
],
139149
columns: tenant.defaultDomainName === 'AllTenants' ? Altcolumns : columns,
140150
path: '/api/ListMFAUsers',

src/views/tenant/administration/GraphExplorer.jsx

Lines changed: 83 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect, useState, useRef } from 'react'
1+
import React, { useEffect, useState, useRef, useMemo } from 'react'
22
import {
33
CAlert,
44
CButton,
@@ -31,6 +31,7 @@ import { OnChange } from 'react-final-form-listeners'
3131
import { cellGenericFormatter } from 'src/components/tables/CellGenericFormat'
3232
import PropTypes from 'prop-types'
3333
import { CippCodeOffCanvas, ModalService } from 'src/components/utilities'
34+
import { debounce } from 'lodash-es'
3435

3536
const GraphExplorer = () => {
3637
const tenant = useSelector((state) => state.app.currentTenant)
@@ -39,6 +40,7 @@ const GraphExplorer = () => {
3940
const [alertVisible, setAlertVisible] = useState()
4041
const [random, setRandom] = useState('')
4142
const [random2, setRandom2] = useState('')
43+
const [random3, setRandom3] = useState('')
4244
const [ocVisible, setOCVisible] = useState(false)
4345
const [searchNow, setSearchNow] = useState(false)
4446
const [visibleA, setVisibleA] = useState(true)
@@ -49,13 +51,30 @@ const GraphExplorer = () => {
4951
}
5052
const [execGraphRequest, graphrequest] = useLazyGenericGetRequestQuery()
5153
const [execPostRequest, postResults] = useLazyGenericPostRequestQuery()
54+
const [execPropRequest, availableProperties] = useLazyGenericGetRequestQuery()
5255
const {
5356
data: customPresets = [],
5457
isFetching: presetsIsFetching,
5558
error: presetsError,
5659
} = useGenericGetRequestQuery({ path: '/api/ListGraphExplorerPresets', params: { random2 } })
5760
const QueryColumns = { set: false, data: [] }
5861

62+
function endpointChange(value) {
63+
execPropRequest({
64+
path: '/api/ListGraphRequest',
65+
params: {
66+
Endpoint: value,
67+
ListProperties: true,
68+
TenantFilter: tenant.defaultDomainName,
69+
IgnoreErrors: true,
70+
random: (Math.random() + 1).toString(36).substring(7),
71+
},
72+
})
73+
}
74+
const debounceEndpointChange = useMemo(() => {
75+
return debounce(endpointChange, 1000)
76+
}, [endpointChange])
77+
5978
if (graphrequest.isSuccess) {
6079
if (graphrequest.data?.Results?.length > 0) {
6180
//set columns
@@ -217,10 +236,15 @@ const GraphExplorer = () => {
217236

218237
useEffect(() => {
219238
if (params?.endpoint) {
239+
var select = ''
240+
if (params?.$select) {
241+
select = params.$select.map((p) => p.value).join(',')
242+
}
220243
execGraphRequest({
221244
path: 'api/ListGraphRequest',
222245
params: {
223246
...params,
247+
$select: select,
224248
random: random,
225249
},
226250
})
@@ -237,15 +261,36 @@ const GraphExplorer = () => {
237261
{({ form }) => (
238262
<OnChange name={field}>
239263
{(value) => {
264+
if (field == 'endpoint') {
265+
debounceEndpointChange(value)
266+
}
240267
if (value?.value) {
241268
let preset = presets.filter(function (obj) {
242269
return obj.id === value.value
243270
})
244271
if (preset[0]?.id !== '') {
245-
if (preset[0]?.params[set]) {
246-
onChange(preset[0]?.params[set])
272+
if (set == 'endpoint') {
273+
debounceEndpointChange(preset[0]?.params[set])
274+
}
275+
if (set == '$select') {
276+
if (preset[0]?.params[set]) {
277+
var properties = preset[0].params[set].split(',')
278+
var selectedProps = properties.map((prop) => {
279+
return {
280+
label: prop,
281+
value: prop,
282+
}
283+
})
284+
onChange(selectedProps)
285+
} else {
286+
onChange('')
287+
}
247288
} else {
248-
onChange(preset[0][set])
289+
if (preset[0]?.params[set]) {
290+
onChange(preset[0]?.params[set])
291+
} else {
292+
onChange(preset[0][set])
293+
}
249294
}
250295
}
251296
}
@@ -263,6 +308,10 @@ const GraphExplorer = () => {
263308

264309
function getPresetProps(values) {
265310
var newvals = Object.assign({}, values)
311+
console.log(newvals)
312+
if (newvals?.$select !== undefined && Array.isArray(newvals?.$select)) {
313+
newvals.$select = newvals?.$select.map((p) => p.value).join(',')
314+
}
266315
delete newvals['reportTemplate']
267316
delete newvals['tenantFilter']
268317
delete newvals['IsShared']
@@ -454,19 +503,38 @@ const GraphExplorer = () => {
454503
placeholder="Enter the Graph Endpoint you'd like to run the custom report for."
455504
/>
456505
<WhenFieldChanges field="reportTemplate" set="endpoint" />
506+
<WhenFieldChanges field="endpoint" set="endpoint" />
457507
<RFFCFormInput
458508
type="text"
459509
name="$filter"
460510
label="Filter"
461511
placeholder="Enter the filter string for the Graph query"
462512
/>
463513
<WhenFieldChanges field="reportTemplate" set="$filter" />
464-
<RFFCFormInput
465-
type="text"
466-
name="$select"
467-
label="Select"
468-
placeholder="Select the columns to use for this query"
469-
/>
514+
<div className="mb-3">
515+
<RFFSelectSearch
516+
name="$select"
517+
label="Select"
518+
placeholder="Select the columns to use for this query"
519+
retainInput={true}
520+
multi={true}
521+
values={
522+
availableProperties?.data?.Results
523+
? availableProperties?.data?.Results.map((prop) => {
524+
return {
525+
name: prop,
526+
value: prop,
527+
}
528+
})
529+
: []
530+
}
531+
allowCreate={true}
532+
refreshFunction={() =>
533+
setRandom3((Math.random() + 1).toString(36).substring(7))
534+
}
535+
isLoading={availableProperties.isFetching}
536+
/>
537+
</div>
470538
<WhenFieldChanges field="reportTemplate" set="$select" />
471539
<RFFCFormInput
472540
type="text"
@@ -504,6 +572,11 @@ const GraphExplorer = () => {
504572
<hr />
505573
<CippPage title="Report Results" tenantSelector={false}>
506574
{!searchNow && <span>Execute a search to get started.</span>}
575+
{graphrequest.isFetching && (
576+
<div className="my-2">
577+
<CSpinner className="me-2" /> Loading Data
578+
</div>
579+
)}
507580
{graphrequest.isSuccess && QueryColumns.set && searchNow && (
508581
<CCard className="content-card">
509582
<CCardHeader className="d-flex justify-content-between align-items-center">

version_latest.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5.2.0
1+
5.2.1

0 commit comments

Comments
 (0)