mirror of
https://github.com/bitwarden/directory-connector
synced 2025-12-15 07:43:27 +00:00
stop and start syncing
This commit is contained in:
@@ -33,6 +33,9 @@ import { UserService } from 'jslib/abstractions/user.service';
|
|||||||
|
|
||||||
import { ConstantsService } from 'jslib/services/constants.service';
|
import { ConstantsService } from 'jslib/services/constants.service';
|
||||||
|
|
||||||
|
import { ConfigurationService } from '../services/configuration.service';
|
||||||
|
import { SyncService } from '../services/sync.service';
|
||||||
|
|
||||||
const BroadcasterSubscriptionId = 'AppComponent';
|
const BroadcasterSubscriptionId = 'AppComponent';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -62,7 +65,8 @@ export class AppComponent implements OnInit {
|
|||||||
private authService: AuthService, private router: Router, private analytics: Angulartics2,
|
private authService: AuthService, private router: Router, private analytics: Angulartics2,
|
||||||
private toasterService: ToasterService, private i18nService: I18nService,
|
private toasterService: ToasterService, private i18nService: I18nService,
|
||||||
private platformUtilsService: PlatformUtilsService, private ngZone: NgZone,
|
private platformUtilsService: PlatformUtilsService, private ngZone: NgZone,
|
||||||
private componentFactoryResolver: ComponentFactoryResolver, private messagingService: MessagingService) { }
|
private componentFactoryResolver: ComponentFactoryResolver, private messagingService: MessagingService,
|
||||||
|
private configurationService: ConfigurationService, private syncService: SyncService) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {
|
this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {
|
||||||
@@ -71,6 +75,41 @@ export class AppComponent implements OnInit {
|
|||||||
case 'logout':
|
case 'logout':
|
||||||
this.logOut(!!message.expired);
|
this.logOut(!!message.expired);
|
||||||
break;
|
break;
|
||||||
|
case 'checkDirSync':
|
||||||
|
try {
|
||||||
|
const syncConfig = await this.configurationService.getSync();
|
||||||
|
if (syncConfig.interval == null || syncConfig.interval < 5) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const syncInterval = syncConfig.interval * 60000;
|
||||||
|
const lastGroupSync = await this.configurationService.getLastGroupSyncDate();
|
||||||
|
const lastUserSync = await this.configurationService.getLastUserSyncDate();
|
||||||
|
let lastSync: Date = null;
|
||||||
|
if (lastGroupSync != null && lastUserSync == null) {
|
||||||
|
lastSync = lastGroupSync;
|
||||||
|
} else if (lastGroupSync == null && lastUserSync != null) {
|
||||||
|
lastSync = lastUserSync;
|
||||||
|
} else if (lastGroupSync != null && lastUserSync != null) {
|
||||||
|
if (lastGroupSync.getTime() < lastUserSync.getTime()) {
|
||||||
|
lastSync = lastGroupSync;
|
||||||
|
} else {
|
||||||
|
lastSync = lastUserSync;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastSyncAgo = syncInterval + 1;
|
||||||
|
if (lastSync != null) {
|
||||||
|
lastSyncAgo = new Date().getTime() - lastSync.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastSyncAgo >= syncInterval) {
|
||||||
|
await this.syncService.sync(false, false);
|
||||||
|
}
|
||||||
|
} catch { }
|
||||||
|
|
||||||
|
this.messagingService.send('scheduleNextDirSync');
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -71,7 +71,8 @@ const containerService = new ContainerService(cryptoService, platformUtilsServic
|
|||||||
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, false);
|
||||||
const configurationService = new ConfigurationService(storageService, secureStorageService);
|
const configurationService = new ConfigurationService(storageService, secureStorageService);
|
||||||
const syncSevrice = new SyncService(configurationService, logService, cryptoFunctionService, apiService);
|
const syncSevrice = new SyncService(configurationService, logService, cryptoFunctionService, apiService,
|
||||||
|
messagingService);
|
||||||
|
|
||||||
const analytics = new Analytics(window, () => true, platformUtilsService, storageService, appIdService);
|
const analytics = new Analytics(window, () => true, platformUtilsService, storageService, appIdService);
|
||||||
containerService.attachToWindow(window);
|
containerService.attachToWindow(window);
|
||||||
|
|||||||
@@ -14,8 +14,9 @@
|
|||||||
<strong *ngIf="syncRunning" class="text-success">Running</strong>
|
<strong *ngIf="syncRunning" class="text-success">Running</strong>
|
||||||
<strong *ngIf="!syncRunning" class="text-danger">Stopped</strong>
|
<strong *ngIf="!syncRunning" class="text-danger">Stopped</strong>
|
||||||
</p>
|
</p>
|
||||||
<button (click)="start()" class="btn btn-primary">
|
<button #startBtn (click)="start()" [appApiAction]="startPromise" class="btn btn-primary" [disabled]="startBtn.loading">
|
||||||
<i class="fa fa-play fa-fw"></i>
|
<i class="fa fa-play fa-fw" [hidden]="startBtn.loading"></i>
|
||||||
|
<i class="fa fa-spinner fa-fw fa-spin" [hidden]="!startBtn.loading"></i>
|
||||||
Start Sync
|
Start Sync
|
||||||
</button>
|
</button>
|
||||||
<button (click)="stop()" class="btn btn-primary">
|
<button (click)="stop()" class="btn btn-primary">
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
|
NgZone,
|
||||||
OnInit,
|
OnInit,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
|
||||||
|
import { ToasterService } from 'angular2-toaster';
|
||||||
|
|
||||||
import { I18nService } from 'jslib/abstractions/i18n.service';
|
import { I18nService } from 'jslib/abstractions/i18n.service';
|
||||||
|
import { MessagingService } from 'jslib/abstractions/messaging.service';
|
||||||
|
|
||||||
import { AzureDirectoryService } from '../../services/azure-directory.service';
|
import { AzureDirectoryService } from '../../services/azure-directory.service';
|
||||||
import { GSuiteDirectoryService } from '../../services/gsuite-directory.service';
|
import { GSuiteDirectoryService } from '../../services/gsuite-directory.service';
|
||||||
@@ -15,6 +19,10 @@ import { GroupEntry } from '../../models/groupEntry';
|
|||||||
import { UserEntry } from '../../models/userEntry';
|
import { UserEntry } from '../../models/userEntry';
|
||||||
import { ConfigurationService } from '../../services/configuration.service';
|
import { ConfigurationService } from '../../services/configuration.service';
|
||||||
|
|
||||||
|
import { BroadcasterService } from 'jslib/angular/services/broadcaster.service';
|
||||||
|
|
||||||
|
const BroadcasterSubscriptionId = 'DashboardComponent';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-dashboard',
|
selector: 'app-dashboard',
|
||||||
templateUrl: 'dashboard.component.html',
|
templateUrl: 'dashboard.component.html',
|
||||||
@@ -28,24 +36,43 @@ export class DashboardComponent implements OnInit {
|
|||||||
simPromise: Promise<any>;
|
simPromise: Promise<any>;
|
||||||
simSinceLast: boolean = false;
|
simSinceLast: boolean = false;
|
||||||
syncPromise: Promise<any>;
|
syncPromise: Promise<any>;
|
||||||
|
startPromise: Promise<any>;
|
||||||
lastGroupSync: Date;
|
lastGroupSync: Date;
|
||||||
lastUserSync: Date;
|
lastUserSync: Date;
|
||||||
syncRunning: boolean;
|
syncRunning: boolean;
|
||||||
|
|
||||||
constructor(private i18nService: I18nService, private syncService: SyncService,
|
constructor(private i18nService: I18nService, private syncService: SyncService,
|
||||||
private configurationService: ConfigurationService) { }
|
private configurationService: ConfigurationService, private broadcasterService: BroadcasterService,
|
||||||
|
private ngZone: NgZone, private messagingService: MessagingService,
|
||||||
|
private toasterService: ToasterService) { }
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.lastGroupSync = await this.configurationService.getLastGroupSyncDate();
|
this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {
|
||||||
this.lastUserSync = await this.configurationService.getLastUserSyncDate();
|
this.ngZone.run(async () => {
|
||||||
|
switch (message.command) {
|
||||||
|
case 'dirSyncCompleted':
|
||||||
|
this.updateLastSync();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.updateLastSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
async start() {
|
async start() {
|
||||||
|
this.startPromise = this.syncService.sync(false, false);
|
||||||
|
await this.startPromise;
|
||||||
|
this.messagingService.send('scheduleNextDirSync');
|
||||||
this.syncRunning = true;
|
this.syncRunning = true;
|
||||||
|
this.toasterService.popAsync('success', null, 'Syncing started.');
|
||||||
}
|
}
|
||||||
|
|
||||||
async stop() {
|
async stop() {
|
||||||
|
this.messagingService.send('cancelDirSync');
|
||||||
this.syncRunning = false;
|
this.syncRunning = false;
|
||||||
|
this.toasterService.popAsync('success', null, 'Syncing stopped.');
|
||||||
}
|
}
|
||||||
|
|
||||||
async sync() {
|
async sync() {
|
||||||
@@ -115,4 +142,9 @@ export class DashboardComponent implements OnInit {
|
|||||||
a.displayName.localeCompare(b.displayName);
|
a.displayName.localeCompare(b.displayName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async updateLastSync() {
|
||||||
|
this.lastGroupSync = await this.configurationService.getLastGroupSyncDate();
|
||||||
|
this.lastUserSync = await this.configurationService.getLastUserSyncDate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { WindowMain } from 'jslib/electron/window.main';
|
|||||||
|
|
||||||
import { MenuMain } from './menu.main';
|
import { MenuMain } from './menu.main';
|
||||||
|
|
||||||
const SyncInterval = 5 * 60 * 1000; // 5 minutes
|
const SyncCheckInterval = 60 * 1000; // 1 minute
|
||||||
|
|
||||||
export class MessagingMain {
|
export class MessagingMain {
|
||||||
private syncTimeout: NodeJS.Timer;
|
private syncTimeout: NodeJS.Timer;
|
||||||
@@ -21,9 +21,14 @@ export class MessagingMain {
|
|||||||
|
|
||||||
onMessage(message: any) {
|
onMessage(message: any) {
|
||||||
switch (message.command) {
|
switch (message.command) {
|
||||||
case 'scheduleNextSync':
|
case 'scheduleNextDirSync':
|
||||||
this.scheduleNextSync();
|
this.scheduleNextSync();
|
||||||
break;
|
break;
|
||||||
|
case 'cancelDirSync':
|
||||||
|
if (this.syncTimeout) {
|
||||||
|
global.clearTimeout(this.syncTimeout);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -40,8 +45,8 @@ export class MessagingMain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.windowMain.win.webContents.send('messagingService', {
|
this.windowMain.win.webContents.send('messagingService', {
|
||||||
command: 'checkSyncVault',
|
command: 'checkDirSync',
|
||||||
});
|
});
|
||||||
}, SyncInterval);
|
}, SyncCheckInterval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { ImportDirectoryRequestUser } from 'jslib/models/request/importDirectory
|
|||||||
import { ApiService } from 'jslib/abstractions/api.service';
|
import { ApiService } from 'jslib/abstractions/api.service';
|
||||||
import { CryptoFunctionService } from 'jslib/abstractions/cryptoFunction.service';
|
import { CryptoFunctionService } from 'jslib/abstractions/cryptoFunction.service';
|
||||||
import { LogService } from 'jslib/abstractions/log.service';
|
import { LogService } from 'jslib/abstractions/log.service';
|
||||||
|
import { MessagingService } from 'jslib/abstractions/messaging.service';
|
||||||
import { StorageService } from 'jslib/abstractions/storage.service';
|
import { StorageService } from 'jslib/abstractions/storage.service';
|
||||||
|
|
||||||
import { Utils } from 'jslib/misc/utils';
|
import { Utils } from 'jslib/misc/utils';
|
||||||
@@ -28,7 +29,8 @@ export class SyncService {
|
|||||||
private dirType: DirectoryType;
|
private dirType: DirectoryType;
|
||||||
|
|
||||||
constructor(private configurationService: ConfigurationService, private logService: LogService,
|
constructor(private configurationService: ConfigurationService, private logService: LogService,
|
||||||
private cryptoFunctionService: CryptoFunctionService, private apiService: ApiService) { }
|
private cryptoFunctionService: CryptoFunctionService, private apiService: ApiService,
|
||||||
|
private messagingService: MessagingService) { }
|
||||||
|
|
||||||
async sync(force: boolean, test: boolean): Promise<[GroupEntry[], UserEntry[]]> {
|
async sync(force: boolean, test: boolean): Promise<[GroupEntry[], UserEntry[]]> {
|
||||||
this.dirType = await this.configurationService.getDirectoryType();
|
this.dirType = await this.configurationService.getDirectoryType();
|
||||||
@@ -46,6 +48,7 @@ export class SyncService {
|
|||||||
const startingUserDelta = await this.configurationService.getUserDeltaToken();
|
const startingUserDelta = await this.configurationService.getUserDeltaToken();
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
|
||||||
|
this.messagingService.send('dirSyncStarted');
|
||||||
try {
|
try {
|
||||||
const entries = await directoryService.getEntries(force, test);
|
const entries = await directoryService.getEntries(force, test);
|
||||||
const groups = entries[0];
|
const groups = entries[0];
|
||||||
@@ -56,6 +59,7 @@ export class SyncService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (test || groups == null || groups.length === 0 || users == null || users.length === 0) {
|
if (test || groups == null || groups.length === 0 || users == null || users.length === 0) {
|
||||||
|
this.messagingService.send('dirSyncCompleted', { successfully: true });
|
||||||
return [groups, users];
|
return [groups, users];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,12 +89,15 @@ export class SyncService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.messagingService.send('dirSyncCompleted', { successfully: true });
|
||||||
return [groups, users];
|
return [groups, users];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!test) {
|
if (!test) {
|
||||||
await this.configurationService.saveGroupDeltaToken(startingGroupDelta);
|
await this.configurationService.saveGroupDeltaToken(startingGroupDelta);
|
||||||
await this.configurationService.saveUserDeltaToken(startingUserDelta);
|
await this.configurationService.saveUserDeltaToken(startingUserDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.messagingService.send('dirSyncCompleted', { successfully: false });
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user