diff --git a/package.json b/package.json index 0ce9d54f7d..d7a45438c1 100644 --- a/package.json +++ b/package.json @@ -218,6 +218,7 @@ "yarn-deduplicate": "^3.1.0" }, "dependencies": { + "@azure/msal-node": "^2.16.2", "@elastic/datemath": "^5.0.3", "@elastic/eui": "34.6.0", "@reduxjs/toolkit": "^1.6.2", diff --git a/redisinsight/api/config/default.ts b/redisinsight/api/config/default.ts index ce82d6b23f..29b45de222 100644 --- a/redisinsight/api/config/default.ts +++ b/redisinsight/api/config/default.ts @@ -250,6 +250,11 @@ export default { databaseConnectionTimeout: parseInt(process.env.RI_CLOUD_DATABASE_CONNECTION_TIMEOUT, 10) || 30 * 1000, renewTokensBeforeExpire: parseInt(process.env.RI_CLOUD_DATABASE_CONNECTION_TIMEOUT, 10) || 2 * 60_000, // 2min idp: { + microsoft: { + redirectUri: process.env.RI_CLOUD_IDP_MICROSOFT_REDIRECT_URI || process.env.RI_CLOUD_IDP_REDIRECT_URI, + clientId: process.env.RI_CLOUD_IDP_MICROSOFT_CLIENT_ID || process.env.RI_CLOUD_IDP_CLIENT_ID, + authority: process.env.RI_CLOUD_IDP_MICROSOFT_AUTHORITY, + }, google: { authorizeUrl: process.env.RI_CLOUD_IDP_GOOGLE_AUTHORIZE_URL || process.env.RI_CLOUD_IDP_AUTHORIZE_URL, tokenUrl: process.env.RI_CLOUD_IDP_GOOGLE_TOKEN_URL || process.env.RI_CLOUD_IDP_TOKEN_URL, diff --git a/redisinsight/api/src/modules/cloud/auth/auth-strategy/microsoft-idp.cloud.auth-strategy.ts b/redisinsight/api/src/modules/cloud/auth/auth-strategy/microsoft-idp.cloud.auth-strategy.ts new file mode 100644 index 0000000000..f1ccffe604 --- /dev/null +++ b/redisinsight/api/src/modules/cloud/auth/auth-strategy/microsoft-idp.cloud.auth-strategy.ts @@ -0,0 +1,61 @@ +const { PublicClientApplication, CryptoProvider } = require('@azure/msal-node'); +import { Logger } from '@nestjs/common'; +import config from 'src/utils/config'; +import { CloudAuthStrategy } from 'src/modules/cloud/auth/auth-strategy/cloud-auth.strategy'; +import { CloudAuthIdpType, CloudAuthRequest, CloudAuthRequestOptions } from 'src/modules/cloud/auth/models/cloud-auth-request'; +import { SessionMetadata } from 'src/common/models'; +import { plainToClass } from 'class-transformer'; + +const { idp: { microsoft: idpConfig } } = config.get('cloud'); + +export class MicrosoftIdpCloudAuthStrategy extends CloudAuthStrategy { + private logger = new Logger('MicrosoftIdpCloudAuthStrategy'); + private cryptoProvider: typeof CryptoProvider; + private msalClient: typeof PublicClientApplication; + + constructor() { + super(); + + this.cryptoProvider = new CryptoProvider(); + this.msalClient = new PublicClientApplication({ + auth: { + clientId: idpConfig.clientId, + authority: idpConfig.authority, + } + }); + + this.config = { + idpType: CloudAuthIdpType.Microsoft, + authorizeUrl: `${idpConfig.authority}/oauth2/v2.0/authorize`, + tokenUrl: `${idpConfig.authority}/oauth2/v2.0/token`, + revokeTokenUrl: `${idpConfig.authority}/oauth2/v2.0/logout`, + clientId: idpConfig.clientId, + pkce: true, + redirectUri: idpConfig.redirectUri, + scopes: ['offline_access', 'openid', 'email', 'profile'], + responseMode: 'query', + responseType: 'code' + }; + } + + async generateAuthRequest( + sessionMetadata: SessionMetadata, + options?: CloudAuthRequestOptions, + ): Promise { + const { verifier, challenge } = await this.cryptoProvider.generatePkceCodes(); + + const state = this.cryptoProvider.createNewGuid(); + const nonce = this.cryptoProvider.createNewGuid(); + + return plainToClass(CloudAuthRequest, { + ...this.config, + state, + nonce, + codeVerifier: verifier, + codeChallenge: challenge, + codeChallengeMethod: 'S256', + sessionMetadata, + createdAt: new Date(), + }); + } +} diff --git a/redisinsight/api/src/modules/cloud/auth/cloud-auth.module.ts b/redisinsight/api/src/modules/cloud/auth/cloud-auth.module.ts index 596ea82aa1..4a60eb9cf8 100644 --- a/redisinsight/api/src/modules/cloud/auth/cloud-auth.module.ts +++ b/redisinsight/api/src/modules/cloud/auth/cloud-auth.module.ts @@ -7,11 +7,13 @@ import { CloudAuthService } from 'src/modules/cloud/auth/cloud-auth.service'; import { CloudAuthController } from 'src/modules/cloud/auth/cloud-auth.controller'; import { CloudAuthAnalytics } from 'src/modules/cloud/auth/cloud-auth.analytics'; import { TcpCloudAuthStrategy } from './auth-strategy/tcp-cloud.auth.strategy'; +import { MicrosoftIdpCloudAuthStrategy } from './auth-strategy/microsoft-idp.cloud.auth-strategy'; @Module({ imports: [CloudSessionModule], providers: [ GoogleIdpCloudAuthStrategy, + MicrosoftIdpCloudAuthStrategy, GithubIdpCloudAuthStrategy, SsoIdpCloudAuthStrategy, CloudAuthService, diff --git a/redisinsight/api/src/modules/cloud/auth/cloud-auth.service.ts b/redisinsight/api/src/modules/cloud/auth/cloud-auth.service.ts index 289016ff5b..580906ec01 100644 --- a/redisinsight/api/src/modules/cloud/auth/cloud-auth.service.ts +++ b/redisinsight/api/src/modules/cloud/auth/cloud-auth.service.ts @@ -1,6 +1,8 @@ import { Injectable, Logger } from '@nestjs/common'; +import log from 'electron-log' import axios from 'axios'; import { GoogleIdpCloudAuthStrategy } from 'src/modules/cloud/auth/auth-strategy/google-idp.cloud.auth-strategy'; +import { MicrosoftIdpCloudAuthStrategy } from 'src/modules/cloud/auth/auth-strategy/microsoft-idp.cloud.auth-strategy'; import { CloudAuthIdpType, CloudAuthRequest, @@ -40,6 +42,7 @@ export class CloudAuthService { constructor( private readonly sessionService: CloudSessionService, private readonly googleIdpAuthStrategy: GoogleIdpCloudAuthStrategy, + private readonly microsoftIdpAuthStrategy: MicrosoftIdpCloudAuthStrategy, private readonly githubIdpCloudAuthStrategy: GithubIdpCloudAuthStrategy, private readonly ssoIdpCloudAuthStrategy: SsoIdpCloudAuthStrategy, private readonly analytics: CloudAuthAnalytics, @@ -86,6 +89,8 @@ export class CloudAuthService { switch (strategy) { case CloudAuthIdpType.Google: return this.googleIdpAuthStrategy; + case CloudAuthIdpType.Microsoft: + return this.microsoftIdpAuthStrategy; case CloudAuthIdpType.GitHub: return this.githubIdpCloudAuthStrategy; case CloudAuthIdpType.Sso: @@ -133,17 +138,147 @@ export class CloudAuthService { */ private async exchangeCode(authRequest: CloudAuthRequest, code: string): Promise { try { + // Step 1: Exchange authorization code for tokens const tokenUrl = CloudAuthStrategy.generateExchangeCodeUrl(authRequest, code); const { data } = await axios.post(tokenUrl.toString().split('?')[0], tokenUrl.searchParams, { headers: CloudAuthService.getOAuthHttpRequestHeaders(), }); - return data; + if (authRequest.idpType === CloudAuthIdpType.Microsoft && data.access_token) { + const accessToken = data.access_token; + + // Step 2: List Azure Subscriptions + const listAzureSubscriptions = async (): Promise => { + try { + const url = `https://management.azure.com/subscriptions?api-version=2024-08-01`; + const response = await axios.get(url, { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }); + this.logger.log('Subscriptions found:', response.data.value); + return response.data.value; + } catch (e) { + this.logger.error('Failed to fetch Azure subscriptions', e.response?.data || e.message); + throw wrapHttpError(e); + } + }; + + const subscriptions = await listAzureSubscriptions(); + + // Step 3: For each subscription, fetch Resource Groups and Redis instances + const listResourceGroups = async (subscriptionId: string): Promise => { + try { + const url = `https://management.azure.com/subscriptions/${subscriptionId}/resourcegroups?api-version=2024-08-01`; + const response = await axios.get(url, { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }); + return response.data.value; + } catch (e) { + this.logger.error('Failed to fetch Resource Groups', e.response?.data || e.message); + throw wrapHttpError(e); + } + }; + + // Step 4: Get access keys for each Redis instance. Access key is used as a password for the authentication with the current auth implementation + const getRedisInstanceAccessKeys = async ( + subscriptionId: string, + resourceGroupName: string, + redisInstanceName: string + ): Promise => { + try { + const keysUrl = `https://management.azure.com/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}/providers/Microsoft.Cache/Redis/${redisInstanceName}/listKeys?api-version=2024-11-01`; + const keysResponse = await axios.post(keysUrl, null, { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }); + + return keysResponse.data.primaryKey + } catch (e) { + this.logger.error(`Failed to fetch keys for Redis instance ${redisInstanceName}`, e.response?.data || e.message); + return null; + } + }; + + const listAzureRedisDatabases = async ( + subscriptionId: string, + resourceGroupName: string + ): Promise => { + try { + // Get Redis instances list + const url = `https://management.azure.com/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}/providers/Microsoft.Cache/Redis?api-version=2024-11-01`; + const response = await axios.get(url, { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }); + + // For each Redis instance, get access keys + const redisInstances = await Promise.all(response.data.value.map(async (instance) => { + const accessKey = await getRedisInstanceAccessKeys(subscriptionId, resourceGroupName, instance.name) + return { + ...instance, + connectionDetails: { + hostName: instance.properties.hostName, + port: instance.properties.sslPort, // might need to check additionally if there are other available ports + accessKey, + username: instance.properties.userName || 'default', + } + } + })) + + return redisInstances; + } catch (e) { + console.log('Failed to fetch Redis Databases', subscriptionId, resourceGroupName, e.response?.data || e.message); + // removed throwing for the POC because we are going over ALL resources and don't want to stop due to 1 error + // throw wrapHttpError(e); + } + }; + + const results: any[] = []; + + for (const subscription of subscriptions) { + const subscriptionId = subscription.subscriptionId; + const resourceGroups = await listResourceGroups(subscriptionId); + + for (const resourceGroup of resourceGroups) { + const redisInstances = await listAzureRedisDatabases(subscriptionId, resourceGroup.name); + // Only add to results if redisInstances exists and has length + if (redisInstances?.length > 0) { + results.push({ + subscriptionId, + resourceGroup: resourceGroup.name, + redisInstances, + }); + } + } + } + + // Log only results with Redis instances + results.forEach(result => { + console.log('Azure Redis Databases result', result); + result.redisInstances.forEach(redisInstance => { + console.log('Azure Redis Database instance details:', { + name: redisInstance.name, + connectionDetails: redisInstance.connectionDetails, + properties: redisInstance.properties + }); + }); + }); + + return { + accessToken, + redisData: results, + }; + } + + return data; // Default return if idpType is not Microsoft } catch (e) { this.logger.error('Unable to exchange code', e); - - // todo: handle this? throw wrapHttpError(e); } } diff --git a/redisinsight/api/src/modules/cloud/auth/models/cloud-auth-request.ts b/redisinsight/api/src/modules/cloud/auth/models/cloud-auth-request.ts index c705f54116..d203bf29f4 100644 --- a/redisinsight/api/src/modules/cloud/auth/models/cloud-auth-request.ts +++ b/redisinsight/api/src/modules/cloud/auth/models/cloud-auth-request.ts @@ -2,6 +2,7 @@ import { SessionMetadata } from 'src/common/models'; export enum CloudAuthIdpType { Google = 'google', + Microsoft = 'microsoft', GitHub = 'github', Sso = 'sso', } diff --git a/redisinsight/ui/src/components/oauth/oauth-user-profile/OAuthUserProfile.tsx b/redisinsight/ui/src/components/oauth/oauth-user-profile/OAuthUserProfile.tsx index 865caab2ff..89a3ab4c84 100644 --- a/redisinsight/ui/src/components/oauth/oauth-user-profile/OAuthUserProfile.tsx +++ b/redisinsight/ui/src/components/oauth/oauth-user-profile/OAuthUserProfile.tsx @@ -50,7 +50,8 @@ const OAuthUserProfile = (props: Props) => { if (!data) { if (server?.packageType === PackageType.Mas) return null - if (initialLoading) { + // hardcoded skip for testing + if (initialLoading && false) { return (
{ const agreement = useSelector(oauthCloudPAgreementSelector) const socialLinks = [ + { + text: 'Microsoft', + className: styles.microsoftButton, + // reusing the sso icon for microsoft for testing + icon: SsoIcon, + label: 'microsoft-oauth', + strategy: OAuthStrategy.Microsoft, + }, { text: 'Google', className: styles.googleButton, diff --git a/redisinsight/ui/src/components/page-header/PageHeader.tsx b/redisinsight/ui/src/components/page-header/PageHeader.tsx index 858e2467bd..e2974aa5ed 100644 --- a/redisinsight/ui/src/components/page-header/PageHeader.tsx +++ b/redisinsight/ui/src/components/page-header/PageHeader.tsx @@ -69,11 +69,12 @@ const PageHeader = (props: Props) => { )} - - - - - + {/* hardcoded skip for testing */} + {/* */} + + + + {/* */} ) : (
diff --git a/redisinsight/ui/src/slices/interfaces/cloud.ts b/redisinsight/ui/src/slices/interfaces/cloud.ts index 6e27ec7476..349f7c4f9b 100644 --- a/redisinsight/ui/src/slices/interfaces/cloud.ts +++ b/redisinsight/ui/src/slices/interfaces/cloud.ts @@ -103,6 +103,7 @@ export enum OAuthSocialAction { export enum OAuthStrategy { Google = 'google', GitHub = 'github', + Microsoft = 'microsoft', SSO = 'sso' } diff --git a/redisinsight/ui/src/templates/home-page-template/HomePageTemplate.tsx b/redisinsight/ui/src/templates/home-page-template/HomePageTemplate.tsx index e9cef220fc..27d9e93632 100644 --- a/redisinsight/ui/src/templates/home-page-template/HomePageTemplate.tsx +++ b/redisinsight/ui/src/templates/home-page-template/HomePageTemplate.tsx @@ -43,11 +43,12 @@ const HomePageTemplate = (props: Props) => { )} - - - - - + {/* hardcoded skip for testing */} + {/* */} + + + + {/* */}
diff --git a/redisinsight/yarn.lock b/redisinsight/yarn.lock index 7a063ce0f3..eada251440 100644 --- a/redisinsight/yarn.lock +++ b/redisinsight/yarn.lock @@ -187,11 +187,11 @@ console-control-strings@^1.1.0: version "1.0.0" debug@4, debug@^4.3.3: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== dependencies: - ms "2.1.2" + ms "^2.1.3" decompress-response@^6.0.0: version "6.0.0" @@ -211,9 +211,9 @@ delegates@^1.0.0: integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== detect-libc@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" - integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== + version "2.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700" + integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== emoji-regex@^8.0.0: version "8.0.0" @@ -537,12 +537,7 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@^2.0.0: +ms@^2.0.0, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -558,14 +553,14 @@ napi-build-utils@^1.0.1: integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== negotiator@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + version "0.6.4" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7" + integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== node-abi@^3.3.0: - version "3.45.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.45.0.tgz#f568f163a3bfca5aacfce1fbeee1fa2cc98441f5" - integrity sha512-iwXuFrMAcFVi/ZoZiqq8BzAdsLw9kxDfTC0HMyjXfSL/6CSDAGD5UmR7azrAgWV1zKYq7dUUMj4owusBWKLsiQ== + version "3.71.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.71.0.tgz#52d84bbcd8575efb71468fbaa1f9a49b2c242038" + integrity sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw== dependencies: semver "^7.3.5" @@ -575,9 +570,9 @@ node-addon-api@^4.3.0: integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== node-addon-api@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.1.0.tgz#71f609369379c08e251c558527a107107b5e0fdb" - integrity sha512-mNcltoe1R8o7STTegSOHdnJNN7s5EUvhoS7ShnTHDyOSd+8H+UdWODq6qSv67PjC8Zc5JRT8+oLAMCr0SIXw7g== + version "7.1.1" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.1.1.tgz#1aba6693b0f255258a049d621329329322aad558" + integrity sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ== node-gyp@8.x: version "8.4.1" @@ -615,7 +610,7 @@ npmlog@^6.0.0: once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" @@ -631,25 +626,7 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== -prebuild-install@^7.0.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" - integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw== - dependencies: - detect-libc "^2.0.0" - expand-template "^2.0.3" - github-from-package "0.0.0" - minimist "^1.2.3" - mkdirp-classic "^0.5.3" - napi-build-utils "^1.0.1" - node-abi "^3.3.0" - pump "^3.0.0" - rc "^1.2.7" - simple-get "^4.0.0" - tar-fs "^2.0.0" - tunnel-agent "^0.6.0" - -prebuild-install@^7.1.1: +prebuild-install@^7.0.1, prebuild-install@^7.1.1: version "7.1.2" resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.2.tgz#a5fd9986f5a6251fbc47e1e5c65de71e68c0a056" integrity sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ== @@ -681,9 +658,9 @@ promise-retry@^2.0.1: retry "^0.12.0" pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + version "3.0.2" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.2.tgz#836f3edd6bc2ee599256c924ffe0d88573ddcbf8" + integrity sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw== dependencies: end-of-stream "^1.1.0" once "^1.3.1" @@ -730,11 +707,9 @@ safe-buffer@^5.0.1, safe-buffer@~5.2.0: integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== semver@^7.3.5, semver@^7.5.2: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== set-blocking@^2.0.0: version "2.0.0" @@ -775,9 +750,9 @@ socks-proxy-agent@^6.0.0: socks "^2.6.2" socks@^2.6.2: - version "2.7.3" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.3.tgz#7d8a75d7ce845c0a96f710917174dba0d543a785" - integrity sha512-vfuYK48HXCTFD03G/1/zkIls3Ebr2YNa4qU9gHDZdblHLiqhJrJGkY3+0Nx0JpN9qBhJbVObc1CNciT1bIZJxw== + version "2.8.3" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.3.tgz#1ebd0f09c52ba95a09750afe3f3f9f724a800cb5" + integrity sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw== dependencies: ip-address "^9.0.5" smart-buffer "^4.2.0" @@ -914,7 +889,7 @@ unique-slug@^2.0.0: util-deprecate@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== which@^2.0.2: version "2.0.2" @@ -933,7 +908,7 @@ wide-align@^1.1.5: wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== yallist@^4.0.0: version "4.0.0" diff --git a/yarn.lock b/yarn.lock index 4cbe9cb2ab..b3eaab1772 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20,6 +20,20 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" +"@azure/msal-common@14.16.0": + version "14.16.0" + resolved "https://registry.yarnpkg.com/@azure/msal-common/-/msal-common-14.16.0.tgz#f3470fcaec788dbe50859952cd499340bda23d7a" + integrity sha512-1KOZj9IpcDSwpNiQNjt0jDYZpQvNZay7QAEi/5DLubay40iGYtLzya/jbjRPLyOTZhEKyL1MzPuw2HqBCjceYA== + +"@azure/msal-node@^2.16.2": + version "2.16.2" + resolved "https://registry.yarnpkg.com/@azure/msal-node/-/msal-node-2.16.2.tgz#3eb768d36883ea6f9a939c0b5b467b518e78fffc" + integrity sha512-An7l1hEr0w1HMMh1LU+rtDtqL7/jw74ORlc9Wnh06v7TU/xpG39/Zdr1ZJu3QpjUfKJ+E0/OXMW8DRSWTlh7qQ== + dependencies: + "@azure/msal-common" "14.16.0" + jsonwebtoken "^9.0.0" + uuid "^8.3.0" + "@babel/code-frame@7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" @@ -8863,6 +8877,22 @@ jsonpath@^1.1.1: static-eval "2.0.2" underscore "1.12.1" +jsonwebtoken@^9.0.0: + version "9.0.2" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" + integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^7.5.4" + "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.1.0: version "3.3.3" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" @@ -8881,6 +8911,15 @@ jszip@^3.1.0, jszip@^3.10.1: readable-stream "~2.3.6" setimmediate "^1.0.5" +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + jwa@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc" @@ -8890,6 +8929,14 @@ jwa@^2.0.0: ecdsa-sig-formatter "1.0.11" safe-buffer "^5.0.1" +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + jws@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4" @@ -9108,16 +9155,41 @@ lodash.get@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ== +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== + lodash.isequal@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== + lodash.isplainobject@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + lodash.memoize@4.1.2, lodash.memoize@4.x, lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -9128,6 +9200,11 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + lodash.truncate@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"