{"id":21310948,"url":"https://github.com/webqit/webflo-oauth2-client","last_synced_at":"2026-05-18T11:05:21.375Z","repository":{"id":57684612,"uuid":"479945529","full_name":"webqit/webflo-oauth2-client","owner":"webqit","description":"Webflo OAuth2 library for Node.js","archived":false,"fork":false,"pushed_at":"2022-07-21T12:37:19.000Z","size":736,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-02T20:08:38.237Z","etag":null,"topics":["nodejs","oauth","oauth2","oauth2-client","webflo"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/webqit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-04-10T07:33:38.000Z","updated_at":"2022-07-30T00:09:04.000Z","dependencies_parsed_at":"2022-09-13T20:20:21.643Z","dependency_job_id":null,"html_url":"https://github.com/webqit/webflo-oauth2-client","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/webqit/webflo-oauth2-client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webqit%2Fwebflo-oauth2-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webqit%2Fwebflo-oauth2-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webqit%2Fwebflo-oauth2-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webqit%2Fwebflo-oauth2-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/webqit","download_url":"https://codeload.github.com/webqit/webflo-oauth2-client/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webqit%2Fwebflo-oauth2-client/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265311871,"owners_count":23745161,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["nodejs","oauth","oauth2","oauth2-client","webflo"],"created_at":"2024-11-21T17:15:17.069Z","updated_at":"2026-05-18T11:05:16.339Z","avatar_url":"https://github.com/webqit.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Webflo OAuth2 Client\n\n\u003c!-- BADGES/ --\u003e\n\n\u003cspan class=\"badge-npmversion\"\u003e\u003ca href=\"https://npmjs.org/package/@webqit/webflo-oauth2-client\" title=\"View this project on NPM\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/@webqit/webflo-oauth2-client.svg\" alt=\"NPM version\" /\u003e\u003c/a\u003e\u003c/span\u003e\n\u003cspan class=\"badge-npmdownloads\"\u003e\u003ca href=\"https://npmjs.org/package/@webqit/webflo-oauth2-client\" title=\"View this project on NPM\"\u003e\u003cimg src=\"https://img.shields.io/npm/dm/@webqit/webflo-oauth2-client.svg\" alt=\"NPM downloads\" /\u003e\u003c/a\u003e\u003c/span\u003e\n\n\u003c!-- /BADGES --\u003e\n\nWebflo OAuth2 library for Node.js.\n\n## Installation\n\n```shell\nnpm i @webqit/webflo-oauth2-client\n```\n\n## Usage\n\n```js\nimport { ConsentFlow } from '@webqit/webflo-oauth2-client';\n```\n\n### Initialization\n\n```js\nconst createConsentFlow = ( httpEvent, fetch ) =\u003e {\n\n    // Client app config\n    const client = {\n        // The application's base URL. E.g. http://localhost:3000/ (local), https://example.com/ (production)\n        baseUrl: process.env.OAUTH2_CALLBACK_HOST,\n        // Application's auth-flow endpoints, relative to base URL\n        callbacks: {\n            // The route where you'll handle signed-in callback from provider screen. (See below: The \"Signed-In\" Callback Route)\n            signedIn: '/auth',\n            // The route where you'll handle signed-out callback from provider screen. (See below: A \"Sign Out\" Route)\n            signedOut: '/',\n        },\n    };\n\n    // Provider: auth0\n    const auth0 = {\n        // Auth0-issued client ID\n        clientId: process.env.AUTH0_CLIENT_ID,\n        // Auth0-issued client secret\n        clientSecret: process.env.AUTH0_CLIENT_SECRET,\n        // OAuth2 server base URL. E.g. https://example.us.auth0.com/\n        baseUrl: process.env.AUTH0_BASE_URL,\n        // Auth0-issued auth-flow endpoints, relative to base URL\n        endpoints: {\n            signIn: '/authorize',\n            token: '/oauth/token',\n            revoke: undefined,\n            signOut: '/v2/logout',\n        },\n        // Parameters for verifying Auth0-issued ID Tokens\n        jwtokens: { jwksUrl: '.well-known/jwks.json', }\n    };\n\n    // Provider: google\n    const google = {\n        // Google-issued client ID\n        clientId: process.env.GOOGLE_CLIENT_ID,\n        // Google-issued client secret\n        clientSecret: process.env.GOOGLE_CLIENT_SECRET,\n        // OAuth2 server base URL. Always https://oauth2.googleapis.com/ for Google\n        baseUrl: process.env.GOOGLE_BASE_URL,\n        // Google-issued auth-flow endpoints, relative to base URL\n        endpoints: {\n            signIn: 'https://accounts.google.com/o/oauth2/v2/auth',\n            token: '/token',\n            revoke: '/revoke',\n            signOut: undefined,\n        },\n        // Parameters for verifying Google-issued ID Tokens\n        jwtokens: { jwksUrl: 'https://www.googleapis.com/oauth2/v3/certs', }\n    };\n\n    // Auth instance\n    return new ConsentFlow( httpEvent, {\n        client, providers: { google/* as default provider */, auth0 },\n    }, fetch );\n\n};\n```\n\n### Initialization Route\n\nAt the application's root handler, you'd initialize oauth2 client into the `context` object that is passed around:\n\n```js\nexport default function( httpEvent, context, next, fetch ) {\n    context.oauth2 = createConsentFlow( httpEvent, fetch );\n    if ( next.pathname ) return next( context );\n    return { titleBar: 'Home' };\n}\n```\n\n### A Protected \"Sign In\" Route\n\nTo protect a route, you'd call the `signIn()` method with optional fields - `{ provider /* defaults to the name of the first provider in list */, scope, audience }`:\n\n```js\nexport default function( httpEvent, context, next, fetch ) {\n    return context.oauth2.signIn( { /* optional */scope: 'openid' }, session =\u003e {\n        // Authenticated...\n        // otherwise this function is not called, and user is redirected to provider sign in screen\n        // session is same as context.oauth2.session\n\n        // Are we going to a protected child page?\n        // session can always be accessed as context.oauth2.session down the hierarchy\n        if ( next.pathname ) return next( context );\n\n        // See what's in auth session\n        console.log( session ); // { access_token, token_type: 'Bearer', scope, provider, info, ...etc }\n        // See what's in session.info\n        console.log( session.info ); // { iss, sub: \u003cuser ID\u003e, exp, ...etc }\n        // (If \"profile\", \"email\" were in the value of the \"scope\" parameter (as an array or a space-delimitted string), other infos would be available: email, name, avatar_url, etc.)\n\n        // Call an API endpoint at provider\n        const provider = context.oauth2.client.provider( /* specify provider name, otherwise default provider is implied */ );\n        const endpoint = '/userinfo'; // Or if defined in provider settings object above: endpoint = provider.endpoints.userinfo\n        const user = await provider.call( session.access_token, endpoint, { ...optionalBody } );\n\n        /*\n        Or if you wish...\n        const user = await fetch( 'https://oauth2.example.com/endpoint', {\n            body: JSON.stringify( { ...optionalBody } ),\n            headers: { 'Content-Type': 'application/json', Authorization: session.access_token }\n        } ).then( res =\u003e res.json() );\n        */\n\n        // Show accounts page\n        return {\n            titleBar: 'My Account',\n            email: user.email,\n        }\n    } );\n}\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eThe \u003ccode\u003econtext.oauth2.signIn()\u003c/code\u003e function could also be called without a callback...\u003c/summary\u003e\n\n```js\nexport default function( httpEvent, context, next, fetch ) {\n    let session, redirect, sessionOrRedirect = context.oauth2.signIn( { /* optional */scope: 'openid' } );\n    if ( sessionOrRedirect instanceof httpEvent.Response ) {\n        // User is being redirected to provider sign in screen\n        return ( redirect = sessionOrRedirect /* formality assignment */ );\n    }\n    // Authenticated...\n    session = sessionOrRedirect;\n    // session is same as context.oauth2.session\n    \n    // Are we going to a protected child page?\n    // session can always be accessed as context.oauth2.session down the hierarchy\n    if ( next.pathname ) return next( context );\n\n    // See what's in auth session\n    console.log( session ); // { access_token, token_type: 'Bearer', scope, provider, info, ...etc }\n    // See what's in session.info\n    console.log( session.info ); // { iss, sub: \u003cuser ID\u003e, exp, ...etc }\n    // (If \"profile\", \"email\" were in the value of the \"scope\" parameter (as an array or a space-delimitted string), other infos would be available: email, name, avatar_url, etc.)\n\n    // Call an API endpoint at provider\n    const provider = context.oauth2.client.provider( /* specify provider name, otherwise default provider is implied */ );\n    const endpoint = '/userinfo'; // Or if defined in provider settings object above: endpoint = provider.endpoints.userinfo\n    const user = await provider.call( session.access_token, endpoint, { ...optionalBody } );\n\n    /*\n    Or if you wish...\n    const user = await fetch( 'https://oauth2.example.com/endpoint', {\n        body: JSON.stringify( { ...optionalBody } ),\n        headers: { 'Content-Type': 'application/json', Authorization: session.access_token }\n    } ).then( res =\u003e res.json() );\n    */\n\n    // Show accounts page\n    return {\n        titleBar: 'My Account',\n        email: user.email,\n    }\n}\n```\n\n\u003c/details\u003e\n\n\n### The \"Signed In\" Callback Route\n\nTo handle the \"signed-in\" redirect from *provider* screen - at the specified callback URL `client.callbacks.signedIn`:\n\n```js\nexport default function( httpEvent, context, next ) {\n    if ( context.oauth2.isSigningIn() /* Detects if a sign-in session is ongoing */ ) {\n        // Performs \"authorization_code\" grant and redirects user back to the original protected route - where signIn() was called\n        return context.oauth2.handleSignInCallback();\n    }\n    // Returns the context.oauth2.session object or false\n    return context.oauth2.isSignedIn()?.info || {};\n}\n```\n\n### A \"Sign Out\" Route\n\nTo perform \"sign out\" at any route:\n\n```js\nexport default function( httpEvent, context, next ) {\n    if ( context.oauth2.isSignedIn() ) {\n        // User is signed-out (and is redirected to provider's sign-out URL, where given),\n        // then redirected back to \"/\" as specified in client.callbacks.signedOut\n        return context.oauth2.signOut();\n    }\n    return next();\n}\n```\n\n## Full Documentation\n\nFull documentation, including integrating other providers, coming soon.\n\n## Issues\n\nTo report bugs or request features, please submit an issue to this repository.\n\n## License\n\nMIT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebqit%2Fwebflo-oauth2-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwebqit%2Fwebflo-oauth2-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebqit%2Fwebflo-oauth2-client/lists"}