@@ -5,26 +5,24 @@ const wireGuardConfig = document.querySelector('.wire-guard-config');
55const v2rayConfig = document . querySelector ( '.v2ray-config' ) ;
66const container = document . querySelector ( '.container' ) ;
77
8- // Event Listener for Config Button
8+ // Event: Generate Config
99getConfigBtn . addEventListener ( 'click' , async ( ) => {
1010 getConfigBtn . disabled = true ;
1111 getConfigBtn . textContent = 'Generating...' ;
12- console . log ( 'Button clicked!' ) ;
1312 try {
1413 showSpinner ( ) ;
1514 const { publicKey, privateKey } = await fetchKeys ( ) ;
1615 const installId = generateRandomString ( 22 ) ;
1716 const fcmToken = `${ installId } :APA91b${ generateRandomString ( 134 ) } ` ;
1817 const accountData = await fetchAccount ( publicKey , installId , fcmToken ) ;
19- if ( accountData ) generateConfig ( accountData , privateKey ) ;
18+ if ( accountData ) await generateConfig ( accountData , privateKey ) ;
2019 } catch ( error ) {
2120 console . error ( 'Error processing configuration:' , error ) ;
2221 showPopup ( 'Failed to generate config. Please try again.' , 'error' ) ;
2322 } finally {
2423 hideSpinner ( ) ;
2524 getConfigBtn . disabled = false ;
2625 getConfigBtn . textContent = 'Get Free Config' ;
27- // Scroll to the config section after generating
2826 setTimeout ( ( ) => {
2927 if ( wireGuardConfig . firstChild ) {
3028 wireGuardConfig . scrollIntoView ( { behavior : 'smooth' , block : 'start' } ) ;
@@ -33,7 +31,7 @@ getConfigBtn.addEventListener('click', async () => {
3331 }
3432} ) ;
3533
36- // Fetch Public and Private Keys
34+ // Fetch Key Pair
3735const fetchKeys = async ( ) => {
3836 try {
3937 const response = await fetch ( 'https://www.iranguard.workers.dev/keys' ) ;
@@ -49,11 +47,11 @@ const fetchKeys = async () => {
4947 }
5048} ;
5149
52- // Extract Specific Key from Text Data
50+ // Extract key from text
5351const extractKey = ( data , keyName ) =>
5452 data . match ( new RegExp ( `${ keyName } :\\s(.+)` ) ) ?. [ 1 ] . trim ( ) || null ;
5553
56- // Fetch Account Configuration
54+ // Fetch Account Config
5755const fetchAccount = async ( publicKey , installId , fcmToken ) => {
5856 const apiUrl = 'https://www.iranguard.workers.dev/wg' ;
5957 try {
@@ -82,29 +80,48 @@ const fetchAccount = async (publicKey, installId, fcmToken) => {
8280 }
8381} ;
8482
85- // Generate and Display Configurations
86- const generateConfig = ( data , privateKey ) => {
83+ // Fetch random IPv4 endpoint
84+ const fetchRandomEndpoint = async ( ) => {
85+ const fallback = 'engage.cloudflareclient.com:2408' ;
86+ try {
87+ const res = await fetch ( 'https://raw.githubusercontent.com/ircfspace/endpoint/refs/heads/main/ip.json' ) ;
88+ if ( ! res . ok ) throw new Error ( `HTTP ${ res . status } ` ) ;
89+ const data = await res . json ( ) ;
90+ if ( ! Array . isArray ( data . ipv4 ) || data . ipv4 . length === 0 ) throw new Error ( "No IPv4 available" ) ;
91+ const random = data . ipv4 [ Math . floor ( Math . random ( ) * data . ipv4 . length ) ] ;
92+ return random ;
93+ } catch ( e ) {
94+ console . warn ( "Falling back to default endpoint:" , e ) ;
95+ return fallback ;
96+ }
97+ } ;
98+
99+ // Generate Config and Update UI
100+ const generateConfig = async ( data , privateKey ) => {
87101 const reserved = generateReserved ( data . config . client_id ) ;
88- const wireGuardText = generateWireGuardConfig ( data , privateKey ) ;
102+ const endpoint = await fetchRandomEndpoint ( ) ;
103+
104+ const wireGuardText = generateWireGuardConfig ( data , privateKey , endpoint ) ;
89105 const v2rayText = generateV2RayURL (
90106 privateKey ,
91107 data . config . peers [ 0 ] . public_key ,
92108 data . config . interface . addresses . v4 ,
93109 data . config . interface . addresses . v6 ,
94- reserved
110+ reserved ,
111+ endpoint
95112 ) ;
113+
96114 updateDOM ( wireGuardConfig , 'WireGuard Format' , 'wireguardBox' , wireGuardText , 'message1' ) ;
97115 updateDOM ( v2rayConfig , 'V2Ray Format' , 'v2rayBox' , v2rayText , 'message2' ) ;
98116 downloadBtn . style . display = 'block' ;
99-
100- // Add event listeners to newly created copy buttons
117+
101118 document . querySelectorAll ( '.copy-button' ) . forEach ( btn => {
102119 btn . addEventListener ( 'click' , handleCopyButtonClick ) ;
103120 } ) ;
104121} ;
105122
106- // Generate WireGuard Configuration Text
107- const generateWireGuardConfig = ( data , privateKey ) => `
123+ // WireGuard Config Template
124+ const generateWireGuardConfig = ( data , privateKey , endpoint ) => `
108125[Interface]
109126PrivateKey = ${ privateKey }
110127Address = ${ data . config . interface . addresses . v4 } /32, ${ data . config . interface . addresses . v6 } /128
@@ -114,25 +131,25 @@ MTU = 1280
114131[Peer]
115132PublicKey = ${ data . config . peers [ 0 ] . public_key }
116133AllowedIPs = 0.0.0.0/0, ::/0
117- Endpoint = engage.cloudflareclient.com:2408
134+ Endpoint = ${ endpoint }
118135` ;
119136
120- // Generate Reserved Parameter Dynamically
137+ // Reserved parameter
121138const generateReserved = ( clientId ) =>
122139 Array . from ( atob ( clientId ) )
123140 . map ( ( char ) => char . charCodeAt ( 0 ) )
124141 . slice ( 0 , 3 )
125142 . join ( '%2C' ) ;
126143
127144// Generate V2Ray URL
128- const generateV2RayURL = ( privateKey , publicKey , ipv4 , ipv6 , reserved ) =>
129- `wireguard://${ encodeURIComponent ( privateKey ) } @engage.cloudflareclient.com:2408 ?address=${ encodeURIComponent (
145+ const generateV2RayURL = ( privateKey , publicKey , ipv4 , ipv6 , reserved , endpoint ) =>
146+ `wireguard://${ encodeURIComponent ( privateKey ) } @${ endpoint } ?address=${ encodeURIComponent (
130147 ipv4 + '/32'
131148 ) } ,${ encodeURIComponent ( ipv6 + '/128' ) } &reserved=${ reserved } &publickey=${ encodeURIComponent (
132149 publicKey
133150 ) } &mtu=1420#V2ray-Config`;
134151
135- // Update DOM with Configurations
152+ // Update Config Boxes in UI
136153const updateDOM = ( container , title , textareaId , content , messageId ) => {
137154 container . innerHTML = `
138155 <h2>${ title } </h2>
@@ -142,19 +159,18 @@ const updateDOM = (container, title, textareaId, content, messageId) => {
142159 ` ;
143160} ;
144161
145- // Show and Hide Spinner
162+ // Spinner Show/ Hide
146163const showSpinner = ( ) => {
147164 const spinner = document . querySelector ( '.spinner' ) ;
148165 if ( spinner ) spinner . style . display = 'block' ;
149166} ;
150-
151167const hideSpinner = ( ) => {
152168 const spinner = document . querySelector ( '.spinner' ) ;
153169 if ( spinner ) spinner . style . display = 'none' ;
154170} ;
155171
156- // Handle Copy Button Click
157- const handleCopyButtonClick = async function ( e ) {
172+ // Handle Copy
173+ const handleCopyButtonClick = async function ( ) {
158174 const targetId = this . getAttribute ( 'data-target' ) ;
159175 const messageId = this . getAttribute ( 'data-message' ) ;
160176 try {
@@ -169,7 +185,7 @@ const handleCopyButtonClick = async function(e) {
169185 }
170186} ;
171187
172- // Show Copy Success or Error Message
188+ // Show Copy Message
173189const showCopyMessage = ( messageId , message ) => {
174190 const messageElement = document . getElementById ( messageId ) ;
175191 if ( messageElement ) {
@@ -182,21 +198,15 @@ const showCopyMessage = (messageId, message) => {
182198 }
183199} ;
184200
185- // Show popup notification
201+ // Show Popup Message
186202const showPopup = ( message , type = 'success' ) => {
187203 const popup = document . createElement ( 'div' ) ;
188204 popup . className = 'popup-message' ;
189205 popup . textContent = message ;
190-
191- if ( type === 'error' ) {
192- popup . style . backgroundColor = '#d32f2f' ;
193- }
194-
206+ if ( type === 'error' ) popup . style . backgroundColor = '#d32f2f' ;
195207 document . body . appendChild ( popup ) ;
196208 setTimeout ( ( ) => {
197- if ( popup . parentNode ) {
198- popup . parentNode . removeChild ( popup ) ;
199- }
209+ if ( popup . parentNode ) popup . parentNode . removeChild ( popup ) ;
200210 } , 2500 ) ;
201211} ;
202212
@@ -208,7 +218,7 @@ const generateRandomString = (length) =>
208218 )
209219 ) . join ( '' ) ;
210220
211- // Download Configuration as File
221+ // Download Config Button
212222downloadBtn . addEventListener ( 'click' , ( ) => {
213223 const content = document . querySelector ( '#wireguardBox' ) ?. value || "No configuration available" ;
214224 if ( content === "No configuration available" ) {
@@ -219,6 +229,7 @@ downloadBtn.addEventListener('click', () => {
219229 showPopup ( 'Configuration file downloaded' ) ;
220230} ) ;
221231
232+ // Download Config File
222233const downloadConfig = ( fileName , content ) => {
223234 const element = document . createElement ( 'a' ) ;
224235 const file = new Blob ( [ content ] , { type : 'text/plain' } ) ;
@@ -229,20 +240,15 @@ const downloadConfig = (fileName, content) => {
229240 document . body . removeChild ( element ) ;
230241} ;
231242
232- // Check for viewport size changes
243+ // Responsive UI
233244function checkViewportSize ( ) {
234245 if ( window . innerWidth <= 480 ) {
235- // For very small screens
236246 container . style . padding = '15px' ;
237247 } else if ( window . innerWidth <= 768 ) {
238- // For small screens
239248 container . style . padding = '20px' ;
240249 } else {
241- // For larger screens
242250 container . style . padding = '32px' ;
243251 }
244252}
245-
246- // Run on page load and when window is resized
247253window . addEventListener ( 'load' , checkViewportSize ) ;
248- window . addEventListener ( 'resize' , checkViewportSize ) ;
254+ window . addEventListener ( 'resize' , checkViewportSize ) ;
0 commit comments