@sapphire/plugin-api 8.1.0-next.93565ea → 8.1.0-next.9f69aae
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +1 -1
- package/dist/cjs/lib/structures/api/CookieStore.cjs +2 -2
- package/dist/cjs/lib/structures/api/CookieStore.cjs.map +1 -1
- package/dist/cjs/lib/structures/http/Auth.cjs +1 -1
- package/dist/cjs/lib/structures/http/Auth.cjs.map +1 -1
- package/dist/cjs/lib/utils/_body/RequestHeadersProxy.cjs +1 -1
- package/dist/cjs/lib/utils/_body/RequestHeadersProxy.cjs.map +1 -1
- package/dist/esm/index.d.mts +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/lib/structures/api/CookieStore.mjs +2 -2
- package/dist/esm/lib/structures/api/CookieStore.mjs.map +1 -1
- package/dist/esm/lib/structures/http/Auth.mjs +1 -1
- package/dist/esm/lib/structures/http/Auth.mjs.map +1 -1
- package/dist/esm/lib/utils/_body/RequestHeadersProxy.mjs +1 -1
- package/dist/esm/lib/utils/_body/RequestHeadersProxy.mjs.map +1 -1
- package/package.json +7 -7
package/dist/esm/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAoDO,IAAM,OAAkB,GAAA","file":"index.mjs","sourcesContent":["import type { Server, ServerOptions } from './lib/structures/http/Server';\nimport type { MiddlewareStore } from './lib/structures/MiddlewareStore';\nimport type { RouteStore } from './lib/structures/RouteStore';\n\nexport * from './lib/structures/api/ApiRequest';\nexport * from './lib/structures/api/ApiResponse';\nexport * from './lib/structures/api/CookieStore';\nexport * from './lib/structures/http/Auth';\nexport * from './lib/structures/http/HttpCodes';\nexport * from './lib/structures/http/HttpMethods';\nexport * from './lib/structures/http/Server';\nexport * from './lib/structures/Middleware';\nexport * from './lib/structures/MiddlewareStore';\nexport * from './lib/structures/Route';\nexport * from './lib/structures/router/RouterBranch';\nexport * from './lib/structures/router/RouterNode';\nexport * from './lib/structures/router/RouterRoot';\nexport * from './lib/structures/RouteStore';\nexport type * from './lib/utils/MimeType';\n\nexport { loadListeners } from './listeners/_load';\nexport { loadMiddlewares } from './middlewares/_load';\nexport { loadRoutes } from './routes/_load';\n\ndeclare module 'discord.js' {\n\tinterface Client {\n\t\tserver: Server;\n\t}\n\n\tinterface ClientOptions {\n\t\tapi?: ServerOptions;\n\t}\n}\n\ndeclare module '@sapphire/pieces' {\n\tinterface StoreRegistryEntries {\n\t\troutes: RouteStore;\n\t\tmiddlewares: MiddlewareStore;\n\t}\n\n\tinterface Container {\n\t\tserver: Server;\n\t}\n}\n\n/**\n * The [@sapphire/plugin-api](https://github.com/sapphiredev/plugins/blob/main/packages/api) version that you are currently using.\n * An example use of this is showing it of in a bot information command.\n *\n * Note to Sapphire developers: This needs to explicitly be `string` so it is not typed as the string that gets replaced by esbuild\n */\n// eslint-disable-next-line @typescript-eslint/no-inferrable-types\nexport const version: string = '8.1.0-next.
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAoDO,IAAM,OAAkB,GAAA","file":"index.mjs","sourcesContent":["import type { Server, ServerOptions } from './lib/structures/http/Server';\nimport type { MiddlewareStore } from './lib/structures/MiddlewareStore';\nimport type { RouteStore } from './lib/structures/RouteStore';\n\nexport * from './lib/structures/api/ApiRequest';\nexport * from './lib/structures/api/ApiResponse';\nexport * from './lib/structures/api/CookieStore';\nexport * from './lib/structures/http/Auth';\nexport * from './lib/structures/http/HttpCodes';\nexport * from './lib/structures/http/HttpMethods';\nexport * from './lib/structures/http/Server';\nexport * from './lib/structures/Middleware';\nexport * from './lib/structures/MiddlewareStore';\nexport * from './lib/structures/Route';\nexport * from './lib/structures/router/RouterBranch';\nexport * from './lib/structures/router/RouterNode';\nexport * from './lib/structures/router/RouterRoot';\nexport * from './lib/structures/RouteStore';\nexport type * from './lib/utils/MimeType';\n\nexport { loadListeners } from './listeners/_load';\nexport { loadMiddlewares } from './middlewares/_load';\nexport { loadRoutes } from './routes/_load';\n\ndeclare module 'discord.js' {\n\tinterface Client {\n\t\tserver: Server;\n\t}\n\n\tinterface ClientOptions {\n\t\tapi?: ServerOptions;\n\t}\n}\n\ndeclare module '@sapphire/pieces' {\n\tinterface StoreRegistryEntries {\n\t\troutes: RouteStore;\n\t\tmiddlewares: MiddlewareStore;\n\t}\n\n\tinterface Container {\n\t\tserver: Server;\n\t}\n}\n\n/**\n * The [@sapphire/plugin-api](https://github.com/sapphiredev/plugins/blob/main/packages/api) version that you are currently using.\n * An example use of this is showing it of in a bot information command.\n *\n * Note to Sapphire developers: This needs to explicitly be `string` so it is not typed as the string that gets replaced by esbuild\n */\n// eslint-disable-next-line @typescript-eslint/no-inferrable-types\nexport const version: string = '8.1.0-next.9f69aae';\n"]}
|
|
@@ -34,7 +34,7 @@ var _CookieStore = class _CookieStore extends Map {
|
|
|
34
34
|
}
|
|
35
35
|
insert(name, entry) {
|
|
36
36
|
let set = this.response.getHeader("Set-Cookie");
|
|
37
|
-
if (set ===
|
|
37
|
+
if (set === void 0) {
|
|
38
38
|
set = [];
|
|
39
39
|
} else if (!Array.isArray(set)) {
|
|
40
40
|
set = [set.toString()];
|
|
@@ -45,7 +45,7 @@ var _CookieStore = class _CookieStore extends Map {
|
|
|
45
45
|
}
|
|
46
46
|
prepare(name, value, { expires, maxAge, domain, path, httpOnly } = {}) {
|
|
47
47
|
const now = /* @__PURE__ */ new Date();
|
|
48
|
-
if (expires ===
|
|
48
|
+
if (expires === void 0) {
|
|
49
49
|
expires = now;
|
|
50
50
|
}
|
|
51
51
|
name = _CookieStore.encodeCookieOctet(name);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/lib/structures/api/CookieStore.ts"],"names":[],"mappings":";;;AAOO,IAAM,YAAA,GAAN,MAAM,YAAA,SAAoB,GAAoB,CAAA;AAAA,EAM7C,WAAY,CAAA,OAAA,EAAqB,QAAuB,EAAA,MAAA,EAAiB,eAAiC,EAAA;AAChH,IAAM,KAAA,EAAA;AANP,IAAU,aAAA,CAAA,IAAA,EAAA,SAAA,CAAA;AACV,IAAU,aAAA,CAAA,IAAA,EAAA,UAAA,CAAA;AACV,IAAQ,aAAA,CAAA,IAAA,EAAA,QAAA,CAAA;AACR,IAAQ,aAAA,CAAA,IAAA,EAAA,QAAA,CAAA;AAKP,IAAA,IAAA,CAAK,OAAU,GAAA,OAAA;AACf,IAAA,IAAA,CAAK,QAAW,GAAA,QAAA;AAGhB,IAAA,MAAM,EAAE,MAAA,GAAS,EAAG,EAAA,GAAI,OAAQ,CAAA,OAAA;AAChC,IAAM,MAAA,KAAA,GAAQ,MAAO,CAAA,KAAA,CAAM,GAAG,CAAA;AAE9B,IAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACzB,MAAM,MAAA,KAAA,GAAQ,IAAK,CAAA,OAAA,CAAQ,GAAG,CAAA;AAC9B,MAAA,IAAI,UAAU,EAAI,EAAA;AAElB,MAAM,MAAA,GAAA,GAAM,mBAAmB,IAAK,CAAA,KAAA,CAAM,GAAG,KAAK,CAAA,CAAE,MAAM,CAAA;AAC1D,MAAM,MAAA,KAAA,GAAQ,mBAAmB,IAAK,CAAA,KAAA,CAAM,QAAQ,CAAC,CAAA,CAAE,MAAM,CAAA;AAC7D,MAAK,IAAA,CAAA,GAAA,CAAI,KAAK,KAAK,CAAA;AAAA;AAGpB,IAAM,MAAA,CAAC,SAAS,CAAA,GAAI,IAAK,CAAA,OAAA,CAAQ,OAAQ,CAAA,IAAA,EAAM,KAAM,CAAA,GAAG,CAAK,IAAA,CAAC,EAAE,CAAA;AAEhE,IAAA,IAAA,CAAK,MAAS,GAAA,eAAA,IAAmB,IAAK,CAAA,aAAA,CAAc,SAAS,CAAA;AAE7D,IAAA,IAAI,IAAK,CAAA,OAAA,CAAQ,MAAO,CAAA,aAAA,KAAkB,KAAK,MAAQ,EAAA;AACtD,MAAM,MAAA,IAAI,MAAM,mFAAmF,CAAA;AAAA;AAIpG,IAAA,IAAA,CAAK,MAAS,GAAA,MAAA;AAAA;AACf,EAEO,GAAA,CAAI,IAAc,EAAA,KAAA,EAAe,OAAuC,EAAA;AAC9E,IAAA,IAAA,CAAK,OAAO,IAAM,EAAA,IAAA,CAAK,QAAQ,IAAM,EAAA,KAAA,EAAO,OAAO,CAAC,CAAA;AAAA;AACrD,EAEO,OAAO,IAAc,EAAA;AAC3B,IAAK,IAAA,CAAA,GAAA,CAAI,MAAM,EAAI,EAAA,EAAE,yBAAa,IAAA,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA;AAAA;AAC5C,EAEU,MAAA,CAAO,MAAc,KAAe,EAAA;AAC7C,IAAA,IAAI,GAAM,GAAA,IAAA,CAAK,QAAS,CAAA,SAAA,CAAU,YAAY,CAAA;AAE9C,IAAA,IAAI,QAAQ,
|
|
1
|
+
{"version":3,"sources":["../../../../../src/lib/structures/api/CookieStore.ts"],"names":[],"mappings":"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","file":"CookieStore.mjs","sourcesContent":["// Copyright (c) 2018 Stanislav Woodger. All rights reserved. MIT license.\n// Source: https://github.com/woodger/cookie-httponly\n\nimport { getDomain } from 'tldts';\nimport type { ApiRequest } from './ApiRequest';\nimport type { ApiResponse } from './ApiResponse';\n\nexport class CookieStore extends Map<string, string> {\n\tprotected request: ApiRequest;\n\tprotected response: ApiResponse;\n\tprivate domain: string;\n\tprivate secure: boolean;\n\n\tpublic constructor(request: ApiRequest, response: ApiResponse, secure: boolean, domainOverwrite?: string | null) {\n\t\tsuper();\n\n\t\tthis.request = request;\n\t\tthis.response = response;\n\n\t\t// Read cookies\n\t\tconst { cookie = '' } = request.headers;\n\t\tconst pairs = cookie.split(';');\n\n\t\tfor (const pair of pairs) {\n\t\t\tconst index = pair.indexOf('=');\n\t\t\tif (index === -1) continue;\n\n\t\t\tconst key = decodeURIComponent(pair.slice(0, index).trim());\n\t\t\tconst value = decodeURIComponent(pair.slice(index + 1).trim());\n\t\t\tthis.set(key, value);\n\t\t}\n\n\t\tconst [splitHost] = this.request.headers.host?.split(':') ?? [''];\n\n\t\tthis.domain = domainOverwrite ?? this.getHostDomain(splitHost);\n\n\t\tif (this.request.socket.remoteAddress === this.domain) {\n\t\t\tthrow new Error('The connection must be established from the domain name (i.e., not an IP address)');\n\t\t}\n\n\t\t// RFC 6265 4.1.2.5. The Secure Attribute\n\t\tthis.secure = secure;\n\t}\n\n\tpublic add(name: string, value: string, options?: SecureCookieStoreSetOptions) {\n\t\tthis.insert(name, this.prepare(name, value, options));\n\t}\n\n\tpublic remove(name: string) {\n\t\tthis.add(name, '', { expires: new Date(0) });\n\t}\n\n\tprotected insert(name: string, entry: string) {\n\t\tlet set = this.response.getHeader('Set-Cookie');\n\n\t\tif (set === undefined) {\n\t\t\tset = [];\n\t\t} else if (!Array.isArray(set)) {\n\t\t\tset = [set.toString()];\n\t\t}\n\n\t\tset = set.filter((i) => i.slice(0, i.indexOf('=')) !== name);\n\t\tset.push(entry);\n\n\t\tthis.response.setHeader('Set-Cookie', set);\n\t}\n\n\tprotected prepare(name: string, value: string, { expires, maxAge, domain, path, httpOnly }: SecureCookieStoreSetOptions = {}) {\n\t\tconst now = new Date();\n\n\t\tif (expires === undefined) {\n\t\t\texpires = now;\n\t\t}\n\n\t\t// RFC 6265 4.1.1. Syntax\n\t\tname = CookieStore.encodeCookieOctet(name);\n\t\tvalue = CookieStore.encodeCookieOctet(value);\n\n\t\tlet entry = `${name}=${value}`;\n\n\t\tif (expires !== now) {\n\t\t\tentry += `; Expires=${expires.toUTCString()}`;\n\t\t} else if (maxAge) {\n\t\t\tentry += `; Max-Age=${maxAge}`;\n\t\t}\n\n\t\t// RFC 6265 5.1.3 Domain Matching\n\t\tdomain = (domain ?? this.domain).toLowerCase();\n\n\t\tentry += `; Domain=${domain}`;\n\t\tentry += `; Path=${path ?? '/'}`;\n\n\t\tif (this.secure) {\n\t\t\tentry += `; Secure`;\n\t\t}\n\n\t\tif (httpOnly ?? true) {\n\t\t\tentry += `; HttpOnly`;\n\t\t}\n\n\t\treturn entry;\n\t}\n\n\t/**\n\t * Parses a host using the {@linkplain https://github.com/remusao/tldts tldts} library to extract the domain.\n\t * This is used for the domain of the cookie\n\t * @param host The hot to parse\n\t * @returns Either the host in all lower case or the parsed domain, ready for use on cookies\n\t */\n\tprivate getHostDomain(host: string): string {\n\t\t// Transform the host to lower case\n\t\tconst lowercaseHost = host.toLowerCase();\n\n\t\t// Try parsing the host with tldts\n\t\tconst tldParsedInfo = getDomain(lowercaseHost);\n\n\t\t// If the domain is not defined then return the host in lowercase\n\t\tif (!tldParsedInfo) return lowercaseHost;\n\n\t\t// If the domain was found from parsing then prefix it with a . for a cookie that works with subdomains and return it\n\t\treturn `.${tldParsedInfo}`;\n\t}\n\n\t// RFC 6265 4.1.1. Syntax\n\tprivate static readonly octetRegExp = /[^\\x21\\x23-\\x2B\\x2D-\\x3A\\x3C-\\x5B\\x5D-\\x7E]/g;\n\n\tprivate static encodeCookieOctet(value: string) {\n\t\tif (CookieStore.octetRegExp.test(value)) {\n\t\t\tthrow new Error(`Invalid character in value`);\n\t\t}\n\n\t\treturn encodeURIComponent(value);\n\t}\n}\n\nexport interface SecureCookieStoreSetOptions {\n\texpires?: Date;\n\tmaxAge?: number;\n\tdomain?: string;\n\tpath?: string;\n\thttpOnly?: boolean;\n}\n"]}
|
|
@@ -98,7 +98,7 @@ var _Auth = class _Auth {
|
|
|
98
98
|
return data;
|
|
99
99
|
}
|
|
100
100
|
async fetchInformation(scope, token, url) {
|
|
101
|
-
if (!this.scopes.includes(scope)) return
|
|
101
|
+
if (!this.scopes.includes(scope)) return void 0;
|
|
102
102
|
const result = await fetch(url, {
|
|
103
103
|
headers: {
|
|
104
104
|
authorization: `Bearer ${token}`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/lib/structures/http/Auth.ts"],"names":[],"mappings":"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","file":"Auth.mjs","sourcesContent":["import { isThenable, type Awaitable } from '@sapphire/utilities';\nimport { createCipheriv, createDecipheriv, randomBytes } from 'crypto';\nimport {\n\tOAuth2Scopes,\n\tRouteBases,\n\tRoutes,\n\ttype RESTGetAPICurrentUserConnectionsResult,\n\ttype RESTGetAPICurrentUserGuildsResult,\n\ttype RESTGetAPICurrentUserResult,\n\ttype Snowflake\n} from 'discord.js';\nimport { fetch } from 'undici';\n\nexport class Auth {\n\t/**\n\t * The client's application id, this can be retrieved in Discord Developer Portal at https://discord.com/developers/applications.\n\t * @since 1.0.0\n\t */\n\tpublic id: Snowflake;\n\n\t/**\n\t * The name for the cookie, this will be used to identify a Secure HttpOnly cookie.\n\t * @since 1.0.0\n\t */\n\tpublic cookie: string;\n\n\t/**\n\t * The scopes defined at https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-scopes.\n\t * @since 1.0.0\n\t */\n\tpublic scopes: readonly OAuth2Scopes[];\n\n\t/**\n\t * The redirect uri.\n\t * @since 1.0.0\n\t */\n\tpublic redirect: string | undefined;\n\n\t/**\n\t * The transformers used for {@link Auth.fetchData}.\n\t * @since 1.4.0\n\t */\n\tpublic transformers: LoginDataTransformer[];\n\n\tpublic domainOverwrite: string | null = null;\n\n\t#secret: string;\n\n\tprivate constructor(options: ServerOptionsAuth) {\n\t\tthis.id = options.id;\n\t\tthis.cookie = options.cookie ?? 'SAPPHIRE_AUTH';\n\t\tthis.scopes = options.scopes ?? [OAuth2Scopes.Identify];\n\t\tthis.redirect = options.redirect;\n\t\tthis.#secret = options.secret;\n\t\tthis.transformers = options.transformers ?? [];\n\t\tthis.domainOverwrite = options.domainOverwrite ?? null;\n\t}\n\n\t/**\n\t * The client secret, this can be retrieved in Discord Developer Portal at https://discord.com/developers/applications.\n\t * @since 1.0.0\n\t */\n\tpublic get secret() {\n\t\treturn this.#secret;\n\t}\n\n\t/**\n\t * Encrypts an object with aes-256-cbc to use as a token.\n\t * @since 1.0.0\n\t * @param data An object to encrypt\n\t */\n\tpublic encrypt(data: AuthData): string {\n\t\tconst iv = randomBytes(16);\n\t\tconst cipher = createCipheriv('aes-256-cbc', this.#secret, iv);\n\t\treturn `${cipher.update(JSON.stringify(data), 'utf8', 'base64') + cipher.final('base64')}.${iv.toString('base64')}`;\n\t}\n\n\t/**\n\t * Decrypts an object with aes-256-cbc to use as a token.\n\t * @since 1.0.0\n\t * @param token An data to decrypt\n\t */\n\tpublic decrypt(token: string): AuthData | null {\n\t\tconst [data, iv] = token.split('.');\n\t\tconst decipher = createDecipheriv('aes-256-cbc', this.#secret, Buffer.from(iv, 'base64'));\n\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(decipher.update(data, 'base64', 'utf8') + decipher.final('utf8')) as AuthData;\n\t\t\t// If the token expired, return null:\n\t\t\treturn parsed.expires >= Date.now() ? parsed : null;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Retrieves the data for a specific user.\n\t * @since 1.4.0\n\t * @param token The access token from the user.\n\t */\n\tpublic async fetchData(token: string): Promise<LoginData> {\n\t\t// Fetch the information:\n\t\tconst [user, guilds, connections] = await Promise.all([\n\t\t\tthis.fetchInformation<RESTGetAPICurrentUserResult>(OAuth2Scopes.Identify, token, `${RouteBases.api}${Routes.user()}`),\n\t\t\tthis.fetchInformation<RESTGetAPICurrentUserGuildsResult>(OAuth2Scopes.Guilds, token, `${RouteBases.api}${Routes.userGuilds()}`),\n\t\t\tthis.fetchInformation<RESTGetAPICurrentUserConnectionsResult>(\n\t\t\t\tOAuth2Scopes.Connections,\n\t\t\t\ttoken,\n\t\t\t\t`${RouteBases.api}${Routes.userConnections()}`\n\t\t\t)\n\t\t]);\n\n\t\t// Transform the information:\n\t\tlet data: LoginData = { user, guilds, connections };\n\t\tfor (const transformer of this.transformers) {\n\t\t\tconst result = transformer(data);\n\t\t\tif (isThenable(result)) data = await result;\n\t\t\telse data = result as LoginData;\n\t\t}\n\n\t\treturn data;\n\t}\n\n\tprivate async fetchInformation<T>(scope: OAuth2Scopes, token: string, url: string): Promise<T | null | undefined> {\n\t\tif (!this.scopes.includes(scope)) return undefined;\n\n\t\tconst result = await fetch(url, {\n\t\t\theaders: {\n\t\t\t\tauthorization: `Bearer ${token}`\n\t\t\t}\n\t\t});\n\n\t\treturn result.ok ? ((await result.json()) as T) : null;\n\t}\n\n\tpublic static create(options?: ServerOptionsAuth): Auth | null {\n\t\tif (!options?.secret || !options.id) return null;\n\t\treturn new Auth(options);\n\t}\n}\n\n/**\n * Defines the authentication data, this is to be encrypted and decrypted by the server.\n * @since 1.0.0\n */\nexport interface AuthData {\n\t/**\n\t * The user ID.\n\t * @since 1.0.0\n\t */\n\tid: string;\n\n\t/**\n\t * The timestamp at which the token expires.\n\t * @since 1.0.0\n\t */\n\texpires: number;\n\n\t/**\n\t * The refresh token.\n\t * @since 1.0.0\n\t */\n\trefresh: string;\n\n\t/**\n\t * The access token.\n\t * @since 1.0.0\n\t */\n\ttoken: string;\n}\n\n/**\n * Defines the authentication options.\n * @since 1.0.0\n */\nexport interface ServerOptionsAuth {\n\t/**\n\t * The client's application id, this can be retrieved in Discord Developer Portal at https://discord.com/developers/applications.\n\t * @since 1.0.0\n\t */\n\tid: Snowflake;\n\n\t/**\n\t * The name for the cookie, this will be used to identify a Secure HttpOnly cookie.\n\t * @since 1.0.0\n\t * @default 'SAPPHIRE_AUTH'\n\t */\n\tcookie?: string;\n\n\t/**\n\t * The client secret, this can be retrieved in Discord Developer Portal at https://discord.com/developers/applications.\n\t * @since 1.0.0\n\t */\n\tsecret: string;\n\n\t/**\n\t * The scopes defined at https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-scopes.\n\t * @since 1.0.0\n\t * @default [OAuth2Scopes.Identify]\n\t */\n\tscopes?: OAuth2Scopes[];\n\n\t/**\n\t * The redirect uri. This will default to {@link OAuth2BodyData.redirectUri} if missing.\n\t * @since 1.0.0\n\t */\n\tredirect?: string;\n\n\t/**\n\t * The login data transformers used for {@link Auth.fetchData}.\n\t * @since 1.4.0\n\t * @default []\n\t */\n\ttransformers?: LoginDataTransformer[];\n\t/**\n\t * The domain that should be used for the cookie. This overwrites the automatic detection of the domain.\n\t * @remark if you want to support subdomains (`one.example.two` and `two.example.com`) then you need to use prefix your domain with a `.`, for example `.example.com`\n\t * @since 2.1.0\n\t * @default undefined\n\t */\n\tdomainOverwrite?: string;\n}\n\n/**\n * The login data sent when fetching data from a user.\n * @since 1.4.0\n */\nexport interface LoginData {\n\t/**\n\t * The user data, defined when the `'identify'` scope is defined.\n\t * @since 1.4.0\n\t */\n\tuser?: RESTGetAPICurrentUserResult | null;\n\n\t/**\n\t * The guilds data, defined when the `'guilds'` scope is defined.\n\t * @since 1.4.0\n\t */\n\tguilds?: RESTGetAPICurrentUserGuildsResult | null;\n\n\t/**\n\t * The connections data, defined when the `'connections'` scope is defined.\n\t * @since 1.4.0\n\t */\n\tconnections?: RESTGetAPICurrentUserConnectionsResult | null;\n}\n\n/**\n * A login data transformer.\n * @since 1.4.0\n */\nexport interface LoginDataTransformer<T extends LoginData = LoginData> {\n\t/**\n\t * Transforms the object by mutating its properties or adding new ones.\n\t * @since 1.4.0\n\t */\n\t(data: LoginData): Awaitable<T>;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/lib/structures/http/Auth.ts"],"names":[],"mappings":"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","file":"Auth.mjs","sourcesContent":["import { isThenable, type Awaitable } from '@sapphire/utilities';\nimport { createCipheriv, createDecipheriv, randomBytes } from 'crypto';\nimport {\n\tOAuth2Scopes,\n\tRouteBases,\n\tRoutes,\n\ttype RESTGetAPICurrentUserConnectionsResult,\n\ttype RESTGetAPICurrentUserGuildsResult,\n\ttype RESTGetAPICurrentUserResult,\n\ttype Snowflake\n} from 'discord.js';\nimport { fetch } from 'undici';\n\nexport class Auth {\n\t/**\n\t * The client's application id, this can be retrieved in Discord Developer Portal at https://discord.com/developers/applications.\n\t * @since 1.0.0\n\t */\n\tpublic id: Snowflake;\n\n\t/**\n\t * The name for the cookie, this will be used to identify a Secure HttpOnly cookie.\n\t * @since 1.0.0\n\t */\n\tpublic cookie: string;\n\n\t/**\n\t * The scopes defined at https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-scopes.\n\t * @since 1.0.0\n\t */\n\tpublic scopes: readonly OAuth2Scopes[];\n\n\t/**\n\t * The redirect uri.\n\t * @since 1.0.0\n\t */\n\tpublic redirect: string | undefined;\n\n\t/**\n\t * The transformers used for {@link Auth.fetchData}.\n\t * @since 1.4.0\n\t */\n\tpublic transformers: LoginDataTransformer[];\n\n\tpublic domainOverwrite: string | null = null;\n\n\t#secret: string;\n\n\tprivate constructor(options: ServerOptionsAuth) {\n\t\tthis.id = options.id;\n\t\tthis.cookie = options.cookie ?? 'SAPPHIRE_AUTH';\n\t\tthis.scopes = options.scopes ?? [OAuth2Scopes.Identify];\n\t\tthis.redirect = options.redirect;\n\t\tthis.#secret = options.secret;\n\t\tthis.transformers = options.transformers ?? [];\n\t\tthis.domainOverwrite = options.domainOverwrite ?? null;\n\t}\n\n\t/**\n\t * The client secret, this can be retrieved in Discord Developer Portal at https://discord.com/developers/applications.\n\t * @since 1.0.0\n\t */\n\tpublic get secret() {\n\t\treturn this.#secret;\n\t}\n\n\t/**\n\t * Encrypts an object with aes-256-cbc to use as a token.\n\t * @since 1.0.0\n\t * @param data An object to encrypt\n\t */\n\tpublic encrypt(data: AuthData): string {\n\t\tconst iv = randomBytes(16);\n\t\tconst cipher = createCipheriv('aes-256-cbc', this.#secret, iv);\n\t\treturn `${cipher.update(JSON.stringify(data), 'utf8', 'base64') + cipher.final('base64')}.${iv.toString('base64')}`;\n\t}\n\n\t/**\n\t * Decrypts an object with aes-256-cbc to use as a token.\n\t * @since 1.0.0\n\t * @param token An data to decrypt\n\t */\n\tpublic decrypt(token: string): AuthData | null {\n\t\tconst [data, iv] = token.split('.');\n\t\tconst decipher = createDecipheriv('aes-256-cbc', this.#secret, Buffer.from(iv, 'base64'));\n\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(decipher.update(data, 'base64', 'utf8') + decipher.final('utf8')) as AuthData;\n\t\t\t// If the token expired, return null:\n\t\t\treturn parsed.expires >= Date.now() ? parsed : null;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Retrieves the data for a specific user.\n\t * @since 1.4.0\n\t * @param token The access token from the user.\n\t */\n\tpublic async fetchData(token: string): Promise<LoginData> {\n\t\t// Fetch the information:\n\t\tconst [user, guilds, connections] = await Promise.all([\n\t\t\tthis.fetchInformation<RESTGetAPICurrentUserResult>(OAuth2Scopes.Identify, token, `${RouteBases.api}${Routes.user()}`),\n\t\t\tthis.fetchInformation<RESTGetAPICurrentUserGuildsResult>(OAuth2Scopes.Guilds, token, `${RouteBases.api}${Routes.userGuilds()}`),\n\t\t\tthis.fetchInformation<RESTGetAPICurrentUserConnectionsResult>(\n\t\t\t\tOAuth2Scopes.Connections,\n\t\t\t\ttoken,\n\t\t\t\t`${RouteBases.api}${Routes.userConnections()}`\n\t\t\t)\n\t\t]);\n\n\t\t// Transform the information:\n\t\tlet data: LoginData = { user, guilds, connections };\n\t\tfor (const transformer of this.transformers) {\n\t\t\tconst result = transformer(data);\n\t\t\tif (isThenable(result)) data = await result;\n\t\t\telse data = result as LoginData;\n\t\t}\n\n\t\treturn data;\n\t}\n\n\tprivate async fetchInformation<T>(scope: OAuth2Scopes, token: string, url: string): Promise<T | null | undefined> {\n\t\tif (!this.scopes.includes(scope)) return undefined;\n\n\t\tconst result = await fetch(url, {\n\t\t\theaders: {\n\t\t\t\tauthorization: `Bearer ${token}`\n\t\t\t}\n\t\t});\n\n\t\treturn result.ok ? ((await result.json()) as T) : null;\n\t}\n\n\tpublic static create(options?: ServerOptionsAuth): Auth | null {\n\t\tif (!options?.secret || !options.id) return null;\n\t\treturn new Auth(options);\n\t}\n}\n\n/**\n * Defines the authentication data, this is to be encrypted and decrypted by the server.\n * @since 1.0.0\n */\nexport interface AuthData {\n\t/**\n\t * The user ID.\n\t * @since 1.0.0\n\t */\n\tid: string;\n\n\t/**\n\t * The timestamp at which the token expires.\n\t * @since 1.0.0\n\t */\n\texpires: number;\n\n\t/**\n\t * The refresh token.\n\t * @since 1.0.0\n\t */\n\trefresh: string;\n\n\t/**\n\t * The access token.\n\t * @since 1.0.0\n\t */\n\ttoken: string;\n}\n\n/**\n * Defines the authentication options.\n * @since 1.0.0\n */\nexport interface ServerOptionsAuth {\n\t/**\n\t * The client's application id, this can be retrieved in Discord Developer Portal at https://discord.com/developers/applications.\n\t * @since 1.0.0\n\t */\n\tid: Snowflake;\n\n\t/**\n\t * The name for the cookie, this will be used to identify a Secure HttpOnly cookie.\n\t * @since 1.0.0\n\t * @default 'SAPPHIRE_AUTH'\n\t */\n\tcookie?: string;\n\n\t/**\n\t * The client secret, this can be retrieved in Discord Developer Portal at https://discord.com/developers/applications.\n\t * @since 1.0.0\n\t */\n\tsecret: string;\n\n\t/**\n\t * The scopes defined at https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-scopes.\n\t * @since 1.0.0\n\t * @default [OAuth2Scopes.Identify]\n\t */\n\tscopes?: OAuth2Scopes[];\n\n\t/**\n\t * The redirect uri. This will default to {@link OAuth2BodyData.redirectUri} if missing.\n\t * @since 1.0.0\n\t */\n\tredirect?: string;\n\n\t/**\n\t * The login data transformers used for {@link Auth.fetchData}.\n\t * @since 1.4.0\n\t * @default []\n\t */\n\ttransformers?: LoginDataTransformer[];\n\t/**\n\t * The domain that should be used for the cookie. This overwrites the automatic detection of the domain.\n\t * @remark if you want to support subdomains (`one.example.two` and `two.example.com`) then you need to use prefix your domain with a `.`, for example `.example.com`\n\t * @since 2.1.0\n\t * @default undefined\n\t */\n\tdomainOverwrite?: string;\n}\n\n/**\n * The login data sent when fetching data from a user.\n * @since 1.4.0\n */\nexport interface LoginData {\n\t/**\n\t * The user data, defined when the `'identify'` scope is defined.\n\t * @since 1.4.0\n\t */\n\tuser?: RESTGetAPICurrentUserResult | null;\n\n\t/**\n\t * The guilds data, defined when the `'guilds'` scope is defined.\n\t * @since 1.4.0\n\t */\n\tguilds?: RESTGetAPICurrentUserGuildsResult | null;\n\n\t/**\n\t * The connections data, defined when the `'connections'` scope is defined.\n\t * @since 1.4.0\n\t */\n\tconnections?: RESTGetAPICurrentUserConnectionsResult | null;\n}\n\n/**\n * A login data transformer.\n * @since 1.4.0\n */\nexport interface LoginDataTransformer<T extends LoginData = LoginData> {\n\t/**\n\t * Transforms the object by mutating its properties or adding new ones.\n\t * @since 1.4.0\n\t */\n\t(data: LoginData): Awaitable<T>;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/lib/utils/_body/RequestHeadersProxy.ts"],"names":[],"mappings":";;;;;AAMO,IAAM,oBAAA,GAAN,MAAM,oBAAuC,CAAA;AAAA,EAG5C,YAAY,OAAqB,EAAA;AAFxC,IAAiB,aAAA,CAAA,IAAA,EAAA,SAAA,CAAA;AAGhB,IAAA,IAAA,CAAK,OAAU,GAAA,OAAA;AAAA;AAChB,EAEO,MAAA,CAAO,MAAc,KAAqB,EAAA;AAChD,IAAM,MAAA,EAAE,OAAQ,EAAA,GAAI,IAAK,CAAA,OAAA;AACzB,IAAM,MAAA,OAAA,GAAU,QAAQ,IAAI,CAAA;AAC5B,IAAA,IAAI,OAAS,EAAA;AACZ,MAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,OAAO,CAAG,EAAA;AAC3B,QAAA,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,OACZ,MAAA;AACN,QAAA,OAAA,CAAQ,IAAI,CAAA,GAAI,CAAC,OAAA,EAAS,KAAK,CAAA;AAAA;AAChC,KACM,MAAA;AACN,MAAA,OAAA,CAAQ,IAAI,CAAI,GAAA,KAAA;AAAA;AACjB;AACD,EAEO,OAAO,IAAoB,EAAA;AACjC,IAAK,IAAA,CAAA,OAAA,CAAQ,OAAQ,CAAA,IAAI,CAAI,GAAA,
|
|
1
|
+
{"version":3,"sources":["../../../../../src/lib/utils/_body/RequestHeadersProxy.ts"],"names":[],"mappings":"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","file":"RequestHeadersProxy.mjs","sourcesContent":["import { isNullishOrEmpty } from '@sapphire/utilities';\nimport { splitSetCookieString } from 'cookie-es';\nimport type { Headers, SpecIterableIterator } from 'undici';\nimport type { ApiRequest } from '../../structures/api/ApiRequest';\nimport { NodeUtilInspectSymbol } from '../constants';\n\nexport class RequestHeadersProxy implements Headers {\n\tprivate readonly request: ApiRequest;\n\n\tpublic constructor(request: ApiRequest) {\n\t\tthis.request = request;\n\t}\n\n\tpublic append(name: string, value: string): void {\n\t\tconst { headers } = this.request;\n\t\tconst current = headers[name];\n\t\tif (current) {\n\t\t\tif (Array.isArray(current)) {\n\t\t\t\tcurrent.push(value);\n\t\t\t} else {\n\t\t\t\theaders[name] = [current, value];\n\t\t\t}\n\t\t} else {\n\t\t\theaders[name] = value;\n\t\t}\n\t}\n\n\tpublic delete(name: string): void {\n\t\tthis.request.headers[name] = undefined;\n\t}\n\n\tpublic get(name: string): string | null {\n\t\treturn normalizeValue(this.request.headers[name]);\n\t}\n\n\tpublic has(name: string): boolean {\n\t\treturn !isNullishOrEmpty(this.request.headers[name]);\n\t}\n\n\tpublic set(name: string, value: string): void {\n\t\tthis.request.headers[name] = value;\n\t}\n\n\tpublic getSetCookie(): string[] {\n\t\tconst setCookie = this.get('set-cookie');\n\t\treturn setCookie === null ? [] : splitSetCookieString(setCookie);\n\t}\n\n\tpublic forEach(callbackfn: (value: string, key: string, iterable: Headers) => void, thisArg?: unknown): void {\n\t\tfor (const [key, value] of this.entries()) {\n\t\t\tcallbackfn.call(thisArg, value, key, this);\n\t\t}\n\t}\n\n\tpublic *keys(): SpecIterableIterator<string> {\n\t\tconst { headers } = this.request;\n\t\tfor (const key of Object.keys(headers)) {\n\t\t\tconst value = headers[key];\n\n\t\t\tif (!isNullishOrEmpty(value)) {\n\t\t\t\tyield key;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic *values(): SpecIterableIterator<string> {\n\t\tconst { headers } = this.request;\n\t\tfor (const key of Object.keys(headers)) {\n\t\t\tconst value = headers[key];\n\n\t\t\tif (!isNullishOrEmpty(value)) {\n\t\t\t\tyield normalizeValue(value);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic *entries(): SpecIterableIterator<[string, string]> {\n\t\tconst { headers } = this.request;\n\t\tfor (const key of Object.keys(headers)) {\n\t\t\tconst value = headers[key];\n\n\t\t\tif (!isNullishOrEmpty(value)) {\n\t\t\t\tyield [key, normalizeValue(value)];\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic [Symbol.iterator](): SpecIterableIterator<[string, string]> {\n\t\treturn this.entries();\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/class-literal-property-style\n\tpublic get [Symbol.toStringTag]() {\n\t\treturn 'Headers';\n\t}\n\n\tpublic [NodeUtilInspectSymbol]() {\n\t\treturn Object.fromEntries(this.entries());\n\t}\n}\n\nfunction normalizeValue(value: string | string[] | undefined): string {\n\tif (Array.isArray(value)) {\n\t\treturn value.join(', ');\n\t}\n\n\treturn String(value ?? '');\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sapphire/plugin-api",
|
|
3
|
-
"version": "8.1.0-next.
|
|
3
|
+
"version": "8.1.0-next.9f69aae",
|
|
4
4
|
"description": "Plugin for @sapphire/framework to expose a REST API",
|
|
5
5
|
"author": "@sapphire",
|
|
6
6
|
"license": "MIT",
|
|
@@ -51,11 +51,11 @@
|
|
|
51
51
|
"check-update": "cliff-jumper --dry-run"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@types/ws": "^8.
|
|
54
|
+
"@types/ws": "^8.18.1",
|
|
55
55
|
"@vladfrangu/async_event_emitter": "2.4.6",
|
|
56
|
-
"cookie-es": "^
|
|
57
|
-
"tldts": "^
|
|
58
|
-
"undici": "^7.
|
|
56
|
+
"cookie-es": "^2.0.0",
|
|
57
|
+
"tldts": "^7.0.0",
|
|
58
|
+
"undici": "^7.8.0"
|
|
59
59
|
},
|
|
60
60
|
"repository": {
|
|
61
61
|
"type": "git",
|
|
@@ -89,8 +89,8 @@
|
|
|
89
89
|
"@favware/cliff-jumper": "^6.0.0",
|
|
90
90
|
"@favware/rollup-type-bundler": "^4.0.0",
|
|
91
91
|
"concurrently": "^9.1.2",
|
|
92
|
-
"tsup": "^8.
|
|
93
|
-
"tsx": "^4.19.
|
|
92
|
+
"tsup": "^8.4.0",
|
|
93
|
+
"tsx": "^4.19.3",
|
|
94
94
|
"typedoc": "^0.26.11",
|
|
95
95
|
"typedoc-json-parser": "^10.2.0",
|
|
96
96
|
"typescript": "~5.4.5"
|