Merge branch 'pickle-com:main' into main
This commit is contained in:
		
						commit
						22f53918e0
					
				@ -13,6 +13,12 @@ publish:
 | 
			
		||||
    repo: glass
 | 
			
		||||
    releaseType: draft
 | 
			
		||||
 | 
			
		||||
# Protocols configuration for deep linking
 | 
			
		||||
protocols:
 | 
			
		||||
    name: PickleGlass Protocol
 | 
			
		||||
    schemes: 
 | 
			
		||||
        - pickleglass
 | 
			
		||||
 | 
			
		||||
# List of files to be included in the app package
 | 
			
		||||
files:
 | 
			
		||||
    - src/**/*
 | 
			
		||||
@ -29,6 +35,27 @@ extraResources:
 | 
			
		||||
asarUnpack:
 | 
			
		||||
    - "src/assets/SystemAudioDump"
 | 
			
		||||
 | 
			
		||||
# Windows configuration
 | 
			
		||||
win:
 | 
			
		||||
    icon: src/assets/logo.ico
 | 
			
		||||
    target:
 | 
			
		||||
        - target: nsis
 | 
			
		||||
          arch: x64
 | 
			
		||||
        - target: portable
 | 
			
		||||
          arch: x64
 | 
			
		||||
    publisherName: Pickle Team
 | 
			
		||||
    requestedExecutionLevel: asInvoker
 | 
			
		||||
 | 
			
		||||
# NSIS installer configuration for Windows
 | 
			
		||||
nsis:
 | 
			
		||||
    oneClick: false
 | 
			
		||||
    perMachine: false
 | 
			
		||||
    allowToChangeInstallationDirectory: true
 | 
			
		||||
    deleteAppDataOnUninstall: true
 | 
			
		||||
    createDesktopShortcut: always
 | 
			
		||||
    createStartMenuShortcut: true
 | 
			
		||||
    shortcutName: Glass
 | 
			
		||||
 | 
			
		||||
# macOS specific configuration
 | 
			
		||||
mac:
 | 
			
		||||
    # The application category type
 | 
			
		||||
 | 
			
		||||
@ -2,9 +2,20 @@ const crypto = require('crypto');
 | 
			
		||||
 | 
			
		||||
function ipcRequest(req, channel, payload) {
 | 
			
		||||
    return new Promise((resolve, reject) => {
 | 
			
		||||
        // 즉시 브리지 상태 확인 - 문제있으면 바로 실패
 | 
			
		||||
        if (!req.bridge || typeof req.bridge.emit !== 'function') {
 | 
			
		||||
            reject(new Error('IPC bridge is not available'));
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const responseChannel = `${channel}-${crypto.randomUUID()}`;
 | 
			
		||||
        
 | 
			
		||||
        req.bridge.once(responseChannel, (response) => {
 | 
			
		||||
            if (!response) {
 | 
			
		||||
                reject(new Error(`No response received from ${channel}`));
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            if (response.success) {
 | 
			
		||||
                resolve(response.data);
 | 
			
		||||
            } else {
 | 
			
		||||
@ -12,7 +23,12 @@ function ipcRequest(req, channel, payload) {
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        req.bridge.emit('web-data-request', channel, responseChannel, payload);
 | 
			
		||||
        try {
 | 
			
		||||
            req.bridge.emit('web-data-request', channel, responseChannel, payload);
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            req.bridge.removeAllListeners(responseChannel);
 | 
			
		||||
            reject(new Error(`Failed to emit IPC request: ${error.message}`));
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -25,11 +25,22 @@ router.get('/profile', async (req, res) => {
 | 
			
		||||
 | 
			
		||||
router.post('/find-or-create', async (req, res) => {
 | 
			
		||||
    try {
 | 
			
		||||
        console.log('[API] find-or-create request received:', req.body);
 | 
			
		||||
        
 | 
			
		||||
        if (!req.body || !req.body.uid) {
 | 
			
		||||
            return res.status(400).json({ error: 'User data with uid is required' });
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        const user = await ipcRequest(req, 'find-or-create-user', req.body);
 | 
			
		||||
        console.log('[API] find-or-create response:', user);
 | 
			
		||||
        res.status(200).json(user);
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
        console.error('Failed to find or create user via IPC:', error);
 | 
			
		||||
        res.status(500).json({ error: 'Failed to find or create user' });
 | 
			
		||||
        console.error('Request body:', req.body);
 | 
			
		||||
        res.status(500).json({ 
 | 
			
		||||
            error: 'Failed to find or create user',
 | 
			
		||||
            details: error.message 
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,8 +2,17 @@ const sqliteClient = require('../../services/sqliteClient');
 | 
			
		||||
 | 
			
		||||
function findOrCreate(user) {
 | 
			
		||||
    const db = sqliteClient.getDb();
 | 
			
		||||
    
 | 
			
		||||
    if (!user || !user.uid) {
 | 
			
		||||
        throw new Error('User object and uid are required');
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    const { uid, displayName, email } = user;
 | 
			
		||||
    const now = Math.floor(Date.now() / 1000);
 | 
			
		||||
    
 | 
			
		||||
    // Validate inputs
 | 
			
		||||
    const safeDisplayName = displayName || 'User';
 | 
			
		||||
    const safeEmail = email || 'no-email@example.com';
 | 
			
		||||
 | 
			
		||||
    const query = `
 | 
			
		||||
        INSERT INTO users (uid, display_name, email, created_at)
 | 
			
		||||
@ -14,11 +23,15 @@ function findOrCreate(user) {
 | 
			
		||||
    `;
 | 
			
		||||
    
 | 
			
		||||
    try {
 | 
			
		||||
        db.prepare(query).run(uid, displayName, email, now);
 | 
			
		||||
        return getById(uid);
 | 
			
		||||
        console.log('[SQLite] Creating/updating user:', { uid, displayName: safeDisplayName, email: safeEmail });
 | 
			
		||||
        db.prepare(query).run(uid, safeDisplayName, safeEmail, now);
 | 
			
		||||
        const result = getById(uid);
 | 
			
		||||
        console.log('[SQLite] User operation successful:', result);
 | 
			
		||||
        return result;
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
        console.error('SQLite: Failed to find or create user:', err);
 | 
			
		||||
        throw err;
 | 
			
		||||
        console.error('SQLite: User data:', { uid, displayName: safeDisplayName, email: safeEmail });
 | 
			
		||||
        throw new Error(`Failed to create user in database: ${err.message}`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										70
									
								
								src/index.js
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								src/index.js
									
									
									
									
									
								
							@ -61,28 +61,28 @@ function setupProtocolHandling() {
 | 
			
		||||
        
 | 
			
		||||
        let protocolUrl = null;
 | 
			
		||||
        
 | 
			
		||||
        if (process.platform === 'win32') {
 | 
			
		||||
            // Windows
 | 
			
		||||
            const lastArg = commandLine.length > 0 ? commandLine[commandLine.length - 1] : null;
 | 
			
		||||
            if (lastArg && 
 | 
			
		||||
                typeof lastArg === 'string' && 
 | 
			
		||||
                lastArg.startsWith('pickleglass://') && 
 | 
			
		||||
                !lastArg.includes('\\') && 
 | 
			
		||||
                !lastArg.includes('₩')) {
 | 
			
		||||
                protocolUrl = lastArg;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            // Linux or etc
 | 
			
		||||
            const lastArg = commandLine.length > 0 ? commandLine[commandLine.length - 1] : null;
 | 
			
		||||
            if (lastArg && 
 | 
			
		||||
                typeof lastArg === 'string' && 
 | 
			
		||||
                lastArg.startsWith('pickleglass://')) {
 | 
			
		||||
                protocolUrl = lastArg;
 | 
			
		||||
        // Search through all command line arguments for a valid protocol URL
 | 
			
		||||
        for (const arg of commandLine) {
 | 
			
		||||
            if (arg && typeof arg === 'string' && arg.startsWith('pickleglass://')) {
 | 
			
		||||
                // Clean up the URL by removing problematic characters
 | 
			
		||||
                const cleanUrl = arg.replace(/[\\₩]/g, '');
 | 
			
		||||
                
 | 
			
		||||
                // Additional validation for Windows
 | 
			
		||||
                if (process.platform === 'win32') {
 | 
			
		||||
                    // On Windows, ensure the URL doesn't contain file path indicators
 | 
			
		||||
                    if (!cleanUrl.includes(':') || cleanUrl.indexOf('://') === cleanUrl.lastIndexOf(':')) {
 | 
			
		||||
                        protocolUrl = cleanUrl;
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    protocolUrl = cleanUrl;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (protocolUrl) {
 | 
			
		||||
            console.log('[Protocol] Valid URL found from second instance (last arg):', protocolUrl);
 | 
			
		||||
            console.log('[Protocol] Valid URL found from second instance:', protocolUrl);
 | 
			
		||||
            handleCustomUrl(protocolUrl);
 | 
			
		||||
        } else {
 | 
			
		||||
            console.log('[Protocol] No valid protocol URL found in command line arguments');
 | 
			
		||||
@ -135,16 +135,17 @@ function focusMainWindow() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (process.platform === 'win32') {
 | 
			
		||||
    const lastArg = process.argv.length > 0 ? process.argv[process.argv.length - 1] : null;
 | 
			
		||||
    
 | 
			
		||||
    if (lastArg && 
 | 
			
		||||
        typeof lastArg === 'string' && 
 | 
			
		||||
        lastArg.startsWith('pickleglass://') && 
 | 
			
		||||
        !lastArg.includes('\\') && 
 | 
			
		||||
        !lastArg.includes('₩')) {
 | 
			
		||||
        
 | 
			
		||||
        console.log('[Protocol] Found protocol URL in initial arguments (last arg):', lastArg);
 | 
			
		||||
        pendingDeepLinkUrl = lastArg;
 | 
			
		||||
    for (const arg of process.argv) {
 | 
			
		||||
        if (arg && typeof arg === 'string' && arg.startsWith('pickleglass://')) {
 | 
			
		||||
            // Clean up the URL by removing problematic characters (korean characters issue...)
 | 
			
		||||
            const cleanUrl = arg.replace(/[\\₩]/g, '');
 | 
			
		||||
            
 | 
			
		||||
            if (!cleanUrl.includes(':') || cleanUrl.indexOf('://') === cleanUrl.lastIndexOf(':')) {
 | 
			
		||||
                console.log('[Protocol] Found protocol URL in initial arguments:', cleanUrl);
 | 
			
		||||
                pendingDeepLinkUrl = cleanUrl;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    console.log('[Protocol] Initial process.argv:', process.argv);
 | 
			
		||||
@ -376,16 +377,19 @@ async function handleCustomUrl(url) {
 | 
			
		||||
    try {
 | 
			
		||||
        console.log('[Custom URL] Processing URL:', url);
 | 
			
		||||
        
 | 
			
		||||
        // val url
 | 
			
		||||
        // Validate and clean URL
 | 
			
		||||
        if (!url || typeof url !== 'string' || !url.startsWith('pickleglass://')) {
 | 
			
		||||
            console.error('[Custom URL] Invalid URL format:', url);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // val url
 | 
			
		||||
        if (url.includes('\\') || url.includes('₩')) {
 | 
			
		||||
            console.error('[Custom URL] URL contains invalid path characters:', url);
 | 
			
		||||
            return;
 | 
			
		||||
        // Clean up URL by removing problematic characters
 | 
			
		||||
        const cleanUrl = url.replace(/[\\₩]/g, '');
 | 
			
		||||
        
 | 
			
		||||
        // Additional validation
 | 
			
		||||
        if (cleanUrl !== url) {
 | 
			
		||||
            console.log('[Custom URL] Cleaned URL from:', url, 'to:', cleanUrl);
 | 
			
		||||
            url = cleanUrl;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        const urlObj = new URL(url);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user