Greasy Fork is available in English.

Azure Extensions

This repository contains user scripts for enhancing your Azure Portal experience.

Terá de instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

Terá de instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Terá de instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Terá de instalar uma extensão como Tampermonkey para instalar este script.

Terá de instalar uma extensão de gestão de scripts de utilizador para instalar este script.

(Já tenho um gestor de scripts de utilizador, deixe-me instalá-lo!)

Terá de instalar uma extensão como Stylus para instalar este estilo.

Terá de instalar uma extensão como Stylus para instalar este estilo.

Terá de instalar uma extensão como Stylus para instalar este estilo.

Terá de instalar uma extensão de gestão de estilos de utilizador para instalar este estilo.

Terá de instalar uma extensão de gestão de estilos de utilizador para instalar este estilo.

Terá de instalar uma extensão de gestão de estilos de utilizador para instalar este estilo.

(Já tenho um gestor de estilos de utilizador, deixe-me instalá-lo!)

// ==UserScript==
// @name         Azure Extensions
// @namespace    http://tampermonkey.net/
// @version      2024-09-17
// @description  This repository contains user scripts for enhancing your Azure Portal experience.
// @author       Toni Hoffmann, Dominik Weber
// @match        https://portal.azure.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=azure.com
// @grant        none
// ==/UserScript==

// Initial Author: Dominik Weber
function increaseKeyVaultTextfield() {
  const observer = new MutationObserver(() => {
    const element = document.getElementsByClassName('azc-textarea')[0];
    if (element) {
      element.style.height = '300px';
    }
  });
  observer.observe(document.body, { childList: true });
}

// Initial Author: Toni Hoffmann
function extendAutoExpandNavigationGroupings() {
  const observer = new MutationObserver(() => {
    // Get all groupings
    let groupings = Array.from(document.querySelectorAll('button.azc-listView-collapsible-groupheader'));

    // Filter groupings to only those that contain the relevant SVG child
    let relevantGroupings = groupings.filter((grouping) => {
      let svg = grouping.querySelector('svg');
      return svg && svg.firstChild && svg.firstChild.href.baseVal.includes('#FxSymbol0-034');
    });

    // Print the count of relevant groupings
    console.log(`Found ${relevantGroupings.length} relevant groupings`);

    // Click through each relevant grouping
    relevantGroupings.forEach((grouping) => {
      grouping.click();
    });
  });
  observer.observe(document.body, { childList: true });
}

// Initial Author: Toni Hoffmann
function showSecretsInOverview() {
  const observer = new MutationObserver(() => {
    // check if the page is the keyvault secrets page
    const isKeyVaultPage =
      window.location.href.includes('/providers/Microsoft.KeyVault/vaults/') &&
      window.location.href.endsWith('/secrets');
    if (!isKeyVaultPage) {
      return;
    }
    if (hasButtonAlreadyOnFooter()) {
      return;
    }
    if (!footerHasLoaded()) {
      return; 
    }

    function loadKeyvaultContent(keyvault, secret, callback) {
      const token = JSON.parse(
        sessionStorage.getItem(
          Object.keys(sessionStorage).find((key) => key.includes('https://vault.azure.net/user_impersonation'))
        )
      ).secret;
      var xhr = new XMLHttpRequest();
      xhr.open('GET', `https://${keyvault}.vault.azure.net/secrets/${secret}?api-version=7.0`, true);
      xhr.setRequestHeader('Authorization', `Bearer ${token}`); // Set the token as a Bearer token in the Authorization header
      xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
          const content = JSON.parse(xhr.responseText);
          // console.log(content.value);
          callback(content.value);
        }
      };
      xhr.send();
    }

    function showSecrets() {
      // get current url
      const keyVaultName = window.location.href.split('/vaults/')[1].split('/secrets')[0];

      //  Rename the title
      Array.from(
        Array.from(document.querySelectorAll('table.azc-grid-tableHeader tr'))[0].children
      ).pop().firstChild.innerHTML = 'Secret';

      const secretTableRows = Array.from(document.querySelectorAll('table.azc-grid-full tr'));
      // for of
      for (const row of secretTableRows) {
        const secretName = row.children[0].innerText;
        const lastTD = row.children[row.children.length - 1];
        //  lastTD.innerHTML = secretName;
        loadKeyvaultContent(keyVaultName, secretName, function (secret) {
          lastTD.innerHTML = secret;
        });
      }
    }

    // TODO move this to toolbar, but this caused some issues at the moment
    function addButtonToFooter() {
      const footerBar = document.querySelector('.ext-feedback-positioning');
      // add button
      const button = document.createElement('div');
      button.innerHTML = '<div id="custom-show-secret-button" role="button" style="margin-left: 10px; color: var(--colorLink);">Show Secrets</div>';
      button.onclick = function () {
        showSecrets();
      };
      footerBar.appendChild(button);
    }

    function hasButtonAlreadyOnFooter() {
      return document.querySelector('#custom-show-secret-button');
    }

    function footerHasLoaded(){
      return document.querySelector('.ext-feedback-positioning .azc-formElementContainer').innerText.includes('Give feedback');
    }

    addButtonToFooter();
  });
  observer.observe(document.body, { childList: true });
}

(function () {
  'use strict';
  // Choose wich extensions you want to extend:
  extendAutoExpandNavigationGroupings();
  increaseKeyVaultTextfield();
  showSecretsInOverview();
})();