@@ -760,6 +760,20 @@ describe('admin.auth', () => {
760
760
safeDelete ( userRecord . uid ) ;
761
761
}
762
762
} ) ;
763
+
764
+ it ( 'A user with user record disabled is unable to sign in' , async ( ) => {
765
+ const password = 'password' ;
766
+ const email = '[email protected] ' ;
767
+ return admin . auth ( ) . updateUser ( updateUser . uid , { disabled : true , password, email } )
768
+ . then ( ( ) => {
769
+ return clientAuth ( ) . signInWithEmailAndPassword ( email , password ) ;
770
+ } )
771
+ . then ( ( ) => {
772
+ throw new Error ( 'Unexpected success' ) ;
773
+ } , ( error ) => {
774
+ expect ( error ) . to . have . property ( 'code' , 'auth/user-disabled' ) ;
775
+ } ) ;
776
+ } ) ;
763
777
} ) ;
764
778
765
779
it ( 'getUser() fails when called with a non-existing UID' , ( ) => {
@@ -833,53 +847,113 @@ describe('admin.auth', () => {
833
847
} ) ;
834
848
} ) ;
835
849
836
- it ( 'verifyIdToken() fails when called with an invalid token' , ( ) => {
837
- return admin . auth ( ) . verifyIdToken ( 'invalid-token' )
838
- . should . eventually . be . rejected . and . have . property ( 'code' , 'auth/argument-error' ) ;
839
- } ) ;
850
+ describe ( 'verifyIdToken()' , ( ) => {
851
+ const uid = generateRandomString ( 20 ) . toLowerCase ( ) ;
852
+ const email = uid + '@example.com' ;
853
+ const password = 'password' ;
854
+ const userData = {
855
+ uid,
856
+ email,
857
+ emailVerified : false ,
858
+ password,
859
+ } ;
860
+
861
+ // Create the test user before running this suite of tests.
862
+ before ( ( ) => {
863
+ return admin . auth ( ) . createUser ( userData ) ;
864
+ } ) ;
840
865
841
- if ( authEmulatorHost ) {
842
- describe ( 'Auth emulator support' , ( ) => {
843
- const uid = 'authEmulatorUser' ;
844
- before ( ( ) => {
845
- return admin . auth ( ) . createUser ( {
846
- uid,
847
-
848
- password : 'p4ssword' ,
866
+ // Sign out after each test.
867
+ afterEach ( ( ) => {
868
+ return clientAuth ( ) . signOut ( ) ;
869
+ } ) ;
870
+
871
+ after ( ( ) => {
872
+ return safeDelete ( uid ) ;
873
+ } ) ;
874
+
875
+ it ( 'verifyIdToken() fails when called with an invalid token' , ( ) => {
876
+ return admin . auth ( ) . verifyIdToken ( 'invalid-token' )
877
+ . should . eventually . be . rejected . and . have . property ( 'code' , 'auth/argument-error' ) ;
878
+ } ) ;
879
+
880
+ it ( 'verifyIdToken() fails with checkRevoked set to true and corresponding user disabled' , async ( ) => {
881
+ const { user } = await clientAuth ( ) . signInWithEmailAndPassword ( email , password ) ;
882
+ expect ( user ) . to . exist ;
883
+ expect ( user ! . email ) . to . equal ( email ) ;
884
+
885
+ const idToken = await user ! . getIdToken ( ) ;
886
+ let decodedIdToken = await admin . auth ( ) . verifyIdToken ( idToken , true ) ;
887
+ expect ( decodedIdToken . uid ) . to . equal ( uid ) ;
888
+ expect ( decodedIdToken . email ) . to . equal ( email ) ;
889
+
890
+ const userRecord = await admin . auth ( ) . updateUser ( uid , { disabled : true } ) ;
891
+ expect ( userRecord . uid ) . to . equal ( uid ) ;
892
+ expect ( userRecord . email ) . to . equal ( email ) ;
893
+ expect ( userRecord . disabled ) . to . equal ( true ) ;
894
+
895
+ try {
896
+ // If it is in emulator mode, a user-disabled error will be thrown.
897
+ decodedIdToken = await admin . auth ( ) . verifyIdToken ( idToken , false ) ;
898
+ expect ( decodedIdToken . uid ) . to . equal ( uid ) ;
899
+ } catch ( error ) {
900
+ if ( authEmulatorHost ) {
901
+ expect ( error ) . to . have . property ( 'code' , 'auth/user-disabled' ) ;
902
+ } else {
903
+ throw error ;
904
+ }
905
+ }
906
+
907
+ try {
908
+ await admin . auth ( ) . verifyIdToken ( idToken , true ) ;
909
+ } catch ( error ) {
910
+ expect ( error ) . to . have . property ( 'code' , 'auth/user-disabled' ) ;
911
+ }
912
+ } ) ;
913
+
914
+ if ( authEmulatorHost ) {
915
+ describe ( 'Auth emulator support' , ( ) => {
916
+ const uid = 'authEmulatorUser' ;
917
+ before ( ( ) => {
918
+ return admin . auth ( ) . createUser ( {
919
+ uid,
920
+
921
+ password : 'p4ssword' ,
922
+ } ) ;
923
+ } ) ;
924
+ after ( ( ) => {
925
+ return admin . auth ( ) . deleteUser ( uid ) ;
849
926
} ) ;
850
- } ) ;
851
- after ( ( ) => {
852
- return admin . auth ( ) . deleteUser ( uid ) ;
853
- } ) ;
854
927
855
- it ( 'verifyIdToken() succeeds when called with an unsigned token' , ( ) => {
856
- const unsignedToken = mocks . generateIdToken ( {
857
- algorithm : 'none' ,
858
- audience : projectId ,
859
- issuer : 'https://securetoken.google.com/' + projectId ,
860
- subject : uid ,
928
+ it ( 'verifyIdToken() succeeds when called with an unsigned token' , ( ) => {
929
+ const unsignedToken = mocks . generateIdToken ( {
930
+ algorithm : 'none' ,
931
+ audience : projectId ,
932
+ issuer : 'https://securetoken.google.com/' + projectId ,
933
+ subject : uid ,
934
+ } ) ;
935
+ return admin . auth ( ) . verifyIdToken ( unsignedToken ) ;
861
936
} ) ;
862
- return admin . auth ( ) . verifyIdToken ( unsignedToken ) ;
863
- } ) ;
864
937
865
- it ( 'verifyIdToken() fails when called with a token with wrong project' , ( ) => {
866
- const unsignedToken = mocks . generateIdToken ( { algorithm : 'none' , audience : 'nosuch' } ) ;
867
- return admin . auth ( ) . verifyIdToken ( unsignedToken )
868
- . should . eventually . be . rejected . and . have . property ( 'code' , 'auth/argument-error' ) ;
869
- } ) ;
938
+ it ( 'verifyIdToken() fails when called with a token with wrong project' , ( ) => {
939
+ const unsignedToken = mocks . generateIdToken ( { algorithm : 'none' , audience : 'nosuch' } ) ;
940
+ return admin . auth ( ) . verifyIdToken ( unsignedToken )
941
+ . should . eventually . be . rejected . and . have . property ( 'code' , 'auth/argument-error' ) ;
942
+ } ) ;
870
943
871
- it ( 'verifyIdToken() fails when called with a token that does not belong to a user' , ( ) => {
872
- const unsignedToken = mocks . generateIdToken ( {
873
- algorithm : 'none' ,
874
- audience : projectId ,
875
- issuer : 'https://securetoken.google.com/' + projectId ,
876
- subject : 'nosuch' ,
944
+ it ( 'verifyIdToken() fails when called with a token that does not belong to a user' , ( ) => {
945
+ const unsignedToken = mocks . generateIdToken ( {
946
+ algorithm : 'none' ,
947
+ audience : projectId ,
948
+ issuer : 'https://securetoken.google.com/' + projectId ,
949
+ subject : 'nosuch' ,
950
+ } ) ;
951
+ return admin . auth ( ) . verifyIdToken ( unsignedToken )
952
+ . should . eventually . be . rejected . and . have . property ( 'code' , 'auth/user-not-found' ) ;
877
953
} ) ;
878
- return admin . auth ( ) . verifyIdToken ( unsignedToken )
879
- . should . eventually . be . rejected . and . have . property ( 'code' , 'auth/user-not-found' ) ;
880
954
} ) ;
881
- } ) ;
882
- }
955
+ }
956
+ } ) ;
883
957
884
958
describe ( 'Link operations' , ( ) => {
885
959
const uid = generateRandomString ( 20 ) . toLowerCase ( ) ;
@@ -1982,6 +2056,44 @@ describe('admin.auth', () => {
1982
2056
. should . eventually . be . rejected . and . have . property ( 'code' , 'auth/argument-error' ) ;
1983
2057
} ) ;
1984
2058
} ) ;
2059
+
2060
+ it ( 'fails with checkRevoked set to true and corresponding user disabled' , async ( ) => {
2061
+ const expiresIn = 24 * 60 * 60 * 1000 ;
2062
+ const customToken = await admin . auth ( ) . createCustomToken ( uid , { admin : true , groupId : '1234' } ) ;
2063
+ const { user } = await clientAuth ( ) . signInWithCustomToken ( customToken ) ;
2064
+ expect ( user ) . to . exist ;
2065
+
2066
+ const idToken = await user ! . getIdToken ( ) ;
2067
+ const decodedIdTokenClaims = await admin . auth ( ) . verifyIdToken ( idToken ) ;
2068
+ expect ( decodedIdTokenClaims . uid ) . to . be . equal ( uid ) ;
2069
+
2070
+ const sessionCookie = await admin . auth ( ) . createSessionCookie ( idToken , { expiresIn } ) ;
2071
+ let decodedIdToken = await admin . auth ( ) . verifySessionCookie ( sessionCookie , true ) ;
2072
+ expect ( decodedIdToken . uid ) . to . equal ( uid ) ;
2073
+
2074
+ const userRecord = await admin . auth ( ) . updateUser ( uid , { disabled : true } ) ;
2075
+ // Ensure disabled field has been updated.
2076
+ expect ( userRecord . uid ) . to . equal ( uid ) ;
2077
+ expect ( userRecord . disabled ) . to . equal ( true ) ;
2078
+
2079
+ try {
2080
+ // If it is in emulator mode, a user-disabled error will be thrown.
2081
+ decodedIdToken = await admin . auth ( ) . verifySessionCookie ( sessionCookie , false ) ;
2082
+ expect ( decodedIdToken . uid ) . to . equal ( uid ) ;
2083
+ } catch ( error ) {
2084
+ if ( authEmulatorHost ) {
2085
+ expect ( error ) . to . have . property ( 'code' , 'auth/user-disabled' ) ;
2086
+ } else {
2087
+ throw error ;
2088
+ }
2089
+ }
2090
+
2091
+ try {
2092
+ await admin . auth ( ) . verifySessionCookie ( sessionCookie , true ) ;
2093
+ } catch ( error ) {
2094
+ expect ( error ) . to . have . property ( 'code' , 'auth/user-disabled' ) ;
2095
+ }
2096
+ } ) ;
1985
2097
} ) ;
1986
2098
1987
2099
describe ( 'importUsers()' , ( ) => {
0 commit comments