Skip to content

Commit bf58c1d

Browse files
committed
feat: Add secret rotation
1 parent 3e03dbc commit bf58c1d

File tree

3 files changed

+66
-5
lines changed

3 files changed

+66
-5
lines changed

internal/portal/src/common/Icons.tsx

+12
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,18 @@ export const CollapseIcon = () => (
229229
</svg>
230230
);
231231

232+
export const RotateIcon = () => (
233+
<svg
234+
width="16"
235+
height="16"
236+
viewBox="0 0 16 16"
237+
fill="none"
238+
xmlns="http://www.w3.org/2000/svg"
239+
>
240+
<path d="M8.0002 12.8002C6.66686 12.8002 5.53353 12.3335 4.6002 11.4002C3.66686 10.4669 3.2002 9.33353 3.2002 8.0002C3.2002 6.66686 3.66686 5.53353 4.6002 4.6002C5.53353 3.66686 6.66686 3.2002 8.0002 3.2002C8.72242 3.2002 9.39186 3.3502 10.0085 3.6502C10.6252 3.9502 11.1558 4.3502 11.6002 4.8502V3.8002C11.6002 3.6302 11.6574 3.48769 11.7717 3.37269C11.886 3.25769 12.0277 3.2002 12.1967 3.2002C12.3657 3.2002 12.5085 3.25769 12.6252 3.37269C12.7419 3.48769 12.8002 3.6302 12.8002 3.8002V6.6002C12.8002 6.7702 12.7427 6.9127 12.6277 7.0277C12.5127 7.1427 12.3702 7.2002 12.2002 7.2002H9.4002C9.2302 7.2002 9.0877 7.14303 8.9727 7.02871C8.8577 6.91438 8.8002 6.77271 8.8002 6.60371C8.8002 6.4347 8.8577 6.29186 8.9727 6.1752C9.0877 6.05853 9.2302 6.0002 9.4002 6.0002H10.9835C10.6613 5.51131 10.2391 5.12242 9.71686 4.83353C9.19464 4.54464 8.62242 4.4002 8.0002 4.4002C7.0002 4.4002 6.1502 4.7502 5.4502 5.4502C4.7502 6.1502 4.4002 7.0002 4.4002 8.0002C4.4002 9.0002 4.7502 9.8502 5.4502 10.5502C6.1502 11.2502 7.0002 11.6002 8.0002 11.6002C8.83353 11.6002 9.56686 11.3474 10.2002 10.8419C10.8335 10.3363 11.2502 9.7002 11.4502 8.93353C11.4946 8.77797 11.5863 8.65575 11.7252 8.56686C11.8641 8.47797 12.0115 8.44464 12.1674 8.46686C12.3337 8.48908 12.4669 8.56408 12.5669 8.69186C12.6669 8.81964 12.7002 8.96131 12.6669 9.11686C12.4113 10.1835 11.8558 11.0641 11.0002 11.7585C10.1446 12.453 9.14464 12.8002 8.0002 12.8002Z" />
241+
</svg>
242+
);
243+
232244
export const Loading = () => (
233245
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="24px">
234246
<radialGradient

internal/portal/src/scenes/Destination/Destination.scss

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
rgba(0, 0, 0, 0.08) 100%
1515
),
1616
var(--colors-background-neutral-2);
17-
background-color: var(--COLORS_BACKGROUND_CONTAINER_PRIMARY_LIGHT);
17+
background-color: var(--colors-background-neutral-2);
1818
border-radius: var(--radius-m);
1919
box-shadow: var(--colors-shadow-button);
2020

@@ -40,7 +40,7 @@
4040

4141
.tabs-container {
4242
margin-top: 24px;
43-
border-bottom: 1px solid #e5e7eb;
43+
border-bottom: 1px solid var(--colors-outline-neutral);
4444
}
4545

4646
.tabs {
@@ -83,8 +83,8 @@
8383
align-items: flex-start;
8484

8585
> span:first-child {
86-
width: 140px;
87-
min-width: 140px;
86+
width: 200px;
87+
min-width: 200px;
8888
color: var(--colors-foreground-neutral-2);
8989
}
9090

internal/portal/src/scenes/Destination/DestinationSettings/DestinationSettings.tsx

+50-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ import TopicPicker from "../../../common/TopicPicker/TopicPicker";
44
import { useNavigate } from "react-router-dom";
55

66
import "./DestinationSettings.scss";
7-
import { DeleteIcon, DisableIcon, SaveIcon } from "../../../common/Icons";
7+
import {
8+
DeleteIcon,
9+
DisableIcon,
10+
RotateIcon,
11+
SaveIcon,
12+
} from "../../../common/Icons";
813
import { ApiContext } from "../../../app";
914
import { mutate } from "swr";
1015
import { showToast } from "../../../common/Toast/Toast";
@@ -30,6 +35,7 @@ const DestinationSettings = ({
3035
const [isTopicsSaving, setIsTopicsSaving] = useState(false);
3136
const [isConfigSaving, setIsConfigSaving] = useState(false);
3237
const [isDeleting, setIsDeleting] = useState(false);
38+
const [isRotatingSecret, setIsRotatingSecret] = useState(false);
3339

3440
const handleToggleEnabled = () => {
3541
if (!destination.disabled_at) {
@@ -133,6 +139,32 @@ const DestinationSettings = ({
133139
});
134140
};
135141

142+
const handleRotateSecret = () => {
143+
setIsRotatingSecret(true);
144+
apiClient
145+
.fetch(`destinations/${destination.id}`, {
146+
method: "PATCH",
147+
body: JSON.stringify({
148+
credentials: {
149+
rotate_secret: true,
150+
},
151+
}),
152+
})
153+
.then((data) => {
154+
showToast("success", "Secret rotated successfully");
155+
mutate(`destinations/${destination.id}`, data, false);
156+
})
157+
.catch((error) => {
158+
showToast(
159+
"error",
160+
`${error.message.charAt(0).toUpperCase() + error.message.slice(1)}`
161+
);
162+
})
163+
.finally(() => {
164+
setIsRotatingSecret(false);
165+
});
166+
};
167+
136168
const [isConfigFormValid, setIsConfigFormValid] = useState(false);
137169

138170
const handleConfigFormValidation = (e: React.FormEvent<HTMLFormElement>) => {
@@ -214,6 +246,23 @@ const DestinationSettings = ({
214246
</Button>
215247
</form>
216248
</div>
249+
250+
{type.type === "webhook" && (
251+
<>
252+
<hr />
253+
<div className="destination-settings__actions">
254+
<h2 className="title-l">Rotate Secret</h2>
255+
<p className="body-m muted">
256+
Rotate the destination signing secret. This will generate a new
257+
secret and invalid the current one after 24 hours.
258+
</p>
259+
<Button onClick={handleRotateSecret} loading={isRotatingSecret}>
260+
<RotateIcon />
261+
Rotate
262+
</Button>
263+
</div>
264+
</>
265+
)}
217266
<hr />
218267
<div className="destination-settings__actions">
219268
<h2 className="title-l">

0 commit comments

Comments
 (0)