Files
toolkit/packages/core/src/oidc-utils.ts
T

84 lines
2.4 KiB
TypeScript
Raw Normal View History

2021-08-23 18:49:15 +05:30
/* eslint-disable @typescript-eslint/no-extraneous-class */
2021-08-04 09:24:51 +05:30
import * as actions_http_client from '@actions/http-client'
2021-08-25 16:54:45 -04:00
import {IRequestOptions} from '@actions/http-client/interfaces'
import {HttpClient} from '@actions/http-client'
import {BearerCredentialHandler} from '@actions/http-client/auth'
import {debug, setSecret} from './core'
2021-08-16 12:46:17 +05:30
interface TokenResponse {
2021-08-23 10:49:53 +05:30
value?: string
2021-08-04 09:24:51 +05:30
}
2021-08-16 12:46:17 +05:30
export class OidcClient {
2021-08-23 18:49:15 +05:30
private static createHttpClient(
allowRetry = true,
maxRetry = 10
): actions_http_client.HttpClient {
const requestOptions: IRequestOptions = {
2021-08-17 09:32:42 +05:30
allowRetries: allowRetry,
maxRetries: maxRetry
}
2021-08-23 18:49:15 +05:30
return new HttpClient(
'actions/oidc-client',
2021-08-25 16:47:39 -04:00
[new BearerCredentialHandler(OidcClient.getRequestToken())],
2021-08-23 18:49:15 +05:30
requestOptions
)
2021-08-04 09:24:51 +05:30
}
2021-08-25 16:47:39 -04:00
private static getRequestToken(): string {
const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN']
2021-08-09 06:36:02 +05:30
if (!token) {
2021-08-25 17:02:45 -04:00
throw new Error(
'Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable'
)
2021-08-09 06:36:02 +05:30
}
return token
2021-08-04 09:24:51 +05:30
}
2021-08-23 18:49:15 +05:30
private static getIDTokenUrl(): string {
const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']
2021-08-09 06:36:02 +05:30
if (!runtimeUrl) {
throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable')
}
2021-08-25 16:47:39 -04:00
return runtimeUrl
2021-08-09 06:36:02 +05:30
}
2021-08-04 09:24:51 +05:30
2021-08-25 16:54:45 -04:00
private static async getCall(id_token_url: string): Promise<string> {
2021-08-23 10:49:53 +05:30
const httpclient = OidcClient.createHttpClient()
2021-08-23 18:49:15 +05:30
const res = await httpclient
2021-08-25 16:47:39 -04:00
.getJson<TokenResponse>(id_token_url)
2021-08-23 18:49:15 +05:30
.catch(error => {
throw new Error(
`Failed to get ID Token. \n
2021-08-12 10:07:18 +05:30
Error Code : ${error.statusCode}\n
2021-08-12 16:14:22 +05:30
Error Message: ${error.result.message}`
2021-08-23 18:49:15 +05:30
)
})
2021-08-04 09:24:51 +05:30
2021-08-16 12:46:17 +05:30
const id_token = res.result?.value
2021-08-23 10:49:53 +05:30
if (!id_token) {
2021-08-09 06:36:02 +05:30
throw new Error('Response json body do not have ID Token field')
}
return id_token
}
2021-08-23 18:49:15 +05:30
static async getIDToken(audience?: string): Promise<string> {
2021-08-09 06:36:02 +05:30
try {
// New ID Token is requested from action service
2021-08-25 16:47:39 -04:00
let id_token_url: string = OidcClient.getIDTokenUrl()
if (audience) {
2021-08-25 17:35:01 -04:00
id_token_url = `${id_token_url}&audience=${encodeURIComponent(audience)}`
2021-08-25 16:47:39 -04:00
}
2021-08-09 06:36:02 +05:30
debug(`ID token url is ${id_token_url}`)
2021-08-04 09:24:51 +05:30
2021-08-25 16:47:39 -04:00
const id_token = await OidcClient.getCall(id_token_url)
2021-08-12 10:07:18 +05:30
setSecret(id_token)
2021-08-09 06:36:02 +05:30
return id_token
} catch (error) {
throw new Error(`Error message: ${error.message}`)
}
2021-08-04 09:24:51 +05:30
}
2021-08-23 18:49:15 +05:30
}