Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

소셜 로그인 연동 #319

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions SNUTT-2022/SNUTT.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
738407102B6060F800007E62 /* ThemeState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 738406F82B57154400007E62 /* ThemeState.swift */; };
73AB84D22C35128B0075DE83 /* IntegrateAccountScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73AB84D12C35128B0075DE83 /* IntegrateAccountScene.swift */; };
73AB84D42C3514080075DE83 /* IntegrateAccountViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73AB84D32C3514080075DE83 /* IntegrateAccountViewModel.swift */; };
73B6E0882CCB34B2006DD4F0 /* SocialProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73B6E0862CCB34AA006DD4F0 /* SocialProvider.swift */; };
B800A38B2B76132C008E8D84 /* SearchTimeMaskDto.swift in Sources */ = {isa = PBXBuildFile; fileRef = B800A38A2B76132C008E8D84 /* SearchTimeMaskDto.swift */; };
B800A38C2B77BD78008E8D84 /* SearchTimeMaskDto.swift in Sources */ = {isa = PBXBuildFile; fileRef = B800A38A2B76132C008E8D84 /* SearchTimeMaskDto.swift */; };
B82EA54C2B62C8490029FDF3 /* LectureMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B82EA54B2B62C8490029FDF3 /* LectureMapView.swift */; };
Expand Down Expand Up @@ -377,6 +378,7 @@
738407042B577E9000007E62 /* ThemeDetailScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeDetailScene.swift; sourceTree = "<group>"; };
73AB84D12C35128B0075DE83 /* IntegrateAccountScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntegrateAccountScene.swift; sourceTree = "<group>"; };
73AB84D32C3514080075DE83 /* IntegrateAccountViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntegrateAccountViewModel.swift; sourceTree = "<group>"; };
73B6E0862CCB34AA006DD4F0 /* SocialProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocialProvider.swift; sourceTree = "<group>"; };
B800A38A2B76132C008E8D84 /* SearchTimeMaskDto.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchTimeMaskDto.swift; sourceTree = "<group>"; };
B82EA54B2B62C8490029FDF3 /* LectureMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LectureMapView.swift; sourceTree = "<group>"; };
B82EA54D2B6393190029FDF3 /* KakaoMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KakaoMapView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1040,6 +1042,7 @@
731D9FFC297BC5060027BA25 /* Bookmark.swift */,
738406ED2B57107C00007E62 /* Theme.swift */,
B84A4EA02B6035EE00C1E1A0 /* Building.swift */,
73B6E0862CCB34AA006DD4F0 /* SocialProvider.swift */,
);
path = Models;
sourceTree = "<group>";
Expand Down Expand Up @@ -1601,6 +1604,7 @@
BE9413BF28C2157600171060 /* NotificationDto.swift in Sources */,
DCD41A7527E5CEA500CF380E /* AppState.swift in Sources */,
CE4777F32A6ADCAC00E03253 /* VacancyRepository.swift in Sources */,
73B6E0882CCB34B2006DD4F0 /* SocialProvider.swift in Sources */,
DC1E0ED4287738F2005632A3 /* TimetableRouter.swift in Sources */,
DC29159F28660F7800FE5F9A /* ReviewScene.swift in Sources */,
CE3384BA2A86704100437CC5 /* FriendsService.swift in Sources */,
Expand Down
1 change: 1 addition & 0 deletions SNUTT-2022/SNUTT/AppState/States/UserState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import SwiftUI
class UserState {
@Published var accessToken: String?
@Published var current: User?
@Published var socialProvider: SocialProvider?

/// Primary key of User. Required to logout. This is not `localId`.
var userId: String?
Expand Down
4 changes: 2 additions & 2 deletions SNUTT-2022/SNUTT/Extensions/FacebookLogin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import FacebookLogin

protocol FacebookLoginProtocol: BaseViewModelProtocol {
func performFacebookSignIn()
func handleFacebookToken(fbId: String, fbToken: String) async
func handleFacebookToken(facebookId: String, facebookToken: String) async
}

extension FacebookLoginProtocol {
Expand Down Expand Up @@ -44,7 +44,7 @@ extension FacebookLoginProtocol {
}

Task { @MainActor in
await self.handleFacebookToken(fbId: fbUserId, fbToken: fbToken)
await self.handleFacebookToken(facebookId: fbUserId, facebookToken: fbToken)
}
}
}
Expand Down
26 changes: 26 additions & 0 deletions SNUTT-2022/SNUTT/Models/SocialProvider.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// SocialProvider.swift
// SNUTT
//
// Created by 이채민 on 10/25/24.
//

import Foundation

struct SocialProvider {
var local: Bool
var facebook: Bool
var google: Bool
var kakao: Bool
var apple: Bool
}

extension SocialProvider {
init(from dto: SocialProviderDto) {
local = dto.local
facebook = dto.facebook
google = dto.google
kakao = dto.kakao
apple = dto.apple
}
}
8 changes: 8 additions & 0 deletions SNUTT-2022/SNUTT/Repositories/Dto/UserDto.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,11 @@ struct SendVerificationCodeDto: Decodable {
struct EmailVerifiedDto: Decodable {
let is_email_verified: Bool
}

struct SocialProviderDto: Codable {
let local: Bool
let facebook: Bool
let google: Bool
let kakao: Bool
let apple: Bool
}
39 changes: 35 additions & 4 deletions SNUTT-2022/SNUTT/Repositories/Router/UserRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Foundation
enum UserRouter: Router {
var baseURL: URL {
switch self {
case .getUser, .changeNickname:
case .getUser, .getSocialProvider, .changeNickname:
return URL(string: NetworkConfiguration.serverV1BaseURL + "/users")!
default:
return URL(string: NetworkConfiguration.serverV1BaseURL + "/user")!
Expand All @@ -21,10 +21,15 @@ enum UserRouter: Router {
static let shouldAddToken: Bool = true

case getUser
case getSocialProvider
case changeNickname(nickname: String)
case changePassword(oldPassword: String, newPassword: String)
case addLocalId(localId: String, localPassword: String)
case connectFacebook(fbId: String, fbToken: String)
case connectKakao(kakaoToken: String)
case disconnectKakao
case connectGoogle(googleToken: String)
case disconnectGoogle
case connectFacebook(facebookId: String, facebookToken: String)
case disconnectFacebook
case getFB
case addDevice(fcmToken: String)
Expand All @@ -37,12 +42,22 @@ enum UserRouter: Router {
switch self {
case .getUser:
return .get
case .getSocialProvider:
return .get
case .changeNickname:
return .patch
case .changePassword:
return .put
case .addLocalId:
return .post
case .connectKakao:
return .post
case .disconnectKakao:
return .delete
case .connectGoogle:
return .post
case .disconnectGoogle:
return .delete
case .connectFacebook:
return .post
case .disconnectFacebook:
Expand All @@ -66,8 +81,14 @@ enum UserRouter: Router {
switch self {
case .getUser, .changeNickname:
return "/me"
case .getSocialProvider:
return "/me/social_providers"
case .changePassword, .addLocalId:
return "/password"
case .connectKakao, .disconnectKakao:
return "/kakao"
case .connectGoogle, .disconnectGoogle:
return "/google"
case .connectFacebook, .disconnectFacebook, .getFB:
return "/facebook"
case let .addDevice(fcmToken):
Expand All @@ -87,14 +108,24 @@ enum UserRouter: Router {
switch self {
case .getUser:
return nil
case .getSocialProvider:
return nil
case let .changeNickname(nickname):
return ["nickname": nickname]
case let .changePassword(oldPassword, newPassword):
return ["old_password": oldPassword, "new_password": newPassword]
case let .addLocalId(localId, localPasword):
return ["id": localId, "password": localPasword]
case let .connectFacebook(fbId, fbToken):
return ["fb_id": fbId, "fb_token": fbToken]
case let .connectKakao(kakaoToken):
return ["token": kakaoToken]
case .disconnectKakao:
return nil
case let .connectGoogle(googleToken):
return ["token": googleToken]
case .disconnectGoogle:
return nil
case let .connectFacebook(facebookId, facebookToken):
return ["fb_id": facebookId, "fb_token": facebookToken]
case .disconnectFacebook:
return nil
case .getFB:
Expand Down
50 changes: 47 additions & 3 deletions SNUTT-2022/SNUTT/Repositories/UserRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@ import Foundation

protocol UserRepositoryProtocol {
func fetchUser() async throws -> UserDto
func fetchSocialProvider() async throws -> SocialProviderDto
func changeNickname(to nickname: String) async throws -> UserDto
func connectFacebook(fbId: String, fbToken: String) async throws -> TokenResponseDto
func connectKakao(kakaoToken: String) async throws -> TokenResponseDto
func disconnectKakao() async throws -> TokenResponseDto
func connectGoogle(googleToken: String) async throws -> TokenResponseDto
func disconnectGoogle() async throws -> TokenResponseDto
func connectFacebook(facebookId: String, facebookToken: String) async throws -> TokenResponseDto
func disconnectFacebook() async throws -> TokenResponseDto
func changePassword(from oldPassword: String, to newPassword: String) async throws -> TokenResponseDto
func addLocalId(localId: String, localPassword: String) async throws -> TokenResponseDto
Expand All @@ -36,16 +41,55 @@ class UserRepository: UserRepositoryProtocol {
.handlingError()
}

func fetchSocialProvider() async throws -> SocialProviderDto {
return try await session
.request(UserRouter.getSocialProvider)
.serializingDecodable(SocialProviderDto.self)
.handlingError()
}

func changeNickname(to nickname: String) async throws -> UserDto {
return try await session
.request(UserRouter.changeNickname(nickname: nickname))
.serializingDecodable(UserDto.self)
.handlingError()
}

func connectFacebook(fbId: String, fbToken: String) async throws -> TokenResponseDto {
func connectKakao(kakaoToken: String) async throws ->
TokenResponseDto
{
return try await session
.request(UserRouter.connectKakao(kakaoToken: kakaoToken))
.serializingDecodable(TokenResponseDto.self)
.handlingError()
}

func disconnectKakao() async throws -> TokenResponseDto {
return try await session
.request(UserRouter.disconnectKakao)
.serializingDecodable(TokenResponseDto.self)
.handlingError()
}

func connectGoogle(googleToken: String) async throws ->
TokenResponseDto
{
return try await session
.request(UserRouter.connectGoogle(googleToken: googleToken))
.serializingDecodable(TokenResponseDto.self)
.handlingError()
}

func disconnectGoogle() async throws -> TokenResponseDto {
return try await session
.request(UserRouter.disconnectKakao)
.serializingDecodable(TokenResponseDto.self)
.handlingError()
}

func connectFacebook(facebookId: String, facebookToken: String) async throws -> TokenResponseDto {
return try await session
.request(UserRouter.connectFacebook(fbId: fbId, fbToken: fbToken))
.request(UserRouter.connectFacebook(facebookId: facebookId, facebookToken: facebookToken))
.serializingDecodable(TokenResponseDto.self)
.handlingError()
}
Expand Down
43 changes: 39 additions & 4 deletions SNUTT-2022/SNUTT/Services/UserService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,17 @@ import Foundation
@MainActor
protocol UserServiceProtocol: Sendable {
func fetchUser() async throws
func fetchSocialProvider() async throws
func changeNickname(to nickname: String) async throws
func deleteUser() async throws
func addLocalId(localId: String, localPassword: String) async throws
func changePassword(from oldPassword: String, to newPassword: String) async throws
func connectKakao(kakaoToken: String) async throws
func disconnectKakao() async throws
func connectGoogle(googleToken: String) async throws
func disconnectGoogle() async throws
func connectFacebook(facebookId: String, facebookToken: String) async throws
func disconnectFacebook() async throws
func connectFacebook(fbId: String, fbToken: String) async throws
func addDevice(fcmToken: String) async throws
func deleteDevice(fcmToken: String) async throws
func sendVerificationCode(email: String) async throws
Expand All @@ -36,6 +41,11 @@ struct UserService: UserServiceProtocol, UserAuthHandler {
localRepositories.userDefaultsRepository
}

func fetchSocialProvider() async throws {
let dto = try await userRepository.fetchSocialProvider()
appState.user.socialProvider = SocialProvider(from: dto)
}

func fetchUser() async throws {
let dto = try await userRepository.fetchUser()
updateUser(from: dto)
Expand All @@ -56,8 +66,28 @@ struct UserService: UserServiceProtocol, UserAuthHandler {
try await updateToken(from: dto)
}

func connectFacebook(fbId: String, fbToken: String) async throws {
let dto = try await userRepository.connectFacebook(fbId: fbId, fbToken: fbToken)
func connectKakao(kakaoToken: String) async throws {
let dto = try await userRepository.connectKakao(kakaoToken: kakaoToken)
try await updateToken(from: dto)
}

func disconnectKakao() async throws {
let dto = try await userRepository.disconnectKakao()
try await updateToken(from: dto)
}

func connectGoogle(googleToken: String) async throws {
let dto = try await userRepository.connectGoogle(googleToken: googleToken)
try await updateToken(from: dto)
}

func disconnectGoogle() async throws {
let dto = try await userRepository.disconnectGoogle()
try await updateToken(from: dto)
}

func connectFacebook(facebookId: String, facebookToken: String) async throws {
let dto = try await userRepository.connectFacebook(facebookId: facebookId, facebookToken: facebookToken)
try await updateToken(from: dto)
}

Expand Down Expand Up @@ -114,12 +144,17 @@ struct UserService: UserServiceProtocol, UserAuthHandler {

class FakeUserService: UserServiceProtocol {
func fetchUser() {}
func fetchSocialProvider() {}
func changeNickname(to _: String) async throws {}
func deleteUser() async throws {}
func addLocalId(localId _: String, localPassword _: String) async throws {}
func changePassword(from _: String, to _: String) async throws {}
func connectKakao(kakaoToken _: String) async throws {}
func disconnectKakao() async throws {}
func connectGoogle(googleToken _: String) async throws {}
func disconnectGoogle() async throws {}
func connectFacebook(facebookId _: String, facebookToken _: String) async throws {}
func disconnectFacebook() async throws {}
func connectFacebook(fbId _: String, fbToken _: String) async throws {}
func addDevice(fcmToken _: String) async throws {}
func deleteDevice(fcmToken _: String) async throws {}
func sendVerificationCode(email _: String) async throws {}
Expand Down
Loading