Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 20 additions & 27 deletions src/auth/auth-api-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {deepCopy} from '../utils/deep-copy';
import {FirebaseApp} from '../firebase-app';
import {AuthClientErrorCode, FirebaseAuthError, FirebaseError} from '../utils/error';
import {
HttpMethod, SignedApiRequestHandler, ApiSettings,
ApiSettings, AuthorizedHttpClient, HttpRequestConfig, HttpError,
} from '../utils/api-request';
import {CreateRequest, UpdateRequest} from './user-record';
import {
Expand Down Expand Up @@ -429,12 +429,8 @@ export const FIREBASE_AUTH_SIGN_UP_NEW_USER = new ApiSettings('signupNewUser', '
* Class that provides mechanism to send requests to the Firebase Auth backend endpoints.
*/
export class FirebaseAuthRequestHandler {
private host: string = FIREBASE_AUTH_HOST;
private port: number = FIREBASE_AUTH_PORT;
private path: string = FIREBASE_AUTH_PATH;
private headers: object = FIREBASE_AUTH_HEADER;
private timeout: number = FIREBASE_AUTH_TIMEOUT;
private signedApiRequestHandler: SignedApiRequestHandler;
private baseUrl: string = `https://${FIREBASE_AUTH_HOST}${FIREBASE_AUTH_PATH}`;
private httpClient: AuthorizedHttpClient;

/**
* @param {any} response The response to check for errors.
Expand All @@ -449,7 +445,7 @@ export class FirebaseAuthRequestHandler {
* @constructor
*/
constructor(app: FirebaseApp) {
this.signedApiRequestHandler = new SignedApiRequestHandler(app);
this.httpClient = new AuthorizedHttpClient(app);
}

/**
Expand Down Expand Up @@ -805,38 +801,35 @@ export class FirebaseAuthRequestHandler {
* @return {Promise<object>} A promise that resolves with the response.
*/
private invokeRequestHandler(apiSettings: ApiSettings, requestData: object): Promise<object> {
const path: string = this.path + apiSettings.getEndpoint();
const httpMethod: HttpMethod = apiSettings.getHttpMethod();
return Promise.resolve()
.then(() => {
// Validate request.
const requestValidator = apiSettings.getRequestValidator();
requestValidator(requestData);
// Process request.
return this.signedApiRequestHandler.sendRequest(
this.host, this.port, path, httpMethod, requestData, this.headers, this.timeout);
const req: HttpRequestConfig = {
method: apiSettings.getHttpMethod(),
url: `${this.baseUrl}${apiSettings.getEndpoint()}`,
headers: FIREBASE_AUTH_HEADER,
data: requestData,
timeout: FIREBASE_AUTH_TIMEOUT,
};
return this.httpClient.send(req);
})
.then((response) => {
// Check for backend errors in the response.
const errorCode = FirebaseAuthRequestHandler.getErrorCode(response);
if (errorCode) {
throw FirebaseAuthError.fromServerError(errorCode, /* message */ undefined, response);
}
// Validate response.
const responseValidator = apiSettings.getResponseValidator();
responseValidator(response);
responseValidator(response.data);
// Return entire response.
return response;
return response.data;
})
.catch((response) => {
const error = (typeof response === 'object' && 'statusCode' in response) ?
response.error : response;
if (error instanceof FirebaseError) {
throw error;
.catch((err) => {
if (err instanceof HttpError) {
const error = err.response.data;
const errorCode = FirebaseAuthRequestHandler.getErrorCode(error);
throw FirebaseAuthError.fromServerError(errorCode, /* message */ undefined, error);
}

const errorCode = FirebaseAuthRequestHandler.getErrorCode(error);
throw FirebaseAuthError.fromServerError(errorCode, /* message */ undefined, error);
throw err;
});
}
}
13 changes: 6 additions & 7 deletions src/utils/api-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,11 @@ class DefaultHttpResponse implements HttpResponse {
}

export class HttpError extends Error {

public readonly response: HttpResponse;

constructor(resp: LowLevelResponse) {
super(`Server responded with status ${resp.status}.`);
this.response = new DefaultHttpResponse(resp);
constructor(public readonly response: HttpResponse) {
super(`Server responded with status ${response.status}.`);
// Set the prototype so that instanceof checks will work correctly.
// See: https://github.com/Microsoft/TypeScript/issues/13965
Object.setPrototypeOf(this, HttpError.prototype);
}
}

Expand Down Expand Up @@ -153,7 +152,7 @@ export class HttpClient {
return this.sendWithRetry(config, attempts + 1);
}
if (err.response) {
throw new HttpError(err.response);
throw new HttpError(new DefaultHttpResponse(err.response));
}
if (err.code === 'ETIMEDOUT') {
throw new FirebaseAppError(
Expand Down
Loading