aboutsummaryrefslogtreecommitdiffhomepage
path: root/packages/tests/src/api/users/two-factor.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/tests/src/api/users/two-factor.ts')
-rw-r--r--packages/tests/src/api/users/two-factor.ts206
1 files changed, 206 insertions, 0 deletions
diff --git a/packages/tests/src/api/users/two-factor.ts b/packages/tests/src/api/users/two-factor.ts
new file mode 100644
index 000000000..fda125d20
--- /dev/null
+++ b/packages/tests/src/api/users/two-factor.ts
@@ -0,0 +1,206 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { HttpStatusCode, HttpStatusCodeType } from '@peertube/peertube-models'
5import { expectStartWith } from '@tests/shared/checks.js'
6import {
7 cleanupTests,
8 createSingleServer,
9 PeerTubeServer,
10 setAccessTokensToServers,
11 TwoFactorCommand
12} from '@peertube/peertube-server-commands'
13
14async function login (options: {
15 server: PeerTubeServer
16 username: string
17 password: string
18 otpToken?: string
19 expectedStatus?: HttpStatusCodeType
20}) {
21 const { server, username, password, otpToken, expectedStatus } = options
22
23 const user = { username, password }
24 const { res, body: { access_token: token } } = await server.login.loginAndGetResponse({ user, otpToken, expectedStatus })
25
26 return { res, token }
27}
28
29describe('Test users', function () {
30 let server: PeerTubeServer
31 let otpSecret: string
32 let requestToken: string
33
34 const userUsername = 'user1'
35 let userId: number
36 let userPassword: string
37 let userToken: string
38
39 before(async function () {
40 this.timeout(30000)
41
42 server = await createSingleServer(1)
43
44 await setAccessTokensToServers([ server ])
45 const res = await server.users.generate(userUsername)
46 userId = res.userId
47 userPassword = res.password
48 userToken = res.token
49 })
50
51 it('Should not add the header on login if two factor is not enabled', async function () {
52 const { res, token } = await login({ server, username: userUsername, password: userPassword })
53
54 expect(res.header['x-peertube-otp']).to.not.exist
55
56 await server.users.getMyInfo({ token })
57 })
58
59 it('Should request two factor and get the secret and uri', async function () {
60 const { otpRequest } = await server.twoFactor.request({ userId, token: userToken, currentPassword: userPassword })
61
62 expect(otpRequest.requestToken).to.exist
63
64 expect(otpRequest.secret).to.exist
65 expect(otpRequest.secret).to.have.lengthOf(32)
66
67 expect(otpRequest.uri).to.exist
68 expectStartWith(otpRequest.uri, 'otpauth://')
69 expect(otpRequest.uri).to.include(otpRequest.secret)
70
71 requestToken = otpRequest.requestToken
72 otpSecret = otpRequest.secret
73 })
74
75 it('Should not have two factor confirmed yet', async function () {
76 const { twoFactorEnabled } = await server.users.getMyInfo({ token: userToken })
77 expect(twoFactorEnabled).to.be.false
78 })
79
80 it('Should confirm two factor', async function () {
81 await server.twoFactor.confirmRequest({
82 userId,
83 token: userToken,
84 otpToken: TwoFactorCommand.buildOTP({ secret: otpSecret }).generate(),
85 requestToken
86 })
87 })
88
89 it('Should not add the header on login if two factor is enabled and password is incorrect', async function () {
90 const { res, token } = await login({ server, username: userUsername, password: 'fake', expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
91
92 expect(res.header['x-peertube-otp']).to.not.exist
93 expect(token).to.not.exist
94 })
95
96 it('Should add the header on login if two factor is enabled and password is correct', async function () {
97 const { res, token } = await login({
98 server,
99 username: userUsername,
100 password: userPassword,
101 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
102 })
103
104 expect(res.header['x-peertube-otp']).to.exist
105 expect(token).to.not.exist
106
107 await server.users.getMyInfo({ token })
108 })
109
110 it('Should not login with correct password and incorrect otp secret', async function () {
111 const otp = TwoFactorCommand.buildOTP({ secret: 'a'.repeat(32) })
112
113 const { res, token } = await login({
114 server,
115 username: userUsername,
116 password: userPassword,
117 otpToken: otp.generate(),
118 expectedStatus: HttpStatusCode.BAD_REQUEST_400
119 })
120
121 expect(res.header['x-peertube-otp']).to.not.exist
122 expect(token).to.not.exist
123 })
124
125 it('Should not login with correct password and incorrect otp code', async function () {
126 const { res, token } = await login({
127 server,
128 username: userUsername,
129 password: userPassword,
130 otpToken: '123456',
131 expectedStatus: HttpStatusCode.BAD_REQUEST_400
132 })
133
134 expect(res.header['x-peertube-otp']).to.not.exist
135 expect(token).to.not.exist
136 })
137
138 it('Should not login with incorrect password and correct otp code', async function () {
139 const otpToken = TwoFactorCommand.buildOTP({ secret: otpSecret }).generate()
140
141 const { res, token } = await login({
142 server,
143 username: userUsername,
144 password: 'fake',
145 otpToken,
146 expectedStatus: HttpStatusCode.BAD_REQUEST_400
147 })
148
149 expect(res.header['x-peertube-otp']).to.not.exist
150 expect(token).to.not.exist
151 })
152
153 it('Should correctly login with correct password and otp code', async function () {
154 const otpToken = TwoFactorCommand.buildOTP({ secret: otpSecret }).generate()
155
156 const { res, token } = await login({ server, username: userUsername, password: userPassword, otpToken })
157
158 expect(res.header['x-peertube-otp']).to.not.exist
159 expect(token).to.exist
160
161 await server.users.getMyInfo({ token })
162 })
163
164 it('Should have two factor enabled when getting my info', async function () {
165 const { twoFactorEnabled } = await server.users.getMyInfo({ token: userToken })
166 expect(twoFactorEnabled).to.be.true
167 })
168
169 it('Should disable two factor and be able to login without otp token', async function () {
170 await server.twoFactor.disable({ userId, token: userToken, currentPassword: userPassword })
171
172 const { res, token } = await login({ server, username: userUsername, password: userPassword })
173 expect(res.header['x-peertube-otp']).to.not.exist
174
175 await server.users.getMyInfo({ token })
176 })
177
178 it('Should have two factor disabled when getting my info', async function () {
179 const { twoFactorEnabled } = await server.users.getMyInfo({ token: userToken })
180 expect(twoFactorEnabled).to.be.false
181 })
182
183 it('Should enable two factor auth without password from an admin', async function () {
184 const { otpRequest } = await server.twoFactor.request({ userId })
185
186 await server.twoFactor.confirmRequest({
187 userId,
188 otpToken: TwoFactorCommand.buildOTP({ secret: otpRequest.secret }).generate(),
189 requestToken: otpRequest.requestToken
190 })
191
192 const { twoFactorEnabled } = await server.users.getMyInfo({ token: userToken })
193 expect(twoFactorEnabled).to.be.true
194 })
195
196 it('Should disable two factor auth without password from an admin', async function () {
197 await server.twoFactor.disable({ userId })
198
199 const { twoFactorEnabled } = await server.users.getMyInfo({ token: userToken })
200 expect(twoFactorEnabled).to.be.false
201 })
202
203 after(async function () {
204 await cleanupTests([ server ])
205 })
206})