diff --git a/Signal/src/Loki/Settings/DeviceLinkingModal.swift b/Signal/src/Loki/Settings/DeviceLinkingModal.swift index 8110bbfeb..2d6553348 100644 --- a/Signal/src/Loki/Settings/DeviceLinkingModal.swift +++ b/Signal/src/Loki/Settings/DeviceLinkingModal.swift @@ -108,7 +108,7 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate { mnemonicLabel.isHidden = (mode == .master) if mode == .slave { let hexEncodedPublicKey = OWSIdentityManager.shared().identityKeyPair()!.hexEncodedPublicKey.removing05PrefixIfNeeded() - mnemonicLabel.text = Mnemonic.encode(hexEncodedString: hexEncodedPublicKey).split(separator: " ")[0..<3].joined(separator: " ") + mnemonicLabel.text = Mnemonic.hash(hexEncodedString: hexEncodedPublicKey) } let buttonHeight = cancelButton.button.titleLabel!.font.pointSize * 48 / 17 authorizeButton.set(.height, to: buttonHeight) @@ -130,7 +130,7 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate { titleLabel.text = NSLocalizedString("Linking Request Received", comment: "") subtitleLabel.text = NSLocalizedString("Please check that the words below match the ones shown on your other device", comment: "") let hexEncodedPublicKey = deviceLink.slave.hexEncodedPublicKey.removing05PrefixIfNeeded() - mnemonicLabel.text = Mnemonic.encode(hexEncodedString: hexEncodedPublicKey).split(separator: " ")[0..<3].joined(separator: " ") + mnemonicLabel.text = Mnemonic.hash(hexEncodedString: hexEncodedPublicKey) mnemonicLabel.isHidden = false authorizeButton.isHidden = false } diff --git a/Signal/src/Loki/Settings/DeviceLinksVC.swift b/Signal/src/Loki/Settings/DeviceLinksVC.swift index b757c9dbb..5a3ddcebc 100644 --- a/Signal/src/Loki/Settings/DeviceLinksVC.swift +++ b/Signal/src/Loki/Settings/DeviceLinksVC.swift @@ -206,7 +206,7 @@ private extension DeviceLinksVC { // MARK: Updating private func update() { titleLabel.text = device.displayName - subtitleLabel.text = Mnemonic.encode(hexEncodedString: device.hexEncodedPublicKey.removing05PrefixIfNeeded()).split(separator: " ")[0..<3].joined(separator: " ") + subtitleLabel.text = Mnemonic.hash(hexEncodedString: device.hexEncodedPublicKey.removing05PrefixIfNeeded()) } } } diff --git a/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m b/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m index 8f5c9b3ed..6541c31ba 100644 --- a/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m +++ b/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.m @@ -125,15 +125,13 @@ #endif OWSTableSection *section = [OWSTableSection new]; - if (isMasterDevice) { - [section addItem:[OWSTableItem itemWithCustomCellBlock:^{ - return [weakSelf profileHeaderCell]; + [section addItem:[OWSTableItem itemWithCustomCellBlock:^{ + return [weakSelf profileHeaderCell]; + } customRowHeight:100.f actionBlock:^{ + if (isMasterDevice) { + [weakSelf showProfile]; } - customRowHeight:100.f - actionBlock:^{ - [weakSelf showProfile]; - }]]; - } + }]]; if (OWSSignalService.sharedInstance.isCensorshipCircumventionActive) { [section @@ -313,6 +311,9 @@ - (UITableViewCell *)profileHeaderCell { + NSString *masterDeviceHexEncodedPublicKey = [NSUserDefaults.standardUserDefaults stringForKey:@"masterDeviceHexEncodedPublicKey"]; + BOOL isMasterDevice = (masterDeviceHexEncodedPublicKey == nil); + UITableViewCell *cell = [OWSTableItem newCell]; cell.preservesSuperviewLayoutMargins = YES; cell.contentView.preservesSuperviewLayoutMargins = YES; @@ -331,7 +332,7 @@ [avatarView autoSetDimension:ALDimensionHeight toSize:kLargeAvatarSize]; avatarView.contactID = OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey; - if (!localProfileAvatarImage) { + if (isMasterDevice && !localProfileAvatarImage) { UIImage *cameraImage = [UIImage imageNamed:@"settings-avatar-camera"]; UIImageView *cameraImageView = [[UIImageView alloc] initWithImage:cameraImage]; [cell.contentView addSubview:cameraImageView]; @@ -350,11 +351,13 @@ titleLabel.text = localProfileName; titleLabel.textColor = [Theme primaryColor]; titleLabel.font = [UIFont ows_dynamicTypeTitle2Font]; - } else { + } else if (isMasterDevice) { titleLabel.text = NSLocalizedString( @"APP_SETTINGS_EDIT_PROFILE_NAME_PROMPT", @"Text prompting user to edit their profile name."); titleLabel.textColor = [UIColor ows_materialBlueColor]; titleLabel.font = [UIFont ows_dynamicTypeHeadlineFont]; + } else { + titleLabel.hidden = YES; } titleLabel.lineBreakMode = NSLineBreakByTruncatingTail; [nameView addSubview:titleLabel]; @@ -365,27 +368,43 @@ UILabel *subtitleLabel = [UILabel new]; subtitleLabel.textColor = [Theme secondaryColor]; subtitleLabel.font = [UIFont ows_regularFontWithSize:kSubtitlePointSize]; - subtitleLabel.attributedText = [[NSAttributedString alloc] - initWithString:[PhoneNumber bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:[TSAccountManager - localNumber]]]; + NSString *hexEncodedPublicKey = masterDeviceHexEncodedPublicKey ?: TSAccountManager.localNumber; + subtitleLabel.attributedText = [[NSAttributedString alloc] initWithString:hexEncodedPublicKey]; subtitleLabel.lineBreakMode = NSLineBreakByTruncatingTail; [nameView addSubview:subtitleLabel]; [subtitleLabel autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:titleLabel]; - [subtitleLabel autoPinLeadingToSuperviewMargin]; - [subtitleLabel autoPinEdgeToSuperviewEdge:ALEdgeBottom]; + if (isMasterDevice) { + [subtitleLabel autoPinEdgeToSuperviewEdge:ALEdgeBottom]; + } [subtitleLabel autoPinWidthToSuperview]; + + if (!isMasterDevice) { + UILabel *linkedDeviceLabel = [UILabel new]; + linkedDeviceLabel.textColor = [Theme secondaryColor]; + linkedDeviceLabel.font = [UIFont ows_regularFontWithSize:12.f]; + NSString *shortID = [LKMnemonic hashHexEncodedString:[TSAccountManager.localNumber removing05PrefixIfNeeded]]; + linkedDeviceLabel.attributedText = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:NSLocalizedString(@"Linked device (%@)", ""), shortID]]; + linkedDeviceLabel.lineBreakMode = NSLineBreakByTruncatingTail; + [nameView addSubview:linkedDeviceLabel]; + [linkedDeviceLabel autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:subtitleLabel]; + [linkedDeviceLabel autoPinEdgeToSuperviewEdge:ALEdgeBottom]; + [linkedDeviceLabel autoPinWidthToSuperview]; + [nameView autoPinTrailingToSuperviewMargin]; + } - UIImage *disclosureImage = [UIImage imageNamed:(CurrentAppContext().isRTL ? @"NavBarBack" : @"NavBarBackRTL")]; - OWSAssertDebug(disclosureImage); - UIImageView *disclosureButton = - [[UIImageView alloc] initWithImage:[disclosureImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]]; - disclosureButton.tintColor = [UIColor colorWithRGBHex:0xcccccc]; - [cell.contentView addSubview:disclosureButton]; - [disclosureButton autoVCenterInSuperview]; - [disclosureButton autoPinTrailingToSuperviewMargin]; - [disclosureButton autoPinLeadingToTrailingEdgeOfView:nameView offset:16.f]; - [disclosureButton setContentCompressionResistancePriority:(UILayoutPriorityDefaultHigh + 1) - forAxis:UILayoutConstraintAxisHorizontal]; + if (isMasterDevice) { + UIImage *disclosureImage = [UIImage imageNamed:(CurrentAppContext().isRTL ? @"NavBarBack" : @"NavBarBackRTL")]; + OWSAssertDebug(disclosureImage); + UIImageView *disclosureButton = + [[UIImageView alloc] initWithImage:[disclosureImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]]; + disclosureButton.tintColor = [UIColor colorWithRGBHex:0xcccccc]; + [cell.contentView addSubview:disclosureButton]; + [disclosureButton autoVCenterInSuperview]; + [disclosureButton autoPinTrailingToSuperviewMargin]; + [disclosureButton autoPinLeadingToTrailingEdgeOfView:nameView offset:16.f]; + [disclosureButton setContentCompressionResistancePriority:(UILayoutPriorityDefaultHigh + 1) + forAxis:UILayoutConstraintAxisHorizontal]; + } cell.accessibilityIdentifier = ACCESSIBILITY_IDENTIFIER_WITH_NAME(self, @"profile"); diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index d15a68680..f8d1e9a55 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -2671,3 +2671,4 @@ "Device Unlinked" = "Device Unlinked"; "Your device was unlinked successfully" = "Your device was unlinked successfully"; "Unnamed Device" = "Unnamed Device"; +"Linked device (%@)" = "Linked device (%@)"; diff --git a/SignalServiceKit/src/Loki/Crypto/Mnemonic.swift b/SignalServiceKit/src/Loki/Crypto/Mnemonic.swift index b560d0ede..c44e39daa 100644 --- a/SignalServiceKit/src/Loki/Crypto/Mnemonic.swift +++ b/SignalServiceKit/src/Loki/Crypto/Mnemonic.swift @@ -58,6 +58,10 @@ public enum Mnemonic { } } + public static func hash(hexEncodedString string: String, language: Language = .english) -> String { + return encode(hexEncodedString: string).split(separator: " ")[0..<3].joined(separator: " ") + } + public static func encode(hexEncodedString string: String, language: Language = .english) -> String { var string = string let wordSet = language.loadWordSet() @@ -146,6 +150,11 @@ public final class ObjCMnemonic : NSObject { override private init() { } + @objc(hashHexEncodedString:) + public static func hash(hexEncodedString string: String) -> String { + return Mnemonic.hash(hexEncodedString: string) + } + @objc(encodeHexEncodedString:) public static func encode(hexEncodedString string: String) -> String { return Mnemonic.encode(hexEncodedString: string) diff --git a/SignalServiceKit/src/Loki/Utilities/String+Trimming.swift b/SignalServiceKit/src/Loki/Utilities/String+Trimming.swift index 49df99a43..0e9078269 100644 --- a/SignalServiceKit/src/Loki/Utilities/String+Trimming.swift +++ b/SignalServiceKit/src/Loki/Utilities/String+Trimming.swift @@ -7,3 +7,12 @@ public extension String { return result } } + +@objc extension NSString { + + @objc public func removing05PrefixIfNeeded() -> NSString { + var result = self as String + if result.count == 66 && result.hasPrefix("05") { result.removeFirst(2) } + return result as NSString + } +}