Skip to content

Commit 04290f2

Browse files
feat. added script to toggle permission
1 parent 923511f commit 04290f2

File tree

3 files changed

+130
-2
lines changed

3 files changed

+130
-2
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
"cordova-plugin-websocket": {},
3838
"cordova-plugin-buildinfo": {},
3939
"com.foxdebug.acode.rk.exec.proot": {},
40-
"com.foxdebug.acode.rk.exec.terminal": {},
41-
"cordova-plugin-system": {}
40+
"cordova-plugin-system": {},
41+
"com.foxdebug.acode.rk.exec.terminal": {}
4242
},
4343
"platforms": [
4444
"android"

src/plugins/terminal/plugin.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@
2323

2424
<source-file src="scripts/init-sandbox.sh" target-dir="assets"/>
2525
<source-file src="scripts/init-alpine.sh" target-dir="assets"/>
26+
27+
<config-file target="AndroidManifest.xml" parent="/manifest">
28+
29+
</config-file>
30+
2631

2732
</platform>
2833
</plugin>

utils/storage_manager.mjs

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#!/usr/bin/env node
2+
3+
import readline from 'node:readline';
4+
import { stdin as input, stdout as output } from 'node:process';
5+
import { readFile, writeFile } from 'node:fs/promises';
6+
import { join } from 'node:path';
7+
import { execSync } from 'node:child_process';
8+
9+
10+
const npmPrefix = execSync('npm prefix').toString().trim();
11+
const pluginXmlPath = join(npmPrefix, 'src/plugins/terminal/plugin.xml');
12+
const permissionLine = ` <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />`;
13+
const permissionRegex = /^\s*<uses-permission android:name="android\.permission\.MANAGE_EXTERNAL_STORAGE"\s*\/>\s*$/gm;
14+
15+
async function addPermission() {
16+
try {
17+
let xml = await readFile(pluginXmlPath, 'utf-8');
18+
19+
if (xml.includes('android.permission.MANAGE_EXTERNAL_STORAGE')) {
20+
console.log('Permission already exists in plugin.xml');
21+
return false;
22+
}
23+
24+
const pattern = /<config-file\s+target="AndroidManifest\.xml"\s+parent="\/manifest">\s*<\/config-file>/;
25+
26+
if (pattern.test(xml)) {
27+
xml = xml.replace(pattern, match => {
28+
return match.replace(
29+
'</config-file>',
30+
`\n${permissionLine}\n </config-file>`
31+
);
32+
});
33+
34+
await writeFile(pluginXmlPath, xml, 'utf-8');
35+
console.log('Permission added inside existing <config-file> block.');
36+
return true
37+
} else {
38+
console.error('Could not find <config-file parent="/manifest"> block.');
39+
return false
40+
}
41+
} catch (err) {
42+
console.error('Failed to add permission:', err);
43+
return false
44+
}
45+
}
46+
47+
async function removePermission() {
48+
try {
49+
let xml = await readFile(pluginXmlPath, 'utf-8');
50+
51+
if (!xml.includes('android.permission.MANAGE_EXTERNAL_STORAGE')) {
52+
console.log('Permission not found — nothing to remove.');
53+
return false;
54+
}
55+
56+
const cleanedXml = xml.replace(permissionRegex, '');
57+
await writeFile(pluginXmlPath, cleanedXml, 'utf-8');
58+
console.log('Permission removed from plugin.xml');
59+
return true
60+
} catch (err) {
61+
console.error('Failed to remove permission:', err);
62+
return false
63+
}
64+
}
65+
66+
67+
function updatePlugin() {
68+
try {
69+
const prefix = execSync('npm prefix').toString().trim();
70+
const pluginPath = join(prefix, 'src/plugins/terminal');
71+
72+
execSync('cordova plugin remove com.foxdebug.acode.rk.exec.terminal', { stdio: 'inherit' });
73+
execSync(`cordova plugin add "${pluginPath}"`, { stdio: 'inherit' });
74+
75+
console.log('✅ Plugin updated successfully.');
76+
} catch (err) {
77+
console.error(err.message);
78+
process.exit(1);
79+
}
80+
}
81+
82+
async function handleAnswer(answer) {
83+
answer = answer.trim().toLowerCase();
84+
if (answer === 'yes' || answer === 'y') {
85+
if(await addPermission()){
86+
updatePlugin()
87+
}
88+
89+
} else if (answer === 'no' || answer === 'n') {
90+
if(await removePermission()){
91+
updatePlugin()
92+
}
93+
94+
} else {
95+
console.error("Invalid input. Please type 'yes' or 'no'.");
96+
process.exit(1);
97+
}
98+
}
99+
100+
function prompt() {
101+
const rl = readline.createInterface({ input, output });
102+
rl.question("Enable 'MANAGE_EXTERNAL_STORAGE' permission? Y/n: ", async (answer) => {
103+
rl.close();
104+
await handleAnswer(answer);
105+
});
106+
}
107+
108+
const args = process.argv.slice(2);
109+
let answer = null;
110+
111+
if (args.includes('--yes') || args.includes('-y')) {
112+
answer = 'yes';
113+
} else if (args.includes('--no') || args.includes('-n')) {
114+
answer = 'no';
115+
} else if (args[0]) {
116+
answer = args[0];
117+
}
118+
119+
if (answer) {
120+
await handleAnswer(answer);
121+
} else {
122+
prompt();
123+
}

0 commit comments

Comments
 (0)