UNPKG

@adonisjs/ally

Version:

Social authentication provider for AdonisJS

183 lines (181 loc) 5.27 kB
import { Oauth2Driver } from "../../chunk-EXGR73T6.js"; import "../../chunk-NK6X76EQ.js"; import "../../chunk-TSIMPJ6I.js"; // src/drivers/discord.ts var DiscordDriver = class extends Oauth2Driver { /** * @param ctx - The HTTP context * @param config - Configuration for the Discord driver */ constructor(ctx, config) { super(ctx, config); this.config = config; this.loadState(); } config; /** * Discord token endpoint URL. */ accessTokenUrl = "https://discord.com/api/oauth2/token"; /** * Discord authorization endpoint URL. */ authorizeUrl = "https://discord.com/oauth2/authorize"; /** * Discord user profile endpoint URL. */ userInfoUrl = "https://discord.com/api/users/@me"; /** * The param name for the authorization code */ codeParamName = "code"; /** * The param name for the error */ errorParamName = "error"; /** * Cookie name for storing the "discord_oauth_state" */ stateCookieName = "discord_oauth_state"; /** * Parameter name to be used for sending and receiving the state * from Discord */ stateParamName = "state"; /** * Parameter name for defining the scopes */ scopeParamName = "scope"; /** * Scopes separator */ scopesSeparator = " "; /** * Configures the redirect request with default scopes and Discord-specific * parameters like prompt, guild_id, and permissions. * * @param request - The redirect request to configure */ configureRedirectRequest(request) { request.scopes(this.config.scopes || ["identify", "email"]); request.param("response_type", "code"); request.param("grant_type", "authorization_code"); request.param("integration_type", 1); if (this.config.prompt) { request.param("prompt", this.config.prompt); } if (this.config.guildId) { request.param("guild_id", this.config.guildId); } if (this.config.disableGuildSelect !== void 0) { request.param("disable_guild_select", this.config.disableGuildSelect); } if (this.config.permissions !== void 0) { request.param("permissions", this.config.permissions); } } /** * Configures the access token request with Discord-specific requirements. * * @param request - The API request to configure */ configureAccessTokenRequest(request) { if (!this.isStateless) { request.field("state", this.stateCookieValue); } } /** * Creates an authenticated HTTP request with the proper authorization * header for Discord API calls. * * @param url - The API endpoint URL * @param token - The access token */ getAuthenticatedRequest(url, token) { const request = this.httpClient(url); request.header("Authorization", `Bearer ${token}`); request.header("Accept", "application/json"); request.parseAs("json"); return request; } /** * Fetches the authenticated user's profile information from the Discord API. * * @param token - The access token * @param callback - Optional callback to customize the API request * * @see https://discord.com/developers/docs/resources/user#get-current-user */ async getUserInfo(token, callback) { const request = this.getAuthenticatedRequest(this.config.userInfoUrl || this.userInfoUrl, token); if (typeof callback === "function") { callback(request); } const body = await request.get(); return { id: body.id, name: `${body.username}#${body.discriminator}`, nickName: body.username, avatarUrl: body.avatar ? `https://cdn.discordapp.com/avatars/${body.id}/${body.avatar}.${body.avatar.startsWith("a_") ? "gif" : "png"}` : `https://cdn.discordapp.com/embed/avatars/${body.discriminator % 5}.png`, email: body.email, // May not always be there (requires email scope) emailVerificationState: "verified" in body ? body.verified ? "verified" : "unverified" : "unsupported", original: body }; } /** * Check if the error from the callback indicates that the user * denied authorization. */ accessDenied() { const error = this.getError(); if (!error) { return false; } return error === "access_denied"; } /** * Get the authenticated user's profile information using * the authorization code from the callback request. * * @param callback - Optional callback to customize the API request * * @example * ```ts * const user = await ally.use('discord').user() * console.log(user.name, user.email) * ``` */ async user(callback) { const token = await this.accessToken(callback); const user = await this.getUserInfo(token.token, callback); return { ...user, token }; } /** * Get the user's profile information using an existing * access token. * * @param token - The Discord access token * @param callback - Optional callback to customize the API request * * @example * ```ts * const user = await ally.use('discord').userFromToken(accessToken) * ``` */ async userFromToken(token, callback) { const user = await this.getUserInfo(token, callback); return { ...user, token: { token, type: "bearer" } }; } }; export { DiscordDriver };