11import { exec , spawn , toast } from "kernelsu-alt" ;
22import '@material/web/all.js' ;
3+ import { translations , loadTranslations } from './locales.js' ;
34
45let scriptOnly = false ;
56let shellRunning = false ;
@@ -54,6 +55,8 @@ function applyButtonEventListeners() {
5455 const confirmFetchBtn = document . getElementById ( 'confirm-fetch' ) ;
5556 const githubBtn = document . getElementById ( 'github-btn' ) ;
5657 const helpBtn = document . getElementById ( 'help-btn' ) ;
58+ const helpDialog = document . getElementById ( 'help-dialog' ) ;
59+ const romSignCheck = document . getElementById ( 'rom-sign-check' ) ;
5760
5861 fetchBtn . onclick = ( ) => {
5962 if ( randomRadio . checked ) randomRadio . checked = false ;
@@ -84,21 +87,21 @@ function applyButtonEventListeners() {
8487 lines . forEach ( line => appendToOutput ( line ) ) ;
8588 appendToOutput ( "" ) ;
8689 } else {
87- appendToOutput ( `[!] Failed to read pif.prop : ${ result . stderr } ` , true ) ;
90+ appendToOutput ( `[!] ${ translations . output_error_read_pif_prop } : ${ result . stderr } ` , true ) ;
8891 }
8992 }
9093
9194 securityPatchBtn . onclick = async ( ) => {
9295 await exec ( `sh ${ moddir } /security_patch.sh --${ securityPatchBtn . selected ? 'enable' : 'disable' } ` ) ;
9396 await loadAutoSecurityPatchConfig ( ) ;
94- appendToOutput ( `[+] ${ securityPatchBtn . selected ? 'Enabled' : 'Disbled' } auto security patch.` ) ;
97+ appendToOutput ( `[+] ${ securityPatchBtn . selected ? translations . output_enabled : translations . output_disabled } auto security patch.` ) ;
9598 }
9699
97100 scriptOnlyBtn . onclick = async ( ) => {
98101 await exec ( `${ scriptOnly ? 'rm -rf /data/adb/pif_script_only' : 'touch /data/adb/pif_script_only' } || true` ) ;
99102 killGms ( ) ;
100103 loadScriptOnlyConfig ( ) ;
101- appendToOutput ( `[+] ${ scriptOnly ? 'Disabled' : 'Enabled' } script only mode.` ) ;
104+ appendToOutput ( `[+] ${ scriptOnly ? translations . output_disabled : translations . output_enabled } script only mode.` ) ;
102105 }
103106
104107 confirmFetchBtn . addEventListener ( 'click' , ( e ) => {
@@ -143,7 +146,19 @@ function applyButtonEventListeners() {
143146 } ) ;
144147
145148 githubBtn . onclick = ( ) => linkRedirect ( `https://github.com/${ repository } /releases/latest` ) ;
146- helpBtn . onclick = ( ) => linkRedirect ( `https://github.com/${ repository } #options` ) ;
149+ helpBtn . onclick = ( ) => helpDialog . show ( ) ;
150+
151+ romSignCheck . onclick = ( ) => {
152+ const command = romSignCheck . parentElement . querySelector ( 'code' ) . textContent ;
153+ appendToOutput ( command ) ;
154+ appendToOutput ( '' ) ;
155+ exec ( command ) . then ( ( result ) => {
156+ const isSuccess = result . errno === 0 ;
157+ setTimeout ( ( ) => {
158+ appendToOutput ( isSuccess ? result . stdout : result . stderr , ! isSuccess ) ;
159+ } , 600 ) ;
160+ } ) ;
161+ }
147162}
148163
149164function linkRedirect ( link ) {
@@ -188,8 +203,8 @@ async function loadSpoofConfig() {
188203
189204 if ( model === null ) model = pifMap . MODEL ;
190205 } catch ( error ) {
191- appendToOutput ( `[!] Failed to load spoof config : ${ error } ` , true ) ;
192- appendToOutput ( '[!] Warning: Do not use third party tools to fetch pif.prop' ) ;
206+ appendToOutput ( `[!] ${ translations . output_error_load_spoof_config } : ${ error } ` , true ) ;
207+ appendToOutput ( '[!] ' + translations . output_warning_third_party_tool ) ;
193208 resetPifProp ( ) ;
194209 }
195210}
@@ -202,7 +217,7 @@ function resetPifProp() {
202217 return response . text ( ) ;
203218 } )
204219 . catch ( error => {
205- return fetch ( `https://raw .gitmirror.com/${ repository } /${ branch } /module/pif.prop` )
220+ return fetch ( `https://hub .gitmirror.com/raw.githubusercontent .com/${ repository } /${ branch } /module/pif.prop` )
206221 . then ( response => {
207222 if ( ! response . ok ) throw new Error ( `HTTP error! status: ${ response . status } ` ) ;
208223 return response . text ( ) ;
@@ -212,16 +227,16 @@ function resetPifProp() {
212227 const pifProp = text . trim ( ) ;
213228 const { errno, stderr } = await exec ( `
214229 echo '${ pifProp } ' > ${ moddir } /pif.prop
215- rm -f /data/adb/pif.prop || true
230+ rm -f /data/adb/pif.prop
216231 ` ) ;
217232 if ( errno === 0 ) {
218- appendToOutput ( ` [+] Successfully reset pif.prop` ) ;
233+ appendToOutput ( ' [+] ' + translations . output_reset_pif_prop ) ;
219234 } else {
220- appendToOutput ( `[!] Failed to reset pif.prop: ${ stderr } ` , true ) ;
235+ throw new Error ( stderr ) ;
221236 }
222237 } )
223238 . catch ( error => {
224- appendToOutput ( `[!] Failed to reset pif.prop : ${ error . message } ` ) ;
239+ appendToOutput ( `[!] ${ translations . output_error_reset_failed } : ${ error . message } ` , true ) ;
225240 } ) ;
226241}
227242
@@ -238,7 +253,6 @@ function setupSpoofConfigButton() {
238253 [ ! -f /data/adb/pif.prop ] || echo "/data/adb/pif.prop"
239254 ` ) ;
240255 result . stdout . on ( 'data' , ( data ) => pifFile += data + '\n' ) ;
241- result . stderr . on ( 'data' , ( data ) => appendToOutput ( `[!] Failed to find pif.prop: ` + data , true ) ) ;
242256 result . on ( 'exit' , ( code ) => {
243257 if ( code !== 0 ) return ;
244258 updateSpoofConfig ( toggle , item . config , pifFile ) ;
@@ -284,34 +298,21 @@ function updateSpoofConfig(toggle, type, pifFile) {
284298 if ( code === 0 ) {
285299 if ( prompted ) return ;
286300 prompted = true ;
287- appendToOutput ( `[+] ${ toggle . selected ? "Enabled" : "Disabled" } ${ type } ` ) ;
301+ appendToOutput ( `[+] ${ toggle . selected ? translations . output_enabled : translations . output_disabled } ${ type } ` ) ;
288302 } else {
289303 throw new Error ( 'Failed to write ' + pifFile ) ;
290304 }
291305 } ) ;
292306
293307 // reminder
294308 if ( ! reminded && ( type === "spoofVendingBuild" || type === "spoofVendingSdk" ) && pifMap . spoofVendingBuild && pifMap . spoofVendingSdk ) {
295- appendToOutput ( '[!] spoofVendingSdk will not take effect when spoofVendingBuild is enabled.' ) ;
309+ appendToOutput ( '[!] ' + translations . output_spoofVendingSdk_spoofVendingBuild ) ;
296310 reminded = true ;
297311 }
298-
299- // reminder
300- if ( ! reminded && type === "spoofSignature" ) {
301- reminded = true ;
302- const signature = await exec ( 'unzip -l /system/etc/security/otacerts.zip | grep -oE "testkey|releasekey"' ) ;
303- if ( signature . errno === 0 ) {
304- if ( signature . stdout . trim ( ) === "testkey" && ! pifMap . spoofSignature ) {
305- appendToOutput ( '[!] Unsigned ROM detected, enable spoofSignature to fix.' ) ;
306- } else if ( signature . stdout . trim ( ) === "releasekey" && pifMap . spoofSignature ) {
307- appendToOutput ( '[+] Signed ROM detected, enabling spoofSignature might not be useful.' ) ;
308- }
309- }
310- }
311312 } ) ;
312313 } catch ( error ) {
313314 console . error ( `Failed to update ${ pifFile } :` , error ) ;
314- appendToOutput ( `[!] Failed to ${ toggle . selected ? "enable" : "disable" } ${ item . config } ` ) ;
315+ appendToOutput ( `[!] ${ toggle . selected ? output_error_enable_failed : output_error_disable_failed } ${ item . config } ` ) ;
315316 }
316317 }
317318}
@@ -344,29 +345,19 @@ function runAction() {
344345 if ( model && product ) opts = { env : { MODEL : `"${ model } "` , PRODUCT : `"${ product } "` } } ;
345346 const scriptOutput = spawn ( "sh" , [ `${ moddir } /autopif.sh` ] , opts ) ;
346347 scriptOutput . stdout . on ( 'data' , ( data ) => appendToOutput ( data ) ) ;
347- scriptOutput . stderr . on ( 'data' , ( data ) => appendToOutput ( `[!] Error executing autopif.sh: ${ data } ` , true ) ) ;
348+ scriptOutput . stderr . on ( 'data' , ( data ) => appendToOutput ( data , true ) ) ;
348349 scriptOutput . on ( 'exit' , ( ) => {
349350 appendToOutput ( "" ) ;
350351 muteToggle ( false ) ;
351352 } ) ;
352- scriptOutput . on ( 'error' , ( ) => {
353- appendToOutput ( "[!] Error: Fail to execute autopif.sh" , true ) ;
354- appendToOutput ( "" ) ;
355- muteToggle ( false ) ;
356- } ) ;
357353}
358354
359355function updateAutopif ( ) {
360356 muteToggle ( true ) ;
361357 const scriptOutput = spawn ( "sh" , [ `${ moddir } /autopif_ota.sh` ] ) ;
362358 scriptOutput . stdout . on ( 'data' , ( data ) => appendToOutput ( data ) ) ;
363- scriptOutput . stderr . on ( 'data' , ( data ) => appendToOutput ( `[!] Error executing autopif_ota.sh: ${ data } ` , true ) ) ;
359+ scriptOutput . stderr . on ( 'data' , ( data ) => appendToOutput ( data , true ) ) ;
364360 scriptOutput . on ( 'exit' , ( ) => muteToggle ( false ) ) ;
365- scriptOutput . on ( 'error' , ( ) => {
366- appendToOutput ( "[!] Error: Fail to execute autopif_ota.sh" , true ) ;
367- appendToOutput ( "" ) ;
368- muteToggle ( false ) ;
369- } ) ;
370361}
371362
372363function muteToggle ( mute , scriptOnly = null ) {
@@ -454,7 +445,7 @@ function loadScriptOnlyConfig() {
454445}
455446
456447function fetchPifProp ( ) {
457- appendToOutput ( "[+] Fetching pif.prop from GitHub..." ) ;
448+ appendToOutput ( "[+] " + translations . output_fetching_from_github ) ;
458449 appendToOutput ( "" ) ;
459450 fetch ( `https://raw.githubusercontent.com/${ repository } /bot/device_prop/${ product } .prop` )
460451 . then ( response => {
489480 if ( result . errno === 0 ) {
490481 result . stdout . split ( '\n' ) . forEach ( line => appendToOutput ( line ) ) ;
491482 } else {
492- appendToOutput ( " [!] Failed to write /data/adb/pif.prop: " + result . stderr , true ) ;
483+ appendToOutput ( ` [!] ${ translations . output_error_write_pif_prop } : ` + result . stderr , true ) ;
493484 }
494485 killGms ( ) ;
495486 } ) ;
496487 } )
497488 . catch ( error => {
498- appendToOutput ( ' [!] Failed to fetch pif.prop: ' + error , true ) ;
489+ appendToOutput ( ` [!] ${ translations . output_error_fetch_pif_prop } : ` + error , true ) ;
499490 } ) ;
500491}
501492
@@ -544,7 +535,7 @@ function setupDeviceList() {
544535 } ) ;
545536 } )
546537 . catch ( error => {
547- list . querySelector ( '#device-list-loading' ) . innerHTML = ' <div>Failed to load device list </div>' ;
538+ list . querySelector ( '#device-list-loading' ) . innerHTML = ` <div>${ translations . device_list_load_failed } </div>` ;
548539 document . getElementById ( 'confirm-fetch' ) . disabled = true ;
549540 } ) ;
550541}
@@ -558,22 +549,37 @@ function checkPropDate() {
558549 different="$(($current_epoch - $prop_epoch))"
559550 if [ $different -gt 5184000 ]; then
560551 # 60d * 24h * 60m * 60s = 5184000
561- echo "[!] pif.prop is likely outdated, consider fetching once to update it. "
552+ echo "outdated"
562553 fi
563554 ` , { env : { PATH : "$PATH:/data/adb/ap/bin:/data/adb/ksu/bin:/data/adb/magisk" } } ) . then ( ( result ) => {
564- if ( result . stdout . trim ( ) !== '' ) appendToOutput ( result . stdout . trim ( ) , true ) ;
555+ if ( result . stdout . includes ( "outdated" ) ) appendToOutput ( '[!] ' + translations . output_oudated_pif_prop , true ) ;
565556 } ) ;
566557}
567558
559+ // Notify when selinux is permissive
568560function checkSeLinuxStatus ( ) {
569561 exec ( 'getenforce' ) . then ( ( result ) => {
570562 if ( result . errno !== 0 ) return ;
571563 if ( result . stdout . trim ( ) === 'Permissive' ) {
572- appendToOutput ( "[!] SELinux status is permissive." , true )
564+ appendToOutput ( "[!] " + translations . output_selinux_permissive , true )
573565 }
574566 } ) ;
575567}
576568
569+ // Notify spoofSignature is on/off when rom is signed with releasekey/testkey
570+ function checkRomSignature ( ) {
571+ const toggle = document . getElementById ( 'spoofSignature' ) ;
572+ exec ( 'unzip -l /system/etc/security/otacerts.zip | grep -oE "testkey|releasekey"' ) . then ( ( signature ) => {
573+ if ( signature . errno === 0 ) {
574+ if ( signature . stdout . trim ( ) === "testkey" && ! toggle . selected ) {
575+ appendToOutput ( '[!] ' + translations . output_testkey ) ;
576+ } else if ( signature . stdout . trim ( ) === "releasekey" && toggle . selected ) {
577+ appendToOutput ( '[+] ' + translations . output_releasekey ) ;
578+ }
579+ }
580+ } ) . catch ( ( ) => { } ) ;
581+ }
582+
577583function getDistance ( touch1 , touch2 ) {
578584 return Math . hypot (
579585 touch1 . clientX - touch2 . clientX ,
@@ -638,6 +644,7 @@ document.querySelectorAll('md-dialog').forEach(dialog => {
638644} ) ;
639645
640646document . addEventListener ( 'DOMContentLoaded' , async ( ) => {
647+ await loadTranslations ( ) ;
641648 checkMMRL ( ) ;
642649 appendSpoofConfigToggles ( ) ;
643650 loadVersionFromModuleProp ( ) ;
@@ -649,6 +656,7 @@ document.addEventListener('DOMContentLoaded', async () => {
649656 updateAutopif ( ) ;
650657 checkSeLinuxStatus ( ) ;
651658 checkPropDate ( ) ;
659+ checkRomSignature ( ) ;
652660
653661 document . querySelectorAll ( '[unresolved]' ) . forEach ( el => el . removeAttribute ( 'unresolved' ) ) ;
654662} ) ;
0 commit comments