mirror of
https://github.com/bitwarden/directory-connector
synced 2025-12-11 05:43:26 +00:00
CLI support for SSO Login (#57)
* sso login support * fix build and lint issues * allow web vault URL to be set
This commit is contained in:
2
jslib
2
jslib
Submodule jslib updated: 57ace40845...14b01f2e5d
27
package-lock.json
generated
27
package-lock.json
generated
@@ -9906,6 +9906,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"is-docker": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ=="
|
||||||
|
},
|
||||||
"is-extendable": {
|
"is-extendable": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
|
||||||
@@ -10102,6 +10107,14 @@
|
|||||||
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
|
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"is-wsl": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
|
||||||
|
"requires": {
|
||||||
|
"is-docker": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"is-yarn-global": {
|
"is-yarn-global": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz",
|
||||||
@@ -12077,6 +12090,15 @@
|
|||||||
"mimic-fn": "^1.0.0"
|
"mimic-fn": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"open": {
|
||||||
|
"version": "7.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/open/-/open-7.1.0.tgz",
|
||||||
|
"integrity": "sha512-lLPI5KgOwEYCDKXf4np7y1PBEkj7HYIyP2DY8mVDRnx0VIIu6bNrRB0R66TuO7Mack6EnTNLm4uvcl1UoklTpA==",
|
||||||
|
"requires": {
|
||||||
|
"is-docker": "^2.0.0",
|
||||||
|
"is-wsl": "^2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"optionator": {
|
"optionator": {
|
||||||
"version": "0.8.2",
|
"version": "0.8.2",
|
||||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
|
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
|
||||||
@@ -17324,6 +17346,11 @@
|
|||||||
"version": "0.8.28",
|
"version": "0.8.28",
|
||||||
"resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.28.tgz",
|
"resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.28.tgz",
|
||||||
"integrity": "sha512-MjwlvV0wr65IQiT0WSHedo/zUhAqtypMdTUjqroV81RohGj1XANwHuC37dwYxphTRbZBYidk0gNS0dQrU2Q3Pw=="
|
"integrity": "sha512-MjwlvV0wr65IQiT0WSHedo/zUhAqtypMdTUjqroV81RohGj1XANwHuC37dwYxphTRbZBYidk0gNS0dQrU2Q3Pw=="
|
||||||
|
},
|
||||||
|
"zxcvbn": {
|
||||||
|
"version": "4.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/zxcvbn/-/zxcvbn-4.4.2.tgz",
|
||||||
|
"integrity": "sha1-KOwXzwl0PtyrBW3dixsGJizHPDA="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,7 +220,9 @@
|
|||||||
"lunr": "2.3.3",
|
"lunr": "2.3.3",
|
||||||
"node-fetch": "2.2.0",
|
"node-fetch": "2.2.0",
|
||||||
"node-forge": "0.7.6",
|
"node-forge": "0.7.6",
|
||||||
|
"open": "7.1.0",
|
||||||
"rxjs": "6.3.3",
|
"rxjs": "6.3.3",
|
||||||
"zone.js": "0.8.28"
|
"zone.js": "0.8.28",
|
||||||
|
"zxcvbn": "4.4.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<h4>{{'customEnvironment' | i18n}}</h4>
|
<h4>{{'customEnvironment' | i18n}}</h4>
|
||||||
<p>{{'customEnvironmentFooter' | i18n}}</p>
|
<p>{{'customEnvironmentFooter' | i18n}}</p>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="webVaultUrl">{{'webVaultUrl' | i18n}}</label>
|
||||||
|
<input id="webVaultUrl" type="text" name="WebVaultUrl" [(ngModel)]="webVaultUrl"
|
||||||
|
class="form-control">
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="apiUrl">{{'apiUrl' | i18n}}</label>
|
<label for="apiUrl">{{'apiUrl' | i18n}}</label>
|
||||||
<input id="apiUrl" type="text" name="ApiUrl" [(ngModel)]="apiUrl" class="form-control">
|
<input id="apiUrl" type="text" name="ApiUrl" [(ngModel)]="apiUrl" class="form-control">
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import { ContainerService } from 'jslib/services/container.service';
|
|||||||
import { CryptoService } from 'jslib/services/crypto.service';
|
import { CryptoService } from 'jslib/services/crypto.service';
|
||||||
import { EnvironmentService } from 'jslib/services/environment.service';
|
import { EnvironmentService } from 'jslib/services/environment.service';
|
||||||
import { NodeCryptoFunctionService } from 'jslib/services/nodeCryptoFunction.service';
|
import { NodeCryptoFunctionService } from 'jslib/services/nodeCryptoFunction.service';
|
||||||
|
import { PasswordGenerationService } from 'jslib/services/passwordGeneration.service';
|
||||||
import { StateService } from 'jslib/services/state.service';
|
import { StateService } from 'jslib/services/state.service';
|
||||||
import { TokenService } from 'jslib/services/token.service';
|
import { TokenService } from 'jslib/services/token.service';
|
||||||
import { UserService } from 'jslib/services/user.service';
|
import { UserService } from 'jslib/services/user.service';
|
||||||
@@ -46,6 +47,9 @@ import { EnvironmentService as EnvironmentServiceAbstraction } from 'jslib/abstr
|
|||||||
import { I18nService as I18nServiceAbstraction } from 'jslib/abstractions/i18n.service';
|
import { I18nService as I18nServiceAbstraction } from 'jslib/abstractions/i18n.service';
|
||||||
import { LogService as LogServiceAbstraction } from 'jslib/abstractions/log.service';
|
import { LogService as LogServiceAbstraction } from 'jslib/abstractions/log.service';
|
||||||
import { MessagingService as MessagingServiceAbstraction } from 'jslib/abstractions/messaging.service';
|
import { MessagingService as MessagingServiceAbstraction } from 'jslib/abstractions/messaging.service';
|
||||||
|
import {
|
||||||
|
PasswordGenerationService as PasswordGenerationServiceAbstraction,
|
||||||
|
} from 'jslib/abstractions/passwordGeneration.service';
|
||||||
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from 'jslib/abstractions/platformUtils.service';
|
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from 'jslib/abstractions/platformUtils.service';
|
||||||
import { StateService as StateServiceAbstraction } from 'jslib/abstractions/state.service';
|
import { StateService as StateServiceAbstraction } from 'jslib/abstractions/state.service';
|
||||||
import { StorageService as StorageServiceAbstraction } from 'jslib/abstractions/storage.service';
|
import { StorageService as StorageServiceAbstraction } from 'jslib/abstractions/storage.service';
|
||||||
@@ -57,8 +61,8 @@ const i18nService = new I18nService(window.navigator.language, './locales');
|
|||||||
const stateService = new StateService();
|
const stateService = new StateService();
|
||||||
const broadcasterService = new BroadcasterService();
|
const broadcasterService = new BroadcasterService();
|
||||||
const messagingService = new ElectronRendererMessagingService(broadcasterService);
|
const messagingService = new ElectronRendererMessagingService(broadcasterService);
|
||||||
const platformUtilsService = new ElectronPlatformUtilsService(i18nService, messagingService, true);
|
|
||||||
const storageService: StorageServiceAbstraction = new ElectronStorageService(remote.app.getPath('userData'));
|
const storageService: StorageServiceAbstraction = new ElectronStorageService(remote.app.getPath('userData'));
|
||||||
|
const platformUtilsService = new ElectronPlatformUtilsService(i18nService, messagingService, true, storageService);
|
||||||
const secureStorageService: StorageServiceAbstraction = new ElectronRendererSecureStorageService();
|
const secureStorageService: StorageServiceAbstraction = new ElectronRendererSecureStorageService();
|
||||||
const cryptoFunctionService: CryptoFunctionServiceAbstraction = new NodeCryptoFunctionService();
|
const cryptoFunctionService: CryptoFunctionServiceAbstraction = new NodeCryptoFunctionService();
|
||||||
const cryptoService = new CryptoService(storageService, secureStorageService, cryptoFunctionService);
|
const cryptoService = new CryptoService(storageService, secureStorageService, cryptoFunctionService);
|
||||||
@@ -70,10 +74,11 @@ const environmentService = new EnvironmentService(apiService, storageService, nu
|
|||||||
const userService = new UserService(tokenService, storageService);
|
const userService = new UserService(tokenService, storageService);
|
||||||
const containerService = new ContainerService(cryptoService);
|
const containerService = new ContainerService(cryptoService);
|
||||||
const authService = new AuthService(cryptoService, apiService, userService, tokenService, appIdService,
|
const authService = new AuthService(cryptoService, apiService, userService, tokenService, appIdService,
|
||||||
i18nService, platformUtilsService, messagingService, false);
|
i18nService, platformUtilsService, messagingService, null, false);
|
||||||
const configurationService = new ConfigurationService(storageService, secureStorageService);
|
const configurationService = new ConfigurationService(storageService, secureStorageService);
|
||||||
const syncService = new SyncService(configurationService, logService, cryptoFunctionService, apiService,
|
const syncService = new SyncService(configurationService, logService, cryptoFunctionService, apiService,
|
||||||
messagingService, i18nService);
|
messagingService, i18nService);
|
||||||
|
const passwordGenerationService = new PasswordGenerationService(cryptoService, storageService, null);
|
||||||
|
|
||||||
const analytics = new Analytics(window, () => true, platformUtilsService, storageService, appIdService);
|
const analytics = new Analytics(window, () => true, platformUtilsService, storageService, appIdService);
|
||||||
containerService.attachToWindow(window);
|
containerService.attachToWindow(window);
|
||||||
@@ -134,6 +139,7 @@ export function initFactory(): Function {
|
|||||||
{ provide: LogServiceAbstraction, useValue: logService },
|
{ provide: LogServiceAbstraction, useValue: logService },
|
||||||
{ provide: ConfigurationService, useValue: configurationService },
|
{ provide: ConfigurationService, useValue: configurationService },
|
||||||
{ provide: SyncService, useValue: syncService },
|
{ provide: SyncService, useValue: syncService },
|
||||||
|
{ provide: PasswordGenerationServiceAbstraction, useValue: passwordGenerationService },
|
||||||
{
|
{
|
||||||
provide: APP_INITIALIZER,
|
provide: APP_INITIALIZER,
|
||||||
useFactory: initFactory,
|
useFactory: initFactory,
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import { LowdbStorageService } from 'jslib/services/lowdbStorage.service';
|
|||||||
import { NodeApiService } from 'jslib/services/nodeApi.service';
|
import { NodeApiService } from 'jslib/services/nodeApi.service';
|
||||||
import { NodeCryptoFunctionService } from 'jslib/services/nodeCryptoFunction.service';
|
import { NodeCryptoFunctionService } from 'jslib/services/nodeCryptoFunction.service';
|
||||||
import { NoopMessagingService } from 'jslib/services/noopMessaging.service';
|
import { NoopMessagingService } from 'jslib/services/noopMessaging.service';
|
||||||
|
import { PasswordGenerationService } from 'jslib/services/passwordGeneration.service';
|
||||||
import { TokenService } from 'jslib/services/token.service';
|
import { TokenService } from 'jslib/services/token.service';
|
||||||
import { UserService } from 'jslib/services/user.service';
|
import { UserService } from 'jslib/services/user.service';
|
||||||
|
|
||||||
@@ -52,6 +53,7 @@ export class Main {
|
|||||||
authService: AuthService;
|
authService: AuthService;
|
||||||
configurationService: ConfigurationService;
|
configurationService: ConfigurationService;
|
||||||
syncService: SyncService;
|
syncService: SyncService;
|
||||||
|
passwordGenerationService: PasswordGenerationService;
|
||||||
program: Program;
|
program: Program;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -92,11 +94,12 @@ export class Main {
|
|||||||
this.userService = new UserService(this.tokenService, this.storageService);
|
this.userService = new UserService(this.tokenService, this.storageService);
|
||||||
this.containerService = new ContainerService(this.cryptoService);
|
this.containerService = new ContainerService(this.cryptoService);
|
||||||
this.authService = new AuthService(this.cryptoService, this.apiService, this.userService, this.tokenService,
|
this.authService = new AuthService(this.cryptoService, this.apiService, this.userService, this.tokenService,
|
||||||
this.appIdService, this.i18nService, this.platformUtilsService, this.messagingService, true);
|
this.appIdService, this.i18nService, this.platformUtilsService, this.messagingService, null, false);
|
||||||
this.configurationService = new ConfigurationService(this.storageService, this.secureStorageService,
|
this.configurationService = new ConfigurationService(this.storageService, this.secureStorageService,
|
||||||
process.env.BITWARDENCLI_CONNECTOR_PLAINTEXT_SECRETS !== 'true');
|
process.env.BITWARDENCLI_CONNECTOR_PLAINTEXT_SECRETS !== 'true');
|
||||||
this.syncService = new SyncService(this.configurationService, this.logService, this.cryptoFunctionService,
|
this.syncService = new SyncService(this.configurationService, this.logService, this.cryptoFunctionService,
|
||||||
this.apiService, this.messagingService, this.i18nService);
|
this.apiService, this.messagingService, this.i18nService);
|
||||||
|
this.passwordGenerationService = new PasswordGenerationService(this.cryptoService, this.storageService, null);
|
||||||
this.program = new Program(this);
|
this.program = new Program(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -140,6 +140,9 @@
|
|||||||
"baseUrl": {
|
"baseUrl": {
|
||||||
"message": "Server URL"
|
"message": "Server URL"
|
||||||
},
|
},
|
||||||
|
"webVaultUrl": {
|
||||||
|
"message": "Web Vault Server URL"
|
||||||
|
},
|
||||||
"apiUrl": {
|
"apiUrl": {
|
||||||
"message": "API Server URL"
|
"message": "API Server URL"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ export class Program extends BaseProgram {
|
|||||||
.description('Log into a user account.')
|
.description('Log into a user account.')
|
||||||
.option('--method <method>', 'Two-step login method.')
|
.option('--method <method>', 'Two-step login method.')
|
||||||
.option('--code <code>', 'Two-step login code.')
|
.option('--code <code>', 'Two-step login code.')
|
||||||
|
.option('--sso', 'Log in with Single-Sign On.')
|
||||||
.on('--help', () => {
|
.on('--help', () => {
|
||||||
writeLn('\n Notes:');
|
writeLn('\n Notes:');
|
||||||
writeLn('');
|
writeLn('');
|
||||||
@@ -96,11 +97,14 @@ export class Program extends BaseProgram {
|
|||||||
writeLn(' bw login');
|
writeLn(' bw login');
|
||||||
writeLn(' bw login john@example.com myPassword321');
|
writeLn(' bw login john@example.com myPassword321');
|
||||||
writeLn(' bw login john@example.com myPassword321 --method 1 --code 249213');
|
writeLn(' bw login john@example.com myPassword321 --method 1 --code 249213');
|
||||||
|
writeLn(' bw login --sso');
|
||||||
writeLn('', true);
|
writeLn('', true);
|
||||||
})
|
})
|
||||||
.action(async (email: string, password: string, cmd: program.Command) => {
|
.action(async (email: string, password: string, cmd: program.Command) => {
|
||||||
await this.exitIfAuthed();
|
await this.exitIfAuthed();
|
||||||
const command = new LoginCommand(this.main.authService, this.main.apiService, this.main.i18nService);
|
const command = new LoginCommand(this.main.authService, this.main.apiService, this.main.i18nService,
|
||||||
|
this.main.environmentService, this.main.passwordGenerationService, this.main.cryptoFunctionService,
|
||||||
|
'connector');
|
||||||
const response = await command.run(email, password, cmd);
|
const response = await command.run(email, password, cmd);
|
||||||
this.processResponse(response);
|
this.processResponse(response);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import { AzureConfiguration } from '../models/azureConfiguration';
|
|||||||
import { GSuiteConfiguration } from '../models/gsuiteConfiguration';
|
import { GSuiteConfiguration } from '../models/gsuiteConfiguration';
|
||||||
import { LdapConfiguration } from '../models/ldapConfiguration';
|
import { LdapConfiguration } from '../models/ldapConfiguration';
|
||||||
import { OktaConfiguration } from '../models/oktaConfiguration';
|
import { OktaConfiguration } from '../models/oktaConfiguration';
|
||||||
|
import { OneLoginConfiguration } from '../models/oneLoginConfiguration';
|
||||||
import { SyncConfiguration } from '../models/syncConfiguration';
|
import { SyncConfiguration } from '../models/syncConfiguration';
|
||||||
import { OneLoginConfiguration } from 'src/models/oneLoginConfiguration';
|
|
||||||
|
|
||||||
const StoredSecurely = '[STORED SECURELY]';
|
const StoredSecurely = '[STORED SECURELY]';
|
||||||
const Keys = {
|
const Keys = {
|
||||||
|
|||||||
@@ -160,8 +160,8 @@ export class OneLoginDirectoryService extends BaseDirectoryService implements Di
|
|||||||
const req: RequestInit = {
|
const req: RequestInit = {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
'Authorization': 'bearer:' + this.accessToken,
|
Authorization: 'bearer:' + this.accessToken,
|
||||||
'Accept': 'application/json',
|
Accept: 'application/json',
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
const response = await fetch(new Request(url, req));
|
const response = await fetch(new Request(url, req));
|
||||||
|
|||||||
Reference in New Issue
Block a user