Skip to content

Commit a170892

Browse files
committed
feat :: [#183] 비밀번호 변경 api 연동
1 parent ed600bf commit a170892

File tree

10 files changed

+78
-16
lines changed

10 files changed

+78
-16
lines changed

Projects/Data/Sources/API/AuthAPI.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public enum AuthAPI {
1010
case signin(req: SigninRequestParams)
1111
case refreshToken
1212
case signup(req: SignupRequestParams)
13+
case passwordChange(req: PasswordChangeRequestParams)
1314
}
1415

1516
extension AuthAPI: PiCKAPI {
@@ -27,12 +28,14 @@ extension AuthAPI: PiCKAPI {
2728
return "/signup"
2829
case .refreshToken:
2930
return "/refresh"
31+
case .passwordChange:
32+
return "/password"
3033
}
3134
}
3235

3336
public var method: Moya.Method {
3437
switch self {
35-
case .signin, .signup:
38+
case .signin, .signup, .passwordChange:
3639
return .post
3740
case .refreshToken:
3841
return .put
@@ -45,6 +48,8 @@ extension AuthAPI: PiCKAPI {
4548
return .requestJSONEncodable(req)
4649
case let .signup(req):
4750
return .requestJSONEncodable(req)
51+
case let .passwordChange(req):
52+
return .requestJSONEncodable(req)
4853
default:
4954
return .requestPlain
5055
}

Projects/Data/Sources/DI/UseCaseAssembly.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ public final class UseCaseAssembly: Assembly {
2121
container.register(RefreshTokenUseCase.self) { resolver in
2222
RefreshTokenUseCase(repository: resolver.resolve(AuthRepository.self)!)
2323
}
24+
container.register(PasswordChangeUseCase.self) { resolver in
25+
PasswordChangeUseCase(repository: resolver.resolve(AuthRepository.self)!)
26+
}
2427
// MARK: Home
2528
container.register(FetchApplyStatusUsecase.self) { resolver in
2629
FetchApplyStatusUsecase(repository: resolver.resolve(HomeRepository.self)!)

Projects/Data/Sources/DataSource/AuthDataSource.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import AppNetwork
1111
protocol AuthDataSource {
1212
func signin(req: SigninRequestParams) -> Single<TokenDTO>
1313
func signup(req: SignupRequestParams) -> Completable
14+
func passwordChange(req: PasswordChangeRequestParams) -> Completable
1415
func logout()
1516
func refreshToken() -> Single<TokenDTO>
1617
}
@@ -36,6 +37,12 @@ class AuthDataSourceImpl: BaseDataSource<AuthAPI>, AuthDataSource {
3637
.asCompletable()
3738
}
3839

40+
func passwordChange(req: PasswordChangeRequestParams) -> Completable {
41+
return request(.passwordChange(req: req))
42+
.filterSuccessfulStatusCodes()
43+
.asCompletable()
44+
}
45+
3946
func logout() {
4047
keychain.delete(type: .accessToken)
4148
keychain.delete(type: .refreshToken)

Projects/Data/Sources/Repository/AuthRepositoryImpl.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ class AuthRepositoryImpl: AuthRepository {
1717
init(remoteDataSource: AuthDataSource) {
1818
self.remoteDataSource = remoteDataSource
1919
}
20-
// func signup(req: SignupRequestParams) -> Completable {
21-
//
22-
// }
20+
2321
func signin(req: SigninRequestParams) -> Completable {
2422
return Completable.create { [weak self] completable in
2523
guard let self = self else { return Disposables.create {} }
@@ -47,6 +45,10 @@ class AuthRepositoryImpl: AuthRepository {
4745
return remoteDataSource.signup(req: req)
4846
}
4947

48+
func passwordChange(req: PasswordChangeRequestParams) -> Completable {
49+
return remoteDataSource.passwordChange(req: req)
50+
}
51+
5052
func logout() {
5153
return remoteDataSource.logout()
5254
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Foundation
2+
3+
public struct PasswordChangeRequestParams: Encodable {
4+
public let password: String
5+
public let code: String
6+
7+
public init(
8+
password: String,
9+
code: String
10+
) {
11+
self.password = password
12+
self.code = code
13+
}
14+
}

Projects/Domain/Sources/Repository/AuthRepository.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import RxSwift
55
public protocol AuthRepository {
66
func signin(req: SigninRequestParams) -> Completable
77
func signup(req: SignupRequestParams) -> Completable
8+
func passwordChange(req: PasswordChangeRequestParams) -> Completable
89
func logout()
910
func refreshToken() -> Completable
1011
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import Foundation
2+
3+
import RxSwift
4+
5+
public class PasswordChangeUseCase {
6+
let repository: AuthRepository
7+
8+
public init(repository: AuthRepository) {
9+
self.repository = repository
10+
}
11+
12+
public func execute(req: PasswordChangeRequestParams) -> Completable {
13+
return repository.passwordChange(req: req)
14+
}
15+
16+
}

Projects/Presentation/Sources/DI/PresentationAssembly.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,9 @@ public final class PresentationAssembly: Assembly {
215215
ChangePasswordViewController(viewModel: resolver.resolve(ChangePasswordViewModel.self)!)
216216
}
217217
container.register(NewPasswordViewModel.self) { resolver in
218-
NewPasswordViewModel()
218+
NewPasswordViewModel(
219+
passwordChangeUseCase: resolver.resolve(PasswordChangeUseCase.self)!
220+
)
219221
}
220222
container.register(NewPasswordViewController.self) { resolver in
221223
NewPasswordViewController(viewModel: resolver.resolve(NewPasswordViewModel.self)!)

Projects/Presentation/Sources/Scene/AllTab/ChangePassword/NewPassword/NewPasswordViewController.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import DesignSystem
88

99
public class NewPasswordViewController: BaseViewController<NewPasswordViewModel> {
1010
public var verificationCode: String = ""
11+
1112
private let titleLabel = PiCKLabel(
1213
text: "PiCK 비밀번호 변경하기",
1314
textColor: .modeBlack,
@@ -42,14 +43,15 @@ public class NewPasswordViewController: BaseViewController<NewPasswordViewModel>
4243
public override func attribute() {
4344
super.attribute()
4445

46+
navigationTitleText = "비밀번호 변경"
4547
navigationController?.interactivePopGestureRecognizer?.isEnabled = false
4648
}
4749

4850
public override func bind() {
4951
let input = NewPasswordViewModel.Input(
5052
nextButtonTap: changeButton.rx.tap.asObservable(),
51-
emailText: newPasswordTextField.rx.text.orEmpty.asObservable(),
52-
certificationText: newPWCheckTextField.rx.text.orEmpty.asObservable()
53+
newPasswordText: newPasswordTextField.rx.text.orEmpty.asObservable(),
54+
certificationText: Observable.just(verificationCode)
5355
)
5456

5557
let output = viewModel.transform(input: input)

Projects/Presentation/Sources/Scene/AllTab/ChangePassword/NewPassword/NewPasswordViewModel.swift

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@ public class NewPasswordViewModel: BaseViewModel, Stepper {
99
private let disposeBag = DisposeBag()
1010
public var steps = PublishRelay<Step>()
1111

12-
public init() {
12+
private let passwordChangeUseCase: PasswordChangeUseCase
1313

14+
public init(
15+
passwordChangeUseCase: PasswordChangeUseCase
16+
) {
17+
self.passwordChangeUseCase = passwordChangeUseCase
1418
}
1519

1620
public struct Input {
1721
let nextButtonTap: Observable<Void>
18-
let emailText: Observable<String>
22+
let newPasswordText: Observable<String>
1923
let certificationText: Observable<String>
2024
}
2125

@@ -25,21 +29,27 @@ public class NewPasswordViewModel: BaseViewModel, Stepper {
2529

2630
public func transform(input: Input) -> Output {
2731
let isFormValid = Observable.combineLatest(
28-
input.emailText,
32+
input.newPasswordText,
2933
input.certificationText
30-
) { email, certification in
31-
return !email.isEmpty && !certification.isEmpty
34+
) { password, certification in
35+
return !password.isEmpty && !certification.isEmpty
3236
}
3337
.distinctUntilChanged()
3438

3539
input.nextButtonTap
3640
.withLatestFrom(Observable.combineLatest(
37-
input.emailText,
41+
input.newPasswordText,
3842
input.certificationText
3943
))
40-
.do(onNext: { email, certification in
41-
})
42-
.map { _ in PiCKStep.logoutIsRequired }
44+
.flatMapLatest { [weak self] password, certification -> Observable<Step> in
45+
guard let self = self else { return Observable<Step>.empty() }
46+
let params = PasswordChangeRequestParams(
47+
password: password,
48+
code: certification
49+
)
50+
return self.passwordChangeUseCase.execute(req: params)
51+
.andThen(Observable.just(PiCKStep.signinIsRequired))
52+
}
4353
.bind(to: steps)
4454
.disposed(by: disposeBag)
4555

0 commit comments

Comments
 (0)