Giter Club home page Giter Club logo

aio-lib-ims's Introduction

Version Downloads/week Build Status License Codecov Coverage Greenkeeper badge

Adobe I/O IMS Library

The Adobe I/O IMS Library helps interacting with the IMS API as well as creating and invalidating tokens. To support multiple use cases and environments, there is not a single configuration managed by this library but multiple configurations called IMS configuration contexts. Each configuration context holds configuration data needed to create tokens. See the Configuration section below.

Installation

To install the Adobe I/O IMS Library, simple use npm:

$ npm install @adobe/aio-lib-ims --save

Quickstart

Before using the AIO IMS Library you need to create an integration on Adobe I/O Console from where you can the grab the integration details to setup a first configuration context. Let's use an OAuth2 integration as an example:

const { context, getToken, getTokenData } = require('@adobe/aio-lib-ims');

const config = {
  callback_url: "https://callback.example.org",
  client_id: "123456cafebabe",
  client_secret: "12345678-cafe-babe-cafe-9999",
  scope: "openid"
};
await context.set('example', config, true);
await context.setCurrent('example');

const token = await getToken();
const tokenDecoded = getTokenData(token);

See the API Documentation for full details.

Configuration

The AIO IMS Library transparently maintains the login configuration and keep access and refresh tokens for reuse before they expire.

All configuration is stored in a single $ims root property.

The library supports maintaining multiple configurations for different use cases. Each such configuration is stored in its own named object with the $ims configuration. Such a configuration is called an IMS (configuration) context and has a label which allows to refer to the configuration by name.

To simplify usage, there may be a designated current context which is always used if explicit context is not given to the command. Inside the $ims configuration object, the name of the current context is stored in the $current property.

Here is an example $ims configuration

{
  $ims: {
    sample_jwt: {
      client_id: "<jwt-clientid>",
      client_secret: "XXX",
      techacct: "<guid>@techacct.adobe.com",
      meta_scopes: [
        "ent_dataservices_sdk"
      ],
      ims_org_id: "<org-guid>@AdobeOrg",
      private_key: "XXX"
    },
    sample_oauth2: {
      callback_url: "https://callback.example.com",
      client_id: "<oauth2-clientid>",
      client_secret: "XXX",
      scope: "openid AdobeID"
    },
    $current: "sample_oauth2",
    $plugins: [
      "sample-aio-lib-ims-plugin"
    ]
  }
}

Running on a Desktop

When running on your local machine the AIO IMS is leveraging the Configuration module for use by aio-cli plugins to load and update the configuration stored in .aio and .env files. The library supports both local and global aio configurations.

Here is an example that relies on the AIO IMS to generate a token from an existing configuration:

const { context, getToken } = require('@adobe/aio-lib-ims');

await context.setCurrent('my-config');
const token = await getToken();

Running in an Adobe I/O Runtime action

The AIO IMS Library can also be used in an Adobe I/O Runtime action. In this case the IMS configuration must be set beforehand. The library is relying on the Cloud State Library to persist the access tokens across action invocations and reduce the number of requests to IMS.

Here is an Adobe I/O Runtime action example that leverages the AIO IMS:

const { context, getToken } = require('@adobe/aio-lib-ims');

function main ({ imsContextConfig, ...params }) {
  // the IMS context configuration is passed as action parameter
  // imsContextConfig = { client_id, client_secret, techacct, meta_scopes, ims_org_id, private_key }
  await context.set('my_ctx', imsContextConfig)

  const token = await getToken('my_ctx')
}

Note that for now cached tokens will only be accessible from the action that created them. In the above example, the token persisted under 'my_ctx' will not be retrievable from a different action even if it uses the same context key.

IMS Environment

The use of IMS environments is reserved to Adobe use. For information it is indicated by the env configuration context property and takes one of the values prod and stage. The default value is prod. In general, you do not need to deal with this property.

JWT Configuration

JWT (service to service integration) configuration requires the following properties:

Property Description
client_id The IMS (Oauth2) Client ID. This is the API Key in the integration overview of the Adobe I/O Console.
client_secret The IMS (OAUth2) Client Secret
techacct The Technical Account ID from the integration overview screen in the I/O Console
meta_scopes An array of meta scope names. These are the labels of one ore more special properties in the sample JWT payload. They can be found in the JWT tab of the I/O Console integration in the JWT payload properties of the form "https://<ims-host>/s/ent_dataservices_sdk": true,. There may be one or more of depending on the services to which the integration is subscribed. The values to list in the meta_scopes property are the last segment of the URL. In the example case, this would be ent_dataservices_sdk.
ims_org_id The Organization ID from the integration overview screen in the I/O Console.
private_key The private key matching any one of the Public Keys of the integration.

OAuth2 Configuration

OAuth2 configuration requires the following properties:

Property Description
client_id The IMS (Oauth2) Client ID. This is the API Key in the integration overview of the Adobe I/O Console.
client_secret The IMS (OAUth2) Client Secret
callback_url The Default redirect URI from the integration overview screen in the I/O Console. Alternatively, any URI matching one of the Redirect URI patterns may be used.
scope Scopes to assign to the tokens. This is a string of space separated scope names which depends on the services this integration is subscribed to. Adobe I/O Console does not currently expose the list of scopes defined for OAuth2 integrations, a good list of scopes by service can be found in OAuth 2.0 Scopes. At the very least you may want to enter openid.

Adding Configuration Support

The AIO IMS Library handles common tasks around tokens by itself. This includes storing access and refresh tokens in the configuration context, checking those tokens for expiry, and refreshing as needed. Only when an access token (and a refresh token) needs to be created anew from the configuration context credentials, do the plugins come into play.

When a new access token needs to be created from credentials, the IMS Library implements the following algorithm:

  • Collect the AIO IMS Library plugins
  • Iterate over this collection and for each plugin do:
    • require the plugin
    • Call the plugin's supports(config) function with the configuration context
    • If supports(config) returns true then call the plugin's imsLogin(ims, config, force) function with an instance of the Ims class, the configuration context, and a boolean flag described below in Forced imsLogin.

From this algorithm we can derive the following requirements for a plugin:

  • MUST be installed and available to the require function of the AIO IMS Library.

  • MUST set the script to be loaded by require-ing the plugin's root folder in the package.json#/main property (this is actually how require loads the package's main script when using the folder containing the package.json file).

  • MUST export an object from this script with the following two properties being functions:

    Property Signature Description
    supports (config) => boolean Given the IMS configuration context, returns true if the configuration can be used for the plugins login mechanism.
    imsLogin (ims, config, force) => Promise Given the Ims instance and the IMS configuration context implement the authentication with IMS and return a Promise resolving to a token object. See Forced imsLogin for details on the force parameter.

Forced imsLogin

Some plugins support an OAuth2 login mechanism where the actual account for which an access token is generated depends on the user input. For example the OAuth2 plugin implements an ExpressJS application to implemented the three legged OAuth2 flow. During this flow the user enters their credentials for IMS to validate.

Typically IMS will set some cookies to cache the login state in the browser to improve the user experience in a standard OAUth2 web application. In CLI contexts it might not always be desired to always get a token for the same user, particularly in testing scenarios.

To allow changing user identity in the OAuth2 plugin or to prevent reusing cached information, the force flag to the imsLogin function indicates whether to clean the caches before logging in. true meaning to clean the cache, while false indicates that using the cached information is just fine.

imsLogin Promise

The promise returned form imsLogin must resolve to a token object having the following general structure:

{
  access_token: {
    token: <token-value>,
    expiry: <token-expiry-time-in-ms-since-epoch>
  },
  refresh_token: {
    token: <token-value>,
    expiry: <token-expiry-time-in-ms-since-epoch>
  },
  ...<more properties>...
}

The access_token object containing the token value and expiry time is required and login will fail if this property is missing. The refresh_token is optional and may not always be present. Any additional properties are currently ignored.

The Ims.exchangeJwtToken() and Ims.getAccessToken() functions both return a Promise resolving to a token object as expected to be returned from the imsLogin function.

Implementing Plugins

Since plugins are accessed using standard require , one npm package only provides exactly one IMS plugin extension. Multiple plugins must be implemented in separate plugins. The configuration support modules for JWT and OAuth2 are two such packages. The IMS Library has a dependency on the JWT and OAuth2 plugins and will always try to use those.

Additional plugins must be npm install-ed and listed in the $ims/$plugins array property. This can easily be done in the package postinstall script like this:

const { context } = require('@adobe/aio-lib-ims');
context.plugins = context.plugins.push(process.env.npm_package_name);

NOTE: You want to actually first check whether the plugin is already listed, and you might also want to provide a preuninstall script to remove the plugin from the list again when being uninstalled.

Contributing

Contributions are welcomed! Read the Contributing Guide for more information.

Licensing

This project is licensed under the Apache V2 License. See LICENSE for more information.

aio-lib-ims's People

Contributors

shazron avatar fmeschbe avatar moritzraho avatar greenkeeper[bot] avatar bobvanmanen avatar purplecabbage avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.