Skip to content

Commit

Permalink
iOS InContext Email Protection Signup (#1839)
Browse files Browse the repository at this point in the history
Task/Issue URL: https://app.asana.com/0/72649045549333/1202940260106121/f
Tech Design URL:
CC:

Description:
Adds Email InContext Signup protection to iOS
  • Loading branch information
amddg44 authored Aug 24, 2023
1 parent 4074976 commit bc095b9
Show file tree
Hide file tree
Showing 49 changed files with 2,450 additions and 116 deletions.
4 changes: 3 additions & 1 deletion Core/ContentBlocking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@ public final class ContentBlocking {

private init(privacyConfigurationManager: PrivacyConfigurationManaging? = nil) {
let internalUserDecider = DefaultInternalUserDecider(store: InternalUserStore())
let statisticsStore = StatisticsUserDefaults()
let privacyConfigurationManager = privacyConfigurationManager
?? PrivacyConfigurationManager(fetchedETag: UserDefaultsETagStorage().loadEtag(for: .privacyConfiguration),
fetchedData: FileStore().loadAsData(for: .privacyConfiguration),
embeddedDataProvider: AppPrivacyConfigurationDataProvider(),
localProtection: DomainsProtectionUserDefaultsStore(),
errorReporting: Self.debugEvents,
internalUserDecider: internalUserDecider)
internalUserDecider: internalUserDecider,
installDate: statisticsStore.installDate)
self.privacyConfigurationManager = privacyConfigurationManager

trackerDataManager = TrackerDataManager(etag: UserDefaultsETagStorage().loadEtag(for: .trackerDataSet),
Expand Down
3 changes: 3 additions & 0 deletions Core/FeatureFlag.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public enum FeatureFlag: String {
case autofillInlineIconCredentials
case autofillAccessCredentialManagement
case autofillPasswordGeneration
case incontextSignup
case appTrackingProtection
case networkProtection
}
Expand All @@ -47,6 +48,8 @@ extension FeatureFlag: FeatureFlagSourceProviding {
return .remoteReleasable(.subfeature(AutofillSubfeature.accessCredentialManagement))
case .autofillPasswordGeneration:
return .remoteReleasable(.subfeature(AutofillSubfeature.autofillPasswordGeneration))
case .incontextSignup:
return .remoteReleasable(.feature(.incontextSignup))
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions Core/LocaleExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@ extension Locale {
"MC", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT", "RO", "RS", "RU", "SE", "SI", "SK",
"SM", "TR", "UA", "GB", "VA"].contains(regionCode)
}

public var isEnglishLanguage: Bool {
return Locale.preferredLanguages.first?.lowercased().starts(with: "en") ?? false
}
}
19 changes: 19 additions & 0 deletions Core/PixelEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,15 @@ extension Pixel {
case credentialsCleanupAttemptedWhileSyncWasEnabled

case invalidPayload(Configuration)

case emailIncontextPromptDisplayed
case emailIncontextPromptConfirmed
case emailIncontextPromptDismissed
case emailIncontextPromptDismissedPersistent
case emailIncontextModalDisplayed
case emailIncontextModalDismissed
case emailIncontextModalExitEarly
case emailIncontextModalExitEarlyContinue
}

}
Expand Down Expand Up @@ -859,6 +868,16 @@ extension Pixel.Event {
case .credentialsCleanupAttemptedWhileSyncWasEnabled: return "m_d_credentials_cleanup_attempted_while_sync_was_enabled"

case .invalidPayload(let configuration): return "m_d_\(configuration.rawValue)_invalid_payload".lowercased()

// MARK: - InContext Email Protection
case .emailIncontextPromptDisplayed: return "m_email_incontext_prompt_displayed"
case .emailIncontextPromptConfirmed: return "m_email_incontext_prompt_confirmed"
case .emailIncontextPromptDismissed: return "m_email_incontext_prompt_dismissed"
case .emailIncontextPromptDismissedPersistent: return "m_email_incontext_prompt_dismissed_persisted"
case .emailIncontextModalDisplayed: return "m_email_incontext_modal_displayed"
case .emailIncontextModalDismissed: return "m_email_incontext_modal_dismissed"
case .emailIncontextModalExitEarly: return "m_email_incontext_modal_exit_early"
case .emailIncontextModalExitEarlyContinue: return "m_email_incontext_modal_exit_early_continue"
}

}
Expand Down
54 changes: 53 additions & 1 deletion DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,9 @@
B6CB93E5286445AB0090FEB4 /* Base64DownloadSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6CB93E4286445AB0090FEB4 /* Base64DownloadSession.swift */; };
C10CB5F32A1A5BDF0048E503 /* AutofillViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = C10CB5F22A1A5BDF0048E503 /* AutofillViews.swift */; };
C111B26927F579EF006558B1 /* BookmarkOrFolderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C111B26827F579EF006558B1 /* BookmarkOrFolderTests.swift */; };
C12726EE2A5FF88C00215B02 /* EmailSignupPromptView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C12726ED2A5FF88C00215B02 /* EmailSignupPromptView.swift */; };
C12726F02A5FF89900215B02 /* EmailSignupPromptViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C12726EF2A5FF89900215B02 /* EmailSignupPromptViewModel.swift */; };
C12726F22A5FF8CB00215B02 /* EmailSignupPromptViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C12726F12A5FF8CB00215B02 /* EmailSignupPromptViewController.swift */; };
C13B32D22A0E750700A59236 /* AutofillSettingStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = C13B32D12A0E750700A59236 /* AutofillSettingStatus.swift */; };
C14882DA27F2011C00D59F0C /* BookmarksExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14882D727F2011C00D59F0C /* BookmarksExporter.swift */; };
C14882DC27F2011C00D59F0C /* BookmarksImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14882D927F2011C00D59F0C /* BookmarksImporter.swift */; };
Expand All @@ -680,6 +683,7 @@
C14882ED27F211A000D59F0C /* SwiftSoup in Frameworks */ = {isa = PBXBuildFile; productRef = C14882EC27F211A000D59F0C /* SwiftSoup */; };
C14E2F7729DE14EA002AC515 /* AutofillInterfaceUsernameTruncatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14E2F7629DE14EA002AC515 /* AutofillInterfaceUsernameTruncatorTests.swift */; };
C158AC7B297AB5DC0008723A /* MockSecureVault.swift in Sources */ = {isa = PBXBuildFile; fileRef = C158AC7A297AB5DC0008723A /* MockSecureVault.swift */; };
C159DF072A430B60007834BB /* EmailSignupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C159DF062A430B60007834BB /* EmailSignupViewController.swift */; };
C160544129D6044D00B715A1 /* AutofillInterfaceUsernameTruncator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C160544029D6044D00B715A1 /* AutofillInterfaceUsernameTruncator.swift */; };
C17B59592A03AAD30055F2D1 /* PasswordGenerationPromptViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C17B59562A03AAD30055F2D1 /* PasswordGenerationPromptViewModel.swift */; };
C17B595A2A03AAD30055F2D1 /* PasswordGenerationPromptViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C17B59572A03AAD30055F2D1 /* PasswordGenerationPromptViewController.swift */; };
Expand All @@ -698,6 +702,9 @@
C1CCCBA7283E101500CF3791 /* FaviconsHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1CCCBA6283E101500CF3791 /* FaviconsHelper.swift */; };
C1D21E2D293A5965006E5A05 /* AutofillLoginSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1D21E2C293A5965006E5A05 /* AutofillLoginSession.swift */; };
C1D21E2F293A599C006E5A05 /* AutofillLoginSessionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1D21E2E293A599C006E5A05 /* AutofillLoginSessionTests.swift */; };
C1F341C52A6924000032057B /* EmailAddressPromptView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1F341C42A6924000032057B /* EmailAddressPromptView.swift */; };
C1F341C72A6924100032057B /* EmailAddressPromptViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1F341C62A6924100032057B /* EmailAddressPromptViewModel.swift */; };
C1F341C92A6926920032057B /* EmailAddressPromptViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1F341C82A6926920032057B /* EmailAddressPromptViewController.swift */; };
CB258D1229A4F24900DEBA24 /* ConfigurationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB258D0F29A4D0FD00DEBA24 /* ConfigurationManager.swift */; };
CB258D1329A4F24E00DEBA24 /* ConfigurationStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB84C7C029A3F0280088A5B8 /* ConfigurationStore.swift */; };
CB258D1D29A52AF900DEBA24 /* EtagStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9896632322C56716007BE4FE /* EtagStorage.swift */; };
Expand Down Expand Up @@ -2244,6 +2251,9 @@
B6CB93E4286445AB0090FEB4 /* Base64DownloadSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base64DownloadSession.swift; sourceTree = "<group>"; };
C10CB5F22A1A5BDF0048E503 /* AutofillViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutofillViews.swift; sourceTree = "<group>"; };
C111B26827F579EF006558B1 /* BookmarkOrFolderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkOrFolderTests.swift; sourceTree = "<group>"; };
C12726ED2A5FF88C00215B02 /* EmailSignupPromptView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmailSignupPromptView.swift; sourceTree = "<group>"; };
C12726EF2A5FF89900215B02 /* EmailSignupPromptViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmailSignupPromptViewModel.swift; sourceTree = "<group>"; };
C12726F12A5FF8CB00215B02 /* EmailSignupPromptViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmailSignupPromptViewController.swift; sourceTree = "<group>"; };
C13B32D12A0E750700A59236 /* AutofillSettingStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutofillSettingStatus.swift; sourceTree = "<group>"; };
C14882D727F2011C00D59F0C /* BookmarksExporter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarksExporter.swift; sourceTree = "<group>"; };
C14882D927F2011C00D59F0C /* BookmarksImporter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarksImporter.swift; sourceTree = "<group>"; };
Expand All @@ -2254,6 +2264,7 @@
C14882E927F20DD000D59F0C /* MockBookmarksCoreDataStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockBookmarksCoreDataStorage.swift; sourceTree = "<group>"; };
C14E2F7629DE14EA002AC515 /* AutofillInterfaceUsernameTruncatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutofillInterfaceUsernameTruncatorTests.swift; sourceTree = "<group>"; };
C158AC7A297AB5DC0008723A /* MockSecureVault.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockSecureVault.swift; sourceTree = "<group>"; };
C159DF062A430B60007834BB /* EmailSignupViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmailSignupViewController.swift; sourceTree = "<group>"; };
C160544029D6044D00B715A1 /* AutofillInterfaceUsernameTruncator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutofillInterfaceUsernameTruncator.swift; sourceTree = "<group>"; };
C17B59562A03AAD30055F2D1 /* PasswordGenerationPromptViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordGenerationPromptViewModel.swift; sourceTree = "<group>"; };
C17B59572A03AAD30055F2D1 /* PasswordGenerationPromptViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordGenerationPromptViewController.swift; sourceTree = "<group>"; };
Expand All @@ -2272,6 +2283,9 @@
C1CCCBA6283E101500CF3791 /* FaviconsHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FaviconsHelper.swift; sourceTree = "<group>"; };
C1D21E2C293A5965006E5A05 /* AutofillLoginSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutofillLoginSession.swift; sourceTree = "<group>"; };
C1D21E2E293A599C006E5A05 /* AutofillLoginSessionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutofillLoginSessionTests.swift; sourceTree = "<group>"; };
C1F341C42A6924000032057B /* EmailAddressPromptView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmailAddressPromptView.swift; sourceTree = "<group>"; };
C1F341C62A6924100032057B /* EmailAddressPromptViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmailAddressPromptViewModel.swift; sourceTree = "<group>"; };
C1F341C82A6926920032057B /* EmailAddressPromptViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmailAddressPromptViewController.swift; sourceTree = "<group>"; };
CB1AEFB02799AA940031AE3D /* SwiftUICollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUICollectionViewCell.swift; sourceTree = "<group>"; };
CB24F70E29A3EB15006DCC58 /* AppConfigurationURLProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppConfigurationURLProvider.swift; path = ../Core/AppConfigurationURLProvider.swift; sourceTree = "<group>"; };
CB258D0C29A4CD0500DEBA24 /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3521,6 +3535,7 @@
B652DF02287C01EE00C12A9C /* ContentBlocking */,
310D09192799EF5C00DC0060 /* Downloads */,
F143C2C51E4A08F300CFDE3A /* DuckDuckGo.entitlements */,
C159DF052A430B36007834BB /* EmailProtection */,
839F119520DBC489007CD8C2 /* Feedback */,
85F2FFFE2215C163006BB258 /* FindInPage */,
F13B4BF31F18C73A00814661 /* Home */,
Expand Down Expand Up @@ -4157,6 +4172,15 @@
name = ImportExport;
sourceTree = "<group>";
};
C159DF052A430B36007834BB /* EmailProtection */ = {
isa = PBXGroup;
children = (
C1F341C32A6923D70032057B /* EmailAddressPrompt */,
C1CAA3D52A630ECB00807703 /* EmailSignup */,
);
name = EmailProtection;
sourceTree = "<group>";
};
C17B59552A03AAC40055F2D1 /* PasswordGeneration */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -4194,6 +4218,27 @@
name = AutofillLoginUI;
sourceTree = "<group>";
};
C1CAA3D52A630ECB00807703 /* EmailSignup */ = {
isa = PBXGroup;
children = (
C159DF062A430B60007834BB /* EmailSignupViewController.swift */,
C12726ED2A5FF88C00215B02 /* EmailSignupPromptView.swift */,
C12726EF2A5FF89900215B02 /* EmailSignupPromptViewModel.swift */,
C12726F12A5FF8CB00215B02 /* EmailSignupPromptViewController.swift */,
);
name = EmailSignup;
sourceTree = "<group>";
};
C1F341C32A6923D70032057B /* EmailAddressPrompt */ = {
isa = PBXGroup;
children = (
C1F341C42A6924000032057B /* EmailAddressPromptView.swift */,
C1F341C62A6924100032057B /* EmailAddressPromptViewModel.swift */,
C1F341C82A6926920032057B /* EmailAddressPromptViewController.swift */,
);
name = EmailAddressPrompt;
sourceTree = "<group>";
};
CB1AEFB6279AF6420031AE3D /* WidgetEducation */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -5948,6 +5993,7 @@
EEFD562F2A65B6CA00DAEC48 /* NetworkProtectionInviteViewModel.swift in Sources */,
1E8AD1D927C4FEC100ABA377 /* DownloadsListSectioningHelper.swift in Sources */,
1E4DCF4827B6A35400961E25 /* DownloadsListModel.swift in Sources */,
C12726F02A5FF89900215B02 /* EmailSignupPromptViewModel.swift in Sources */,
31669B9A28020A460071CC18 /* SaveLoginViewModel.swift in Sources */,
EE4FB1882A28D11900E5CBA7 /* NetworkProtectionStatusViewModel.swift in Sources */,
0290472029E708B70008FE3C /* AppTPManageTrackersViewModel.swift in Sources */,
Expand Down Expand Up @@ -5976,6 +6022,7 @@
319A37152829A55F0079FBCE /* AutofillListItemTableViewCell.swift in Sources */,
1EA513782866039400493C6A /* TrackerAnimationLogic.swift in Sources */,
854A01332A558B3A00FCC628 /* UIView+Constraints.swift in Sources */,
C12726EE2A5FF88C00215B02 /* EmailSignupPromptView.swift in Sources */,
83134D7D20E2D725006CE65D /* FeedbackSender.swift in Sources */,
B652DF12287C336E00C12A9C /* ContentBlockingUpdating.swift in Sources */,
314C92BA27C3E7CB0042EC96 /* QuickLookContainerViewController.swift in Sources */,
Expand Down Expand Up @@ -6045,6 +6092,7 @@
1E8AD1D527C2E22900ABA377 /* DownloadsListSectionViewModel.swift in Sources */,
4BC6DD1C2A60E6AD001EC129 /* ReportBrokenSiteView.swift in Sources */,
31584616281AFB46004ADB8B /* AutofillLoginDetailsViewController.swift in Sources */,
C1F341C72A6924100032057B /* EmailAddressPromptViewModel.swift in Sources */,
F47E53D9250A97330037C686 /* OnboardingDefaultBroswerViewController.swift in Sources */,
F13B4BD51F183B3600814661 /* TabsModelPersistenceExtension.swift in Sources */,
980891A52237D4F500313A70 /* FeedbackNavigator.swift in Sources */,
Expand Down Expand Up @@ -6137,6 +6185,7 @@
986C7FA724171C6000A3557D /* BrokenSiteCategories.swift in Sources */,
85DB12ED2A1FED0C000A4A72 /* AppDelegate+AppDeepLinks.swift in Sources */,
98DA6ECA2181E41F00E65433 /* ThemeManager.swift in Sources */,
C159DF072A430B60007834BB /* EmailSignupViewController.swift in Sources */,
1E016AB6294A5EB100F21625 /* CustomDaxDialog.swift in Sources */,
02341FA42A437999008A1531 /* OnboardingStepView.swift in Sources */,
F1CA3C3B1F045B65005FADB3 /* Authenticator.swift in Sources */,
Expand Down Expand Up @@ -6167,6 +6216,7 @@
8565A34B1FC8D96B00239327 /* LaunchTabNotification.swift in Sources */,
0290472829E861BE0008FE3C /* AppTPTrackerDetailViewModel.swift in Sources */,
311BD1AD2836BB3900AEF6C1 /* AutofillItemsEmptyView.swift in Sources */,
C1F341C52A6924000032057B /* EmailAddressPromptView.swift in Sources */,
316931D727BD10BB0095F5ED /* SaveToDownloadsAlert.swift in Sources */,
31C70B5B2804C61000FB6AD1 /* SaveAutofillLoginManager.swift in Sources */,
85449EFD23FDA71F00512AAF /* KeyboardSettings.swift in Sources */,
Expand All @@ -6178,6 +6228,7 @@
1EC458462948932500CB2B13 /* UIHostingControllerExtension.swift in Sources */,
1E4DCF4E27B6A69600961E25 /* DownloadsListHostingController.swift in Sources */,
020108A129A5610C00644F9D /* AppTPActivityHostingViewController.swift in Sources */,
C1F341C92A6926920032057B /* EmailAddressPromptViewController.swift in Sources */,
02025B0F29884DC500E694E7 /* AppTrackerDataParser.swift in Sources */,
027F48742A4B5904001A1C6C /* AppTPAboutView.swift in Sources */,
311BD1B12836C0CA00AEF6C1 /* AutofillLoginListAuthenticator.swift in Sources */,
Expand Down Expand Up @@ -6234,6 +6285,7 @@
851DFD87212C39D300D95F20 /* TabSwitcherButton.swift in Sources */,
8505836A219F424500ED4EDB /* UIAlertControllerExtension.swift in Sources */,
37FCAAB229914232000E420A /* WindowsBrowserWaitlistView.swift in Sources */,
C12726F22A5FF8CB00215B02 /* EmailSignupPromptViewController.swift in Sources */,
0290472C29E8821E0008FE3C /* AppTPBreakageFormHeaderView.swift in Sources */,
983EABB8236198F6003948D1 /* DatabaseMigration.swift in Sources */,
314C92B827C3DD660042EC96 /* QuickLookPreviewView.swift in Sources */,
Expand Down Expand Up @@ -8816,7 +8868,7 @@
repositoryURL = "https://github.com/DuckDuckGo/BrowserServicesKit";
requirement = {
kind = exactVersion;
version = 75.0.4;
version = 75.1.0;
};
};
C14882EB27F211A000D59F0C /* XCRemoteSwiftPackageReference "SwiftSoup" */ = {
Expand Down
Loading

0 comments on commit bc095b9

Please sign in to comment.