Update Ghostgram features

This commit is contained in:
ichmagmaus 812
2026-03-07 18:15:32 +01:00
parent 32b0dddcd9
commit 13a43b9068
902 changed files with 148302 additions and 62355 deletions
@@ -329,10 +329,10 @@ public func grantSecureIdAccess(network: Network, peerId: PeerId, publicKey: Str
var valueHashes: [Api.SecureValueHash] = []
for value in values {
valueHashes.append(.secureValueHash(type: apiSecureValueType(value: value.value), hash: Buffer(data: value.opaqueHash)))
valueHashes.append(.secureValueHash(.init(type: apiSecureValueType(value: value.value), hash: Buffer(data: value.opaqueHash))))
}
return network.request(Api.functions.account.acceptAuthorization(botId: peerId.id._internalGetInt64Value(), scope: scope, publicKey: publicKey, valueHashes: valueHashes, credentials: .secureCredentialsEncrypted(data: Buffer(data: encryptedCredentialsData), hash: Buffer(data: decryptedCredentialsHash), secret: Buffer(data: encryptedSecretData))))
return network.request(Api.functions.account.acceptAuthorization(botId: peerId.id._internalGetInt64Value(), scope: scope, publicKey: publicKey, valueHashes: valueHashes, credentials: .secureCredentialsEncrypted(.init(data: Buffer(data: encryptedCredentialsData), hash: Buffer(data: decryptedCredentialsHash), secret: Buffer(data: encryptedSecretData)))))
|> mapError { error -> GrantSecureIdAccessError in
return .generic
}
@@ -44,7 +44,8 @@ private func parseSecureValueType(_ type: Api.SecureValueType, selfie: Bool, tra
private func parseSecureData(_ value: Api.SecureData) -> (data: Data, hash: Data, secret: Data) {
switch value {
case let .secureData(data, dataHash, secret):
case let .secureData(secureDataData):
let (data, dataHash, secret) = (secureDataData.data, secureDataData.dataHash, secureDataData.secret)
return (data.makeData(), dataHash.makeData(), secret.makeData())
}
}
@@ -55,7 +56,8 @@ struct ParsedSecureValue {
func parseSecureValue(context: SecureIdAccessContext, value: Api.SecureValue, errors: [Api.SecureValueError]) -> ParsedSecureValue? {
switch value {
case let .secureValue(_, type, data, frontSide, reverseSide, selfie, translation, files, plainData, hash):
case let .secureValue(secureValueData):
let (_, type, data, frontSide, reverseSide, selfie, translation, files, plainData, hash) = (secureValueData.flags, secureValueData.type, secureValueData.data, secureValueData.frontSide, secureValueData.reverseSide, secureValueData.selfie, secureValueData.translation, secureValueData.files, secureValueData.plainData, secureValueData.hash)
let parsedFileReferences = files.flatMap { $0.compactMap(SecureIdFileReference.init) } ?? []
let parsedFiles = parsedFileReferences.map(SecureIdVerificationDocumentReference.remote)
let parsedTranslationReferences = translation.flatMap { $0.compactMap(SecureIdFileReference.init) } ?? []
@@ -204,7 +206,8 @@ func parseSecureValue(context: SecureIdAccessContext, value: Api.SecureValue, er
return nil
}
switch publicData {
case let .securePlainPhone(phone):
case let .securePlainPhone(securePlainPhoneData):
let (phone) = (securePlainPhoneData.phone)
value = .phone(SecureIdPhoneValue(phone: phone))
default:
return nil
@@ -214,7 +217,8 @@ func parseSecureValue(context: SecureIdAccessContext, value: Api.SecureValue, er
return nil
}
switch publicData {
case let .securePlainEmail(email):
case let .securePlainEmail(securePlainEmailData):
let (email) = (securePlainEmailData.email)
value = .email(SecureIdEmailValue(email: email))
default:
return nil
@@ -262,17 +266,21 @@ public func requestSecureIdForm(accountPeerId: PeerId, postbox: Postbox, network
|> mapToSignal { result -> Signal<EncryptedSecureIdForm, RequestSecureIdFormError> in
return postbox.transaction { transaction -> EncryptedSecureIdForm in
switch result {
case let .authorizationForm(_, requiredTypes, values, errors, users, termsUrl):
case let .authorizationForm(authorizationFormData):
let (_, requiredTypes, values, errors, users, termsUrl) = (authorizationFormData.flags, authorizationFormData.requiredTypes, authorizationFormData.values, authorizationFormData.errors, authorizationFormData.users, authorizationFormData.privacyPolicyUrl)
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: AccumulatedPeers(users: users))
return EncryptedSecureIdForm(peerId: peerId, requestedFields: requiredTypes.map { requiredType in
switch requiredType {
case let .secureRequiredType(flags, type):
case let .secureRequiredType(secureRequiredTypeData):
let (flags, type) = (secureRequiredTypeData.flags, secureRequiredTypeData.type)
return .just(parseSecureValueType(type, selfie: (flags & 1 << 1) != 0, translation: (flags & 1 << 2) != 0, nativeNames: (flags & 1 << 0) != 0))
case let .secureRequiredTypeOneOf(types):
case let .secureRequiredTypeOneOf(secureRequiredTypeOneOfData):
let (types) = (secureRequiredTypeOneOfData.types)
let parsedInnerTypes = types.compactMap { innerType -> SecureIdRequestedFormFieldValue? in
switch innerType {
case let .secureRequiredType(flags, type):
case let .secureRequiredType(secureRequiredTypeData):
let (flags, type) = (secureRequiredTypeData.flags, secureRequiredTypeData.type)
return parseSecureValueType(type, selfie: (flags & 1 << 1) != 0, translation: (flags & 1 << 2) != 0, nativeNames: (flags & 1 << 0) != 0)
case .secureRequiredTypeOneOf:
return nil
@@ -89,9 +89,9 @@ func decryptedSecureValueData(context: SecureIdValueAccessContext, encryptedData
private func apiInputSecretFile(_ file: SecureIdVerificationDocumentReference) -> Api.InputSecureFile {
switch file {
case let .remote(file):
return Api.InputSecureFile.inputSecureFile(id: file.id, accessHash: file.accessHash)
return Api.InputSecureFile.inputSecureFile(.init(id: file.id, accessHash: file.accessHash))
case let .uploaded(file):
return Api.InputSecureFile.inputSecureFileUploaded(id: file.id, parts: file.parts, md5Checksum: file.md5Checksum, fileHash: Buffer(data: file.fileHash), secret: Buffer(data: file.encryptedSecret))
return Api.InputSecureFile.inputSecureFileUploaded(.init(id: file.id, parts: file.parts, md5Checksum: file.md5Checksum, fileHash: Buffer(data: file.fileHash), secret: Buffer(data: file.encryptedSecret)))
}
}
@@ -142,9 +142,9 @@ private func inputSecureIdValueData(value: SecureIdValue) -> InputSecureIdValueD
let (dict, fileReferences, translations) = rentalAgreement.serialize()
return InputSecureIdValueData(type: .secureValueTypeRentalAgreement, dict: dict, fileReferences: fileReferences, translationReferences: translations, frontSideReference: nil, backSideReference: nil, selfieReference: nil, publicData: nil)
case let .phone(phone):
return InputSecureIdValueData(type: .secureValueTypePhone, dict: nil, fileReferences: [], translationReferences: [], frontSideReference: nil, backSideReference: nil, selfieReference: nil, publicData: .securePlainPhone(phone: phone.phone))
return InputSecureIdValueData(type: .secureValueTypePhone, dict: nil, fileReferences: [], translationReferences: [], frontSideReference: nil, backSideReference: nil, selfieReference: nil, publicData: .securePlainPhone(.init(phone: phone.phone)))
case let .email(email):
return InputSecureIdValueData(type: .secureValueTypeEmail, dict: nil, fileReferences: [], translationReferences: [], frontSideReference: nil, backSideReference: nil, selfieReference: nil, publicData: .securePlainEmail(email: email.email))
return InputSecureIdValueData(type: .secureValueTypeEmail, dict: nil, fileReferences: [], translationReferences: [], frontSideReference: nil, backSideReference: nil, selfieReference: nil, publicData: .securePlainEmail(.init(email: email.email)))
}
}
@@ -175,7 +175,7 @@ private func makeInputSecureValue(context: SecureIdAccessContext, value: SecureI
} else {
return nil
}
secureData = .secureData(data: Buffer(data: encryptedData.data), dataHash: Buffer(data: encryptedData.dataHash), secret: Buffer(data: encryptedData.encryptedSecret))
secureData = .secureData(.init(data: Buffer(data: encryptedData.data), dataHash: Buffer(data: encryptedData.dataHash), secret: Buffer(data: encryptedData.encryptedSecret)))
}
var flags: Int32 = 0
@@ -205,7 +205,7 @@ private func makeInputSecureValue(context: SecureIdAccessContext, value: SecureI
flags |= 1 << 5
}
return Api.InputSecureValue.inputSecureValue(flags: flags, type: inputData.type, data: secureData, frontSide: inputData.frontSideReference.flatMap(apiInputSecretFile), reverseSide: inputData.backSideReference.flatMap(apiInputSecretFile), selfie: inputData.selfieReference.flatMap(apiInputSecretFile), translation: translations, files: files, plainData: inputData.publicData)
return Api.InputSecureValue.inputSecureValue(.init(flags: flags, type: inputData.type, data: secureData, frontSide: inputData.frontSideReference.flatMap(apiInputSecretFile), reverseSide: inputData.backSideReference.flatMap(apiInputSecretFile), selfie: inputData.selfieReference.flatMap(apiInputSecretFile), translation: translations, files: files, plainData: inputData.publicData))
}
public func saveSecureIdValue(postbox: Postbox, network: Network, context: SecureIdAccessContext, value: SecureIdValue, uploadedFiles: [Data: Data]) -> Signal<SecureIdValueWithContext, SaveSecureIdValueError> {
@@ -286,7 +286,7 @@ public func dropSecureId(network: Network, currentPassword: String) -> Signal<Vo
if let currentPasswordDerivation = authData.currentPasswordDerivation, let srpSessionData = authData.srpSessionData {
let kdfResult = passwordKDF(encryptionProvider: network.encryptionProvider, password: currentPassword, derivation: currentPasswordDerivation, srpSessionData: srpSessionData)
if let kdfResult = kdfResult {
checkPassword = .inputCheckPasswordSRP(srpId: kdfResult.id, A: Buffer(data: kdfResult.A), M1: Buffer(data: kdfResult.M1))
checkPassword = .inputCheckPasswordSRP(.init(srpId: kdfResult.id, A: Buffer(data: kdfResult.A), M1: Buffer(data: kdfResult.M1)))
} else {
return .fail(.generic)
}
@@ -305,7 +305,7 @@ public func dropSecureId(network: Network, currentPassword: String) -> Signal<Vo
case .passwordSettings:
var flags: Int32 = 0
flags |= (1 << 2)
return network.request(Api.functions.account.updatePasswordSettings(password: .inputCheckPasswordEmpty, newSettings: .passwordInputSettings(flags: flags, newAlgo: nil, newPasswordHash: nil, hint: nil, email: nil, newSecureSettings: nil)), automaticFloodWait: false)
return network.request(Api.functions.account.updatePasswordSettings(password: .inputCheckPasswordEmpty, newSettings: .passwordInputSettings(.init(flags: flags, newAlgo: nil, newPasswordHash: nil, hint: nil, email: nil, newSecureSettings: nil))), automaticFloodWait: false)
|> map { _ in }
|> mapError { _ in
return AuthorizationPasswordVerificationError.generic
@@ -5,7 +5,7 @@ import TelegramApi
extension SecureFileMediaResource: TelegramCloudMediaResource, TelegramMultipartFetchableResource, EncryptedMediaResource {
func apiInputLocation(fileReference: Data?) -> Api.InputFileLocation? {
return Api.InputFileLocation.inputSecureFileLocation(id: self.file.id, accessHash: self.file.accessHash)
return Api.InputFileLocation.inputSecureFileLocation(.init(id: self.file.id, accessHash: self.file.accessHash))
}
public func decrypt(data: Data, params: Any) -> Data? {
@@ -27,9 +27,11 @@ public func secureIdConfiguration(postbox: Postbox, network: Network) -> Signal<
assertionFailure()
return .complete()
}
case let .passportConfig(hash, countriesLangs):
case let .passportConfig(passportConfigData):
let (hash, countriesLangs) = (passportConfigData.hash, passportConfigData.countriesLangs)
switch countriesLangs {
case let .dataJSON(data):
case let .dataJSON(dataJSONData):
let data = dataJSONData.data
let value = SecureIdConfiguration(jsonString: data)
parsed = CachedSecureIdConfiguration(value: value, hash: hash)
}
@@ -38,7 +38,8 @@ public enum SecureIdGender {
extension SecureIdFileReference {
init?(apiFile: Api.SecureFile) {
switch apiFile {
case let .secureFile(id, accessHash, size, dcId, date, fileHash, secret):
case let .secureFile(secureFileData):
let (id, accessHash, size, dcId, date, fileHash, secret) = (secureFileData.id, secureFileData.accessHash, secureFileData.size, secureFileData.dcId, secureFileData.date, secureFileData.fileHash, secureFileData.secret)
self.init(id: id, accessHash: accessHash, size: size, datacenterId: dcId, timestamp: date, fileHash: fileHash.makeData(), encryptedSecret: secret.makeData())
case .secureFileEmpty:
return nil
@@ -71,9 +71,11 @@ func parseSecureIdValueContentErrors(dataHash: Data?, fileHashes: Set<Data>, sel
var result: [SecureIdValueContentErrorKey: SecureIdValueContentError] = [:]
for error in errors {
switch error {
case let .secureValueError(type, _, text):
case let .secureValueError(secureValueErrorData):
let (type, _, text) = (secureValueErrorData.type, secureValueErrorData.hash, secureValueErrorData.text)
result[.value(SecureIdValueKey(apiType: type))] = text
case let .secureValueErrorData(type, errorDataHash, field, text):
case let .secureValueErrorData(secureValueErrorDataData):
let (type, errorDataHash, field, text) = (secureValueErrorDataData.type, secureValueErrorDataData.dataHash, secureValueErrorDataData.field, secureValueErrorDataData.text)
if errorDataHash.makeData() == dataHash {
switch type {
case .secureValueTypePersonalDetails:
@@ -104,11 +106,13 @@ func parseSecureIdValueContentErrors(dataHash: Data?, fileHashes: Set<Data>, sel
break
}
}
case let .secureValueErrorFile(_, fileHash, text):
case let .secureValueErrorFile(secureValueErrorFileData):
let (_, fileHash, text) = (secureValueErrorFileData.type, secureValueErrorFileData.fileHash, secureValueErrorFileData.text)
if fileHashes.contains(fileHash.makeData()) {
result[.file(hash: fileHash.makeData())] = text
}
case let .secureValueErrorFiles(_, fileHash, text):
case let .secureValueErrorFiles(secureValueErrorFilesData):
let (_, fileHash, text) = (secureValueErrorFilesData.type, secureValueErrorFilesData.fileHash, secureValueErrorFilesData.text)
var containsAll = true
loop: for hash in fileHash {
if !fileHashes.contains(hash.makeData()) {
@@ -119,11 +123,13 @@ func parseSecureIdValueContentErrors(dataHash: Data?, fileHashes: Set<Data>, sel
if containsAll {
result[.files(hashes: Set(fileHash.map { $0.makeData() }))] = text
}
case let .secureValueErrorTranslationFile(_, fileHash, text):
case let .secureValueErrorTranslationFile(secureValueErrorTranslationFileData):
let (_, fileHash, text) = (secureValueErrorTranslationFileData.type, secureValueErrorTranslationFileData.fileHash, secureValueErrorTranslationFileData.text)
if fileHashes.contains(fileHash.makeData()) {
result[.translationFile(hash: fileHash.makeData())] = text
}
case let .secureValueErrorTranslationFiles(_, fileHash, text):
case let .secureValueErrorTranslationFiles(secureValueErrorTranslationFilesData):
let (_, fileHash, text) = (secureValueErrorTranslationFilesData.type, secureValueErrorTranslationFilesData.fileHash, secureValueErrorTranslationFilesData.text)
var containsAll = true
loop: for hash in fileHash {
if !fileHashes.contains(hash.makeData()) {
@@ -134,15 +140,18 @@ func parseSecureIdValueContentErrors(dataHash: Data?, fileHashes: Set<Data>, sel
if containsAll {
result[.translationFiles(hashes: Set(fileHash.map { $0.makeData() }))] = text
}
case let .secureValueErrorSelfie(_, fileHash, text):
case let .secureValueErrorSelfie(secureValueErrorSelfieData):
let (_, fileHash, text) = (secureValueErrorSelfieData.type, secureValueErrorSelfieData.fileHash, secureValueErrorSelfieData.text)
if selfieHash == fileHash.makeData() {
result[.selfie(hash: fileHash.makeData())] = text
}
case let .secureValueErrorFrontSide(_, fileHash, text):
case let .secureValueErrorFrontSide(secureValueErrorFrontSideData):
let (_, fileHash, text) = (secureValueErrorFrontSideData.type, secureValueErrorFrontSideData.fileHash, secureValueErrorFrontSideData.text)
if frontSideHash == fileHash.makeData() {
result[.frontSide(hash: fileHash.makeData())] = text
}
case let .secureValueErrorReverseSide(_, fileHash, text):
case let .secureValueErrorReverseSide(secureValueErrorReverseSideData):
let (_, fileHash, text) = (secureValueErrorReverseSideData.type, secureValueErrorReverseSideData.fileHash, secureValueErrorReverseSideData.text)
if backSideHash == fileHash.makeData() {
result[.backSide(hash: fileHash.makeData())] = text
}
@@ -112,12 +112,8 @@ public func uploadSecureIdFile(context: SecureIdAccessContext, postbox: Postbox,
switch result {
case let .progress(value):
return .single(.progress(value))
case let .inputFile(file):
if case let .inputFile(id, parts, _, md5Checksum) = file {
return .single(.result(UploadedSecureIdFile(id: id, parts: parts, md5Checksum: md5Checksum, fileHash: encryptedData.hash, encryptedSecret: encryptedData.encryptedSecret), encryptedData.data))
} else {
return .fail(.generic)
}
case let .inputFile(.inputFile(fileData)):
return .single(.result(UploadedSecureIdFile(id: fileData.id, parts: fileData.parts, md5Checksum: fileData.md5Checksum, fileHash: encryptedData.hash, encryptedSecret: encryptedData.encryptedSecret), encryptedData.data))
default:
return .fail(.generic)
}
@@ -19,7 +19,7 @@ public struct SecureIdPreparePhoneVerificationPayload {
}
public func secureIdPreparePhoneVerification(network: Network, value: SecureIdPhoneValue) -> Signal<SecureIdPreparePhoneVerificationPayload, SecureIdPreparePhoneVerificationError> {
return network.request(Api.functions.account.sendVerifyPhoneCode(phoneNumber: value.phone, settings: .codeSettings(flags: 0, logoutTokens: nil, token: nil, appSandbox: nil)), automaticFloodWait: false)
return network.request(Api.functions.account.sendVerifyPhoneCode(phoneNumber: value.phone, settings: .codeSettings(.init(flags: 0, logoutTokens: nil, token: nil, appSandbox: nil))), automaticFloodWait: false)
|> mapError { error -> SecureIdPreparePhoneVerificationError in
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
return .flood
@@ -28,7 +28,8 @@ public func secureIdPreparePhoneVerification(network: Network, value: SecureIdPh
}
|> mapToSignal { sentCode -> Signal<SecureIdPreparePhoneVerificationPayload, SecureIdPreparePhoneVerificationError> in
switch sentCode {
case let .sentCode(_, type, phoneCodeHash, nextType, timeout):
case let .sentCode(sentCodeData):
let (type, phoneCodeHash, nextType, timeout) = (sentCodeData.type, sentCodeData.phoneCodeHash, sentCodeData.nextType, sentCodeData.timeout)
return .single(SecureIdPreparePhoneVerificationPayload(type: SentAuthorizationCodeType(apiType: type), nextType: nextType.flatMap(AuthorizationCodeNextType.init), timeout: timeout, phone: value.phone, phoneCodeHash: phoneCodeHash))
case .sentCodeSuccess, .sentCodePaymentRequired:
return .never()
@@ -84,7 +85,8 @@ public func secureIdPrepareEmailVerification(network: Network, value: SecureIdEm
}
|> map { sentCode -> SecureIdPrepareEmailVerificationPayload in
switch sentCode {
case .sentEmailCode(_, let length):
case let .sentEmailCode(sentEmailCodeData):
let length = sentEmailCodeData.length
return SecureIdPrepareEmailVerificationPayload(email: value.email, length: length)
}
}
@@ -97,7 +99,7 @@ public enum SecureIdCommitEmailVerificationError {
}
public func secureIdCommitEmailVerification(postbox: Postbox, network: Network, context: SecureIdAccessContext, payload: SecureIdPrepareEmailVerificationPayload, code: String) -> Signal<SecureIdValueWithContext, SecureIdCommitEmailVerificationError> {
return network.request(Api.functions.account.verifyEmail(purpose: .emailVerifyPurposePassport, verification: .emailVerificationCode(code: code)), automaticFloodWait: false)
return network.request(Api.functions.account.verifyEmail(purpose: .emailVerifyPurposePassport, verification: .emailVerificationCode(.init(code: code))), automaticFloodWait: false)
|> mapError { error -> SecureIdCommitEmailVerificationError in
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
return .flood