Requirements
- Node.js 18.0 or later
- No external dependencies
Installation
Use the single-file SDK directly from GitHub:
Direct download
curl
Git clone
Download authforge.mjs and copy it into your project.If you are using TypeScript, also download authforge.d.ts. curl -O https://raw.githubusercontent.com/AuthForgeCC/authforge-node/main/authforge.mjs
# Optional for TypeScript projects:
curl -O https://raw.githubusercontent.com/AuthForgeCC/authforge-node/main/authforge.d.ts
git clone https://github.com/AuthForgeCC/authforge-node.git
cp authforge-node/authforge.mjs ./your-project/
# Optional for TypeScript projects:
cp authforge-node/authforge.d.ts ./your-project/
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