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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@starasia/sso-api

v0.0.2

Published

SSO integration package for Node.js backend applications

Readme

@starasia/sso-api

NPM package untuk mempermudah integrasi SSO (Single Sign-On) internal dengan sistem backend Node.js menggunakan Express.js framework.

Features

  • 🔐 JWT verification dengan RS256 algorithm
  • 🚀 Easy Express.js middleware integration
  • ✅ TypeScript support dengan full type definitions
  • 📦 Redis caching untuk token validation (optional)
  • 🔄 Automatic public key caching dan refresh
  • 🛡️ Comprehensive error handling
  • 🎯 Multiple token types support (AUTH, ACCESS, REFRESH)

Installation

npm install @starasia/sso-api

atau dengan yarn:

yarn add @starasia/sso-api

atau dengan pnpm:

pnpm add @starasia/sso-api

Quick Start

import express from 'express'
import { config, auth, AUTH_TYPE, RequestWithAccessToken } from '@starasia/sso-api'

const app = express()
app.use(express.json())

// Initialize SSO
const ssoRouter = config({
  clientId: process.env.SSO_CLIENT_ID!,
  clientSecret: process.env.SSO_CLIENT_SECRET!,
  baseUrl: process.env.SSO_BASE_URL!,
  redisUrl: process.env.REDIS_URL, // optional
})

// Mount SSO routes
app.use('/auth', ssoRouter)

// Protected route example
app.get('/api/profile', 
  auth(AUTH_TYPE.ACCESS), 
  (req, res) => {
    const { tokenPayload } = req as RequestWithAccessToken
    res.json({ user: tokenPayload })
  }
)

app.listen(3000, () => {
  console.log('Server running on port 3000')
})

Authentication Flow

  1. Login: User mengirim email dan password ke POST /auth/login
    • Response: authToken dan redirectUri
  2. Callback: Kirim authToken ke POST /auth/callback
    • Response: idToken, authToken, accessToken, refreshToken
  3. Use Access Token: Gunakan accessToken untuk mengakses protected endpoints
  4. Refresh: Gunakan refreshToken untuk mendapatkan accessToken baru ketika expired

API Reference

Configuration

config(options: SSOConfig): Router

Inisialisasi SSO configuration dan return Express Router dengan SSO routes.

Parameters:

| Name | Type | Required | Default | Description | |------|------|----------|---------|-------------| | clientId | string | Yes | - | SSO client ID | | clientSecret | string | Yes | - | SSO client secret | | baseUrl | string | Yes | - | SSO server base URL | | issuer | string | No | baseUrl | JWT issuer untuk validation | | redisUrl | string | No | undefined | Redis connection URL (optional) | | publicKeyUrl | string | No | ${baseUrl}/auth/public-key | Public key endpoint URL | | publicKeyCacheTTL | number | No | 3600 | Public key cache TTL in seconds |

Example:

const ssoRouter = config({
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret',
  baseUrl: 'https://sso.example.com',
  issuer: 'https://sso.example.com',
  redisUrl: 'redis://localhost:6379',
  publicKeyCacheTTL: 7200,
})

app.use('/auth', ssoRouter)

Middleware

auth(type: AUTH_TYPE): RequestHandler

Authentication middleware untuk protect routes dengan JWT verification.

Token Types:

  • AUTH_TYPE.AUTH - Authentication token
  • AUTH_TYPE.ACCESS - Access token (default)
  • AUTH_TYPE.REFRESH - Refresh token

Example:

import { auth, AUTH_TYPE, RequestWithAccessToken } from '@starasia/sso-api'

// Protect with ACCESS token (default)
app.get('/api/protected', 
  auth(AUTH_TYPE.ACCESS), 
  (req, res) => {
    const { tokenPayload } = req as RequestWithAccessToken
    res.json({ user: tokenPayload })
  }
)

// Protect with AUTH token
app.post('/api/admin', 
  auth(AUTH_TYPE.AUTH), 
  (req, res) => {
    // Only accessible with AUTH token
    res.json({ message: 'Admin access granted' })
  }
)

Routes

Package ini otomatis menyediakan authentication endpoints:

POST /auth/login

Login dengan email dan password. Mengembalikan authToken dan redirectUri.

Request Body:

{
  "email": "[email protected]",
  "password": "password123"
}

Response:

{
  "success": true,
  "data": {
    "authToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
    "redirectUri": "https://app.example.com/callback"
  },
  "message": "Login successful"
}

POST /auth/callback

Handle callback dan exchange authToken untuk mendapatkan semua tokens (idToken, authToken, accessToken, refreshToken).

Request Body:

{
  "authToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Response:

{
  "success": true,
  "data": {
    "idToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
    "authToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
    "accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refreshToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
    "expiresIn": 3600
  },
  "message": "Callback processed successfully"
}

POST /auth/refresh

Refresh access token menggunakan refresh token.

Request Body:

{
  "refreshToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Response:

{
  "success": true,
  "data": {
    "accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refreshToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
    "expiresIn": 3600
  }
}

POST /auth/logout

Logout dan revoke tokens (requires ACCESS token).

Headers:

Authorization: Bearer <access_token>

Response:

{
  "success": true,
  "data": null,
  "message": "Logout successful"
}

GET /auth/userinfo

Get current user information (requires ACCESS token).

Headers:

Authorization: Bearer <access_token>

Response:

{
  "success": true,
  "data": {
    "sub": "user-id-123",
    "email": "[email protected]",
    "name": "John Doe"
  }
}

GET /auth/verify

Verify token validity (requires ACCESS token).

Headers:

Authorization: Bearer <access_token>

Response:

{
  "success": true,
  "data": {
    "valid": true,
    "payload": {
      "sub": "user-id-123",
      "email": "[email protected]",
      "type": "ACCESS",
      "iat": 1234567890,
      "exp": 1234571490
    }
  }
}

GET /auth/health

Health check endpoint.

Response:

{
  "success": true,
  "data": {
    "status": "healthy",
    "timestamp": "2025-01-01T00:00:00.000Z"
  }
}

TypeScript Support

Package ini fully typed dengan TypeScript:

import { 
  config, 
  auth, 
  AUTH_TYPE,
  SSOConfig,
  RequestWithAccessToken,
  PayloadAccessToken 
} from '@starasia/sso-api'

// Configuration types
const ssoConfig: SSOConfig = {
  clientId: 'client-id',
  clientSecret: 'client-secret',
  baseUrl: 'https://sso.example.com',
}

// Extended Request types
app.get('/profile', auth(AUTH_TYPE.ACCESS), (req, res) => {
  const { tokenPayload } = req as RequestWithAccessToken
  // tokenPayload is fully typed as PayloadAccessToken
  console.log(tokenPayload.sub, tokenPayload.email)
})

Error Handling

Package ini menggunakan standardized error responses:

{
  "success": false,
  "error": {
    "message": "Invalid or expired token",
    "statusCode": 401
  }
}

Error Codes:

| Status Code | Error Message | Description | |-------------|---------------|-------------| | 400 | Invalid SSO configuration | Configuration tidak valid | | 400 | Authorization token is required | Token tidak ditemukan | | 400 | Invalid token format | Format token salah | | 401 | Invalid or expired token | Token invalid atau expired | | 401 | Token has expired | Token sudah expired | | 403 | Wrong token type | Token type tidak sesuai endpoint | | 403 | Token has been revoked | Token sudah di-revoke | | 500 | Failed to connect to SSO server | Koneksi ke SSO server gagal | | 500 | Failed to fetch public key | Gagal fetch public key |

Advanced Usage

Custom Error Handler

import { errorHandler, notFoundHandler } from '@starasia/sso-api'

// Use custom error handler
app.use(errorHandler)
app.use(notFoundHandler)

Using Utilities

import { 
  generateChallengeCode, 
  successResponse, 
  errorResponse 
} from '@starasia/sso-api'

// Generate challenge code for OAuth flows
const challenge = generateChallengeCode(32)

// Use response helpers
app.get('/custom', (req, res) => {
  return successResponse(res, { data: 'value' }, 'Success message')
})

Multiple Token Type Protection

import { auth, AUTH_TYPE } from '@starasia/sso-api'

// Different protection levels
app.get('/public', (req, res) => {
  res.json({ message: 'Public endpoint' })
})

app.get('/user', auth(AUTH_TYPE.ACCESS), (req, res) => {
  res.json({ message: 'User endpoint' })
})

app.get('/admin', auth(AUTH_TYPE.AUTH), (req, res) => {
  res.json({ message: 'Admin endpoint' })
})

Environment Variables

Example .env file:

SSO_CLIENT_ID=your-client-id
SSO_CLIENT_SECRET=your-client-secret
SSO_BASE_URL=https://sso.example.com
REDIS_URL=redis://localhost:6379

Requirements

  • Node.js >= 18.0.0
  • Express.js >= 4.18.0

Dependencies

  • axios - HTTP client untuk SSO server communication
  • jsonwebtoken - JWT verification dengan RS256
  • ioredis - Redis client untuk token caching (optional)

Contributing

Contributions are welcome! Please follow these guidelines:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Setup

# Clone repository
git clone https://github.com/starasia/sso-api.git
cd sso-api

# Install dependencies
npm install

# Run development mode
npm run dev

# Run tests
npm test

# Build package
npm run build

# Lint code
npm run lint

# Format code
npm run format

License

MIT © Starasia

Examples

Lihat folder examples/ untuk contoh penggunaan lengkap:

  • examples/basic-usage.ts - Contoh implementasi basic dengan Express.js
  • examples/authentication-flow.md - Dokumentasi lengkap authentication flow dengan curl examples dan frontend integration

Support

For issues and questions, please open an issue on GitHub.