@juzi/whatsapp-web.js
Advanced tools
Comparing version 1.16.14 to 1.18.0
@@ -10,2 +10,6 @@ const { Client, Location, List, Buttons, LocalAuth} = require('./index'); | ||
client.on('loading_screen', (percent, message) => { | ||
console.log('LOADING SCREEN', percent, message); | ||
}); | ||
client.on('qr', (qr) => { | ||
@@ -12,0 +16,0 @@ // NOTE: This event will not be fired if a session is specified. |
import { EventEmitter } from 'events' | ||
import { RequestInit } from 'node-fetch' | ||
import puppeteer from 'puppeteer' | ||
import * as puppeteer from 'puppeteer' | ||
@@ -250,2 +250,11 @@ declare namespace WAWebJS { | ||
/** Emitted when a reaction is sent, received, updated or removed */ | ||
on(event: 'message_reaction', listener: ( | ||
/** The reaction object */ | ||
reaction: Reaction | ||
) => void): this | ||
/** Emitted when loading screen is appearing */ | ||
on(event: 'loading_screen', listener: (percent: string, message: string) => void): this | ||
/** Emitted when the QR code is received */ | ||
@@ -266,2 +275,5 @@ on(event: 'qr', listener: ( | ||
on(event: 'ready', listener: () => void): this | ||
/** Emitted when the RemoteAuth session is saved successfully on the external Database */ | ||
on(event: 'remote_session_saved', listener: () => void): this | ||
} | ||
@@ -356,2 +368,5 @@ | ||
getAuthEventPayload: () => Promise<any>; | ||
afterAuthReady: () => Promise<void>; | ||
disconnect: () => Promise<void>; | ||
destroy: () => Promise<void>; | ||
logout: () => Promise<void>; | ||
@@ -377,3 +392,27 @@ } | ||
} | ||
/** | ||
* Remote-based authentication | ||
*/ | ||
export class RemoteAuth extends AuthStrategy { | ||
public clientId?: string; | ||
public dataPath?: string; | ||
constructor(options?: { | ||
store: Store, | ||
clientId?: string, | ||
dataPath?: string, | ||
backupSyncIntervalMs: number | ||
}) | ||
} | ||
/** | ||
* Remote store interface | ||
*/ | ||
export interface Store { | ||
sessionExists: (options: { session: string }) => Promise<boolean> | boolean, | ||
delete: (options: { session: string }) => Promise<any> | any, | ||
save: (options: { session: string }) => Promise<any> | any, | ||
extract: (options: { session: string, path: string }) => Promise<any> | any, | ||
} | ||
/** | ||
@@ -476,5 +515,7 @@ * Legacy session auth strategy | ||
QR_RECEIVED = 'qr', | ||
LOADING_SCREEN = 'loading_screen', | ||
DISCONNECTED = 'disconnected', | ||
STATE_CHANGED = 'change_state', | ||
BATTERY_CHANGED = 'change_battery', | ||
REMOTE_SESSION_SAVED = 'remote_session_saved' | ||
} | ||
@@ -722,3 +763,3 @@ | ||
/** | ||
* Forwards this message to another chat | ||
* Forwards this message to another chat (that you chatted before, otherwise it will fail) | ||
*/ | ||
@@ -820,2 +861,4 @@ forward: (chat: Chat | string) => Promise<void>, | ||
filename?: string | null | ||
/** Document file size in bytes. Value can be null. */ | ||
filesize?: number | null | ||
@@ -826,4 +869,5 @@ /** | ||
* @param {?string} filename Document file name. Value can be null | ||
* @param {?number} filesize Document file size in bytes. Value can be null. | ||
*/ | ||
constructor(mimetype: string, data: string, filename?: string | null) | ||
constructor(mimetype: string, data: string, filename?: string | null, filesize?: number | null) | ||
@@ -1035,2 +1079,6 @@ /** Creates a MessageMedia instance from a local file path */ | ||
limit?: number | ||
/** | ||
* Return only messages from the bot number or vise versa. To get all messages, leave the option undefined. | ||
*/ | ||
fromMe?: boolean | ||
} | ||
@@ -1318,4 +1366,17 @@ | ||
} | ||
/** Message type Reaction */ | ||
export class Reaction { | ||
id: MessageId | ||
orphan: number | ||
orphanReason?: string | ||
timestamp: number | ||
reaction: string | ||
read: boolean | ||
msgId: MessageId | ||
senderId: string | ||
ack?: number | ||
} | ||
} | ||
export = WAWebJS |
@@ -28,2 +28,3 @@ 'use strict'; | ||
LocalAuth: require('./src/authStrategies/LocalAuth'), | ||
RemoteAuth: require('./src/authStrategies/RemoteAuth'), | ||
LegacySessionAuth: require('./src/authStrategies/LegacySessionAuth'), | ||
@@ -30,0 +31,0 @@ |
117
package.json
{ | ||
"name": "@juzi/whatsapp-web.js", | ||
"version": "1.16.14", | ||
"description": "Library for interacting with the WhatsApp Web API ", | ||
"main": "./index.js", | ||
"typings": "./index.d.ts", | ||
"scripts": { | ||
"test": "mocha tests --recursive --timeout 5000", | ||
"test-single": "mocha", | ||
"shell": "node --experimental-repl-await ./shell.js", | ||
"generate-docs": "node_modules/.bin/jsdoc --configure .jsdoc.json --verbose" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/juzibot/whatsapp-web.js.git" | ||
}, | ||
"keywords": [ | ||
"whatsapp", | ||
"whatsapp-web", | ||
"api", | ||
"bot", | ||
"client", | ||
"node" | ||
], | ||
"author": "Pedro Lopez", | ||
"license": "Apache-2.0", | ||
"bugs": { | ||
"url": "https://github.com/juzibot/whatsapp-web.js/issues" | ||
}, | ||
"homepage": "https://wwebjs.dev/", | ||
"dependencies": { | ||
"puppeteer-extra": "^3.2.3", | ||
"puppeteer-extra-plugin-anonymize-ua": "^2.3.3", | ||
"puppeteer-extra-plugin-stealth": "^2.9.0", | ||
"@pedroslopez/moduleraid": "^5.0.2", | ||
"fluent-ffmpeg": "^2.1.2", | ||
"jsqr": "^1.3.1", | ||
"mime": "^3.0.0", | ||
"node-fetch": "^2.6.5", | ||
"node-webpmux": "^3.1.0", | ||
"puppeteer": "^13.0.0" | ||
}, | ||
"devDependencies": { | ||
"@types/node-fetch": "^2.5.12", | ||
"chai": "^4.3.4", | ||
"chai-as-promised": "^7.1.1", | ||
"dotenv": "^16.0.0", | ||
"eslint": "^8.4.1", | ||
"eslint-plugin-mocha": "^10.0.3", | ||
"jsdoc": "^3.6.4", | ||
"jsdoc-baseline": "^0.1.5", | ||
"mocha": "^9.0.2", | ||
"sinon": "^13.0.1" | ||
}, | ||
"engines": { | ||
"node": ">=12.0.0" | ||
} | ||
"name": "@juzi/whatsapp-web.js", | ||
"version": "1.18.0", | ||
"description": "Library for interacting with the WhatsApp Web API ", | ||
"main": "./index.js", | ||
"typings": "./index.d.ts", | ||
"scripts": { | ||
"test": "mocha tests --recursive --timeout 5000", | ||
"test-single": "mocha", | ||
"shell": "node --experimental-repl-await ./shell.js", | ||
"generate-docs": "node_modules/.bin/jsdoc --configure .jsdoc.json --verbose" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/juzibot/whatsapp-web.js.git" | ||
}, | ||
"keywords": [ | ||
"whatsapp", | ||
"whatsapp-web", | ||
"api", | ||
"bot", | ||
"client", | ||
"node" | ||
], | ||
"author": "Pedro Lopez", | ||
"license": "Apache-2.0", | ||
"bugs": { | ||
"url": "https://github.com/juzibot/whatsapp-web.js/issues" | ||
}, | ||
"homepage": "https://wwebjs.dev/", | ||
"dependencies": { | ||
"puppeteer-extra": "^3.2.3", | ||
"puppeteer-extra-plugin-anonymize-ua": "^2.3.3", | ||
"puppeteer-extra-plugin-stealth": "^2.9.0", | ||
"@pedroslopez/moduleraid": "^5.0.2", | ||
"fluent-ffmpeg": "^2.1.2", | ||
"jsqr": "^1.3.1", | ||
"mime": "^3.0.0", | ||
"node-fetch": "^2.6.5", | ||
"node-webpmux": "^3.1.0", | ||
"puppeteer": "^13.0.0" | ||
}, | ||
"devDependencies": { | ||
"@types/node-fetch": "^2.5.12", | ||
"chai": "^4.3.4", | ||
"chai-as-promised": "^7.1.1", | ||
"dotenv": "^16.0.0", | ||
"eslint": "^8.4.1", | ||
"eslint-plugin-mocha": "^10.0.3", | ||
"jsdoc": "^3.6.4", | ||
"jsdoc-baseline": "^0.1.5", | ||
"mocha": "^9.0.2", | ||
"sinon": "^13.0.1" | ||
}, | ||
"engines": { | ||
"node": ">=12.0.0" | ||
}, | ||
"optionalDependencies": { | ||
"archiver": "^5.3.1", | ||
"fs-extra": "^10.1.0", | ||
"unzipper": "^0.10.11" | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
[![npm](https://img.shields.io/npm/v/whatsapp-web.js.svg)](https://www.npmjs.com/package/whatsapp-web.js) [![Depfu](https://badges.depfu.com/badges/4a65a0de96ece65fdf39e294e0c8dcba/overview.svg)](https://depfu.com/github/pedroslopez/whatsapp-web.js?project_id=9765) ![WhatsApp_Web 2.2224.8](https://img.shields.io/badge/WhatsApp_Web-2.2224.8-brightgreen.svg) [![Discord Chat](https://img.shields.io/discord/698610475432411196.svg?logo=discord)](https://discord.gg/H7DqQs4) | ||
[![npm](https://img.shields.io/npm/v/whatsapp-web.js.svg)](https://www.npmjs.com/package/whatsapp-web.js) [![Depfu](https://badges.depfu.com/badges/4a65a0de96ece65fdf39e294e0c8dcba/overview.svg)](https://depfu.com/github/pedroslopez/whatsapp-web.js?project_id=9765) ![WhatsApp_Web 2.2240.7](https://img.shields.io/badge/WhatsApp_Web-2.2240.7-brightgreen.svg) [![Discord Chat](https://img.shields.io/discord/698610475432411196.svg?logo=discord)](https://discord.gg/H7DqQs4) | ||
@@ -3,0 +3,0 @@ # whatsapp-web.js |
@@ -21,2 +21,5 @@ 'use strict'; | ||
async getAuthEventPayload() {} | ||
async afterAuthReady() {} | ||
async disconnect() {} | ||
async destroy() {} | ||
async logout() {} | ||
@@ -23,0 +26,0 @@ } |
@@ -18,3 +18,3 @@ 'use strict'; | ||
const ContactFactory = require('./factories/ContactFactory'); | ||
const { ClientInfo, Message, MessageMedia, Contact, Location, GroupNotification, Label, Call, Buttons, List} = require('./structures'); | ||
const { ClientInfo, Message, MessageMedia, Contact, Location, GroupNotification, Label, Call, Buttons, List, Reaction } = require('./structures'); | ||
const LegacySessionAuth = require('./authStrategies/LegacySessionAuth'); | ||
@@ -124,2 +124,48 @@ const NoAuth = require('./authStrategies/NoAuth'); | ||
await page.evaluate(`function getElementByXpath(path) { | ||
return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; | ||
}`); | ||
let lastPercent = null, | ||
lastPercentMessage = null; | ||
await page.exposeFunction('loadingScreen', async (percent, message) => { | ||
if (lastPercent !== percent || lastPercentMessage !== message) { | ||
this.emit(Events.LOADING_SCREEN, percent, message); | ||
lastPercent = percent; | ||
lastPercentMessage = message; | ||
} | ||
}); | ||
await page.evaluate( | ||
async function (selectors) { | ||
var observer = new MutationObserver(function () { | ||
let progressBar = window.getElementByXpath( | ||
selectors.PROGRESS | ||
); | ||
let progressMessage = window.getElementByXpath( | ||
selectors.PROGRESS_MESSAGE | ||
); | ||
if (progressBar) { | ||
window.loadingScreen( | ||
progressBar.value, | ||
progressMessage.innerText | ||
); | ||
} | ||
}); | ||
observer.observe(document, { | ||
attributes: true, | ||
childList: true, | ||
characterData: true, | ||
subtree: true, | ||
}); | ||
}, | ||
{ | ||
PROGRESS: '//*[@id=\'app\']/div/div/div[2]/progress', | ||
PROGRESS_MESSAGE: '//*[@id=\'app\']/div/div/div[3]', | ||
} | ||
); | ||
const INTRO_IMG_SELECTOR = '[data-testid="intro-md-beta-logo-dark"], [data-testid="intro-md-beta-logo-light"], [data-asset-intro-image-light="true"], [data-asset-intro-image-dark="true"]'; | ||
@@ -383,3 +429,3 @@ const INTRO_QRCODE_SELECTOR = 'div[data-ref] canvas'; | ||
await page.exposeFunction('onAppStateChangedEvent', (state) => { | ||
await page.exposeFunction('onAppStateChangedEvent', async (state) => { | ||
@@ -411,2 +457,3 @@ /** | ||
*/ | ||
await this.authStrategy.disconnect(); | ||
this.emit(Events.DISCONNECTED, state); | ||
@@ -451,2 +498,23 @@ this.destroy(); | ||
await page.exposeFunction('onReaction', (reactions) => { | ||
for (const reaction of reactions) { | ||
/** | ||
* Emitted when a reaction is sent, received, updated or removed | ||
* @event Client#message_reaction | ||
* @param {object} reaction | ||
* @param {object} reaction.id - Reaction id | ||
* @param {number} reaction.orphan - Orphan | ||
* @param {?string} reaction.orphanReason - Orphan reason | ||
* @param {number} reaction.timestamp - Timestamp | ||
* @param {string} reaction.reaction - Reaction | ||
* @param {boolean} reaction.read - Read | ||
* @param {object} reaction.msgId - Parent message id | ||
* @param {string} reaction.senderId - Sender id | ||
* @param {?number} reaction.ack - Ack | ||
*/ | ||
this.emit(Events.MESSAGE_REACTION, new Reaction(this, reaction)); | ||
} | ||
}); | ||
await page.evaluate(() => { | ||
@@ -471,2 +539,18 @@ window.Store.Msg.on('change', (msg) => { window.onChangeMessageEvent(window.WWebJS.getMessageModel(msg)); }); | ||
}); | ||
{ | ||
const module = window.Store.createOrUpdateReactionsModule; | ||
const ogMethod = module.createOrUpdateReactions; | ||
module.createOrUpdateReactions = ((...args) => { | ||
window.onReaction(args[0].map(reaction => { | ||
const msgKey = window.Store.MsgKey.fromString(reaction.msgKey); | ||
const parentMsgKey = window.Store.MsgKey.fromString(reaction.parentMsgKey); | ||
const timestamp = reaction.timestamp / 1000; | ||
return {...reaction, msgKey, parentMsgKey, timestamp }; | ||
})); | ||
return ogMethod(...args); | ||
}).bind(module); | ||
} | ||
}); | ||
@@ -484,2 +568,3 @@ | ||
if(!appState || appState === WAState.PAIRING) { | ||
await this.authStrategy.disconnect(); | ||
this.emit(Events.DISCONNECTED, 'NAVIGATION'); | ||
@@ -927,3 +1012,9 @@ await this.destroy(); | ||
const commonGroups = await this.pupPage.evaluate(async (contactId) => { | ||
const contact = window.Store.Contact.get(contactId); | ||
let contact = window.Store.Contact.get(contactId); | ||
if (!contact) { | ||
const wid = window.Store.WidFactory.createUserWid(contactId); | ||
const chatConstructor = window.Store.Contact.getModelsArray().find(c=>!c.isGroup).constructor; | ||
contact = new chatConstructor({id: wid}); | ||
} | ||
if (contact.commonGroups) { | ||
@@ -930,0 +1021,0 @@ return contact.commonGroups.serialize(); |
@@ -173,4 +173,5 @@ 'use strict'; | ||
* Loads chat messages, sorted from earliest to latest. | ||
* @param {Object} searchOptions Options for searching messages. Right now only limit is supported. | ||
* @param {Object} searchOptions Options for searching messages. Right now only limit and fromMe is supported. | ||
* @param {Number} [searchOptions.limit] The amount of messages to return. If no limit is specified, the available messages will be returned. Note that the actual number of returned messages may be smaller if there aren't enough messages in the conversation. Set this to Infinity to load all messages. | ||
* @param {Boolean} [searchOptions.fromMe] Return only messages from the bot number or vise versa. To get all messages, leave the option undefined. | ||
* @returns {Promise<Array<Message>>} | ||
@@ -180,3 +181,11 @@ */ | ||
let messages = await this.client.pupPage.evaluate(async (chatId, searchOptions) => { | ||
const msgFilter = m => !m.isNotification; // dont include notification messages | ||
const msgFilter = (m) => { | ||
if (m.isNotification) { | ||
return false; // dont include notification messages | ||
} | ||
if (searchOptions && searchOptions.fromMe && m.id.fromMe !== searchOptions.fromMe) { | ||
return false; | ||
} | ||
return true; | ||
}; | ||
@@ -183,0 +192,0 @@ const chat = window.Store.Chat.get(chatId); |
@@ -21,2 +21,3 @@ module.exports = { | ||
Payment: require('./Payment'), | ||
Reaction: require('./Reaction'), | ||
}; |
@@ -345,2 +345,4 @@ 'use strict'; | ||
await this.client.pupPage.evaluate(async (messageId, reaction) => { | ||
if (!messageId) { return undefined; } | ||
const msg = await window.Store.Msg.get(messageId); | ||
@@ -360,3 +362,3 @@ await window.Store.sendReactionToMsg(msg, reaction); | ||
/** | ||
* Forwards this message to another chat | ||
* Forwards this message to another chat (that you chatted before, otherwise it will fail) | ||
* | ||
@@ -413,3 +415,3 @@ * @param {string|Chat} chat Chat model or chat ID to which the message will be forwarded | ||
const data = window.WWebJS.arrayBufferToBase64(decryptedMedia); | ||
const data = await window.WWebJS.arrayBufferToBase64Async(decryptedMedia); | ||
@@ -419,3 +421,4 @@ return { | ||
mimetype: msg.mimetype, | ||
filename: msg.filename | ||
filename: msg.filename, | ||
filesize: msg.size | ||
}; | ||
@@ -429,3 +432,3 @@ } catch (e) { | ||
if (!result) return undefined; | ||
return new MessageMedia(result.mimetype, result.data, result.filename); | ||
return new MessageMedia(result.mimetype, result.data, result.filename, result.filesize); | ||
} | ||
@@ -435,3 +438,3 @@ | ||
* Deletes a message from the chat | ||
* @param {?boolean} everyone If true and the message is sent by the current user, will delete it for everyone in the chat. | ||
* @param {?boolean} everyone If true and the message is sent by the current user or the user is an admin, will delete it for everyone in the chat. | ||
*/ | ||
@@ -442,4 +445,4 @@ async delete(everyone) { | ||
if (everyone && msg.id.fromMe && msg._canRevoke()) { | ||
return window.Store.Cmd.sendRevokeMsgs(msg.chat, [msg], {type: 'Sender'}); | ||
if (everyone && msg._canRevoke()) { | ||
return window.Store.Cmd.sendRevokeMsgs(msg.chat, [msg], { type: msg.id.fromMe ? 'Sender' : 'Admin' }); | ||
} | ||
@@ -459,3 +462,3 @@ | ||
if (msg.canStar()) { | ||
return msg.chat.sendStarMsgs([msg], true); | ||
return window.Store.Cmd.sendStarMsgs(msg.chat, [msg], false); | ||
} | ||
@@ -473,3 +476,3 @@ }, this.id._serialized); | ||
if (msg.canStar()) { | ||
return msg.chat.sendStarMsgs([msg], false); | ||
return window.Store.Cmd.sendUnstarMsgs(msg.chat, [msg], false); | ||
} | ||
@@ -476,0 +479,0 @@ }, this.id._serialized); |
@@ -13,6 +13,7 @@ 'use strict'; | ||
* @param {string} data Base64-encoded data of the file | ||
* @param {?string} filename Document file name | ||
* @param {?string} filename Document file name. Value can be null | ||
* @param {?number} filesize Document file size in bytes. Value can be null | ||
*/ | ||
class MessageMedia { | ||
constructor(mimetype, data, filename) { | ||
constructor(mimetype, data, filename, filesize) { | ||
/** | ||
@@ -31,6 +32,12 @@ * MIME type of the attachment | ||
/** | ||
* Name of the file (for documents) | ||
* Document file name. Value can be null | ||
* @type {?string} | ||
*/ | ||
this.filename = filename; | ||
/** | ||
* Document file size in bytes. Value can be null | ||
* @type {?number} | ||
*/ | ||
this.filesize = filesize; | ||
} | ||
@@ -73,2 +80,3 @@ | ||
const mime = response.headers.get('Content-Type'); | ||
const size = response.headers.get('Content-Length'); | ||
@@ -89,3 +97,3 @@ const contentDisposition = response.headers.get('Content-Disposition'); | ||
return { data, mime, name }; | ||
return { data, mime, name, size }; | ||
} | ||
@@ -103,3 +111,3 @@ | ||
return new MessageMedia(mimetype, res.data, filename); | ||
return new MessageMedia(mimetype, res.data, filename, res.size || null); | ||
} | ||
@@ -106,0 +114,0 @@ } |
@@ -14,3 +14,3 @@ 'use strict'; | ||
takeoverTimeoutMs: 0, | ||
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36', | ||
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36', | ||
ffmpegPath: 'ffmpeg', | ||
@@ -45,2 +45,3 @@ bypassCSP: false | ||
MESSAGE_ACK: 'message_ack', | ||
MESSAGE_REACTION: 'message_reaction', | ||
MEDIA_UPLOADED: 'media_uploaded', | ||
@@ -51,6 +52,8 @@ GROUP_JOIN: 'group_join', | ||
QR_RECEIVED: 'qr', | ||
LOADING_SCREEN: 'loading_screen', | ||
DISCONNECTED: 'disconnected', | ||
STATE_CHANGED: 'change_state', | ||
BATTERY_CHANGED: 'change_battery', | ||
INCOMING_CALL: 'incoming_call' | ||
INCOMING_CALL: 'incoming_call', | ||
REMOTE_SESSION_SAVED: 'remote_session_saved' | ||
}; | ||
@@ -57,0 +60,0 @@ |
@@ -53,2 +53,4 @@ 'use strict'; | ||
window.Store.sendReactionToMsg = window.mR.findModule('sendReactionToMsg')[0].sendReactionToMsg; | ||
window.Store.createOrUpdateReactionsModule = window.mR.findModule('createOrUpdateReactions')[0]; | ||
window.Store.EphemeralFields = window.mR.findModule('getEphemeralFields')[0]; | ||
window.Store.StickerTools = { | ||
@@ -230,7 +232,3 @@ ...window.mR.findModule('toWebpSticker')[0], | ||
const ephemeralSettings = { | ||
ephemeralDuration: chat.isEphemeralSettingOn() ? chat.getEphemeralSetting() : undefined, | ||
ephemeralSettingTimestamp: chat.getEphemeralSettingTimestamp() || undefined, | ||
disappearingModeInitiator: chat.getDisappearingModeInitiator() || undefined, | ||
}; | ||
const ephemeralFields = window.Store.EphemeralFields.getEphemeralFields(chat); | ||
@@ -249,3 +247,3 @@ const message = { | ||
type: 'chat', | ||
...ephemeralSettings, | ||
...ephemeralFields, | ||
...locationOptions, | ||
@@ -371,3 +369,3 @@ ...attOptions, | ||
msg.isStatusV3 = message.isStatusV3; | ||
msg.links = (message.getLinks()).map(link => ({ | ||
msg.links = (message.getRawLinks()).map(link => ({ | ||
link: link.href, | ||
@@ -486,2 +484,16 @@ isSuspicious: Boolean(link.suspiciousCharacters && link.suspiciousCharacters.size) | ||
window.WWebJS.arrayBufferToBase64Async = (arrayBuffer) => | ||
new Promise((resolve, reject) => { | ||
const blob = new Blob([arrayBuffer], { | ||
type: 'application/octet-stream', | ||
}); | ||
const fileReader = new FileReader(); | ||
fileReader.onload = () => { | ||
const [, data] = fileReader.result.split(','); | ||
resolve(data); | ||
}; | ||
fileReader.onerror = (e) => reject(e); | ||
fileReader.readAsDataURL(blob); | ||
}); | ||
window.WWebJS.getFileHash = async (data) => { | ||
@@ -488,0 +500,0 @@ let buffer = await data.arrayBuffer(); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
241450
44
5709
13
5