mirror of
https://github.com/bitwarden/directory-connector
synced 2025-12-05 23:53:21 +00:00
Compare commits
6 Commits
refactor/i
...
v2.10.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c999d40917 | ||
|
|
9d8ed5ea8d | ||
|
|
f041c2b703 | ||
|
|
14a7833512 | ||
|
|
94d3ece7a9 | ||
|
|
8981b97632 |
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -61,7 +61,7 @@ jobs:
|
||||
echo "::set-output name=branch-name::$BRANCH_NAME"
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: bitwarden/gh-actions/download-artifacts@23433be15ed6fd046ce12b6889c5184a8d9c8783
|
||||
uses: bitwarden/gh-actions/download-artifacts@c1fa8e09871a860862d6bbe36184b06d2c7e35a8
|
||||
with:
|
||||
workflow: build.yml
|
||||
workflow_conclusion: success
|
||||
|
||||
2
jslib
2
jslib
Submodule jslib updated: 9950fb42a1...e595c0548e
@@ -21,16 +21,6 @@ export abstract class StateService extends BaseStateServiceAbstraction<Account>
|
||||
| OktaConfiguration
|
||||
| OneLoginConfiguration
|
||||
) => Promise<any>;
|
||||
getLdapKey: (options?: StorageOptions) => Promise<string>;
|
||||
setLdapKey: (value: string, options?: StorageOptions) => Promise<void>;
|
||||
getGsuiteKey: (options?: StorageOptions) => Promise<string>;
|
||||
setGsuiteKey: (value: string, options?: StorageOptions) => Promise<void>;
|
||||
getAzureKey: (options?: StorageOptions) => Promise<string>;
|
||||
setAzureKey: (value: string, options?: StorageOptions) => Promise<void>;
|
||||
getOktaKey: (options?: StorageOptions) => Promise<string>;
|
||||
setOktaKey: (value: string, options?: StorageOptions) => Promise<void>;
|
||||
getOneLoginKey: (options?: StorageOptions) => Promise<string>;
|
||||
setOneLoginKey: (value: string, options?: StorageOptions) => Promise<void>;
|
||||
getLdapConfiguration: (options?: StorageOptions) => Promise<LdapConfiguration>;
|
||||
setLdapConfiguration: (value: LdapConfiguration, options?: StorageOptions) => Promise<void>;
|
||||
getGsuiteConfiguration: (options?: StorageOptions) => Promise<GSuiteConfiguration>;
|
||||
|
||||
@@ -30,7 +30,6 @@ import { NodeCryptoFunctionService } from "jslib-node/services/nodeCryptoFunctio
|
||||
|
||||
import { StateService as StateServiceAbstraction } from "../../abstractions/state.service";
|
||||
import { Account } from "../../models/account";
|
||||
import { refreshToken } from "../../services/api.service";
|
||||
import { AuthService } from "../../services/auth.service";
|
||||
import { I18nService } from "../../services/i18n.service";
|
||||
import { NoopTwoFactorService } from "../../services/noop/noopTwoFactor.service";
|
||||
@@ -41,14 +40,6 @@ import { SyncService } from "../../services/sync.service";
|
||||
import { AuthGuardService } from "./auth-guard.service";
|
||||
import { LaunchGuardService } from "./launch-guard.service";
|
||||
|
||||
function refreshTokenCallback(injector: Injector) {
|
||||
return () => {
|
||||
const stateService = injector.get(StateServiceAbstraction);
|
||||
const authService = injector.get(AuthServiceAbstraction);
|
||||
return refreshToken(stateService, authService);
|
||||
};
|
||||
}
|
||||
|
||||
export function initFactory(
|
||||
environmentService: EnvironmentServiceAbstraction,
|
||||
i18nService: I18nService,
|
||||
@@ -129,26 +120,26 @@ export function initFactory(
|
||||
platformUtilsService: PlatformUtilsServiceAbstraction,
|
||||
environmentService: EnvironmentServiceAbstraction,
|
||||
messagingService: MessagingServiceAbstraction,
|
||||
injector: Injector
|
||||
appIdService: AppIdServiceAbstraction
|
||||
) =>
|
||||
new NodeApiService(
|
||||
tokenService,
|
||||
platformUtilsService,
|
||||
environmentService,
|
||||
appIdService,
|
||||
async (expired: boolean) => messagingService.send("logout", { expired: expired }),
|
||||
"Bitwarden_DC/" +
|
||||
platformUtilsService.getApplicationVersion() +
|
||||
" (" +
|
||||
platformUtilsService.getDeviceString().toUpperCase() +
|
||||
")",
|
||||
refreshTokenCallback(injector)
|
||||
")"
|
||||
),
|
||||
deps: [
|
||||
TokenServiceAbstraction,
|
||||
PlatformUtilsServiceAbstraction,
|
||||
EnvironmentServiceAbstraction,
|
||||
MessagingServiceAbstraction,
|
||||
Injector,
|
||||
AppIdServiceAbstraction,
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
17
src/bwdc.ts
17
src/bwdc.ts
@@ -7,7 +7,6 @@ import { ClientType } from "jslib-common/enums/clientType";
|
||||
import { LogLevelType } from "jslib-common/enums/logLevelType";
|
||||
import { StateFactory } from "jslib-common/factories/stateFactory";
|
||||
import { GlobalState } from "jslib-common/models/domain/globalState";
|
||||
import { ApiLogInCredentials } from "jslib-common/models/domain/logInCredentials";
|
||||
import { AppIdService } from "jslib-common/services/appId.service";
|
||||
import { CipherService } from "jslib-common/services/cipher.service";
|
||||
import { CollectionService } from "jslib-common/services/collection.service";
|
||||
@@ -149,18 +148,20 @@ export class Main {
|
||||
this.tokenService = new TokenService(this.stateService);
|
||||
this.messagingService = new NoopMessagingService();
|
||||
this.environmentService = new EnvironmentService(this.stateService);
|
||||
|
||||
const customUserAgent =
|
||||
"Bitwarden_DC/" +
|
||||
this.platformUtilsService.getApplicationVersion() +
|
||||
" (" +
|
||||
this.platformUtilsService.getDeviceString().toUpperCase() +
|
||||
")";
|
||||
this.apiService = new NodeApiService(
|
||||
this.tokenService,
|
||||
this.platformUtilsService,
|
||||
this.environmentService,
|
||||
this.appIdService,
|
||||
async (expired: boolean) => await this.logout(),
|
||||
"Bitwarden_DC/" +
|
||||
this.platformUtilsService.getApplicationVersion() +
|
||||
" (" +
|
||||
this.platformUtilsService.getDeviceString().toUpperCase() +
|
||||
")",
|
||||
(clientId, clientSecret) =>
|
||||
this.authService.logIn(new ApiLogInCredentials(clientId, clientSecret))
|
||||
customUserAgent
|
||||
);
|
||||
this.containerService = new ContainerService(this.cryptoService);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "@bitwarden/directory-connector",
|
||||
"productName": "Bitwarden Directory Connector",
|
||||
"description": "Sync your user directory to your Bitwarden organization.",
|
||||
"version": "2.10.0",
|
||||
"version": "2.10.2",
|
||||
"author": "Bitwarden Inc. <hello@bitwarden.com> (https://bitwarden.com)",
|
||||
"homepage": "https://bitwarden.com",
|
||||
"license": "GPL-3.0",
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
import { AuthService } from "jslib-common/abstractions/auth.service";
|
||||
import { EnvironmentService } from "jslib-common/abstractions/environment.service";
|
||||
import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
|
||||
import { TokenService } from "jslib-common/abstractions/token.service";
|
||||
import { ApiLogInCredentials } from "jslib-common/models/domain/logInCredentials";
|
||||
import { ApiService as ApiServiceBase } from "jslib-common/services/api.service";
|
||||
|
||||
import { StateService } from "../abstractions/state.service";
|
||||
|
||||
export async function refreshToken(stateService: StateService, authService: AuthService) {
|
||||
try {
|
||||
const clientId = await stateService.getApiKeyClientId();
|
||||
const clientSecret = await stateService.getApiKeyClientSecret();
|
||||
if (clientId != null && clientSecret != null) {
|
||||
await authService.logIn(new ApiLogInCredentials(clientId, clientSecret));
|
||||
}
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
}
|
||||
|
||||
export class ApiService extends ApiServiceBase {
|
||||
constructor(
|
||||
tokenService: TokenService,
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
environmentService: EnvironmentService,
|
||||
private refreshTokenCallback: () => Promise<void>,
|
||||
logoutCallback: (expired: boolean) => Promise<void>,
|
||||
customUserAgent: string = null
|
||||
) {
|
||||
super(tokenService, platformUtilsService, environmentService, logoutCallback, customUserAgent);
|
||||
}
|
||||
|
||||
doRefreshToken(): Promise<void> {
|
||||
return this.refreshTokenCallback();
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import { LogService } from "jslib-common/abstractions/log.service";
|
||||
import { StateMigrationService } from "jslib-common/abstractions/stateMigration.service";
|
||||
import { StorageService } from "jslib-common/abstractions/storage.service";
|
||||
import { StateFactory } from "jslib-common/factories/stateFactory";
|
||||
import { EnvironmentUrls } from "jslib-common/models/domain/environmentUrls";
|
||||
import { GlobalState } from "jslib-common/models/domain/globalState";
|
||||
import { StorageOptions } from "jslib-common/models/domain/storageOptions";
|
||||
import { StateService as BaseStateService } from "jslib-common/services/state.service";
|
||||
@@ -60,24 +61,30 @@ export class StateService
|
||||
}
|
||||
|
||||
if (this.useSecureStorageForSecrets) {
|
||||
// Do not introduce secrets into the in-memory account object
|
||||
const configWithSecrets = Object.assign({}, config);
|
||||
|
||||
switch (type) {
|
||||
case DirectoryType.Ldap:
|
||||
(config as any).password = await this.getLdapKey();
|
||||
(configWithSecrets as any).password = await this.getLdapKey();
|
||||
break;
|
||||
case DirectoryType.AzureActiveDirectory:
|
||||
(config as any).key = await this.getAzureKey();
|
||||
(configWithSecrets as any).key = await this.getAzureKey();
|
||||
break;
|
||||
case DirectoryType.Okta:
|
||||
(config as any).token = await this.getOktaKey();
|
||||
(configWithSecrets as any).token = await this.getOktaKey();
|
||||
break;
|
||||
case DirectoryType.GSuite:
|
||||
(config as any).privateKey = await this.getGsuiteKey();
|
||||
(configWithSecrets as any).privateKey = await this.getGsuiteKey();
|
||||
break;
|
||||
case DirectoryType.OneLogin:
|
||||
(config as any).clientSecret = await this.getOneLoginKey();
|
||||
(configWithSecrets as any).clientSecret = await this.getOneLoginKey();
|
||||
break;
|
||||
}
|
||||
|
||||
return configWithSecrets as T;
|
||||
}
|
||||
|
||||
return config as T;
|
||||
}
|
||||
|
||||
@@ -90,45 +97,53 @@ export class StateService
|
||||
| OktaConfiguration
|
||||
| OneLoginConfiguration
|
||||
): Promise<any> {
|
||||
const savedConfig: any = Object.assign({}, config);
|
||||
if (this.useSecureStorageForSecrets) {
|
||||
switch (type) {
|
||||
case DirectoryType.Ldap:
|
||||
await this.setLdapKey(savedConfig.password);
|
||||
savedConfig.password = StoredSecurely;
|
||||
await this.setLdapConfiguration(savedConfig);
|
||||
case DirectoryType.Ldap: {
|
||||
const ldapConfig = config as LdapConfiguration;
|
||||
await this.setLdapKey(ldapConfig.password);
|
||||
ldapConfig.password = StoredSecurely;
|
||||
await this.setLdapConfiguration(ldapConfig);
|
||||
break;
|
||||
case DirectoryType.AzureActiveDirectory:
|
||||
await this.setAzureKey(savedConfig.key);
|
||||
savedConfig.key = StoredSecurely;
|
||||
await this.setAzureConfiguration(savedConfig);
|
||||
}
|
||||
case DirectoryType.AzureActiveDirectory: {
|
||||
const azureConfig = config as AzureConfiguration;
|
||||
await this.setAzureKey(azureConfig.key);
|
||||
azureConfig.key = StoredSecurely;
|
||||
await this.setAzureConfiguration(azureConfig);
|
||||
break;
|
||||
case DirectoryType.Okta:
|
||||
await this.setOktaKey(savedConfig.token);
|
||||
savedConfig.token = StoredSecurely;
|
||||
await this.setOktaConfiguration(savedConfig);
|
||||
}
|
||||
case DirectoryType.Okta: {
|
||||
const oktaConfig = config as OktaConfiguration;
|
||||
await this.setOktaKey(oktaConfig.token);
|
||||
oktaConfig.token = StoredSecurely;
|
||||
await this.setOktaConfiguration(oktaConfig);
|
||||
break;
|
||||
case DirectoryType.GSuite:
|
||||
if (savedConfig.privateKey == null) {
|
||||
}
|
||||
case DirectoryType.GSuite: {
|
||||
const gsuiteConfig = config as GSuiteConfiguration;
|
||||
if (gsuiteConfig.privateKey == null) {
|
||||
await this.setGsuiteKey(null);
|
||||
} else {
|
||||
(config as GSuiteConfiguration).privateKey = savedConfig.privateKey =
|
||||
savedConfig.privateKey.replace(/\\n/g, "\n");
|
||||
await this.setGsuiteKey(savedConfig.privateKey);
|
||||
savedConfig.privateKey = StoredSecurely;
|
||||
const normalizedPrivateKey = gsuiteConfig.privateKey.replace(/\\n/g, "\n");
|
||||
await this.setGsuiteKey(normalizedPrivateKey);
|
||||
gsuiteConfig.privateKey = StoredSecurely;
|
||||
}
|
||||
await this.setGsuiteConfiguration(savedConfig);
|
||||
await this.setGsuiteConfiguration(gsuiteConfig);
|
||||
break;
|
||||
case DirectoryType.OneLogin:
|
||||
await this.setOneLoginKey(savedConfig.clientSecret);
|
||||
savedConfig.clientSecret = StoredSecurely;
|
||||
await this.setOneLoginConfiguration(savedConfig);
|
||||
}
|
||||
case DirectoryType.OneLogin: {
|
||||
const oneLoginConfig = config as OneLoginConfiguration;
|
||||
await this.setOneLoginKey(oneLoginConfig.clientSecret);
|
||||
oneLoginConfig.clientSecret = StoredSecurely;
|
||||
await this.setOneLoginConfiguration(oneLoginConfig);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async getLdapKey(options?: StorageOptions): Promise<string> {
|
||||
private async getLdapKey(options?: StorageOptions): Promise<string> {
|
||||
options = this.reconcileOptions(options, await this.defaultSecureStorageOptions());
|
||||
if (options?.userId == null) {
|
||||
return null;
|
||||
@@ -138,7 +153,7 @@ export class StateService
|
||||
);
|
||||
}
|
||||
|
||||
async setLdapKey(value: string, options?: StorageOptions): Promise<void> {
|
||||
private async setLdapKey(value: string, options?: StorageOptions): Promise<void> {
|
||||
options = this.reconcileOptions(options, await this.defaultSecureStorageOptions());
|
||||
if (options?.userId == null) {
|
||||
return;
|
||||
@@ -150,7 +165,7 @@ export class StateService
|
||||
);
|
||||
}
|
||||
|
||||
async getGsuiteKey(options?: StorageOptions): Promise<string> {
|
||||
private async getGsuiteKey(options?: StorageOptions): Promise<string> {
|
||||
options = this.reconcileOptions(options, await this.defaultSecureStorageOptions());
|
||||
if (options?.userId == null) {
|
||||
return null;
|
||||
@@ -160,7 +175,7 @@ export class StateService
|
||||
);
|
||||
}
|
||||
|
||||
async setGsuiteKey(value: string, options?: StorageOptions): Promise<void> {
|
||||
private async setGsuiteKey(value: string, options?: StorageOptions): Promise<void> {
|
||||
options = this.reconcileOptions(options, await this.defaultSecureStorageOptions());
|
||||
if (options?.userId == null) {
|
||||
return;
|
||||
@@ -172,7 +187,7 @@ export class StateService
|
||||
);
|
||||
}
|
||||
|
||||
async getAzureKey(options?: StorageOptions): Promise<string> {
|
||||
private async getAzureKey(options?: StorageOptions): Promise<string> {
|
||||
options = this.reconcileOptions(options, await this.defaultSecureStorageOptions());
|
||||
if (options?.userId == null) {
|
||||
return null;
|
||||
@@ -182,7 +197,7 @@ export class StateService
|
||||
);
|
||||
}
|
||||
|
||||
async setAzureKey(value: string, options?: StorageOptions): Promise<void> {
|
||||
private async setAzureKey(value: string, options?: StorageOptions): Promise<void> {
|
||||
options = this.reconcileOptions(options, await this.defaultSecureStorageOptions());
|
||||
if (options?.userId == null) {
|
||||
return;
|
||||
@@ -194,7 +209,7 @@ export class StateService
|
||||
);
|
||||
}
|
||||
|
||||
async getOktaKey(options?: StorageOptions): Promise<string> {
|
||||
private async getOktaKey(options?: StorageOptions): Promise<string> {
|
||||
options = this.reconcileOptions(options, await this.defaultSecureStorageOptions());
|
||||
if (options?.userId == null) {
|
||||
return null;
|
||||
@@ -204,7 +219,7 @@ export class StateService
|
||||
);
|
||||
}
|
||||
|
||||
async setOktaKey(value: string, options?: StorageOptions): Promise<void> {
|
||||
private async setOktaKey(value: string, options?: StorageOptions): Promise<void> {
|
||||
options = this.reconcileOptions(options, await this.defaultSecureStorageOptions());
|
||||
if (options?.userId == null) {
|
||||
return;
|
||||
@@ -216,7 +231,7 @@ export class StateService
|
||||
);
|
||||
}
|
||||
|
||||
async getOneLoginKey(options?: StorageOptions): Promise<string> {
|
||||
private async getOneLoginKey(options?: StorageOptions): Promise<string> {
|
||||
options = this.reconcileOptions(options, await this.defaultSecureStorageOptions());
|
||||
if (options?.userId == null) {
|
||||
return null;
|
||||
@@ -226,7 +241,7 @@ export class StateService
|
||||
);
|
||||
}
|
||||
|
||||
async setOneLoginKey(value: string, options?: StorageOptions): Promise<void> {
|
||||
private async setOneLoginKey(value: string, options?: StorageOptions): Promise<void> {
|
||||
options = this.reconcileOptions(options, await this.defaultSecureStorageOptions());
|
||||
if (options?.userId == null) {
|
||||
return;
|
||||
@@ -568,4 +583,8 @@ export class StateService
|
||||
};
|
||||
return Object.assign(this.createAccount(), persistentAccountInformation);
|
||||
}
|
||||
|
||||
async getEnvironmentUrls(options?: StorageOptions): Promise<EnvironmentUrls> {
|
||||
return this.getGlobalEnvironmentUrls(options);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user