npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@primno/dataverse-auth

v0.7.0

Published

Authenticate to Dataverse and Dynamics 365 with a connection string or OAuth 2.0. Provides a token persistence cache.

Downloads

32

Readme

Dataverse Authentication for Node.JS

npm npm build node-current

@primno/dataverse-auth is a library for Node.JS to authenticate to Dataverse / Dynamics 365.

@primno/dataverse-auth provides:

Works with @primno/dataverse-client to make requests to Dataverse / Dynamics 365 CE, but can be used as a standalone library.

This package is part of the Primno framework.

Compatibility

@primno/dataverse-auth works with Dataverse / Dynamics 365.

Dynamics 365 CE (on-premises) is supported since version 9.0 with CBA/IFD deployment (ADFS 2019+ with OAuth enabled in deployment settings).

Tip If you are using Dynamics 365 App for Outlook on your on-premises environment, the prerequisite are met.

Quick start

Installation

  npm install @primno/dataverse-auth

Usage

With connection string authentication:

import { ConnStringTokenProvider } from '@primno/dataverse-auth';

const tokenProvider = new ConnStringTokenProvider(
    "AuthType=OAuth;Url=https://<Environnement>.crm.dynamics.com;UserName=<UserName>;TokenCacheStorePath=./.cache/token.json",
    {
        oAuth: {
            // For persistent token cache on Linux/Mac to store the token in the keychain.
            // Only used when TokenCacheStorePath is set.
            persistence: {
                serviceName: "<serviceName>", // Optional, default to "Primno.DataverseClient"
                accountName: "<accountName>" // Optional, default to "MSALCache"
            },
            // For device code flow
            deviceCodeCallback: (deviceCode) => {
                console.log(deviceCode.message);
            }
        }
     }
);

const token = await tokenProvider.getToken();

With OAuth:

import { OAuthTokenProvider } from '@primno/dataverse-auth';

const tokenProvider = new OAuthTokenProvider({
    url: "https://<Environment>.crm.dynamics.com",
    credentials: {
        clientId: "51f81489-12ee-4a9e-aaae-a2591f45987d", // Sample client id
        redirectUri: "app://58145B91-0C36-4500-8554-080854F2AC97", // Sample redirect uri
        authorityUrl: "https://login.microsoftonline.com/common",
        scope: "https://<Environment>.crm.dynamics.com/.default",
        grantType: "device_code",
        userName: "<Username>"
    },
    persistence: {
        enabled: false
    },
    deviceCodeCallback: (deviceCode) => {
        console.log(deviceCode.message);
    }
});

const token = await tokenProvider.getToken();

Authentication

dataverse-auth is provided with 2 authentication providers :

  • Connection string
  • OAuth2

Connection string

ConnStringTokenProvider provides a token by using a connection string (see Dataverse doc and D365 CE on-premises doc).

Only OAuth authentication type is supported.

The token can be persisted using the TokenCacheStorePath connection string parameter. To learn more about the token cache, see Token cache.

const tokenProvider = new ConnStringTokenProvider(
    "AuthType=OAuth;Url=https://<Environnement>.crm.dynamics.com;UserName=<UserName>;TokenCacheStorePath=./.cache/token.json",
    {
        oAuth: {
            // For persistent token cache on Linux/Mac to store the token in the keychain.
            // Only used when TokenCacheStorePath is set.
            persistence: {
                serviceName: "<serviceName>", // Optional, default to "Primno.DataverseClient"
                accountName: "<accountName>" // Optional, default to "MSALCache"
            },
            // For device code flow. Show the url and code to the user.
            deviceCodeCallback: (deviceCode) => {
                console.log(deviceCode.message);
            }
        }
     }
);

OAuth flows

ConnStringTokenProvider determines which OAuth flow to use based on the parameters in the connection string.

| Parameters | Flow | |-----------|------| | UserName and Password | User password | | ClientId and ClientSecret | Client credential | | UserName only | Device code |

Note Device code flow allows to authenticate with MFA enabled.

Examples:

| Environment | AuthType | OAuth flow | Connection string | |-------------|----------|------------|-------------------| | Dataverse | OAuth | Device code | AuthType=OAuth;Url=https://<Environnement>.crm.dynamics.com;UserName=<UserName> | | Dataverse | OAuth | User password | AuthType=OAuth;Url=https://<Environnement>.crm.dynamics.com;UserName=<UserName>;Password=<Password> | | Dataverse | OAuth | Client credential | AuthType=OAuth;Url=https://<Environnement>.crm.dynamics.com;ClientId=<ClientId>;ClientSecret=<ClientSecret>;RedirectUri=<RedirectUri> | | On-premises | OAuth | User password | AuthType=OAuth;RedirectUri=<RedirectUri>;Url=https://<D365Url>;UserName=<Domain>\<UserName>;Password=<Password> |

OAuth2

OAuthTokenProvider provides OAuth2 authentication.

const tokenProvider = new OAuthTokenProvider(options);

Options definition:

interface OAuthConfig {
    /**
     * OAuth2 credentials
     */
    credentials: {
        /**
         * OAuth flow
         */
        grantType: "client_credential" | "password" | "device_code";
        /**
         * Client ID.
         * @default "51f81489-12ee-4a9e-aaae-a2591f45987d" (Sample client id)
         */
        clientId?: string;
        /**
         * Client secret for ConfidentialClientApplication.
         * If set, clientCertificate is not required.
         */
        clientSecret?: string;
        /**
         * Client certificate for ConfidentialClientApplication.
         * If set, clientSecret is not required.
         */
        clientCertificate?: {
            thumbprint: string;
            privateKey: string;
        },
        /**
         * Authority URL (eg: https://login.microsoftonline.com/common/)
         */
        authorityUrl: string;
        /**
         * Username for password and device_code flow.
         */
        userName?: string;
        /**
         * Password for password flow.
         */
        password?: string;
        /**
         * Redirect URI.
         */
        redirectUri?: string;
        /**
         * Scope. Dataverse url suffixed with .default.
         */
        scope?: string;
    };

    /**
     * Persistence options
     */
    persistence: {
        /**
         * Enable persistence. Default: false.
         */
        enabled: true;
        
        /**
         * Cache path.
         */
        cachePath: string;

        /**
         * Service name. Only used on Linux/MacOS to store the token in the keychain. Default: "Primno.DataverseClient"
         */
        serviceName: string;

        /**
         * Account name. Only used on Linux/MacOS to store the token in the keychain. Default: "MSALCache"
         */
        accountName: string;
    };

    /**
     * Device code callback. Only used when grant_type is device_code.
     * @param response The device code response
     * @returns 
     */
    deviceCodeCallback?: (response: DeviceCodeResponse) => void;

    /**
     * Dataverse / D365 url. Eg: https://org.crm.dynamics.com
     */
    url: string;
}

Discover authority

To discover the authority url, you can use the discoverAuthority method.

interface Authority {
    authUrl: string; 
    resource?: string;
}

const authority: Authority = await discoverAuthority("<DataverseOrOnPremisesUrl>");

Token cache persistence

The token can be persisted using the persistence option.

It is encrypted using DPAPI on Windows, libsecret on Linux and the Keychain on MacOS.

Queries

If you want to query the Dataverse API, you can use @primno/dataverse-client package.

Troubleshooting

Unable to verify the first certificate

On on-premises environments, you may have this error :

Error: unable to verify the first certificate

To fix this issue, you can add your enterprise CA certificate to the trusted root certificate authorities by setting the NODE_EXTRA_CA_CERTS environment variable. See Node.js documentation for more information.

Credits

Thanks to Microsoft for persistence cache (msal-node-extensions).