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

oauth2-handler-example

v1.0.0

Published

This is an example project demonstrating how to use the `@blur-effect/oauth2-handler` package with Google Calendar API. The example showcases multi-account support, allowing users to connect and manage multiple Google accounts simultaneously.

Readme

OAuth2 Handler Example

This is an example project demonstrating how to use the @blur-effect/oauth2-handler package with Google Calendar API. The example showcases multi-account support, allowing users to connect and manage multiple Google accounts simultaneously.

Setup Instructions

  1. Install dependencies:
npm install
  1. Create a .env file in the root directory with the following variables:
# Server Configuration
PORT=3000
SESSION_SECRET=your-session-secret

# Google OAuth Configuration
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_CALLBACK_URL=http://localhost:3000/oauth2/callback/google
  1. Set up a Google Cloud Project and OAuth 2.0 credentials:

    • Go to the Google Cloud Console (https://console.cloud.google.com)
    • Create a new project or select an existing one
    • Enable the Google Calendar API for your project
    • Go to Credentials > Create Credentials > OAuth client ID
    • Choose "Web application" as the application type
    • Set the following:
      • Name: Your app name
      • Authorized JavaScript origins: http://localhost:3000
      • Authorized redirect URIs: http://localhost:3000/oauth2/callback/google
    • Copy the Client ID and Client Secret to your .env file
  2. Start the server:

npm start
  1. Visit http://localhost:3000 in your browser

Multi-Account Support

This example demonstrates how to implement multi-account support using the OAuth2 handler:

Testing Multiple Accounts

  1. Log in with your first Google account
  2. Click "Add Another Account" to add additional accounts
  3. Use different Google accounts for each login
  4. Switch between accounts using the "Switch" button
  5. Use "Remove" to delete a specific account
  6. Use "Logout All" to clear all accounts

Implementation Details

The multi-account functionality is implemented through:

  1. Session Storage:

    • Accounts are stored in an array within the Express session
    • Each account maintains its own authentication state and calendar events
  2. Account Management:

    • Active account is tracked via activeAccountIndex in the session
    • Users can switch between accounts without re-authenticating
    • The UI clearly indicates which account is currently active
  3. Token Management:

    • Each account has its own OAuth tokens
    • Individual accounts can be deleted via the UI
    • When an account is removed, its OAuth tokens are properly deleted

Key Methods

Token Store Methods

The UniversalTokenStore class provides these key methods for multi-account support:

  1. getUserAccounts(agentId, provider):
    • Retrieves all user accounts for a specific agent and provider
    • Returns an array of StoredUserData objects containing user info and tokens
    • Used to display multiple connected accounts in the UI
const userAccounts = await store.getUserAccounts(req.sessionID, 'google');
  1. deleteByEmail(agentId, provider, email):
    • Deletes a specific account by its email address
    • Returns a boolean indicating if the deletion was successful
    • Used when removing a specific account
const deleted = await store.deleteByEmail(req.sessionID, 'google', email);
  1. save(agentId, provider, tokens):

    • Saves OAuth tokens for a specific user
    • Also fetches and stores user info using the provider's fetcher
    • Called automatically during OAuth callback
  2. registerProvider(provider, fetcher):

    • Registers a user info fetcher for a specific provider
    • The fetcher is used to retrieve user data from access tokens
    • Essential for storing user information alongside tokens
store.registerProvider('google', new GoogleUserInfoFetcher());

Route Handler Methods

The Express application implements these route handlers for multi-account management:

  1. OAuth Callback Handler - /oauth2/callback/google:

    • Processes OAuth authentication callbacks
    • Retrieves user information and adds to session accounts array
    • Updates existing accounts or adds new ones
  2. Switch Account - /switch-account/:index:

    • Changes the active account by updating activeAccountIndex
    • Preserves all connected accounts in the session
    • Allows switching without re-authentication
  3. Logout Specific Account - /logout/:index:

    • Removes a specific account from the session
    • Deletes the associated token from the token store
    • Updates the active index if needed
  4. Logout All Accounts - /logout-all:

    • Destroys the session entirely
    • Removes all connected accounts at once

Session Management

The application uses Express session middleware to maintain account state:

app.use(async (req, res, next) => {
  // Initialize the accounts array if it doesn't exist
  if (!req.session.accounts) {
    req.session.accounts = [];
  }
  
  // Set the active account if there's at least one and none is active
  if (req.session.accounts.length > 0 && req.session.activeAccountIndex === undefined) {
    req.session.activeAccountIndex = 0;
  }
  
  next();
});

The session stores:

  • accounts: Array of connected user accounts
  • activeAccountIndex: Index of the currently active account

Account Refresh Method

The application refreshes account data on page load:

// In home route handler
if (req.session.accounts && req.session.accounts.length > 0) {
  const userAccounts = await store.getUserAccounts(req.sessionID, 'google');
  
  // Update accounts data if available
  if (userAccounts && userAccounts.length > 0) {
    // Create an updated accounts array preserving our events data
    const updatedAccounts = [];
    
    // Process all stored accounts from the token store
    for (const userData of userAccounts) {
      // Find if we already have this account in the session
      const existingIndex = req.session.accounts.findIndex(
        acc => acc.email === userData.userInfo.email
      );
      
      // Update existing or add new account
      // ...
    }
  }
}

Key Features

  • Google OAuth authentication with multi-account support
  • Google Calendar API integration
  • Session management for multiple accounts
  • Protected routes
  • Calendar event display and management
  • Token deletion by email
  • Account switching interface

Key Implementation Components

  • UniversalTokenStore: Stores tokens and user data, supports multiple accounts per session
  • Multiple Account UI: Displays all connected accounts with active account indication
  • Middleware: Ensures session initialization and account data refreshing

Project Structure

  • src/index.js - Main application file with multi-account implementation
  • src/views/ - EJS templates with account management UI
  • src/public/ - Static assets including CSS for multi-account interface
  • .env - Environment variables (not included in git)

Debugging

The application includes debugging information to help understand the multi-account flow:

  • Debug info panel shows active account index and total accounts
  • Console logs for authentication flow and account management
  • Visual indicators for the active account

API Reference

Routes

  • / - Home page with account list
  • /auth/google - Start Google OAuth flow
  • /oauth2/callback/google - OAuth callback handler
  • /switch-account/:index - Switch to another connected account
  • /logout/:index - Remove a specific account
  • /logout-all - Remove all connected accounts
  • /calendar - View calendar events for the active account
  • /delete-token - API endpoint to delete tokens by email