From 6a4beaafd101a9348948572fe5bf094842a7a29e Mon Sep 17 00:00:00 2001 From: leotrinh Date: Thu, 5 Mar 2026 15:33:02 +0700 Subject: [PATCH 1/3] bug: fixed set api endpoint failed --- CHANGELOG.md | 24 +++++++++ MIGRATION_GUIDE.md | 21 ++++++++ README.md | 15 +++++- RELEASE_NOTES.md | 52 +++++++++++++++++++ docs/Usage.md | 10 ++++ examples/cf-service-usage-example.js | 16 ++++++ index.js | 2 +- lib/model/cloudcontroller/CloudController.js | 53 ++++++++++++++++++-- package.json | 2 +- test/lib/ApiMigrationTests.js | 10 ++-- types/index.d.ts | 4 +- 11 files changed, 195 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2eb1a7..481f0e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ +## Version 1.0.4 2026-03-05 + +**HOTFIX RELEASE — Critical: v3 Authentication Flow Broken** + +### Bug Fixes (Critical) +- **`getInfo()` v3 mode called non-existent `/v3/info`**: CF API v3 has no `/v3/info` endpoint. Changed to root endpoint `/` which returns `{ links: { uaa, login, ... } }`. Response is normalized to include `authorization_endpoint` and `token_endpoint` at top level for backward compatibility with all existing consumer code. +- **`authorization_endpoint` was `undefined` in v3 mode**: The standard auth flow `info.authorization_endpoint → usersUAA.setEndPoint()` was completely broken for all v1.0.0+ users using default v3. + +### New Features +- **`CloudController.getAuthorizationEndpoint()`**: Convenience method that returns UAA endpoint URL directly. Works with both v2 and v3, abstracts away response shape differences. + +### TypeScript +- Added `getAuthorizationEndpoint(): Promise` to `CloudController` type declarations + +### Files Modified +- `lib/model/cloudcontroller/CloudController.js` +- `types/index.d.ts` +- `examples/cf-service-usage-example.js` + +### Tests +- All **93 passing**, 0 failing + +--- + ## Version 1.0.3 2026-03-05 **PATCH RELEASE — Code Quality Fixes & JSDoc Documentation** diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index 54ba4a0..bbddf5f 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -1,5 +1,26 @@ # Migration Guide: cf-nodejs-client → cf-node-client v1.0.0 +## Important: v1.0.4 Hotfix — Authentication Flow + +If you upgraded to v1.0.0–v1.0.3 and hit the error: +``` +Invalid endpoint URL: "undefined". Must be a valid http:// or https:// URL. +``` + +**Upgrade to v1.0.4** — this fixes `getInfo()` in v3 mode. The standard auth pattern now works correctly: + +```javascript +// This works in v1.0.4+ (both v2 and v3): +const info = await cfController.getInfo(); +usersUAA.setEndPoint(info.authorization_endpoint); // ✅ No longer undefined + +// Or use the new convenience method (recommended): +const authEndpoint = await cfController.getAuthorizationEndpoint(); +usersUAA.setEndPoint(authEndpoint); +``` + +--- + ## Overview The cf-nodejs-client package has been renamed to `cf-node-client` and upgraded to version 1.0.0 with full Cloud Foundry API v3 support. diff --git a/README.md b/README.md index 94d23c7..81f97c3 100644 --- a/README.md +++ b/README.md @@ -107,9 +107,16 @@ npm install cf-node-client ```javascript const { CloudController, UsersUAA, Apps } = require("cf-node-client"); -const uaa = new UsersUAA("https://login."); +// Step 1: Get UAA endpoint from Cloud Controller +const cc = new CloudController("https://api."); +const authEndpoint = await cc.getAuthorizationEndpoint(); + +// Step 2: Authenticate +const uaa = new UsersUAA(); +uaa.setEndPoint(authEndpoint); const token = await uaa.login("user", "pass"); +// Step 3: Use the token const apps = new Apps("https://api."); apps.setToken(token); const result = await apps.getApps(); @@ -128,7 +135,11 @@ import { OAuthToken } from "cf-node-client"; -const uaa = new UsersUAA("https://login."); +const cc = new CloudController("https://api."); +const authEndpoint: string = await cc.getAuthorizationEndpoint(); + +const uaa = new UsersUAA(); +uaa.setEndPoint(authEndpoint); const token: OAuthToken = await uaa.login("user", "pass"); const apps = new Apps("https://api."); diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index bb5e2d4..d24f190 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,55 @@ +# cf-node-client v1.0.4 — Hotfix: v3 getInfo() Broken Authentication Flow + +**Package**: cf-node-client v1.0.4 +**Release Date**: March 5, 2026 +**Status**: Production Ready +**Severity**: **Critical Hotfix** + +## What's Fixed in v1.0.4 + +### Bug Fix — `getInfo()` Returns `undefined` for `authorization_endpoint` (v3 Mode) + +**Impact**: All users on v1.0.0+ using default v3 mode. The standard authentication flow was completely broken: + +```javascript +// This common pattern was broken in v3 mode: +const info = await cfController.getInfo(); +usersUAA.setEndPoint(info.authorization_endpoint); // ❌ undefined → Error thrown +``` + +**Root Cause**: `CloudController.getInfo()` called `/v3/info` which does not exist in Cloud Foundry. CF v3 uses the root endpoint `/` which returns a different response shape: +- v2: `{ authorization_endpoint: "https://...", token_endpoint: "https://..." }` +- v3 root: `{ links: { uaa: { href: "https://..." }, login: { href: "https://..." } } }` + +**Fix**: `getInfo()` in v3 mode now calls the correct root endpoint `/` and **normalizes** the response by adding `authorization_endpoint` and `token_endpoint` at the top level. All existing consumer code works without changes. + +### New Convenience Method — `getAuthorizationEndpoint()` + +A version-agnostic helper that extracts the UAA endpoint from CF info. Recommended for new code: + +```javascript +// Old pattern (still works): +const info = await cfController.getInfo(); +usersUAA.setEndPoint(info.authorization_endpoint); + +// New pattern (cleaner): +const authEndpoint = await cfController.getAuthorizationEndpoint(); +usersUAA.setEndPoint(authEndpoint); +``` + +### Files Modified + +| File | Change | +|------|--------| +| `lib/model/cloudcontroller/CloudController.js` | Fixed `getInfo()` v3 endpoint + response normalization; added `getAuthorizationEndpoint()` | +| `types/index.d.ts` | Added `getAuthorizationEndpoint(): Promise` type declaration | +| `examples/cf-service-usage-example.js` | Added `getAuthTokenV2()` example using new convenience method | + +### Tests +- All **93 tests passing**, 0 failing + +--- + # cf-node-client v1.0.2 — Security: Zero Vulnerabilities **Package**: cf-node-client v1.0.2 diff --git a/docs/Usage.md b/docs/Usage.md index 60e26a8..251ea14 100644 --- a/docs/Usage.md +++ b/docs/Usage.md @@ -12,11 +12,21 @@ const { CloudController, UsersUAA } = require('cf-node-client'); const cfController = new CloudController('https://api.cf.example.com'); const usersUAA = new UsersUAA(); +// Option 1: Using getInfo() — works with both v2 and v3 const info = await cfController.getInfo(); usersUAA.setEndPoint(info.authorization_endpoint); const token = await usersUAA.login('username', 'password'); + +// Option 2: Using getAuthorizationEndpoint() — recommended, cleaner +const authEndpoint = await cfController.getAuthorizationEndpoint(); +usersUAA.setEndPoint(authEndpoint); +const token = await usersUAA.login('username', 'password'); ``` +> **Note (v1.0.4):** In v3 mode, `getInfo()` calls the CF root endpoint `/` and normalizes +> the response so `info.authorization_endpoint` is always available. The new +> `getAuthorizationEndpoint()` convenience method is the recommended approach for new code. + ## Organizations ```js diff --git a/examples/cf-service-usage-example.js b/examples/cf-service-usage-example.js index 2ec83cd..bf48c51 100644 --- a/examples/cf-service-usage-example.js +++ b/examples/cf-service-usage-example.js @@ -32,12 +32,28 @@ function getAuthToken() { const cfController = new CloudController(apiCF); const usersUAA = new UsersUAA(); + // Works with both v2 and v3 — getInfo() normalizes the response return cfController.getInfo().then(function (info) { usersUAA.setEndPoint(info.authorization_endpoint); return usersUAA.login(credentials.username, credentials.password); }); } +/** + * Alternative: Use the convenience method getAuthorizationEndpoint(). + * Cleaner and version-agnostic — recommended for new code. + * @returns {Promise} OAuth token object + */ +function getAuthTokenV2() { + const cfController = new CloudController(apiCF); + const usersUAA = new UsersUAA(); + + return cfController.getAuthorizationEndpoint().then(function (authEndpoint) { + usersUAA.setEndPoint(authEndpoint); + return usersUAA.login(credentials.username, credentials.password); + }); +} + // ============================================================================= // 2. ORGANIZATIONS — Find by Name / List / Get by GUID // ============================================================================= diff --git a/index.js b/index.js index 6cac346..b562686 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,7 @@ "use strict"; /** Library Version */ -module.exports.version = "1.0.3"; +module.exports.version = "1.0.4"; // ── Cloud Controller models ──────────────────────────────────────────── const Apps = require("./lib/model/cloudcontroller/Apps"); diff --git a/lib/model/cloudcontroller/CloudController.js b/lib/model/cloudcontroller/CloudController.js index c9699d7..ac091ca 100644 --- a/lib/model/cloudcontroller/CloudController.js +++ b/lib/model/cloudcontroller/CloudController.js @@ -20,15 +20,40 @@ class CloudController extends CloudControllerBase { } /** - * Get information from Cloud Controller + * Get information from Cloud Controller. + * * v2: {@link http://apidocs.cloudfoundry.org/214/info/get_info.html} - * v3: {@link https://v3-apidocs.cloudfoundry.org/#get-info} + * v3: Uses the root endpoint (/) — CF v3 has no /v3/info. + * The response is **normalized** so that `authorization_endpoint` + * and `token_endpoint` are always present at the top level, + * keeping backward compatibility with existing consumer code. * - * @return {Promise} Resolves with JSON info + * @return {Promise} Resolves with JSON info (always contains + * `authorization_endpoint` and `token_endpoint`) */ getInfo() { if (this.isUsingV3()) { - return this.REST.requestV3("GET", `${this.API_URL}/v3/info`); + // CF v3: root endpoint "/" returns { links: { uaa: {href}, login: {href}, … } } + const options = { + method: "GET", + url: `${this.API_URL}/`, + headers: { Accept: "application/json" } + }; + return this.REST.request(options, this.HttpStatus.OK, true) + .then(function (result) { + // Normalize: add v2-style fields for backward compatibility + if (result && result.links) { + if (result.links.login && result.links.login.href) { + result.authorization_endpoint = result.links.login.href; + } else if (result.links.uaa && result.links.uaa.href) { + result.authorization_endpoint = result.links.uaa.href; + } + if (result.links.uaa && result.links.uaa.href) { + result.token_endpoint = result.links.uaa.href; + } + } + return result; + }); } const options = { method: "GET", @@ -37,6 +62,26 @@ class CloudController extends CloudControllerBase { return this.REST.request(options, this.HttpStatus.OK, true); } + /** + * Get the UAA authorization endpoint URL from Cloud Controller info. + * Works with both v2 and v3 — abstracts away the response shape difference. + * + * @return {Promise} Resolves with the authorization endpoint URL + * @throws {Error} If authorization endpoint is not found in the info response + */ + getAuthorizationEndpoint() { + return this.getInfo().then(function (info) { + const endpoint = info.authorization_endpoint; + if (!endpoint) { + throw new Error( + "Could not determine authorization_endpoint from CF info response. " + + "Ensure the Cloud Controller is reachable and returns valid info." + ); + } + return endpoint; + }); + } + /** * Get all feature flags * v2: {@link http://apidocs.cloudfoundry.org/214/feature_flags/get_all_feature_flags.html} diff --git a/package.json b/package.json index 6189267..6eb2bbb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cf-node-client", - "version": "1.0.3", + "version": "1.0.4", "description": "A Cloud Foundry Client for Node.js supporting TypeScript and JavaScript.", "author": "Leo Trinh ", "license": "Apache-2.0", diff --git a/test/lib/ApiMigrationTests.js b/test/lib/ApiMigrationTests.js index 566bc2c..e4e6fd5 100644 --- a/test/lib/ApiMigrationTests.js +++ b/test/lib/ApiMigrationTests.js @@ -10,7 +10,7 @@ const CloudController = require('../../lib/model/cloudcontroller/CloudController const ApiConfig = require('../../lib/config/ApiConfig'); const ApiVersionManager = require('../../lib/config/ApiVersionManager'); -describe('cf-node-client v1.0.3 - API v3 Migration', function () { +describe('cf-node-client v1.0.4 - API v3 Migration', function () { this.timeout(5000); describe('Package Configuration', function () { @@ -20,14 +20,14 @@ describe('cf-node-client v1.0.3 - API v3 Migration', function () { expect(pkg.name).to.equal('cf-node-client'); }); - it('should have version 1.0.3', function () { + it('should have version 1.0.4', function () { const pkg = require('../../package.json'); - expect(pkg.version).to.equal('1.0.3'); + expect(pkg.version).to.equal('1.0.4'); }); - it('should have index.js export version 1.0.3', function () { + it('should have index.js export version 1.0.4', function () { const lib = require('../../index.js'); - expect(lib.version).to.equal('1.0.3'); + expect(lib.version).to.equal('1.0.4'); }); it('should export all 16 Cloud Foundry models', function () { diff --git a/types/index.d.ts b/types/index.d.ts index 6b9cf96..d717788 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -117,8 +117,10 @@ export class CloudControllerBase { export class CloudController extends CloudControllerBase { constructor(endPoint: string, options?: CloudControllerBaseOptions); - /** Get Cloud Controller info */ + /** Get Cloud Controller info (normalized: always has authorization_endpoint & token_endpoint) */ getInfo(): Promise; + /** Get UAA authorization endpoint URL (works with both v2 and v3) */ + getAuthorizationEndpoint(): Promise; /** Get all feature flags */ getFeaturedFlags(): Promise; /** Get a specific feature flag */ From be74c8a064d134cb91059e457dff6df98c3537e9 Mon Sep 17 00:00:00 2001 From: leotrinh Date: Thu, 5 Mar 2026 16:21:14 +0700 Subject: [PATCH 2/3] bug: fix critcial bug --- lib/model/cloudcontroller/Spaces.js | 10 ++++++++++ lib/utils/HttpUtils.js | 6 +++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/model/cloudcontroller/Spaces.js b/lib/model/cloudcontroller/Spaces.js index c11bcf9..1b85f3f 100644 --- a/lib/model/cloudcontroller/Spaces.js +++ b/lib/model/cloudcontroller/Spaces.js @@ -559,6 +559,16 @@ class Spaces extends CloudControllerBase { return this.REST.request(options, this.HttpStatus.OK, true); } + /** + * Get apps in a Space (alias for getApps — backward compatibility) + * @param {String} guid [Space GUID] + * @param {Object} filter [Filter options] + * @return {Promise} [Promise resolving to apps list] + */ + getSpaceApps(guid, filter) { + return this.getApps(guid, filter); + } + /** * Get ALL spaces across all pages (auto-pagination). * Returns a flat array of every space resource. diff --git a/lib/utils/HttpUtils.js b/lib/utils/HttpUtils.js index fa9b536..9c31781 100644 --- a/lib/utils/HttpUtils.js +++ b/lib/utils/HttpUtils.js @@ -122,7 +122,11 @@ class HttpUtils { // Try to parse error body as JSON for better error info try { const errJson = JSON.parse(text); - const err = new Error(errJson.description || errJson.message || text); + const errMsg = errJson.description + || errJson.message + || (errJson.errors && errJson.errors.length > 0 && errJson.errors[0].detail) + || text; + const err = new Error(errMsg); err.statusCode = response.status; err.body = errJson; throw err; From 8853c2503d984bf188ddcf9259fac733cfeea3c0 Mon Sep 17 00:00:00 2001 From: leotrinh Date: Thu, 5 Mar 2026 16:22:14 +0700 Subject: [PATCH 3/3] chore: update docs --- doc/Apps.html | 2 +- doc/AppsCopy.html | 2 +- doc/AppsCore.html | 2 +- doc/AppsDeployment.html | 2 +- doc/BuildPacks.html | 2 +- doc/CfIgnoreHelper.html | 2 +- doc/CloudController.html | 153 +++++++++++++- doc/CloudControllerBase.html | 2 +- doc/Domains.html | 2 +- doc/Events.html | 2 +- doc/HttpUtils.html | 10 +- doc/Jobs.html | 2 +- doc/Logs.html | 2 +- doc/Organizations.html | 2 +- doc/OrganizationsQuota.html | 2 +- doc/Routes.html | 2 +- doc/ServiceBindings.html | 2 +- doc/ServiceInstances.html | 2 +- doc/ServicePlans.html | 2 +- doc/Services.html | 2 +- doc/Spaces.html | 186 +++++++++++++++++- doc/SpacesQuota.html | 2 +- doc/Stacks.html | 2 +- doc/UserProvidedServices.html | 2 +- doc/Users.html | 2 +- doc/UsersUAA.html | 2 +- doc/index.html | 2 +- doc/model_cloudcontroller_Apps.js.html | 2 +- doc/model_cloudcontroller_AppsCopy.js.html | 2 +- doc/model_cloudcontroller_AppsCore.js.html | 2 +- ...del_cloudcontroller_AppsDeployment.js.html | 2 +- doc/model_cloudcontroller_BuildPacks.js.html | 2 +- ...el_cloudcontroller_CloudController.js.html | 55 +++++- ...loudcontroller_CloudControllerBase.js.html | 2 +- doc/model_cloudcontroller_Domains.js.html | 2 +- doc/model_cloudcontroller_Events.js.html | 2 +- doc/model_cloudcontroller_Jobs.js.html | 2 +- ...odel_cloudcontroller_Organizations.js.html | 2 +- ...cloudcontroller_OrganizationsQuota.js.html | 2 +- doc/model_cloudcontroller_Routes.js.html | 2 +- ...el_cloudcontroller_ServiceBindings.js.html | 2 +- ...l_cloudcontroller_ServiceInstances.js.html | 2 +- ...model_cloudcontroller_ServicePlans.js.html | 2 +- doc/model_cloudcontroller_Services.js.html | 2 +- doc/model_cloudcontroller_Spaces.js.html | 12 +- doc/model_cloudcontroller_SpacesQuota.js.html | 2 +- doc/model_cloudcontroller_Stacks.js.html | 2 +- ...oudcontroller_UserProvidedServices.js.html | 2 +- doc/model_cloudcontroller_Users.js.html | 2 +- doc/model_metrics_Logs.js.html | 2 +- doc/model_uaa_UsersUAA.js.html | 2 +- doc/utils_CfIgnoreHelper.js.html | 2 +- doc/utils_HttpUtils.js.html | 8 +- 53 files changed, 449 insertions(+), 69 deletions(-) diff --git a/doc/Apps.html b/doc/Apps.html index db35521..3cc1e1c 100644 --- a/doc/Apps.html +++ b/doc/Apps.html @@ -181,7 +181,7 @@

Home

Classes

  • diff --git a/doc/AppsCopy.html b/doc/AppsCopy.html index f593b6a..27a6fc1 100644 --- a/doc/AppsCopy.html +++ b/doc/AppsCopy.html @@ -859,7 +859,7 @@

    Home

    Classes

    • diff --git a/doc/AppsCore.html b/doc/AppsCore.html index ed8be7d..fe6d967 100644 --- a/doc/AppsCore.html +++ b/doc/AppsCore.html @@ -1988,7 +1988,7 @@

      Home

      Classes

      • diff --git a/doc/AppsDeployment.html b/doc/AppsDeployment.html index 6a341f5..5be3ded 100644 --- a/doc/AppsDeployment.html +++ b/doc/AppsDeployment.html @@ -2402,7 +2402,7 @@

        Home

        Classes

        • diff --git a/doc/BuildPacks.html b/doc/BuildPacks.html index bc39577..ae649e9 100644 --- a/doc/BuildPacks.html +++ b/doc/BuildPacks.html @@ -1150,7 +1150,7 @@

          Home

          Classes

          • diff --git a/doc/CfIgnoreHelper.html b/doc/CfIgnoreHelper.html index da58b17..bab52b5 100644 --- a/doc/CfIgnoreHelper.html +++ b/doc/CfIgnoreHelper.html @@ -1107,7 +1107,7 @@

            Home

            Classes

            • diff --git a/doc/CloudController.html b/doc/CloudController.html index 998a904..389f078 100644 --- a/doc/CloudController.html +++ b/doc/CloudController.html @@ -275,6 +275,145 @@

              Methods

              +

              getAuthorizationEndpoint() → {Promise.<String>}

              + + + + + + +
              + Get the UAA authorization endpoint URL from Cloud Controller info. Works with both v2 and v3 — abstracts away the response shape difference. +
              + + + + + + + + + + + + + +
              + + + + + + + + + + + + + + + + + + + + + + + + + + +
              Source:
              +
              + + + + + + + +
              + + + + + + + + + + + + + +
              Throws:
              + + + +
              +
              +
              + If authorization endpoint is not found in the info response +
              +
              +
              +
              +
              +
              + Type +
              +
              + +Error + + +
              +
              +
              +
              +
              + + + + + +
              Returns:
              + + +
              + Resolves with the authorization endpoint URL +
              + + + +
              +
              + Type +
              +
              + +Promise.<String> + + +
              +
              + + + + + + + + + + + + +

              getFeaturedFlag(flag) → {Promise}

              @@ -376,7 +515,7 @@
              Parameters:
              Source:
              @@ -486,7 +625,7 @@

              getFe
              Source:
              @@ -552,7 +691,7 @@

              getInfo - Get information from Cloud Controller v2: http://apidocs.cloudfoundry.org/214/info/get_info.html v3: https://v3-apidocs.cloudfoundry.org/#get-info + Get information from Cloud Controller. v2: http://apidocs.cloudfoundry.org/214/info/get_info.html v3: Uses the root endpoint (/) — CF v3 has no /v3/info. The response is **normalized** so that `authorization_endpoint` and `token_endpoint` are always present at the top level, keeping backward compatibility with existing consumer code. @@ -596,7 +735,7 @@

              getInfoSource:
              @@ -625,7 +764,7 @@
              Returns:
              - Resolves with JSON info + Resolves with JSON info (always contains `authorization_endpoint` and `token_endpoint`)
              @@ -798,7 +937,7 @@
              Parameters:
              Source:
              @@ -872,7 +1011,7 @@

              Home

              Classes

              • diff --git a/doc/CloudControllerBase.html b/doc/CloudControllerBase.html index 06925ca..3790f1f 100644 --- a/doc/CloudControllerBase.html +++ b/doc/CloudControllerBase.html @@ -2477,7 +2477,7 @@

                Home

                Classes

                • diff --git a/doc/Domains.html b/doc/Domains.html index c110f61..b2abc44 100644 --- a/doc/Domains.html +++ b/doc/Domains.html @@ -939,7 +939,7 @@

                  Home

                  Classes

                  • diff --git a/doc/Events.html b/doc/Events.html index 8fb67ba..2a58b8b 100644 --- a/doc/Events.html +++ b/doc/Events.html @@ -619,7 +619,7 @@

                    Home

                    Classes

                    • diff --git a/doc/HttpUtils.html b/doc/HttpUtils.html index 7d0b485..1532711 100644 --- a/doc/HttpUtils.html +++ b/doc/HttpUtils.html @@ -334,7 +334,7 @@
                      Parameters:
                      Source:
                      @@ -821,7 +821,7 @@
                      Parameters:
                      Source:
                      @@ -1098,7 +1098,7 @@
                      Parameters:
                      Source:
                      @@ -1326,7 +1326,7 @@
                      Parameters:
                      Source:
                      @@ -1400,7 +1400,7 @@

                      Home

                      Classes

                      • diff --git a/doc/Jobs.html b/doc/Jobs.html index 0209a19..07ebe72 100644 --- a/doc/Jobs.html +++ b/doc/Jobs.html @@ -991,7 +991,7 @@

                        Home

                        Classes

                        • diff --git a/doc/Logs.html b/doc/Logs.html index 4ac0e19..ff511cd 100644 --- a/doc/Logs.html +++ b/doc/Logs.html @@ -723,7 +723,7 @@

                          Home

                          Classes

                          • diff --git a/doc/Organizations.html b/doc/Organizations.html index e6171e1..77622a3 100644 --- a/doc/Organizations.html +++ b/doc/Organizations.html @@ -2492,7 +2492,7 @@

                            Home

                            Classes

                            • diff --git a/doc/OrganizationsQuota.html b/doc/OrganizationsQuota.html index 2fd99f0..08a515d 100644 --- a/doc/OrganizationsQuota.html +++ b/doc/OrganizationsQuota.html @@ -1083,7 +1083,7 @@

                              Home

                              Classes

                              • diff --git a/doc/Routes.html b/doc/Routes.html index 2ef14e1..4284c67 100644 --- a/doc/Routes.html +++ b/doc/Routes.html @@ -1298,7 +1298,7 @@

                                Home

                                Classes

                                • diff --git a/doc/ServiceBindings.html b/doc/ServiceBindings.html index 7967bee..f127ddc 100644 --- a/doc/ServiceBindings.html +++ b/doc/ServiceBindings.html @@ -1116,7 +1116,7 @@

                                  Home

                                  Classes

                                  • diff --git a/doc/ServiceInstances.html b/doc/ServiceInstances.html index 22f8627..bea2f5a 100644 --- a/doc/ServiceInstances.html +++ b/doc/ServiceInstances.html @@ -2882,7 +2882,7 @@

                                    Home

                                    Classes

                                    • diff --git a/doc/ServicePlans.html b/doc/ServicePlans.html index e76ff8e..4d25dad 100644 --- a/doc/ServicePlans.html +++ b/doc/ServicePlans.html @@ -939,7 +939,7 @@

                                      Home

                                      Classes

                                      • diff --git a/doc/Services.html b/doc/Services.html index a6c3717..6e8190d 100644 --- a/doc/Services.html +++ b/doc/Services.html @@ -1139,7 +1139,7 @@

                                        Home

                                        Classes

                                        • diff --git a/doc/Spaces.html b/doc/Spaces.html index 07554d6..377ddc0 100644 --- a/doc/Spaces.html +++ b/doc/Spaces.html @@ -531,7 +531,7 @@
                                          Parameters:
                                          Source:
                                          @@ -1476,6 +1476,188 @@
                                          Returns:
                                          +

                                          getSpaceApps(guid, filter) → {Promise}

                                          + + + + + + +
                                          + Get apps in a Space (alias for getApps — backward compatibility) +
                                          + + + + + + + + + +
                                          Parameters:
                                          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                          NameTypeDescription
                                          guid + + +String + + + + [Space GUID]
                                          filter + + +Object + + + + [Filter options]
                                          + + + + + + +
                                          + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                          Source:
                                          +
                                          + + + + + + + +
                                          + + + + + + + + + + + + + + + +
                                          Returns:
                                          + + +
                                          + [Promise resolving to apps list] +
                                          + + + +
                                          +
                                          + Type +
                                          +
                                          + +Promise + + +
                                          +
                                          + + + + + + + + + + + + +

                                          getSpaceByName(name, orgGuidopt) → {Promise}

                                          @@ -2558,7 +2740,7 @@

                                          Home

                                          Classes

                                          • diff --git a/doc/SpacesQuota.html b/doc/SpacesQuota.html index d9721c1..2afd434 100644 --- a/doc/SpacesQuota.html +++ b/doc/SpacesQuota.html @@ -1083,7 +1083,7 @@

                                            Home

                                            Classes

                                            • diff --git a/doc/Stacks.html b/doc/Stacks.html index b424cb7..1bb7533 100644 --- a/doc/Stacks.html +++ b/doc/Stacks.html @@ -621,7 +621,7 @@

                                              Home

                                              Classes

                                              • diff --git a/doc/UserProvidedServices.html b/doc/UserProvidedServices.html index 734a4a0..49df7b4 100644 --- a/doc/UserProvidedServices.html +++ b/doc/UserProvidedServices.html @@ -1080,7 +1080,7 @@

                                                Home

                                                Classes

                                                • diff --git a/doc/Users.html b/doc/Users.html index bc8c883..7bdc43f 100644 --- a/doc/Users.html +++ b/doc/Users.html @@ -939,7 +939,7 @@

                                                  Home

                                                  Classes

                                                  • diff --git a/doc/UsersUAA.html b/doc/UsersUAA.html index 7958eb8..a873dd3 100644 --- a/doc/UsersUAA.html +++ b/doc/UsersUAA.html @@ -2139,7 +2139,7 @@

                                                    Home

                                                    Classes

                                                    • diff --git a/doc/index.html b/doc/index.html index 295f65a..f5ad8c9 100644 --- a/doc/index.html +++ b/doc/index.html @@ -86,7 +86,7 @@

                                                      Home

                                                      Classes

                                                      • diff --git a/doc/model_cloudcontroller_Apps.js.html b/doc/model_cloudcontroller_Apps.js.html index 6f8a172..6a698b2 100644 --- a/doc/model_cloudcontroller_Apps.js.html +++ b/doc/model_cloudcontroller_Apps.js.html @@ -91,7 +91,7 @@

                                                        Home

                                                        Classes

                                                        • diff --git a/doc/model_cloudcontroller_AppsCopy.js.html b/doc/model_cloudcontroller_AppsCopy.js.html index d96f0b0..64e5b2a 100644 --- a/doc/model_cloudcontroller_AppsCopy.js.html +++ b/doc/model_cloudcontroller_AppsCopy.js.html @@ -156,7 +156,7 @@

                                                          Home

                                                          Classes

                                                          • diff --git a/doc/model_cloudcontroller_AppsCore.js.html b/doc/model_cloudcontroller_AppsCore.js.html index 8304255..14f0419 100644 --- a/doc/model_cloudcontroller_AppsCore.js.html +++ b/doc/model_cloudcontroller_AppsCore.js.html @@ -313,7 +313,7 @@

                                                            Home

                                                            Classes

                                                            • diff --git a/doc/model_cloudcontroller_AppsDeployment.js.html b/doc/model_cloudcontroller_AppsDeployment.js.html index 16cbb75..4b4e302 100644 --- a/doc/model_cloudcontroller_AppsDeployment.js.html +++ b/doc/model_cloudcontroller_AppsDeployment.js.html @@ -339,7 +339,7 @@

                                                              Home

                                                              Classes

                                                              • diff --git a/doc/model_cloudcontroller_BuildPacks.js.html b/doc/model_cloudcontroller_BuildPacks.js.html index b6e6300..859b05c 100644 --- a/doc/model_cloudcontroller_BuildPacks.js.html +++ b/doc/model_cloudcontroller_BuildPacks.js.html @@ -196,7 +196,7 @@

                                                                Home

                                                                Classes

                                                                • diff --git a/doc/model_cloudcontroller_CloudController.js.html b/doc/model_cloudcontroller_CloudController.js.html index 7a06491..092f1a8 100644 --- a/doc/model_cloudcontroller_CloudController.js.html +++ b/doc/model_cloudcontroller_CloudController.js.html @@ -68,15 +68,40 @@

                                                                  Source: model/cloudcontroller/CloudController.js

                                                                  } /** - * Get information from Cloud Controller + * Get information from Cloud Controller. + * * v2: {@link http://apidocs.cloudfoundry.org/214/info/get_info.html} - * v3: {@link https://v3-apidocs.cloudfoundry.org/#get-info} + * v3: Uses the root endpoint (/) — CF v3 has no /v3/info. + * The response is **normalized** so that `authorization_endpoint` + * and `token_endpoint` are always present at the top level, + * keeping backward compatibility with existing consumer code. * - * @return {Promise} Resolves with JSON info + * @return {Promise} Resolves with JSON info (always contains + * `authorization_endpoint` and `token_endpoint`) */ getInfo() { if (this.isUsingV3()) { - return this.REST.requestV3("GET", `${this.API_URL}/v3/info`); + // CF v3: root endpoint "/" returns { links: { uaa: {href}, login: {href}, … } } + const options = { + method: "GET", + url: `${this.API_URL}/`, + headers: { Accept: "application/json" } + }; + return this.REST.request(options, this.HttpStatus.OK, true) + .then(function (result) { + // Normalize: add v2-style fields for backward compatibility + if (result && result.links) { + if (result.links.login && result.links.login.href) { + result.authorization_endpoint = result.links.login.href; + } else if (result.links.uaa && result.links.uaa.href) { + result.authorization_endpoint = result.links.uaa.href; + } + if (result.links.uaa && result.links.uaa.href) { + result.token_endpoint = result.links.uaa.href; + } + } + return result; + }); } const options = { method: "GET", @@ -85,6 +110,26 @@

                                                                  Source: model/cloudcontroller/CloudController.js

                                                                  return this.REST.request(options, this.HttpStatus.OK, true); } + /** + * Get the UAA authorization endpoint URL from Cloud Controller info. + * Works with both v2 and v3 — abstracts away the response shape difference. + * + * @return {Promise<String>} Resolves with the authorization endpoint URL + * @throws {Error} If authorization endpoint is not found in the info response + */ + getAuthorizationEndpoint() { + return this.getInfo().then(function (info) { + const endpoint = info.authorization_endpoint; + if (!endpoint) { + throw new Error( + "Could not determine authorization_endpoint from CF info response. " + + "Ensure the Cloud Controller is reachable and returns valid info." + ); + } + return endpoint; + }); + } + /** * Get all feature flags * v2: {@link http://apidocs.cloudfoundry.org/214/feature_flags/get_all_feature_flags.html} @@ -167,7 +212,7 @@

                                                                  Home

                                                                  Classes

                                                                  • diff --git a/doc/model_cloudcontroller_CloudControllerBase.js.html b/doc/model_cloudcontroller_CloudControllerBase.js.html index 61b5d0e..bb57a46 100644 --- a/doc/model_cloudcontroller_CloudControllerBase.js.html +++ b/doc/model_cloudcontroller_CloudControllerBase.js.html @@ -355,7 +355,7 @@

                                                                    Home

                                                                    Classes

                                                                    • diff --git a/doc/model_cloudcontroller_Domains.js.html b/doc/model_cloudcontroller_Domains.js.html index f5e9a19..f72a201 100644 --- a/doc/model_cloudcontroller_Domains.js.html +++ b/doc/model_cloudcontroller_Domains.js.html @@ -172,7 +172,7 @@

                                                                      Home

                                                                      Classes

                                                                      • diff --git a/doc/model_cloudcontroller_Events.js.html b/doc/model_cloudcontroller_Events.js.html index f3c0a6a..bc591ef 100644 --- a/doc/model_cloudcontroller_Events.js.html +++ b/doc/model_cloudcontroller_Events.js.html @@ -168,7 +168,7 @@

                                                                        Home

                                                                        Classes

                                                                        • diff --git a/doc/model_cloudcontroller_Jobs.js.html b/doc/model_cloudcontroller_Jobs.js.html index 6e85c5a..c4ecff9 100644 --- a/doc/model_cloudcontroller_Jobs.js.html +++ b/doc/model_cloudcontroller_Jobs.js.html @@ -170,7 +170,7 @@

                                                                          Home

                                                                          Classes

                                                                          • diff --git a/doc/model_cloudcontroller_Organizations.js.html b/doc/model_cloudcontroller_Organizations.js.html index 792bdb5..fa957bf 100644 --- a/doc/model_cloudcontroller_Organizations.js.html +++ b/doc/model_cloudcontroller_Organizations.js.html @@ -617,7 +617,7 @@

                                                                            Home

                                                                            Classes

                                                                            • diff --git a/doc/model_cloudcontroller_OrganizationsQuota.js.html b/doc/model_cloudcontroller_OrganizationsQuota.js.html index b9071c3..eec2b93 100644 --- a/doc/model_cloudcontroller_OrganizationsQuota.js.html +++ b/doc/model_cloudcontroller_OrganizationsQuota.js.html @@ -208,7 +208,7 @@

                                                                              Home

                                                                              Classes

                                                                              • diff --git a/doc/model_cloudcontroller_Routes.js.html b/doc/model_cloudcontroller_Routes.js.html index ebea281..fda45d6 100644 --- a/doc/model_cloudcontroller_Routes.js.html +++ b/doc/model_cloudcontroller_Routes.js.html @@ -371,7 +371,7 @@

                                                                                Home

                                                                                Classes

                                                                                • diff --git a/doc/model_cloudcontroller_ServiceBindings.js.html b/doc/model_cloudcontroller_ServiceBindings.js.html index 49221be..0d12915 100644 --- a/doc/model_cloudcontroller_ServiceBindings.js.html +++ b/doc/model_cloudcontroller_ServiceBindings.js.html @@ -320,7 +320,7 @@

                                                                                  Home

                                                                                  Classes

                                                                                  • diff --git a/doc/model_cloudcontroller_ServiceInstances.js.html b/doc/model_cloudcontroller_ServiceInstances.js.html index 28efa78..e31b2cc 100644 --- a/doc/model_cloudcontroller_ServiceInstances.js.html +++ b/doc/model_cloudcontroller_ServiceInstances.js.html @@ -598,7 +598,7 @@

                                                                                    Home

                                                                                    Classes

                                                                                    • diff --git a/doc/model_cloudcontroller_ServicePlans.js.html b/doc/model_cloudcontroller_ServicePlans.js.html index cdfd8c2..9ea6013 100644 --- a/doc/model_cloudcontroller_ServicePlans.js.html +++ b/doc/model_cloudcontroller_ServicePlans.js.html @@ -188,7 +188,7 @@

                                                                                      Home

                                                                                      Classes

                                                                                      • diff --git a/doc/model_cloudcontroller_Services.js.html b/doc/model_cloudcontroller_Services.js.html index 5b5ad4f..eaaee07 100644 --- a/doc/model_cloudcontroller_Services.js.html +++ b/doc/model_cloudcontroller_Services.js.html @@ -288,7 +288,7 @@

                                                                                        Home

                                                                                        Classes

                                                                                        • diff --git a/doc/model_cloudcontroller_Spaces.js.html b/doc/model_cloudcontroller_Spaces.js.html index 0cf55cd..0cd4222 100644 --- a/doc/model_cloudcontroller_Spaces.js.html +++ b/doc/model_cloudcontroller_Spaces.js.html @@ -607,6 +607,16 @@

                                                                                          Source: model/cloudcontroller/Spaces.js

                                                                                          return this.REST.request(options, this.HttpStatus.OK, true); } + /** + * Get apps in a Space (alias for getApps — backward compatibility) + * @param {String} guid [Space GUID] + * @param {Object} filter [Filter options] + * @return {Promise} [Promise resolving to apps list] + */ + getSpaceApps(guid, filter) { + return this.getApps(guid, filter); + } + /** * Get ALL spaces across all pages (auto-pagination). * Returns a flat array of every space resource. @@ -640,7 +650,7 @@

                                                                                          Home

                                                                                          Classes

                                                                                          • diff --git a/doc/model_cloudcontroller_SpacesQuota.js.html b/doc/model_cloudcontroller_SpacesQuota.js.html index f291dfd..ef2d206 100644 --- a/doc/model_cloudcontroller_SpacesQuota.js.html +++ b/doc/model_cloudcontroller_SpacesQuota.js.html @@ -204,7 +204,7 @@

                                                                                            Home

                                                                                            Classes

                                                                                            • diff --git a/doc/model_cloudcontroller_Stacks.js.html b/doc/model_cloudcontroller_Stacks.js.html index 7ffdad0..055980a 100644 --- a/doc/model_cloudcontroller_Stacks.js.html +++ b/doc/model_cloudcontroller_Stacks.js.html @@ -128,7 +128,7 @@

                                                                                              Home

                                                                                              Classes

                                                                                              • diff --git a/doc/model_cloudcontroller_UserProvidedServices.js.html b/doc/model_cloudcontroller_UserProvidedServices.js.html index 9615cf3..e8ae3ac 100644 --- a/doc/model_cloudcontroller_UserProvidedServices.js.html +++ b/doc/model_cloudcontroller_UserProvidedServices.js.html @@ -213,7 +213,7 @@

                                                                                                Home

                                                                                                Classes

                                                                                                • diff --git a/doc/model_cloudcontroller_Users.js.html b/doc/model_cloudcontroller_Users.js.html index 76e20c4..a0d0df7 100644 --- a/doc/model_cloudcontroller_Users.js.html +++ b/doc/model_cloudcontroller_Users.js.html @@ -169,7 +169,7 @@

                                                                                                  Home

                                                                                                  Classes

                                                                                                  • diff --git a/doc/model_metrics_Logs.js.html b/doc/model_metrics_Logs.js.html index 4755204..26372c0 100644 --- a/doc/model_metrics_Logs.js.html +++ b/doc/model_metrics_Logs.js.html @@ -143,7 +143,7 @@

                                                                                                    Home

                                                                                                    Classes

                                                                                                    • diff --git a/doc/model_uaa_UsersUAA.js.html b/doc/model_uaa_UsersUAA.js.html index 27014fb..5ebf52e 100644 --- a/doc/model_uaa_UsersUAA.js.html +++ b/doc/model_uaa_UsersUAA.js.html @@ -300,7 +300,7 @@

                                                                                                      Home

                                                                                                      Classes

                                                                                                      • diff --git a/doc/utils_CfIgnoreHelper.js.html b/doc/utils_CfIgnoreHelper.js.html index d190a0a..347d1ff 100644 --- a/doc/utils_CfIgnoreHelper.js.html +++ b/doc/utils_CfIgnoreHelper.js.html @@ -252,7 +252,7 @@

                                                                                                        Home

                                                                                                        Classes

                                                                                                        • diff --git a/doc/utils_HttpUtils.js.html b/doc/utils_HttpUtils.js.html index 8abf30d..e5ba912 100644 --- a/doc/utils_HttpUtils.js.html +++ b/doc/utils_HttpUtils.js.html @@ -170,7 +170,11 @@

                                                                                                          Source: utils/HttpUtils.js

                                                                                                          // Try to parse error body as JSON for better error info try { const errJson = JSON.parse(text); - const err = new Error(errJson.description || errJson.message || text); + const errMsg = errJson.description + || errJson.message + || (errJson.errors && errJson.errors.length > 0 && errJson.errors[0].detail) + || text; + const err = new Error(errMsg); err.statusCode = response.status; err.body = errJson; throw err; @@ -345,7 +349,7 @@

                                                                                                          Home

                                                                                                          Classes