@@ -7,6 +7,9 @@ $(document).ready(function () {
77 checkObfs : contentSection . dataset . checkObfsUrl ,
88 enableObfs : contentSection . dataset . enableObfsUrl ,
99 disableObfs : contentSection . dataset . disableObfsUrl ,
10+ checkMasquerade : contentSection . dataset . checkMasqueradeUrl ,
11+ enableMasquerade : contentSection . dataset . enableMasqueradeUrl ,
12+ disableMasquerade : contentSection . dataset . disableMasqueradeUrl ,
1013 setPortTemplate : contentSection . dataset . setPortUrlTemplate ,
1114 setSniTemplate : contentSection . dataset . setSniUrlTemplate ,
1215 updateGeoTemplate : contentSection . dataset . updateGeoUrlTemplate
@@ -23,10 +26,10 @@ $(document).ready(function () {
2326 return / ^ [ 0 - 9 ] + $ / . test ( port ) && parseInt ( port ) > 0 && parseInt ( port ) <= 65535 ;
2427 }
2528
26- function confirmAction ( actionName , callback ) {
29+ function confirmAction ( title , text , callback ) {
2730 Swal . fire ( {
28- title : `Are you sure?` ,
29- text : `Do you really want to ${ actionName } ?` ,
31+ title : title ,
32+ text : text ,
3033 icon : "warning" ,
3134 showCancelButton : true ,
3235 confirmButtonColor : "#3085d6" ,
@@ -53,13 +56,12 @@ $(document).ready(function () {
5356 }
5457 } ,
5558 success : function ( response ) {
56- Swal . fire ( "Success!" , successMessage , "success" ) . then ( ( ) => {
57- if ( showReload ) {
59+ const message = typeof response . detail === 'string' ? response . detail : successMessage ;
60+ Swal . fire ( "Success!" , message , "success" ) . then ( ( ) => {
61+ if ( showReload && ! postSuccessCallback ) {
5862 location . reload ( ) ;
59- } else {
60- if ( postSuccessCallback ) {
61- postSuccessCallback ( response ) ;
62- }
63+ } else if ( postSuccessCallback ) {
64+ postSuccessCallback ( response ) ;
6365 }
6466 } ) ;
6567 } ,
@@ -83,7 +85,6 @@ $(document).ready(function () {
8385 }
8486 }
8587 Swal . fire ( "Error!" , errorMessage , "error" ) ;
86- console . error ( "AJAX Error:" , status , error , xhr . responseText ) ;
8788 } ,
8889 complete : function ( ) {
8990 if ( buttonSelector ) {
@@ -118,95 +119,122 @@ $(document).ready(function () {
118119 }
119120
120121 function initUI ( ) {
121- $ . ajax ( {
122- url : API_URLS . getPort ,
123- type : "GET" ,
124- success : function ( data ) {
125- $ ( "#hysteria_port" ) . val ( data . port || "" ) ;
126- } ,
127- error : function ( xhr , status , error ) {
128- console . error ( "Failed to fetch port:" , error , xhr . responseText ) ;
129- }
130- } ) ;
131-
132- $ . ajax ( {
133- url : API_URLS . getSni ,
134- type : "GET" ,
135- success : function ( data ) {
136- $ ( "#sni_domain" ) . val ( data . sni || "" ) ;
137- } ,
138- error : function ( xhr , status , error ) {
139- console . error ( "Failed to fetch SNI domain:" , error , xhr . responseText ) ;
140- }
141- } ) ;
122+ $ . get ( API_URLS . getPort , data => $ ( "#hysteria_port" ) . val ( data . port || "" ) ) ;
123+ $ . get ( API_URLS . getSni , data => $ ( "#sni_domain" ) . val ( data . sni || "" ) ) ;
142124 }
143125
144- function fetchObfsStatus ( ) {
145- $ . ajax ( {
146- url : API_URLS . checkObfs ,
147- type : "GET" ,
148- success : function ( data ) {
149- updateObfsUI ( data . obfs ) ;
150- } ,
151- error : function ( xhr , status , error ) {
152- $ ( "#obfs_status_message" ) . html ( '<span class="text-danger">Failed to fetch OBFS status.</span>' ) ;
153- console . error ( "Failed to fetch OBFS status:" , error , xhr . responseText ) ;
154- $ ( "#obfs_enable_btn" ) . hide ( ) ;
155- $ ( "#obfs_disable_btn" ) . hide ( ) ;
156- }
126+ function fetchAllStatuses ( ) {
127+ Promise . all ( [
128+ $ . ajax ( { url : API_URLS . checkObfs , type : "GET" } ) ,
129+ $ . ajax ( { url : API_URLS . checkMasquerade , type : "GET" } )
130+ ] ) . then ( ( [ obfsResponse , masqueradeResponse ] ) => {
131+ const obfsStatus = obfsResponse . obfs ;
132+ const masqueradeStatus = masqueradeResponse . status ;
133+
134+ const isObfsActive = obfsStatus === "OBFS is active." ;
135+ const isMasqueradeActive = masqueradeStatus === "Enabled" ;
136+
137+ updateObfsUI ( obfsStatus , isMasqueradeActive ) ;
138+ updateMasqueradeUI ( masqueradeStatus , isObfsActive ) ;
139+
140+ } ) . catch ( error => {
141+ console . error ( "Failed to fetch statuses:" , error ) ;
142+ $ ( "#obfs_status_message" ) . html ( '<span class="text-danger">Failed to fetch status.</span>' ) ;
143+ $ ( "#masquerade_status_message" ) . html ( '<span class="text-danger">Failed to fetch status.</span>' ) ;
157144 } ) ;
158145 }
146+
147+ function updateObfsUI ( statusMessage , isMasqueradeEnabled ) {
148+ const container = $ ( "#obfs_status_container" ) ;
149+ const msgElement = $ ( "#obfs_status_message" ) ;
150+ const enableBtn = $ ( "#obfs_enable_btn" ) ;
151+ const disableBtn = $ ( "#obfs_disable_btn" ) ;
159152
160- function updateObfsUI ( statusMessage ) {
161- $ ( "#obfs_status_message" ) . text ( statusMessage ) ;
162- if ( statusMessage === "OBFS is active." ) {
163- $ ( "#obfs_enable_btn" ) . hide ( ) ;
164- $ ( "#obfs_disable_btn" ) . show ( ) ;
165- $ ( "#obfs_status_container" ) . removeClass ( "border-danger border-warning alert-danger alert-warning" ) . addClass ( "border-success alert-success" ) ;
153+ container . removeClass ( "border-success alert-success border-warning alert-warning border-danger alert-danger border-info alert-info" ) ;
154+ enableBtn . hide ( ) ;
155+ disableBtn . hide ( ) ;
156+
157+ if ( isMasqueradeEnabled ) {
158+ msgElement . text ( "Cannot be managed while Masquerade is active." ) ;
159+ container . addClass ( "border-info alert-info" ) ;
160+ } else if ( statusMessage === "OBFS is active." ) {
161+ msgElement . text ( statusMessage ) ;
162+ disableBtn . show ( ) ;
163+ container . addClass ( "border-success alert-success" ) ;
166164 } else if ( statusMessage === "OBFS is not active." ) {
167- $ ( "#obfs_enable_btn" ) . show ( ) ;
168- $ ( "#obfs_disable_btn" ) . hide ( ) ;
169- $ ( "#obfs_status_container" ) . removeClass ( "border-success border-danger alert-success alert-danger" ) . addClass ( "border-warning alert-warning" ) ;
165+ msgElement . text ( statusMessage ) ;
166+ enableBtn . show ( ) ;
167+ container . addClass ( "border-warning alert-warning" ) ;
170168 } else {
171- $ ( "#obfs_enable_btn" ) . hide ( ) ;
172- $ ( "#obfs_disable_btn" ) . hide ( ) ;
173- $ ( "#obfs_status_container" ) . removeClass ( "border-success border-warning alert-success alert-warning" ) . addClass ( "border-danger alert-danger" ) ;
169+ msgElement . html ( `<span class="text-danger">${ statusMessage } </span>` ) ;
170+ container . addClass ( "border-danger alert-danger" ) ;
171+ }
172+ }
173+
174+ function updateMasqueradeUI ( statusMessage , isObfsEnabled ) {
175+ const container = $ ( "#masquerade_status_container" ) ;
176+ const msgElement = $ ( "#masquerade_status_message" ) ;
177+ const enableBtn = $ ( "#masquerade_enable_btn" ) ;
178+ const disableBtn = $ ( "#masquerade_disable_btn" ) ;
179+
180+ container . removeClass ( "border-success alert-success border-warning alert-warning border-danger alert-danger border-info alert-info" ) ;
181+ enableBtn . hide ( ) ;
182+ disableBtn . hide ( ) ;
183+
184+ if ( isObfsEnabled ) {
185+ msgElement . text ( "Cannot be managed while OBFS is active." ) ;
186+ container . addClass ( "border-info alert-info" ) ;
187+ } else if ( statusMessage === "Enabled" ) {
188+ msgElement . text ( statusMessage ) ;
189+ disableBtn . show ( ) ;
190+ container . addClass ( "border-success alert-success" ) ;
191+ } else if ( statusMessage === "Disabled" ) {
192+ msgElement . text ( statusMessage ) ;
193+ enableBtn . show ( ) ;
194+ container . addClass ( "border-warning alert-warning" ) ;
195+ } else {
196+ msgElement . html ( `<span class="text-danger">${ statusMessage } </span>` ) ;
197+ container . addClass ( "border-danger alert-danger" ) ;
174198 }
175199 }
176200
177201 function enableObfs ( ) {
178- confirmAction ( "enable OBFS" , function ( ) {
179- sendRequest (
180- API_URLS . enableObfs ,
181- "GET" ,
182- null ,
183- "OBFS enabled successfully!" ,
184- "#obfs_enable_btn" ,
185- false ,
186- fetchObfsStatus
187- ) ;
188- } ) ;
202+ confirmAction (
203+ "Enable OBFS?" ,
204+ "This will require all users to update their configuration files to reconnect." ,
205+ ( ) => sendRequest ( API_URLS . enableObfs , "GET" , null , "OBFS enabled successfully!" , "#obfs_enable_btn" , false , fetchAllStatuses )
206+ ) ;
189207 }
190208
191209 function disableObfs ( ) {
192- confirmAction ( "disable OBFS" , function ( ) {
193- sendRequest (
194- API_URLS . disableObfs ,
195- "GET" ,
196- null ,
197- "OBFS disabled successfully!" ,
198- "#obfs_disable_btn" ,
199- false ,
200- fetchObfsStatus
201- ) ;
202- } ) ;
210+ confirmAction (
211+ "Disable OBFS?" ,
212+ "This will disconnect all current users. They must update their configurations to reconnect." ,
213+ ( ) => sendRequest ( API_URLS . disableObfs , "GET" , null , "OBFS disabled successfully!" , "#obfs_disable_btn" , false , fetchAllStatuses )
214+ ) ;
215+ }
216+
217+ function enableMasquerade ( ) {
218+ confirmAction (
219+ "Enable Masquerade?" ,
220+ "This will enable the string masquerade mode." ,
221+ ( ) => sendRequest ( API_URLS . enableMasquerade , "GET" , null , "Masquerade enabled successfully!" , "#masquerade_enable_btn" , false , fetchAllStatuses )
222+ ) ;
223+ }
224+
225+ function disableMasquerade ( ) {
226+ confirmAction (
227+ "Disable Masquerade?" ,
228+ "This will disable the masquerade feature." ,
229+ ( ) => sendRequest ( API_URLS . disableMasquerade , "GET" , null , "Masquerade disabled successfully!" , "#masquerade_disable_btn" , false , fetchAllStatuses )
230+ ) ;
203231 }
204232
205233 function changePort ( ) {
206234 if ( ! validateForm ( 'port_form' ) ) return ;
207235 const port = $ ( "#hysteria_port" ) . val ( ) ;
208236 const url = API_URLS . setPortTemplate . replace ( "PORT_PLACEHOLDER" , port ) ;
209- confirmAction ( "change the port" , function ( ) {
237+ confirmAction ( "Are you sure?" , "Do you really want to change the port? ", ( ) => {
210238 sendRequest ( url , "GET" , null , "Port changed successfully!" , "#port_change" ) ;
211239 } ) ;
212240 }
@@ -215,7 +243,7 @@ $(document).ready(function () {
215243 if ( ! validateForm ( 'sni_form' ) ) return ;
216244 const domain = $ ( "#sni_domain" ) . val ( ) ;
217245 const url = API_URLS . setSniTemplate . replace ( "SNI_PLACEHOLDER" , domain ) ;
218- confirmAction ( "change the SNI" , function ( ) {
246+ confirmAction ( "Are you sure?" , "Do you really want to change the SNI? ", ( ) => {
219247 sendRequest ( url , "GET" , null , "SNI changed successfully!" , "#sni_change" ) ;
220248 } ) ;
221249 }
@@ -225,42 +253,29 @@ $(document).ready(function () {
225253 const buttonId = `#geo_update_${ country } ` ;
226254 const url = API_URLS . updateGeoTemplate . replace ( 'COUNTRY_PLACEHOLDER' , country ) ;
227255
228- confirmAction ( `update the Geo files for ${ countryName } ` , function ( ) {
229- sendRequest (
230- url ,
231- "GET" ,
232- null ,
233- `Geo files for ${ countryName } updated successfully!` ,
234- buttonId ,
235- false ,
236- null
237- ) ;
238- } ) ;
256+ confirmAction (
257+ "Update Geo Files?" ,
258+ `Do you really want to update the Geo files for ${ countryName } ?` ,
259+ ( ) => sendRequest ( url , "GET" , null , `Geo files for ${ countryName } updated successfully!` , buttonId , false , null )
260+ ) ;
239261 }
240262
241263 initUI ( ) ;
242- fetchObfsStatus ( ) ;
264+ fetchAllStatuses ( ) ;
243265
244266 $ ( "#port_change" ) . on ( "click" , changePort ) ;
245267 $ ( "#sni_change" ) . on ( "click" , changeSNI ) ;
246268 $ ( "#obfs_enable_btn" ) . on ( "click" , enableObfs ) ;
247269 $ ( "#obfs_disable_btn" ) . on ( "click" , disableObfs ) ;
248- $ ( "#geo_update_iran" ) . on ( "click" , function ( ) { updateGeo ( 'iran' ) ; } ) ;
249- $ ( "#geo_update_china" ) . on ( "click" , function ( ) { updateGeo ( 'china' ) ; } ) ;
250- $ ( "#geo_update_russia" ) . on ( "click" , function ( ) { updateGeo ( 'russia' ) ; } ) ;
251-
252- $ ( '#sni_domain' ) . on ( 'input' , function ( ) {
253- if ( isValidDomain ( $ ( this ) . val ( ) ) ) {
254- $ ( this ) . removeClass ( 'is-invalid' ) ;
255- } else if ( $ ( this ) . val ( ) . trim ( ) !== "" ) {
256- $ ( this ) . addClass ( 'is-invalid' ) ;
257- } else {
258- $ ( this ) . removeClass ( 'is-invalid' ) ;
259- }
260- } ) ;
270+ $ ( "#masquerade_enable_btn" ) . on ( "click" , enableMasquerade ) ;
271+ $ ( "#masquerade_disable_btn" ) . on ( "click" , disableMasquerade ) ;
272+ $ ( "#geo_update_iran" ) . on ( "click" , ( ) => updateGeo ( 'iran' ) ) ;
273+ $ ( "#geo_update_china" ) . on ( "click" , ( ) => updateGeo ( 'china' ) ) ;
274+ $ ( "#geo_update_russia" ) . on ( "click" , ( ) => updateGeo ( 'russia' ) ) ;
261275
262- $ ( '#hysteria_port' ) . on ( 'input' , function ( ) {
263- if ( isValidPort ( $ ( this ) . val ( ) ) ) {
276+ $ ( '#sni_domain, #hysteria_port' ) . on ( 'input' , function ( ) {
277+ const validator = $ ( this ) . attr ( 'id' ) === 'sni_domain' ? isValidDomain : isValidPort ;
278+ if ( validator ( $ ( this ) . val ( ) ) ) {
264279 $ ( this ) . removeClass ( 'is-invalid' ) ;
265280 } else if ( $ ( this ) . val ( ) . trim ( ) !== "" ) {
266281 $ ( this ) . addClass ( 'is-invalid' ) ;
0 commit comments