| … | … | @@ -13,9 +13,8 @@ const fs = require('bare-fs') |
| 13 | 13 | const path = require('bare-path') |
| 14 | 14 | const os = require('bare-os') |
| 15 | 15 | |
| 16 | | // Check if running under Pear |
| 16 | // Check if running under Pear (legacy path) |
| 17 | 17 | const isPear = typeof Pear !== 'undefined' |
| 18 | | let appDrive = null |
| 19 | 18 | |
| 20 | 19 | const { |
| 21 | 20 | initializeStorage, |
| … | … | @@ -226,7 +225,7 @@ const PORT = parseInt(process.env.PORT || config.server?.port || 4004) |
| 226 | 225 | const HOST = process.env.WALLET_HOST || config.server?.host || 'localhost' |
| 227 | 226 | // Use process.cwd() instead of __dirname for Pear compatibility |
| 228 | 227 | // Pear sets cwd to the app bundle directory, but __dirname is empty |
| 229 | | const UI_DIR = path.join(process.cwd(), 'ui') |
| 228 | const UI_DIR = path.join(__dirname, 'ui') |
| 230 | 229 | |
| 231 | 230 | // Track pending device add sessions |
| 232 | 231 | // Map<sessionId, { inviteCode, status, deviceName, error }> |
| … | … | @@ -318,10 +317,7 @@ const ALLOWED_ORIGINS = [ |
| 318 | 317 | // 'https://your-production-domain.com' |
| 319 | 318 | ] |
| 320 | 319 | |
| 321 | | // If running under Pear, add the Pear protocol origin |
| 322 | | if (isPear && typeof Pear !== 'undefined' && Pear.config?.key) { |
| 323 | | ALLOWED_ORIGINS.push(`pear://${Pear.config.key}`) |
| 324 | | } |
| 320 | // pear:// CORS origin no longer needed — apps run locally |
| 325 | 321 | |
| 326 | 322 | /** |
| 327 | 323 | * Set CORS headers with origin whitelist |
| … | … | @@ -1839,44 +1835,23 @@ const mimeTypes = { |
| 1839 | 1835 | '.svg': 'image/svg+xml' |
| 1840 | 1836 | } |
| 1841 | 1837 | |
| 1842 | | // Serve static files |
| 1838 | // Serve static files from local filesystem |
| 1843 | 1839 | async function serveStatic(req, res) { |
| 1844 | 1840 | const fileName = req.url === '/' ? 'index.html' : req.url.substring(1) |
| 1845 | 1841 | |
| 1846 | 1842 | try { |
| 1847 | 1843 | let content |
| 1848 | 1844 | |
| 1849 | | if (appDrive) { |
| 1850 | | // Running from pear:// - read from app bundle using pear-appdrive |
| 1851 | | const bundlePath = '/ui/' + fileName |
| 1852 | | console.log(`[STATIC] Reading from Pear bundle: ${bundlePath}`) |
| 1853 | | content = await appDrive.get(bundlePath) |
| 1845 | const filePath = path.join(UI_DIR, fileName) |
| 1854 | 1846 | |
| 1855 | | if (!content) { |
| 1856 | | console.error(`[STATIC] File not found in bundle: ${bundlePath}`) |
| 1857 | | res.statusCode = 404 |
| 1858 | | res.end('Not found') |
| 1859 | | return |
| 1860 | | } |
| 1861 | | } else { |
| 1862 | | // Local development - read from filesystem |
| 1863 | | const filePath = path.join(UI_DIR, fileName) |
| 1864 | | |
| 1865 | | // Security: prevent directory traversal |
| 1866 | | if (!filePath.startsWith(UI_DIR)) { |
| 1867 | | console.error(`Security error: ${filePath} is outside ${UI_DIR}`) |
| 1868 | | res.statusCode = 403 |
| 1869 | | res.end('Forbidden') |
| 1870 | | return |
| 1871 | | } |
| 1847 | // Security: prevent directory traversal |
| 1848 | if (!filePath.startsWith(UI_DIR)) { |
| 1849 | res.statusCode = 403 |
| 1850 | res.end('Forbidden') |
| 1851 | return |
| 1852 | } |
| 1872 | 1853 | |
| 1873 | | // Check if file exists |
| 1874 | | if (!fs.existsSync(filePath)) { |
| 1875 | | console.error(`File not found: ${filePath}`) |
| 1876 | | console.error(` UI_DIR: ${UI_DIR}`) |
| 1877 | | console.error(` __dirname: ${__dirname}`) |
| 1878 | | console.error(` process.cwd(): ${process.cwd()}`) |
| 1879 | | console.error(` Requested URL: ${req.url}`) |
| 1854 | if (!fs.existsSync(filePath)) { |
| 1880 | 1855 | |
| 1881 | 1856 | res.statusCode = 404 |
| 1882 | 1857 | res.end('Not found') |
| … | … | @@ -1903,22 +1878,8 @@ async function serveStatic(req, res) { |
| 1903 | 1878 | // Server instance (created in startServer function) |
| 1904 | 1879 | let server = null |
| 1905 | 1880 | |
| 1906 | | // Start server function (wrapping prevents Pear port remapping) |
| 1881 | // Start server function |
| 1907 | 1882 | async function startServer() { |
| 1908 | | // Initialize Pear appDrive for reading bundled UI files |
| 1909 | | if (isPear && !appDrive) { |
| 1910 | | try { |
| 1911 | | // Use dynamic import for ESM module in CommonJS |
| 1912 | | const AppDriveModule = await import('pear-appdrive') |
| 1913 | | const AppDrive = AppDriveModule.default || AppDriveModule |
| 1914 | | appDrive = new AppDrive() |
| 1915 | | await appDrive.ready() |
| 1916 | | console.log('[DEBUG] pear-appdrive initialized - can read bundled UI files') |
| 1917 | | } catch (err) { |
| 1918 | | console.error('[DEBUG] pear-appdrive failed:', err.message) |
| 1919 | | console.error(' UI files will be served from filesystem (may fail in Pear)') |
| 1920 | | } |
| 1921 | | } |
| 1922 | 1883 | |
| 1923 | 1884 | // Main HTTP server |
| 1924 | 1885 | server = http.createServer(async (req, res) => { |