Improve password handling
- Error out if auth is enabled but no password is passed in - Indicate password location on login page
This commit is contained in:
parent
524b0205e9
commit
c0d6eb4664
@ -22,6 +22,7 @@ rules:
|
||||
# For overloads.
|
||||
no-dupe-class-members: off
|
||||
"@typescript-eslint/no-use-before-define": off
|
||||
"@typescript-eslint/no-non-null-assertion": off
|
||||
|
||||
settings:
|
||||
# Does not work with CommonJS unfortunately.
|
||||
|
@ -56,8 +56,7 @@
|
||||
"stylelint": "^13.0.0",
|
||||
"stylelint-config-recommended": "^3.0.0",
|
||||
"ts-node": "^8.4.1",
|
||||
"typescript": "3.7.2",
|
||||
"yarn": "^1.22.4"
|
||||
"typescript": "3.7.2"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/node": "^12.12.7",
|
||||
@ -79,7 +78,8 @@
|
||||
"tar": "^6.0.1",
|
||||
"tar-fs": "^2.0.0",
|
||||
"ws": "^7.2.0",
|
||||
"xdg-basedir": "^4.0.0"
|
||||
"xdg-basedir": "^4.0.0",
|
||||
"yarn": "^1.22.4"
|
||||
},
|
||||
"bin": {
|
||||
"code-server": "out/node/entry.js"
|
||||
|
@ -26,7 +26,7 @@
|
||||
<div class="card-box">
|
||||
<div class="header">
|
||||
<h1 class="main">Welcome to code-server</h1>
|
||||
<div class="sub">Please log in below. Check code-server's logs for the generated password.</div>
|
||||
<div class="sub">Please log in below. {{PASSWORD_MSG}}</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<form class="login-form" method="post">
|
||||
|
@ -2,8 +2,8 @@ import * as http from "http"
|
||||
import * as limiter from "limiter"
|
||||
import * as querystring from "querystring"
|
||||
import { HttpCode, HttpError } from "../../common/http"
|
||||
import { AuthType, HttpProvider, HttpResponse, Route } from "../http"
|
||||
import { hash } from "../util"
|
||||
import { AuthType, HttpProvider, HttpProviderOptions, HttpResponse, Route } from "../http"
|
||||
import { hash, humanPath } from "../util"
|
||||
|
||||
interface LoginPayload {
|
||||
password?: string
|
||||
@ -18,6 +18,14 @@ interface LoginPayload {
|
||||
* Login HTTP provider.
|
||||
*/
|
||||
export class LoginHttpProvider extends HttpProvider {
|
||||
public constructor(
|
||||
options: HttpProviderOptions,
|
||||
private readonly configFile: string,
|
||||
private readonly envPassword: boolean,
|
||||
) {
|
||||
super(options)
|
||||
}
|
||||
|
||||
public async handleRequest(route: Route, request: http.IncomingMessage): Promise<HttpResponse> {
|
||||
if (this.options.auth !== AuthType.Password || !this.isRoot(route)) {
|
||||
throw new HttpError("Not found", HttpCode.NotFound)
|
||||
@ -46,6 +54,11 @@ export class LoginHttpProvider extends HttpProvider {
|
||||
public async getRoot(route: Route, error?: Error): Promise<HttpResponse> {
|
||||
const response = await this.getUtf8Resource(this.rootPath, "src/browser/pages/login.html")
|
||||
response.content = response.content.replace(/{{ERROR}}/, error ? `<div class="error">${error.message}</div>` : "")
|
||||
let passwordMsg = `Check the config file at ${humanPath(this.configFile)} for the password.`
|
||||
if (this.envPassword) {
|
||||
passwordMsg = "Password was set from $PASSWORD."
|
||||
}
|
||||
response.content = response.content.replace(/{{PASSWORD_MSG}}/g, passwordMsg)
|
||||
return this.replaceTemplates(route, response)
|
||||
}
|
||||
|
||||
|
@ -36,10 +36,21 @@ const main = async (cliArgs: Args): Promise<void> => {
|
||||
// This prioritizes the flags set in args over the ones in the config file.
|
||||
let args = Object.assign(configArgs, cliArgs)
|
||||
|
||||
if (!args.auth) {
|
||||
args = {
|
||||
...args,
|
||||
auth: AuthType.Password,
|
||||
}
|
||||
}
|
||||
|
||||
logger.trace(`Using extensions-dir at ${humanPath(args["extensions-dir"])}`)
|
||||
logger.trace(`Using user-data-dir at ${humanPath(args["user-data-dir"])}`)
|
||||
|
||||
const envPassword = !!process.env.PASSWORD
|
||||
const password = args.auth === AuthType.Password && (process.env.PASSWORD || args.password)
|
||||
if (args.auth === AuthType.Password && !password) {
|
||||
throw new Error("Please pass in a password via the config file or $PASSWORD")
|
||||
}
|
||||
const [host, port] = bindAddrFromAllSources(cliArgs, configArgs)
|
||||
|
||||
// Spawn the main HTTP server.
|
||||
@ -69,7 +80,7 @@ const main = async (cliArgs: Args): Promise<void> => {
|
||||
const api = httpServer.registerHttpProvider("/api", ApiHttpProvider, httpServer, vscode, args["user-data-dir"])
|
||||
const update = httpServer.registerHttpProvider("/update", UpdateHttpProvider, false)
|
||||
httpServer.registerHttpProvider("/proxy", ProxyHttpProvider)
|
||||
httpServer.registerHttpProvider("/login", LoginHttpProvider)
|
||||
httpServer.registerHttpProvider("/login", LoginHttpProvider, args.config!, envPassword)
|
||||
httpServer.registerHttpProvider("/static", StaticHttpProvider)
|
||||
httpServer.registerHttpProvider("/dashboard", DashboardHttpProvider, api, update)
|
||||
|
||||
@ -79,15 +90,8 @@ const main = async (cliArgs: Args): Promise<void> => {
|
||||
const serverAddress = await httpServer.listen()
|
||||
logger.info(`HTTP server listening on ${serverAddress}`)
|
||||
|
||||
if (!args.auth) {
|
||||
args = {
|
||||
...args,
|
||||
auth: AuthType.Password,
|
||||
}
|
||||
}
|
||||
|
||||
if (args.auth === AuthType.Password) {
|
||||
if (process.env.PASSWORD) {
|
||||
if (envPassword) {
|
||||
logger.info(" - Using password from $PASSWORD")
|
||||
} else {
|
||||
logger.info(` - Using password from ${humanPath(args.config)}`)
|
||||
|
Reference in New Issue
Block a user