/* eslint-disable camelcase */ import * as querystring from "querystring"; import { Option, tryDo, isHttpError } from "@shared/common/async_utils"; import got, { HTTPError } from "got"; const OAUTH_API = "https://discord.com/api/oauth2"; 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 class OAuth2 { static getAuthUrl(opts: AuthorizeRequest): string { return `${OAUTH_API}/authorize?${querystring.stringify(opts)}`; } static async getToken(opts: AccessTokenRequest): Promise> { const result = await tryDo(got(`${OAUTH_API}/token`, { method: "post", form: opts, })); if (!result.ok) { if (isHttpError(result.error)) { return { error: `Failed to authenticate. Error: ${result.error.message}`, ok: false }; } return { error: "Unexpected error", ok: false }; } return { ok: true, ...result.result.body }; } }