UNPKG

@sapphire/plugin-api

Version:

Plugin for @sapphire/framework to expose a REST API

120 lines (118 loc) 4.03 kB
import { __name, __publicField, __privateAdd, __privateSet, __privateGet } from '../../../chunk-S573YWRP.mjs'; import { isThenable } from '@sapphire/utilities'; import { randomBytes, createCipheriv, createDecipheriv } from 'crypto'; import { OAuth2Scopes, RouteBases, Routes } from 'discord.js'; import { fetch } from 'undici'; var _secret; var _Auth = class _Auth { constructor(options) { /** * The client's application id, this can be retrieved in Discord Developer Portal at https://discord.com/developers/applications. * @since 1.0.0 */ __publicField(this, "id"); /** * The name for the cookie, this will be used to identify a Secure HttpOnly cookie. * @since 1.0.0 */ __publicField(this, "cookie"); /** * The scopes defined at https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-scopes. * @since 1.0.0 */ __publicField(this, "scopes"); /** * The redirect uri. * @since 1.0.0 */ __publicField(this, "redirect"); /** * The transformers used for {@link Auth.fetchData}. * @since 1.4.0 */ __publicField(this, "transformers"); __publicField(this, "domainOverwrite", null); __privateAdd(this, _secret); this.id = options.id; this.cookie = options.cookie ?? "SAPPHIRE_AUTH"; this.scopes = options.scopes ?? [OAuth2Scopes.Identify]; this.redirect = options.redirect; __privateSet(this, _secret, options.secret); this.transformers = options.transformers ?? []; this.domainOverwrite = options.domainOverwrite ?? null; } /** * The client secret, this can be retrieved in Discord Developer Portal at https://discord.com/developers/applications. * @since 1.0.0 */ get secret() { return __privateGet(this, _secret); } /** * Encrypts an object with aes-256-cbc to use as a token. * @since 1.0.0 * @param data An object to encrypt */ encrypt(data) { const iv = randomBytes(16); const cipher = createCipheriv("aes-256-cbc", __privateGet(this, _secret), iv); return `${cipher.update(JSON.stringify(data), "utf8", "base64") + cipher.final("base64")}.${iv.toString("base64")}`; } /** * Decrypts an object with aes-256-cbc to use as a token. * @since 1.0.0 * @param token An data to decrypt */ decrypt(token) { const [data, iv] = token.split("."); const decipher = createDecipheriv("aes-256-cbc", __privateGet(this, _secret), Buffer.from(iv, "base64")); try { const parsed = JSON.parse(decipher.update(data, "base64", "utf8") + decipher.final("utf8")); return parsed.expires >= Date.now() ? parsed : null; } catch { return null; } } /** * Retrieves the data for a specific user. * @since 1.4.0 * @param token The access token from the user. */ async fetchData(token) { const [user, guilds, connections] = await Promise.all([ this.fetchInformation(OAuth2Scopes.Identify, token, `${RouteBases.api}${Routes.user()}`), this.fetchInformation(OAuth2Scopes.Guilds, token, `${RouteBases.api}${Routes.userGuilds()}`), this.fetchInformation( OAuth2Scopes.Connections, token, `${RouteBases.api}${Routes.userConnections()}` ) ]); let data = { user, guilds, connections }; for (const transformer of this.transformers) { const result = transformer(data); if (isThenable(result)) data = await result; else data = result; } return data; } async fetchInformation(scope, token, url) { if (!this.scopes.includes(scope)) return void 0; const result = await fetch(url, { headers: { authorization: `Bearer ${token}` } }); return result.ok ? await result.json() : null; } static create(options) { if (!options?.secret || !options.id) return null; return new _Auth(options); } }; _secret = new WeakMap(); __name(_Auth, "Auth"); var Auth = _Auth; export { Auth }; //# sourceMappingURL=Auth.mjs.map //# sourceMappingURL=Auth.mjs.map