From 290ba7261797d6fd46db9747a176aea3e38ef859 Mon Sep 17 00:00:00 2001 From: abose Date: Tue, 7 Oct 2025 20:25:13 +0530 Subject: [PATCH 1/5] docs: update how to run local server enpoint in browser --- src/services/readme-login-browser-no_dist.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/services/readme-login-browser-no_dist.md b/src/services/readme-login-browser-no_dist.md index f9b684c652..f9e9ee7928 100644 --- a/src/services/readme-login-browser-no_dist.md +++ b/src/services/readme-login-browser-no_dist.md @@ -99,9 +99,7 @@ function _getAccountBaseURL() { For testing with a local account server instance: 1. **Configure Proxy Server:** - - Edit `serve-proxy.js` - - **Comment out:** `const ACCOUNT_SERVER = 'https://account.phcode.dev'; // Production` - - **Uncomment:** `const ACCOUNT_SERVER = 'http://localhost:5000'; // Local development` + - use `npm run serveLocalAccount` to serve phoenix repo server, instead of using npm run serve command. 2. **Setup Local Account Server:** - Start your local account development stack on `localhost:5000` From 440e4d22f5df8401925ae03b9b7d2da18a622e2d Mon Sep 17 00:00:00 2001 From: abose Date: Wed, 8 Oct 2025 14:46:10 +0530 Subject: [PATCH 2/5] chore: desktop app accounts communication via accounts proxy --- serve-proxy.js | 24 ++++++++++++++++---- src/services/login-desktop.js | 22 +++++++++++++----- src/services/manage-licenses.js | 3 +++ src/services/readme-login-desktop-no_dist.md | 7 +++--- 4 files changed, 42 insertions(+), 14 deletions(-) diff --git a/serve-proxy.js b/serve-proxy.js index b2323667fc..5afa996468 100644 --- a/serve-proxy.js +++ b/serve-proxy.js @@ -7,8 +7,12 @@ const path = require('path'); const fs = require('fs'); const httpProxy = require('http-proxy'); +const ACCOUNT_PROD = 'https://account.phcode.dev'; +const ACCOUNT_STAGING = 'https://account-stage.phcode.dev'; +const ACCOUNT_DEV = 'http://localhost:5000'; + // Account server configuration - switch between local and production -let accountServer = 'https://account.phcode.dev'; // Production +let accountServer = ACCOUNT_PROD; // Production // Set to local development server if --localAccount flag is provided // Default configuration @@ -24,6 +28,8 @@ let config = { // Parse command line arguments function parseArgs() { const args = process.argv.slice(2); + let hasLocalAccount = false; + let hasStagingAccount = false; for (let i = 0; i < args.length; i++) { const arg = args[i]; @@ -46,11 +52,21 @@ function parseArgs() { } else if (arg === '--log-ip') { config.logIp = true; } else if (arg === '--localAccount') { - accountServer = 'http://localhost:5000'; + hasLocalAccount = true; + accountServer = ACCOUNT_DEV; + } else if (arg === '--stagingAccount') { + hasStagingAccount = true; + accountServer = ACCOUNT_STAGING; } else if (!arg.startsWith('-')) { config.root = path.resolve(arg); } } + + // Check for mutually exclusive flags + if (hasLocalAccount && hasStagingAccount) { + console.error('Error: --localAccount and --stagingAccount cannot be used together'); + process.exit(1); + } } // Create proxy server @@ -81,7 +97,7 @@ proxy.on('proxyReq', (proxyReq, req) => { // Transform referer from localhost:8000 to phcode.dev if (originalReferer && originalReferer.includes('localhost:8000')) { - const newReferer = originalReferer.replace(/localhost:8000/g, 'phcode.dev'); + const newReferer = originalReferer.replace(/http:\/\/localhost:8000/g, 'https://phcode.dev'); proxyReq.setHeader('Referer', newReferer); } else if (!originalReferer) { proxyReq.setHeader('Referer', 'https://phcode.dev/'); @@ -89,7 +105,7 @@ proxy.on('proxyReq', (proxyReq, req) => { // Transform origin from localhost:8000 to phcode.dev if (originalOrigin && originalOrigin.includes('localhost:8000')) { - const newOrigin = originalOrigin.replace(/localhost:8000/g, 'phcode.dev'); + const newOrigin = originalOrigin.replace(/http:\/\/localhost:8000/g, 'https://phcode.dev'); proxyReq.setHeader('Origin', newOrigin); } diff --git a/src/services/login-desktop.js b/src/services/login-desktop.js index e7058654e6..251fff301e 100644 --- a/src/services/login-desktop.js +++ b/src/services/login-desktop.js @@ -80,9 +80,19 @@ define(function (require, exports, module) { * For desktop apps, this directly uses the configured account URL */ function getAccountBaseURL() { + if (location.hostname === 'localhost' || location.hostname === '127.0.0.1') { + return '/proxy/accounts'; + } return Phoenix.config.account_url.replace(/\/$/, ''); // Remove trailing slash } + /** + * Get the account website URL for opening browser tabs + */ + function _getAccountWebURL() { + return Phoenix.config.account_url; + } + const ERR_RETRY_LATER = "retry_later"; const ERR_INVALID = "invalid"; @@ -96,7 +106,7 @@ define(function (require, exports, module) { * never rejects. */ async function _resolveAPIKey(apiKey, validationCode) { - const resolveURL = `${Phoenix.config.account_url}resolveAppSessionID?appSessionID=${apiKey}&validationCode=${validationCode}`; + const resolveURL = `${getAccountBaseURL()}/resolveAppSessionID?appSessionID=${apiKey}&validationCode=${validationCode}`; if (!navigator.onLine) { return {err: ERR_RETRY_LATER}; } @@ -196,7 +206,7 @@ define(function (require, exports, module) { const authPortURL = _getAutoAuthPortURL(); const platformStr = PLATFORM_STRINGS[Phoenix.platform] || Phoenix.platform; const appName = encodeURIComponent(`${Strings.APP_NAME} Desktop on ${platformStr}`); - const resolveURL = `${Phoenix.config.account_url}getAppAuthSession?autoAuthPort=${authPortURL}&appName=${appName}`; + const resolveURL = `${getAccountBaseURL()}/getAppAuthSession?autoAuthPort=${authPortURL}&appName=${appName}`; // {"isSuccess":true,"appSessionID":"a uuid...","validationCode":"SWXP07"} try { if(Phoenix.isTestWindow && fetchFn === fetch){ @@ -254,7 +264,7 @@ define(function (require, exports, module) { } const {appSessionID, validationCode} = appAuthSession; await setAutoVerificationCode(validationCode); - const appSignInURL = `${Phoenix.config.account_url}authorizeApp?appSessionID=${appSessionID}`; + const appSignInURL = `${_getAccountWebURL()}authorizeApp?appSessionID=${appSessionID}`; // Show dialog with validation code const dialogData = { @@ -350,7 +360,7 @@ define(function (require, exports, module) { } async function signOutAccount() { - const resolveURL = `${Phoenix.config.account_url}logoutSession`; + const resolveURL = `${getAccountBaseURL()}/logoutSession`; try { let input = { appSessionID: userProfile.apiKey @@ -378,7 +388,7 @@ define(function (require, exports, module) { Strings.SIGNED_OUT_FAILED_MESSAGE ); dialog.done(() => { - NativeApp.openURLInDefaultBrowser(Phoenix.config.account_url + "#advanced"); + NativeApp.openURLInDefaultBrowser(_getAccountWebURL() + "#advanced"); }); Metrics.countEvent(Metrics.EVENT_TYPE.AUTH, 'logoutFail', Phoenix.platform); return; @@ -399,7 +409,7 @@ define(function (require, exports, module) { Strings.SIGNED_OUT_FAILED_MESSAGE ); dialog.done(() => { - NativeApp.openURLInDefaultBrowser(Phoenix.config.account_url + "#advanced"); + NativeApp.openURLInDefaultBrowser(_getAccountWebURL() + "#advanced"); }); Metrics.countEvent(Metrics.EVENT_TYPE.AUTH, 'getAppAuth', Phoenix.platform); logger.reportError(error, "Failed to call logout calling" + resolveURL); diff --git a/src/services/manage-licenses.js b/src/services/manage-licenses.js index 9d8e4cec86..1c67aa0146 100644 --- a/src/services/manage-licenses.js +++ b/src/services/manage-licenses.js @@ -44,6 +44,9 @@ define(function (require, exports, module) { * Get the API base URL for license operations */ function _getAPIBaseURL() { + if (location.hostname === 'localhost' || location.hostname === '127.0.0.1') { + return '/proxy/accounts'; + } return Phoenix.config.account_url.replace(/\/$/, ''); // Remove trailing slash } diff --git a/src/services/readme-login-desktop-no_dist.md b/src/services/readme-login-desktop-no_dist.md index 1e7ee1cc23..33fbfc96bf 100644 --- a/src/services/readme-login-desktop-no_dist.md +++ b/src/services/readme-login-desktop-no_dist.md @@ -241,9 +241,8 @@ pref.on('change', _verifyLogin); For testing desktop authentication with a local account server: -1. **Configure Account URL:** - - Edit `src/config.json` - - Change `account_url` from `https://account.phcode.dev/` to `http://localhost:5000/` (or your local server URL) +1. **Configure Proxy Server:** + - use `npm run serveLocalAccount` to serve phoenix repo server, instead of using npm run serve command. 2. **Rebuild Application:** ```bash @@ -326,4 +325,4 @@ if(resolveResponse.userDetails) { For desktop implementation details, see the source code in `src/services/login-desktop.js`. For browser authentication, see `src/services/login-browser.js` and `readme-login-browser-no_dist.md`. -For deeper understanding of the Kernel Mode Trust security architecture and secure credential storage implementation, refer to the Kernel Mode Trust source files (out of scope for this document). \ No newline at end of file +For deeper understanding of the Kernel Mode Trust security architecture and secure credential storage implementation, refer to the Kernel Mode Trust source files (out of scope for this document). From 6b42f3a0d9acedb495c79531387ffa36b49417cc Mon Sep 17 00:00:00 2001 From: abose Date: Wed, 8 Oct 2025 14:56:20 +0530 Subject: [PATCH 3/5] chore: npm run serveStagingAccount impl --- package.json | 1 + src/services/readme-login-browser-no_dist.md | 7 +++++-- src/services/readme-login-desktop-no_dist.md | 21 +++++++++----------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index b6f8f6eecc..c1fd82627e 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "_majorVersionBump": "gulp majorVersionBump", "serve": "node serve-proxy.js . -p 8000 -c-1", "serveLocalAccount": "node serve-proxy.js . -p 8000 -c-1 --localAccount", + "serveStagingAccount": "node serve-proxy.js . -p 8000 -c-1 --stagingAccount", "_serveWithWebCacheHelp": "echo !!!Make sure to npm run release:dev/stageing/prod before testing the cache!!!", "serveWithWebCache": "npm run _releaseWebCache && npm run _serveWithWebCacheHelp && http-server ./dist -p 8000 -c-1", "serveExternal": "node serve-proxy.js . -p 8000 -a 0.0.0.0 --log-ip -c-1", diff --git a/src/services/readme-login-browser-no_dist.md b/src/services/readme-login-browser-no_dist.md index f9e9ee7928..837dc4b2b3 100644 --- a/src/services/readme-login-browser-no_dist.md +++ b/src/services/readme-login-browser-no_dist.md @@ -100,6 +100,7 @@ For testing with a local account server instance: 1. **Configure Proxy Server:** - use `npm run serveLocalAccount` to serve phoenix repo server, instead of using npm run serve command. + - use `npm run serveStagingAccount` to use the staging endpoint. To get access to staging server, contact team. 2. **Setup Local Account Server:** - Start your local account development stack on `localhost:5000` @@ -109,10 +110,12 @@ Now just visit login server at `http://localhost:5000` and login. It should work at https://localhost:8000/src when you run phoenix code dev server via `npm run serve`. This works without any manual cookie copy needed as the dev server sets cookies localhost wide. But if that didnt work, please see manual cookie copy instructions below. + +For staging server at https://account-stage.phcode.dev , you may need to copy cookie manually like below: 1. **Login and Copy Session:** - - Navigate to `http://localhost:5000` in browser - - Login with test credentials + - Navigate to `http://localhost:5000` in browser. (if staging, use https://account-stage.phcode.dev) + - Login with your credentials - Copy `session` cookie value from DevTools 2. **Set Cookie in Phoenix App:** diff --git a/src/services/readme-login-desktop-no_dist.md b/src/services/readme-login-desktop-no_dist.md index 33fbfc96bf..97673f1197 100644 --- a/src/services/readme-login-desktop-no_dist.md +++ b/src/services/readme-login-desktop-no_dist.md @@ -243,22 +243,19 @@ For testing desktop authentication with a local account server: 1. **Configure Proxy Server:** - use `npm run serveLocalAccount` to serve phoenix repo server, instead of using npm run serve command. + - use `npm run serveStagingAccount` to use the staging endpoint. To get access to staging server, contact team. -2. **Rebuild Application:** - ```bash - npm run build - ``` - -3. **Start Your Local Account Server:** - - Ensure your local account server is running on the configured port (e.g., localhost:5000) - - Verify all authentication endpoints are properly configured +2. **Setup Local Account Server:** + - Start your local account development stack on `localhost:5000` + - Ensure all login endpoints are properly configured -4. **Test Desktop Authentication:** - - Desktop app will now use your local server for all authentication calls - - Verification codes and API key resolution will go through your local server +3. **Test Desktop Authentication:** + - Desktop app will now use your local/staging server for all authentication calls + - Verification codes and API key resolution will go through your local/staging server - Auto-verification will attempt to connect to your local account service -**Note:** Unlike browser testing which requires proxy server configuration, desktop apps simply use the `account_url` directly from config.json. +**Note:** Like browser testing which requires proxy server configuration, desktop apps also use the proxy server +for communication with backend. ## Troubleshooting From cb7992d154bd907cf8ac48e65329aff06b6a1435 Mon Sep 17 00:00:00 2001 From: abose Date: Wed, 8 Oct 2025 15:32:50 +0530 Subject: [PATCH 4/5] chore: dynamic proxy config comunicates acount server url to use for phoenix local dev --- serve-proxy.js | 25 +++++++++++++++++++++++++ src/brackets.config.staging.json | 3 ++- src/index.html | 17 ++++++++++++++++- src/utils/Global.js | 5 ++--- test/SpecRunner.html | 1 + 5 files changed, 46 insertions(+), 5 deletions(-) diff --git a/serve-proxy.js b/serve-proxy.js index 5afa996468..75430df8f4 100644 --- a/serve-proxy.js +++ b/serve-proxy.js @@ -270,6 +270,31 @@ const server = http.createServer((req, res) => { return; } + // Handle proxy config request + if (parsedUrl.pathname === '/proxy/config') { + const configResponse = { + accountURL: accountServer + '/' + }; + + if (!config.silent) { + console.log(`[CONFIG] ${req.method} ${parsedUrl.pathname} -> ${JSON.stringify(configResponse)}`); + } + + const headers = { + 'Content-Type': 'application/json' + }; + + if (config.cors) { + headers['Access-Control-Allow-Origin'] = '*'; + headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'; + headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization, Cache-Control'; + } + + res.writeHead(200, headers); + res.end(JSON.stringify(configResponse)); + return; + } + // Check if this is a proxy request if (parsedUrl.pathname.startsWith('/proxy/accounts')) { // Extract the path after /proxy/accounts diff --git a/src/brackets.config.staging.json b/src/brackets.config.staging.json index 6ba54f9810..68fd51439d 100644 --- a/src/brackets.config.staging.json +++ b/src/brackets.config.staging.json @@ -10,5 +10,6 @@ "bugsnagEnv" : "staging", "app_notification_url" : "https://updates.phcode.io/appNotifications/staging/", "app_update_url" : "https://updates.phcode.io/tauri/update-latest-pre-release.json", - "promotions_url" : "https://promotions.phcode.dev/dev/" + "promotions_url" : "https://promotions.phcode.dev/dev/", + "account_url" : "https://account-stage.phcode.dev/" } diff --git a/src/index.html b/src/index.html index 13f8831710..830fa6a5e5 100644 --- a/src/index.html +++ b/src/index.html @@ -446,7 +446,22 @@ loadJS('verify-dependencies-loaded.js', null, document.body); } - function _startRequireLoop() { + async function _startRequireLoop() { + // If running on localhost, fetch proxy config to get dynamic account URL + if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') { + try { + const response = await fetch('/proxy/config'); + if (response.ok) { + const config = await response.json(); + if (config.accountURL) { + window.AppConfig.config.account_url = config.accountURL; + console.log('Applied dynamic account URL from proxy:', config.accountURL); + } + } + } catch (error) { + console.warn('Failed to fetch proxy config, using default account URL:', error); + } + } loadJS('thirdparty/requirejs/require.js', _requireDone, document.body, "main"); } if(window.PhStore){ diff --git a/src/utils/Global.js b/src/utils/Global.js index ba44641e52..e4fb5ed120 100644 --- a/src/utils/Global.js +++ b/src/utils/Global.js @@ -28,8 +28,7 @@ define(function (require, exports, module) { - var configJSON = require("text!config.json"), - UrlParams = require("utils/UrlParams").UrlParams; + const UrlParams = require("utils/UrlParams").UrlParams; // Define core brackets namespace if it isn't already defined // @@ -57,7 +56,7 @@ define(function (require, exports, module) { // Parse src/config.json try { - global.brackets.metadata = JSON.parse(configJSON); + global.brackets.metadata = window.AppConfig; global.brackets.config = global.brackets.metadata.config; } catch (err) { console.log(err); diff --git a/test/SpecRunner.html b/test/SpecRunner.html index feaaf3ecd2..e4c2d73356 100644 --- a/test/SpecRunner.html +++ b/test/SpecRunner.html @@ -148,6 +148,7 @@ +