// npm 패키지
@touchvue/chat
TouchVue Chat Component Library
버전
54
메인테이너
1
라이선스
ISC
최초 publish
2025-09-04
publisher
wadecnchart
tarball
26,611,473 B
AUTO-PUBLISHED·1개 버전 인덱싱됨·최근 publish: 2026-05-18
// exfil path
what is read → where it shipssteals
- ○ clipboard
sends to
(no destination string extracted — payload may be dynamic / obfuscated)
→ view full payload// offending code· @1.0.0-beta.54· 3 files flagged
llm: benign · 0.85→ 의심 전송지 없음, 원격 실행 형태 없음 — 1 known-vendor host(s).
- @1.0.0-beta.54··AUTO-PUBLISHED·publisher: wadecnchartheuristic 75/100static flags 1llm benign (0.85) via ollamanew-publisher:8dmature-packageosv-flagged:MAL-2026-4459clipboard-access
→ 의심 전송지 없음, 원격 실행 형태 없음 — 1 known-vendor host(s).
// offending code· 3 files flaggedpatterns: 1
--- package/lib/packages/components/touchchat/src/AiChat/ChatInput.vue2.js (excerpt) --- 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var vue = require('vue'); var MarkLayer = require('../../component/MarkLayer.vue.js'); var FileContent = require('../../component/FileContent.vue.js'); var QuoteContent = require('../../component/QuoteContent.vue.js'); var UploadView = require('../../component/UploadView.vue.js'); var Screenshot = require('../../component/Screenshot.vue.js'); var VoiceView = require('../../component/VoiceView.vue.js'); var RealtimeVoice = require('../../component/RealtimeVoice.vue.js'); var ModuleSelect = require('../../component/ModuleSelect.vue.js'); var tools = require('../../utils/tools.js'); var _sfc_main = /* @__PURE__ */ vue.defineComponent({ __name: "ChatInput", props: { inputValue: {}, isChating: { type: Boolean }, enableDeepThinking: { type: Boolean } }, emits: ["send", "stop", "update:enableDeepThinking", "update:inputValue", "moduleInfo"], setup(__props, { expose: __expose, emit: __emit }) { const props = __props; const placeholder = vue.inject("placeholder", "\u8BF7\u8F93\u5165..."); const layout = vue.inject("layout", "side, think, upload, chain, screen,realtime"); const modules = vue.inject("modules", []); const iModules = vue.ref(modules); vue.watch( () => modules, (newVal) => { iModules.value = newVal; console.log("modules === ChatInput.vue === 128", newVal); } // { immediate: true } ); const allowedTypes --- package/lib/packages/components/touchchat/src/AiChat/Chat/useCopy.js (excerpt) --- 'use strict'; var tools = require('../../../utils/tools.js'); function useCopy() { const copyToClipboard = (text, successMsg = "\u590D\u5236\u6210\u529F", errorMsg = "\u590D\u5236\u5931\u8D25") => { if (!text) { tools.showToast("\u590D\u5236\u5185\u5BB9\u4E3A\u7A7A", "warning"); return; } if (navigator.clipboard && window.isSecureContext) { navigator.clipboard.writeText(text).then(() => { tools.showToast(successMsg, "info"); }).catch((err) => { console.error("\u590D\u5236\u5931\u8D25:", err); fallbackCopy(text, successMsg, errorMsg); }); } else { fallbackCopy(text, successMsg, errorMsg); } }; const fallbackCopy = (text, successMsg, errorMsg) => { const textArea = document.createElement("textarea"); textArea.value = text; textArea.style.position = "fixed"; textArea.style.left = "-999999px"; textArea.style.top = "-999999px"; document.body.appendChild(textArea); textArea.focus(); textArea.select(); try { const successful = document.execCommand("copy"); tools.showToast(successful ? successMsg : errorMsg, successful ? "info" : "error"); } catch (err) { console.error("\u590D\u5236\u5931\u8D25:", err); tools.showToast(errorMsg, "error"); } finally { document.body.removeChild(textArea); } }; const copyWithFeedback = (text, button, originalText = "", copiedText = "\u5DF2\u590D\u5236", duration = 2e3) => { if (!tex --- package/es/packages/components/touchchat/src/AiChat/ChatInput.vue2.mjs (excerpt) --- import { defineComponent, inject, ref, watch, provide, computed, onMounted, openBlock, createElementBlock, renderSlot, createCommentVNode, createBlock, createElementVNode, unref, withKeys, normalizeClass, withCtx, toDisplayString, Fragment, createVNode, nextTick } from 'vue'; import MarkLayer from '../../component/MarkLayer.vue.mjs'; import FileContent from '../../component/FileContent.vue.mjs'; import QuoteContent from '../../component/QuoteContent.vue.mjs'; import UploadView from '../../component/UploadView.vue.mjs'; import Screenshot from '../../component/Screenshot.vue.mjs'; import Voice from '../../component/VoiceView.vue.mjs'; import RealtimeVoice from '../../component/RealtimeVoice.vue.mjs'; import ModuleSelect from '../../component/ModuleSelect.vue.mjs'; import { showToast } from '../../utils/tools.mjs'; var _sfc_main = /* @__PURE__ */ defineComponent({ __name: "ChatInput", props: { inputValue: {}, isChating: { type: Boolean }, enableDeepThinking: { type: Boolean } }, emits: ["send", "stop", "update:enableDeepThinking", "update:inputValue", "moduleInfo"], setup(__props, { expose: __expose, emit: __emit }) { const props = __props; const placeholder = inject("placeholder", "\u8BF7\u8F93\u5165..."); const layout = inject("layout", "side, think, upload, chain, screen,realtime"); const modules = inject("modules", []); const iModules = ref(modules); watch( () => modules, (newVal) => { iModules.value = newVal --- bundled output (OSV-MAL flagged — LLM scope expansion) --- --- lib/_virtual/_commonjsHelpers.js (bundled) --- 'use strict'; function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } exports.getDefaultExportFromCjs = getDefaultExportFromCjs; //# sourceMappingURL=_commonjsHelpers.js.map --- lib/_virtual/_plugin-vue_export-helper.js (bundled) --- 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _export_sfc = (sfc, props) => { const target = sfc.__vccOpts || sfc; for (const [key, val] of props) { target[key] = val; } return target; }; exports.default = _export_sfc; //# sourceMappingURL=_plugin-vue_export-helper.js.map
