fix(mobile): passcode timing options (#1744)
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
}
|
||||
|
||||
@@ -2,3 +2,9 @@ export enum MobileUnlockTiming {
|
||||
Immediately = 'immediately',
|
||||
OnQuit = 'on-quit',
|
||||
}
|
||||
|
||||
export type TimingDisplayOption = {
|
||||
title: string
|
||||
key: MobileUnlockTiming
|
||||
selected: boolean
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user