@azure/identity 4.14.0-alpha.20251219.1 → 4.14.0-alpha.20251222.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -57,5 +57,10 @@ export declare class IdentityClient extends ServiceClient implements INetworkMod
57
57
  * - `oid`: Object Identifier of the authenticated user.
58
58
  */
59
59
  private logIdentifiers;
60
+ /**
61
+ * Parses the response body if possible. Add error properties if parsing fails.
62
+ * This follows MSAL INetworkModule behavior so the response is in expected format.
63
+ */
64
+ private parseResponseBody;
60
65
  }
61
66
  //# sourceMappingURL=identityClient.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"identityClient.d.ts","sourceRoot":"","sources":["../../../src/client/identityClient.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,2BAA2B,CAAC;AAEnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAM/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAU3E;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,WAAW,EAAE,WAAW,CAAC;IACzB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,aAAc,YAAW,cAAc;IAClE,aAAa,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,8BAA8B,CAAC,CAAU;IACjD,OAAO,CAAC,gBAAgB,CAA6C;IACrE,OAAO,CAAC,uBAAuB,CAAkB;IAEjD,OAAO,CAAC,sBAAsB,CAAyB;gBAE3C,OAAO,CAAC,EAAE,sBAAsB;IAmCtC,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAmCzE,kBAAkB,CACtB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAkEhC,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,eAAe;IAe3D,aAAa,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI;IAgB3C,gBAAgB,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM;IAUnD,mBAAmB,CAAC,CAAC,EACzB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAqBxB,oBAAoB,CAAC,CAAC,EAC1B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAsB9B;;;OAGG;IACH,yBAAyB,IAAI,sBAAsB;IAGnD;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,cAAc;CA6BvB"}
1
+ {"version":3,"file":"identityClient.d.ts","sourceRoot":"","sources":["../../../src/client/identityClient.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,2BAA2B,CAAC;AAEnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAM/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAgB3E;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,WAAW,EAAE,WAAW,CAAC;IACzB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,aAAc,YAAW,cAAc;IAClE,aAAa,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,8BAA8B,CAAC,CAAU;IACjD,OAAO,CAAC,gBAAgB,CAA6C;IACrE,OAAO,CAAC,uBAAuB,CAAkB;IAEjD,OAAO,CAAC,sBAAsB,CAAyB;gBAE3C,OAAO,CAAC,EAAE,sBAAsB;IAmCtC,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAmCzE,kBAAkB,CACtB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAkEhC,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,eAAe;IAe3D,aAAa,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI;IAgB3C,gBAAgB,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM;IAUnD,mBAAmB,CAAC,CAAC,EACzB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAqBxB,oBAAoB,CAAC,CAAC,EAC1B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAsB9B;;;OAGG;IACH,yBAAyB,IAAI,sBAAsB;IAGnD;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,cAAc;IA8BtB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;CA2C1B"}
@@ -10,6 +10,12 @@ import { logger } from "../util/logging.js";
10
10
  import { parseExpirationTimestamp, parseRefreshTimestamp, } from "../credentials/managedIdentityCredential/utils.js";
11
11
  import { getAuthorityHost } from "../util/authorityHost.js";
12
12
  const noCorrelationId = "noCorrelationId";
13
+ const HttpStatus = {
14
+ CLIENT_ERROR_RANGE_START: 400,
15
+ CLIENT_ERROR_RANGE_END: 499,
16
+ SERVER_ERROR_RANGE_START: 500,
17
+ SERVER_ERROR_RANGE_END: 599,
18
+ };
13
19
  /**
14
20
  * The network module used by the Identity credentials.
15
21
  *
@@ -181,7 +187,7 @@ export class IdentityClient extends ServiceClient {
181
187
  const response = await this.sendRequest(request);
182
188
  this.logIdentifiers(response);
183
189
  return {
184
- body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,
190
+ body: this.parseResponseBody(response),
185
191
  headers: response.headers.toJSON(),
186
192
  status: response.status,
187
193
  };
@@ -199,7 +205,7 @@ export class IdentityClient extends ServiceClient {
199
205
  const response = await this.sendRequest(request);
200
206
  this.logIdentifiers(response);
201
207
  return {
202
- body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,
208
+ body: this.parseResponseBody(response),
203
209
  headers: response.headers.toJSON(),
204
210
  status: response.status,
205
211
  };
@@ -243,5 +249,50 @@ export class IdentityClient extends ServiceClient {
243
249
  logger.warning("allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:", e.message);
244
250
  }
245
251
  }
252
+ /**
253
+ * Parses the response body if possible. Add error properties if parsing fails.
254
+ * This follows MSAL INetworkModule behavior so the response is in expected format.
255
+ */
256
+ parseResponseBody(response) {
257
+ let parsedBody;
258
+ try {
259
+ parsedBody = JSON.parse(response.bodyAsText || "");
260
+ }
261
+ catch (error) {
262
+ logger.info(`IdentityClient: Could not parse response body: ${error}`);
263
+ let errorType;
264
+ let errorDescriptionHelper;
265
+ /**
266
+ * Determine error type based on status code ranges following MSAL patterns:
267
+ * Client error responses (400 – 499)
268
+ * Server error responses (500 – 599)
269
+ */
270
+ if (response.status >= HttpStatus.CLIENT_ERROR_RANGE_START &&
271
+ response.status <= HttpStatus.CLIENT_ERROR_RANGE_END) {
272
+ errorType = "client_error";
273
+ errorDescriptionHelper = "A client";
274
+ }
275
+ else if (response.status >= HttpStatus.SERVER_ERROR_RANGE_START &&
276
+ response.status <= HttpStatus.SERVER_ERROR_RANGE_END) {
277
+ errorType = "server_error";
278
+ errorDescriptionHelper = "A server";
279
+ }
280
+ else {
281
+ errorType = "unknown_error";
282
+ errorDescriptionHelper = "An unknown";
283
+ }
284
+ const errorDescriptionLines = [
285
+ `${errorDescriptionHelper} error occured.`,
286
+ `Http status code: ${response.status}`,
287
+ `Http status message: ${response.bodyAsText || "Unknown"}`,
288
+ `Headers: ${JSON.stringify(response.headers)}`,
289
+ ];
290
+ parsedBody = {
291
+ error: errorType,
292
+ error_description: errorDescriptionLines.join("\n"),
293
+ };
294
+ }
295
+ return parsedBody;
296
+ }
246
297
  }
247
298
  //# sourceMappingURL=identityClient.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"identityClient.js","sourceRoot":"","sources":["../../../src/client/identityClient.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAErF,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAG5C,OAAO,EACL,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,MAAM,eAAe,GAAG,iBAAiB,CAAC;AAiB1C;;;;;;GAMG;AACH,MAAM,OAAO,cAAe,SAAQ,aAAa;IACxC,aAAa,CAAS;IACrB,8BAA8B,CAAW;IACzC,gBAAgB,CAA6C;IAC7D,uBAAuB,GAAY,KAAK,CAAC;IACjD,4BAA4B;IACpB,sBAAsB,CAAyB;IAEvD,YAAY,OAAgC;QAC1C,MAAM,cAAc,GAAG,qBAAqB,WAAW,EAAE,CAAC;QAC1D,MAAM,eAAe,GAAG,OAAO,EAAE,gBAAgB,EAAE,eAAe;YAChE,CAAC,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC,eAAe,IAAI,cAAc,EAAE;YACjE,CAAC,CAAC,GAAG,cAAc,EAAE,CAAC;QAExB,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC9E,CAAC;QAED,KAAK,CAAC;YACJ,kBAAkB,EAAE,iCAAiC;YACrD,YAAY,EAAE;gBACZ,UAAU,EAAE,CAAC;aACd;YACD,GAAG,OAAO;YACV,gBAAgB,EAAE;gBAChB,eAAe;aAChB;YACD,OAAO;SACR,CAAC,CAAC;QAEH,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;QAC7B,IAAI,CAAC,gBAAgB,GAAG,IAAI,GAAG,EAAE,CAAC;QAClC,IAAI,CAAC,8BAA8B,GAAG,OAAO,EAAE,cAAc,EAAE,8BAA8B,CAAC;QAC9F,4BAA4B;QAC5B,IAAI,CAAC,sBAAsB,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC;QAE7C,2BAA2B;QAC3B,IAAI,OAAO,EAAE,uBAAuB,EAAE,CAAC;YACrC,IAAI,CAAC,uBAAuB,GAAG,OAAO,CAAC,uBAAuB,CAAC;QACjE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,OAAwB;QAC7C,MAAM,CAAC,IAAI,CAAC,6CAA6C,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,QAAQ,CAAC,UAAU,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC,EAAE,CAAC;YAChF,MAAM,UAAU,GAA4B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YAE5E,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC;gBAC7B,OAAO,IAAI,CAAC;YACd,CAAC;YAED,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;YAE9B,MAAM,KAAK,GAAG;gBACZ,WAAW,EAAE;oBACX,KAAK,EAAE,UAAU,CAAC,YAAY;oBAC9B,kBAAkB,EAAE,wBAAwB,CAAC,UAAU,CAAC;oBACxD,qBAAqB,EAAE,qBAAqB,CAAC,UAAU,CAAC;oBACxD,SAAS,EAAE,QAAQ;iBACL;gBAChB,YAAY,EAAE,UAAU,CAAC,aAAa;aACvC,CAAC;YAEF,MAAM,CAAC,IAAI,CACT,oBAAoB,OAAO,CAAC,GAAG,gCAAgC,KAAK,CAAC,WAAW,CAAC,kBAAkB,EAAE,CACtG,CAAC;YACF,OAAO,KAAK,CAAC;QACf,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,GAAG,IAAI,mBAAmB,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;YAC5E,MAAM,CAAC,OAAO,CACZ,sDAAsD,QAAQ,CAAC,MAAM,KAAK,KAAK,CAAC,aAAa,CAAC,gBAAgB,EAAE,CACjH,CAAC;YACF,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,kBAAkB,CACtB,QAAgB,EAChB,QAAgB,EAChB,MAAc,EACd,YAAgC,EAChC,YAAgC,EAChC,UAA2B,EAAE;QAE7B,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,CAAC,IAAI,CACT,2DAA2D,QAAQ,aAAa,MAAM,UAAU,CACjG,CAAC;QAEF,MAAM,aAAa,GAAG;YACpB,UAAU,EAAE,eAAe;YAC3B,SAAS,EAAE,QAAQ;YACnB,aAAa,EAAE,YAAY;YAC3B,KAAK,EAAE,MAAM;SACd,CAAC;QAEF,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC9B,aAAqB,CAAC,aAAa,GAAG,YAAY,CAAC;QACtD,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,aAAa,CAAC,CAAC;QAEjD,OAAO,aAAa,CAAC,QAAQ,CAC3B,mCAAmC,EACnC,OAAO,EACP,KAAK,EAAE,cAAc,EAAE,EAAE;YACvB,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,8BAA8B,CAAC,QAAQ,CAAC,CAAC;gBAC3D,MAAM,OAAO,GAAG,qBAAqB,CAAC;oBACpC,GAAG,EAAE,GAAG,IAAI,CAAC,aAAa,IAAI,QAAQ,IAAI,SAAS,EAAE;oBACrD,MAAM,EAAE,MAAM;oBACd,IAAI,EAAE,KAAK,CAAC,QAAQ,EAAE;oBACtB,WAAW,EAAE,OAAO,CAAC,WAAW;oBAChC,OAAO,EAAE,iBAAiB,CAAC;wBACzB,MAAM,EAAE,kBAAkB;wBAC1B,cAAc,EAAE,mCAAmC;qBACpD,CAAC;oBACF,cAAc,EAAE,cAAc,CAAC,cAAc;iBAC9C,CAAC,CAAC;gBAEH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;gBACtD,MAAM,CAAC,IAAI,CAAC,kDAAkD,QAAQ,EAAE,CAAC,CAAC;gBAC1E,OAAO,QAAQ,CAAC;YAClB,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,IACE,GAAG,CAAC,IAAI,KAAK,uBAAuB;oBACpC,GAAG,CAAC,aAAa,CAAC,KAAK,KAAK,sBAAsB,EAClD,CAAC;oBACD,qDAAqD;oBACrD,yDAAyD;oBACzD,0CAA0C;oBAC1C,MAAM,CAAC,IAAI,CAAC,uDAAuD,QAAQ,EAAE,CAAC,CAAC;oBAC/E,OAAO,IAAI,CAAC;gBACd,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,OAAO,CACZ,0DAA0D,QAAQ,KAAK,GAAG,EAAE,CAC7E,CAAC;oBACF,MAAM,GAAG,CAAC;gBACZ,CAAC;YACH,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;IAED,gFAAgF;IAChF,mEAAmE;IAEnE,mBAAmB,CAAC,aAAqB;QACvC,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;QACnE,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7B,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;QACtD,MAAM,eAAe,GAAG,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC;QAClD,UAAU,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,GAAG,MAAM,EAAE,EAAE;YACxC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;YACpD,IAAI,eAAe,EAAE,CAAC;gBACpB,eAAe,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACnD,CAAC;QACH,CAAC,CAAC;QACF,OAAO,UAAU,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED,aAAa,CAAC,aAAsB;QAClC,MAAM,GAAG,GAAG,aAAa,IAAI,eAAe,CAAC;QAC7C,MAAM,WAAW,GAAG;YAClB,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YACzC,uDAAuD;YACvD,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;SACtD,CAAC;QACF,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QACD,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,UAAU,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;QACD,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC5C,CAAC;IAED,gBAAgB,CAAC,OAA+B;QAC9C,MAAM,SAAS,GAAG,OAAO,EAAE,IAAI;YAC7B,EAAE,KAAK,CAAC,GAAG,CAAC;aACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;aAC9B,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,mBAAmB,CAAC,CAAC;QAChD,OAAO,SAAS,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC;IAC3F,CAAC;IAED,yCAAyC;IAEzC,KAAK,CAAC,mBAAmB,CACvB,GAAW,EACX,OAA+B;QAE/B,MAAM,OAAO,GAAG,qBAAqB,CAAC;YACpC,GAAG;YACH,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,OAAO,EAAE,IAAI;YACnB,uBAAuB,EAAE,IAAI,CAAC,uBAAuB;YACrD,OAAO,EAAE,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC;YAC5C,WAAW,EAAE,IAAI,CAAC,mBAAmB,CAAC,eAAe,CAAC;SACvD,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAEjD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAE9B,OAAO;YACL,IAAI,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS;YACvE,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE;YAClC,MAAM,EAAE,QAAQ,CAAC,MAAM;SACxB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,oBAAoB,CACxB,GAAW,EACX,OAA+B;QAE/B,MAAM,OAAO,GAAG,qBAAqB,CAAC;YACpC,GAAG;YACH,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,OAAO,EAAE,IAAI;YACnB,OAAO,EAAE,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC;YAC5C,uBAAuB,EAAE,IAAI,CAAC,uBAAuB;YACrD,4DAA4D;YAC5D,WAAW,EAAE,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;SACtE,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAEjD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAE9B,OAAO;YACL,IAAI,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS;YACvE,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE;YAClC,MAAM,EAAE,QAAQ,CAAC,MAAM;SACxB,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,yBAAyB;QACvB,OAAO,IAAI,CAAC,sBAAsB,CAAC;IACrC,CAAC;IACD;;;;;;;;;;;OAWG;IACK,cAAc,CAAC,QAA0B;QAC/C,IAAI,CAAC,IAAI,CAAC,8BAA8B,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;YACjE,OAAO;QACT,CAAC;QACD,MAAM,cAAc,GAAG,kCAAkC,CAAC;QAC1D,IAAI,CAAC;YACH,MAAM,MAAM,GAAI,QAAgB,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YAC/E,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC;YACxC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,uEAAuE;gBACvE,OAAO;YACT,CAAC;YACD,MAAM,cAAc,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACjD,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CACzC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CACvD,CAAC;YAEF,MAAM,CAAC,IAAI,CACT,sCAAsC,KAAK,gBAAgB,GAAG,0BAC5D,GAAG,IAAI,cACT,uBAAuB,GAAG,EAAE,CAC7B,CAAC;QACJ,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,MAAM,CAAC,OAAO,CACZ,6FAA6F,EAC7F,CAAC,CAAC,OAAO,CACV,CAAC;QACJ,CAAC;IACH,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { INetworkModule, NetworkRequestOptions, NetworkResponse } from \"@azure/msal-node\";\nimport type { AccessToken, GetTokenOptions } from \"@azure/core-auth\";\nimport { ServiceClient } from \"@azure/core-client\";\nimport type { PipelineRequest, PipelineResponse } from \"@azure/core-rest-pipeline\";\nimport { createHttpHeaders, createPipelineRequest } from \"@azure/core-rest-pipeline\";\nimport type { AbortSignalLike } from \"@azure/abort-controller\";\nimport { AuthenticationError, AuthenticationErrorName } from \"../errors.js\";\nimport { getIdentityTokenEndpointSuffix } from \"../util/identityTokenEndpoint.js\";\nimport { SDK_VERSION } from \"../constants.js\";\nimport { tracingClient } from \"../util/tracing.js\";\nimport { logger } from \"../util/logging.js\";\nimport type { TokenCredentialOptions } from \"../tokenCredentialOptions.js\";\nimport type { TokenResponseParsedBody } from \"../credentials/managedIdentityCredential/utils.js\";\nimport {\n parseExpirationTimestamp,\n parseRefreshTimestamp,\n} from \"../credentials/managedIdentityCredential/utils.js\";\nimport { getAuthorityHost } from \"../util/authorityHost.js\";\n\nconst noCorrelationId = \"noCorrelationId\";\n\n/**\n * An internal type used to communicate details of a token request's\n * response that should not be sent back as part of the access token.\n */\nexport interface TokenResponse {\n /**\n * The AccessToken to be returned from getToken.\n */\n accessToken: AccessToken;\n /**\n * The refresh token if the 'offline_access' scope was used.\n */\n refreshToken?: string;\n}\n\n/**\n * The network module used by the Identity credentials.\n *\n * It allows for credentials to abort any pending request independently of the MSAL flow,\n * by calling to the `abortRequests()` method.\n *\n */\nexport class IdentityClient extends ServiceClient implements INetworkModule {\n public authorityHost: string;\n private allowLoggingAccountIdentifiers?: boolean;\n private abortControllers: Map<string, AbortController[] | undefined>;\n private allowInsecureConnection: boolean = false;\n // used for WorkloadIdentity\n private tokenCredentialOptions: TokenCredentialOptions;\n\n constructor(options?: TokenCredentialOptions) {\n const packageDetails = `azsdk-js-identity/${SDK_VERSION}`;\n const userAgentPrefix = options?.userAgentOptions?.userAgentPrefix\n ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`\n : `${packageDetails}`;\n\n const baseUri = getAuthorityHost(options);\n if (!baseUri.startsWith(\"https:\")) {\n throw new Error(\"The authorityHost address must use the 'https' protocol.\");\n }\n\n super({\n requestContentType: \"application/json; charset=utf-8\",\n retryOptions: {\n maxRetries: 3,\n },\n ...options,\n userAgentOptions: {\n userAgentPrefix,\n },\n baseUri,\n });\n\n this.authorityHost = baseUri;\n this.abortControllers = new Map();\n this.allowLoggingAccountIdentifiers = options?.loggingOptions?.allowLoggingAccountIdentifiers;\n // used for WorkloadIdentity\n this.tokenCredentialOptions = { ...options };\n\n // used for ManagedIdentity\n if (options?.allowInsecureConnection) {\n this.allowInsecureConnection = options.allowInsecureConnection;\n }\n }\n\n async sendTokenRequest(request: PipelineRequest): Promise<TokenResponse | null> {\n logger.info(`IdentityClient: sending token request to [${request.url}]`);\n const response = await this.sendRequest(request);\n if (response.bodyAsText && (response.status === 200 || response.status === 201)) {\n const parsedBody: TokenResponseParsedBody = JSON.parse(response.bodyAsText);\n\n if (!parsedBody.access_token) {\n return null;\n }\n\n this.logIdentifiers(response);\n\n const token = {\n accessToken: {\n token: parsedBody.access_token,\n expiresOnTimestamp: parseExpirationTimestamp(parsedBody),\n refreshAfterTimestamp: parseRefreshTimestamp(parsedBody),\n tokenType: \"Bearer\",\n } as AccessToken,\n refreshToken: parsedBody.refresh_token,\n };\n\n logger.info(\n `IdentityClient: [${request.url}] token acquired, expires on ${token.accessToken.expiresOnTimestamp}`,\n );\n return token;\n } else {\n const error = new AuthenticationError(response.status, response.bodyAsText);\n logger.warning(\n `IdentityClient: authentication error. HTTP status: ${response.status}, ${error.errorResponse.errorDescription}`,\n );\n throw error;\n }\n }\n\n async refreshAccessToken(\n tenantId: string,\n clientId: string,\n scopes: string,\n refreshToken: string | undefined,\n clientSecret: string | undefined,\n options: GetTokenOptions = {},\n ): Promise<TokenResponse | null> {\n if (refreshToken === undefined) {\n return null;\n }\n logger.info(\n `IdentityClient: refreshing access token with client ID: ${clientId}, scopes: ${scopes} started`,\n );\n\n const refreshParams = {\n grant_type: \"refresh_token\",\n client_id: clientId,\n refresh_token: refreshToken,\n scope: scopes,\n };\n\n if (clientSecret !== undefined) {\n (refreshParams as any).client_secret = clientSecret;\n }\n\n const query = new URLSearchParams(refreshParams);\n\n return tracingClient.withSpan(\n \"IdentityClient.refreshAccessToken\",\n options,\n async (updatedOptions) => {\n try {\n const urlSuffix = getIdentityTokenEndpointSuffix(tenantId);\n const request = createPipelineRequest({\n url: `${this.authorityHost}/${tenantId}/${urlSuffix}`,\n method: \"POST\",\n body: query.toString(),\n abortSignal: options.abortSignal,\n headers: createHttpHeaders({\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n }),\n tracingOptions: updatedOptions.tracingOptions,\n });\n\n const response = await this.sendTokenRequest(request);\n logger.info(`IdentityClient: refreshed token for client ID: ${clientId}`);\n return response;\n } catch (err: any) {\n if (\n err.name === AuthenticationErrorName &&\n err.errorResponse.error === \"interaction_required\"\n ) {\n // It's likely that the refresh token has expired, so\n // return null so that the credential implementation will\n // initiate the authentication flow again.\n logger.info(`IdentityClient: interaction required for client ID: ${clientId}`);\n return null;\n } else {\n logger.warning(\n `IdentityClient: failed refreshing token for client ID: ${clientId}: ${err}`,\n );\n throw err;\n }\n }\n },\n );\n }\n\n // Here is a custom layer that allows us to abort requests that go through MSAL,\n // since MSAL doesn't allow us to pass options all the way through.\n\n generateAbortSignal(correlationId: string): AbortSignalLike {\n const controller = new AbortController();\n const controllers = this.abortControllers.get(correlationId) || [];\n controllers.push(controller);\n this.abortControllers.set(correlationId, controllers);\n const existingOnAbort = controller.signal.onabort;\n controller.signal.onabort = (...params) => {\n this.abortControllers.set(correlationId, undefined);\n if (existingOnAbort) {\n existingOnAbort.apply(controller.signal, params);\n }\n };\n return controller.signal;\n }\n\n abortRequests(correlationId?: string): void {\n const key = correlationId || noCorrelationId;\n const controllers = [\n ...(this.abortControllers.get(key) || []),\n // MSAL passes no correlation ID to the get requests...\n ...(this.abortControllers.get(noCorrelationId) || []),\n ];\n if (!controllers.length) {\n return;\n }\n for (const controller of controllers) {\n controller.abort();\n }\n this.abortControllers.set(key, undefined);\n }\n\n getCorrelationId(options?: NetworkRequestOptions): string {\n const parameter = options?.body\n ?.split(\"&\")\n .map((part) => part.split(\"=\"))\n .find(([key]) => key === \"client-request-id\");\n return parameter && parameter.length ? parameter[1] || noCorrelationId : noCorrelationId;\n }\n\n // The MSAL network module methods follow\n\n async sendGetRequestAsync<T>(\n url: string,\n options?: NetworkRequestOptions,\n ): Promise<NetworkResponse<T>> {\n const request = createPipelineRequest({\n url,\n method: \"GET\",\n body: options?.body,\n allowInsecureConnection: this.allowInsecureConnection,\n headers: createHttpHeaders(options?.headers),\n abortSignal: this.generateAbortSignal(noCorrelationId),\n });\n\n const response = await this.sendRequest(request);\n\n this.logIdentifiers(response);\n\n return {\n body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,\n headers: response.headers.toJSON(),\n status: response.status,\n };\n }\n\n async sendPostRequestAsync<T>(\n url: string,\n options?: NetworkRequestOptions,\n ): Promise<NetworkResponse<T>> {\n const request = createPipelineRequest({\n url,\n method: \"POST\",\n body: options?.body,\n headers: createHttpHeaders(options?.headers),\n allowInsecureConnection: this.allowInsecureConnection,\n // MSAL doesn't send the correlation ID on the get requests.\n abortSignal: this.generateAbortSignal(this.getCorrelationId(options)),\n });\n\n const response = await this.sendRequest(request);\n\n this.logIdentifiers(response);\n\n return {\n body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,\n headers: response.headers.toJSON(),\n status: response.status,\n };\n }\n\n /**\n *\n * @internal\n */\n getTokenCredentialOptions(): TokenCredentialOptions {\n return this.tokenCredentialOptions;\n }\n /**\n * If allowLoggingAccountIdentifiers was set on the constructor options\n * we try to log the account identifiers by parsing the received access token.\n *\n * The account identifiers we try to log are:\n * - `appid`: The application or Client Identifier.\n * - `upn`: User Principal Name.\n * - It might not be available in some authentication scenarios.\n * - If it's not available, we put a placeholder: \"No User Principal Name available\".\n * - `tid`: Tenant Identifier.\n * - `oid`: Object Identifier of the authenticated user.\n */\n private logIdentifiers(response: PipelineResponse): void {\n if (!this.allowLoggingAccountIdentifiers || !response.bodyAsText) {\n return;\n }\n const unavailableUpn = \"No User Principal Name available\";\n try {\n const parsed = (response as any).parsedBody || JSON.parse(response.bodyAsText);\n const accessToken = parsed.access_token;\n if (!accessToken) {\n // Without an access token allowLoggingAccountIdentifiers isn't useful.\n return;\n }\n const base64Metadata = accessToken.split(\".\")[1];\n const { appid, upn, tid, oid } = JSON.parse(\n Buffer.from(base64Metadata, \"base64\").toString(\"utf8\"),\n );\n\n logger.info(\n `[Authenticated account] Client ID: ${appid}. Tenant ID: ${tid}. User Principal Name: ${\n upn || unavailableUpn\n }. Object ID (user): ${oid}`,\n );\n } catch (e: any) {\n logger.warning(\n \"allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:\",\n e.message,\n );\n }\n }\n}\n"]}
1
+ {"version":3,"file":"identityClient.js","sourceRoot":"","sources":["../../../src/client/identityClient.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { INetworkModule, NetworkRequestOptions, NetworkResponse } from \"@azure/msal-node\";\nimport type { AccessToken, GetTokenOptions } from \"@azure/core-auth\";\nimport { ServiceClient } from \"@azure/core-client\";\nimport type { PipelineRequest, PipelineResponse } from \"@azure/core-rest-pipeline\";\nimport { createHttpHeaders, createPipelineRequest } from \"@azure/core-rest-pipeline\";\nimport type { AbortSignalLike } from \"@azure/abort-controller\";\nimport { AuthenticationError, AuthenticationErrorName } from \"../errors.js\";\nimport { getIdentityTokenEndpointSuffix } from \"../util/identityTokenEndpoint.js\";\nimport { SDK_VERSION } from \"../constants.js\";\nimport { tracingClient } from \"../util/tracing.js\";\nimport { logger } from \"../util/logging.js\";\nimport type { TokenCredentialOptions } from \"../tokenCredentialOptions.js\";\nimport type { TokenResponseParsedBody } from \"../credentials/managedIdentityCredential/utils.js\";\nimport {\n parseExpirationTimestamp,\n parseRefreshTimestamp,\n} from \"../credentials/managedIdentityCredential/utils.js\";\nimport { getAuthorityHost } from \"../util/authorityHost.js\";\n\nconst noCorrelationId = \"noCorrelationId\";\nconst HttpStatus = {\n CLIENT_ERROR_RANGE_START: 400,\n CLIENT_ERROR_RANGE_END: 499,\n SERVER_ERROR_RANGE_START: 500,\n SERVER_ERROR_RANGE_END: 599,\n};\n\n/**\n * An internal type used to communicate details of a token request's\n * response that should not be sent back as part of the access token.\n */\nexport interface TokenResponse {\n /**\n * The AccessToken to be returned from getToken.\n */\n accessToken: AccessToken;\n /**\n * The refresh token if the 'offline_access' scope was used.\n */\n refreshToken?: string;\n}\n\n/**\n * The network module used by the Identity credentials.\n *\n * It allows for credentials to abort any pending request independently of the MSAL flow,\n * by calling to the `abortRequests()` method.\n *\n */\nexport class IdentityClient extends ServiceClient implements INetworkModule {\n public authorityHost: string;\n private allowLoggingAccountIdentifiers?: boolean;\n private abortControllers: Map<string, AbortController[] | undefined>;\n private allowInsecureConnection: boolean = false;\n // used for WorkloadIdentity\n private tokenCredentialOptions: TokenCredentialOptions;\n\n constructor(options?: TokenCredentialOptions) {\n const packageDetails = `azsdk-js-identity/${SDK_VERSION}`;\n const userAgentPrefix = options?.userAgentOptions?.userAgentPrefix\n ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`\n : `${packageDetails}`;\n\n const baseUri = getAuthorityHost(options);\n if (!baseUri.startsWith(\"https:\")) {\n throw new Error(\"The authorityHost address must use the 'https' protocol.\");\n }\n\n super({\n requestContentType: \"application/json; charset=utf-8\",\n retryOptions: {\n maxRetries: 3,\n },\n ...options,\n userAgentOptions: {\n userAgentPrefix,\n },\n baseUri,\n });\n\n this.authorityHost = baseUri;\n this.abortControllers = new Map();\n this.allowLoggingAccountIdentifiers = options?.loggingOptions?.allowLoggingAccountIdentifiers;\n // used for WorkloadIdentity\n this.tokenCredentialOptions = { ...options };\n\n // used for ManagedIdentity\n if (options?.allowInsecureConnection) {\n this.allowInsecureConnection = options.allowInsecureConnection;\n }\n }\n\n async sendTokenRequest(request: PipelineRequest): Promise<TokenResponse | null> {\n logger.info(`IdentityClient: sending token request to [${request.url}]`);\n const response = await this.sendRequest(request);\n if (response.bodyAsText && (response.status === 200 || response.status === 201)) {\n const parsedBody: TokenResponseParsedBody = JSON.parse(response.bodyAsText);\n\n if (!parsedBody.access_token) {\n return null;\n }\n\n this.logIdentifiers(response);\n\n const token = {\n accessToken: {\n token: parsedBody.access_token,\n expiresOnTimestamp: parseExpirationTimestamp(parsedBody),\n refreshAfterTimestamp: parseRefreshTimestamp(parsedBody),\n tokenType: \"Bearer\",\n } as AccessToken,\n refreshToken: parsedBody.refresh_token,\n };\n\n logger.info(\n `IdentityClient: [${request.url}] token acquired, expires on ${token.accessToken.expiresOnTimestamp}`,\n );\n return token;\n } else {\n const error = new AuthenticationError(response.status, response.bodyAsText);\n logger.warning(\n `IdentityClient: authentication error. HTTP status: ${response.status}, ${error.errorResponse.errorDescription}`,\n );\n throw error;\n }\n }\n\n async refreshAccessToken(\n tenantId: string,\n clientId: string,\n scopes: string,\n refreshToken: string | undefined,\n clientSecret: string | undefined,\n options: GetTokenOptions = {},\n ): Promise<TokenResponse | null> {\n if (refreshToken === undefined) {\n return null;\n }\n logger.info(\n `IdentityClient: refreshing access token with client ID: ${clientId}, scopes: ${scopes} started`,\n );\n\n const refreshParams = {\n grant_type: \"refresh_token\",\n client_id: clientId,\n refresh_token: refreshToken,\n scope: scopes,\n };\n\n if (clientSecret !== undefined) {\n (refreshParams as any).client_secret = clientSecret;\n }\n\n const query = new URLSearchParams(refreshParams);\n\n return tracingClient.withSpan(\n \"IdentityClient.refreshAccessToken\",\n options,\n async (updatedOptions) => {\n try {\n const urlSuffix = getIdentityTokenEndpointSuffix(tenantId);\n const request = createPipelineRequest({\n url: `${this.authorityHost}/${tenantId}/${urlSuffix}`,\n method: \"POST\",\n body: query.toString(),\n abortSignal: options.abortSignal,\n headers: createHttpHeaders({\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n }),\n tracingOptions: updatedOptions.tracingOptions,\n });\n\n const response = await this.sendTokenRequest(request);\n logger.info(`IdentityClient: refreshed token for client ID: ${clientId}`);\n return response;\n } catch (err: any) {\n if (\n err.name === AuthenticationErrorName &&\n err.errorResponse.error === \"interaction_required\"\n ) {\n // It's likely that the refresh token has expired, so\n // return null so that the credential implementation will\n // initiate the authentication flow again.\n logger.info(`IdentityClient: interaction required for client ID: ${clientId}`);\n return null;\n } else {\n logger.warning(\n `IdentityClient: failed refreshing token for client ID: ${clientId}: ${err}`,\n );\n throw err;\n }\n }\n },\n );\n }\n\n // Here is a custom layer that allows us to abort requests that go through MSAL,\n // since MSAL doesn't allow us to pass options all the way through.\n\n generateAbortSignal(correlationId: string): AbortSignalLike {\n const controller = new AbortController();\n const controllers = this.abortControllers.get(correlationId) || [];\n controllers.push(controller);\n this.abortControllers.set(correlationId, controllers);\n const existingOnAbort = controller.signal.onabort;\n controller.signal.onabort = (...params) => {\n this.abortControllers.set(correlationId, undefined);\n if (existingOnAbort) {\n existingOnAbort.apply(controller.signal, params);\n }\n };\n return controller.signal;\n }\n\n abortRequests(correlationId?: string): void {\n const key = correlationId || noCorrelationId;\n const controllers = [\n ...(this.abortControllers.get(key) || []),\n // MSAL passes no correlation ID to the get requests...\n ...(this.abortControllers.get(noCorrelationId) || []),\n ];\n if (!controllers.length) {\n return;\n }\n for (const controller of controllers) {\n controller.abort();\n }\n this.abortControllers.set(key, undefined);\n }\n\n getCorrelationId(options?: NetworkRequestOptions): string {\n const parameter = options?.body\n ?.split(\"&\")\n .map((part) => part.split(\"=\"))\n .find(([key]) => key === \"client-request-id\");\n return parameter && parameter.length ? parameter[1] || noCorrelationId : noCorrelationId;\n }\n\n // The MSAL network module methods follow\n\n async sendGetRequestAsync<T>(\n url: string,\n options?: NetworkRequestOptions,\n ): Promise<NetworkResponse<T>> {\n const request = createPipelineRequest({\n url,\n method: \"GET\",\n body: options?.body,\n allowInsecureConnection: this.allowInsecureConnection,\n headers: createHttpHeaders(options?.headers),\n abortSignal: this.generateAbortSignal(noCorrelationId),\n });\n\n const response = await this.sendRequest(request);\n\n this.logIdentifiers(response);\n\n return {\n body: this.parseResponseBody(response) as T,\n headers: response.headers.toJSON(),\n status: response.status,\n };\n }\n\n async sendPostRequestAsync<T>(\n url: string,\n options?: NetworkRequestOptions,\n ): Promise<NetworkResponse<T>> {\n const request = createPipelineRequest({\n url,\n method: \"POST\",\n body: options?.body,\n headers: createHttpHeaders(options?.headers),\n allowInsecureConnection: this.allowInsecureConnection,\n // MSAL doesn't send the correlation ID on the get requests.\n abortSignal: this.generateAbortSignal(this.getCorrelationId(options)),\n });\n\n const response = await this.sendRequest(request);\n\n this.logIdentifiers(response);\n\n return {\n body: this.parseResponseBody(response) as T,\n headers: response.headers.toJSON(),\n status: response.status,\n };\n }\n\n /**\n *\n * @internal\n */\n getTokenCredentialOptions(): TokenCredentialOptions {\n return this.tokenCredentialOptions;\n }\n /**\n * If allowLoggingAccountIdentifiers was set on the constructor options\n * we try to log the account identifiers by parsing the received access token.\n *\n * The account identifiers we try to log are:\n * - `appid`: The application or Client Identifier.\n * - `upn`: User Principal Name.\n * - It might not be available in some authentication scenarios.\n * - If it's not available, we put a placeholder: \"No User Principal Name available\".\n * - `tid`: Tenant Identifier.\n * - `oid`: Object Identifier of the authenticated user.\n */\n private logIdentifiers(response: PipelineResponse): void {\n if (!this.allowLoggingAccountIdentifiers || !response.bodyAsText) {\n return;\n }\n const unavailableUpn = \"No User Principal Name available\";\n try {\n const parsed = (response as any).parsedBody || JSON.parse(response.bodyAsText);\n const accessToken = parsed.access_token;\n if (!accessToken) {\n // Without an access token allowLoggingAccountIdentifiers isn't useful.\n return;\n }\n const base64Metadata = accessToken.split(\".\")[1];\n const { appid, upn, tid, oid } = JSON.parse(\n Buffer.from(base64Metadata, \"base64\").toString(\"utf8\"),\n );\n\n logger.info(\n `[Authenticated account] Client ID: ${appid}. Tenant ID: ${tid}. User Principal Name: ${\n upn || unavailableUpn\n }. Object ID (user): ${oid}`,\n );\n } catch (e: any) {\n logger.warning(\n \"allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:\",\n e.message,\n );\n }\n }\n\n /**\n * Parses the response body if possible. Add error properties if parsing fails.\n * This follows MSAL INetworkModule behavior so the response is in expected format.\n */\n private parseResponseBody(response: PipelineResponse) {\n let parsedBody: {};\n try {\n parsedBody = JSON.parse(response.bodyAsText || \"\");\n } catch (error) {\n logger.info(`IdentityClient: Could not parse response body: ${error}`);\n let errorType;\n let errorDescriptionHelper;\n /**\n * Determine error type based on status code ranges following MSAL patterns:\n * Client error responses (400 – 499)\n * Server error responses (500 – 599)\n */\n if (\n response.status >= HttpStatus.CLIENT_ERROR_RANGE_START &&\n response.status <= HttpStatus.CLIENT_ERROR_RANGE_END\n ) {\n errorType = \"client_error\";\n errorDescriptionHelper = \"A client\";\n } else if (\n response.status >= HttpStatus.SERVER_ERROR_RANGE_START &&\n response.status <= HttpStatus.SERVER_ERROR_RANGE_END\n ) {\n errorType = \"server_error\";\n errorDescriptionHelper = \"A server\";\n } else {\n errorType = \"unknown_error\";\n errorDescriptionHelper = \"An unknown\";\n }\n\n const errorDescriptionLines = [\n `${errorDescriptionHelper} error occured.`,\n `Http status code: ${response.status}`,\n `Http status message: ${response.bodyAsText || \"Unknown\"}`,\n `Headers: ${JSON.stringify(response.headers)}`,\n ];\n parsedBody = {\n error: errorType,\n error_description: errorDescriptionLines.join(\"\\n\"),\n };\n }\n return parsedBody;\n }\n}\n"]}
@@ -57,5 +57,10 @@ export declare class IdentityClient extends ServiceClient implements INetworkMod
57
57
  * - `oid`: Object Identifier of the authenticated user.
58
58
  */
59
59
  private logIdentifiers;
60
+ /**
61
+ * Parses the response body if possible. Add error properties if parsing fails.
62
+ * This follows MSAL INetworkModule behavior so the response is in expected format.
63
+ */
64
+ private parseResponseBody;
60
65
  }
61
66
  //# sourceMappingURL=identityClient.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"identityClient.d.ts","sourceRoot":"","sources":["../../../src/client/identityClient.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,2BAA2B,CAAC;AAEnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAM/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAU3E;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,WAAW,EAAE,WAAW,CAAC;IACzB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,aAAc,YAAW,cAAc;IAClE,aAAa,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,8BAA8B,CAAC,CAAU;IACjD,OAAO,CAAC,gBAAgB,CAA6C;IACrE,OAAO,CAAC,uBAAuB,CAAkB;IAEjD,OAAO,CAAC,sBAAsB,CAAyB;gBAE3C,OAAO,CAAC,EAAE,sBAAsB;IAmCtC,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAmCzE,kBAAkB,CACtB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAkEhC,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,eAAe;IAe3D,aAAa,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI;IAgB3C,gBAAgB,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM;IAUnD,mBAAmB,CAAC,CAAC,EACzB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAqBxB,oBAAoB,CAAC,CAAC,EAC1B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAsB9B;;;OAGG;IACH,yBAAyB,IAAI,sBAAsB;IAGnD;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,cAAc;CA6BvB"}
1
+ {"version":3,"file":"identityClient.d.ts","sourceRoot":"","sources":["../../../src/client/identityClient.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,2BAA2B,CAAC;AAEnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAM/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAgB3E;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,WAAW,EAAE,WAAW,CAAC;IACzB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,aAAc,YAAW,cAAc;IAClE,aAAa,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,8BAA8B,CAAC,CAAU;IACjD,OAAO,CAAC,gBAAgB,CAA6C;IACrE,OAAO,CAAC,uBAAuB,CAAkB;IAEjD,OAAO,CAAC,sBAAsB,CAAyB;gBAE3C,OAAO,CAAC,EAAE,sBAAsB;IAmCtC,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAmCzE,kBAAkB,CACtB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAkEhC,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,eAAe;IAe3D,aAAa,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI;IAgB3C,gBAAgB,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM;IAUnD,mBAAmB,CAAC,CAAC,EACzB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAqBxB,oBAAoB,CAAC,CAAC,EAC1B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAsB9B;;;OAGG;IACH,yBAAyB,IAAI,sBAAsB;IAGnD;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,cAAc;IA8BtB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;CA2C1B"}
@@ -13,6 +13,12 @@ const logging_js_1 = require("../util/logging.js");
13
13
  const utils_js_1 = require("../credentials/managedIdentityCredential/utils.js");
14
14
  const authorityHost_js_1 = require("../util/authorityHost.js");
15
15
  const noCorrelationId = "noCorrelationId";
16
+ const HttpStatus = {
17
+ CLIENT_ERROR_RANGE_START: 400,
18
+ CLIENT_ERROR_RANGE_END: 499,
19
+ SERVER_ERROR_RANGE_START: 500,
20
+ SERVER_ERROR_RANGE_END: 599,
21
+ };
16
22
  /**
17
23
  * The network module used by the Identity credentials.
18
24
  *
@@ -184,7 +190,7 @@ class IdentityClient extends core_client_1.ServiceClient {
184
190
  const response = await this.sendRequest(request);
185
191
  this.logIdentifiers(response);
186
192
  return {
187
- body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,
193
+ body: this.parseResponseBody(response),
188
194
  headers: response.headers.toJSON(),
189
195
  status: response.status,
190
196
  };
@@ -202,7 +208,7 @@ class IdentityClient extends core_client_1.ServiceClient {
202
208
  const response = await this.sendRequest(request);
203
209
  this.logIdentifiers(response);
204
210
  return {
205
- body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,
211
+ body: this.parseResponseBody(response),
206
212
  headers: response.headers.toJSON(),
207
213
  status: response.status,
208
214
  };
@@ -246,6 +252,51 @@ class IdentityClient extends core_client_1.ServiceClient {
246
252
  logging_js_1.logger.warning("allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:", e.message);
247
253
  }
248
254
  }
255
+ /**
256
+ * Parses the response body if possible. Add error properties if parsing fails.
257
+ * This follows MSAL INetworkModule behavior so the response is in expected format.
258
+ */
259
+ parseResponseBody(response) {
260
+ let parsedBody;
261
+ try {
262
+ parsedBody = JSON.parse(response.bodyAsText || "");
263
+ }
264
+ catch (error) {
265
+ logging_js_1.logger.info(`IdentityClient: Could not parse response body: ${error}`);
266
+ let errorType;
267
+ let errorDescriptionHelper;
268
+ /**
269
+ * Determine error type based on status code ranges following MSAL patterns:
270
+ * Client error responses (400 – 499)
271
+ * Server error responses (500 – 599)
272
+ */
273
+ if (response.status >= HttpStatus.CLIENT_ERROR_RANGE_START &&
274
+ response.status <= HttpStatus.CLIENT_ERROR_RANGE_END) {
275
+ errorType = "client_error";
276
+ errorDescriptionHelper = "A client";
277
+ }
278
+ else if (response.status >= HttpStatus.SERVER_ERROR_RANGE_START &&
279
+ response.status <= HttpStatus.SERVER_ERROR_RANGE_END) {
280
+ errorType = "server_error";
281
+ errorDescriptionHelper = "A server";
282
+ }
283
+ else {
284
+ errorType = "unknown_error";
285
+ errorDescriptionHelper = "An unknown";
286
+ }
287
+ const errorDescriptionLines = [
288
+ `${errorDescriptionHelper} error occured.`,
289
+ `Http status code: ${response.status}`,
290
+ `Http status message: ${response.bodyAsText || "Unknown"}`,
291
+ `Headers: ${JSON.stringify(response.headers)}`,
292
+ ];
293
+ parsedBody = {
294
+ error: errorType,
295
+ error_description: errorDescriptionLines.join("\n"),
296
+ };
297
+ }
298
+ return parsedBody;
299
+ }
249
300
  }
250
301
  exports.IdentityClient = IdentityClient;
251
302
  //# sourceMappingURL=identityClient.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"identityClient.js","sourceRoot":"","sources":["../../../src/client/identityClient.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { INetworkModule, NetworkRequestOptions, NetworkResponse } from \"@azure/msal-node\";\nimport type { AccessToken, GetTokenOptions } from \"@azure/core-auth\";\nimport { ServiceClient } from \"@azure/core-client\";\nimport type { PipelineRequest, PipelineResponse } from \"@azure/core-rest-pipeline\";\nimport { createHttpHeaders, createPipelineRequest } from \"@azure/core-rest-pipeline\";\nimport type { AbortSignalLike } from \"@azure/abort-controller\";\nimport { AuthenticationError, AuthenticationErrorName } from \"../errors.js\";\nimport { getIdentityTokenEndpointSuffix } from \"../util/identityTokenEndpoint.js\";\nimport { SDK_VERSION } from \"../constants.js\";\nimport { tracingClient } from \"../util/tracing.js\";\nimport { logger } from \"../util/logging.js\";\nimport type { TokenCredentialOptions } from \"../tokenCredentialOptions.js\";\nimport type { TokenResponseParsedBody } from \"../credentials/managedIdentityCredential/utils.js\";\nimport {\n parseExpirationTimestamp,\n parseRefreshTimestamp,\n} from \"../credentials/managedIdentityCredential/utils.js\";\nimport { getAuthorityHost } from \"../util/authorityHost.js\";\n\nconst noCorrelationId = \"noCorrelationId\";\n\n/**\n * An internal type used to communicate details of a token request's\n * response that should not be sent back as part of the access token.\n */\nexport interface TokenResponse {\n /**\n * The AccessToken to be returned from getToken.\n */\n accessToken: AccessToken;\n /**\n * The refresh token if the 'offline_access' scope was used.\n */\n refreshToken?: string;\n}\n\n/**\n * The network module used by the Identity credentials.\n *\n * It allows for credentials to abort any pending request independently of the MSAL flow,\n * by calling to the `abortRequests()` method.\n *\n */\nexport class IdentityClient extends ServiceClient implements INetworkModule {\n public authorityHost: string;\n private allowLoggingAccountIdentifiers?: boolean;\n private abortControllers: Map<string, AbortController[] | undefined>;\n private allowInsecureConnection: boolean = false;\n // used for WorkloadIdentity\n private tokenCredentialOptions: TokenCredentialOptions;\n\n constructor(options?: TokenCredentialOptions) {\n const packageDetails = `azsdk-js-identity/${SDK_VERSION}`;\n const userAgentPrefix = options?.userAgentOptions?.userAgentPrefix\n ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`\n : `${packageDetails}`;\n\n const baseUri = getAuthorityHost(options);\n if (!baseUri.startsWith(\"https:\")) {\n throw new Error(\"The authorityHost address must use the 'https' protocol.\");\n }\n\n super({\n requestContentType: \"application/json; charset=utf-8\",\n retryOptions: {\n maxRetries: 3,\n },\n ...options,\n userAgentOptions: {\n userAgentPrefix,\n },\n baseUri,\n });\n\n this.authorityHost = baseUri;\n this.abortControllers = new Map();\n this.allowLoggingAccountIdentifiers = options?.loggingOptions?.allowLoggingAccountIdentifiers;\n // used for WorkloadIdentity\n this.tokenCredentialOptions = { ...options };\n\n // used for ManagedIdentity\n if (options?.allowInsecureConnection) {\n this.allowInsecureConnection = options.allowInsecureConnection;\n }\n }\n\n async sendTokenRequest(request: PipelineRequest): Promise<TokenResponse | null> {\n logger.info(`IdentityClient: sending token request to [${request.url}]`);\n const response = await this.sendRequest(request);\n if (response.bodyAsText && (response.status === 200 || response.status === 201)) {\n const parsedBody: TokenResponseParsedBody = JSON.parse(response.bodyAsText);\n\n if (!parsedBody.access_token) {\n return null;\n }\n\n this.logIdentifiers(response);\n\n const token = {\n accessToken: {\n token: parsedBody.access_token,\n expiresOnTimestamp: parseExpirationTimestamp(parsedBody),\n refreshAfterTimestamp: parseRefreshTimestamp(parsedBody),\n tokenType: \"Bearer\",\n } as AccessToken,\n refreshToken: parsedBody.refresh_token,\n };\n\n logger.info(\n `IdentityClient: [${request.url}] token acquired, expires on ${token.accessToken.expiresOnTimestamp}`,\n );\n return token;\n } else {\n const error = new AuthenticationError(response.status, response.bodyAsText);\n logger.warning(\n `IdentityClient: authentication error. HTTP status: ${response.status}, ${error.errorResponse.errorDescription}`,\n );\n throw error;\n }\n }\n\n async refreshAccessToken(\n tenantId: string,\n clientId: string,\n scopes: string,\n refreshToken: string | undefined,\n clientSecret: string | undefined,\n options: GetTokenOptions = {},\n ): Promise<TokenResponse | null> {\n if (refreshToken === undefined) {\n return null;\n }\n logger.info(\n `IdentityClient: refreshing access token with client ID: ${clientId}, scopes: ${scopes} started`,\n );\n\n const refreshParams = {\n grant_type: \"refresh_token\",\n client_id: clientId,\n refresh_token: refreshToken,\n scope: scopes,\n };\n\n if (clientSecret !== undefined) {\n (refreshParams as any).client_secret = clientSecret;\n }\n\n const query = new URLSearchParams(refreshParams);\n\n return tracingClient.withSpan(\n \"IdentityClient.refreshAccessToken\",\n options,\n async (updatedOptions) => {\n try {\n const urlSuffix = getIdentityTokenEndpointSuffix(tenantId);\n const request = createPipelineRequest({\n url: `${this.authorityHost}/${tenantId}/${urlSuffix}`,\n method: \"POST\",\n body: query.toString(),\n abortSignal: options.abortSignal,\n headers: createHttpHeaders({\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n }),\n tracingOptions: updatedOptions.tracingOptions,\n });\n\n const response = await this.sendTokenRequest(request);\n logger.info(`IdentityClient: refreshed token for client ID: ${clientId}`);\n return response;\n } catch (err: any) {\n if (\n err.name === AuthenticationErrorName &&\n err.errorResponse.error === \"interaction_required\"\n ) {\n // It's likely that the refresh token has expired, so\n // return null so that the credential implementation will\n // initiate the authentication flow again.\n logger.info(`IdentityClient: interaction required for client ID: ${clientId}`);\n return null;\n } else {\n logger.warning(\n `IdentityClient: failed refreshing token for client ID: ${clientId}: ${err}`,\n );\n throw err;\n }\n }\n },\n );\n }\n\n // Here is a custom layer that allows us to abort requests that go through MSAL,\n // since MSAL doesn't allow us to pass options all the way through.\n\n generateAbortSignal(correlationId: string): AbortSignalLike {\n const controller = new AbortController();\n const controllers = this.abortControllers.get(correlationId) || [];\n controllers.push(controller);\n this.abortControllers.set(correlationId, controllers);\n const existingOnAbort = controller.signal.onabort;\n controller.signal.onabort = (...params) => {\n this.abortControllers.set(correlationId, undefined);\n if (existingOnAbort) {\n existingOnAbort.apply(controller.signal, params);\n }\n };\n return controller.signal;\n }\n\n abortRequests(correlationId?: string): void {\n const key = correlationId || noCorrelationId;\n const controllers = [\n ...(this.abortControllers.get(key) || []),\n // MSAL passes no correlation ID to the get requests...\n ...(this.abortControllers.get(noCorrelationId) || []),\n ];\n if (!controllers.length) {\n return;\n }\n for (const controller of controllers) {\n controller.abort();\n }\n this.abortControllers.set(key, undefined);\n }\n\n getCorrelationId(options?: NetworkRequestOptions): string {\n const parameter = options?.body\n ?.split(\"&\")\n .map((part) => part.split(\"=\"))\n .find(([key]) => key === \"client-request-id\");\n return parameter && parameter.length ? parameter[1] || noCorrelationId : noCorrelationId;\n }\n\n // The MSAL network module methods follow\n\n async sendGetRequestAsync<T>(\n url: string,\n options?: NetworkRequestOptions,\n ): Promise<NetworkResponse<T>> {\n const request = createPipelineRequest({\n url,\n method: \"GET\",\n body: options?.body,\n allowInsecureConnection: this.allowInsecureConnection,\n headers: createHttpHeaders(options?.headers),\n abortSignal: this.generateAbortSignal(noCorrelationId),\n });\n\n const response = await this.sendRequest(request);\n\n this.logIdentifiers(response);\n\n return {\n body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,\n headers: response.headers.toJSON(),\n status: response.status,\n };\n }\n\n async sendPostRequestAsync<T>(\n url: string,\n options?: NetworkRequestOptions,\n ): Promise<NetworkResponse<T>> {\n const request = createPipelineRequest({\n url,\n method: \"POST\",\n body: options?.body,\n headers: createHttpHeaders(options?.headers),\n allowInsecureConnection: this.allowInsecureConnection,\n // MSAL doesn't send the correlation ID on the get requests.\n abortSignal: this.generateAbortSignal(this.getCorrelationId(options)),\n });\n\n const response = await this.sendRequest(request);\n\n this.logIdentifiers(response);\n\n return {\n body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,\n headers: response.headers.toJSON(),\n status: response.status,\n };\n }\n\n /**\n *\n * @internal\n */\n getTokenCredentialOptions(): TokenCredentialOptions {\n return this.tokenCredentialOptions;\n }\n /**\n * If allowLoggingAccountIdentifiers was set on the constructor options\n * we try to log the account identifiers by parsing the received access token.\n *\n * The account identifiers we try to log are:\n * - `appid`: The application or Client Identifier.\n * - `upn`: User Principal Name.\n * - It might not be available in some authentication scenarios.\n * - If it's not available, we put a placeholder: \"No User Principal Name available\".\n * - `tid`: Tenant Identifier.\n * - `oid`: Object Identifier of the authenticated user.\n */\n private logIdentifiers(response: PipelineResponse): void {\n if (!this.allowLoggingAccountIdentifiers || !response.bodyAsText) {\n return;\n }\n const unavailableUpn = \"No User Principal Name available\";\n try {\n const parsed = (response as any).parsedBody || JSON.parse(response.bodyAsText);\n const accessToken = parsed.access_token;\n if (!accessToken) {\n // Without an access token allowLoggingAccountIdentifiers isn't useful.\n return;\n }\n const base64Metadata = accessToken.split(\".\")[1];\n const { appid, upn, tid, oid } = JSON.parse(\n Buffer.from(base64Metadata, \"base64\").toString(\"utf8\"),\n );\n\n logger.info(\n `[Authenticated account] Client ID: ${appid}. Tenant ID: ${tid}. User Principal Name: ${\n upn || unavailableUpn\n }. Object ID (user): ${oid}`,\n );\n } catch (e: any) {\n logger.warning(\n \"allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:\",\n e.message,\n );\n }\n }\n}\n"]}
1
+ {"version":3,"file":"identityClient.js","sourceRoot":"","sources":["../../../src/client/identityClient.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { INetworkModule, NetworkRequestOptions, NetworkResponse } from \"@azure/msal-node\";\nimport type { AccessToken, GetTokenOptions } from \"@azure/core-auth\";\nimport { ServiceClient } from \"@azure/core-client\";\nimport type { PipelineRequest, PipelineResponse } from \"@azure/core-rest-pipeline\";\nimport { createHttpHeaders, createPipelineRequest } from \"@azure/core-rest-pipeline\";\nimport type { AbortSignalLike } from \"@azure/abort-controller\";\nimport { AuthenticationError, AuthenticationErrorName } from \"../errors.js\";\nimport { getIdentityTokenEndpointSuffix } from \"../util/identityTokenEndpoint.js\";\nimport { SDK_VERSION } from \"../constants.js\";\nimport { tracingClient } from \"../util/tracing.js\";\nimport { logger } from \"../util/logging.js\";\nimport type { TokenCredentialOptions } from \"../tokenCredentialOptions.js\";\nimport type { TokenResponseParsedBody } from \"../credentials/managedIdentityCredential/utils.js\";\nimport {\n parseExpirationTimestamp,\n parseRefreshTimestamp,\n} from \"../credentials/managedIdentityCredential/utils.js\";\nimport { getAuthorityHost } from \"../util/authorityHost.js\";\n\nconst noCorrelationId = \"noCorrelationId\";\nconst HttpStatus = {\n CLIENT_ERROR_RANGE_START: 400,\n CLIENT_ERROR_RANGE_END: 499,\n SERVER_ERROR_RANGE_START: 500,\n SERVER_ERROR_RANGE_END: 599,\n};\n\n/**\n * An internal type used to communicate details of a token request's\n * response that should not be sent back as part of the access token.\n */\nexport interface TokenResponse {\n /**\n * The AccessToken to be returned from getToken.\n */\n accessToken: AccessToken;\n /**\n * The refresh token if the 'offline_access' scope was used.\n */\n refreshToken?: string;\n}\n\n/**\n * The network module used by the Identity credentials.\n *\n * It allows for credentials to abort any pending request independently of the MSAL flow,\n * by calling to the `abortRequests()` method.\n *\n */\nexport class IdentityClient extends ServiceClient implements INetworkModule {\n public authorityHost: string;\n private allowLoggingAccountIdentifiers?: boolean;\n private abortControllers: Map<string, AbortController[] | undefined>;\n private allowInsecureConnection: boolean = false;\n // used for WorkloadIdentity\n private tokenCredentialOptions: TokenCredentialOptions;\n\n constructor(options?: TokenCredentialOptions) {\n const packageDetails = `azsdk-js-identity/${SDK_VERSION}`;\n const userAgentPrefix = options?.userAgentOptions?.userAgentPrefix\n ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`\n : `${packageDetails}`;\n\n const baseUri = getAuthorityHost(options);\n if (!baseUri.startsWith(\"https:\")) {\n throw new Error(\"The authorityHost address must use the 'https' protocol.\");\n }\n\n super({\n requestContentType: \"application/json; charset=utf-8\",\n retryOptions: {\n maxRetries: 3,\n },\n ...options,\n userAgentOptions: {\n userAgentPrefix,\n },\n baseUri,\n });\n\n this.authorityHost = baseUri;\n this.abortControllers = new Map();\n this.allowLoggingAccountIdentifiers = options?.loggingOptions?.allowLoggingAccountIdentifiers;\n // used for WorkloadIdentity\n this.tokenCredentialOptions = { ...options };\n\n // used for ManagedIdentity\n if (options?.allowInsecureConnection) {\n this.allowInsecureConnection = options.allowInsecureConnection;\n }\n }\n\n async sendTokenRequest(request: PipelineRequest): Promise<TokenResponse | null> {\n logger.info(`IdentityClient: sending token request to [${request.url}]`);\n const response = await this.sendRequest(request);\n if (response.bodyAsText && (response.status === 200 || response.status === 201)) {\n const parsedBody: TokenResponseParsedBody = JSON.parse(response.bodyAsText);\n\n if (!parsedBody.access_token) {\n return null;\n }\n\n this.logIdentifiers(response);\n\n const token = {\n accessToken: {\n token: parsedBody.access_token,\n expiresOnTimestamp: parseExpirationTimestamp(parsedBody),\n refreshAfterTimestamp: parseRefreshTimestamp(parsedBody),\n tokenType: \"Bearer\",\n } as AccessToken,\n refreshToken: parsedBody.refresh_token,\n };\n\n logger.info(\n `IdentityClient: [${request.url}] token acquired, expires on ${token.accessToken.expiresOnTimestamp}`,\n );\n return token;\n } else {\n const error = new AuthenticationError(response.status, response.bodyAsText);\n logger.warning(\n `IdentityClient: authentication error. HTTP status: ${response.status}, ${error.errorResponse.errorDescription}`,\n );\n throw error;\n }\n }\n\n async refreshAccessToken(\n tenantId: string,\n clientId: string,\n scopes: string,\n refreshToken: string | undefined,\n clientSecret: string | undefined,\n options: GetTokenOptions = {},\n ): Promise<TokenResponse | null> {\n if (refreshToken === undefined) {\n return null;\n }\n logger.info(\n `IdentityClient: refreshing access token with client ID: ${clientId}, scopes: ${scopes} started`,\n );\n\n const refreshParams = {\n grant_type: \"refresh_token\",\n client_id: clientId,\n refresh_token: refreshToken,\n scope: scopes,\n };\n\n if (clientSecret !== undefined) {\n (refreshParams as any).client_secret = clientSecret;\n }\n\n const query = new URLSearchParams(refreshParams);\n\n return tracingClient.withSpan(\n \"IdentityClient.refreshAccessToken\",\n options,\n async (updatedOptions) => {\n try {\n const urlSuffix = getIdentityTokenEndpointSuffix(tenantId);\n const request = createPipelineRequest({\n url: `${this.authorityHost}/${tenantId}/${urlSuffix}`,\n method: \"POST\",\n body: query.toString(),\n abortSignal: options.abortSignal,\n headers: createHttpHeaders({\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n }),\n tracingOptions: updatedOptions.tracingOptions,\n });\n\n const response = await this.sendTokenRequest(request);\n logger.info(`IdentityClient: refreshed token for client ID: ${clientId}`);\n return response;\n } catch (err: any) {\n if (\n err.name === AuthenticationErrorName &&\n err.errorResponse.error === \"interaction_required\"\n ) {\n // It's likely that the refresh token has expired, so\n // return null so that the credential implementation will\n // initiate the authentication flow again.\n logger.info(`IdentityClient: interaction required for client ID: ${clientId}`);\n return null;\n } else {\n logger.warning(\n `IdentityClient: failed refreshing token for client ID: ${clientId}: ${err}`,\n );\n throw err;\n }\n }\n },\n );\n }\n\n // Here is a custom layer that allows us to abort requests that go through MSAL,\n // since MSAL doesn't allow us to pass options all the way through.\n\n generateAbortSignal(correlationId: string): AbortSignalLike {\n const controller = new AbortController();\n const controllers = this.abortControllers.get(correlationId) || [];\n controllers.push(controller);\n this.abortControllers.set(correlationId, controllers);\n const existingOnAbort = controller.signal.onabort;\n controller.signal.onabort = (...params) => {\n this.abortControllers.set(correlationId, undefined);\n if (existingOnAbort) {\n existingOnAbort.apply(controller.signal, params);\n }\n };\n return controller.signal;\n }\n\n abortRequests(correlationId?: string): void {\n const key = correlationId || noCorrelationId;\n const controllers = [\n ...(this.abortControllers.get(key) || []),\n // MSAL passes no correlation ID to the get requests...\n ...(this.abortControllers.get(noCorrelationId) || []),\n ];\n if (!controllers.length) {\n return;\n }\n for (const controller of controllers) {\n controller.abort();\n }\n this.abortControllers.set(key, undefined);\n }\n\n getCorrelationId(options?: NetworkRequestOptions): string {\n const parameter = options?.body\n ?.split(\"&\")\n .map((part) => part.split(\"=\"))\n .find(([key]) => key === \"client-request-id\");\n return parameter && parameter.length ? parameter[1] || noCorrelationId : noCorrelationId;\n }\n\n // The MSAL network module methods follow\n\n async sendGetRequestAsync<T>(\n url: string,\n options?: NetworkRequestOptions,\n ): Promise<NetworkResponse<T>> {\n const request = createPipelineRequest({\n url,\n method: \"GET\",\n body: options?.body,\n allowInsecureConnection: this.allowInsecureConnection,\n headers: createHttpHeaders(options?.headers),\n abortSignal: this.generateAbortSignal(noCorrelationId),\n });\n\n const response = await this.sendRequest(request);\n\n this.logIdentifiers(response);\n\n return {\n body: this.parseResponseBody(response) as T,\n headers: response.headers.toJSON(),\n status: response.status,\n };\n }\n\n async sendPostRequestAsync<T>(\n url: string,\n options?: NetworkRequestOptions,\n ): Promise<NetworkResponse<T>> {\n const request = createPipelineRequest({\n url,\n method: \"POST\",\n body: options?.body,\n headers: createHttpHeaders(options?.headers),\n allowInsecureConnection: this.allowInsecureConnection,\n // MSAL doesn't send the correlation ID on the get requests.\n abortSignal: this.generateAbortSignal(this.getCorrelationId(options)),\n });\n\n const response = await this.sendRequest(request);\n\n this.logIdentifiers(response);\n\n return {\n body: this.parseResponseBody(response) as T,\n headers: response.headers.toJSON(),\n status: response.status,\n };\n }\n\n /**\n *\n * @internal\n */\n getTokenCredentialOptions(): TokenCredentialOptions {\n return this.tokenCredentialOptions;\n }\n /**\n * If allowLoggingAccountIdentifiers was set on the constructor options\n * we try to log the account identifiers by parsing the received access token.\n *\n * The account identifiers we try to log are:\n * - `appid`: The application or Client Identifier.\n * - `upn`: User Principal Name.\n * - It might not be available in some authentication scenarios.\n * - If it's not available, we put a placeholder: \"No User Principal Name available\".\n * - `tid`: Tenant Identifier.\n * - `oid`: Object Identifier of the authenticated user.\n */\n private logIdentifiers(response: PipelineResponse): void {\n if (!this.allowLoggingAccountIdentifiers || !response.bodyAsText) {\n return;\n }\n const unavailableUpn = \"No User Principal Name available\";\n try {\n const parsed = (response as any).parsedBody || JSON.parse(response.bodyAsText);\n const accessToken = parsed.access_token;\n if (!accessToken) {\n // Without an access token allowLoggingAccountIdentifiers isn't useful.\n return;\n }\n const base64Metadata = accessToken.split(\".\")[1];\n const { appid, upn, tid, oid } = JSON.parse(\n Buffer.from(base64Metadata, \"base64\").toString(\"utf8\"),\n );\n\n logger.info(\n `[Authenticated account] Client ID: ${appid}. Tenant ID: ${tid}. User Principal Name: ${\n upn || unavailableUpn\n }. Object ID (user): ${oid}`,\n );\n } catch (e: any) {\n logger.warning(\n \"allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:\",\n e.message,\n );\n }\n }\n\n /**\n * Parses the response body if possible. Add error properties if parsing fails.\n * This follows MSAL INetworkModule behavior so the response is in expected format.\n */\n private parseResponseBody(response: PipelineResponse) {\n let parsedBody: {};\n try {\n parsedBody = JSON.parse(response.bodyAsText || \"\");\n } catch (error) {\n logger.info(`IdentityClient: Could not parse response body: ${error}`);\n let errorType;\n let errorDescriptionHelper;\n /**\n * Determine error type based on status code ranges following MSAL patterns:\n * Client error responses (400 – 499)\n * Server error responses (500 – 599)\n */\n if (\n response.status >= HttpStatus.CLIENT_ERROR_RANGE_START &&\n response.status <= HttpStatus.CLIENT_ERROR_RANGE_END\n ) {\n errorType = \"client_error\";\n errorDescriptionHelper = \"A client\";\n } else if (\n response.status >= HttpStatus.SERVER_ERROR_RANGE_START &&\n response.status <= HttpStatus.SERVER_ERROR_RANGE_END\n ) {\n errorType = \"server_error\";\n errorDescriptionHelper = \"A server\";\n } else {\n errorType = \"unknown_error\";\n errorDescriptionHelper = \"An unknown\";\n }\n\n const errorDescriptionLines = [\n `${errorDescriptionHelper} error occured.`,\n `Http status code: ${response.status}`,\n `Http status message: ${response.bodyAsText || \"Unknown\"}`,\n `Headers: ${JSON.stringify(response.headers)}`,\n ];\n parsedBody = {\n error: errorType,\n error_description: errorDescriptionLines.join(\"\\n\"),\n };\n }\n return parsedBody;\n }\n}\n"]}
@@ -57,5 +57,10 @@ export declare class IdentityClient extends ServiceClient implements INetworkMod
57
57
  * - `oid`: Object Identifier of the authenticated user.
58
58
  */
59
59
  private logIdentifiers;
60
+ /**
61
+ * Parses the response body if possible. Add error properties if parsing fails.
62
+ * This follows MSAL INetworkModule behavior so the response is in expected format.
63
+ */
64
+ private parseResponseBody;
60
65
  }
61
66
  //# sourceMappingURL=identityClient.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"identityClient.d.ts","sourceRoot":"","sources":["../../../src/client/identityClient.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,2BAA2B,CAAC;AAEnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAM/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAU3E;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,WAAW,EAAE,WAAW,CAAC;IACzB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,aAAc,YAAW,cAAc;IAClE,aAAa,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,8BAA8B,CAAC,CAAU;IACjD,OAAO,CAAC,gBAAgB,CAA6C;IACrE,OAAO,CAAC,uBAAuB,CAAkB;IAEjD,OAAO,CAAC,sBAAsB,CAAyB;gBAE3C,OAAO,CAAC,EAAE,sBAAsB;IAmCtC,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAmCzE,kBAAkB,CACtB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAkEhC,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,eAAe;IAe3D,aAAa,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI;IAgB3C,gBAAgB,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM;IAUnD,mBAAmB,CAAC,CAAC,EACzB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAqBxB,oBAAoB,CAAC,CAAC,EAC1B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAsB9B;;;OAGG;IACH,yBAAyB,IAAI,sBAAsB;IAGnD;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,cAAc;CA6BvB"}
1
+ {"version":3,"file":"identityClient.d.ts","sourceRoot":"","sources":["../../../src/client/identityClient.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,2BAA2B,CAAC;AAEnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAM/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAgB3E;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,WAAW,EAAE,WAAW,CAAC;IACzB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,aAAc,YAAW,cAAc;IAClE,aAAa,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,8BAA8B,CAAC,CAAU;IACjD,OAAO,CAAC,gBAAgB,CAA6C;IACrE,OAAO,CAAC,uBAAuB,CAAkB;IAEjD,OAAO,CAAC,sBAAsB,CAAyB;gBAE3C,OAAO,CAAC,EAAE,sBAAsB;IAmCtC,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAmCzE,kBAAkB,CACtB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAkEhC,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,eAAe;IAe3D,aAAa,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI;IAgB3C,gBAAgB,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM;IAUnD,mBAAmB,CAAC,CAAC,EACzB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAqBxB,oBAAoB,CAAC,CAAC,EAC1B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAsB9B;;;OAGG;IACH,yBAAyB,IAAI,sBAAsB;IAGnD;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,cAAc;IA8BtB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;CA2C1B"}
@@ -10,6 +10,12 @@ import { logger } from "../util/logging.js";
10
10
  import { parseExpirationTimestamp, parseRefreshTimestamp, } from "../credentials/managedIdentityCredential/utils.js";
11
11
  import { getAuthorityHost } from "../util/authorityHost.js";
12
12
  const noCorrelationId = "noCorrelationId";
13
+ const HttpStatus = {
14
+ CLIENT_ERROR_RANGE_START: 400,
15
+ CLIENT_ERROR_RANGE_END: 499,
16
+ SERVER_ERROR_RANGE_START: 500,
17
+ SERVER_ERROR_RANGE_END: 599,
18
+ };
13
19
  /**
14
20
  * The network module used by the Identity credentials.
15
21
  *
@@ -181,7 +187,7 @@ export class IdentityClient extends ServiceClient {
181
187
  const response = await this.sendRequest(request);
182
188
  this.logIdentifiers(response);
183
189
  return {
184
- body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,
190
+ body: this.parseResponseBody(response),
185
191
  headers: response.headers.toJSON(),
186
192
  status: response.status,
187
193
  };
@@ -199,7 +205,7 @@ export class IdentityClient extends ServiceClient {
199
205
  const response = await this.sendRequest(request);
200
206
  this.logIdentifiers(response);
201
207
  return {
202
- body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,
208
+ body: this.parseResponseBody(response),
203
209
  headers: response.headers.toJSON(),
204
210
  status: response.status,
205
211
  };
@@ -243,5 +249,50 @@ export class IdentityClient extends ServiceClient {
243
249
  logger.warning("allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:", e.message);
244
250
  }
245
251
  }
252
+ /**
253
+ * Parses the response body if possible. Add error properties if parsing fails.
254
+ * This follows MSAL INetworkModule behavior so the response is in expected format.
255
+ */
256
+ parseResponseBody(response) {
257
+ let parsedBody;
258
+ try {
259
+ parsedBody = JSON.parse(response.bodyAsText || "");
260
+ }
261
+ catch (error) {
262
+ logger.info(`IdentityClient: Could not parse response body: ${error}`);
263
+ let errorType;
264
+ let errorDescriptionHelper;
265
+ /**
266
+ * Determine error type based on status code ranges following MSAL patterns:
267
+ * Client error responses (400 – 499)
268
+ * Server error responses (500 – 599)
269
+ */
270
+ if (response.status >= HttpStatus.CLIENT_ERROR_RANGE_START &&
271
+ response.status <= HttpStatus.CLIENT_ERROR_RANGE_END) {
272
+ errorType = "client_error";
273
+ errorDescriptionHelper = "A client";
274
+ }
275
+ else if (response.status >= HttpStatus.SERVER_ERROR_RANGE_START &&
276
+ response.status <= HttpStatus.SERVER_ERROR_RANGE_END) {
277
+ errorType = "server_error";
278
+ errorDescriptionHelper = "A server";
279
+ }
280
+ else {
281
+ errorType = "unknown_error";
282
+ errorDescriptionHelper = "An unknown";
283
+ }
284
+ const errorDescriptionLines = [
285
+ `${errorDescriptionHelper} error occured.`,
286
+ `Http status code: ${response.status}`,
287
+ `Http status message: ${response.bodyAsText || "Unknown"}`,
288
+ `Headers: ${JSON.stringify(response.headers)}`,
289
+ ];
290
+ parsedBody = {
291
+ error: errorType,
292
+ error_description: errorDescriptionLines.join("\n"),
293
+ };
294
+ }
295
+ return parsedBody;
296
+ }
246
297
  }
247
298
  //# sourceMappingURL=identityClient.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"identityClient.js","sourceRoot":"","sources":["../../../src/client/identityClient.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { INetworkModule, NetworkRequestOptions, NetworkResponse } from \"@azure/msal-node\";\nimport type { AccessToken, GetTokenOptions } from \"@azure/core-auth\";\nimport { ServiceClient } from \"@azure/core-client\";\nimport type { PipelineRequest, PipelineResponse } from \"@azure/core-rest-pipeline\";\nimport { createHttpHeaders, createPipelineRequest } from \"@azure/core-rest-pipeline\";\nimport type { AbortSignalLike } from \"@azure/abort-controller\";\nimport { AuthenticationError, AuthenticationErrorName } from \"../errors.js\";\nimport { getIdentityTokenEndpointSuffix } from \"../util/identityTokenEndpoint.js\";\nimport { SDK_VERSION } from \"../constants.js\";\nimport { tracingClient } from \"../util/tracing.js\";\nimport { logger } from \"../util/logging.js\";\nimport type { TokenCredentialOptions } from \"../tokenCredentialOptions.js\";\nimport type { TokenResponseParsedBody } from \"../credentials/managedIdentityCredential/utils.js\";\nimport {\n parseExpirationTimestamp,\n parseRefreshTimestamp,\n} from \"../credentials/managedIdentityCredential/utils.js\";\nimport { getAuthorityHost } from \"../util/authorityHost.js\";\n\nconst noCorrelationId = \"noCorrelationId\";\n\n/**\n * An internal type used to communicate details of a token request's\n * response that should not be sent back as part of the access token.\n */\nexport interface TokenResponse {\n /**\n * The AccessToken to be returned from getToken.\n */\n accessToken: AccessToken;\n /**\n * The refresh token if the 'offline_access' scope was used.\n */\n refreshToken?: string;\n}\n\n/**\n * The network module used by the Identity credentials.\n *\n * It allows for credentials to abort any pending request independently of the MSAL flow,\n * by calling to the `abortRequests()` method.\n *\n */\nexport class IdentityClient extends ServiceClient implements INetworkModule {\n public authorityHost: string;\n private allowLoggingAccountIdentifiers?: boolean;\n private abortControllers: Map<string, AbortController[] | undefined>;\n private allowInsecureConnection: boolean = false;\n // used for WorkloadIdentity\n private tokenCredentialOptions: TokenCredentialOptions;\n\n constructor(options?: TokenCredentialOptions) {\n const packageDetails = `azsdk-js-identity/${SDK_VERSION}`;\n const userAgentPrefix = options?.userAgentOptions?.userAgentPrefix\n ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`\n : `${packageDetails}`;\n\n const baseUri = getAuthorityHost(options);\n if (!baseUri.startsWith(\"https:\")) {\n throw new Error(\"The authorityHost address must use the 'https' protocol.\");\n }\n\n super({\n requestContentType: \"application/json; charset=utf-8\",\n retryOptions: {\n maxRetries: 3,\n },\n ...options,\n userAgentOptions: {\n userAgentPrefix,\n },\n baseUri,\n });\n\n this.authorityHost = baseUri;\n this.abortControllers = new Map();\n this.allowLoggingAccountIdentifiers = options?.loggingOptions?.allowLoggingAccountIdentifiers;\n // used for WorkloadIdentity\n this.tokenCredentialOptions = { ...options };\n\n // used for ManagedIdentity\n if (options?.allowInsecureConnection) {\n this.allowInsecureConnection = options.allowInsecureConnection;\n }\n }\n\n async sendTokenRequest(request: PipelineRequest): Promise<TokenResponse | null> {\n logger.info(`IdentityClient: sending token request to [${request.url}]`);\n const response = await this.sendRequest(request);\n if (response.bodyAsText && (response.status === 200 || response.status === 201)) {\n const parsedBody: TokenResponseParsedBody = JSON.parse(response.bodyAsText);\n\n if (!parsedBody.access_token) {\n return null;\n }\n\n this.logIdentifiers(response);\n\n const token = {\n accessToken: {\n token: parsedBody.access_token,\n expiresOnTimestamp: parseExpirationTimestamp(parsedBody),\n refreshAfterTimestamp: parseRefreshTimestamp(parsedBody),\n tokenType: \"Bearer\",\n } as AccessToken,\n refreshToken: parsedBody.refresh_token,\n };\n\n logger.info(\n `IdentityClient: [${request.url}] token acquired, expires on ${token.accessToken.expiresOnTimestamp}`,\n );\n return token;\n } else {\n const error = new AuthenticationError(response.status, response.bodyAsText);\n logger.warning(\n `IdentityClient: authentication error. HTTP status: ${response.status}, ${error.errorResponse.errorDescription}`,\n );\n throw error;\n }\n }\n\n async refreshAccessToken(\n tenantId: string,\n clientId: string,\n scopes: string,\n refreshToken: string | undefined,\n clientSecret: string | undefined,\n options: GetTokenOptions = {},\n ): Promise<TokenResponse | null> {\n if (refreshToken === undefined) {\n return null;\n }\n logger.info(\n `IdentityClient: refreshing access token with client ID: ${clientId}, scopes: ${scopes} started`,\n );\n\n const refreshParams = {\n grant_type: \"refresh_token\",\n client_id: clientId,\n refresh_token: refreshToken,\n scope: scopes,\n };\n\n if (clientSecret !== undefined) {\n (refreshParams as any).client_secret = clientSecret;\n }\n\n const query = new URLSearchParams(refreshParams);\n\n return tracingClient.withSpan(\n \"IdentityClient.refreshAccessToken\",\n options,\n async (updatedOptions) => {\n try {\n const urlSuffix = getIdentityTokenEndpointSuffix(tenantId);\n const request = createPipelineRequest({\n url: `${this.authorityHost}/${tenantId}/${urlSuffix}`,\n method: \"POST\",\n body: query.toString(),\n abortSignal: options.abortSignal,\n headers: createHttpHeaders({\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n }),\n tracingOptions: updatedOptions.tracingOptions,\n });\n\n const response = await this.sendTokenRequest(request);\n logger.info(`IdentityClient: refreshed token for client ID: ${clientId}`);\n return response;\n } catch (err: any) {\n if (\n err.name === AuthenticationErrorName &&\n err.errorResponse.error === \"interaction_required\"\n ) {\n // It's likely that the refresh token has expired, so\n // return null so that the credential implementation will\n // initiate the authentication flow again.\n logger.info(`IdentityClient: interaction required for client ID: ${clientId}`);\n return null;\n } else {\n logger.warning(\n `IdentityClient: failed refreshing token for client ID: ${clientId}: ${err}`,\n );\n throw err;\n }\n }\n },\n );\n }\n\n // Here is a custom layer that allows us to abort requests that go through MSAL,\n // since MSAL doesn't allow us to pass options all the way through.\n\n generateAbortSignal(correlationId: string): AbortSignalLike {\n const controller = new AbortController();\n const controllers = this.abortControllers.get(correlationId) || [];\n controllers.push(controller);\n this.abortControllers.set(correlationId, controllers);\n const existingOnAbort = controller.signal.onabort;\n controller.signal.onabort = (...params) => {\n this.abortControllers.set(correlationId, undefined);\n if (existingOnAbort) {\n existingOnAbort.apply(controller.signal, params);\n }\n };\n return controller.signal;\n }\n\n abortRequests(correlationId?: string): void {\n const key = correlationId || noCorrelationId;\n const controllers = [\n ...(this.abortControllers.get(key) || []),\n // MSAL passes no correlation ID to the get requests...\n ...(this.abortControllers.get(noCorrelationId) || []),\n ];\n if (!controllers.length) {\n return;\n }\n for (const controller of controllers) {\n controller.abort();\n }\n this.abortControllers.set(key, undefined);\n }\n\n getCorrelationId(options?: NetworkRequestOptions): string {\n const parameter = options?.body\n ?.split(\"&\")\n .map((part) => part.split(\"=\"))\n .find(([key]) => key === \"client-request-id\");\n return parameter && parameter.length ? parameter[1] || noCorrelationId : noCorrelationId;\n }\n\n // The MSAL network module methods follow\n\n async sendGetRequestAsync<T>(\n url: string,\n options?: NetworkRequestOptions,\n ): Promise<NetworkResponse<T>> {\n const request = createPipelineRequest({\n url,\n method: \"GET\",\n body: options?.body,\n allowInsecureConnection: this.allowInsecureConnection,\n headers: createHttpHeaders(options?.headers),\n abortSignal: this.generateAbortSignal(noCorrelationId),\n });\n\n const response = await this.sendRequest(request);\n\n this.logIdentifiers(response);\n\n return {\n body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,\n headers: response.headers.toJSON(),\n status: response.status,\n };\n }\n\n async sendPostRequestAsync<T>(\n url: string,\n options?: NetworkRequestOptions,\n ): Promise<NetworkResponse<T>> {\n const request = createPipelineRequest({\n url,\n method: \"POST\",\n body: options?.body,\n headers: createHttpHeaders(options?.headers),\n allowInsecureConnection: this.allowInsecureConnection,\n // MSAL doesn't send the correlation ID on the get requests.\n abortSignal: this.generateAbortSignal(this.getCorrelationId(options)),\n });\n\n const response = await this.sendRequest(request);\n\n this.logIdentifiers(response);\n\n return {\n body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,\n headers: response.headers.toJSON(),\n status: response.status,\n };\n }\n\n /**\n *\n * @internal\n */\n getTokenCredentialOptions(): TokenCredentialOptions {\n return this.tokenCredentialOptions;\n }\n /**\n * If allowLoggingAccountIdentifiers was set on the constructor options\n * we try to log the account identifiers by parsing the received access token.\n *\n * The account identifiers we try to log are:\n * - `appid`: The application or Client Identifier.\n * - `upn`: User Principal Name.\n * - It might not be available in some authentication scenarios.\n * - If it's not available, we put a placeholder: \"No User Principal Name available\".\n * - `tid`: Tenant Identifier.\n * - `oid`: Object Identifier of the authenticated user.\n */\n private logIdentifiers(response: PipelineResponse): void {\n if (!this.allowLoggingAccountIdentifiers || !response.bodyAsText) {\n return;\n }\n const unavailableUpn = \"No User Principal Name available\";\n try {\n const parsed = (response as any).parsedBody || JSON.parse(response.bodyAsText);\n const accessToken = parsed.access_token;\n if (!accessToken) {\n // Without an access token allowLoggingAccountIdentifiers isn't useful.\n return;\n }\n const base64Metadata = accessToken.split(\".\")[1];\n const { appid, upn, tid, oid } = JSON.parse(\n Buffer.from(base64Metadata, \"base64\").toString(\"utf8\"),\n );\n\n logger.info(\n `[Authenticated account] Client ID: ${appid}. Tenant ID: ${tid}. User Principal Name: ${\n upn || unavailableUpn\n }. Object ID (user): ${oid}`,\n );\n } catch (e: any) {\n logger.warning(\n \"allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:\",\n e.message,\n );\n }\n }\n}\n"]}
1
+ {"version":3,"file":"identityClient.js","sourceRoot":"","sources":["../../../src/client/identityClient.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { INetworkModule, NetworkRequestOptions, NetworkResponse } from \"@azure/msal-node\";\nimport type { AccessToken, GetTokenOptions } from \"@azure/core-auth\";\nimport { ServiceClient } from \"@azure/core-client\";\nimport type { PipelineRequest, PipelineResponse } from \"@azure/core-rest-pipeline\";\nimport { createHttpHeaders, createPipelineRequest } from \"@azure/core-rest-pipeline\";\nimport type { AbortSignalLike } from \"@azure/abort-controller\";\nimport { AuthenticationError, AuthenticationErrorName } from \"../errors.js\";\nimport { getIdentityTokenEndpointSuffix } from \"../util/identityTokenEndpoint.js\";\nimport { SDK_VERSION } from \"../constants.js\";\nimport { tracingClient } from \"../util/tracing.js\";\nimport { logger } from \"../util/logging.js\";\nimport type { TokenCredentialOptions } from \"../tokenCredentialOptions.js\";\nimport type { TokenResponseParsedBody } from \"../credentials/managedIdentityCredential/utils.js\";\nimport {\n parseExpirationTimestamp,\n parseRefreshTimestamp,\n} from \"../credentials/managedIdentityCredential/utils.js\";\nimport { getAuthorityHost } from \"../util/authorityHost.js\";\n\nconst noCorrelationId = \"noCorrelationId\";\nconst HttpStatus = {\n CLIENT_ERROR_RANGE_START: 400,\n CLIENT_ERROR_RANGE_END: 499,\n SERVER_ERROR_RANGE_START: 500,\n SERVER_ERROR_RANGE_END: 599,\n};\n\n/**\n * An internal type used to communicate details of a token request's\n * response that should not be sent back as part of the access token.\n */\nexport interface TokenResponse {\n /**\n * The AccessToken to be returned from getToken.\n */\n accessToken: AccessToken;\n /**\n * The refresh token if the 'offline_access' scope was used.\n */\n refreshToken?: string;\n}\n\n/**\n * The network module used by the Identity credentials.\n *\n * It allows for credentials to abort any pending request independently of the MSAL flow,\n * by calling to the `abortRequests()` method.\n *\n */\nexport class IdentityClient extends ServiceClient implements INetworkModule {\n public authorityHost: string;\n private allowLoggingAccountIdentifiers?: boolean;\n private abortControllers: Map<string, AbortController[] | undefined>;\n private allowInsecureConnection: boolean = false;\n // used for WorkloadIdentity\n private tokenCredentialOptions: TokenCredentialOptions;\n\n constructor(options?: TokenCredentialOptions) {\n const packageDetails = `azsdk-js-identity/${SDK_VERSION}`;\n const userAgentPrefix = options?.userAgentOptions?.userAgentPrefix\n ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`\n : `${packageDetails}`;\n\n const baseUri = getAuthorityHost(options);\n if (!baseUri.startsWith(\"https:\")) {\n throw new Error(\"The authorityHost address must use the 'https' protocol.\");\n }\n\n super({\n requestContentType: \"application/json; charset=utf-8\",\n retryOptions: {\n maxRetries: 3,\n },\n ...options,\n userAgentOptions: {\n userAgentPrefix,\n },\n baseUri,\n });\n\n this.authorityHost = baseUri;\n this.abortControllers = new Map();\n this.allowLoggingAccountIdentifiers = options?.loggingOptions?.allowLoggingAccountIdentifiers;\n // used for WorkloadIdentity\n this.tokenCredentialOptions = { ...options };\n\n // used for ManagedIdentity\n if (options?.allowInsecureConnection) {\n this.allowInsecureConnection = options.allowInsecureConnection;\n }\n }\n\n async sendTokenRequest(request: PipelineRequest): Promise<TokenResponse | null> {\n logger.info(`IdentityClient: sending token request to [${request.url}]`);\n const response = await this.sendRequest(request);\n if (response.bodyAsText && (response.status === 200 || response.status === 201)) {\n const parsedBody: TokenResponseParsedBody = JSON.parse(response.bodyAsText);\n\n if (!parsedBody.access_token) {\n return null;\n }\n\n this.logIdentifiers(response);\n\n const token = {\n accessToken: {\n token: parsedBody.access_token,\n expiresOnTimestamp: parseExpirationTimestamp(parsedBody),\n refreshAfterTimestamp: parseRefreshTimestamp(parsedBody),\n tokenType: \"Bearer\",\n } as AccessToken,\n refreshToken: parsedBody.refresh_token,\n };\n\n logger.info(\n `IdentityClient: [${request.url}] token acquired, expires on ${token.accessToken.expiresOnTimestamp}`,\n );\n return token;\n } else {\n const error = new AuthenticationError(response.status, response.bodyAsText);\n logger.warning(\n `IdentityClient: authentication error. HTTP status: ${response.status}, ${error.errorResponse.errorDescription}`,\n );\n throw error;\n }\n }\n\n async refreshAccessToken(\n tenantId: string,\n clientId: string,\n scopes: string,\n refreshToken: string | undefined,\n clientSecret: string | undefined,\n options: GetTokenOptions = {},\n ): Promise<TokenResponse | null> {\n if (refreshToken === undefined) {\n return null;\n }\n logger.info(\n `IdentityClient: refreshing access token with client ID: ${clientId}, scopes: ${scopes} started`,\n );\n\n const refreshParams = {\n grant_type: \"refresh_token\",\n client_id: clientId,\n refresh_token: refreshToken,\n scope: scopes,\n };\n\n if (clientSecret !== undefined) {\n (refreshParams as any).client_secret = clientSecret;\n }\n\n const query = new URLSearchParams(refreshParams);\n\n return tracingClient.withSpan(\n \"IdentityClient.refreshAccessToken\",\n options,\n async (updatedOptions) => {\n try {\n const urlSuffix = getIdentityTokenEndpointSuffix(tenantId);\n const request = createPipelineRequest({\n url: `${this.authorityHost}/${tenantId}/${urlSuffix}`,\n method: \"POST\",\n body: query.toString(),\n abortSignal: options.abortSignal,\n headers: createHttpHeaders({\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n }),\n tracingOptions: updatedOptions.tracingOptions,\n });\n\n const response = await this.sendTokenRequest(request);\n logger.info(`IdentityClient: refreshed token for client ID: ${clientId}`);\n return response;\n } catch (err: any) {\n if (\n err.name === AuthenticationErrorName &&\n err.errorResponse.error === \"interaction_required\"\n ) {\n // It's likely that the refresh token has expired, so\n // return null so that the credential implementation will\n // initiate the authentication flow again.\n logger.info(`IdentityClient: interaction required for client ID: ${clientId}`);\n return null;\n } else {\n logger.warning(\n `IdentityClient: failed refreshing token for client ID: ${clientId}: ${err}`,\n );\n throw err;\n }\n }\n },\n );\n }\n\n // Here is a custom layer that allows us to abort requests that go through MSAL,\n // since MSAL doesn't allow us to pass options all the way through.\n\n generateAbortSignal(correlationId: string): AbortSignalLike {\n const controller = new AbortController();\n const controllers = this.abortControllers.get(correlationId) || [];\n controllers.push(controller);\n this.abortControllers.set(correlationId, controllers);\n const existingOnAbort = controller.signal.onabort;\n controller.signal.onabort = (...params) => {\n this.abortControllers.set(correlationId, undefined);\n if (existingOnAbort) {\n existingOnAbort.apply(controller.signal, params);\n }\n };\n return controller.signal;\n }\n\n abortRequests(correlationId?: string): void {\n const key = correlationId || noCorrelationId;\n const controllers = [\n ...(this.abortControllers.get(key) || []),\n // MSAL passes no correlation ID to the get requests...\n ...(this.abortControllers.get(noCorrelationId) || []),\n ];\n if (!controllers.length) {\n return;\n }\n for (const controller of controllers) {\n controller.abort();\n }\n this.abortControllers.set(key, undefined);\n }\n\n getCorrelationId(options?: NetworkRequestOptions): string {\n const parameter = options?.body\n ?.split(\"&\")\n .map((part) => part.split(\"=\"))\n .find(([key]) => key === \"client-request-id\");\n return parameter && parameter.length ? parameter[1] || noCorrelationId : noCorrelationId;\n }\n\n // The MSAL network module methods follow\n\n async sendGetRequestAsync<T>(\n url: string,\n options?: NetworkRequestOptions,\n ): Promise<NetworkResponse<T>> {\n const request = createPipelineRequest({\n url,\n method: \"GET\",\n body: options?.body,\n allowInsecureConnection: this.allowInsecureConnection,\n headers: createHttpHeaders(options?.headers),\n abortSignal: this.generateAbortSignal(noCorrelationId),\n });\n\n const response = await this.sendRequest(request);\n\n this.logIdentifiers(response);\n\n return {\n body: this.parseResponseBody(response) as T,\n headers: response.headers.toJSON(),\n status: response.status,\n };\n }\n\n async sendPostRequestAsync<T>(\n url: string,\n options?: NetworkRequestOptions,\n ): Promise<NetworkResponse<T>> {\n const request = createPipelineRequest({\n url,\n method: \"POST\",\n body: options?.body,\n headers: createHttpHeaders(options?.headers),\n allowInsecureConnection: this.allowInsecureConnection,\n // MSAL doesn't send the correlation ID on the get requests.\n abortSignal: this.generateAbortSignal(this.getCorrelationId(options)),\n });\n\n const response = await this.sendRequest(request);\n\n this.logIdentifiers(response);\n\n return {\n body: this.parseResponseBody(response) as T,\n headers: response.headers.toJSON(),\n status: response.status,\n };\n }\n\n /**\n *\n * @internal\n */\n getTokenCredentialOptions(): TokenCredentialOptions {\n return this.tokenCredentialOptions;\n }\n /**\n * If allowLoggingAccountIdentifiers was set on the constructor options\n * we try to log the account identifiers by parsing the received access token.\n *\n * The account identifiers we try to log are:\n * - `appid`: The application or Client Identifier.\n * - `upn`: User Principal Name.\n * - It might not be available in some authentication scenarios.\n * - If it's not available, we put a placeholder: \"No User Principal Name available\".\n * - `tid`: Tenant Identifier.\n * - `oid`: Object Identifier of the authenticated user.\n */\n private logIdentifiers(response: PipelineResponse): void {\n if (!this.allowLoggingAccountIdentifiers || !response.bodyAsText) {\n return;\n }\n const unavailableUpn = \"No User Principal Name available\";\n try {\n const parsed = (response as any).parsedBody || JSON.parse(response.bodyAsText);\n const accessToken = parsed.access_token;\n if (!accessToken) {\n // Without an access token allowLoggingAccountIdentifiers isn't useful.\n return;\n }\n const base64Metadata = accessToken.split(\".\")[1];\n const { appid, upn, tid, oid } = JSON.parse(\n Buffer.from(base64Metadata, \"base64\").toString(\"utf8\"),\n );\n\n logger.info(\n `[Authenticated account] Client ID: ${appid}. Tenant ID: ${tid}. User Principal Name: ${\n upn || unavailableUpn\n }. Object ID (user): ${oid}`,\n );\n } catch (e: any) {\n logger.warning(\n \"allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:\",\n e.message,\n );\n }\n }\n\n /**\n * Parses the response body if possible. Add error properties if parsing fails.\n * This follows MSAL INetworkModule behavior so the response is in expected format.\n */\n private parseResponseBody(response: PipelineResponse) {\n let parsedBody: {};\n try {\n parsedBody = JSON.parse(response.bodyAsText || \"\");\n } catch (error) {\n logger.info(`IdentityClient: Could not parse response body: ${error}`);\n let errorType;\n let errorDescriptionHelper;\n /**\n * Determine error type based on status code ranges following MSAL patterns:\n * Client error responses (400 – 499)\n * Server error responses (500 – 599)\n */\n if (\n response.status >= HttpStatus.CLIENT_ERROR_RANGE_START &&\n response.status <= HttpStatus.CLIENT_ERROR_RANGE_END\n ) {\n errorType = \"client_error\";\n errorDescriptionHelper = \"A client\";\n } else if (\n response.status >= HttpStatus.SERVER_ERROR_RANGE_START &&\n response.status <= HttpStatus.SERVER_ERROR_RANGE_END\n ) {\n errorType = \"server_error\";\n errorDescriptionHelper = \"A server\";\n } else {\n errorType = \"unknown_error\";\n errorDescriptionHelper = \"An unknown\";\n }\n\n const errorDescriptionLines = [\n `${errorDescriptionHelper} error occured.`,\n `Http status code: ${response.status}`,\n `Http status message: ${response.bodyAsText || \"Unknown\"}`,\n `Headers: ${JSON.stringify(response.headers)}`,\n ];\n parsedBody = {\n error: errorType,\n error_description: errorDescriptionLines.join(\"\\n\"),\n };\n }\n return parsedBody;\n }\n}\n"]}
@@ -57,5 +57,10 @@ export declare class IdentityClient extends ServiceClient implements INetworkMod
57
57
  * - `oid`: Object Identifier of the authenticated user.
58
58
  */
59
59
  private logIdentifiers;
60
+ /**
61
+ * Parses the response body if possible. Add error properties if parsing fails.
62
+ * This follows MSAL INetworkModule behavior so the response is in expected format.
63
+ */
64
+ private parseResponseBody;
60
65
  }
61
66
  //# sourceMappingURL=identityClient.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"identityClient.d.ts","sourceRoot":"","sources":["../../../src/client/identityClient.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,2BAA2B,CAAC;AAEnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAM/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAU3E;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,WAAW,EAAE,WAAW,CAAC;IACzB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,aAAc,YAAW,cAAc;IAClE,aAAa,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,8BAA8B,CAAC,CAAU;IACjD,OAAO,CAAC,gBAAgB,CAA6C;IACrE,OAAO,CAAC,uBAAuB,CAAkB;IAEjD,OAAO,CAAC,sBAAsB,CAAyB;gBAE3C,OAAO,CAAC,EAAE,sBAAsB;IAmCtC,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAmCzE,kBAAkB,CACtB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAkEhC,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,eAAe;IAe3D,aAAa,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI;IAgB3C,gBAAgB,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM;IAUnD,mBAAmB,CAAC,CAAC,EACzB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAqBxB,oBAAoB,CAAC,CAAC,EAC1B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAsB9B;;;OAGG;IACH,yBAAyB,IAAI,sBAAsB;IAGnD;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,cAAc;CA6BvB"}
1
+ {"version":3,"file":"identityClient.d.ts","sourceRoot":"","sources":["../../../src/client/identityClient.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,2BAA2B,CAAC;AAEnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAM/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAgB3E;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,WAAW,EAAE,WAAW,CAAC;IACzB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,aAAc,YAAW,cAAc;IAClE,aAAa,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,8BAA8B,CAAC,CAAU;IACjD,OAAO,CAAC,gBAAgB,CAA6C;IACrE,OAAO,CAAC,uBAAuB,CAAkB;IAEjD,OAAO,CAAC,sBAAsB,CAAyB;gBAE3C,OAAO,CAAC,EAAE,sBAAsB;IAmCtC,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAmCzE,kBAAkB,CACtB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAkEhC,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,eAAe;IAe3D,aAAa,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI;IAgB3C,gBAAgB,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM;IAUnD,mBAAmB,CAAC,CAAC,EACzB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAqBxB,oBAAoB,CAAC,CAAC,EAC1B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAsB9B;;;OAGG;IACH,yBAAyB,IAAI,sBAAsB;IAGnD;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,cAAc;IA8BtB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;CA2C1B"}
@@ -10,6 +10,12 @@ import { logger } from "../util/logging.js";
10
10
  import { parseExpirationTimestamp, parseRefreshTimestamp, } from "../credentials/managedIdentityCredential/utils.js";
11
11
  import { getAuthorityHost } from "../util/authorityHost.js";
12
12
  const noCorrelationId = "noCorrelationId";
13
+ const HttpStatus = {
14
+ CLIENT_ERROR_RANGE_START: 400,
15
+ CLIENT_ERROR_RANGE_END: 499,
16
+ SERVER_ERROR_RANGE_START: 500,
17
+ SERVER_ERROR_RANGE_END: 599,
18
+ };
13
19
  /**
14
20
  * The network module used by the Identity credentials.
15
21
  *
@@ -181,7 +187,7 @@ export class IdentityClient extends ServiceClient {
181
187
  const response = await this.sendRequest(request);
182
188
  this.logIdentifiers(response);
183
189
  return {
184
- body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,
190
+ body: this.parseResponseBody(response),
185
191
  headers: response.headers.toJSON(),
186
192
  status: response.status,
187
193
  };
@@ -199,7 +205,7 @@ export class IdentityClient extends ServiceClient {
199
205
  const response = await this.sendRequest(request);
200
206
  this.logIdentifiers(response);
201
207
  return {
202
- body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,
208
+ body: this.parseResponseBody(response),
203
209
  headers: response.headers.toJSON(),
204
210
  status: response.status,
205
211
  };
@@ -243,5 +249,50 @@ export class IdentityClient extends ServiceClient {
243
249
  logger.warning("allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:", e.message);
244
250
  }
245
251
  }
252
+ /**
253
+ * Parses the response body if possible. Add error properties if parsing fails.
254
+ * This follows MSAL INetworkModule behavior so the response is in expected format.
255
+ */
256
+ parseResponseBody(response) {
257
+ let parsedBody;
258
+ try {
259
+ parsedBody = JSON.parse(response.bodyAsText || "");
260
+ }
261
+ catch (error) {
262
+ logger.info(`IdentityClient: Could not parse response body: ${error}`);
263
+ let errorType;
264
+ let errorDescriptionHelper;
265
+ /**
266
+ * Determine error type based on status code ranges following MSAL patterns:
267
+ * Client error responses (400 – 499)
268
+ * Server error responses (500 – 599)
269
+ */
270
+ if (response.status >= HttpStatus.CLIENT_ERROR_RANGE_START &&
271
+ response.status <= HttpStatus.CLIENT_ERROR_RANGE_END) {
272
+ errorType = "client_error";
273
+ errorDescriptionHelper = "A client";
274
+ }
275
+ else if (response.status >= HttpStatus.SERVER_ERROR_RANGE_START &&
276
+ response.status <= HttpStatus.SERVER_ERROR_RANGE_END) {
277
+ errorType = "server_error";
278
+ errorDescriptionHelper = "A server";
279
+ }
280
+ else {
281
+ errorType = "unknown_error";
282
+ errorDescriptionHelper = "An unknown";
283
+ }
284
+ const errorDescriptionLines = [
285
+ `${errorDescriptionHelper} error occured.`,
286
+ `Http status code: ${response.status}`,
287
+ `Http status message: ${response.bodyAsText || "Unknown"}`,
288
+ `Headers: ${JSON.stringify(response.headers)}`,
289
+ ];
290
+ parsedBody = {
291
+ error: errorType,
292
+ error_description: errorDescriptionLines.join("\n"),
293
+ };
294
+ }
295
+ return parsedBody;
296
+ }
246
297
  }
247
298
  //# sourceMappingURL=identityClient.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"identityClient.js","sourceRoot":"","sources":["../../../src/client/identityClient.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { INetworkModule, NetworkRequestOptions, NetworkResponse } from \"@azure/msal-node\";\nimport type { AccessToken, GetTokenOptions } from \"@azure/core-auth\";\nimport { ServiceClient } from \"@azure/core-client\";\nimport type { PipelineRequest, PipelineResponse } from \"@azure/core-rest-pipeline\";\nimport { createHttpHeaders, createPipelineRequest } from \"@azure/core-rest-pipeline\";\nimport type { AbortSignalLike } from \"@azure/abort-controller\";\nimport { AuthenticationError, AuthenticationErrorName } from \"../errors.js\";\nimport { getIdentityTokenEndpointSuffix } from \"../util/identityTokenEndpoint.js\";\nimport { SDK_VERSION } from \"../constants.js\";\nimport { tracingClient } from \"../util/tracing.js\";\nimport { logger } from \"../util/logging.js\";\nimport type { TokenCredentialOptions } from \"../tokenCredentialOptions.js\";\nimport type { TokenResponseParsedBody } from \"../credentials/managedIdentityCredential/utils.js\";\nimport {\n parseExpirationTimestamp,\n parseRefreshTimestamp,\n} from \"../credentials/managedIdentityCredential/utils.js\";\nimport { getAuthorityHost } from \"../util/authorityHost.js\";\n\nconst noCorrelationId = \"noCorrelationId\";\n\n/**\n * An internal type used to communicate details of a token request's\n * response that should not be sent back as part of the access token.\n */\nexport interface TokenResponse {\n /**\n * The AccessToken to be returned from getToken.\n */\n accessToken: AccessToken;\n /**\n * The refresh token if the 'offline_access' scope was used.\n */\n refreshToken?: string;\n}\n\n/**\n * The network module used by the Identity credentials.\n *\n * It allows for credentials to abort any pending request independently of the MSAL flow,\n * by calling to the `abortRequests()` method.\n *\n */\nexport class IdentityClient extends ServiceClient implements INetworkModule {\n public authorityHost: string;\n private allowLoggingAccountIdentifiers?: boolean;\n private abortControllers: Map<string, AbortController[] | undefined>;\n private allowInsecureConnection: boolean = false;\n // used for WorkloadIdentity\n private tokenCredentialOptions: TokenCredentialOptions;\n\n constructor(options?: TokenCredentialOptions) {\n const packageDetails = `azsdk-js-identity/${SDK_VERSION}`;\n const userAgentPrefix = options?.userAgentOptions?.userAgentPrefix\n ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`\n : `${packageDetails}`;\n\n const baseUri = getAuthorityHost(options);\n if (!baseUri.startsWith(\"https:\")) {\n throw new Error(\"The authorityHost address must use the 'https' protocol.\");\n }\n\n super({\n requestContentType: \"application/json; charset=utf-8\",\n retryOptions: {\n maxRetries: 3,\n },\n ...options,\n userAgentOptions: {\n userAgentPrefix,\n },\n baseUri,\n });\n\n this.authorityHost = baseUri;\n this.abortControllers = new Map();\n this.allowLoggingAccountIdentifiers = options?.loggingOptions?.allowLoggingAccountIdentifiers;\n // used for WorkloadIdentity\n this.tokenCredentialOptions = { ...options };\n\n // used for ManagedIdentity\n if (options?.allowInsecureConnection) {\n this.allowInsecureConnection = options.allowInsecureConnection;\n }\n }\n\n async sendTokenRequest(request: PipelineRequest): Promise<TokenResponse | null> {\n logger.info(`IdentityClient: sending token request to [${request.url}]`);\n const response = await this.sendRequest(request);\n if (response.bodyAsText && (response.status === 200 || response.status === 201)) {\n const parsedBody: TokenResponseParsedBody = JSON.parse(response.bodyAsText);\n\n if (!parsedBody.access_token) {\n return null;\n }\n\n this.logIdentifiers(response);\n\n const token = {\n accessToken: {\n token: parsedBody.access_token,\n expiresOnTimestamp: parseExpirationTimestamp(parsedBody),\n refreshAfterTimestamp: parseRefreshTimestamp(parsedBody),\n tokenType: \"Bearer\",\n } as AccessToken,\n refreshToken: parsedBody.refresh_token,\n };\n\n logger.info(\n `IdentityClient: [${request.url}] token acquired, expires on ${token.accessToken.expiresOnTimestamp}`,\n );\n return token;\n } else {\n const error = new AuthenticationError(response.status, response.bodyAsText);\n logger.warning(\n `IdentityClient: authentication error. HTTP status: ${response.status}, ${error.errorResponse.errorDescription}`,\n );\n throw error;\n }\n }\n\n async refreshAccessToken(\n tenantId: string,\n clientId: string,\n scopes: string,\n refreshToken: string | undefined,\n clientSecret: string | undefined,\n options: GetTokenOptions = {},\n ): Promise<TokenResponse | null> {\n if (refreshToken === undefined) {\n return null;\n }\n logger.info(\n `IdentityClient: refreshing access token with client ID: ${clientId}, scopes: ${scopes} started`,\n );\n\n const refreshParams = {\n grant_type: \"refresh_token\",\n client_id: clientId,\n refresh_token: refreshToken,\n scope: scopes,\n };\n\n if (clientSecret !== undefined) {\n (refreshParams as any).client_secret = clientSecret;\n }\n\n const query = new URLSearchParams(refreshParams);\n\n return tracingClient.withSpan(\n \"IdentityClient.refreshAccessToken\",\n options,\n async (updatedOptions) => {\n try {\n const urlSuffix = getIdentityTokenEndpointSuffix(tenantId);\n const request = createPipelineRequest({\n url: `${this.authorityHost}/${tenantId}/${urlSuffix}`,\n method: \"POST\",\n body: query.toString(),\n abortSignal: options.abortSignal,\n headers: createHttpHeaders({\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n }),\n tracingOptions: updatedOptions.tracingOptions,\n });\n\n const response = await this.sendTokenRequest(request);\n logger.info(`IdentityClient: refreshed token for client ID: ${clientId}`);\n return response;\n } catch (err: any) {\n if (\n err.name === AuthenticationErrorName &&\n err.errorResponse.error === \"interaction_required\"\n ) {\n // It's likely that the refresh token has expired, so\n // return null so that the credential implementation will\n // initiate the authentication flow again.\n logger.info(`IdentityClient: interaction required for client ID: ${clientId}`);\n return null;\n } else {\n logger.warning(\n `IdentityClient: failed refreshing token for client ID: ${clientId}: ${err}`,\n );\n throw err;\n }\n }\n },\n );\n }\n\n // Here is a custom layer that allows us to abort requests that go through MSAL,\n // since MSAL doesn't allow us to pass options all the way through.\n\n generateAbortSignal(correlationId: string): AbortSignalLike {\n const controller = new AbortController();\n const controllers = this.abortControllers.get(correlationId) || [];\n controllers.push(controller);\n this.abortControllers.set(correlationId, controllers);\n const existingOnAbort = controller.signal.onabort;\n controller.signal.onabort = (...params) => {\n this.abortControllers.set(correlationId, undefined);\n if (existingOnAbort) {\n existingOnAbort.apply(controller.signal, params);\n }\n };\n return controller.signal;\n }\n\n abortRequests(correlationId?: string): void {\n const key = correlationId || noCorrelationId;\n const controllers = [\n ...(this.abortControllers.get(key) || []),\n // MSAL passes no correlation ID to the get requests...\n ...(this.abortControllers.get(noCorrelationId) || []),\n ];\n if (!controllers.length) {\n return;\n }\n for (const controller of controllers) {\n controller.abort();\n }\n this.abortControllers.set(key, undefined);\n }\n\n getCorrelationId(options?: NetworkRequestOptions): string {\n const parameter = options?.body\n ?.split(\"&\")\n .map((part) => part.split(\"=\"))\n .find(([key]) => key === \"client-request-id\");\n return parameter && parameter.length ? parameter[1] || noCorrelationId : noCorrelationId;\n }\n\n // The MSAL network module methods follow\n\n async sendGetRequestAsync<T>(\n url: string,\n options?: NetworkRequestOptions,\n ): Promise<NetworkResponse<T>> {\n const request = createPipelineRequest({\n url,\n method: \"GET\",\n body: options?.body,\n allowInsecureConnection: this.allowInsecureConnection,\n headers: createHttpHeaders(options?.headers),\n abortSignal: this.generateAbortSignal(noCorrelationId),\n });\n\n const response = await this.sendRequest(request);\n\n this.logIdentifiers(response);\n\n return {\n body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,\n headers: response.headers.toJSON(),\n status: response.status,\n };\n }\n\n async sendPostRequestAsync<T>(\n url: string,\n options?: NetworkRequestOptions,\n ): Promise<NetworkResponse<T>> {\n const request = createPipelineRequest({\n url,\n method: \"POST\",\n body: options?.body,\n headers: createHttpHeaders(options?.headers),\n allowInsecureConnection: this.allowInsecureConnection,\n // MSAL doesn't send the correlation ID on the get requests.\n abortSignal: this.generateAbortSignal(this.getCorrelationId(options)),\n });\n\n const response = await this.sendRequest(request);\n\n this.logIdentifiers(response);\n\n return {\n body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,\n headers: response.headers.toJSON(),\n status: response.status,\n };\n }\n\n /**\n *\n * @internal\n */\n getTokenCredentialOptions(): TokenCredentialOptions {\n return this.tokenCredentialOptions;\n }\n /**\n * If allowLoggingAccountIdentifiers was set on the constructor options\n * we try to log the account identifiers by parsing the received access token.\n *\n * The account identifiers we try to log are:\n * - `appid`: The application or Client Identifier.\n * - `upn`: User Principal Name.\n * - It might not be available in some authentication scenarios.\n * - If it's not available, we put a placeholder: \"No User Principal Name available\".\n * - `tid`: Tenant Identifier.\n * - `oid`: Object Identifier of the authenticated user.\n */\n private logIdentifiers(response: PipelineResponse): void {\n if (!this.allowLoggingAccountIdentifiers || !response.bodyAsText) {\n return;\n }\n const unavailableUpn = \"No User Principal Name available\";\n try {\n const parsed = (response as any).parsedBody || JSON.parse(response.bodyAsText);\n const accessToken = parsed.access_token;\n if (!accessToken) {\n // Without an access token allowLoggingAccountIdentifiers isn't useful.\n return;\n }\n const base64Metadata = accessToken.split(\".\")[1];\n const { appid, upn, tid, oid } = JSON.parse(\n Buffer.from(base64Metadata, \"base64\").toString(\"utf8\"),\n );\n\n logger.info(\n `[Authenticated account] Client ID: ${appid}. Tenant ID: ${tid}. User Principal Name: ${\n upn || unavailableUpn\n }. Object ID (user): ${oid}`,\n );\n } catch (e: any) {\n logger.warning(\n \"allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:\",\n e.message,\n );\n }\n }\n}\n"]}
1
+ {"version":3,"file":"identityClient.js","sourceRoot":"","sources":["../../../src/client/identityClient.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { INetworkModule, NetworkRequestOptions, NetworkResponse } from \"@azure/msal-node\";\nimport type { AccessToken, GetTokenOptions } from \"@azure/core-auth\";\nimport { ServiceClient } from \"@azure/core-client\";\nimport type { PipelineRequest, PipelineResponse } from \"@azure/core-rest-pipeline\";\nimport { createHttpHeaders, createPipelineRequest } from \"@azure/core-rest-pipeline\";\nimport type { AbortSignalLike } from \"@azure/abort-controller\";\nimport { AuthenticationError, AuthenticationErrorName } from \"../errors.js\";\nimport { getIdentityTokenEndpointSuffix } from \"../util/identityTokenEndpoint.js\";\nimport { SDK_VERSION } from \"../constants.js\";\nimport { tracingClient } from \"../util/tracing.js\";\nimport { logger } from \"../util/logging.js\";\nimport type { TokenCredentialOptions } from \"../tokenCredentialOptions.js\";\nimport type { TokenResponseParsedBody } from \"../credentials/managedIdentityCredential/utils.js\";\nimport {\n parseExpirationTimestamp,\n parseRefreshTimestamp,\n} from \"../credentials/managedIdentityCredential/utils.js\";\nimport { getAuthorityHost } from \"../util/authorityHost.js\";\n\nconst noCorrelationId = \"noCorrelationId\";\nconst HttpStatus = {\n CLIENT_ERROR_RANGE_START: 400,\n CLIENT_ERROR_RANGE_END: 499,\n SERVER_ERROR_RANGE_START: 500,\n SERVER_ERROR_RANGE_END: 599,\n};\n\n/**\n * An internal type used to communicate details of a token request's\n * response that should not be sent back as part of the access token.\n */\nexport interface TokenResponse {\n /**\n * The AccessToken to be returned from getToken.\n */\n accessToken: AccessToken;\n /**\n * The refresh token if the 'offline_access' scope was used.\n */\n refreshToken?: string;\n}\n\n/**\n * The network module used by the Identity credentials.\n *\n * It allows for credentials to abort any pending request independently of the MSAL flow,\n * by calling to the `abortRequests()` method.\n *\n */\nexport class IdentityClient extends ServiceClient implements INetworkModule {\n public authorityHost: string;\n private allowLoggingAccountIdentifiers?: boolean;\n private abortControllers: Map<string, AbortController[] | undefined>;\n private allowInsecureConnection: boolean = false;\n // used for WorkloadIdentity\n private tokenCredentialOptions: TokenCredentialOptions;\n\n constructor(options?: TokenCredentialOptions) {\n const packageDetails = `azsdk-js-identity/${SDK_VERSION}`;\n const userAgentPrefix = options?.userAgentOptions?.userAgentPrefix\n ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`\n : `${packageDetails}`;\n\n const baseUri = getAuthorityHost(options);\n if (!baseUri.startsWith(\"https:\")) {\n throw new Error(\"The authorityHost address must use the 'https' protocol.\");\n }\n\n super({\n requestContentType: \"application/json; charset=utf-8\",\n retryOptions: {\n maxRetries: 3,\n },\n ...options,\n userAgentOptions: {\n userAgentPrefix,\n },\n baseUri,\n });\n\n this.authorityHost = baseUri;\n this.abortControllers = new Map();\n this.allowLoggingAccountIdentifiers = options?.loggingOptions?.allowLoggingAccountIdentifiers;\n // used for WorkloadIdentity\n this.tokenCredentialOptions = { ...options };\n\n // used for ManagedIdentity\n if (options?.allowInsecureConnection) {\n this.allowInsecureConnection = options.allowInsecureConnection;\n }\n }\n\n async sendTokenRequest(request: PipelineRequest): Promise<TokenResponse | null> {\n logger.info(`IdentityClient: sending token request to [${request.url}]`);\n const response = await this.sendRequest(request);\n if (response.bodyAsText && (response.status === 200 || response.status === 201)) {\n const parsedBody: TokenResponseParsedBody = JSON.parse(response.bodyAsText);\n\n if (!parsedBody.access_token) {\n return null;\n }\n\n this.logIdentifiers(response);\n\n const token = {\n accessToken: {\n token: parsedBody.access_token,\n expiresOnTimestamp: parseExpirationTimestamp(parsedBody),\n refreshAfterTimestamp: parseRefreshTimestamp(parsedBody),\n tokenType: \"Bearer\",\n } as AccessToken,\n refreshToken: parsedBody.refresh_token,\n };\n\n logger.info(\n `IdentityClient: [${request.url}] token acquired, expires on ${token.accessToken.expiresOnTimestamp}`,\n );\n return token;\n } else {\n const error = new AuthenticationError(response.status, response.bodyAsText);\n logger.warning(\n `IdentityClient: authentication error. HTTP status: ${response.status}, ${error.errorResponse.errorDescription}`,\n );\n throw error;\n }\n }\n\n async refreshAccessToken(\n tenantId: string,\n clientId: string,\n scopes: string,\n refreshToken: string | undefined,\n clientSecret: string | undefined,\n options: GetTokenOptions = {},\n ): Promise<TokenResponse | null> {\n if (refreshToken === undefined) {\n return null;\n }\n logger.info(\n `IdentityClient: refreshing access token with client ID: ${clientId}, scopes: ${scopes} started`,\n );\n\n const refreshParams = {\n grant_type: \"refresh_token\",\n client_id: clientId,\n refresh_token: refreshToken,\n scope: scopes,\n };\n\n if (clientSecret !== undefined) {\n (refreshParams as any).client_secret = clientSecret;\n }\n\n const query = new URLSearchParams(refreshParams);\n\n return tracingClient.withSpan(\n \"IdentityClient.refreshAccessToken\",\n options,\n async (updatedOptions) => {\n try {\n const urlSuffix = getIdentityTokenEndpointSuffix(tenantId);\n const request = createPipelineRequest({\n url: `${this.authorityHost}/${tenantId}/${urlSuffix}`,\n method: \"POST\",\n body: query.toString(),\n abortSignal: options.abortSignal,\n headers: createHttpHeaders({\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n }),\n tracingOptions: updatedOptions.tracingOptions,\n });\n\n const response = await this.sendTokenRequest(request);\n logger.info(`IdentityClient: refreshed token for client ID: ${clientId}`);\n return response;\n } catch (err: any) {\n if (\n err.name === AuthenticationErrorName &&\n err.errorResponse.error === \"interaction_required\"\n ) {\n // It's likely that the refresh token has expired, so\n // return null so that the credential implementation will\n // initiate the authentication flow again.\n logger.info(`IdentityClient: interaction required for client ID: ${clientId}`);\n return null;\n } else {\n logger.warning(\n `IdentityClient: failed refreshing token for client ID: ${clientId}: ${err}`,\n );\n throw err;\n }\n }\n },\n );\n }\n\n // Here is a custom layer that allows us to abort requests that go through MSAL,\n // since MSAL doesn't allow us to pass options all the way through.\n\n generateAbortSignal(correlationId: string): AbortSignalLike {\n const controller = new AbortController();\n const controllers = this.abortControllers.get(correlationId) || [];\n controllers.push(controller);\n this.abortControllers.set(correlationId, controllers);\n const existingOnAbort = controller.signal.onabort;\n controller.signal.onabort = (...params) => {\n this.abortControllers.set(correlationId, undefined);\n if (existingOnAbort) {\n existingOnAbort.apply(controller.signal, params);\n }\n };\n return controller.signal;\n }\n\n abortRequests(correlationId?: string): void {\n const key = correlationId || noCorrelationId;\n const controllers = [\n ...(this.abortControllers.get(key) || []),\n // MSAL passes no correlation ID to the get requests...\n ...(this.abortControllers.get(noCorrelationId) || []),\n ];\n if (!controllers.length) {\n return;\n }\n for (const controller of controllers) {\n controller.abort();\n }\n this.abortControllers.set(key, undefined);\n }\n\n getCorrelationId(options?: NetworkRequestOptions): string {\n const parameter = options?.body\n ?.split(\"&\")\n .map((part) => part.split(\"=\"))\n .find(([key]) => key === \"client-request-id\");\n return parameter && parameter.length ? parameter[1] || noCorrelationId : noCorrelationId;\n }\n\n // The MSAL network module methods follow\n\n async sendGetRequestAsync<T>(\n url: string,\n options?: NetworkRequestOptions,\n ): Promise<NetworkResponse<T>> {\n const request = createPipelineRequest({\n url,\n method: \"GET\",\n body: options?.body,\n allowInsecureConnection: this.allowInsecureConnection,\n headers: createHttpHeaders(options?.headers),\n abortSignal: this.generateAbortSignal(noCorrelationId),\n });\n\n const response = await this.sendRequest(request);\n\n this.logIdentifiers(response);\n\n return {\n body: this.parseResponseBody(response) as T,\n headers: response.headers.toJSON(),\n status: response.status,\n };\n }\n\n async sendPostRequestAsync<T>(\n url: string,\n options?: NetworkRequestOptions,\n ): Promise<NetworkResponse<T>> {\n const request = createPipelineRequest({\n url,\n method: \"POST\",\n body: options?.body,\n headers: createHttpHeaders(options?.headers),\n allowInsecureConnection: this.allowInsecureConnection,\n // MSAL doesn't send the correlation ID on the get requests.\n abortSignal: this.generateAbortSignal(this.getCorrelationId(options)),\n });\n\n const response = await this.sendRequest(request);\n\n this.logIdentifiers(response);\n\n return {\n body: this.parseResponseBody(response) as T,\n headers: response.headers.toJSON(),\n status: response.status,\n };\n }\n\n /**\n *\n * @internal\n */\n getTokenCredentialOptions(): TokenCredentialOptions {\n return this.tokenCredentialOptions;\n }\n /**\n * If allowLoggingAccountIdentifiers was set on the constructor options\n * we try to log the account identifiers by parsing the received access token.\n *\n * The account identifiers we try to log are:\n * - `appid`: The application or Client Identifier.\n * - `upn`: User Principal Name.\n * - It might not be available in some authentication scenarios.\n * - If it's not available, we put a placeholder: \"No User Principal Name available\".\n * - `tid`: Tenant Identifier.\n * - `oid`: Object Identifier of the authenticated user.\n */\n private logIdentifiers(response: PipelineResponse): void {\n if (!this.allowLoggingAccountIdentifiers || !response.bodyAsText) {\n return;\n }\n const unavailableUpn = \"No User Principal Name available\";\n try {\n const parsed = (response as any).parsedBody || JSON.parse(response.bodyAsText);\n const accessToken = parsed.access_token;\n if (!accessToken) {\n // Without an access token allowLoggingAccountIdentifiers isn't useful.\n return;\n }\n const base64Metadata = accessToken.split(\".\")[1];\n const { appid, upn, tid, oid } = JSON.parse(\n Buffer.from(base64Metadata, \"base64\").toString(\"utf8\"),\n );\n\n logger.info(\n `[Authenticated account] Client ID: ${appid}. Tenant ID: ${tid}. User Principal Name: ${\n upn || unavailableUpn\n }. Object ID (user): ${oid}`,\n );\n } catch (e: any) {\n logger.warning(\n \"allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:\",\n e.message,\n );\n }\n }\n\n /**\n * Parses the response body if possible. Add error properties if parsing fails.\n * This follows MSAL INetworkModule behavior so the response is in expected format.\n */\n private parseResponseBody(response: PipelineResponse) {\n let parsedBody: {};\n try {\n parsedBody = JSON.parse(response.bodyAsText || \"\");\n } catch (error) {\n logger.info(`IdentityClient: Could not parse response body: ${error}`);\n let errorType;\n let errorDescriptionHelper;\n /**\n * Determine error type based on status code ranges following MSAL patterns:\n * Client error responses (400 – 499)\n * Server error responses (500 – 599)\n */\n if (\n response.status >= HttpStatus.CLIENT_ERROR_RANGE_START &&\n response.status <= HttpStatus.CLIENT_ERROR_RANGE_END\n ) {\n errorType = \"client_error\";\n errorDescriptionHelper = \"A client\";\n } else if (\n response.status >= HttpStatus.SERVER_ERROR_RANGE_START &&\n response.status <= HttpStatus.SERVER_ERROR_RANGE_END\n ) {\n errorType = \"server_error\";\n errorDescriptionHelper = \"A server\";\n } else {\n errorType = \"unknown_error\";\n errorDescriptionHelper = \"An unknown\";\n }\n\n const errorDescriptionLines = [\n `${errorDescriptionHelper} error occured.`,\n `Http status code: ${response.status}`,\n `Http status message: ${response.bodyAsText || \"Unknown\"}`,\n `Headers: ${JSON.stringify(response.headers)}`,\n ];\n parsedBody = {\n error: errorType,\n error_description: errorDescriptionLines.join(\"\\n\"),\n };\n }\n return parsedBody;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@azure/identity",
3
3
  "sdk-type": "client",
4
- "version": "4.14.0-alpha.20251219.1",
4
+ "version": "4.14.0-alpha.20251222.2",
5
5
  "description": "Provides credential implementations for Azure SDK libraries that can authenticate with Microsoft Entra ID",
6
6
  "main": "./dist/commonjs/index.js",
7
7
  "module": "./dist/esm/index.js",
@@ -88,10 +88,10 @@
88
88
  "tshy": "^3.0.3",
89
89
  "typescript": "~5.9.3",
90
90
  "vitest": "^4.0.8",
91
+ "@azure-tools/test-recorder": "^4.1.1",
91
92
  "@azure-tools/test-utils-vitest": "^2.0.1",
92
- "@azure/eslint-plugin-azure-sdk": "^3.0.0",
93
93
  "@azure/dev-tool": "^1.0.0",
94
- "@azure-tools/test-recorder": "^4.1.1"
94
+ "@azure/eslint-plugin-azure-sdk": "^3.0.0"
95
95
  },
96
96
  "type": "module",
97
97
  "tshy": {