11< html >
22< head >
3- < script src ="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js "> </ script >
4- < script src ="/js/main.js "> </ script >
3+ < meta charset ="UTF-8 ">
4+ < script src ="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js "> </ script >
5+ < script src ="/js/main.js "> </ script >
6+ < script type ="module " src ="/js/dangerModal.js "> </ script >
7+ < script type ="module " src ="/js/operations.js "> </ script >
8+ < script type ="module " src ="/js/output.js "> </ script >
9+ < script type ="module " src ="/js/roleBadge.js "> </ script >
10+ < link rel ="stylesheet " href ="/css/style.css ">
511</ head >
612< body >
713< h1 > UID2 Env - Client Side Keypair Management</ h1 >
814
915< a href ="/ "> Back</ a >
1016
11- < br >
12- < br >
13-
14- < h3 > Inputs</ h3 >
15-
16- < label for ="subscriptionId "> Subscription id:</ label >
17- < input type ="text " id ="subscriptionId " name ="subscriptionId ">
18- < label for ="siteId "> Site id:</ label >
19- < input type ="text " id ="siteId " name ="siteId ">
20- < label for ="name "> Keypair Name:</ label >
21- < input type ="text " id ="name " name ="name ">
22- < label for ="disable "> Disable Keypair:</ label >
23- < input type ="checkbox " id ="disable " name ="disable " value ="true ">
24-
25- < br >
26- < br >
27-
28- < h3 > Operations</ h3 >
29-
30- < ul >
31- < li class ="ro-sem " style ="display: none "> < a href ="# " id ="doList "> List Keypairs</ a > </ li >
32- < li class ="ro-sem " style ="display: none "> < a href ="# " id ="doListSite "> List Keypairs By Site Id</ a > </ li >
33- < li class ="ro-sem " style ="display: none "> < a href ="# " id ="doListSubscription "> Reveal Keypair By Subscription Id</ a > </ li >
34- < li class ="ro-sem " style ="display: none "> < a href ="# " id ="doCreate "> Create Keypair</ a > </ li >
35- < li class ="ro-sem " style ="display: none "> < a href ="# " id ="doUpdate "> Update Keypair</ a > </ li >
36- < li class ="ro-sem " style ="display: none "> < a href ="# " id ="doDelete "> Delete Keypair</ a > </ li >
37- </ ul >
38-
39- < br >
40-
41- < h3 > Output</ h3 >
42-
43- < div id ="output ">
44- < pre id ="errorOutput "> </ pre >
45- < pre id ="standardOutput "> </ pre >
17+ < div class ="main-content ">
18+ < div class ="operations-container "> </ div >
19+ < div class ="output-container "> </ div >
4620</ div >
4721
48- < script language ="JavaScript ">
49- $ ( document ) . ready ( function ( ) {
50- $ ( '#doList' ) . on ( 'click' , function ( ) {
51- doApiCall ( 'GET' , '/api/client_side_keypairs/list' , '#standardOutput' , '#errorOutput' ) ;
52- } ) ;
53-
54- $ ( '#doListSite' ) . on ( 'click' , function ( ) {
55- const siteId = parseInt ( $ ( '#siteId' ) . val ( ) )
56- if ( ! siteId ) {
57- $ ( '#errorOutput' ) . text ( "required parameters: site_id" )
58- return
22+ < script type ="module ">
23+ import { initializeOperations } from '/js/operations.js' ;
24+ import { initializeOutput } from '/js/output.js' ;
25+
26+ document . addEventListener ( 'DOMContentLoaded' , function ( ) {
27+ const operationConfig = [
28+ {
29+ type : 'read-only' ,
30+ title : 'Read Only Operations' ,
31+ operations : [
32+ {
33+ id : 'doList' ,
34+ title : 'List Keypairs' ,
35+ role : 'maintainer' ,
36+ inputs : [ ] ,
37+ apiCall : {
38+ method : 'GET' ,
39+ url : '/api/client_side_keypairs/list'
40+ }
41+ } ,
42+ {
43+ id : 'doListSite' ,
44+ title : 'List Keypairs By Site ID' ,
45+ role : 'maintainer' ,
46+ inputs : [
47+ {
48+ id : 'siteId-listSite' ,
49+ name : 'siteId' ,
50+ label : 'Site ID' ,
51+ required : true ,
52+ size : 1 ,
53+ type : 'number'
5954 }
60- doApiCallWithCallback ( 'GET' , '/api/client_side_keypairs/list' , function ( text ) {
61- let resp = JSON . parse ( text )
62- resp = resp . filter ( obj => obj . site_id === siteId )
63- $ ( '#standardOutput' ) . text ( JSON . stringify ( resp , null , 2 ) ) ;
64- } , errorCallback ) ;
65- } ) ;
66-
67- $ ( '#doListSubscription' ) . on ( 'click' , function ( ) {
68- const subscriptionId = $ ( '#subscriptionId' ) . val ( )
69- if ( ! subscriptionId ) {
70- $ ( '#errorOutput' ) . text ( "required parameters: subscription_id" )
71- return
55+ ] ,
56+ apiCall : {
57+ method : 'GET' ,
58+ url : '/api/client_side_keypairs/list'
59+ } ,
60+ postProcess : ( response , inputs ) => {
61+ const siteId = parseInt ( inputs . siteId ) ;
62+ return response . filter ( keypair => keypair . site_id === siteId ) ;
63+ }
64+ } ,
65+ {
66+ id : 'doListSubscription' ,
67+ title : 'Get Keypair By Subscription ID' ,
68+ role : 'maintainer' ,
69+ inputs : [
70+ {
71+ id : 'subscriptionId-get' ,
72+ name : 'subscriptionId' ,
73+ label : 'Subscription ID' ,
74+ required : true ,
75+ size : 2
7276 }
73- const url = '/api/client_side_keypairs/' + encodeURIComponent ( subscriptionId ) ;
74-
75- doApiCall ( 'GET' , url , '#standardOutput' , '#errorOutput' ) ;
76- } ) ;
77-
78- $ ( '#doCreate' ) . on ( 'click' , function ( ) {
79- const siteId = $ ( '#siteId' ) . val ( ) ;
80- const name = $ ( '#name' ) . val ( ) ;
81- const disabled = ( $ ( '#disable' ) . is ( ':checked' ) ) ;
82- if ( ! siteId ) {
83- $ ( '#errorOutput' ) . text ( "required parameters: site_id" )
84- return
77+ ] ,
78+ apiCall : {
79+ method : 'GET' ,
80+ getUrl : ( inputs ) => `/api/client_side_keypairs/${ encodeURIComponent ( inputs . subscriptionId ) } `
81+ }
82+ }
83+ ]
84+ } ,
85+ {
86+ type : 'write' ,
87+ title : 'Write Operations' ,
88+ operations : [
89+ {
90+ id : 'doCreate' ,
91+ title : 'Add Keypair' ,
92+ role : 'maintainer' ,
93+ inputs : [
94+ {
95+ id : 'siteId-create' ,
96+ name : 'siteId' ,
97+ label : 'Site ID' ,
98+ required : true ,
99+ size : 1 ,
100+ type : 'number'
101+ } ,
102+ {
103+ id : 'name-create' ,
104+ name : 'name' ,
105+ label : 'Keypair Name' ,
106+ required : false ,
107+ size : 2
108+ } ,
109+ {
110+ id : 'disable-create' ,
111+ name : 'disable' ,
112+ label : 'Disable Keypair' ,
113+ type : 'checkbox' ,
114+ size : 1
85115 }
86-
87- const payload = { "site_id" : parseInt ( siteId ) , "name" : name , "disabled" : disabled }
88-
89- doApiCall ( 'POST' , '/api/client_side_keypairs/add' , '#standardOutput' , '#errorOutput' , JSON . stringify ( payload ) ) ;
90- } ) ;
91-
92- $ ( '#doUpdate' ) . on ( 'click' , function ( ) {
93- const subscriptionId = $ ( '#subscriptionId' ) . val ( )
94- const name = $ ( '#name' ) . val ( ) ;
95- const disabled = ( $ ( '#disable' ) . is ( ':checked' ) ) ;
96-
97- if ( ! subscriptionId ) {
98- $ ( '#errorOutput' ) . text ( "required parameters: subscription_id" )
99- return
116+ ] ,
117+ apiCall : {
118+ method : 'POST' ,
119+ url : '/api/client_side_keypairs/add' ,
120+ getPayload : ( inputs ) => ( {
121+ site_id : parseInt ( inputs . siteId ) ,
122+ name : inputs . name || '' ,
123+ disabled : inputs . disable || false
124+ } )
125+ }
126+ } ,
127+ {
128+ id : 'doUpdate' ,
129+ title : 'Update Keypair' ,
130+ role : 'maintainer' ,
131+ inputs : [
132+ {
133+ id : 'subscriptionId-update' ,
134+ name : 'subscriptionId' ,
135+ label : 'Subscription ID' ,
136+ required : true ,
137+ size : 2
138+ } ,
139+ {
140+ id : 'name-update' ,
141+ name : 'name' ,
142+ label : 'Keypair Name' ,
143+ required : false ,
144+ size : 2
145+ } ,
146+ {
147+ id : 'disable-update' ,
148+ name : 'disable' ,
149+ label : 'Disable Keypair' ,
150+ type : 'checkbox' ,
151+ size : 1
100152 }
101-
102- const confirmationMessage = getUpdateKeypairConfirmationMessage ( disabled , subscriptionId ) ;
103- if ( ! confirm ( confirmationMessage ) ) return ;
104-
105- const payload = { "subscription_id" : subscriptionId , "disabled" : disabled }
106- if ( name ) {
107- payload [ "name" ] = name
153+ ] ,
154+ preProcess : ( inputs ) => {
155+ // Show confirmation dialog with appropriate message
156+ const disabled = inputs . disable ;
157+ const action = disabled ? 'disable' : 'enable' ;
158+ const baseMessage = `You may ignore this warning if you are not changing the disabled status of this keypair.\n\nAre you sure you want to ${ action } ${ inputs . subscriptionId } ?` ;
159+
160+ let confirmationMessage ;
161+ if ( disabled ) {
162+ confirmationMessage = `Disabling this client-side keypair will prevent it from using CSTG.\nBefore proceeding, ensure there is no valid traffic, and confirm that the participant has provided consent.\n\n${ baseMessage } ` ;
163+ } else {
164+ confirmationMessage = `Enabling this client-side keypair will allow it to use CSTG.\n\n${ baseMessage } ` ;
108165 }
109-
110- doApiCall ( 'POST' , '/api/client_side_keypairs/update' , '#standardOutput' , '#errorOutput' , JSON . stringify ( payload ) ) ;
111- } ) ;
112-
113- $ ( '#doDelete' ) . on ( 'click' , function ( ) {
114- const subscriptionId = $ ( '#subscriptionId' ) . val ( ) ;
115- if ( ! subscriptionId ) {
116- $ ( '#errorOutput' ) . text ( "required parameters: subscription_id" ) ;
117- return ;
166+
167+ return confirm ( confirmationMessage ) ? inputs : null ;
168+ } ,
169+ apiCall : {
170+ method : 'POST' ,
171+ url : '/api/client_side_keypairs/update' ,
172+ getPayload : ( inputs ) => {
173+ const payload = {
174+ subscription_id : inputs . subscriptionId ,
175+ disabled : inputs . disable || false
176+ } ;
177+ if ( inputs . name ) {
178+ payload . name = inputs . name ;
179+ }
180+ return payload ;
118181 }
119-
120- if ( ! confirm ( `Are you sure you want to delete ${ subscriptionId } ?` ) ) return ;
121-
122- const payload = { "subscription_id" : subscriptionId } ;
123-
124- doApiCall ( 'POST' , '/api/client_side_keypairs/delete' , '#standardOutput' , '#errorOutput' , JSON . stringify ( payload ) ) ;
125- } ) ;
126-
127- } ) ;
128-
129- function getUpdateKeypairConfirmationMessage ( disabled , subscriptionId ) {
130- let action = disabled ? 'disable' : 'enable' ;
131- let confirmationMessage = `You may ignore this warning if you are not changing the disabled status of this keypair.\n\nAre you sure you want to ${ action } ${ subscriptionId } ?` ;
132-
133- if ( disabled ) {
134- confirmationMessage = `Disabling this client-side keypair will prevent it from using CSTG.\nBefore proceeding, ensure there is no valid traffic, and confirm that the participant has provided consent.\n\n${ confirmationMessage } ` ;
135- } else {
136- confirmationMessage = `Enabling this client-side keypair will allow it to use CSTG.\n\n${ confirmationMessage } ` ;
182+ }
137183 }
138- return confirmationMessage ;
184+ ]
185+ } ,
186+ {
187+ type : 'danger-zone' ,
188+ title : '☠️ Danger Zone ☠️' ,
189+ operations : [
190+ {
191+ id : 'doDelete' ,
192+ title : 'Delete Keypair' ,
193+ role : 'elevated' ,
194+ inputs : [
195+ {
196+ id : 'subscriptionId-delete' ,
197+ name : 'subscriptionId' ,
198+ label : 'Subscription ID' ,
199+ required : true ,
200+ size : 2
201+ }
202+ ] ,
203+ description : 'This will permanently delete the client-side keypair. This action cannot be undone.' ,
204+ preProcess : ( inputs ) => {
205+ const message = `Are you sure you want to delete ${ inputs . subscriptionId } ?` ;
206+ return confirm ( message ) ? inputs : null ;
207+ } ,
208+ apiCall : {
209+ method : 'POST' ,
210+ url : '/api/client_side_keypairs/delete' ,
211+ getPayload : ( inputs ) => ( {
212+ subscription_id : inputs . subscriptionId
213+ } )
214+ }
215+ }
216+ ]
139217 }
218+ ] ;
219+
220+ initializeOperations ( operationConfig ) ;
221+ initializeOutput ( ) ;
222+ } ) ;
140223</ script >
141224
142225</ body >
143- </ html >
226+ </ html >
0 commit comments