Re"structuring" pluginCertifier

This commit is contained in:
Jean Ouina 2020-06-12 23:44:01 +02:00
parent 4ed3c4b78b
commit 93a735193b
12 changed files with 343 additions and 327 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -78,6 +78,7 @@ export const settings = {
/* Content */ /* Content */
"Content Error Modal": {id: "fork-ps-1", info: "Shows a modal with plugin/theme errors", implemented: true, hidden: false, cat: "core", category: "content manager"}, "Content Error Modal": {id: "fork-ps-1", info: "Shows a modal with plugin/theme errors", implemented: true, hidden: false, cat: "core", category: "content manager"},
"Scan Plugins": {id: "fork-ps-6", info: "Scan plugins for any threat that can be hidden inside.", implemented: true, hidden: false, cat: "core", category: "content manager"},
"Show Toasts": {id: "fork-ps-2", info: "Shows a small notification for important information", implemented: true, hidden: false, cat: "core", category: "content manager"}, "Show Toasts": {id: "fork-ps-2", info: "Shows a small notification for important information", implemented: true, hidden: false, cat: "core", category: "content manager"},
"Scroll To Settings": {id: "fork-ps-3", info: "Auto-scrolls to a plugin's settings when the button is clicked (only if out of view)", implemented: true, hidden: false, cat: "core", category: "content manager"}, "Scroll To Settings": {id: "fork-ps-3", info: "Auto-scrolls to a plugin's settings when the button is clicked (only if out of view)", implemented: true, hidden: false, cat: "core", category: "content manager"},
"Automatic Loading": {id: "fork-ps-5", info: "Automatically loads, reloads, and unloads plugins and themes", implemented: true, hidden: false, cat: "core", category: "content manager"}, "Automatic Loading": {id: "fork-ps-5", info: "Automatically loads, reloads, and unloads plugins and themes", implemented: true, hidden: false, cat: "core", category: "content manager"},
@ -129,6 +130,7 @@ export const defaultCookie = {
"fork-ps-3": true, "fork-ps-3": true,
"fork-ps-4": true, "fork-ps-4": true,
"fork-ps-5": true, "fork-ps-5": true,
"fork-ps-6": true,
"fork-es-2": false, "fork-es-2": false,
"fork-es-3": true, "fork-es-3": true,
"fork-wp-1": false, "fork-wp-1": false,

View File

@ -1,8 +1,8 @@
const __non_webpack_require__ = window.require
import {bdConfig, bdplugins, bdthemes} from "../0globals"; import {bdConfig, bdplugins, bdthemes} from "../0globals";
import pluginModule from "./pluginModule"; import pluginModule from "./pluginModule";
import themeModule from "./themeModule"; import themeModule from "./themeModule";
import Utils from "./utils"; import Utils from "./utils";
import * as crypto from "crypto"
const path = require("path"); const path = require("path");
const fs = require("fs"); const fs = require("fs");
@ -171,9 +171,9 @@ export default new class ContentManager {
if (typeof(filename) === "undefined" || typeof(type) === "undefined") return; if (typeof(filename) === "undefined" || typeof(type) === "undefined") return;
const isPlugin = type === "plugin"; const isPlugin = type === "plugin";
const baseFolder = isPlugin ? this.pluginsFolder : this.themesFolder; const baseFolder = isPlugin ? this.pluginsFolder : this.themesFolder;
try {__non_webpack_require__(path.resolve(baseFolder, filename));} try {window.require(path.resolve(baseFolder, filename));}
catch (error) {return {name: filename, file: filename, message: "Could not be compiled.", error: {message: error.message, stack: error.stack}};} catch (error) {return {name: filename, file: filename, message: "Could not be compiled.", error: {message: error.message, stack: error.stack}};}
const content = __non_webpack_require__(path.resolve(baseFolder, filename)); const content = window.require(path.resolve(baseFolder, filename));
if(!content.name)return {name: filename, file: filename, message: "Cannot escape the ID.", error: {message: "Cannot read property 'replace' of undefined", stack: "Cannot read property 'replace' of undefined"}} if(!content.name)return {name: filename, file: filename, message: "Cannot escape the ID.", error: {message: "Cannot read property 'replace' of undefined", stack: "Cannot read property 'replace' of undefined"}}
content.id = Utils.escapeID(content.name); content.id = Utils.escapeID(content.name);
if (isPlugin) { if (isPlugin) {
@ -189,14 +189,14 @@ export default new class ContentManager {
delete bdthemes[content.name]; delete bdthemes[content.name];
bdthemes[content.name] = content; bdthemes[content.name] = content;
} }
} }
unloadContent(filename, type) { unloadContent(filename, type) {
if (typeof(filename) === "undefined" || typeof(type) === "undefined") return; if (typeof(filename) === "undefined" || typeof(type) === "undefined") return;
const isPlugin = type === "plugin"; const isPlugin = type === "plugin";
const baseFolder = isPlugin ? this.pluginsFolder : this.themesFolder; const baseFolder = isPlugin ? this.pluginsFolder : this.themesFolder;
try { try {
delete __non_webpack_require__.cache[__non_webpack_require__.resolve(path.resolve(baseFolder, filename))]; delete window.require.cache[window.require.resolve(path.resolve(baseFolder, filename))];
} }
catch (err) {return {name: filename, file: filename, message: "Could not be unloaded.", error: {message: err.message, stack: err.stack}};} catch (err) {return {name: filename, file: filename, message: "Could not be unloaded.", error: {message: err.message, stack: err.stack}};}
} }
@ -204,7 +204,7 @@ export default new class ContentManager {
isLoaded(filename, type) { isLoaded(filename, type) {
const isPlugin = type === "plugin"; const isPlugin = type === "plugin";
const baseFolder = isPlugin ? this.pluginsFolder : this.themesFolder; const baseFolder = isPlugin ? this.pluginsFolder : this.themesFolder;
try {__non_webpack_require__.cache[__non_webpack_require__.resolve(path.resolve(baseFolder, filename))];} try {window.require.cache[window.require.resolve(path.resolve(baseFolder, filename))];}
catch (err) {return false;} catch (err) {return false;}
return true; return true;
} }

View File

@ -47,6 +47,7 @@ Core.prototype.init = async function() {
return; return;
} }
/*
const latestLocalVersion = bdConfig.updater ? bdConfig.updater.LatestVersion : bdConfig.latestVersion; const latestLocalVersion = bdConfig.updater ? bdConfig.updater.LatestVersion : bdConfig.latestVersion;
if (latestLocalVersion > bdConfig.version) { if (latestLocalVersion > bdConfig.version) {
Utils.showConfirmationModal("Update Available", [`There is an update available for BandagedBD's Injector (${latestLocalVersion}).`, "You can either update and restart now, or later."], { Utils.showConfirmationModal("Update Available", [`There is an update available for BandagedBD's Injector (${latestLocalVersion}).`, "You can either update and restart now, or later."], {
@ -66,7 +67,7 @@ Core.prototype.init = async function() {
} }
} }
}); });
} }*/
Utils.log("Startup", "Initializing Settings"); Utils.log("Startup", "Initializing Settings");
this.initSettings(); this.initSettings();
@ -107,7 +108,7 @@ Core.prototype.init = async function() {
DataStore.setBDData("version", bbdVersion); DataStore.setBDData("version", bbdVersion);
} }
const emojiModule = EmojiModule EmojiModule.start()
Utils.suppressErrors(this.patchSocial.bind(this), "BD Social Patch")(); Utils.suppressErrors(this.patchSocial.bind(this), "BD Social Patch")();
Utils.suppressErrors(this.patchGuildPills.bind(this), "BD Guild Pills Patch")(); Utils.suppressErrors(this.patchGuildPills.bind(this), "BD Guild Pills Patch")();
@ -125,6 +126,7 @@ Core.prototype.init = async function() {
} }
const logo = document.querySelector("#app-mount > div.typeWindows-1za-n7.withFrame-haYltI.titleBar-AC4pGV.horizontalReverse-3tRjY7.flex-1O1GKY.directionRowReverse-m8IjIq.justifyStart-2NDFzi.alignStretch-DpGPf3.da-typeWindows.da-withFrame.da-titleBar.da-horizontalReverse.da-flex.da-directionRowReverse.da-justifyStart.da-alignStretch > div.wordmarkWindows-1v0lYD.wordmark-2iDDfm.da-wordmarkWindows.da-wordmark") const logo = document.querySelector("#app-mount > div.typeWindows-1za-n7.withFrame-haYltI.titleBar-AC4pGV.horizontalReverse-3tRjY7.flex-1O1GKY.directionRowReverse-m8IjIq.justifyStart-2NDFzi.alignStretch-DpGPf3.da-typeWindows.da-withFrame.da-titleBar.da-horizontalReverse.da-flex.da-directionRowReverse.da-justifyStart.da-alignStretch > div.wordmarkWindows-1v0lYD.wordmark-2iDDfm.da-wordmarkWindows.da-wordmark")
if(logo){ if(logo){
logo.style.top = "3px"
logo.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" height="10" width="70" viewBox="0 0 72.54 10" style="margin-left: -5px, margin-top: 10px"> logo.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" height="10" width="70" viewBox="0 0 72.54 10" style="margin-left: -5px, margin-top: 10px">
<path fill="currentColor" d="M44.81,9.67V6.33c0-1.21,2.13-1.49,2.78-.28l2-.81A3.53,3.53,0,0,0,46.2,3c-1.92,0-3.81,1.13-3.81,3.33V9.67c0,2.21,1.89,3.33,3.77,3.33a3.87,3.87,0,0,0,3.45-2.18l-2.12-1C47,11.17,44.81,10.85,44.81,9.67ZM10.68,12.89h2.41V3.17H10.68ZM71.76,3.14H68.19V7.23L70.57,9.4v-4h1.27c.81,0,1.21.41,1.21,1v3c0,.63-.38,1.05-1.21,1.05H68.18v2.31h3.57c1.92,0,3.72-1,3.72-3.2V6.39C75.48,4.13,73.68,3.14,71.76,3.14ZM54.22,3c-2,0-4,1.1-4,3.34V9.66c0,2.23,2,3.34,4,3.34s3.95-1.11,3.95-3.34V6.34C58.19,4.11,56.2,3,54.22,3Zm1.55,6.66c0,.7-.78,1.06-1.54,1.06s-1.55-.35-1.55-1.06V6.34c0-.72.75-1.1,1.5-1.1s1.59.35,1.59,1.1ZM66.84,6.34c0-2.29-1.58-3.2-3.55-3.2H59.46v9.73h2.45V9.77h.43l2.22,3.09h3L65,9.52C66.13,9.15,66.84,8.14,66.84,6.34ZM63.33,7.65H61.91V5.43h1.42A1.11,1.11,0,1,1,63.33,7.65ZM29.83,13h2.42V3.06H29.83V6.73l-3,0V3.09H24.7v9.78h2.14V8.68l3,0ZM17.16,9.76V6.42c0-1.21,2.13-1.49,2.78-.28l2-.81a3.55,3.55,0,0,0-3.36-2.24c-1.92,0-3.81,1.13-3.81,3.33V9.76c0,2.21,2,3.15,3.9,3.15s3.58-1,3.58-3V7.58H18.79l0,1.36H20.3v.77C20.3,10.92,17.16,10.94,17.16,9.76Z" transform="translate(-2.93 -3)"/> <path fill="currentColor" d="M44.81,9.67V6.33c0-1.21,2.13-1.49,2.78-.28l2-.81A3.53,3.53,0,0,0,46.2,3c-1.92,0-3.81,1.13-3.81,3.33V9.67c0,2.21,1.89,3.33,3.77,3.33a3.87,3.87,0,0,0,3.45-2.18l-2.12-1C47,11.17,44.81,10.85,44.81,9.67ZM10.68,12.89h2.41V3.17H10.68ZM71.76,3.14H68.19V7.23L70.57,9.4v-4h1.27c.81,0,1.21.41,1.21,1v3c0,.63-.38,1.05-1.21,1.05H68.18v2.31h3.57c1.92,0,3.72-1,3.72-3.2V6.39C75.48,4.13,73.68,3.14,71.76,3.14ZM54.22,3c-2,0-4,1.1-4,3.34V9.66c0,2.23,2,3.34,4,3.34s3.95-1.11,3.95-3.34V6.34C58.19,4.11,56.2,3,54.22,3Zm1.55,6.66c0,.7-.78,1.06-1.54,1.06s-1.55-.35-1.55-1.06V6.34c0-.72.75-1.1,1.5-1.1s1.59.35,1.59,1.1ZM66.84,6.34c0-2.29-1.58-3.2-3.55-3.2H59.46v9.73h2.45V9.77h.43l2.22,3.09h3L65,9.52C66.13,9.15,66.84,8.14,66.84,6.34ZM63.33,7.65H61.91V5.43h1.42A1.11,1.11,0,1,1,63.33,7.65ZM29.83,13h2.42V3.06H29.83V6.73l-3,0V3.09H24.7v9.78h2.14V8.68l3,0ZM17.16,9.76V6.42c0-1.21,2.13-1.49,2.78-.28l2-.81a3.55,3.55,0,0,0-3.36-2.24c-1.92,0-3.81,1.13-3.81,3.33V9.76c0,2.21,2,3.15,3.9,3.15s3.58-1,3.58-3V7.58H18.79l0,1.36H20.3v.77C20.3,10.92,17.16,10.94,17.16,9.76Z" transform="translate(-2.93 -3)"/>
<polygon fill="currentColor" points="35.91 0.06 38.43 0.06 38.43 1.84 35.92 1.81 35.97 10 33.55 10 33.49 1.75 30.98 1.74 30.98 0.06 33.49 0.06 35.91 0.06"/> <polygon fill="currentColor" points="35.91 0.06 38.43 0.06 38.43 1.84 35.92 1.81 35.97 10 33.55 10 33.49 1.75 30.98 1.74 30.98 0.06 33.49 0.06 35.91 0.06"/>
@ -176,9 +178,13 @@ Core.prototype.initSettings = function () {
} }
}; };
let classNameLayer
let classNameSocialLinks
let classNameModal
Core.prototype.initObserver = function () { Core.prototype.initObserver = function () {
const mainObserver = new MutationObserver((mutations) => { const mainObserver = new MutationObserver((mutations) => {
for (let i = 0, mlen = mutations.length; i < mlen; i++) { for (let i = 0, mlen = mutations.length; i < mlen; i++) {
const mutation = mutations[i]; const mutation = mutations[i];
if (typeof pluginModule !== "undefined") pluginModule.rawObserver(mutation); if (typeof pluginModule !== "undefined") pluginModule.rawObserver(mutation);
@ -188,13 +194,9 @@ Core.prototype.initObserver = function () {
const node = mutation.addedNodes[0]; const node = mutation.addedNodes[0];
let [ if(!classNameLayer)classNameLayer = BDModules.get((e) => e.layer && typeof e.layer === "string" && e.animating)[0].layer
classNameLayer, if(!classNameSocialLinks)classNameSocialLinks = BDModules.get((e) => e.socialLinks && typeof e.socialLinks === "string")[0].socialLinks
classNameSocialLinks if(!classNameModal)classNameModal = BDModules.get((e) => e.modal && typeof e.modal === "string" && e.inner && typeof e.inner === "string" && !e.responsiveWidthMobile)[0].modal
] = [
BDModules.get((e) => e.layer && typeof e.layer === "string" && e.animating)[0].layer,
BDModules.get((e) => e.socialLinks && typeof e.socialLinks === "string")[0].socialLinks
]
if (node.classList.contains(classNameLayer)) { if (node.classList.contains(classNameLayer)) {
if (node.getElementsByClassName("guild-settings-base-section").length) node.setAttribute("layer-id", "server-settings"); if (node.getElementsByClassName("guild-settings-base-section").length) node.setAttribute("layer-id", "server-settings");
@ -208,6 +210,28 @@ Core.prototype.initObserver = function () {
if (node.parentElement == document.body && node.querySelector("#ace_settingsmenu")) node.id = "ace_settingsmenu_container"; if (node.parentElement == document.body && node.querySelector("#ace_settingsmenu")) node.id = "ace_settingsmenu_container";
/*
if(node.classList.contains(classNameModal)){
try{
/**
* @type {Element}
*//*
const UserProfile = Utils.getNestedProp(node, "childNodes.0.childNodes.0")
let user = BDV2.getInternalInstance(node).pendingProps.children.props.children.props.user
console.log(user)
if(UserProfile && UserProfile.childNodes.length === 2){
let header = UserProfile.childNodes[0].childNodes[0]
let children = BDV2.getInternalInstance(header).return.pendingProps.children[1]
console.log(children)
children.push(BDV2.react.createElement("p", {}, "sltsv"))
}
}catch(e){
console.error("An error occured in Badge Rendering:", e)
}
}*/
// Emoji Picker // Emoji Picker
//node.getElementsByClassName("emojiPicker-3m1S-j").length && !node.querySelector(".emojiPicker-3m1S-j").parentElement.classList.contains("animatorLeft-1EQxU0") //node.getElementsByClassName("emojiPicker-3m1S-j").length && !node.querySelector(".emojiPicker-3m1S-j").parentElement.classList.contains("animatorLeft-1EQxU0")
//if (node.classList.contains(classNameLayer2) && node.getElementsByClassName(classNameEmojiPicker).length && !node.querySelector("."+classNameEmojiPicker).parentElement.classList.contains(classNameAnimatorLeft)) quickEmoteMenu.obsCallback(node); //if (node.classList.contains(classNameLayer2) && node.getElementsByClassName(classNameEmojiPicker).length && !node.querySelector("."+classNameEmojiPicker).parentElement.classList.contains(classNameAnimatorLeft)) quickEmoteMenu.obsCallback(node);
@ -481,7 +505,7 @@ Core.prototype.patchMemberList = function() {
children.push( children.push(
BDV2.React.createElement(TooltipWrap, {color: "black", side: "top", text: "Lightcord Developer"}, BDV2.React.createElement(TooltipWrap, {color: "black", side: "top", text: "Lightcord Developer"},
BDV2.React.createElement(Anchor, {className: "bd-member-badge", href: "https://github.com/Lightcord/Lightcord", title: "Lightcord", target: "_blank"}, BDV2.React.createElement(Anchor, {className: "bd-member-badge", href: "https://github.com/Lightcord/Lightcord", title: "Lightcord", target: "_blank"},
BDV2.React.createElement(LightcordLogo, {size: "32px", className: "bd-logo"}) BDV2.React.createElement(LightcordLogo, {size: "16px", className: "bd-logo"})
) )
) )
); );

View File

@ -180,6 +180,10 @@ export default new class EmojiModule {
this.cancelEmoteRender(); this.cancelEmoteRender();
this.cancelEmoteRender = null; this.cancelEmoteRender = null;
} }
start(){
}
} }
function D(e, t, n, r, o, i, s, u, l, c) { function D(e, t, n, r, o, i, s, u, l, c) {

View File

@ -4,16 +4,11 @@ import * as crypto from "crypto"
import BDV2 from "./v2" import BDV2 from "./v2"
import tooltipWrap from "../ui/tooltipWrap" import tooltipWrap from "../ui/tooltipWrap"
import Utils from "./utils" import Utils from "./utils"
import { createReadStream } from "fs"
import { basename } from "path"
const debug = true
const cache = {} const cache = {}
const cache2 = {} const cache2 = {}
/*
const PinnedModule = BDModules.get(e => e.default && e.default.getPinnedMessages)[0].default
const ChannelModule = BDModules.get(e => e.default && e.default.getChannelId)[0].default
const fetchMessagesModule = BDModules.get(e => e.default && e.default.fetchMessages)[0].default
const fetchMessagesModule2 = BDModules.get(e => e.default && e.default.fetchMessages)[1].default
const getMessagesModule = BDModules.get(e => e.default && e.default.getMessages)[0].default*/
export default new class PluginCertifier { export default new class PluginCertifier {
constructor(){} constructor(){}
@ -25,103 +20,15 @@ export default new class PluginCertifier {
} }
start(){ start(){
/*const dispatcher = window.Lightcord.DiscordModules.dispatcher
const constants = window.Lightcord.DiscordModules.constants
const originalFetchMessages = fetchMessagesModule.fetchMessages }
fetchMessagesModule.fetchMessages = function(){
const returnValue = originalFetchMessages.apply(this, arguments)
if(returnValue instanceof Promise){
returnValue
.then(() => {
const ev = getMessagesModule.getMessages(ChannelModule.getChannelId())
process.nextTick(() => {
for(const message of ev._array){
const attachments = message.attachments || []
if(attachments.length === 0)continue // no attachments
attachments.forEach(attachment => {
processAttachment(attachment)
})
}
})
})
}
return returnValue
}
const originalFetchMessages2 = fetchMessagesModule2.fetchMessages isTrusted(hash){
fetchMessagesModule2.fetchMessages = function(){ return cache[hash] && !cache[hash].suspect
const returnValue = originalFetchMessages2.apply(this, arguments)
if(returnValue instanceof Promise){
returnValue
.then(() => {
const ev = getMessagesModule.getMessages(ChannelModule.getChannelId())
process.nextTick(() => {
for(const message of ev._array){
const attachments = message.attachments || []
if(attachments.length === 0)continue // no attachments
attachments.forEach(attachment => {
processAttachment(attachment)
})
}
})
})
}
return returnValue
}
const alreadyUsed = {}
const originalGetPinnedMessages = PinnedModule.getPinnedMessages.bind(PinnedModule)
PinnedModule.getPinnedMessages = function(){
const pinned = originalGetPinnedMessages(...arguments)
if(!pinned || alreadyUsed[pinned.id])return pinned
alreadyUsed[pinned.id] = true
setTimeout(() => {
delete alreadyUsed[pinned.id]
for(const message of pinned.messages){
const attachments = message.attachments || []
if(attachments.length === 0)continue // no attachments
attachments.forEach(attachment => {
processAttachment(attachment)
})
}
}, 50);
return pinned
}
dispatcher.subscribe(constants.ActionTypes.MESSAGE_CREATE, (ev) => {
const message = ev.message
if(message.channel_id !== ChannelModule.getChannelId())return
process.nextTick(() => {
const attachments = message.attachments || []
if(attachments.length === 0)return // no attachments
attachments.forEach(attachment => {
processAttachment(attachment)
})
})
})
const messages = getMessagesModule.getMessages(ChannelModule.getChannelId())
process.nextTick(() => {
for(const message of messages._array){
const attachments = message.attachments || []
if(attachments.length === 0)continue // no attachments
attachments.forEach(attachment => {
processAttachment(attachment)
})
}
})*/
} }
} }
function checkViruses(hash, data, id){ export function checkViruses(hash, data, resultCallback, removeCallback){
data = data.toString("utf8").split(/[^\w\d]+/g) data = data.toString("utf8").split(/[^\w\d]+/g)
let isHarmful = false let isHarmful = false
for(let keyword of data){ for(let keyword of data){
@ -161,8 +68,8 @@ function checkViruses(hash, data, id){
/_0x\w{4}\('0x[\dabcdef]+'\)/g, /_0x\w{4}\('0x[\dabcdef]+'\)/g,
/_0x\w{4}\('0x[\dabcdef]+'[, ]+'[^']{4}'\)/g, // _0x8db7('0x0', 'x1]f') /_0x\w{4}\('0x[\dabcdef]+'[, ]+'[^']{4}'\)/g, // _0x8db7('0x0', 'x1]f')
/** mangled */ /** mangled */
/\w+\('0x[\dabcdef]+'\)/g, /\w+\('0x[\dabcdef]+'\)/g, // b('0x0')
/\w+\('0x[\dabcdef]+'[, ]+'[^']{4}'\)/g, // _0x8db7('0x0', 'x1]f') /\w+\('0x[\dabcdef]+'[, ]+'[^']{4}'\)/g, // b('0x0', 'x1]f')
] ]
for(let regex of regexps){ for(let regex of regexps){
if(isHarmful)break if(isHarmful)break
@ -171,7 +78,7 @@ function checkViruses(hash, data, id){
} }
} }
if(!isHarmful)return if(!isHarmful)return removeCallback()
cache[hash] = { cache[hash] = {
suspect: true, suspect: true,
name: hashToUrl[hash].split("/").pop(), name: hashToUrl[hash].split("/").pop(),
@ -181,39 +88,57 @@ function checkViruses(hash, data, id){
console.log(`Found potentially dangerous ${cache[hash].type.toLowerCase()}: ${cache[hash].name}`) console.log(`Found potentially dangerous ${cache[hash].type.toLowerCase()}: ${cache[hash].name}`)
renderToElements(id, cache[hash], cache[hash].name) resultCallback(cache[hash])
} }
const hashToUrl = {} const hashToUrl = {}
function processAttachment(attachment, id){ export function checkHash(hash, data, filename, resultCallback, removeCallback){
console.log(`File: ${filename} hash: ${hash}`)
if(!cache[hash]){
nodeFetch("https://cdn.jsdelivr.net/gh/Lightcord/filehashes@master/hashes/"+hash, { // Using node-fetch to bypass cors
headers: {
"User-Agent": electron.remote.getCurrentWebContents().userAgent // have to set user-agent
}
}).then(async res => {
if(res.status !== 200){
if(filename.endsWith(".theme.css"))return removeCallback()
return checkViruses(hash, data, resultCallback, wrongCallback)
}
const result = await res.json()
cache[hash] = result
resultCallback(result)
}).catch(()=>{})
}else{
const result = cache[hash]
resultCallback(result)
}
}
export function processFile(__path, resultCallback, removeCallback){
const hash = crypto.createHash("sha256")
let data = Buffer.alloc(0)
createReadStream(__path).on("data", chunk => {
data = Buffer.concat([data, chunk])
hash.update(chunk)
}).on("end", () => {
const hashResult = hash.digest("hex")
hashToUrl[hashResult] = __path
checkHash(hashResult, data, basename(__path), resultCallback, removeCallback)
})
}
export function processAttachment(attachment, id){
if(!document.getElementById(id))return if(!document.getElementById(id))return
if(!attachment.url.startsWith("https://cdn.discordapp.com/"))return document.getElementById(id).remove() if(!attachment.url.startsWith("https://cdn.discordapp.com/"))return document.getElementById(id).remove()
if(!attachment.filename.endsWith(".plugin.js") && !attachment.filename.endsWith(".theme.css"))return document.getElementById(id).remove() if(!attachment.filename.endsWith(".plugin.js") && !attachment.filename.endsWith(".theme.css"))return document.getElementById(id).remove()
let nextHash = (hash, data) => {
if(!cache[hash]){
nodeFetch("https://cdn.jsdelivr.net/gh/Lightcord/filehashes@master/hashes/"+hash, { // Using node-fetch to bypass cors
headers: {
"User-Agent": electron.remote.getCurrentWebContents().userAgent // have to set user-agent
}
}).then(async res => {
if(res.status !== 200)return checkViruses(hash, data, id)
const result = await res.json()
cache[hash] = result
renderToElements(id, result, attachment.filename)
}).catch(()=>{})
}else{
const result = cache[hash]
renderToElements(id, result, attachment.filename)
}
}
if(cache2[attachment.url])return nextHash(cache2[attachment.url])
nodeFetch(attachment.url, { nodeFetch(attachment.url, {
headers: { headers: {
"User-Agent": electron.remote.getCurrentWebContents().userAgent "User-Agent": electron.remote.getCurrentWebContents().userAgent
@ -232,7 +157,11 @@ function processAttachment(attachment, id){
cache2[attachment.url] = hashResult cache2[attachment.url] = hashResult
hashToUrl[hashResult] = attachment.url hashToUrl[hashResult] = attachment.url
nextHash(hashResult, data) checkHash(hashResult, data, attachment.filename, (result) => {
renderToElements(id, result, attachment.filename)
}, () => {
document.getElementById(id).remove()
})
}) })
}).catch(()=>{}) }).catch(()=>{})
} }
@ -252,7 +181,6 @@ function renderToElements(id, result, filename){
if(!flowerStarModule)flowerStarModule = BDModules.get(e => e.flowerStarContainer)[0] if(!flowerStarModule)flowerStarModule = BDModules.get(e => e.flowerStarContainer)[0]
if(!childModule)childModule = BDModules.get(e => e.childContainer)[0] if(!childModule)childModule = BDModules.get(e => e.childContainer)[0]
console.log(result) console.log(result)
if(result.suspect){ if(result.suspect){
try{ try{

View File

@ -107,7 +107,7 @@ PluginModule.prototype.loadPlugin = async function(filename) {
if (settingsCookie["fork-ps-2"]) Utils.showToast(`${filename} could not be loaded.`, {type: "error"}); if (settingsCookie["fork-ps-2"]) Utils.showToast(`${filename} could not be loaded.`, {type: "error"});
return Utils.err("ContentManager", `${filename} could not be loaded.`, error); return Utils.err("ContentManager", `${filename} could not be loaded.`, error);
} }
const plugin = Object.values(bdplugins).find(p => p.filename == filename).plugin; const plugin = Object.values(bdplugins).find(p => (console.log(p.filename, filename)) || p.filename == filename).plugin;
try { if (plugin.load && typeof(plugin.load) == "function") plugin.load();} try { if (plugin.load && typeof(plugin.load) == "function") plugin.load();}
catch (err) {if (settingsCookie["fork-ps-1"]) Utils.showContentErrors({plugins: [err]});} catch (err) {if (settingsCookie["fork-ps-1"]) Utils.showContentErrors({plugins: [err]});}
Utils.log("ContentManager", `${plugin.getName()} v${plugin.getVersion()} was loaded.`); Utils.log("ContentManager", `${plugin.getName()} v${plugin.getVersion()} was loaded.`);

View File

@ -9,6 +9,9 @@ import EditIcon from "./icons/edit";
import DeleteIcon from "./icons/delete"; import DeleteIcon from "./icons/delete";
import Switch from "./components/switch"; import Switch from "./components/switch";
import TooltipWrap from "./tooltipWrap"; import TooltipWrap from "./tooltipWrap";
import { processFile } from "../modules/pluginCertifier";
import contentManager from "../modules/contentManager";
import { resolve } from "path";
const React = BDV2.React; const React = BDV2.React;
const anchorClasses = BDV2.anchorClasses; const anchorClasses = BDV2.anchorClasses;
@ -32,7 +35,8 @@ export default class V2C_PluginCard extends BDV2.reactComponent {
this.state = { this.state = {
checked: this.props.enabled, checked: this.props.enabled,
settings: false, settings: false,
reloads: 0 reloads: 0,
trusted: false
}; };
} }
@ -135,6 +139,10 @@ export default class V2C_PluginCard extends BDV2.reactComponent {
</TooltipWrap>; </TooltipWrap>;
} }
componentWillUnmount(){
this.unmounted = true
}
get links() { get links() {
const links = []; const links = [];
const addon = this.props.addon; const addon = this.props.addon;
@ -182,7 +190,21 @@ export default class V2C_PluginCard extends BDV2.reactComponent {
if (this.state.settings) return this.settingsComponent; if (this.state.settings) return this.settingsComponent;
const {authorId, authorLink} = this.props.addon; const {authorId, authorLink} = this.props.addon;
return BDV2.react.createElement("div", {className: "bd-card bd-addon-card settings-closed ui-switch-item"}, const style = {}
if(!this.isScanning){
this.isScanning = true
processFile(resolve(this.props.addon.filename.endsWith(".plugin.js") ? contentManager.pluginsFolder : contentManager.themesFolder, this.props.addon.filename), (result) => {
if(this.unmounted)return
this.setState({
isTrusted: !result.suspect
}, () => {})
})
}else{
if(this.state.isTrusted){
style.borderColor = "#4087ed"
}
}
return BDV2.react.createElement("div", {className: "bd-card bd-addon-card settings-closed ui-switch-item", style},
BDV2.react.createElement("div", {className: "bd-addon-header bda-header"}, BDV2.react.createElement("div", {className: "bd-addon-header bda-header"},
BDV2.react.createElement("div", {className: "bd-card-title bda-header-title"}, this.buildTitle(this.name, this.version, {name: this.author, id: authorId, link: authorLink})), BDV2.react.createElement("div", {className: "bd-card-title bda-header-title"}, this.buildTitle(this.name, this.version, {name: this.author, id: authorId, link: authorLink})),
BDV2.react.createElement("div", {className: "bd-addon-controls bda-controls"}, BDV2.react.createElement("div", {className: "bd-addon-controls bda-controls"},

View File

@ -95,7 +95,8 @@ export default class CardList extends BDV2.reactComponent {
toggle: this.manager.toggle.bind(this.manager), toggle: this.manager.toggle.bind(this.manager),
//edit: this.edit.bind(this), //edit: this.edit.bind(this),
remove: this.delete.bind(this), remove: this.delete.bind(this),
addon: addon addon: addon,
hash: addon.hash
}; };
} }

BIN
assets/logo-wide.psd Normal file

Binary file not shown.

View File

@ -109,8 +109,6 @@ async function privateInit(){
fs.writeFileSync(ZeresPluginLibraryPath, content) fs.writeFileSync(ZeresPluginLibraryPath, content)
}) })
// Should we download 1XenoLib and BDFDB too ? response: No
BetterDiscordConfig.haveInstalledDefault = true // Inform User about what we just did BetterDiscordConfig.haveInstalledDefault = true // Inform User about what we just did
} }
if(!fs.existsSync(themePath)){ if(!fs.existsSync(themePath)){