forked from coder/code-server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlogin.test.ts
142 lines (115 loc) · 4.82 KB
/
login.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import { RateLimiter } from "../../../../src/node/routes/login"
import { mockLogger } from "../../../utils/helpers"
import * as httpserver from "../../../utils/httpserver"
import * as integration from "../../../utils/integration"
describe("login", () => {
beforeAll(() => {
mockLogger()
})
describe("RateLimiter", () => {
it("should allow one try ", () => {
const limiter = new RateLimiter()
expect(limiter.removeToken()).toBe(true)
})
it("should pull tokens from both limiters (minute & hour)", () => {
const limiter = new RateLimiter()
// Try twice, which pulls two from the minute bucket
limiter.removeToken()
limiter.removeToken()
// Check that we can still try
// which should be true since there are 12 remaining in the hour bucket
expect(limiter.canTry()).toBe(true)
expect(limiter.removeToken()).toBe(true)
})
it("should not allow more than 14 tries in less than an hour", () => {
const limiter = new RateLimiter()
// The limiter allows 2 tries per minute plus 12 per hour
// so if we run it 15 times, 14 should return true and the last
// should return false
for (let i = 1; i <= 14; i++) {
expect(limiter.removeToken()).toBe(true)
}
expect(limiter.canTry()).toBe(false)
expect(limiter.removeToken()).toBe(false)
})
})
describe("/login", () => {
let _codeServer: httpserver.HttpServer | undefined
function codeServer(): httpserver.HttpServer {
if (!_codeServer) {
throw new Error("tried to use code-server before setting it up")
}
return _codeServer
}
// Store whatever might be in here so we can restore it afterward.
// TODO: We should probably pass this as an argument somehow instead of
// manipulating the environment.
const previousEnvPassword = process.env.PASSWORD
beforeEach(async () => {
process.env.PASSWORD = "test"
_codeServer = await integration.setup(["--auth=password"], "")
})
afterEach(async () => {
process.env.PASSWORD = previousEnvPassword
if (_codeServer) {
await _codeServer.dispose()
_codeServer = undefined
}
})
it("should return HTML with 'Missing password' message", async () => {
const resp = await codeServer().fetch("/login", { method: "POST" })
expect(resp.status).toBe(200)
const htmlContent = await resp.text()
expect(htmlContent).toContain("Missing password")
})
it("should return HTML with 'Incorrect password' message", async () => {
const params = new URLSearchParams()
params.append("password", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
const resp = await codeServer().fetch("/login", {
method: "POST",
body: params,
})
expect(resp.status).toBe(200)
const htmlContent = await resp.text()
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}</h1>`)
expect(htmlContent).toContain(`<title>${appName} login</title>`)
})
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}</h1>`)
expect(htmlContent).toContain(`<title>${appName} login</title>`)
})
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}`)
})
})
})