UNPKG

pipebomb.js

Version:

Library for interacting with Pipe Bomb servers

147 lines 5.88 kB
import Axios from "axios"; import CollectionCache from "./collection/CollectionCache.js"; import Context from "./Context.js"; import TrackCache from "./music/TrackCache.js"; import V1 from "./version/V1.js"; import Cryptico from "./Crypto.js"; import CryptoJS from "crypto-js"; import { BufferShim } from "./lib/Buffer.js"; export default class PipeBomb { constructor(serverURL, options) { this.context = new Context(serverURL, this, options); this.trackCache = new TrackCache(this.context, options?.trackCacheTime ?? 60); this.collectionCache = new CollectionCache(this.context, this.trackCache, options?.CollectionCacheTime ?? 600); this.v1 = new V1(this.context, this.trackCache, this.collectionCache); } async authenticate(username, options) { let privateKey = options?.privateKey; if (privateKey) { this.context.setPrivateKey(options.privateKey); } else { privateKey = this.context.getPrivateKey(); if (!privateKey) { throw `Pipe Bomb instance has not been assigned a private key`; } } this.context.setUsername(username); const key = Cryptico.RSAKey.parse(BufferShim.from(privateKey, "base64").toString("utf-8")); const publicKey = Cryptico.publicKeyString(key); const userID = PipeBomb.getUserIDFromPublicKey(publicKey); this.context.setPrivateKey(privateKey); const response = await this.context.makeRequest("post", "v1/login", { user_id: userID, public_key: publicKey, create_if_missing: !!options?.createIfMissing }); if (response.statusCode != 200 || typeof response.response?.secret != "string") throw response; const secret = response.response.secret; const decrypted = PipeBomb.decrypt(secret, privateKey); const tokenResponse = await this.context.makeRequest("post", "v1/authenticate", { user_id: userID, username, secret: decrypted }); if (tokenResponse.statusCode != 200 || typeof tokenResponse.response?.token != "string") throw tokenResponse; const token = tokenResponse.response.token; this.context.setToken(token); return token; } static async checkHost(serverURL) { if (serverURL.toLowerCase().startsWith("http://")) { serverURL = serverURL.substring(7); } else if (serverURL.toLowerCase().startsWith("https://")) { serverURL = serverURL.substring(8); } while (serverURL.endsWith("/")) { serverURL = serverURL.slice(0, -1); } function connect(https) { return new Promise(async (resolve, reject) => { Axios.get(`http${https ? "s" : ""}://${serverURL}/v1/identify`) .then(data => { if (data.data?.statusCode == 200 && data.data?.response?.pipeBombServer === true || typeof data.data?.response?.name === "string") { return resolve(data.data.response.name); } reject("not pipe bomb"); }, () => { reject("connection failure"); }); }); } try { const name = await connect(true); return { host: "https://" + serverURL, name, https: true }; } catch (e) { if (e == "not pipe bomb") { return null; } } try { const name = await connect(false); return { host: "http://" + serverURL, name, https: false }; } catch { } return null; } static getCredentialHash(username, password) { const passwordHash = CryptoJS.SHA256(password).toString(); const usernameHash = CryptoJS.SHA256(username).toString(); const hash = CryptoJS.SHA256(passwordHash + usernameHash).toString(); return hash; } static getUserIDFromPublicKey(publicKey) { return Cryptico.publicKeyID(publicKey); } static generatePrivateKey(accountHash) { const privateKeyJson = Cryptico.generateRSAKey(accountHash, 2048); const privateKey = BufferShim.from(JSON.stringify(privateKeyJson.toJSON())).toString("base64"); return privateKey; } static getAccountKeys(privateKey) { const privateKeyJson = Cryptico.RSAKey.parse(BufferShim.from(privateKey, "base64").toString("utf-8")); const publicKey = Cryptico.publicKeyString(privateKeyJson); return { publicKey, userID: this.getUserIDFromPublicKey(publicKey) }; } static encrypt(message, publicKey) { try { if (typeof message == "object") { message = JSON.stringify(message); } } catch { } const response = Cryptico.encrypt(message, publicKey); if (response.status != "success") throw `Failed to encrypt payload with public key`; return response.cipher; } static decrypt(message, privateKey) { const key = Cryptico.RSAKey.parse(BufferShim.from(privateKey, "base64").toString("utf-8")); const response = Cryptico.decrypt(JSON.stringify(message), key); if (response.status != "success") throw `Failed to decrypt payload with private key`; try { if (response.plaintext.startsWith("[") || response.plaintext.startsWith("{")) { return JSON.parse(response.plaintext); } } catch { } return response.plaintext; } } //# sourceMappingURL=index.js.map