mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #9956 from overleaf/em-node-fetch-web
Replace request-promise with fetch in web acceptance tests GitOrigin-RevId: f50357cdea2d1353d7a82c5346b149018f91823f
This commit is contained in:
parent
00b051e2d7
commit
fe963ba692
9 changed files with 368 additions and 453 deletions
89
package-lock.json
generated
89
package-lock.json
generated
|
@ -25893,49 +25893,6 @@
|
|||
"throttleit": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/request-promise-core": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
|
||||
"integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.19"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"request": "^2.34"
|
||||
}
|
||||
},
|
||||
"node_modules/request-promise-native": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
|
||||
"integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
|
||||
"deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142",
|
||||
"dependencies": {
|
||||
"request-promise-core": "1.1.4",
|
||||
"stealthy-require": "^1.1.1",
|
||||
"tough-cookie": "^2.3.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"request": "^2.34"
|
||||
}
|
||||
},
|
||||
"node_modules/request-promise-native/node_modules/tough-cookie": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
|
||||
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
|
||||
"dependencies": {
|
||||
"psl": "^1.1.28",
|
||||
"punycode": "^2.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/request/node_modules/form-data": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
|
||||
|
@ -28212,14 +28169,6 @@
|
|||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/stealthy-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
|
||||
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/stream-buffers": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.2.tgz",
|
||||
|
@ -35066,7 +35015,6 @@
|
|||
"recurly": "^4.0.0",
|
||||
"referer-parser": "0.0.3",
|
||||
"request": "^2.88.2",
|
||||
"request-promise-native": "^1.0.8",
|
||||
"requestretry": "^6.0.0",
|
||||
"rimraf": "2.2.6",
|
||||
"rolling-rate-limiter": "^0.2.10",
|
||||
|
@ -35169,6 +35117,7 @@
|
|||
"terser-webpack-plugin": "^5.3.1",
|
||||
"timekeeper": "^2.2.0",
|
||||
"to-string-loader": "^1.2.0",
|
||||
"tough-cookie": "^4.0.0",
|
||||
"typescript": "^4.5.5",
|
||||
"val-loader": "^4.0.0",
|
||||
"webpack": "^5.71.0",
|
||||
|
@ -42853,7 +42802,6 @@
|
|||
"recurly": "^4.0.0",
|
||||
"referer-parser": "0.0.3",
|
||||
"request": "^2.88.2",
|
||||
"request-promise-native": "^1.0.8",
|
||||
"requestretry": "^6.0.0",
|
||||
"requirejs": "^2.3.6",
|
||||
"rimraf": "2.2.6",
|
||||
|
@ -42870,6 +42818,7 @@
|
|||
"terser-webpack-plugin": "^5.3.1",
|
||||
"timekeeper": "^2.2.0",
|
||||
"to-string-loader": "^1.2.0",
|
||||
"tough-cookie": "^4.0.0",
|
||||
"tsscmp": "^1.0.6",
|
||||
"typescript": "^4.5.5",
|
||||
"underscore": "^1.13.1",
|
||||
|
@ -61749,35 +61698,6 @@
|
|||
"throttleit": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"request-promise-core": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
|
||||
"integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
|
||||
"requires": {
|
||||
"lodash": "^4.17.19"
|
||||
}
|
||||
},
|
||||
"request-promise-native": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
|
||||
"integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
|
||||
"requires": {
|
||||
"request-promise-core": "1.1.4",
|
||||
"stealthy-require": "^1.1.1",
|
||||
"tough-cookie": "^2.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"tough-cookie": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
|
||||
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
|
||||
"requires": {
|
||||
"psl": "^1.1.28",
|
||||
"punycode": "^2.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"requestretry": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/requestretry/-/requestretry-4.1.2.tgz",
|
||||
|
@ -63594,11 +63514,6 @@
|
|||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
|
||||
},
|
||||
"stealthy-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
|
||||
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
|
||||
},
|
||||
"stream-buffers": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.2.tgz",
|
||||
|
|
|
@ -9,9 +9,10 @@ describe('Launchpad', function () {
|
|||
const user = new UserHelper()
|
||||
|
||||
it('should show the launchpad page', async function () {
|
||||
const response = await user.request.get('/launchpad')
|
||||
expect(response.statusCode).to.equal(200)
|
||||
const $ = cheerio.load(response.body)
|
||||
const response = await user.fetch('/launchpad')
|
||||
expect(response.status).to.equal(200)
|
||||
const body = await response.text()
|
||||
const $ = cheerio.load(body)
|
||||
expect($('h2').first().text()).to.equal('Create the first Admin account')
|
||||
expect($('form[name="email"]').first()).to.exist
|
||||
expect($('form[name="password"]').first()).to.exist
|
||||
|
@ -19,45 +20,54 @@ describe('Launchpad', function () {
|
|||
|
||||
it('should allow for creation of the first admin user', async function () {
|
||||
// Load the launchpad page
|
||||
const initialPageResponse = await user.request.get('/launchpad')
|
||||
expect(initialPageResponse.statusCode).to.equal(200)
|
||||
const $ = cheerio.load(initialPageResponse.body)
|
||||
const initialPageResponse = await user.fetch('/launchpad')
|
||||
expect(initialPageResponse.status).to.equal(200)
|
||||
const initialPageBody = await initialPageResponse.text()
|
||||
const $ = cheerio.load(initialPageBody)
|
||||
expect($('h2').first().text()).to.equal('Create the first Admin account')
|
||||
expect($('form[name="email"]').first()).to.exist
|
||||
expect($('form[name="password"]').first()).to.exist
|
||||
|
||||
// Submit the form
|
||||
let csrfToken = await user.getCsrfToken()
|
||||
const postResponse = await user.request.post({
|
||||
url: '/launchpad/register_admin',
|
||||
json: {
|
||||
const postResponse = await user.fetch('/launchpad/register_admin', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
_csrf: csrfToken,
|
||||
email: adminEmail,
|
||||
password: adminPassword,
|
||||
},
|
||||
}),
|
||||
})
|
||||
expect(postResponse.statusCode).to.equal(200)
|
||||
expect(postResponse.body).to.deep.equal({ redir: '/launchpad' })
|
||||
expect(postResponse.status).to.equal(200)
|
||||
const postBody = await postResponse.json()
|
||||
expect(postBody).to.deep.equal({ redir: '/launchpad' })
|
||||
|
||||
// Try to load the page again
|
||||
const secondPageResponse = await user.request.get('/launchpad', {
|
||||
simple: false,
|
||||
})
|
||||
expect(secondPageResponse.statusCode).to.equal(302)
|
||||
expect(secondPageResponse.headers.location).to.equal('/login')
|
||||
const secondPageResponse = await user.fetch('/launchpad')
|
||||
expect(secondPageResponse.status).to.equal(302)
|
||||
expect(secondPageResponse.headers.get('location')).to.equal(
|
||||
UserHelper.url('/login').toString()
|
||||
)
|
||||
|
||||
// Forbid submitting the form again
|
||||
csrfToken = await user.getCsrfToken()
|
||||
const badPostResponse = await user.request.post({
|
||||
url: '/launchpad/register_admin',
|
||||
json: {
|
||||
const badPostResponse = await user.fetch('/launchpad/register_admin', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
_csrf: csrfToken,
|
||||
email: adminEmail + '1',
|
||||
password: adminPassword + '1',
|
||||
},
|
||||
simple: false,
|
||||
}),
|
||||
})
|
||||
expect(badPostResponse.statusCode).to.equal(403)
|
||||
expect(badPostResponse.status).to.equal(403)
|
||||
|
||||
// Log in as this new admin user
|
||||
const adminUser = await UserHelper.loginUser({
|
||||
|
|
|
@ -206,7 +206,6 @@
|
|||
"recurly": "^4.0.0",
|
||||
"referer-parser": "0.0.3",
|
||||
"request": "^2.88.2",
|
||||
"request-promise-native": "^1.0.8",
|
||||
"requestretry": "^6.0.0",
|
||||
"rimraf": "2.2.6",
|
||||
"rolling-rate-limiter": "^0.2.10",
|
||||
|
@ -309,6 +308,7 @@
|
|||
"terser-webpack-plugin": "^5.3.1",
|
||||
"timekeeper": "^2.2.0",
|
||||
"to-string-loader": "^1.2.0",
|
||||
"tough-cookie": "^4.0.0",
|
||||
"typescript": "^4.5.5",
|
||||
"val-loader": "^4.0.0",
|
||||
"webpack": "^5.71.0",
|
||||
|
|
|
@ -13,31 +13,21 @@ describe('BetaProgram', function () {
|
|||
})
|
||||
})
|
||||
it('should opt in', async function () {
|
||||
const response = await userHelper.request.post('/beta/opt-in', {
|
||||
simple: false,
|
||||
})
|
||||
expect(response.statusCode).to.equal(302)
|
||||
response.statusCode.should.equal(302)
|
||||
expect(response.headers.location).to.equal('/beta/participate')
|
||||
const user = (
|
||||
await UserHelper.getUser({
|
||||
email,
|
||||
})
|
||||
).user
|
||||
const response = await userHelper.fetch('/beta/opt-in', { method: 'POST' })
|
||||
expect(response.status).to.equal(302)
|
||||
expect(response.headers.get('location')).to.equal(
|
||||
UserHelper.url('/beta/participate').toString()
|
||||
)
|
||||
const user = (await UserHelper.getUser({ email })).user
|
||||
expect(user.betaProgram).to.equal(true)
|
||||
})
|
||||
it('should opt out', async function () {
|
||||
const response = await userHelper.request.post('/beta/opt-out', {
|
||||
simple: false,
|
||||
})
|
||||
expect(response.statusCode).to.equal(302)
|
||||
response.statusCode.should.equal(302)
|
||||
expect(response.headers.location).to.equal('/beta/participate')
|
||||
const user = (
|
||||
await UserHelper.getUser({
|
||||
email,
|
||||
})
|
||||
).user
|
||||
const response = await userHelper.fetch('/beta/opt-out', { method: 'POST' })
|
||||
expect(response.status).to.equal(302)
|
||||
expect(response.headers.get('location')).to.equal(
|
||||
UserHelper.url('/beta/participate').toString()
|
||||
)
|
||||
const user = (await UserHelper.getUser({ email })).user
|
||||
expect(user.betaProgram).to.equal(false)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -13,10 +13,9 @@ describe('PasswordReset', function () {
|
|||
|
||||
// generate the token
|
||||
await userHelper.getCsrfToken()
|
||||
response = await userHelper.request.post('/user/password/reset', {
|
||||
form: {
|
||||
email,
|
||||
},
|
||||
response = await userHelper.fetch('/user/password/reset', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({ email }),
|
||||
})
|
||||
|
||||
token = (
|
||||
|
@ -32,20 +31,20 @@ describe('PasswordReset', function () {
|
|||
email,
|
||||
password: userHelper.getDefaultPassword(),
|
||||
})
|
||||
response = await userHelper.request.get(
|
||||
`/user/password/set?passwordResetToken=${token}&email=${email}`,
|
||||
{ simple: false }
|
||||
response = await userHelper.fetch(
|
||||
`/user/password/set?passwordResetToken=${token}&email=${email}`
|
||||
)
|
||||
expect(response.statusCode).to.equal(302)
|
||||
expect(response.headers.location).to.equal(
|
||||
`/user/password/set${emailQuery}`
|
||||
expect(response.status).to.equal(302)
|
||||
expect(response.headers.get('location')).to.equal(
|
||||
UserHelper.url(`/user/password/set${emailQuery}`).toString()
|
||||
)
|
||||
// send reset request
|
||||
response = await userHelper.request.post('/user/password/set', {
|
||||
form: {
|
||||
response = await userHelper.fetch('/user/password/set', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
passwordResetToken: token,
|
||||
password: 'a-password',
|
||||
},
|
||||
}),
|
||||
})
|
||||
userHelper = await UserHelper.getUser({ email })
|
||||
user = userHelper.user
|
||||
|
@ -75,20 +74,20 @@ describe('PasswordReset', function () {
|
|||
email: otherUserEmail,
|
||||
password: userHelper.getDefaultPassword(),
|
||||
})
|
||||
response = await userHelper.request.get(
|
||||
`/user/password/set?passwordResetToken=${token}&email=${email}`,
|
||||
{ simple: false }
|
||||
response = await userHelper.fetch(
|
||||
`/user/password/set?passwordResetToken=${token}&email=${email}`
|
||||
)
|
||||
expect(response.statusCode).to.equal(302)
|
||||
expect(response.headers.location).to.equal(
|
||||
`/user/password/set${emailQuery}`
|
||||
expect(response.status).to.equal(302)
|
||||
expect(response.headers.get('location')).to.equal(
|
||||
UserHelper.url(`/user/password/set${emailQuery}`).toString()
|
||||
)
|
||||
// send reset request
|
||||
response = await userHelper.request.post('/user/password/set', {
|
||||
form: {
|
||||
response = await userHelper.fetch('/user/password/set', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
passwordResetToken: token,
|
||||
password: 'a-password',
|
||||
},
|
||||
}),
|
||||
})
|
||||
userHelper = await UserHelper.getUser({ email })
|
||||
user = userHelper.user
|
||||
|
@ -110,20 +109,20 @@ describe('PasswordReset', function () {
|
|||
})
|
||||
describe('when not logged in', function () {
|
||||
beforeEach(async function () {
|
||||
response = await userHelper.request.get(
|
||||
`/user/password/set?passwordResetToken=${token}&email=${email}`,
|
||||
{ simple: false }
|
||||
response = await userHelper.fetch(
|
||||
`/user/password/set?passwordResetToken=${token}&email=${email}`
|
||||
)
|
||||
expect(response.statusCode).to.equal(302)
|
||||
expect(response.headers.location).to.equal(
|
||||
`/user/password/set${emailQuery}`
|
||||
expect(response.status).to.equal(302)
|
||||
expect(response.headers.get('location')).to.equal(
|
||||
UserHelper.url(`/user/password/set${emailQuery}`).toString()
|
||||
)
|
||||
// send reset request
|
||||
response = await userHelper.request.post('/user/password/set', {
|
||||
form: {
|
||||
response = await userHelper.fetch('/user/password/set', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
passwordResetToken: token,
|
||||
password: 'a-password',
|
||||
},
|
||||
}),
|
||||
})
|
||||
userHelper = await UserHelper.getUser({ email })
|
||||
user = userHelper.user
|
||||
|
@ -144,24 +143,23 @@ describe('PasswordReset', function () {
|
|||
})
|
||||
describe('password checks', function () {
|
||||
beforeEach(async function () {
|
||||
response = await userHelper.request.get(
|
||||
`/user/password/set?passwordResetToken=${token}&email=${email}`,
|
||||
{ simple: false }
|
||||
response = await userHelper.fetch(
|
||||
`/user/password/set?passwordResetToken=${token}&email=${email}`
|
||||
)
|
||||
expect(response.statusCode).to.equal(302)
|
||||
expect(response.headers.location).to.equal(
|
||||
`/user/password/set${emailQuery}`
|
||||
expect(response.status).to.equal(302)
|
||||
expect(response.headers.get('location')).to.equal(
|
||||
UserHelper.url(`/user/password/set${emailQuery}`).toString()
|
||||
)
|
||||
})
|
||||
it('without a password should return 400 and not log the change', async function () {
|
||||
// send reset request
|
||||
response = await userHelper.request.post('/user/password/set', {
|
||||
form: {
|
||||
response = await userHelper.fetch('/user/password/set', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
passwordResetToken: token,
|
||||
},
|
||||
simple: false,
|
||||
}),
|
||||
})
|
||||
expect(response.statusCode).to.equal(400)
|
||||
expect(response.status).to.equal(400)
|
||||
userHelper = await UserHelper.getUser({ email })
|
||||
|
||||
const auditLog = userHelper.getAuditLogWithoutNoise()
|
||||
|
@ -170,14 +168,14 @@ describe('PasswordReset', function () {
|
|||
|
||||
it('without a valid password should return 400 and not log the change', async function () {
|
||||
// send reset request
|
||||
response = await userHelper.request.post('/user/password/set', {
|
||||
form: {
|
||||
response = await userHelper.fetch('/user/password/set', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
passwordResetToken: token,
|
||||
password: 'short',
|
||||
},
|
||||
simple: false,
|
||||
}),
|
||||
})
|
||||
expect(response.statusCode).to.equal(400)
|
||||
expect(response.status).to.equal(400)
|
||||
userHelper = await UserHelper.getUser({ email })
|
||||
|
||||
const auditLog = userHelper.getAuditLogWithoutNoise()
|
||||
|
@ -187,41 +185,45 @@ describe('PasswordReset', function () {
|
|||
it('should flag email in password', async function () {
|
||||
const localPart = email.split('@').shift()
|
||||
// send bad password
|
||||
response = await userHelper.request.post('/user/password/set', {
|
||||
form: {
|
||||
response = await userHelper.fetch('/user/password/set', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
passwordResetToken: token,
|
||||
password: localPart,
|
||||
email,
|
||||
},
|
||||
json: true,
|
||||
simple: false,
|
||||
}),
|
||||
})
|
||||
expect(response.statusCode).to.equal(400)
|
||||
expect(response.body).to.deep.equal({
|
||||
expect(response.status).to.equal(400)
|
||||
const body = await response.json()
|
||||
expect(body).to.deep.equal({
|
||||
message: { text: 'password contains part of email address' },
|
||||
})
|
||||
})
|
||||
|
||||
it('should be able to retry after providing an invalid password', async function () {
|
||||
// send bad password
|
||||
response = await userHelper.request.post('/user/password/set', {
|
||||
form: {
|
||||
response = await userHelper.fetch('/user/password/set', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
passwordResetToken: token,
|
||||
password: 'short',
|
||||
},
|
||||
simple: false,
|
||||
}),
|
||||
})
|
||||
expect(response.statusCode).to.equal(400)
|
||||
expect(response.status).to.equal(400)
|
||||
|
||||
// send good password
|
||||
response = await userHelper.request.post('/user/password/set', {
|
||||
form: {
|
||||
response = await userHelper.fetch('/user/password/set', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
passwordResetToken: token,
|
||||
password: 'SomeThingVeryStrong!11',
|
||||
},
|
||||
simple: false,
|
||||
}),
|
||||
})
|
||||
expect(response.statusCode).to.equal(200)
|
||||
expect(response.status).to.equal(200)
|
||||
userHelper = await UserHelper.getUser({ email })
|
||||
|
||||
const auditLog = userHelper.getAuditLogWithoutNoise()
|
||||
|
@ -230,17 +232,16 @@ describe('PasswordReset', function () {
|
|||
|
||||
it('when the password is the same as current, should return 400 and log the change', async function () {
|
||||
// send reset request
|
||||
response = await userHelper.request.post('/user/password/set', {
|
||||
form: {
|
||||
response = await userHelper.fetch('/user/password/set', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
passwordResetToken: token,
|
||||
password: userHelper.getDefaultPassword(),
|
||||
},
|
||||
simple: false,
|
||||
}),
|
||||
})
|
||||
expect(response.statusCode).to.equal(400)
|
||||
expect(JSON.parse(response.body).message.key).to.equal(
|
||||
'password-must-be-different'
|
||||
)
|
||||
expect(response.status).to.equal(400)
|
||||
const body = await response.json()
|
||||
expect(body.message.key).to.equal('password-must-be-different')
|
||||
userHelper = await UserHelper.getUser({ email })
|
||||
|
||||
const auditLog = userHelper.getAuditLogWithoutNoise()
|
||||
|
@ -251,80 +252,81 @@ describe('PasswordReset', function () {
|
|||
|
||||
describe('multiple attempts to set the password, reaching attempt limit', async function () {
|
||||
beforeEach(async function () {
|
||||
response = await userHelper.request.get(
|
||||
`/user/password/set?passwordResetToken=${token}&email=${email}`,
|
||||
{ simple: false }
|
||||
response = await userHelper.fetch(
|
||||
`/user/password/set?passwordResetToken=${token}&email=${email}`
|
||||
)
|
||||
expect(response.statusCode).to.equal(302)
|
||||
expect(response.headers.location).to.equal(
|
||||
`/user/password/set${emailQuery}`
|
||||
expect(response.status).to.equal(302)
|
||||
expect(response.headers.get('location')).to.equal(
|
||||
UserHelper.url(`/user/password/set${emailQuery}`).toString()
|
||||
)
|
||||
})
|
||||
|
||||
it('should allow multiple attempts with same-password error, then deny further attempts', async function () {
|
||||
const sendSamePasswordRequest = async function () {
|
||||
return userHelper.request.post('/user/password/set', {
|
||||
form: {
|
||||
return userHelper.fetch('/user/password/set', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
passwordResetToken: token,
|
||||
password: userHelper.getDefaultPassword(),
|
||||
},
|
||||
simple: false,
|
||||
}),
|
||||
})
|
||||
}
|
||||
// Three attempts at setting the password, all rejected for being the same as
|
||||
// the current password
|
||||
const response1 = await sendSamePasswordRequest()
|
||||
expect(response1.statusCode).to.equal(400)
|
||||
expect(JSON.parse(response1.body).message.key).to.equal(
|
||||
'password-must-be-different'
|
||||
)
|
||||
expect(response1.status).to.equal(400)
|
||||
const body1 = await response1.json()
|
||||
expect(body1.message.key).to.equal('password-must-be-different')
|
||||
const response2 = await sendSamePasswordRequest()
|
||||
expect(response2.statusCode).to.equal(400)
|
||||
expect(JSON.parse(response2.body).message.key).to.equal(
|
||||
'password-must-be-different'
|
||||
)
|
||||
expect(response2.status).to.equal(400)
|
||||
const body2 = await response2.json()
|
||||
expect(body2.message.key).to.equal('password-must-be-different')
|
||||
const response3 = await sendSamePasswordRequest()
|
||||
expect(response3.statusCode).to.equal(400)
|
||||
expect(JSON.parse(response3.body).message.key).to.equal(
|
||||
'password-must-be-different'
|
||||
)
|
||||
expect(response3.status).to.equal(400)
|
||||
const body3 = await response3.json()
|
||||
expect(body3.message.key).to.equal('password-must-be-different')
|
||||
// Fourth attempt is rejected because the token has been used too many times
|
||||
const response4 = await sendSamePasswordRequest()
|
||||
expect(response4.statusCode).to.equal(404)
|
||||
expect(JSON.parse(response4.body).message.key).to.equal('token-expired')
|
||||
expect(response4.status).to.equal(404)
|
||||
const body4 = await response4.json()
|
||||
expect(body4.message.key).to.equal('token-expired')
|
||||
})
|
||||
|
||||
it('should allow multiple attempts with same-password error, then set the password', async function () {
|
||||
const sendSamePasswordRequest = async function () {
|
||||
return userHelper.request.post('/user/password/set', {
|
||||
form: {
|
||||
return userHelper.fetch('/user/password/set', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
passwordResetToken: token,
|
||||
password: userHelper.getDefaultPassword(),
|
||||
},
|
||||
simple: false,
|
||||
}),
|
||||
})
|
||||
}
|
||||
// Two attempts at setting the password, all rejected for being the same as
|
||||
// the current password
|
||||
const response1 = await sendSamePasswordRequest()
|
||||
expect(response1.statusCode).to.equal(400)
|
||||
expect(JSON.parse(response1.body).message.key).to.equal(
|
||||
'password-must-be-different'
|
||||
)
|
||||
expect(response1.status).to.equal(400)
|
||||
const body1 = await response1.json()
|
||||
expect(body1.message.key).to.equal('password-must-be-different')
|
||||
const response2 = await sendSamePasswordRequest()
|
||||
expect(response2.statusCode).to.equal(400)
|
||||
expect(JSON.parse(response2.body).message.key).to.equal(
|
||||
'password-must-be-different'
|
||||
)
|
||||
expect(response2.status).to.equal(400)
|
||||
const body2 = await response2.json()
|
||||
expect(body2.message.key).to.equal('password-must-be-different')
|
||||
// Third attempt is succeeds
|
||||
const response3 = await userHelper.request.post('/user/password/set', {
|
||||
form: {
|
||||
const response3 = await userHelper.fetch('/user/password/set', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
passwordResetToken: token,
|
||||
password: 'some-new-password',
|
||||
},
|
||||
simple: false,
|
||||
}),
|
||||
})
|
||||
expect(response3.statusCode).to.equal(200)
|
||||
expect(response3.status).to.equal(200)
|
||||
// Check the user and audit log
|
||||
userHelper = await UserHelper.getUser({ email })
|
||||
user = userHelper.user
|
||||
|
@ -342,83 +344,79 @@ describe('PasswordReset', function () {
|
|||
|
||||
describe('without a valid token', function () {
|
||||
it('no token should redirect to page to re-request reset token', async function () {
|
||||
response = await userHelper.request.get(
|
||||
`/user/password/set?&email=${email}`,
|
||||
{ simple: false }
|
||||
response = await userHelper.fetch(`/user/password/set?&email=${email}`)
|
||||
expect(response.status).to.equal(302)
|
||||
expect(response.headers.get('location')).to.equal(
|
||||
UserHelper.url('/user/password/reset').toString()
|
||||
)
|
||||
expect(response.statusCode).to.equal(302)
|
||||
expect(response.headers.location).to.equal('/user/password/reset')
|
||||
})
|
||||
it('should show error for invalid tokens and return 404 if used', async function () {
|
||||
const invalidToken = 'not-real-token'
|
||||
response = await userHelper.request.get(
|
||||
`/user/password/set?&passwordResetToken=${invalidToken}&email=${email}`,
|
||||
{ simple: false }
|
||||
response = await userHelper.fetch(
|
||||
`/user/password/set?&passwordResetToken=${invalidToken}&email=${email}`
|
||||
)
|
||||
expect(response.statusCode).to.equal(302)
|
||||
expect(response.headers.location).to.equal(
|
||||
`/user/password/reset?error=token_expired`
|
||||
expect(response.status).to.equal(302)
|
||||
expect(response.headers.get('location')).to.equal(
|
||||
UserHelper.url('/user/password/reset?error=token_expired').toString()
|
||||
)
|
||||
// send reset request
|
||||
response = await userHelper.request.post('/user/password/set', {
|
||||
form: {
|
||||
response = await userHelper.fetch('/user/password/set', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
passwordResetToken: invalidToken,
|
||||
password: 'a-password',
|
||||
},
|
||||
simple: false,
|
||||
}),
|
||||
})
|
||||
expect(response.statusCode).to.equal(404)
|
||||
expect(response.status).to.equal(404)
|
||||
})
|
||||
})
|
||||
describe('password reset', function () {
|
||||
it('should return 200 if email field is valid', async function () {
|
||||
response = await userHelper.request.post(`/user/password/reset`, {
|
||||
form: {
|
||||
email,
|
||||
},
|
||||
response = await userHelper.fetch(`/user/password/reset`, {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({ email }),
|
||||
})
|
||||
expect(response.statusCode).to.equal(200)
|
||||
expect(response.status).to.equal(200)
|
||||
})
|
||||
|
||||
it('should return 400 if email field is missing', async function () {
|
||||
response = await userHelper.request.post(`/user/password/reset`, {
|
||||
form: {
|
||||
mail: email,
|
||||
},
|
||||
simple: false,
|
||||
response = await userHelper.fetch(`/user/password/reset`, {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({ mail: email }),
|
||||
})
|
||||
expect(response.statusCode).to.equal(400)
|
||||
expect(response.status).to.equal(400)
|
||||
})
|
||||
})
|
||||
describe('password set', function () {
|
||||
it('should return 200 if password and passwordResetToken fields are valid', async function () {
|
||||
response = await userHelper.request.post(`/user/password/set`, {
|
||||
form: {
|
||||
response = await userHelper.fetch(`/user/password/set`, {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
password: 'new-password',
|
||||
passwordResetToken: token,
|
||||
},
|
||||
}),
|
||||
})
|
||||
expect(response.statusCode).to.equal(200)
|
||||
expect(response.status).to.equal(200)
|
||||
})
|
||||
|
||||
it('should return 400 if password field is missing', async function () {
|
||||
response = await userHelper.request.post(`/user/password/set`, {
|
||||
form: {
|
||||
response = await userHelper.fetch(`/user/password/set`, {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
passwordResetToken: token,
|
||||
},
|
||||
simple: false,
|
||||
}),
|
||||
})
|
||||
expect(response.statusCode).to.equal(400)
|
||||
expect(response.status).to.equal(400)
|
||||
})
|
||||
|
||||
it('should return 400 if passwordResetToken field is missing', async function () {
|
||||
response = await userHelper.request.post(`/user/password/set`, {
|
||||
form: {
|
||||
response = await userHelper.fetch(`/user/password/set`, {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
password: 'new-password',
|
||||
},
|
||||
simple: false,
|
||||
}),
|
||||
})
|
||||
expect(response.statusCode).to.equal(400)
|
||||
expect(response.status).to.equal(400)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -23,19 +23,19 @@ describe('PasswordUpdate', function () {
|
|||
})
|
||||
describe('success', function () {
|
||||
beforeEach(async function () {
|
||||
response = await userHelper.request.post('/user/password/update', {
|
||||
form: {
|
||||
response = await userHelper.fetch('/user/password/update', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
currentPassword: password,
|
||||
newPassword1: 'new-password',
|
||||
newPassword2: 'new-password',
|
||||
},
|
||||
simple: false,
|
||||
}),
|
||||
})
|
||||
userHelper = await UserHelper.getUser({ email })
|
||||
user = userHelper.user
|
||||
})
|
||||
it('should return 200', async function () {
|
||||
expect(response.statusCode).to.equal(200)
|
||||
expect(response.status).to.equal(200)
|
||||
})
|
||||
it('should update the audit log', function () {
|
||||
const auditLog = userHelper.getAuditLogWithoutNoise()
|
||||
|
@ -50,17 +50,17 @@ describe('PasswordUpdate', function () {
|
|||
describe('errors', function () {
|
||||
describe('missing current password', function () {
|
||||
beforeEach(async function () {
|
||||
response = await userHelper.request.post('/user/password/update', {
|
||||
form: {
|
||||
response = await userHelper.fetch('/user/password/update', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
newPassword1: 'new-password',
|
||||
newPassword2: 'new-password',
|
||||
},
|
||||
simple: false,
|
||||
}),
|
||||
})
|
||||
userHelper = await UserHelper.getUser({ email })
|
||||
})
|
||||
it('should return 500', async function () {
|
||||
expect(response.statusCode).to.equal(500)
|
||||
expect(response.status).to.equal(500)
|
||||
})
|
||||
it('should not update audit log', async function () {
|
||||
const auditLog = userHelper.getAuditLogWithoutNoise()
|
||||
|
@ -69,18 +69,18 @@ describe('PasswordUpdate', function () {
|
|||
})
|
||||
describe('wrong current password', function () {
|
||||
beforeEach(async function () {
|
||||
response = await userHelper.request.post('/user/password/update', {
|
||||
form: {
|
||||
response = await userHelper.fetch('/user/password/update', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
currentPassword: 'wrong-password',
|
||||
newPassword1: 'new-password',
|
||||
newPassword2: 'new-password',
|
||||
},
|
||||
simple: false,
|
||||
}),
|
||||
})
|
||||
userHelper = await UserHelper.getUser({ email })
|
||||
})
|
||||
it('should return 400', async function () {
|
||||
expect(response.statusCode).to.equal(400)
|
||||
expect(response.status).to.equal(400)
|
||||
})
|
||||
it('should not update audit log', async function () {
|
||||
const auditLog = userHelper.getAuditLogWithoutNoise()
|
||||
|
@ -89,22 +89,26 @@ describe('PasswordUpdate', function () {
|
|||
})
|
||||
describe('newPassword1 does not match newPassword2', function () {
|
||||
beforeEach(async function () {
|
||||
response = await userHelper.request.post('/user/password/update', {
|
||||
form: {
|
||||
response = await userHelper.fetch('/user/password/update', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
currentPassword: password,
|
||||
newPassword1: 'new-password',
|
||||
newPassword2: 'oops-password',
|
||||
},
|
||||
json: true,
|
||||
simple: false,
|
||||
}),
|
||||
})
|
||||
userHelper = await UserHelper.getUser({ email })
|
||||
})
|
||||
it('should return 400', async function () {
|
||||
expect(response.statusCode).to.equal(400)
|
||||
expect(response.status).to.equal(400)
|
||||
})
|
||||
it('should return error message', async function () {
|
||||
expect(response.body.message).to.equal('Passwords do not match')
|
||||
const body = await response.json()
|
||||
expect(body.message).to.equal('Passwords do not match')
|
||||
})
|
||||
it('should not update audit log', async function () {
|
||||
const auditLog = userHelper.getAuditLogWithoutNoise()
|
||||
|
@ -113,22 +117,26 @@ describe('PasswordUpdate', function () {
|
|||
})
|
||||
describe('new password is not valid', function () {
|
||||
beforeEach(async function () {
|
||||
response = await userHelper.request.post('/user/password/update', {
|
||||
form: {
|
||||
response = await userHelper.fetch('/user/password/update', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
currentPassword: password,
|
||||
newPassword1: 'short',
|
||||
newPassword2: 'short',
|
||||
},
|
||||
json: true,
|
||||
simple: false,
|
||||
}),
|
||||
})
|
||||
userHelper = await UserHelper.getUser({ email })
|
||||
})
|
||||
it('should return 400', async function () {
|
||||
expect(response.statusCode).to.equal(400)
|
||||
expect(response.status).to.equal(400)
|
||||
})
|
||||
it('should return error message', async function () {
|
||||
expect(response.body.message).to.equal('password is too short')
|
||||
const body = await response.json()
|
||||
expect(body.message).to.equal('password is too short')
|
||||
})
|
||||
it('should not update audit log', async function () {
|
||||
const auditLog = userHelper.getAuditLogWithoutNoise()
|
||||
|
|
|
@ -43,19 +43,18 @@ describe('PrimaryEmailCheck', function () {
|
|||
describe('redirections', function () {
|
||||
describe('when the user has signed up recently', function () {
|
||||
it("shouldn't be redirected from project list to the primary email check page", async function () {
|
||||
const response = await userHelper.request.get(
|
||||
'/project' + SPLIT_TEST_QUERY
|
||||
)
|
||||
expect(response.statusCode).to.equal(200)
|
||||
const response = await userHelper.fetch('/project' + SPLIT_TEST_QUERY)
|
||||
expect(response.status).to.equal(200)
|
||||
})
|
||||
|
||||
it('should be redirected from the primary email check page to the project list', async function () {
|
||||
const response = await userHelper.request.get(
|
||||
'/user/emails/primary-email-check' + SPLIT_TEST_QUERY,
|
||||
{ simple: false }
|
||||
const response = await userHelper.fetch(
|
||||
'/user/emails/primary-email-check' + SPLIT_TEST_QUERY
|
||||
)
|
||||
expect(response.status).to.equal(302)
|
||||
expect(response.headers.get('location')).to.equal(
|
||||
UserHelper.url('/project').toString()
|
||||
)
|
||||
expect(response.statusCode).to.equal(302)
|
||||
expect(response.headers.location).to.equal('/project')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -68,19 +67,18 @@ describe('PrimaryEmailCheck', function () {
|
|||
})
|
||||
|
||||
it("shouldn't be redirected from project list to the primary email check page", async function () {
|
||||
const response = await userHelper.request.get(
|
||||
'/project' + SPLIT_TEST_QUERY
|
||||
)
|
||||
expect(response.statusCode).to.equal(200)
|
||||
const response = await userHelper.fetch('/project' + SPLIT_TEST_QUERY)
|
||||
expect(response.status).to.equal(200)
|
||||
})
|
||||
|
||||
it('should be redirected from the primary email check page to the project list', async function () {
|
||||
const response = await userHelper.request.get(
|
||||
'/user/emails/primary-email-check' + SPLIT_TEST_QUERY,
|
||||
{ simple: false }
|
||||
const response = await userHelper.fetch(
|
||||
'/user/emails/primary-email-check' + SPLIT_TEST_QUERY
|
||||
)
|
||||
expect(response.status).to.equal(302)
|
||||
expect(response.headers.get('location')).to.equal(
|
||||
UserHelper.url('/project').toString()
|
||||
)
|
||||
expect(response.statusCode).to.equal(302)
|
||||
expect(response.headers.location).to.equal('/project')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -100,19 +98,18 @@ describe('PrimaryEmailCheck', function () {
|
|||
})
|
||||
|
||||
it("shouldn't be redirected from project list to the primary email check page", async function () {
|
||||
const response = await userHelper.request.get(
|
||||
'/project' + SPLIT_TEST_QUERY
|
||||
)
|
||||
expect(response.statusCode).to.equal(200)
|
||||
const response = await userHelper.fetch('/project' + SPLIT_TEST_QUERY)
|
||||
expect(response.status).to.equal(200)
|
||||
})
|
||||
|
||||
it('should be redirected from the primary email check page to the project list', async function () {
|
||||
const response = await userHelper.request.get(
|
||||
'/user/emails/primary-email-check' + SPLIT_TEST_QUERY,
|
||||
{ simple: false }
|
||||
const response = await userHelper.fetch(
|
||||
'/user/emails/primary-email-check' + SPLIT_TEST_QUERY
|
||||
)
|
||||
expect(response.status).to.equal(302)
|
||||
expect(response.headers.get('location')).to.equal(
|
||||
UserHelper.url('/project').toString()
|
||||
)
|
||||
expect(response.statusCode).to.equal(302)
|
||||
expect(response.headers.location).to.equal('/project')
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -125,21 +122,18 @@ describe('PrimaryEmailCheck', function () {
|
|||
})
|
||||
|
||||
it('should be redirected from project list to the primary email check page', async function () {
|
||||
const response = await userHelper.request.get(
|
||||
'/project' + SPLIT_TEST_QUERY,
|
||||
{ simple: false }
|
||||
)
|
||||
expect(response.statusCode).to.equal(302)
|
||||
expect(response.headers.location).to.equal(
|
||||
'/user/emails/primary-email-check'
|
||||
const response = await userHelper.fetch('/project' + SPLIT_TEST_QUERY)
|
||||
expect(response.status).to.equal(302)
|
||||
expect(response.headers.get('location')).to.equal(
|
||||
UserHelper.url('/user/emails/primary-email-check').toString()
|
||||
)
|
||||
})
|
||||
|
||||
it('can visit the primary email check page', async function () {
|
||||
const response = await userHelper.request.get(
|
||||
const response = await userHelper.fetch(
|
||||
'/user/emails/primary-email-check'
|
||||
)
|
||||
expect(response.statusCode).to.equal(200)
|
||||
expect(response.status).to.equal(200)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -154,34 +148,32 @@ describe('PrimaryEmailCheck', function () {
|
|||
$set: { lastPrimaryEmailCheck: new Date(time) },
|
||||
})
|
||||
|
||||
checkResponse = await userHelper.request.post(
|
||||
checkResponse = await userHelper.fetch(
|
||||
'/user/emails/primary-email-check' + SPLIT_TEST_QUERY,
|
||||
{
|
||||
form: {},
|
||||
simple: false,
|
||||
}
|
||||
{ method: 'POST' }
|
||||
)
|
||||
})
|
||||
|
||||
it('should be redirected to the project list page', function () {
|
||||
expect(checkResponse.statusCode).to.equal(302)
|
||||
expect(checkResponse.headers.location).to.equal('/project')
|
||||
expect(checkResponse.status).to.equal(302)
|
||||
expect(checkResponse.headers.get('location')).to.equal(
|
||||
UserHelper.url('/project').toString()
|
||||
)
|
||||
})
|
||||
|
||||
it("shouldn't be redirected from project list to the primary email check page any longer", async function () {
|
||||
const response = await userHelper.request.get(
|
||||
'/project' + SPLIT_TEST_QUERY
|
||||
)
|
||||
expect(response.statusCode).to.equal(200)
|
||||
const response = await userHelper.fetch('/project' + SPLIT_TEST_QUERY)
|
||||
expect(response.status).to.equal(200)
|
||||
})
|
||||
|
||||
it('visiting the primary email check page should redirect to the project list page', async function () {
|
||||
const response = await userHelper.request.get(
|
||||
'/user/emails/primary-email-check',
|
||||
{ simple: false }
|
||||
const response = await userHelper.fetch(
|
||||
'/user/emails/primary-email-check'
|
||||
)
|
||||
expect(response.status).to.equal(302)
|
||||
expect(response.headers.get('location')).to.equal(
|
||||
UserHelper.url('/project').toString()
|
||||
)
|
||||
expect(response.statusCode).to.equal(302)
|
||||
expect(response.headers.location).to.equal('/project')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -668,15 +668,14 @@ describe('ProjectDuplicateNames', function () {
|
|||
})
|
||||
it('should handle characters that would cause an invalid regular expression', async function () {
|
||||
const projectName = 'Example (test'
|
||||
response = await userHelper.request.post('/project/new', {
|
||||
simple: false,
|
||||
form: { projectName },
|
||||
response = await userHelper.fetch('/project/new', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams([['projectName', projectName]]),
|
||||
})
|
||||
expect(response.statusCode).to.equal(200) // can create project
|
||||
response = await userHelper.request.get(
|
||||
`/project/${JSON.parse(response.body).project_id}`
|
||||
)
|
||||
expect(response.statusCode).to.equal(200) // can open project
|
||||
const body = await response.json()
|
||||
expect(response.status).to.equal(200) // can create project
|
||||
response = await userHelper.fetch(`/project/${body.project_id}`)
|
||||
expect(response.status).to.equal(200) // can open project
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const { expect } = require('chai')
|
||||
const { CookieJar } = require('tough-cookie')
|
||||
const AuthenticationManager = require('../../../../app/src/Features/Authentication/AuthenticationManager')
|
||||
const Settings = require('@overleaf/settings')
|
||||
const InstitutionsAPI = require('../../../../app/src/Features/Institutions/InstitutionsAPI')
|
||||
|
@ -6,7 +7,7 @@ const UserCreator = require('../../../../app/src/Features/User/UserCreator')
|
|||
const UserGetter = require('../../../../app/src/Features/User/UserGetter')
|
||||
const UserUpdater = require('../../../../app/src/Features/User/UserUpdater')
|
||||
const moment = require('moment')
|
||||
const request = require('request-promise-native')
|
||||
const fetch = require('node-fetch')
|
||||
const { db } = require('../../../../app/src/infrastructure/mongodb')
|
||||
const { ObjectId } = require('mongodb')
|
||||
const {
|
||||
|
@ -82,43 +83,33 @@ class UserHelper {
|
|||
// used to store mongo user object once created/loaded
|
||||
this.user = null
|
||||
// cookie jar
|
||||
this.jar = request.jar()
|
||||
// create new request instance
|
||||
this.request = request.defaults({})
|
||||
// initialize request instance with default options
|
||||
this.setRequestDefaults({
|
||||
baseUrl: UserHelper.baseUrl(),
|
||||
followRedirect: false,
|
||||
jar: this.jar,
|
||||
resolveWithFullResponse: true,
|
||||
this.jar = new CookieJar()
|
||||
}
|
||||
|
||||
async fetch(url, opts = {}) {
|
||||
url = UserHelper.url(url)
|
||||
const headers = {}
|
||||
const cookieString = this.jar.getCookieStringSync(url)
|
||||
if (cookieString) {
|
||||
headers.Cookie = cookieString
|
||||
}
|
||||
if (this._csrfToken) {
|
||||
headers['x-csrf-token'] = this._csrfToken
|
||||
}
|
||||
const response = await fetch(url, {
|
||||
redirect: 'manual',
|
||||
...opts,
|
||||
headers: { ...headers, ...opts.headers },
|
||||
})
|
||||
}
|
||||
|
||||
/* Set defaults for request object. Applied over existing defaults.
|
||||
* @param {object} [defaults]
|
||||
*/
|
||||
setRequestDefaults(defaults = {}) {
|
||||
// request-promise instance for making requests
|
||||
this.request = this.request.defaults(defaults)
|
||||
// From https://www.npmjs.com/package/node-fetch#extract-set-cookie-header
|
||||
const cookies = response.headers.raw()['set-cookie']
|
||||
if (cookies != null) {
|
||||
for (const cookie of cookies) {
|
||||
this.jar.setCookieSync(cookie, url)
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a request for the user and run expectations on the response.
|
||||
* @param {object} [requestOptions] options to pass to request
|
||||
* @param {object} [responseExpectations] expectations:
|
||||
* - {Int} statusCode the expected status code
|
||||
* - {RegEx} message a matcher for the message
|
||||
*/
|
||||
async expectErrorOnRequest(requestOptions, responseExpectations) {
|
||||
let error
|
||||
try {
|
||||
await this.request(requestOptions)
|
||||
} catch (e) {
|
||||
error = e
|
||||
}
|
||||
expect(error).to.exist
|
||||
expect(error.statusCode).to.equal(responseExpectations.statusCode)
|
||||
expect(error.message).to.match(responseExpectations.message)
|
||||
return response
|
||||
}
|
||||
|
||||
/* async http api call methods */
|
||||
|
@ -128,12 +119,8 @@ class UserHelper {
|
|||
*/
|
||||
async getCsrfToken() {
|
||||
// get csrf token from api and store
|
||||
const response = await this.request.get('/dev/csrf')
|
||||
this._csrfToken = response.body
|
||||
// use csrf token for requests
|
||||
this.setRequestDefaults({
|
||||
headers: { 'x-csrf-token': this._csrfToken },
|
||||
})
|
||||
const response = await this.fetch('/dev/csrf')
|
||||
this._csrfToken = await response.text()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -142,13 +129,11 @@ class UserHelper {
|
|||
* @returns {object} http response
|
||||
*/
|
||||
async logout(options = {}) {
|
||||
// do not throw exception on 302
|
||||
options.simple = false
|
||||
// post logout
|
||||
const response = await this.request.post('/logout', options)
|
||||
const response = await this.fetch('/logout', { method: 'POST', ...options })
|
||||
if (
|
||||
response.statusCode !== 302 ||
|
||||
!response.headers.location.includes('/login')
|
||||
response.status !== 302 ||
|
||||
!response.headers.get('location').includes('/login')
|
||||
) {
|
||||
throw new Error('logout failed')
|
||||
}
|
||||
|
@ -168,6 +153,13 @@ class UserHelper {
|
|||
return `http://${process.env.HTTP_TEST_HOST || 'localhost'}:23000`
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a full URL given a path
|
||||
*/
|
||||
static url(path) {
|
||||
return new URL(path, UserHelper.baseUrl())
|
||||
}
|
||||
|
||||
/* static async instantiation methods */
|
||||
|
||||
/**
|
||||
|
@ -247,17 +239,30 @@ class UserHelper {
|
|||
const userHelper = new UserHelper()
|
||||
const loginPath = Settings.enableLegacyLogin ? '/login/legacy' : '/login'
|
||||
await userHelper.getCsrfToken()
|
||||
const response = await userHelper.request.post(loginPath, {
|
||||
json: {
|
||||
const response = await userHelper.fetch(loginPath, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
'g-recaptcha-response': 'valid',
|
||||
...userData,
|
||||
},
|
||||
}),
|
||||
})
|
||||
if (response.statusCode !== 200 || response.body.redir !== '/project') {
|
||||
if (!response.ok) {
|
||||
const error = new Error('login failed')
|
||||
error.response = response
|
||||
throw error
|
||||
}
|
||||
|
||||
const body = await response.json()
|
||||
if (body.redir !== '/project') {
|
||||
const error = new Error('login failed')
|
||||
error.response = response
|
||||
throw error
|
||||
}
|
||||
|
||||
userHelper.user = await UserGetter.promises.getUser({
|
||||
email: userData.email,
|
||||
})
|
||||
|
@ -274,10 +279,10 @@ class UserHelper {
|
|||
* @returns {Boolean}
|
||||
*/
|
||||
async isLoggedIn() {
|
||||
const response = await this.request.get('/user/sessions', {
|
||||
followRedirect: true,
|
||||
const response = await this.fetch('/user/sessions', {
|
||||
redirect: 'follow',
|
||||
})
|
||||
return response.request.path === '/user/sessions'
|
||||
return !response.redirected
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -292,8 +297,16 @@ class UserHelper {
|
|||
const userHelper = new UserHelper()
|
||||
await userHelper.getCsrfToken()
|
||||
userData = userHelper.getDefaultEmailPassword(userData)
|
||||
options.json = userData
|
||||
const { body } = await userHelper.request.post('/register', options)
|
||||
const response = await userHelper.fetch('/register', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
},
|
||||
body: JSON.stringify(userData),
|
||||
...options,
|
||||
})
|
||||
const body = await response.json()
|
||||
if (body.message && body.message.type === 'error') {
|
||||
throw new Error(`register api error: ${body.message.text}`)
|
||||
}
|
||||
|
@ -321,14 +334,11 @@ class UserHelper {
|
|||
}
|
||||
|
||||
async addEmail(email) {
|
||||
const response = await this.request.post({
|
||||
form: {
|
||||
email,
|
||||
},
|
||||
simple: false,
|
||||
uri: '/user/emails',
|
||||
const response = await this.fetch('/user/emails', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams([['email', email]]),
|
||||
})
|
||||
expect(response.statusCode).to.equal(204)
|
||||
expect(response.status).to.equal(204)
|
||||
}
|
||||
|
||||
async addEmailAndConfirm(userId, email) {
|
||||
|
@ -393,16 +403,12 @@ class UserHelper {
|
|||
}
|
||||
|
||||
async confirmEmail(userId, email) {
|
||||
let response
|
||||
// UserHelper.createUser does not create a confirmation token
|
||||
response = await this.request.post({
|
||||
form: {
|
||||
email,
|
||||
},
|
||||
simple: false,
|
||||
uri: '/user/emails/resend_confirmation',
|
||||
let response = await this.fetch('/user/emails/resend_confirmation', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams([['email', email]]),
|
||||
})
|
||||
expect(response.statusCode).to.equal(200)
|
||||
expect(response.status).to.equal(200)
|
||||
const tokenData = await db.tokens
|
||||
.find({
|
||||
use: 'email_confirmation',
|
||||
|
@ -411,14 +417,11 @@ class UserHelper {
|
|||
usedAt: { $exists: false },
|
||||
})
|
||||
.next()
|
||||
response = await this.request.post({
|
||||
form: {
|
||||
token: tokenData.token,
|
||||
},
|
||||
simple: false,
|
||||
uri: '/user/emails/confirm',
|
||||
response = await this.fetch('/user/emails/confirm', {
|
||||
method: 'POST',
|
||||
body: new URLSearchParams([['token', tokenData.token]]),
|
||||
})
|
||||
expect(response.statusCode).to.equal(200)
|
||||
expect(response.status).to.equal(200)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue