[Key Connector] Add support for key connector (#406)

Co-authored-by: Hinton <oscar@oscarhinton.com>
This commit is contained in:
Thomas Rittson 2021-11-10 04:00:16 +10:00 committed by GitHub
parent 720bd004a1
commit 85f4f1e727
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 30 additions and 11 deletions

2
jslib

@ -1 +1 @@
Subproject commit 2db9e1ce0d7a702f07f20ecb916dd8191ff617e1 Subproject commit c4fb4a35ab7a0d3e3b5c398779e01a1a03ba3633

View File

@ -25,6 +25,7 @@ import { ExportService } from 'jslib-common/services/export.service';
import { FileUploadService } from 'jslib-common/services/fileUpload.service'; import { FileUploadService } from 'jslib-common/services/fileUpload.service';
import { FolderService } from 'jslib-common/services/folder.service'; import { FolderService } from 'jslib-common/services/folder.service';
import { ImportService } from 'jslib-common/services/import.service'; import { ImportService } from 'jslib-common/services/import.service';
import { KeyConnectorService } from 'jslib-common/services/keyConnector.service';
import { NoopMessagingService } from 'jslib-common/services/noopMessaging.service'; import { NoopMessagingService } from 'jslib-common/services/noopMessaging.service';
import { PasswordGenerationService } from 'jslib-common/services/passwordGeneration.service'; import { PasswordGenerationService } from 'jslib-common/services/passwordGeneration.service';
import { PolicyService } from 'jslib-common/services/policy.service'; import { PolicyService } from 'jslib-common/services/policy.service';
@ -85,6 +86,7 @@ export class Main {
logService: ConsoleLogService; logService: ConsoleLogService;
sendService: SendService; sendService: SendService;
fileUploadService: FileUploadService; fileUploadService: FileUploadService;
keyConnectorService: KeyConnectorService;
constructor() { constructor() {
let p = null; let p = null;
@ -136,14 +138,17 @@ export class Main {
this.policyService = new PolicyService(this.userService, this.storageService, this.apiService); this.policyService = new PolicyService(this.userService, this.storageService, this.apiService);
this.sendService = new SendService(this.cryptoService, this.userService, this.apiService, this.fileUploadService, this.sendService = new SendService(this.cryptoService, this.userService, this.apiService, this.fileUploadService,
this.storageService, this.i18nService, this.cryptoFunctionService); this.storageService, this.i18nService, this.cryptoFunctionService);
this.keyConnectorService = new KeyConnectorService(this.storageService, this.userService, this.cryptoService,
this.apiService, this.environmentService, this.tokenService, this.logService);
this.vaultTimeoutService = new VaultTimeoutService(this.cipherService, this.folderService, this.vaultTimeoutService = new VaultTimeoutService(this.cipherService, this.folderService,
this.collectionService, this.cryptoService, this.platformUtilsService, this.storageService, this.collectionService, this.cryptoService, this.platformUtilsService, this.storageService,
this.messagingService, this.searchService, this.userService, this.tokenService, this.policyService, this.messagingService, this.searchService, this.userService, this.tokenService, this.policyService,
async () => await this.cryptoService.clearStoredKey('auto'), null); this.keyConnectorService, async () => await this.cryptoService.clearStoredKey('auto'), null);
this.syncService = new SyncService(this.userService, this.apiService, this.settingsService, this.syncService = new SyncService(this.userService, this.apiService, this.settingsService,
this.folderService, this.cipherService, this.cryptoService, this.collectionService, this.folderService, this.cipherService, this.cryptoService, this.collectionService,
this.storageService, this.messagingService, this.policyService, this.sendService, this.storageService, this.messagingService, this.policyService, this.sendService,
this.logService, async (expired: boolean) => await this.logout()); this.logService, this.tokenService, this.keyConnectorService,
async (expired: boolean) => await this.logout());
this.passwordGenerationService = new PasswordGenerationService(this.cryptoService, this.storageService, this.passwordGenerationService = new PasswordGenerationService(this.cryptoService, this.storageService,
this.policyService); this.policyService);
this.totpService = new TotpService(this.storageService, this.cryptoFunctionService, this.logService); this.totpService = new TotpService(this.storageService, this.cryptoFunctionService, this.logService);
@ -153,7 +158,8 @@ export class Main {
this.cryptoService); 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, this.appIdService, this.i18nService, this.platformUtilsService, this.messagingService,
this.vaultTimeoutService, this.logService, this.cryptoFunctionService, true); this.vaultTimeoutService, this.logService, this.cryptoFunctionService, this.environmentService,
this.keyConnectorService, true);
this.auditService = new AuditService(this.cryptoFunctionService, this.apiService); this.auditService = new AuditService(this.cryptoFunctionService, this.apiService);
this.program = new Program(this); this.program = new Program(this);
this.vaultProgram = new VaultProgram(this); this.vaultProgram = new VaultProgram(this);

View File

@ -38,6 +38,7 @@ export class ConfigCommand {
icons: options.icons || null, icons: options.icons || null,
notifications: options.notifications || null, notifications: options.notifications || null,
events: options.events || null, events: options.events || null,
keyConnector: options.keyConnector || null,
}); });
const res = new MessageResponse('Saved setting `config`.', null); const res = new MessageResponse('Saved setting `config`.', null);
return Response.success(res); return Response.success(res);

View File

@ -7,6 +7,7 @@ import { CryptoService } from 'jslib-common/abstractions/crypto.service';
import { CryptoFunctionService } from 'jslib-common/abstractions/cryptoFunction.service'; import { CryptoFunctionService } from 'jslib-common/abstractions/cryptoFunction.service';
import { EnvironmentService } from 'jslib-common/abstractions/environment.service'; import { EnvironmentService } from 'jslib-common/abstractions/environment.service';
import { I18nService } from 'jslib-common/abstractions/i18n.service'; import { I18nService } from 'jslib-common/abstractions/i18n.service';
import { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';
import { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service'; import { PasswordGenerationService } from 'jslib-common/abstractions/passwordGeneration.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service'; import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { PolicyService } from 'jslib-common/abstractions/policy.service'; import { PolicyService } from 'jslib-common/abstractions/policy.service';
@ -27,19 +28,19 @@ export class LoginCommand extends BaseLoginCommand {
i18nService: I18nService, environmentService: EnvironmentService, i18nService: I18nService, environmentService: EnvironmentService,
passwordGenerationService: PasswordGenerationService, platformUtilsService: PlatformUtilsService, passwordGenerationService: PasswordGenerationService, platformUtilsService: PlatformUtilsService,
userService: UserService, cryptoService: CryptoService, policyService: PolicyService, userService: UserService, cryptoService: CryptoService, policyService: PolicyService,
private logoutCallback: () => Promise<void>) { keyConnectorService: KeyConnectorService, private logoutCallback: () => Promise<void>) {
super(authService, apiService, i18nService, environmentService, passwordGenerationService, super(authService, apiService, i18nService, environmentService, passwordGenerationService,
cryptoFunctionService, platformUtilsService, userService, cryptoService, policyService, cryptoFunctionService, platformUtilsService, userService, cryptoService, policyService,
'cli', syncService); 'cli', syncService, keyConnectorService);
this.logout = this.logoutCallback; this.logout = this.logoutCallback;
this.validatedParams = async () => { this.validatedParams = async () => {
const key = await cryptoFunctionService.randomBytes(64); const key = await cryptoFunctionService.randomBytes(64);
process.env.BW_SESSION = Utils.fromBufferToB64(key); process.env.BW_SESSION = Utils.fromBufferToB64(key);
}; };
this.success = async () => { this.success = async () => {
await syncService.fullSync(true); const usesKeyConnector = await this.keyConnectorService.getUsesKeyConnector();
if ((this.options.sso != null || this.options.apikey != null) && this.canInteract) { if ((this.options.sso != null || this.options.apikey != null) && this.canInteract && !usesKeyConnector) {
const res = new MessageResponse('You are logged in!', '\n' + const res = new MessageResponse('You are logged in!', '\n' +
'To unlock your vault, use the `unlock` command. ex:\n' + 'To unlock your vault, use the `unlock` command. ex:\n' +
'$ bw unlock'); '$ bw unlock');

View File

@ -9,7 +9,7 @@ import { UserService } from 'jslib-common/abstractions/user.service';
import { Response } from 'jslib-node/cli/models/response'; import { Response } from 'jslib-node/cli/models/response';
import { MessageResponse } from 'jslib-node/cli/models/response/messageResponse'; import { MessageResponse } from 'jslib-node/cli/models/response/messageResponse';
import { PasswordVerificationRequest } from 'jslib-common/models/request/passwordVerificationRequest'; import { SecretVerificationRequest } from 'jslib-common/models/request/secretVerificationRequest';
import { Utils } from 'jslib-common/misc/utils'; import { Utils } from 'jslib-common/misc/utils';
@ -64,7 +64,7 @@ export class UnlockCommand {
passwordValid = await this.cryptoService.compareAndUpdateKeyHash(password, key); passwordValid = await this.cryptoService.compareAndUpdateKeyHash(password, key);
} else { } else {
const serverKeyHash = await this.cryptoService.hashPassword(password, key, HashPurpose.ServerAuthorization); const serverKeyHash = await this.cryptoService.hashPassword(password, key, HashPurpose.ServerAuthorization);
const request = new PasswordVerificationRequest(); const request = new SecretVerificationRequest();
request.masterPasswordHash = serverKeyHash; request.masterPasswordHash = serverKeyHash;
try { try {
await this.apiService.postAccountVerifyPassword(request); await this.apiService.postAccountVerifyPassword(request);

View File

@ -139,7 +139,7 @@ export class Program extends BaseProgram {
this.main.cryptoFunctionService, this.main.syncService, this.main.i18nService, this.main.cryptoFunctionService, this.main.syncService, this.main.i18nService,
this.main.environmentService, this.main.passwordGenerationService, this.main.environmentService, this.main.passwordGenerationService,
this.main.platformUtilsService, this.main.userService, this.main.cryptoService, this.main.platformUtilsService, this.main.userService, this.main.cryptoService,
this.main.policyService, async () => await this.main.logout()); this.main.policyService, this.main.keyConnectorService, async () => await this.main.logout());
const response = await command.run(email, password, options); const response = await command.run(email, password, options);
this.processResponse(response); this.processResponse(response);
} }
@ -173,6 +173,16 @@ export class Program extends BaseProgram {
}) })
.action(async cmd => { .action(async cmd => {
await this.exitIfNotAuthed(); await this.exitIfNotAuthed();
if (this.main.keyConnectorService.getUsesKeyConnector()) {
const logoutCommand = new LogoutCommand(this.main.authService, this.main.i18nService,
async () => await this.main.logout());
await logoutCommand.run();
this.processResponse(Response.error('You cannot lock your vault because you are using Key Connector. ' +
'To protect your vault, you have been logged out.'), true);
return;
}
const command = new LockCommand(this.main.vaultTimeoutService); const command = new LockCommand(this.main.vaultTimeoutService);
const response = await command.run(cmd); const response = await command.run(cmd);
this.processResponse(response); this.processResponse(response);
@ -301,6 +311,7 @@ export class Program extends BaseProgram {
.option('--icons <url>', 'Provides a custom icons service URL that differs from the base URL.') .option('--icons <url>', 'Provides a custom icons service URL that differs from the base URL.')
.option('--notifications <url>', 'Provides a custom notifications URL that differs from the base URL.') .option('--notifications <url>', 'Provides a custom notifications URL that differs from the base URL.')
.option('--events <url>', 'Provides a custom events URL that differs from the base URL.') .option('--events <url>', 'Provides a custom events URL that differs from the base URL.')
.option('--key-connector <url>', 'Provides the URL for your Key Connector server.')
.on('--help', () => { .on('--help', () => {
writeLn('\n Settings:'); writeLn('\n Settings:');
writeLn(''); writeLn('');