libre-webui 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +204 -0
- package/backend/dist/db.d.ts +19 -0
- package/backend/dist/db.d.ts.map +1 -0
- package/backend/dist/db.js +355 -0
- package/backend/dist/db.js.map +1 -0
- package/backend/dist/env.d.ts +2 -0
- package/backend/dist/env.d.ts.map +1 -0
- package/backend/dist/env.js +22 -0
- package/backend/dist/env.js.map +1 -0
- package/backend/dist/index.d.ts +4 -0
- package/backend/dist/index.d.ts.map +1 -0
- package/backend/dist/index.js +751 -0
- package/backend/dist/index.js.map +1 -0
- package/backend/dist/middleware/auth.d.ts +18 -0
- package/backend/dist/middleware/auth.d.ts.map +1 -0
- package/backend/dist/middleware/auth.js +98 -0
- package/backend/dist/middleware/auth.js.map +1 -0
- package/backend/dist/middleware/index.d.ts +5 -0
- package/backend/dist/middleware/index.d.ts.map +1 -0
- package/backend/dist/middleware/index.js +62 -0
- package/backend/dist/middleware/index.js.map +1 -0
- package/backend/dist/models/personaModel.d.ts +37 -0
- package/backend/dist/models/personaModel.d.ts.map +1 -0
- package/backend/dist/models/personaModel.js +269 -0
- package/backend/dist/models/personaModel.js.map +1 -0
- package/backend/dist/models/userModel.d.ts +86 -0
- package/backend/dist/models/userModel.d.ts.map +1 -0
- package/backend/dist/models/userModel.js +212 -0
- package/backend/dist/models/userModel.js.map +1 -0
- package/backend/dist/routes/auth.d.ts +3 -0
- package/backend/dist/routes/auth.d.ts.map +1 -0
- package/backend/dist/routes/auth.js +389 -0
- package/backend/dist/routes/auth.js.map +1 -0
- package/backend/dist/routes/chat.d.ts +3 -0
- package/backend/dist/routes/chat.d.ts.map +1 -0
- package/backend/dist/routes/chat.js +767 -0
- package/backend/dist/routes/chat.js.map +1 -0
- package/backend/dist/routes/documents.d.ts +3 -0
- package/backend/dist/routes/documents.d.ts.map +1 -0
- package/backend/dist/routes/documents.js +244 -0
- package/backend/dist/routes/documents.js.map +1 -0
- package/backend/dist/routes/ollama.d.ts +3 -0
- package/backend/dist/routes/ollama.d.ts.map +1 -0
- package/backend/dist/routes/ollama.js +549 -0
- package/backend/dist/routes/ollama.js.map +1 -0
- package/backend/dist/routes/personas.d.ts +3 -0
- package/backend/dist/routes/personas.d.ts.map +1 -0
- package/backend/dist/routes/personas.js +505 -0
- package/backend/dist/routes/personas.js.map +1 -0
- package/backend/dist/routes/plugins.d.ts +3 -0
- package/backend/dist/routes/plugins.d.ts.map +1 -0
- package/backend/dist/routes/plugins.js +417 -0
- package/backend/dist/routes/plugins.js.map +1 -0
- package/backend/dist/routes/preferences.d.ts +3 -0
- package/backend/dist/routes/preferences.d.ts.map +1 -0
- package/backend/dist/routes/preferences.js +303 -0
- package/backend/dist/routes/preferences.js.map +1 -0
- package/backend/dist/routes/tts.d.ts +3 -0
- package/backend/dist/routes/tts.d.ts.map +1 -0
- package/backend/dist/routes/tts.js +304 -0
- package/backend/dist/routes/tts.js.map +1 -0
- package/backend/dist/routes/users.d.ts +3 -0
- package/backend/dist/routes/users.d.ts.map +1 -0
- package/backend/dist/routes/users.js +246 -0
- package/backend/dist/routes/users.js.map +1 -0
- package/backend/dist/services/authService.d.ts +51 -0
- package/backend/dist/services/authService.d.ts.map +1 -0
- package/backend/dist/services/authService.js +153 -0
- package/backend/dist/services/authService.js.map +1 -0
- package/backend/dist/services/chatService.d.ts +52 -0
- package/backend/dist/services/chatService.d.ts.map +1 -0
- package/backend/dist/services/chatService.js +645 -0
- package/backend/dist/services/chatService.js.map +1 -0
- package/backend/dist/services/documentService.d.ts +34 -0
- package/backend/dist/services/documentService.d.ts.map +1 -0
- package/backend/dist/services/documentService.js +428 -0
- package/backend/dist/services/documentService.js.map +1 -0
- package/backend/dist/services/encryptionService.d.ts +62 -0
- package/backend/dist/services/encryptionService.d.ts.map +1 -0
- package/backend/dist/services/encryptionService.js +284 -0
- package/backend/dist/services/encryptionService.js.map +1 -0
- package/backend/dist/services/memoryService.d.ts +140 -0
- package/backend/dist/services/memoryService.d.ts.map +1 -0
- package/backend/dist/services/memoryService.js +867 -0
- package/backend/dist/services/memoryService.js.map +1 -0
- package/backend/dist/services/mutationEngineService.d.ts +49 -0
- package/backend/dist/services/mutationEngineService.d.ts.map +1 -0
- package/backend/dist/services/mutationEngineService.js +432 -0
- package/backend/dist/services/mutationEngineService.js.map +1 -0
- package/backend/dist/services/ollamaService.d.ts +55 -0
- package/backend/dist/services/ollamaService.d.ts.map +1 -0
- package/backend/dist/services/ollamaService.js +450 -0
- package/backend/dist/services/ollamaService.js.map +1 -0
- package/backend/dist/services/personaService.d.ts +67 -0
- package/backend/dist/services/personaService.d.ts.map +1 -0
- package/backend/dist/services/personaService.js +373 -0
- package/backend/dist/services/personaService.js.map +1 -0
- package/backend/dist/services/pluginService.d.ts +42 -0
- package/backend/dist/services/pluginService.d.ts.map +1 -0
- package/backend/dist/services/pluginService.js +961 -0
- package/backend/dist/services/pluginService.js.map +1 -0
- package/backend/dist/services/preferencesService.d.ts +35 -0
- package/backend/dist/services/preferencesService.d.ts.map +1 -0
- package/backend/dist/services/preferencesService.js +255 -0
- package/backend/dist/services/preferencesService.js.map +1 -0
- package/backend/dist/services/simpleGitHubOAuth.d.ts +48 -0
- package/backend/dist/services/simpleGitHubOAuth.d.ts.map +1 -0
- package/backend/dist/services/simpleGitHubOAuth.js +203 -0
- package/backend/dist/services/simpleGitHubOAuth.js.map +1 -0
- package/backend/dist/services/simpleHuggingFaceOAuth.d.ts +43 -0
- package/backend/dist/services/simpleHuggingFaceOAuth.d.ts.map +1 -0
- package/backend/dist/services/simpleHuggingFaceOAuth.js +159 -0
- package/backend/dist/services/simpleHuggingFaceOAuth.js.map +1 -0
- package/backend/dist/services/userService.d.ts +1 -0
- package/backend/dist/services/userService.d.ts.map +1 -0
- package/backend/dist/services/userService.js +18 -0
- package/backend/dist/services/userService.js.map +1 -0
- package/backend/dist/storage.d.ts +55 -0
- package/backend/dist/storage.d.ts.map +1 -0
- package/backend/dist/storage.js +741 -0
- package/backend/dist/storage.js.map +1 -0
- package/backend/dist/test-encryption.d.ts +2 -0
- package/backend/dist/test-encryption.d.ts.map +1 -0
- package/backend/dist/test-encryption.js +64 -0
- package/backend/dist/test-encryption.js.map +1 -0
- package/backend/dist/types/index.d.ts +523 -0
- package/backend/dist/types/index.d.ts.map +1 -0
- package/backend/dist/types/index.js +31 -0
- package/backend/dist/types/index.js.map +1 -0
- package/backend/dist/utils/generationUtils.d.ts +10 -0
- package/backend/dist/utils/generationUtils.d.ts.map +1 -0
- package/backend/dist/utils/generationUtils.js +49 -0
- package/backend/dist/utils/generationUtils.js.map +1 -0
- package/backend/dist/utils/hash.d.ts +29 -0
- package/backend/dist/utils/hash.d.ts.map +1 -0
- package/backend/dist/utils/hash.js +73 -0
- package/backend/dist/utils/hash.js.map +1 -0
- package/backend/dist/utils/jwt.d.ts +37 -0
- package/backend/dist/utils/jwt.d.ts.map +1 -0
- package/backend/dist/utils/jwt.js +86 -0
- package/backend/dist/utils/jwt.js.map +1 -0
- package/bin/cli.js +150 -0
- package/electron/main.js +322 -0
- package/frontend/dist/_redirects +1 -0
- package/frontend/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/frontend/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/frontend/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/frontend/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/frontend/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/frontend/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/frontend/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/frontend/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/frontend/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/frontend/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/frontend/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/frontend/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/frontend/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/frontend/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/frontend/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/frontend/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/frontend/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/frontend/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/frontend/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/frontend/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/frontend/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/frontend/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/frontend/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/frontend/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/frontend/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/frontend/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/frontend/dist/assets/index-CRQkB7Wz.js +3 -0
- package/frontend/dist/css/index-B1OjddR-.css +1 -0
- package/frontend/dist/favicon-dark.png +0 -0
- package/frontend/dist/favicon-light.png +0 -0
- package/frontend/dist/index.html +23 -0
- package/frontend/dist/js/ArtifactContainer-c_oi7XMs.js +23 -0
- package/frontend/dist/js/ArtifactDemoPage-CdfwJVXu.js +98 -0
- package/frontend/dist/js/ChatPage-CyotkmS0.js +281 -0
- package/frontend/dist/js/ModelsPage-DNaziPHc.js +2 -0
- package/frontend/dist/js/PersonasPage-DcnbJf8Q.js +13 -0
- package/frontend/dist/js/UserManagementPage-DtTf92dS.js +1 -0
- package/frontend/dist/js/markdown-vendor-D-79K2xZ.js +22 -0
- package/frontend/dist/js/react-vendor-N--QU9DW.js +8 -0
- package/frontend/dist/js/router-vendor-B-t91v39.js +3 -0
- package/frontend/dist/js/ui-vendor-VxSCY_bv.js +177 -0
- package/frontend/dist/js/utils-vendor-DNzxLBGx.js +6 -0
- package/frontend/dist/logo-dark.png +0 -0
- package/frontend/dist/logo-light.png +0 -0
- package/frontend/dist/logo.svg +14 -0
- package/package.json +128 -0
- package/plugins/anthropic.json +25 -0
- package/plugins/elevenlabs.json +58 -0
- package/plugins/gemini.json +57 -0
- package/plugins/github.json +23 -0
- package/plugins/groq.json +25 -0
- package/plugins/mistral.json +73 -0
- package/plugins/openai-tts.json +38 -0
- package/plugins/openai.json +132 -0
- package/plugins/openrouter.json +353 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Libre WebUI
|
|
3
|
+
* Copyright (C) 2025 Kroonen AI, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at:
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import crypto from 'crypto';
|
|
18
|
+
import fs from 'fs';
|
|
19
|
+
import path from 'path';
|
|
20
|
+
import { fileURLToPath } from 'url';
|
|
21
|
+
// ESM __dirname equivalent
|
|
22
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
23
|
+
const __dirname = path.dirname(__filename);
|
|
24
|
+
/**
|
|
25
|
+
* Encryption service for sensitive data
|
|
26
|
+
* Provides AES-256-GCM encryption for application-level encryption
|
|
27
|
+
*/
|
|
28
|
+
export class EncryptionService {
|
|
29
|
+
/**
|
|
30
|
+
* Automatically add the encryption key to the .env file or persistent storage
|
|
31
|
+
*/
|
|
32
|
+
addKeyToEnvFile(encryptionKey) {
|
|
33
|
+
const isDocker = process.env.DOCKER_ENV === 'true';
|
|
34
|
+
if (isDocker) {
|
|
35
|
+
// In Docker, store key in persistent data directory
|
|
36
|
+
this.saveKeyToPersistentStorage(encryptionKey);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// In regular environment, store in .env file
|
|
40
|
+
this.saveKeyToEnvFile(encryptionKey);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Save encryption key to persistent data directory (for Docker)
|
|
45
|
+
*/
|
|
46
|
+
saveKeyToPersistentStorage(encryptionKey) {
|
|
47
|
+
try {
|
|
48
|
+
const dataDir = process.env.DATA_DIR || path.join(process.cwd(), 'backend', 'data');
|
|
49
|
+
const keyPath = path.join(dataDir, '.encryption_key');
|
|
50
|
+
// Ensure data directory exists
|
|
51
|
+
if (!fs.existsSync(dataDir)) {
|
|
52
|
+
fs.mkdirSync(dataDir, { recursive: true });
|
|
53
|
+
}
|
|
54
|
+
// Write the key to persistent storage
|
|
55
|
+
fs.writeFileSync(keyPath, encryptionKey, 'utf8');
|
|
56
|
+
console.info(`✅ Automatically saved ENCRYPTION_KEY to persistent storage: ${keyPath}`);
|
|
57
|
+
console.info('🔐 Encryption key will persist across container restarts');
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error('❌ Failed to save ENCRYPTION_KEY to persistent storage:', error);
|
|
61
|
+
console.warn(' Please set ENCRYPTION_KEY environment variable manually:');
|
|
62
|
+
console.warn(` ENCRYPTION_KEY=${encryptionKey}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Find the .env file location - checks multiple possible locations
|
|
67
|
+
*/
|
|
68
|
+
findEnvFilePath() {
|
|
69
|
+
// Possible .env file locations in order of priority
|
|
70
|
+
const possiblePaths = [
|
|
71
|
+
path.join(process.cwd(), 'backend', '.env'), // Running from project root (npm run dev)
|
|
72
|
+
path.join(process.cwd(), '.env'), // Running from backend directory
|
|
73
|
+
path.join(__dirname, '..', '..', '.env'), // Relative to this file (backend/src/services -> backend/)
|
|
74
|
+
];
|
|
75
|
+
// Find the first existing .env file
|
|
76
|
+
for (const envPath of possiblePaths) {
|
|
77
|
+
if (fs.existsSync(envPath)) {
|
|
78
|
+
return envPath;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// If no .env exists, prefer the backend/.env location if backend dir exists
|
|
82
|
+
const backendEnvPath = path.join(process.cwd(), 'backend', '.env');
|
|
83
|
+
const backendDir = path.dirname(backendEnvPath);
|
|
84
|
+
if (fs.existsSync(backendDir)) {
|
|
85
|
+
return backendEnvPath;
|
|
86
|
+
}
|
|
87
|
+
// Fallback to cwd/.env
|
|
88
|
+
return path.join(process.cwd(), '.env');
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Save encryption key to .env file (for regular environments)
|
|
92
|
+
*/
|
|
93
|
+
saveKeyToEnvFile(encryptionKey) {
|
|
94
|
+
try {
|
|
95
|
+
const envPath = this.findEnvFilePath();
|
|
96
|
+
let envContent = '';
|
|
97
|
+
// Read existing .env file if it exists
|
|
98
|
+
if (fs.existsSync(envPath)) {
|
|
99
|
+
envContent = fs.readFileSync(envPath, 'utf8');
|
|
100
|
+
// Check if ENCRYPTION_KEY already exists (commented or uncommented)
|
|
101
|
+
if (/^ENCRYPTION_KEY=/m.test(envContent)) {
|
|
102
|
+
console.warn('⚠️ ENCRYPTION_KEY already exists in .env file, skipping auto-generation');
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// If there's a commented ENCRYPTION_KEY line, replace it with the actual key
|
|
106
|
+
if (envContent.includes('# ENCRYPTION_KEY=')) {
|
|
107
|
+
envContent = envContent.replace(/# ENCRYPTION_KEY=.*/, `ENCRYPTION_KEY=${encryptionKey}`);
|
|
108
|
+
fs.writeFileSync(envPath, envContent, 'utf8');
|
|
109
|
+
console.info(`✅ Automatically added ENCRYPTION_KEY to .env file: ${envPath}`);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Add the encryption key to the content
|
|
114
|
+
const keyLine = `\n# Database Encryption\n# 64-character encryption key for protecting sensitive data\nENCRYPTION_KEY=${encryptionKey}\n`;
|
|
115
|
+
if (envContent && !envContent.endsWith('\n')) {
|
|
116
|
+
envContent += '\n';
|
|
117
|
+
}
|
|
118
|
+
envContent += keyLine;
|
|
119
|
+
// Write back to .env file
|
|
120
|
+
fs.writeFileSync(envPath, envContent, 'utf8');
|
|
121
|
+
console.info(`✅ Automatically added ENCRYPTION_KEY to .env file: ${envPath}`);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
console.error('❌ Failed to automatically add ENCRYPTION_KEY to .env file:', error);
|
|
125
|
+
console.warn(' Please manually add the following line to your .env file:');
|
|
126
|
+
console.warn(` ENCRYPTION_KEY=${encryptionKey}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Load encryption key from persistent storage (for Docker)
|
|
131
|
+
*/
|
|
132
|
+
loadKeyFromPersistentStorage() {
|
|
133
|
+
try {
|
|
134
|
+
const dataDir = process.env.DATA_DIR || path.join(process.cwd(), 'backend', 'data');
|
|
135
|
+
const keyPath = path.join(dataDir, '.encryption_key');
|
|
136
|
+
if (fs.existsSync(keyPath)) {
|
|
137
|
+
const key = fs.readFileSync(keyPath, 'utf8').trim();
|
|
138
|
+
if (key.length === 64) {
|
|
139
|
+
console.info(`✅ Loaded encryption key from persistent storage: ${keyPath}`);
|
|
140
|
+
return key;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
console.warn('⚠️ Failed to load encryption key from persistent storage:', error);
|
|
146
|
+
}
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
constructor() {
|
|
150
|
+
this.algorithm = 'aes-256-gcm';
|
|
151
|
+
// Get encryption key from environment, persistent storage, or generate one
|
|
152
|
+
let keyString = process.env.ENCRYPTION_KEY;
|
|
153
|
+
// If no environment variable, try loading from persistent storage in Docker
|
|
154
|
+
if (!keyString && process.env.DOCKER_ENV === 'true') {
|
|
155
|
+
const persistentKey = this.loadKeyFromPersistentStorage();
|
|
156
|
+
if (persistentKey) {
|
|
157
|
+
keyString = persistentKey;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (keyString) {
|
|
161
|
+
if (keyString.length !== 64) {
|
|
162
|
+
throw new Error(`ENCRYPTION_KEY must be exactly 64 hex characters (32 bytes). Current length: ${keyString.length}`);
|
|
163
|
+
}
|
|
164
|
+
this.encryptionKey = Buffer.from(keyString, 'hex');
|
|
165
|
+
if (this.encryptionKey.length !== 32) {
|
|
166
|
+
throw new Error('Invalid ENCRYPTION_KEY: hex decoding failed');
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
// Generate a new key and automatically add it to appropriate storage
|
|
171
|
+
this.encryptionKey = crypto.randomBytes(32);
|
|
172
|
+
const newKeyString = this.encryptionKey.toString('hex');
|
|
173
|
+
console.warn(`⚠️ No ENCRYPTION_KEY found. Generated key: ${newKeyString}`);
|
|
174
|
+
// Automatically add the key to appropriate storage (Docker vs regular)
|
|
175
|
+
this.addKeyToEnvFile(newKeyString);
|
|
176
|
+
if (process.env.DOCKER_ENV === 'true') {
|
|
177
|
+
console.info('🔐 Generated encryption key saved to persistent storage');
|
|
178
|
+
console.info(' Key will persist across container restarts');
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
console.info('🔐 Generated encryption key has been automatically added to your .env file');
|
|
182
|
+
console.info(' Restart the application to use the persistent key');
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
static getInstance() {
|
|
187
|
+
if (!EncryptionService.instance) {
|
|
188
|
+
EncryptionService.instance = new EncryptionService();
|
|
189
|
+
}
|
|
190
|
+
return EncryptionService.instance;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Encrypt sensitive text data
|
|
194
|
+
*/
|
|
195
|
+
encrypt(plaintext) {
|
|
196
|
+
if (!plaintext)
|
|
197
|
+
return plaintext;
|
|
198
|
+
try {
|
|
199
|
+
const iv = crypto.randomBytes(16); // 16 bytes for AES
|
|
200
|
+
const cipher = crypto.createCipheriv(this.algorithm, this.encryptionKey, iv);
|
|
201
|
+
let encrypted = cipher.update(plaintext, 'utf8', 'hex');
|
|
202
|
+
encrypted += cipher.final('hex');
|
|
203
|
+
const authTag = cipher.getAuthTag();
|
|
204
|
+
// Combine IV, auth tag, and encrypted data
|
|
205
|
+
return (iv.toString('hex') + ':' + authTag.toString('hex') + ':' + encrypted);
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
console.error('Encryption error:', error);
|
|
209
|
+
throw new Error('Failed to encrypt data');
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Decrypt encrypted text data
|
|
214
|
+
*/
|
|
215
|
+
decrypt(encryptedData) {
|
|
216
|
+
if (!encryptedData || !encryptedData.includes(':')) {
|
|
217
|
+
// Data doesn't contain colons, likely unencrypted
|
|
218
|
+
if (process.env.DEBUG_ENCRYPTION) {
|
|
219
|
+
console.debug('Decryption: Data appears to be unencrypted (no colons found)');
|
|
220
|
+
}
|
|
221
|
+
return encryptedData;
|
|
222
|
+
}
|
|
223
|
+
try {
|
|
224
|
+
const parts = encryptedData.split(':');
|
|
225
|
+
if (parts.length !== 3) {
|
|
226
|
+
console.warn(`Decryption: Invalid format (expected 3 parts, got ${parts.length}), treating as unencrypted data`);
|
|
227
|
+
return encryptedData;
|
|
228
|
+
}
|
|
229
|
+
const [ivHex, authTagHex, encrypted] = parts;
|
|
230
|
+
// Validate hex format before attempting to convert
|
|
231
|
+
if (!/^[a-fA-F0-9]+$/.test(ivHex) || !/^[a-fA-F0-9]+$/.test(authTagHex)) {
|
|
232
|
+
console.warn('Decryption: Invalid hex format, treating as unencrypted data');
|
|
233
|
+
return encryptedData;
|
|
234
|
+
}
|
|
235
|
+
const iv = Buffer.from(ivHex, 'hex');
|
|
236
|
+
const authTag = Buffer.from(authTagHex, 'hex');
|
|
237
|
+
const decipher = crypto.createDecipheriv(this.algorithm, this.encryptionKey, iv);
|
|
238
|
+
decipher.setAuthTag(authTag);
|
|
239
|
+
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
|
|
240
|
+
decrypted += decipher.final('utf8');
|
|
241
|
+
return decrypted;
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
console.error('Decryption error:', error);
|
|
245
|
+
console.warn('Treating as unencrypted data for backward compatibility');
|
|
246
|
+
return encryptedData; // Return original data if decryption fails
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Encrypt JSON objects
|
|
251
|
+
*/
|
|
252
|
+
encryptObject(obj) {
|
|
253
|
+
return this.encrypt(JSON.stringify(obj));
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Decrypt JSON objects
|
|
257
|
+
*/
|
|
258
|
+
decryptObject(encryptedData) {
|
|
259
|
+
const decrypted = this.decrypt(encryptedData);
|
|
260
|
+
return JSON.parse(decrypted);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Check if data appears to be encrypted
|
|
264
|
+
*/
|
|
265
|
+
isEncrypted(data) {
|
|
266
|
+
return Boolean(data && data.includes(':') && data.split(':').length === 3);
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Generate a new encryption key
|
|
270
|
+
*/
|
|
271
|
+
static generateKey() {
|
|
272
|
+
return crypto.randomBytes(32).toString('hex');
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Get the current encryption key (for first-time setup display)
|
|
276
|
+
* WARNING: Only use this during first-time setup when showing the key to the admin
|
|
277
|
+
*/
|
|
278
|
+
getKeyForDisplay() {
|
|
279
|
+
return this.encryptionKey.toString('hex');
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
// Export singleton instance
|
|
283
|
+
export const encryptionService = EncryptionService.getInstance();
|
|
284
|
+
//# sourceMappingURL=encryptionService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryptionService.js","sourceRoot":"","sources":["../../src/services/encryptionService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,2BAA2B;AAC3B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IAK5B;;OAEG;IACK,eAAe,CAAC,aAAqB;QAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,MAAM,CAAC;QAEnD,IAAI,QAAQ,EAAE,CAAC;YACb,oDAAoD;YACpD,IAAI,CAAC,0BAA0B,CAAC,aAAa,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,6CAA6C;YAC7C,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED;;OAEG;IACK,0BAA0B,CAAC,aAAqB;QACtD,IAAI,CAAC;YACH,MAAM,OAAO,GACX,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;YACtE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;YAEtD,+BAA+B;YAC/B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5B,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7C,CAAC;YAED,sCAAsC;YACtC,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC;YACjD,OAAO,CAAC,IAAI,CACV,+DAA+D,OAAO,EAAE,CACzE,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC;QAC3E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CACX,wDAAwD,EACxD,KAAK,CACN,CAAC;YACF,OAAO,CAAC,IAAI,CACV,6DAA6D,CAC9D,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,qBAAqB,aAAa,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED;;OAEG;IACK,eAAe;QACrB,oDAAoD;QACpD,MAAM,aAAa,GAAG;YACpB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,0CAA0C;YACvF,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,EAAE,iCAAiC;YACnE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,2DAA2D;SACtG,CAAC;QAEF,oCAAoC;QACpC,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE,CAAC;YACpC,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC3B,OAAO,OAAO,CAAC;YACjB,CAAC;QACH,CAAC;QAED,4EAA4E;QAC5E,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QACnE,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAChD,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,OAAO,cAAc,CAAC;QACxB,CAAC;QAED,uBAAuB;QACvB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,aAAqB;QAC5C,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;YACvC,IAAI,UAAU,GAAG,EAAE,CAAC;YAEpB,uCAAuC;YACvC,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC3B,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAE9C,oEAAoE;gBACpE,IAAI,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;oBACzC,OAAO,CAAC,IAAI,CACV,0EAA0E,CAC3E,CAAC;oBACF,OAAO;gBACT,CAAC;gBAED,6EAA6E;gBAC7E,IAAI,UAAU,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;oBAC7C,UAAU,GAAG,UAAU,CAAC,OAAO,CAC7B,qBAAqB,EACrB,kBAAkB,aAAa,EAAE,CAClC,CAAC;oBACF,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;oBAC9C,OAAO,CAAC,IAAI,CACV,sDAAsD,OAAO,EAAE,CAChE,CAAC;oBACF,OAAO;gBACT,CAAC;YACH,CAAC;YAED,wCAAwC;YACxC,MAAM,OAAO,GAAG,wGAAwG,aAAa,IAAI,CAAC;YAE1I,IAAI,UAAU,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7C,UAAU,IAAI,IAAI,CAAC;YACrB,CAAC;YAED,UAAU,IAAI,OAAO,CAAC;YAEtB,0BAA0B;YAC1B,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;YAC9C,OAAO,CAAC,IAAI,CACV,sDAAsD,OAAO,EAAE,CAChE,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CACX,4DAA4D,EAC5D,KAAK,CACN,CAAC;YACF,OAAO,CAAC,IAAI,CACV,8DAA8D,CAC/D,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,qBAAqB,aAAa,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED;;OAEG;IACK,4BAA4B;QAClC,IAAI,CAAC;YACH,MAAM,OAAO,GACX,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;YACtE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;YAEtD,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC3B,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;gBACpD,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;oBACtB,OAAO,CAAC,IAAI,CACV,oDAAoD,OAAO,EAAE,CAC9D,CAAC;oBACF,OAAO,GAAG,CAAC;gBACb,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CACV,4DAA4D,EAC5D,KAAK,CACN,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;QArKQ,cAAS,GAAG,aAAa,CAAC;QAsKhC,2EAA2E;QAC3E,IAAI,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAE3C,4EAA4E;QAC5E,IAAI,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;YACpD,MAAM,aAAa,GAAG,IAAI,CAAC,4BAA4B,EAAE,CAAC;YAC1D,IAAI,aAAa,EAAE,CAAC;gBAClB,SAAS,GAAG,aAAa,CAAC;YAC5B,CAAC;QACH,CAAC;QAED,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,SAAS,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CACb,gFAAgF,SAAS,CAAC,MAAM,EAAE,CACnG,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YACnD,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;gBACrC,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;aAAM,CAAC;YACN,qEAAqE;YACrE,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAExD,OAAO,CAAC,IAAI,CACV,+CAA+C,YAAY,EAAE,CAC9D,CAAC;YAEF,uEAAuE;YACvE,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;YAEnC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;gBACtC,OAAO,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;gBACxE,OAAO,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;YAChE,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CACV,4EAA4E,CAC7E,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,WAAW;QACvB,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,CAAC;YAChC,iBAAiB,CAAC,QAAQ,GAAG,IAAI,iBAAiB,EAAE,CAAC;QACvD,CAAC;QACD,OAAO,iBAAiB,CAAC,QAAQ,CAAC;IACpC,CAAC;IAED;;OAEG;IACI,OAAO,CAAC,SAAiB;QAC9B,IAAI,CAAC,SAAS;YAAE,OAAO,SAAS,CAAC;QAEjC,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAmB;YACtD,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAClC,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,aAAa,EAClB,EAAE,CACH,CAAC;YAEF,IAAI,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;YACxD,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAEjC,MAAM,OAAO,GAAI,MAA2B,CAAC,UAAU,EAAE,CAAC;YAE1D,2CAA2C;YAC3C,OAAO,CACL,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,SAAS,CACrE,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED;;OAEG;IACI,OAAO,CAAC,aAAqB;QAClC,IAAI,CAAC,aAAa,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACnD,kDAAkD;YAClD,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;gBACjC,OAAO,CAAC,KAAK,CACX,8DAA8D,CAC/D,CAAC;YACJ,CAAC;YACD,OAAO,aAAa,CAAC;QACvB,CAAC;QAED,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACvC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,OAAO,CAAC,IAAI,CACV,qDAAqD,KAAK,CAAC,MAAM,iCAAiC,CACnG,CAAC;gBACF,OAAO,aAAa,CAAC;YACvB,CAAC;YAED,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC;YAE7C,mDAAmD;YACnD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;gBACxE,OAAO,CAAC,IAAI,CACV,8DAA8D,CAC/D,CAAC;gBACF,OAAO,aAAa,CAAC;YACvB,CAAC;YAED,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YACrC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YAE/C,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB,CACtC,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,aAAa,EAClB,EAAE,CACH,CAAC;YACD,QAA+B,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAErD,IAAI,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;YAC1D,SAAS,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAEpC,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;YAC1C,OAAO,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;YACxE,OAAO,aAAa,CAAC,CAAC,2CAA2C;QACnE,CAAC;IACH,CAAC;IAED;;OAEG;IACI,aAAa,CAAC,GAA4B;QAC/C,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACI,aAAa,CAAI,aAAqB;QAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACI,WAAW,CAAC,IAAY;QAC7B,OAAO,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;IAC7E,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,WAAW;QACvB,OAAO,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC;IAED;;;OAGG;IACI,gBAAgB;QACrB,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;CACF;AAED,4BAA4B;AAC5B,MAAM,CAAC,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { PersonaMemoryEntry, MemorySearchResult, EmbeddingModel } from '../types/index.js';
|
|
2
|
+
export type MemoryType = 'fact' | 'preference' | 'experience' | 'emotional' | 'context' | 'instruction' | 'general';
|
|
3
|
+
export interface EnhancedMemoryEntry extends PersonaMemoryEntry {
|
|
4
|
+
memory_type?: MemoryType;
|
|
5
|
+
access_count?: number;
|
|
6
|
+
last_accessed?: number;
|
|
7
|
+
decay_factor?: number;
|
|
8
|
+
consolidated_from?: string[];
|
|
9
|
+
}
|
|
10
|
+
export declare class MemoryService {
|
|
11
|
+
private db;
|
|
12
|
+
private embeddingModels;
|
|
13
|
+
constructor();
|
|
14
|
+
/**
|
|
15
|
+
* Ensure database is available
|
|
16
|
+
*/
|
|
17
|
+
private ensureDatabase;
|
|
18
|
+
private initializeTables;
|
|
19
|
+
/**
|
|
20
|
+
* Migrate database to add new columns for existing tables
|
|
21
|
+
*/
|
|
22
|
+
private migrateDatabase;
|
|
23
|
+
/**
|
|
24
|
+
* Get SQLite column type for a given column name
|
|
25
|
+
*/
|
|
26
|
+
private getColumnType;
|
|
27
|
+
/**
|
|
28
|
+
* Classify memory content into a type
|
|
29
|
+
*/
|
|
30
|
+
classifyMemoryType(content: string): MemoryType;
|
|
31
|
+
/**
|
|
32
|
+
* Calculate enhanced importance score based on multiple factors
|
|
33
|
+
*/
|
|
34
|
+
calculateEnhancedImportance(content: string, memoryType: MemoryType, _context?: string): number;
|
|
35
|
+
/**
|
|
36
|
+
* Apply time-based decay to importance score
|
|
37
|
+
*/
|
|
38
|
+
applyDecay(originalImportance: number, timestamp: number, accessCount?: number, lastAccessed?: number): number;
|
|
39
|
+
/**
|
|
40
|
+
* Get available embedding models
|
|
41
|
+
*/
|
|
42
|
+
getEmbeddingModels(): EmbeddingModel[];
|
|
43
|
+
/**
|
|
44
|
+
* Generate embedding for text using specified model
|
|
45
|
+
*/
|
|
46
|
+
private generateEmbedding;
|
|
47
|
+
/**
|
|
48
|
+
* Store a memory entry with embedding and automatic classification
|
|
49
|
+
*/
|
|
50
|
+
storeMemory(userId: string, personaId: string, content: string, embeddingModel: string, context?: string, importanceScore?: number, memoryType?: MemoryType): Promise<EnhancedMemoryEntry>;
|
|
51
|
+
/**
|
|
52
|
+
* Find similar memories (for deduplication)
|
|
53
|
+
*/
|
|
54
|
+
private findSimilarMemories;
|
|
55
|
+
/**
|
|
56
|
+
* Reinforce a memory (increases importance and access count)
|
|
57
|
+
*/
|
|
58
|
+
reinforceMemory(memoryId: string): Promise<boolean>;
|
|
59
|
+
/**
|
|
60
|
+
* Calculate cosine similarity between two vectors
|
|
61
|
+
*/
|
|
62
|
+
private cosineSimilarity;
|
|
63
|
+
/**
|
|
64
|
+
* Search memories using semantic similarity with enhanced relevance scoring
|
|
65
|
+
*/
|
|
66
|
+
searchMemories(userId: string, personaId: string, query: string, embeddingModel: string, topK?: number, minSimilarity?: number, memoryTypes?: MemoryType[]): Promise<MemorySearchResult[]>;
|
|
67
|
+
/**
|
|
68
|
+
* Update memory access tracking
|
|
69
|
+
*/
|
|
70
|
+
private updateMemoryAccess;
|
|
71
|
+
/**
|
|
72
|
+
* Get all memories for a persona
|
|
73
|
+
*/
|
|
74
|
+
getMemories(userId: string, personaId: string, limit?: number, offset?: number): Promise<PersonaMemoryEntry[]>;
|
|
75
|
+
/**
|
|
76
|
+
* Get memory count for a persona
|
|
77
|
+
*/
|
|
78
|
+
getMemoryCount(userId: string, personaId: string): Promise<number>;
|
|
79
|
+
/**
|
|
80
|
+
* Get memory status for a persona
|
|
81
|
+
*/
|
|
82
|
+
getMemoryStatus(userId: string, personaId: string): Promise<{
|
|
83
|
+
memory_count: number;
|
|
84
|
+
last_backup?: number;
|
|
85
|
+
size_mb: number;
|
|
86
|
+
}>;
|
|
87
|
+
/**
|
|
88
|
+
* Delete all memories for a persona (wipe)
|
|
89
|
+
*/
|
|
90
|
+
wipeMemories(userId: string, personaId: string): Promise<number>;
|
|
91
|
+
/**
|
|
92
|
+
* Export memories for backup
|
|
93
|
+
*/
|
|
94
|
+
exportMemories(userId: string, personaId: string): Promise<PersonaMemoryEntry[]>;
|
|
95
|
+
/**
|
|
96
|
+
* Import memories from backup
|
|
97
|
+
*/
|
|
98
|
+
importMemories(memories: PersonaMemoryEntry[], targetUserId: string): Promise<number>;
|
|
99
|
+
/**
|
|
100
|
+
* Update memory importance score
|
|
101
|
+
*/
|
|
102
|
+
updateMemoryImportance(memoryId: string, importanceScore: number): Promise<boolean>;
|
|
103
|
+
/**
|
|
104
|
+
* Delete old memories based on retention policy
|
|
105
|
+
*/
|
|
106
|
+
cleanupOldMemories(userId: string, personaId: string, retentionDays: number): Promise<number>;
|
|
107
|
+
/**
|
|
108
|
+
* Consolidate similar memories to reduce redundancy and save space
|
|
109
|
+
* This merges memories with high similarity into a single, more comprehensive memory
|
|
110
|
+
*/
|
|
111
|
+
consolidateMemories(userId: string, personaId: string, embeddingModel: string, similarityThreshold?: number): Promise<{
|
|
112
|
+
consolidated: number;
|
|
113
|
+
deleted: number;
|
|
114
|
+
}>;
|
|
115
|
+
/**
|
|
116
|
+
* Create consolidated content from multiple similar memories
|
|
117
|
+
*/
|
|
118
|
+
private createConsolidatedContent;
|
|
119
|
+
/**
|
|
120
|
+
* Get memory statistics for a persona
|
|
121
|
+
*/
|
|
122
|
+
getMemoryStats(userId: string, personaId: string): Promise<{
|
|
123
|
+
total_count: number;
|
|
124
|
+
by_type: Record<string, number>;
|
|
125
|
+
avg_importance: number;
|
|
126
|
+
oldest_memory: number | null;
|
|
127
|
+
newest_memory: number | null;
|
|
128
|
+
total_accesses: number;
|
|
129
|
+
}>;
|
|
130
|
+
/**
|
|
131
|
+
* Apply decay to all memories (should be called periodically)
|
|
132
|
+
*/
|
|
133
|
+
applyGlobalDecay(userId: string, personaId: string): Promise<number>;
|
|
134
|
+
/**
|
|
135
|
+
* Get important memories (facts, preferences, instructions) that should always be included
|
|
136
|
+
*/
|
|
137
|
+
getCoreMemories(userId: string, personaId: string, limit?: number): Promise<PersonaMemoryEntry[]>;
|
|
138
|
+
}
|
|
139
|
+
export declare const memoryService: MemoryService;
|
|
140
|
+
//# sourceMappingURL=memoryService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memoryService.d.ts","sourceRoot":"","sources":["../../src/services/memoryService.ts"],"names":[],"mappings":"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"}
|