Skip to content

Commit 485ba88

Browse files
committed
Add csrf for login/logout
1 parent 42f7e00 commit 485ba88

File tree

1 file changed

+34
-5
lines changed

1 file changed

+34
-5
lines changed

src/api.ts

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import cheerio from 'cheerio'
12
import * as fs from 'fs-extra'
23
import nodeFetch from 'node-fetch'
34
import tough = require('tough-cookie')
@@ -8,7 +9,8 @@ import config from './config'
89

910
interface APIOptions {
1011
serverUrl: string
11-
cookiePath: string
12+
cookiePath: string,
13+
enterprise: boolean
1214
}
1315

1416
type nodeFetchType = (url: RequestInfo, init?: RequestInit | undefined) => Promise<Response>
@@ -36,10 +38,11 @@ export type HistoryItem = {
3638
*/
3739
class API {
3840
public readonly serverUrl: string
41+
private readonly enterprise: boolean
3942
private readonly _fetch: nodeFetchType
4043

4144
constructor() {
42-
const {serverUrl, cookiePath}: APIOptions = config
45+
const {serverUrl, cookiePath, enterprise}: APIOptions = config
4346

4447
fs.ensureFileSync(cookiePath)
4548

@@ -48,16 +51,18 @@ class API {
4851

4952
this._fetch = fetch
5053
this.serverUrl = serverUrl
54+
this.enterprise = enterprise
5155
}
5256

5357
async login(email: string, password: string) {
5458
const response = await this.fetch(`${this.serverUrl}/login`, {
5559
method: 'post',
5660
body: encodeFormComponent({email, password}),
57-
headers: {
61+
headers: await this.wrapHeaders({
5862
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
59-
}
63+
})
6064
})
65+
6166
return response.status === 200
6267
}
6368

@@ -73,7 +78,12 @@ class API {
7378
}
7479

7580
async logout() {
76-
const response = await this.fetch(`${this.serverUrl}/logout`)
81+
const response = await this.fetch(`${this.serverUrl}/logout`, {
82+
method: this.enterprise ? 'POST' : 'GET',
83+
headers: await this.wrapHeaders({
84+
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
85+
})
86+
})
7787
return response.status === 200
7888
}
7989

@@ -149,6 +159,25 @@ class API {
149159
get domain() {
150160
return url.parse(this.serverUrl).host
151161
}
162+
163+
private async wrapHeaders(headers: any) {
164+
if (this.enterprise) {
165+
const csrf = await this.loadCSRFToken()
166+
return {
167+
...headers,
168+
'X-XSRF-Token': csrf
169+
}
170+
} else {
171+
return headers
172+
}
173+
}
174+
175+
private async loadCSRFToken() {
176+
const html = await this.fetch(`${this.serverUrl}`).then(r => r.text())
177+
const $ = cheerio.load(html)
178+
179+
return $('meta[name="csrf-token"]').attr('content') || ''
180+
}
152181
}
153182

154183
export default API

0 commit comments

Comments
 (0)