aboutsummaryrefslogtreecommitdiff
path: root/chat
diff options
context:
space:
mode:
Diffstat (limited to 'chat')
-rw-r--r--chat/chat-modules.js43
-rw-r--r--chat/chat-ui.html2
2 files changed, 32 insertions, 13 deletions
diff --git a/chat/chat-modules.js b/chat/chat-modules.js
index 26ad115..140e379 100644
--- a/chat/chat-modules.js
+++ b/chat/chat-modules.js
@@ -343,22 +343,41 @@ function importModules() {
input.onchange = async function (e) {
var file = e.target.files[0];
if (!file) return;
+ if (file.size > 1048576) { showToast('File too large (max 1MB)'); return; }
try {
var text = await file.text();
var imported = JSON.parse(text);
- if (Array.isArray(imported)) {
- for (var i = 0; i < imported.length; i++) {
- var m = imported[i];
- m.id = m.id + '_imported';
- modules.push(m);
- }
- saveModules();
- renderModuleList();
- updateHelpPanel();
- showToast('Modules imported!');
- } else {
- showToast('Invalid format');
+ if (!Array.isArray(imported)) { showToast('Invalid format: expected array'); return; }
+ var valid = [];
+ for (var i = 0; i < imported.length; i++) {
+ var m = imported[i];
+ if (!m || typeof m !== 'object') continue;
+ if (typeof m.name !== 'string' || m.name.length > 80) continue;
+ if (typeof m.desc !== 'string' || m.desc.length > 200) continue;
+ if (typeof m.prompt !== 'string' || m.prompt.length > 10000) continue;
+ if (m.help && typeof m.help !== 'string') continue;
+ if (m.commands && typeof m.commands !== 'string') continue;
+ // Sanitize ID — only allow a-z0-9-
+ var rawId = typeof m.id === 'string' ? m.id : m.name.toLowerCase().replace(/\s+/g, '-');
+ var safeId = rawId.toLowerCase().replace(/[^a-z0-9-]/g, '').substring(0, 64);
+ if (!safeId) safeId = 'imported_' + Date.now();
+ valid.push({
+ id: safeId + '_imported',
+ name: m.name,
+ desc: m.desc || '',
+ prompt: m.prompt || '',
+ help: m.help || '',
+ commands: m.commands || ''
+ });
}
+ if (valid.length === 0) { showToast('No valid modules found in file'); return; }
+ for (var i = 0; i < valid.length; i++) {
+ modules.push(valid[i]);
+ }
+ saveModules();
+ renderModuleList();
+ updateHelpPanel();
+ showToast(valid.length + ' module' + (valid.length > 1 ? 's' : '') + ' imported!');
} catch (err) {
showToast('Import failed: ' + err.message);
}
diff --git a/chat/chat-ui.html b/chat/chat-ui.html
index 9f6dd4b..efe0347 100644
--- a/chat/chat-ui.html
+++ b/chat/chat-ui.html
@@ -154,7 +154,7 @@
<button class="modal-close" onclick="closePreviewModal()">×</button>
</div>
<div class="modal-body" style="height:calc(100% - 60px);padding:0;">
- <iframe id="previewFrame" style="width:100%;height:100%;border:none;"></iframe>
+ <iframe id="previewFrame" style="width:100%;height:100%;border:none;" sandbox="allow-same-origin"></iframe>
</div>
</div>
</div>