code-server/src/util.ts

120 lines
4.1 KiB
TypeScript
Raw Normal View History

2019-07-16 02:31:05 +08:00
import * as cp from "child_process";
2019-07-13 04:21:00 +08:00
import * as crypto from "crypto";
2019-07-12 06:12:52 +08:00
import * as fs from "fs";
import * as os from "os";
import * as path from "path";
import * as util from "util";
2019-07-17 08:26:05 +08:00
import * as rg from "vscode-ripgrep";
2019-07-12 06:12:52 +08:00
import { getPathFromAmdModule } from "vs/base/common/amd";
2019-07-13 04:21:00 +08:00
import { getMediaMime as vsGetMediaMime } from "vs/base/common/mime";
import { extname } from "vs/base/common/path";
2019-07-12 06:12:52 +08:00
import { URITransformer, IRawURITransformer } from "vs/base/common/uriIpc";
import { mkdirp } from "vs/base/node/pfs";
2019-07-26 06:39:43 +08:00
export enum AuthType {
Password = "password",
}
2019-07-12 06:12:52 +08:00
export const tmpdir = path.join(os.tmpdir(), "code-server");
export const generateCertificate = async (): Promise<{ cert: string, certKey: string }> => {
const paths = {
cert: path.join(tmpdir, "self-signed.cert"),
certKey: path.join(tmpdir, "self-signed.key"),
};
const exists = await Promise.all([
util.promisify(fs.exists)(paths.cert),
util.promisify(fs.exists)(paths.certKey),
]);
if (!exists[0] || !exists[1]) {
const pem = require.__$__nodeRequire(path.resolve(__dirname, "../node_modules/pem/lib/pem")) as typeof import("pem");
const certs = await new Promise<import("pem").CertificateCreationResult>((resolve, reject): void => {
pem.createCertificate({ selfSigned: true }, (error, result) => {
if (error) {
return reject(error);
}
resolve(result);
});
});
2019-07-20 06:43:54 +08:00
await mkdirp(tmpdir);
2019-07-12 06:12:52 +08:00
await Promise.all([
util.promisify(fs.writeFile)(paths.cert, certs.certificate),
util.promisify(fs.writeFile)(paths.certKey, certs.serviceKey),
]);
}
return paths;
};
2019-07-23 05:00:59 +08:00
export const uriTransformerPath = getPathFromAmdModule(require, "vs/server/src/uriTransformer");
2019-07-12 06:12:52 +08:00
export const getUriTransformer = (remoteAuthority: string): URITransformer => {
2019-07-23 05:00:59 +08:00
const rawURITransformerFactory = <any>require.__$__nodeRequire(uriTransformerPath);
2019-07-12 06:12:52 +08:00
const rawURITransformer = <IRawURITransformer>rawURITransformerFactory(remoteAuthority);
return new URITransformer(rawURITransformer);
};
2019-07-13 04:21:00 +08:00
export const generatePassword = async (length: number = 24): Promise<string> => {
const buffer = Buffer.alloc(Math.ceil(length / 2));
await util.promisify(crypto.randomFill)(buffer);
return buffer.toString("hex").substring(0, length);
};
export const getMediaMime = (filePath?: string): string => {
return filePath && (vsGetMediaMime(filePath) || {
".css": "text/css",
".html": "text/html",
".js": "text/javascript",
".json": "application/json",
}[extname(filePath)]) || "text/plain";
};
2019-07-16 02:31:05 +08:00
export const isWsl = async (): Promise<boolean> => {
return process.platform === "linux"
&& os.release().toLowerCase().indexOf("microsoft") !== -1
|| (await util.promisify(fs.readFile)("/proc/version", "utf8"))
.toLowerCase().indexOf("microsoft") !== -1;
};
export const open = async (url: string): Promise<void> => {
const args = <string[]>[];
const options = <cp.SpawnOptions>{};
const platform = await isWsl() ? "wsl" : process.platform;
2019-07-20 06:43:54 +08:00
let command = platform === "darwin" ? "open" : "xdg-open";
if (platform === "win32" || platform === "wsl") {
command = platform === "wsl" ? "cmd.exe" : "cmd";
args.push("/c", "start", '""', "/b");
url = url.replace(/&/g, "^&");
2019-07-16 02:31:05 +08:00
}
2019-07-20 06:43:54 +08:00
const proc = cp.spawn(command, [...args, url], options);
2019-07-16 02:31:05 +08:00
await new Promise((resolve, reject) => {
proc.on("error", reject);
proc.on("close", (code) => {
return code !== 0
? reject(new Error(`Failed to open with code ${code}`))
: resolve();
});
});
};
2019-07-17 08:26:05 +08:00
/**
* Extract executables to the temporary directory. This is required since we
* can't execute binaries stored within our binary.
*/
export const unpackExecutables = async (): Promise<void> => {
const rgPath = (rg as any).binaryRgPath;
2019-07-18 06:41:25 +08:00
const destination = path.join(tmpdir, path.basename(rgPath || ""));
if (rgPath && !(await util.promisify(fs.exists)(destination))) {
2019-07-17 08:26:05 +08:00
await mkdirp(tmpdir);
2019-07-18 06:41:25 +08:00
await util.promisify(fs.writeFile)(destination, await util.promisify(fs.readFile)(rgPath));
2019-07-17 08:26:05 +08:00
await util.promisify(fs.chmod)(destination, "755");
}
};
export const buildAllowedMessage = (t: typeof AuthType): string => {
const values = <string[]>Object.keys(t).map((k) => t[k]);
return `Allowed value${values.length === 1 ? " is" : "s are"} ${values.map((t) => `'${t}'`).join(",")}`;
};