import { map, Observable } from "rxjs"; import { PolicyService } from "../../admin-console/abstractions/policy/policy.service.abstraction"; import { PolicyType } from "../../admin-console/enums"; import { AUTOFILL_SETTINGS_DISK, AUTOFILL_SETTINGS_DISK_LOCAL, ActiveUserState, GlobalState, KeyDefinition, StateProvider, UserKeyDefinition, } from "../../platform/state"; import { ClearClipboardDelay, AutofillOverlayVisibility } from "../constants"; import { ClearClipboardDelaySetting, InlineMenuVisibilitySetting } from "../types"; const AUTOFILL_ON_PAGE_LOAD = new UserKeyDefinition(AUTOFILL_SETTINGS_DISK, "autofillOnPageLoad", { deserializer: (value: boolean) => value ?? false, clearOn: [], }); const AUTOFILL_ON_PAGE_LOAD_DEFAULT = new UserKeyDefinition( AUTOFILL_SETTINGS_DISK, "autofillOnPageLoadDefault", { deserializer: (value: boolean) => value ?? false, clearOn: [], }, ); const AUTOFILL_ON_PAGE_LOAD_CALLOUT_DISMISSED = new UserKeyDefinition( AUTOFILL_SETTINGS_DISK, "autofillOnPageLoadCalloutIsDismissed", { deserializer: (value: boolean) => value ?? false, clearOn: [], }, ); const AUTOFILL_ON_PAGE_LOAD_POLICY_TOAST_HAS_DISPLAYED = new UserKeyDefinition( AUTOFILL_SETTINGS_DISK, "autofillOnPageLoadPolicyToastHasDisplayed", { deserializer: (value: boolean) => value ?? false, clearOn: [], }, ); const AUTO_COPY_TOTP = new UserKeyDefinition(AUTOFILL_SETTINGS_DISK, "autoCopyTotp", { deserializer: (value: boolean) => value ?? true, clearOn: [], }); const INLINE_MENU_VISIBILITY = new KeyDefinition( AUTOFILL_SETTINGS_DISK_LOCAL, "inlineMenuVisibility", { deserializer: (value: InlineMenuVisibilitySetting) => value ?? AutofillOverlayVisibility.Off, }, ); const SHOW_INLINE_MENU_IDENTITIES = new UserKeyDefinition( AUTOFILL_SETTINGS_DISK, "showInlineMenuIdentities", { deserializer: (value: boolean) => value ?? true, clearOn: [], }, ); const SHOW_INLINE_MENU_CARDS = new UserKeyDefinition( AUTOFILL_SETTINGS_DISK, "showInlineMenuCards", { deserializer: (value: boolean) => value ?? true, clearOn: [], }, ); const ENABLE_CONTEXT_MENU = new KeyDefinition(AUTOFILL_SETTINGS_DISK, "enableContextMenu", { deserializer: (value: boolean) => value ?? true, }); const CLEAR_CLIPBOARD_DELAY = new UserKeyDefinition( AUTOFILL_SETTINGS_DISK_LOCAL, "clearClipboardDelay", { deserializer: (value: ClearClipboardDelaySetting) => value ?? ClearClipboardDelay.Never, clearOn: [], }, ); export abstract class AutofillSettingsServiceAbstraction { autofillOnPageLoad$: Observable; setAutofillOnPageLoad: (newValue: boolean) => Promise; autofillOnPageLoadDefault$: Observable; setAutofillOnPageLoadDefault: (newValue: boolean) => Promise; autofillOnPageLoadCalloutIsDismissed$: Observable; setAutofillOnPageLoadCalloutIsDismissed: (newValue: boolean) => Promise; activateAutofillOnPageLoadFromPolicy$: Observable; setAutofillOnPageLoadPolicyToastHasDisplayed: (newValue: boolean) => Promise; autofillOnPageLoadPolicyToastHasDisplayed$: Observable; autoCopyTotp$: Observable; setAutoCopyTotp: (newValue: boolean) => Promise; inlineMenuVisibility$: Observable; setInlineMenuVisibility: (newValue: InlineMenuVisibilitySetting) => Promise; showInlineMenuIdentities$: Observable; setShowInlineMenuIdentities: (newValue: boolean) => Promise; showInlineMenuCards$: Observable; setShowInlineMenuCards: (newValue: boolean) => Promise; enableContextMenu$: Observable; setEnableContextMenu: (newValue: boolean) => Promise; clearClipboardDelay$: Observable; setClearClipboardDelay: (newValue: ClearClipboardDelaySetting) => Promise; } export class AutofillSettingsService implements AutofillSettingsServiceAbstraction { private autofillOnPageLoadState: ActiveUserState; readonly autofillOnPageLoad$: Observable; private autofillOnPageLoadDefaultState: ActiveUserState; readonly autofillOnPageLoadDefault$: Observable; private autofillOnPageLoadCalloutIsDismissedState: ActiveUserState; readonly autofillOnPageLoadCalloutIsDismissed$: Observable; readonly activateAutofillOnPageLoadFromPolicy$: Observable; private autofillOnPageLoadPolicyToastHasDisplayedState: ActiveUserState; readonly autofillOnPageLoadPolicyToastHasDisplayed$: Observable; private autoCopyTotpState: ActiveUserState; readonly autoCopyTotp$: Observable; private inlineMenuVisibilityState: GlobalState; readonly inlineMenuVisibility$: Observable; private showInlineMenuIdentitiesState: ActiveUserState; readonly showInlineMenuIdentities$: Observable; private showInlineMenuCardsState: ActiveUserState; readonly showInlineMenuCards$: Observable; private enableContextMenuState: GlobalState; readonly enableContextMenu$: Observable; private clearClipboardDelayState: ActiveUserState; readonly clearClipboardDelay$: Observable; constructor( private stateProvider: StateProvider, private policyService: PolicyService, ) { this.autofillOnPageLoadState = this.stateProvider.getActive(AUTOFILL_ON_PAGE_LOAD); this.autofillOnPageLoad$ = this.autofillOnPageLoadState.state$.pipe(map((x) => x ?? false)); this.autofillOnPageLoadDefaultState = this.stateProvider.getActive( AUTOFILL_ON_PAGE_LOAD_DEFAULT, ); this.autofillOnPageLoadDefault$ = this.autofillOnPageLoadDefaultState.state$.pipe( map((x) => x ?? true), ); this.autofillOnPageLoadCalloutIsDismissedState = this.stateProvider.getActive( AUTOFILL_ON_PAGE_LOAD_CALLOUT_DISMISSED, ); this.autofillOnPageLoadCalloutIsDismissed$ = this.autofillOnPageLoadCalloutIsDismissedState.state$.pipe(map((x) => x ?? false)); this.activateAutofillOnPageLoadFromPolicy$ = this.policyService.policyAppliesToActiveUser$( PolicyType.ActivateAutofill, ); this.autofillOnPageLoadPolicyToastHasDisplayedState = this.stateProvider.getActive( AUTOFILL_ON_PAGE_LOAD_POLICY_TOAST_HAS_DISPLAYED, ); this.autofillOnPageLoadPolicyToastHasDisplayed$ = this.autofillOnPageLoadPolicyToastHasDisplayedState.state$.pipe(map((x) => x ?? false)); this.autoCopyTotpState = this.stateProvider.getActive(AUTO_COPY_TOTP); this.autoCopyTotp$ = this.autoCopyTotpState.state$.pipe(map((x) => x ?? true)); this.inlineMenuVisibilityState = this.stateProvider.getGlobal(INLINE_MENU_VISIBILITY); this.inlineMenuVisibility$ = this.inlineMenuVisibilityState.state$.pipe( map((x) => x ?? AutofillOverlayVisibility.Off), ); this.showInlineMenuIdentitiesState = this.stateProvider.getActive(SHOW_INLINE_MENU_IDENTITIES); this.showInlineMenuIdentities$ = this.showInlineMenuIdentitiesState.state$.pipe( map((x) => x ?? true), ); this.showInlineMenuCardsState = this.stateProvider.getActive(SHOW_INLINE_MENU_CARDS); this.showInlineMenuCards$ = this.showInlineMenuCardsState.state$.pipe(map((x) => x ?? true)); this.enableContextMenuState = this.stateProvider.getGlobal(ENABLE_CONTEXT_MENU); this.enableContextMenu$ = this.enableContextMenuState.state$.pipe(map((x) => x ?? true)); this.clearClipboardDelayState = this.stateProvider.getActive(CLEAR_CLIPBOARD_DELAY); this.clearClipboardDelay$ = this.clearClipboardDelayState.state$.pipe( map((x) => x ?? ClearClipboardDelay.Never), ); } async setAutofillOnPageLoad(newValue: boolean): Promise { await this.autofillOnPageLoadState.update(() => newValue); } async setAutofillOnPageLoadDefault(newValue: boolean): Promise { await this.autofillOnPageLoadDefaultState.update(() => newValue); } async setAutofillOnPageLoadCalloutIsDismissed(newValue: boolean): Promise { await this.autofillOnPageLoadCalloutIsDismissedState.update(() => newValue); } async setAutofillOnPageLoadPolicyToastHasDisplayed(newValue: boolean): Promise { await this.autofillOnPageLoadPolicyToastHasDisplayedState.update(() => newValue); } async setAutoCopyTotp(newValue: boolean): Promise { await this.autoCopyTotpState.update(() => newValue); } async setInlineMenuVisibility(newValue: InlineMenuVisibilitySetting): Promise { await this.inlineMenuVisibilityState.update(() => newValue); } async setShowInlineMenuIdentities(newValue: boolean): Promise { await this.showInlineMenuIdentitiesState.update(() => newValue); } async setShowInlineMenuCards(newValue: boolean): Promise { await this.showInlineMenuCardsState.update(() => newValue); } async setEnableContextMenu(newValue: boolean): Promise { await this.enableContextMenuState.update(() => newValue); } async setClearClipboardDelay(newValue: ClearClipboardDelaySetting): Promise { await this.clearClipboardDelayState.update(() => newValue); } }