Versionv1

This article is for sites built with only HTML, CSS, and JavaScript (no React). It replaces the old pages at
developers.intastellarsolutions.com/identity/sign-in/web/docs/js-docs.

Behaviour matches the published npm package @intastellar/signin-sdk-react (see dist/api.js / dist/useIntastellar.js, e.g. api.js on jsDelivr). Your plain JS should follow the same flow so it stays compatible with Intastellar Accounts.

Note: Automated requests to the legacy js-docs URL sometimes receive only the site shell, not the full article. This page is the supported home for that material.

What you need (checklist)

  • HTTPS in production (popups and cookies).
  • Popups allowed for your origin.
  • Intastellar client ID and registered app display name (appName / service).
  • A small build step (esbuild, Vite, Webpack, etc.) that bundles @intastellar/signin-sdk-react for the browser. The package is CommonJS and declares React as a peer dependency; if the bundler pulls React for a bundle that only uses IntastellarAPI, stub or omit React or install peers so resolution succeeds.

Legacy script tag (do not use)

The old template used:

<script src="https://account.api.intastellarsolutions.com/insign/client.js"></script>

That URL returns 404. New sites should use IntastellarAPI from the npm package (bundled for the browser), not that legacy URL.

Frequently asked questions

Prefer React?

Use @intastellar/signin-sdk-reactIntastellar Sign-In — React and JavaScript.

The flow requires window.open. Ask visitors to allow popups for your site. See Logout, errors, and troubleshooting.

“Nothing happens” after login in the popup

You must post a message back to the popup when you receive the token (see the flow below). Skipping that step breaks the hosted flow.

This flow sets inta_acc on success (see example below). Treat it as part of your integration contract with the SDK behaviour, not as a value to copy from random sites.


Technical reference — configuration (same as IntastellarConfig)

FieldRequiredDefault / notes
appNameYesRegistered service / app display name.
clientIdYesOAuth key sent as query param key.
loginUriNoIf omitted, the SDK uses hostname + port + pathname only (no https://). Used as the continue query parameter.
scopesNoDefault in the React hook is profile. Passed as scope and encoded in entryFlow as btoa(scopes).
typeNo'signin' (default) or 'signup' — changes the hosted URL (see below).
emailNoIf set with type: 'signin', opens the password entry flow URL.

Hosted URLs (IntastellarAPI.buildLoginUrl)

The SDK picks the base URL as follows (api.js):

  • Default (OAuth chooser):
    https://www.intastellaraccounts.com/signin/v2/ws/oauth/oauthchooser
  • Email + sign-in (email set and type === 'signin'):
    https://www.intastellaraccounts.com/signin/v2/ws/oauth/pwd
  • Sign-up (type === 'signup'):
    https://www.intastellaraccounts.com/Signup/

Query parameters include (from the implementation): service (app name), continue (login URI), entryFlow (btoa(scopes)), key (client id), access_id (encoded parent-style host, with port if present), passive, flowName, Entry, scope, and optionally identifier (email).

API base URL and HTTP endpoints

  • Base: https://apis.intastellaraccounts.com (IntastellarAPI.baseUrl).

Verify token (after popup posts the token string to the opener):

  • GET /verify
  • Header: Authorization: Bearer <token>
  • Content-Type: application/json

Current user (first-party cookie session on your domain):

  • GET /usercontent/js/getuser?origin=<window.location.host>
  • credentials: 'include', CORS mode cors
  1. Build the login URL with IntastellarAPI.buildLoginUrl(...).

  2. Open it with:

    window.open(url, 'intastellarLogin', 'height=719,width=500,left=100,top=100,resizable=no')
  3. Listen on window for message.

  4. When event.data is a non-empty string (the token), send immediately to the popup:

    loginWindow.postMessage("iframe-token-received", event.origin);

    Omitting this breaks the hosted flow.

  5. Remove your listener, call IntastellarAPI.verifyToken(token), then persist the session. The React hook sets a first-party cookie:

    • Name: inta_acc
    • Value: the token string
    • Domain: parent-style host derived like the SDK’s getDomain() (strip subdomains when the first label is not numeric, then drop any port for the cookie domain)
    • Path: /
    • Expiry: hook uses ~2 years ahead
  6. If the user closes the popup without completing sign-in, clear the interval and remove the listener (the SDK checks popup.closed every second).

In production, validate event.origin against the origins Intastellar documents for your environment before trusting event.data.

Example: index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Sign in</title>
    <link rel="stylesheet" href="/css/site.css" />
  </head>
  <body>
    <button type="button" id="inta-signin">Sign in with Intastellar</button>
    <script src="/js/intastellar-signin-bundle.js"></script>
  </body>
</html>

Build intastellar-signin-bundle.js from an entry file that imports IntastellarAPI and attaches the click handler (see below).

Example: vanilla entry module (mirrors useIntastellar sign-in)

Same control flow as signin() in useIntastellar.js, without React state.

import { IntastellarAPI } from "@intastellar/signin-sdk-react";
 
const config = {
  appName: "Your registered app display name",
  clientId: "your-client-id",
  // loginUri: optional — defaults to hostname + port + pathname
  scopes: "profile",
  type: "signin",
};
 
function getDomain() {
  let domain = window.location.hostname || window.location.host;
  const domainParts = domain.split(".");
  if (domainParts.length > 2) domainParts.shift();
  if (isNaN(Number(domainParts[0]))) domain = domainParts.join(".");
  return domain.split(":")[0];
}
 
function setCookie(name, value, domain, expires) {
  let cookieString = `${name}=${value}; domain=${domain}; path=/`;
  if (expires) cookieString += `; expires=${expires.toUTCString()}`;
  document.cookie = cookieString;
}
 
function openIntastellarSignIn(email) {
  const loginUri =
    config.loginUri ??
    `${location.hostname}${location.port ? ":" + location.port : ""}${location.pathname}`;
 
  const loginUrl = IntastellarAPI.buildLoginUrl({
    appName: config.appName,
    clientId: config.clientId,
    loginUri,
    scopes: config.scopes || "profile",
    email,
    type: config.type || "signin",
  });
 
  const loginWindow = window.open(
    loginUrl,
    "intastellarLogin",
    "height=719,width=500,left=100,top=100,resizable=no",
  );
  if (!loginWindow) {
    alert("Please enable popups for this website");
    return;
  }
 
  function onMessage(event) {
    const token = event.data;
    if (!(token && typeof token === "string")) return;
 
    loginWindow.postMessage("iframe-token-received", event.origin);
    window.removeEventListener("message", onMessage);
 
    IntastellarAPI.verifyToken(token)
      .then((account) => {
        const expires = new Date();
        expires.setFullYear(expires.getFullYear() + 2);
        setCookie("inta_acc", token, getDomain(), expires);
        console.log("Signed in:", account.user);
        if (!loginWindow.closed) loginWindow.close();
      })
      .catch((err) => {
        console.error(err);
        if (!loginWindow.closed) loginWindow.close();
      });
  }
 
  window.addEventListener("message", onMessage);
 
  const timer = setInterval(() => {
    if (loginWindow.closed) {
      clearInterval(timer);
      window.removeEventListener("message", onMessage);
    }
  }, 1000);
}
 
document.getElementById("inta-signin")?.addEventListener("click", () => {
  openIntastellarSignIn();
});

Optional: after a successful sign-in, call IntastellarAPI.getUsers() to align with the SDK’s “who is logged in” check (same cookie + origin behaviour).

Logout (same idea as the hook)

Clear the session cookie on your parent domain and reload, matching the SDK’s logout:

const domain = getDomain();
document.cookie = `inta_acc=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.${domain};`;
window.location.reload();

Last updated