@misonou/brew-extension-auth
TypeScript icon, indicating that this package has built-in type declarations

0.3.0 • Public • Published

About brew-extension-auth

This is a preview extension for single sign-on in brew.js application.

Currently supported single sign-on providers:

  • Password authentication using fetch
  • MSAL.js (Microsoft Entra ID)

Working on:

  • generic OAuth2 client

Usage

import brew from "brew-js/app";
import Router from "brew-js/extension/router";
import Auth from "@misonou/brew-extension-auth";
import MsalAuthProvider from "@misonou/brew-extension-auth/msal";

export const app = brew.with(Router, Auth)(app => {
    app.useRouter({
        /* router options */
    });
    app.useAuth({
        providers: [
            // create provider using factory method
            MsalAuthProvider.create('microsoft', clientId, authority, scopes)
        ],
        resolveUser({ identity }) {
            return identity; // value will be exposed as `app.user`
        }
    });
});

Typed user object

By casting the extension with specific user object type, app.user will be enforced with the given type.

If there are multiple identity providers, it may be advantageous to unify the user object by resolveUser.

import brew from "brew-js/app";
import Router from "brew-js/extension/router";
import Auth, { AuthExtension } from "@misonou/brew-extension-auth";

interface User {
    id: string;
    // ...
}

brew.with(Router, Auth as AuthExtension<User>)(app => {
    app.useAuth({
        // ...
        resolveUser() {
            // require to return an object of type `User`
            return createMyUserObject();
        }
    })
});

API

// performs login and logout
function onClickLogin() {
    return app.login();
}
function onClickLogout() {
    return app.logout();
}

// events
app.on('login', e => {
    console.log(e.user);
});
app.on('logout', e => {
    // user that was logged in (previously exposed as app.user)
    console.log(e.user);
});
app.on('sessionEnded', e => {
    // user has logged out in other tabs
    // user will be softly logged out after sessionExpired is handled
});

Using return path

// redirect to the page user originally liked to access after logging in
app.login({
    returnPath: app.canNavigateBack ? undefined : app.initialPath
});

Using multiple providers

When there are multiple providers, either provider or loginHint must be provided to app.login so that the correct provider can be resolved.

// setup
app.useAuth({
    providers: [
        MsalAuthProvider.create('microsoft1', clientId1, authority1, scopes),
        MsalAuthProvider.create('microsoft2', clientId2, authority2, scopes),
    ],
    // ...
});

// login
app.login({ provider: 'microsoft1' }); //or
app.login({ loginHint: 'test@tenant-domain1.com' });

Note that the first suitable provider will be picked, therefore provider that accept all login IDs should be put at last.

Middleware

Middleware is available for DOM fetch and axios to which

  • automatically set Authorization header with bearer token when user is logged in
  • when necessary, the provider will try to renew access token.

After creating app with auth extension, you can use the corresponding function to create middleware.

Fetch

import { createFetchMiddleware } from "@misonou/brew-extension-auth";

// fetch without next middleware
const fetch = createFetchMiddleware(app);
fetch(new Request('https://example.org/api/v1'));
fetch('https://example.org/api/v1', { /* ... */ });

With other utility such as fetch-run:

import { Api } from "fetch-run";
import { createFetchMiddleware } from "@misonou/brew-extension-auth";

const fetch = createFetchMiddleware(app);
const api = Api.create('https://example.org/api/v1');
api.use(next => req => fetch(req, next));

axios

import axios from "axios";
import { createAxiosMiddleware } from "@misonou/brew-extension-auth";

const client = axios.create();
createAxiosMiddleware(app)(client);

Providers

Password authentication using fetch

Now it is easily implementable with AuthProvider and JSONClient.

Examples are in use src/examples folder.

import { AuthProvider } from "@misonou/brew-extension-auth";

app.useAuth({
    providers: [
        AuthProvider.from('my', new MyClient())
    ],
    // ...
});

MSAL.js

Requires to install @azure/msal-browser.

The simplest way to create a provider is to have your client ID, authority and scopes:

import MsalAuthProvider from "@misonou/brew-extension-auth/msal";

MsalAuthProvider.create('microsoft',
    clientId, // Client ID on App registration
    'https://login.microsoftonline.com/common', // can be organizations or your tenant's authority
    ['openid', 'profile']);

The MSAL applications will be initialized with default configuration:

// it must be before calling MsalAuthProvider.create
MsalAuthProvider.setDefault({
    auth: { /* ... */ },
    cache: { /* ... */ },
    logging: { /* ... */ },
    telemetry: { /* ... */ }
});

You can also create provider with more flexibility by creating PCA yourself:

import { PublicClientApplication } from "@azure/msal-browser";
import MsalAuthProvider from "@misonou/brew-extension-auth/msal";

MsalAuthProvider.create('microsoft',
    new PublicClientApplication({ /* ... */ }),
    { scopes: ['openid', 'profile'] });

Using UMD distribution

Here is an example on how to include and access exported members in UMD environment:

<!-- dependencies (not showing all) -->
<script src="https://unkpg.com/brew-js"></script>
<!-- main extension -->
<script src="https://unkpg.com/@misonou/brew-extension-auth"></script>
<!-- MSAL provider -->
<script src="https://unpkg.com/@misonou/brew-extension-auth/dist/brew-auth-msal.min.js"></script>

<script>
brew.with(brew.Auth)(app => {
    // access MSAL provider factory
    brew.Auth.MsalAuthProvider.create(/* ... */)

    // access middleware
    brew.Auth.createFetchMiddleware(app)
});
</script>

Readme

Keywords

none

Package Sidebar

Install

npm i @misonou/brew-extension-auth

Weekly Downloads

7

Version

0.3.0

License

ISC

Unpacked Size

177 kB

Total Files

28

Last publish

Collaborators

  • misonou