Better protection for your saved passwords.
Note: The best way to install and use this extension is by installing the InterSystems ObjectScript Extension Pack and following the documentation here.
InterSystems Server Manager is a Visual Studio Code extension for defining connections to InterSystems servers. These definitions can used by other VS Code extensions when they make connections. One example is the ObjectScript extension for code editing. The Launch WebTerminals extension is another.
See the CHANGELOG for changes in each release.
We are pleased to publish version 3.2 of this extension. This replaces version 2, improving the security of stored passwords by integrating with VS Code's Authentication Provider API. Version 3 was originally created for the November 2021 InterSystems Security Contest and made available as a pre-release.
Thanks to George James Software for backing this development effort.
Beginning with version 2, Server Manager has enabled you to store connection passwords in the native keystore of your workstation's operating system. This provided a more secure alternative to keeping them as plaintext in your JSON files. However, the getServerSpec
function in Server Manager 2's API allowed any installed extension to obtain these stored passwords without requiring your consent.
VS Code's Authentication Provider API (vscode.authentication
), introduced in version 1.54 (February 2021) became mature enough in version 1.63 for us to use.
Server Manager 3 does the following:
getServerSpec
unless insecurely stored in JSON.Items #2 and #3 have implications regarding backward compatibility. An interim legacy mode is available to help with the transition from Server Manager 2, but it may be removed in a future release.
If you previously used Server Manager 2 to store passwords you can run the command Migrate Legacy Passwords
from Command Palette to migrate these. At the end of the migration procedure you will be given the option to delete the old copies. For best security we recommend you do this, but if you want to delay that step until after you are confident you won't want to revert to version 2, decline password deletion initially and re-run the migration later. Your Server Manager 3 passwords will not be overwritten.
The first time you expand a server in the tree VS Code displays a modal dialog asking for your permission:
If you allow this and your server definition in intersystems.servers
does not specify a username
the next step is:
If you proceed, or if this step was skipped because your server definition includes a username, the next step is:
If you click the 'key' button at the upper right corner of the dialog after typing your password it will be saved securely in your workstation keychain, from where the 'InterSystems Server Credentials' authentication provider will be able to retrieve it after you restart VS Code.
If instead you press 'Enter' the password will be available only until you restart VS Code.
Either way, you are now signed in on the specified account.
When another extension first asks to use an InterSystems Server Credentials account you must either allow this or deny it. For example, when the InterSystems ObjectScript extension uses the new authentication provider you get this dialog after you click the edit pencil button alongside a namespace in the Server Manager tree:
You can use the menu of VS Code's Accounts icon in the activity bar to manage your signed in accounts:
The 'Manage Trusted Extensions' option lets you remove an extension from the list of those you previously granted access to this InterSystems Server Credentials account:
The 'Sign Out' option lets you sign out this account after confirmation:
When signing out an account for which you previously saved the password you will get an option to delete the password, unless you have altered the intersystemsServerManager.credentialsProvider.deletePasswordOnSignout
setting:
The following features were originally introduced in Server Manager version 2.
Server Manager displays connection definitions as a tree on an InterSystems Tools view:
In this tree you can:
In common with the rest of VS Code, Server Manager stores your connection settings in JSON files. VS Code settings are arranged in a hierarchy that you can learn more about here.
Server Manager can store connection passwords in the native keystore of your workstation's operating system. This is a more secure alternative to you putting them as plaintext in your JSON files.
On Windows, Server Manager can create connection entries for all connections you previously defined with the original Windows app called InterSystems Server Manager. This action is available from the '...
' menu at the top right corner of Server Manager's tree.
+
' button on Server Manager's title bar.All Servers
to see your new entry in the tree.The server definition is added to your user-level settings.json
file and also appears at the top of the 'Recent' folder.
Optionally use its context menu to store the password for the username you entered when defining the server. You can also set the color of the server icon.
The 'star' button that appears when you hover over the row lets you add the server to the Favorites
list at the top of the tree.
isfs://server:namespace/
folder to your VS Code workspace, or use the 'viewing eye' icon to add an isfs-readonly://server:namespace/
one.Learn more about isfs
and isfs-readonly
folders in the InterSystems ObjectScript for VS Code documentation.
If you are already doing client-side editing of your code (for example, managing it with Git), be sure you understand the consequences of also doing server-side editing using
isfs
. The ObjectScript extension's README outlines the differences between client-side and server-side editing. If in doubt, limit yourself toisfs-readonly
by only using the eye icon.
When you have a folder or a workspace (including a multi-root one) open in VS Code, the Server Manager displays a 'Current' node at the start of its tree if your workspace references any server defined in Server Manager. The linking happens automatically if you added workspace folders from Server Manager as described above. If you are using the client-side mode of working, your objectscript.conn
setting needs to use the server
property.
When you hover over a server entry in the tree, two command buttons let you launch InterSystems Management Portal.
The first button uses VS Code's Simple Browser feature, which creates a tab alongside any documents you may have open. The second button opens Portal in your workstation's default web browser.
Locate the five web applications whose path begins with /csp/sys
Alter the Use Cookie for Session
setting on each of them so it is Autodetect
instead of Always
.
Remember to save the change. The change is not thought to have any adverse effects on the usage of Portal from ordinary browsers, which will continue to use session cookies.
To manage your server definitions, including changing the username it connects with, edit the relevant JSON file.
...
' menu, choose Edit Settings
. This opens VS Code's Settings Editor and filters its contents.Edit in settings.json
link.In this example two connections have been defined:
"intersystems.servers": {
"dev": {
"webServer": {
"scheme": "https",
"host": "webhost.local",
"port": 443,
"pathPrefix": "/iris/dev"
},
"username": "alice",
"description": "Development server serviced by central web host over HTTPS"
},
"my-local": {
"webServer": {
"scheme": "http",
"host": "127.0.0.1",
"port": 52773
},
"description": "My local IRIS instance"
},
"/default": "my-local",
"/hideEmbeddedEntries": true
}
The JSON editor offers the usual IntelliSense as you work in this structure.
Notice how you can add a description
property to each connection. This will be shown in the hover in Server Manager's tree, and alongside the entry if a server quickpick is used.
Servers are displayed in the quickpick in the order they are defined in the JSON file. The exception is that if a server name is set as the value of the /default
property (see example above) it will be shown first in the list.
A set of embedded servers with names beginning default~
will appear at the end of the lists unless you add the property "/hideEmbeddedEntries": true
to your intersystems.server
object to hide them (see above).
Server Manager 3 makes changes which may degrade the user experience relative to version 2. To revert, make this user-level setting:
"intersystemsServerManager.authentication.provider": "none"
Please only use this as a short term measure until extensions that use the Server Manager getServerSpec
API get updated to use the 'intersystems-server-credentials' authentication provider. The setting may be removed in a future release.
These features use VS Code's extension-private global state storage. Data is not present in your settings.json
file.
The All Servers
tree respects the optional /default
and /hideEmbeddedEntries
settings in the intersystems.servers
JSON.
If a server has been named in /default
it is promoted to the top of the list, which is otherwise presented in alphabetical order.
Embedded entries (built-in default ones) are demoted to the end of the list, or omitted completely if /hideEmbeddedEntries
is true.
The NPM package @intersystems-community/intersystems-servermanager
defines the types used by the API which this extension exports. It also declares some constants.
An extension XYZ needing to connect to InterSystems servers should include "@intersystems-community/intersystems-servermanager": "latest"
in the "devDependencies"
object in its package.json
.
It might also define Server Manager as a dependency in its package.json
like this:
"extensionDependencies": [
"intersystems-community.servermanager"
],
Alternatively the activate
method of XYZ can detect whether the extension is already available, then offer to install it if not:
import * as serverManager from '@intersystems-community/intersystems-servermanager';
...
let extension = vscode.extensions.getExtension(serverManager.EXTENSION_ID);
if (!extension) {
// Optionally ask user for permission
// ...
<span class="pl-k">await</span> <span class="pl-s1">vscode</span><span class="pl-kos">.</span><span class="pl-c1">commands</span><span class="pl-kos">.</span><span class="pl-en">executeCommand</span><span class="pl-kos">(</span><span class="pl-s">'workbench.extensions.installExtension'</span><span class="pl-kos">,</span> <span class="pl-s1">serverManager</span><span class="pl-kos">.</span><span class="pl-c1">EXTENSION_ID</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-s1">extension</span> <span class="pl-c1">=</span> <span class="pl-s1">vscode</span><span class="pl-kos">.</span><span class="pl-c1">extensions</span><span class="pl-kos">.</span><span class="pl-en">getExtension</span><span class="pl-kos">(</span><span class="pl-s1">serverManager</span><span class="pl-kos">.</span><span class="pl-c1">EXTENSION_ID</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
}
if (!extension.isActive) {
await extension.activate();
}
XYZ can then use the extension's API to obtain the properties of a named server definition:
const serverManagerApi = extension.exports;
if (serverManagerApi && serverManagerApi.getServerSpec) { // defensive coding
const serverSpec: serverManager.IServerSpec | undefined = await serverManagerApi.getServerSpec(serverName);
}
The username
and password
properties will only be present if defined in the settings JSON. Storage of password
there is deprecated and strongly discouraged.
To obtain the password with which to connect, use code like this which will also prompt for a username if absent:
if (typeof serverSpec.password === 'undefined') {
const scopes = [serverSpec.name, serverSpec.username || ''];
let session = await vscode.authentication.getSession(serverManager.AUTHENTICATION_PROVIDER, scopes, { silent: true });
if (!session) {
session = await vscode.authentication.getSession(serverManager.AUTHENTICATION_PROVIDER, scopes, { createIfNone: true });
}
if (session) {
serverSpec.username = session.scopes[1];
serverSpec.password = session.accessToken;
}
}
To offer the user a quickpick of servers:
const serverName: string = await serverManagerApi.pickServer();
To obtain an array of server names:
const allServerNames: serverManager.IServerName[] = await serverManagerApi.getServerNames();
For up-to-date details of the API, including result types and available parameters, review the source code of the extension's activate
method here.
Better protection for your saved passwords.
Actually published on 29-Jun-2022
http.proxyStrictSSL
is set to false
(#137).2.0.8 (28-Mar-2022)
2.0.7 (02-Feb-2022)
2.0.6 (28-Sep-2021)
Image links below are broken because OpenExchange doesn't handle them correctly when fetching the description from GitHub. To view them please click here.
Server Manager now has a UI.
See change log after installation, or preview it via link on Version History section of Download page.
Initial Release