Update Ghostgram features

This commit is contained in:
ichmagmaus 812
2026-03-07 18:15:32 +01:00
parent 1a3303b059
commit 24a7ec39d9
902 changed files with 148295 additions and 62348 deletions
@@ -35,7 +35,8 @@ func _internal_exportAuthTransferToken(accountManager: AccountManager<TelegramAc
}
|> mapToSignal { result -> Signal<Api.auth.LoginToken?, ExportAuthTransferTokenError> in
switch result {
case let .password(_, _, _, _, hint, _, _, _, _, _, _):
case let .password(passwordData):
let hint = passwordData.hint
return account.postbox.transaction { transaction -> Api.auth.LoginToken? in
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .passwordEntry(hint: hint ?? "", number: nil, code: nil, suggestReset: false, syncContacts: syncContacts)))
return nil
@@ -52,9 +53,11 @@ func _internal_exportAuthTransferToken(accountManager: AccountManager<TelegramAc
return .single(.passwordRequested(account))
}
switch result {
case let .loginToken(expires, token):
case let .loginToken(loginTokenData):
let (expires, token) = (loginTokenData.expires, loginTokenData.token)
return .single(.displayToken(AuthTransferExportedToken(value: token.makeData(), validUntil: expires)))
case let .loginTokenMigrateTo(dcId, token):
case let .loginTokenMigrateTo(loginTokenMigrateToData):
let (dcId, token) = (loginTokenMigrateToData.dcId, loginTokenMigrateToData.token)
let updatedAccount = account.changedMasterDatacenterId(accountManager: accountManager, masterDatacenterId: dcId)
return updatedAccount
|> castError(ExportAuthTransferTokenError.self)
@@ -73,7 +76,8 @@ func _internal_exportAuthTransferToken(accountManager: AccountManager<TelegramAc
}
|> mapToSignal { result -> Signal<Api.auth.LoginToken?, ExportAuthTransferTokenError> in
switch result {
case let .password(_, _, _, _, hint, _, _, _, _, _, _):
case let .password(passwordData):
let hint = passwordData.hint
return updatedAccount.postbox.transaction { transaction -> Api.auth.LoginToken? in
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: updatedAccount.testingEnvironment, masterDatacenterId: updatedAccount.masterDatacenterId, contents: .passwordEntry(hint: hint ?? "", number: nil, code: nil, suggestReset: false, syncContacts: syncContacts)))
return nil
@@ -90,15 +94,17 @@ func _internal_exportAuthTransferToken(accountManager: AccountManager<TelegramAc
return .single(.passwordRequested(updatedAccount))
}
switch result {
case let .loginTokenSuccess(authorization):
case let .loginTokenSuccess(loginTokenSuccessData):
let authorization = loginTokenSuccessData.authorization
switch authorization {
case let .authorization(_, _, _, futureAuthToken, user):
case let .authorization(authorizationData):
let (futureAuthToken, apiUser) = (authorizationData.futureAuthToken, authorizationData.user)
if let futureAuthToken = futureAuthToken {
storeFutureLoginToken(accountManager: accountManager, token: futureAuthToken.makeData())
}
return updatedAccount.postbox.transaction { transaction -> Signal<ExportAuthTransferTokenResult, ExportAuthTransferTokenError> in
let user = TelegramUser(user: user)
let user = TelegramUser(user: apiUser)
let state = AuthorizedAccountState(isTestingEnvironment: updatedAccount.testingEnvironment, masterDatacenterId: updatedAccount.masterDatacenterId, peerId: user.id, state: nil, invalidatedChannels: [])
initializedAppSettingsAfterLogin(transaction: transaction, appVersion: updatedAccount.networkArguments.appVersion, syncContacts: syncContacts)
transaction.setState(state)
@@ -118,15 +124,17 @@ func _internal_exportAuthTransferToken(accountManager: AccountManager<TelegramAc
}
}
}
case let .loginTokenSuccess(authorization):
case let .loginTokenSuccess(loginTokenSuccessData):
let authorization = loginTokenSuccessData.authorization
switch authorization {
case let .authorization(_, _, _, futureAuthToken, user):
case let .authorization(authorizationData):
let (futureAuthToken, apiUser) = (authorizationData.futureAuthToken, authorizationData.user)
if let futureAuthToken = futureAuthToken {
storeFutureLoginToken(accountManager: accountManager, token: futureAuthToken.makeData())
}
return account.postbox.transaction { transaction -> Signal<ExportAuthTransferTokenResult, ExportAuthTransferTokenError> in
let user = TelegramUser(user: user)
let user = TelegramUser(user: apiUser)
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil, invalidatedChannels: [])
initializedAppSettingsAfterLogin(transaction: transaction, appVersion: account.networkArguments.appVersion, syncContacts: syncContacts)
transaction.setState(state)
@@ -18,7 +18,7 @@ public enum RequestCancelAccountResetDataError {
}
func _internal_requestCancelAccountResetData(network: Network, hash: String) -> Signal<CancelAccountResetData, RequestCancelAccountResetDataError> {
return network.request(Api.functions.account.sendConfirmPhoneCode(hash: hash, settings: .codeSettings(flags: 0, logoutTokens: nil, token: nil, appSandbox: nil)), automaticFloodWait: false)
return network.request(Api.functions.account.sendConfirmPhoneCode(hash: hash, settings: .codeSettings(.init(flags: 0, logoutTokens: nil, token: nil, appSandbox: nil))), automaticFloodWait: false)
|> mapError { error -> RequestCancelAccountResetDataError in
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
return .limitExceeded
@@ -28,7 +28,8 @@ func _internal_requestCancelAccountResetData(network: Network, hash: String) ->
}
|> mapToSignal { sentCode -> Signal<CancelAccountResetData, RequestCancelAccountResetDataError> 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)
var parsedNextType: AuthorizationCodeNextType?
if let nextType = nextType {
parsedNextType = AuthorizationCodeNextType(apiType: nextType)
@@ -51,7 +52,8 @@ func _internal_requestNextCancelAccountResetOption(network: Network, phoneNumber
}
|> mapToSignal { sentCode -> Signal<CancelAccountResetData, RequestCancelAccountResetDataError> 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)
var parsedNextType: AuthorizationCodeNextType?
if let nextType = nextType {
parsedNextType = AuthorizationCodeNextType(apiType: nextType)
@@ -116,7 +116,7 @@ public extension TelegramEngine {
guard let kdfResult = passwordKDF(encryptionProvider: network.encryptionProvider, password: password, derivation: currentPasswordDerivation, srpSessionData: srpSessionData) else {
return .fail(.generic)
}
return .single(.inputCheckPasswordSRP(srpId: kdfResult.id, A: Buffer(data: kdfResult.A), M1: Buffer(data: kdfResult.M1)))
return .single(.inputCheckPasswordSRP(.init(srpId: kdfResult.id, A: Buffer(data: kdfResult.A), M1: Buffer(data: kdfResult.M1))))
} else {
return .single(nil)
}
@@ -15,7 +15,8 @@ func _internal_twoStepVerificationConfiguration(account: Account) -> Signal<TwoS
|> retryRequest
|> map { result -> TwoStepVerificationConfiguration in
switch result {
case let .password(flags, currentAlgo, _, _, hint, emailUnconfirmedPattern, _, _, _, pendingResetDate, _):
case let .password(passwordData):
let (flags, currentAlgo, hint, emailUnconfirmedPattern, pendingResetDate) = (passwordData.flags, passwordData.currentAlgo, passwordData.hint, passwordData.emailUnconfirmedPattern, passwordData.pendingResetDate)
if currentAlgo != nil {
return .set(hint: hint ?? "", hasRecoveryEmail: (flags & (1 << 0)) != 0, pendingEmail: emailUnconfirmedPattern.flatMap({ TwoStepVerificationPendingEmail(pattern: $0, codeLength: nil) }), hasSecureValues: (flags & (1 << 1)) != 0, pendingResetTimestamp: pendingResetDate)
} else {
@@ -56,7 +57,7 @@ func _internal_requestTwoStepVerifiationSettings(network: Network, password: Str
return .fail(.generic)
}
return network.request(Api.functions.account.getPasswordSettings(password: .inputCheckPasswordSRP(srpId: kdfResult.id, A: Buffer(data: kdfResult.A), M1: Buffer(data: kdfResult.M1))), automaticFloodWait: false)
return network.request(Api.functions.account.getPasswordSettings(password: .inputCheckPasswordSRP(.init(srpId: kdfResult.id, A: Buffer(data: kdfResult.A), M1: Buffer(data: kdfResult.M1)))), automaticFloodWait: false)
|> mapError { error -> AuthorizationPasswordVerificationError in
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
return .limitExceeded
@@ -68,11 +69,13 @@ func _internal_requestTwoStepVerifiationSettings(network: Network, password: Str
}
|> mapToSignal { result -> Signal<TwoStepVerificationSettings, AuthorizationPasswordVerificationError> in
switch result {
case let .passwordSettings(_, email, secureSettings):
case let .passwordSettings(passwordSettingsData):
let (email, secureSettings) = (passwordSettingsData.email, passwordSettingsData.secureSettings)
var parsedSecureSecret: TwoStepVerificationSecureSecret?
if let secureSettings = secureSettings {
switch secureSettings {
case let .secureSecretSettings(secureAlgo, secureSecret, secureSecretId):
case let .secureSecretSettings(secureSecretSettingsData):
let (secureAlgo, secureSecret, secureSecretId) = (secureSecretSettingsData.secureAlgo, secureSecretSettingsData.secureSecret, secureSecretSettingsData.secureSecretId)
if secureSecret.size != 32 {
return .fail(.generic)
}
@@ -141,7 +144,7 @@ func _internal_updateTwoStepVerificationPassword(network: Network, currentPasswo
let checkPassword: Api.InputCheckPasswordSRP
if let currentPasswordDerivation = authData.currentPasswordDerivation, let srpSessionData = authData.srpSessionData {
if let kdfResult = passwordKDF(encryptionProvider: network.encryptionProvider, password: currentPassword ?? "", derivation: currentPasswordDerivation, srpSessionData: srpSessionData) {
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)
}
@@ -156,7 +159,7 @@ func _internal_updateTwoStepVerificationPassword(network: Network, currentPasswo
flags |= (1 << 0)
}
return network.request(Api.functions.account.updatePasswordSettings(password: checkPassword, newSettings: .passwordInputSettings(flags: flags, newAlgo: .passwordKdfAlgoUnknown, newPasswordHash: Buffer(data: Data()), hint: "", email: "", newSecureSettings: nil)), automaticFloodWait: true)
return network.request(Api.functions.account.updatePasswordSettings(password: checkPassword, newSettings: .passwordInputSettings(.init(flags: flags, newAlgo: .passwordKdfAlgoUnknown, newPasswordHash: Buffer(data: Data()), hint: "", email: "", newSecureSettings: nil))), automaticFloodWait: true)
|> mapError { _ -> UpdateTwoStepVerificationPasswordError in
return .generic
}
@@ -189,10 +192,10 @@ func _internal_updateTwoStepVerificationPassword(network: Network, currentPasswo
var updatedSecureSettings: Api.SecureSecretSettings?
if let updatedSecureSecret = updatedSecureSecret {
flags |= 1 << 2
updatedSecureSettings = .secureSecretSettings(secureAlgo: updatedSecureSecret.derivation.apiAlgo, secureSecret: Buffer(data: updatedSecureSecret.data), secureSecretId: updatedSecureSecret.id)
updatedSecureSettings = .secureSecretSettings(.init(secureAlgo: updatedSecureSecret.derivation.apiAlgo, secureSecret: Buffer(data: updatedSecureSecret.data), secureSecretId: updatedSecureSecret.id))
}
return network.request(Api.functions.account.updatePasswordSettings(password: checkPassword, newSettings: Api.account.PasswordInputSettings.passwordInputSettings(flags: flags, newAlgo: updatedPasswordDerivation.apiAlgo, newPasswordHash: Buffer(data: updatedPasswordHash), hint: hint, email: email, newSecureSettings: updatedSecureSettings)), automaticFloodWait: false)
return network.request(Api.functions.account.updatePasswordSettings(password: checkPassword, newSettings: Api.account.PasswordInputSettings.passwordInputSettings(.init(flags: flags, newAlgo: updatedPasswordDerivation.apiAlgo, newPasswordHash: Buffer(data: updatedPasswordHash), hint: hint, email: email, newSecureSettings: updatedSecureSettings))), automaticFloodWait: false)
|> map { _ -> UpdateTwoStepVerificationPasswordResult in
return .password(password: password, pendingEmail: nil)
}
@@ -245,14 +248,14 @@ func updateTwoStepVerificationSecureSecret(network: Network, password: String, s
return .fail(.generic)
}
let checkPassword: Api.InputCheckPasswordSRP = .inputCheckPasswordSRP(srpId: kdfResult.id, A: Buffer(data: kdfResult.A), M1: Buffer(data: kdfResult.M1))
let checkPassword: Api.InputCheckPasswordSRP = .inputCheckPasswordSRP(.init(srpId: kdfResult.id, A: Buffer(data: kdfResult.A), M1: Buffer(data: kdfResult.M1)))
guard let (encryptedSecret, secretDerivation, secretId) = encryptedSecureSecret(secretData: secret, password: password, inputDerivation: authData.nextSecurePasswordDerivation) else {
return .fail(.generic)
}
let flags: Int32 = (1 << 2)
return network.request(Api.functions.account.updatePasswordSettings(password: checkPassword, newSettings: .passwordInputSettings(flags: flags, newAlgo: nil, newPasswordHash: nil, hint: "", email: "", newSecureSettings: .secureSecretSettings(secureAlgo: secretDerivation.apiAlgo, secureSecret: Buffer(data: encryptedSecret), secureSecretId: secretId))), automaticFloodWait: true)
return network.request(Api.functions.account.updatePasswordSettings(password: checkPassword, newSettings: .passwordInputSettings(.init(flags: flags, newAlgo: nil, newPasswordHash: nil, hint: "", email: "", newSecureSettings: .secureSecretSettings(.init(secureAlgo: secretDerivation.apiAlgo, secureSecret: Buffer(data: encryptedSecret), secureSecretId: secretId))))), automaticFloodWait: true)
|> mapError { _ -> UpdateTwoStepVerificationSecureSecretError in
return .generic
}
@@ -273,13 +276,13 @@ func _internal_updateTwoStepVerificationEmail(network: Network, currentPassword:
guard let kdfResult = passwordKDF(encryptionProvider: network.encryptionProvider, password: currentPassword, derivation: currentPasswordDerivation, srpSessionData: srpSessionData) else {
return .fail(.generic)
}
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 {
checkPassword = .inputCheckPasswordEmpty
}
let flags: Int32 = 1 << 1
return network.request(Api.functions.account.updatePasswordSettings(password: checkPassword, newSettings: Api.account.PasswordInputSettings.passwordInputSettings(flags: flags, newAlgo: nil, newPasswordHash: nil, hint: nil, email: updatedEmail, newSecureSettings: nil)), automaticFloodWait: false)
return network.request(Api.functions.account.updatePasswordSettings(password: checkPassword, newSettings: Api.account.PasswordInputSettings.passwordInputSettings(.init(flags: flags, newAlgo: nil, newPasswordHash: nil, hint: nil, email: updatedEmail, newSecureSettings: nil))), automaticFloodWait: false)
|> map { _ -> UpdateTwoStepVerificationPasswordResult in
return .password(password: currentPassword, pendingEmail: nil)
}
@@ -327,7 +330,8 @@ func _internal_requestTwoStepVerificationPasswordRecoveryCode(network: Network)
}
|> map { result -> String in
switch result {
case let .passwordRecovery(emailPattern):
case let .passwordRecovery(passwordRecoveryData):
let (emailPattern) = (passwordRecoveryData.emailPattern)
return emailPattern
}
}
@@ -370,12 +374,13 @@ func _internal_requestTemporaryTwoStepPasswordToken(account: Account, password:
return .fail(MTRpcError(errorCode: 400, errorDescription: "KDF_ERROR"))
}
let checkPassword: Api.InputCheckPasswordSRP = .inputCheckPasswordSRP(srpId: kdfResult.id, A: Buffer(data: kdfResult.A), M1: Buffer(data: kdfResult.M1))
let checkPassword: Api.InputCheckPasswordSRP = .inputCheckPasswordSRP(.init(srpId: kdfResult.id, A: Buffer(data: kdfResult.A), M1: Buffer(data: kdfResult.M1)))
return account.network.request(Api.functions.account.getTmpPassword(password: checkPassword, period: period), automaticFloodWait: false)
|> map { result -> TemporaryTwoStepPasswordToken in
switch result {
case let .tmpPassword(tmpPassword, validUntil):
case let .tmpPassword(tmpPasswordData):
let (tmpPassword, validUntil) = (tmpPasswordData.tmpPassword, tmpPasswordData.validUntil)
return TemporaryTwoStepPasswordToken(token: tmpPassword.makeData(), validUntilDate: validUntil, requiresBiometrics: requiresBiometrics)
}
}
@@ -407,11 +412,13 @@ func _internal_requestTwoStepPasswordReset(network: Network) -> Signal<RequestTw
return network.request(Api.functions.account.resetPassword(), automaticFloodWait: false)
|> map { result -> RequestTwoStepPasswordResetResult in
switch result {
case let .resetPasswordFailedWait(retryDate):
case let .resetPasswordFailedWait(resetPasswordFailedWaitData):
let retryDate = resetPasswordFailedWaitData.retryDate
return .error(reason: .limitExceeded(retryAtTimestamp: retryDate))
case .resetPasswordOk:
return .done
case let .resetPasswordRequestedWait(untilDate):
case let .resetPasswordRequestedWait(resetPasswordRequestedWaitData):
let untilDate = resetPasswordRequestedWaitData.untilDate
return .waitingForReset(resetAtTimestamp: untilDate)
}
}