diff --git a/src/node/cli.ts b/src/node/cli.ts
index bee8cbe43..ea45b8033 100644
--- a/src/node/cli.ts
+++ b/src/node/cli.ts
@@ -85,6 +85,8 @@ export interface UserProvidedArgs extends UserProvidedCodeArgs {
"ignore-last-opened"?: boolean
link?: OptionalString
verbose?: boolean
+ "app-name"?: string
+ "welcome-text"?: string
/* Positional arguments. */
_?: string[]
}
@@ -238,7 +240,16 @@ export const options: Options
> = {
log: { type: LogLevel },
verbose: { type: "boolean", short: "vvv", description: "Enable verbose logging." },
-
+ "app-name": {
+ type: "string",
+ short: "an",
+ description: "The name to use in branding. Will be shown in titlebar and welcome message",
+ },
+ "welcome-text": {
+ type: "string",
+ short: "w",
+ description: "Text to show on login page",
+ },
link: {
type: OptionalString,
description: `
diff --git a/src/node/routes/login.ts b/src/node/routes/login.ts
index 262147232..633c34ba4 100644
--- a/src/node/routes/login.ts
+++ b/src/node/routes/login.ts
@@ -28,6 +28,8 @@ export class RateLimiter {
const getRoot = async (req: Request, error?: Error): Promise => {
const content = await fs.readFile(path.join(rootPath, "src/browser/pages/login.html"), "utf8")
+ const appName = req.args["app-name"] || "code-server"
+ const welcomeText = req.args["welcome-text"] || `Welcome to ${appName}`
let passwordMsg = `Check the config file at ${humanPath(os.homedir(), req.args.config)} for the password.`
if (req.args.usingEnvPassword) {
passwordMsg = "Password was set from $PASSWORD."
@@ -38,6 +40,8 @@ const getRoot = async (req: Request, error?: Error): Promise => {
return replaceTemplates(
req,
content
+ .replace(/{{APP_NAME}}/g, appName)
+ .replace(/{{WELCOME_TEXT}}/g, welcomeText)
.replace(/{{PASSWORD_MSG}}/g, passwordMsg)
.replace(/{{ERROR}}/, error ? `${escapeHtml(error.message)}
` : ""),
)
diff --git a/test/unit/node/cli.test.ts b/test/unit/node/cli.test.ts
index 51e707001..4afa404c0 100644
--- a/test/unit/node/cli.test.ts
+++ b/test/unit/node/cli.test.ts
@@ -67,6 +67,8 @@ describe("parser", () => {
"1",
"--verbose",
+ ["--app-name", "custom instance name"],
+ ["--welcome-text", "welcome to code"],
"2",
["--locale", "ja"],
@@ -123,6 +125,8 @@ describe("parser", () => {
socket: path.resolve("mumble"),
"socket-mode": "777",
verbose: true,
+ "app-name": "custom instance name",
+ "welcome-text": "welcome to code",
version: true,
"bind-addr": "192.169.0.1:8080",
})
diff --git a/test/unit/node/routes/login.test.ts b/test/unit/node/routes/login.test.ts
index b132c0e87..b2cf44651 100644
--- a/test/unit/node/routes/login.test.ts
+++ b/test/unit/node/routes/login.test.ts
@@ -92,5 +92,51 @@ describe("login", () => {
expect(htmlContent).toContain("Incorrect password")
})
+
+ it("should return correct app-name", async () => {
+ process.env.PASSWORD = previousEnvPassword
+ const appName = "testnäme"
+ const codeServer = await integration.setup([`--app-name=${appName}`], "")
+ const resp = await codeServer.fetch("/login", { method: "GET" })
+
+ const htmlContent = await resp.text()
+ expect(resp.status).toBe(200)
+ expect(htmlContent).toContain(`${appName}`)
+ expect(htmlContent).toContain(`${appName} login`)
+ })
+
+ it("should return correct app-name when unset", async () => {
+ process.env.PASSWORD = previousEnvPassword
+ const appName = "code-server"
+ const codeServer = await integration.setup([], "")
+ const resp = await codeServer.fetch("/login", { method: "GET" })
+
+ const htmlContent = await resp.text()
+ expect(resp.status).toBe(200)
+ expect(htmlContent).toContain(`${appName}`)
+ expect(htmlContent).toContain(`${appName} login`)
+ })
+
+ it("should return correct welcome text", async () => {
+ process.env.PASSWORD = previousEnvPassword
+ const welcomeText = "Welcome to your code workspace! öäü🔐"
+ const codeServer = await integration.setup([`--welcome-text=${welcomeText}`], "")
+ const resp = await codeServer.fetch("/login", { method: "GET" })
+
+ const htmlContent = await resp.text()
+ expect(resp.status).toBe(200)
+ expect(htmlContent).toContain(welcomeText)
+ })
+
+ it("should return correct welcome text when none is set but app-name is", async () => {
+ process.env.PASSWORD = previousEnvPassword
+ const appName = "testnäme"
+ const codeServer = await integration.setup([`--app-name=${appName}`], "")
+ const resp = await codeServer.fetch("/login", { method: "GET" })
+
+ const htmlContent = await resp.text()
+ expect(resp.status).toBe(200)
+ expect(htmlContent).toContain(`Welcome to ${appName}`)
+ })
})
})