Add warning sheet when copying Recovery Key

This commit is contained in:
Sasha Weiss 2026-06-04 11:29:34 -07:00 committed by GitHub
parent 15ada8dcf0
commit a978b4cc8b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 181 additions and 1 deletions

View File

@ -115,7 +115,7 @@ class BackupRecordKeyViewController: OWSViewController, OWSNavigationChildContro
comment: "Title for a button allowing users to copy their 'Recovery Key' to the clipboard.",
)),
primaryAction: UIAction { [weak self] _ in
self?.copyToClipboard()
self?.copyToClipboardWithConfirmation()
},
),
]
@ -175,6 +175,53 @@ class BackupRecordKeyViewController: OWSViewController, OWSNavigationChildContro
stackView.setCustomSpacing(32, after: aepTextView)
}
private func copyToClipboardWithConfirmation() {
let bodyText: NSAttributedString = OWSLocalizedString(
"BACKUP_RECORD_KEY_COPY_WARNING_SHEET_BODY",
comment: "Body for a warning sheet shown before copying the user's 'Recovery Key' to the clipboard, warning them not to share it with anyone.",
).styled(
with: .font(.dynamicTypeSubheadline),
.xmlRules([.style("bold", StringStyle(.font(.dynamicTypeSubheadline.bold())))]),
)
let warningSheet = HeroSheetViewController(
hero: .circleIcon(
icon: .errorTriangle,
iconSize: 40,
tintColor: .Signal.red,
backgroundColor: UIColor(rgbHex: 0xF8E0D9),
),
title: OWSLocalizedString(
"BACKUP_RECORD_KEY_COPY_WARNING_SHEET_TITLE",
comment: "Title for a warning sheet shown before copying the user's 'Recovery Key' to the clipboard.",
),
body: HeroSheetViewController.Body(
textContent: .attributed(bodyText),
),
primary: .button(HeroSheetViewController.Button(
title: OWSLocalizedString(
"BACKUP_RECORD_KEY_COPY_WARNING_SHEET_PRIMARY_BUTTON_TITLE",
comment: "Title for the primary button in a warning sheet shown before copying the user's 'Recovery Key' to the clipboard, which acknowledges the warning and proceeds with the copy.",
),
action: { sheet in
sheet.dismiss(animated: true) { [weak self] in
guard let self else { return }
copyToClipboard()
}
},
)),
secondary: .button(HeroSheetViewController.Button(
title: CommonStrings.learnMore,
style: .secondary,
action: .custom({ sheet in
UIApplication.shared.open(.Support.phishingPrevention)
}),
)),
)
present(warningSheet, animated: true)
}
private func copyToClipboard() {
UIPasteboard.general.setItems(
[[UIPasteboard.typeAutomatic: displayableAEP.displayString]],

View File

@ -0,0 +1,16 @@
{
"images" : [
{
"filename" : "error-triangle.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}

View File

@ -0,0 +1,107 @@
%PDF-1.7
1 0 obj
<< >>
endobj
2 0 obj
<< /Length 3 0 R >>
stream
/DeviceRGB CS
/DeviceRGB cs
q
1.000000 0.000000 -0.000000 1.000000 0.980103 15.426270 cm
0.000000 0.000000 0.000000 scn
11.019876 2.073738 m
10.324054 2.073738 9.775503 1.481371 9.828871 0.787598 c
10.252174 -4.715347 l
10.283031 -5.116498 10.617537 -5.426263 11.019876 -5.426263 c
11.422214 -5.426263 11.756720 -5.116498 11.787577 -4.715347 c
12.210880 0.787598 l
12.264248 1.481371 11.715697 2.073738 11.019876 2.073738 c
h
f*
n
Q
q
1.000000 0.000000 -0.000000 1.000000 0.980103 20.426270 cm
0.000000 0.000000 0.000000 scn
9.769861 -12.926263 m
9.769861 -12.235908 10.329505 -11.676263 11.019861 -11.676263 c
11.710217 -11.676263 12.269861 -12.235908 12.269861 -12.926263 c
12.269861 -13.616619 11.710217 -14.176262 11.019861 -14.176262 c
10.329505 -14.176262 9.769861 -13.616619 9.769861 -12.926263 c
h
f*
n
Q
q
1.000000 0.000000 -0.000000 1.000000 0.980103 2.568329 cm
0.000000 0.000000 0.000000 scn
8.107189 18.687922 m
9.410621 20.914618 12.629106 20.914612 13.932535 18.687920 c
21.572298 5.636655 l
22.889338 3.386715 21.266691 0.556679 18.659622 0.556679 c
3.380099 0.556679 l
0.773029 0.556679 -0.849612 3.386719 0.467425 5.636659 c
8.107189 18.687922 l
h
12.422260 17.803856 m
11.794682 18.875969 10.245042 18.875969 9.617465 17.803858 c
1.977700 4.752595 l
1.343571 3.669292 2.124843 2.306679 3.380099 2.306679 c
18.659622 2.306679 l
19.914881 2.306679 20.696152 3.669289 20.062023 4.752591 c
12.422260 17.803856 l
h
f*
n
Q
endstream
endobj
3 0 obj
1436
endobj
4 0 obj
<< /Annots []
/Type /Page
/MediaBox [ 0.000000 0.000000 24.000000 24.000000 ]
/Resources 1 0 R
/Contents 2 0 R
/Parent 5 0 R
>>
endobj
5 0 obj
<< /Kids [ 4 0 R ]
/Count 1
/Type /Pages
>>
endobj
6 0 obj
<< /Pages 5 0 R
/Type /Catalog
>>
endobj
xref
0 7
0000000000 65535 f
0000000010 00000 n
0000000034 00000 n
0000001526 00000 n
0000001549 00000 n
0000001722 00000 n
0000001796 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
1855
%%EOF

View File

@ -652,6 +652,15 @@
/* Title for a button allowing users to copy their 'Recovery Key' to the clipboard. */
"BACKUP_RECORD_KEY_COPY_TO_CLIPBOARD_BUTTON_TITLE" = "Copy to Clipboard";
/* Body for a warning sheet shown before copying the user's 'Recovery Key' to the clipboard, warning them not to share it with anyone. */
"BACKUP_RECORD_KEY_COPY_WARNING_SHEET_BODY" = "Signal will <bold>never</bold> message you for your recovery key. Do not respond to a chat pretending to be Signal. Store your recovery key somewhere safe and do not share it with anyone.";
/* Title for the primary button in a warning sheet shown before copying the user's 'Recovery Key' to the clipboard, which acknowledges the warning and proceeds with the copy. */
"BACKUP_RECORD_KEY_COPY_WARNING_SHEET_PRIMARY_BUTTON_TITLE" = "Got It";
/* Title for a warning sheet shown before copying the user's 'Recovery Key' to the clipboard. */
"BACKUP_RECORD_KEY_COPY_WARNING_SHEET_TITLE" = "Do Not Share Your Recovery Key";
/* Title for a button allowing users to create a new 'Recovery Key'. */
"BACKUP_RECORD_KEY_CREATE_NEW_KEY_BUTTON_TITLE" = "Create New Key";

View File

@ -13,6 +13,7 @@ extension URL {
public static let groups: URL = .supportArticle("360007319331")
public static let inactivePrimaryDevice: URL = .supportArticle("9021007554074")
public static let linkedDevices: URL = .supportArticle("360007320551")
public static let phishingPrevention: URL = .supportArticle("9932566320410")
public static let pin: URL = .supportArticle("360007059792")
public static let profilesAndMessageRequests: URL = .supportArticle("360007459591")
public static let proxies: URL = .supportArticle("360056052052")