import * as program from "commander"; import { StateService } from "@/libs/abstractions/state.service"; import { DirectoryType } from "@/libs/enums/directoryType"; import { EntraIdConfiguration } from "@/libs/models/entraIdConfiguration"; import { GSuiteConfiguration } from "@/libs/models/gsuiteConfiguration"; import { LdapConfiguration } from "@/libs/models/ldapConfiguration"; import { OktaConfiguration } from "@/libs/models/oktaConfiguration"; import { OneLoginConfiguration } from "@/libs/models/oneLoginConfiguration"; import { SyncConfiguration } from "@/libs/models/syncConfiguration"; import { ConnectorUtils } from "@/libs/utils"; import { I18nService } from "@/jslib/common/src/abstractions/i18n.service"; import { NodeUtils } from "@/jslib/common/src/misc/nodeUtils"; import { EnvironmentUrls } from "@/jslib/common/src/models/domain/environmentUrls"; import { Response } from "@/src-cli/cli/models/response"; import { MessageResponse } from "@/src-cli/cli/models/response/messageResponse"; export class ConfigCommand { private directory: DirectoryType; private ldap = new LdapConfiguration(); private gsuite = new GSuiteConfiguration(); private entra = new EntraIdConfiguration(); private okta = new OktaConfiguration(); private oneLogin = new OneLoginConfiguration(); private sync = new SyncConfiguration(); constructor( private stateService: StateService, private i18nService: I18nService, ) {} async run(setting: string, value: string, options: program.OptionValues): Promise { setting = setting.toLowerCase(); if (value == null || value === "") { if (options.secretfile) { value = await NodeUtils.readFirstLine(options.secretfile); } else if (options.secretenv && process.env[options.secretenv]) { value = process.env[options.secretenv]; } } try { switch (setting) { case "server": await this.setServer(value); break; case "directory": await this.setDirectory(value); break; case "ldap.password": await this.setLdapPassword(value); break; case "gsuite.key": await this.setGSuiteKey(value); break; // Azure Active Directory was renamed to Entra ID, but we've kept the old key name // to be backwards compatible with existing configurations. case "azure.key": case "entra.key": await this.setEntraIdKey(value); break; case "okta.token": await this.setOktaToken(value); break; case "onelogin.secret": await this.setOneLoginSecret(value); break; default: return Response.badRequest("Unknown setting."); } } catch (e) { return Response.error(e); } const res = new MessageResponse(this.i18nService.t("savedSetting", setting), null); return Response.success(res); } private async setServer(url: string) { url = url === "null" || url === "bitwarden.com" || url === "https://bitwarden.com" ? null : url; const urls = new EnvironmentUrls(); urls.base = url; await this.stateService.setEnvironmentUrls(urls); } private async setDirectory(type: string) { const dir = parseInt(type, null); if (dir < DirectoryType.Ldap || dir > DirectoryType.OneLogin) { throw new Error("Invalid directory type value."); } await this.loadConfig(); this.directory = dir; await this.saveConfig(); } private async setLdapPassword(password: string) { await this.loadConfig(); this.ldap.password = password; await this.saveConfig(); } private async setGSuiteKey(key: string) { await this.loadConfig(); this.gsuite.privateKey = key != null ? key.trimLeft() : null; await this.saveConfig(); } private async setEntraIdKey(key: string) { await this.loadConfig(); this.entra.key = key; await this.saveConfig(); } private async setOktaToken(token: string) { await this.loadConfig(); this.okta.token = token; await this.saveConfig(); } private async setOneLoginSecret(secret: string) { await this.loadConfig(); this.oneLogin.clientSecret = secret; await this.saveConfig(); } private async loadConfig() { this.directory = await this.stateService.getDirectoryType(); this.ldap = (await this.stateService.getDirectory(DirectoryType.Ldap)) || this.ldap; this.gsuite = (await this.stateService.getDirectory(DirectoryType.GSuite)) || this.gsuite; this.entra = (await this.stateService.getDirectory(DirectoryType.EntraID)) || this.entra; this.okta = (await this.stateService.getDirectory(DirectoryType.Okta)) || this.okta; this.oneLogin = (await this.stateService.getDirectory(DirectoryType.OneLogin)) || this.oneLogin; this.sync = (await this.stateService.getSync()) || this.sync; } private async saveConfig() { ConnectorUtils.adjustConfigForSave(this.ldap, this.sync); await this.stateService.setDirectoryType(this.directory); await this.stateService.setDirectory(DirectoryType.Ldap, this.ldap); await this.stateService.setDirectory(DirectoryType.GSuite, this.gsuite); await this.stateService.setDirectory(DirectoryType.EntraID, this.entra); await this.stateService.setDirectory(DirectoryType.Okta, this.okta); await this.stateService.setDirectory(DirectoryType.OneLogin, this.oneLogin); await this.stateService.setSync(this.sync); } }