parent
91f49e1efd
commit
e7945bea94
4 changed files with 19 additions and 15 deletions
|
@ -73,9 +73,9 @@ yarn binary ${vscodeVersion} ${codeServerVersion} # Or you can package it into a
|
||||||
## Security
|
## Security
|
||||||
|
|
||||||
### Authentication
|
### Authentication
|
||||||
To enable built-in password authentication use `code-server --auth password`. By
|
By default `code-server` enables password authentication using a randomly
|
||||||
default it will use a randomly generated password but you can set the
|
generated password. You can set the `PASSWORD` environment variable to use your
|
||||||
`$PASSWORD` environment variable to use your own.
|
own instead or use `--auth none` to disable password authentication.
|
||||||
|
|
||||||
Do not expose `code-server` to the open internet without some form of
|
Do not expose `code-server` to the open internet without some form of
|
||||||
authentication.
|
authentication.
|
||||||
|
|
|
@ -86,7 +86,7 @@ const startVscode = async (): Promise<void | void[]> => {
|
||||||
const args = getArgs();
|
const args = getArgs();
|
||||||
const extra = args["_"] || [];
|
const extra = args["_"] || [];
|
||||||
const options = {
|
const options = {
|
||||||
auth: args.auth,
|
auth: args.auth || AuthType.Password,
|
||||||
basePath: args["base-path"],
|
basePath: args["base-path"],
|
||||||
cert: args.cert,
|
cert: args.cert,
|
||||||
certKey: args["cert-key"],
|
certKey: args["cert-key"],
|
||||||
|
@ -95,9 +95,9 @@ const startVscode = async (): Promise<void | void[]> => {
|
||||||
password: process.env.PASSWORD,
|
password: process.env.PASSWORD,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (options.auth && enumToArray(AuthType).filter((t) => t === options.auth).length === 0) {
|
if (enumToArray(AuthType).filter((t) => t === options.auth).length === 0) {
|
||||||
throw new Error(`'${options.auth}' is not a valid authentication type.`);
|
throw new Error(`'${options.auth}' is not a valid authentication type.`);
|
||||||
} else if (options.auth && !options.password) {
|
} else if (options.auth === "password" && !options.password) {
|
||||||
options.password = await generatePassword();
|
options.password = await generatePassword();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,10 +125,13 @@ const startVscode = async (): Promise<void | void[]> => {
|
||||||
]);
|
]);
|
||||||
logger.info(`Server listening on ${serverAddress}`);
|
logger.info(`Server listening on ${serverAddress}`);
|
||||||
|
|
||||||
if (options.auth && !process.env.PASSWORD) {
|
if (options.auth === "password" && !process.env.PASSWORD) {
|
||||||
logger.info(` - Password is ${options.password}`);
|
logger.info(` - Password is ${options.password}`);
|
||||||
logger.info(" - To use your own password, set the PASSWORD environment variable");
|
logger.info(" - To use your own password, set the PASSWORD environment variable");
|
||||||
} else if (options.auth) {
|
if (!args.auth) {
|
||||||
|
logger.info(" - To disable use `--auth none`");
|
||||||
|
}
|
||||||
|
} else if (options.auth === "password") {
|
||||||
logger.info(" - Using custom password for authentication");
|
logger.info(" - Using custom password for authentication");
|
||||||
} else {
|
} else {
|
||||||
logger.info(" - No authentication");
|
logger.info(" - No authentication");
|
||||||
|
|
|
@ -110,7 +110,7 @@ export class HttpError extends Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ServerOptions {
|
export interface ServerOptions {
|
||||||
readonly auth?: AuthType;
|
readonly auth: AuthType;
|
||||||
readonly basePath?: string;
|
readonly basePath?: string;
|
||||||
readonly connectionToken?: string;
|
readonly connectionToken?: string;
|
||||||
readonly cert?: string;
|
readonly cert?: string;
|
||||||
|
@ -133,7 +133,7 @@ export abstract class Server {
|
||||||
|
|
||||||
public constructor(options: ServerOptions) {
|
public constructor(options: ServerOptions) {
|
||||||
this.options = {
|
this.options = {
|
||||||
host: options.auth && options.cert ? "0.0.0.0" : "localhost",
|
host: options.auth === "password" && options.cert ? "0.0.0.0" : "localhost",
|
||||||
...options,
|
...options,
|
||||||
basePath: options.basePath ? options.basePath.replace(/\/+$/, "") : "",
|
basePath: options.basePath ? options.basePath.replace(/\/+$/, "") : "",
|
||||||
};
|
};
|
||||||
|
@ -269,7 +269,7 @@ export abstract class Server {
|
||||||
base = path.normalize(base);
|
base = path.normalize(base);
|
||||||
requestPath = path.normalize(requestPath || "/index.html");
|
requestPath = path.normalize(requestPath || "/index.html");
|
||||||
|
|
||||||
if (base !== "/login" || !this.options.auth || requestPath !== "/index.html") {
|
if (base !== "/login" || this.options.auth !== "password" || requestPath !== "/index.html") {
|
||||||
this.ensureGet(request);
|
this.ensureGet(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,7 +300,7 @@ export abstract class Server {
|
||||||
response.cache = true;
|
response.cache = true;
|
||||||
return response;
|
return response;
|
||||||
case "/login":
|
case "/login":
|
||||||
if (!this.options.auth || requestPath !== "/index.html") {
|
if (this.options.auth !== "password" || requestPath !== "/index.html") {
|
||||||
throw new HttpError("Not found", HttpCode.NotFound);
|
throw new HttpError("Not found", HttpCode.NotFound);
|
||||||
}
|
}
|
||||||
return this.tryLogin(request);
|
return this.tryLogin(request);
|
||||||
|
@ -421,7 +421,7 @@ export abstract class Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
private authenticate(request: http.IncomingMessage, payload?: LoginPayload): boolean {
|
private authenticate(request: http.IncomingMessage, payload?: LoginPayload): boolean {
|
||||||
if (!this.options.auth) {
|
if (this.options.auth !== "password") {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const safeCompare = localRequire<typeof import("safe-compare")>("safe-compare/index");
|
const safeCompare = localRequire<typeof import("safe-compare")>("safe-compare/index");
|
||||||
|
|
|
@ -14,6 +14,7 @@ import { mkdirp } from "vs/base/node/pfs";
|
||||||
|
|
||||||
export enum AuthType {
|
export enum AuthType {
|
||||||
Password = "password",
|
Password = "password",
|
||||||
|
None = "none",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum FormatType {
|
export enum FormatType {
|
||||||
|
@ -127,7 +128,7 @@ export const enumToArray = (t: any): string[] => {
|
||||||
|
|
||||||
export const buildAllowedMessage = (t: any): string => {
|
export const buildAllowedMessage = (t: any): string => {
|
||||||
const values = enumToArray(t);
|
const values = enumToArray(t);
|
||||||
return `Allowed value${values.length === 1 ? " is" : "s are"} ${values.map((t) => `'${t}'`).join(",")}`;
|
return `Allowed value${values.length === 1 ? " is" : "s are"} ${values.map((t) => `'${t}'`).join(", ")}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue