minor fix
This commit is contained in:
parent
2a1edb6ed8
commit
3031d0d288
@ -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)
|
||||
|
@ -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 { 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;
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,7 @@ app.whenReady().then(async () => {
|
||||
await authService.initialize();
|
||||
|
||||
//////// after_modelStateService ////////
|
||||
modelStateService.initialize();
|
||||
await modelStateService.initialize();
|
||||
//////// after_modelStateService ////////
|
||||
|
||||
listenService.setupIpcHandlers();
|
||||
|
Loading…
x
Reference in New Issue
Block a user