@@ -127,14 +127,15 @@ class AuthResourceUrlBuilder {
127127 /**
128128 * The resource URL builder constructor.
129129 *
130- * @param projectId - The resource project ID .
130+ * @param app - The app for this URL builder .
131131 * @param version - The endpoint API version.
132+ * @param emulatorHost - Optional emulator host captured at init time.
132133 * @constructor
133134 */
134- constructor ( protected app : App , protected version : string = 'v1' ) {
135- if ( useEmulator ( ) ) {
135+ constructor ( protected app : App , protected version : string = 'v1' , emHost ?: string ) {
136+ if ( emHost ) {
136137 this . urlFormat = utils . formatString ( FIREBASE_AUTH_EMULATOR_BASE_URL_FORMAT , {
137- host : emulatorHost ( )
138+ host : emHost
138139 } ) ;
139140 } else {
140141 this . urlFormat = FIREBASE_AUTH_BASE_URL_FORMAT ;
@@ -191,16 +192,17 @@ class TenantAwareAuthResourceUrlBuilder extends AuthResourceUrlBuilder {
191192 /**
192193 * The tenant aware resource URL builder constructor.
193194 *
194- * @param projectId - The resource project ID .
195+ * @param app - The app for this URL builder .
195196 * @param version - The endpoint API version.
196197 * @param tenantId - The tenant ID.
198+ * @param emHost - Optional emulator host captured at init time.
197199 * @constructor
198200 */
199- constructor ( protected app : App , protected version : string , protected tenantId : string ) {
200- super ( app , version ) ;
201- if ( useEmulator ( ) ) {
201+ constructor ( protected app : App , protected version : string , protected tenantId : string , emHost ?: string ) {
202+ super ( app , version , emHost ) ;
203+ if ( emHost ) {
202204 this . urlFormat = utils . formatString ( FIREBASE_AUTH_EMULATOR_TENANT_URL_FORMAT , {
203- host : emulatorHost ( )
205+ host : emHost
204206 } ) ;
205207 } else {
206208 this . urlFormat = FIREBASE_AUTH_TENANT_URL_FORMAT ;
@@ -229,8 +231,15 @@ class TenantAwareAuthResourceUrlBuilder extends AuthResourceUrlBuilder {
229231 */
230232class AuthHttpClient extends AuthorizedHttpClient {
231233
234+ private readonly isEmulator : boolean ;
235+
236+ constructor ( app : FirebaseApp , isEmulator : boolean ) {
237+ super ( app ) ;
238+ this . isEmulator = isEmulator ;
239+ }
240+
232241 protected getToken ( ) : Promise < string > {
233- if ( useEmulator ( ) ) {
242+ if ( this . isEmulator ) {
234243 return Promise . resolve ( 'owner' ) ;
235244 }
236245
@@ -1048,6 +1057,7 @@ const LIST_INBOUND_SAML_CONFIGS = new ApiSettings('/inboundSamlConfigs', 'GET')
10481057export abstract class AbstractAuthRequestHandler {
10491058
10501059 protected readonly httpClient : AuthorizedHttpClient ;
1060+ public readonly emulatorHostValue : string | undefined ;
10511061 private authUrlBuilder : AuthResourceUrlBuilder ;
10521062 private projectConfigUrlBuilder : AuthResourceUrlBuilder ;
10531063
@@ -1102,17 +1112,21 @@ export abstract class AbstractAuthRequestHandler {
11021112
11031113 /**
11041114 * @param app - The app used to fetch access tokens to sign API requests.
1115+ * @param emHost - Optional emulator host override. When provided (including
1116+ * null for explicitly no emulator), this value is used instead of reading
1117+ * from the FIREBASE_AUTH_EMULATOR_HOST environment variable.
11051118 * @constructor
11061119 */
1107- constructor ( protected readonly app : App ) {
1120+ constructor ( protected readonly app : App , emHost ?: string | null ) {
11081121 if ( typeof app !== 'object' || app === null || ! ( 'options' in app ) ) {
11091122 throw new FirebaseAuthError (
11101123 authClientErrorCode . INVALID_ARGUMENT ,
11111124 'First argument passed to admin.auth() must be a valid Firebase app instance.' ,
11121125 ) ;
11131126 }
11141127
1115- this . httpClient = new AuthHttpClient ( app as FirebaseApp ) ;
1128+ this . emulatorHostValue = emHost !== undefined ? ( emHost || undefined ) : emulatorHost ( ) ;
1129+ this . httpClient = new AuthHttpClient ( app as FirebaseApp , ! ! this . emulatorHostValue ) ;
11161130 }
11171131
11181132 /**
@@ -2021,6 +2035,11 @@ export abstract class AbstractAuthRequestHandler {
20212035/** Instantiates the getConfig endpoint settings. */
20222036const GET_PROJECT_CONFIG = new ApiSettings ( '/config' , 'GET' )
20232037 . setResponseValidator ( ( response : RequestResponse ) => {
2038+ // The Auth emulator does not populate the resource `name` field on the
2039+ // project config response, so skip the assertion when running against it.
2040+ if ( useEmulator ( ) ) {
2041+ return ;
2042+ }
20242043 const data = response . data ;
20252044 // Response should always contain at least the config name.
20262045 if ( ! validator . isNonEmptyString ( data ?. name ) ) {
@@ -2035,6 +2054,11 @@ const GET_PROJECT_CONFIG = new ApiSettings('/config', 'GET')
20352054/** Instantiates the updateConfig endpoint settings. */
20362055const UPDATE_PROJECT_CONFIG = new ApiSettings ( '/config?updateMask={updateMask}' , 'PATCH' )
20372056 . setResponseValidator ( ( response : RequestResponse ) => {
2057+ // The Auth emulator does not populate the resource `name` field on the
2058+ // project config response, so skip the assertion when running against it.
2059+ if ( useEmulator ( ) ) {
2060+ return ;
2061+ }
20382062 const data = response . data ;
20392063 // Response should always contain at least the config name.
20402064 if ( ! validator . isNonEmptyString ( data ?. name ) ) {
@@ -2135,21 +2159,21 @@ export class AuthRequestHandler extends AbstractAuthRequestHandler {
21352159 */
21362160 constructor ( app : App ) {
21372161 super ( app ) ;
2138- this . authResourceUrlBuilder = new AuthResourceUrlBuilder ( app , 'v2' ) ;
2162+ this . authResourceUrlBuilder = new AuthResourceUrlBuilder ( app , 'v2' , this . emulatorHostValue ) ;
21392163 }
21402164
21412165 /**
21422166 * @returns A new Auth user management resource URL builder instance.
21432167 */
21442168 protected newAuthUrlBuilder ( ) : AuthResourceUrlBuilder {
2145- return new AuthResourceUrlBuilder ( this . app , 'v1' ) ;
2169+ return new AuthResourceUrlBuilder ( this . app , 'v1' , this . emulatorHostValue ) ;
21462170 }
21472171
21482172 /**
21492173 * @returns A new project config resource URL builder instance.
21502174 */
21512175 protected newProjectConfigUrlBuilder ( ) : AuthResourceUrlBuilder {
2152- return new AuthResourceUrlBuilder ( this . app , 'v2' ) ;
2176+ return new AuthResourceUrlBuilder ( this . app , 'v2' , this . emulatorHostValue ) ;
21532177 }
21542178
21552179 /**
@@ -2306,24 +2330,25 @@ export class TenantAwareAuthRequestHandler extends AbstractAuthRequestHandler {
23062330 *
23072331 * @param app - The app used to fetch access tokens to sign API requests.
23082332 * @param tenantId - The request handler's tenant ID.
2333+ * @param emHost - Optional emulator host override captured at init time.
23092334 * @constructor
23102335 */
2311- constructor ( app : App , private readonly tenantId : string ) {
2312- super ( app ) ;
2336+ constructor ( app : App , private readonly tenantId : string , emHost ?: string | null ) {
2337+ super ( app , emHost ) ;
23132338 }
23142339
23152340 /**
23162341 * @returns A new Auth user management resource URL builder instance.
23172342 */
23182343 protected newAuthUrlBuilder ( ) : AuthResourceUrlBuilder {
2319- return new TenantAwareAuthResourceUrlBuilder ( this . app , 'v1' , this . tenantId ) ;
2344+ return new TenantAwareAuthResourceUrlBuilder ( this . app , 'v1' , this . tenantId , this . emulatorHostValue ) ;
23202345 }
23212346
23222347 /**
23232348 * @returns A new project config resource URL builder instance.
23242349 */
23252350 protected newProjectConfigUrlBuilder ( ) : AuthResourceUrlBuilder {
2326- return new TenantAwareAuthResourceUrlBuilder ( this . app , 'v2' , this . tenantId ) ;
2351+ return new TenantAwareAuthResourceUrlBuilder ( this . app , 'v2' , this . tenantId , this . emulatorHostValue ) ;
23272352 }
23282353
23292354 /**
0 commit comments