minor fix
This commit is contained in:
		
							parent
							
								
									2a1edb6ed8
								
							
						
					
					
						commit
						3031d0d288
					
				@ -43,9 +43,10 @@ export default function LoginPage() {
 | 
				
			|||||||
            
 | 
					            
 | 
				
			||||||
            window.location.href = deepLinkUrl
 | 
					            window.location.href = deepLinkUrl
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            setTimeout(() => {
 | 
					            // Maybe we don't need this
 | 
				
			||||||
              alert('Login completed. Please return to Pickle Glass app.')
 | 
					            // setTimeout(() => {
 | 
				
			||||||
            }, 1000)
 | 
					            //   alert('Login completed. Please return to Pickle Glass app.')
 | 
				
			||||||
 | 
					            // }, 1000)
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
          } catch (error) {
 | 
					          } catch (error) {
 | 
				
			||||||
            console.error('❌ Deep link processing failed:', error)
 | 
					            console.error('❌ Deep link processing failed:', error)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,89 +0,0 @@
 | 
				
			|||||||
const crypto = require('crypto');
 | 
					 | 
				
			||||||
const { app } = require('electron');
 | 
					 | 
				
			||||||
const os = require('os');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CryptoService {
 | 
					 | 
				
			||||||
    constructor() {
 | 
					 | 
				
			||||||
        this.algorithm = 'aes-256-gcm';
 | 
					 | 
				
			||||||
        this.saltLength = 32;
 | 
					 | 
				
			||||||
        this.tagLength = 16;
 | 
					 | 
				
			||||||
        this.ivLength = 16;
 | 
					 | 
				
			||||||
        this.iterations = 100000;
 | 
					 | 
				
			||||||
        this.keyLength = 32;
 | 
					 | 
				
			||||||
        this._derivedKey = null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    _getMachineId() {
 | 
					 | 
				
			||||||
        const machineInfo = `${os.hostname()}-${os.platform()}-${os.arch()}`;
 | 
					 | 
				
			||||||
        const appPath = app.getPath('userData');
 | 
					 | 
				
			||||||
        return crypto.createHash('sha256').update(machineInfo + appPath).digest('hex');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    _deriveKey() {
 | 
					 | 
				
			||||||
        if (this._derivedKey) return this._derivedKey;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        const machineId = this._getMachineId();
 | 
					 | 
				
			||||||
        const salt = crypto.createHash('sha256').update('pickle-glass-salt').digest();
 | 
					 | 
				
			||||||
        this._derivedKey = crypto.pbkdf2Sync(machineId, salt, this.iterations, this.keyLength, 'sha256');
 | 
					 | 
				
			||||||
        return this._derivedKey;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    encrypt(text) {
 | 
					 | 
				
			||||||
        if (!text) return null;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            const iv = crypto.randomBytes(this.ivLength);
 | 
					 | 
				
			||||||
            const salt = crypto.randomBytes(this.saltLength);
 | 
					 | 
				
			||||||
            const key = this._deriveKey();
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            const cipher = crypto.createCipheriv(this.algorithm, key, iv);
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            const encrypted = Buffer.concat([
 | 
					 | 
				
			||||||
                cipher.update(text, 'utf8'),
 | 
					 | 
				
			||||||
                cipher.final()
 | 
					 | 
				
			||||||
            ]);
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            const tag = cipher.getAuthTag();
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            const combined = Buffer.concat([salt, iv, tag, encrypted]);
 | 
					 | 
				
			||||||
            return combined.toString('base64');
 | 
					 | 
				
			||||||
        } catch (error) {
 | 
					 | 
				
			||||||
            console.error('[CryptoService] Encryption failed:', error.message);
 | 
					 | 
				
			||||||
            throw new Error('Encryption failed');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    decrypt(encryptedData) {
 | 
					 | 
				
			||||||
        if (!encryptedData) return null;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            const combined = Buffer.from(encryptedData, 'base64');
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            const salt = combined.slice(0, this.saltLength);
 | 
					 | 
				
			||||||
            const iv = combined.slice(this.saltLength, this.saltLength + this.ivLength);
 | 
					 | 
				
			||||||
            const tag = combined.slice(this.saltLength + this.ivLength, this.saltLength + this.ivLength + this.tagLength);
 | 
					 | 
				
			||||||
            const encrypted = combined.slice(this.saltLength + this.ivLength + this.tagLength);
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            const key = this._deriveKey();
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            const decipher = crypto.createDecipheriv(this.algorithm, key, iv);
 | 
					 | 
				
			||||||
            decipher.setAuthTag(tag);
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            const decrypted = Buffer.concat([
 | 
					 | 
				
			||||||
                decipher.update(encrypted),
 | 
					 | 
				
			||||||
                decipher.final()
 | 
					 | 
				
			||||||
            ]);
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            return decrypted.toString('utf8');
 | 
					 | 
				
			||||||
        } catch (error) {
 | 
					 | 
				
			||||||
            console.error('[CryptoService] Decryption failed:', error.message);
 | 
					 | 
				
			||||||
            throw new Error('Decryption failed');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    clearCache() {
 | 
					 | 
				
			||||||
        this._derivedKey = null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = new CryptoService();
 | 
					 | 
				
			||||||
@ -2,7 +2,7 @@ const Store = require('electron-store');
 | 
				
			|||||||
const fetch = require('node-fetch');
 | 
					const fetch = require('node-fetch');
 | 
				
			||||||
const { ipcMain, webContents } = require('electron');
 | 
					const { ipcMain, webContents } = require('electron');
 | 
				
			||||||
const { PROVIDERS } = require('../ai/factory');
 | 
					const { PROVIDERS } = require('../ai/factory');
 | 
				
			||||||
const cryptoService = require('./cryptoService');
 | 
					const encryptionService = require('./encryptionService');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ModelStateService {
 | 
					class ModelStateService {
 | 
				
			||||||
    constructor(authService) {
 | 
					    constructor(authService) {
 | 
				
			||||||
@ -11,8 +11,8 @@ class ModelStateService {
 | 
				
			|||||||
        this.state = {};
 | 
					        this.state = {};
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    initialize() {
 | 
					    async initialize() {
 | 
				
			||||||
        this._loadStateForCurrentUser();
 | 
					        await this._loadStateForCurrentUser();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.setupIpcHandlers();
 | 
					        this.setupIpcHandlers();
 | 
				
			||||||
        console.log('[ModelStateService] Initialized.');
 | 
					        console.log('[ModelStateService] Initialized.');
 | 
				
			||||||
@ -64,8 +64,12 @@ class ModelStateService {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _loadStateForCurrentUser() {
 | 
					    async _loadStateForCurrentUser() {
 | 
				
			||||||
        const userId = this.authService.getCurrentUserId();
 | 
					        const userId = this.authService.getCurrentUserId();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // Initialize encryption service for current user
 | 
				
			||||||
 | 
					        await encryptionService.initializeKey(userId);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        const initialApiKeys = Object.keys(PROVIDERS).reduce((acc, key) => {
 | 
					        const initialApiKeys = Object.keys(PROVIDERS).reduce((acc, key) => {
 | 
				
			||||||
            acc[key] = null;
 | 
					            acc[key] = null;
 | 
				
			||||||
            return acc;
 | 
					            return acc;
 | 
				
			||||||
@ -83,7 +87,7 @@ class ModelStateService {
 | 
				
			|||||||
                this.state.apiKeys[p] = null;
 | 
					                this.state.apiKeys[p] = null;
 | 
				
			||||||
            } else if (this.state.apiKeys[p] && p !== 'ollama' && p !== 'whisper') {
 | 
					            } else if (this.state.apiKeys[p] && p !== 'ollama' && p !== 'whisper') {
 | 
				
			||||||
                try {
 | 
					                try {
 | 
				
			||||||
                    this.state.apiKeys[p] = cryptoService.decrypt(this.state.apiKeys[p]);
 | 
					                    this.state.apiKeys[p] = encryptionService.decrypt(this.state.apiKeys[p]);
 | 
				
			||||||
                } catch (error) {
 | 
					                } catch (error) {
 | 
				
			||||||
                    console.error(`[ModelStateService] Failed to decrypt API key for ${p}, resetting`);
 | 
					                    console.error(`[ModelStateService] Failed to decrypt API key for ${p}, resetting`);
 | 
				
			||||||
                    this.state.apiKeys[p] = null;
 | 
					                    this.state.apiKeys[p] = null;
 | 
				
			||||||
@ -107,7 +111,7 @@ class ModelStateService {
 | 
				
			|||||||
        for (const [provider, key] of Object.entries(stateToSave.apiKeys)) {
 | 
					        for (const [provider, key] of Object.entries(stateToSave.apiKeys)) {
 | 
				
			||||||
            if (key && provider !== 'ollama' && provider !== 'whisper') {
 | 
					            if (key && provider !== 'ollama' && provider !== 'whisper') {
 | 
				
			||||||
                try {
 | 
					                try {
 | 
				
			||||||
                    stateToSave.apiKeys[provider] = cryptoService.encrypt(key);
 | 
					                    stateToSave.apiKeys[provider] = encryptionService.encrypt(key);
 | 
				
			||||||
                } catch (error) {
 | 
					                } catch (error) {
 | 
				
			||||||
                    console.error(`[ModelStateService] Failed to encrypt API key for ${provider}`);
 | 
					                    console.error(`[ModelStateService] Failed to encrypt API key for ${provider}`);
 | 
				
			||||||
                    stateToSave.apiKeys[provider] = null;
 | 
					                    stateToSave.apiKeys[provider] = null;
 | 
				
			||||||
 | 
				
			|||||||
@ -415,7 +415,7 @@ export class AskView extends LitElement {
 | 
				
			|||||||
            background: rgba(0, 0, 0, 0.1);
 | 
					            background: rgba(0, 0, 0, 0.1);
 | 
				
			||||||
            border-top: 1px solid rgba(255, 255, 255, 0.1);
 | 
					            border-top: 1px solid rgba(255, 255, 255, 0.1);
 | 
				
			||||||
            flex-shrink: 0;
 | 
					            flex-shrink: 0;
 | 
				
			||||||
            transition: all 0.3s ease-in-out;
 | 
					            transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out;
 | 
				
			||||||
            transform-origin: bottom;
 | 
					            transform-origin: bottom;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -541,6 +541,7 @@ export class AskView extends LitElement {
 | 
				
			|||||||
        this.handleStreamChunk = this.handleStreamChunk.bind(this);
 | 
					        this.handleStreamChunk = this.handleStreamChunk.bind(this);
 | 
				
			||||||
        this.handleStreamEnd = this.handleStreamEnd.bind(this);
 | 
					        this.handleStreamEnd = this.handleStreamEnd.bind(this);
 | 
				
			||||||
        this.handleSendText = this.handleSendText.bind(this);
 | 
					        this.handleSendText = this.handleSendText.bind(this);
 | 
				
			||||||
 | 
					        this.handleGlobalSendRequest = this.handleGlobalSendRequest.bind(this);
 | 
				
			||||||
        this.handleTextKeydown = this.handleTextKeydown.bind(this);
 | 
					        this.handleTextKeydown = this.handleTextKeydown.bind(this);
 | 
				
			||||||
        this.closeResponsePanel = this.closeResponsePanel.bind(this);
 | 
					        this.closeResponsePanel = this.closeResponsePanel.bind(this);
 | 
				
			||||||
        this.handleCopy = this.handleCopy.bind(this);
 | 
					        this.handleCopy = this.handleCopy.bind(this);
 | 
				
			||||||
@ -556,7 +557,6 @@ export class AskView extends LitElement {
 | 
				
			|||||||
        this.loadLibraries();
 | 
					        this.loadLibraries();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // --- Resize helpers ---
 | 
					        // --- Resize helpers ---
 | 
				
			||||||
        this.adjustHeightThrottle = null;
 | 
					 | 
				
			||||||
        this.isThrottled = false;
 | 
					        this.isThrottled = false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1220,6 +1220,14 @@ export class AskView extends LitElement {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    handleGlobalSendRequest() {
 | 
					    handleGlobalSendRequest() {
 | 
				
			||||||
        const textInput = this.shadowRoot?.getElementById('textInput');
 | 
					        const textInput = this.shadowRoot?.getElementById('textInput');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!this.showTextInput) {
 | 
				
			||||||
 | 
					            this.showTextInput = true;
 | 
				
			||||||
 | 
					            this.requestUpdate();
 | 
				
			||||||
 | 
					            this.focusTextInput();
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!textInput) return;
 | 
					        if (!textInput) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        textInput.focus();
 | 
					        textInput.focus();
 | 
				
			||||||
@ -1349,12 +1357,11 @@ export class AskView extends LitElement {
 | 
				
			|||||||
    adjustWindowHeightThrottled() {
 | 
					    adjustWindowHeightThrottled() {
 | 
				
			||||||
        if (this.isThrottled) return;
 | 
					        if (this.isThrottled) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.adjustWindowHeight();
 | 
					 | 
				
			||||||
        this.isThrottled = true;
 | 
					        this.isThrottled = true;
 | 
				
			||||||
 | 
					        requestAnimationFrame(() => {
 | 
				
			||||||
        this.adjustHeightThrottle = setTimeout(() => {
 | 
					            this.adjustWindowHeight();
 | 
				
			||||||
            this.isThrottled = false;
 | 
					            this.isThrottled = false;
 | 
				
			||||||
        }, 16);
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -199,7 +199,7 @@ app.whenReady().then(async () => {
 | 
				
			|||||||
        await authService.initialize();
 | 
					        await authService.initialize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //////// after_modelStateService ////////
 | 
					        //////// after_modelStateService ////////
 | 
				
			||||||
        modelStateService.initialize();
 | 
					        await modelStateService.initialize();
 | 
				
			||||||
        //////// after_modelStateService ////////
 | 
					        //////// after_modelStateService ////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        listenService.setupIpcHandlers();
 | 
					        listenService.setupIpcHandlers();
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user