@@ -24,6 +24,7 @@ import MultiFactorConfigState = auth.MultiFactorConfigState;
24
24
import AuthFactorType = auth . AuthFactorType ;
25
25
import EmailSignInProviderConfig = auth . EmailSignInProviderConfig ;
26
26
import OIDCAuthProviderConfig = auth . OIDCAuthProviderConfig ;
27
+ import OAuthResponseType = auth . OAuthResponseType ;
27
28
import SAMLAuthProviderConfig = auth . SAMLAuthProviderConfig ;
28
29
29
30
/** A maximum of 10 test phone number / code pairs can be configured. */
@@ -75,6 +76,8 @@ export interface OIDCConfigServerRequest {
75
76
issuer ?: string ;
76
77
displayName ?: string ;
77
78
enabled ?: boolean ;
79
+ clientSecret ?: string ;
80
+ responseType ?: OAuthResponseType ;
78
81
[ key : string ] : any ;
79
82
}
80
83
@@ -87,6 +90,8 @@ export interface OIDCConfigServerResponse {
87
90
issuer ?: string ;
88
91
displayName ?: string ;
89
92
enabled ?: boolean ;
93
+ clientSecret ?: string ;
94
+ responseType ?: OAuthResponseType ;
90
95
}
91
96
92
97
/** The server side email configuration request interface. */
@@ -650,6 +655,8 @@ export class OIDCConfig implements OIDCAuthProviderConfig {
650
655
public readonly providerId : string ;
651
656
public readonly issuer : string ;
652
657
public readonly clientId : string ;
658
+ public readonly clientSecret ?: string ;
659
+ public readonly responseType : OAuthResponseType ;
653
660
654
661
/**
655
662
* Converts a client side request to a OIDCConfigServerRequest which is the format
@@ -676,6 +683,12 @@ export class OIDCConfig implements OIDCAuthProviderConfig {
676
683
request . displayName = options . displayName ;
677
684
request . issuer = options . issuer ;
678
685
request . clientId = options . clientId ;
686
+ if ( typeof options . clientSecret !== 'undefined' ) {
687
+ request . clientSecret = options . clientSecret ;
688
+ }
689
+ if ( typeof options . responseType !== 'undefined' ) {
690
+ request . responseType = options . responseType ;
691
+ }
679
692
return request ;
680
693
}
681
694
@@ -715,6 +728,12 @@ export class OIDCConfig implements OIDCAuthProviderConfig {
715
728
providerId : true ,
716
729
clientId : true ,
717
730
issuer : true ,
731
+ clientSecret : true ,
732
+ responseType : true ,
733
+ } ;
734
+ const validResponseTypes = {
735
+ idToken : true ,
736
+ code : true ,
718
737
} ;
719
738
if ( ! validator . isNonNullObject ( options ) ) {
720
739
throw new FirebaseAuthError (
@@ -773,6 +792,59 @@ export class OIDCConfig implements OIDCAuthProviderConfig {
773
792
'"OIDCAuthProviderConfig.displayName" must be a valid string.' ,
774
793
) ;
775
794
}
795
+ if ( typeof options . clientSecret !== 'undefined' &&
796
+ ! validator . isNonEmptyString ( options . clientSecret ) ) {
797
+ throw new FirebaseAuthError (
798
+ AuthClientErrorCode . INVALID_CONFIG ,
799
+ '"OIDCAuthProviderConfig.clientSecret" must be a valid string.' ,
800
+ ) ;
801
+ }
802
+ if ( validator . isNonNullObject ( options . responseType ) && typeof options . responseType !== 'undefined' ) {
803
+ Object . keys ( options . responseType ) . forEach ( ( key ) => {
804
+ if ( ! ( key in validResponseTypes ) ) {
805
+ throw new FirebaseAuthError (
806
+ AuthClientErrorCode . INVALID_CONFIG ,
807
+ `"${ key } " is not a valid OAuthResponseType parameter.` ,
808
+ ) ;
809
+ }
810
+ } ) ;
811
+
812
+ const idToken = options . responseType . idToken ;
813
+ if ( typeof idToken !== 'undefined' && ! validator . isBoolean ( idToken ) ) {
814
+ throw new FirebaseAuthError (
815
+ AuthClientErrorCode . INVALID_ARGUMENT ,
816
+ '"OIDCAuthProviderConfig.responseType.idToken" must be a boolean.' ,
817
+ ) ;
818
+ }
819
+
820
+ const code = options . responseType . code ;
821
+ if ( typeof code !== 'undefined' ) {
822
+ if ( ! validator . isBoolean ( code ) ) {
823
+ throw new FirebaseAuthError (
824
+ AuthClientErrorCode . INVALID_ARGUMENT ,
825
+ '"OIDCAuthProviderConfig.responseType.code" must be a boolean.' ,
826
+ ) ;
827
+ }
828
+
829
+ // If code flow is enabled, client secret must be provided.
830
+ if ( code && typeof options . clientSecret === 'undefined' ) {
831
+ throw new FirebaseAuthError (
832
+ AuthClientErrorCode . MISSING_OAUTH_CLIENT_SECRET ,
833
+ 'The OAuth configuration client secret is required to enable OIDC code flow.' ,
834
+ ) ;
835
+ }
836
+ }
837
+
838
+ const allKeys = Object . keys ( options . responseType ) . length ;
839
+ const enabledCount = Object . values ( options . responseType ) . filter ( Boolean ) . length ;
840
+ // Only one of OAuth response types can be set to true.
841
+ if ( allKeys > 1 && enabledCount != 1 ) {
842
+ throw new FirebaseAuthError (
843
+ AuthClientErrorCode . INVALID_OAUTH_RESPONSETYPE ,
844
+ 'Only exactly one OAuth responseType should be set to true.' ,
845
+ ) ;
846
+ }
847
+ }
776
848
}
777
849
778
850
/**
@@ -806,6 +878,13 @@ export class OIDCConfig implements OIDCAuthProviderConfig {
806
878
// When enabled is undefined, it takes its default value of false.
807
879
this . enabled = ! ! response . enabled ;
808
880
this . displayName = response . displayName ;
881
+
882
+ if ( typeof response . clientSecret !== 'undefined' ) {
883
+ this . clientSecret = response . clientSecret ;
884
+ }
885
+ if ( typeof response . responseType !== 'undefined' ) {
886
+ this . responseType = response . responseType ;
887
+ }
809
888
}
810
889
811
890
/** @return {OIDCAuthProviderConfig } The plain object representation of the OIDCConfig. */
@@ -816,6 +895,8 @@ export class OIDCConfig implements OIDCAuthProviderConfig {
816
895
providerId : this . providerId ,
817
896
issuer : this . issuer ,
818
897
clientId : this . clientId ,
898
+ clientSecret : deepCopy ( this . clientSecret ) ,
899
+ responseType : deepCopy ( this . responseType ) ,
819
900
} ;
820
901
}
821
902
}
0 commit comments