diff --git a/GoogleSignIn/Sources/GIDRestrictedScopesRegistry.m b/GoogleSignIn/Sources/GIDRestrictedScopesRegistry.m index c2b11ca5..e7c4f782 100644 --- a/GoogleSignIn/Sources/GIDRestrictedScopesRegistry.m +++ b/GoogleSignIn/Sources/GIDRestrictedScopesRegistry.m @@ -24,10 +24,8 @@ @implementation GIDRestrictedScopesRegistry - (instancetype)init { self = [super init]; if (self) { - _restrictedScopes = [NSSet setWithObjects:kAccountDetailTypeAgeOver18Scope, nil]; - _scopeToClassMapping = @{ - kAccountDetailTypeAgeOver18Scope: [GIDVerifyAccountDetail class], - }; + _restrictedScopes = [NSSet set]; + _scopeToClassMapping = @{}; } return self; } diff --git a/GoogleSignIn/Sources/GIDVerifyAccountDetail/Implementations/GIDVerifiableAccountDetail.m b/GoogleSignIn/Sources/GIDVerifyAccountDetail/Implementations/GIDVerifiableAccountDetail.m index 71e48da2..c4f29bc3 100644 --- a/GoogleSignIn/Sources/GIDVerifyAccountDetail/Implementations/GIDVerifiableAccountDetail.m +++ b/GoogleSignIn/Sources/GIDVerifyAccountDetail/Implementations/GIDVerifiableAccountDetail.m @@ -18,8 +18,6 @@ #if TARGET_OS_IOS && !TARGET_OS_MACCATALYST -NSString *const kAccountDetailTypeAgeOver18Scope = @"https://www.googleapis.com/auth/verified.age.over18.standard"; - @implementation GIDVerifiableAccountDetail - (instancetype)initWithAccountDetailType:(GIDAccountDetailType)accountDetailType { @@ -31,12 +29,7 @@ - (instancetype)initWithAccountDetailType:(GIDAccountDetailType)accountDetailTyp } - (nullable NSString *)scope { - switch (self.accountDetailType) { - case GIDAccountDetailTypeAgeOver18: - return kAccountDetailTypeAgeOver18Scope; - default: - return nil; - } + return nil; } - (BOOL)isEqual:(id)object { @@ -51,9 +44,6 @@ - (NSUInteger)hash { } + (GIDAccountDetailType)detailTypeWithString:(NSString *)detailTypeString { - if ([detailTypeString isEqualToString:kAccountDetailTypeAgeOver18Scope]) { - return GIDAccountDetailTypeAgeOver18; - } return GIDAccountDetailTypeUnknown; } diff --git a/GoogleSignIn/Sources/Public/GoogleSignIn/GIDVerifiableAccountDetail.h b/GoogleSignIn/Sources/Public/GoogleSignIn/GIDVerifiableAccountDetail.h index 81b055ce..aaf2a606 100644 --- a/GoogleSignIn/Sources/Public/GoogleSignIn/GIDVerifiableAccountDetail.h +++ b/GoogleSignIn/Sources/Public/GoogleSignIn/GIDVerifiableAccountDetail.h @@ -26,13 +26,8 @@ NS_ASSUME_NONNULL_BEGIN typedef NS_ENUM(NSInteger, GIDAccountDetailType) { /// Used when the account detail type is unspecified or cannot be matched. GIDAccountDetailTypeUnknown, - /// User account detail for age over 18. - GIDAccountDetailTypeAgeOver18, }; -/// String scope representing the account detail type for age over 18. -extern NSString *const kAccountDetailTypeAgeOver18Scope; - /// Helper object used to hold the enumeration representing a list of /// account details that Google can verify via GSI. @interface GIDVerifiableAccountDetail : NSObject diff --git a/GoogleSignIn/Tests/Unit/GIDRestrictedScopesRegistryTest.m b/GoogleSignIn/Tests/Unit/GIDRestrictedScopesRegistryTest.m index eb67e6ae..b930d6ef 100644 --- a/GoogleSignIn/Tests/Unit/GIDRestrictedScopesRegistryTest.m +++ b/GoogleSignIn/Tests/Unit/GIDRestrictedScopesRegistryTest.m @@ -27,18 +27,16 @@ @implementation GIDRestrictedScopesRegistryTest - (void)testIsScopeRestricted { GIDRestrictedScopesRegistry *registry = [[GIDRestrictedScopesRegistry alloc] init]; - BOOL isRestricted = [registry isScopeRestricted:kAccountDetailTypeAgeOver18Scope]; - XCTAssertTrue(isRestricted); + BOOL isRestricted = [registry isScopeRestricted:@"some_scope"]; + XCTAssertFalse(isRestricted); } - (void)testRestrictedScopesToClassMappingInSet { GIDRestrictedScopesRegistry *registry = [[GIDRestrictedScopesRegistry alloc] init]; - NSSet *scopes = [NSSet setWithObjects:kAccountDetailTypeAgeOver18Scope, @"some_other_scope", nil]; + NSSet *scopes = [NSSet setWithObjects:@"some_scope", @"some_other_scope", nil]; NSDictionary *mapping = [registry restrictedScopesToClassMappingInSet:scopes]; - XCTAssertEqual(mapping.count, 1); - XCTAssertEqualObjects(mapping[kAccountDetailTypeAgeOver18Scope], [GIDVerifyAccountDetail class]); - XCTAssertNil(mapping[@"some_other_scope"]); + XCTAssertEqual(mapping.count, 0); } @end diff --git a/GoogleSignIn/Tests/Unit/GIDSignInInternalOptionsTest.m b/GoogleSignIn/Tests/Unit/GIDSignInInternalOptionsTest.m index 3c2e7fee..0707cd34 100644 --- a/GoogleSignIn/Tests/Unit/GIDSignInInternalOptionsTest.m +++ b/GoogleSignIn/Tests/Unit/GIDSignInInternalOptionsTest.m @@ -40,8 +40,9 @@ - (void)testDefaultOptionsForVerificationFlow { hostedDomain:nil openIDRealm:kOpenIDRealm]; UIViewController *presentingViewController = [[UIViewController alloc] init]; - GIDVerifiableAccountDetail *ageOver18Detail = [[GIDVerifiableAccountDetail alloc] initWithAccountDetailType:GIDAccountDetailTypeAgeOver18]; - NSArray *accountDetailsToVerify = @[ageOver18Detail]; + GIDVerifiableAccountDetail *testAccountDetail = + [[GIDVerifiableAccountDetail alloc] initWithAccountDetailType:GIDAccountDetailTypeUnknown]; + NSArray *accountDetailsToVerify = @[testAccountDetail]; NSString *loginHint = @"login_hint"; GIDSignInInternalOptions *options = diff --git a/GoogleSignIn/Tests/Unit/GIDSignInTest.m b/GoogleSignIn/Tests/Unit/GIDSignInTest.m index 2a73bc67..abcd24b4 100644 --- a/GoogleSignIn/Tests/Unit/GIDSignInTest.m +++ b/GoogleSignIn/Tests/Unit/GIDSignInTest.m @@ -1341,32 +1341,6 @@ - (void)testTokenEndpointEMMError { XCTAssertNil(_signIn.currentUser, @"should not have current user"); } -- (void)testValidScopesException { - NSString *requestedScope = @"https://www.googleapis.com/auth/verified.age.over18.standard"; - NSString *expectedException = - [NSString stringWithFormat:@"The following scopes are not supported in the 'addScopes' flow. " - "Please use the appropriate classes to handle these:\n%@ -> %@\n", - requestedScope, NSStringFromClass([GIDVerifyAccountDetail class])]; - BOOL threw = NO; - @try { - [_signIn addScopes:@[requestedScope] -#if TARGET_OS_IOS || TARGET_OS_MACCATALYST - presentingViewController:_presentingViewController -#elif TARGET_OS_OSX - presentingWindow:_presentingWindow -#endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST - completion:_completion]; - } @catch (NSException *exception) { - threw = YES; - XCTAssertEqualObjects(exception.description, expectedException); - } @finally { - } - XCTAssert(threw); - - // TODO: Keep mocks from carrying forward to subsequent tests. (#410) - [_authState stopMocking]; -} - #endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST #pragma mark - Helpers diff --git a/GoogleSignIn/Tests/Unit/GIDVerifiableAccountDetailTest.m b/GoogleSignIn/Tests/Unit/GIDVerifiableAccountDetailTest.m index 88c050ee..e25fb065 100644 --- a/GoogleSignIn/Tests/Unit/GIDVerifiableAccountDetailTest.m +++ b/GoogleSignIn/Tests/Unit/GIDVerifiableAccountDetailTest.m @@ -23,20 +23,23 @@ @interface GIDVerifiableAccountDetailTests : XCTestCase @implementation GIDVerifiableAccountDetailTests - (void)testDesignatedInitializer { - GIDVerifiableAccountDetail *detail = [[GIDVerifiableAccountDetail alloc] initWithAccountDetailType:GIDAccountDetailTypeAgeOver18]; + GIDVerifiableAccountDetail *detail = + [[GIDVerifiableAccountDetail alloc] initWithAccountDetailType:GIDAccountDetailTypeUnknown]; XCTAssertNotNil(detail); - XCTAssertEqual(detail.accountDetailType, GIDAccountDetailTypeAgeOver18); + XCTAssertEqual(detail.accountDetailType, GIDAccountDetailTypeUnknown); } - (void)testScopeRetrieval { - GIDVerifiableAccountDetail *detail = [[GIDVerifiableAccountDetail alloc] initWithAccountDetailType:GIDAccountDetailTypeAgeOver18]; + GIDVerifiableAccountDetail *detail = + [[GIDVerifiableAccountDetail alloc] initWithAccountDetailType:GIDAccountDetailTypeUnknown]; NSString *retrievedScope = [detail scope]; - XCTAssertEqualObjects(retrievedScope, kAccountDetailTypeAgeOver18Scope); + XCTAssertNil(retrievedScope); } - (void)testScopeRetrieval_MissingScope { NSInteger missingScope = 5; - GIDVerifiableAccountDetail *detail = [[GIDVerifiableAccountDetail alloc] initWithAccountDetailType:missingScope]; + GIDVerifiableAccountDetail *detail = + [[GIDVerifiableAccountDetail alloc] initWithAccountDetailType:missingScope]; NSString *retrievedScope = [detail scope]; XCTAssertNil(retrievedScope); } diff --git a/GoogleSignIn/Tests/Unit/GIDVerifiedAccountDetailResultTest.m b/GoogleSignIn/Tests/Unit/GIDVerifiedAccountDetailResultTest.m index 884d961a..e83df213 100644 --- a/GoogleSignIn/Tests/Unit/GIDVerifiedAccountDetailResultTest.m +++ b/GoogleSignIn/Tests/Unit/GIDVerifiedAccountDetailResultTest.m @@ -36,7 +36,7 @@ - (void)testInit { OIDAuthState *authState = [OIDAuthState testInstance]; GIDVerifiableAccountDetail *verifiedAccountDetail = - [[GIDVerifiableAccountDetail alloc] initWithAccountDetailType:GIDAccountDetailTypeAgeOver18]; + [[GIDVerifiableAccountDetail alloc] initWithAccountDetailType:GIDAccountDetailTypeUnknown]; NSArray *verifiedList = @[verifiedAccountDetail, verifiedAccountDetail]; @@ -52,12 +52,8 @@ - (void)testInit { XCTAssertEqual(result.refreshToken.tokenString, authState.lastTokenResponse.refreshToken); } -- (void)testRefreshTokensWithCompletion_success { - GIDVerifiableAccountDetail *verifiedAccountDetail = - [[GIDVerifiableAccountDetail alloc] initWithAccountDetailType:GIDAccountDetailTypeAgeOver18]; - - NSString *kAccountDetailList = [NSString stringWithFormat:@"%@", - kAccountDetailTypeAgeOver18Scope]; +- (void)testRefreshTokensWithCompletion_randomScope { + NSString *kAccountDetailList = [NSString stringWithFormat:@"some_scope"]; OIDTokenResponse *tokenResponse = [OIDTokenResponse testInstanceWithScope:kAccountDetailList]; OIDAuthState *authState = [OIDAuthState testInstanceWithTokenResponse:tokenResponse]; GIDVerifiedAccountDetailHandlingFake *result = @@ -65,19 +61,14 @@ - (void)testRefreshTokensWithCompletion_success { verifiedAuthState:authState error:nil]; - NSArray *expectedVerifiedList = - @[verifiedAccountDetail]; - GIDVerifiedAccountDetailResult *expectedResult = - [[GIDVerifiedAccountDetailResult alloc] initWithAccountDetails:expectedVerifiedList - authState:authState]; - XCTestExpectation *expectation = [self expectationWithDescription:@"Refreshed verified account details completion called"]; [result refreshTokensWithCompletion:^(GIDVerifiedAccountDetailResult * _Nullable refreshedResult, NSError * _Nullable error) { XCTAssertNil(error); XCTAssertNotNil(refreshedResult); - XCTAssertTrue([refreshedResult isEqual:expectedResult]); + XCTAssertEqual([refreshedResult.verifiedAccountDetails count], 0, + @"verifiedAccountDetails should have a count of 0"); [expectation fulfill]; }]; @@ -103,8 +94,8 @@ - (void)testRefreshTokensWithCompletion_noTokenResponse { XCTAssertEqual(error, expectedError); XCTAssertEqual(error.code, kGIDSignInErrorCodeUnknown); XCTAssertNotNil(refreshedResult); - XCTAssertTrue([refreshedResult.verifiedAccountDetails count] == 0, - @"verifiedAccountDetails should have a count of 0"); + XCTAssertEqual([refreshedResult.verifiedAccountDetails count], 0, + @"verifiedAccountDetails should have a count of 0"); [expectation fulfill]; }]; diff --git a/GoogleSignIn/Tests/Unit/GIDVerifyAccountDetailTest.m b/GoogleSignIn/Tests/Unit/GIDVerifyAccountDetailTest.m index a5efdfff..afea8a12 100644 --- a/GoogleSignIn/Tests/Unit/GIDVerifyAccountDetailTest.m +++ b/GoogleSignIn/Tests/Unit/GIDVerifyAccountDetailTest.m @@ -65,9 +65,9 @@ - (void)setUp { _verifyAccountDetail = [[GIDVerifyAccountDetail alloc] init]; - GIDVerifiableAccountDetail *ageOver18Detail = - [[GIDVerifiableAccountDetail alloc] initWithAccountDetailType:GIDAccountDetailTypeAgeOver18]; - _verifiableAccountDetails = @[ageOver18Detail]; + GIDVerifiableAccountDetail *testAccountDetail = + [[GIDVerifiableAccountDetail alloc] initWithAccountDetailType:GIDAccountDetailTypeUnknown]; + _verifiableAccountDetails = @[testAccountDetail]; _fakeMainBundle = [[GIDFakeMainBundle alloc] initWithClientID:kClientId serverClientID:kServerClientId diff --git a/Samples/Swift/DaysUntilBirthday/DaysUntilBirthday.xcodeproj/project.pbxproj b/Samples/Swift/DaysUntilBirthday/DaysUntilBirthday.xcodeproj/project.pbxproj index f1f0664b..53d18171 100644 --- a/Samples/Swift/DaysUntilBirthday/DaysUntilBirthday.xcodeproj/project.pbxproj +++ b/Samples/Swift/DaysUntilBirthday/DaysUntilBirthday.xcodeproj/project.pbxproj @@ -7,11 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 641495132C405D0200C9A613 /* VerifiedAgeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 641495122C405D0200C9A613 /* VerifiedAgeViewModel.swift */; }; - 641495152C405E1400C9A613 /* VerificationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 641495142C405E1400C9A613 /* VerificationView.swift */; }; - 641495172C405E3600C9A613 /* VerificationLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 641495162C405E3600C9A613 /* VerificationLoader.swift */; }; - 6499D22A2C4B2F4200825B30 /* Verification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6499D2292C4B2F4200825B30 /* Verification.swift */; }; - 6499D22C2C4B3B1500825B30 /* AgeVerificationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6499D22B2C4B3B1500825B30 /* AgeVerificationView.swift */; }; 7345AD032703D9470020AFB1 /* DaysUntilBirthday.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7345AD022703D9470020AFB1 /* DaysUntilBirthday.swift */; }; 7345AD052703D9470020AFB1 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7345AD042703D9470020AFB1 /* ContentView.swift */; }; 7345AD072703D9480020AFB1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7345AD062703D9480020AFB1 /* Assets.xcassets */; }; @@ -58,11 +53,6 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 641495122C405D0200C9A613 /* VerifiedAgeViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerifiedAgeViewModel.swift; sourceTree = ""; }; - 641495142C405E1400C9A613 /* VerificationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerificationView.swift; sourceTree = ""; }; - 641495162C405E3600C9A613 /* VerificationLoader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerificationLoader.swift; sourceTree = ""; }; - 6499D2292C4B2F4200825B30 /* Verification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Verification.swift; sourceTree = ""; }; - 6499D22B2C4B3B1500825B30 /* AgeVerificationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AgeVerificationView.swift; sourceTree = ""; }; 7345ACFF2703D9470020AFB1 /* DaysUntilBirthday (iOS).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DaysUntilBirthday (iOS).app"; sourceTree = BUILT_PRODUCTS_DIR; }; 7345AD022703D9470020AFB1 /* DaysUntilBirthday.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DaysUntilBirthday.swift; sourceTree = ""; }; 7345AD042703D9470020AFB1 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; @@ -213,9 +203,7 @@ children = ( 7345AD042703D9470020AFB1 /* ContentView.swift */, 739FCC45270E467600C92042 /* BirthdayView.swift */, - 6499D22B2C4B3B1500825B30 /* AgeVerificationView.swift */, 7345AD112703D9C30020AFB1 /* SignInView.swift */, - 641495142C405E1400C9A613 /* VerificationView.swift */, 7345AD142703D9C30020AFB1 /* UserProfileImageView.swift */, ); path = Views; @@ -225,7 +213,6 @@ isa = PBXGroup; children = ( 739FCC47270E659A00C92042 /* Birthday.swift */, - 6499D2292C4B2F4200825B30 /* Verification.swift */, ); path = Models; sourceTree = ""; @@ -234,7 +221,6 @@ isa = PBXGroup; children = ( 7345AD162703D9C30020AFB1 /* AuthenticationViewModel.swift */, - 641495122C405D0200C9A613 /* VerifiedAgeViewModel.swift */, 736F49BB270E102C00580053 /* BirthdayViewModel.swift */, ); path = ViewModels; @@ -245,7 +231,6 @@ children = ( 7345AD172703D9C30020AFB1 /* GoogleSignInAuthenticator.swift */, 736F49B9270E05E200580053 /* BirthdayLoader.swift */, - 641495162C405E3600C9A613 /* VerificationLoader.swift */, 7345AD192703D9C30020AFB1 /* UserProfileImageLoader.swift */, ); path = Services; @@ -389,9 +374,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6499D22A2C4B2F4200825B30 /* Verification.swift in Sources */, 739FCC48270E659A00C92042 /* Birthday.swift in Sources */, - 6499D22C2C4B3B1500825B30 /* AgeVerificationView.swift in Sources */, 739FCC46270E467600C92042 /* BirthdayView.swift in Sources */, 7345AD1B2703D9C30020AFB1 /* SignInView.swift in Sources */, 7345AD212703D9C30020AFB1 /* GoogleSignInAuthenticator.swift in Sources */, @@ -400,12 +383,9 @@ 736F49BC270E102C00580053 /* BirthdayViewModel.swift in Sources */, 736F49BA270E05E200580053 /* BirthdayLoader.swift in Sources */, 7345AD242703D9C30020AFB1 /* UserProfileView.swift in Sources */, - 641495172C405E3600C9A613 /* VerificationLoader.swift in Sources */, 7345AD202703D9C30020AFB1 /* AuthenticationViewModel.swift in Sources */, - 641495132C405D0200C9A613 /* VerifiedAgeViewModel.swift in Sources */, 7345AD052703D9470020AFB1 /* ContentView.swift in Sources */, 7345AD032703D9470020AFB1 /* DaysUntilBirthday.swift in Sources */, - 641495152C405E1400C9A613 /* VerificationView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Samples/Swift/DaysUntilBirthday/DaysUntilBirthdayForPod.xcodeproj/project.pbxproj b/Samples/Swift/DaysUntilBirthday/DaysUntilBirthdayForPod.xcodeproj/project.pbxproj index 2cb5d1d9..d7dacb97 100644 --- a/Samples/Swift/DaysUntilBirthday/DaysUntilBirthdayForPod.xcodeproj/project.pbxproj +++ b/Samples/Swift/DaysUntilBirthday/DaysUntilBirthdayForPod.xcodeproj/project.pbxproj @@ -8,11 +8,6 @@ /* Begin PBXBuildFile section */ 4C6A2BA2321434ACBD2AF201 /* Pods_DaysUntilBirthdayForPod__macOS_.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 926A15D393D684C68E09FB0F /* Pods_DaysUntilBirthdayForPod__macOS_.framework */; }; - 641495072C3C90E100C9A613 /* VerificationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 641495062C3C90E100C9A613 /* VerificationView.swift */; }; - 6414950A2C3E094B00C9A613 /* VerifiedAgeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 641495092C3E094B00C9A613 /* VerifiedAgeViewModel.swift */; }; - 6414950C2C3E0C7A00C9A613 /* VerificationLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6414950B2C3E0C7A00C9A613 /* VerificationLoader.swift */; }; - 6499D22A2C4B2F4200825B30 /* Verification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6499D2292C4B2F4200825B30 /* Verification.swift */; }; - 6499D22C2C4B3B1500825B30 /* AgeVerificationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6499D22B2C4B3B1500825B30 /* AgeVerificationView.swift */; }; 7345AD032703D9470020AFB1 /* DaysUntilBirthday.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7345AD022703D9470020AFB1 /* DaysUntilBirthday.swift */; }; 7345AD052703D9470020AFB1 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7345AD042703D9470020AFB1 /* ContentView.swift */; }; 7345AD072703D9480020AFB1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7345AD062703D9480020AFB1 /* Assets.xcassets */; }; @@ -50,11 +45,6 @@ 1A129363EBB5DF1F41FAAB14 /* Pods-DaysUntilBirthdayForPod(macOS).release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DaysUntilBirthdayForPod(macOS).release.xcconfig"; path = "Target Support Files/Pods-DaysUntilBirthdayForPod(macOS)/Pods-DaysUntilBirthdayForPod(macOS).release.xcconfig"; sourceTree = ""; }; 29BEB027A694593FA0450863 /* Pods-DaysUntilBirthdayForPod(iOS).debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DaysUntilBirthdayForPod(iOS).debug.xcconfig"; path = "Target Support Files/Pods-DaysUntilBirthdayForPod(iOS)/Pods-DaysUntilBirthdayForPod(iOS).debug.xcconfig"; sourceTree = ""; }; 5CF615341A61D92D89389D44 /* Pods-DaysUntilBirthdayForPod (macOS).release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DaysUntilBirthdayForPod (macOS).release.xcconfig"; path = "Target Support Files/Pods-DaysUntilBirthdayForPod (macOS)/Pods-DaysUntilBirthdayForPod (macOS).release.xcconfig"; sourceTree = ""; }; - 641495062C3C90E100C9A613 /* VerificationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerificationView.swift; sourceTree = ""; }; - 641495092C3E094B00C9A613 /* VerifiedAgeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerifiedAgeViewModel.swift; sourceTree = ""; }; - 6414950B2C3E0C7A00C9A613 /* VerificationLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerificationLoader.swift; sourceTree = ""; }; - 6499D2292C4B2F4200825B30 /* Verification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Verification.swift; sourceTree = ""; }; - 6499D22B2C4B3B1500825B30 /* AgeVerificationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AgeVerificationView.swift; sourceTree = ""; }; 7345ACFF2703D9470020AFB1 /* DaysUntilBirthdayForPod (iOS).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DaysUntilBirthdayForPod (iOS).app"; sourceTree = BUILT_PRODUCTS_DIR; }; 7345AD022703D9470020AFB1 /* DaysUntilBirthday.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DaysUntilBirthday.swift; sourceTree = ""; }; 7345AD042703D9470020AFB1 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; @@ -205,8 +195,6 @@ children = ( 7345AD042703D9470020AFB1 /* ContentView.swift */, 739FCC45270E467600C92042 /* BirthdayView.swift */, - 6499D22B2C4B3B1500825B30 /* AgeVerificationView.swift */, - 641495062C3C90E100C9A613 /* VerificationView.swift */, 7345AD112703D9C30020AFB1 /* SignInView.swift */, 7345AD142703D9C30020AFB1 /* UserProfileImageView.swift */, ); @@ -217,7 +205,6 @@ isa = PBXGroup; children = ( 739FCC47270E659A00C92042 /* Birthday.swift */, - 6499D2292C4B2F4200825B30 /* Verification.swift */, ); path = Models; sourceTree = ""; @@ -227,7 +214,6 @@ children = ( 7345AD162703D9C30020AFB1 /* AuthenticationViewModel.swift */, 736F49BB270E102C00580053 /* BirthdayViewModel.swift */, - 641495092C3E094B00C9A613 /* VerifiedAgeViewModel.swift */, ); path = ViewModels; sourceTree = ""; @@ -236,7 +222,6 @@ isa = PBXGroup; children = ( 7345AD172703D9C30020AFB1 /* GoogleSignInAuthenticator.swift */, - 6414950B2C3E0C7A00C9A613 /* VerificationLoader.swift */, 736F49B9270E05E200580053 /* BirthdayLoader.swift */, 7345AD192703D9C30020AFB1 /* UserProfileImageLoader.swift */, ); @@ -427,18 +412,13 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6499D22A2C4B2F4200825B30 /* Verification.swift in Sources */, 739FCC48270E659A00C92042 /* Birthday.swift in Sources */, - 6499D22C2C4B3B1500825B30 /* AgeVerificationView.swift in Sources */, - 641495072C3C90E100C9A613 /* VerificationView.swift in Sources */, 739FCC46270E467600C92042 /* BirthdayView.swift in Sources */, 7345AD1B2703D9C30020AFB1 /* SignInView.swift in Sources */, 7345AD212703D9C30020AFB1 /* GoogleSignInAuthenticator.swift in Sources */, - 6414950A2C3E094B00C9A613 /* VerifiedAgeViewModel.swift in Sources */, 7345AD232703D9C30020AFB1 /* UserProfileImageLoader.swift in Sources */, 7345AD1E2703D9C30020AFB1 /* UserProfileImageView.swift in Sources */, 736F49BC270E102C00580053 /* BirthdayViewModel.swift in Sources */, - 6414950C2C3E0C7A00C9A613 /* VerificationLoader.swift in Sources */, 736F49BA270E05E200580053 /* BirthdayLoader.swift in Sources */, 7345AD242703D9C30020AFB1 /* UserProfileView.swift in Sources */, 7345AD202703D9C30020AFB1 /* AuthenticationViewModel.swift in Sources */, diff --git a/Samples/Swift/DaysUntilBirthday/DaysUntilBirthdayUITests(iOS)/DaysUntilBirthdayUITests_iOS.swift b/Samples/Swift/DaysUntilBirthday/DaysUntilBirthdayUITests(iOS)/DaysUntilBirthdayUITests_iOS.swift index f35f3761..0515b908 100644 --- a/Samples/Swift/DaysUntilBirthday/DaysUntilBirthdayUITests(iOS)/DaysUntilBirthdayUITests_iOS.swift +++ b/Samples/Swift/DaysUntilBirthday/DaysUntilBirthdayUITests(iOS)/DaysUntilBirthdayUITests_iOS.swift @@ -23,6 +23,8 @@ class DaysUntilBirthdayUITests_iOS: XCTestCase { "Would you like to save this password to use with apps and websites?" private let signInDisclaimerHeaderText = "Sign in to Days Until Birthday" + private let returningUserSignInDisclaimerHeaderText = + "You’re signing back in to Days Until Birthday" private let accessHeaderText = "Days Until Birthday wants access to your Google Account" private let additionalAccessHeaderText = "Days Until Birthday wants additional access to your Google Account" private let appTrustWarningText = "Make sure you trust Days Until Birthday" @@ -70,27 +72,6 @@ class DaysUntilBirthdayUITests_iOS: XCTestCase { return XCTFail("Signing out should return user to sign in view") } } - - func testFetchVerificationSignalAndDisconnect() { - sampleApp.launch() - - XCTAssertTrue(navigateToVerifyMyAge()) - XCTAssertTrue(displayVerificationSignal()) - - guard sampleApp - .navigationBars - .buttons["Sign-in with Google"] - .waitForExistence(timeout: timeout) else { - return XCTFail("Failed to show navigation button back to Sign In View") - } - sampleApp.navigationBars.buttons["Sign-in with Google"].tap() - - guard sampleApp - .buttons["GoogleSignInButton"] - .waitForExistence(timeout: timeout) else { - return XCTFail("Failed to return user to sign in view") - } - } } extension DaysUntilBirthdayUITests_iOS { @@ -212,7 +193,7 @@ extension DaysUntilBirthdayUITests_iOS { return false } - handleSignInDisclaimerIfNeeded() + handleReturningUserSignInDisclaimerIfNeeded() handleAccessRequestIfNeeded() return true @@ -285,83 +266,6 @@ extension DaysUntilBirthdayUITests_iOS { return true } - /// Navigates to the verification view from the user profile view. - /// - returns: `true` if the navigation was performed successfully. - /// - note: This method will attempt to find a pop up asking for permission to - /// sign in with Google. - func navigateToVerifyMyAge() -> Bool { - guard sampleApp.buttons["Verify"] - .waitForExistence(timeout: timeout) else { - XCTFail("Failed to find button navigating to verify my age view") - return false - } - sampleApp.buttons["Verify"].tap() - - if springboardApp - .staticTexts[signInStaticText] - .waitForExistence(timeout: timeout) { - guard springboardApp - .buttons["Continue"] - .waitForExistence(timeout: timeout) else { - XCTFail("Failed to find 'Continue' button") - return false - } - springboardApp.buttons["Continue"].tap() - - if sampleApp - .staticTexts[Credential.email.rawValue] - .waitForExistence(timeout: timeout) { - XCTAssertTrue(useExistingSignIn()) - } else { - XCTAssertTrue(signInForTheFirstTime()) - } - - handleConsentRequestIfNeeded() - } - - guard sampleApp.staticTexts["Verified Account!"] - .waitForExistence(timeout: timeout) else { - XCTFail("Failed to show age verification view") - return false - } - - guard sampleApp.staticTexts["Access Token:"] - .waitForExistence(timeout: timeout) else { - XCTFail("Access Token element did not appear") - return false - } - - return true - } - - /// Displays a sheet over the Verification view with the fetched verification signal.. - /// - returns: `true` if the display was performed successfully. - func displayVerificationSignal() -> Bool { - guard sampleApp.buttons["Fetch Age Verification Signal"] - .waitForExistence(timeout: timeout) else { - XCTFail("Failed to find button to refresh access token") - return false - } - sampleApp.buttons["Fetch Age Verification Signal"].tap() - - guard sampleApp.staticTexts["User is verified over 18!"] - .waitForExistence(timeout: timeout) else { - XCTFail("Failed to show age verification signal view") - return false - } - - guard sampleApp - .navigationBars - .buttons["Close"] - .waitForExistence(timeout: timeout) else { - XCTFail("Failed to show close button back to age signal view") - return false - } - sampleApp.navigationBars.buttons["Close"].tap() - - return true - } - /// Proceeds through the view with header "Days Until Birthday wants additional access to your Google Account" if needed. func handleAccessRequestIfNeeded() { let currentlyShowingAdditionalAccessHeaderText = @@ -401,6 +305,18 @@ extension DaysUntilBirthdayUITests_iOS { } } + func handleReturningUserSignInDisclaimerIfNeeded() { + let currentlyShowingReturningUserSignInDisclaimer = + sampleApp.staticTexts[returningUserSignInDisclaimerHeaderText] + .waitForExistence(timeout: timeout) && + sampleApp.buttons["Continue"] + .waitForExistence(timeout: timeout) + + if currentlyShowingReturningUserSignInDisclaimer { + sampleApp.buttons["Continue"].tap() + } + } + /// This method looks for an account in the current view that reflects an already-signed-in state, and taps it. /// - returns: true if the signed-in account was found and tapped, otherwise returns false. func findAndTapExistingSignedInEmail() -> Bool { diff --git a/Samples/Swift/DaysUntilBirthday/Shared/Models/Verification.swift b/Samples/Swift/DaysUntilBirthday/Shared/Models/Verification.swift deleted file mode 100644 index 5f9c69e4..00000000 --- a/Samples/Swift/DaysUntilBirthday/Shared/Models/Verification.swift +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2024 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import Foundation - -struct Verification: Decodable { - let signal: String - - init(from decoder: Decoder) throws { - let container = try decoder.singleValueContainer() - self.signal = try container.decode(String.self) - } - - init(signal: String) { - self.signal = signal - } - - static let noVerificationSignal: Verification = Verification(signal: "No signal found") -} - -struct VerificationResponse: Decodable { - let verifications: [Verification] - let firstVerification: Verification - - init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - self.verifications = try container.decode([Verification].self, forKey:.ageVerificationResults) - guard let first = verifications.first else { - throw Error.noVerificationInResult - } - self.firstVerification = first - } -} - -extension VerificationResponse { - enum CodingKeys: String, CodingKey { - case ageVerificationResults - } -} - -extension VerificationResponse { - enum Error: Swift.Error { - case noVerificationInResult - } -} - -/* - { - "name": "ageVerification", - "verificationId": "A verification id string", - "ageVerificationResults": [ - "AGE_PENDING" - ] - } - */ diff --git a/Samples/Swift/DaysUntilBirthday/Shared/Services/VerificationLoader.swift b/Samples/Swift/DaysUntilBirthday/Shared/Services/VerificationLoader.swift deleted file mode 100644 index 380dce36..00000000 --- a/Samples/Swift/DaysUntilBirthday/Shared/Services/VerificationLoader.swift +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright 2024 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import Combine -import Foundation -import GoogleSignIn - -#if os(iOS) - -/// An observable class for verifying via Google. -final class VerificationLoader: ObservableObject { - /// The `Verification` object of the current user holding the age verification signal. - /// - note: Changes to this property will be published to observers. - @Published private(set) var verification: Verification? - - private var verifiedAgeViewModel: VerifiedAgeViewModel - private let baseUrlString = "https://verifywithgoogle.googleapis.com/v1/ageVerification" - - private lazy var components: URLComponents? = { - var comps = URLComponents(string: baseUrlString) - return comps - }() - - private lazy var request: URLRequest? = { - guard let components = components, let url = components.url else { - return nil - } - return URLRequest(url: url) - }() - - /// Creates an instance of this loader. - /// - parameter verifiedAgeViewModel: The view model to use to set age verification signal on. - init(verifiedViewAgeModel: VerifiedAgeViewModel) { - self.verifiedAgeViewModel = verifiedViewAgeModel - } - - private func createSession(verifyResult: GIDVerifiedAccountDetailResult, - completion: @escaping (Result) -> Void) { - guard let token = verifyResult.accessToken?.tokenString else { - completion(.failure(.couldNotCreateURLSession)) - return - } - let configuration = URLSessionConfiguration.default - configuration.httpAdditionalHeaders = [ - "Authorization": "Bearer \(token)" - ] - let session = URLSession(configuration: configuration) - completion(.success(session)) - } - - /// Creates a `Publisher` to fetch a user's `Verification` holding their age verification signal. - /// - parameter completion: A closure passing back the `AnyPublisher` - /// upon success. - func verificationPublisher(verifyResult: GIDVerifiedAccountDetailResult, - completion: @escaping (AnyPublisher) -> Void) { - createSession(verifyResult: verifyResult) { [weak self] result in - switch result { - case .success(let urlSession): - guard let request = self?.request else { - return completion(Fail(error:.couldNotCreateURLRequest).eraseToAnyPublisher()) - } - let verificationPublisher = urlSession.dataTaskPublisher(for: request) - .tryMap { data, error -> Verification in - let decoder = JSONDecoder() - let verificationResponse = try decoder.decode(VerificationResponse.self, from: data) - return verificationResponse.firstVerification - } - .mapError { error -> Error in - guard let loaderError = error as? Error else { - return Error.couldNotFetchVerificationSignal(underlying: error) - } - return loaderError - } - .receive(on: DispatchQueue.main) - .eraseToAnyPublisher() - completion(verificationPublisher) - case .failure(let error): - completion(Fail(error: error).eraseToAnyPublisher()) - } - } - } - - /// Verifies the user's age is over 18 based upon the selected account. - /// - note: Successful calls to this method will set the `verificationState` property of the - /// `verifiedAgeViewModel` instance passed to the initializer. - func verifyUserAgeOver18() { - guard let rootViewController = UIApplication.shared.windows.first?.rootViewController else { - print("There is no root view controller!") - return - } - - let accountDetails: [GIDVerifiableAccountDetail] = [ - GIDVerifiableAccountDetail(accountDetailType: .ageOver18) - ] - let verifyAccountDetail = GIDVerifyAccountDetail() - verifyAccountDetail.verifyAccountDetails(accountDetails, presenting: rootViewController) { - verifyResult, error in - guard let verifyResult else { - self.verifiedAgeViewModel.verificationState = .unverified - print("Error! \(String(describing: error))") - return - } - self.verifiedAgeViewModel.verificationState = .verified(verifyResult) - } - } - - private var cancellable: AnyCancellable? - - /// Fetches the age verification signal of the current user. - func fetchAgeVerificationSignal(verifyResult: GIDVerifiedAccountDetailResult, - completion: @escaping () -> Void) { - self.verificationPublisher(verifyResult: verifyResult) { publisher in - self.cancellable = publisher.sink( - receiveCompletion: { sinkCompletion in - if case .failure(let error) = sinkCompletion { - self.verification = Verification.noVerificationSignal - print("Error retrieving age verification: \(error)") - completion() - } - }, - receiveValue: { verification in - self.verification = verification - completion() - } - ) - } - } -} - -extension VerificationLoader { - /// An error representing what went wrong in fetching a user's number of day until their birthday. - enum Error: Swift.Error { - case couldNotFetchVerificationSignal(underlying: Swift.Error) - case couldNotCreateURLRequest - case couldNotCreateURLSession - } -} - -#endif diff --git a/Samples/Swift/DaysUntilBirthday/Shared/ViewModels/VerifiedAgeViewModel.swift b/Samples/Swift/DaysUntilBirthday/Shared/ViewModels/VerifiedAgeViewModel.swift deleted file mode 100644 index 642d5b56..00000000 --- a/Samples/Swift/DaysUntilBirthday/Shared/ViewModels/VerifiedAgeViewModel.swift +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2024 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import SwiftUI -import GoogleSignIn - -#if os(iOS) - -/// A class conforming to `ObservableObject` used to represent a user's verification status. -final class VerifiedAgeViewModel: ObservableObject { - /// The user's account verification status. - /// - note: This will publish updates when its value changes. - @Published var verificationState: VerificationState - /// The age verification signal telling whether the user's age is over 18 or pending. - /// - note: This will publish updates when its value changes. - @Published var ageVerificationSignal: AgeVerificationSignal - /// Indicates whether the view to display the user's age is over 18 should be shown. - /// - note: This will publish updates when its value changes. - @Published var isShowingAgeVerificationSignal = false - /// Indicates whether an alert should be displayed to inform the user that they are not verified as over 18. - /// - note: This will publish updates when its value changes. - @Published var isShowingAgeVerificationAlert = false - - /// Minimum time to expiration for a restored access token (10 minutes). - let kMinimumRestoredAccessTokenTimeToExpire: TimeInterval = 600.0 - - private lazy var loader: VerificationLoader = { - return VerificationLoader(verifiedViewAgeModel: self) - }() - - /// An enumeration representing possible states of an age verification signal. - enum AgeVerificationSignal: String { - /// The user's age has been verified to be over 18. - case ageOver18Standard = "AGE_OVER_18_STANDARD" - /// The user's age verification is pending. - case agePending = "AGE_PENDING" - /// Indicates there was no age verification signal found. - case noAgeVerificationSignal = "Signal Unavailable" - } - - /// Creates an instance of this view model. - init() { - self.verificationState = .unverified - self.ageVerificationSignal = .noAgeVerificationSignal - } - - /// Verifies the user's age is over 18. - func verifyUserAgeOver18() { - switch self.verificationState { - case .verified(let result): - if let expirationDate = result.accessToken?.expirationDate, - expirationDate.timeIntervalSinceNow <= kMinimumRestoredAccessTokenTimeToExpire { - result.refreshTokens { (result, error) in - self.verificationState = .verified(result) - } - } - case .unverified: - loader.verifyUserAgeOver18() - } - } - - /// Fetches the age verification signal representing whether the user's age is over 18 or pending. - func fetchAgeVerificationSignal(verifyResult: GIDVerifiedAccountDetailResult) { - loader.fetchAgeVerificationSignal(verifyResult: verifyResult) { - let signal = self.loader.verification?.signal ?? "" - self.ageVerificationSignal = AgeVerificationSignal(rawValue: signal) ?? - .noAgeVerificationSignal - - if (self.ageVerificationSignal == .ageOver18Standard) { - self.isShowingAgeVerificationSignal = true - self.isShowingAgeVerificationAlert = false - } else { - self.isShowingAgeVerificationSignal = false - self.isShowingAgeVerificationAlert = true - } - } - } -} - -extension VerifiedAgeViewModel { - /// An enumeration representing verified status. - enum VerificationState { - /// The user's account is verified and is the associated value of this case. - case verified(GIDVerifiedAccountDetailResult) - /// The user's account is not verified. - case unverified - } -} - -#endif diff --git a/Samples/Swift/DaysUntilBirthday/Shared/Views/AgeVerificationView.swift b/Samples/Swift/DaysUntilBirthday/Shared/Views/AgeVerificationView.swift deleted file mode 100644 index 2b3c0be8..00000000 --- a/Samples/Swift/DaysUntilBirthday/Shared/Views/AgeVerificationView.swift +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2024 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import SwiftUI -import GoogleSignIn - -struct AgeVerificationResultView: View { - /// The age verification signal telling whether the user's age is over 18 or pending. - let ageVerificationSignal: String - - @Environment(\.presentationMode) var presentationMode - - var body: some View { - NavigationView { - VStack { - Text("Age Verification Signal: \(ageVerificationSignal)") - Spacer() - } - .navigationTitle("User is verified over 18!") - .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { - Button("Close") { - presentationMode.wrappedValue.dismiss() - } - } - } - } - } -} diff --git a/Samples/Swift/DaysUntilBirthday/Shared/Views/SignInView.swift b/Samples/Swift/DaysUntilBirthday/Shared/Views/SignInView.swift index 2d7eb0aa..5eecffcc 100644 --- a/Samples/Swift/DaysUntilBirthday/Shared/Views/SignInView.swift +++ b/Samples/Swift/DaysUntilBirthday/Shared/Views/SignInView.swift @@ -19,10 +19,6 @@ import GoogleSignInSwift struct SignInView: View { @EnvironmentObject var authViewModel: AuthenticationViewModel -#if os(iOS) - @State var verificationflowInitiated = false - @StateObject var verifiedAgeViewModel = VerifiedAgeViewModel() -#endif @ObservedObject var vm = GoogleSignInButtonViewModel() var body: some View { @@ -73,38 +69,6 @@ struct SignInView: View { #endif } } - HStack { - VStack { -#if os(iOS) - Text("Verify your Age") - .font(.title) - .fontWeight(.semibold) - .frame(maxWidth: .infinity, alignment: .leading) - .padding() - Button(action: { - verifiedAgeViewModel.verifyUserAgeOver18() - verificationflowInitiated = true - }) { - Text("Verify") - .font(.headline) - .foregroundColor(.gray) - .padding() - .frame(maxWidth: .infinity, alignment: .leading) - .background(Color.white) - .overlay( - RoundedRectangle(cornerRadius: 2) - .stroke(Color.gray.opacity(0.3), lineWidth: 1)) - .shadow(color: Color.black.opacity(0.1), radius: 3, x: 0, y: 2) - } - .padding(.horizontal) - NavigationLink(isActive: $verificationflowInitiated) { - VerificationView(verifiedAgeViewModel: verifiedAgeViewModel) - } label: { - EmptyView() - } -#endif - } - } Spacer() } } diff --git a/Samples/Swift/DaysUntilBirthday/Shared/Views/VerificationView.swift b/Samples/Swift/DaysUntilBirthday/Shared/Views/VerificationView.swift deleted file mode 100644 index fe072b11..00000000 --- a/Samples/Swift/DaysUntilBirthday/Shared/Views/VerificationView.swift +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2024 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import SwiftUI -import GoogleSignIn - -struct VerificationView: View { - @ObservedObject var verifiedAgeViewModel: VerifiedAgeViewModel - - var body: some View { - switch verifiedAgeViewModel.verificationState { - case .verified(let result): - Button("Fetch Age Verification Signal") { - verifiedAgeViewModel.fetchAgeVerificationSignal(verifyResult: result) - } - .padding(10) - .overlay( - RoundedRectangle(cornerRadius: 30) - .stroke(Color.gray) - ) - .padding(.bottom) - if #available(iOS 15, *) { - VStack(alignment:.leading) { - Text("List of result object properties:") - .font(.headline) - - HStack(alignment: .top) { - Text("Access Token:") - Text(result.accessToken?.tokenString ?? "Not available") - } - HStack(alignment: .top) { - Text("Refresh Token:") - Text(result.refreshToken?.tokenString ?? "Not available") - } - HStack { - Text("Expiration:") - if let expirationDate = result.accessToken?.expirationDate { - Text(formatDateWithDateFormatter(expirationDate)) - } else { - Text("Not available") - } - } - Spacer() - } - .navigationTitle("Verified Account!") - .toolbar { - ToolbarItemGroup(placement: .navigationBarTrailing) { - Button(NSLocalizedString("Refresh", comment: "Refresh button"), - action:{refresh(results: result)}) - } - } - .sheet(isPresented: $verifiedAgeViewModel.isShowingAgeVerificationSignal) { - AgeVerificationResultView(ageVerificationSignal: verifiedAgeViewModel.ageVerificationSignal.rawValue) - } - .alert("Oh no! User is not verified over 18.", - isPresented: $verifiedAgeViewModel.isShowingAgeVerificationAlert) { - Button("OK", role: .cancel) { } - } message: { - Text("Age Verification Signal: \(verifiedAgeViewModel.ageVerificationSignal.rawValue)") - } - } - case .unverified: - ProgressView() - .navigationTitle(NSLocalizedString("Unverified account", - comment: "Unverified account label")) - } - } - - func formatDateWithDateFormatter(_ date: Date) -> String { - let dateFormatter = DateFormatter() - dateFormatter.dateStyle = .medium - dateFormatter.timeStyle = .short - return dateFormatter.string(from: date) - } - - func refresh(results: GIDVerifiedAccountDetailResult) { - results.refreshTokens { (result, error) in - verifiedAgeViewModel.verificationState = .verified(result) - } - } -}