Skip to content

Commit 1febb6f

Browse files
committed
Fix certificate sync issue when choose upload option for both normal cert and km cert
1 parent 12f4ae2 commit 1febb6f

File tree

3 files changed

+86
-33
lines changed

3 files changed

+86
-33
lines changed

portals/admin/src/main/webapp/source/src/app/components/KeyManagers/AddEditKeyManager.jsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,7 +1735,12 @@ function AddEditKeyManager(props) {
17351735
</Grid>
17361736
<Grid item xs={12} md={12} lg={9}>
17371737
<Box component='div' m={1}>
1738-
<Certificates certificates={certificates} dispatch={dispatch} isConfigCert={false} />
1738+
<Certificates
1739+
fieldName='certificates'
1740+
certificates={certificates}
1741+
dispatch={dispatch}
1742+
isJwksNeeded
1743+
/>
17391744
</Box>
17401745
</Grid>
17411746
<Grid item xs={12}>
@@ -1783,8 +1788,6 @@ function AddEditKeyManager(props) {
17831788
setAdditionalProperties={setAdditionalProperties}
17841789
hasErrors={hasErrors}
17851790
validating={validating}
1786-
dispatch={dispatch}
1787-
certificates={certificates}
17881791
/>
17891792
</Box>
17901793
</Grid>

portals/admin/src/main/webapp/source/src/app/components/KeyManagers/Certificates.jsx

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from 'react';
1+
import React, { useState, useEffect } from 'react';
22
import Radio from '@mui/material/Radio';
33
import RadioGroup from '@mui/material/RadioGroup';
44
import FormControlLabel from '@mui/material/FormControlLabel';
@@ -16,29 +16,51 @@ import Tabs from '@mui/material/Tabs';
1616
import Tab from '@mui/material/Tab';
1717
import Alert from 'AppComponents/Shared/Alert';
1818

19-
const cache = {};
2019
/**
2120
* Renders the certificate add/edit page.
2221
* @param {JSON} props Input props form parent components.
2322
* @returns {JSX} Certificate upload/add UI.
2423
*/
2524
export default function Certificates(props) {
2625
const intl = useIntl();
27-
const { certificates: { type, value }, dispatch, isConfigCert } = props;
26+
const {
27+
fieldName,
28+
[fieldName]: { type, value },
29+
dispatch,
30+
isJwksNeeded,
31+
} = props;
2832
const [selectedTab, setSelectedTab] = useState(0);
2933
const [file, setFile] = useState(null);
30-
cache[type] = value;
34+
// Keep certificate cache local to this instance
35+
const [certCache, setCertCache] = useState({
36+
PEM: '',
37+
JWKS: '',
38+
});
39+
40+
// Update cache when value changes
41+
useEffect(() => {
42+
setCertCache((prev) => ({
43+
...prev,
44+
[type]: value,
45+
}));
46+
}, [type, value]);
3147

3248
const onDrop = (acceptedFile) => {
3349
const reader = new FileReader();
3450
setFile(acceptedFile[0]);
3551
reader.readAsText(acceptedFile[0], 'UTF-8');
3652
reader.onload = (evt) => {
53+
const newValue = btoa(evt.target.result);
54+
// Update both cache and parent
55+
setCertCache((prev) => ({
56+
...prev,
57+
[type]: newValue,
58+
}));
3759
dispatch({
38-
field: 'certificates',
60+
field: fieldName,
3961
value: {
4062
type,
41-
value: btoa(evt.target.result),
63+
value: newValue,
4264
},
4365
});
4466
};
@@ -53,19 +75,26 @@ export default function Certificates(props) {
5375
const handleChange = (event) => {
5476
const { value: selected, name } = event.target;
5577
if (name === 'certificateType') {
78+
// When switching certificate type, use the cached value for that type
5679
dispatch({
57-
field: 'certificates',
80+
field: fieldName,
5881
value: {
5982
type: selected,
60-
value: cache[selected],
83+
value: certCache[selected] || '',
6184
},
6285
});
6386
} else {
87+
// When updating certificate value, update both cache and parent
88+
const newValue = name === 'certificateValueUrl' ? selected : btoa(selected);
89+
setCertCache((prev) => ({
90+
...prev,
91+
[type]: newValue,
92+
}));
6493
dispatch({
65-
field: 'certificates',
94+
field: fieldName,
6695
value: {
6796
type,
68-
value: name === 'certificateValueUrl' ? selected : btoa(selected),
97+
value: newValue,
6998
},
7099
});
71100
}
@@ -75,7 +104,7 @@ export default function Certificates(props) {
75104
};
76105
return (
77106
<>
78-
{!isConfigCert && (
107+
{isJwksNeeded && (
79108
<FormControl variant='standard' component='fieldset'>
80109
<RadioGroup
81110
style={{ flexDirection: 'row' }}
@@ -106,7 +135,7 @@ export default function Certificates(props) {
106135
onChange={handleChange}
107136
/>
108137
)}
109-
{(isConfigCert || type === 'PEM') && (
138+
{(!isJwksNeeded || type === 'PEM') && (
110139
<>
111140
<AppBar position='static' color='default'>
112141
<Tabs value={selectedTab} onChange={handleTabChange}>
@@ -175,7 +204,13 @@ export default function Certificates(props) {
175204
</>
176205
);
177206
}
207+
Certificates.defaultProps = {
208+
fieldName: 'certificates',
209+
isJwksNeeded: false,
210+
};
211+
178212
Certificates.propTypes = {
179-
certificates: PropTypes.shape({}).isRequired,
213+
fieldName: PropTypes.string,
180214
dispatch: PropTypes.func.isRequired,
215+
isJwksNeeded: PropTypes.bool,
181216
};

portals/admin/src/main/webapp/source/src/app/components/KeyManagers/KeyManagerConfiguration.jsx

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect } from 'react';
1+
import React, { useEffect, useReducer } from 'react';
22
import { styled } from '@mui/material/styles';
33
import {
44
TextField, Checkbox, FormControlLabel, Box, FormLabel, FormControl,
@@ -10,6 +10,20 @@ import { FormattedMessage } from 'react-intl';
1010

1111
const StyledSpan = styled('span')(({ theme }) => ({ color: theme.palette.error.dark }));
1212

13+
/**
14+
* Reducer
15+
* @param {JSON} state The second number.
16+
* @returns {Promise}
17+
*/
18+
function certificateReducer(state, newValue) {
19+
const { field, value } = newValue;
20+
if (field === 'tenantWideCertificates') {
21+
return { ...state, [field]: value };
22+
} else {
23+
return newValue;
24+
}
25+
}
26+
1327
export default function KeyManagerConfiguration(props) {
1428
const {
1529
keymanagerConnectorConfigurations,
@@ -19,22 +33,18 @@ export default function KeyManagerConfiguration(props) {
1933
validating,
2034
} = props;
2135

22-
const dispatch = (action) => {
23-
// Handle certificate updates based on the field name
24-
if (action.field === 'certificates') {
25-
// Store the complete certificate object
26-
setAdditionalProperties('certificates', {
27-
type: action.value.type,
28-
value: action.value.value,
29-
});
36+
// Change from constant to state
37+
const [tenantWideCertificates, dispatch] = useReducer(certificateReducer,
38+
additionalProperties?.certificates || {
39+
type: 'PEM',
40+
value: '',
41+
});
42+
// Add effect to watch for changes
43+
useEffect(() => {
44+
if (tenantWideCertificates) {
45+
setAdditionalProperties('certificates', tenantWideCertificates);
3046
}
31-
};
32-
33-
// Update certificates structure to match what Certificates.jsx expects
34-
const certificates = additionalProperties?.certificates || {
35-
type: 'PEM',
36-
value: '',
37-
};
47+
}, [tenantWideCertificates, setAdditionalProperties]);
3848

3949
const onChange = (e) => {
4050
const {
@@ -267,7 +277,12 @@ export default function KeyManagerConfiguration(props) {
267277
{label}
268278
{required && <StyledSpan>*</StyledSpan>}
269279
</FormLabel>
270-
<Certificates certificates={certificates} dispatch={dispatch} isConfigCert />
280+
<Certificates
281+
fieldName='tenantWideCertificates'
282+
tenantWideCertificates={tenantWideCertificates}
283+
dispatch={dispatch}
284+
isJwksNeeded={false}
285+
/>
271286
</FormControl>
272287
);
273288
}

0 commit comments

Comments
 (0)