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

[Feat] #57 - 비밀번호 변경 뷰 구현 #58

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public struct I18N {
public static let setting = "설정"
public static let myinfo = "내 정보"
public static let bioEdit = "한 마디 편집"
public static let passwordEdit = "비밀번호 편집"
public static let passwordEdit = "비밀번호 변경"
public static let nicknameEdit = "닉네임 변경"
public static let serviceUsagePolicy = "서비스 이용방침"
public static let personalInfoPolicy = "개인정보처리방침"
Expand All @@ -94,5 +94,7 @@ public struct I18N {
public static let resetMission = "미션 초기화"
public static let logout = "로그아웃"
public static let withdraw = "탈퇴하기"
public static let passwordEditSuccess = "비밀번호가 변경되었습니다."
public static let passwordEditFail = "비밀번호 변경 실패"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,21 @@ import Network

public class SettingRepository {

private let networkService: UserService
private let networkService: AuthService
private let cancelBag = CancelBag()

public init(service: UserService) {
public init(service: AuthService) {
self.networkService = service
}
}

extension SettingRepository: SettingRepositoryInterface {

}

extension SettingRepository: PasswordChangeRepositoryInterface {
public func changePassword(password: String) -> AnyPublisher<Bool, Error> {
networkService.changePassword(password: password, userId: 12).map { statusCode in statusCode == 200 }
.eraseToAnyPublisher()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// PasswordSettingTransform.swift
// Data
//
// Created by sejin on 2022/12/26.
// Copyright © 2022 SOPT-Stamp-iOS. All rights reserved.
//

import Foundation

import Domain
import Network

extension PasswordChangeEntity {

public func toDomain() -> PasswordChangeModel {
return PasswordChangeModel.init()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// PasswordChangeModel.swift
// Domain
//
// Created by sejin on 2022/12/26.
// Copyright © 2022 SOPT-Stamp-iOS. All rights reserved.
//

import Foundation

public struct PasswordChangeModel {

public init() {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// PasswordChangeRepositoryInterface.swift
// Domain
//
// Created by sejin on 2022/12/26.
// Copyright © 2022 SOPT-Stamp-iOS. All rights reserved.
//

import Combine

public protocol PasswordChangeRepositoryInterface {
func changePassword(password: String) -> AnyPublisher<Bool, Error>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
//
// PasswordChangeUseCase.swift
// Domain
//
// Created by sejin on 2022/12/26.
// Copyright © 2022 SOPT-Stamp-iOS. All rights reserved.
//

import Foundation
import Combine

import Core

public protocol PasswordChangeUseCase {
func checkPassword(password: String)
func checkAccordPassword(firstPassword: String, secondPassword: String)
func changePassword(password: String)

var isPasswordFormValid: CurrentValueSubject<Bool, Error> { get set }
var isAccordPassword: CurrentValueSubject<Bool, Error> { get set }
var isValidForm: CurrentValueSubject<Bool, Error> { get set }
var passwordChangeSuccess: CurrentValueSubject<Bool, Error> { get set }
}

public class DefaultPasswordChangeUseCase {

private let repository: PasswordChangeRepositoryInterface
private var cancelBag = CancelBag()

public var isPasswordFormValid = CurrentValueSubject<Bool, Error>(false)
public var isAccordPassword = CurrentValueSubject<Bool, Error>(false)
public var isValidForm = CurrentValueSubject<Bool, Error>(false)
public var passwordChangeSuccess = CurrentValueSubject<Bool, Error>(false)

public init(repository: PasswordChangeRepositoryInterface) {
self.repository = repository
self.bindFormValid()
}
}

extension DefaultPasswordChangeUseCase: PasswordChangeUseCase {
public func checkPassword(password: String) {
checkPasswordForm(password: password)
}

public func checkAccordPassword(firstPassword: String, secondPassword: String) {
checkAccordPasswordForm(firstPassword: firstPassword, secondPassword: secondPassword)
}

public func changePassword(password: String) {
repository.changePassword(password: password)
.sink { event in
print("PasswordChangeUseCase: \(event)")
} receiveValue: { isSuccess in
self.passwordChangeSuccess.send(isSuccess)
}.store(in: cancelBag)
}
}

// MARK: - Methods

extension DefaultPasswordChangeUseCase {
func bindFormValid() {
isPasswordFormValid.combineLatest(isAccordPassword)
.map { (isPasswordValid, isAccordPassword) in
(isPasswordValid && isAccordPassword)
}
.sink { event in
print("PasswordChangeUseCase - completion: \(event)")
} receiveValue: { isValid in
self.isValidForm.send(isValid)
}.store(in: cancelBag)
}

func checkPasswordForm(password: String) {
let passwordRegEx = "^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[!@#$%^&*()_+=-]).{8,15}" // 8자리 ~ 15자리 영어+숫자+특수문자
let passwordTest = NSPredicate(format: "SELF MATCHES %@", passwordRegEx)
let isValid = passwordTest.evaluate(with: password)
isPasswordFormValid.send(isValid)
}

func checkAccordPasswordForm(firstPassword: String, secondPassword: String) {
let isValid = (firstPassword == secondPassword)
isAccordPassword.send(isValid)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,18 @@
// Copyright © 2022 SOPT-Stamp-iOS. All rights reserved.
//


import UIKit

import SnapKit

public extension UIViewController {
func showToast(message: String) {
Toast.show(message: message, controller: self)
Toast.show(message: message, view: self.view, safeAreaBottomInset: self.safeAreaBottomInset())
}
}

public class Toast {
static func show(message: String, controller: UIViewController) {
public static func show(message: String, view: UIView, safeAreaBottomInset: CGFloat = 0) {

let toastContainer = UIView()
let toastLabel = UILabel()
Expand All @@ -37,11 +36,11 @@ public class Toast {
toastLabel.sizeToFit()

toastContainer.addSubview(toastLabel)
controller.view.addSubview(toastContainer)
view.addSubview(toastContainer)

toastContainer.snp.makeConstraints {
$0.centerX.equalToSuperview()
$0.bottom.equalTo(controller.safeAreaBottomInset()).inset(40)
$0.bottom.equalToSuperview().inset(safeAreaBottomInset+40)
$0.width.equalTo(213)
$0.height.equalTo(44)
}
Expand Down
18 changes: 18 additions & 0 deletions SOPT-Stamp-iOS/Projects/Modules/Network/Sources/API/AuthAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,29 @@ import Moya
public enum AuthAPI {
case getNicknameAvailable(nickname: String)
case getEmailAvailable(email: String)
case changePassword(password: String, userId: Int)
}

extension AuthAPI: BaseAPI {

public static var apiType: APIType = .auth

// MARK: - Header
public var headers: [String: String]? {
switch self {
case .changePassword(_, let userId):
return HeaderType.userId(userId: userId).value
default: return HeaderType.json.value
}
}

// MARK: - Path
public var path: String {
switch self {
case .getNicknameAvailable, .getEmailAvailable:
return ""
case .changePassword:
return "password"
}
}

Expand All @@ -33,6 +45,8 @@ extension AuthAPI: BaseAPI {
switch self {
case .getNicknameAvailable, .getEmailAvailable:
return .get
case .changePassword:
return .put
}
}

Expand All @@ -42,6 +56,8 @@ extension AuthAPI: BaseAPI {
switch self {
case .getNicknameAvailable, .getEmailAvailable:
break
case .changePassword(let password, _):
params["password"] = password
}
return params
}
Expand All @@ -59,6 +75,8 @@ extension AuthAPI: BaseAPI {
return .requestParameters(parameters: ["nickname": nickname], encoding: URLEncoding.queryString)
case .getEmailAvailable(let email):
return .requestParameters(parameters: ["email": email], encoding: URLEncoding.queryString)
case .changePassword:
return .requestParameters(parameters: bodyParameters ?? [:], encoding: parameterEncoding)
default:
return .requestPlain
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// PasswordChangeEntity.swift
// Network
//
// Created by sejin on 2022/12/26.
// Copyright © 2022 SOPT-Stamp-iOS. All rights reserved.
//

import Foundation

public struct PasswordChangeEntity {

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public typealias DefaultAuthService = BaseService<AuthAPI>
public protocol AuthService {
func getNicknameAvailable(nickname: String) -> AnyPublisher<Int, Error>
func getEmailAvailable(email: String) -> AnyPublisher<Int, Error>
func changePassword(password: String, userId: Int) -> AnyPublisher<Int, Error>
}

extension DefaultAuthService: AuthService {
Expand All @@ -27,4 +28,8 @@ extension DefaultAuthService: AuthService {
public func getEmailAvailable(email: String) -> AnyPublisher<Int, Error> {
return requestObjectInCombineNoResult(.getEmailAvailable(email: email))
}

public func changePassword(password: String, userId: Int) -> AnyPublisher<Int, Error> {
return requestObjectInCombineNoResult(.changePassword(password: password, userId: userId))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ public protocol ModuleFactoryInterface {
func makeAlertVC(title: String, customButtonTitle: String) -> AlertVC
func makeRankingVC() -> RankingVC
func makeSettingVC() -> SettingVC
func makePasswordChangeVC() -> PasswordChangeVC
}
Loading