public async getAccountSecurityToken()

in lib/ads-adal-library/src/engine/AzureAuth.ts [102:166]


	public async getAccountSecurityToken(account: AzureAccount, tenantId: string, azureResource: AADResource): Promise<Token | undefined> {
		if (account.isStale === true) {
			this.logger.log('Account was stale. No tokens being fetched.');
			return undefined;
		}
		const tenant = account.properties.tenants.find(t => t.id === tenantId);

		if (!tenant) {
			throw new AzureAuthError(ErrorCodes.Tenant, this.errorLookup.getTenantNotFoundError({ tenantId }), undefined);
		}

		const cachedTokens = await this.getSavedToken(tenant, azureResource, account.key);

		// Let's check to see if we can just use the cached tokens to return to the user
		if (cachedTokens?.accessToken) {
			let expiry = Number(cachedTokens.expiresOn);
			if (Number.isNaN(expiry)) {
				this.logger.log('Expiration time was not defined. This is expected on first launch');
				expiry = 0;
			}
			const currentTime = new Date().getTime() / 1000;

			let accessToken = cachedTokens.accessToken;
			let expiresOn = Number(cachedTokens.expiresOn);
			const remainingTime = expiry - currentTime;
			const maxTolerance = 2 * 60; // two minutes

			if (remainingTime < maxTolerance) {
				const result = await this.refreshToken(tenant, azureResource, cachedTokens.refreshToken);
				if (!result) {
					return undefined;
				}
				accessToken = result.accessToken;
				expiresOn = Number(result.expiresOn);
			}
			// Let's just return here.
			if (accessToken) {
				return {
					...accessToken,
					expiresOn: expiresOn,
					tokenType: 'Bearer'
				};
			}
		}

		// User didn't have any cached tokens, or the cached tokens weren't useful.
		// For most users we can use the refresh token from the general microsoft resource to an access token of basically any type of resource we want.
		const baseTokens = await this.getSavedToken(this.commonTenant, this.providerSettings.resources.windowsManagementResource, account.key);
		if (!baseTokens) {
			this.logger.error('User had no base tokens for the basic resource registered. This should not happen and indicates something went wrong with the authentication cycle');
			account.isStale = true;
			// Something failed with the authentication, or your tokens have been deleted from the system. Please try adding your account to Azure Data Studio again
			throw new AzureAuthError(ErrorCodes.AuthError, this.errorLookup.getSimpleError(ErrorCodes.AuthError));
		}
		// Let's try to convert the access token type, worst case we'll have to prompt the user to do an interactive authentication.
		const result = await this.refreshToken(tenant, azureResource, baseTokens.refreshToken);
		if (result?.accessToken) {
			return {
				...result.accessToken,
				expiresOn: Number(result.expiresOn),
				tokenType: 'Bearer'
			};
		}
		return undefined;
	}