Skip to content

Feature Request: Official support for integration with firebase-admin and google-auth-library ExternalAccountClient. #1322

Closed
@LumaKernel

Description

@LumaKernel

Is your feature request related to a problem? Please describe.
firebase-admin requires credential in STS response format, but it is not exposed:

https://github.com/LumaKernel/google-auth-library-nodejs/blob/21a91c2c6e5317e6f6e2e8709bca2953999f98d4/src/auth/baseexternalclient.ts#L432-L432

We can calculate STS response from cachedAccessToken that is calculated from above, but it is private field.

Describe the solution you'd like
Exposing cached STS response, and optionally, exposing cachedAccessToken.

Describe alternatives you've considered
Only storing cached STS response and make cachedAccessToken getter.

Additional context

Workaround:

import admin from 'firebase-admin'
import type { GoogleOAuthAccessToken } from 'firebase-admin/app'
import type { FooAccountClient, Credentials as GoogleAPICredentials } from 'google-auth-library'

// Converting to original STS response format.
const convertToFirebaseCredential = (gapiCred: GoogleAPICredentials): GoogleOAuthAccessToken => {
  const { access_token, expiry_date } = gapiCred
  if (typeof access_token !== 'string')
    throw new Error('Google auth credential without access_token is incompatible')
  if (typeof expiry_date !== 'number')
    throw new Error('Google auth credential without expiry_date is incompatible')
  return {
    access_token,
    // inverse opertation of following
    // https://github.com/googleapis/google-auth-library-nodejs/blob/5ed910513451c82e2551777a3e2212964799ef8e/src/auth/baseexternalclient.ts#L446-L446
    expires_in: Math.floor((expiry_date - new Date().getTime()) / 1000),
  }
}

// Usage example
const createApp = async () => {
  const client = new FooAccountClient({ /* ... */ });
  const credential = {
    getAccessToken: async () => {
      await client.getAccessToken()
      // cachedAccessToken is private
      const gapiCred: GoogleAPICredentials = (client as any).cachedAccessToken
      return convertToFirebaseCredential(gapiCred)
    },
  };
  admin.initializeApp({
    // ...
    credential,
  });
}

It is real working workaround in our project.

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: feature request‘Nice-to-have’ improvement, new feature or different behavior or design.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions