1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
3 import { expect } from 'chai'
4 import { expectStartWith } from '@server/tests/shared'
5 import { HttpStatusCode } from '@shared/models'
6 import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServers, TwoFactorCommand } from '@shared/server-commands'
8 async function login (options: {
12 expectedStatus?: HttpStatusCode
14 const { server, password = server.store.user.password, otpToken, expectedStatus } = options
16 const user = { username: server.store.user.username, password }
17 const { res, body: { access_token: token } } = await server.login.loginAndGetResponse({ user, otpToken, expectedStatus })
22 describe('Test users', function () {
23 let server: PeerTubeServer
26 let requestToken: string
28 before(async function () {
31 server = await createSingleServer(1)
33 await setAccessTokensToServers([ server ])
35 const { id } = await server.users.getMyInfo()
39 it('Should not add the header on login if two factor is not enabled', async function () {
40 const { res, token } = await login({ server })
42 expect(res.header['x-peertube-otp']).to.not.exist
44 await server.users.getMyInfo({ token })
47 it('Should request two factor and get the secret and uri', async function () {
48 const { otpRequest } = await server.twoFactor.request({
50 currentPassword: server.store.user.password
53 expect(otpRequest.requestToken).to.exist
55 expect(otpRequest.secret).to.exist
56 expect(otpRequest.secret).to.have.lengthOf(32)
58 expect(otpRequest.uri).to.exist
59 expectStartWith(otpRequest.uri, 'otpauth://')
60 expect(otpRequest.uri).to.include(otpRequest.secret)
62 requestToken = otpRequest.requestToken
63 otpSecret = otpRequest.secret
66 it('Should not have two factor confirmed yet', async function () {
67 const { twoFactorEnabled } = await server.users.getMyInfo()
68 expect(twoFactorEnabled).to.be.false
71 it('Should confirm two factor', async function () {
72 await server.twoFactor.confirmRequest({
74 otpToken: TwoFactorCommand.buildOTP({ secret: otpSecret }).generate(),
79 it('Should not add the header on login if two factor is enabled and password is incorrect', async function () {
80 const { res, token } = await login({ server, password: 'fake', expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
82 expect(res.header['x-peertube-otp']).to.not.exist
83 expect(token).to.not.exist
86 it('Should add the header on login if two factor is enabled and password is correct', async function () {
87 const { res, token } = await login({ server, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
89 expect(res.header['x-peertube-otp']).to.exist
90 expect(token).to.not.exist
92 await server.users.getMyInfo({ token })
95 it('Should not login with correct password and incorrect otp secret', async function () {
96 const otp = TwoFactorCommand.buildOTP({ secret: 'a'.repeat(32) })
98 const { res, token } = await login({ server, otpToken: otp.generate(), expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
100 expect(res.header['x-peertube-otp']).to.not.exist
101 expect(token).to.not.exist
104 it('Should not login with correct password and incorrect otp code', async function () {
105 const { res, token } = await login({ server, otpToken: '123456', expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
107 expect(res.header['x-peertube-otp']).to.not.exist
108 expect(token).to.not.exist
111 it('Should not login with incorrect password and correct otp code', async function () {
112 const otpToken = TwoFactorCommand.buildOTP({ secret: otpSecret }).generate()
114 const { res, token } = await login({ server, password: 'fake', otpToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
116 expect(res.header['x-peertube-otp']).to.not.exist
117 expect(token).to.not.exist
120 it('Should correctly login with correct password and otp code', async function () {
121 const otpToken = TwoFactorCommand.buildOTP({ secret: otpSecret }).generate()
123 const { res, token } = await login({ server, otpToken })
125 expect(res.header['x-peertube-otp']).to.not.exist
126 expect(token).to.exist
128 await server.users.getMyInfo({ token })
131 it('Should have two factor enabled when getting my info', async function () {
132 const { twoFactorEnabled } = await server.users.getMyInfo()
133 expect(twoFactorEnabled).to.be.true
136 it('Should disable two factor and be able to login without otp token', async function () {
137 await server.twoFactor.disable({ userId: rootId, currentPassword: server.store.user.password })
139 const { res, token } = await login({ server })
140 expect(res.header['x-peertube-otp']).to.not.exist
142 await server.users.getMyInfo({ token })
145 it('Should have two factor disabled when getting my info', async function () {
146 const { twoFactorEnabled } = await server.users.getMyInfo()
147 expect(twoFactorEnabled).to.be.false
150 after(async function () {
151 await cleanupTests([ server ])