@@ -24,6 +24,7 @@ import MultiFactorConfigState = auth.MultiFactorConfigState;
2424import AuthFactorType = auth . AuthFactorType ;
2525import EmailSignInProviderConfig = auth . EmailSignInProviderConfig ;
2626import OIDCAuthProviderConfig = auth . OIDCAuthProviderConfig ;
27+ import OAuthResponseType = auth . OAuthResponseType ;
2728import SAMLAuthProviderConfig = auth . SAMLAuthProviderConfig ;
2829
2930/** A maximum of 10 test phone number / code pairs can be configured. */
@@ -75,6 +76,8 @@ export interface OIDCConfigServerRequest {
7576 issuer ?: string ;
7677 displayName ?: string ;
7778 enabled ?: boolean ;
79+ clientSecret ?: string ;
80+ responseType ?: OAuthResponseType ;
7881 [ key : string ] : any ;
7982}
8083
@@ -87,6 +90,8 @@ export interface OIDCConfigServerResponse {
8790 issuer ?: string ;
8891 displayName ?: string ;
8992 enabled ?: boolean ;
93+ clientSecret ?: string ;
94+ responseType ?: OAuthResponseType ;
9095}
9196
9297/** The server side email configuration request interface. */
@@ -650,6 +655,8 @@ export class OIDCConfig implements OIDCAuthProviderConfig {
650655 public readonly providerId : string ;
651656 public readonly issuer : string ;
652657 public readonly clientId : string ;
658+ public readonly clientSecret ?: string ;
659+ public readonly responseType : OAuthResponseType ;
653660
654661 /**
655662 * Converts a client side request to a OIDCConfigServerRequest which is the format
@@ -676,6 +683,12 @@ export class OIDCConfig implements OIDCAuthProviderConfig {
676683 request . displayName = options . displayName ;
677684 request . issuer = options . issuer ;
678685 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+ }
679692 return request ;
680693 }
681694
@@ -715,6 +728,12 @@ export class OIDCConfig implements OIDCAuthProviderConfig {
715728 providerId : true ,
716729 clientId : true ,
717730 issuer : true ,
731+ clientSecret : true ,
732+ responseType : true ,
733+ } ;
734+ const validResponseTypes = {
735+ idToken : true ,
736+ code : true ,
718737 } ;
719738 if ( ! validator . isNonNullObject ( options ) ) {
720739 throw new FirebaseAuthError (
@@ -773,6 +792,59 @@ export class OIDCConfig implements OIDCAuthProviderConfig {
773792 '"OIDCAuthProviderConfig.displayName" must be a valid string.' ,
774793 ) ;
775794 }
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+ }
776848 }
777849
778850 /**
@@ -806,6 +878,13 @@ export class OIDCConfig implements OIDCAuthProviderConfig {
806878 // When enabled is undefined, it takes its default value of false.
807879 this . enabled = ! ! response . enabled ;
808880 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+ }
809888 }
810889
811890 /** @return {OIDCAuthProviderConfig } The plain object representation of the OIDCConfig. */
@@ -816,6 +895,8 @@ export class OIDCConfig implements OIDCAuthProviderConfig {
816895 providerId : this . providerId ,
817896 issuer : this . issuer ,
818897 clientId : this . clientId ,
898+ clientSecret : deepCopy ( this . clientSecret ) ,
899+ responseType : deepCopy ( this . responseType ) ,
819900 } ;
820901 }
821902}
0 commit comments