Skip to content

Commit 070e0cc

Browse files
authored
Integrate VertexAI with Auth (#8216)
1 parent 964bd26 commit 070e0cc

File tree

7 files changed

+63
-1
lines changed

7 files changed

+63
-1
lines changed

packages/vertexai/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ function registerVertex(): void {
4040
(container, { instanceIdentifier: location }) => {
4141
// getImmediate for FirebaseApp will always succeed
4242
const app = container.getProvider('app').getImmediate();
43+
const auth = container.getProvider('auth-internal');
4344
const appCheckProvider = container.getProvider('app-check-internal');
44-
return new VertexAIService(app, appCheckProvider, { location });
45+
return new VertexAIService(app, auth, appCheckProvider, { location });
4546
},
4647
ComponentType.PUBLIC
4748
).setMultipleInstances(true)

packages/vertexai/src/models/generative-model.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ export class GenerativeModel {
7979
this._apiSettings.getAppCheckToken = () =>
8080
(vertexAI as VertexAIService).appCheck!.getToken();
8181
}
82+
83+
if ((vertexAI as VertexAIService).auth) {
84+
this._apiSettings.getAuthToken = () =>
85+
(vertexAI as VertexAIService).auth!.getToken();
86+
}
8287
}
8388
if (modelParams.model.includes('/')) {
8489
if (modelParams.model.startsWith('models/')) {

packages/vertexai/src/requests/request.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ describe('request methods', () => {
101101
apiKey: 'key',
102102
project: 'myproject',
103103
location: 'moon',
104+
getAuthToken: () => Promise.resolve({ accessToken: 'authtoken' }),
104105
getAppCheckToken: () => Promise.resolve({ token: 'appchecktoken' })
105106
};
106107
const fakeUrl = new RequestUrl(
@@ -173,6 +174,42 @@ describe('request methods', () => {
173174
const headers = await getHeaders(fakeUrl);
174175
expect(headers.has('X-Firebase-AppCheck')).to.be.false;
175176
});
177+
it('adds auth token if it exists', async () => {
178+
const headers = await getHeaders(fakeUrl);
179+
expect(headers.get('Authorization')).to.equal('Firebase authtoken');
180+
});
181+
it('ignores auth token header if no auth service', async () => {
182+
const fakeUrl = new RequestUrl(
183+
'models/model-name',
184+
Task.GENERATE_CONTENT,
185+
{
186+
apiKey: 'key',
187+
project: 'myproject',
188+
location: 'moon'
189+
},
190+
true,
191+
{}
192+
);
193+
const headers = await getHeaders(fakeUrl);
194+
expect(headers.has('Authorization')).to.be.false;
195+
});
196+
it('ignores auth token header if returned token was undefined', async () => {
197+
const fakeUrl = new RequestUrl(
198+
'models/model-name',
199+
Task.GENERATE_CONTENT,
200+
{
201+
apiKey: 'key',
202+
project: 'myproject',
203+
location: 'moon',
204+
//@ts-ignore
205+
getAppCheckToken: () => Promise.resolve()
206+
},
207+
true,
208+
{}
209+
);
210+
const headers = await getHeaders(fakeUrl);
211+
expect(headers.has('Authorization')).to.be.false;
212+
});
176213
});
177214
describe('makeRequest', () => {
178215
it('no error', async () => {

packages/vertexai/src/requests/request.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,14 @@ export async function getHeaders(url: RequestUrl): Promise<Headers> {
8787
headers.append('X-Firebase-AppCheck', appCheckToken.token);
8888
}
8989
}
90+
91+
if (url.apiSettings.getAuthToken) {
92+
const authToken = await url.apiSettings.getAuthToken();
93+
if (authToken) {
94+
headers.append('Authorization', `Firebase ${authToken.accessToken}`);
95+
}
96+
}
97+
9098
return headers;
9199
}
92100

packages/vertexai/src/service.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ describe('VertexAIService', () => {
3535
it('uses custom location if specified', () => {
3636
const vertexAI = new VertexAIService(
3737
fakeApp,
38+
/* authProvider */ undefined,
3839
/* appCheckProvider */ undefined,
3940
{ location: 'somewhere' }
4041
);

packages/vertexai/src/service.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,26 @@ import {
2222
FirebaseAppCheckInternal
2323
} from '@firebase/app-check-interop-types';
2424
import { Provider } from '@firebase/component';
25+
import {
26+
FirebaseAuthInternal,
27+
FirebaseAuthInternalName
28+
} from '@firebase/auth-interop-types';
2529
import { DEFAULT_LOCATION } from './constants';
2630

2731
export class VertexAIService implements VertexAI, _FirebaseService {
32+
auth: FirebaseAuthInternal | null;
2833
appCheck: FirebaseAppCheckInternal | null;
2934
location: string;
3035

3136
constructor(
3237
public app: FirebaseApp,
38+
authProvider?: Provider<FirebaseAuthInternalName>,
3339
appCheckProvider?: Provider<AppCheckInternalComponentName>,
3440
public options?: VertexAIOptions
3541
) {
3642
const appCheck = appCheckProvider?.getImmediate({ optional: true });
43+
const auth = authProvider?.getImmediate({ optional: true });
44+
this.auth = auth || null;
3745
this.appCheck = appCheck || null;
3846
this.location = this.options?.location || DEFAULT_LOCATION;
3947
}

packages/vertexai/src/types/internal.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@
1616
*/
1717

1818
import { AppCheckTokenResult } from '@firebase/app-check-interop-types';
19+
import { FirebaseAuthTokenData } from '@firebase/auth-interop-types';
1920

2021
export interface ApiSettings {
2122
apiKey: string;
2223
project: string;
2324
location: string;
25+
getAuthToken?: () => Promise<FirebaseAuthTokenData | null>;
2426
getAppCheckToken?: () => Promise<AppCheckTokenResult>;
2527
}

0 commit comments

Comments
 (0)