UNPKG

elysia-oauth2

Version:

Elysia plugin for OAuth 2.0 Authorization Flow with more than 48 providers

108 lines (105 loc) 3.35 kB
import * as arctic from 'arctic'; export * from 'arctic'; import { Elysia } from 'elysia'; function oauth2(providersCredentials, options = {}) { const providers = {}; const cookieDefaults = { secure: true, sameSite: "lax", path: "/", httpOnly: true, maxAge: 60 * 30, // 30 min ...options.cookie }; for (const provider of Object.keys( providersCredentials )) { providers[provider] = new arctic[provider]( ...providersCredentials[provider] ); } return new Elysia({ name: "elysia-oauth2" }).error("OAUTH2_REQUEST_ERROR", arctic.OAuth2RequestError).derive(function deriveOauth2Methods({ cookie, query, redirect }) { return { oauth2: { createURL: (provider, ...options2) => { const state = arctic.generateState(); cookie.state.set({ value: state, ...cookieDefaults }); if ([3, 2].includes( providers[provider].validateAuthorizationCode.length )) { const codeVerifier = arctic.generateCodeVerifier(); cookie.codeVerifier.set({ value: codeVerifier, ...cookieDefaults }); options2.unshift(codeVerifier); } return providers[provider].createAuthorizationURL( state, ...options2 ); }, // TODO: reuse createURL method redirect: async (provider, ...options2) => { const state = arctic.generateState(); cookie.state.set({ value: state, ...cookieDefaults }); if ([3, 2].includes( providers[provider].validateAuthorizationCode.length )) { const codeVerifier = arctic.generateCodeVerifier(); cookie.codeVerifier.set({ value: codeVerifier, ...cookieDefaults }); options2.unshift(codeVerifier); } const url = providers[provider].createAuthorizationURL( state, ...options2 ); return redirect(url.href); }, authorize: async (provider, ...options2) => { if (cookie.state.value !== query.state) throw Error("state mismatch"); cookie.state.remove(); if ([3, 2].includes( providers[provider].validateAuthorizationCode.length )) { if (!cookie.codeVerifier.value) throw new Error( `Bug with ${String( provider )} and codeVerifier. Please open issue` ); options2.unshift(cookie.codeVerifier.value); cookie.codeVerifier.remove(); } const tokens = await providers[provider].validateAuthorizationCode( query.code, ...options2 ); return tokens; }, refresh: async (provider, ...options2) => { const tokens = await providers[provider].refreshAccessToken( ...options2 ); return tokens; }, revoke: async (provider, ...options2) => { const response = await providers[provider].revokeToken(...options2); return response; } } }; }).as("plugin"); } export { oauth2 };