elysia-oauth2
Version:
Elysia plugin for OAuth 2.0 Authorization Flow with more than 48 providers
108 lines (105 loc) • 3.35 kB
JavaScript
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 };