@jaaahn/hyper-id-client
v2.0.0
Published
**This library is for internal use only.**
Readme
HyperID Client Library
This library is for internal use only.
Table of Contents
- Web Client (Browser)
- Web Client: Mental Model
- Web Client: Basic Setup
- Web Client: Using in Components
- Web Client: API Reference
- Web Client: Outline of Authentication Flow
- Web Client: Recommended Patterns
- Web Client: Best Practices
- Server
Web Client (Browser)
Web Client: Mental Model
This library operates in exactly three modes:
| Mode | Has user info | Has valid access token | Meaning |
| ----------- | ------------- | ---------------------- | --------------------------------------------------------------------- |
| loggedOut | ❌ | ❌ | No authenticated session |
| cached | ✅ | ❌ | User known locally (offline or hydration), but no usable access token |
| verified | ✅ | ✅ | Fully authenticated, server access allowed |
Important Design Principles:
- The user is only logged out if:
- The auth server returns 401 or 403
- The user calls
logout()
- Network/server failures never log the user out
- Cached mode allows the app to operate offline
- Verification automatically happens:
- On startup (if online)
- When coming back online
- When a request needs a valid access token
Web Client: Basic Setup
main.js
import useAuth, { configureAuth, initAuth } from "@jaaahn/hyper-id-client/web";
configureAuth({
apiURL: "https://localhost:8080",
webURL: "https://localhost:3000",
publicKey: "your_app_public_key",
includeTokenIn: ["list_of_baseURLs_to_your_first_party_server"],
});
const { addAxiosInterceptors, installVue } = useAuth();
addAxiosInterceptors(axios);
installVue(router);
// if "useAuth" is not used here, call the "initAuth" method synchronouslyWeb Client: Using in Components
import useAuth from "@jaaahn/hyper-id-client/web";
export default {
setup() {
const { user, authMode, isAuthenticated, isVerifiedMode, isCachedMode, authenticate, logout } = useAuth();
return {
user,
authMode,
isAuthenticated,
isVerifiedMode,
isCachedMode,
authenticate,
logout,
};
},
};Web Client: API Reference
The client library exposes three functions:
export default useAuth();
export configureAuth(...);
export initAuth(...);
export getUserId(...);Configuration via configureAuth(config)
Must be called once before using anything else.
configureAuth({
apiURL: string,
webURL: string,
publicKey: string,
includeTokenIn: string[],
suppressErrors?: boolean
});Options
| Option | Required | Description |
| ---------------- | -------- | -------------------------------------------------------- |
| apiURL | ✅ | Base URL of your authentication API |
| webURL | ✅ | Base URL of your auth frontend |
| publicKey | ✅ | Public key for OAuth flow |
| includeTokenIn | ✅ | List of base URLs where access tokens should be attached |
| suppressErrors | ❌ | Prevents visible alert on authentication failure |
Initialization via initAuth()
Note: The initAuth function is automatically invoked if calling "useAuth" the first time. If you call "useAuth" in "main.js", you can omit the separate call to "initAuth".
This function starts authentication lifecycle.
- Performs hydration
- Attempts verification (if online)
- Enables automatic re-verification on reconnect
await initAuth();You may await it if your app depends on verified state before mounting. Do not await it, if only parts of your application UI / logic require a verified state. Use await getUserId() instead.
Composable useAuth()
Returns reactive authentication state and actions:
authMode
authMode.value;One of:
"loggedOut""cached""verified"
user
Reactive user object (or null).
user.value?.id;user_id
Shortcut for:
user.value?.id ?? null;isAuthenticated
true if not in loggedOut mode.
Equivalent to:
authMode !== "loggedOut";isVerifiedMode
true only when a valid access token is present.
Equivalent to:
authMode === "verified";isCachedMode
true when:
- Offline
- Hydrating
- Server unreachable
Equivalent to:
authMode === "cached";isOnline
Reactive browser online state.
authenticate(redirectToRoute?)
Starts OAuth flow.
authenticate("/");After successful authentication:
- Access token stored (session)
- Refresh token stored (localStorage)
- User fetched
- Mode becomes
verified
logout()
Logs user out.
- Notifies server (if online)
- Clears refresh token
- Clears cached user
- Switches to
loggedOut
openAccountSettings()
Opens auth provider profile page.
getAccessToken()
Returns current access token (or null).
getAccessTokenExpiresAt()
Returns expiration date.
readAppData()
const data = await readAppData();Throws if not verified.
writeAppData(payload)
await writeAppData({ theme: "dark" });Throws if not verified.
The data object should be a dictionary containing key-value pairs.
Only strings can be stored as values. Any non-ASCII characters are automatically removed from keys.
If a key is set to null, it will be deleted from the DB. If an existing key is not mentioned, it won't be touched.
Example:
{
"hello": "world",
"foo": 2, // Will be transformed to string
"bar": true, // Will be transformed to string
"test": null // Will delete the key `test` from the DB
}Warning: This does NOT perform escaping so make shure to have a XSS preventioning system implemented if storing user generated content
addAxiosInterceptors(axiosInstance)
Automatically:
- Waits for initialization
- Refreshes expired tokens
- Attaches access token to whitelisted URLs
addAxiosInterceptors(axios);installVue(router)
Adds OAuth callback route:
/auth/callbackHandles:
- Authorization code exchange
- Access token retrieval
- Refresh token storage
- User fetch
- Cleanup of URL params
Helper Function getUserId(enforce?=true)
Returns a promise => can be awaited. Promise resolves to a plain number, not a vue reactive ref.
Use this function if your app logic has to wait until authentication initialization is completed and then needs the user's id.
This function is effectively a shortcut for:
let { user_id, initPromise } = useAuth();
await initPromise;
if (user_id.value == null) throw new Error("User must be logged in to use this feature");Web Client: Outline of Authentication Flow
Startup
- Check for refresh token
- If none →
loggedOut - If user cached →
cached - If online → attempt verification
Verification
- Exchange refresh token → access token
- If denied (401/403) →
loggedOut - If network error →
cached - If success → fetch user →
verified
Offline Handling
If browser goes offline:
- Mode remains unchanged
- Access token is not cleared
- Server calls will fail naturally
If browser comes back online:
- If in
cachedmode → automatic verification attempt
Web Client: Recommended Patterns
Awaitable getUserId
If your application logic needs to get the user's id and should halt until verification has been attempted, then use:
const user_id = await getUserId();If user_id can also be null, but you still want to await verification, turn "enforce" off:
const user_id = await getUserId(false);Await verification
If your application logic needs to await a verification attempt, use initPromise exposed by useAuth
let { user, initPromise } = useAuth();
await initPromise;
if (user.value == null) throw new Error("User must be logged in to use this feature");After await initPromise:
- Verification has been ATTEMPTED
- You're now in one of:
- verified mode (success)
- cached mode (network error, but user known)
- loggedOut mode (denied or no refresh token)
Show offline badge
if (isCachedMode.value) {
// Show "Offline Mode"
}Require full verification for critical features
let { isVerifiedMode, initPromise } = useAuth();
await initPromise;
if (!isVerifiedMode.value) {
throw new Error("Feature requires online authentication");
}Show user immediately during hydration
Since cached mode exposes user, your UI can render immediately without waiting for verification.
Web Client: Best Practices
- ✅ Always call
configureAuth()before anything else, followed by either auseAuthorinitAuthcall to kick-off initialization - ✅ Use
isVerifiedModefor server-protected features - ✅ Use
isAuthenticatedfor general UI state - ✅ Await
initPromiseif app logic shall wait until initialization is done - ✅ Use
await getUserId()if app logic shall wait until initialization is done and then get the user's id - ✅ Never manually mutate authMode
Server
Initialization
// auth.js
import { serverInstance } from "@jaaahn/hyper-id-client/server";
// Create new auth server instance
let auth = new serverInstance({
apiURL: "https://localhost:8080",
privateKey: "your_app_private_key",
});
export default auth;Express Middleware
// Add the middleware to your express application in "index.js"
app.use(auth.express.validateSession());
// If you require an authenticated user for a route
app.get("/myRoute", auth.express.enforceSession(), (request, response) => {
let { user, appdata } = request.hyperid;
});Read User's AppData
await auth.readAppData(user_id);Write User's AppData
await auth.writeAppData(user_id, data);The data object should be a dictionary containing key-value pairs.
Only strings can be stored as values. Any non-ASCII characters are automatically removed from keys.
If a key is set to null, it will be deleted from the DB.
If an existing key is not mentioned, it won't be touched.
Example:
{
hello: "world",
foo: 2, // Will be transformed to string
bar: true, // Will be transformed to string
test: null, // Will delete the key `test` from the DB
}Warning: This does NOT perform escaping so make shure to have a XSS preventioning system implemented if storing user generated content
Get Info About App
await auth.getAppInfo();Get a List of All Users
await auth.getAllUsers();Get One User
await auth.getOneUser(search);Search by user_id or by email.
