@xfinitypros/sdk
v0.2.5
Published
Official Xfinity Pros Group API SDK
Readme
@xfinitypros/sdk
The official TypeScript/JavaScript SDK for the Xfinity Pros Group (XPG) API.
This library provides a strongly typed, cross-platform client for web applications, server components, desktop clients (Tauri/Electron), and mobile platforms to communicate securely with api.xfinitypros.com.
🔒 Security Notice:
@xfinitypros/sdkis purely a client communication layer over HTTPS. It never contains direct database connections (PostgreSQL/Drizzle), database credentials, session secrets, or API keys for third-party providers. All security boundaries and business logic are owned and enforced by the XPG API.
For desktop applications, the SDK supports short-lived access tokens, long-lived refresh tokens, authorization codes, and pluggable secure token storage.
Installation
npm install @xfinitypros/sdkor with yarn / pnpm / bun:
pnpm add @xfinitypros/sdk
# or
yarn add @xfinitypros/sdk
# or
bun add @xfinitypros/sdkQuick Start
Basic Client Creation
import { XPGClient } from "@xfinitypros/sdk";
const xpg = new XPGClient();The client defaults to:
https://api.xfinitypros.comEnvironment Configuration
Production
import { XPGClient } from "@xfinitypros/sdk";
export const xpg = new XPGClient({
baseUrl: process.env.NEXT_PUBLIC_XPG_API_URL ?? "https://api.xfinitypros.com",
});Local Development
import { XPGClient } from "@xfinitypros/sdk";
const xpg = new XPGClient({
baseUrl: "http://localhost:4000",
});Authentication
XPG authentication separates user authentication from application authorization.
The main components are:
auth.xfinitypros.com
│
│ User authentication
▼
api.xfinitypros.com
│
│ Authorization Code
▼
Application
│
│ /auth/exchange
▼
Access Token + Refresh TokenThe API owns:
- User accounts
- Password verification
- User status
- Sessions
- Authorization codes
- Access tokens
- Refresh tokens
- Authorization
- Authentication business logic
auth.xfinitypros.com provides the user-facing authentication experience.
The SDK provides the client communication layer.
Authentication Flow
There are two important stages:
Stage 1 — Authenticate the user
The authentication application sends the user's credentials to:
POST /auth/loginThe API verifies the credentials.
When the request is part of an authorization flow, the API creates a short-lived authorization code.
Stage 2 — Exchange the authorization code
The application receives the authorization code and sends it to:
POST /auth/exchangeThe API validates the code and creates/returns an authenticated session with:
- Access token
- Refresh token
- Session information
- User information
The access and refresh tokens are not returned directly from the normal browser login flow.
Desktop Authentication
Desktop applications such as Tauri should normally authenticate through:
auth.xfinitypros.comThe desktop application should not collect or store the user's password.
The recommended flow is:
Tauri Application
│
│ Open browser
▼
auth.xfinitypros.com/authorize
│
│ User logs in
▼
api.xfinitypros.com/auth/login
│
│ Authentication succeeds
▼
Authorization Code Created
│
│ Redirect
▼
xpg-content://auth/callback?code=abc123
│
▼
Tauri Application
│
│ /auth/exchange
▼
api.xfinitypros.com
│
▼
Access Token + Refresh Token
│
├── Access Token → Memory
│
└── Refresh Token → Secure OS StorageAuthorization Requests
A desktop application can start authentication by opening the XPG authentication application.
For example:
https://auth.xfinitypros.com/authorize?client_id=xpg-content&redirect_uri=xpg-content://auth/callbackThe authorization request identifies:
client_id— the application requesting authenticationredirect_uri— where the authorization code should be returned
The authorization server should validate that the client_id and redirect_uri combination is registered and allowed.
Login
The authentication application can use:
const result = await xpg.auth.login({
email,
password,
clientId: "xpg-content",
redirectUri: "xpg-content://auth/callback",
});The API validates the credentials.
For an authorization flow, the API creates a short-lived authorization code and returns information similar to:
{
user: {
id: "usr_123",
email: "[email protected]",
name: "Jane Doe"
},
code: "abc123",
redirectUri: "xpg-content://auth/callback",
expiresAt: "2026-08-12T15:30:00.000Z"
}The authentication application then redirects the browser:
window.location.href = `${result.redirectUri}?code=${encodeURIComponent(result.code)}`;The authorization code is:
- Short-lived
- Single-use
- Associated with the user
- Associated with the client
- Associated with the redirect URI
The API stores a hash of the authorization code rather than the raw code.
Authorization Code Exchange
After authentication, the desktop application receives:
xpg-content://auth/callback?code=abc123The application extracts the authorization code and exchanges it:
const result = await xpg.auth.exchangeCode({
code: "abc123",
clientId: "xpg-content",
});The SDK sends:
POST /auth/exchangewith:
{
"code": "abc123",
"clientId": "xpg-content"
}The API validates and consumes the authorization code.
If successful, it returns:
{
user: {
id: "usr_123",
email: "[email protected]",
name: "Jane Doe"
},
session: {
id: "sess_123",
clientId: "xpg-content",
deviceName: "My Desktop",
expiresAt: "..."
},
accessToken: "...",
refreshToken: "..."
}The SDK automatically stores the returned tokens:
Authorization Code
│
▼
/auth/exchange
│
▼
Access Token + Refresh Token
│
▼
XPGClient.setTokens()
│
▼
XPGTokenStorageAuthorization codes should only be used once.
Tauri Deep-Link Authentication
Tauri applications can register a custom URI scheme such as:
xpg-content://The authentication application redirects to:
xpg-content://auth/callback?code=abc123The Tauri application receives the deep-link URL and extracts:
code=abc123It can then call:
const result = await xpg.auth.exchangeCode({
code,
clientId: "xpg-content",
});After the exchange succeeds, the application has an authenticated XPG session.
The application should then store the refresh token using secure platform storage.
Token Management
The SDK distinguishes between:
- Access token — short-lived credential used for API requests.
- Refresh token — longer-lived credential used to obtain new access tokens.
- Authorization code — short-lived, single-use credential used to establish an application session.
- Token storage — application-provided storage for securely persisting tokens.
The SDK keeps the active access token in memory and can optionally persist both tokens through an XPGTokenStorage implementation.
XPGTokenStorage
The SDK provides an interface rather than deciding where tokens should be stored.
export interface XPGTokenStorage {
getAccessToken(): Promise<string | null>;
getRefreshToken(): Promise<string | null>;
setTokens(tokens: {
accessToken: string;
refreshToken: string;
}): Promise<void>;
clear(): Promise<void>;
}This allows each platform to use an appropriate storage mechanism.
Desktop applications
For Tauri/Electron applications, implement this interface using secure OS credential/keychain storage.
Do not store refresh tokens in:
localStorage- plain JSON files
- normal browser storage
- source code
- environment variables shipped with the application
The refresh token should be treated as a sensitive credential.
Creating a Client with Token Storage
import { XPGClient } from "@xfinitypros/sdk";
import { secureTokenStorage } from "./token-storage";
export const xpg = new XPGClient({
baseUrl: "https://api.xfinitypros.com",
tokenStorage: secureTokenStorage,
});The SDK automatically persists tokens when an authentication method returns an access token and refresh token.
Direct Login
Direct email/password login is available for applications that are intentionally designed to use that flow.
const result = await xpg.auth.login({
email: "[email protected]",
password: "securepassword",
});This authenticates the user with the API.
For authorization-based applications, provide the client and redirect information:
const result = await xpg.auth.login({
email: "[email protected]",
password: "securepassword",
clientId: "xpg-content",
redirectUri: "xpg-content://auth/callback",
});When clientId and redirectUri are provided, the API creates an authorization code.
The login response does not contain the application's access and refresh tokens.
For desktop applications, prefer the browser-based authorization-code flow.
Two-Factor Authentication
If two-factor authentication is required, the authentication application should complete the required verification before creating the authorization code.
The exact two-factor flow is controlled by the XPG authentication service.
Example:
const result = await xpg.auth.verifyTwoFactor({
userId,
code: "123456",
});After successful verification, the authentication flow can continue and create the authorization code for the requesting application.
Current User
Once an application has an access token:
const { user, session } = await xpg.auth.me();
console.log(user);
console.log(session);The SDK automatically includes:
Authorization: Bearer <access-token>when an access token is available.
Refreshing an Access Token
Access tokens are intentionally short-lived.
When an access token expires, use the refresh token to obtain a new token pair:
const result = await xpg.auth.refresh({
refreshToken: "your-refresh-token",
});The SDK automatically replaces the stored tokens:
Old Access Token
Old Refresh Token
│
▼
/auth/refresh
│
▼
New Access Token
New Refresh Token
│
▼
XPGTokenStorage.setTokens()Applications should generally avoid manually passing refresh tokens throughout their code.
A secure token storage implementation should provide the refresh token when required.
Logout
const result = await xpg.auth.logout();
console.log(result.status);
// "success"
console.log(result.message);
// "Logged out successfully"Logout performs two operations:
- Sends the logout request to the API so the server-side session can be revoked.
- Clears the locally stored access and refresh tokens.
await xpg.auth.logout();Bearer Token Management
The current access token can be managed directly when necessary.
Set access token
xpg.setAccessToken("access-token");Get access token
const accessToken = xpg.getAccessToken();Clear access token
xpg.clearAccessToken();These methods only manage the in-memory access token.
They do not replace secure refresh-token storage.
For persistent authentication, prefer:
await xpg.setTokens({
accessToken,
refreshToken,
});and provide an XPGTokenStorage implementation.
Users
The xpg.users module provides access to XPG user operations.
List Users
const users = await xpg.users.list();
console.log(users);The method returns an array of User objects:
const users: User[] = await xpg.users.list();Each user currently contains:
{
id: string;
email: string;
name: string;
status: string;
createdAt: string;
updatedAt: string;
}Example:
const users = await xpg.users.list();
for (const user of users) {
console.log(user.name);
console.log(user.email);
console.log(user.status);
}The underlying API endpoint is:
GET /usersNote: User listing is currently an administrative operation and should be protected by the XPG API's authorization system before being exposed to normal users.
Create User
The SDK can create users through the users module:
const user = await xpg.users.create({
email: "[email protected]",
name: "John Doe",
password: "securepassword",
});The underlying API endpoint is:
POST /usersThe API validates the request and handles password hashing.
The returned user does not contain the user's password or password hash.
Example response:
{
id: "usr_123",
email: "[email protected]",
name: "John Doe",
status: "active",
createdAt: "...",
updatedAt: "..."
}Note: User creation should be protected by the XPG API's authorization system before being exposed to normal users.
Organizations
The xpg.organizations module provides organization management.
List organizations
const organizations = await xpg.organizations.list();Get an organization
const organization = await xpg.organizations.get("org_123");API Requests
All SDK modules use the same authenticated client.
For example:
const users = await xpg.users.list();If an access token exists, the request automatically contains:
Authorization: Bearer <access-token>Other API modules follow the same pattern:
const organization = await xpg.organizations.get("org_123");Error Handling
All API errors are parsed into XPGApiError objects containing status codes and machine-readable error codes.
import { XPGApiError } from "@xfinitypros/sdk";
try {
await xpg.auth.login({
email,
password,
});
} catch (err) {
if (err instanceof XPGApiError) {
console.error("Status:", err.status);
console.error("Code:", err.code);
console.error("Message:", err.message);
}
}For example:
Status: 401
Code: INVALID_PASSWORD
Message: Invalid passwordOther authentication errors may include:
USER_MISSING
USER_INACTIVE
INVALID_PASSWORD
INVALID_AUTHORIZATION_CODE
INVALID_REFRESH_TOKEN
INVALID_2FA_CODE
USER_ALREADY_EXISTSAvailable Modules
The SDK is organized modularly for scalability across XPG applications:
xpg.auth— Authentication, authorization codes, sessions and tokensxpg.users— User listing, creation, profiles and user operationsxpg.organizations— Organization managementxpg.employees— Employee directory and managementxpg.tasks— Task managementxpg.billing— Invoices and billing operationsxpg.accounting— Accounts and ledger operationsxpg.ai— XPG AI provider endpoints
Some modules are planned and may not yet be available in the current SDK version.
Browser and Server Compatibility
@xfinitypros/sdk uses the standard Web fetch API and can be used with:
- Browser applications
- React
- Vue
- Svelte
- Angular
- Next.js
- Next.js Server Components
- Next.js Server Actions
- Node.js
- Bun
- Tauri
- Electron
- React Native
Applications should provide platform-appropriate token storage where persistent authentication is required.
Cookie-Based Authentication
The client supports the standard fetch credentials configuration:
const xpg = new XPGClient({
credentials: "include",
});This can be useful for browser-based applications using HTTP cookies.
For example:
await xpg.auth.me();will make the request with:
credentials: "include";Cookie authentication is primarily useful in browser environments where the API and frontend are configured for secure cookie-based sessions.
Desktop applications should generally use bearer access tokens with secure refresh-token storage instead.
Security Model
The SDK intentionally does not contain authentication secrets or database access.
Application
│
▼
@xfinitypros/sdk
│
│ HTTPS
▼
api.xfinitypros.com
│
├── Authentication
├── Authorization
├── Sessions
├── Authorization Codes
├── Access Tokens
├── Refresh Tokens
├── Business Logic
└── PostgreSQLThe SDK only handles communication with the API and local token management.
Desktop Authentication
The recommended desktop authentication architecture is:
┌──────────────────────┐
│ Tauri Application │
└──────────┬───────────┘
│
│ Open browser
▼
┌─────────────────────────────┐
│ auth.xfinitypros.com │
│ │
│ Login / Registration │
│ 2FA │
└─────────────┬───────────────┘
│
│ /auth/login
▼
┌─────────────────────────────┐
│ api.xfinitypros.com │
│ │
│ Verify credentials │
│ Create authorization code │
└─────────────┬───────────────┘
│
│ redirect
▼
┌─────────────────────────────┐
│ xpg-content://auth/callback │
│ ?code=abc123 │
└─────────────┬───────────────┘
│
│ Deep-link
▼
┌──────────────────────┐
│ Tauri Application │
└──────────┬───────────┘
│
│ /auth/exchange
▼
┌─────────────────────────────┐
│ api.xfinitypros.com │
│ │
│ Validate authorization │
│ code │
│ │
│ Create session │
└─────────────┬───────────────┘
│
│
▼
Access Token
Refresh Token
Session
│
┌──────┴──────┐
│ │
▼ ▼
Memory Secure OS
StorageThis architecture means:
- The desktop application does not collect the user's password.
auth.xfinitypros.comprovides the login experience.api.xfinitypros.comremains the authority for authentication and sessions.- Authorization codes are short-lived and single-use.
- Access tokens are used for normal API requests.
- Refresh tokens are stored securely.
- The SDK does not have direct database access.
Publishing to npm
Make your changes
pnpm run typecheck
pnpm run buildRun tests
pnpm testBump the version
npm version patchOr:
npm version minoror:
npm version majorPublish
npm publishYou might need to npm login again.
Test your login with:
npm whoamiLicense
MIT © Xfinity Pros Group
