Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | 412x 412x 412x 412x 412x 412x 412x 412x 4x 4x | import { addAzureParams, AZURE_BASE_URL } from '../../../client-side-encryption/providers/azure'; import { MongoAzureError } from '../../../error'; import { get } from '../../../utils'; import type { MongoCredentials } from '../mongo_credentials'; import { type AccessToken, MachineWorkflow } from './machine_workflow'; import { type TokenCache } from './token_cache'; /** Azure request headers. */ const AZURE_HEADERS = Object.freeze({ Metadata: 'true', Accept: 'application/json' }); /** Invalid endpoint result error. */ const ENDPOINT_RESULT_ERROR = 'Azure endpoint did not return a value with only access_token and expires_in properties'; /** Error for when the token audience is missing in the environment. */ const TOKEN_RESOURCE_MISSING_ERROR = 'TOKEN_RESOURCE must be set in the auth mechanism properties when ENVIRONMENT is azure.'; /** * Device workflow implementation for Azure. * * @internal */ export class AzureMachineWorkflow extends MachineWorkflow { /** * Instantiate the machine workflow. */ constructor(cache: TokenCache) { super(cache); } /** * Get the token from the environment. */ async getToken(credentials?: MongoCredentials): Promise<AccessToken> { const tokenAudience = credentials?.mechanismProperties.TOKEN_RESOURCE; const username = credentials?.username; if (!tokenAudience) { throw new MongoAzureError(TOKEN_RESOURCE_MISSING_ERROR); } const response = await getAzureTokenData(tokenAudience, username); if (!isEndpointResultValid(response)) { throw new MongoAzureError(ENDPOINT_RESULT_ERROR); } return response; } } /** * Hit the Azure endpoint to get the token data. */ async function getAzureTokenData(tokenAudience: string, username?: string): Promise<AccessToken> { const url = new URL(AZURE_BASE_URL); addAzureParams(url, tokenAudience, username); const response = await get(url, { headers: AZURE_HEADERS }); if (response.status !== 200) { throw new MongoAzureError( `Status code ${response.status} returned from the Azure endpoint. Response body: ${response.body}` ); } const result = JSON.parse(response.body); return { access_token: result.access_token, expires_in: Number(result.expires_in) }; } /** * Determines if a result returned from the endpoint is valid. * This means the result is not nullish, contains the access_token required field * and the expires_in required field. */ function isEndpointResultValid( token: unknown ): token is { access_token: unknown; expires_in: unknown } { if (token == null || typeof token !== 'object') return false; return ( 'access_token' in token && typeof token.access_token === 'string' && 'expires_in' in token && typeof token.expires_in === 'number' ); } |