From 2edf3fb68d7d37126551669faf1a2c87e5f79da8 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Wed, 20 Mar 2019 17:33:11 -0400 Subject: [PATCH] data-file and last-sync commands --- src/bwdc.ts | 18 +++++++------- src/commands/lastSync.command.ts | 29 ++++++++++++++++++++++ src/program.ts | 42 ++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 src/commands/lastSync.command.ts diff --git a/src/bwdc.ts b/src/bwdc.ts index 7dd34327..27fe3bf3 100644 --- a/src/bwdc.ts +++ b/src/bwdc.ts @@ -31,6 +31,7 @@ import { Program } from './program'; const packageJson = require('./package.json'); export class Main { + dataFilePath: string; logService: ConsoleLogService; messagingService: NoopMessagingService; storageService: LowdbStorageService; @@ -53,21 +54,20 @@ export class Main { constructor() { const applicationName = 'Bitwarden Directory Connector'; - let p = null; if (process.env.BITWARDENCLI_CONNECTOR_APPDATA_DIR) { - p = path.resolve(process.env.BITWARDENCLI_CONNECTOR_APPDATA_DIR); + this.dataFilePath = path.resolve(process.env.BITWARDENCLI_CONNECTOR_APPDATA_DIR); } else if (process.env.BITWARDEN_CONNECTOR_APPDATA_DIR) { - p = path.resolve(process.env.BITWARDEN_CONNECTOR_APPDATA_DIR); + this.dataFilePath = path.resolve(process.env.BITWARDEN_CONNECTOR_APPDATA_DIR); } else if (fs.existsSync(path.join(__dirname, 'bitwarden-connector-appdata'))) { - p = path.join(__dirname, 'bitwarden-connector-appdata'); + this.dataFilePath = path.join(__dirname, 'bitwarden-connector-appdata'); } else if (process.platform === 'darwin') { - p = path.join(process.env.HOME, 'Library/Application Support/' + applicationName); + this.dataFilePath = path.join(process.env.HOME, 'Library/Application Support/' + applicationName); } else if (process.platform === 'win32') { - p = path.join(process.env.APPDATA, applicationName); + this.dataFilePath = path.join(process.env.APPDATA, applicationName); } else if (process.env.XDG_CONFIG_HOME) { - p = path.join(process.env.XDG_CONFIG_HOME, applicationName); + this.dataFilePath = path.join(process.env.XDG_CONFIG_HOME, applicationName); } else { - p = path.join(process.env.HOME, '.config/' + applicationName); + this.dataFilePath = path.join(process.env.HOME, '.config/' + applicationName); } this.i18nService = new I18nService('en', './locales'); @@ -75,7 +75,7 @@ export class Main { this.logService = new ConsoleLogService(this.platformUtilsService.isDev(), (level) => process.env.BWCLI_DEBUG !== 'true' && level <= LogLevelType.Info); this.cryptoFunctionService = new NodeCryptoFunctionService(); - this.storageService = new LowdbStorageService(null, p, true); + this.storageService = new LowdbStorageService(null, this.dataFilePath, true); this.secureStorageService = new KeytarSecureStorageService(applicationName); this.cryptoService = new CryptoService(this.storageService, this.secureStorageService, this.cryptoFunctionService); diff --git a/src/commands/lastSync.command.ts b/src/commands/lastSync.command.ts new file mode 100644 index 00000000..d04312f1 --- /dev/null +++ b/src/commands/lastSync.command.ts @@ -0,0 +1,29 @@ +import * as program from 'commander'; + +import { ConfigurationService } from '../services/configuration.service'; + +import { Response } from 'jslib/cli/models/response'; +import { StringResponse } from 'jslib/cli/models/response/stringResponse'; + +export class LastSyncCommand { + constructor(private configurationService: ConfigurationService) { } + + async run(object: string, cmd: program.Command): Promise { + try { + switch (object.toLowerCase()) { + case 'groups': + const groupsDate = await this.configurationService.getLastGroupSyncDate(); + const groupsRes = new StringResponse(groupsDate == null ? null : groupsDate.toISOString()); + return Response.success(groupsRes); + case 'users': + const usersDate = await this.configurationService.getLastUserSyncDate(); + const usersRes = new StringResponse(usersDate == null ? null : usersDate.toISOString()); + return Response.success(usersRes); + default: + return Response.badRequest('Unknown object.'); + } + } catch (e) { + return Response.error(e); + } + } +} diff --git a/src/program.ts b/src/program.ts index 9869d672..a405c9a1 100644 --- a/src/program.ts +++ b/src/program.ts @@ -1,10 +1,12 @@ import * as chk from 'chalk'; import * as program from 'commander'; +import * as path from 'path'; import { Main } from './bwdc'; import { ClearCacheCommand } from './commands/clearCache.command'; import { ConfigCommand } from './commands/config.command'; +import { LastSyncCommand } from './commands/lastSync.command'; import { SyncCommand } from './commands/sync.command'; import { TestCommand } from './commands/test.command'; @@ -14,6 +16,9 @@ import { UpdateCommand } from 'jslib/cli/commands/update.command'; import { BaseProgram } from 'jslib/cli/baseProgram'; +import { Response } from 'jslib/cli/models/response'; +import { StringResponse } from 'jslib/cli/models/response/stringResponse'; + const chalk = chk.default; const writeLn = (s: string, finalLine: boolean = false) => { if (finalLine && process.platform === 'win32') { @@ -61,8 +66,10 @@ export class Program extends BaseProgram { program.on('--help', () => { writeLn('\n Examples:'); writeLn(''); + writeLn(' bwdc login'); writeLn(' bwdc test'); writeLn(' bwdc sync'); + writeLn(' bwdc last-sync'); writeLn(' bwdc config server https://bw.company.com'); writeLn(' bwdc update'); writeLn('', true); @@ -143,6 +150,27 @@ export class Program extends BaseProgram { this.processResponse(response); }); + program + .command('last-sync ') + .description('Get the last successful sync date.') + .on('--help', () => { + writeLn('\n Notes:'); + writeLn(''); + writeLn(' Returns empty response if no sync has been performed for the given object.'); + writeLn(''); + writeLn(' Examples:'); + writeLn(''); + writeLn(' bwdc last-sync groups'); + writeLn(' bwdc last-sync users'); + writeLn('', true); + }) + .action(async (object: string, cmd: program.Command) => { + await this.exitIfNotAuthed(); + const command = new LastSyncCommand(this.main.configurationService); + const response = await command.run(object, cmd); + this.processResponse(response); + }); + program .command('config ') .description('Configure settings.') @@ -174,6 +202,20 @@ export class Program extends BaseProgram { this.processResponse(response); }); + program + .command('data-file') + .description('Path to data.json database file.') + .on('--help', () => { + writeLn('\n Examples:'); + writeLn(''); + writeLn(' bwdc data-file'); + writeLn('', true); + }) + .action(() => { + this.processResponse( + Response.success(new StringResponse(path.join(this.main.dataFilePath, 'data.json')))); + }); + program .command('clear-cache') .description('Clear the sync cache.')