21
21
import sinonChai from 'sinon-chai' ;
22
22
23
23
//import { mockTotp } from '../../helpers/integration/helpers';
24
- import { Auth , createUserWithEmailAndPassword , multiFactor , signInAnonymously , signInWithEmailAndPassword , UserCredential } from '@firebase/auth' ;
25
-
24
+ import { Auth , createUserWithEmailAndPassword , multiFactor , signInWithEmailAndPassword , UserCredential , sendEmailVerification , applyActionCode , getMultiFactorResolver } from '@firebase/auth' ;
25
+ import { FirebaseError , getApp } from '@firebase/app' ;
26
26
import {
27
27
cleanUpTestInstance ,
28
+ code ,
28
29
getTestInstance ,
29
- mockTotp ,
30
+ getTotpCode ,
31
+ delay ,
30
32
randomEmail
31
33
} from '../../helpers/integration/helpers' ;
32
34
import { MultiFactorAssertionImpl } from '../../../src/mfa/mfa_assertion' ;
33
35
34
36
import { MultiFactorSessionImpl } from '../../../src/mfa/mfa_session' ;
35
- import { TotpMultiFactorAssertionImpl , TotpMultiFactorGenerator , TotpSecret } from '../../../src/mfa/assertions/totp' ;
37
+ import { TotpMultiFactorGenerator , TotpSecret } from '../../../src/mfa/assertions/totp' ;
36
38
import * as MFA from '../../../src/api/account_management/mfa' ;
37
- import { FirebaseError } from '@firebase/util' ;
39
+ import { async } from '@firebase/util' ;
40
+ import { UserCredentialImpl } from '../../../src/core/user/user_credential_impl' ;
41
+ import { resolve } from 'dns' ;
42
+ import { UserCredentialInternal } from '../../../internal' ;
38
43
39
44
40
45
41
46
use ( chaiAsPromised ) ;
42
47
use ( sinonChai ) ;
43
48
44
- const TOTP_COMB_A = {
45
-
46
- response : { sharedSecretKey : 'secretKey3' ,
47
- verificationCodeLength : 30 ,
48
- hashingAlgorithm : 'sha1' ,
49
- periodSec :30 ,
50
- sessionInfo : 'testsSessionInfo' ,
51
- finalizeEnrollmentTime : Date . now ( )
52
- } ,
53
- code : '...'
54
- } ;
55
-
56
- const TOTP_COMB_B = {
57
-
58
- response : { sharedSecretKey : 'secretKey2' ,
59
- verificationCodeLength : 30 ,
60
- hashingAlgorithm : 'sha1' ,
61
- periodSec : 30 ,
62
- sessionInfo : 'testsSessionInfo' ,
63
- finalizeEnrollmentTime : Date . now ( )
64
- } ,
65
- code : '...'
66
- } ;
67
-
68
49
describe ( ' Integration tests: Mfa TOTP' , ( ) => {
50
+
51
+
69
52
let auth : Auth ;
70
53
let idToken : string ;
71
54
let signUpCred : UserCredential ;
55
+ let totpSecret : TotpSecret ;
72
56
let email : string ;
73
57
let assertion : MultiFactorAssertionImpl ;
74
58
let _request : MFA . StartTotpMfaEnrollmentRequest ;
75
59
let startMfaResponse : MFA . StartTotpMfaEnrollmentResponse ;
76
60
let displayName : string ;
77
61
beforeEach ( async ( ) => {
78
62
auth = getTestInstance ( ) ;
79
- email = randomEmail ( ) ;
80
- idToken = 'testIdToken' ;
81
- signUpCred = await createUserWithEmailAndPassword (
82
- auth ,
83
- email ,
84
- 'password'
85
- ) ;
86
- await auth . signOut ( ) ;
63
+
64
+ displayName = 'totp-integration-test' ;
65
+ // signUpCred = await createUserWithEmailAndPassword(
66
+
67
+ // auth,
68
+ // email,
69
+ // 'password'
70
+ // );
71
+ // await auth.signOut();
87
72
} ) ;
88
73
89
74
afterEach ( async ( ) => {
90
75
await cleanUpTestInstance ( auth ) ;
91
76
92
77
} ) ;
93
- it ( 'should verify using otp' , async ( ) => {
94
78
79
+ it ( 'should not enroll if incorrect totp supplied' , async ( ) => {
80
+ let session ;
81
+ console . log ( email ) ;
82
+ console . log ( 'session info for: ' , getApp ( ) . options . projectId ) ;
83
+ console . log ( 'auth current User:' , auth . currentUser ) ;
84
+ const cr = await signInWithEmailAndPassword ( auth , email , 'password' ) ;
85
+
86
+ console . log ( 'signed In for totp' ) ;
87
+ const mfaUser = multiFactor ( cr . user ) ;
88
+
89
+ console . log ( 'session info for: ' ) ;
90
+ session = await mfaUser . getSession ( ) ;
91
+ console . log ( JSON . stringify ( session ) ) ;
92
+
93
+
94
+ totpSecret = await TotpMultiFactorGenerator . generateSecret (
95
+ session
96
+ ) ;
97
+
98
+ console . log ( "**** totpSecret****" ) ;
99
+ console . log ( totpSecret . secretKey ) ;
100
+ console . log ( totpSecret . codeLength ) ;
101
+ console . log ( totpSecret . codeIntervalSeconds ) ;
102
+ console . log ( totpSecret . hashingAlgorithm ) ;
103
+
104
+ const totpVerificationCode = getTotpCode ( totpSecret . secretKey , totpSecret . codeIntervalSeconds , totpSecret . codeLength , totpSecret . hashingAlgorithm ) ;
105
+
106
+ const multiFactorAssertion = TotpMultiFactorGenerator . assertionForEnrollment (
107
+ totpSecret ,
108
+ totpVerificationCode + '0'
109
+ ) ;
110
+
111
+ console . log ( totpVerificationCode ) ;
112
+ await expect ( mfaUser . enroll ( multiFactorAssertion , displayName ) ) . to . be . rejectedWith ( 'auth/invalid-verification-code' ) ;
113
+ await auth . signOut ( ) ;
114
+ } )
115
+ it ( 'should enroll using correct otp' , async ( ) => {
116
+
117
+ let session ;
95
118
console . log ( email ) ;
119
+ console . log ( 'session info for: ' , getApp ( ) . options . projectId ) ;
120
+ console . log ( 'auth current User:' , auth . currentUser ) ;
96
121
const cr = await signInWithEmailAndPassword ( auth , email , 'password' ) ;
97
122
98
- startMfaResponse = { totpSessionInfo : TOTP_COMB_A . response }
99
123
124
+ // await sendEmailVerification(cr.user);
100
125
101
-
102
- const mfaUser = multiFactor ( cr . user ) ;
103
- sinon . spy ( MultiFactorSessionImpl , '_fromIdtoken' ) ;
104
-
105
- sinon . stub ( mfaUser , 'getSession' ) . returns (
106
- Promise . resolve ( MultiFactorSessionImpl . _fromIdtoken ( idToken , auth as any ) ) ) ;
107
-
108
- sinon . stub ( MFA , 'startEnrollTotpMfa' ) . callsFake ( ( _auth , _request ) => {
126
+ // //Apply the email verification code
127
+ // await applyActionCode(auth, (await code(email)).oobCode);
128
+ // await cr.user.reload();
129
+ // expect(cr.user.emailVerified).to.be.true;
109
130
110
- return Promise . resolve ( startMfaResponse )
111
- } )
131
+ console . log ( 'signed In for totp' ) ;
132
+ const mfaUser = multiFactor ( cr . user ) ;
112
133
113
-
134
+ console . log ( 'session info for: ' ) ;
114
135
115
- const session = await mfaUser . getSession ( ) ;
116
-
117
- console . log ( session ) ;
136
+
137
+ session = await mfaUser . getSession ( ) ;
138
+
139
+
140
+ console . log ( 'session' ) ;
141
+ console . log ( JSON . stringify ( session ) ) ;
142
+
118
143
119
- const totpSecret = await TotpMultiFactorGenerator . generateSecret (
144
+ totpSecret = await TotpMultiFactorGenerator . generateSecret (
120
145
session
121
146
) ;
122
147
123
- console . log ( "**** totpSecret" + totpSecret ) ;
124
- // https://stackoverflow.com/questions/48931815/sinon-stub-not-replacing-function
125
- // https://stackoverflow.com/questions/61051247/chai-spies-expect-to-have-been-called-is-failing-on-local-methods
126
- expect ( MultiFactorSessionImpl . _fromIdtoken ) . to . have . been . calledOnce ;
127
- //expect(TotpSecret._fromStartTotpMfaEnrollmentResponse).to.have.been.calledOnce ;
128
- expect ( MFA . startEnrollTotpMfa ) . to . have . been . calledOnce ;
148
+ console . log ( "**** totpSecret****" ) ;
149
+
150
+ console . log ( totpSecret . secretKey ) ;
151
+ console . log ( totpSecret . codeLength ) ;
152
+ console . log ( totpSecret . codeIntervalSeconds ) ;
153
+ console . log ( totpSecret . hashingAlgorithm ) ;
129
154
130
- expect ( await MFA . startEnrollTotpMfa ( auth as any , _request ) ) . to . eql ( startMfaResponse )
131
-
132
- expect ( totpSecret . secretKey ) . to . eql ( startMfaResponse . totpSessionInfo . sharedSecretKey )
133
- expect ( totpSecret . codeLength ) . to . eql ( startMfaResponse . totpSessionInfo . verificationCodeLength )
134
155
135
- const totpVerificationCode = await mockTotp ( totpSecret . secretKey , totpSecret . codeLength , totpSecret . codeIntervalSeconds ) ;
156
+
157
+
158
+ const totpVerificationCode = getTotpCode ( totpSecret . secretKey , totpSecret . codeIntervalSeconds , totpSecret . codeLength , totpSecret . hashingAlgorithm ) ;
136
159
137
160
const multiFactorAssertion = TotpMultiFactorGenerator . assertionForEnrollment (
138
161
totpSecret ,
139
162
totpVerificationCode
140
163
) ;
141
164
console . log ( totpVerificationCode ) ;
142
- // auth/invalid-idToken
143
- await expect ( mfaUser . enroll ( multiFactorAssertion , displayName ) ) . to . be . rejectedWith ( 'auth/invalid-user-token' )
165
+
166
+ await expect ( mfaUser . enroll ( multiFactorAssertion , displayName ) ) . to . be . fulfilled ;
144
167
168
+ await auth . signOut ( ) ;
169
+
170
+ //await expect(signInWithEmailAndPassword(auth, email, 'password')).to.be.rejectedWith('auth/multi-factor-auth-required');
171
+
172
+
173
+ //await expect().to.be.rejectedWith(FirebaseError);
174
+
175
+ } )
176
+
177
+ it ( 'should allow sign-in for correct totp' , async ( ) => {
178
+ let session ;
179
+ let cr ;
180
+ let resolver ;
181
+ console . log ( email ) ;
182
+ console . log ( 'session info for: ' , getApp ( ) . options . projectId ) ;
183
+
184
+ await delay ( 15 * 1000 ) ;
185
+ try {
186
+
187
+ const userCredential = await signInWithEmailAndPassword ( auth , email , 'password' ) ;
188
+
189
+ console . log ( 'success: ' , userCredential ) ;
190
+
191
+ throw new Error ( 'Signin should not have been successful' ) ;
192
+
193
+ } catch ( error ) {
194
+
195
+
196
+ console . log ( 'error occured: ' , ( error as any ) . code ) ;
197
+ expect ( ( error as any ) . code ) . to . eql ( 'auth/multi-factor-auth-required' ) ;
198
+
199
+ resolver = getMultiFactorResolver ( auth , error as any ) ;
200
+ console . log ( resolver . hints , totpSecret . secretKey ) ;
201
+ expect ( resolver . hints ) . to . have . length ( 1 ) ;
202
+
203
+ const totpVerificationCode = getTotpCode ( totpSecret . secretKey , totpSecret . codeIntervalSeconds , totpSecret . codeLength , totpSecret . hashingAlgorithm ) ;
204
+ console . log ( totpVerificationCode , resolver . hints [ 0 ] . uid )
205
+ const assertion = TotpMultiFactorGenerator . assertionForSignIn (
206
+ resolver . hints [ 0 ] . uid ,
207
+ totpVerificationCode + '0'
208
+ ) ;
209
+
210
+ console . log ( assertion ) ;
211
+
212
+
213
+ await expect ( resolver . resolveSignIn ( assertion ) ) . to . be . rejectedWith ( 'nothing' ) ;
214
+
215
+ await auth . signOut ( ) ;
216
+
217
+ }
218
+
219
+
220
+ } )
221
+
222
+ it ( 'should allow sign-in with for correct totp and unenroll successfully' , async ( ) => {
145
223
146
224
} )
147
225
} )
0 commit comments