Utilities for implementing OAuth2 / OpenID Connect based login in Node.js services --- ## Install ```bash # Update project npm config to refer to correct registry for the @js scope echo '@js:registry=https://gitea.jbrumond.me/api/packages/js/npm/' >> ./.npmrc npm install --save @js/oidc-login # optional - additional supporting typescript definitions npm install --save-dev @js/types ``` ## Usage ### Setup PKCE Provider ```ts import { create_pkce_cookie_provider } from '@js/oidc-login'; const pkce = create_pkce_cookie_provider({ // Cookie name name: 'pkce_verifier_code', // Use "Secure" cookie directive (only send over HTTPS)? secure: true, // Cookie time-to-live (in seconds) ttl: 300, // Number of bytes of random data to generate for the verification // code (more is stronger, must be in range 32-96) code_bytes: 48, }); ``` ### Preparing a PKCE Challenge ```ts const { // This is a `Set-Cookie` header value containing the PKCE verifier // code that should be sent to the client when redirecting to the // OAuth2 provider to start the login process set_cookie_header, // This is the PKCE challenge code that should be sent to the OAuth2 // provider as a parameter in the redirect pkce_code_challenge, } = await pkce.prepare_pkce_challenge(); ``` ### Verifying a PKCE Challenge ```ts // Retrieve the PKCE verifier from the cookie sent back by the client. // This should be sent to the OAuth2 provider when fetching the token set // in the login callback const pkce_code_verifier = pkce.read_pkce_code_verifier(req.headers.cookie); // When responding to the login callback request, send the invalidator cookie // to delete the previous set PKCE cookie res.setHeader('set-cookie', pkce.invalidate_cookie); ``` ### Setup Session Credentials Provider ```ts import { create_session_credentials_provider } from '@js/oidc-login'; const creds = create_session_credentials_provider({ // Cookie name name: 'session_token', // Use "Secure" cookie directive (only send over HTTPS)? secure: true, // Cookie time-to-live (in seconds) ttl: 3600, // Cryptographic hashing function to use for stored secrets hash(secret: string) { // SEE BELOW return ''; }, // Verification function for the hashing function above verify_hash(secret: string, hashed_secret: string) { // SEE BELOW return true; }, }); ``` #### Using argon2 hashing ```bash npm install --save argon2 ``` ```ts import { hash, verify, argon2id } from 'argon2'; import { create_session_credentials_provider } from '@js/oidc-login'; const creds = create_session_credentials_provider({ name: 'session_token', secure: true, ttl: 3600, hash(secret: string) { return hash(password, { type: argon2id, // hash options... }); }, verify_hash(secret: string, hashed_secret: string) { return verify(hashed_secret, secret); }, }); ``` ### Creating New Sessions ```ts const { // This is a `Set-Cookie` header value containing the new session token // that can be sent to a client to finish a web login process set_cookie_header, // The hashed secret that should be stored for later verification hashed_secret, // The session token details session_token: { // Unique prefix string that can be used to lookup the session // for later verification prefix, // The secret value generated for token secret, // The complete, raw token string token, }, } = await creds.prepare_new_session_credentials(); ```