Commit ec6477d3 authored by Elephant's avatar Elephant
Browse files

RELEASE 2.6.0

parent eb56bb33
This diff is collapsed.
......@@ -60,8 +60,8 @@
"repositoryURL": "https://github.com/Scandit/datacapture-spm-barcode.git",
"state": {
"branch": null,
"revision": "392396aa63f1bf6419dd1e0b39e116fb4695eda1",
"version": "6.9.0"
"revision": "95df67f4a7625a83175899cfd01587970a2049c8",
"version": "6.10.1"
}
},
{
......@@ -69,8 +69,8 @@
"repositoryURL": "https://github.com/Scandit/datacapture-spm-core",
"state": {
"branch": null,
"revision": "46ad1804687e59e88d7558495802e0311dc8da1c",
"version": "6.9.0"
"revision": "9d70d9514d1b4381e9e47952f290539e05f21a49",
"version": "6.10.1"
}
},
{
......@@ -78,8 +78,8 @@
"repositoryURL": "https://github.com/eu-digital-green-certificates/json-logic-swift.git",
"state": {
"branch": null,
"revision": "c830f34a35753f4d441bd291e40e4a4feee9ede0",
"version": "1.1.9"
"revision": "e59a317e03491abe1f04c87b965a52abae243ddd",
"version": "1.1.8"
}
},
{
......@@ -96,8 +96,8 @@
"repositoryURL": "https://github.com/Kitura/KituraContracts.git",
"state": {
"branch": null,
"revision": "8418006e39e2efae9b31ae92721cb597ac29c617",
"version": "1.2.200"
"revision": "8a4778c3aa7833e9e1af884e8819d436c237cd70",
"version": "1.2.201"
}
},
{
......@@ -123,8 +123,8 @@
"repositoryURL": "https://github.com/kylef/PathKit.git",
"state": {
"branch": null,
"revision": "73f8e9dca9b7a3078cb79128217dc8f2e585a511",
"version": "1.0.0"
"revision": "3bfd2737b700b9a36565a8c94f4ad2b050a5e574",
"version": "1.0.1"
}
},
{
......
......@@ -5,7 +5,7 @@
//
import Foundation
import WalletCommunication
import INCommunication
import os.log
import UIKit
......
......@@ -81,7 +81,12 @@ struct PlusValidity: Codable {
struct HealthPassValidity: PassVerifierCommonRulesConfig, Codable {
let testNegativePcrEndHour, testNegativeAntigenicEndHour: Int
let testPositivePcrEndDay, testPositivePcrStartDay, testPositiveAntigenicStartDay, testPositiveAntigenicEndDay, recoveryStartDay: Int
let vaccineDelay, vaccineDelayJanssen, vaccineDelayMax, vaccineDelayMaxJanssen,vaccineBoosterDelayNew, vaccineBoosterDelayMax: Int
let vaccineDelay, vaccineDelayMax: Int
let vaccineBoosterDelayNew, vaccineBoosterDelayMax: Int
let vaccineDelayJanssen1, vaccineDelayMaxJanssen1, vaccineDelayJanssen2, vaccineDelayMaxJanssen2, vaccineBoosterDelayMaxJanssen: Int
let vaccineDelayNovavax, vaccineDelayMaxRecoveryNovavax, vaccineDelayMaxNovavax, vaccineBoosterDelayMaxNovavax: Int
let vaccineBoosterDelayUnderAgeNew, vaccineDelayMaxRecovery: Int
let vaccineBoosterAgePeriod: String
let recoveryAcceptanceAgePeriod: String
......@@ -91,7 +96,12 @@ struct HealthPassValidity: PassVerifierCommonRulesConfig, Codable {
struct VaccinePassValidity: PassVerifierCommonRulesConfig, Codable {
let testNegativePcrEndHour, testNegativeAntigenicEndHour: Int
let testPositivePcrEndDay, testPositivePcrStartDay, testPositiveAntigenicStartDay, testPositiveAntigenicEndDay, recoveryStartDay: Int
let vaccineDelay, vaccineDelayJanssen, vaccineDelayMax, vaccineDelayMaxJanssen,vaccineBoosterDelayNew, vaccineBoosterDelayMax: Int
let vaccineDelay, vaccineDelayMax: Int
let vaccineBoosterDelayNew, vaccineBoosterDelayMax: Int
let vaccineDelayJanssen1, vaccineDelayMaxJanssen1, vaccineDelayJanssen2, vaccineDelayMaxJanssen2, vaccineBoosterDelayMaxJanssen: Int
let vaccineDelayNovavax, vaccineDelayMaxRecoveryNovavax, vaccineDelayMaxNovavax, vaccineBoosterDelayMaxNovavax: Int
let vaccineBoosterDelayUnderAgeNew, vaccineDelayMaxRecovery: Int
let vaccineBoosterAgePeriod: String
let testAcceptanceAgePeriod: String
......
......@@ -19,21 +19,28 @@ struct ConstRules {
testPositiveAntigenicEndDay: 183,
recoveryStartDay: 11,
vaccineDelay: 7,
vaccineDelayJanssen: 28,
vaccineDelayMax: 221,
vaccineDelayMaxJanssen: 68,
vaccineDelayMax: 129,
vaccineBoosterDelayNew: 7,
vaccineBoosterDelayMax: 6000,
vaccineBoosterDelayUnderAgeNew:7,
vaccineDelayMaxRecovery: 221,
vaccineDelayJanssen1: 28,
vaccineDelayMaxJanssen1: 68,
vaccineDelayJanssen2: 7,
vaccineDelayMaxJanssen2: 129,
vaccineBoosterDelayMaxJanssen: 129,
vaccineDelayNovavax: 7,
vaccineDelayMaxRecoveryNovavax: 160,
vaccineDelayMaxNovavax: 150,
vaccineBoosterDelayMaxNovavax: 170,
vaccineBoosterDelayUnderAgeNew: 7,
vaccineDelayMaxRecovery: 129,
vaccineBoosterAgePeriod: "P18Y1M",
testAcceptanceAgePeriod: "P16Y",
recoveryAcceptanceAgePeriod: "P18Y",
recoveryDelayMaxTV: 183,
recoveryDelayMax: 183,
recoveryDelayMaxUnderAge: 183
recoveryDelayMaxTV: 6000,
recoveryDelayMax: 122,
recoveryDelayMaxUnderAge: 122
)
static let healthPassValidity = HealthPassValidity(
testNegativePcrEndHour: 24,
testNegativeAntigenicEndHour: 24,
......@@ -43,18 +50,25 @@ struct ConstRules {
testPositiveAntigenicEndDay: 183,
recoveryStartDay: 11,
vaccineDelay: 7,
vaccineDelayJanssen: 28,
vaccineDelayMax: 221,
vaccineDelayMaxJanssen: 68,
vaccineDelayMax: 129,
vaccineBoosterDelayNew: 7,
vaccineBoosterDelayMax: 6000,
vaccineBoosterDelayUnderAgeNew:7,
vaccineDelayMaxRecovery: 221,
vaccineDelayJanssen1: 28,
vaccineDelayMaxJanssen1: 68,
vaccineDelayJanssen2: 7,
vaccineDelayMaxJanssen2: 129,
vaccineBoosterDelayMaxJanssen: 129,
vaccineDelayNovavax: 7,
vaccineDelayMaxRecoveryNovavax: 160,
vaccineDelayMaxNovavax: 150,
vaccineBoosterDelayMaxNovavax: 170,
vaccineBoosterDelayUnderAgeNew: 7,
vaccineDelayMaxRecovery: 129,
vaccineBoosterAgePeriod: "P18Y1M",
recoveryAcceptanceAgePeriod: "P18Y",
recoveryDelayMaxTV: 183,
recoveryDelayMax: 183,
recoveryDelayMaxUnderAge: 183
recoveryDelayMaxTV: 6000,
recoveryDelayMax: 122,
recoveryDelayMaxUnderAge: 122
)
static let vaccineProphylaxisList = [
......@@ -88,6 +102,7 @@ struct ConstRules {
"EU/1/20/1507": "Spikevax (previously COVID-19 Vaccine Moderna)",
"EU/1/21/1529": "Vaxzevria",
"EU/1/20/1525": "COVID-19 Vaccine Janssen",
"EU/1/21/1618": "Nuvaxovid",
"Covishield": "Covishield (ChAdOx1_nCoV-19)",
"R-Covi": "R-Covi",
"Covid-19 vaccine (recombinante)": "Covid-19 vaccine (recombinante)"
......@@ -179,5 +194,7 @@ struct ConstRules {
"LP217198-3": "Rapid immunoassay",
"945584": "94558-4 Antigénique COVID"
]
static let testPrefixes = ["TV"]
}
......@@ -255,17 +255,17 @@ extension Date {
}
#endif
func roundingToBeginningOfDay() -> Date? {
func roundingToBeginningOfDay() -> Date {
var components: DateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: self)
components.hour = 0
components.minute = 0
components.second = 0
return Calendar.current.date(from: components)
return Calendar.current.date(from: components)!
}
func roundingToEndOfDay() -> Date {
var components: DateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: self)
components.hour = 24
components.hour = 23
components.minute = 59
components.second = 59
return Calendar.current.date(from: components)!
......
//
// WalletCommunication+extension.swift
// INCommunication+extension.swift
// Anticovid Verify
//
import Foundation
import WalletCore
import WalletCommunication
import INCore
import INCommunication
import Combine
extension WalletRequestService {
func executeRequest<D: Decodable & Encodable>(_ requestConvertible: INURLRequestConvertible, type: D.Type, typeDateDecoderStrategy: JSONDecoder.DateDecodingStrategy = .deferredToDate, headers: INHTTPHeaders? = nil, p12: WalletPKCS12? = nil, httpShouldSetCookies: Bool = true, timeout: Int? = 20, pinCertificates: [SecCertificate] = [SecCertificate]()) -> Future<D, Error> {
extension INRequestService {
func executeRequest<D: Decodable & Encodable>(_ requestConvertible: INURLRequestConvertible, type: D.Type, typeDateDecoderStrategy: JSONDecoder.DateDecodingStrategy = .deferredToDate, headers: INHTTPHeaders? = nil, p12: INPKCS12? = nil, httpShouldSetCookies: Bool = true, timeout: Int? = 20, pinCertificates: [SecCertificate] = [SecCertificate]()) -> Future<D, Error> {
Future { promise in
let date = Date()
let text = date.dateTimeString + " " + (requestConvertible.urlRequest?.url?.path ?? " unknown path ") + " start"
......
......@@ -187,4 +187,13 @@ extension String {
func caseInsensitiveHasPrefix(_ prefix: String) -> Bool {
return lowercased().hasPrefix(prefix.lowercased())
}
func checkAndReturnCurrentPrefix(in prefixes: [String]) -> String {
for current in prefixes {
if self.caseInsensitiveHasPrefix(current) {
return current
}
}
return ""
}
}
......@@ -5,7 +5,7 @@
//
import Foundation
import WalletCore
import INCore
class PremiumManager {
......@@ -30,20 +30,20 @@ class PremiumManager {
private(set) var tokenOT: String {
get {
return try! WalletPersistentData.getString(forKey: tokenOTKey, encrypted: false, defaultValue: "")
return try! INPersistentData.getString(forKey: tokenOTKey, encrypted: false, defaultValue: "")
}
set(value) {
modeSelected = !value.isEmpty ? .OT : modesAvailable().first!
try! WalletPersistentData.saveString(key: tokenOTKey, value: value, encrypted: false)
try! INPersistentData.saveString(key: tokenOTKey, value: value, encrypted: false)
}
}
private(set) var siren: String {
get {
return try! WalletPersistentData.getString(forKey: sirenKey, encrypted: false, defaultValue: "")
return try! INPersistentData.getString(forKey: sirenKey, encrypted: false, defaultValue: "")
}
set(value) {
try! WalletPersistentData.saveString(key: sirenKey, value: value, encrypted: false)
try! INPersistentData.saveString(key: sirenKey, value: value, encrypted: false)
}
}
......@@ -93,10 +93,10 @@ class PremiumManager {
private(set) var isPremium: Bool {
get {
return try! WalletPersistentData.getBool(forKey: shouldShowFullResultKey, encrypted: false, defaultValue: false)
return try! INPersistentData.getBool(forKey: shouldShowFullResultKey, encrypted: false, defaultValue: false)
}
set(value) {
try! WalletPersistentData.saveBool(key: shouldShowFullResultKey, value: value, encrypted: false)
try! INPersistentData.saveBool(key: shouldShowFullResultKey, value: value, encrypted: false)
}
}
......@@ -155,16 +155,7 @@ class PremiumManager {
return selection
}
func activatePremium(expirationDate: Date, tokenOT: String, siren: String) {
isPremium = true
modeSelected = .OT
expirationDateForOT = expirationDate.timeIntervalSince1970
self.tokenOT = tokenOT
self.siren = siren
modeConfigurations.append(contentsOf: [.OT, .tacVerifPlus])
scheduleResetPremiumIfNeeded()
}
func resetPremium() {
isPremium = false
......
......@@ -5,8 +5,8 @@
import Foundation
import WalletCommunication
import WalletCore
import INCommunication
import INCore
import os.log
import Combine
......@@ -100,7 +100,7 @@ class BlacklistSynchronization {
return Fail(error: SyncError.cannotFetchBlacklistAtCurrentTime).eraseToAnyPublisher()
}
return WalletRequestService.shared.executeRequest(service.routerService, type: BlacklistResponse.self,
return INRequestService.shared.executeRequest(service.routerService, type: BlacklistResponse.self,
timeout: 10, pinCertificates: service.routerService.getPinningCerts())
.tryMap { [weak self] response -> FetchStartIndex in
return service.isDCC ?
......
......@@ -4,8 +4,8 @@
//
import Foundation
import WalletCommunication
import WalletCore
import INCommunication
import INCore
import os.log
import Combine
import CertLogic
......@@ -37,7 +37,7 @@ private extension CertLogicRulesSynchronization {
let service = ServiceRouter.ruleIds
return WalletRequestService.shared.executeRequest(service, type: [RuleBaseResponse].self, pinCertificates: service.getPinningCerts())
return INRequestService.shared.executeRequest(service, type: [RuleBaseResponse].self, pinCertificates: service.getPinningCerts())
.tryMap { [unowned self] response in
try self.certLogicMotorManager.handleRuleBasesResponse(response)
.rulesToAdd
......@@ -68,7 +68,7 @@ private extension CertLogicRulesSynchronization {
let service = ServiceRouter.rulesDetails(ruleHashes: ruleIds.map { $0.hash })
return WalletRequestService.shared.executeRequest(service, type: [CertLogic.Rule].self,
return INRequestService.shared.executeRequest(service, type: [CertLogic.Rule].self,
pinCertificates: service.getPinningCerts())
.tryMap { [unowned self, ruleIds] response in
try self.certLogicMotorManager.handleRulesResponse(response, withIds: ruleIds)
......
......@@ -4,8 +4,8 @@
//
import Foundation
import WalletCommunication
import WalletCore
import INCommunication
import INCore
import os.log
import Combine
import CertLogic
......@@ -29,7 +29,7 @@ private extension CertLogicValueSetsSynchronization {
func fetchValueSetBases() -> AnyPublisher<[ValueSetBaseResponse], Error> {
let service = ServiceRouter.valueSetIds
return WalletRequestService.shared.executeRequest(service,
return INRequestService.shared.executeRequest(service,
type: [ValueSetBaseResponse].self,
timeout: 10,
pinCertificates: service.getPinningCerts())
......@@ -46,7 +46,7 @@ private extension CertLogicValueSetsSynchronization {
let service = ServiceRouter.valueSetDetails(valueSetIds: valueSetsIds.map { $0.hash } )
return WalletRequestService.shared.executeRequest(service, type: [CertLogic.ValueSet].self,
return INRequestService.shared.executeRequest(service, type: [CertLogic.ValueSet].self,
timeout: 10,
pinCertificates: service.getPinningCerts())
.tryMap { [unowned self, valueSetsIds] response in
......
......@@ -4,8 +4,8 @@
//
import Foundation
import WalletCommunication
import WalletCore
import INCommunication
import INCore
import os.log
import Combine
......@@ -16,7 +16,7 @@ class CheckAppVersionSynchronization {
func synchronize() -> AnyPublisher<Void, Error> {
let service = ServiceRouter.checkMinVersion
return WalletRequestService.shared
return INRequestService.shared
.executeRequest(service, type: AppConf.self)
.flatMap(handleCheckAppVersionResponse(response:))
.eraseToAnyPublisher()
......
......@@ -4,8 +4,8 @@
//
import Foundation
import WalletCommunication
import WalletCore
import INCommunication
import INCore
import os.log
import Combine
......@@ -43,7 +43,7 @@ class ConfigurationSynchronization {
func fetchConfiguration() -> AnyPublisher<Void, Error> {
let service = ServiceRouter.updateCertificates
return WalletRequestService.shared.executeRequest(service,
return INRequestService.shared.executeRequest(service,
type: CertificatesUpdateResponse.self,
typeDateDecoderStrategy: .formatted(Date.dateFormatter),
timeout: 10,
......@@ -56,12 +56,15 @@ class ConfigurationSynchronization {
private func handleConfigurationResponse(_ response: CertificatesUpdateResponse) throws {
certificatesManager.saveCertificates(certs: response)
uiDataManager.save(specificValues: response.specificValues)
confDataManager.save(specificValues: response.specificValues)
confDataManager.save(remindData: response)
try rulesService.save(specificValues: response.specificValues)
try blackListRepository.save(configuration: response.specificValues.blacklist)
VaccinePassVerifierService.shared.configuration = VaccinePassVerifierService.shared.rulesMotorService.vaccinePassVerifierConfiguration() ?? ConstRules.vaccinePassValidity
HealthPassVerifierService.shared.configuration = HealthPassVerifierService.shared.rulesMotorService.healthPassVerifierConfiguration() ?? ConstRules.healthPassValidity
DetailedResultVerifierService.shared.configuration = DetailedResultVerifierService.shared.rulesMotorService.plusValidityConfiguration() ?? ConstRules.plusValidity
}
}
......@@ -4,13 +4,13 @@
//
import Foundation
import WalletCore
import INCore
import OSLog
import Combine
class SyncManager {
public static let shared = SyncManager()
lazy private var configSync = ConfigurationSynchronization()
lazy private var blacklistSync = BlacklistSynchronization()
lazy private var rulesSync = CertLogicRulesSynchronization()
......@@ -24,21 +24,21 @@ class SyncManager {
get {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
return dateFormatter.date(from: "2022-02-14 10:00:00") ?? Date(timeIntervalSince1970: 0)
return dateFormatter.date(from: "2022-02-28 10:00:00") ?? Date(timeIntervalSince1970: 0)
}
}
/**
Date at which the last sync was done
Date at which the last sync was done
*/
var lastSyncDate : Date? {
get{
let timeInSecondes = try? WalletPersistentData.getLong(forKey: CertificatesManager.certificatesLastUpdateKey,defaultValue: 0)
let timeInSecondes = try? INPersistentData.getLong(forKey: CertificatesManager.certificatesLastUpdateKey,defaultValue: 0)
guard let timeInsecs = timeInSecondes, timeInsecs > 0 else { return nil }
return Date(timeIntervalSince1970: TimeInterval(timeInsecs))
}
set(value){
try? WalletPersistentData.saveLong(key: CertificatesManager.certificatesLastUpdateKey, value: Int64(value?.timeIntervalSince1970 ?? 0))
try? INPersistentData.saveLong(key: CertificatesManager.certificatesLastUpdateKey, value: Int64(value?.timeIntervalSince1970 ?? 0))
}
}
......@@ -80,30 +80,30 @@ class SyncManager {
guard let lastSyncDate = lastSyncDate else {
return true
}
return !UserDataManager.sharedInstance.hasMigrateToCriticalVersion || localSyncDate > lastSyncDate
}
/**
Start to synchronize all functionnalities if needed.
- Parameter force: True to synchronize only if needed, else forces synchronization
*/
func start(force: Bool = false) -> AnyPublisher<Void, Error> {
FileLogger.shared.write(text: "\n" + Date().dateTimeString + " start sync automatically \(!force)")
guard (shouldSyncApp() || force) else {
FileLogger.shared.write(text: Date().dateTimeString + "sync not needed")
return Fail(error: SyncError.noNeedToSync).eraseToAnyPublisher()
}
let isPremium = PremiumManager.shared.isPremium
let text = isPremium ? "true" : "false"
FileLogger.shared.write(text: Date().dateTimeString + " is premium " + text )
let toSync: [SyncingFunctionnality] = isPremium ?
[.baseConfiguration(chainWith: .blacklist(chainWith: .checkAppVersion(chainWith: .OTModeConfiguration(chainWith: nil)), force: force)), .stats()] :
[.baseConfiguration(chainWith: .blacklist(chainWith: .checkAppVersion(chainWith: nil))), .stats()]
[.baseConfiguration(chainWith: .blacklist(chainWith: .checkAppVersion(chainWith: .OTModeConfiguration(chainWith: nil)), force: force))] :
[.baseConfiguration(chainWith: .blacklist(chainWith: .checkAppVersion(chainWith: nil)))]
return start(toSync: toSync)
}
......@@ -113,8 +113,8 @@ class SyncManager {
*/
func startLocal() -> AnyPublisher<Void, Error> {
os_log("%@",type: .info, "Sync Local start \(Date().dateTimeString)")
_ = try? RulesMotorRepository.shared.deletePreviousRules()
RulesMotorRepository.shared.deletePreviousRules()
try? CertLogicMotorRepository.shared.deleteRules()
try? CertLogicMotorRepository.shared.deleteValueSets()
......@@ -125,6 +125,10 @@ class SyncManager {
UIDataManager.shared.save(specificValues: response.specificValues)
ConfDataManager.shared.save(specificValues: response.specificValues)
ConfDataManager.shared.save(remindData: response)
VaccinePassVerifierService.shared.configuration = VaccinePassVerifierService.shared.rulesMotorService.vaccinePassVerifierConfiguration() ?? ConstRules.vaccinePassValidity
HealthPassVerifierService.shared.configuration = HealthPassVerifierService.shared.rulesMotorService.healthPassVerifierConfiguration() ?? ConstRules.healthPassValidity
DetailedResultVerifierService.shared.configuration = DetailedResultVerifierService.shared.rulesMotorService.plusValidityConfiguration() ?? ConstRules.plusValidity
}
if let responseRuleBases = CertLogicMotorManager.shared.loadLocalRulesId() {
......@@ -143,7 +147,6 @@ class SyncManager {
}
}
try? CountriesManager.shared.loadLocalCountriesFromResourcesAndRules()
if let response = CertLogicMotorManager.shared.loadLocalBL2DDoc() {
......@@ -154,12 +157,12 @@ class SyncManager {
}
FileLogger.shared.write(text: "Sync Local End")
lastSyncDate = localSyncDate
UserDataManager.sharedInstance.hasMigrateToCriticalVersion = true
os_log("%@",type: .info, "Sync local end \(Date().dateTimeString)")
return Just(())
.setFailureType(to: Error.self)
.eraseToAnyPublisher()
......@@ -180,24 +183,17 @@ private extension SyncManager {
}
isSyncingInProgress = true
// Creates publisher for each functionnality to sync
// Then zip them together
var publisher: AnyPublisher<Void, Error>!
toSync.forEach {
// create new publisher from
let newPublisher = $0.chain.reduce(start(toSync: $0), { partialResult, toSync in
partialResult.flatMap { [self] in self.start(toSync: toSync) }.eraseToAnyPublisher()
})
if publisher == nil {
publisher = newPublisher