import { Directive, OnDestroy, OnInit, TemplateRef, ViewContainerRef } from '@angular/core'; import { MsalBroadcastService, MsalService } from '@azure/msal-angular'; import { InteractionStatus } from '@azure/msal-browser'; import { filter, Subject, Subscription, takeUntil } from 'rxjs'; @Directive({ selector: '[authorized]' }) export class AuthorizedDirective implements OnInit, OnDestroy { private hasView: boolean = false; private readonly _destroying$ = new Subject<void>(); private broadcastSubscription!: Subscription; /** * Constructor * @param templateRef Referentie to the template that contains the HTML element that the directive is placed on * @param viewContainer The view container to which the templateRef will be added * @param authService Authentication service * @param broadcastService Broadcast service to listen for changes in the authentication state */ constructor( private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef, private authService: MsalService, private broadcastService: MsalBroadcastService ) { this.setDisplay(); } /** * Runs when directive is initialized */ public ngOnInit(): void { this.broadcastSubscription = this.broadcastService.inProgress$.pipe( filter((eventType: InteractionStatus) => eventType === InteractionStatus.None), takeUntil(this._destroying$) ).subscribe(() => { this.setDisplay(); }); } /** * Clearup any subscriptions */ public ngOnDestroy(): void { this._destroying$.next(undefined); this._destroying$.complete(); this.broadcastSubscription.unsubscribe(); } /** * Sets the display of the element based on the users authentication */ private setDisplay(): void { const account = this.authService.instance.getActiveAccount(); if (account && !this.hasView) { this.viewContainer.createEmbeddedView(this.templateRef); this.hasView = true; } else if (!account && this.hasView) { this.viewContainer.clear(); this.hasView = false; } } }