DEV Community

Kentaro Inomata
Kentaro Inomata

Posted on

msal-browser plugin for Vue 3 Composition API and TypeScript

Just check it out.

src/plugins/msal.ts

import { ref, computed, ComputedRef, inject } from "vue";
import { type Plugin, type Ref } from 'vue';

import {
  Configuration,
  PublicClientApplication,
  LogLevel,
  AuthenticationResult,
} from "@azure/msal-browser";

export type Msal = {
  isAuthenticated: ComputedRef<boolean>,
  result: Ref<AuthenticationResult | null>,
  login: () => Promise<void>,
  logout: () => Promise<void>,
};

export const createMsal = async () => {
  const config: Configuration = {
    auth: {
      clientId: import.meta.env.VITE_AUTH_CLIENTID,
      authority: import.meta.env.VITE_AUTH_AUTHORITY,
      knownAuthorities: [import.meta.env.VITE_AUTH_TENANT_DOMAIN],
      redirectUri: import.meta.env.VITE_AUTH_REDIRECT_URI,
    },
    cache: {
      cacheLocation: "localStorage",
      storeAuthStateInCookie: false,
    },
    system: {
      loggerOptions: {
        loggerCallback: (level, message, containsPii) => {
          if (containsPii) {
            return;
          }
          switch (level) {
            case LogLevel.Error:
              console.error(message);
              return;
            case LogLevel.Warning:
              console.warn(message);
              return;
            case LogLevel.Info:
              console.info(message);
              return;
            case LogLevel.Verbose:
              console.debug(message);
              return;
          }
        },
      },
    },
  };

  const scopes = (import.meta.env.VITE_AUTH_SCOPES as string).split(' ').filter(Boolean);
  const client = new PublicClientApplication(config);
  await client.initialize();
  const result = ref(await client.handleRedirectPromise());
  const isAuthenticated = computed(() => result.value != null);
  const login = async () => {
    if (client.getAllAccounts().length > 0) {
      client.setActiveAccount(client.getAllAccounts()[0]);
      result.value = await client.acquireTokenSilent({
        redirectUri: config.auth.redirectUri,
        scopes: scopes
      });
    } else {
      await client.acquireTokenRedirect({
        redirectStartPage: location.href,
        redirectUri: config.auth.redirectUri,
        scopes: scopes
      });
    }
  };
  const logout = async () => {
    await client.logoutRedirect();
  }

  const msalPlugin: Plugin = {
    install(app) {
      app.provide<Msal>("msal", { isAuthenticated, result, login, logout });
    }
  }
  return msalPlugin;
};

export const useMsal = () => {
  return inject<Msal>("msal")!;
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)