fix(mobile): passcode timing options (#1744)

This commit is contained in:
Mo
2022-10-05 10:08:54 -05:00
committed by GitHub
parent a4de9a05a9
commit 6c26b96cdc
14 changed files with 151 additions and 130 deletions

View File

@@ -45,7 +45,6 @@ import {
FileService,
SubscriptionClientInterface,
SubscriptionManager,
StorageValueModes,
} from '@standardnotes/services'
import { FilesClientInterface } from '@standardnotes/files'
import { ComputePrivateWorkspaceIdentifier } from '@standardnotes/encryption'
@@ -65,7 +64,6 @@ import { SNLog } from '../Log'
import { Challenge, ChallengeResponse } from '../Services'
import { ApplicationConstructorOptions, FullyResolvedApplicationOptions } from './Options/ApplicationOptions'
import { ApplicationOptionsDefaults } from './Options/Defaults'
import { MobileUnlockTiming } from '@Lib/Services/Protection/MobileUnlockTiming'
/** How often to automatically sync, in milliseconds */
const DEFAULT_AUTO_SYNC_INTERVAL = 30_000
@@ -899,24 +897,6 @@ export class SNApplication
return this.launched
}
public hasBiometrics(): boolean {
return this.protectionService.hasBiometricsEnabled()
}
/**
* @returns whether the operation was successful or not
*/
public enableBiometrics(): boolean {
return this.protectionService.enableBiometrics()
}
/**
* @returns whether the operation was successful or not
*/
public disableBiometrics(): Promise<boolean> {
return this.protectionService.disableBiometrics()
}
public hasPasscode(): boolean {
return this.protocolService.hasPasscode()
}
@@ -936,38 +916,6 @@ export class SNApplication
return this.deinit(this.getDeinitMode(), DeinitSource.Lock)
}
setBiometricsTiming(timing: MobileUnlockTiming) {
return this.protectionService.setBiometricsTiming(timing)
}
getMobileScreenshotPrivacyEnabled(): boolean {
return this.protectionService.getMobileScreenshotPrivacyEnabled()
}
setMobileScreenshotPrivacyEnabled(isEnabled: boolean) {
return this.protectionService.setMobileScreenshotPrivacyEnabled(isEnabled)
}
getMobilePasscodeTiming(): MobileUnlockTiming | undefined {
return this.getValue(StorageKey.MobilePasscodeTiming, StorageValueModes.Nonwrapped) as
| MobileUnlockTiming
| undefined
}
getMobileBiometricsTiming(): MobileUnlockTiming | undefined {
return this.getValue(StorageKey.MobileBiometricsTiming, StorageValueModes.Nonwrapped) as
| MobileUnlockTiming
| undefined
}
getBiometricsTimingOptions() {
return this.protectionService.getBiometricsTimingOptions()
}
getPasscodeTimingOptions() {
return this.protectionService.getPasscodeTimingOptions()
}
isNativeMobileWeb() {
return this.environment === Environment.NativeMobileWeb
}

View File

@@ -1,8 +1,19 @@
import { ChallengeReason } from '@standardnotes/services'
import { DecryptedItem } from '@standardnotes/models'
import { TimingDisplayOption, MobileUnlockTiming } from './MobileUnlockTiming'
export interface ProtectionsClientInterface {
authorizeProtectedActionForItems<T extends DecryptedItem>(files: T[], challengeReason: ChallengeReason): Promise<T[]>
authorizeItemAccess(item: DecryptedItem): Promise<boolean>
getMobileBiometricsTiming(): MobileUnlockTiming | undefined
getMobilePasscodeTiming(): MobileUnlockTiming | undefined
setMobileBiometricsTiming(timing: MobileUnlockTiming): void
setMobilePasscodeTiming(timing: MobileUnlockTiming): void
setMobileScreenshotPrivacyEnabled(isEnabled: boolean): void
getMobileScreenshotPrivacyEnabled(): boolean
getMobilePasscodeTimingOptions(): TimingDisplayOption[]
getMobileBiometricsTimingOptions(): TimingDisplayOption[]
hasBiometricsEnabled(): boolean
enableBiometrics(): boolean
disableBiometrics(): Promise<boolean>
}

View File

@@ -2,3 +2,9 @@ export enum MobileUnlockTiming {
Immediately = 'immediately',
OnQuit = 'on-quit',
}
export type TimingDisplayOption = {
title: string
key: MobileUnlockTiming
selected: boolean
}

View File

@@ -18,7 +18,7 @@ import {
} from '@standardnotes/services'
import { ProtectionsClientInterface } from './ClientInterface'
import { ContentType } from '@standardnotes/common'
import { MobileUnlockTiming } from './MobileUnlockTiming'
import { MobileUnlockTiming, TimingDisplayOption } from './MobileUnlockTiming'
export enum ProtectionEvent {
UnprotectedSessionBegan = 'UnprotectedSessionBegan',
@@ -64,8 +64,8 @@ export const ProtectionSessionDurations = [
*/
export class SNProtectionService extends AbstractService<ProtectionEvent> implements ProtectionsClientInterface {
private sessionExpiryTimeout = -1
private mobilePasscodeTiming: MobileUnlockTiming | undefined = MobileUnlockTiming.Immediately
private mobileBiometricsTiming: MobileUnlockTiming | undefined = MobileUnlockTiming.Immediately
private mobilePasscodeTiming: MobileUnlockTiming | undefined = MobileUnlockTiming.OnQuit
private mobileBiometricsTiming: MobileUnlockTiming | undefined = MobileUnlockTiming.OnQuit
constructor(
private protocolService: EncryptionService,
@@ -87,8 +87,8 @@ export class SNProtectionService extends AbstractService<ProtectionEvent> implem
override handleApplicationStage(stage: ApplicationStage): Promise<void> {
if (stage === ApplicationStage.LoadedDatabase_12) {
this.updateSessionExpiryTimer(this.getSessionExpiryDate())
this.mobilePasscodeTiming = this.getPasscodeTiming()
this.mobileBiometricsTiming = this.getBiometricsTiming()
this.mobilePasscodeTiming = this.getMobilePasscodeTiming()
this.mobileBiometricsTiming = this.getMobileBiometricsTiming()
}
return Promise.resolve()
}
@@ -229,7 +229,7 @@ export class SNProtectionService extends AbstractService<ProtectionEvent> implem
})
}
getPasscodeTimingOptions() {
getMobilePasscodeTimingOptions(): TimingDisplayOption[] {
return [
{
title: 'Immediately',
@@ -244,7 +244,7 @@ export class SNProtectionService extends AbstractService<ProtectionEvent> implem
]
}
getBiometricsTimingOptions() {
getMobileBiometricsTimingOptions(): TimingDisplayOption[] {
return [
{
title: 'Immediately',
@@ -259,25 +259,32 @@ export class SNProtectionService extends AbstractService<ProtectionEvent> implem
]
}
private getBiometricsTiming(): MobileUnlockTiming | undefined {
getMobileBiometricsTiming(): MobileUnlockTiming | undefined {
return this.storageService.getValue<MobileUnlockTiming | undefined>(
StorageKey.MobileBiometricsTiming,
StorageValueModes.Nonwrapped,
MobileUnlockTiming.OnQuit,
)
}
private getPasscodeTiming(): MobileUnlockTiming | undefined {
getMobilePasscodeTiming(): MobileUnlockTiming | undefined {
return this.storageService.getValue<MobileUnlockTiming | undefined>(
StorageKey.MobilePasscodeTiming,
StorageValueModes.Nonwrapped,
MobileUnlockTiming.OnQuit,
)
}
async setBiometricsTiming(timing: MobileUnlockTiming) {
setMobileBiometricsTiming(timing: MobileUnlockTiming): void {
this.storageService.setValue(StorageKey.MobileBiometricsTiming, timing, StorageValueModes.Nonwrapped)
this.mobileBiometricsTiming = timing
}
setMobilePasscodeTiming(timing: MobileUnlockTiming): void {
this.storageService.setValue(StorageKey.MobilePasscodeTiming, timing, StorageValueModes.Nonwrapped)
this.mobilePasscodeTiming = timing
}
setMobileScreenshotPrivacyEnabled(isEnabled: boolean) {
return this.storageService.setValue(StorageKey.MobileScreenshotPrivacyEnabled, isEnabled, StorageValueModes.Default)
}

View File

@@ -62,7 +62,7 @@ describe('device authentication', function () {
const passcode = 'foobar'
const wrongPasscode = 'barfoo'
await application.addPasscode(passcode)
await application.protectionService.enableBiometrics()
await application.protections.enableBiometrics()
expect(await application.hasPasscode()).to.equal(true)
expect((await application.protectionService.createLaunchChallenge()).prompts.length).to.equal(2)
expect(application.protocolService.rootKeyEncryption.keyMode).to.equal(KeyMode.WrapperOnly)

View File

@@ -311,7 +311,7 @@ describe('protections', function () {
it('no account, no passcode, biometrics', async function () {
application = await Factory.createInitAppWithFakeCrypto()
await application.enableBiometrics()
await application.protections.enableBiometrics()
expect(application.hasProtectionSources()).to.be.true
})
@@ -324,7 +324,7 @@ describe('protections', function () {
it('no account, passcode, biometrics', async function () {
application = await Factory.createInitAppWithFakeCrypto()
await application.addPasscode('passcode')
await application.enableBiometrics()
await application.protections.enableBiometrics()
expect(application.hasProtectionSources()).to.be.true
})
@@ -345,7 +345,7 @@ describe('protections', function () {
email: UuidGenerator.GenerateUuid(),
password: UuidGenerator.GenerateUuid(),
})
await application.enableBiometrics()
await application.protections.enableBiometrics()
expect(application.hasProtectionSources()).to.be.true
})
@@ -372,7 +372,7 @@ describe('protections', function () {
})
Factory.handlePasswordChallenges(application, password)
await application.addPasscode('passcode')
await application.enableBiometrics()
await application.protections.enableBiometrics()
expect(application.hasProtectionSources()).to.be.true
})
})