Skip to content

Commit 33cdaf9

Browse files
authored
Fixes browser app, adds no-auth (#38)
* Add no-auth flag * Install packages for app dir
1 parent 7b627cc commit 33cdaf9

File tree

3 files changed

+79
-40
lines changed

3 files changed

+79
-40
lines changed

packages/server/src/cli.ts

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export class Entry extends Command {
2424
open: flags.boolean({ char: "o", description: "Open in browser on startup" }),
2525
port: flags.integer({ char: "p", default: 8080, description: "Port to bind on" }),
2626
version: flags.version({ char: "v" }),
27+
"no-auth": flags.boolean({ default: false }),
2728

2829
// Dev flags
2930
"bootstrap-fork": flags.string({ hidden: true }),
@@ -132,41 +133,47 @@ export class Entry extends Command {
132133

133134
const password = "023450wf0951";
134135
const hasCustomHttps = certData && certKeyData;
135-
const app = await createApp((app) => {
136-
app.use((req, res, next) => {
137-
res.on("finish", () => {
138-
logger.trace(`\u001B[1m${req.method} ${res.statusCode} \u001B[0m${req.url}`, field("host", req.hostname), field("ip", req.ip));
136+
const app = await createApp({
137+
bypassAuth: flags["no-auth"],
138+
registerMiddleware: (app): void => {
139+
app.use((req, res, next) => {
140+
res.on("finish", () => {
141+
logger.trace(`\u001B[1m${req.method} ${res.statusCode} \u001B[0m${req.url}`, field("host", req.hostname), field("ip", req.ip));
142+
});
143+
144+
next();
139145
});
140-
141-
next();
142-
});
143-
// If we're not running from the binary and we aren't serving the static
144-
// pre-built version, use webpack to serve the web files.
145-
if (!isCli && !serveStatic) {
146-
const webpackConfig = require(path.join(__dirname, "..", "..", "web", "webpack.config.js"));
147-
const compiler = require("webpack")(webpackConfig);
148-
app.use(require("webpack-dev-middleware")(compiler, {
149-
logger,
150-
publicPath: webpackConfig.output.publicPath,
151-
stats: webpackConfig.stats,
152-
}));
153-
app.use(require("webpack-hot-middleware")(compiler));
154-
}
155-
}, {
156-
builtInExtensionsDirectory: builtInExtensionsDir,
157-
dataDirectory: dataDir,
158-
workingDirectory: workingDir,
159-
fork: (modulePath: string, args: string[], options: ForkOptions): ChildProcess => {
160-
if (options && options.env && options.env.AMD_ENTRYPOINT) {
161-
return forkModule(options.env.AMD_ENTRYPOINT, args, options, dataDir);
146+
// If we're not running from the binary and we aren't serving the static
147+
// pre-built version, use webpack to serve the web files.
148+
if (!isCli && !serveStatic) {
149+
const webpackConfig = require(path.join(__dirname, "..", "..", "web", "webpack.config.js"));
150+
const compiler = require("webpack")(webpackConfig);
151+
app.use(require("webpack-dev-middleware")(compiler, {
152+
logger,
153+
publicPath: webpackConfig.output.publicPath,
154+
stats: webpackConfig.stats,
155+
}));
156+
app.use(require("webpack-hot-middleware")(compiler));
162157
}
163-
164-
return fork(modulePath, args, options);
165158
},
166-
}, password, hasCustomHttps ? {
167-
key: certKeyData,
168-
cert: certData,
169-
} : undefined);
159+
serverOptions: {
160+
builtInExtensionsDirectory: builtInExtensionsDir,
161+
dataDirectory: dataDir,
162+
workingDirectory: workingDir,
163+
fork: (modulePath: string, args: string[], options: ForkOptions): ChildProcess => {
164+
if (options && options.env && options.env.AMD_ENTRYPOINT) {
165+
return forkModule(options.env.AMD_ENTRYPOINT, args, options, dataDir);
166+
}
167+
168+
return fork(modulePath, args, options);
169+
},
170+
},
171+
password,
172+
httpsOptions: hasCustomHttps ? {
173+
key: certKeyData,
174+
cert: certData,
175+
} : undefined,
176+
});
170177

171178
logger.info("Starting webserver...", field("host", flags.host), field("port", flags.port));
172179
app.server.listen(flags.port, flags.host);
@@ -191,8 +198,12 @@ export class Entry extends Command {
191198
logger.warn("Documentation on securing your setup: https://coder.com/docs");
192199
}
193200

194-
logger.info(" ");
195-
logger.info(`Password:\u001B[1m ${password}`);
201+
if (!flags["no-auth"]) {
202+
logger.info(" ");
203+
logger.info(`Password:\u001B[1m ${password}`);
204+
} else {
205+
logger.warn("Launched without authentication.");
206+
}
196207
logger.info(" ");
197208
logger.info("Started (click the link below to open):");
198209
logger.info(`http://localhost:${flags.port}/`);

packages/server/src/server.ts

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,15 @@ import { handle as handleTunnel } from "@coder/tunnel/src/server";
2020
import { createPortScanner } from "./portScanner";
2121
import { buildDir, isCli } from "./constants";
2222

23-
export const createApp = async (registerMiddleware?: (app: express.Application) => void, options?: ServerOptions, password?: string, httpsOptions?: https.ServerOptions): Promise<{
23+
interface CreateAppOptions {
24+
registerMiddleware?: (app: express.Application) => void;
25+
serverOptions?: ServerOptions;
26+
password?: string;
27+
httpsOptions?: https.ServerOptions;
28+
bypassAuth?: boolean;
29+
}
30+
31+
export const createApp = async (options: CreateAppOptions): Promise<{
2432
readonly express: express.Application;
2533
readonly server: http.Server;
2634
readonly wss: ws.Server;
@@ -38,15 +46,26 @@ export const createApp = async (registerMiddleware?: (app: express.Application)
3846
return cookies;
3947
};
4048

49+
const ensureAuthed = (req: http.IncomingMessage, res: express.Response): boolean => {
50+
if (!isAuthed(req)) {
51+
res.status(401);
52+
res.end();
53+
54+
return false;
55+
}
56+
57+
return true;
58+
};
59+
4160
const isAuthed = (req: http.IncomingMessage): boolean => {
4261
try {
43-
if (!password || !isCli) {
62+
if (!options.password || options.bypassAuth) {
4463
return true;
4564
}
4665

4766
// Try/catch placed here just in case
4867
const cookies = parseCookies(req);
49-
if (cookies.password && cookies.password === password) {
68+
if (cookies.password && cookies.password === options.password) {
5069
return true;
5170
}
5271
} catch (ex) {
@@ -62,8 +81,8 @@ export const createApp = async (registerMiddleware?: (app: express.Application)
6281
};
6382

6483
const app = express();
65-
if (registerMiddleware) {
66-
registerMiddleware(app);
84+
if (options.registerMiddleware) {
85+
options.registerMiddleware(app);
6786
}
6887

6988
const certs = await new Promise<pem.CertificateCreationResult>((res, rej): void => {
@@ -134,7 +153,7 @@ export const createApp = async (registerMiddleware?: (app: express.Application)
134153
onClose: (cb): void => ws.addEventListener("close", () => cb()),
135154
};
136155

137-
const server = new Server(connection, options);
156+
const server = new Server(connection, options.serverOptions);
138157
});
139158

140159
const baseDir = buildDir || path.join(__dirname, "..");
@@ -150,6 +169,10 @@ export const createApp = async (registerMiddleware?: (app: express.Application)
150169
}
151170
});
152171
app.get("/resource/:url(*)", async (req, res) => {
172+
if (!ensureAuthed(req, res)) {
173+
return;
174+
}
175+
153176
try {
154177
const fullPath = `/${req.params.url}`;
155178
// const relative = path.relative(options!.dataDirectory, fullPath);
@@ -184,6 +207,10 @@ export const createApp = async (registerMiddleware?: (app: express.Application)
184207
}
185208
});
186209
app.post("/resource/:url(*)", async (req, res) => {
210+
if (!ensureAuthed(req, res)) {
211+
return;
212+
}
213+
187214
try {
188215
const fullPath = `/${req.params.url}`;
189216

scripts/install-packages.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,4 @@ const handlePackages = (dir: string): void => {
4040
};
4141

4242
handlePackages(resolve(__dirname, "..", "packages"));
43+
handlePackages(resolve(__dirname, "..", "packages", "app"));

0 commit comments

Comments
 (0)