no message

This commit is contained in:
Peter 2018-04-24 16:42:07 +03:00
parent e9dfb0a082
commit c602d31eba
7 changed files with 139 additions and 16 deletions

View File

@ -100,6 +100,7 @@
D00DBBD81E64E41100DB5485 /* CreateSecretChat.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00DBBD61E64E41100DB5485 /* CreateSecretChat.swift */; };
D00DBBDA1E64E67E00DB5485 /* UpdateSecretChat.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00DBBD91E64E67E00DB5485 /* UpdateSecretChat.swift */; };
D00DBBDB1E64E67E00DB5485 /* UpdateSecretChat.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00DBBD91E64E67E00DB5485 /* UpdateSecretChat.swift */; };
D0136309208F3B0900EB3653 /* SecureIdValueContentError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0136308208F3B0900EB3653 /* SecureIdValueContentError.swift */; };
D01749591E1092BC0057C89A /* RequestStartBot.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01749581E1092BC0057C89A /* RequestStartBot.swift */; };
D017495E1E118F790057C89A /* AccountStateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D017495D1E118F790057C89A /* AccountStateManager.swift */; };
D01749601E118FC30057C89A /* AccountIntermediateState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D017495F1E118FC30057C89A /* AccountIntermediateState.swift */; };
@ -741,6 +742,7 @@
D00D97C91E32917C00E5C2B6 /* PeerInputActivityManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerInputActivityManager.swift; sourceTree = "<group>"; };
D00DBBD61E64E41100DB5485 /* CreateSecretChat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateSecretChat.swift; sourceTree = "<group>"; };
D00DBBD91E64E67E00DB5485 /* UpdateSecretChat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdateSecretChat.swift; sourceTree = "<group>"; };
D0136308208F3B0900EB3653 /* SecureIdValueContentError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureIdValueContentError.swift; sourceTree = "<group>"; };
D01749581E1092BC0057C89A /* RequestStartBot.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestStartBot.swift; sourceTree = "<group>"; };
D017495D1E118F790057C89A /* AccountStateManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountStateManager.swift; sourceTree = "<group>"; };
D017495F1E118FC30057C89A /* AccountIntermediateState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountIntermediateState.swift; sourceTree = "<group>"; };
@ -1690,6 +1692,7 @@
D0E412D6206A866B00BEE4A2 /* UploadSecureIdFile.swift */,
D0E412ED206AF65500BEE4A2 /* GrantSecureIdAccess.swift */,
D02D60AA206BA64100FEFE1E /* VerifySecureIdValue.swift */,
D0136308208F3B0900EB3653 /* SecureIdValueContentError.swift */,
D093D7E82064135300BC3599 /* Values */,
);
name = "Secure ID";
@ -2024,6 +2027,7 @@
D0AAD1A81E32602500D5B9DE /* AutoremoveTimeoutMessageAttribute.swift in Sources */,
C2366C831E4F3EAA0097CCFF /* GroupReturnAndLeft.swift in Sources */,
C230BEB61EE9A3760029586C /* ChannelAdminEventLogs.swift in Sources */,
D0136309208F3B0900EB3653 /* SecureIdValueContentError.swift in Sources */,
D03B0D3D1D6319E200955575 /* Fetch.swift in Sources */,
D02D60A7206BA5F900FEFE1E /* SecureIdValue.swift in Sources */,
D0DF0C931D81AD09008AEB01 /* MessageUtils.swift in Sources */,

View File

@ -680,11 +680,19 @@ public struct Api {
return nil
}
}
if let item = Api.parse(reader, signature: signature) as? T {
array.append(item)
}
else {
return nil
if elementType == Buffer.self {
if let item = parseBytes(reader) as? T {
array.append(item)
} else {
return nil
}
} else {
if let item = Api.parse(reader, signature: signature) as? T {
array.append(item)
}
else {
return nil
}
}
i += 1
}

View File

@ -32,9 +32,9 @@ private final class ProxyServerItemContext {
return ActionDisposable {
disposable?.dispose()
}
} |> runOn(queue)).start(next: { status in
updated(status)
})
} |> runOn(queue)).start(next: { status in
updated(status)
})
}
deinit {

View File

@ -49,7 +49,7 @@ struct ParsedSecureValue {
let valueWithContext: SecureIdValueWithContext
}
func parseSecureValue(context: SecureIdAccessContext, value: Api.SecureValue) -> ParsedSecureValue? {
func parseSecureValue(context: SecureIdAccessContext, value: Api.SecureValue, errors: [Api.SecureValueError]) -> ParsedSecureValue? {
switch value {
case let .secureValue(_, type, data, files, plainData, selfie, hash):
let parsedFileReferences = files.flatMap { $0.compactMap(SecureIdFileReference.init) } ?? []
@ -60,11 +60,14 @@ func parseSecureValue(context: SecureIdAccessContext, value: Api.SecureValue) ->
let encryptedMetadata: SecureIdEncryptedValueMetadata?
var parsedFileMetadata: [SecureIdEncryptedValueFileMetadata] = []
var parsedSelfieMetadata: SecureIdEncryptedValueFileMetadata?
var contentsId: Data?
if let data = data {
let (encryptedData, decryptedHash, encryptedSecret) = parseSecureData(data)
guard let valueContext = decryptedSecureValueAccessContext(context: context, encryptedSecret: encryptedSecret, decryptedDataHash: decryptedHash) else {
return nil
}
contentsId = decryptedHash
decryptedData = decryptedSecureValueData(context: valueContext, encryptedData: encryptedData, decryptedDataHash: decryptedHash)
if decryptedData == nil {
@ -169,12 +172,12 @@ func parseSecureValue(context: SecureIdAccessContext, value: Api.SecureValue) ->
}
}
return ParsedSecureValue(valueWithContext: SecureIdValueWithContext(value: value, files: parsedFileMetadata, selfie: parsedSelfieMetadata, encryptedMetadata: encryptedMetadata, opaqueHash: hash.makeData()))
return ParsedSecureValue(valueWithContext: SecureIdValueWithContext(value: value, errors: parseSecureIdValueContentErrors(dataHash: contentsId, fileHashes: Set(parsedFileMetadata.map { $0.hash }), selfieHash: parsedSelfieMetadata?.hash, errors: errors), files: parsedFileMetadata, selfie: parsedSelfieMetadata, encryptedMetadata: encryptedMetadata, opaqueHash: hash.makeData()))
}
}
private func parseSecureValues(context: SecureIdAccessContext, values: [Api.SecureValue]) -> [SecureIdValueWithContext] {
return values.map({ parseSecureValue(context: context, value: $0) }).compactMap({ $0?.valueWithContext })
private func parseSecureValues(context: SecureIdAccessContext, values: [Api.SecureValue], errors: [Api.SecureValueError]) -> [SecureIdValueWithContext] {
return values.map({ parseSecureValue(context: context, value: $0, errors: errors) }).compactMap({ $0?.valueWithContext })
}
public struct EncryptedSecureIdForm {
@ -183,6 +186,7 @@ public struct EncryptedSecureIdForm {
public let termsUrl: String?
let encryptedValues: [Api.SecureValue]
let errors: [Api.SecureValueError]
}
public func requestSecureIdForm(postbox: Postbox, network: Network, peerId: PeerId, scope: String, publicKey: String) -> Signal<EncryptedSecureIdForm, RequestSecureIdFormError> {
@ -208,12 +212,12 @@ public func requestSecureIdForm(postbox: Postbox, network: Network, peerId: Peer
return EncryptedSecureIdForm(peerId: peerId, requestedFields: requiredTypes.map {
return parseSecureValueType($0, selfie: (flags & 1 << 1) != 0)
}, termsUrl: termsUrl, encryptedValues: values)
}, termsUrl: termsUrl, encryptedValues: values, errors: errors)
}
} |> mapError { _ in return RequestSecureIdFormError.generic }
}
}
public func decryptedSecureIdForm(context: SecureIdAccessContext, form: EncryptedSecureIdForm) -> SecureIdForm? {
return SecureIdForm(peerId: form.peerId, requestedFields: form.requestedFields, values: parseSecureValues(context: context, values: form.encryptedValues))
return SecureIdForm(peerId: form.peerId, requestedFields: form.requestedFields, values: parseSecureValues(context: context, values: form.encryptedValues, errors: form.errors))
}

View File

@ -210,7 +210,7 @@ public func saveSecureIdValue(postbox: Postbox, network: Network, context: Secur
return .generic
}
|> mapToSignal { result -> Signal<SecureIdValueWithContext, SaveSecureIdValueError> in
guard let parsedValue = parseSecureValue(context: context, value: result) else {
guard let parsedValue = parseSecureValue(context: context, value: result, errors: []) else {
return .fail(.generic)
}

View File

@ -124,13 +124,15 @@ struct SecureIdEncryptedValueMetadata: Equatable {
public struct SecureIdValueWithContext: Equatable {
public let value: SecureIdValue
public let errors: [SecureIdValueContentErrorKey: SecureIdValueContentError]
let files: [SecureIdEncryptedValueFileMetadata]
let selfie: SecureIdEncryptedValueFileMetadata?
let encryptedMetadata: SecureIdEncryptedValueMetadata?
let opaqueHash: Data
init(value: SecureIdValue, files: [SecureIdEncryptedValueFileMetadata], selfie: SecureIdEncryptedValueFileMetadata?, encryptedMetadata: SecureIdEncryptedValueMetadata?, opaqueHash: Data) {
init(value: SecureIdValue, errors: [SecureIdValueContentErrorKey: SecureIdValueContentError], files: [SecureIdEncryptedValueFileMetadata], selfie: SecureIdEncryptedValueFileMetadata?, encryptedMetadata: SecureIdEncryptedValueMetadata?, opaqueHash: Data) {
self.value = value
self.errors = errors
self.files = files
self.selfie = selfie
self.encryptedMetadata = encryptedMetadata

View File

@ -0,0 +1,105 @@
import Foundation
public enum SecureIdValueContentErrorKey: Hashable {
case field(SecureIdValueContentErrorField)
case file(hash: Data)
case files
case selfie
}
public enum SecureIdValueContentErrorField: Hashable {
case personalDetails(SecureIdValueContentErrorPersonalDetailsField)
case passport(SecureIdValueContentErrorPassportField)
case driversLicense(SecureIdValueContentErrorDriversLicenseField)
case idCard(SecureIdValueContentErrorIdCardField)
case address(SecureIdValueContentErrorAddressField)
}
public enum SecureIdValueContentErrorPersonalDetailsField: String, Hashable {
case firstName = "first_name"
case lastName = "last_name"
case birthdate = "birth_date"
case gender = "gender"
case countryCode = "country_code"
}
public enum SecureIdValueContentErrorPassportField: String, Hashable {
case documentId = "document_no"
case expiryDate = "expiry_date"
}
public enum SecureIdValueContentErrorDriversLicenseField: String, Hashable {
case documentId = "document_no"
case expiryDate = "expiry_date"
}
public enum SecureIdValueContentErrorIdCardField: String, Hashable {
case documentId = "document_no"
case expiryDate = "expiry_date"
}
public enum SecureIdValueContentErrorAddressField: String, Hashable {
case streetLine1 = "street_line1"
case streetLine2 = "street_line2"
case city = "city"
case state = "state"
case countryCode = "country_code"
case postCode = "post_code"
}
public typealias SecureIdValueContentError = String
func parseSecureIdValueContentErrors(dataHash: Data?, fileHashes: Set<Data>, selfieHash: Data?, errors: [Api.SecureValueError]) -> [SecureIdValueContentErrorKey: SecureIdValueContentError] {
var result: [SecureIdValueContentErrorKey: SecureIdValueContentError] = [:]
for error in errors {
switch error {
case let .secureValueErrorData(type, errorDataHash, field, text):
if errorDataHash.makeData() == dataHash {
switch type {
case .secureValueTypePersonalDetails:
if let parsedField = SecureIdValueContentErrorPersonalDetailsField(rawValue: field) {
result[.field(.personalDetails(parsedField))] = text
}
case .secureValueTypePassport:
if let parsedField = SecureIdValueContentErrorPassportField(rawValue: field) {
result[.field(.passport(parsedField))] = text
}
case .secureValueTypeDriverLicense:
if let parsedField = SecureIdValueContentErrorDriversLicenseField(rawValue: field) {
result[.field(.driversLicense(parsedField))] = text
}
case .secureValueTypeIdentityCard:
if let parsedField = SecureIdValueContentErrorIdCardField(rawValue: field) {
result[.field(.idCard(parsedField))] = text
}
case .secureValueTypeAddress:
if let parsedField = SecureIdValueContentErrorAddressField(rawValue: field) {
result[.field(.address(parsedField))] = text
}
default:
break
}
}
case let .secureValueErrorFile(_, fileHash, text):
if fileHashes.contains(fileHash.makeData()) {
result[.file(hash: fileHash.makeData())] = text
}
case let .secureValueErrorFiles(_, fileHash, text):
var containsAll = true
loop: for hash in fileHash {
if !fileHashes.contains(hash.makeData()) {
containsAll = false
break loop
}
}
if containsAll {
result[.files] = text
}
case let .secureValueErrorSelfie(_, fileHash, text):
if selfieHash == fileHash.makeData() {
result[.selfie] = text
}
}
}
return result
}