mirror of
https://github.com/bitwarden/mobile
synced 2025-01-31 02:37:27 +01:00
[PM-1748] Fix Watch TOTP details on Always On Display (#2515)
* 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 * Fixed PR labeler for WatchOS changes * PM-1748 watchOS made username privacy sensitive for always on display * Revert "Fixed PR labeler for WatchOS changes" This reverts commit 3c55f380696ee0d6a6a363bcf4603bdae59c7d19. --------- Co-authored-by: Álison Fernandes <vvolkgang@users.noreply.github.com>
This commit is contained in:
parent
6bb654e630
commit
37f1a7087e
@ -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)),
|
||||||
|
@ -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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
|
||||||
@ -49,6 +50,7 @@ struct CipherDetailsView: View {
|
|||||||
.fontWeight(.bold)
|
.fontWeight(.bold)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.truncationMode(.tail)
|
.truncationMode(.tail)
|
||||||
|
.privacySensitive()
|
||||||
}
|
}
|
||||||
if cipherDetailsViewModel.totpFormatted == "" {
|
if cipherDetailsViewModel.totpFormatted == "" {
|
||||||
ProgressView()
|
ProgressView()
|
||||||
@ -61,6 +63,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 +73,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 +87,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{
|
||||||
|
@ -36,6 +36,7 @@ struct CipherItemView: View {
|
|||||||
.truncationMode(.tail)
|
.truncationMode(.tail)
|
||||||
.foregroundColor(Color.ui.darkTextMuted)
|
.foregroundColor(Color.ui.darkTextMuted)
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
.privacySensitive()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding()
|
.padding()
|
||||||
|
@ -87,6 +87,7 @@ struct CipherListView: View {
|
|||||||
.font(.headline)
|
.font(.headline)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.truncationMode(.tail)
|
.truncationMode(.tail)
|
||||||
|
.privacySensitive()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user