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

@theranova/auth-sdk

v0.6.1

Published

Theranova Platform OAuth2 Authentication SDK for frontend applications

Downloads

1,221

Readme

@theranova/auth-sdk

Theranova Platform OAuth2 Authentication SDK for frontend applications.

Highlights

  • handleCallback() supports both standard query callbacks and hash-router callbacks like /#/callback?code=....
  • startSilentRefresh() enables pre-expiry token refresh with cross-tab coordination for SPA apps.
  • syncTokens() lets Electron or other multi-process apps sync short-lived renderer tokens without replaying OAuth callbacks.

Installation

# npm
npm install @theranova/auth-sdk

# pnpm
pnpm add @theranova/auth-sdk

# yarn
yarn add @theranova/auth-sdk

Quick Start

import { TheranovaAuth } from '@theranova/auth-sdk';

// 프로덕션 환경 - issuer 생략 (기본값 사용)
const auth = new TheranovaAuth({
  clientId: 'your-client-id',
  redirectUri: 'https://your-app.com/callback',
});

// Start login flow
await auth.login();

Configuration

interface TheranovaAuthConfig {
  /** OAuth2 client ID */
  clientId: string;
  /** Redirect URI for OAuth2 callback */
  redirectUri: string;
  /** 
   * Authorization server issuer URL (optional)
   * @default 'https://auth.theranova.co.kr'
   */
  issuer?: string;
  /** OAuth2 scopes (default: openid profile email offline_access) */
  scopes?: string[];
  /** Storage key for tokens (default: theranova_auth_tokens) */
  storageKey?: string;
  /** Post-logout redirect URI */
  postLogoutRedirectUri?: string;
  /**
   * Automatically register device after login callback
   * @default true
   */
  autoRegisterDevice?: boolean;
  /**
   * Resource indicator for JWT access token
   * @example 'urn:aira:api'
   */
  resource?: string;
  /**
   * Called when session is revoked or refresh fails
   */
  onSessionRevoked?: (event: SessionRevokedEvent) => void;
}

개발 환경 설정

로컬 개발 시에만 issuer를 override:

const auth = new TheranovaAuth({
  clientId: 'your-client-id',
  redirectUri: 'http://localhost:4200/callback',
  issuer: 'http://localhost:3001', // 로컬 Auth 서버
  resource: 'urn:aira:api',
});

Usage

Login

// Start OAuth2 PKCE login flow
// This will redirect to the authorization server
await auth.login();

Handle Callback

In your callback page:

import { TheranovaAuthError } from '@theranova/auth-sdk';

try {
  const tokens = await auth.handleCallback();
  console.log('Login successful:', tokens);
  // Redirect to your app
  window.location.href = '/dashboard';
} catch (error) {
  if (error instanceof TheranovaAuthError) {
    console.error('Auth failed:', error.canonicalCode, error.errorDescription);
  }
  console.error('Login failed:', error);
}

Hash-router callback URLs are also supported:

https://your-app.com/#/callback?code=...&state=...

Check Authentication

if (auth.isAuthenticated()) {
  console.log('User is logged in');
}

Get Access Token

// Automatically refreshes if expired
const token = await auth.getAccessToken();

// Use in API calls
fetch('/api/data', {
  headers: {
    'Authorization': `Bearer ${token}`,
  },
});

Get User Info

// Get user info from ID token
const userInfo = auth.getUserInfo();
console.log('User:', userInfo.name, userInfo.email);

Get Access Token Claims (JWT decode)

const claims = auth.getAccessTokenClaims();
if (claims?.enrollment_status) {
  console.log('enrollment_status:', claims.enrollment_status);
}

Session Revoked Callback

const auth = new TheranovaAuth({
  clientId: 'your-client-id',
  redirectUri: 'http://localhost:4200/callback',
  issuer: 'http://localhost:3001',
  resource: 'urn:aira:api',
  onSessionRevoked: (event) => {
    console.warn('Session revoked:', event.type, event.canonicalCode);
    // 앱 정책에 따라 재로그인 이동
    window.location.href = '/login';
  },
});

Silent Refresh

Start automatic token refresh after login or token restore:

await auth.handleCallback();
auth.startSilentRefresh();

If another process refreshed the token already, sync the renderer copy without replaying OAuth:

auth.syncTokens({
  accessToken: refreshed.accessToken,
  refreshToken: refreshed.refreshToken,
  expiresIn: refreshed.expiresIn,
});

Local Logout

Clears tokens from the current app only. Other connected apps remain logged in.

auth.logout();
// Redirect to login page
window.location.href = '/login';

Global Logout (SSO)

Logs out from all connected applications via the authorization server.

// Get logout URL (useful if you need to do something before logout)
const logoutUrl = auth.getGlobalLogoutUrl();

// Or logout and redirect immediately
auth.logoutGlobal();

Token Management

TokenManager

For advanced token management:

import { TokenManager } from '@theranova/auth-sdk';

const tokenManager = new TokenManager('my-app-tokens');

// Get tokens
const tokens = tokenManager.get();

// Check if expired
if (tokenManager.isExpired()) {
  // Refresh or re-login
}

// Clear tokens
tokenManager.clear();

Important Notes

  1. Device Management: This SDK handles authentication only. Device management is handled separately by the Theranova Platform.

  2. PKCE: This SDK uses OAuth2 with PKCE (Proof Key for Code Exchange) for enhanced security in public clients (browser apps).

  3. JWT Access Tokens: The Theranova Platform issues JWT access tokens. Opaque tokens are not supported.

  4. SSO Logout: When using logoutGlobal(), all connected applications will be logged out via OIDC front-channel or back-channel logout.

  5. Canonical Error Codes: For enrollment/app gate errors, use TheranovaAuthError.canonicalCode instead of raw message parsing.

License

MIT