Skip to content

Commit 00c7530

Browse files
committed
(chore): Add GID and SignInViewModel
1 parent eb02aa9 commit 00c7530

File tree

6 files changed

+307
-0
lines changed

6 files changed

+307
-0
lines changed

ScribbleLab.xcodeproj/project.pbxproj

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,22 @@
6262
388DC81F2CCBE37200C80FF9 /* ScribbleLabUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ScribbleLabUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
6363
/* End PBXFileReference section */
6464

65+
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
66+
387BC5162CCD1BFA00B3D2A4 /* Exceptions for "ScribbleLab" folder in "ScribbleLab" target */ = {
67+
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
68+
membershipExceptions = (
69+
Info.plist,
70+
);
71+
target = 388DC8032CCBE36F00C80FF9 /* ScribbleLab */;
72+
};
73+
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
74+
6575
/* Begin PBXFileSystemSynchronizedRootGroup section */
6676
388DC8062CCBE36F00C80FF9 /* ScribbleLab */ = {
6777
isa = PBXFileSystemSynchronizedRootGroup;
78+
exceptions = (
79+
387BC5162CCD1BFA00B3D2A4 /* Exceptions for "ScribbleLab" folder in "ScribbleLab" target */,
80+
);
6881
path = ScribbleLab;
6982
sourceTree = "<group>";
7083
};
@@ -483,6 +496,7 @@
483496
ENABLE_HARDENED_RUNTIME = YES;
484497
ENABLE_PREVIEWS = YES;
485498
GENERATE_INFOPLIST_FILE = YES;
499+
INFOPLIST_FILE = ScribbleLab/Info.plist;
486500
INFOPLIST_KEY_CFBundleDisplayName = ScribbleLab;
487501
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
488502
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
@@ -636,6 +650,7 @@
636650
ENABLE_HARDENED_RUNTIME = YES;
637651
ENABLE_PREVIEWS = YES;
638652
GENERATE_INFOPLIST_FILE = YES;
653+
INFOPLIST_FILE = ScribbleLab/Info.plist;
639654
INFOPLIST_KEY_CFBundleDisplayName = ScribbleLab;
640655
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
641656
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
@@ -843,6 +858,7 @@
843858
ENABLE_HARDENED_RUNTIME = YES;
844859
ENABLE_PREVIEWS = YES;
845860
GENERATE_INFOPLIST_FILE = YES;
861+
INFOPLIST_FILE = ScribbleLab/Info.plist;
846862
INFOPLIST_KEY_CFBundleDisplayName = ScribbleLab;
847863
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
848864
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
@@ -887,6 +903,7 @@
887903
ENABLE_HARDENED_RUNTIME = YES;
888904
ENABLE_PREVIEWS = YES;
889905
GENERATE_INFOPLIST_FILE = YES;
906+
INFOPLIST_FILE = ScribbleLab/Info.plist;
890907
INFOPLIST_KEY_CFBundleDisplayName = ScribbleLab;
891908
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.education";
892909
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//
2+
// Application_utility.swift
3+
// ScribbleLab
4+
//
5+
// Copyright (c) 2024 ScribbleLabApp LLC. - All rights reserved.
6+
//
7+
// Redistribution and use in source and binary forms, with or without
8+
// modification, are permitted provided that the following conditions are met:
9+
//
10+
// 1. Redistributions of source code must retain the above copyright notice, this
11+
// list of conditions and the following disclaimer.
12+
//
13+
// 2. Redistributions in binary form must reproduce the above copyright notice,
14+
// this list of conditions and the following disclaimer in the documentation
15+
// and/or other materials provided with the distribution.
16+
//
17+
// 3. Neither the name of the copyright holder nor the names of its
18+
// contributors may be used to endorse or promote products derived from
19+
// this software without specific prior written permission.
20+
//
21+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24+
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25+
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26+
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27+
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28+
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29+
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
32+
import UIKit
33+
import SwiftUI
34+
35+
final class Application_Utility: UIViewController {
36+
static var rootViewController: UIViewController {
37+
guard let screen = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
38+
return .init()
39+
}
40+
41+
guard let root = screen.windows.first?.rootViewController else {
42+
return .init()
43+
}
44+
45+
return root
46+
}
47+
}

ScribbleLab/Core/Authentication/Models/SignInViewModel.swift

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,68 @@
2929
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3030
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3131

32+
import Combine
3233
import Foundation
34+
import Firebase
35+
import FirebaseAuth
36+
import ScribbleFoundation
37+
38+
class SignInViewModel: ObservableObject {
39+
40+
/// Published property holding the entered email.
41+
@Published var password: String = ""
42+
43+
/// Published property holding the entered password.
44+
@Published var email: String = ""
45+
46+
/// Published property determining if the log-in button is enabled.
47+
///
48+
/// The button is enabled when the entered password contains at least 8 characters,
49+
/// the email contains an '@', and the username is not empty.
50+
///
51+
@Published var loginButtonDisabled: Bool = true
52+
53+
var cancellables = Set<AnyCancellable>()
54+
55+
// I have no f*** clue of what is happening here right now - Never touch this pice of
56+
// code or else you'll die
57+
// Thank you very much for your understanding
58+
// Whishing you a great day!
59+
init() {
60+
$email
61+
.combineLatest($password)
62+
.map { [weak self] email, password in
63+
self?.validateInput(email: email, password: password) ?? false
64+
}
65+
.assign(to: \.loginButtonDisabled, on: self)
66+
.store(in: &cancellables)
67+
}
68+
69+
/// Validates the email and password for login.
70+
/// - Parameters:
71+
/// - email: The email to validate.
72+
/// - password: The password to validate.
73+
/// - Returns: A boolean indicating whether the input is valid for login.
74+
private func validateInput(email: String, password: String) -> Bool {
75+
return !email.isEmpty && validateEmail(withEmail: email) && password.count >= 8
76+
}
77+
78+
func validateEmail(withEmail email: String) -> Bool {
79+
return Validation.isValidEmail(email)
80+
}
81+
82+
func signIn() async throws {
83+
try await SCIDAuthService.shared.logIn(withEmail: email, password: password)
84+
}
85+
86+
deinit {
87+
cancellables.forEach { $0.cancel() }
88+
cancellables.removeAll()
89+
90+
Task {
91+
await ScribbleLabApp().logger.log(
92+
"SignInViewModel succesfully deinitialized - SCRG-S0"
93+
)
94+
}
95+
}
96+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
//
2+
// SignInWithGoogleViewModel.swift
3+
// ScribbleLab · Authentication
4+
//
5+
// Copyright (c) 2024 ScribbleLabApp LLC. - All rights reserved.
6+
//
7+
// Redistribution and use in source and binary forms, with or without
8+
// modification, are permitted provided that the following conditions are met:
9+
//
10+
// 1. Redistributions of source code must retain the above copyright notice, this
11+
// list of conditions and the following disclaimer.
12+
//
13+
// 2. Redistributions in binary form must reproduce the above copyright notice,
14+
// this list of conditions and the following disclaimer in the documentation
15+
// and/or other materials provided with the distribution.
16+
//
17+
// 3. Neither the name of the copyright holder nor the names of its
18+
// contributors may be used to endorse or promote products derived from
19+
// this software without specific prior written permission.
20+
//
21+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24+
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25+
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26+
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27+
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28+
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29+
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
32+
import Foundation
33+
import Firebase
34+
import FirebaseAuth
35+
import GoogleSignIn
36+
import ScribbleFoundation
37+
38+
class SignInWithGoogleViewModel: ObservableObject {
39+
@Published var isLogInSucceded: Bool = false
40+
41+
// swiftlint:disable:next function_body_length
42+
func proceedWithGoogle() {
43+
guard let clientID = FirebaseApp.app()?.options.clientID else {
44+
Task {
45+
await ScribbleLabApp().logger.error(
46+
"FIR/GID Client ID is not available. GID-E115"
47+
)
48+
}
49+
return
50+
}
51+
52+
let config = GIDConfiguration(clientID: clientID)
53+
GIDSignIn.sharedInstance.configuration = config
54+
55+
GIDSignIn.sharedInstance.signIn(
56+
withPresenting: Application_Utility.rootViewController
57+
) { user, error in
58+
if let error = error {
59+
Task {
60+
await ScribbleLabApp().logger.error(
61+
"Failed to present GID OAuth sheet with error \(error.localizedDescription) - GID-E110"
62+
)
63+
}
64+
return
65+
}
66+
67+
guard let user = user?.user, let idToken = user.idToken else {
68+
Task {
69+
await ScribbleLabApp().logger.error(
70+
"User or ID Token is not available. GID-E116"
71+
)
72+
}
73+
return
74+
}
75+
76+
let accessToken = user.accessToken
77+
let credential = GoogleAuthProvider.credential(
78+
withIDToken: idToken.tokenString,
79+
accessToken: accessToken.tokenString
80+
)
81+
82+
Auth.auth().signIn(with: credential) { res, error in
83+
if let error = error {
84+
Task {
85+
await ScribbleLabApp().logger.error(
86+
"Failed to sign in using GID with error \(error.localizedDescription) - GID-E118"
87+
)
88+
}
89+
return
90+
}
91+
92+
guard let user = res?.user else {
93+
Task {
94+
await ScribbleLabApp().logger.error(
95+
"User is not available after sign-in. - GID-E119")
96+
}
97+
return
98+
}
99+
print("User signed in: \(user.uid) - SCID-S0")
100+
}
101+
}
102+
}
103+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
//
2+
// SignUpViewModel.swift
3+
// ScribbleLab · Authentication
4+
//
5+
// Copyright (c) 2024 ScribbleLabApp LLC. - All rights reserved.
6+
//
7+
// Redistribution and use in source and binary forms, with or without
8+
// modification, are permitted provided that the following conditions are met:
9+
//
10+
// 1. Redistributions of source code must retain the above copyright notice, this
11+
// list of conditions and the following disclaimer.
12+
//
13+
// 2. Redistributions in binary form must reproduce the above copyright notice,
14+
// this list of conditions and the following disclaimer in the documentation
15+
// and/or other materials provided with the distribution.
16+
//
17+
// 3. Neither the name of the copyright holder nor the names of its
18+
// contributors may be used to endorse or promote products derived from
19+
// this software without specific prior written permission.
20+
//
21+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24+
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25+
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26+
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27+
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28+
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29+
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
32+
import Combine
33+
import Foundation
34+
import Firebase
35+
import FirebaseAuth
36+
import ScribbleFoundation
37+
38+
class SignUpViewModel: ObservableObject {
39+
40+
@Published var email: String = ""
41+
@Published var password: String = ""
42+
@Published var username: String = ""
43+
44+
/// Published property determining if the sign-up button is enabled.
45+
///
46+
/// The button is enabled when the entered password contains at least 8 characters,
47+
/// the email contains an '@', and the username is not empty.
48+
///
49+
@Published var isSignUpButtonEnabled = false
50+
51+
private var cancellables = Set<AnyCancellable>()
52+
53+
54+
55+
init() {}
56+
57+
58+
deinit {}
59+
}

ScribbleLab/Info.plist

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>FirebaseAutomaticScreenReportingEnabled</key>
6+
<false/>
7+
<key>CFBundleURLTypes</key>
8+
<array>
9+
<dict>
10+
<key>CFBundleTypeRole</key>
11+
<string>Editor</string>
12+
<key>CFBundleURLName</key>
13+
<string>com.googleusercontent.apps.357715374736-ptifl9j6ranh8fvgq9ue3d6oivq864v8</string>
14+
</dict>
15+
</array>
16+
</dict>
17+
</plist>

0 commit comments

Comments
 (0)