@hiveio/hb-auth
v1.28.4-rc0
Published
Auth library for browser applications that use Beekeeper
Downloads
39
Readme
HB Auth
Auth library for browser applications that use Beekeeper.
The biggest goal of hb-auth library is making operations that require signing by users easier while keeping their keys secure in browser's IndexedDB in an encrypted format. Most important and underlying system of this library is @hiveio/beekeeper. hb-auth provides a minimal API that allows you seamless user authorization for your web application that interacts with Hive Blockchain.
📥 Installation
This is a Node.js module available through the npm registry.
Before installing, download and install Node.js. Node.js 20 or higher is required.
Installation is done using the
npm install command:
npm install @hiveio/hb-authhb-auth is written in TypeScript, so out of the box it gives you clear API spec.
If you want to use development versions of our packages, set @hiveio scope to use our GitLab registry:
echo @hiveio:registry=https://gitlab.syncad.com/api/v4/groups/136/-/packages/npm/ >> .npmrc
npm install @hiveio/hb-auth🛠️ Worker file configuration
This is a crucial step for having hb-auth work since it is based on WebWorkers. Thanks to WebWorkers, user's keys are never exposed to the main thread of your application. Also, if your browser supports SharedWorkers, multiple tabs of your application can share the same worker instance, meaning after user logs in in one tab, other tabs can use the same session without asking user to log in again.
There is a file called worker.js and assets directory in @hiveio/hb-auth package. They should be copied in your public directory where you serve your application.
Path from your public directory should be defined in client options while creating new instance as below. Default value is /auth/worker.js.
new OnlineClient(false, { workerUrl: "/your/path/to/worker.js" })
// or
new OfflineClient({ workerUrl: "/your/path/to/worker.js" })Files inside the assets directory or the assets directory itself should not be renamed as their relative paths are hardcoded in the worker.js file.
Example directory structure of your project:
my-app/
public/
vendor/
auth/
worker.js
assets/
beekeeper_wasm.common-J4dPjPbz.wasmDifferance between OnlineClient and OfflineClient is that OnlineClient connects to a given Hive node in order to verify that user actually has an ownership over the requested account (either direct or indirect via account auths).
💡 Example usage
As a an example you can check example in this project.
This is an application that demonstrates user flow (register, login and logout).
Registering user account in safe storage
import { OnlineClient } from "@hiveio/hb-auth";
const authInstance = new OnlineClient();
await authInstance.initialize();
try {
await authInstance.register(
"guest4test", // username of an existing account on Hive
"password", // password of user's choice for wallet encryption
"5JkFnXrLM2ap9t3AmAxBJvQHF7xSKtnTrCTginQCkhzU5S7ecPT", // private posting key
"posting", // role
true, // strict mode - you can disable it if you want to enable account auths login
);
console.log("User registered successfully in the service worker");
await authInstance.logout("guest4test"); // optional, just to demonstrate logout
await authInstance.logoutAll(); // You can also logout all users
} catch (error) {
console.error(error.message);
}Authenticate without registering
This example shows how to login to existing registered user account without providing private keys.
import { OnlineClient } from "@hiveio/hb-auth";
const authInstance = new OnlineClient();
await authInstance.initialize();
try {
await authInstance.authenticate(
"guest4test", // previously registered user account name
"password", // password used during registration
"posting" // role
);
const userInfo = await authInstance.getAuthByUser("guest4test");
console.log("guest4test logged in data:", userInfo);
} catch (error) {
console.error(error.message);
}Lock and Unlock wallet
import { OnlineClient } from "@hiveio/hb-auth";
const authInstance = new OnlineClient();
await authInstance.initialize();
try {
await authInstance.authenticate(
"guest4test", // previously registered user account name
"password", // password used during registration
"posting" // role
);
await authInstance.lock();
console.log("Wallet locked");
await authInstance.unlock("guest4test", "password"); // Will throw if wrong password
console.log("Wallet unlocked");
} catch (error) {
console.error(error.message);
}Import key for existing account
import { OnlineClient } from "@hiveio/hb-auth";
const authInstance = new OnlineClient();
await authInstance.initialize();
try {
await authInstance.authenticate(
"guest4test",
"password",
"posting"
);
await authInstance.importKey(
"guest4test",
"5KGKYWMXReJewfj5M29APNMqGEu173DzvHv5TeJAg9SkjUeQV78", // Private active key of the account
"active",
);
} catch (error) {
console.error(error.message);
}Get account authorities and invalidate them
import { OnlineClient } from "@hiveio/hb-auth";
const authInstance = new OnlineClient();
await authInstance.initialize();
try {
// First we have to authenticate to a registered account in order to modify it's keys
await authInstance.authenticate(
"guest4test",
"password",
"posting"
);
const auths = await authInstance.getAuthByUser("guest4test");
if(auths === null)
throw new Error("Account not found");
for(const role of auths.registeredKeyTypes) {
console.log("Invalidating existing key for role:", role);
await authInstance.invalidateExistingKey("guest4test", role);
}
} catch (error) {
console.error(error.message);
}List registered users
import { OnlineClient } from "@hiveio/hb-auth";
const authInstance = new OnlineClient();
await authInstance.initialize();
try {
const specificUser = await authInstance.getRegisteredUserByUsername("guest4test");
const allUsers = await authInstance.getRegisteredUsers();
console.log("Specific user:", specificUser);
console.log("All registered users:", allUsers);
} catch (error) {
console.error(error.message);
}Sign transaction using registered account
import { OnlineClient } from "@hiveio/hb-auth";
const authInstance = new OnlineClient();
await authInstance.initialize();
const sigDigest = "ab03729fec712369237321"; // This value should be retrieved from @hiveio/wax transaction
try {
await authInstance.authenticate(
"guest4test",
"password",
"posting"
);
const signature = await authInstance.sign("guest4test", sigDigest, "posting");
console.log("Transaction signature:", signature);
} catch (error) {
console.error(error.message);
}Sign without registering (one-time signing)
import { OnlineClient } from "@hiveio/hb-auth";
const authInstance = new OnlineClient();
await authInstance.initialize();
const sigDigest = "ab03729fec712369237321"; // This value should be retrieved from @hiveio/wax transaction
try {
// Note: We are not authenticating here, just direct signing
const signature = await authInstance.singleSign(
"guest4test",
sigDigest,
"5JkFnXrLM2ap9t3AmAxBJvQHF7xSKtnTrCTginQCkhzU5S7ecPT", // private posting key
"posting"
);
console.log("Transaction signature:", signature);
} catch (error) {
console.error(error.message);
}📖 API Reference
For a detailed API definition, please see our Wiki.
🛠️ Development and Testing
Environment Setup
Clone the repository and install the dependencies:
git clone https://gitlab.syncad.com/hive/hb-auth.git --recurse-submodules
cd hb-auth
corepack enable
pnpm installBuild
Compile the TypeScript source code:
pnpm buildRun Tests
Before running tests, review and copy to .env file from .env.example and set appropriate values.
Execute the test suite:
pnpm test📄 License
This project is licensed under the MIT License. See the LICENSE.md file for details.
