@@ -4,7 +4,12 @@ import TopicPicker from "../../../common/TopicPicker/TopicPicker";
4
4
import { useNavigate } from "react-router-dom" ;
5
5
6
6
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" ;
8
13
import { ApiContext } from "../../../app" ;
9
14
import { mutate } from "swr" ;
10
15
import { showToast } from "../../../common/Toast/Toast" ;
@@ -30,6 +35,7 @@ const DestinationSettings = ({
30
35
const [ isTopicsSaving , setIsTopicsSaving ] = useState ( false ) ;
31
36
const [ isConfigSaving , setIsConfigSaving ] = useState ( false ) ;
32
37
const [ isDeleting , setIsDeleting ] = useState ( false ) ;
38
+ const [ isRotatingSecret , setIsRotatingSecret ] = useState ( false ) ;
33
39
34
40
const handleToggleEnabled = ( ) => {
35
41
if ( ! destination . disabled_at ) {
@@ -133,6 +139,32 @@ const DestinationSettings = ({
133
139
} ) ;
134
140
} ;
135
141
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
+
136
168
const [ isConfigFormValid , setIsConfigFormValid ] = useState ( false ) ;
137
169
138
170
const handleConfigFormValidation = ( e : React . FormEvent < HTMLFormElement > ) => {
@@ -214,6 +246,23 @@ const DestinationSettings = ({
214
246
</ Button >
215
247
</ form >
216
248
</ 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
+ ) }
217
266
< hr />
218
267
< div className = "destination-settings__actions" >
219
268
< h2 className = "title-l" >
0 commit comments