Skip to main content

Requirements

  • Node.js 18.0 or later
  • No external dependencies

Installation

Use the single-file SDK directly from GitHub:
Download authforge.mjs and copy it into your project.If you are using TypeScript, also download authforge.d.ts.

TypeScript projects

For TypeScript projects, copy both files into the same directory:
  • authforge.mjs
  • authforge.d.ts
Then import normally:
import { AuthForgeClient } from "./authforge.mjs";
If your TypeScript setup does not automatically resolve the adjacent declaration file, add a local shim:
// authforge-local.d.ts
declare module "./authforge.mjs" {
  export * from "./authforge";
}

Quick start

import { AuthForgeClient } from "./authforge.mjs";
import * as readline from "node:readline/promises";

const client = new AuthForgeClient({
    appId: "YOUR_APP_ID",
    appSecret: "YOUR_APP_SECRET",
    heartbeatMode: "SERVER",
});

const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
const key = await rl.question("Enter license key: ");
rl.close();

if (await client.login(key)) {
    console.log("Authenticated!");
    // Your app logic here - heartbeats run in the background
} else {
    console.error("Invalid license key.");
    process.exit(1);
}

Constructor parameters

const client = new AuthForgeClient({
    appId: "YOUR_APP_ID",                     // Required - from dashboard
    appSecret: "YOUR_APP_SECRET",             // Required - from dashboard
    heartbeatMode: "SERVER",                  // Required - "SERVER" or "LOCAL"
    heartbeatInterval: 900,                   // Optional - seconds (default: 900 = 15 min)
    apiBaseUrl: "https://auth.authforge.cc",  // Optional
    onFailure: null,                          // Optional - callback(reason, exception)
    requestTimeout: 15,                       // Optional - HTTP timeout in seconds
});

Login

const success = await client.login(licenseKey);
Returns Promise<boolean>. It resolves to true if authentication succeeded, false otherwise. On success, the SDK starts background heartbeats automatically.

Failure callback

If authentication or a heartbeat fails, the SDK calls your onFailure callback. If no callback is set (or the callback throws), the SDK exits the process.
function handleFailure(reason, exception) {
    if (reason === "login_failed") {
        console.error("Login failed - check your license key.");
        return;
    }

    if (reason === "heartbeat_failed") {
        console.error("Heartbeat failed - saving state and shutting down.");
        saveApplicationState();
    }
}

const client = new AuthForgeClient({
    appId: "YOUR_APP_ID",
    appSecret: "YOUR_APP_SECRET",
    heartbeatMode: "SERVER",
    onFailure: handleFailure,
});
If you don’t set onFailure, the SDK terminates the process immediately on any failure. Set a callback in production for graceful shutdown.

Reading variables

After successful login, app variables and license variables are available on the client:
if (await client.login(licenseKey)) {
    // App-wide variables (set in dashboard or API)
    const appVars = client.appVariables;
    if (appVars.maintenanceMode) {
        console.log("Server is under maintenance.");
        process.exit(0);
    }

    // Per-license variables
    const plan = client.licenseVariables.plan ?? "basic";
    if (plan === "pro") {
        enableProFeatures();
    }
}

Heartbeat modes

// SERVER mode - validates with the API every interval
const serverClient = new AuthForgeClient({
    appId: "YOUR_APP_ID",
    appSecret: "YOUR_APP_SECRET",
    heartbeatMode: "SERVER",
    heartbeatInterval: 900,
});

// LOCAL mode - verifies locally, re-validates when prepaid block expires
const localClient = new AuthForgeClient({
    appId: "YOUR_APP_ID",
    appSecret: "YOUR_APP_SECRET",
    heartbeatMode: "LOCAL",
    heartbeatInterval: 900,
});
See Heartbeat Modes for a detailed comparison.

Full example

import { AuthForgeClient } from "./authforge.mjs";
import * as readline from "node:readline/promises";

function saveState() {
    console.log("Saving application state...");
    // Your save logic here
}

const client = new AuthForgeClient({
    appId: "YOUR_APP_ID",
    appSecret: "YOUR_APP_SECRET",
    heartbeatMode: "SERVER",
    heartbeatInterval: 900,
    onFailure: (reason, exception) => {
        console.error(`Auth failure: ${reason}`);
        if (exception) {
            console.error(`Detail: ${exception.message ?? exception}`);
        }
        saveState();
        process.exit(1);
    },
});

const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
const key = await rl.question("Enter license key: ");
rl.close();

if (!(await client.login(key))) {
    console.error("Invalid license key.");
    process.exit(1);
}

console.log("Licensed and running!");

const minVersion = client.appVariables.minVersion;
if (minVersion && APP_VERSION < minVersion) {
    console.error(`Please update to version ${minVersion} or later.`);
    process.exit(1);
}

process.on("SIGINT", () => {
    saveState();
    process.exit(0);
});

setInterval(() => {
    // Your app logic here
}, 1000);

GitHub

Full source, changelog, and issues: AuthForgeCC/authforge-node