@@ -21,6 +21,7 @@ import sinonChai from 'sinon-chai';
21
21
import {
22
22
Auth ,
23
23
multiFactor ,
24
+ MultiFactorUser ,
24
25
signInWithEmailAndPassword ,
25
26
getMultiFactorResolver
26
27
} from '@firebase/auth' ;
@@ -30,6 +31,7 @@ import {
30
31
getTestInstance ,
31
32
getTotpCode ,
32
33
email ,
34
+ fakePassword ,
33
35
incorrectTotpCode
34
36
} from '../../helpers/integration/helpers' ;
35
37
@@ -42,22 +44,30 @@ import { getEmulatorUrl } from '../../helpers/integration/settings';
42
44
use ( chaiAsPromised ) ;
43
45
use ( sinonChai ) ;
44
46
45
- describe ( ' Integration tests: Mfa TOTP' , ( ) => {
46
- let auth : Auth ;
47
- let totpSecret : TotpSecret ;
48
- let displayName : string ;
49
- let totpTimestamp : Date ;
50
- let emulatorUrl : string | null ;
47
+ let auth : Auth ;
48
+ let totpSecret : TotpSecret ;
49
+ let displayName : string ;
50
+ let totpTimestamp : Date ;
51
+ let emulatorUrl : string | null ;
52
+ let mfaUser : MultiFactorUser | null ;
53
+
54
+ describe ( ' Integration tests: Mfa enrollement using totp' , ( ) => {
51
55
beforeEach ( async ( ) => {
52
56
emulatorUrl = getEmulatorUrl ( ) ;
53
57
if ( ! emulatorUrl ) {
58
+ mfaUser = null ;
54
59
auth = getTestInstance ( ) ;
55
60
displayName = 'totp-integration-test' ;
56
61
}
57
62
} ) ;
58
63
59
64
afterEach ( async ( ) => {
60
65
if ( ! emulatorUrl ) {
66
+ if ( mfaUser && mfaUser . enrolledFactors . length > 0 ) {
67
+ for ( let i = 0 ; i < mfaUser . enrolledFactors . length ; i ++ ) {
68
+ await mfaUser . unenroll ( mfaUser . enrolledFactors [ i ] ) ;
69
+ }
70
+ }
61
71
await cleanUpTestInstance ( auth ) ;
62
72
}
63
73
} ) ;
@@ -66,10 +76,12 @@ describe(' Integration tests: Mfa TOTP', () => {
66
76
if ( emulatorUrl ) {
67
77
this . skip ( ) ;
68
78
}
69
- const cr = await signInWithEmailAndPassword ( auth , email , 'password' ) ;
70
- const mfaUser = multiFactor ( cr . user ) ;
79
+
80
+ const cr = await signInWithEmailAndPassword ( auth , email , fakePassword ) ;
81
+ mfaUser = multiFactor ( cr . user ) ;
71
82
const session = await mfaUser . getSession ( ) ;
72
83
totpSecret = await TotpMultiFactorGenerator . generateSecret ( session ) ;
84
+
73
85
const multiFactorAssertion =
74
86
TotpMultiFactorGenerator . assertionForEnrollment (
75
87
totpSecret ,
@@ -85,16 +97,12 @@ describe(' Integration tests: Mfa TOTP', () => {
85
97
if ( emulatorUrl ) {
86
98
this . skip ( ) ;
87
99
}
88
- const cr = await signInWithEmailAndPassword ( auth , email , 'password' ) ;
89
-
90
- const mfaUser = multiFactor ( cr . user ) ;
91
100
101
+ const cr = await signInWithEmailAndPassword ( auth , email , fakePassword ) ;
102
+ mfaUser = multiFactor ( cr . user ) ;
92
103
const session = await mfaUser . getSession ( ) ;
93
-
94
104
totpSecret = await TotpMultiFactorGenerator . generateSecret ( session ) ;
95
-
96
105
totpTimestamp = new Date ( ) ;
97
-
98
106
const totpVerificationCode = getTotpCode (
99
107
totpSecret . secretKey ,
100
108
totpSecret . codeIntervalSeconds ,
@@ -107,18 +115,61 @@ describe(' Integration tests: Mfa TOTP', () => {
107
115
totpSecret ,
108
116
totpVerificationCode
109
117
) ;
118
+
110
119
await expect ( mfaUser . enroll ( multiFactorAssertion , displayName ) ) . to . be
111
120
. fulfilled ;
112
121
} ) ;
122
+ } ) ;
123
+
124
+ describe ( 'Integration tests: sign-in for mfa-enrolled users' , ( ) => {
125
+ beforeEach ( async ( ) => {
126
+ emulatorUrl = getEmulatorUrl ( ) ;
127
+ mfaUser = null ;
128
+
129
+ if ( ! emulatorUrl ) {
130
+ auth = getTestInstance ( ) ;
131
+ displayName = 'totp-integration-test' ;
132
+
133
+ const cr = await signInWithEmailAndPassword ( auth , email , fakePassword ) ;
134
+ mfaUser = multiFactor ( cr . user ) ;
135
+ const session = await mfaUser . getSession ( ) ;
136
+ totpSecret = await TotpMultiFactorGenerator . generateSecret ( session ) ;
137
+ totpTimestamp = new Date ( ) ;
138
+ const totpVerificationCode = getTotpCode (
139
+ totpSecret . secretKey ,
140
+ totpSecret . codeIntervalSeconds ,
141
+ totpSecret . codeLength ,
142
+ totpTimestamp
143
+ ) ;
144
+
145
+ const multiFactorAssertion =
146
+ TotpMultiFactorGenerator . assertionForEnrollment (
147
+ totpSecret ,
148
+ totpVerificationCode
149
+ ) ;
150
+
151
+ await mfaUser . enroll ( multiFactorAssertion , displayName ) ;
152
+ }
153
+ } ) ;
154
+
155
+ afterEach ( async ( ) => {
156
+ if ( ! emulatorUrl ) {
157
+ if ( mfaUser && mfaUser . enrolledFactors . length > 0 ) {
158
+ for ( let i = 0 ; i < mfaUser . enrolledFactors . length ; i ++ ) {
159
+ await mfaUser . unenroll ( mfaUser . enrolledFactors [ i ] ) ;
160
+ }
161
+ }
162
+ await cleanUpTestInstance ( auth ) ;
163
+ }
164
+ } ) ;
113
165
114
166
it ( 'should not allow sign-in with incorrect totp' , async function ( ) {
115
167
let resolver : any ;
116
-
117
168
if ( emulatorUrl ) {
118
169
this . skip ( ) ;
119
170
}
120
171
try {
121
- await signInWithEmailAndPassword ( auth , email , 'password' ) ;
172
+ await signInWithEmailAndPassword ( auth , email , fakePassword ) ;
122
173
123
174
throw new Error ( 'Signin should not have been successful' ) ;
124
175
} catch ( error ) {
@@ -145,7 +196,7 @@ describe(' Integration tests: Mfa TOTP', () => {
145
196
this . skip ( ) ;
146
197
}
147
198
try {
148
- await signInWithEmailAndPassword ( auth , email , 'password' ) ;
199
+ await signInWithEmailAndPassword ( auth , email , fakePassword ) ;
149
200
150
201
throw new Error ( 'Signin should not have been successful' ) ;
151
202
} catch ( error ) {
@@ -169,11 +220,10 @@ describe(' Integration tests: Mfa TOTP', () => {
169
220
totpVerificationCode
170
221
) ;
171
222
const userCredential = await resolver . resolveSignIn ( assertion ) ;
172
-
173
- const mfaUser = multiFactor ( userCredential . user ) ;
223
+ mfaUser = multiFactor ( userCredential . user ) ;
174
224
175
225
await expect ( mfaUser . unenroll ( resolver . hints [ 0 ] . uid ) ) . to . be . fulfilled ;
176
- await expect ( signInWithEmailAndPassword ( auth , email , 'password' ) ) . to . be
226
+ await expect ( signInWithEmailAndPassword ( auth , email , fakePassword ) ) . to . be
177
227
. fulfilled ;
178
228
}
179
229
} ) ;
0 commit comments