npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

oauth-connector

v0.0.9

Published

OAuth Connector SDK for automatic token management and refresh with multiple persistence strategies

Readme

OAuth Connector SDK

A Node.js SDK for OAuth token management with multiple persistence strategies, encryption support, and background token synchronization.

GitHub npm

Features

  • 🔐 Optional Persistence: Local file or remote storage (S3, etc.) - storage strategy is optional
  • 🔒 Encryption Support: AES-256-GCM encryption for token storage
  • 🔄 Automatic Token Refresh: Automatic token refresh when expired or within grace period
  • ⚙️ Multiple OAuth Providers: Zoho, Google, and generic OAuth support
  • 🔁 Background Sync: Automatic token refresh in the background

Installation

npm install oauth-connector

Quick Start

import { Connector, ZohoOAuth } from 'oauth-connector';
import type { ZohoOauthConfig } from 'oauth-connector';

const oauthConfig: ZohoOauthConfig = {
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret',
  accountsDomain: 'accounts.zoho.com',
  refreshToken: 'initial-refresh-token'
};

const serviceConfig = new ZohoOAuth(oauthConfig);

// Create connector WITHOUT storage strategy (in-memory cache only)
const connector = new Connector(serviceConfig);

const token = await connector.getAccessToken();
console.log(token);

Local File Strategy with Zoho

import { Connector, LocalStorageStrategy, ZohoOAuth } from 'oauth-connector';
import type { ZohoOauthConfig } from 'oauth-connector';

const storageConfig = new LocalStorageStrategy({
  filePath: './tokens.json',
  encryptionKey: 'your-encryption-key',
});

const oauthConfig: ZohoOauthConfig = {
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret',
  accountsDomain: 'accounts.zoho.com', // or 'accounts.zoho.eu', 'accounts.zoho.in', etc.
  refreshToken: 'initial-refresh-token'
};

const serviceConfig = new ZohoOAuth(oauthConfig);
const connector = new Connector(serviceConfig, storageConfig);

const token = await connector.getAccessToken();
console.log(token);

Remote Strategy

import { Connector, RemoteStorageStrategy, ZohoOAuth } from 'oauth-connector';
import type { ZohoOauthConfig, TokenData } from 'oauth-connector';
import { S3Client, PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';

const s3Client = new S3Client({ region: 'us-east-1' });
const bucketName = 'my-token-bucket';

const storageConfig = new RemoteStorageStrategy({
  onUpload: async (tokenData: TokenData) => {
    await s3Client.send(new PutObjectCommand({
      Bucket: bucketName,
      Key: 'tokens.json',
      Body: JSON.stringify(tokenData),
    }));
  },
  onDownload: async (): Promise<TokenData | null> => {
   try{
      const response = await s3Client.send(new GetObjectCommand({
        Bucket: bucketName,
        Key: 'tokens.json',
      }));
      const data = await response.Body.transformToString();
      return JSON.parse(data);
   } catch{
      return null;
   }
  },
  encryptionKey: 'your-encryption-key',
});

const oauthConfig: ZohoOauthConfig = {
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret',
  accountsDomain: 'accounts.zoho.com',
  refreshToken: 'initial-refresh-token',
};

const serviceConfig = new ZohoOAuth(oauthConfig);
const connector = new Connector(serviceConfig, storageConfig, {});

Catalyst Cache Strategy

Note: This will work only on Catalyst Function/Appsail.

import { Connector, CatalystCacheStorageStrategy, ZohoOAuth } from 'oauth-connector';
import type { ZohoOauthConfig } from 'oauth-connector';
import { IncomingMessage } from 'http';
import express from 'express';

const app = express();

app.post('/api/oauth', async (req: express.Request, res: express.Response) => {
  const storageConfig = new CatalystCacheStorageStrategy({
    httpReq: req as IncomingMessage,
    key: 'oauth-token',
    encryptionKey: 'your-encryption-key', // Optional
  });

  const oauthConfig: ZohoOauthConfig = {
    clientId: 'your-client-id',
    clientSecret: 'your-client-secret',
    accountsDomain: 'accounts.zoho.com',
    refreshToken: 'initial-refresh-token',
  };

  const serviceConfig = new ZohoOAuth(oauthConfig);
  const connector = new Connector(serviceConfig, storageConfig);

  const token = await connector.getAccessToken();
  res.json({ token });
});

API Reference

Connector

Main class that orchestrates OAuth service and persistence strategy.

Constructor

new Connector(
  oauthService: OAuthService,
  storageStrategy?: StorageStrategy, // Optional
  options?: ConnectorOptions
)

Options

interface ConnectorOptions {
  instanceId?: string;              // Unique ID for multi-instance support
  backgroundSyncIntervalInSecs?: number;  // Seconds between background syncs (if provided, sync is enabled)
  graceExpiryTimeInSecs?: number;   // Seconds - refresh token when expiresAt - graceExpiryTimeInSecs is reached (default: 0)
  debug?: boolean;                  // Enable debug logging
}

Methods

  • getAccessToken(): Promise<string> - Get access token (auto-refreshes if expired). Uses in-memory cache for fast access.
  • refreshToken(): Promise<TokenData> - Manually refresh token
  • destroy(): void - Cleanup resources (stops background sync and clears cache)

Callbacks

connector.onFetchingAccessToken = () => {
  console.log('Fetching token...');
};

connector.onTokenRefreshed = (token: TokenData) => {
  console.log('Token refreshed:', token);
};

connector.onTokenError = (error: Error) => {
  console.error('Token error:', error);
};

Note: If no storage strategy is provided, the connector uses in-memory caching only. Tokens are cached for performance but not persisted across restarts.

Contributing

Contributions are welcome! Please read our Contributing Guide for details on our code of conduct and the process for submitting pull requests.

Repository Links

Development

Build

npm run build

Lint

npm run lint
npm run lint:fix

Format

npm run format

License

This project is licensed under the MIT License - see the LICENSE file for details.