В VSCode существует несколько способов хранить настройки пользователя. До прихода версии 1.53.0 конфиденциальную информацию приходилось сохранять в Memento объектах в workspaceState и globalState или например keytar. А хранение паролей с токенами в стандартном конфигурационном файле или с помощью переменных окружения, являлось не самой лучшей идеей, так как эти данные могли быть прочитаны и кэшированы другими расширениями.
В статье мы посмотрим на способы чтения данных из settings.json и environment variables. А затем создадим класс с минимальным функционалом, отвечающий за хранение и отдачу ключей со значениями из VSCode SecretStorage.

Проект мы условно назовем fancycolor. Процесс инициализации проекта подробно расписан в документации VSCode Extensions, поэтому сразу приступим к интересному.
settings.json
Все настройки от всех VSCode extensions хранятся в общем файле settings.json и соответственно могут быть доступны из любого расширения. К примеру, из нашего приложения fancycolor мы можем легко прочитать список всех хостов и соответствующие им платформы из нашего конфига другого популярного приложения SSH - Remote.
const configurationWorkspace = workspace.getConfiguration()
const sshRemotePlatform: string | undefined = configurationWorkspace.get(
"remote.SSH.remotePlatform"
)
console.log(sshRemotePlatform)Данный код выведет список вашей конфигурации для расширения SSH - Remote.
Proxy {ubuntu: 'linux', home: 'linux', raspberry: 'linux'}environment variables
VSCode расширения по умолчанию имеют доступ к переменным окружения пользователя. Все переменные которые вы сохранили в .bashrc в Linux или User.Environment в Windows можно получить с помощью глобального объекта process.env.
Например создадим файл /home/ubuntu/.env с переменной ACCESS_TOKEN_ENV и добавим его в .bashrc.
echo 'export ACCESS_TOKEN_ENV="d8aba3b2-fda0-414a-b867-4798b7892bb4"' >> /home/ubuntu/.env
echo "source /home/ubuntu/.env" >> /home/ubuntu/.bashrcВ Windows тоже самое достигается через Powershell.
[System.Environment]::SetEnvironmentVariable('ACCESS_TOKEN_ENV', 'd8aba3b2-fda0-414a-b867-4798b7892bb4', [System.EnvironmentVariableTarget]::User)Теперь прочитаем его в VSCode fancycolor extension.
import * as process from "process"
export const accessTokenEnv = process.env["ACCESS_TOKEN_ENV"]
console.log(accessTokenEnv)В выводе мы видим наш токен.
d8aba3b2-fda0-414a-b867-4798b7892bb4SecretStorage
На сегодняшний день является лучшим способом хранения паролей, логинов, токенов и другой конфиденциальной информации в VSCode. Для демонстрации создадим простенький класс AuthSettings, где будем хранить fancycolor_token, с минимально необходимыми методами:
initдля инициализации нашего SecretStoragegetter
instancestoreAuthDataдля записи в SecretStoragegetAuthDataдля извлечения данных из SecretStorage
import { ExtensionContext, SecretStorage } from "vscode"
export default class AuthSettings {
private static _instance: AuthSettings
constructor(private secretStorage: SecretStorage) {}
static init(context: ExtensionContext): void {
/*
Create instance of new AuthSettings.
*/
AuthSettings._instance = new AuthSettings(context.secrets)
}
static get instance(): AuthSettings {
/*
Getter of our AuthSettings existing instance.
*/
return AuthSettings._instance
}
async storeAuthData(token?: string): Promise<void> {
/*
Update values in bugout_auth secret storage.
*/
if (token) {
this.secretStorage.store("fancycolor_token", token)
}
}
async getAuthData(): Promise<string | undefined> {
/*
Retrieve data from secret storage.
*/
return await this.secretStorage.get("fancycolor_token")
}
}В extension.ts напишем функционал позволяющий добавлять и извлекать токен с помощью команд в Command Palette.
import * as vscode from "vscode"
import AuthSettings from "./settings"
export function activate(context: vscode.ExtensionContext) {
// Initialize and get current instance of our Secret Storage
AuthSettings.init(context)
const settings = AuthSettings.instance
// Register commands to save and retrieve token
vscode.commands.registerCommand("fancycolor.setToken", async () => {
const tokenInput = await vscode.window.showInputBox()
await settings.storeAuthData(tokenInput)
})
vscode.commands.registerCommand("fancycolor.getToken", async () => {
const tokenOutput = await settings.getAuthData()
console.log(tokenOutput)
})
}
export function deactivate() {}Останется только в package.json зарегистрировать команды fancycolor.setToken и fancycolor.getToken. В последствии при работе с VSCode SecretStorage, мы сможем обратиться исключительно к конкретному SecretStorage созданному для нашего приложения, которому будет присвоен свой _id: 'undefined_publisher.fancycolor'.