1
0
mirror of https://github.com/bitwarden/mobile.git synced 2024-12-28 17:18:23 +01:00

PM-1748 Fix watchOS issue where the TOTP code wasn't being regenerated after always on display. Also, blurred totp code and timer value when entering in Always On Display

This commit is contained in:
Federico Maccaroni 2023-05-08 21:32:01 +02:00
parent 6bb654e630
commit 9bbff141ac
3 changed files with 23 additions and 11 deletions

View File

@ -2,7 +2,7 @@ import Foundation
struct CipherMock { struct CipherMock {
static let ciphers:[Cipher] = [ static let ciphers:[Cipher] = [
Cipher(id: "0", name: "1933", userId: "123123", login: Login(username: "thisisatest@testing.com", totp: "otpauth://account?period=10&secret=LLLLLLLLLLLLLLLL", uris: cipherLoginUris)), Cipher(id: "0", name: "MySite", userId: "123123", login: Login(username: "test@testing.com", totp: "otpauth://account?period=10&secret=LLLLLLLLLLLLLLLL", uris: cipherLoginUris)),
Cipher(id: "1", name: "GitHub", userId: "123123", login: Login(username: "thisisatest@testing.com", totp: "LLLLLLLLLLLLLLLL", uris: cipherLoginUris)), Cipher(id: "1", name: "GitHub", userId: "123123", login: Login(username: "thisisatest@testing.com", totp: "LLLLLLLLLLLLLLLL", uris: cipherLoginUris)),
Cipher(id: "2", name: "No user", userId: "123123", login: Login(username: nil, totp: "otpauth://account?period=10&digits=8&algorithm=sha256&secret=LLLLLLLLLLLLLLLL", uris: cipherLoginUris)), Cipher(id: "2", name: "No user", userId: "123123", login: Login(username: nil, totp: "otpauth://account?period=10&digits=8&algorithm=sha256&secret=LLLLLLLLLLLLLLLL", uris: cipherLoginUris)),
Cipher(id: "3", name: "Site 2", userId: "123123", login: Login(username: "longtestemail000000@fastmailasdfasdf.com", totp: "otpauth://account?period=10&digits=7&algorithm=sha512&secret=LLLLLLLLLLLLLLLL", uris: cipherLoginUris)), Cipher(id: "3", name: "Site 2", userId: "123123", login: Login(username: "longtestemail000000@fastmailasdfasdf.com", totp: "otpauth://account?period=10&digits=7&algorithm=sha512&secret=LLLLLLLLLLLLLLLL", uris: cipherLoginUris)),

View File

@ -34,8 +34,27 @@ class CipherDetailsViewModel: ObservableObject{
self.counter = self.period - mod self.counter = self.period - mod
self.progress = Double(self.counter) / Double(self.period) self.progress = Double(self.counter) / Double(self.period)
} }
if mod == 0 || self.totpFormatted == "" { if mod == 0 || self.totpFormatted == "" {
do { do {
try self.regenerateTotp()
} catch {
DispatchQueue.main.async {
self.totpFormatted = "error"
t.invalidate()
}
}
}
})
RunLoop.current.add(timer!, forMode: .common)
timer?.fire()
}
func stopGeneration() {
self.timer?.invalidate()
}
func regenerateTotp() throws {
var totpF = try TotpService.shared.GetCodeAsync(key: self.key) ?? "" var totpF = try TotpService.shared.GetCodeAsync(key: self.key) ?? ""
if totpF.count > 4 { if totpF.count > 4 {
let halfIndex = totpF.index(totpF.startIndex, offsetBy: totpF.count / 2) let halfIndex = totpF.index(totpF.startIndex, offsetBy: totpF.count / 2)
@ -44,20 +63,5 @@ class CipherDetailsViewModel: ObservableObject{
DispatchQueue.main.async { DispatchQueue.main.async {
self.totpFormatted = totpF self.totpFormatted = totpF
} }
} catch {
DispatchQueue.main.async {
self.totpFormatted = "error"
t.invalidate()
}
}
}
})
RunLoop.current.add(timer!, forMode: .common)
timer?.fire()
}
func stopGeneration(){
self.timer?.invalidate()
} }
} }

View File

@ -2,6 +2,7 @@ import SwiftUI
struct CipherDetailsView: View { struct CipherDetailsView: View {
@ObservedObject var cipherDetailsViewModel: CipherDetailsViewModel @ObservedObject var cipherDetailsViewModel: CipherDetailsViewModel
@Environment(\.scenePhase) var scenePhase
let iconSize: CGSize = CGSize(width: 30, height: 30) let iconSize: CGSize = CGSize(width: 30, height: 30)
@ -61,6 +62,7 @@ struct CipherDetailsView: View {
.minimumScaleFactor(0.01) .minimumScaleFactor(0.01)
.lineLimit(1) .lineLimit(1)
.id(cipherDetailsViewModel.totpFormatted) .id(cipherDetailsViewModel.totpFormatted)
.privacySensitive()
.transition(transition) .transition(transition)
.animation(.default.speed(0.7), value: cipherDetailsViewModel.totpFormatted) .animation(.default.speed(0.7), value: cipherDetailsViewModel.totpFormatted)
Spacer() Spacer()
@ -70,6 +72,7 @@ struct CipherDetailsView: View {
Text("\(cipherDetailsViewModel.counter)") Text("\(cipherDetailsViewModel.counter)")
.font(.title3) .font(.title3)
.fontWeight(.semibold) .fontWeight(.semibold)
.privacySensitive()
} }
} }
.padding(.top, 20) .padding(.top, 20)
@ -83,6 +86,11 @@ struct CipherDetailsView: View {
.onDisappear{ .onDisappear{
self.cipherDetailsViewModel.stopGeneration() self.cipherDetailsViewModel.stopGeneration()
} }
.onChange(of: scenePhase) { newPhase in
if newPhase == .active {
try? self.cipherDetailsViewModel.regenerateTotp()
}
}
} }
var iconPlaceholderImage: some View{ var iconPlaceholderImage: some View{