{"version":3,"sources":["../../../packages/core/security/credssp-manager.ts"],"names":[],"mappings":"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","file":"credssp-manager.d.ts","sourcesContent":["import { from, Observable, of, Subject, throwError } from 'rxjs';\r\nimport { filter, map, mergeMap, take } from 'rxjs/operators';\r\nimport { AppContext } from '../data/app-context';\r\nimport { ErrorExtended } from '../data/error-extended';\r\nimport { Logging } from '../diagnostics/logging';\r\nimport { Strings } from '../generated/strings';\r\nimport {\r\n    ClientRoleConfiguration,\r\n    ConfigurationStatus,\r\n    Credentials,\r\n    GatewayLocalPowerShellConfig,\r\n    RpcCredSSPOperation,\r\n    RpcCredSSPOperationResult,\r\n    RpcCredSSPOperationResultMember,\r\n    RpcCredSSPOperationType,\r\n    RpcCredSspResponseKey,\r\n    ServerRoleConfiguration\r\n} from '../rpc/credssp/rpc-credssp-model';\r\nimport { RpcCredSspRequestClient } from '../rpc/credssp/rpc-credssp-request-client';\r\nimport { Rpc } from '../rpc/rpc';\r\nimport { GatewayInstallationType } from '../shared/gateway-inventory/gateway-inventory';\r\nimport { GatewayInventoryCache } from '../shared/gateway-inventory/gateway-inventory-cache';\r\n\r\n/**\r\n * CredSPP Manager class. Handles detecting and configuring CredSSP on a set of servers.\r\n */\r\nexport class CredSSPManager {\r\n    private strings = MsftSme.getStrings<Strings>().MsftSmeShell.Core.CredSSPManager;\r\n\r\n    private watcher: Subject<RpcCredSSPOperationResult>;\r\n\r\n    private gatewayInventoryCache: GatewayInventoryCache;\r\n\r\n    /**\r\n     * Initializes a new instance of the Authorization Manager class.\r\n     *\r\n     * @param rpc The rpc to forward auth requests to a parent window\r\n     */\r\n    constructor(private rpc: Rpc) {\r\n        this.watcher = new Subject<RpcCredSSPOperationResult>();\r\n    }\r\n\r\n    public initialize(appContext: AppContext) {\r\n        // When in Shell do not register.\r\n        if (!this.rpc.isShell) {\r\n            this.rpc.register(RpcCredSspResponseKey.command, this.onRpcResponse.bind(this));\r\n        }\r\n\r\n        this.gatewayInventoryCache = new GatewayInventoryCache(appContext);\r\n    }\r\n\r\n    /**\r\n     * New Enable CredSSP on the passed in server.\r\n     *\r\n     * @param serverName This server on which CredSSP should be enabled\r\n     * @param verbose (Optional) Specify whether a solution (if any) should be returned if CredSSP errored\r\n     */\r\n    public wsmanEnableManagedServer(serverName: string, verbose: boolean = false): Observable<boolean> {\r\n        if (this.rpc.isShell) {\r\n            throw new Error('Not supported on the shell environment.');\r\n        }\r\n\r\n        if (MsftSme.isNullOrWhiteSpace(serverName)) {\r\n            throw new Error('A server name must be provided.');\r\n        }\r\n\r\n        return this.sendRequest<boolean>({\r\n            requestId: MsftSme.getUniqueId(),\r\n            operation: RpcCredSSPOperationType.EnableManagedServer,\r\n            serverNames: [serverName],\r\n            notificationTitle: null,\r\n            notificationId: null\r\n        }, verbose, RpcCredSSPOperationResultMember.Succeeded);\r\n    }\r\n\r\n    /**\r\n     * New Disable CredSSP for the passed in server.\r\n     *\r\n     * @param serverName This server on which CredSSP should be disabled\r\n     * @param verbose (Optional) Specify whether a solution (if any) should be returned if CredSSP errored\r\n     */\r\n    public wsmanDisableManagedServer(serverName: string, verbose: boolean = false): Observable<boolean> {\r\n        if (this.rpc.isShell) {\r\n            throw new Error('Not supported on the shell environment.');\r\n        }\r\n\r\n        if (MsftSme.isNullOrWhiteSpace(serverName)) {\r\n            throw new Error('A server name must be provided.');\r\n        }\r\n\r\n        return this.sendRequest<boolean>({\r\n            requestId: MsftSme.getUniqueId(),\r\n            operation: RpcCredSSPOperationType.DisableManagedServer,\r\n            serverNames: [serverName],\r\n            notificationTitle: null,\r\n            notificationId: null\r\n        }, verbose, RpcCredSSPOperationResultMember.Succeeded);\r\n    }\r\n\r\n    /**\r\n     * New Enable CredSSP client role for the gateway and delegate to the list of servers.\r\n     *\r\n     * @param serverNames This list of servers where CredSSP should be enabled.\r\n     * @param verbose (Optional) Specify whether a solution (if any) should be returned if CredSSP errored\r\n     */\r\n    public wsmanEnableClientRole(serverNames: string[], verbose: boolean = false): Observable<boolean> {\r\n        if (this.rpc.isShell) {\r\n            throw new Error('Not supported on the shell environment.');\r\n        }\r\n\r\n        if (!serverNames || serverNames.length < 1) {\r\n            throw new Error('At least one server name must be provided.');\r\n        }\r\n\r\n        return this.sendRequest<boolean>({\r\n            requestId: MsftSme.getUniqueId(),\r\n            operation: RpcCredSSPOperationType.EnableClientRole,\r\n            serverNames: serverNames,\r\n            notificationTitle: null,\r\n            notificationId: null\r\n        }, verbose, RpcCredSSPOperationResultMember.Succeeded);\r\n    }\r\n\r\n    /**\r\n     * New Disable CredSSP client role for the gateway and remove all delegated servers.\r\n     *\r\n     * @param serverNames This list of servers where CredSSP should be disabled\r\n     * @param verbose (Optional) Specify whether a solution (if any) should be returned if CredSSP errored\r\n     */\r\n    public wsmanDisableClientRole(serverNames: string[], verbose: boolean = false): Observable<boolean> {\r\n        if (this.rpc.isShell) {\r\n            throw new Error('Not supported on the shell environment.');\r\n        }\r\n\r\n        if (!serverNames || serverNames.length < 1) {\r\n            throw new Error('At least one server name must be provided.');\r\n        }\r\n\r\n        return this.sendRequest<boolean>({\r\n            requestId: MsftSme.getUniqueId(),\r\n            operation: RpcCredSSPOperationType.DisableClientRole,\r\n            serverNames,\r\n            notificationTitle: null,\r\n            notificationId: null\r\n        }, verbose, RpcCredSSPOperationResultMember.Succeeded);\r\n    }\r\n\r\n    /**\r\n     * @deprecated\r\n     * Use tryGatewayLocalPowershellConfig instead which will only enable CredSSP when the gateway is making\r\n     * a double hop to a remote node. This method will enable CredSSP every time, even in cases where\r\n     * it is not needed.\r\n     *\r\n     * New Enable the server as a CredSSP server, and enable the gateway as a CredSSP client of the server.\r\n     *\r\n     * @param serverName The server where CredSSP delegation should be enabled\r\n     * @param verbose (Optional) Specify whether a solution (if any) should be returned if CredSSP errored\r\n     */\r\n    public wsmanEnableDelegation(serverName: string, verbose: boolean = false): Observable<boolean> {\r\n        if (this.rpc.isShell) {\r\n            throw new Error('Not supported on the shell environment.');\r\n        }\r\n\r\n        if (MsftSme.isNullOrWhiteSpace(serverName)) {\r\n            throw new Error('The server name must be provided.');\r\n        }\r\n\r\n        return this.sendRequest<boolean>({\r\n            requestId: MsftSme.getUniqueId(),\r\n            operation: RpcCredSSPOperationType.EnableDelegation,\r\n            serverNames: [serverName],\r\n            notificationTitle: null,\r\n            notificationId: null\r\n        }, verbose, RpcCredSSPOperationResultMember.Succeeded);\r\n    }\r\n\r\n    /**\r\n     * Check to see if given servers contain the gateway machine. If not, enable CredSSP on index 0 of serverNames,\r\n     * otherwise, do nothing.\r\n     *\r\n     * Note: Will only check if local runspace can be used if msft.sme.shell.localRunspace experiment key is set\r\n     * or gateway is running as WAC in Portal. Otherwise will fall back to calling {@link wsmanEnableDelegation}.\r\n     * This is because old installs of WAC do not have the necessary shell RPC endpoint or PowerShell API functionality.\r\n     *\r\n     * @param serverNames String array of server names to check for a match with the gateway server name.\r\n     * If not found, CredSSP will be enabled between the gateway machine and the server name at index 0.\r\n     * @param verbose (Optional) Specify whether a solution (if any) should be returned if CredSSP errored.\r\n     * @returns GatewayLocalPowerShellConfig object if success.\r\n     * @throws If call is made from shell, serverNames is empty or contains empty values, or unable to enable CredSSP.\r\n     */\r\n    public tryGatewayLocalPowerShellConfig(serverNames: string[], verbose: boolean = false): Observable<GatewayLocalPowerShellConfig> {\r\n        if (this.rpc.isShell) {\r\n            throw new Error('Not supported on the shell environment.');\r\n        }\r\n\r\n        if (serverNames.length === 0 || serverNames.some(serverName => MsftSme.isNullOrWhiteSpace(serverName))) {\r\n            throw new Error('The server name(s) must be provided.');\r\n        }\r\n\r\n        if (MsftSme.isExperimentEnabled('localRunspace', true)) {\r\n            return this.sendRequest<GatewayLocalPowerShellConfig>({\r\n                requestId: MsftSme.getUniqueId(),\r\n                operation: RpcCredSSPOperationType.TryGatewayLocalPowerShellConfig,\r\n                serverNames: serverNames,\r\n                notificationTitle: null,\r\n                notificationId: null\r\n            }, verbose, RpcCredSSPOperationResultMember.Data);\r\n        }\r\n\r\n        return this.gatewayInventoryCache.query({}).pipe(\r\n            take(1),\r\n            mergeMap(inventory => {\r\n                if (inventory.instance.installationType === GatewayInstallationType.AzureVmExtension) {\r\n                    return this.sendRequest<GatewayLocalPowerShellConfig>({\r\n                        requestId: MsftSme.getUniqueId(),\r\n                        operation: RpcCredSSPOperationType.TryGatewayLocalPowerShellConfig,\r\n                        serverNames: serverNames,\r\n                        notificationTitle: null,\r\n                        notificationId: null\r\n                    }, verbose, RpcCredSSPOperationResultMember.Data);\r\n                }\r\n\r\n                // Fallback to using the old, deprecated wsmanEnableDelegation method if user is running an old version of WAC.\r\n                // Uses index 0 because if serverNames does not contain the gateway machine, the given name(s) should all be able to\r\n                // delegate credentials (by receiving the) in a double hop scenario.\r\n                return this.wsmanEnableDelegation(serverNames[0], verbose).pipe(\r\n                    map(response => {\r\n                        if (!response) {\r\n                            throw new Error(this.strings.TryGatewayLocalPowerShellConfigNotConfirmed.error);\r\n                        }\r\n\r\n                        const data: GatewayLocalPowerShellConfig = {\r\n                            configuredServerConnectionString: serverNames[0],\r\n                            powerShellOptions: { authenticationMechanism: 'Credssp' }\r\n                        };\r\n\r\n                        return data;\r\n                    })\r\n                );\r\n            })\r\n        );\r\n    }\r\n\r\n    /**\r\n     * Test WSMan CredSSP connection from gateway to server(s)\r\n     *\r\n     * @param serverNames the servers to test connection to from gateway\r\n     * @param credentials explicit credentials(username and password) to be used to WSMan CredSSP test\r\n     * @param verbose (Optional) Specify whether a solution (if any) should be returned if CredSSP errored\r\n     * @returns true if we can safely connect to all server without isssues otherwise returns false\r\n     */\r\n    public testCredSSP(serverNames: string[], credentials: Credentials, verbose: boolean = false): Observable<boolean> {\r\n        if (this.rpc.isShell) {\r\n            throw new Error('Not supported on the shell environment.');\r\n        }\r\n\r\n        if (!serverNames.length || serverNames.some(\r\n            serverName => MsftSme.isNullOrWhiteSpace(serverName))\r\n        ) {\r\n            throw new Error('The server name(s) must be provided.');\r\n        }\r\n\r\n        if (!credentials || !credentials.username || !credentials.password) {\r\n            throw new Error('Username and password must be provided in the options.');\r\n        }\r\n\r\n        return this.sendRequest<boolean>({\r\n            requestId: MsftSme.getUniqueId(),\r\n            operation: RpcCredSSPOperationType.TestCredSSP,\r\n            serverNames: serverNames,\r\n            credentials,\r\n            notificationTitle: null,\r\n            notificationId: null\r\n        }, verbose, RpcCredSSPOperationResultMember.Succeeded);\r\n    }\r\n\r\n    /**\r\n     * Get the CredSSP client role configuration of the gateway, including:\r\n     * 1. Client role of gateway to delegate fresh credentials\r\n     * 2. Which servers can be delegated fresh credentials\r\n     *\r\n     * @param serverNames The list of servers to check credential delegation status\r\n     * @param verbose (Optional) Specify whether a solution (if any) should be returned if CredSSP errored\r\n     * @returns ClientRoleConfiguration object of the gateway client role configuration\r\n     */\r\n    public wsmanGetClientConfigurationOnGateway(serverNames: string[], verbose: boolean = false): Observable<ClientRoleConfiguration> {\r\n        if (this.rpc.isShell) {\r\n            throw new Error('Not supported on the shell environment.');\r\n        }\r\n\r\n        if (!serverNames || serverNames.length < 1) {\r\n            throw new Error('At least one server name must be provided.');\r\n        }\r\n\r\n        return this.sendRequest<ConfigurationStatus>({\r\n            requestId: MsftSme.getUniqueId(),\r\n            operation: RpcCredSSPOperationType.ConfirmClientConfiguration,\r\n            serverNames,\r\n            notificationTitle: null,\r\n            notificationId: null\r\n        }, verbose, RpcCredSSPOperationResultMember.ConfigurationStatus).pipe(map(response => response.client));\r\n    }\r\n\r\n    /**\r\n     * Get the CredSSP server role configuration of the server.\r\n     *\r\n     * @param serverName The server to get the CredSSP configuration\r\n     * @param verbose (Optional) Specify whether a solution (if any) should be returned if CredSSP errored\r\n     * @returns ServerRoleConfiguration object of the managed server server role configuration\r\n     */\r\n    public wsmanGetManagedServerConfiguration(serverNames: string[], verbose: boolean = false): Observable<ServerRoleConfiguration[]> {\r\n        if (this.rpc.isShell) {\r\n            throw new Error('Not supported on the shell environment.');\r\n        }\r\n\r\n        if (!serverNames || serverNames.length < 1) {\r\n            throw new Error('At least one server name must be provided.');\r\n        }\r\n\r\n        return this.sendRequest<ConfigurationStatus>({\r\n            requestId: MsftSme.getUniqueId(),\r\n            operation: RpcCredSSPOperationType.ConfirmManagedServerConfiguration,\r\n            serverNames,\r\n            notificationTitle: null,\r\n            notificationId: null\r\n        }, verbose, RpcCredSSPOperationResultMember.ConfigurationStatus).pipe(map(response => <ServerRoleConfiguration[]>response.servers));\r\n    }\r\n\r\n    /**\r\n     * Get the CredSSP delegation configuration, including:\r\n     * 1. Client role of gateway to delegate fresh credentials\r\n     * 2. Which servers can be delegated fresh credentials\r\n     * 3. Server roles of each servers\r\n     *\r\n     * @param serverNames The list of servers to check credential delegation from gateway and to check server role status\r\n     * @param verbose (Optional) Specify whether a solution (if any) should be returned if CredSSP errored\r\n     * @returns ConfigurationData object of the client and server role configuation\r\n     */\r\n    public wsmanGetDelegationConfiguration(serverNames: string[], verbose: boolean = false): Observable<ConfigurationStatus> {\r\n        if (this.rpc.isShell) {\r\n            throw new Error('Not supported on the shell environment.');\r\n        }\r\n\r\n        if (!serverNames || serverNames.length < 1) {\r\n            throw new Error('At least one server name must be provided.');\r\n        }\r\n\r\n        return this.sendRequest<ConfigurationStatus>({\r\n            requestId: MsftSme.getUniqueId(),\r\n            operation: RpcCredSSPOperationType.ConfirmDelegation,\r\n            serverNames,\r\n            notificationTitle: null,\r\n            notificationId: null\r\n        }, verbose, RpcCredSSPOperationResultMember.ConfigurationStatus);\r\n    }\r\n\r\n    /**\r\n     * @deprecated\r\n     * Notification message wouldn't be displayed from this call. Display the notification by own code,\r\n     * and use wsmanEnableManagedServer instead.\r\n     *\r\n     * Enable CredSSP on the passed in server.\r\n     *\r\n     * @param alertTitle Title for notifications raised by this servers.  Should be contextual to the scenario that is using this service\r\n     * @param serverName This server on which CredSSP should be enabled\r\n     * @param alertId Optional notification Id\r\n     */\r\n    public enableManagedServer(alertTitle: string, serverName: string, alertId?: string): Observable<boolean> {\r\n        if (this.rpc.isShell) {\r\n            throw new Error('Not supported on the shell environment.');\r\n        }\r\n\r\n        if (MsftSme.isNullOrWhiteSpace(serverName)) {\r\n            throw new Error('A server name must be provided.');\r\n        }\r\n\r\n        return this.sendRequest<boolean>({\r\n            requestId: MsftSme.getUniqueId(),\r\n            operation: RpcCredSSPOperationType.EnableManagedServer,\r\n            serverNames: [serverName],\r\n            notificationTitle: alertTitle,\r\n            notificationId: alertId\r\n        }, false, RpcCredSSPOperationResultMember.Succeeded);\r\n    }\r\n\r\n    /**\r\n     * @deprecated\r\n     * Notification message wouldn't be displayed from this call. Display the notification by own code,\r\n     * and use wsmanDisableManagedServer instead.\r\n     *\r\n     * Disable CredSSP for the passed in server.\r\n     *\r\n     * @param alertTitle Title for notifications raised by this servers.  Should be contextual to the scenario that is using this service\r\n     * @param serverName This server on which CredSSP should be disabled\r\n     * @param alertId Optional notification Id\r\n     */\r\n    public disableManagedServer(alertTitle: string, serverName: string, alertId?: string): Observable<boolean> {\r\n        if (this.rpc.isShell) {\r\n            throw new Error('Not supported on the shell environment.');\r\n        }\r\n\r\n        if (MsftSme.isNullOrWhiteSpace(serverName)) {\r\n            throw new Error('A server name must be provided.');\r\n        }\r\n\r\n        return this.sendRequest<boolean>({\r\n            requestId: MsftSme.getUniqueId(),\r\n            operation: RpcCredSSPOperationType.DisableManagedServer,\r\n            serverNames: [serverName],\r\n            notificationTitle: alertTitle,\r\n            notificationId: alertId\r\n        }, false, RpcCredSSPOperationResultMember.Succeeded);\r\n    }\r\n\r\n    /**\r\n     * @deprecated\r\n     * Notification message wouldn't be displayed from this call. Display the notification by own code,\r\n     * and use wsmanEnableClientRole instead.\r\n     *\r\n     * Enable CredSSP client role for the gateway and delegate to the list of servers.\r\n     *\r\n     * @param alertTitle Title for notifications raised by this servers.  Should be contextual to the scenario that is using this service\r\n     * @param serverNames This list of servers where CredSSP should be enabled.\r\n     * @param alertId Optional notification Id\r\n     */\r\n    public enableClientRole(alertTitle: string, serverNames: string[], alertId?: string): Observable<boolean> {\r\n        if (this.rpc.isShell) {\r\n            throw new Error('Not supported on the shell environment.');\r\n        }\r\n\r\n        if (!serverNames || serverNames.length < 1) {\r\n            throw new Error('At least one server name must be provided.');\r\n        }\r\n\r\n        return this.sendRequest<boolean>({\r\n            requestId: MsftSme.getUniqueId(),\r\n            operation: RpcCredSSPOperationType.EnableClientRole,\r\n            serverNames: serverNames,\r\n            notificationTitle: alertTitle,\r\n            notificationId: alertId\r\n        }, false, RpcCredSSPOperationResultMember.Succeeded);\r\n    }\r\n\r\n    /**\r\n     * @deprecated\r\n     * Notification message wouldn't be displayed from this call. Display the notification by own code,\r\n     * and use wsmanDisableClientRole instead.\r\n     *\r\n     * Disable CredSSP client role for the gateway and remove all delegated servers.\r\n     *\r\n     * @param alertTitle Title for notifications raised by this servers.  Should be contextual to the scenario that is using this service\r\n     * @param serverNames This list of servers where CredSSP should be disabled.\r\n     * @param alertId Optional notification Id\r\n     */\r\n    public disableClientRole(alertTitle: string, serverNames: string[], alertId?: string): Observable<boolean> {\r\n        if (this.rpc.isShell) {\r\n            throw new Error('Not supported on the shell environment.');\r\n        }\r\n\r\n        if (!serverNames || serverNames.length < 1) {\r\n            throw new Error('At least one server name must be provided.');\r\n        }\r\n\r\n        return this.sendRequest<boolean>({\r\n            requestId: MsftSme.getUniqueId(),\r\n            operation: RpcCredSSPOperationType.DisableClientRole,\r\n            serverNames,\r\n            notificationTitle: alertTitle,\r\n            notificationId: alertId\r\n        }, false, RpcCredSSPOperationResultMember.Succeeded);\r\n    }\r\n\r\n    /**\r\n     * @deprecated\r\n     * Notification message wouldn't be displayed from this call. Display the notification by own code,\r\n     * and use wsmanEnableDelegation instead.\r\n     *\r\n     * Enable the server as a CredSSP server, and enable the gateway as a CredSSP client of the server.\r\n     *\r\n     * @param alertTitle Title for notifications raised by this servers.  Should be contextual to the scenario that is using this service\r\n     * @param serverName The sever where CredSSP delegation should be enabled.\r\n     * @param alertId Optional notification Id\r\n     */\r\n    public enableDelegation(alertTitle: string, serverName: string, alertId?: string): Observable<boolean> {\r\n        if (this.rpc.isShell) {\r\n            throw new Error('Not supported on the shell environment.');\r\n        }\r\n\r\n        if (MsftSme.isNullOrWhiteSpace(serverName)) {\r\n            throw new Error('The server name must be provided.');\r\n        }\r\n\r\n        return this.sendRequest<boolean>({\r\n            requestId: MsftSme.getUniqueId(),\r\n            operation: RpcCredSSPOperationType.EnableDelegation,\r\n            serverNames: [serverName],\r\n            notificationTitle: alertTitle,\r\n            notificationId: alertId\r\n        }, false, RpcCredSSPOperationResultMember.Succeeded);\r\n    }\r\n\r\n    /**\r\n     * @deprecated\r\n     * This method is obsolete!\r\n     *\r\n     * Disable the server as a CredSSP server, and disable the gateway as a CredSSP client of the server.\r\n     *\r\n     * @param alertTitle Title for notifications raised by this servers.  Should be contextual to the scenario that is using this service\r\n     * @param serverName The sever where CredSSP delegation should be disabled.\r\n     * @param alertId Optional notification Id\r\n     */\r\n    public disableDelegation(): Observable<boolean> {\r\n        return of(true);\r\n    }\r\n\r\n    /**\r\n     * The RPC request to the CredSSPManagerShellService.\r\n     * @param request The requested CredSSP manager operation\r\n     * @param verbose Specify whether a solution (if any) should be returned if CredSSP errored\r\n     * @param returnProperty The property of the RPC result object to return\r\n     */\r\n    private sendRequest<TResult>(request: RpcCredSSPOperation, verbose: boolean, returnProperty: string): Observable<TResult> {\r\n        Logging.logDebug(\r\n            'CredSSPManager',\r\n            'Sending request to CredSSPManagerService. Request:{0}'.format(JSON.stringify(request)));\r\n\r\n        return from(RpcCredSspRequestClient.credSspRequest(this.rpc, request))\r\n            .pipe(\r\n                mergeMap(() => this.watcher),\r\n                filter(result => result.requestId === request.requestId),\r\n                take(1),\r\n                mergeMap(result => {\r\n                    // shell reports 'error' property originated from the CredSSP operation.\r\n                    // the client using this API should get this error message to display to user.\r\n                    if (result.error) {\r\n                        if (verbose) {\r\n                            const error = new ErrorExtended<{solutionMessage: string}>(result.error);\r\n                            error.extendedSource = `${request.operation}-credSSPError`;\r\n                            error.extended = { solutionMessage: result.solutionMessage };\r\n                            return throwError(() => error);\r\n                        } else {\r\n                            return throwError(() => new Error(result.error));\r\n                        }\r\n                    }\r\n\r\n                    return of(<TResult>result[returnProperty]);\r\n                }));\r\n    }\r\n\r\n    /**\r\n     * Process the RPC response from the CredSSPManagerShellService.\r\n     * @param data The requested CredSSP manager operation result.\r\n     */\r\n    private onRpcResponse(data: RpcCredSSPOperationResult): Promise<any> {\r\n        Logging.logDebug(\r\n            'CredSSPManager',\r\n            'Processing response from CredSSPManagerService Response:{0}'.format(JSON.stringify(data)));\r\n\r\n        this.watcher.next(data);\r\n\r\n        return Promise.resolve();\r\n    }\r\n}\r\n"]}