authrix
Version:
Lightweight, flexible authentication library for Node.js and TypeScript.
775 lines (767 loc) • 22.4 kB
TypeScript
export { generateOAuthState, getGoogleOAuthURL, handleGoogleCallback, parseOAuthState, resetGoogleOAuthConfig, revokeGoogleTokens, validateGoogleIdToken } from './providers/google.js';
export { checkGitHubOrgMembership, getGitHubOAuthURL, getGitHubRateLimit, getGitHubUserOrganizations, handleGitHubCallback, resetGitHubOAuthConfig, revokeGitHubToken, validateGitHubToken } from './providers/github.js';
interface AppleTokenResponse {
access_token: string;
token_type: string;
expires_in: number;
refresh_token?: string;
id_token: string;
}
interface AppleIdTokenPayload {
iss: string;
aud: string;
exp: number;
iat: number;
sub: string;
at_hash?: string;
email?: string;
email_verified?: string | boolean;
auth_time?: number;
nonce_supported?: boolean;
real_user_status?: number;
}
interface AppleOAuthUser {
id: string;
email?: string;
name?: string;
provider: "apple";
emailVerified: boolean;
metadata?: {
firstName?: string;
lastName?: string;
realUserStatus?: number;
};
}
declare function getAppleOAuthURL(options?: {
state?: string;
scopes?: string[];
responseMode?: "query" | "fragment" | "form_post" | "web_message";
nonce?: string;
redirectUri?: string;
}): string;
declare function handleAppleCallback(code: string, options?: {
user?: string | {
name?: {
firstName?: string;
lastName?: string;
};
email?: string;
};
state?: string;
skipEmailVerification?: boolean;
redirectUri?: string;
includeTokens?: boolean;
}): Promise<AppleOAuthUser & {
tokens?: {
access: string;
refresh?: string;
idToken: string;
};
}>;
/**
* Revoke Apple OAuth tokens
*/
declare function revokeAppleTokens(token: string, tokenType?: "access_token" | "refresh_token"): Promise<boolean>;
/**
* Refresh Apple access token
*/
declare function refreshAppleAccessToken(refreshToken: string): Promise<AppleTokenResponse | null>;
/**
* Validate Apple ID token
*/
declare function validateAppleIdToken(idToken: string): Promise<AppleIdTokenPayload | null>;
/**
* Generate a secure state parameter for CSRF protection
*/
declare function generateAppleOAuthState(data?: any): string;
/**
* Parse Apple OAuth state parameter
*/
declare function parseAppleOAuthState(state: string): {
token: string;
data?: any;
};
/**
* Generate nonce for Apple OAuth
*/
declare function generateAppleNonce(): string;
/**
* Reset cached configuration (useful for testing)
*/
declare function resetAppleOAuthConfig(): void;
declare function signWithES256(message: string, privateKey: string): Promise<string>;
interface LinkedInTokenResponse {
access_token: string;
expires_in: number;
refresh_token?: string;
refresh_token_expires_in?: number;
scope?: string;
token_type: string;
id_token?: string;
}
interface LinkedInUserInfo {
sub: string;
email: string;
email_verified: boolean;
name: string;
picture?: string;
given_name?: string;
family_name?: string;
locale?: {
country: string;
language: string;
};
}
interface LinkedInOAuthUser {
id: string;
email: string;
name?: string;
avatar?: string;
provider: "linkedin";
emailVerified: boolean;
metadata?: {
givenName?: string;
familyName?: string;
locale?: {
country: string;
language: string;
};
};
}
declare function getLinkedInOAuthURL(options?: {
state?: string;
scopes?: string[];
loginHint?: string;
prompt?: "consent" | "select_account";
redirectUri?: string;
}): string;
declare function handleLinkedInCallback(code: string, options?: {
skipEmailVerification?: boolean;
redirectUri?: string;
includeTokens?: boolean;
state?: string;
}): Promise<LinkedInOAuthUser & {
tokens?: {
access: string;
refresh?: string;
idToken?: string;
};
}>;
/**
* Revoke LinkedIn OAuth tokens
*/
declare function revokeLinkedInTokens(token: string): Promise<boolean>;
/**
* Introspect LinkedIn OAuth token
*/
declare function introspectLinkedInToken(token: string): Promise<any | null>;
/**
* Refresh LinkedIn access token
*/
declare function refreshLinkedInAccessToken(refreshToken: string): Promise<LinkedInTokenResponse | null>;
/**
* Validate LinkedIn ID token (lightweight, no external dependencies)
*/
declare function validateLinkedInIdToken(idToken: string): Promise<LinkedInUserInfo | null>;
/**
* Generate a secure state parameter for CSRF protection
*/
declare function generateLinkedInOAuthState(data?: any): string;
/**
* Parse LinkedIn OAuth state parameter
*/
declare function parseLinkedInOAuthState(state: string): {
token: string;
data?: any;
};
/**
* Reset cached configuration (useful for testing)
*/
declare function resetLinkedInOAuthConfig(): void;
interface DiscordUser {
id: string;
username: string;
discriminator: string;
global_name?: string | null;
avatar?: string | null;
bot?: boolean;
system?: boolean;
mfa_enabled?: boolean;
banner?: string | null;
accent_color?: number | null;
locale?: string;
verified?: boolean;
email?: string | null;
flags?: number;
premium_type?: number;
public_flags?: number;
avatar_decoration?: string | null;
}
interface OAuthUser$3 {
id: string;
email?: string;
username: string;
displayName: string;
avatar?: string;
provider: "discord";
emailVerified: boolean;
metadata?: {
discriminator?: string;
globalName?: string;
banner?: string;
accentColor?: number;
locale?: string;
mfaEnabled?: boolean;
premiumType?: "none" | "nitro_classic" | "nitro" | "nitro_basic";
flags?: number;
publicFlags?: number;
bot?: boolean;
system?: boolean;
guilds?: Array<{
id: string;
name: string;
icon?: string;
owner?: boolean;
}>;
connections?: Array<{
type: string;
name: string;
verified: boolean;
}>;
};
}
declare const DiscordPermissions: {
readonly CREATE_INSTANT_INVITE: bigint;
readonly KICK_MEMBERS: bigint;
readonly BAN_MEMBERS: bigint;
readonly ADMINISTRATOR: bigint;
readonly MANAGE_CHANNELS: bigint;
readonly MANAGE_GUILD: bigint;
readonly ADD_REACTIONS: bigint;
readonly VIEW_AUDIT_LOG: bigint;
readonly PRIORITY_SPEAKER: bigint;
readonly STREAM: bigint;
readonly VIEW_CHANNEL: bigint;
readonly SEND_MESSAGES: bigint;
readonly SEND_TTS_MESSAGES: bigint;
readonly MANAGE_MESSAGES: bigint;
readonly EMBED_LINKS: bigint;
readonly ATTACH_FILES: bigint;
readonly READ_MESSAGE_HISTORY: bigint;
readonly MENTION_EVERYONE: bigint;
readonly USE_EXTERNAL_EMOJIS: bigint;
readonly VIEW_GUILD_INSIGHTS: bigint;
readonly CONNECT: bigint;
readonly SPEAK: bigint;
readonly MUTE_MEMBERS: bigint;
readonly DEAFEN_MEMBERS: bigint;
readonly MOVE_MEMBERS: bigint;
readonly USE_VAD: bigint;
readonly CHANGE_NICKNAME: bigint;
readonly MANAGE_NICKNAMES: bigint;
readonly MANAGE_ROLES: bigint;
readonly MANAGE_WEBHOOKS: bigint;
readonly MANAGE_GUILD_EXPRESSIONS: bigint;
readonly USE_APPLICATION_COMMANDS: bigint;
readonly REQUEST_TO_SPEAK: bigint;
readonly MANAGE_EVENTS: bigint;
readonly MANAGE_THREADS: bigint;
readonly CREATE_PUBLIC_THREADS: bigint;
readonly CREATE_PRIVATE_THREADS: bigint;
readonly USE_EXTERNAL_STICKERS: bigint;
readonly SEND_MESSAGES_IN_THREADS: bigint;
readonly USE_EMBEDDED_ACTIVITIES: bigint;
readonly MODERATE_MEMBERS: bigint;
};
declare function getDiscordOAuthURL(options?: {
state?: string;
scopes?: string[];
permissions?: bigint;
guildId?: string;
disableGuildSelect?: boolean;
prompt?: "none" | "consent";
redirectUri?: string;
responseType?: "code" | "token";
}): string;
declare function handleDiscordCallback(code: string, options?: {
state?: string;
redirectUri?: string;
includeTokens?: boolean;
fetchGuilds?: boolean;
fetchConnections?: boolean;
}): Promise<OAuthUser$3 & {
tokens?: {
access: string;
refresh: string;
expiresAt: Date;
};
}>;
/**
* Refresh Discord OAuth token
*/
declare function refreshDiscordToken(refreshToken: string): Promise<{
accessToken: string;
refreshToken: string;
expiresAt: Date;
}>;
/**
* Revoke Discord OAuth token
*/
declare function revokeDiscordToken(token: string, tokenType?: "access_token" | "refresh_token"): Promise<boolean>;
/**
* Get Discord user by ID (requires bot token)
*/
declare function getDiscordUserById(userId: string, botToken?: string): Promise<DiscordUser | null>;
/**
* Check if user is in a specific guild
*/
declare function checkGuildMembership(accessToken: string, guildId: string): Promise<boolean>;
/**
* Get user's roles in a guild (requires appropriate scopes)
*/
declare function getGuildMemberRoles(accessToken: string, guildId: string): Promise<string[] | null>;
/**
* Validate Discord access token
*/
declare function validateDiscordToken(token: string): Promise<boolean>;
/**
* Generate bot invite URL
*/
declare function getDiscordBotInviteURL(options?: {
clientId?: string;
permissions?: bigint;
scopes?: string[];
guildId?: string;
disableGuildSelect?: boolean;
}): string;
/**
* Reset cached configuration (useful for testing)
*/
declare function resetDiscordOAuthConfig(): void;
/**
* Calculate permission integer from permission names
*/
declare function calculatePermissions(permissions: (keyof typeof DiscordPermissions)[]): bigint;
interface FacebookLongLivedTokenResponse {
access_token: string;
token_type: string;
expires_in: number;
}
interface FacebookUser {
id: string;
name?: string;
first_name?: string;
last_name?: string;
middle_name?: string;
email?: string;
picture?: {
data: {
height: number;
is_silhouette: boolean;
url: string;
width: number;
};
};
birthday?: string;
gender?: string;
location?: {
id: string;
name: string;
};
hometown?: {
id: string;
name: string;
};
languages?: Array<{
id: string;
name: string;
}>;
link?: string;
locale?: string;
timezone?: number;
updated_time?: string;
verified?: boolean;
age_range?: {
min?: number;
max?: number;
};
}
interface FacebookTokenDebugInfo {
data: {
app_id: string;
type: string;
application: string;
data_access_expires_at: number;
expires_at: number;
is_valid: boolean;
scopes: string[];
user_id: string;
metadata?: {
auth_type?: string;
sso?: string;
};
};
}
interface OAuthUser$2 {
id: string;
email?: string;
username?: string;
name?: string;
avatar?: string;
provider: "facebook";
emailVerified: boolean;
metadata?: {
firstName?: string;
lastName?: string;
middleName?: string;
birthday?: string;
gender?: string;
location?: string;
hometown?: string;
languages?: string[];
profileLink?: string;
locale?: string;
timezone?: number;
ageRange?: {
min?: number;
max?: number;
};
updatedAt?: string;
permissions?: string[];
};
}
declare function getFacebookOAuthURL(options?: {
state?: string;
scopes?: string[];
redirectUri?: string;
display?: "page" | "popup" | "touch";
authType?: "rerequest" | "reauthenticate";
responseType?: "code" | "token" | "code token";
}): string;
declare function handleFacebookCallback(code: string, options?: {
state?: string;
redirectUri?: string;
includeTokens?: boolean;
fetchPermissions?: boolean;
exchangeForLongLived?: boolean;
}): Promise<OAuthUser$2 & {
tokens?: {
access: string;
expiresIn?: number;
type: string;
scopes?: string[];
};
}>;
/**
* Exchange short-lived token for long-lived token
*/
declare function exchangeForLongLivedToken(shortLivedToken: string): Promise<FacebookLongLivedTokenResponse>;
/**
* Debug and validate Facebook access token
*/
declare function debugToken(token: string, appAccessToken?: string): Promise<FacebookTokenDebugInfo>;
/**
* Get user's granted permissions
*/
declare function getUserPermissions(accessToken: string): Promise<string[]>;
/**
* Revoke specific permission or all permissions
*/
declare function revokeFacebookPermission(accessToken: string, permission?: string): Promise<boolean>;
/**
* Get Facebook user by ID
*/
declare function getFacebookUserById(userId: string, accessToken: string, fields?: string[]): Promise<FacebookUser | null>;
/**
* Validate Facebook access token
*/
declare function validateFacebookToken(token: string): Promise<boolean>;
/**
* Get app access token (for server-to-server calls)
*/
declare function getAppAccessToken(): string;
/**
* Delete user data (GDPR compliance)
*/
declare function deleteFacebookUserData(userId: string, confirmationCode?: string): Promise<{
url: string;
confirmation_code: string;
}>;
/**
* Reset cached configuration (useful for testing)
*/
declare function resetFacebookOAuthConfig(): void;
/**
* Get Facebook login status URL for JS SDK
*/
declare function getFacebookLoginStatusURL(appId?: string): string;
/**
* Verify webhook signature (for Facebook webhooks)
*/
declare function verifyFacebookWebhookSignature(signature: string, body: string, appSecret?: string): boolean;
interface XUserResponse {
data: {
id: string;
name: string;
username: string;
created_at: string;
description?: string;
location?: string;
url?: string;
verified: boolean;
verified_type?: "blue" | "business" | "government" | "none";
profile_image_url?: string;
public_metrics?: {
followers_count: number;
following_count: number;
tweet_count: number;
listed_count: number;
like_count: number;
};
protected: boolean;
};
includes?: {
tweets?: Array<any>;
};
}
interface OAuthUser$1 {
id: string;
email?: string;
username: string;
name: string;
avatar?: string;
provider: "x" | "twitter";
emailVerified: boolean;
metadata?: {
description?: string;
location?: string;
url?: string;
verified: boolean;
verifiedType?: string;
protected: boolean;
followersCount?: number;
followingCount?: number;
tweetCount?: number;
likeCount?: number;
createdAt?: string;
};
}
declare class PKCEUtils {
static generateCodeVerifier(): string;
static generateCodeChallenge(verifier: string): Promise<string>;
static base64URLEncode(buffer: Uint8Array | Buffer): string;
static generateState(): string;
}
declare function getXOAuthURL(options?: {
state?: string;
scopes?: string[];
redirectUri?: string;
prompt?: "none" | "consent";
accessType?: "online" | "offline";
}): Promise<{
url: string;
state: string;
codeVerifier: string;
}>;
declare function handleXCallback(code: string, state: string, options?: {
codeVerifier?: string;
redirectUri?: string;
includeToken?: boolean;
includeEmail?: boolean;
}): Promise<OAuthUser$1 & {
token?: string;
refreshToken?: string;
}>;
/**
* Refresh X OAuth token
*/
declare function refreshXToken(refreshToken: string): Promise<{
accessToken: string;
refreshToken?: string;
}>;
/**
* Revoke X OAuth token
*/
declare function revokeXToken(token: string, tokenType?: "access_token" | "refresh_token"): Promise<boolean>;
/**
* Get X user by ID
*/
declare function getXUserById(userId: string, accessToken: string): Promise<XUserResponse | null>;
/**
* Validate X access token
*/
declare function validateXToken(token: string): Promise<boolean>;
/**
* Clean up PKCE storage (for production, this would be in Redis/cache)
*/
declare function cleanupPKCEStorage(): void;
/**
* Reset cached configuration (useful for testing)
*/
declare function resetXOAuthConfig(): void;
interface OAuthProviderConfig {
name: string;
clientId: string;
clientSecret: string;
redirectUri: string;
endpoints: {
authorization: string;
token: string;
userInfo?: string;
revoke?: string;
};
scopes?: string[];
authorizationParams?: Record<string, string>;
tokenParams?: Record<string, string>;
userInfoHeaders?: Record<string, string>;
userProfileMapping?: UserProfileMapping;
pkce?: boolean;
state?: boolean;
}
interface UserProfileMapping {
id: string | ((data: any) => string);
email: string | ((data: any) => string);
name?: string | ((data: any) => string | undefined);
avatar?: string | ((data: any) => string | undefined);
emailVerified?: string | ((data: any) => boolean);
metadata?: Record<string, string | ((data: any) => any)>;
}
interface TokenResponse {
access_token: string;
token_type: string;
expires_in?: number;
refresh_token?: string;
scope?: string;
id_token?: string;
[key: string]: any;
}
interface OAuthUser {
id: string;
email: string;
name?: string;
avatar?: string;
provider: string;
emailVerified?: boolean;
metadata?: Record<string, any>;
raw?: any;
}
interface OAuthTokens {
access: string;
refresh?: string;
idToken?: string;
expiresIn?: number;
tokenType: string;
}
interface OAuthCallbackResult {
user: OAuthUser;
tokens?: OAuthTokens;
}
interface AuthorizationURLOptions {
state?: string;
scopes?: string[];
loginHint?: string;
prompt?: string;
accessType?: string;
additionalParams?: Record<string, string>;
}
interface CallbackOptions {
state?: string;
includeTokens?: boolean;
includeRawResponse?: boolean;
skipEmailVerification?: boolean;
}
declare class CustomOAuthProvider {
private config;
private pkceStore;
constructor(config: OAuthProviderConfig);
private validateConfig;
private normalizeConfig;
/**
* Generate OAuth Authorization URL
*/
getAuthorizationURL(options?: AuthorizationURLOptions): Promise<string>;
/**
* Handle OAuth Callback
*/
handleCallback(code: string, options?: CallbackOptions): Promise<OAuthCallbackResult>;
/**
* Exchange authorization code for tokens
*/
private exchangeCodeForTokens;
/**
* Fetch user information from provider's API
*/
private fetchUserInfo;
/**
* Map provider-specific user profile to standard format
*/
private mapUserProfile;
/**
* Revoke OAuth tokens
*/
revokeTokens(token: string, tokenType?: 'access_token' | 'refresh_token'): Promise<boolean>;
/**
* Refresh access token
*/
refreshAccessToken(refreshToken: string): Promise<TokenResponse>;
/**
* Validate ID token (basic validation without crypto)
*/
validateIdToken(idToken: string): Promise<any | null>;
/**
* Decode JWT token
*/
private decodeJWT;
/**
* Generate state parameter for CSRF protection
*/
generateState(data?: any): string;
/**
* Parse state parameter
*/
parseState(state: string): {
token: string;
data?: any;
};
/**
* Get provider configuration
*/
getConfig(): Readonly<OAuthProviderConfig>;
/**
* Update provider configuration
*/
updateConfig(updates: Partial<OAuthProviderConfig>): void;
/**
* Clear PKCE store (for cleanup)
*/
clearPKCEStore(): void;
}
declare class OAuthProviderManager {
private providers;
/**
* Register a new OAuth provider
*/
register(config: OAuthProviderConfig): CustomOAuthProvider;
/**
* Get a registered provider
*/
get(name: string): CustomOAuthProvider | undefined;
/**
* Remove a provider
*/
remove(name: string): boolean;
/**
* List all registered providers
*/
list(): string[];
/**
* Check if a provider is registered
*/
has(name: string): boolean;
/**
* Clear all providers
*/
clear(): void;
}
declare const oAuthManager: OAuthProviderManager;
export { type AuthorizationURLOptions, type CallbackOptions, CustomOAuthProvider, DiscordPermissions, type OAuthCallbackResult, type OAuthProviderConfig, OAuthProviderManager, type OAuthTokens, type OAuthUser, PKCEUtils, type TokenResponse, type UserProfileMapping, calculatePermissions, checkGuildMembership, cleanupPKCEStorage, debugToken as debugFacebookToken, deleteFacebookUserData, exchangeForLongLivedToken, generateAppleNonce, generateAppleOAuthState, generateLinkedInOAuthState, getAppleOAuthURL, getDiscordBotInviteURL, getDiscordOAuthURL, getDiscordUserById, getAppAccessToken as getFacebookAppAccessToken, getFacebookLoginStatusURL, getFacebookOAuthURL, getFacebookUserById, getUserPermissions as getFacebookUserPermissions, getGuildMemberRoles, getLinkedInOAuthURL, getXOAuthURL, getXUserById, handleAppleCallback, handleDiscordCallback, handleFacebookCallback, handleLinkedInCallback, handleXCallback, introspectLinkedInToken, oAuthManager, parseAppleOAuthState, parseLinkedInOAuthState, refreshAppleAccessToken, refreshDiscordToken, refreshLinkedInAccessToken, refreshXToken, resetAppleOAuthConfig, resetDiscordOAuthConfig, resetFacebookOAuthConfig, resetLinkedInOAuthConfig, resetXOAuthConfig, revokeAppleTokens, revokeDiscordToken, revokeFacebookPermission, revokeLinkedInTokens, revokeXToken, signWithES256, validateAppleIdToken, validateDiscordToken, validateFacebookToken, validateLinkedInIdToken, validateXToken, verifyFacebookWebhookSignature };