Socket
Socket
Sign inDemoInstall

arctic

Package Overview
Dependencies
37
Maintainers
1
Versions
49
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.3.6 to 0.4.0

dist/providers/microsoft-entra.d.ts

19

dist/index.d.ts
export { Apple } from "./providers/apple.js";
export { AzureAD } from "./providers/azure-ad.js";
export { MicrosoftEntra } from "./providers/microsoft-entra.js";
export { Discord } from "./providers/discord.js";

@@ -12,3 +12,3 @@ export { Facebook } from "./providers/facebook.js";

export type { AppleCredentials, AppleIdTokenClaims, AppleRefreshedTokens, AppleTokens } from "./providers/apple.js";
export type { AzureADIdTokenClaims, AzureADTokens, AzureADUser } from "./providers/azure-ad.js";
export type { MicrosoftEntraIdTokenClaims, MicrosoftEntraTokens, MicrosoftEntraUser } from "./providers/microsoft-entra.js";
export type { DiscordTokens, DiscordUser } from "./providers/discord.js";

@@ -23,1 +23,16 @@ export type { FacebookTokens, FacebookUser } from "./providers/facebook.js";

export { generateCodeVerifier, generateState, OAuth2RequestError } from "oslo/oauth2";
export interface OAuth2Provider {
createAuthorizationURL(state: string): Promise<URL>;
validateAuthorizationCode(code: string): Promise<Tokens>;
refreshAccessToken?(refreshToken: string): Promise<Tokens>;
getUser?(accessToken: string): Promise<{}>;
}
export interface OAuth2ProviderWithPKCE {
createAuthorizationURL(codeVerifier: string): Promise<URL>;
validateAuthorizationCode(code: string, codeVerifier: string): Promise<Tokens>;
refreshAccessToken?(refreshToken: string): Promise<Tokens>;
getUser?(accessToken: string): Promise<{}>;
}
export interface Tokens {
accessToken: string;
}

2

dist/index.js
export { Apple } from "./providers/apple.js";
export { AzureAD } from "./providers/azure-ad.js";
export { MicrosoftEntra } from "./providers/microsoft-entra.js";
export { Discord } from "./providers/discord.js";

@@ -4,0 +4,0 @@ export { Facebook } from "./providers/facebook.js";

@@ -1,2 +0,3 @@

export declare class Apple {
import type { OAuth2Provider } from "../index.js";
export declare class Apple implements OAuth2Provider {
private client;

@@ -3,0 +4,0 @@ private scope;

@@ -1,2 +0,3 @@

export declare class Discord {
import type { OAuth2Provider } from "../index.js";
export declare class Discord implements OAuth2Provider {
private client;

@@ -3,0 +4,0 @@ private scope;

@@ -1,2 +0,3 @@

export declare class Facebook {
import type { OAuth2Provider } from "../index.js";
export declare class Facebook implements OAuth2Provider {
private client;

@@ -3,0 +4,0 @@ private scope;

@@ -1,2 +0,3 @@

export declare class GitHub {
import type { OAuth2Provider } from "../index.js";
export declare class GitHub implements OAuth2Provider {
private client;

@@ -3,0 +4,0 @@ private scope;

@@ -1,2 +0,3 @@

export declare class Google {
import type { OAuth2Provider } from "../index.js";
export declare class Google implements OAuth2Provider {
private client;

@@ -10,4 +11,4 @@ private scope;

});
createAuthorizationURL(state: string, codeVerifier?: string): Promise<URL>;
validateAuthorizationCode(code: string, codeVerifier?: string): Promise<GoogleTokens>;
createAuthorizationURL(state: string): Promise<URL>;
validateAuthorizationCode(code: string): Promise<GoogleTokens>;
getUser(accessToken: string): Promise<GoogleUser>;

@@ -14,0 +15,0 @@ refreshAccessToken(refreshToken: string): Promise<GoogleRefreshedTokens>;

@@ -20,7 +20,6 @@ import { TimeSpan, createDate } from "oslo";

}
async createAuthorizationURL(state, codeVerifier) {
async createAuthorizationURL(state) {
const url = await this.client.createAuthorizationURL({
state,
scope: this.scope,
codeVerifier
state
});

@@ -30,7 +29,6 @@ url.searchParams.set("access_type", this.accessType);

}
async validateAuthorizationCode(code, codeVerifier) {
async validateAuthorizationCode(code) {
const result = await this.client.validateAuthorizationCode(code, {
authenticateWith: "request_body",
credentials: this.clientSecret,
codeVerifier
credentials: this.clientSecret
});

@@ -37,0 +35,0 @@ return {

@@ -1,2 +0,3 @@

export declare class Line {
import type { OAuth2ProviderWithPKCE } from "../index.js";
export declare class Line implements OAuth2ProviderWithPKCE {
private client;

@@ -8,4 +9,4 @@ private scope;

});
createAuthorizationURL(state: string): Promise<URL>;
validateAuthorizationCode(code: string): Promise<LineTokens>;
createAuthorizationURL(codeVerifier: string): Promise<URL>;
validateAuthorizationCode(code: string, codeVerifier: string): Promise<LineTokens>;
getUser(accessToken: string): Promise<LineUser>;

@@ -12,0 +13,0 @@ refreshAccessToken(refreshToken: string): Promise<LineRefreshedTokens>;

import { TimeSpan, createDate } from "oslo";
import { parseJWT } from "oslo/jwt";
import { OAuth2Client } from "oslo/oauth2";
import { OAuth2Client, generateState } from "oslo/oauth2";
const authorizeEndpoint = "https://access.line.me/oauth2/v2.1/authorize";

@@ -18,12 +18,14 @@ const tokenEndpoint = "https://api.line.me/oauth2/v2.1/token";

}
async createAuthorizationURL(state) {
async createAuthorizationURL(codeVerifier) {
return await this.client.createAuthorizationURL({
state,
state: generateState(),
codeVerifier,
scope: this.scope
});
}
async validateAuthorizationCode(code) {
async validateAuthorizationCode(code, codeVerifier) {
const result = await this.client.validateAuthorizationCode(code, {
authenticateWith: "request_body",
credentials: this.clientSecret
credentials: this.clientSecret,
codeVerifier
});

@@ -30,0 +32,0 @@ const parsedIdToken = parseJWT(result.id_token);

@@ -1,10 +0,10 @@

export declare class Spotify {
import type { OAuth2ProviderWithPKCE } from "../index.js";
export declare class Spotify implements OAuth2ProviderWithPKCE {
private client;
private scope;
private clientSecret;
constructor(clientId: string, clientSecret: string, redirectURI: string, options?: {
constructor(clientId: string, redirectURI: string, options?: {
scope?: string[];
});
createAuthorizationURL(state: string): Promise<URL>;
validateAuthorizationCode(code: string): Promise<SpotifyTokens>;
createAuthorizationURL(codeVerifier: string): Promise<URL>;
validateAuthorizationCode(code: string, codeVerifier: string): Promise<SpotifyTokens>;
getUser(accessToken: string): Promise<SpotifyUser>;

@@ -11,0 +11,0 @@ refreshAccessToken(refreshToken: string): Promise<SpotifyTokens>;

@@ -8,4 +8,3 @@ import { TimeSpan, createDate } from "oslo";

scope;
clientSecret;
constructor(clientId, clientSecret, redirectURI, options) {
constructor(clientId, redirectURI, options) {
this.client = new OAuth2Client(clientId, authorizeEndpoint, tokenEndpoint, {

@@ -15,13 +14,12 @@ redirectURI

this.scope = options?.scope ?? [];
this.clientSecret = clientSecret;
}
async createAuthorizationURL(state) {
async createAuthorizationURL(codeVerifier) {
return await this.client.createAuthorizationURL({
state,
codeVerifier,
scope: this.scope
});
}
async validateAuthorizationCode(code) {
async validateAuthorizationCode(code, codeVerifier) {
const result = await this.client.validateAuthorizationCode(code, {
credentials: this.clientSecret
codeVerifier
});

@@ -28,0 +26,0 @@ return {

@@ -1,2 +0,3 @@

export declare class Twitch {
import type { OAuth2Provider } from "../index.js";
export declare class Twitch implements OAuth2Provider {
private client;

@@ -3,0 +4,0 @@ private scope;

@@ -1,2 +0,3 @@

export declare class Twitter {
import type { OAuth2ProviderWithPKCE } from "../index.js";
export declare class Twitter implements OAuth2ProviderWithPKCE {
private client;

@@ -8,3 +9,3 @@ private scope;

});
createAuthorizationURL(state: string, codeVerifier: string): Promise<URL>;
createAuthorizationURL(codeVerifier: string): Promise<URL>;
validateAuthorizationCode(code: string, codeVerifier: string): Promise<TwitterTokens>;

@@ -11,0 +12,0 @@ getUser(accessToken: string): Promise<TwitterUser>;

@@ -1,2 +0,2 @@

import { OAuth2Client } from "oslo/oauth2";
import { OAuth2Client, generateState } from "oslo/oauth2";
const authorizeEndpoint = "https://twitter.com/i/oauth2/authorize";

@@ -16,5 +16,5 @@ const tokenEndpoint = "https://api.twitter.com/2/oauth2/token";

}
async createAuthorizationURL(state, codeVerifier) {
async createAuthorizationURL(codeVerifier) {
return await this.client.createAuthorizationURL({
state,
state: generateState(),
scope: this.scope,

@@ -21,0 +21,0 @@ codeVerifier

{
"name": "arctic",
"type": "module",
"version": "0.3.6",
"version": "0.4.0",
"description": "OAuth 2.0 with built-in providers",

@@ -6,0 +6,0 @@ "main": "dist/index.js",

@@ -11,15 +11,24 @@ # `arctic`

- [Apple](#oauth-20)
- [Azure AD](#oauth-20-with-pkce-flow)
- [Discord](#oauth-20)
- [Facebook](#oauth-20)
- [GitHub](#oauth-20)
- [Google](#oauth-20)
- [LINE](#oauth-20)
- [Spotify](#oauth-20)
- [Twitch](#oauth-20)
- [Twitter](#oauth-20-with-pkce-flow)
### OAuth 2.0
## OAuth 2.0
See [OAuth 2.0 providers](#oauth-20-providers) for instructions.
- Apple
- Discord
- Facebook
- Github
- Google
- Twitch
### OAuth 2.0 with PKCE
See [OAuth 2.0 providers with PKCE](#oauth-20-providers-with-pkce) for instructions.
- Line
- Microsoft Entra
- Spotify
- Twitter
## OAuth 2.0 providers
Most providers require the `client_id` and `client_secret`. You may also optionally pass `scope`. For OIDC clients, `openid` and `profile` scope are always included.

@@ -100,3 +109,3 @@

## OAuth 2.0 with PKCE flow
## OAuth 2.0 providers with PKCE

@@ -125,3 +134,3 @@ Most providers require the `client_id` and `client_secret`. You may also optionally pass `scope`. For OIDC clients, `openid` and `profile` scope are always included.

Generate state and code verifier using `generateState()` and `generateCodeVerifier()`, and store them as cookies. Use them to create an authorization URL with `createAuthorizationURL()` and redirect the user to it.
When using the PKCE flow, `state` is not necessary. Generate a code verifier using `generateCodeVerifier()`, and store it as a cookie. Use them to create an authorization URL with `createAuthorizationURL()` and redirect the user to it.

@@ -131,3 +140,2 @@ ```ts

const state = generateState();
const codeVerifier = generateCodeVerifier();

@@ -137,9 +145,3 @@

// store state and code verifier as cookie
setCookie("state", state, {
secure: true, // set to false in localhost
path: "/",
httpOnly: true,
maxAge: 60 * 10 // 10 min
});
// store code verifier as cookie
setCookie("code_verifier", state, {

@@ -156,3 +158,3 @@ secure: true, // set to false in localhost

Compare the state, and use `validateAuthorizationCode()` to validate the authorization code with the code verifier. This returns an object with an access token, and a refresh token if requested. If the code is invalid, it will throw an `AccessTokenRequestError`.
Use `validateAuthorizationCode()` to validate the authorization code with the code verifier. This returns an object with an access token, and a refresh token if requested. If the code is invalid, it will throw an `AccessTokenRequestError`.

@@ -163,12 +165,4 @@ ```ts

const code = request.url.searchParams.get("code");
const state = request.url.searchParams.get("state");
const codeVerifier = request.url.searchParams.get("code_verifier");
const storedState = getCookie("state");
if (!code || !codeVerifier || state !== storedState) {
// 400
throw new Error("Invalid request");
}
try {

@@ -175,0 +169,0 @@ const tokens = await github.validateAuthorizationCode(code, codeVerifier);

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc