Skip to content

Commit

Permalink
fix(auth): Fix service account issue in createToken() using ADC
Browse files Browse the repository at this point in the history
  • Loading branch information
lahirumaramba committed Dec 5, 2024
1 parent 8358549 commit dcda638
Showing 1 changed file with 13 additions and 6 deletions.
19 changes: 13 additions & 6 deletions src/utils/crypto-signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { AuthorizedHttpClient, HttpRequestConfig, HttpClient, RequestResponseErr

import { Algorithm } from 'jsonwebtoken';
import { ErrorInfo } from '../utils/error';
import * as utils from '../utils/index';
import * as validator from '../utils/validator';

const ALGORITHM_RS256: Algorithm = 'RS256' as const;
Expand Down Expand Up @@ -105,22 +106,23 @@ export class IAMSigner implements CryptoSigner {

private readonly httpClient: AuthorizedHttpClient;
private serviceAccountId?: string;
private app?: App;

constructor(httpClient: AuthorizedHttpClient, serviceAccountId?: string) {
constructor(httpClient: AuthorizedHttpClient, app: App) {
if (!httpClient) {
throw new CryptoSignerError({
code: CryptoSignerErrorCode.INVALID_ARGUMENT,
message: 'INTERNAL ASSERT: Must provide a HTTP client to initialize IAMSigner.',
});
}
if (typeof serviceAccountId !== 'undefined' && !validator.isNonEmptyString(serviceAccountId)) {
if (typeof app !== 'object' || app === null || !('options' in app)) {
throw new CryptoSignerError({
code: CryptoSignerErrorCode.INVALID_ARGUMENT,
message: 'INTERNAL ASSERT: Service account ID must be undefined or a non-empty string.',
message: 'INTERNAL ASSERT: Must provide a valid Firebase app instance.',
});
}
this.httpClient = httpClient;
this.serviceAccountId = serviceAccountId;
this.app = app;
}

/**
Expand Down Expand Up @@ -152,10 +154,15 @@ export class IAMSigner implements CryptoSigner {
/**
* @inheritDoc
*/
public getAccountId(): Promise<string> {
public async getAccountId(): Promise<string> {
if (validator.isNonEmptyString(this.serviceAccountId)) {
return Promise.resolve(this.serviceAccountId);
}
const accountId = await utils.findServiceAccountEmail(this.app!)
if (accountId) {
this.serviceAccountId = accountId;
return Promise.resolve(accountId);
}
const request: HttpRequestConfig = {
method: 'GET',
url: 'http://metadata/computeMetadata/v1/instance/service-accounts/default/email',
Expand Down Expand Up @@ -197,7 +204,7 @@ export function cryptoSignerFromApp(app: App): CryptoSigner {
return new ServiceAccountSigner(credential);
}

return new IAMSigner(new AuthorizedHttpClient(app as FirebaseApp), app.options.serviceAccountId);
return new IAMSigner(new AuthorizedHttpClient(app as FirebaseApp), app);
}

/**
Expand Down

0 comments on commit dcda638

Please sign in to comment.