/* eslint-disable camelcase */ import * as querystring from "querystring"; import { Option, tryDo, isHttpError } from "@shared/common/async_utils"; import got, { HTTPError } from "got"; import { logger } from "./logging"; const DISCORD_API = "https://discord.com/api"; export interface AccessTokenResponse { access_token: string; token_type: string; expires_in: number; refresh_token: string; scope: string; } type GrantType = "authorization_code"; type TokenType = "code" | "token"; export interface AccessTokenRequest { client_id: string; client_secret: string; grant_type: GrantType; code: string; scope: string; redirect_uri: string; } export type AuthorizeRequest = { client_id: string, redirect_url: string, response_type: TokenType, scope: string, } export interface DiscordUser { id: string; username: string; discriminator: string; avatar?: string; bot?: boolean; mfa_enabled?: boolean; locale?: string; verified?: boolean; email?: string; flags?: number; premium_type?: number; } export class DiscordAPI { static getAuthUrl(opts: AuthorizeRequest): string { return `${DISCORD_API}/oauth2/authorize?${querystring.stringify(opts)}`; } static async getToken(opts: AccessTokenRequest): Promise> { const result = await tryDo(got("oauth2/token", { responseType: "json", method: "post", form: opts, prefixUrl: DISCORD_API, })); if (!result.ok) { if (isHttpError(result.error)) { logger.warn("WEB: Failed to authenticate a user: %s", result.error); return { error: "Couldn't authenticate a user (the session might be old). Please try logging in again.", ok: false }; } logger.error("WEB: failed to fetch access token: %s", result.error); return { error: "Unexpected error", ok: false }; } return { ok: true, ...result.result.body }; } static async getCurrentUser(token: string): Promise> { const result = await tryDo(got("users/@me", { responseType: "json", headers: { Authorization: `Bearer ${token}`, }, prefixUrl: DISCORD_API, })); if (!result.ok) { if (isHttpError(result.error)) { return { error: `Failed to check used ID. Error: ${result.error.message}`, ok: false }; } return { error: "Unexpected error", ok: false }; } return { ok: true, ...result.result.body }; } }