mirror of https://git.tuxpa.in/a/code-server.git
Fixes browser app, adds no-auth (#38)
* Add no-auth flag * Install packages for app dir
This commit is contained in:
parent
a07d0c9c3d
commit
be3f0c437f
|
@ -24,6 +24,7 @@ export class Entry extends Command {
|
||||||
open: flags.boolean({ char: "o", description: "Open in browser on startup" }),
|
open: flags.boolean({ char: "o", description: "Open in browser on startup" }),
|
||||||
port: flags.integer({ char: "p", default: 8080, description: "Port to bind on" }),
|
port: flags.integer({ char: "p", default: 8080, description: "Port to bind on" }),
|
||||||
version: flags.version({ char: "v" }),
|
version: flags.version({ char: "v" }),
|
||||||
|
"no-auth": flags.boolean({ default: false }),
|
||||||
|
|
||||||
// Dev flags
|
// Dev flags
|
||||||
"bootstrap-fork": flags.string({ hidden: true }),
|
"bootstrap-fork": flags.string({ hidden: true }),
|
||||||
|
@ -132,41 +133,47 @@ export class Entry extends Command {
|
||||||
|
|
||||||
const password = "023450wf0951";
|
const password = "023450wf0951";
|
||||||
const hasCustomHttps = certData && certKeyData;
|
const hasCustomHttps = certData && certKeyData;
|
||||||
const app = await createApp((app) => {
|
const app = await createApp({
|
||||||
app.use((req, res, next) => {
|
bypassAuth: flags["no-auth"],
|
||||||
res.on("finish", () => {
|
registerMiddleware: (app): void => {
|
||||||
logger.trace(`\u001B[1m${req.method} ${res.statusCode} \u001B[0m${req.url}`, field("host", req.hostname), field("ip", req.ip));
|
app.use((req, res, next) => {
|
||||||
|
res.on("finish", () => {
|
||||||
|
logger.trace(`\u001B[1m${req.method} ${res.statusCode} \u001B[0m${req.url}`, field("host", req.hostname), field("ip", req.ip));
|
||||||
|
});
|
||||||
|
|
||||||
|
next();
|
||||||
});
|
});
|
||||||
|
// If we're not running from the binary and we aren't serving the static
|
||||||
next();
|
// pre-built version, use webpack to serve the web files.
|
||||||
});
|
if (!isCli && !serveStatic) {
|
||||||
// If we're not running from the binary and we aren't serving the static
|
const webpackConfig = require(path.join(__dirname, "..", "..", "web", "webpack.config.js"));
|
||||||
// pre-built version, use webpack to serve the web files.
|
const compiler = require("webpack")(webpackConfig);
|
||||||
if (!isCli && !serveStatic) {
|
app.use(require("webpack-dev-middleware")(compiler, {
|
||||||
const webpackConfig = require(path.join(__dirname, "..", "..", "web", "webpack.config.js"));
|
logger,
|
||||||
const compiler = require("webpack")(webpackConfig);
|
publicPath: webpackConfig.output.publicPath,
|
||||||
app.use(require("webpack-dev-middleware")(compiler, {
|
stats: webpackConfig.stats,
|
||||||
logger,
|
}));
|
||||||
publicPath: webpackConfig.output.publicPath,
|
app.use(require("webpack-hot-middleware")(compiler));
|
||||||
stats: webpackConfig.stats,
|
|
||||||
}));
|
|
||||||
app.use(require("webpack-hot-middleware")(compiler));
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
builtInExtensionsDirectory: builtInExtensionsDir,
|
|
||||||
dataDirectory: dataDir,
|
|
||||||
workingDirectory: workingDir,
|
|
||||||
fork: (modulePath: string, args: string[], options: ForkOptions): ChildProcess => {
|
|
||||||
if (options && options.env && options.env.AMD_ENTRYPOINT) {
|
|
||||||
return forkModule(options.env.AMD_ENTRYPOINT, args, options, dataDir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fork(modulePath, args, options);
|
|
||||||
},
|
},
|
||||||
}, password, hasCustomHttps ? {
|
serverOptions: {
|
||||||
key: certKeyData,
|
builtInExtensionsDirectory: builtInExtensionsDir,
|
||||||
cert: certData,
|
dataDirectory: dataDir,
|
||||||
} : undefined);
|
workingDirectory: workingDir,
|
||||||
|
fork: (modulePath: string, args: string[], options: ForkOptions): ChildProcess => {
|
||||||
|
if (options && options.env && options.env.AMD_ENTRYPOINT) {
|
||||||
|
return forkModule(options.env.AMD_ENTRYPOINT, args, options, dataDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fork(modulePath, args, options);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
password,
|
||||||
|
httpsOptions: hasCustomHttps ? {
|
||||||
|
key: certKeyData,
|
||||||
|
cert: certData,
|
||||||
|
} : undefined,
|
||||||
|
});
|
||||||
|
|
||||||
logger.info("Starting webserver...", field("host", flags.host), field("port", flags.port));
|
logger.info("Starting webserver...", field("host", flags.host), field("port", flags.port));
|
||||||
app.server.listen(flags.port, flags.host);
|
app.server.listen(flags.port, flags.host);
|
||||||
|
@ -191,8 +198,12 @@ export class Entry extends Command {
|
||||||
logger.warn("Documentation on securing your setup: https://coder.com/docs");
|
logger.warn("Documentation on securing your setup: https://coder.com/docs");
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(" ");
|
if (!flags["no-auth"]) {
|
||||||
logger.info(`Password:\u001B[1m ${password}`);
|
logger.info(" ");
|
||||||
|
logger.info(`Password:\u001B[1m ${password}`);
|
||||||
|
} else {
|
||||||
|
logger.warn("Launched without authentication.");
|
||||||
|
}
|
||||||
logger.info(" ");
|
logger.info(" ");
|
||||||
logger.info("Started (click the link below to open):");
|
logger.info("Started (click the link below to open):");
|
||||||
logger.info(`http://localhost:${flags.port}/`);
|
logger.info(`http://localhost:${flags.port}/`);
|
||||||
|
|
|
@ -20,7 +20,15 @@ import { handle as handleTunnel } from "@coder/tunnel/src/server";
|
||||||
import { createPortScanner } from "./portScanner";
|
import { createPortScanner } from "./portScanner";
|
||||||
import { buildDir, isCli } from "./constants";
|
import { buildDir, isCli } from "./constants";
|
||||||
|
|
||||||
export const createApp = async (registerMiddleware?: (app: express.Application) => void, options?: ServerOptions, password?: string, httpsOptions?: https.ServerOptions): Promise<{
|
interface CreateAppOptions {
|
||||||
|
registerMiddleware?: (app: express.Application) => void;
|
||||||
|
serverOptions?: ServerOptions;
|
||||||
|
password?: string;
|
||||||
|
httpsOptions?: https.ServerOptions;
|
||||||
|
bypassAuth?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createApp = async (options: CreateAppOptions): Promise<{
|
||||||
readonly express: express.Application;
|
readonly express: express.Application;
|
||||||
readonly server: http.Server;
|
readonly server: http.Server;
|
||||||
readonly wss: ws.Server;
|
readonly wss: ws.Server;
|
||||||
|
@ -38,15 +46,26 @@ export const createApp = async (registerMiddleware?: (app: express.Application)
|
||||||
return cookies;
|
return cookies;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ensureAuthed = (req: http.IncomingMessage, res: express.Response): boolean => {
|
||||||
|
if (!isAuthed(req)) {
|
||||||
|
res.status(401);
|
||||||
|
res.end();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
const isAuthed = (req: http.IncomingMessage): boolean => {
|
const isAuthed = (req: http.IncomingMessage): boolean => {
|
||||||
try {
|
try {
|
||||||
if (!password || !isCli) {
|
if (!options.password || options.bypassAuth) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try/catch placed here just in case
|
// Try/catch placed here just in case
|
||||||
const cookies = parseCookies(req);
|
const cookies = parseCookies(req);
|
||||||
if (cookies.password && cookies.password === password) {
|
if (cookies.password && cookies.password === options.password) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
|
@ -62,8 +81,8 @@ export const createApp = async (registerMiddleware?: (app: express.Application)
|
||||||
};
|
};
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
if (registerMiddleware) {
|
if (options.registerMiddleware) {
|
||||||
registerMiddleware(app);
|
options.registerMiddleware(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
const certs = await new Promise<pem.CertificateCreationResult>((res, rej): void => {
|
const certs = await new Promise<pem.CertificateCreationResult>((res, rej): void => {
|
||||||
|
@ -134,7 +153,7 @@ export const createApp = async (registerMiddleware?: (app: express.Application)
|
||||||
onClose: (cb): void => ws.addEventListener("close", () => cb()),
|
onClose: (cb): void => ws.addEventListener("close", () => cb()),
|
||||||
};
|
};
|
||||||
|
|
||||||
const server = new Server(connection, options);
|
const server = new Server(connection, options.serverOptions);
|
||||||
});
|
});
|
||||||
|
|
||||||
const baseDir = buildDir || path.join(__dirname, "..");
|
const baseDir = buildDir || path.join(__dirname, "..");
|
||||||
|
@ -150,6 +169,10 @@ export const createApp = async (registerMiddleware?: (app: express.Application)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
app.get("/resource/:url(*)", async (req, res) => {
|
app.get("/resource/:url(*)", async (req, res) => {
|
||||||
|
if (!ensureAuthed(req, res)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const fullPath = `/${req.params.url}`;
|
const fullPath = `/${req.params.url}`;
|
||||||
// const relative = path.relative(options!.dataDirectory, fullPath);
|
// const relative = path.relative(options!.dataDirectory, fullPath);
|
||||||
|
@ -184,6 +207,10 @@ export const createApp = async (registerMiddleware?: (app: express.Application)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
app.post("/resource/:url(*)", async (req, res) => {
|
app.post("/resource/:url(*)", async (req, res) => {
|
||||||
|
if (!ensureAuthed(req, res)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const fullPath = `/${req.params.url}`;
|
const fullPath = `/${req.params.url}`;
|
||||||
|
|
||||||
|
|
|
@ -40,3 +40,4 @@ const handlePackages = (dir: string): void => {
|
||||||
};
|
};
|
||||||
|
|
||||||
handlePackages(resolve(__dirname, "..", "packages"));
|
handlePackages(resolve(__dirname, "..", "packages"));
|
||||||
|
handlePackages(resolve(__dirname, "..", "packages", "app"));
|
||||||
|
|
Loading…
Reference in New Issue