Skip to content
This repository has been archived by the owner on Mar 4, 2024. It is now read-only.

indykite/indykite-sdk-web

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

IndyKite logo

IndyKite Client UI SDK

IndyKite is a cloud identity platform built to secure and manage human & non-person (IoT) identities and their data. This repository containts the JavaScript Library packages for IndyKite Platform Client SDK.

This library contains multiple client libraries for each service of the platform.

NPM version npm type definitions codecov

In order to access to the platform you must obtain an API key first.

Terminology

Definition Description
Digital Twin A digital twin is the digital identity of a physical entity on/in a software/identity system
Application Space ID ID of the application where the digital twin belongs to
Application Agent ID ID of the agent which makes the application available for the different calls
Tenant ID ID of the tenant where the digital twin belongs to. The tenant is belong to an application space
Private Key and Settings The secret which required to reach the system. Indykite provides the necessary secrets
Property The digital twin's property (eg.: email, name)
JWT JSON Web Tokens
Introspect A process used to validate the token and to retrieve properties assigned to the token
Patch property Add, change or delete a property of a digital twin

Documentation

Visit the IndyKite One Developer Community site for official IndyKite documentation and to find out how to use the entire platform for your project.

Prerequisites

You need to have the following before using the Web SDK:

  • An AppSpace, App, AppAgent, and AppAgent credentials
  • A deployed authentication flow

Installation

From npm:
npm install @indykiteone/indykite-sdk-web

From yarn:

yarn add @indykiteone/indykite-sdk-web

Import version

You can use the Web SDK by importing the SDK as a package to your JavaScript framework. With this option, the source files are in a readable (unbuilt) form. Since this form is not prebuilt, it is necessary to build your application using tools such as webpack or babel.

import { IKUIInit } from "@indykiteone/indykite-sdk-web";

Note: If you are building apps with frameworks like React, Angular or Vue.js. You have most likely already setup a build process (often automatically by the framework), and therefore do not need to do anything.

From CDN:

UNPKG

<script src="https://unpkg.com/@indykiteone/indykite-sdk-web/dist/iksdkweb.dist.js"></script>

jsDelivr

<script src="https://cdn.jsdelivr.net/npm/@indykiteone/indykite-sdk-web/dist/iksdkweb.dist.js"></script>

Browser support

CDN .dist.js version is built with support for all recent versions of major browsers (Chrome, Firefox, Safari, Edge, Opera).

API

dist.js package

In case of using the dist package. All functions are exported under the IK keyword. For example:

<script src="https://unpkg.com/@indykiteone/indykite-sdk-web/dist/iksdkweb.dist.js"></script>
<script>
 IK.IKUIInit({});
</script

Getting Started

Trial

For a trial please contact IndyKite to setup and configure the platform.

Init

To use the UI elements provided by the @indykiteone/indykite-sdk-web library, you first need to initialize lib. This should be done in entry point to the app.

import { IKUIInit } from "@indykiteone/indykite-sdk-web";

IKUIInit({
  baseUri: process.env.REACT_APP_INDY_BASE_URI,
  applicationId: process.env.REACT_APP_INDY_CLIENT_ID,
  tenantId: process.env.REACT_APP_INDY_TENANT_ID,
  disableInlineStyles: true,
});

You should use the disableInlineStyles property set to true, because inline styles are deprecated now. See the CSS section in order to get more information.

Core - UI API

To use the UI elements provided by the @indykiteone/indykite-sdk-web library, make sure you've completed initializing the library as described above. As all render functions do network setup calls, they should be treated as side effects in the JS framework of your application.

Rendering login/registration screen with different auth flows

Simple registration

This authentication flow doesn't allow you to do anything special but registering a new user using username and password.

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKForm = () => {
  React.useEffect(() => {
    IKUICore.renderForm({
      renderElementSelector: "#form-container",
      onSuccess: (data) => {
        console.log(data);
        // You can store the access token from the data object, but the UISDK can handle
        // all this for you so theoretically you don't need to manage tokens yourself.
        // The authentication flow ended here and you can do a redirection to your application now
      },
      onFail: (error) => {
        console.error(error);
      },
    });
  }, []);

  return (
    <div>
      <div id="form-container" />
    </div>
  );
};

Simple login with no actions

This authetication flow lets you log in with a username and password.

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKForm = () => {
  React.useEffect(() => {
    IKUICore.renderForm({
      renderElementSelector: "#form-container",
      onSuccess: (data) => {
        console.log(data);
        // You can store the access token from the data object, but the UISDK can handle
        // all this for you so theoretically you don't need to manage tokens yourself.
        // The authentication flow ended here and you can do a redirection to your application now.
      },
      onFail: (error) => {
        console.error(error);
      },
    });
  }, []);

  return (
    <div>
      <div id="form-container" />
    </div>
  );
};

Simple login with some actions

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKForm = () => {
  React.useEffect(() => {
    IKUICore.renderForm({
      renderElementSelector: "#form-container",
      onSuccess: (data) => {
        console.log(data);
        // You can store the access token from the data object, but the UISDK can handle
        // all this for you so theoretically you don't need to manage tokens yourself.
        // The authentication flow ended here and you can do a redirection to your application now
      },
      onFail: (error) => {
        console.error(error);
      },
      actionLabels: {
        KEY_FORGOTTEN: "Forgotten password?",
        KEY_REGISTER: "Registration",
      },
    });
  }, []);

  return (
    <div>
      <div id="form-container" />
    </div>
  );
};

Login flow with OIDC providers

When the flow doesn't continue after returning from the OIDC provider

You need to put the following code to your login page, e.g. https://yourpage.com/login:

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKForm = () => {
  React.useEffect(() => {
    IKUICore.renderForm({
      renderElementSelector: "#form-container",
      onSuccess: (data) => {
        console.log(data);
        // You will not get the access token here, because you will be redirected
        // to an OIDC provider page (e.g. google.com) and then to your callback page
      },
      onFail: (error) => {
        console.error(error);
      },
    });
  }, []);

  return (
    <div>
      <div id="form-container" />
    </div>
  );
};

This code will display a Google option to log in. After clicking the option, you will be redirected to the Google site where you will be authenticated. After that, you will be redirected back to your callback URL. Put the following code to your call back page, which can be, for example, https://yourpage.com/callback:

import React from "react";
import { IKUIOidc } from "@indykiteone/indykite-sdk-web";

// This is where Google and other providers can redirect you
const Callback = () => {
  React.useEffect(() => {
    // It's important that oidcCallback is called just once, multiple calls can end up with errors
    IKUIOidc.oidcCallback()
      .then((data) => {
        // You can save the token in your app in case you need it but UISDK can handle all this for you
        // so theoretically you don't need to manage tokens yourself.
        // The authentication flow ended here and you can do a redirection to your application now
        console.log(data);
      })
      .catch((e) => {
        // The App developer is responsible for handling the error in this phase.
        console.error(e);
      });
  }, []);

  return (
    <div>
      <h3>general callback</h3>
    </div>
  );
};

When the flow continues after returning from the OIDC provider

You need to put this code in your login page, for example, https://yourpage.com/login:

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKForm = () => {
  React.useEffect(() => {
    IKUICore.renderForm({
      renderElementSelector: "#form-container",
      onSuccess: (data) => {
        console.log(data);
        // After you finish your authentication with an OIDC provider you should be redirected
        // back to this login page.
        // You can store the access token from the data object, but the UISDK can handle
        // all this for you so theoretically you don't need to manage tokens yourself.
        // The authentication flow ended here and you can do a redirection to your application now
      },
      onFail: (error) => {
        console.error(error);
      },
      actionLabels: {
        KEY_FINISH: "Finish",
      },
    });
  }, []);

  return (
    <div>
      <div id="form-container" />
    </div>
  );
};

And this code to your callback page you set as the Redirect URL in your OIDC provider, for example, https://yourpage.com/callback:

import React from "react";
import { IKUIOidc } from "@indykiteone/indykite-sdk-web";

// This is where FB, Google and other providers can redirect you
const Callback = () => {
  React.useEffect(() => {
    // It's important that oidcCallback is called just once, multiple calls can end up with errors
    IKUIOidc.oidcCallback()
      .then((data) => {
        // In this case the data should contain a `redirect_to` property and you should redirect to this location.
        if (data.redirect_to) {
          window.location.href = data.redirect_to;
        }
      })
      .catch((e) => {
        // The App developer is responsible for handling the error in this phase.
        console.error(e);
      });
  }, []);

  return (
    <div>
      <h3>general callback</h3>
    </div>
  );
};

Multiple login flows (using the Switch node)

Use the switch node to merge mutliple authentication flows into one. If you want to use the Default branch, you don't need to specify any new properties. This code will use the Default branch.

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKForm = () => {
  React.useEffect(() => {
    IKUICore.renderForm({
      renderElementSelector: "#form-container",
      onSuccess: (data) => {
        console.log(data);
        // You can store the access token from the data object, but the UISDK can handle
        // all this for you so theoretically you don't need to manage tokens yourself.
        // The authentication flow ended here and you can do a redirection to your application now
      },
      onFail: (error) => {
        console.error(error);
      },
      actionLabels: {
        KEY_REGISTER: "Registration",
      },
    });
  }, []);

  return (
    <div>
      <div id="form-container" />
    </div>
  );
};

The register branch will be used if the condition specified inside the Switch node is fulfilled. By default there's a following condition:

has(session.input) && has(session.input.flow) && session.input.flow=='register'

It checks whether the input object has a property flow set to register. You can define the input object with passing the arguments property to your IKUICore.renderForm call:

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKForm = () => {
  React.useEffect(() => {
    IKUICore.renderForm({
      renderElementSelector: "#form-container",
      onSuccess: (data) => {
        console.log(data);
        // You can store the access token from the data object, but the UISDK can handle
        // all this for you so theoretically you don't need to manage tokens yourself.
        // The authentication flow ended here and you can do a redirection to your application now
      },
      onFail: (error) => {
        console.error(error);
      },
      actionLabels: {
        KEY_REGISTER: "Registration",
      },
      arguments: {
        flow: "register",
      },
    });
  }, []);

  return (
    <div>
      <div id="form-container" />
    </div>
  );
};

Forgotten password flow

Use an action (click the Did you forget your password? button)

In the beginning, you can call IKUICore.renderForm as usual. The login screen will contain an action "Forgotten password?".

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKForm = () => {
  React.useEffect(() => {
    IKUICore.renderForm({
      renderElementSelector: "#form-container",
      onSuccess: (data) => {
        console.log(data);
        // You will not end here in case a user wants to reset its password.
      },
      onFail: (error) => {
        console.error(error);
      },
      actionLabels: {
        KEY_FORGOTTEN: "Forgotten password?",
        KEY_REGISTER: "Registration",
      },
    });
  }, []);

  return (
    <div>
      <div id="form-container" />
    </div>
  );
};

When a user sends a request to reset their password, they will get an email containing a reference ID in the link confirming the password resent. You need to extract this ID from the URL and pass it to the IKUICore.renderForm function as an token property.

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKResetPasswordForm = ({ referenceId }) => {
  React.useEffect(() => {
    if (referenceId) {
      IKUICore.renderForm({
        renderElementSelector: "#form-container",
        onSuccess: (data) => {
          console.log(data);
          // You can store the access token from the data object, but the UISDK can handle
          // all this for you so theoretically you don't need to manage tokens yourself.
          // The authentication flow ended here and you can do a redirection to your application now
        },
        onFail: (error) => {
          console.error(error);
        },
        token: referenceId,
      });
    }
  }, [referenceId]);

  return (
    <div>
      <div id="form-container" />
    </div>
  );
};

Use a special URL

If you want to start your flow with the reset password screen, use the Switch node, as mentioned in the Multiple login flows section. If you add the flow argument with a value specified by you (in the authentication flow builder) to your IKUICore.renderForm call, the Switch node will use the direct connection with the Forgotten Password node.

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKForm = () => {
  React.useEffect(() => {
    IKUICore.renderForm({
      renderElementSelector: "#form-container",
      onSuccess: (data) => {
        console.log(data);
        // You will not end here in case a user wants to reset its password.
      },
      onFail: (error) => {
        console.error(error);
      },
      actionLabels: {
        KEY_FORGOTTEN: "Forgotten password?",
        KEY_REGISTER: "Registration",
      },
      arguments: {
        flow: "reset-password",
      },
    });
  }, []);

  return (
    <div>
      <div id="form-container" />
    </div>
  );
};

When a user sends a request to reset his password, he will get an email containing a reference ID in the link confirming the password resetting. You need to extract this ID from the URL and pass it to the IKUICore.renderForm function as an token property.

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKResetPasswordForm = ({ referenceId }) => {
  React.useEffect(() => {
    if (referenceId) {
      IKUICore.renderForm({
        renderElementSelector: "#form-container",
        onSuccess: (data) => {
          console.log(data);
          // You can store the access token from the data object, but the UISDK can handle
          // all this for you so theoretically you don't need to manage tokens yourself.
          // The authentication flow ended here and you can do a redirection to your application now
        },
        onFail: (error) => {
          console.error(error);
        },
        token: referenceId,
      });
    }
  }, [referenceId]);

  return (
    <div>
      <div id="form-container" />
    </div>
  );
};

Log in with tokens

OTP Token

A user can get an invitation email which contains a reference ID. You need to pass this ID the same way as you did in the Reset password flow, and that's to use this ID as the token property. This will cause your authentication to start with the Input Invitation node.

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKResetPasswordForm = ({ referenceId }) => {
  React.useEffect(() => {
    if (referenceId) {
      IKUICore.renderForm({
        renderElementSelector: "#form-container",
        onSuccess: (data) => {
          console.log(data);
          // You can store the access token from the data object, but the UISDK can handle
          // all this for you so theoretically you don't need to manage tokens yourself.
          // The authentication flow ended here and you can do a redirection to your application now
        },
        onFail: (error) => {
          console.error(error);
        },
        token: referenceId,
      });
    }
  }, [referenceId]);

  return (
    <div>
      <div id="form-container" />
    </div>
  );
};

Magic link

An authentication flow can also use a Magic Link. In this case a user is asked to enter a code they got in an email. The received email may contain a reference ID - very likely used in a clickable URL address. After this address is opened you need to ensure that the authentication flow is started with the ~token property in the same way how it was used in the previous example.

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKMagicLinkForm = ({ referenceId }) => {
  React.useEffect(() => {
    if (referenceId) {
      IKUICore.renderForm({
        renderElementSelector: "#form-container",
        onSuccess: (data) => {
          console.log(data);
          // You can store the access token from the data object, but the UISDK can handle
          // all this for you so theoretically you don't need to manage tokens yourself.
          // The authentication flow ended here and you can do a redirection to your application now
        },
        onFail: (error) => {
          console.error(error);
        },
        token: referenceId,
      });
    }
  }, [referenceId]);

  return (
    <div>
      <div id="form-container" />
    </div>
  );
};

Please note that in order to make this working you need to setup your email configuration. For more details see this tutorial.

Custom OIDC provider

In case you want to act as an OIDC provider, you have to call the IKUIOidc.handleOidcOriginalParamsAndRedirect function before you start your auth flow.

import { IKUIOidc } from "@indykiteone/indykite-sdk-web";

const pathToLogin = "/login";
IKUIOidc.handleOidcOriginalParamsAndRedirect(pathToLogin);

This helps the SDK know that you are an OIDC provider, and after you authenticated, the SDK should return you back to the original application. The pathToLogin should point to an endpoint where you will call the IKUICore.renderForm as usual.

Authentication status

After you have successfully finished the authentication flow, you don't have to store the access tokens on your own. The SDK does it for you. You can use the following functions to manage the authentication status.

  • IKUIUserAPI.isAuthenticated()
    • Check whether there's an authenticated user
  • IKUIUserAPI.getValidAccessToken()
    • Get the access token of currently logged user
  • IKUIUserAPI.refreshAccessToken()
    • Refresh the access token of currently logged user
  • IKUIUserAPI.logoutUser()
    • Logout currently logged user

Customize components

Replace a form component

Input

This example shows how to add a custom class name to the input element.

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKForm = () => {
  React.useEffect(() => {
    IKUICore.renderForm({
      renderElementSelector: "#form-container",
      onSuccess: (data) => {
        console.log(data);
      },
      onFail: (error) => {
        console.error(error);
      },
      onRenderComponent: (component: HTMLElement, componentType: string) => {
        if (componentType === "form") {
          const inputs = component.getElementsByTagName("input");
          // Should be always only one, but this is a general solution
          if (inputs.length > 0) {
            Array.from(inputs).forEach((input) => input.classList.add("my-input-class"));
          }
          return component;
        }

        return component;
      },
    });
  }, []);

  return (
    <div>
      <div id="form-container" />
    </div>
  );
};

Submit button

This example shows how to replace an original submit button element with a totally new one.

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKForm = () => {
  React.useEffect(() => {
    IKUICore.renderForm({
      renderElementSelector: "#form-container",
      onSuccess: (data) => {
        console.log(data);
      },
      onFail: (error) => {
        console.error(error);
      },
      onRenderComponent: (
        component: HTMLElement,
        componentType: string,
        componentSubtype: string,
        ...rest: unknown[]
      ) => {
        if (componentType === "form" && componentSubtype === "submit") {
          const [clickHandler] = rest as [Function];
          const newButton = document.createElement("button");
          newButton.innerText = "Custom submit";
          newButton.addEventListener("click", clickHandler as any);
          return newButton;
        }

        return component;
      },
    });
  }, []);

  return (
    <div>
      <div id="form-container" />
    </div>
  );
};

Replace an action button

Here you can see how to replace the default <a> link with a custom <button> element.

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKForm = () => {
  React.useEffect(() => {
    IKUICore.renderForm({
      renderElementSelector: "#form-container",
      onSuccess: (data) => {
        console.log(data);
      },
      onFail: (error) => {
        console.error(error);
      },
      actionLabels: {
        KEY_FORGOTTEN: "Forgotten password?",
        KEY_REGISTER: "Register",
      },
      onRenderComponent: (
        component: HTMLElement,
        componentType: string,
        componentSubtype: string,
        ...rest: unknown[]
      ) => {
        if (componentType === "action" && componentSubtype === "forgotten") {
          const [label] = rest as [string];
          const buttonEl = document.createElement("button");
          buttonEl.innerText = label;
          return buttonEl;
        }

        return component;
      },
    });
  });

  return (
    <div>
      <div id="form-container" style={{ width: 350 }} />
    </div>
  );
};

Replace an OIDC provider button

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKForm = () => {
  React.useEffect(() => {
    IKUICore.renderForm({
      renderElementSelector: "#form-container",
      onSuccess: (data) => {
        console.log(data);
      },
      onFail: (error) => {
        console.error(error);
      },
      onRenderComponent: (component: HTMLElement, componentType: string, ...rest: unknown[]) => {
        if (componentType === "oidcButton") {
          const [provider, clickHandler, id, url] = rest as [string, Function, string, string];
          const buttonEl = document.createElement("button");
          buttonEl.innerText = provider;
          buttonEl.addEventListener("click", clickHandler as any);
          buttonEl.id = id;
          return buttonEl;
        }

        return component;
      },
    });
  });

  return (
    <div>
      <div id="form-container" style={{ width: 350 }} />
    </div>
  );
};

Replace a message label

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKForm = () => {
  React.useEffect(() => {
    IKUICore.renderForm({
      renderElementSelector: "#form-container",
      onSuccess: (data) => {
        console.log(data);
      },
      onFail: (error) => {
        console.error(error);
      },
      onRenderComponent: (component: HTMLElement, componentType: string, ...rest: unknown[]) => {
        if (componentType === "message") {
          const [context] = rest as [any];
          const newMessageEl = document.createElement("div");
          newMessageEl.innerHTML = `
            <b>${context.style}:</b> ${context.msg}
          `;
          return newMessageEl;
        }

        return component;
      },
    });
  });

  return (
    <div>
      <div id="form-container" style={{ width: 350 }} />
    </div>
  );
};

Transition from render to renderForm function

Add a Terms & Conditions section

In order to make some customizations in the rendered form, you can use the onBeforeRender property. This function is called with the prepared form which will be rendered. You have an option to customize it as you wish. For example, you can put your Terms & Conditions content to the bottom of the screen, as shown in the following example.

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKForm = () => {
  React.useEffect(() => {
    IKUICore.renderForm({
      renderElementSelector: "#form-container",
      onSuccess: (data) => {
        console.log(data);
      },
      onFail: (error) => {
        console.error(error);
      },
      onRenderComponent: (
        component: HTMLElement,
        componentType: string,
        componentSubtype: string,
        ...rest: unknown[]
      ) => {
        // Use this function in order to change the Register button label
        if (componentType === "form" && componentSubtype === "submit") {
          const [clickHandler, label, context] = rest as [Function, string, any];
          if (context["~ui"].startsWith("passwordCreate")) {
            component.innerText = "Agree & Register";
          }
        }
        return component;
      },
      onBeforeRender: (form) => {
        const termsAndConditionsEl = document.createElement("div");

        // You can put any "Terms & Conditions" content you want here.
        termsAndConditionsEl.innerHTML = "<b>Terms & Conditions</b>";

        const uiContainerEl = form.querySelector(".ui-container");
        uiContainerEl?.appendChild(termsAndConditionsEl);
        return form;
      },
    });
  });

  return (
    <div>
      <div id="form-container" style={{ width: 350 }} />
    </div>
  );
};

If the onBeforeRender property returns a nullable value, then the original form content is used.

Add password policies under an input field

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const policiesEl = document.createElement("div");

const checkPolicies = () => {
  const inputEl = document.getElementById("IKUISDK-input-password") as HTMLInputElement;
  policiesEl.innerHTML = "";

  if (inputEl.value.length < 4) {
    policiesEl.innerHTML = "The password must be at least 4 characters long";
    return false;
  }

  return true;
};

const IKForm = () => {
  React.useEffect(() => {
    IKUICore.renderForm({
      renderElementSelector: "#form-container",
      onSuccess: (data) => {
        console.log(data);
      },
      onFail: (error) => {
        console.error(error);
      },
      onRenderComponent: (
        component: HTMLElement,
        componentType: string,
        componentSubtype: string,
        ...rest: unknown[]
      ) => {
        // Firsty we need to check the type of the rendered component
        // (in general, the third argument doesn't have to be a component subtype)
        if (componentType === "form") {
          if (componentSubtype === "password-confirm") {
            const wrapperEl = document.createElement("div");

            // append the original input element
            wrapperEl.appendChild(component);

            // append the container where missing policies will be written when they are not met
            wrapperEl.appendChild(policiesEl);
            return wrapperEl;
          } else if (componentSubtype === "submit") {
            const [handleClick, label, context] = rest as [Function, string, any];

            // We don't want to add the policies checker to the login screen
            if (context["~ui"].startsWith("passwordCreate")) {
              // We don't want to call the default click handler (that wouldn't check the policies)
              component.removeEventListener("click", handleClick as any);

              // We want to call a custom one which checks the policies
              component.addEventListener("click", (ev) => {
                ev.preventDefault();

                // the checkPolicies returns `true` only when the policies are fulfilled
                if (checkPolicies()) {
                  // in that case we can run the original click handler
                  handleClick(ev);
                }
              });
            }
          }
        }

        return component;
      },
    });
  });

  return (
    <div>
      <div id="form-container" style={{ width: 350 }} />
    </div>
  );
};

Add action button translations

In the authentication builder in action nodes, you can specify your own locale keys. Then, using the actionLabels property, you can map your custom messages.

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKForm = () => {
  React.useEffect(() => {
    IKUICore.renderForm({
      renderElementSelector: "#form-container",
      onSuccess: (data) => {
        console.log(data);
      },
      onFail: (error) => {
        console.error(error);
      },
      actionLabels: {
        KEY_FORGOTTEN: "Forgotten password?",
        KEY_REGISTER: "Register",
      },
    });
  });

  return (
    <div>
      <div id="form-container" style={{ width: 350 }} />
    </div>
  );
};

Redirect to a different URL after clicking an action button

The redirection is not directly supported, because it's not necessary (and it causes your authflow to restart from the beginning). But, if you still want to do it, you can replace the original action link with your custom one. In this case, the componentSubtype is a name of the action used in the authentication builder.

import ReactDOM from "react-dom";
import { IKUICore } from "@indykiteone/indykite-sdk-web";

const IKForm = () => {
  React.useEffect(() => {
    IKUICore.renderForm({
      renderElementSelector: "#form-container",
      onSuccess: (data) => {
        console.log(data);
      },
      onFail: (error) => {
        console.error(error);
      },
      actionLabels: {
        KEY_FORGOTTEN: "Forgotten password?",
        KEY_REGISTER: "Register",
      },
      onRenderComponent: (
        component: HTMLElement,
        componentType: string,
        componentSubtype: string,
      ) => {
        // We want to open a different URL after the "Forgotten password" action is clicked
        if (componentType === "action" && componentSubtype === "forgotten") {
          const newActionEl = component.cloneNode(true) as HTMLElement;
          const linkEl = newActionEl.querySelector("a");
          linkEl?.addEventListener("click", () => {
            window.location.href = "https://newpage.com";
          });
          return newActionEl;
        }

        return component;
      },
    });
  });

  return (
    <div>
      <div id="form-container" style={{ width: 350 }} />
    </div>
  );
};

CSS

Originally, the SDK was released with inline styling, but it was too difficult for developers to override the styles with custom ones. Now, inline styling is deprecated and you should import a CSS file with the styles. If you want to use our default CSS file, you can import it from the package like this:

import "@indykiteone/indykite-sdk-web/dist/styles.css";

To start using this CSS approach, you need to set the disableInlineStyles property in your IKUIInit call. See the Init section.

TypeScript

The library has built-in types and is compatible with typescript projects.

SDK Development

Look into using npm link in case you want to develop the lib with the app
https://medium.com/dailyjs/how-to-use-npm-link-7375b6219557

In case you update the response don't forget to update CommonJS docs and also any typescript definitions.

Commit message follows commit guidelines

Install husky pre-commit hooks npm install & npm run prepare

Localisation development

All the messages and keys are stored in the localise.com app under project Indykite https://app.lokalise.com/project/5428220160b483af770945.85338584/

All the keys for only UI SDK should have tag uisdk.

To export new localisation keys and error messages. Go to download page https://app.lokalise.com/download/5428220160b483af770945.85338584/

Download settings are as follows:

Format: JSON
- Include all platform keys YES

Plural format: ICU
Placeholder format: ICU

Click on build and download. Put the final JSONs into folder lib/services/core/locale/src See file .github/export-settings.png for the export settings from localise.

Roadmap

Checkout our roadmap on our issues page

Contributing

Contribution guidelines for this project

Support, Feedback, Connect with other developers

We'd love to have you connect with us or other community developers over at IndyKite.one

Feel free to file a bug, submit an issue or give us feedback on our issues page

Vulnerability Reporting

Responsible Disclosure

Changelog

Coming Soon!

Contributers / Acknowledgements

Coming Soon!

What is IndyKite

IndyKite is a cloud identity platform built to secure and manage human & non-person (IoT) identities and their data. Based on open source standards, the cloud platform gives developers the ability to secure data and embed identity controls into their Web 3.0 applications. Empowering the world’s 23 million developers without the need to involve security and identity specialists.

License

This project is licensed under the terms of the Apache 2.0 license.