Some minor changes

This commit is contained in:
WolverinDEV 2021-02-12 10:21:53 +01:00
parent 5e6aac77ed
commit ab7da09c25
3 changed files with 48 additions and 50 deletions

View File

@ -129,7 +129,7 @@ export async function write_version(file: string, platform: string, arch: string
} }
export async function deploy(platform: string, arch: string, channel: string, version: Version, update_file: string, install_file: string, install_suffix: string) { export async function deploy(platform: string, arch: string, channel: string, version: Version, update_file: string, install_file: string, install_suffix: string) {
await new Promise(resolve => { await new Promise(resolve => {
const url = (process.env["teaclient_deploy_url"] || "http://clientapi.teaspeak.de/") + "api.php"; const url = (process.env["teaclient_deploy_url"] || "https://clientapi.teaspeak.de/") + "api.php";
console.log("Requesting " + url); console.log("Requesting " + url);
console.log("Uploading update file " + update_file); console.log("Uploading update file " + update_file);
console.log("Uploading install file " + install_file); console.log("Uploading install file " + install_file);

View File

@ -28,8 +28,6 @@ export type UpdateStatsCallback = (message: string, progress: number) => void;
export type UpdateLogCallback = (type: "error" | "info", message: string) => void; export type UpdateLogCallback = (type: "error" | "info", message: string) => void;
export function updateServerUrl() : string { export function updateServerUrl() : string {
/* FIXME! */
return "https://clientapi.teaspeak.de/";
return processArguments.has_value(...Arguments.SERVER_URL) ? processArguments.value(...Arguments.SERVER_URL) : "https://clientapi.teaspeak.de/"; return processArguments.has_value(...Arguments.SERVER_URL) ? processArguments.value(...Arguments.SERVER_URL) : "https://clientapi.teaspeak.de/";
} }
@ -253,51 +251,54 @@ if(typeof(String.prototype.trim) === "undefined")
} }
export async function ensureTargetFilesAreWriteable(updateFile: string) : Promise<string[]> { export async function ensureTargetFilesAreWriteable(updateFile: string) : Promise<string[]> {
const original_fs = require('original-fs'); const originalFs = require('original-fs');
if(!fs.existsSync(updateFile)) { if(!fs.existsSync(updateFile)) {
throw "Missing update file (" + updateFile + ")"; throw "Missing update file (" + updateFile + ")";
} }
let parent_path = app.getAppPath(); let parentPath = await fs.realpath(path.dirname(app.getPath("exe")));
if(parent_path.endsWith(".asar")) { const testAccess = async (file: string, mode: number) => {
parent_path = path.join(parent_path, "..", ".."); return await new Promise<NodeJS.ErrnoException>(resolve => originalFs.access(file, mode, resolve));
parent_path = fs.realpathSync(parent_path);
}
const test_access = async (file: string, mode: number) => {
return await new Promise<NodeJS.ErrnoException>(resolve => original_fs.access(file, mode, resolve));
}; };
let code = await test_access(updateFile, original_fs.constants.R_OK); let code = await testAccess(updateFile, originalFs.constants.R_OK);
if(code) if(code) {
throw "Failed test read for update file. (" + updateFile + " results in " + code.code + ")"; throw "Failed test read for update file. (" + updateFile + " results in " + code.code + ")";
}
const fstream = original_fs.createReadStream(updateFile); const fstream = originalFs.createReadStream(updateFile);
const tar_stream = tar.extract(); const tar_stream = tar.extract();
const errors: string[] = []; const errors: string[] = [];
const tester = async (header: Headers) => { const tester = async (header: Headers) => {
const entry_path = path.normalize(path.join(parent_path, header.name)); const entry_path = path.normalize(path.join(parentPath, header.name));
if(header.type == "file") { if(header.type == "file") {
if(original_fs.existsSync(entry_path)) { if(originalFs.existsSync(entry_path)) {
code = await test_access(entry_path, original_fs.constants.W_OK); code = await testAccess(entry_path, originalFs.constants.W_OK);
if(code) if(code) {
errors.push("Failed to acquire write permissions for file " + entry_path + " (Code " + code.code + ")"); errors.push("Failed to acquire write permissions for file " + entry_path + " (Code " + code.code + ")");
}
} else { } else {
let directory = path.dirname(entry_path); let directory = path.dirname(entry_path);
while(directory.length != 0 && !original_fs.existsSync(directory)) while(directory.length != 0 && !originalFs.existsSync(directory)) {
directory = path.normalize(path.join(directory, "..")); directory = path.normalize(path.join(directory, ".."));
}
code = await test_access(directory, original_fs.constants.W_OK); code = await testAccess(directory, originalFs.constants.W_OK);
if(code) errors.push("Failed to acquire write permissions for directory " + entry_path + " (Code " + code.code + ". Target directory " + directory + ")"); if(code) {
errors.push("Failed to acquire write permissions for directory " + entry_path + " (Code " + code.code + ". Target directory " + directory + ")");
}
} }
} else if(header.type == "directory") { } else if(header.type == "directory") {
let directory = path.dirname(entry_path); let directory = path.dirname(entry_path);
while(directory.length != 0 && !original_fs.existsSync(directory)) while(directory.length != 0 && !originalFs.existsSync(directory)) {
directory = path.normalize(path.join(directory, "..")); directory = path.normalize(path.join(directory, ".."));
}
code = await test_access(directory, original_fs.constants.W_OK); code = await testAccess(directory, originalFs.constants.W_OK);
if(code) errors.push("Failed to acquire write permissions for directory " + entry_path + " (Code " + code.code + ". Target directory " + directory + ")"); if(code) {
errors.push("Failed to acquire write permissions for directory " + entry_path + " (Code " + code.code + ". Target directory " + directory + ")");
}
} }
}; };
@ -324,7 +325,7 @@ export async function ensureTargetFilesAreWriteable(updateFile: string) : Promis
return errors; return errors;
} }
namespace install_config { namespace InstallConfig {
export interface LockFile { export interface LockFile {
filename: string; filename: string;
timeout: number; timeout: number;
@ -350,9 +351,9 @@ namespace install_config {
} }
} }
async function createUpdateInstallConfig(sourceRoot: string, targetRoot: string) : Promise<install_config.ConfigFile> { async function createUpdateInstallConfig(sourceRoot: string, targetRoot: string) : Promise<InstallConfig.ConfigFile> {
console.log("Building update install config for target directory: %s. Update source: %o", targetRoot, sourceRoot); console.log("Building update install config for target directory: %s. Update source: %o", targetRoot, sourceRoot);
const result: install_config.ConfigFile = { } as any; const result: InstallConfig.ConfigFile = { } as any;
result.version = 1; result.version = 1;
@ -373,7 +374,7 @@ async function createUpdateInstallConfig(sourceRoot: string, targetRoot: string)
{ {
"error-id": "main-exe-lock", "error-id": "main-exe-lock",
filename: app.getPath("exe"), filename: app.getPath("exe"),
timeout: 5000 timeout: 10 * 1000
} }
]; ];
@ -382,14 +383,14 @@ async function createUpdateInstallConfig(sourceRoot: string, targetRoot: string)
]; ];
const dirWalker = async (relative_path: string) => { const dirWalker = async (relative_path: string) => {
const source_directory = path.join(sourceRoot, relative_path); const sourceDirectory = path.join(sourceRoot, relative_path);
const target_directory = path.join(targetRoot, relative_path); const targetDirectory = path.join(targetRoot, relative_path);
let files: string[]; let files: string[];
try { try {
files = await util.promisify(ofs.readdir)(source_directory); files = await util.promisify(ofs.readdir)(sourceDirectory);
} catch(error) { } catch(error) {
console.warn("Failed to iterate over source directory \"%s\": %o", source_directory, error); console.warn("Failed to iterate over source directory \"%s\": %o", sourceDirectory, error);
return; return;
} }
@ -406,8 +407,8 @@ async function createUpdateInstallConfig(sourceRoot: string, targetRoot: string)
continue; continue;
} }
const source_file = path.join(source_directory, file); const source_file = path.join(sourceDirectory, file);
const target_file = path.join(target_directory, file); const target_file = path.join(targetDirectory, file);
//TODO check if file content has changed else ignore? //TODO check if file content has changed else ignore?
@ -657,25 +658,21 @@ export async function prepareUpdateExecute(targetVersion: UpdateVersion, callbac
callbackStats("Downloading update", status.percent); callbackStats("Downloading update", status.percent);
}, callbackLog); }, callbackLog);
/* TODO: Remove this step and let the actual updater so this. If this fails we'll already receiving appropiate error messages. */ /* TODO: Remove this step and let the actual updater so this. If this fails we'll already receiving appropriate error messages. */
if(os.platform() !== "win32") { if(os.platform() !== "win32") {
callbackLog("info", "Checking file permissions"); callbackLog("info", "Checking file permissions");
callbackStats("Checking file permissions", .25); callbackStats("Checking file permissions", .25);
/* We must be on a unix based system */ /* We must be on a unix based system */
try { const inaccessiblePaths = await ensureTargetFilesAreWriteable(updateFilePath);
const inaccessiblePaths = await ensureTargetFilesAreWriteable(updateFilePath); if(inaccessiblePaths.length > 0) {
if(inaccessiblePaths.length > 0) { console.log("Failed to access the following files:");
console.log("Failed to access the following files:"); for(const fail of inaccessiblePaths) {
for(const fail of inaccessiblePaths) { console.log(" - " + fail);
console.log(" - " + fail);
}
const executeCommand = "sudo " + path.normalize(app.getAppPath()) + " --update-execute";
throw "Failed to access target files.\nPlease execute this app with administrator (sudo) privileges.\nUse the following command:\n" + executeCommand;
} }
} catch(error) {
console.warn("Failed to validate target file accessibility: %o", error); const executeCommand = "sudo " + path.normalize(app.getPath("exe")) + " --no-sandbox --update-execute";
throw "Failed to access target files.\nPlease execute this app with administrator (sudo) privileges.\nUse the following command:\n" + executeCommand;
} }
} else { } else {
/* the windows update already requests admin privileges */ /* the windows update already requests admin privileges */
@ -753,8 +750,9 @@ export async function prepareUpdateExecute(targetVersion: UpdateVersion, callbac
return; return;
} }
if(electron.app.hasSingleInstanceLock()) if(electron.app.hasSingleInstanceLock()) {
electron.app.releaseSingleInstanceLock(); electron.app.releaseSingleInstanceLock();
}
const ids = child_process.execSync("pgrep TeaClient").toString().split(os.EOL).map(e => e.trim()).reverse().join(" "); const ids = child_process.execSync("pgrep TeaClient").toString().split(os.EOL).map(e => e.trim()).reverse().join(" ");
console.log("Executing %s", "kill -9 " + ids); console.log("Executing %s", "kill -9 " + ids);

View File

@ -1,5 +1,5 @@
{ {
"name": "TeaClient", "name": "teaspeak_client",
"version": "1.5.0-8", "version": "1.5.0-8",
"description": "", "description": "",
"main": "main.js", "main": "main.js",