/* * Test Module: API Key & User Isolation * Tests scenarios 1 and 2 */ 'use strict'; const utils = require('../utils.js').LinkdingSyncTests; const SCENARIO_NAME = 'API Key & User Isolation Tests'; // Helper to create a test bookmark with work API key async function createWorkBookmark(url, options) { utils.SessionManager.setContext( CONFIG.serverUrl, CONFIG.workApiKey, CONFIG.workUser, CONFIG.workBundle ); return utils.Helpers.createBookmark(url, options); } // Helper to create a test bookmark with personal API key async function createPersonalBookmark(url, options) { utils.SessionManager.setContext( CONFIG.serverUrl, CONFIG.personalApiKey, CONFIG.personalUser, CONFIG.personalBundle ); return utils.Helpers.createBookmark(url, options); } // Helper to fetch with work API key async function fetchWork(id) { utils.SessionManager.setContext( CONFIG.serverUrl, CONFIG.workApiKey, CONFIG.workUser, CONFIG.workBundle ); return utils.Helpers.fetchBookmark(id); } // Helper to fetch with personal API key async function fetchPersonal(id) { utils.SessionManager.setContext( CONFIG.serverUrl, CONFIG.personalApiKey, CONFIG.personalUser, CONFIG.personalBundle ); return utils.Helpers.fetchBookmark(id); } // Helper to list with personal API key async function listPersonal(queryParams = {}) { utils.SessionManager.setContext( CONFIG.serverUrl, CONFIG.personalApiKey, CONFIG.personalUser, CONFIG.personalBundle ); return utils.SessionManager.call('/api/bookmarks/', 'GET', queryParams); } // Test 1: Same URL, Different API Keys, Same User async function test1_SameUserDifferentKeys() { console.log('\n=== Test 1: Same URL, Different API Keys, Same User ==='); console.log('Purpose: Verify if API keys provide isolation within same user'); try { // Create with work key const bm1 = await createWorkBookmark('https://isolation-test.example.com', { title: 'Isolation Test - Work Key' }); // Create same URL with personal key const bm2 = await createPersonalBookmark('https://isolation-test.example.com', { title: 'Isolation Test - Personal Key' }); console.log(` Work bookmark ID: ${bm1.id}`); console.log(` Personal bookmark ID: ${bm2.id}`); if (bm1.id === bm2.id) { utils.Formatters.consoleResult('Test 1', 'FAIL', 'Same bookmark ID - API keys do NOT provide isolation'); console.log(' → Same user means same bookmarks regardless of API key'); return { pass: false, reason: 'API keys do not provide isolation within same user' }; } else { utils.Formatters.consoleResult('Test 1', 'PASS', 'Different bookmark IDs - API keys provide isolation'); console.log(' → Different API keys create separate bookmarks'); return { pass: true, ids: { work: bm1.id, personal: bm2.id } }; } } catch (error) { utils.Formatters.consoleResult('Test 1', 'FAIL', error.message); throw error; } } // Test 2: Different Users - Verify isolation async function test2_DifferentUsers() { console.log('\n=== Test 2: Different Users - Verify Isolation ==='); console.log('Purpose: Verify isolation between different users'); try { // Create bookmark as work user const workUrl = 'https://cross-user-isolation.example.com'; const workBookmark = await createWorkBookmark(workUrl, { title: 'Cross-User Test - Work' }); console.log(` Bookmark created by work user: ID=${workBookmark.id}`); // Work user sees their own bookmark const workFetch = await fetchWork(workBookmark.id); console.log(` Work user sees bookmark: ${workFetch.title}`); // Personal user queries for the test bookmark utils.SessionManager.setContext( CONFIG.serverUrl, CONFIG.personalApiKey, CONFIG.personalUser, CONFIG.personalBundle ); const personalFetch = await listPersonal({ limit: 100 }); console.log(` Personal user sees ${personalFetch.count || personalFetch.results?.length || 0} bookmarks`); if (personalFetch.results && personalFetch.results.length > 0) { utils.Formatters.consoleResult('Test 2', 'FAIL', 'Users can see each other\'s bookmarks'); console.log(' → Sharing enabled or same underlying user'); return { pass: false, reason: 'Users can see each other\'s bookmarks (sharing or same user)' }; } else { utils.Formatters.consoleResult('Test 2', 'PASS', 'Proper user isolation exists'); console.log(' → Can use different API keys for isolation'); return { pass: true }; } } catch (error) { utils.Formatters.consoleResult('Test 2', 'FAIL', error.message); throw error; } } // Run all tests async function runIsolationTests() { console.log('\n' + '='.repeat(60)); console.log(' ' + SCENARIO_NAME); console.log('='.repeat(60)); const results = []; try { results[0] = await test1_SameUserDifferentKeys(); results[1] = await test2_DifferentUsers(); } catch (error) { console.error('Test suite error:', error.message); utils.Helpers.resetBookmarks(); } console.log('\n' + '='.repeat(60)); console.log(' Isolation Tests Complete'); console.log('='.repeat(60)); return results; } // Export window.LinkdingSyncTests.TestIsolation = { run: runIsolationTests, test1: test1_SameUserDifferentKeys, test2: test2_DifferentUsers };