u2a 3.4.19 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/src/commands/configure.js +63 -0
- package/src/index.js +8 -0
- package/src/utils/appGenerator.js +1 -1
- package/src/utils/builder.js +2 -1
- package/src/utils/config.js +6 -0
- package/src/utils/logger.js +13 -1
- package/src/utils/noroot.js +7 -3
- package/src/utils/postinstall.js +126 -0
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "u2a",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
4
4
|
"description": "URL to App - Turn any URL into a desktop application",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"u2a": "src/index.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"start": "node src/index.js"
|
|
10
|
+
"start": "node src/index.js",
|
|
11
|
+
"postinstall": "node src/utils/postinstall.js"
|
|
11
12
|
},
|
|
12
13
|
"keywords": [
|
|
13
14
|
"cli",
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const { SETTINGS_PATH } = require('../utils/config');
|
|
3
|
+
const Logger = require('../utils/logger');
|
|
4
|
+
const chalk = require('chalk');
|
|
5
|
+
|
|
6
|
+
const logger = new Logger('configure');
|
|
7
|
+
|
|
8
|
+
function configureReports(action) {
|
|
9
|
+
try {
|
|
10
|
+
let settings = {};
|
|
11
|
+
if (fs.existsSync(SETTINGS_PATH)) {
|
|
12
|
+
settings = JSON.parse(fs.readFileSync(SETTINGS_PATH, 'utf8'));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (action === 'status') {
|
|
16
|
+
const status = settings.send_anon_reports !== false;
|
|
17
|
+
logger.info(`Anonymous reports are currently ${status ? chalk.green('enabled') : chalk.yellow('disabled')}`);
|
|
18
|
+
return;
|
|
19
|
+
} else if (action === 'enable') {
|
|
20
|
+
settings.send_anon_reports = true;
|
|
21
|
+
logger.info(chalk.green('Anonymous reports have been enabled'));
|
|
22
|
+
} else if (action === 'disable') {
|
|
23
|
+
settings.send_anon_reports = false;
|
|
24
|
+
logger.info(chalk.yellow('Anonymous reports have been disabled'));
|
|
25
|
+
} else {
|
|
26
|
+
logger.error(`Invalid action: ${action}`);
|
|
27
|
+
logger.info('Available actions: status, enable, disable');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
fs.writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2));
|
|
32
|
+
} catch (err) {
|
|
33
|
+
logger.error(`Error configuring reports`, err.message);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function configure(category, action) {
|
|
38
|
+
if (!category || !action) {
|
|
39
|
+
logger.error('Missing category or action');
|
|
40
|
+
logger.info('Usage: u2a configure [category] [action]');
|
|
41
|
+
logger.info('Available categories:');
|
|
42
|
+
logger.info(' reports - Configure anonymous usage reports');
|
|
43
|
+
logger.info('Available actions:');
|
|
44
|
+
logger.info(' status - Check current status');
|
|
45
|
+
logger.info(' enable - Enable specified category');
|
|
46
|
+
logger.info(' disable - Disable specified category');
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
switch (category) {
|
|
51
|
+
case 'reports':
|
|
52
|
+
configureReports(action);
|
|
53
|
+
break;
|
|
54
|
+
default:
|
|
55
|
+
logger.error(`Unknown configuration category: ${category}`);
|
|
56
|
+
logger.info('Available categories: reports');
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = {
|
|
62
|
+
configure
|
|
63
|
+
};
|
package/src/index.js
CHANGED
|
@@ -11,6 +11,7 @@ const { program } = require('commander');
|
|
|
11
11
|
const { createApp } = require('./commands/create');
|
|
12
12
|
const { listApps } = require('./commands/list');
|
|
13
13
|
const { removeApp } = require('./commands/remove');
|
|
14
|
+
const { configure } = require('./commands/configure');
|
|
14
15
|
const { version } = require('../package.json');
|
|
15
16
|
const { setupConfig } = require('./utils/config');
|
|
16
17
|
const { checkNotRoot } = require('./utils/noroot');
|
|
@@ -50,6 +51,13 @@ setupConfig();
|
|
|
50
51
|
.description('Remove an existing application')
|
|
51
52
|
.action(removeApp);
|
|
52
53
|
|
|
54
|
+
program
|
|
55
|
+
.command('configure [category] [action]')
|
|
56
|
+
.description('Configure application settings')
|
|
57
|
+
.action((category, action) => {
|
|
58
|
+
configure(category, action);
|
|
59
|
+
});
|
|
60
|
+
|
|
53
61
|
program.on('command:*', () => {
|
|
54
62
|
console.error(`\nInvalid command: ${program.args.join(' ')}`);
|
|
55
63
|
console.log(`\nUse --help to see the list of available commands.`);
|
|
@@ -254,7 +254,7 @@ app.on('activate', () => {
|
|
|
254
254
|
}
|
|
255
255
|
});
|
|
256
256
|
`;
|
|
257
|
-
}
|
|
257
|
+
} // note for one day: put this in a different file
|
|
258
258
|
|
|
259
259
|
async function createPackageJson(appName, iconPath, isExecutable = false, createSetup = false) {
|
|
260
260
|
const u2aPackagePath = path.resolve(__dirname, '../../package.json');
|
package/src/utils/builder.js
CHANGED
|
@@ -114,7 +114,8 @@ async function buildSetup(appDir, platform, arch) {
|
|
|
114
114
|
return null;
|
|
115
115
|
}
|
|
116
116
|
} catch (error) {
|
|
117
|
-
logger.error(`Error while building setup
|
|
117
|
+
logger.error(`Error while building setup.`, error);
|
|
118
|
+
logger.warn('Try to run u2a with administrator privileges to avoid this error.');
|
|
118
119
|
return null;
|
|
119
120
|
}
|
|
120
121
|
}
|
package/src/utils/config.js
CHANGED
|
@@ -6,6 +6,7 @@ const CONFIG_DIR = path.join(os.homedir(), '.u2a');
|
|
|
6
6
|
const APPS_DIR = path.join(CONFIG_DIR, 'apps');
|
|
7
7
|
const LOGS_DIR = path.join(CONFIG_DIR, 'logs');
|
|
8
8
|
const DB_PATH = path.join(CONFIG_DIR, 'db.json');
|
|
9
|
+
const SETTINGS_PATH = path.join(CONFIG_DIR, 'settings.json');
|
|
9
10
|
|
|
10
11
|
function setupConfig() {
|
|
11
12
|
if (!fs.existsSync(CONFIG_DIR)) {
|
|
@@ -20,6 +21,9 @@ function setupConfig() {
|
|
|
20
21
|
if (!fs.existsSync(DB_PATH)) {
|
|
21
22
|
fs.writeFileSync(DB_PATH, JSON.stringify({}, null, 2));
|
|
22
23
|
}
|
|
24
|
+
if (!fs.existsSync(SETTINGS_PATH)) {
|
|
25
|
+
fs.writeFileSync(SETTINGS_PATH, JSON.stringify({}, null, 2));
|
|
26
|
+
}
|
|
23
27
|
}
|
|
24
28
|
|
|
25
29
|
function readDB() {
|
|
@@ -41,6 +45,8 @@ module.exports = {
|
|
|
41
45
|
CONFIG_DIR,
|
|
42
46
|
APPS_DIR,
|
|
43
47
|
LOGS_DIR,
|
|
48
|
+
DB_PATH,
|
|
49
|
+
SETTINGS_PATH,
|
|
44
50
|
setupConfig,
|
|
45
51
|
readDB,
|
|
46
52
|
writeDB,
|
package/src/utils/logger.js
CHANGED
|
@@ -3,6 +3,18 @@ const path = require('path');
|
|
|
3
3
|
const chalk = require('chalk');
|
|
4
4
|
const { LOGS_DIR } = require('./config');
|
|
5
5
|
|
|
6
|
+
/*
|
|
7
|
+
To use:
|
|
8
|
+
const Logger = require('./logger');
|
|
9
|
+
const logger = new Logger('name');
|
|
10
|
+
|
|
11
|
+
//then
|
|
12
|
+
logger.info('information');
|
|
13
|
+
logger.warn('warning');
|
|
14
|
+
logger.error('error message', 'error');
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
|
|
6
18
|
class Logger {
|
|
7
19
|
constructor(component) {
|
|
8
20
|
this.component = component;
|
|
@@ -24,7 +36,7 @@ class Logger {
|
|
|
24
36
|
|
|
25
37
|
info(message) {
|
|
26
38
|
const formattedMessage = this._format('INFO', message);
|
|
27
|
-
console.log(chalk.
|
|
39
|
+
console.log(chalk.blueBright(formattedMessage));
|
|
28
40
|
this._writeToFile(formattedMessage);
|
|
29
41
|
}
|
|
30
42
|
|
package/src/utils/noroot.js
CHANGED
|
@@ -6,7 +6,7 @@ const logger = new Logger('noroot');
|
|
|
6
6
|
|
|
7
7
|
async function checkNotRoot(allowRoot = false) {
|
|
8
8
|
if (allowRoot) {
|
|
9
|
-
logger.warn('Running with elevated privileges. This is not recommended.'
|
|
9
|
+
logger.warn('Running with elevated privileges. This is not recommended.');
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
12
|
|
|
@@ -15,7 +15,9 @@ async function checkNotRoot(allowRoot = false) {
|
|
|
15
15
|
switch (platform) {
|
|
16
16
|
case 'win32':
|
|
17
17
|
if (await isAdmin()) {
|
|
18
|
-
logger.error('This application should not be run as an administrator.'
|
|
18
|
+
logger.error('This application should not be run as an administrator.');
|
|
19
|
+
logger.warn('Run with --allowroot to avoid this message.');
|
|
20
|
+
logger.warn('Running u2a as administrator can be dangerous.');
|
|
19
21
|
process.exit(1);
|
|
20
22
|
}
|
|
21
23
|
break;
|
|
@@ -23,7 +25,9 @@ async function checkNotRoot(allowRoot = false) {
|
|
|
23
25
|
case 'darwin':
|
|
24
26
|
case 'linux':
|
|
25
27
|
if (process.getuid() === 0) {
|
|
26
|
-
logger.error('This application should not be run as root.'
|
|
28
|
+
logger.error('This application should not be run as root.');
|
|
29
|
+
logger.warn('Run with --allowroot to avoid this message.');
|
|
30
|
+
logger.warn('Running u2a as root can be dangerous.');
|
|
27
31
|
process.exit(1);
|
|
28
32
|
}
|
|
29
33
|
break;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const axios = require('axios');
|
|
4
|
+
const Logger = require('./logger');
|
|
5
|
+
const { setupConfig, CONFIG_DIR, SETTINGS_PATH } = require('./config');
|
|
6
|
+
|
|
7
|
+
setupConfig(); // builds ~/.u2a/*
|
|
8
|
+
|
|
9
|
+
const logger = new Logger('postinstall');
|
|
10
|
+
const postinstallJsonPath = path.join(CONFIG_DIR, 'postinstall.json');
|
|
11
|
+
let isUpgrade = false;
|
|
12
|
+
let currentVersion = '0.0.0'; //0.0.0 for new installations
|
|
13
|
+
let sendAnonReports = true; // u2a configure reports disable to disable
|
|
14
|
+
|
|
15
|
+
const formatVersionLine = (label, version) => {
|
|
16
|
+
// calculates how many spaces we need after the version to have a correct formatting
|
|
17
|
+
const baseLength = `; ${label}: `.length + version.length;
|
|
18
|
+
const spaceCount = Math.max(0, 30 - baseLength);
|
|
19
|
+
const spaces = ' '.repeat(spaceCount);
|
|
20
|
+
|
|
21
|
+
return `; ${label}: ${version}${spaces};`;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
async function run() {
|
|
25
|
+
//check if postinstall.json exists (exists -> update, doesnt -> new install)
|
|
26
|
+
if (fs.existsSync(postinstallJsonPath)) {
|
|
27
|
+
try {
|
|
28
|
+
const postinstallData = JSON.parse(fs.readFileSync(postinstallJsonPath, 'utf8'));
|
|
29
|
+
currentVersion = postinstallData.version || '';
|
|
30
|
+
isUpgrade = true;
|
|
31
|
+
|
|
32
|
+
let newVersion = '';
|
|
33
|
+
try {
|
|
34
|
+
const packageJsonPath = path.join(__dirname, '..', '..', 'package.json');
|
|
35
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
36
|
+
newVersion = packageJson.version || '';
|
|
37
|
+
} catch (err) {
|
|
38
|
+
logger.error(`Error reading package.json for display`, err.message);
|
|
39
|
+
newVersion = 'unknown';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
logger.info(';=============================;');
|
|
43
|
+
logger.info('; u2a has been updated! ;');
|
|
44
|
+
logger.info('; Successfully migrated from ;');
|
|
45
|
+
logger.info(formatVersionLine('Old version', currentVersion));
|
|
46
|
+
logger.info(formatVersionLine('New version', newVersion));
|
|
47
|
+
logger.info(';=============================;');
|
|
48
|
+
} catch (err) {
|
|
49
|
+
logger.error(`Error reading postinstall.json`, err.message);
|
|
50
|
+
isUpgrade = false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (fs.existsSync(SETTINGS_PATH)) {
|
|
55
|
+
try {
|
|
56
|
+
const settingsData = JSON.parse(fs.readFileSync(SETTINGS_PATH, 'utf8'));
|
|
57
|
+
sendAnonReports = settingsData.send_anon_reports !== false;
|
|
58
|
+
} catch (err) {
|
|
59
|
+
logger.error(`Error reading settings.json`, err.message);
|
|
60
|
+
sendAnonReports = true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// shows this cool message if it isnt an upgrade
|
|
65
|
+
if (!isUpgrade) {
|
|
66
|
+
logger.info(';=============================;');
|
|
67
|
+
logger.info('; Welcome to u2a ! ;');
|
|
68
|
+
logger.info('; Thanks for downloading this ;');
|
|
69
|
+
logger.info('; tool ! ;');
|
|
70
|
+
logger.info('; ;');
|
|
71
|
+
logger.info('; Create a local webapp with ;');
|
|
72
|
+
logger.info('; \'u2a create <url/domain>\' ;');
|
|
73
|
+
logger.info('; ;');
|
|
74
|
+
logger.info('; Check docs.urltoapp.xyz for ;');
|
|
75
|
+
logger.info('; more detailed usage. ;');
|
|
76
|
+
logger.info('; ;');
|
|
77
|
+
logger.info('; Note: Anonymous installs ;');
|
|
78
|
+
logger.info('; reports are enabled by ;');
|
|
79
|
+
logger.info('; default. To disable: ;');
|
|
80
|
+
logger.info('; \'u2a configure reports ;');
|
|
81
|
+
logger.info('; disable\' ;');
|
|
82
|
+
logger.info(';=============================;');
|
|
83
|
+
|
|
84
|
+
const settings = { send_anon_reports: true };
|
|
85
|
+
fs.writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const packageJsonPath = path.join(__dirname, '..', '..', 'package.json');
|
|
89
|
+
let newVersion = '';
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
93
|
+
newVersion = packageJson.version || '';
|
|
94
|
+
} catch (err) {
|
|
95
|
+
logger.error(`Error reading package.json`, err.message);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (sendAnonReports) {
|
|
99
|
+
try {
|
|
100
|
+
|
|
101
|
+
const params = new URLSearchParams({
|
|
102
|
+
previousVersion: currentVersion,
|
|
103
|
+
newVersion: newVersion
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// backend here https://github.com/url2app/urltoapp.xyz/blob/main/api/v1/api/reports.php
|
|
107
|
+
await axios.get(`https://urltoapp.xyz/api/v1/reports?${params.toString()}`);
|
|
108
|
+
logger.debug('Anonymous usage report sent');
|
|
109
|
+
} catch (err) {
|
|
110
|
+
logger.debug(`Failed to send anonymous report: ${err.message}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
fs.writeFileSync(postinstallJsonPath, JSON.stringify({
|
|
116
|
+
version: newVersion,
|
|
117
|
+
installed_at: new Date().toISOString()
|
|
118
|
+
}, null, 2));
|
|
119
|
+
} catch (err) {
|
|
120
|
+
logger.error(`Error updating postinstall.json`, err.message);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
run().catch(err => {
|
|
125
|
+
logger.error(`Unexpected error`, err.message);
|
|
126
|
+
});
|