Initial commit

This commit is contained in:
2025-03-07 19:22:02 +01:00
commit 4a98255d83
55743 changed files with 5280367 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
# Visual Studio Tunnels Contracts Library
Tunnels management library for node
+6
View File
@@ -0,0 +1,6 @@
export declare class IdGeneration {
private static nouns;
private static adjectives;
static generateTunnelId(): string;
}
//# sourceMappingURL=idGeneration.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"idGeneration.d.ts","sourceRoot":"","sources":["../../../src/management/idGeneration.ts"],"names":[],"mappings":"AAEA,qBAAa,YAAY;IACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAsJ;IAC1K,OAAO,CAAC,MAAM,CAAC,UAAU,CAAgN;WAE3N,gBAAgB,IAAI,MAAM;CAS3C"}
+19
View File
@@ -0,0 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IdGeneration = void 0;
const dev_tunnels_contracts_1 = require("@microsoft/dev-tunnels-contracts");
class IdGeneration {
static generateTunnelId() {
let tunnelId = "";
tunnelId += this.adjectives[Math.floor(Math.random() * this.adjectives.length)] + "-";
tunnelId += this.nouns[Math.floor(Math.random() * this.nouns.length)] + "-";
for (let i = 0; i < 7; i++) {
tunnelId += dev_tunnels_contracts_1.TunnelConstraints.oldTunnelIdChars[Math.floor(Math.random() * (dev_tunnels_contracts_1.TunnelConstraints.oldTunnelIdChars.length))];
}
return tunnelId;
}
}
exports.IdGeneration = IdGeneration;
IdGeneration.nouns = ["pond", "hill", "mountain", "field", "fog", "ant", "dog", "cat", "shoe", "plane", "chair", "book", "ocean", "lake", "river", "horse"];
IdGeneration.adjectives = ["fun", "happy", "interesting", "neat", "peaceful", "puzzled", "kind", "joyful", "new", "giant", "sneaky", "quick", "majestic", "jolly", "fancy", "tidy", "swift", "silent", "amusing", "spiffy"];
//# sourceMappingURL=idGeneration.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"idGeneration.js","sourceRoot":"","sources":["../../../src/management/idGeneration.ts"],"names":[],"mappings":";;;AAAA,4EAAoE;AAEpE,MAAa,YAAY;IAId,MAAM,CAAC,gBAAgB;QAC1B,IAAI,QAAQ,GAAG,EAAE,CAAC;QAClB,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC;QACtF,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC;QAC5E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YACxB,QAAQ,IAAI,yCAAiB,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,yCAAiB,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;SAC3H;QACD,OAAO,QAAQ,CAAC;IACpB,CAAC;;AAZL,oCAaC;AAZkB,kBAAK,GAAa,CAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAG,OAAO,CAAC,CAAC;AAC3J,uBAAU,GAAa,CAAC,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAG,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC"}
+5
View File
@@ -0,0 +1,5 @@
export * from './tunnelManagementHttpClient';
export * from './tunnelManagementClient';
export * from './tunnelRequestOptions';
export * from './tunnelAccessTokenProperties';
//# sourceMappingURL=index.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/management/index.ts"],"names":[],"mappings":"AAGA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,+BAA+B,CAAC"}
+23
View File
@@ -0,0 +1,23 @@
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./tunnelManagementHttpClient"), exports);
__exportStar(require("./tunnelManagementClient"), exports);
__exportStar(require("./tunnelRequestOptions"), exports);
__exportStar(require("./tunnelAccessTokenProperties"), exports);
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/management/index.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;;;;;;;;;;;;;;;;AAElC,+DAA6C;AAC7C,2DAAyC;AACzC,yDAAuC;AACvC,gEAA8C"}
+18
View File
@@ -0,0 +1,18 @@
{
"name": "@microsoft/dev-tunnels-management",
"version": "1.1.9",
"description": "Tunnels library for Visual Studio tools",
"keywords": [
"Tunnels"
],
"author": "Microsoft",
"license": "MIT",
"dependencies": {
"buffer": "^5.2.1",
"debug": "^4.1.1",
"vscode-jsonrpc": "^4.0.0",
"@microsoft/dev-tunnels-contracts": ">1.1.8",
"axios": "^1.6.2"
},
"main": "./index.js"
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,45 @@
import { Tunnel } from '@microsoft/dev-tunnels-contracts';
/**
* Supports parsing tunnel access token JWT properties to allow for some pre-validation
* and diagnostics.
*
* Applications generally should not attempt to interpret or rely on any token properties
* other than `expiration`, because the service may change or omit those claims in the future.
* Other claims are exposed here only for diagnostic purposes.
*/
export declare class TunnelAccessTokenProperties {
readonly clusterId?: string | undefined;
readonly tunnelId?: string | undefined;
readonly tunnelPorts?: number[] | undefined;
readonly scopes?: string[] | undefined;
readonly issuer?: string | undefined;
readonly expiration?: Date | undefined;
private constructor();
toString(): string;
/**
* Checks if the tunnel access token expiration claim is in the past.
*
* (Does not throw if the token is an invalid format.)
*/
static validateTokenExpiration(token: string): void;
/**
* Attempts to parse a tunnel access token (JWT). This does NOT validate the token
* signature or any claims.
*/
static tryParse(token: string): TunnelAccessTokenProperties | null;
/**
* Gets the tunnal access token trace string.
* 'none' if null or undefined, parsed token info if can be parsed, or 'token' if cannot be parsed.
*/
static getTokenTrace(token?: string | null | undefined): string;
/**
* Gets a tunnel access token that matches any of the provided access token scopes.
* Validates token expiration if the token is found and throws an error if it's expired.
* @param tunnel The tunnel to get the access tokens from.
* @param accessTokenScopes What scopes the token needs to have.
* @returns Tunnel access token if found; otherwise, undefined.
*/
static getTunnelAccessToken(tunnel?: Tunnel | null, accessTokenScopes?: string | string[]): string | undefined;
private static base64UrlDecode;
}
//# sourceMappingURL=tunnelAccessTokenProperties.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"tunnelAccessTokenProperties.d.ts","sourceRoot":"","sources":["../../../src/management/tunnelAccessTokenProperties.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAC;AAE1D;;;;;;;GAOG;AACH,qBAAa,2BAA2B;aAEhB,SAAS,CAAC;aACV,QAAQ,CAAC;aACT,WAAW,CAAC;aACZ,MAAM,CAAC;aACP,MAAM,CAAC;aACP,UAAU,CAAC;IAN/B,OAAO;IASA,QAAQ,IAAI,MAAM;IAyCzB;;;;OAIG;WACW,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAS1D;;;OAGG;WACW,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,2BAA2B,GAAG,IAAI;IAoCzE;;;OAGG;WACW,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM;IAItE;;;;;;OAMG;WACW,oBAAoB,CAC9B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,EACtB,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GACtC,MAAM,GAAG,SAAS;IAoBrB,OAAO,CAAC,MAAM,CAAC,eAAe;CAcjC"}
@@ -0,0 +1,152 @@
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
Object.defineProperty(exports, "__esModule", { value: true });
exports.TunnelAccessTokenProperties = void 0;
/**
* Supports parsing tunnel access token JWT properties to allow for some pre-validation
* and diagnostics.
*
* Applications generally should not attempt to interpret or rely on any token properties
* other than `expiration`, because the service may change or omit those claims in the future.
* Other claims are exposed here only for diagnostic purposes.
*/
class TunnelAccessTokenProperties {
constructor(clusterId, tunnelId, tunnelPorts, scopes, issuer, expiration) {
this.clusterId = clusterId;
this.tunnelId = tunnelId;
this.tunnelPorts = tunnelPorts;
this.scopes = scopes;
this.issuer = issuer;
this.expiration = expiration;
}
toString() {
let s = '';
if (this.tunnelId) {
s += 'tunnel=';
s += this.tunnelId;
if (this.clusterId) {
s += '.';
s += this.clusterId;
}
}
if (this.tunnelPorts && this.tunnelPorts.length > 0) {
if (s.length > 0)
s += ', ';
if (this.tunnelPorts.length === 1) {
s += `port=${this.tunnelPorts[0]}`;
}
else {
s += `ports=[${this.tunnelPorts.join(', ')}]`;
}
}
if (this.scopes) {
if (s.length > 0)
s += ', ';
s += `scopes=[${this.scopes.join(', ')}]`;
}
if (this.issuer) {
if (s.length > 0)
s += ', ';
s += 'issuer=';
s += this.issuer;
}
if (this.expiration) {
if (s.length > 0)
s += ', ';
s += `expiration=${this.expiration.toString().replace('.000Z', 'Z')}`;
}
return s;
}
/**
* Checks if the tunnel access token expiration claim is in the past.
*
* (Does not throw if the token is an invalid format.)
*/
static validateTokenExpiration(token) {
const t = TunnelAccessTokenProperties.tryParse(token);
if (t === null || t === void 0 ? void 0 : t.expiration) {
if (t.expiration < new Date()) {
throw new Error('The access token is expired: ' + t);
}
}
}
/**
* Attempts to parse a tunnel access token (JWT). This does NOT validate the token
* signature or any claims.
*/
static tryParse(token) {
if (typeof token !== 'string')
throw new TypeError('Token string expected.');
// JWTs are encoded in 3 parts: header, body, and signature.
const tokenParts = token.split('.');
if (tokenParts.length !== 3) {
return null;
}
const tokenBodyJson = TunnelAccessTokenProperties.base64UrlDecode(tokenParts[1]);
if (!tokenBodyJson) {
return null;
}
try {
const tokenJson = JSON.parse(tokenBodyJson);
const clusterId = tokenJson.clusterId;
const tunnelId = tokenJson.tunnelId;
const ports = tokenJson.tunnelPorts;
const scp = tokenJson.scp;
const iss = tokenJson.iss;
const exp = tokenJson.exp;
return new TunnelAccessTokenProperties(clusterId, tunnelId, typeof ports === 'number' ? [ports] : ports, scp === null || scp === void 0 ? void 0 : scp.split(' '), iss, typeof exp === 'number' ? new Date(exp * 1000) : undefined);
}
catch (_a) {
return null;
}
}
/**
* Gets the tunnal access token trace string.
* 'none' if null or undefined, parsed token info if can be parsed, or 'token' if cannot be parsed.
*/
static getTokenTrace(token) {
var _a, _b;
return !token ? 'none' : (_b = (_a = TunnelAccessTokenProperties.tryParse(token)) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : 'token';
}
/**
* Gets a tunnel access token that matches any of the provided access token scopes.
* Validates token expiration if the token is found and throws an error if it's expired.
* @param tunnel The tunnel to get the access tokens from.
* @param accessTokenScopes What scopes the token needs to have.
* @returns Tunnel access token if found; otherwise, undefined.
*/
static getTunnelAccessToken(tunnel, accessTokenScopes) {
if (!(tunnel === null || tunnel === void 0 ? void 0 : tunnel.accessTokens) || !accessTokenScopes) {
return;
}
if (!Array.isArray(accessTokenScopes)) {
accessTokenScopes = [accessTokenScopes];
}
for (const scope of accessTokenScopes) {
for (const [key, accessToken] of Object.entries(tunnel.accessTokens)) {
// Each key may be either a single scope or space-delimited list of scopes.
if (accessToken && key.split(' ').includes(scope)) {
TunnelAccessTokenProperties.validateTokenExpiration(accessToken);
return accessToken;
}
}
}
}
static base64UrlDecode(encodedString) {
// Convert from base64url encoding to base64 encoding: replace chars and add padding.
encodedString = encodedString.replace('-', '+');
while (encodedString.length % 4 !== 0) {
encodedString += '=';
}
try {
const result = atob(encodedString);
return result;
}
catch (_a) {
return null;
}
}
}
exports.TunnelAccessTokenProperties = TunnelAccessTokenProperties;
//# sourceMappingURL=tunnelAccessTokenProperties.js.map
@@ -0,0 +1 @@
{"version":3,"file":"tunnelAccessTokenProperties.js","sourceRoot":"","sources":["../../../src/management/tunnelAccessTokenProperties.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;;;AAIlC;;;;;;;GAOG;AACH,MAAa,2BAA2B;IACpC,YACoB,SAAkB,EAClB,QAAiB,EACjB,WAAsB,EACtB,MAAiB,EACjB,MAAe,EACf,UAAiB;QALjB,cAAS,GAAT,SAAS,CAAS;QAClB,aAAQ,GAAR,QAAQ,CAAS;QACjB,gBAAW,GAAX,WAAW,CAAW;QACtB,WAAM,GAAN,MAAM,CAAW;QACjB,WAAM,GAAN,MAAM,CAAS;QACf,eAAU,GAAV,UAAU,CAAO;IAClC,CAAC;IAEG,QAAQ;QACX,IAAI,CAAC,GAAG,EAAE,CAAC;QAEX,IAAI,IAAI,CAAC,QAAQ,EAAE;YACf,CAAC,IAAI,SAAS,CAAC;YACf,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC;YAEnB,IAAI,IAAI,CAAC,SAAS,EAAE;gBAChB,CAAC,IAAI,GAAG,CAAC;gBACT,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC;aACvB;SACJ;QAED,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE;YACjD,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;gBAAE,CAAC,IAAI,IAAI,CAAC;YAC5B,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE;gBAC/B,CAAC,IAAI,QAAQ,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;aACtC;iBAAM;gBACH,CAAC,IAAI,UAAU,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;aACjD;SACJ;QAED,IAAI,IAAI,CAAC,MAAM,EAAE;YACb,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;gBAAE,CAAC,IAAI,IAAI,CAAC;YAC5B,CAAC,IAAI,WAAW,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;SAC7C;QAED,IAAI,IAAI,CAAC,MAAM,EAAE;YACb,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;gBAAE,CAAC,IAAI,IAAI,CAAC;YAC5B,CAAC,IAAI,SAAS,CAAC;YACf,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC;SACpB;QAED,IAAI,IAAI,CAAC,UAAU,EAAE;YACjB,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;gBAAE,CAAC,IAAI,IAAI,CAAC;YAC5B,CAAC,IAAI,cAAc,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;SACzE;QAED,OAAO,CAAC,CAAC;IACb,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,uBAAuB,CAAC,KAAa;QAC/C,MAAM,CAAC,GAAG,2BAA2B,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACtD,IAAI,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,UAAU,EAAE;YACf,IAAI,CAAC,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,EAAE;gBAC3B,MAAM,IAAI,KAAK,CAAC,+BAA+B,GAAG,CAAC,CAAC,CAAC;aACxD;SACJ;IACL,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,QAAQ,CAAC,KAAa;QAChC,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,MAAM,IAAI,SAAS,CAAC,wBAAwB,CAAC,CAAC;QAE7E,4DAA4D;QAC5D,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE;YACzB,OAAO,IAAI,CAAC;SACf;QAED,MAAM,aAAa,GAAG,2BAA2B,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,IAAI,CAAC,aAAa,EAAE;YAChB,OAAO,IAAI,CAAC;SACf;QAED,IAAI;YACA,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YAC5C,MAAM,SAAS,GAAuB,SAAS,CAAC,SAAS,CAAC;YAC1D,MAAM,QAAQ,GAAuB,SAAS,CAAC,QAAQ,CAAC;YACxD,MAAM,KAAK,GAAkC,SAAS,CAAC,WAAW,CAAC;YACnE,MAAM,GAAG,GAAuB,SAAS,CAAC,GAAG,CAAC;YAC9C,MAAM,GAAG,GAAuB,SAAS,CAAC,GAAG,CAAC;YAC9C,MAAM,GAAG,GAAuB,SAAS,CAAC,GAAG,CAAC;YAE9C,OAAO,IAAI,2BAA2B,CAClC,SAAS,EACT,QAAQ,EACR,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAC3C,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,KAAK,CAAC,GAAG,CAAC,EACf,GAAG,EACH,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAC7D,CAAC;SACL;QAAC,WAAM;YACJ,OAAO,IAAI,CAAC;SACf;IACL,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,aAAa,CAAC,KAAiC;;QACzD,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAA,MAAA,2BAA2B,CAAC,QAAQ,CAAC,KAAK,CAAC,0CAAE,QAAQ,EAAE,mCAAI,OAAO,CAAC;IAChG,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,oBAAoB,CAC9B,MAAsB,EACtB,iBAAqC;QAErC,IAAI,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,YAAY,CAAA,IAAI,CAAC,iBAAiB,EAAE;YAC7C,OAAO;SACV;QAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE;YACnC,iBAAiB,GAAG,CAAC,iBAAiB,CAAC,CAAC;SAC3C;QAED,KAAK,MAAM,KAAK,IAAI,iBAAiB,EAAE;YACnC,KAAK,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE;gBAClE,2EAA2E;gBAC3E,IAAI,WAAW,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;oBAC/C,2BAA2B,CAAC,uBAAuB,CAAC,WAAW,CAAC,CAAC;oBACjE,OAAO,WAAW,CAAC;iBACtB;aACJ;SACJ;IACL,CAAC;IAEO,MAAM,CAAC,eAAe,CAAC,aAAqB;QAChD,qFAAqF;QACrF,aAAa,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAChD,OAAO,aAAa,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE;YACnC,aAAa,IAAI,GAAG,CAAC;SACxB;QAED,IAAI;YACA,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC;YACnC,OAAO,MAAM,CAAC;SACjB;QAAC,WAAM;YACJ,OAAO,IAAI,CAAC;SACf;IACL,CAAC;CACJ;AA7JD,kEA6JC"}
@@ -0,0 +1,172 @@
/// <reference types="node" />
import { ClusterDetails, NamedRateStatus, Tunnel, TunnelEndpoint, TunnelPort } from '@microsoft/dev-tunnels-contracts';
import { TunnelRequestOptions } from './tunnelRequestOptions';
import * as https from 'https';
import { CancellationToken } from 'vscode-jsonrpc';
/**
* Interface for a client that manages tunnels and tunnel ports
* via the tunnel service management API.
*/
export interface TunnelManagementClient {
/**
* Override https agent for axios requests.
*/
httpsAgent?: https.Agent;
/**
* Lists tunnels that are owned by the caller.
*
* The list can be filtered by setting `TunnelRequestOptions.labels`. Ports will not be
* included in the returned tunnels unless `TunnelRequestOptions.includePorts` is set to true.
*
* @param clusterId A tunnel cluster ID, or null to list tunnels globally.
* @param domain Tunnel domain, or null for the default domain.
* @param options Request options.
* @param cancellation Optional cancellation token for the request.
*/
listTunnels(clusterId?: string, domain?: string, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<Tunnel[]>;
/**
* Gets one tunnel by ID or name.
*
* Ports will not be included in the returned tunnel unless `TunnelRequestOptions.includePorts`
* is set to true.
*
* @param tunnel Tunnel object including at least either a tunnel name (globally unique,
* if configured) or tunnel ID and cluster ID.
* @param options Request options.
* @param cancellation Optional cancellation token for the request.
*/
getTunnel(tunnel: Tunnel, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<Tunnel | null>;
/**
* Creates a tunnel.
* @param tunnel
* @param options
* @param cancellation Optional cancellation token for the request.
*/
createTunnel(tunnel: Tunnel, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<Tunnel>;
/**
* Updates properties of a tunnel.
* @param tunnel
* @param options
* @param cancellation Optional cancellation token for the request.
*/
updateTunnel(tunnel: Tunnel, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<Tunnel>;
/**
* Updates properties of a tunnel or creates it if it does not exist.
* @param tunnel
* @param options
* @param cancellation Optional cancellation token for the request.
*/
createOrUpdateTunnel(tunnel: Tunnel, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<Tunnel>;
/**
* Deletes a tunnel.
* @param tunnel
* @param options
* @param cancellation Optional cancellation token for the request.
*/
deleteTunnel(tunnel: Tunnel, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<boolean>;
/**
* Creates or updates an endpoint for the tunnel.
* @param tunnel
* @param endpoint
* @param options
* @param cancellation Optional cancellation token for the request.
*/
updateTunnelEndpoint(tunnel: Tunnel, endpoint: TunnelEndpoint, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<TunnelEndpoint>;
/**
* Deletes a tunnel endpoint.
* @param tunnel
* @param id
* @param options
* @param cancellation Optional cancellation token for the request.
*/
deleteTunnelEndpoints(tunnel: Tunnel, id: string, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<boolean>;
/**
* Lists ports on a tunnel.
*
* The list can be filtered by setting `TunnelRequestOptions.labels`.
*
* @param tunnel Tunnel object including at least either a tunnel name (globally unique,
* if configured) or tunnel ID and cluster ID.
* @param options Request options.
* @param cancellation Optional cancellation token for the request.
*/
listTunnelPorts(tunnel: Tunnel, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<TunnelPort[]>;
/**
* Gets one port on a tunnel by port number.
* @param tunnel
* @param portNumber
* @param options
* @param cancellation Optional cancellation token for the request.
*/
getTunnelPort(tunnel: Tunnel, portNumber: number, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<TunnelPort | null>;
/**
* Creates a tunnel port.
* @param tunnel
* @param tunnelPort
* @param options
* @param cancellation Optional cancellation token for the request.
*/
createTunnelPort(tunnel: Tunnel, tunnelPort: TunnelPort, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<TunnelPort>;
/**
* Updates properties of a tunnel port.
* @param tunnel
* @param tunnelPort
* @param options
* @param cancellation Optional cancellation token for the request.
*/
updateTunnelPort(tunnel: Tunnel, tunnelPort: TunnelPort, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<TunnelPort>;
/**
* Updates properties of a tunnel port or creates it if it does not exist.
* @param tunnel
* @param tunnelPort
* @param options
* @param cancellation Optional cancellation token for the request.
*/
createOrUpdateTunnelPort(tunnel: Tunnel, tunnelPort: TunnelPort, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<TunnelPort>;
/**
* Deletes a tunnel port.
* @param tunnel
* @param portNumber
* @param options
* @param cancellation Optional cancellation token for the request.
*/
deleteTunnelPort(tunnel: Tunnel, portNumber: number, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<boolean>;
/**
* Lists limits and consumption status for the calling user.
* @param cancellation Optional cancellation token for the request.
*/
listUserLimits(cancellation?: CancellationToken): Promise<NamedRateStatus[]>;
/**
* Lists details of tunneling service clusters in all supported Azure regions.
* @param cancellation Optional cancellation token for the request.
*/
listClusters(cancellation?: CancellationToken): Promise<ClusterDetails[]>;
/**
* Checks if the tunnel name is available.
* @param tunnelName
* @param cancellation Optional cancellation token for the request.
*/
checkNameAvailablility(tunnelName: string, cancellation?: CancellationToken): Promise<boolean>;
}
/**
* Interface for the user agent product information for TunnelManagementClient
*/
export interface ProductHeaderValue {
/**
* Product name.
*/
name: string;
/**
* Product version. If not supplied, 'unknown' version is used.
*/
version?: string;
}
export declare abstract class TunnelAuthenticationSchemes {
/** Authentication scheme for AAD (or Microsoft account) access tokens. */
static readonly aad = "aad";
/** Authentication scheme for GitHub access tokens. */
static readonly github = "github";
/** Authentication scheme for tunnel access tokens. */
static readonly tunnel = "tunnel";
}
//# sourceMappingURL=tunnelManagementClient.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"tunnelManagementClient.d.ts","sourceRoot":"","sources":["../../../src/management/tunnelManagementClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
Object.defineProperty(exports, "__esModule", { value: true });
exports.TunnelAuthenticationSchemes = void 0;
class TunnelAuthenticationSchemes {
}
exports.TunnelAuthenticationSchemes = TunnelAuthenticationSchemes;
/** Authentication scheme for AAD (or Microsoft account) access tokens. */
TunnelAuthenticationSchemes.aad = 'aad';
/** Authentication scheme for GitHub access tokens. */
TunnelAuthenticationSchemes.github = 'github';
/** Authentication scheme for tunnel access tokens. */
TunnelAuthenticationSchemes.tunnel = 'tunnel';
//# sourceMappingURL=tunnelManagementClient.js.map
@@ -0,0 +1 @@
{"version":3,"file":"tunnelManagementClient.js","sourceRoot":"","sources":["../../../src/management/tunnelManagementClient.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;;;AAuOlC,MAAsB,2BAA2B;;AAAjD,kEASC;AARG,0EAA0E;AACnD,+BAAG,GAAG,KAAK,CAAC;AAEnC,sDAAsD;AAC/B,kCAAM,GAAG,QAAQ,CAAC;AAEzC,sDAAsD;AAC/B,kCAAM,GAAG,QAAQ,CAAC"}
@@ -0,0 +1,122 @@
/// <reference types="node" />
import { Tunnel, TunnelEndpoint, TunnelPort, ClusterDetails, NamedRateStatus, TunnelReportProgressEventArgs } from '@microsoft/dev-tunnels-contracts';
import { ProductHeaderValue, TunnelManagementClient } from './tunnelManagementClient';
import { TunnelRequestOptions } from './tunnelRequestOptions';
import { AxiosAdapter, Method } from 'axios';
import * as https from 'https';
import { CancellationToken, Event } from 'vscode-jsonrpc';
type NullableIfNotBoolean<T> = T extends boolean ? T : T | null;
export declare enum ManagementApiVersions {
Version20230927preview = "2023-09-27-preview"
}
export declare class TunnelManagementHttpClient implements TunnelManagementClient {
readonly httpsAgent?: https.Agent | undefined;
private readonly adapter?;
additionalRequestHeaders?: {
[header: string]: string;
};
apiVersion: string;
private readonly baseAddress;
private readonly userTokenCallback;
private readonly userAgents;
private readonly reportProgressEmitter;
/**
* Event that is raised to report tunnel management progress.
*
* See `Progress` for a description of the different progress events that can be reported.
*/
readonly onReportProgress: Event<TunnelReportProgressEventArgs>;
trace: (msg: string) => void;
/**
* Initializes a new instance of the `TunnelManagementHttpClient` class
* with a client authentication callback, service URI, and HTTP handler.
*
* @param userAgent { name, version } object or a comment string to use as the User-Agent header.
* @param apiVersion ApiVersion to be used for requests, value should be one of ManagementApiVersions enum.
* @param userTokenCallback Optional async callback for retrieving a client authentication
* header value with access token, for AAD or GitHub user authentication. This may be omitted
* for anonymous tunnel clients, or if tunnel access tokens will be specified via
* `TunnelRequestOptions.accessToken`.
* @param tunnelServiceUri Optional tunnel service URI (not including any path). Defaults to
* the global tunnel service URI.
* @param httpsAgent Optional agent that will be invoked for HTTPS requests to the tunnel
* service.
* @param adapter Optional axios adapter to use for HTTP requests.
*/
constructor(userAgents: (ProductHeaderValue | string)[] | ProductHeaderValue | string, apiVersion: ManagementApiVersions, userTokenCallback?: () => Promise<string | null>, tunnelServiceUri?: string, httpsAgent?: https.Agent | undefined, adapter?: AxiosAdapter | undefined);
listTunnels(clusterId?: string, domain?: string, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<Tunnel[]>;
getTunnel(tunnel: Tunnel, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<Tunnel | null>;
createTunnel(tunnel: Tunnel, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<Tunnel>;
createOrUpdateTunnel(tunnel: Tunnel, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<Tunnel>;
updateTunnel(tunnel: Tunnel, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<Tunnel>;
deleteTunnel(tunnel: Tunnel, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<boolean>;
updateTunnelEndpoint(tunnel: Tunnel, endpoint: TunnelEndpoint, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<TunnelEndpoint>;
deleteTunnelEndpoints(tunnel: Tunnel, id: string, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<boolean>;
listUserLimits(cancellation?: CancellationToken): Promise<NamedRateStatus[]>;
listTunnelPorts(tunnel: Tunnel, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<TunnelPort[]>;
getTunnelPort(tunnel: Tunnel, portNumber: number, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<TunnelPort | null>;
createTunnelPort(tunnel: Tunnel, tunnelPort: TunnelPort, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<TunnelPort>;
updateTunnelPort(tunnel: Tunnel, tunnelPort: TunnelPort, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<TunnelPort>;
createOrUpdateTunnelPort(tunnel: Tunnel, tunnelPort: TunnelPort, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<TunnelPort>;
deleteTunnelPort(tunnel: Tunnel, portNumber: number, options?: TunnelRequestOptions, cancellation?: CancellationToken): Promise<boolean>;
listClusters(cancellation?: CancellationToken): Promise<ClusterDetails[]>;
/**
* Sends an HTTP request to the tunnel management API, targeting a specific tunnel.
* This protected method enables subclasses to support additional tunnel management APIs.
* @param method HTTP request method.
* @param tunnel Tunnel that the request is targeting.
* @param accessTokenScopes Required array of access scopes for tokens in `tunnel.accessTokens`
* that could be used to authorize the request.
* @param path Optional request sub-path relative to the tunnel.
* @param query Optional query string to append to the request.
* @param options Request options.
* @param body Optional request body object.
* @param allowNotFound If true, a 404 response is returned as a null or false result
* instead of an error.
* @param cancellationToken Optional cancellation token for the request.
* @param isCreate Set to true if this is a tunnel create request, default is false.
* @returns Result of the request.
*/
protected sendTunnelRequest<TResult>(method: Method, tunnel: Tunnel, accessTokenScopes: string[], path?: string, query?: string, options?: TunnelRequestOptions, body?: object, allowNotFound?: boolean, cancellation?: CancellationToken, isCreate?: boolean): Promise<NullableIfNotBoolean<TResult>>;
/**
* Sends an HTTP request to the tunnel management API.
* This protected method enables subclasses to support additional tunnel management APIs.
* @param method HTTP request method.
* @param clusterId Optional tunnel service cluster ID to direct the request to. If unspecified,
* the request will use the global traffic-manager to find the nearest cluster.
* @param path Required request path.
* @param query Optional query string to append to the request.
* @param options Request options.
* @param body Optional request body object.
* @param allowNotFound If true, a 404 response is returned as a null or false result
* instead of an error.
* @param cancellationToken Optional cancellation token for the request.
* @returns Result of the request.
*/
protected sendRequest<TResult>(method: Method, clusterId: string | undefined, path: string, query?: string, options?: TunnelRequestOptions, body?: object, allowNotFound?: boolean, cancellation?: CancellationToken): Promise<NullableIfNotBoolean<TResult>>;
checkNameAvailablility(tunnelName: string, cancellation?: CancellationToken): Promise<boolean>;
private raiseReportProgress;
private getResponseErrorMessage;
private buildUri;
private buildUriForTunnel;
private getAxiosRequestConfig;
private convertTunnelForRequest;
private convertTunnelPortForRequest;
private tunnelRequestOptionsToQueryString;
/**
* Axios request that can be overridden for unit tests purposes.
* @param config axios request config
* @param _cancellation the cancellation token for the request (used by unit tests to simulate timeouts).
*/
private axiosRequest;
/**
* Makes an HTTP request using Axios, while tracing request and response details.
*/
private request;
private traceHeaders;
private traceAuthorizationHeader;
private traceContent;
private static replaceTokensInContent;
}
export {};
//# sourceMappingURL=tunnelManagementHttpClient.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"tunnelManagementHttpClient.d.ts","sourceRoot":"","sources":["../../../src/management/tunnelManagementHttpClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,787 @@
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
Object.defineProperty(exports, "__esModule", { value: true });
exports.TunnelManagementHttpClient = exports.ManagementApiVersions = void 0;
const dev_tunnels_contracts_1 = require("@microsoft/dev-tunnels-contracts");
const tunnelManagementClient_1 = require("./tunnelManagementClient");
const tunnelAccessTokenProperties_1 = require("./tunnelAccessTokenProperties");
const version_1 = require("./version");
const axios_1 = require("axios");
const tunnelPlanTokenProperties_1 = require("./tunnelPlanTokenProperties");
const idGeneration_1 = require("./idGeneration");
const vscode_jsonrpc_1 = require("vscode-jsonrpc");
const tunnelsApiPath = '/tunnels';
const limitsApiPath = '/userlimits';
const endpointsApiSubPath = '/endpoints';
const portsApiSubPath = '/ports';
const clustersApiPath = '/clusters';
const tunnelAuthentication = 'Authorization';
const checkAvailablePath = ':checkNameAvailability';
const createNameRetries = 3;
var ManagementApiVersions;
(function (ManagementApiVersions) {
ManagementApiVersions["Version20230927preview"] = "2023-09-27-preview";
})(ManagementApiVersions = exports.ManagementApiVersions || (exports.ManagementApiVersions = {}));
function comparePorts(a, b) {
var _a, _b;
return ((_a = a.portNumber) !== null && _a !== void 0 ? _a : Number.MAX_SAFE_INTEGER) - ((_b = b.portNumber) !== null && _b !== void 0 ? _b : Number.MAX_SAFE_INTEGER);
}
function parseDate(value) {
return typeof value === 'string' ? new Date(Date.parse(value)) : value;
}
/**
* Fixes Tunnel properties of type Date that were deserialized as strings.
*/
function parseTunnelDates(tunnel) {
if (!tunnel)
return;
tunnel.created = parseDate(tunnel.created);
if (tunnel.status) {
tunnel.status.lastHostConnectionTime = parseDate(tunnel.status.lastHostConnectionTime);
tunnel.status.lastClientConnectionTime = parseDate(tunnel.status.lastClientConnectionTime);
}
}
/**
* Fixes TunnelPort properties of type Date that were deserialized as strings.
*/
function parseTunnelPortDates(port) {
if (!port)
return;
if (port.status) {
port.status.lastClientConnectionTime = parseDate(port.status.lastClientConnectionTime);
}
}
/**
* Copy access tokens from the request object to the result object, except for any
* tokens that were refreshed by the request.
*/
function preserveAccessTokens(requestObject, resultObject) {
var _a;
// This intentionally does not check whether any existing tokens are expired. So
// expired tokens may be preserved also, if not refreshed. This allows for better
// diagnostics in that case.
if (requestObject.accessTokens && resultObject) {
(_a = resultObject.accessTokens) !== null && _a !== void 0 ? _a : (resultObject.accessTokens = {});
for (const scopeAndToken of Object.entries(requestObject.accessTokens)) {
if (!resultObject.accessTokens[scopeAndToken[0]]) {
resultObject.accessTokens[scopeAndToken[0]] = scopeAndToken[1];
}
}
}
}
const manageAccessTokenScope = [dev_tunnels_contracts_1.TunnelAccessScopes.Manage];
const hostAccessTokenScope = [dev_tunnels_contracts_1.TunnelAccessScopes.Host];
const managePortsAccessTokenScopes = [
dev_tunnels_contracts_1.TunnelAccessScopes.Manage,
dev_tunnels_contracts_1.TunnelAccessScopes.ManagePorts,
dev_tunnels_contracts_1.TunnelAccessScopes.Host,
];
const readAccessTokenScopes = [
dev_tunnels_contracts_1.TunnelAccessScopes.Manage,
dev_tunnels_contracts_1.TunnelAccessScopes.ManagePorts,
dev_tunnels_contracts_1.TunnelAccessScopes.Host,
dev_tunnels_contracts_1.TunnelAccessScopes.Connect,
];
const apiVersions = ["2023-09-27-preview"];
const defaultRequestTimeoutMS = 20000;
class TunnelManagementHttpClient {
/**
* Initializes a new instance of the `TunnelManagementHttpClient` class
* with a client authentication callback, service URI, and HTTP handler.
*
* @param userAgent { name, version } object or a comment string to use as the User-Agent header.
* @param apiVersion ApiVersion to be used for requests, value should be one of ManagementApiVersions enum.
* @param userTokenCallback Optional async callback for retrieving a client authentication
* header value with access token, for AAD or GitHub user authentication. This may be omitted
* for anonymous tunnel clients, or if tunnel access tokens will be specified via
* `TunnelRequestOptions.accessToken`.
* @param tunnelServiceUri Optional tunnel service URI (not including any path). Defaults to
* the global tunnel service URI.
* @param httpsAgent Optional agent that will be invoked for HTTPS requests to the tunnel
* service.
* @param adapter Optional axios adapter to use for HTTP requests.
*/
constructor(userAgents, apiVersion, userTokenCallback, tunnelServiceUri, httpsAgent, adapter) {
var _a;
this.httpsAgent = httpsAgent;
this.adapter = adapter;
this.reportProgressEmitter = new vscode_jsonrpc_1.Emitter();
/**
* Event that is raised to report tunnel management progress.
*
* See `Progress` for a description of the different progress events that can be reported.
*/
this.onReportProgress = this.reportProgressEmitter.event;
this.trace = (msg) => { };
if (apiVersions.indexOf(apiVersion) === -1) {
throw new TypeError(`Invalid API version: ${apiVersion}, must be one of ${apiVersions}`);
}
this.apiVersion = apiVersion;
if (!userAgents) {
throw new TypeError('User agent must be provided.');
}
if (Array.isArray(userAgents)) {
if (userAgents.length === 0) {
throw new TypeError('User agents cannot be empty.');
}
let combinedUserAgents = '';
userAgents.forEach((userAgent) => {
var _a;
if (typeof userAgent !== 'string') {
if (!userAgent.name) {
throw new TypeError('Invalid user agent. The name must be provided.');
}
if (typeof userAgent.name !== 'string') {
throw new TypeError('Invalid user agent. The name must be a string.');
}
if (userAgent.version && typeof userAgent.version !== 'string') {
throw new TypeError('Invalid user agent. The version must be a string.');
}
combinedUserAgents = `${combinedUserAgents}${userAgent.name}/${(_a = userAgent.version) !== null && _a !== void 0 ? _a : 'unknown'} `;
}
else {
combinedUserAgents = `${combinedUserAgents}${userAgent} `;
}
});
this.userAgents = combinedUserAgents.trim();
}
else if (typeof userAgents !== 'string') {
if (!userAgents.name) {
throw new TypeError('Invalid user agent. The name must be provided.');
}
if (typeof userAgents.name !== 'string') {
throw new TypeError('Invalid user agent. The name must be a string.');
}
if (userAgents.version && typeof userAgents.version !== 'string') {
throw new TypeError('Invalid user agent. The version must be a string.');
}
this.userAgents = `${userAgents.name}/${(_a = userAgents.version) !== null && _a !== void 0 ? _a : 'unknown'}`;
}
else {
this.userAgents = userAgents;
}
this.userTokenCallback = userTokenCallback !== null && userTokenCallback !== void 0 ? userTokenCallback : (() => Promise.resolve(null));
if (!tunnelServiceUri) {
tunnelServiceUri = dev_tunnels_contracts_1.TunnelServiceProperties.production.serviceUri;
}
const parsedUri = new URL(tunnelServiceUri);
if (!parsedUri || parsedUri.pathname !== '/') {
throw new TypeError(`Invalid tunnel service URI: ${tunnelServiceUri}`);
}
this.baseAddress = tunnelServiceUri;
}
async listTunnels(clusterId, domain, options, cancellation) {
const queryParams = [clusterId ? null : 'global=true', domain ? `domain=${domain}` : null];
const query = queryParams.filter((p) => !!p).join('&');
const results = (await this.sendRequest('GET', clusterId, tunnelsApiPath, query, options, undefined, undefined, cancellation));
let tunnels = new Array();
if (results.value) {
for (const region of results.value) {
if (region.value) {
tunnels = tunnels.concat(region.value);
}
}
}
tunnels.forEach(parseTunnelDates);
return tunnels;
}
async getTunnel(tunnel, options, cancellation) {
const result = await this.sendTunnelRequest('GET', tunnel, readAccessTokenScopes, undefined, undefined, options, undefined, undefined, cancellation);
preserveAccessTokens(tunnel, result);
parseTunnelDates(result);
return result;
}
async createTunnel(tunnel, options, cancellation) {
const tunnelId = tunnel.tunnelId;
const idGenerated = tunnelId === undefined || tunnelId === null || tunnelId === '';
options = options || {};
options.additionalHeaders = options.additionalHeaders || {};
options.additionalHeaders['If-Not-Match'] = "*";
if (idGenerated) {
tunnel.tunnelId = idGeneration_1.IdGeneration.generateTunnelId();
}
for (let i = 0; i <= createNameRetries; i++) {
try {
const result = (await this.sendTunnelRequest('PUT', tunnel, manageAccessTokenScope, undefined, undefined, options, this.convertTunnelForRequest(tunnel), undefined, cancellation, true));
preserveAccessTokens(tunnel, result);
parseTunnelDates(result);
return result;
}
catch (error) {
if (idGenerated) {
// The tunnel ID was generated and there was a conflict.
// Try again with a new ID.
tunnel.tunnelId = idGeneration_1.IdGeneration.generateTunnelId();
}
else {
throw error;
}
}
}
const result2 = (await this.sendTunnelRequest('PUT', tunnel, manageAccessTokenScope, undefined, undefined, options, this.convertTunnelForRequest(tunnel), undefined, cancellation, true));
preserveAccessTokens(tunnel, result2);
parseTunnelDates(result2);
return result2;
}
async createOrUpdateTunnel(tunnel, options, cancellation) {
const tunnelId = tunnel.tunnelId;
const idGenerated = tunnelId === undefined || tunnelId === null || tunnelId === '';
if (idGenerated) {
tunnel.tunnelId = idGeneration_1.IdGeneration.generateTunnelId();
}
for (let i = 0; i <= createNameRetries; i++) {
try {
const result = (await this.sendTunnelRequest('PUT', tunnel, manageAccessTokenScope, undefined, undefined, options, this.convertTunnelForRequest(tunnel), undefined, cancellation, true));
preserveAccessTokens(tunnel, result);
parseTunnelDates(result);
return result;
}
catch (error) {
if (idGenerated) {
// The tunnel ID was generated and there was a conflict.
// Try again with a new ID.
tunnel.tunnelId = idGeneration_1.IdGeneration.generateTunnelId();
}
else {
throw error;
}
}
}
const result2 = (await this.sendTunnelRequest('PUT', tunnel, manageAccessTokenScope, undefined, "forceCreate=true", options, this.convertTunnelForRequest(tunnel), undefined, cancellation, true));
preserveAccessTokens(tunnel, result2);
parseTunnelDates(result2);
return result2;
}
async updateTunnel(tunnel, options, cancellation) {
options = options || {};
options.additionalHeaders = options.additionalHeaders || {};
options.additionalHeaders['If-Match'] = "*";
const result = (await this.sendTunnelRequest('PUT', tunnel, manageAccessTokenScope, undefined, undefined, options, this.convertTunnelForRequest(tunnel), undefined, cancellation));
preserveAccessTokens(tunnel, result);
parseTunnelDates(result);
return result;
}
async deleteTunnel(tunnel, options, cancellation) {
return await this.sendTunnelRequest('DELETE', tunnel, manageAccessTokenScope, undefined, undefined, options, undefined, true, cancellation);
}
async updateTunnelEndpoint(tunnel, endpoint, options, cancellation) {
if (endpoint.id == null) {
throw new Error('Endpoint ID must be specified when updating an endpoint.');
}
const path = `${endpointsApiSubPath}/${endpoint.id}`;
const result = (await this.sendTunnelRequest('PUT', tunnel, hostAccessTokenScope, path, "connectionMode=" + endpoint.connectionMode, options, endpoint, undefined, cancellation));
if (tunnel.endpoints) {
// Also update the endpoint in the local tunnel object.
tunnel.endpoints = tunnel.endpoints
.filter((e) => e.hostId !== endpoint.hostId ||
e.connectionMode !== endpoint.connectionMode)
.concat(result);
}
return result;
}
async deleteTunnelEndpoints(tunnel, id, options, cancellation) {
const path = `${endpointsApiSubPath}/${id}`;
const result = await this.sendTunnelRequest('DELETE', tunnel, hostAccessTokenScope, path, undefined, options, undefined, true, cancellation);
if (result && tunnel.endpoints) {
// Also delete the endpoint in the local tunnel object.
tunnel.endpoints = tunnel.endpoints.filter((e) => e.id !== id);
}
return result;
}
async listUserLimits(cancellation) {
const results = await this.sendRequest('GET', undefined, limitsApiPath, undefined, undefined, undefined, undefined, cancellation);
return results || [];
}
async listTunnelPorts(tunnel, options, cancellation) {
const results = (await this.sendTunnelRequest('GET', tunnel, readAccessTokenScopes, portsApiSubPath, undefined, options, undefined, undefined, cancellation));
if (results.value) {
results.value.forEach(parseTunnelPortDates);
}
return results.value;
}
async getTunnelPort(tunnel, portNumber, options, cancellation) {
this.raiseReportProgress(dev_tunnels_contracts_1.TunnelProgress.StartingGetTunnelPort);
const path = `${portsApiSubPath}/${portNumber}`;
const result = await this.sendTunnelRequest('GET', tunnel, readAccessTokenScopes, path, undefined, options, undefined, undefined, cancellation);
parseTunnelPortDates(result);
this.raiseReportProgress(dev_tunnels_contracts_1.TunnelProgress.CompletedGetTunnelPort);
return result;
}
async createTunnelPort(tunnel, tunnelPort, options, cancellation) {
this.raiseReportProgress(dev_tunnels_contracts_1.TunnelProgress.StartingCreateTunnelPort);
tunnelPort = this.convertTunnelPortForRequest(tunnel, tunnelPort);
const path = `${portsApiSubPath}/${tunnelPort.portNumber}`;
options = options || {};
options.additionalHeaders = options.additionalHeaders || {};
options.additionalHeaders['If-Not-Match'] = "*";
const result = (await this.sendTunnelRequest('PUT', tunnel, managePortsAccessTokenScopes, path, undefined, options, tunnelPort, undefined, cancellation));
tunnel.ports = tunnel.ports || [];
// Also add the port to the local tunnel object.
tunnel.ports = tunnel.ports
.filter((p) => p.portNumber !== tunnelPort.portNumber)
.concat(result)
.sort(comparePorts);
parseTunnelPortDates(result);
this.raiseReportProgress(dev_tunnels_contracts_1.TunnelProgress.CompletedCreateTunnelPort);
return result;
}
async updateTunnelPort(tunnel, tunnelPort, options, cancellation) {
if (tunnelPort.clusterId && tunnel.clusterId && tunnelPort.clusterId !== tunnel.clusterId) {
throw new Error('Tunnel port cluster ID is not consistent.');
}
options = options || {};
options.additionalHeaders = options.additionalHeaders || {};
options.additionalHeaders['If-Match'] = "*";
const portNumber = tunnelPort.portNumber;
const path = `${portsApiSubPath}/${portNumber}`;
tunnelPort = this.convertTunnelPortForRequest(tunnel, tunnelPort);
const result = (await this.sendTunnelRequest('PUT', tunnel, managePortsAccessTokenScopes, path, undefined, options, tunnelPort, undefined, cancellation));
preserveAccessTokens(tunnelPort, result);
parseTunnelPortDates(result);
tunnel.ports = tunnel.ports || [];
// Also add the port to the local tunnel object.
tunnel.ports = tunnel.ports
.filter((p) => p.portNumber !== tunnelPort.portNumber)
.concat(result)
.sort(comparePorts);
return result;
}
async createOrUpdateTunnelPort(tunnel, tunnelPort, options, cancellation) {
tunnelPort = this.convertTunnelPortForRequest(tunnel, tunnelPort);
const path = `${portsApiSubPath}/${tunnelPort.portNumber}`;
const result = (await this.sendTunnelRequest('PUT', tunnel, managePortsAccessTokenScopes, path, undefined, options, tunnelPort, undefined, cancellation));
tunnel.ports = tunnel.ports || [];
// Also add the port to the local tunnel object.
tunnel.ports = tunnel.ports
.filter((p) => p.portNumber !== tunnelPort.portNumber)
.concat(result)
.sort(comparePorts);
parseTunnelPortDates(result);
return result;
}
async deleteTunnelPort(tunnel, portNumber, options, cancellation) {
const path = `${portsApiSubPath}/${portNumber}`;
const result = await this.sendTunnelRequest('DELETE', tunnel, managePortsAccessTokenScopes, path, undefined, options, undefined, true, cancellation);
if (result && tunnel.ports) {
// Also delete the port in the local tunnel object.
tunnel.ports = tunnel.ports
.filter((p) => p.portNumber !== portNumber)
.sort(comparePorts);
}
return result;
}
async listClusters(cancellation) {
return (await this.sendRequest('GET', undefined, clustersApiPath, undefined, undefined, undefined, false, cancellation));
}
/**
* Sends an HTTP request to the tunnel management API, targeting a specific tunnel.
* This protected method enables subclasses to support additional tunnel management APIs.
* @param method HTTP request method.
* @param tunnel Tunnel that the request is targeting.
* @param accessTokenScopes Required array of access scopes for tokens in `tunnel.accessTokens`
* that could be used to authorize the request.
* @param path Optional request sub-path relative to the tunnel.
* @param query Optional query string to append to the request.
* @param options Request options.
* @param body Optional request body object.
* @param allowNotFound If true, a 404 response is returned as a null or false result
* instead of an error.
* @param cancellationToken Optional cancellation token for the request.
* @param isCreate Set to true if this is a tunnel create request, default is false.
* @returns Result of the request.
*/
async sendTunnelRequest(method, tunnel, accessTokenScopes, path, query, options, body, allowNotFound, cancellation, isCreate = false) {
this.raiseReportProgress(dev_tunnels_contracts_1.TunnelProgress.StartingRequestUri);
const uri = await this.buildUriForTunnel(tunnel, path, query, options, isCreate);
this.raiseReportProgress(dev_tunnels_contracts_1.TunnelProgress.StartingRequestConfig);
const config = await this.getAxiosRequestConfig(tunnel, options, accessTokenScopes);
this.raiseReportProgress(dev_tunnels_contracts_1.TunnelProgress.StartingSendTunnelRequest);
const result = await this.request(method, uri, body, config, allowNotFound, cancellation);
this.raiseReportProgress(dev_tunnels_contracts_1.TunnelProgress.CompletedSendTunnelRequest);
return result;
}
/**
* Sends an HTTP request to the tunnel management API.
* This protected method enables subclasses to support additional tunnel management APIs.
* @param method HTTP request method.
* @param clusterId Optional tunnel service cluster ID to direct the request to. If unspecified,
* the request will use the global traffic-manager to find the nearest cluster.
* @param path Required request path.
* @param query Optional query string to append to the request.
* @param options Request options.
* @param body Optional request body object.
* @param allowNotFound If true, a 404 response is returned as a null or false result
* instead of an error.
* @param cancellationToken Optional cancellation token for the request.
* @returns Result of the request.
*/
async sendRequest(method, clusterId, path, query, options, body, allowNotFound, cancellation) {
this.raiseReportProgress(dev_tunnels_contracts_1.TunnelProgress.StartingSendTunnelRequest);
const uri = await this.buildUri(clusterId, path, query, options);
const config = await this.getAxiosRequestConfig(undefined, options);
const result = await this.request(method, uri, body, config, allowNotFound, cancellation);
this.raiseReportProgress(dev_tunnels_contracts_1.TunnelProgress.CompletedSendTunnelRequest);
return result;
}
async checkNameAvailablility(tunnelName, cancellation) {
tunnelName = encodeURI(tunnelName);
const uri = await this.buildUri(undefined, `${tunnelsApiPath}/${tunnelName}${checkAvailablePath}`);
const config = {
httpsAgent: this.httpsAgent,
adapter: this.adapter,
};
return await this.request('GET', uri, undefined, config, undefined, cancellation);
}
raiseReportProgress(progress) {
const args = {
progress: progress
};
this.reportProgressEmitter.fire(args);
}
getResponseErrorMessage(error, signal) {
var _a, _b, _c, _d;
let errorMessage = '';
if (error.code === 'ECONNABORTED') {
// server timeout
errorMessage = `Timeout reached: ${error.message}`;
}
if (signal.aborted) {
// connection timeout
errorMessage = `Signal aborted: ${error.message}`;
}
if ((_a = error.response) === null || _a === void 0 ? void 0 : _a.data) {
const problemDetails = error.response.data;
if (problemDetails.title || problemDetails.detail) {
errorMessage = `Tunnel service error: ${problemDetails.title}`;
if (problemDetails.detail) {
errorMessage += ' ' + problemDetails.detail;
}
if (problemDetails.errors) {
errorMessage += JSON.stringify(problemDetails.errors);
}
}
}
if (!errorMessage) {
if (error === null || error === void 0 ? void 0 : error.response) {
errorMessage =
'Tunnel service returned status code: ' +
`${error.response.status} ${error.response.statusText}`;
}
else {
errorMessage = (_c = (_b = error === null || error === void 0 ? void 0 : error.message) !== null && _b !== void 0 ? _b : error) !== null && _c !== void 0 ? _c : 'Unknown tunnel service request error.';
}
}
const requestIdHeaderName = 'VsSaaS-Request-Id';
if (((_d = error.response) === null || _d === void 0 ? void 0 : _d.headers) && error.response.headers[requestIdHeaderName]) {
errorMessage += `\nRequest ID: ${error.response.headers[requestIdHeaderName]}`;
}
return errorMessage;
}
// Helper functions
async buildUri(clusterId, path, query, options) {
if (clusterId === undefined && this.userTokenCallback) {
let token = await this.userTokenCallback();
if (token && token.startsWith("tunnelplan")) {
token = token.replace("tunnelplan ", "");
const parsedToken = tunnelPlanTokenProperties_1.TunnelPlanTokenProperties.tryParse(token);
if (parsedToken !== null && parsedToken.clusterId) {
clusterId = parsedToken.clusterId;
}
}
}
let baseAddress = this.baseAddress;
if (clusterId) {
const url = new URL(baseAddress);
const portNumber = parseInt(url.port, 10);
if (url.hostname !== 'localhost' && !url.hostname.startsWith(`${clusterId}.`)) {
// A specific cluster ID was specified (while not running on localhost).
// Prepend the cluster ID to the hostname, and optionally strip a global prefix.
url.hostname = `${clusterId}.${url.hostname}`.replace('global.', '');
baseAddress = url.toString();
}
else if (url.protocol === 'https:' &&
clusterId.startsWith('localhost') &&
portNumber % 10 > 0) {
// Local testing simulates clusters by running the service on multiple ports.
// Change the port number to match the cluster ID suffix.
const clusterNumber = parseInt(clusterId.substring('localhost'.length), 10);
if (clusterNumber > 0 && clusterNumber < 10) {
url.port = (portNumber - (portNumber % 10) + clusterNumber).toString();
baseAddress = url.toString();
}
}
}
baseAddress = `${baseAddress.replace(/\/$/, '')}${path}`;
const optionsQuery = this.tunnelRequestOptionsToQueryString(options, query);
if (optionsQuery) {
baseAddress += `?${optionsQuery}`;
}
return baseAddress;
}
buildUriForTunnel(tunnel, path, query, options, isCreate = false) {
let tunnelPath = '';
if ((tunnel.clusterId || isCreate) && tunnel.tunnelId) {
tunnelPath = `${tunnelsApiPath}/${tunnel.tunnelId}`;
}
else {
throw new Error('Tunnel object must include a tunnel ID always and cluster ID for non creates.');
}
if (options === null || options === void 0 ? void 0 : options.additionalQueryParameters) {
for (const [paramName, paramValue] of Object.entries(options.additionalQueryParameters)) {
if (query) {
query += `&${paramName}=${paramValue}`;
}
else {
query = `${paramName}=${paramValue}`;
}
}
}
return this.buildUri(tunnel.clusterId, tunnelPath + (path ? path : ''), query, options);
}
async getAxiosRequestConfig(tunnel, options, accessTokenScopes) {
// Get access token header
const headers = {};
if (options && options.accessToken) {
tunnelAccessTokenProperties_1.TunnelAccessTokenProperties.validateTokenExpiration(options.accessToken);
headers[tunnelAuthentication] = `${tunnelManagementClient_1.TunnelAuthenticationSchemes.tunnel} ${options.accessToken}`;
}
if (!(tunnelAuthentication in headers) && this.userTokenCallback) {
const token = await this.userTokenCallback();
if (token) {
headers[tunnelAuthentication] = token;
}
}
if (!(tunnelAuthentication in headers)) {
const accessToken = tunnelAccessTokenProperties_1.TunnelAccessTokenProperties.getTunnelAccessToken(tunnel, accessTokenScopes);
if (accessToken) {
headers[tunnelAuthentication] = `${tunnelManagementClient_1.TunnelAuthenticationSchemes.tunnel} ${accessToken}`;
}
}
const copyAdditionalHeaders = (additionalHeaders) => {
if (additionalHeaders) {
for (const [headerName, headerValue] of Object.entries(additionalHeaders)) {
headers[headerName] = headerValue;
}
}
};
copyAdditionalHeaders(this.additionalRequestHeaders);
copyAdditionalHeaders(options === null || options === void 0 ? void 0 : options.additionalHeaders);
const userAgentPrefix = headers['User-Agent'] ? headers['User-Agent'] + ' ' : '';
headers['User-Agent'] = `${userAgentPrefix}${this.userAgents} ${version_1.tunnelSdkUserAgent}`;
// Get axios config
const config = Object.assign(Object.assign({ headers }, (this.httpsAgent && { httpsAgent: this.httpsAgent })), (this.adapter && { adapter: this.adapter }));
if ((options === null || options === void 0 ? void 0 : options.followRedirects) === false) {
config.maxRedirects = 0;
}
return config;
}
convertTunnelForRequest(tunnel) {
var _a;
const convertedTunnel = {
tunnelId: tunnel.tunnelId,
name: tunnel.name,
domain: tunnel.domain,
description: tunnel.description,
labels: tunnel.labels,
options: tunnel.options,
customExpiration: tunnel.customExpiration,
accessControl: !tunnel.accessControl
? undefined
: { entries: tunnel.accessControl.entries.filter((ace) => !ace.isInherited) },
endpoints: tunnel.endpoints,
ports: (_a = tunnel.ports) === null || _a === void 0 ? void 0 : _a.map((p) => this.convertTunnelPortForRequest(tunnel, p)),
};
return convertedTunnel;
}
convertTunnelPortForRequest(tunnel, tunnelPort) {
if (tunnelPort.clusterId && tunnel.clusterId && tunnelPort.clusterId !== tunnel.clusterId) {
throw new Error('Tunnel port cluster ID does not match tunnel.');
}
if (tunnelPort.tunnelId && tunnel.tunnelId && tunnelPort.tunnelId !== tunnel.tunnelId) {
throw new Error('Tunnel port tunnel ID does not match tunnel.');
}
return {
portNumber: tunnelPort.portNumber,
protocol: tunnelPort.protocol,
isDefault: tunnelPort.isDefault,
description: tunnelPort.description,
labels: tunnelPort.labels,
sshUser: tunnelPort.sshUser,
options: tunnelPort.options,
accessControl: !tunnelPort.accessControl
? undefined
: { entries: tunnelPort.accessControl.entries.filter((ace) => !ace.isInherited) },
};
}
tunnelRequestOptionsToQueryString(options, additionalQuery) {
const queryOptions = {};
const queryItems = [];
if (options) {
if (options.includePorts) {
queryOptions.includePorts = ['true'];
}
if (options.includeAccessControl) {
queryOptions.includeAccessControl = ['true'];
}
if (options.tokenScopes) {
dev_tunnels_contracts_1.TunnelAccessControl.validateScopes(options.tokenScopes, undefined, true);
queryOptions.tokenScopes = options.tokenScopes;
}
if (options.forceRename) {
queryOptions.forceRename = ['true'];
}
if (options.labels) {
queryOptions.labels = options.labels;
if (options.requireAllLabels) {
queryOptions.allLabels = ['true'];
}
}
if (options.limit) {
queryOptions.limit = [options.limit.toString()];
}
queryItems.push(...Object.keys(queryOptions).map((key) => {
const value = queryOptions[key];
return `${key}=${value.map(encodeURIComponent).join(',')}`;
}));
}
if (additionalQuery) {
queryItems.push(additionalQuery);
}
queryItems.push(`api-version=${this.apiVersion}`);
const queryString = queryItems.join('&');
return queryString;
}
/**
* Axios request that can be overridden for unit tests purposes.
* @param config axios request config
* @param _cancellation the cancellation token for the request (used by unit tests to simulate timeouts).
*/
async axiosRequest(config, _cancellation) {
return await axios_1.default.request(config);
}
/**
* Makes an HTTP request using Axios, while tracing request and response details.
*/
async request(method, uri, data, config, allowNotFound, cancellation) {
var _a, _b;
this.trace(`${method} ${uri}`);
if (config.headers) {
this.traceHeaders(config.headers);
}
this.traceContent(data);
const traceResponse = (response) => {
this.trace(`${response.status} ${response.statusText}`);
this.traceHeaders(response.headers);
this.traceContent(response.data);
};
let disposable;
const abortController = new AbortController();
let timeout = undefined;
const newAbortSignal = () => {
if (cancellation === null || cancellation === void 0 ? void 0 : cancellation.isCancellationRequested) {
abortController.abort('Cancelled: CancellationToken cancel requested.');
}
else if (cancellation) {
disposable = cancellation.onCancellationRequested(() => abortController.abort('Cancelled: CancellationToken cancel requested.'));
}
else {
timeout = setTimeout(() => abortController.abort('Cancelled: default request timeout reached.'), defaultRequestTimeoutMS);
}
return abortController.signal;
};
try {
config.url = uri;
config.method = method;
config.data = data;
config.signal = newAbortSignal();
config.timeout = defaultRequestTimeoutMS;
const response = await this.axiosRequest(config, cancellation);
traceResponse(response);
// This assumes that TResult is always boolean for DELETE requests.
return (method === 'DELETE' ? true : response.data);
}
catch (e) {
if (!(e instanceof Error) || !e.isAxiosError)
throw e;
const requestError = e;
if (requestError.response) {
traceResponse(requestError.response);
if (allowNotFound && requestError.response.status === 404) {
return (method === 'DELETE' ? false : null);
}
}
requestError.message = this.getResponseErrorMessage(requestError, abortController.signal);
// Axios errors have too much redundant detail! Delete some of it.
delete requestError.request;
if (requestError.response) {
(_a = requestError.config) === null || _a === void 0 ? true : delete _a.httpAgent;
(_b = requestError.config) === null || _b === void 0 ? true : delete _b.httpsAgent;
delete requestError.response.request;
}
throw requestError;
}
finally {
if (timeout) {
clearTimeout(timeout);
}
disposable === null || disposable === void 0 ? void 0 : disposable.dispose();
}
}
traceHeaders(headers) {
for (const [headerName, headerValue] of Object.entries(headers)) {
if (headerName === 'Authorization') {
this.traceAuthorizationHeader(headerName, headerValue);
return;
}
this.trace(`${headerName}: ${headerValue !== null && headerValue !== void 0 ? headerValue : ''}`);
}
}
traceAuthorizationHeader(key, value) {
if (typeof value !== 'string')
return;
const spaceIndex = value.indexOf(' ');
if (spaceIndex < 0) {
this.trace(`${key}: [${value.length}]`);
return;
}
const scheme = value.substring(0, spaceIndex);
const token = value.substring(spaceIndex + 1);
if (scheme.toLowerCase() === tunnelManagementClient_1.TunnelAuthenticationSchemes.tunnel.toLowerCase()) {
const tokenProperties = tunnelAccessTokenProperties_1.TunnelAccessTokenProperties.tryParse(token);
if (tokenProperties) {
this.trace(`${key}: ${scheme} <${tokenProperties}>`);
return;
}
}
this.trace(`${key}: ${scheme} <token>`);
}
traceContent(data) {
if (typeof data === 'object') {
data = JSON.stringify(data, undefined, ' ');
}
if (typeof data === 'string') {
this.trace(TunnelManagementHttpClient.replaceTokensInContent(data));
}
}
static replaceTokensInContent(content) {
var _a;
const tokenRegex = /"(eyJ[a-zA-z0-9\-_]+\.[a-zA-z0-9\-_]+\.[a-zA-z0-9\-_]+)"/;
let match = tokenRegex.exec(content);
while (match) {
let token = match[1];
const tokenProperties = tunnelAccessTokenProperties_1.TunnelAccessTokenProperties.tryParse(token);
token = (_a = tokenProperties === null || tokenProperties === void 0 ? void 0 : tokenProperties.toString()) !== null && _a !== void 0 ? _a : 'token';
content =
content.substring(0, match.index + 1) +
'<' +
token +
'>' +
content.substring(match.index + match[0].length - 1);
match = tokenRegex.exec(content);
}
return content;
}
}
exports.TunnelManagementHttpClient = TunnelManagementHttpClient;
//# sourceMappingURL=tunnelManagementHttpClient.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,36 @@
/**
* Supports parsing tunnel access token JWT properties to allow for some pre-validation
* and diagnostics.
*
* Applications generally should not attempt to interpret or rely on any token properties
* other than `expiration`, because the service may change or omit those claims in the future.
* Other claims are exposed here only for diagnostic purposes.
*/
export declare class TunnelPlanTokenProperties {
readonly clusterId?: string | undefined;
readonly issuer?: string | undefined;
readonly expiration?: Date | undefined;
readonly userEmail?: string | undefined;
readonly tunnelPlanId?: string | undefined;
readonly subscriptionId?: string | undefined;
readonly scopes?: string[] | undefined;
private constructor();
/**
* Checks if the tunnel access token expiration claim is in the past.
*
* (Does not throw if the token is an invalid format.)
*/
static validateTokenExpiration(token: string): void;
/**
* Attempts to parse a tunnel access token (JWT). This does NOT validate the token
* signature or any claims.
*/
static tryParse(token: string): TunnelPlanTokenProperties | null;
/**
* Gets the tunnal access token trace string.
* 'none' if null or undefined, parsed token info if can be parsed, or 'token' if cannot be parsed.
*/
static getTokenTrace(token?: string | null | undefined): string;
private static base64UrlDecode;
}
//# sourceMappingURL=tunnelPlanTokenProperties.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"tunnelPlanTokenProperties.d.ts","sourceRoot":"","sources":["../../../src/management/tunnelPlanTokenProperties.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,qBAAa,yBAAyB;aAEd,SAAS,CAAC;aACV,MAAM,CAAC;aACP,UAAU,CAAC;aACX,SAAS,CAAC;aACV,YAAY,CAAC;aACb,cAAc,CAAC;aACf,MAAM,CAAC;IAP3B,OAAO;IAUP;;;;OAIG;WACW,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAS1D;;;OAGG;WACW,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,yBAAyB,GAAG,IAAI;IAsCvE;;;OAGG;WACW,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM;IAItE,OAAO,CAAC,MAAM,CAAC,eAAe;CAcjC"}
@@ -0,0 +1,92 @@
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
Object.defineProperty(exports, "__esModule", { value: true });
exports.TunnelPlanTokenProperties = void 0;
/**
* Supports parsing tunnel access token JWT properties to allow for some pre-validation
* and diagnostics.
*
* Applications generally should not attempt to interpret or rely on any token properties
* other than `expiration`, because the service may change or omit those claims in the future.
* Other claims are exposed here only for diagnostic purposes.
*/
class TunnelPlanTokenProperties {
constructor(clusterId, issuer, expiration, userEmail, tunnelPlanId, subscriptionId, scopes) {
this.clusterId = clusterId;
this.issuer = issuer;
this.expiration = expiration;
this.userEmail = userEmail;
this.tunnelPlanId = tunnelPlanId;
this.subscriptionId = subscriptionId;
this.scopes = scopes;
}
/**
* Checks if the tunnel access token expiration claim is in the past.
*
* (Does not throw if the token is an invalid format.)
*/
static validateTokenExpiration(token) {
const t = TunnelPlanTokenProperties.tryParse(token);
if (t === null || t === void 0 ? void 0 : t.expiration) {
if (t.expiration < new Date()) {
throw new Error('The access token is expired: ' + t);
}
}
}
/**
* Attempts to parse a tunnel access token (JWT). This does NOT validate the token
* signature or any claims.
*/
static tryParse(token) {
if (typeof token !== 'string')
throw new TypeError('Token string expected.');
// JWTs are encoded in 3 parts: header, body, and signature.
const tokenParts = token.split('.');
if (tokenParts.length !== 3) {
return null;
}
const tokenBodyJson = TunnelPlanTokenProperties.base64UrlDecode(tokenParts[1]);
if (!tokenBodyJson) {
return null;
}
try {
const tokenJson = JSON.parse(tokenBodyJson);
const clusterId = tokenJson.clusterId;
const subscriptionId = tokenJson.subscriptionId;
const tunnelPlanId = tokenJson.tunnelPlanId;
const userEmail = tokenJson.userEmail;
const scp = tokenJson.scp;
const iss = tokenJson.iss;
const exp = tokenJson.exp;
return new TunnelPlanTokenProperties(clusterId, iss, typeof exp === 'number' ? new Date(exp * 1000) : undefined, userEmail, tunnelPlanId, subscriptionId, scp === null || scp === void 0 ? void 0 : scp.split(' '));
}
catch (_a) {
return null;
}
}
/**
* Gets the tunnal access token trace string.
* 'none' if null or undefined, parsed token info if can be parsed, or 'token' if cannot be parsed.
*/
static getTokenTrace(token) {
var _a, _b;
return !token ? 'none' : (_b = (_a = TunnelPlanTokenProperties.tryParse(token)) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : 'token';
}
static base64UrlDecode(encodedString) {
// Convert from base64url encoding to base64 encoding: replace chars and add padding.
encodedString = encodedString.replace('-', '+');
while (encodedString.length % 4 !== 0) {
encodedString += '=';
}
try {
const result = atob(encodedString);
return result;
}
catch (_a) {
return null;
}
}
}
exports.TunnelPlanTokenProperties = TunnelPlanTokenProperties;
//# sourceMappingURL=tunnelPlanTokenProperties.js.map
@@ -0,0 +1 @@
{"version":3,"file":"tunnelPlanTokenProperties.js","sourceRoot":"","sources":["../../../src/management/tunnelPlanTokenProperties.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
/**
* Options for tunnel service requests.
*/
export interface TunnelRequestOptions {
/**
* Gets or sets an access token for the request.
*
* Note this should not be a _user_ access token (such as AAD or GitHub); use the
* callback parameter to the `TunnelManagementHttpClient` constructor to
* supply user access tokens.
*/
accessToken?: string;
/**
* Gets or sets additional headers to be included in the request.
*/
additionalHeaders?: {
[header: string]: string;
};
/**
* Gets or sets additional query parameters to be included in the request.
*/
additionalQueryParameters?: {
[name: string]: string;
};
/**
* Gets or sets a value that indicates whether HTTP redirect responses will be
* automatically followed.
*
* The default is true. If false, a redirect response will cause an error to be thrown,
* with redirect target URI available at `error.response.headers.location`.
*
* The tunnel service often redirects requests to the "home" cluster of the requested
* tunnel, when necessary to fulfill the request.
*/
followRedirects?: boolean;
/**
* Gets or sets a flag that requests tunnel ports when retrieving a tunnel object.
*
* Ports are excluded by default when retrieving a tunnel or when listing or searching
* tunnels. This option enables including ports for all tunnels returned by a list or
* search query.
*/
includePorts?: boolean;
/**
* Gets or sets a flag that requests access control details when retrieving tunnels.
*
* Access control details are always included when retrieving a single tunnel,
* but excluded by default when listing or searching tunnels. This option enables
* including access controls for all tunnels returned by a list or search query.
*/
includeAccessControl?: boolean;
/**
* Gets or sets an optional list of labels to filter the requested tunnels or ports.
*
* Requested labels are compared to the `Tunnel.labels` or `TunnelPort.labels` when calling
* `TunnelManagementClient.listTunnels` or `TunnelManagementClient.listTunnelPorts`
* respectively. By default, an item is included if ANY tag matches; set `requireAllLabels`
* to match ALL labels instead.
*/
labels?: string[];
requireAllLabels?: boolean;
/**
* Gets or sets an optional list of token scopes that are requested when retrieving a
* tunnel or tunnel port object.
*
* Each item in the array must be a single scope from `TunnelAccessScopes` or a space-
* delimited combination of multiple scopes. The service issues an access token for
* each scope or combination and returns the token(s) in the `Tunnel.accessTokens` or
* `TunnelPort.accessTokens` dictionary. If the caller does not have permission to get
* a token for one or more scopes then a token is not returned but the overall request
* does not fail. Token properties including scopes and expiration may be checked using
* `TunnelAccessTokenProperties`.
*/
tokenScopes?: string[];
/**
* If true on a create or update request then upon a name conflict, attempt to rename the
* existing tunnel to null and give the name to the tunnel from the request.
*/
forceRename?: boolean;
/**
* Limits the number of tunnels returned when searching or listing tunnels.
*/
limit?: number;
}
//# sourceMappingURL=tunnelRequestOptions.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"tunnelRequestOptions.d.ts","sourceRoot":"","sources":["../../../src/management/tunnelRequestOptions.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,iBAAiB,CAAC,EAAE;QAAE,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAEjD;;OAEG;IACH,yBAAyB,CAAC,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAEvD;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAMlB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAEvB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB"}
@@ -0,0 +1,5 @@
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=tunnelRequestOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"tunnelRequestOptions.js","sourceRoot":"","sources":["../../../src/management/tunnelRequestOptions.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC"}
+5
View File
@@ -0,0 +1,5 @@
/**
* Tunnel SDK user agent
*/
export declare const tunnelSdkUserAgent: string;
//# sourceMappingURL=version.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../src/management/version.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,eAAO,MAAM,kBAAkB,QAAyD,CAAC"}
+13
View File
@@ -0,0 +1,13 @@
"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
Object.defineProperty(exports, "__esModule", { value: true });
exports.tunnelSdkUserAgent = void 0;
// Get the package version
const packageJson = require("./package.json");
const packageVersion = packageJson.version;
/**
* Tunnel SDK user agent
*/
exports.tunnelSdkUserAgent = `Dev-Tunnels-Service-TypeScript-SDK/${packageVersion}`;
//# sourceMappingURL=version.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/management/version.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;;;AAElC,0BAA0B;AAC1B,8CAA8C;AAC9C,MAAM,cAAc,GAAG,WAAW,CAAC,OAAO,CAAC;AAE3C;;GAEG;AACU,QAAA,kBAAkB,GAAG,sCAAsC,cAAc,EAAE,CAAC"}