diff --git a/.gitignore b/.gitignore index 81dc02b..eb87dfe 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,9 @@ DerivedData *.hmap *.ipa +# AppCode +.idea + # Bundler .bundle diff --git a/Example/Podfile b/Example/Podfile index 10c7fe2..9e49f3b 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -12,7 +12,10 @@ def main_pods pod 'TokenDSDK/AlamofireNetworkJSONAPI', path: '../' pod 'TokenDSDK/RxJSONAPI', path: '../' - pod 'SnapKit' + pod 'SnapKit', '~> 4.2.0' + pod 'Alamofire', '~> 4.8.1' + pod 'RxCocoa', '~> 4.4.1' + pod 'RxSwift', '~> 4.4.1' end target 'TokenDSDK_Example' do diff --git a/Example/Podfile.lock b/Example/Podfile.lock index ec6d0b7..d83c242 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,18 +1,18 @@ PODS: - - Alamofire (4.8.1) - - AlamofireNetworkActivityLogger (2.3.0): - - Alamofire (~> 4.6) + - Alamofire (4.8.2) + - AlamofireNetworkActivityLogger (2.4.0): + - Alamofire (~> 4.8) - DLCryptoKit (2.0.1): - DLOpenSSL - DLJSONAPI (1.0.3): - DLJSONAPI/Default (= 1.0.3) - DLJSONAPI/Default (1.0.3) - DLOpenSSL (1.0.2) - - RxAtomic (4.4.1) - - RxCocoa (4.4.1): - - RxSwift (~> 4.0) - - RxSwift (4.4.1): - - RxAtomic (~> 4.4) + - RxAtomic (4.4.2) + - RxCocoa (4.4.2): + - RxSwift (>= 4.4.2, ~> 4.4) + - RxSwift (4.4.2): + - RxAtomic (>= 4.4.2, ~> 4.4) - SnapKit (4.2.0) - TokenDSDK (3.1.0-rc.28): - TokenDSDK/API (= 3.1.0-rc.28) @@ -38,11 +38,14 @@ PODS: - RxCocoa (~> 4.0) - RxSwift (~> 4.0) - TokenDWallet (>= 3.0.1) - - TokenDWallet (3.0.1): + - TokenDWallet (3.0.5): - DLCryptoKit (>= 2.0.1) DEPENDENCIES: - - SnapKit + - Alamofire (~> 4.8.1) + - RxCocoa (~> 4.4.1) + - RxSwift (~> 4.4.1) + - SnapKit (~> 4.2.0) - TokenDSDK (from `../`) - TokenDSDK/AlamofireNetwork (from `../`) - TokenDSDK/AlamofireNetworkJSONAPI (from `../`) @@ -54,7 +57,7 @@ SPEC REPOS: - DLJSONAPI - DLOpenSSL - TokenDWallet - https://github.com/cocoapods/specs.git: + https://github.com/CocoaPods/Specs.git: - Alamofire - AlamofireNetworkActivityLogger - RxAtomic @@ -67,18 +70,18 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - Alamofire: 16ce2c353fb72865124ddae8a57c5942388f4f11 - AlamofireNetworkActivityLogger: 6f3076652ab7fa6c819b59be08ea038d339e36d8 + Alamofire: ae5c501addb7afdbb13687d7f2f722c78734c2d3 + AlamofireNetworkActivityLogger: 6d3398c692d2c5d83b0c58793537860aca1e383d DLCryptoKit: 491c522583e92c90c09c06bf1192ef741022af33 DLJSONAPI: 4d448f06fd412dae20c53ba1c71d601c4b422ce5 DLOpenSSL: 78d928228cb6d95fcaa354f4f9aba041ccf95457 - RxAtomic: f8d6adc1ccb87a767811269e4875887bc74dbf19 - RxCocoa: 2f35a76bf8887872e28a1914112395b11b8e0e64 - RxSwift: 92fcf68dfef21f3e2ab1965363d9e7b3d787597e + RxAtomic: d00e97c10db88c6f08540e0bf2752fc5a2404167 + RxCocoa: 477990dc3b4c3ff55fb0ac77e1cc06244e0aaec8 + RxSwift: 74c29b693c8e42b0f64400e8b06564575742d649 SnapKit: fe8a619752f3f27075cc9a90244d75c6c3f27e2a - TokenDSDK: 7e52823872e6965b85342d80e65af3a417cdfd2a - TokenDWallet: 3904ec3d99691d6e1c98f58e03d657804e7d08b3 + TokenDSDK: e6091c45d06068bdf71707a47839fcfc68f50b0c + TokenDWallet: 0f415dc845b38227bd99602e341258ec4dda4a32 -PODFILE CHECKSUM: d1e797a0c0d30ff2c5cced44774ad26bca37e2a8 +PODFILE CHECKSUM: ba4a68dcc8ccbebcf2ce6adab7146c6537105235 -COCOAPODS: 1.6.1 +COCOAPODS: 1.8.0 diff --git a/Example/Tests/TokenDSDK_IntegrationTests/Info.plist b/Example/Tests/TokenDSDK_IntegrationTests/Info.plist index 6c40a6c..9c71dca 100644 --- a/Example/Tests/TokenDSDK_IntegrationTests/Info.plist +++ b/Example/Tests/TokenDSDK_IntegrationTests/Info.plist @@ -18,5 +18,10 @@ 1.0 CFBundleVersion 1 + NSAppTransportSecurity + + NSAllowsLocalNetworking + + diff --git a/Example/Tests/TokenDSDK_IntegrationTests/IntegrationTestsConstants.swift b/Example/Tests/TokenDSDK_IntegrationTests/IntegrationTestsConstants.swift new file mode 100644 index 0000000..a1c4a8b --- /dev/null +++ b/Example/Tests/TokenDSDK_IntegrationTests/IntegrationTestsConstants.swift @@ -0,0 +1,15 @@ +// +// IntegrationTestsConstants.swift +// TokenDSDK_IntegrationTests +// +// Created by Yaroslav on 2/28/20. +// Copyright © 2020 CocoaPods. All rights reserved. +// + +import Foundation + +struct IntegrationTestsConstants { + public static let apiUrlString = "http://localhost:8000/_/api/" + public static let email = "test@dl.com" + public static let password = "test@dl.com" +} diff --git a/Example/Tests/TokenDSDK_IntegrationTests/KeyServerIntegrationTests.swift b/Example/Tests/TokenDSDK_IntegrationTests/KeyServerIntegrationTests.swift index 59ff9ad..d0c5dad 100644 --- a/Example/Tests/TokenDSDK_IntegrationTests/KeyServerIntegrationTests.swift +++ b/Example/Tests/TokenDSDK_IntegrationTests/KeyServerIntegrationTests.swift @@ -94,7 +94,7 @@ class KeyServerIntegrationTests: BaseIntegrationTests { self.wait(for: [expectation], timeout: BaseIntegrationTests.requestTimeoutDuraton) } - func testSignUpSignChangePasswordRecovery() { + func testSignUpSignChangePassword() { guard self.isServerReachable else { XCTAssert(false, "Server is not reachable") return @@ -119,15 +119,10 @@ class KeyServerIntegrationTests: BaseIntegrationTests { self.performPasswordUpdate(onSuccess: onSuccess, onFailed: onFailed) } - let performPasswordRecovery: (_ onSuccess: @escaping () -> Void) -> Void = { (onSuccess) in - self.performPasswordRecovery(onSuccess: onSuccess, onFailed: onFailed) - } - let consecutiveOperations: [(_ onSuccess: @escaping () -> Void) -> Void] = [ performSignUp, performSignIn, - performPasswordUpdate, - performPasswordRecovery + performPasswordUpdate ] var performNextOperationRef: ((_ operationIndex: Int) -> Void)? diff --git a/Example/TokenDSDK.xcodeproj/project.pbxproj b/Example/TokenDSDK.xcodeproj/project.pbxproj index b573a03..a3db420 100644 --- a/Example/TokenDSDK.xcodeproj/project.pbxproj +++ b/Example/TokenDSDK.xcodeproj/project.pbxproj @@ -24,11 +24,11 @@ 7F90A485220C548800091A77 /* ApiExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F186FBE21FF67AD009ED556 /* ApiExampleViewController.swift */; }; 7F90A486220C56A200091A77 /* KeyServerExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FA55D8121D3A2290092E536 /* KeyServerExampleViewController.swift */; }; 7FA55D8521D3ACE70092E536 /* ApiExampleViewControllerV3.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FA55D8221D3A2290092E536 /* ApiExampleViewControllerV3.swift */; }; - 7FE04A5521749F1B0018399F /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FE04A5421749F1B0018399F /* Constants.swift */; }; 7FE317B322328E39007ECDAE /* test_upload_image.png in Resources */ = {isa = PBXBuildFile; fileRef = 7FE317B222328E39007ECDAE /* test_upload_image.png */; }; 7FECDD232213157E00EB0367 /* HistoryApiIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FECDD222213157E00EB0367 /* HistoryApiIntegrationTests.swift */; }; 7FECDD252213158E00EB0367 /* BaseIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FECDD242213158E00EB0367 /* BaseIntegrationTests.swift */; }; - 7FECDD27221317B400EB0367 /* IntegrationTestsConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FECDD26221317B400EB0367 /* IntegrationTestsConstants.swift */; }; + C4C0129124095ED000018CC8 /* IntegrationTestsConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C0129024095ED000018CC8 /* IntegrationTestsConstants.swift */; }; + C4C012932409601300018CC8 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C012922409601300018CC8 /* Constants.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -74,14 +74,14 @@ 7FA55D4821D27AA20092E536 /* TokenDSDK_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenDSDK_Tests.swift; sourceTree = ""; }; 7FA55D8121D3A2290092E536 /* KeyServerExampleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyServerExampleViewController.swift; sourceTree = ""; }; 7FA55D8221D3A2290092E536 /* ApiExampleViewControllerV3.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiExampleViewControllerV3.swift; sourceTree = ""; }; - 7FE04A5421749F1B0018399F /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; 7FE317B222328E39007ECDAE /* test_upload_image.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = test_upload_image.png; sourceTree = ""; }; 7FECDD222213157E00EB0367 /* HistoryApiIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryApiIntegrationTests.swift; sourceTree = ""; }; 7FECDD242213158E00EB0367 /* BaseIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseIntegrationTests.swift; sourceTree = ""; }; - 7FECDD26221317B400EB0367 /* IntegrationTestsConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntegrationTestsConstants.swift; sourceTree = ""; }; 88B6A9B90B443C13A977F189 /* Pods-TokenDSDK_IntegrationTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TokenDSDK_IntegrationTests.release.xcconfig"; path = "Target Support Files/Pods-TokenDSDK_IntegrationTests/Pods-TokenDSDK_IntegrationTests.release.xcconfig"; sourceTree = ""; }; 976BCCEDDBF16A300BE60E98 /* Pods-TokenDSDK_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TokenDSDK_Example.release.xcconfig"; path = "Target Support Files/Pods-TokenDSDK_Example/Pods-TokenDSDK_Example.release.xcconfig"; sourceTree = ""; }; C46B692F3572BACFE0A827CE /* Pods-TokenDSDK_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TokenDSDK_Tests.release.xcconfig"; path = "Target Support Files/Pods-TokenDSDK_Tests/Pods-TokenDSDK_Tests.release.xcconfig"; sourceTree = ""; }; + C4C0129024095ED000018CC8 /* IntegrationTestsConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntegrationTestsConstants.swift; sourceTree = ""; }; + C4C012922409601300018CC8 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; CA870871D23FF6195488CBCB /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; D7CC5FAA68093D676BC7208C /* Pods-TokenDSDK_IntegrationTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TokenDSDK_IntegrationTests.debug.xcconfig"; path = "Target Support Files/Pods-TokenDSDK_IntegrationTests/Pods-TokenDSDK_IntegrationTests.debug.xcconfig"; sourceTree = ""; }; DC6FC85D0B04436C56966E1B /* libPods-TokenDSDK_IntegrationTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-TokenDSDK_IntegrationTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -167,11 +167,11 @@ 7F186FBE21FF67AD009ED556 /* ApiExampleViewController.swift */, 7FA55D8221D3A2290092E536 /* ApiExampleViewControllerV3.swift */, 607FACD51AFB9204008FA782 /* AppDelegate.swift */, - 7FE04A5421749F1B0018399F /* Constants.swift */, 7FA55D8121D3A2290092E536 /* KeyServerExampleViewController.swift */, 607FACDC1AFB9204008FA782 /* Images.xcassets */, 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, 607FACD31AFB9204008FA782 /* Supporting Files */, + C4C012922409601300018CC8 /* Constants.swift */, ); name = "Example for TokenDSDK"; path = TokenDSDK; @@ -255,7 +255,7 @@ 7FE317B222328E39007ECDAE /* test_upload_image.png */, 7FECDD242213158E00EB0367 /* BaseIntegrationTests.swift */, 7FECDD222213157E00EB0367 /* HistoryApiIntegrationTests.swift */, - 7FECDD26221317B400EB0367 /* IntegrationTestsConstants.swift */, + C4C0129024095ED000018CC8 /* IntegrationTestsConstants.swift */, 7F01C18F2217094800205456 /* KeyServerIntegrationTests.swift */, ); path = TokenDSDK_IntegrationTests; @@ -504,10 +504,10 @@ buildActionMask = 2147483647; files = ( 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, - 7FE04A5521749F1B0018399F /* Constants.swift in Sources */, 7F90A486220C56A200091A77 /* KeyServerExampleViewController.swift in Sources */, 7F90A485220C548800091A77 /* ApiExampleViewController.swift in Sources */, 7FA55D8521D3ACE70092E536 /* ApiExampleViewControllerV3.swift in Sources */, + C4C012932409601300018CC8 /* Constants.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -531,7 +531,7 @@ 7F5119FB21F77A5000025F96 /* TestsHelpers.swift in Sources */, 7FECDD232213157E00EB0367 /* HistoryApiIntegrationTests.swift in Sources */, 7FECDD252213158E00EB0367 /* BaseIntegrationTests.swift in Sources */, - 7FECDD27221317B400EB0367 /* IntegrationTestsConstants.swift in Sources */, + C4C0129124095ED000018CC8 /* IntegrationTestsConstants.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Example/TokenDSDK/Info.plist b/Example/TokenDSDK/Info.plist index 61861ab..5538b1c 100644 --- a/Example/TokenDSDK/Info.plist +++ b/Example/TokenDSDK/Info.plist @@ -32,5 +32,10 @@ UIInterfaceOrientationPortrait + NSAppTransportSecurity + + NSAllowsLocalNetworking + + diff --git a/Sources/KeyServer/Builders/SignUpRequestBuilder.swift b/Sources/KeyServer/Builders/SignUpRequestBuilder.swift index 7ce5f21..7b7a991 100644 --- a/Sources/KeyServer/Builders/SignUpRequestBuilder.swift +++ b/Sources/KeyServer/Builders/SignUpRequestBuilder.swift @@ -68,6 +68,7 @@ public class SignUpRequestBuilder { passwordFactorKeyPair: passwordFactorKeyPair ) + // TODO: Set default signer role from key value let createRegistrationInfoResult = WalletInfoBuilder.createWalletInfo( email: email, password: password, diff --git a/Sources/KeyServer/WalletInfoBuilder.swift b/Sources/KeyServer/WalletInfoBuilder.swift index 268408e..c9887c6 100644 --- a/Sources/KeyServer/WalletInfoBuilder.swift +++ b/Sources/KeyServer/WalletInfoBuilder.swift @@ -96,6 +96,7 @@ public struct WalletInfoBuilder { password: String, kdfParams: KDFParams, keychainParams: KeychainParams, + defaultSignerRole: UInt64 = 1, transaction: WalletInfoModel.WalletInfoData.Relationships.Transaction? = nil, referrerAccountId: String? = nil ) -> CreateResult { @@ -175,17 +176,30 @@ public struct WalletInfoBuilder { ) included.append(passwordFactorRelationship) - - // Recovery - let recoveryFactorRelationship = WalletInfoBuilder.getFactor( - accountId: recoveryDetails.accountIdBase32Check, - keychainData: recoveryDetails.keychainDataBase64, - salt: recoveryDetails.saltBase64, - id: recoveryDetails.walletIdHex, - type: "recovery" - ) - - included.append(recoveryFactorRelationship) + + // Signers + let accountId = Base32Check.encode(version: .accountIdEd25519, data: keychainParams.newKeyPair.getPublicKeyData()) + let signers = [ + WalletInfoModel.WalletInfoData.Relationships.Signer( + id: recoveryDetails.accountIdBase32Check, + type: "signer", + attributes: WalletInfoModel.WalletInfoData.Relationships.Signer.Attributes( + roleId: 1, + weight: 1000, + identity: 0)), + WalletInfoModel.WalletInfoData.Relationships.Signer( + id: accountId, + type: "signer", + attributes: WalletInfoModel.WalletInfoData.Relationships.Signer.Attributes( + roleId: defaultSignerRole, + weight: 1000, + identity: 0)), + ] + + for signer in signers { + included.append(signer) + } + // Transaction var transactionAPIData: ApiDataRequest? @@ -208,7 +222,7 @@ public struct WalletInfoBuilder { referrer: referrerAPIData, transaction: transactionAPIData, kdf: ApiDataRequest(data: kdfRelationship), - recovery: ApiDataRequest(data: recoveryFactorRelationship), + signers: ApiDataRequest(data: signers), factor: ApiDataRequest(data: passwordFactorRelationship) ) diff --git a/Sources/KeyServer/WalletInfoModel.swift b/Sources/KeyServer/WalletInfoModel.swift index 2b0def1..c00771c 100644 --- a/Sources/KeyServer/WalletInfoModel.swift +++ b/Sources/KeyServer/WalletInfoModel.swift @@ -26,7 +26,7 @@ public struct WalletInfoModel: Encodable { public let referrer: ApiDataRequest? public let transaction: ApiDataRequest? public let kdf: ApiDataRequest - public let recovery: ApiDataRequest + public let signers: ApiDataRequest<[Signer], Include> public let factor: ApiDataRequest public class Transaction: Include { @@ -62,6 +62,35 @@ public struct WalletInfoModel: Encodable { super.init(id: id, type: type) } } + + public class Signer: Include { + + public init(id: String, type: String, attributes: Attributes) { + self.attributes = attributes + + super.init(id: id, type: type) + } + + public let attributes: Attributes + + public struct Attributes: Encodable { + + public let roleId: UInt64 + public let weight: UInt64 + public let identity: UInt64 + } + + public enum SignerIncludeKeys: CodingKey { + case attributes + } + + override public func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: SignerIncludeKeys.self) + + try? container.encode(self.attributes, forKey: .attributes) + } + } public class Factor: Include { @@ -169,7 +198,7 @@ extension WalletInfoModel.WalletInfoData.Relationships: CustomDebugStringConvert fields.append("transaction: \(transaction.data.debugDescription)") } fields.append("kdf: \(self.kdf.data.debugDescription)") - fields.append("recovery: \(self.recovery.data.debugDescription)") + fields.append("signers: \(self.signers.data.debugDescription)") fields.append("factor: \(self.factor.data.debugDescription)") let description = DebugFormattedDescription(fields) @@ -222,6 +251,36 @@ extension WalletInfoModel.WalletInfoData.Relationships.Factor.Attributes: Custom } } +extension WalletInfoModel.WalletInfoData.Relationships.Signer: CustomDebugStringConvertible { + + public var debugDescription: String { + var fields: [String] = [] + + fields.append("type: \(self.type)") + fields.append("id: \(id)") + fields.append("attributes: \(self.attributes.debugDescription)") + + let description = DebugFormattedDescription(fields) + + return description + } +} + +extension WalletInfoModel.WalletInfoData.Relationships.Signer.Attributes: CustomDebugStringConvertible { + + public var debugDescription: String { + var fields: [String] = [] + + fields.append("role_id: \(self.roleId)") + fields.append("weight: \(self.weight)") + fields.append("identity: \(self.identity)") + + let description = DebugFormattedDescription(fields) + + return description + } +} + extension WalletInfoModel.WalletInfoData.Relationships.Referrer: CustomDebugStringConvertible { public var debugDescription: String {