From 3031d0d288afdbd32cc36ce26e864a6ee0965e0b Mon Sep 17 00:00:00 2001 From: jhyang0 Date: Thu, 10 Jul 2025 17:30:33 +0900 Subject: [PATCH] minor fix --- pickleglass_web/app/login/page.tsx | 7 +- src/common/services/cryptoService.js | 89 ------------------------ src/common/services/modelStateService.js | 16 +++-- src/features/ask/AskView.js | 19 +++-- src/index.js | 2 +- 5 files changed, 28 insertions(+), 105 deletions(-) delete mode 100644 src/common/services/cryptoService.js diff --git a/pickleglass_web/app/login/page.tsx b/pickleglass_web/app/login/page.tsx index 60ab49a..b9148fd 100644 --- a/pickleglass_web/app/login/page.tsx +++ b/pickleglass_web/app/login/page.tsx @@ -43,9 +43,10 @@ export default function LoginPage() { window.location.href = deepLinkUrl - setTimeout(() => { - alert('Login completed. Please return to Pickle Glass app.') - }, 1000) + // Maybe we don't need this + // setTimeout(() => { + // alert('Login completed. Please return to Pickle Glass app.') + // }, 1000) } catch (error) { console.error('❌ Deep link processing failed:', error) diff --git a/src/common/services/cryptoService.js b/src/common/services/cryptoService.js deleted file mode 100644 index 79935e4..0000000 --- a/src/common/services/cryptoService.js +++ /dev/null @@ -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(); \ No newline at end of file diff --git a/src/common/services/modelStateService.js b/src/common/services/modelStateService.js index 62a093b..a83b4ac 100644 --- a/src/common/services/modelStateService.js +++ b/src/common/services/modelStateService.js @@ -2,7 +2,7 @@ const Store = require('electron-store'); const fetch = require('node-fetch'); const { ipcMain, webContents } = require('electron'); const { PROVIDERS } = require('../ai/factory'); -const cryptoService = require('./cryptoService'); +const encryptionService = require('./encryptionService'); class ModelStateService { constructor(authService) { @@ -11,8 +11,8 @@ class ModelStateService { this.state = {}; } - initialize() { - this._loadStateForCurrentUser(); + async initialize() { + await this._loadStateForCurrentUser(); this.setupIpcHandlers(); console.log('[ModelStateService] Initialized.'); @@ -64,8 +64,12 @@ class ModelStateService { }); } - _loadStateForCurrentUser() { + async _loadStateForCurrentUser() { const userId = this.authService.getCurrentUserId(); + + // Initialize encryption service for current user + await encryptionService.initializeKey(userId); + const initialApiKeys = Object.keys(PROVIDERS).reduce((acc, key) => { acc[key] = null; return acc; @@ -83,7 +87,7 @@ class ModelStateService { this.state.apiKeys[p] = null; } else if (this.state.apiKeys[p] && p !== 'ollama' && p !== 'whisper') { try { - this.state.apiKeys[p] = cryptoService.decrypt(this.state.apiKeys[p]); + this.state.apiKeys[p] = encryptionService.decrypt(this.state.apiKeys[p]); } catch (error) { console.error(`[ModelStateService] Failed to decrypt API key for ${p}, resetting`); this.state.apiKeys[p] = null; @@ -107,7 +111,7 @@ class ModelStateService { for (const [provider, key] of Object.entries(stateToSave.apiKeys)) { if (key && provider !== 'ollama' && provider !== 'whisper') { try { - stateToSave.apiKeys[provider] = cryptoService.encrypt(key); + stateToSave.apiKeys[provider] = encryptionService.encrypt(key); } catch (error) { console.error(`[ModelStateService] Failed to encrypt API key for ${provider}`); stateToSave.apiKeys[provider] = null; diff --git a/src/features/ask/AskView.js b/src/features/ask/AskView.js index e35db27..b871d3a 100644 --- a/src/features/ask/AskView.js +++ b/src/features/ask/AskView.js @@ -415,7 +415,7 @@ export class AskView extends LitElement { background: rgba(0, 0, 0, 0.1); border-top: 1px solid rgba(255, 255, 255, 0.1); 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; } @@ -541,6 +541,7 @@ export class AskView extends LitElement { this.handleStreamChunk = this.handleStreamChunk.bind(this); this.handleStreamEnd = this.handleStreamEnd.bind(this); this.handleSendText = this.handleSendText.bind(this); + this.handleGlobalSendRequest = this.handleGlobalSendRequest.bind(this); this.handleTextKeydown = this.handleTextKeydown.bind(this); this.closeResponsePanel = this.closeResponsePanel.bind(this); this.handleCopy = this.handleCopy.bind(this); @@ -556,7 +557,6 @@ export class AskView extends LitElement { this.loadLibraries(); // --- Resize helpers --- - this.adjustHeightThrottle = null; this.isThrottled = false; } @@ -1220,6 +1220,14 @@ export class AskView extends LitElement { handleGlobalSendRequest() { const textInput = this.shadowRoot?.getElementById('textInput'); + + if (!this.showTextInput) { + this.showTextInput = true; + this.requestUpdate(); + this.focusTextInput(); + return; + } + if (!textInput) return; textInput.focus(); @@ -1349,12 +1357,11 @@ export class AskView extends LitElement { adjustWindowHeightThrottled() { if (this.isThrottled) return; - this.adjustWindowHeight(); this.isThrottled = true; - - this.adjustHeightThrottle = setTimeout(() => { + requestAnimationFrame(() => { + this.adjustWindowHeight(); this.isThrottled = false; - }, 16); + }); } } diff --git a/src/index.js b/src/index.js index 22a06f5..16be2e4 100644 --- a/src/index.js +++ b/src/index.js @@ -199,7 +199,7 @@ app.whenReady().then(async () => { await authService.initialize(); //////// after_modelStateService //////// - modelStateService.initialize(); + await modelStateService.initialize(); //////// after_modelStateService //////// listenService.setupIpcHandlers();