1- import { ResponseError } from '../../utils '
1+ import type { ProxyInvalidRequest } from '../default '
22
3- export async function authToken ( credentials : string , kv : KVNamespace , subFetch : typeof fetch ) : Promise < string > {
3+ export async function authToken (
4+ credentials : string ,
5+ kv : KVNamespace ,
6+ subFetch : typeof fetch ,
7+ ) : Promise < { token : string } | ProxyInvalidRequest > {
48 const serviceAccountHash = await hash ( credentials )
59 const cacheKey = `gcp-auth:${ serviceAccountHash } `
610 const cachedToken = await kv . get ( cacheKey , { cacheTtl : 300 } )
711 if ( cachedToken ) {
8- return cachedToken
12+ return { token : cachedToken }
913 }
10- const serviceAccount = getServiceAccount ( credentials )
11- const jwt = await jwtSign ( serviceAccount )
12- const token = await getAccessToken ( jwt , subFetch )
13- await kv . put ( cacheKey , token , { expirationTtl : 3000 } )
14- return token
14+ const serviceAccountResult = getServiceAccount ( credentials )
15+ if ( 'error' in serviceAccountResult ) {
16+ return serviceAccountResult
17+ }
18+ const jwt = await jwtSign ( serviceAccountResult )
19+ const tokenResult = await getAccessToken ( jwt , subFetch )
20+ if ( 'error' in tokenResult ) {
21+ return tokenResult
22+ }
23+ await kv . put ( cacheKey , tokenResult . token , { expirationTtl : 3000 } )
24+ return tokenResult
1525}
1626
17- function getServiceAccount ( credentials : string ) : ServiceAccount {
27+ export function getServiceAccount ( credentials : string ) : ServiceAccount | ProxyInvalidRequest {
1828 let sa : ServiceAccount
1929 try {
2030 sa = JSON . parse ( credentials )
2131 } catch ( error ) {
22- throw new ResponseError ( 400 , `provider credentials are not valid JSON: ${ error as Error } ` )
32+ return { error : `provider credentials are not valid JSON: ${ error as Error } ` }
2333 }
2434 if ( typeof sa . client_email !== 'string' ) {
25- throw new ResponseError ( 400 , `"client_email" should be a string, not ${ typeof sa . client_email } ` )
35+ return { error : `"client_email" should be a string, not ${ typeof sa . client_email } ` }
2636 }
2737 if ( typeof sa . private_key !== 'string' ) {
28- throw new ResponseError ( 400 , `"private_key" should be a string, not ${ typeof sa . private_key } ` )
38+ return { error : `"private_key" should be a string, not ${ typeof sa . private_key } ` }
2939 }
3040 if ( typeof sa . project_id !== 'string' ) {
31- throw new ResponseError ( 400 , `"project_id" should be a string, not ${ typeof sa . project_id } ` )
41+ return { error : `"project_id" should be a string, not ${ typeof sa . project_id } ` }
3242 }
3343 return { client_email : sa . client_email , private_key : sa . private_key , project_id : sa . project_id }
3444}
3545
36- export function getProjectId ( credentials : string ) : string {
37- const sa = getServiceAccount ( credentials )
38- return sa . project_id
39- }
40-
4146interface ServiceAccount {
4247 client_email : string
4348 private_key : string
@@ -80,7 +85,7 @@ async function jwtSign(serviceAccount: ServiceAccount): Promise<string> {
8085 return `${ signingInput } .${ b64UrlEncodeArray ( signature ) } `
8186}
8287
83- async function getAccessToken ( jwt : string , subFetch : typeof fetch ) : Promise < string > {
88+ async function getAccessToken ( jwt : string , subFetch : typeof fetch ) : Promise < { token : string } | ProxyInvalidRequest > {
8489 const body = new URLSearchParams ( { grant_type : 'urn:ietf:params:oauth:grant-type:jwt-bearer' , assertion : jwt } )
8590
8691 const response = await subFetch ( tokenUrl , {
@@ -92,10 +97,10 @@ async function getAccessToken(jwt: string, subFetch: typeof fetch): Promise<stri
9297
9398 if ( response . ok ) {
9499 const responseData : TokenResponse = await response . json ( )
95- return responseData . access_token
100+ return { token : responseData . access_token }
96101 } else {
97102 const text = await response . text ( )
98- throw new ResponseError ( 400 , `Failed to get GCP access token, response:\n${ response . status } : ${ text } ` )
103+ return { error : `Failed to get GCP access token, response:\n${ response . status } : ${ text } ` }
99104 }
100105}
101106
0 commit comments