# swissoid-back SwissOID authentication backend for Node.js applications. Provides reusable OIDC authentication components for integrating with SwissOID (Swiss eID). ## Features - 🔐 Full OIDC Authorization Code Flow implementation - 🍪 Session management with Redis - 🔑 JWT verification with JWKS (for validating SwissOID ID tokens and optional DATs) - 🎯 Built for di-why dependency injection - 📦 Reusable authentication components - 🔄 Configurable via environment variables or appConfig ## Installation ```bash npm install swissoid-back ``` ## Requirements - Node.js >= 18 - Redis server for session storage - SwissOID client credentials ## Usage ### With express-knifey / graphql-knifey (Recommended) `swissoid-back` integrates with `express-knifey` middleware handles so gateways/standalone services can share the same DI wiring used across Cronide: ```typescript import DiContainer, { mergeLDs } from 'di-why'; import { apolloSubgraphServerModularLDGen } from 'graphql-knifey'; import { swissoidAuthLoadDict } from 'swissoid-back'; // Define middleware configuration including OIDC routes const middlewareConfig = { global: [ { name: 'expressCorsMiddleware', priority: 90 }, { name: 'expressCookieParserMiddleware', priority: 80 }, { name: 'expressBodyParserMiddleware', priority: 70 }, { name: 'oidcStandardRoutesMiddleware', priority: 60 }, ], '/graphql': [ { name: 'expressGraphqlMiddleware', required: true, priority: -100 }, ], }; const diContainer = new DiContainer({ load: mergeLDs( // GraphQL server with middleware config apolloSubgraphServerModularLDGen({ resolvers, typeDefs, middlewareConfig }), // SwissOID authentication components swissoidAuthLoadDict, // Your other loaders... ) }); ``` ### Direct Express Usage ```typescript import { swissoidAuthLoadDict } from 'swissoid-back'; // Load OIDC routes directly (this will mount them on the express app) await diContainer.load('oidcStandardRoutes'); ``` ### AppConfig Integration swissoid-back provides an appConfigMap that can be merged with your application's configuration: ```typescript import { swissoidMergeAppConfigMap } from 'swissoid-back'; const merged = swissoidMergeAppConfigMap(yourAppConfigMap); export type AppConfig = ReturnType; ``` ### Configuration Create a `.env` file with the required configuration (see `.env.example` for all options): ```env # SwissOID Configuration SWISSOID_ISSUER=https://api.swissoid.com SWISSOID_CLIENT_ID=your-client-id SWISSOID_CLIENT_SECRET=your-client-secret SWISSOID_TOKEN_ENDPOINT=https://api.swissoid.com/token SWISSOID_JWKS_URI=https://api.swissoid.com/.well-known/jwks.json # Redis Configuration REDIS_HOST=localhost REDIS_PORT=6379 # Session Configuration SESSION_COOKIE_NAME=connect.sid SESSION_SECRET=your-session-secret # Optional: override derived state signing secret # STATE_SIGNING_SECRET=your-state-secret # RP Configuration RP_FRONTEND_URL=http://localhost:3000 COOKIE_DOMAIN=localhost OIDC_REDIRECT_BASE_URL=http://localhost:3668 ``` ### Generating strong secrets Use the helper script to produce high-entropy values for `SESSION_SECRET` and `STATE_SIGNING_SECRET`: ```bash npm run generate:secrets ``` You can also invoke the packaged CLI from your own project: ```bash npx swissoid-back-generate-secrets ``` Example output: ``` SESSION_SECRET=8Qd8d...snipped STATE_SIGNING_SECRET=Ob7v3...snipped # Copy the values above into your deployment secret store (.env, Vault, etc.). # Keep them private and rotate on a regular schedule. ``` - Pass `--derive-state` to derive the state secret from the session secret (mirrors the default behaviour when `STATE_SIGNING_SECRET` is omitted). - Adjust entropy with `--session-bytes=` or `--state-bytes=` if you need different lengths (defaults: 48 bytes for the session secret and 32 for the state secret). ## Routes The package provides the following OIDC routes when loaded: - `GET /login` - Initiates OIDC authorization flow - `POST /oidc/callback` - Handles OIDC callback from SwissOID - `GET /oidc/finalize` - Completes authentication and sets session (gateway subsequently mints a DAT for subgraphs) - `GET /auth/status` - Returns current authentication status - `POST /auth/logout` - Logs out the user - `GET /auth/debug` - Debug endpoint to check session and cookie status - `GET /auth/ping` - Connectivity test endpoint ## Components The `swissoidAuthLoadDict` includes: - **redisClient**: Redis connection for session storage - **sessionService**: Session management service - **cookieManager**: Cookie handling utilities - **oidcStandardRoutes**: Express router with OIDC endpoints - **oidcStandardRoutesMiddleware**: Middleware-compatible version for express-knifey integration - **swissoidAppConfigMap**: AppConfig map with priority 60 ## Exports ```typescript // Main LoadDict for di-why import { swissoidAuthLoadDict } from 'swissoid-back'; // AppConfig utilities import { swissoidMergeAppConfigMap } from 'swissoid-back'; // Individual loaders if needed import { sessionService, cookieManager, oidcStandardRoutes, oidcStandardRoutesMiddleware } from 'swissoid-back'; ``` ## License MIT