Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package lime for openSUSE:Factory checked in 
at 2023-06-29 17:28:25
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/lime (Old)
 and      /work/SRC/openSUSE:Factory/.lime.new.13546 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "lime"

Thu Jun 29 17:28:25 2023 rev:22 rq:1095747 version:5.2.73

Changes:
--------
--- /work/SRC/openSUSE:Factory/lime/lime.changes        2023-04-07 
18:17:26.980933718 +0200
+++ /work/SRC/openSUSE:Factory/.lime.new.13546/lime.changes     2023-06-29 
17:28:42.406392321 +0200
@@ -1,0 +2,5 @@
+Wed Jun 28 06:37:19 UTC 2023 - Paolo Stivanin <i...@paolostivanin.com>
+
+- Update to 5.2.73 (no changelog)
+
+-------------------------------------------------------------------

Old:
----
  lime-5.2.49.tar.bz2

New:
----
  lime-5.2.73.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ lime.spec ++++++
--- /var/tmp/diff_new_pack.Ipl6ou/_old  2023-06-29 17:28:43.770400311 +0200
+++ /var/tmp/diff_new_pack.Ipl6ou/_new  2023-06-29 17:28:43.774400334 +0200
@@ -19,7 +19,7 @@
 %define soname  liblime
 %define sover   0
 Name:           lime
-Version:        5.2.49
+Version:        5.2.73
 Release:        0
 Summary:        Instant Message End-to-End Encryption Library
 License:        GPL-3.0-or-later

++++++ add-cstdint.patch ++++++
--- /var/tmp/diff_new_pack.Ipl6ou/_old  2023-06-29 17:28:43.806400521 +0200
+++ /var/tmp/diff_new_pack.Ipl6ou/_new  2023-06-29 17:28:43.810400545 +0200
@@ -1,6 +1,7 @@
-diff -ru orig/src/lime_double_ratchet.cpp mod/src/lime_double_ratchet.cpp
---- orig/src/lime_double_ratchet.cpp   2022-11-09 23:33:57.000000000 +0100
-+++ mod/src/lime_double_ratchet.cpp    2023-03-28 08:12:25.447825643 +0200
+Index: lime-5.2.73/src/lime_double_ratchet.cpp
+===================================================================
+--- lime-5.2.73.orig/src/lime_double_ratchet.cpp
++++ lime-5.2.73/src/lime_double_ratchet.cpp
 @@ -25,6 +25,7 @@
  #include "bctoolbox/exception.hh"
  
@@ -9,13 +10,14 @@
  
  
  using namespace::std;
-diff -ru orig/src/lime_settings.hpp mod/src/lime_settings.hpp
---- orig/src/lime_settings.hpp 2022-11-09 23:33:57.000000000 +0100
-+++ mod/src/lime_settings.hpp  2023-03-28 08:11:58.683669300 +0200
-@@ -20,6 +20,8 @@
- #ifndef lime_settings_hpp
+Index: lime-5.2.73/src/lime_settings.hpp
+===================================================================
+--- lime-5.2.73.orig/src/lime_settings.hpp
++++ lime-5.2.73/src/lime_settings.hpp
+@@ -21,6 +21,8 @@
  #define lime_settings_hpp
  
+ 
 +#include <cstdint>
 +
  namespace lime {

++++++ lime-5.2.49.tar.bz2 -> lime-5.2.73.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/CHANGELOG.md new/lime-5.2.73/CHANGELOG.md
--- old/lime-5.2.49/CHANGELOG.md        2022-11-09 23:33:57.000000000 +0100
+++ new/lime-5.2.73/CHANGELOG.md        2023-05-10 07:45:32.000000000 +0200
@@ -3,8 +3,18 @@
 
 The format is based on [Keep a 
Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic 
Versioning](https://semver.org/spec/v2.0.0.html).
+## [5.3.0] - XXXX-XX-XX
+### Changed
+- Lime manager keeps an open connexion to the db
+- Update timer is managed internally: keep track of last successful update for 
each local user
+- Db schema updated from version 0.0.1 to 0.1.0
+
+
+## [5.2.0] - 2022-11-08
+### Added
+- API to compute peer status for a list of peer device
 
-## [4.5.0] - XXXX-XX-XX
+## [4.5.0] - 2021-03-29
 ### Added
 - Ability to force an active session to stale
 ### Changed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/CMakeLists.txt 
new/lime-5.2.73/CMakeLists.txt
--- old/lime-5.2.49/CMakeLists.txt      2022-11-09 23:33:57.000000000 +0100
+++ new/lime-5.2.73/CMakeLists.txt      2023-05-10 07:45:32.000000000 +0200
@@ -108,11 +108,7 @@
 set(STRICT_OPTIONS_CXX )
 set(STRICT_OPTIONS_OBJC )
 
-if(ENABLE_JNI)
-       set(CMAKE_CXX_STANDARD 14)
-else()
-       set(CMAKE_CXX_STANDARD 11)
-endif()
+set(CMAKE_CXX_STANDARD 14)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
 set(CMAKE_C_STANDARD 99)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/include/lime/lime.hpp 
new/lime-5.2.73/include/lime/lime.hpp
--- old/lime-5.2.49/include/lime/lime.hpp       2022-11-09 23:33:57.000000000 
+0100
+++ new/lime-5.2.73/include/lime/lime.hpp       2023-05-10 07:45:32.000000000 
+0200
@@ -115,8 +115,9 @@
         */
        using limeX3DHServerPostData = std::function<void(const std::string 
&url, const std::string &from, const std::vector<uint8_t> &message, const 
limeX3DHServerResponseProcess &reponseProcess)>;
 
-       /* Forward declare the class managing one lime user*/
+       /* Forward declare the class managing one lime user and class managing 
database */
        class LimeGeneric;
+       class Db;
 
        /** @brief Manage several Lime objects(one is needed for each local 
user).
         *
@@ -128,8 +129,7 @@
                private :
                        std::unordered_map<std::string, 
std::shared_ptr<LimeGeneric>> m_users_cache; // cache of already opened Lime 
Session, identified by user Id (GRUU)
                        std::mutex m_users_mutex; // m_users_cache mutex
-                       std::string m_db_access; // DB access information 
forwarded to SOCI to correctly access database
-                       std::shared_ptr<std::recursive_mutex> m_db_mutex; // 
database access mutex
+                       std::shared_ptr<lime::Db> m_localStorage; // DB access 
information forwarded to SOCI to correctly access database
                        limeX3DHServerPostData m_X3DH_post_data; // send data 
to the X3DH key server
                        void load_user(std::shared_ptr<LimeGeneric> &user, 
const std::string &localDeviceId, const bool allStatus=false); // helper 
function, get from m_users_cache of local Storage the requested Lime object
 
@@ -243,14 +243,15 @@
                        lime::PeerDeviceStatus decrypt(const std::string 
&localDeviceId, const std::string &recipientUserId, const std::string 
&senderDeviceId, const std::vector<uint8_t> &DRmessage, std::vector<uint8_t> 
&plainMessage);
 
                        /**
-                        * @brief Update: shall be called once a day at least, 
performs checks, updates and cleaning operations
+                        * @brief Update: shall be called regularly, once a day 
at least, performs checks, updates and cleaning operations
+                        * The update is performed each OPk_updatePeriod 
(defined in lime::settings to be one day). If the function is called before
+                        * this interval is over, it just does nothing.
                         *
-                        *  - check if we shall update a new SPk to X3DH 
server(SPk lifetime is set in settings)
+                        *  - check if we shall update a new SPk to X3DH 
server(SPk lifetime is set in lime::settings)
                         *  - check if we need to upload OPks to X3DH server
                         *  - remove old SPks, clean double ratchet sessions 
(remove staled, clean their stored keys for skipped messages)
                         *
-                        *  Is performed for all users founds in local storage
-                        *
+                        * @param[in]   localDeviceId           Identify the 
local user acount to use, it must be unique and is also used as Id on the X3DH 
key server, it shall be the GRUU
                         * @param[in]   callback                This operation 
may contact the X3DH server and is thus asynchronous, when server responds,
                         *                                      this callback 
will be called giving the exit status and an error message in case of failure.
                         * @param[in]   OPkServerLowLimit       If server holds 
less OPk than this limit, generate and upload a batch of OPks
@@ -260,11 +261,11 @@
                         * The last two parameters are optional, if not used, 
set to defaults defined in lime::settings
                         * (not done with param default value as the 
lime::settings shall not be available in public include)
                         */
-                       void update(const limeCallback &callback, uint16_t 
OPkServerLowLimit, uint16_t OPkBatchSize);
+                       void update(const std::string &localDeviceId, const 
limeCallback &callback, uint16_t OPkServerLowLimit, uint16_t OPkBatchSize);
                        /**
                         * @overload void update(const limeCallback &callback)
                         */
-                       void update(const limeCallback &callback);
+                       void update(const std::string &localDeviceId, const 
limeCallback &callback);
 
                        /**
                         * @brief retrieve self Identity Key, an EdDSA 
formatted public key
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/include/lime/lime_ffi.h 
new/lime-5.2.73/include/lime/lime_ffi.h
--- old/lime-5.2.49/include/lime/lime_ffi.h     2022-11-09 23:33:57.000000000 
+0100
+++ new/lime-5.2.73/include/lime/lime_ffi.h     2023-05-10 07:45:32.000000000 
+0200
@@ -402,6 +402,7 @@
  *  Is performed for all users founds in local storage
  *
  * @param[in]  manager         pointer to the opaque structure used to 
interact with lime
+ * @param[in]  localDeviceId   Identify the local user account, it must be 
unique and is also be used as Id on the X3DH key server, it shall be the GRUU
  * @param[in]  callback                Performing encryption may involve the 
X3DH server and is thus asynchronous, when the operation is completed,
  *                                     this callback will be called giving the 
exit status and an error message in case of failure.
  * @param[in]  callbackUserData        this pointer will be forwarded to the 
callback as first parameter
@@ -410,7 +411,7 @@
  *
  * @return LIME_FFI_SUCCESS or a negative error code
  */
-int lime_ffi_update(lime_manager_t manager, const lime_ffi_Callback callback, 
void *callbackUserData, uint16_t OPkServerLowLimit, uint16_t OPkBatchSize);
+int lime_ffi_update(lime_manager_t manager, const char *localDeviceId, const 
lime_ffi_Callback callback, void *callbackUserData, uint16_t OPkServerLowLimit, 
uint16_t OPkBatchSize);
 
 /**
  * @brief Set the X3DH key server URL for this identified user
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/src/lime.cpp new/lime-5.2.73/src/lime.cpp
--- old/lime-5.2.49/src/lime.cpp        2022-11-09 23:33:57.000000000 +0100
+++ new/lime-5.2.73/src/lime.cpp        2023-05-10 07:45:32.000000000 +0200
@@ -46,13 +46,12 @@
         * @param[in]           X3DH_post_data                  A function used 
to communicate with the X3DH server
         * @param[in]           Uid                             the DB internal 
Id for this user, speed up DB operations by holding it in DB
         *
-        * @note: ownership of localStorage pointer is transfered to a shared 
pointer, private menber of Lime class
         */
        template <typename Curve>
-       Lime<Curve>::Lime(std::unique_ptr<lime::Db> &&localStorage, const 
std::string &deviceId, const std::string &url, const limeX3DHServerPostData 
&X3DH_post_data, const long int Uid)
+       Lime<Curve>::Lime(std::shared_ptr<lime::Db> localStorage, const 
std::string &deviceId, const std::string &url, const limeX3DHServerPostData 
&X3DH_post_data, const long int Uid)
        : m_RNG{make_RNG()}, m_selfDeviceId{deviceId},
        m_Ik{}, m_Ik_loaded(false),
-       m_localStorage(std::move(localStorage)), m_db_Uid{Uid},
+       m_localStorage(localStorage), m_db_Uid{Uid},
        m_X3DH_post_data{X3DH_post_data}, m_X3DH_Server_URL{url},
        m_DR_sessions_cache{}, m_ongoing_encryption{nullptr}, 
m_encryption_queue{}
        { }
@@ -68,13 +67,12 @@
         * @param[in]           url                             URL of the X3DH 
key server used to publish our keys
         * @param[in]           X3DH_post_data                  A function used 
to communicate with the X3DH server
         *
-        * @note: ownership of localStorage pointer is transfered to a shared 
pointer, private menber of Lime class
         */
        template <typename Curve>
-       Lime<Curve>::Lime(std::unique_ptr<lime::Db> &&localStorage, const 
std::string &deviceId, const std::string &url, const limeX3DHServerPostData 
&X3DH_post_data)
+       Lime<Curve>::Lime(std::shared_ptr<lime::Db> localStorage, const 
std::string &deviceId, const std::string &url, const limeX3DHServerPostData 
&X3DH_post_data)
        : m_RNG{make_RNG()}, m_selfDeviceId{deviceId},
        m_Ik{}, m_Ik_loaded(false),
-       m_localStorage(std::move(localStorage)), m_db_Uid{0},
+       m_localStorage(localStorage), m_db_Uid{0},
        m_X3DH_post_data{X3DH_post_data}, m_X3DH_Server_URL{url},
        m_DR_sessions_cache{}, m_ongoing_encryption{nullptr}, 
m_encryption_queue{}
        {
@@ -378,19 +376,18 @@
         *
         *      Once created a user cannot be modified, insertion of existing 
deviceId will raise an exception.
         *
-        * @param[in]   dbFilename                      Path to filename to use
+        * @param[in]   localStorage                    Database access
         * @param[in]   deviceId                        User to create in DB, 
deviceId shall be the GRUU
         * @param[in]   url                             URL of X3DH key server 
to be used to publish our keys
         * @param[in]   curve                           Which curve shall we 
use for this account, select the implemenation to instanciate when using this 
user
         * @param[in]   OPkInitialBatchSize             Number of OPks in the 
first batch uploaded to X3DH server
         * @param[in]   X3DH_post_data                  A function used to 
communicate with the X3DH server
         * @param[in]   callback                        To provide caller the 
operation result
-        * @param[in]   db_mutex                        a mutex to protect db 
access
         *
         * @return a pointer to the LimeGeneric class allowing access to API 
declared in lime_lime.hpp
         */
-       std::shared_ptr<LimeGeneric> insert_LimeUser(const std::string 
&dbFilename, const std::string &deviceId, const std::string &url, const 
lime::CurveId curve, const uint16_t OPkInitialBatchSize,
-                       const limeX3DHServerPostData &X3DH_post_data, const 
limeCallback &callback, std::shared_ptr<std::recursive_mutex> db_mutex) {
+       std::shared_ptr<LimeGeneric> insert_LimeUser(std::shared_ptr<lime::Db> 
localStorage, const std::string &deviceId, const std::string &url, const 
lime::CurveId curve, const uint16_t OPkInitialBatchSize,
+                       const limeX3DHServerPostData &X3DH_post_data, const 
limeCallback &callback) {
                LIME_LOGI<<"Create Lime user "<<deviceId;
                /* first check the requested curve is instanciable and return 
an exception if not */
 #ifndef EC25519_ENABLED
@@ -404,16 +401,13 @@
                }
 #endif
 
-               /* open DB */
-               auto localStorage = std::unique_ptr<lime::Db>(new 
lime::Db(dbFilename, db_mutex)); // create as unique ptr, ownership is then 
passed to the Lime structure when instanciated
-
                //instanciate the correct Lime object
                switch (curve) {
                        case lime::CurveId::c25519 :
 #ifdef EC25519_ENABLED
                        {
                                /* constructor will insert user in Db, if 
already present, raise an exception*/
-                               auto lime_ptr = 
std::make_shared<Lime<C255>>(std::move(localStorage), deviceId, url, 
X3DH_post_data);
+                               auto lime_ptr = 
std::make_shared<Lime<C255>>(localStorage, deviceId, url, X3DH_post_data);
                                lime_ptr->publish_user(callback, 
OPkInitialBatchSize);
                                return lime_ptr;
                        }
@@ -423,7 +417,7 @@
                        case lime::CurveId::c448 :
 #ifdef EC448_ENABLED
                        {
-                               auto lime_ptr = 
std::make_shared<Lime<C448>>(std::move(localStorage), deviceId, url, 
X3DH_post_data);
+                               auto lime_ptr = 
std::make_shared<Lime<C448>>(localStorage, deviceId, url, X3DH_post_data);
                                lime_ptr->publish_user(callback, 
OPkInitialBatchSize);
                                return lime_ptr;
                        }
@@ -444,18 +438,16 @@
         *      Fail to find the user will raise an exception
         *      If allStatus flag is set to false (default value), raise an 
exception on inactive users otherwise load inactive user.
         *
-        * @param[in]   dbFilename              Path to filename to use
+        * @param[in]   localStorage            Database access
         * @param[in]   deviceId                User to lookup in DB, deviceId 
shall be the GRUU
         * @param[in]   X3DH_post_data          A function used to communicate 
with the X3DH server
-        * @param[in]   db_mutex                a mutex to protect db access
         * @param[in]   allStatus               allow loading of inactive user 
if set to true
         *
         * @return a pointer to the LimeGeneric class allowing access to API 
declared in lime_lime.hpp
         */
-       std::shared_ptr<LimeGeneric> load_LimeUser(const std::string 
&dbFilename, const std::string &deviceId, const limeX3DHServerPostData 
&X3DH_post_data, std::shared_ptr<std::recursive_mutex> db_mutex, const bool 
allStatus) {
+       std::shared_ptr<LimeGeneric> load_LimeUser(std::shared_ptr<lime::Db> 
localStorage, const std::string &deviceId, const limeX3DHServerPostData 
&X3DH_post_data, const bool allStatus) {
 
-               /* open DB and load user */
-               auto localStorage = std::unique_ptr<lime::Db>(new 
lime::Db(dbFilename, db_mutex)); // create as unique ptr, ownership is then 
passed to the Lime structure when instanciated
+               /* load user */
                auto curve = CurveId::unset;
                long int Uid=0;
                std::string x3dh_server_url;
@@ -479,13 +471,13 @@
                switch (curve) {
                        case lime::CurveId::c25519 :
 #ifdef EC25519_ENABLED
-                               return 
std::make_shared<Lime<C255>>(std::move(localStorage), deviceId, 
x3dh_server_url, X3DH_post_data, Uid);
+                               return 
std::make_shared<Lime<C255>>(localStorage, deviceId, x3dh_server_url, 
X3DH_post_data, Uid);
 #endif
                        break;
 
                        case lime::CurveId::c448 :
 #ifdef EC448_ENABLED
-                               return 
std::make_shared<Lime<C448>>(std::move(localStorage), deviceId, 
x3dh_server_url, X3DH_post_data, Uid);
+                               return 
std::make_shared<Lime<C448>>(localStorage, deviceId, x3dh_server_url, 
X3DH_post_data, Uid);
 #endif
                        break;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/src/lime_defines.hpp 
new/lime-5.2.73/src/lime_defines.hpp
--- old/lime-5.2.49/src/lime_defines.hpp        2022-11-09 23:33:57.000000000 
+0100
+++ new/lime-5.2.73/src/lime_defines.hpp        2023-05-10 07:45:32.000000000 
+0200
@@ -20,6 +20,8 @@
 #ifndef lime_defines_hpp
 #define lime_defines_hpp
 
+#include <string>
+
 namespace lime {
 /** @brief Hold constants definition used as settings in all components of the 
lime library
  *
@@ -71,9 +73,9 @@
 
/******************************************************************************/
        /** define a version number for the DB schema as an integer 0xMMmmpp
         *
-        * current version is 0.0.1
+        * current version is 0.1.0
         */
-       constexpr int DBuserVersion=0x000001;
+       constexpr int DBuserVersion=0x000100;
        constexpr uint16_t DBInactiveUserBit = 0x0100;
        constexpr uint16_t DBCurveIdByte = 0x00FF;
        constexpr uint8_t DBInvalidIk = 0x00;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/src/lime_double_ratchet.cpp 
new/lime-5.2.73/src/lime_double_ratchet.cpp
--- old/lime-5.2.49/src/lime_double_ratchet.cpp 2022-11-09 23:33:57.000000000 
+0100
+++ new/lime-5.2.73/src/lime_double_ratchet.cpp 2023-05-10 07:45:32.000000000 
+0200
@@ -57,9 +57,9 @@
        }
 
        /** constant used as input of HKDF like function, see double ratchet 
spec section 5.2 - KDF_CK */
-       const std::array<std::uint8_t,1> hkdf_ck_info{{0x02}};
+       const std::array<uint8_t,1> hkdf_ck_info{{0x02}};
        /** constant used as input of HKDF like function, see double ratchet 
spec section 5.2 - KDF_CK */
-       const std::array<std::uint8_t,1> hkdf_mk_info{{0x01}};
+       const std::array<uint8_t,1> hkdf_mk_info{{0x01}};
 
        /**
         * @brief Key Derivation Function used in Symmetric key ratchet chain.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/src/lime_double_ratchet.hpp 
new/lime-5.2.73/src/lime_double_ratchet.hpp
--- old/lime-5.2.49/src/lime_double_ratchet.hpp 2022-11-09 23:33:57.000000000 
+0100
+++ new/lime-5.2.73/src/lime_double_ratchet.hpp 2023-05-10 07:45:32.000000000 
+0200
@@ -62,7 +62,7 @@
        template <typename Curve>
        struct ReceiverKeyChain {
                X<Curve, lime::Xtype::publicKey> DHr; /**< peer public key 
identifying this chain */
-               std::unordered_map<std::uint16_t, DRMKey> messageKeys; /**< 
message keys indexed by Nr */
+               std::unordered_map<uint16_t, DRMKey> messageKeys; /**< message 
keys indexed by Nr */
                /**
                 * Start a new empty chain
                 * @param[in]   key     the peer DH public key used on this 
chain
@@ -88,8 +88,8 @@
                        DRChainKey m_RK; // 32 bytes root key
                        DRChainKey m_CKs; // 32 bytes key chain for sending
                        DRChainKey m_CKr; // 32 bytes key chain for receiving
-                       std::uint16_t m_Ns,m_Nr; // Message index in sending 
and receiving chain
-                       std::uint16_t m_PN; // Number of messages in previous 
sending chain
+                       uint16_t m_Ns,m_Nr; // Message index in sending and 
receiving chain
+                       uint16_t m_PN; // Number of messages in previous 
sending chain
                        SharedADBuffer m_sharedAD; // Associated Data derived 
from self and peer device Identity key, set once at session creation, given by 
X3DH
                        std::vector<lime::ReceiverKeyChain<Curve>> m_mkskipped; 
// list of skipped message indexed by DH receiver public key and Nr, store MK 
generated during on-going decrypt, lookup is done directly in DB.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/src/lime_double_ratchet_protocol.hpp 
new/lime-5.2.73/src/lime_double_ratchet_protocol.hpp
--- old/lime-5.2.49/src/lime_double_ratchet_protocol.hpp        2022-11-09 
23:33:57.000000000 +0100
+++ new/lime-5.2.73/src/lime_double_ratchet_protocol.hpp        2023-05-10 
07:45:32.000000000 +0200
@@ -111,7 +111,7 @@
 #endif
                /* These constants are needed only for tests purpose, otherwise 
their usage is internal only to double_ratchet_protocol.hpp */
                /** Double ratchet protocol version number */
-               constexpr std::uint8_t DR_v01=0x01;
+               constexpr uint8_t DR_v01=0x01;
 
                /** @brief DR message type byte bit mapping
                 * @code{.unparsed}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/src/lime_ffi.cpp 
new/lime-5.2.73/src/lime_ffi.cpp
--- old/lime-5.2.49/src/lime_ffi.cpp    2022-11-09 23:33:57.000000000 +0100
+++ new/lime-5.2.73/src/lime_ffi.cpp    2023-05-10 07:45:32.000000000 +0200
@@ -420,14 +420,14 @@
        return LIME_FFI_SUCCESS;
 }
 
-int lime_ffi_update(lime_manager_t manager,  const lime_ffi_Callback callback, 
void *callbackUserData, uint16_t OPkServerLowLimit, uint16_t OPkBatchSize) {
+int lime_ffi_update(lime_manager_t manager,  const char *localDeviceId, const 
lime_ffi_Callback callback, void *callbackUserData, uint16_t OPkServerLowLimit, 
uint16_t OPkBatchSize) {
        // just intercept the lime callback, convert the arguments to the 
correct types, add the userData and forward it to the C side
        limeCallback cb([callback, callbackUserData](const lime::CallbackReturn 
status, const std::string message){
                                callback(callbackUserData, 
lime2ffi_CallbackReturn(status), message.data());
                        });
 
        try {
-               manager->context->update(cb, OPkServerLowLimit, OPkBatchSize);
+               manager->context->update(std::string(localDeviceId), cb, 
OPkServerLowLimit, OPkBatchSize);
        } catch (BctbxException const &e) {
                LIME_LOGE<<"FFI failed during update: "<<e.str();
                return LIME_FFI_INTERNAL_ERROR;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/src/lime_impl.hpp 
new/lime-5.2.73/src/lime_impl.hpp
--- old/lime-5.2.49/src/lime_impl.hpp   2022-11-09 23:33:57.000000000 +0100
+++ new/lime-5.2.73/src/lime_impl.hpp   2023-05-10 07:45:32.000000000 +0200
@@ -98,8 +98,8 @@
                        void 
cleanUserData(std::shared_ptr<callbackUserData<Curve>> userData); // clean user 
data
 
                public: /* Implement API defined in lime_lime.hpp in 
LimeGeneric abstract class */
-                       Lime(std::unique_ptr<lime::Db> &&localStorage, const 
std::string &deviceId, const std::string &url, const limeX3DHServerPostData 
&X3DH_post_data);
-                       Lime(std::unique_ptr<lime::Db> &&localStorage, const 
std::string &deviceId, const std::string &url, const limeX3DHServerPostData 
&X3DH_post_data, const long int Uid);
+                       Lime(std::shared_ptr<lime::Db> localStorage, const 
std::string &deviceId, const std::string &url, const limeX3DHServerPostData 
&X3DH_post_data);
+                       Lime(std::shared_ptr<lime::Db> localStorage, const 
std::string &deviceId, const std::string &url, const limeX3DHServerPostData 
&X3DH_post_data, const long int Uid);
                        ~Lime();
                        Lime(Lime<Curve> &a) = delete; // can't copy a session, 
force usage of shared pointers
                        Lime<Curve> &operator=(Lime<Curve> &a) = delete; // 
can't copy a session
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/src/lime_jni.cpp 
new/lime-5.2.73/src/lime_jni.cpp
--- old/lime-5.2.49/src/lime_jni.cpp    2022-11-09 23:33:57.000000000 +0100
+++ new/lime-5.2.73/src/lime_jni.cpp    2023-05-10 07:45:32.000000000 +0200
@@ -402,16 +402,17 @@
                return c2jPeerDeviceStatus(status);
        }
 
-       void update(jni::JNIEnv &env, jni::Object<jStatusCallback> &jstatusObj, 
jni::jint jOPkServerLowLimit, jni::jint jOPkBatchSize) {
+       void update(jni::JNIEnv &env, const jni::String &jlocalDeviceId, 
jni::Object<jStatusCallback> &jstatusObj, jni::jint jOPkServerLowLimit, 
jni::jint jOPkBatchSize) {
                JavaVM *c_vm;
                env.GetJavaVM(&c_vm);
 
-               LIME_LOGD<<"JNI update";
+               LIME_LOGD<<"JNI update for "<<(jni::Make<std::string>(env, 
jlocalDeviceId));
 
                // see create_user for details on this
                auto jstatusObjRef = 
std::make_shared<jni::Global<jni::Object<jStatusCallback>, 
jni::EnvGettingDeleter>>(jni::NewGlobal<jni::EnvGettingDeleter>(env, 
jstatusObj));
 
-               m_manager->update([c_vm, jstatusObjRef] (const 
lime::CallbackReturn status, const std::string message)
+               m_manager->update(jni::Make<std::string>(env, jlocalDeviceId),
+                               [c_vm, jstatusObjRef] (const 
lime::CallbackReturn status, const std::string message)
                                {
                                        // get the env from VM
                                        jni::JNIEnv& g_env { 
jni::GetEnv(*c_vm)};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/src/lime_lime.hpp 
new/lime-5.2.73/src/lime_lime.hpp
--- old/lime-5.2.49/src/lime_lime.hpp   2022-11-09 23:33:57.000000000 +0100
+++ new/lime-5.2.73/src/lime_lime.hpp   2023-05-10 07:45:32.000000000 +0200
@@ -172,10 +172,10 @@
 
        /* Lime Factory functions : return a pointer to the implementation 
using the specified elliptic curve. Two functions: one for creation, one for 
loading from local storage */
 
-       std::shared_ptr<LimeGeneric> insert_LimeUser(const std::string 
&dbFilename, const std::string &deviceId, const std::string &url, const 
lime::CurveId curve, const uint16_t OPkInitialBatchSize,
-                       const limeX3DHServerPostData &X3DH_post_data, const 
limeCallback &callback, std::shared_ptr<std::recursive_mutex> mutex);
+       std::shared_ptr<LimeGeneric> insert_LimeUser(std::shared_ptr<lime::Db> 
localStorage, const std::string &deviceId, const std::string &url, const 
lime::CurveId curve, const uint16_t OPkInitialBatchSize,
+                       const limeX3DHServerPostData &X3DH_post_data, const 
limeCallback &callback);
 
-       std::shared_ptr<LimeGeneric> load_LimeUser(const std::string 
&dbFilename, const std::string &deviceId, const limeX3DHServerPostData 
&X3DH_post_data, std::shared_ptr<std::recursive_mutex> mutex, const bool 
allStatus=false);
+       std::shared_ptr<LimeGeneric> load_LimeUser(std::shared_ptr<lime::Db> 
localStorage, const std::string &deviceId, const limeX3DHServerPostData 
&X3DH_post_data, const bool allStatus=false);
 
 }
 #endif // lime_lime_hpp
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/src/lime_localStorage.cpp 
new/lime-5.2.73/src/lime_localStorage.cpp
--- old/lime-5.2.49/src/lime_localStorage.cpp   2022-11-09 23:33:57.000000000 
+0100
+++ new/lime-5.2.73/src/lime_localStorage.cpp   2023-05-10 07:45:32.000000000 
+0200
@@ -39,176 +39,190 @@
 /* Db public API                                                              
*/
 /*                                                                            
*/
 
/******************************************************************************/
-Db::Db(const std::string &filename, std::shared_ptr<std::recursive_mutex> 
db_mutex) : sql{"sqlite3", filename}, m_db_mutex{db_mutex} {
+Db::Db(const std::string &filename, std::shared_ptr<std::recursive_mutex> 
db_mutex) : m_db_mutex{db_mutex} {
        std::lock_guard<std::recursive_mutex> lock(*m_db_mutex);
        constexpr int db_module_table_not_holding_lime_row = -1;
 
        int userVersion=db_module_table_not_holding_lime_row;
-       sql<<"PRAGMA foreign_keys = ON;"; // make sure this connection enable 
foreign keys
-       transaction tr(sql);
-       // CREATE OR INGORE TABLE db_module_version(
-       sql<<"CREATE TABLE IF NOT EXISTS db_module_version("
-               "name VARCHAR(16) PRIMARY KEY,"
-               "version UNSIGNED INTEGER NOT NULL"
-               ")";
-       sql<<"SELECT version FROM db_module_version WHERE name='lime'", 
into(userVersion);
-
-       // Enforce value in case there is no lime version number in table 
db_module_version
-       if (!sql.got_data()) {
-               userVersion=db_module_table_not_holding_lime_row;
-       }
+       try {
+               sql.open("sqlite3", filename);
+               sql<<"PRAGMA foreign_keys = ON;"; // make sure this connection 
enable foreign keys
+               transaction tr(sql);
+               // CREATE OR IGNORE TABLE db_module_version(
+               sql<<"CREATE TABLE IF NOT EXISTS db_module_version("
+                       "name VARCHAR(16) PRIMARY KEY,"
+                       "version UNSIGNED INTEGER NOT NULL"
+                       ")";
+               sql<<"SELECT version FROM db_module_version WHERE name='lime'", 
into(userVersion);
+
+               // Enforce value in case there is no lime version number in 
table db_module_version
+               if (!sql.got_data()) {
+                       userVersion=db_module_table_not_holding_lime_row;
+               }
 
-       if (userVersion == lime::settings::DBuserVersion) {
-               return;
-       }
+               if (userVersion == lime::settings::DBuserVersion) {
+                       return;
+               }
 
-       if (userVersion > lime::settings::DBuserVersion) { /* nothing to do if 
we encounter a superior version number than expected, just hope it is 
compatible */
-               LIME_LOGE<<"Lime module database schema version found in DB(v 
"<<userVersion<<") is more recent than the one currently supported by the lime 
module(v "<<static_cast<unsigned int>(lime::settings::DBuserVersion)<<")";
-               return;
-       }
+               if (userVersion > lime::settings::DBuserVersion) { /* nothing 
to do if we encounter a superior version number than expected, just hope it is 
compatible */
+                       LIME_LOGE<<"Lime module database schema version found 
in DB(v "<<userVersion<<") is more recent than the one currently supported by 
the lime module(v "<<static_cast<unsigned 
int>(lime::settings::DBuserVersion)<<")";
+                       return;
+               }
 
-       /* Perform update if needed */
-       // update the schema version in DB
-       if (userVersion == db_module_table_not_holding_lime_row) { // but not 
any lime row in it
-               sql<<"INSERT INTO db_module_version(name,version) 
VALUES('lime',:DbVersion)", use(lime::settings::DBuserVersion);
-       } else { // and we had an older version
-               sql<<"UPDATE db_module_version SET version = :DbVersion WHERE 
name='lime'", use(lime::settings::DBuserVersion);
-               /* Do the update here */
+               /* Perform update if needed */
+               // update the schema version in DB
+               if (userVersion == db_module_table_not_holding_lime_row) { // 
but not any lime row in it
+                       sql<<"INSERT INTO db_module_version(name,version) 
VALUES('lime',:DbVersion)", use(lime::settings::DBuserVersion);
+               } else { // and we had an older version
+                       /* Do the update here */
+                       sql<<"ALTER TABLE lime_LocalUsers ADD COLUMN updateTs 
DATETIME";
+                       sql<<"UPDATE lime_LocalUsers SET updateTs = 
CURRENT_TIMESTAMP";
+                       // update version number
+                       sql<<"UPDATE db_module_version SET version = :DbVersion 
WHERE name='lime'", use(lime::settings::DBuserVersion);
+                       tr.commit(); // commit all the previous queries
+                       LIME_LOGI<<"Perform lime database migration from 
version "<<userVersion<<" to version "<<lime::settings::DBuserVersion;
+                       return;
+               }
+
+               // create the lime DB:
+       
+               /*** Double Ratchet tables ***/
+               /* DR Session:
+               *  - DId : link to lime_PeerDevices table, identify which peer 
is associated to this session
+               *  - Uid: link to LocalUsers table, identify which local device 
is associated to this session
+               *  - SessionId(primary key)
+               *  - Ns, Nr, PN : index for sending, receivind and previous 
sending chain
+               *  - DHr : peer current public ECDH key
+               *  - DHs : self current ECDH key. (public || private keys)
+               *  - RK, CKs, CKr : Root key, sender and receiver chain keys
+               *  - AD : Associated data : provided once at session creation 
by X3DH, is derived from initiator public Ik and id, receiver public Ik and id
+               *  - Status : 0 is for stale and 1 is for active, only one 
session shall be active for a peer device, by default created as active
+               *  - timeStamp : is updated when session change status and is 
used to remove stale session after determined time in cleaning operation
+               *  - X3DHInit : when we are initiator, store the generated X3DH 
init message and keep sending it until we've got at least a reply from peer
+               */
+               sql<<"CREATE TABLE DR_sessions( \
+                                       Did INTEGER NOT NULL DEFAULT 0, \
+                                       Uid INTEGER NOT NULL DEFAULT 0, \
+                                       sessionId INTEGER PRIMARY KEY 
AUTOINCREMENT NOT NULL, \
+                                       Ns UNSIGNED INTEGER NOT NULL, \
+                                       Nr UNSIGNED INTEGER NOT NULL, \
+                                       PN UNSIGNED INTEGER NOT NULL, \
+                                       DHr BLOB NOT NULL, \
+                                       DHs BLOB NOT NULL, \
+                                       RK BLOB NOT NULL, \
+                                       CKs BLOB NOT NULL, \
+                                       CKr BLOB NOT NULL, \
+                                       AD BLOB NOT NULL, \
+                                       Status INTEGER NOT NULL DEFAULT 1, \
+                                       timeStamp DATETIME DEFAULT 
CURRENT_TIMESTAMP, \
+                                       X3DHInit BLOB DEFAULT NULL, \
+                                       FOREIGN KEY(Did) REFERENCES 
lime_PeerDevices(Did) ON UPDATE CASCADE ON DELETE CASCADE, \
+                                       FOREIGN KEY(Uid) REFERENCES 
lime_LocalUsers(Uid) ON UPDATE CASCADE ON DELETE CASCADE);";
+       
+               /* DR Message Skipped DH : Store chains of skipped message 
keys, this table store the DHr identifying the chain
+               *  - DHid (primary key)
+               *  - SessionId : foreign key, link to the DR session the 
skipped keys are attached
+               *  - DHr : the peer ECDH public key used in this key chain
+               *  - received : count messages successfully decoded since the 
last MK insertion in that chain, allow to delete chains that are too old
+               */
+               sql<<"CREATE TABLE DR_MSk_DHr( \
+                                       DHid INTEGER PRIMARY KEY AUTOINCREMENT 
NOT NULL, \
+                                       sessionId INTEGER NOT NULL DEFAULT 0, \
+                                       DHr BLOB NOT NULL, \
+                                       received UNSIGNED INTEGER NOT NULL 
DEFAULT 0, \
+                                       FOREIGN KEY(sessionId) REFERENCES 
DR_sessions(sessionId) ON UPDATE CASCADE ON DELETE CASCADE);";
+       
+               /* DR Message Skipped MK : Store chains of skipped message 
keys, this table store the message keys with their index in the chain
+               *  - DHid : foreign key, link to the key chain table: 
DR_Message_Skipped_DH
+               *  - Nr : the id in the key chain
+               *  - MK : the message key stored
+               *  primary key is [DHid,Nr]
+               */
+               sql<<"CREATE TABLE DR_MSk_MK( \
+                                       DHid INTEGER NOT NULL, \
+                                       Nr INTEGER NOT NULL, \
+                                       MK BLOB NOT NULL, \
+                                       PRIMARY KEY( DHid , Nr ), \
+                                       FOREIGN KEY(DHid) REFERENCES 
DR_MSk_DHr(DHid) ON UPDATE CASCADE ON DELETE CASCADE);";
+       
+               /*** Lime tables : local user identities, peer devices 
identities ***/
+               /* List each self account enable on device :
+               *  - Uid : primary key, used to make link with Peer Devices, 
SPk and OPk tables
+               *  - UserId : shall be the GRUU
+               *  - Ik : public||private indentity key (EdDSA key)
+               *  - server : the URL of key Server
+               *  - curveId : identifies the curve used by this user - MUST be 
in sync with server. This integer stores also the activation byte.
+               *               Mapping is: <Activation byte>||<CurveId byte>
+               *               Activation byte is: 0x00 Active, 0x01 inactive
+               *               CurveId byte: as set in lime.hpp
+               *               default the curveId value to 0 which is not one 
of the possible values (defined in lime.hpp)
+               *  - updateTs : Last update timestamp. When was performed an 
update operation for this user.
+               */
+               sql<<"CREATE TABLE lime_LocalUsers( \
+                                       Uid INTEGER PRIMARY KEY AUTOINCREMENT 
NOT NULL, \
+                                       UserId TEXT NOT NULL, \
+                                       Ik BLOB NOT NULL, \
+                                       server TEXT NOT NULL, \
+                                       curveId INTEGER NOT NULL DEFAULT 0, \
+                                       updateTs DATETIME DEFAULT 
CURRENT_TIMESTAMP);";
+       
+               /* Peer Devices :
+               * - Did : primary key, used to make link with DR_sessions table.
+               * - DeviceId: peer device id (shall be its GRUU)
+               * - Ik : Peer device Identity public key, got it from X3DH 
server or X3DH init message
+               * - Status : a flag, 0 : untrusted, 1 : trusted, 2 : unsafe
+               *               The mapping is done in lime.hpp by the 
PeerDeviceStatus enum class definition
+               *
+               * Note: peer device information is shared by all local device, 
hence they are not linked to particular local devices from lime_LocalUsers table
+               *
+               * Note2: The Ik field should be able to be NULL but it is not 
for historical reason.
+               *        When a peer device is inserted without Ik(through the 
set_peerDeviceStatus with a unsafe status is the only way to do that)
+               *        it will be given an Ik set to invalid_Ik (one byte at 
0x00) with the purpose of being unable to match a real Ik as NULL would have 
done
+               */
+               sql<<"CREATE TABLE lime_PeerDevices( \
+                                       Did INTEGER PRIMARY KEY AUTOINCREMENT 
NOT NULL, \
+                                       DeviceId TEXT NOT NULL, \
+                                       Ik BLOB NOT NULL, \
+                                       Status UNSIGNED INTEGER DEFAULT 0);";
+       
+               /*** X3DH tables ***/
+               /* Signed pre-key :
+               * - SPKid : the primary key must be a random number as it is 
public, so avoid leaking information on number of key used
+               * - SPK : Public key||Private Key (ECDH keys)
+               * - timeStamp : Application shall renew SPK regurlarly 
(SPK_LifeTime). Old key are disactivated and deleted after a period 
(SPK_LimboTime))
+               * - Status : a boolean: can be active(1) or stale(0), by 
default any newly inserted key is set to active
+               * - Uid : User Id from lime_LocalUsers table: who's key is this
+               */
+               sql<<"CREATE TABLE X3DH_SPK( \
+                                       SPKid UNSIGNED INTEGER PRIMARY KEY NOT 
NULL, \
+                                       SPK BLOB NOT NULL, \
+                                       timeStamp DATETIME DEFAULT 
CURRENT_TIMESTAMP, \
+                                       Status INTEGER NOT NULL DEFAULT 1, \
+                                       Uid INTEGER NOT NULL, \
+                                       FOREIGN KEY(Uid) REFERENCES 
lime_LocalUsers(Uid) ON UPDATE CASCADE ON DELETE CASCADE);";
+       
+               /* One time pre-key : deleted after usage, generated at user 
creation and on X3DH server request
+               * - OPKid : the primary key must be a random number as it is 
public, so avoid leaking information on number of key used
+               * - OPK : Public key||Private Key (ECDH keys)
+               * - Uid : User Id from lime_LocalUsers table: who's key is this
+               * - Status : a boolean: is likely to be present on X3DH 
Server(1), not anymore on X3DH server(0), by default any newly inserted key is 
set to 1
+               * - timeStamp : timeStamp is set during update if we found out 
a key is no more on server(and we didn't used it as usage delete key).
+               *               So after a limbo period, key is considered 
missing in action and removed from storage.
+               */
+               sql<<"CREATE TABLE X3DH_OPK( \
+                                       OPKid UNSIGNED INTEGER PRIMARY KEY NOT 
NULL, \
+                                       OPK BLOB NOT NULL, \
+                                       Uid INTEGER NOT NULL, \
+                                       Status INTEGER NOT NULL DEFAULT 1, \
+                                       timeStamp DATETIME DEFAULT 
CURRENT_TIMESTAMP, \
+                                       FOREIGN KEY(Uid) REFERENCES 
lime_LocalUsers(Uid) ON UPDATE CASCADE ON DELETE CASCADE);";
+       
                tr.commit(); // commit all the previous queries
-               return;
+       } catch (BctbxException const &e) {
+               throw BCTBX_EXCEPTION << "Db instanciation on file 
"<<filename<<" check failed: "<<e.str();
+       } catch (exception const &e) {
+               throw BCTBX_EXCEPTION << "Db instanciation on file 
"<<filename<<" check failed: "<<e.what();
        }
-
-       // create the lime DB:
-
-       /*** Double Ratchet tables ***/
-       /* DR Session:
-       *  - DId : link to lime_PeerDevices table, identify which peer is 
associated to this session
-       *  - Uid: link to LocalUsers table, identify which local device is 
associated to this session
-       *  - SessionId(primary key)
-       *  - Ns, Nr, PN : index for sending, receivind and previous sending 
chain
-       *  - DHr : peer current public ECDH key
-       *  - DHs : self current ECDH key. (public || private keys)
-       *  - RK, CKs, CKr : Root key, sender and receiver chain keys
-       *  - AD : Associated data : provided once at session creation by X3DH, 
is derived from initiator public Ik and id, receiver public Ik and id
-       *  - Status : 0 is for stale and 1 is for active, only one session 
shall be active for a peer device, by default created as active
-       *  - timeStamp : is updated when session change status and is used to 
remove stale session after determined time in cleaning operation
-       *  - X3DHInit : when we are initiator, store the generated X3DH init 
message and keep sending it until we've got at least a reply from peer
-       */
-       sql<<"CREATE TABLE DR_sessions( \
-                               Did INTEGER NOT NULL DEFAULT 0, \
-                               Uid INTEGER NOT NULL DEFAULT 0, \
-                               sessionId INTEGER PRIMARY KEY AUTOINCREMENT NOT 
NULL, \
-                               Ns UNSIGNED INTEGER NOT NULL, \
-                               Nr UNSIGNED INTEGER NOT NULL, \
-                               PN UNSIGNED INTEGER NOT NULL, \
-                               DHr BLOB NOT NULL, \
-                               DHs BLOB NOT NULL, \
-                               RK BLOB NOT NULL, \
-                               CKs BLOB NOT NULL, \
-                               CKr BLOB NOT NULL, \
-                               AD BLOB NOT NULL, \
-                               Status INTEGER NOT NULL DEFAULT 1, \
-                               timeStamp DATETIME DEFAULT CURRENT_TIMESTAMP, \
-                               X3DHInit BLOB DEFAULT NULL, \
-                               FOREIGN KEY(Did) REFERENCES 
lime_PeerDevices(Did) ON UPDATE CASCADE ON DELETE CASCADE, \
-                               FOREIGN KEY(Uid) REFERENCES 
lime_LocalUsers(Uid) ON UPDATE CASCADE ON DELETE CASCADE);";
-
-       /* DR Message Skipped DH : Store chains of skipped message keys, this 
table store the DHr identifying the chain
-       *  - DHid (primary key)
-       *  - SessionId : foreign key, link to the DR session the skipped keys 
are attached
-       *  - DHr : the peer ECDH public key used in this key chain
-       *  - received : count messages successfully decoded since the last MK 
insertion in that chain, allow to delete chains that are too old
-       */
-       sql<<"CREATE TABLE DR_MSk_DHr( \
-                               DHid INTEGER PRIMARY KEY AUTOINCREMENT NOT 
NULL, \
-                               sessionId INTEGER NOT NULL DEFAULT 0, \
-                               DHr BLOB NOT NULL, \
-                               received UNSIGNED INTEGER NOT NULL DEFAULT 0, \
-                               FOREIGN KEY(sessionId) REFERENCES 
DR_sessions(sessionId) ON UPDATE CASCADE ON DELETE CASCADE);";
-
-       /* DR Message Skipped MK : Store chains of skipped message keys, this 
table store the message keys with their index in the chain
-       *  - DHid : foreign key, link to the key chain table: 
DR_Message_Skipped_DH
-       *  - Nr : the id in the key chain
-       *  - MK : the message key stored
-       *  primary key is [DHid,Nr]
-       */
-       sql<<"CREATE TABLE DR_MSk_MK( \
-                               DHid INTEGER NOT NULL, \
-                               Nr INTEGER NOT NULL, \
-                               MK BLOB NOT NULL, \
-                               PRIMARY KEY( DHid , Nr ), \
-                               FOREIGN KEY(DHid) REFERENCES DR_MSk_DHr(DHid) 
ON UPDATE CASCADE ON DELETE CASCADE);";
-
-       /*** Lime tables : local user identities, peer devices identities ***/
-       /* List each self account enable on device :
-       *  - Uid : primary key, used to make link with Peer Devices, SPk and 
OPk tables
-       *  - User Id : shall be the GRUU
-       *  - Ik : public||private indentity key (EdDSA key)
-       *  - server : the URL of key Server
-       *  - curveId : identifies the curve used by this user - MUST be in sync 
with server. This integer stores also the activation byte.
-       *               Mapping is: <Activation byte>||<CurveId byte>
-       *               Activation byte is: 0x00 Active, 0x01 inactive
-       *               CurveId byte: as set in lime.hpp
-       */
-       sql<<"CREATE TABLE lime_LocalUsers( \
-                               Uid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
\
-                               UserId TEXT NOT NULL, \
-                               Ik BLOB NOT NULL, \
-                               server TEXT NOT NULL, \
-                               curveId INTEGER NOT NULL DEFAULT 0);"; // 
default the curveId value to 0 which is not one of the possible values (defined 
in lime.hpp)
-
-       /* Peer Devices :
-       * - Did : primary key, used to make link with DR_sessions table.
-       * - DeviceId: peer device id (shall be its GRUU)
-       * - Ik : Peer device Identity public key, got it from X3DH server or 
X3DH init message
-       * - Status : a flag, 0 : untrusted, 1 : trusted, 2 : unsafe
-       *               The mapping is done in lime.hpp by the PeerDeviceStatus 
enum class definition
-       *
-       * Note: peer device information is shared by all local device, hence 
they are not linked to particular local devices from lime_LocalUsers table
-       *
-       * Note2: The Ik field should be able to be NULL but it is not for 
historical reason.
-       *        When a peer device is inserted without Ik(through the 
set_peerDeviceStatus with a unsafe status is the only way to do that)
-       *        it will be given an Ik set to invalid_Ik (one byte at 0x00) 
with the purpose of being unable to match a real Ik as NULL would have done
-       */
-       sql<<"CREATE TABLE lime_PeerDevices( \
-                               Did INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
\
-                               DeviceId TEXT NOT NULL, \
-                               Ik BLOB NOT NULL, \
-                               Status UNSIGNED INTEGER DEFAULT 0);";
-
-       /*** X3DH tables ***/
-       /* Signed pre-key :
-       * - SPKid : the primary key must be a random number as it is public, so 
avoid leaking information on number of key used
-       * - SPK : Public key||Private Key (ECDH keys)
-       * - timeStamp : Application shall renew SPK regurlarly (SPK_LifeTime). 
Old key are disactivated and deleted after a period (SPK_LimboTime))
-       * - Status : a boolean: can be active(1) or stale(0), by default any 
newly inserted key is set to active
-       * - Uid : User Id from lime_LocalUsers table: who's key is this
-       */
-       sql<<"CREATE TABLE X3DH_SPK( \
-                               SPKid UNSIGNED INTEGER PRIMARY KEY NOT NULL, \
-                               SPK BLOB NOT NULL, \
-                               timeStamp DATETIME DEFAULT CURRENT_TIMESTAMP, \
-                               Status INTEGER NOT NULL DEFAULT 1, \
-                               Uid INTEGER NOT NULL, \
-                               FOREIGN KEY(Uid) REFERENCES 
lime_LocalUsers(Uid) ON UPDATE CASCADE ON DELETE CASCADE);";
-
-       /* One time pre-key : deleted after usage, generated at user creation 
and on X3DH server request
-       * - OPKid : the primary key must be a random number as it is public, so 
avoid leaking information on number of key used
-       * - OPK : Public key||Private Key (ECDH keys)
-       * - Uid : User Id from lime_LocalUsers table: who's key is this
-       * - Status : a boolean: is likely to be present on X3DH Server(1), not 
anymore on X3DH server(0), by default any newly inserted key is set to 1
-       * - timeStamp : timeStamp is set during update if we found out a key is 
no more on server(and we didn't used it as usage delete key).
-       *               So after a limbo period, key is considered missing in 
action and removed from storage.
-       */
-       sql<<"CREATE TABLE X3DH_OPK( \
-                               OPKid UNSIGNED INTEGER PRIMARY KEY NOT NULL, \
-                               OPK BLOB NOT NULL, \
-                               Uid INTEGER NOT NULL, \
-                               Status INTEGER NOT NULL DEFAULT 1, \
-                               timeStamp DATETIME DEFAULT CURRENT_TIMESTAMP, \
-                               FOREIGN KEY(Uid) REFERENCES 
lime_LocalUsers(Uid) ON UPDATE CASCADE ON DELETE CASCADE);";
-
-       tr.commit(); // commit all the previous queries
 };
 
 /**
@@ -290,20 +304,6 @@
 }
 
 /**
- * @brief Get a list of deviceIds of all local users present in localStorage
- *
- * @param[out] deviceIds       the list of all local users (their device Id)
- */
-void Db::get_allLocalDevices(std::vector<std::string> &deviceIds) {
-       std::lock_guard<std::recursive_mutex> lock(*m_db_mutex);
-       deviceIds.clear();
-       rowset<row> rs = (sql.prepare << "SELECT UserId FROM lime_LocalUsers;");
-       for (const auto &r : rs) {
-               deviceIds.push_back(r.get<std::string>(0));
-       }
-}
-
-/**
  * @brief set the peer device status flag in local storage: unsafe, trusted or 
untrusted.
  *
  * @param[in]  peerDeviceId    The device Id of peer, shall be its GRUU
@@ -558,6 +558,33 @@
 }
 
 /**
+ * @brief checks if a device needs to be updated
+ * return true if the device exists and updateTs is older than OPk_updatePeriod
+ *
+ * @param[in]  deviceId        The device Id
+ *
+ * @return true the updateTs is older than OPk_updatePeriod, false otherwise
+ */
+bool Db::is_updateRequested(const std::string &deviceId) {
+       std::lock_guard<std::recursive_mutex> lock(*m_db_mutex);
+       int count = 0;
+       sql<<"SELECT count(*) FROM Lime_LocalUsers WHERE UserId = :deviceId AND 
updateTs < date('now', '-"<<lime::settings::OPk_updatePeriod<<" seconds') LIMIT 
1;", into(count), use(deviceId);
+       return sql.got_data() && count > 0;
+}
+
+/**
+ * @brief update the update timestamp to now()
+ *
+ * @param[in]  deviceId        The device Id
+ *
+ */
+void Db::set_updateTs(const std::string &deviceId) {
+       std::lock_guard<std::recursive_mutex> lock(*m_db_mutex);
+       sql<<"UPDATE Lime_LocalUsers SET updateTs = CURRENT_TIMESTAMP WHERE 
UserId = :deviceID", use(deviceId);
+}
+
+
+/**
  * @brief delete a peerDevice from local storage
  *
  * @param[in]  peerDeviceId    The device Id to be removed from local storage, 
shall be its GRUU
@@ -1014,7 +1041,7 @@
                // set the inactive user bit on, user is not active until X3DH 
server's confirmation
                int curveId = lime::settings::DBInactiveUserBit | 
static_cast<uint16_t>(Curve::curveId());
 
-               m_localStorage->sql<<"INSERT INTO 
lime_LocalUsers(UserId,Ik,server,curveId) VALUES (:userId,:Ik,:server,:curveId) 
", use(m_selfDeviceId), use(Ik), use(m_X3DH_Server_URL), use(curveId);
+               m_localStorage->sql<<"INSERT INTO 
lime_LocalUsers(UserId,Ik,server,curveId,updateTs) VALUES 
(:userId,:Ik,:server,:curveId, CURRENT_TIMESTAMP) ", use(m_selfDeviceId), 
use(Ik), use(m_X3DH_Server_URL), use(curveId);
        } catch (exception const &e) {
                tr.rollback();
                throw BCTBX_EXCEPTION << "Lime user insertion failed. DB 
backend says: "<<e.what();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/src/lime_localStorage.hpp 
new/lime-5.2.73/src/lime_localStorage.hpp
--- old/lime-5.2.49/src/lime_localStorage.hpp   2022-11-09 23:33:57.000000000 
+0100
+++ new/lime-5.2.73/src/lime_localStorage.hpp   2023-05-10 07:45:32.000000000 
+0200
@@ -53,7 +53,8 @@
                void delete_LimeUser(const std::string &deviceId);
                void clean_DRSessions();
                void clean_SPk();
-               void get_allLocalDevices(std::vector<std::string> &deviceIds);
+               bool is_updateRequested(const std::string &deviceId);
+               void set_updateTs(const std::string &deviceId);
                void set_peerDeviceStatus(const std::string &peerDeviceId, 
const std::vector<uint8_t> &Ik, lime::PeerDeviceStatus status);
                void set_peerDeviceStatus(const std::string &peerDeviceId, 
lime::PeerDeviceStatus status);
                lime::PeerDeviceStatus get_peerDeviceStatus(const std::string 
&peerDeviceId);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/src/lime_manager.cpp 
new/lime-5.2.73/src/lime_manager.cpp
--- old/lime-5.2.49/src/lime_manager.cpp        2022-11-09 23:33:57.000000000 
+0100
+++ new/lime-5.2.73/src/lime_manager.cpp        2023-05-10 07:45:32.000000000 
+0200
@@ -30,11 +30,11 @@
 
 namespace lime {
        LimeManager::LimeManager(const std::string &db_access, const 
limeX3DHServerPostData &X3DH_post_data, std::shared_ptr<std::recursive_mutex> 
db_mutex)
-               : m_users_cache{}, m_db_access{db_access}, 
m_db_mutex{db_mutex}, m_X3DH_post_data{X3DH_post_data} { }
+               : m_users_cache{}, 
m_localStorage{std::make_shared<lime::Db>(db_access, db_mutex)}, 
m_X3DH_post_data{X3DH_post_data} { }
 
        // When no mutex is provided for database access, create one
        LimeManager::LimeManager(const std::string &db_access, const 
limeX3DHServerPostData &X3DH_post_data)
-               : m_users_cache{}, m_db_access{db_access}, 
m_db_mutex{std::make_shared<std::recursive_mutex>()}, 
m_X3DH_post_data{X3DH_post_data} { }
+               : m_users_cache{}, 
m_localStorage{std::make_shared<lime::Db>(db_access, 
std::make_shared<std::recursive_mutex>())}, m_X3DH_post_data{X3DH_post_data} { }
 
        void LimeManager::load_user(std::shared_ptr<LimeGeneric> &user, const 
std::string &localDeviceId, const bool allStatus) {
                // get the Lime manager lock
@@ -42,7 +42,7 @@
                // Load user object
                auto userElem = m_users_cache.find(localDeviceId);
                if (userElem == m_users_cache.end()) { // not in cache, load it 
from DB
-                       user = load_LimeUser(m_db_access, localDeviceId, 
m_X3DH_post_data, m_db_mutex, allStatus);
+                       user = load_LimeUser(m_localStorage, localDeviceId, 
m_X3DH_post_data, allStatus);
                        m_users_cache[localDeviceId]=user;
                } else {
                        user = userElem->second;
@@ -65,9 +65,7 @@
 
                        // then check if it went well, if not delete the user 
from localDB
                        if (returnCode != lime::CallbackReturn::success) {
-                               auto localStorage = 
std::unique_ptr<lime::Db>(new lime::Db(thiz->m_db_access, thiz->m_db_mutex));
-
-                               localStorage->delete_LimeUser(localDeviceId);
+                               
thiz->m_localStorage->delete_LimeUser(localDeviceId);
 
                                // Failure can occur only on X3DH server 
response(local failure generate an exception so we would never
                                // arrive in this callback)), so the lock 
acquired by create_user has already expired when we arrive here
@@ -77,7 +75,7 @@
                });
 
                std::lock_guard<std::mutex> lock(m_users_mutex);
-               m_users_cache.insert({localDeviceId, 
insert_LimeUser(m_db_access, localDeviceId, x3dhServerUrl, curve, 
OPkInitialBatchSize, m_X3DH_post_data, managerCreateCallback, m_db_mutex)});
+               m_users_cache.insert({localDeviceId, 
insert_LimeUser(m_localStorage, localDeviceId, x3dhServerUrl, curve, 
OPkInitialBatchSize, m_X3DH_post_data, managerCreateCallback)});
        }
 
        void LimeManager::delete_user(const std::string &localDeviceId, const 
limeCallback &callback) {
@@ -145,52 +143,50 @@
 
 
        /* This version use default settings */
-       void LimeManager::update(const limeCallback &callback) {
-               update(callback, lime::settings::OPk_serverLowLimit, 
lime::settings::OPk_batchSize);
+       void LimeManager::update(const std::string &localDeviceId, const 
limeCallback &callback) {
+               update(localDeviceId, callback, 
lime::settings::OPk_serverLowLimit, lime::settings::OPk_batchSize);
        }
-       void LimeManager::update(const limeCallback &callback, uint16_t 
OPkServerLowLimit, uint16_t OPkBatchSize) {
-               // open local DB
-               auto localStorage = std::unique_ptr<lime::Db>(new 
lime::Db(m_db_access, m_db_mutex));
-
-               /* DR sessions and old stale SPk cleaning */
-               localStorage->clean_DRSessions();
-               localStorage->clean_SPk();
-
-               // get all users from localStorage
-               std::vector<std::string> deviceIds{};
-               localStorage->get_allLocalDevices(deviceIds);
-
-               //This counter will trace number of callbacks, to trace how 
many operation did end.
-               // we expect two callback per local user account: one for 
update SPk, one for get OPk number on server
-               auto callbackCount = make_shared<size_t>(deviceIds.size()*2);
+       void LimeManager::update(const std::string &localDeviceId, const 
limeCallback &callback, uint16_t OPkServerLowLimit, uint16_t OPkBatchSize) {
+               // Check if the last update was performed more than 
OPk_updatePeriod seconds ago
+               if (!m_localStorage->is_updateRequested(localDeviceId)) {
+                       if (callback) callback(lime::CallbackReturn::success, 
"No update needed");
+                       return;
+               }
+
+               LIME_LOGI<<"Update user "<<localDeviceId;
+
+               /* DR sessions and old stale SPk cleaning - This cleaning is 
performed for all local users as it is easier this way */
+               m_localStorage->clean_DRSessions();
+               m_localStorage->clean_SPk();
+
+               // Load user object
+               std::shared_ptr<LimeGeneric> user;
+               LimeManager::load_user(user, localDeviceId);
+
+               // we expect two callback: one for update SPk, one for get OPk 
number on server
+               auto callbackCount = make_shared<size_t>(2);
                auto globalReturnCode = 
make_shared<lime::CallbackReturn>(lime::CallbackReturn::success);
+               auto localStorage = m_localStorage;
 
                // this callback will get all callbacks from update OPk and SPk 
on all users, when everyone is done, call the callback given to 
LimeManager::update
-               limeCallback managerUpdateCallback([callbackCount, 
globalReturnCode, callback](lime::CallbackReturn returnCode, std::string 
errorMessage) {
+               limeCallback managerUpdateCallback([callbackCount, 
globalReturnCode, callback, localStorage, localDeviceId](lime::CallbackReturn 
returnCode, std::string errorMessage) {
                        (*callbackCount)--;
                        if (returnCode == lime::CallbackReturn::fail) {
                                *globalReturnCode = lime::CallbackReturn::fail; 
// if one fail, return fail at the end of it
                        }
 
                        if (*callbackCount == 0) {
+                               // update the timestamp
+                               localStorage->set_updateTs(localDeviceId);
                                if (callback) callback(*globalReturnCode, "");
                        }
                });
 
+               // send a request to X3DH server to check how many OPk are left 
on server, upload more if needed
+               user->update_OPk(managerUpdateCallback, OPkServerLowLimit, 
OPkBatchSize);
 
-               // for each user
-               for (auto deviceId : deviceIds) {
-                       LIME_LOGI<<"Lime update user "<<deviceId;
-                       //load user
-                       std::shared_ptr<LimeGeneric> user;
-                       LimeManager::load_user(user, deviceId);
-
-                       // send a request to X3DH server to check how many OPk 
are left on server, upload more if needed
-                       user->update_OPk(managerUpdateCallback, 
OPkServerLowLimit, OPkBatchSize);
-
-                       // update the SPk(if needed)
-                       user->update_SPk(managerUpdateCallback);
-               }
+               // update the SPk(if needed)
+               user->update_SPk(managerUpdateCallback);
        }
 
        void LimeManager::get_selfIdentityKey(const std::string &localDeviceId, 
std::vector<uint8_t> &Ik) {
@@ -201,38 +197,23 @@
        }
 
        void LimeManager::set_peerDeviceStatus(const std::string &peerDeviceId, 
const std::vector<uint8_t> &Ik, lime::PeerDeviceStatus status) {
-               // open local DB
-               auto localStorage = std::unique_ptr<lime::Db>(new 
lime::Db(m_db_access, m_db_mutex));
-
-               localStorage->set_peerDeviceStatus(peerDeviceId, Ik, status);
+               m_localStorage->set_peerDeviceStatus(peerDeviceId, Ik, status);
        }
 
        void LimeManager::set_peerDeviceStatus(const std::string &peerDeviceId, 
lime::PeerDeviceStatus status) {
-               // open local DB
-               auto localStorage = std::unique_ptr<lime::Db>(new 
lime::Db(m_db_access, m_db_mutex));
-
-               localStorage->set_peerDeviceStatus(peerDeviceId, status);
+               m_localStorage->set_peerDeviceStatus(peerDeviceId, status);
        }
 
        lime::PeerDeviceStatus LimeManager::get_peerDeviceStatus(const 
std::string &peerDeviceId) {
-               // open local DB
-               auto localStorage = std::unique_ptr<lime::Db>(new 
lime::Db(m_db_access, m_db_mutex));
-
-               return localStorage->get_peerDeviceStatus(peerDeviceId);
+               return m_localStorage->get_peerDeviceStatus(peerDeviceId);
        }
 
        lime::PeerDeviceStatus LimeManager::get_peerDeviceStatus(const 
std::list<std::string> &peerDeviceIds) {
-               // open local DB
-               auto localStorage = std::unique_ptr<lime::Db>(new 
lime::Db(m_db_access, m_db_mutex));
-
-               return localStorage->get_peerDeviceStatus(peerDeviceIds);
+               return m_localStorage->get_peerDeviceStatus(peerDeviceIds);
        }
 
        bool LimeManager::is_localUser(const std::string &deviceId) {
-               // open local DB
-               auto localStorage = std::unique_ptr<lime::Db>(new 
lime::Db(m_db_access, m_db_mutex));
-
-               return localStorage->is_localUser(deviceId);
+               return m_localStorage->is_localUser(deviceId);
        }
 
        void LimeManager::delete_peerDevice(const std::string &peerDeviceId) {
@@ -242,10 +223,7 @@
                        userElem.second->delete_peerDevice(peerDeviceId);
                }
 
-               // open local DB
-               auto localStorage = std::unique_ptr<lime::Db>(new 
lime::Db(m_db_access, m_db_mutex));
-
-               localStorage->delete_peerDevice(peerDeviceId);
+               m_localStorage->delete_peerDevice(peerDeviceId);
        }
 
        void LimeManager::stale_sessions(const std::string &localDeviceId, 
const std::string &peerDeviceId) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/src/lime_settings.hpp 
new/lime-5.2.73/src/lime_settings.hpp
--- old/lime-5.2.49/src/lime_settings.hpp       2022-11-09 23:33:57.000000000 
+0100
+++ new/lime-5.2.73/src/lime_settings.hpp       2023-05-10 07:45:32.000000000 
+0200
@@ -20,6 +20,7 @@
 #ifndef lime_settings_hpp
 #define lime_settings_hpp
 
+
 namespace lime {
 /** @brief Hold constants definition used as settings in all components of the 
lime library
  *
@@ -46,12 +47,12 @@
        static_assert(DRSessionSharedADSize<64, "Shared AD is generated through 
HKDF-Sha512 with only one round implemented so its size can't be more than 
Sha512 max output size");
 
        /** Maximum number of Message we can skip(and store their keys) at 
reception of one message */
-       constexpr std::uint16_t maxMessageSkip=1024;
+       constexpr uint16_t maxMessageSkip=1024;
 
        /** after a message key is stored, count how many messages we can 
receive from peer before deleting the key at next update
         * @note: implemented by receiving key chain, so any new skipped 
message in a chain will reset the counter to 0
         */
-       constexpr std::uint16_t maxMessagesReceivedAfterSkip = 128;
+       constexpr uint16_t maxMessagesReceivedAfterSkip = 128;
 
        /** @brief Maximum length of Sending chain
         *
@@ -59,7 +60,7 @@
         * the DR session is set to stale and we must create another one to 
send messages
         * Can't be more than 2^16 as message number is send on 2 bytes
         */
-       constexpr std::uint16_t maxSendingChain=1000;
+       constexpr uint16_t maxSendingChain=1000;
 
        /** Lifetime of a session once not active anymore, unit is day */
        constexpr unsigned int DRSession_limboTime_days=30;
@@ -83,6 +84,8 @@
        constexpr uint16_t OPk_serverLowLimit = 100;
        /// in days, How long shall we keep an OPk in localStorage once we've 
noticed X3DH server dispatched it
        constexpr unsigned int 
OPk_limboTime_days=SPK_lifeTime_days+SPK_limboTime_days;
+       /// in seconds, how often should we perform an update (check if we 
should publish new OPk, cleaning DB routine etc...)
+       constexpr unsigned int OPk_updatePeriod=86400; // 1 day
 
 } // namespace settings
 
Binary files old/lime-5.2.49/tester/data/pattern_getSelfIk.C25519.sqlite3 and 
new/lime-5.2.73/tester/data/pattern_getSelfIk.C25519.sqlite3 differ
Binary files old/lime-5.2.49/tester/data/pattern_getSelfIk.C448.sqlite3 and 
new/lime-5.2.73/tester/data/pattern_getSelfIk.C448.sqlite3 differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/tester/lime-tester-utils.cpp 
new/lime-5.2.73/tester/lime-tester-utils.cpp
--- old/lime-5.2.49/tester/lime-tester-utils.cpp        2022-11-09 
23:33:57.000000000 +0100
+++ new/lime-5.2.73/tester/lime-tester-utils.cpp        2023-05-10 
07:45:32.000000000 +0200
@@ -502,11 +502,13 @@
  */
 void forwardTime(const std::string &dbFilename, int days) noexcept {
        try {
+               LIME_LOGI<<"Set timestamps back by "<<days<<" days";
                soci::session sql("sqlite3", dbFilename); // open the DB
-               /* move back by days all timeStamp, we have some in DR_sessions 
and X3DH_SPk tables */
+               /* move back by days all timeStamp, we have some in 
DR_sessions, X3DH_SPk and LocalUsers tables */
                sql<<"UPDATE DR_sessions SET timeStamp = date (timeStamp, 
'-"<<days<<" day');";
                sql<<"UPDATE X3DH_SPK SET timeStamp = date (timeStamp, 
'-"<<days<<" day');";
                sql<<"UPDATE X3DH_OPK SET timeStamp = date (timeStamp, 
'-"<<days<<" day');";
+               sql<<"UPDATE Lime_LocalUsers SET updateTs = date (updateTs, 
'-"<<days<<" day');";
        } catch (exception &e) { // swallow any error on DB
                LIME_LOGE<<"Got an error forwarding time in DB: "<<e.what();
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/tester/lime_ffi-tester.c 
new/lime-5.2.73/tester/lime_ffi-tester.c
--- old/lime-5.2.49/tester/lime_ffi-tester.c    2022-11-09 23:33:57.000000000 
+0100
+++ new/lime-5.2.73/tester/lime_ffi-tester.c    2023-05-10 07:45:32.000000000 
+0200
@@ -453,18 +453,16 @@
        /* Around once a day the update function shall be called on LimeManagers
         * it will perform localStorage cleanings
         * update of cryptographic material (Signed Pre-key and One-time 
Pre-keys)
+        * if called more often than once a day it is ignored
         * The update take as optionnal parameters :
         *  - lower bound for One-time Pre-key available on server
         *  - One-time Pre-key batch size to be generated and uploaded if lower 
limit on server is reached
         *
-        * Important : Avoid calling this function when connection to network 
is impossible
-        * try to first fetch any available message on server, process anything 
and then update
-        *
         * This update shall have no effect as Alice still have 
ffi_defaultInitialOPkBatchSize keys on X3DH server
         */
-       lime_ffi_update(aliceManager, statusCallback, NULL, 
ffi_defaultInitialOPkBatchSize, 3);  /* if less than 
ffi_defaultInitialOPkBatchSize keys are availables on server, upload a batch of 
3, typical values shall be higher. */
+       lime_ffi_update(aliceManager, aliceDeviceId, statusCallback, NULL, 
ffi_defaultInitialOPkBatchSize, 3);  /* if less than 
ffi_defaultInitialOPkBatchSize keys are availables on server, upload a batch of 
3, typical values shall be higher. */
        /* That one instead shall upload 3 new OPks to server as we used one of 
Bob's keys */
-       lime_ffi_update(bobManager, statusCallback, NULL, 
ffi_defaultInitialOPkBatchSize, 3); /* if less than 
ffi_defaultInitialOPkBatchSize keys are availables on server, upload a batch of 
3, typical values shall be higher. */
+       lime_ffi_update(bobManager, aliceDeviceId, statusCallback, NULL, 
ffi_defaultInitialOPkBatchSize, 3); /* if less than 
ffi_defaultInitialOPkBatchSize keys are availables on server, upload a batch of 
3, typical values shall be higher. */
        /* wait for updates to complete */
        expected_success += 2;
        BC_ASSERT_TRUE(wait_for(stack, &success_counter, expected_success, 
ffi_wait_for_timeout));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/tester/lime_helloworld-tester.cpp 
new/lime-5.2.73/tester/lime_helloworld-tester.cpp
--- old/lime-5.2.49/tester/lime_helloworld-tester.cpp   2022-11-09 
23:33:57.000000000 +0100
+++ new/lime-5.2.73/tester/lime_helloworld-tester.cpp   2023-05-10 
07:45:32.000000000 +0200
@@ -341,11 +341,9 @@
                // The update take as optionnal parameters :
                //  - lower bound for One-time Pre-key available on server
                //  - One-time Pre-key batch size to be generated and uploaded 
if lower limit on server is reached
-               //
-               // Important : Avoid calling this function when connection to 
network is impossible
-               // try to first fetch any available message on server, process 
anything and then update
-               aliceManager->update(callback, 10, 3); // if less than 10 keys 
are availables on server, upload a batch of 3, typical values shall be higher.
-               bobManager->update(callback); // use default values for the 
limit and batch size
+               //  If called more often than once a day, it just does nothing
+               aliceManager->update(*aliceDeviceId, callback, 10, 3); // if 
less than 10 keys are availables on server, upload a batch of 3, typical values 
shall be higher.
+               bobManager->update(*bobDeviceId, callback); // use default 
values for the limit and batch size
                expected_success+=2;
                /******* end of Users maintenance ****************************/
                // wait for updates to complete
@@ -585,8 +583,8 @@
                //
                // Important : Avoid calling this function when connection to 
network is impossible
                // try to first fetch any available message on server, process 
anything and then update
-               aliceManager->update(callback, 10, 3); // if less than 10 keys 
are availables on server, upload a batch of 3, typical values shall be higher.
-               bobManager->update(callback); // use default values for the 
limit and batch size
+               aliceManager->update(*aliceDeviceId, callback, 10, 3); // if 
less than 10 keys are availables on server, upload a batch of 3, typical values 
shall be higher.
+               bobManager->update(*bobDeviceId, callback); // use default 
values for the limit and batch size
                expected_success+=2;
                /******* end of Users maintenance ****************************/
                // wait for updates to complete
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/tester/lime_lime-tester.cpp 
new/lime-5.2.73/tester/lime_lime-tester.cpp
--- old/lime-5.2.49/tester/lime_lime-tester.cpp 2022-11-09 23:33:57.000000000 
+0100
+++ new/lime-5.2.73/tester/lime_lime-tester.cpp 2023-05-10 07:45:32.000000000 
+0200
@@ -208,7 +208,6 @@
                                });
 
        try {
-               auto bobCount=0;
                for (auto batches=0; batches<batch_number; batches++) {
                        for (auto i=0; i<batch_size; i++) {
                                auto patternIndex = messageCount % 
lime_tester::messages_pattern.size();
@@ -242,7 +241,6 @@
                                
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success,++expected_success,lime_tester::wait_for_timeout));
 
                                // bob decrypt
-                               bobCount++;
                                std::vector<uint8_t> receivedMessage{};
                                // in that context we cannot know the expected 
decrypt return value, just check it is not fail
                                
BC_ASSERT_TRUE(bobManager->decrypt(*bobDeviceId, "bob", *aliceDeviceId, 
(*aliceRecipients)[0].DRmessage, *aliceCipherMessage, receivedMessage) != 
lime::PeerDeviceStatus::fail);
@@ -1374,6 +1372,117 @@
 #endif
 }
 
+static void lime_db_migration() {
+       // Write a db version 1
+       std::string dbFilename("lime_db_migration-v1.sqlite3");
+       remove(dbFilename.data());
+       soci::session   sql;
+       try{
+               sql.open("sqlite3", dbFilename);
+               sql<<"PRAGMA foreign_keys = ON;"; // make sure this connection 
enable foreign keys
+               soci::transaction tr(sql);
+               // CREATE OR IGNORE TABLE db_module_version(
+               sql<<"CREATE TABLE IF NOT EXISTS db_module_version("
+                       "name VARCHAR(16) PRIMARY KEY,"
+                       "version UNSIGNED INTEGER NOT NULL"
+                       ")";
+               auto dbVersion = 1;
+               sql<<"INSERT INTO db_module_version(name,version) 
VALUES('lime',:DbVersion)", soci::use(dbVersion);
+               sql<<"CREATE TABLE DR_sessions( \
+                               Did INTEGER NOT NULL DEFAULT 0, \
+                               Uid INTEGER NOT NULL DEFAULT 0, \
+                               sessionId INTEGER PRIMARY KEY AUTOINCREMENT NOT 
NULL, \
+                               Ns UNSIGNED INTEGER NOT NULL, \
+                               Nr UNSIGNED INTEGER NOT NULL, \
+                               PN UNSIGNED INTEGER NOT NULL, \
+                               DHr BLOB NOT NULL, \
+                               DHs BLOB NOT NULL, \
+                               RK BLOB NOT NULL, \
+                               CKs BLOB NOT NULL, \
+                               CKr BLOB NOT NULL, \
+                               AD BLOB NOT NULL, \
+                               Status INTEGER NOT NULL DEFAULT 1, \
+                               timeStamp DATETIME DEFAULT CURRENT_TIMESTAMP, \
+                               X3DHInit BLOB DEFAULT NULL, \
+                               FOREIGN KEY(Did) REFERENCES 
lime_PeerDevices(Did) ON UPDATE CASCADE ON DELETE CASCADE, \
+                               FOREIGN KEY(Uid) REFERENCES 
lime_LocalUsers(Uid) ON UPDATE CASCADE ON DELETE CASCADE);";
+               sql<<"CREATE TABLE DR_MSk_DHr( \
+                               DHid INTEGER PRIMARY KEY AUTOINCREMENT NOT 
NULL, \
+                               sessionId INTEGER NOT NULL DEFAULT 0, \
+                               DHr BLOB NOT NULL, \
+                               received UNSIGNED INTEGER NOT NULL DEFAULT 0, \
+                               FOREIGN KEY(sessionId) REFERENCES 
DR_sessions(sessionId) ON UPDATE CASCADE ON DELETE CASCADE);";
+               sql<<"CREATE TABLE DR_MSk_MK( \
+                               DHid INTEGER NOT NULL, \
+                               Nr INTEGER NOT NULL, \
+                               MK BLOB NOT NULL, \
+                               PRIMARY KEY( DHid , Nr ), \
+                               FOREIGN KEY(DHid) REFERENCES DR_MSk_DHr(DHid) 
ON UPDATE CASCADE ON DELETE CASCADE);";
+               sql<<"CREATE TABLE lime_LocalUsers( \
+                               Uid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
\
+                               UserId TEXT NOT NULL, \
+                               Ik BLOB NOT NULL, \
+                               server TEXT NOT NULL, \
+                               curveId INTEGER NOT NULL DEFAULT 0);";
+               sql<<"CREATE TABLE lime_PeerDevices( \
+                               Did INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
\
+                               DeviceId TEXT NOT NULL, \
+                               Ik BLOB NOT NULL, \
+                               Status UNSIGNED INTEGER DEFAULT 0);";
+               sql<<"CREATE TABLE X3DH_SPK( \
+                               SPKid UNSIGNED INTEGER PRIMARY KEY NOT NULL, \
+                               SPK BLOB NOT NULL, \
+                               timeStamp DATETIME DEFAULT CURRENT_TIMESTAMP, \
+                               Status INTEGER NOT NULL DEFAULT 1, \
+                               Uid INTEGER NOT NULL, \
+                               FOREIGN KEY(Uid) REFERENCES 
lime_LocalUsers(Uid) ON UPDATE CASCADE ON DELETE CASCADE);";
+               sql<<"CREATE TABLE X3DH_OPK( \
+                               OPKid UNSIGNED INTEGER PRIMARY KEY NOT NULL, \
+                               OPK BLOB NOT NULL, \
+                               Uid INTEGER NOT NULL, \
+                               Status INTEGER NOT NULL DEFAULT 1, \
+                               timeStamp DATETIME DEFAULT CURRENT_TIMESTAMP, \
+                               FOREIGN KEY(Uid) REFERENCES 
lime_LocalUsers(Uid) ON UPDATE CASCADE ON DELETE CASCADE);";
+               // Insert a dummy row in the table modified by the migration as 
some operation are permitted over empty tables but not ones with data
+               sql<<"INSERT INTO lime_LocalUsers(UserId, Ik, server, curveId) 
VALUES ('sip:notauser', '0x1234556', 'http://notalimeserver.com', 1);";
+
+               tr.commit(); // commit all the previous queries
+               sql.close();
+       } catch (BctbxException &e) {
+               LIME_LOGE << e;
+               BC_FAIL("Can't create test version 1 DB");
+               return;
+       }
+
+       // Open a manager giving the same DB, it shall migrate the structure to 
version 2
+       try  {
+               // create Manager
+               std::unique_ptr<LimeManager> manager = 
std::make_unique<LimeManager>(dbFilename, X3DHServerPost);
+       } catch (BctbxException &e) {
+               LIME_LOGE << e;
+               BC_FAIL("Can't open manager to perform DB migration");
+               return;
+       }
+
+       // Version 2 of db added a Timestamp
+       try  {
+               sql.open("sqlite3", dbFilename);
+               int userVersion=-1;
+               sql<<"SELECT version FROM db_module_version WHERE name='lime'", 
soci::into(userVersion);
+               BC_ASSERT_EQUAL(userVersion, 0x100, int, "%d");
+               int haveTs=0;
+               sql<<"SELECT COUNT(*) FROM pragma_table_info('lime_LocalUsers') 
WHERE name='updateTs'", soci::into(haveTs);
+               BC_ASSERT_EQUAL(haveTs, 1, int, "%d");
+       } catch (BctbxException &e) {
+               LIME_LOGE << e;
+               BC_FAIL("Can't check DB migration done");
+               return;
+       }
+       if (cleanDatabase) {
+               remove(dbFilename.data());
+       }
+}
+
 /**
  * Scenario:
  * - Create a user alice
@@ -1417,7 +1526,7 @@
 
                // call the update, set the serverLimit to initialBatch size 
and upload an other initial batch if needed
                // As all the keys are still on server, it shall have no 
effect, check it then
-               aliceManager->update(callback, 
lime_tester::OPkInitialBatchSize, lime_tester::OPkInitialBatchSize);
+               aliceManager->update(*aliceDeviceId, callback, 
lime_tester::OPkInitialBatchSize, lime_tester::OPkInitialBatchSize);
                
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success, 
++expected_success,lime_tester::wait_for_timeout));
                BC_ASSERT_EQUAL((int)lime_tester::get_OPks(dbFilenameAlice, 
*aliceDeviceId), lime_tester::OPkInitialBatchSize, int, "%d");
 
@@ -1452,7 +1561,8 @@
 
                // call the update, set the serverLimit to initialBatch size 
and upload an other initial batch if needed
                // As some keys were removed from server this time we shall 
generate and upload a new batch
-               aliceManager->update(callback, 
lime_tester::OPkInitialBatchSize, lime_tester::OPkInitialBatchSize);
+               lime_tester::forwardTime(dbFilenameAlice, 2); // Forward time 
by 2 days so the update actually do something
+               aliceManager->update(*aliceDeviceId, callback, 
lime_tester::OPkInitialBatchSize, lime_tester::OPkInitialBatchSize);
                
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success, 
++expected_success,lime_tester::wait_for_timeout));
                // we uploaded a new batch but no key were removed from 
localStorage so we now have 2*batch size keys
                BC_ASSERT_EQUAL((int)lime_tester::get_OPks(dbFilenameAlice, 
*aliceDeviceId), 2*lime_tester::OPkInitialBatchSize, int, "%d");
@@ -1475,7 +1585,7 @@
                BC_ASSERT_EQUAL((int)lime_tester::get_OPks(dbFilenameAlice, 
*aliceDeviceId), 2*lime_tester::OPkInitialBatchSize - 1, int, "%d");
 
                // call the update, set the serverLimit to 0, we don't want to 
upload more keys, but too old unused local OPk dispatched by server long ago 
shall be deleted
-               aliceManager->update(callback, 0, 0);
+               aliceManager->update(*aliceDeviceId, callback, 0, 0);
                
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success, 
++expected_success,lime_tester::wait_for_timeout));
 
                // check the local OPk missing on server for a long time has 
been deleted
@@ -1594,7 +1704,7 @@
                        aliceManager = std::unique_ptr<LimeManager>(new 
LimeManager(dbFilenameAlice, X3DHServerPost));
 
                        // call the update, it shall create and upload a new 
SPk but keep the old ones
-                       aliceManager->update(callback, 0, 
lime_tester::OPkInitialBatchSize);
+                       aliceManager->update(*aliceDeviceId, callback, 0, 
lime_tester::OPkInitialBatchSize);
                        
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success, 
++expected_success,lime_tester::wait_for_timeout));
                        SPkExpectedCount++;
 
@@ -1634,7 +1744,7 @@
                aliceManager = std::unique_ptr<LimeManager>(new 
LimeManager(dbFilenameAlice, X3DHServerPost));
 
                // call the update, it shall create and upload a new SPk but 
keep the old ones and delete one
-               aliceManager->update(callback, 0, 
lime_tester::OPkInitialBatchSize);
+               aliceManager->update(*aliceDeviceId, callback, 0, 
lime_tester::OPkInitialBatchSize);
                
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success, 
++expected_success,lime_tester::wait_for_timeout));
                // there shall not be any rise in the number of SPk keys found 
in DB, check that
                SPkCount=0;
@@ -1749,8 +1859,9 @@
                /* update belle-sip stack processing possible incoming messages 
from server */
                belle_sip_stack_sleep(bc_stack,0);
 
-               /* call the update function */
-               bobManager->update(callback, 0, 
lime_tester::OPkInitialBatchSize);
+               /* call the update function, forwardtime by 2 days before or 
the update is skipped */
+               lime_tester::forwardTime(dbFilenameBob, 2);
+               bobManager->update(*bobDeviceId, callback, 0, 
lime_tester::OPkInitialBatchSize);
                
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success, 
++expected_success, lime_tester::wait_for_timeout));
 
                /* Check that bob got 0 message key in local Storage */
@@ -1839,9 +1950,10 @@
                
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success, 
++expected_success,lime_tester::wait_for_timeout));
                // Start a new manager using the backuped local base, so the 
user is present in local but no more on remote
                aliceManager = nullptr;
+               lime_tester::forwardTime(dbFilenameAliceBackup, 2); // forward 
time otherwise the update won't do anything
                aliceManager = std::unique_ptr<LimeManager>(new 
LimeManager(dbFilenameAliceBackup, X3DHServerPost));
                // Update: that shall set all current OPk as dispatched, create 
a new batch of default creation size and republish the user on server
-               aliceManager->update(callback, 
lime_tester::OPkInitialBatchSize, lime_tester::OPkInitialBatchSize);
+               aliceManager->update(*aliceDeviceId, callback, 
lime_tester::OPkInitialBatchSize, lime_tester::OPkInitialBatchSize);
                
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success, 
++expected_success,lime_tester::wait_for_timeout));
                // Bob encrypt a message to Alice, it will fetch keys from 
server
                auto bobRecipients = make_shared<std::vector<RecipientData>>();
@@ -2152,6 +2264,7 @@
 
        limeCallback callback([&counters](lime::CallbackReturn returnCode, 
std::string anythingToSay) {
                                        if (returnCode == 
lime::CallbackReturn::success) {
+                                               LIME_LOGI<<"Lime operation 
success : "<<anythingToSay;
                                                counters.operation_success++;
                                        } else {
                                                counters.operation_failed++;
@@ -2275,8 +2388,8 @@
                BC_ASSERT_EQUAL((int)bobSessionsId.size(), 2, int, "%d");
 
                // run the update function
-               aliceManager->update(callback, 0, 
lime_tester::OPkInitialBatchSize);
-               bobManager->update(callback, 0, 
lime_tester::OPkInitialBatchSize);
+               aliceManager->update(*aliceDevice1, callback, 0, 
lime_tester::OPkInitialBatchSize);
+               bobManager->update(*bobDevice1, callback, 0, 
lime_tester::OPkInitialBatchSize);
                expected_success+=2;
                
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success,expected_success,lime_tester::wait_for_timeout));
 
@@ -2303,8 +2416,8 @@
                bobManager = std::unique_ptr<LimeManager>(new 
LimeManager(dbFilenameBob, X3DHServerPost));
 
                // run the update function
-               aliceManager->update(callback, 0, 
lime_tester::OPkInitialBatchSize);
-               bobManager->update(callback, 0, 
lime_tester::OPkInitialBatchSize);
+               aliceManager->update(*aliceDevice1, callback, 0, 
lime_tester::OPkInitialBatchSize);
+               bobManager->update(*bobDevice1, callback, 0, 
lime_tester::OPkInitialBatchSize);
                expected_success+=2;
                
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success,expected_success,lime_tester::wait_for_timeout));
 
@@ -3328,9 +3441,6 @@
        auto Manager = std::unique_ptr<LimeManager>(new 
LimeManager(dbFilenameAlice, X3DHServerPost));
        auto aliceDeviceName = lime_tester::makeRandomDeviceName("alice.");
 
-       // a mutex to feed internal functions
-       auto m_mutex = std::make_shared<std::recursive_mutex>();
-
        try {
                /*Check if Alice exists in the database */
                BC_ASSERT_FALSE(Manager->is_user(*aliceDeviceName));
@@ -3340,13 +3450,9 @@
                
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success,++expected_success,lime_tester::wait_for_timeout));
                if (counters.operation_failed == 1) return; // skip the end of 
the test if we can't do this
 
-               /*Check if Alice exists in the database */
+               /*Check if Alice exists in the database, it will also load it */
                BC_ASSERT_TRUE(Manager->is_user(*aliceDeviceName));
 
-               /* load alice from from DB */
-               auto alice = load_LimeUser(dbFilenameAlice, *aliceDeviceName, 
X3DHServerPost, m_mutex);
-               /* no need to wait here, it shall load alice immediately */
-
                // Get alice x3dh server url
                BC_ASSERT_TRUE(Manager->get_x3dhServerUrl(*aliceDeviceName) == 
x3dh_server_url);
 
@@ -3368,7 +3474,7 @@
        bool gotExpectedException = false;
        /* Try to create the same user in the same data base, it must fail with 
exception raised */
        try {
-               auto alice = insert_LimeUser(dbFilenameAlice, *aliceDeviceName, 
x3dh_server_url, curve, lime_tester::OPkInitialBatchSize, X3DHServerPost, 
callback, m_mutex);
+               Manager->create_user(*aliceDeviceName, x3dh_server_url, curve, 
lime_tester::OPkInitialBatchSize, callback);
                /* no need to wait here, it must fail immediately */
        } catch (BctbxException &) {
                gotExpectedException = true;
@@ -3379,17 +3485,12 @@
                return;
        }
 
-       /* Try to load a user which is not in DB, it must fail with exception 
raised */
-       gotExpectedException = false;
        try {
-               auto alice = load_LimeUser(dbFilenameAlice, "bob", 
X3DHServerPost, m_mutex);
-               /* no need to wait here, it must fail immediately */
-       } catch (BctbxException &) {
-               gotExpectedException = true;
-       }
-       if (!gotExpectedException) {
-               // we didn't got any exception on trying to load bob from DB
-               BC_FAIL("No exception arised when loading inexistent user from 
DB");
+               /* Check a non existent user is not found */
+               BC_ASSERT_FALSE(Manager->is_user("bob"));
+       } catch (BctbxException &e) {
+               LIME_LOGE << e;
+               BC_FAIL("");
                return;
        }
 
@@ -3423,7 +3524,7 @@
 
        /* Create Alice again */
        try {
-               std::shared_ptr<LimeGeneric> alice = 
insert_LimeUser(dbFilenameAlice, *aliceDeviceName, x3dh_server_url, curve, 
lime_tester::OPkInitialBatchSize, X3DHServerPost, callback, m_mutex);
+               Manager->create_user(*aliceDeviceName, x3dh_server_url, curve, 
lime_tester::OPkInitialBatchSize, callback);
                
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success,++expected_success,lime_tester::wait_for_timeout));
 
                // create another manager with a fresh DB
@@ -3876,7 +3977,7 @@
                        // wait for a random period betwwen 25 and 100 ms
                        
std::this_thread::sleep_for(std::chrono::milliseconds(dis(gen)));
                        // Update
-                       thread_arg.manager->update(callback, serverLimit, 
batchSize);
+                       
thread_arg.manager->update(thread_arg.userlist[thread_arg.userIndex], callback, 
serverLimit, batchSize);
                        expected_success++;
                        serverLimit+=rnd_serverLimit(gen); // improver server 
limit by a random 0 to 4
                        // make sure we process possible message incoming from 
X3DH server
@@ -3959,7 +4060,7 @@
                }
                activeThreads.clear();
 
-               // encrypt, three encryotion threads per user
+               // encrypt, three encryption threads per user
                for (auto i=0; i<3; i++) {
                        for (const auto &arg : devArg) {
                                
activeThreads.emplace_back(lime_multithread_encrypt_thread, arg);
@@ -4151,6 +4252,7 @@
        TEST_NO_TAG("Identity theft", lime_identity_theft),
        TEST_NO_TAG("Multithread", lime_multithread),
        TEST_NO_TAG("Session cancel", lime_session_cancel),
+       TEST_NO_TAG("DB Migration", lime_db_migration)
 };
 
 test_suite_t lime_lime_test_suite = {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lime-5.2.49/tester/lime_server-tester.cpp 
new/lime-5.2.73/tester/lime_server-tester.cpp
--- old/lime-5.2.49/tester/lime_server-tester.cpp       2022-11-09 
23:33:57.000000000 +0100
+++ new/lime-5.2.73/tester/lime_server-tester.cpp       2023-05-10 
07:45:32.000000000 +0200
@@ -152,7 +152,7 @@
                                });
        try {
                // create Manager and device for alice
-               auto aliceManager = std::unique_ptr<LimeManager>(new 
LimeManager(dbFilenameAlice, X3DHServerPost));
+               auto aliceManager = 
std::make_unique<LimeManager>(dbFilenameAlice, X3DHServerPost);
                auto aliceDeviceId = 
lime_tester::makeRandomDeviceName("alice.");
                aliceManager->create_user(*aliceDeviceId, x3dh_server_url, 
curve, 500, callback);
                
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_failed, 
++expected_failure,lime_tester::wait_for_timeout));
@@ -162,29 +162,38 @@
                
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success, 
++expected_success,lime_tester::wait_for_timeout));
 
                // call the update, set the serverLimit 200 and upload an other 
100
-               aliceManager->update(callback, 200, 100);
+               aliceManager=nullptr; // destroy manager before modifying DB
+               lime_tester::forwardTime(dbFilenameAlice, 2);
+               aliceManager = std::make_unique<LimeManager>(dbFilenameAlice, 
X3DHServerPost);
+               aliceManager->update(*aliceDeviceId, callback, 200, 100);
                
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success, 
++expected_success,lime_tester::wait_for_timeout));
                BC_ASSERT_EQUAL((int)lime_tester::get_OPks(dbFilenameAlice, 
*aliceDeviceId), 200, int, "%d");
 
                // call the update, set the serverLimit 300 and upload an other 
100 -> it shall fail but we have 300 OPks in DB
-               aliceManager->update(callback, 300, 100);
+               aliceManager=nullptr; // destroy manager before modifying DB
+               lime_tester::forwardTime(dbFilenameAlice, 2);
+               aliceManager = std::make_unique<LimeManager>(dbFilenameAlice, 
X3DHServerPost);
+               aliceManager->update(*aliceDeviceId, callback, 300, 100);
                
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_failed, 
++expected_failure,lime_tester::wait_for_timeout));
                BC_ASSERT_EQUAL((int)lime_tester::get_OPks(dbFilenameAlice, 
*aliceDeviceId), 300, int, "%d");
 
                // update again, with correct values, server already holds 200 
keys, so the only effect would be to set the failed 100 OPks status to 
dispatched as they are not on server
-               aliceManager->update(callback, 125, 25);
+               aliceManager=nullptr; // destroy manager before modifying DB
+               lime_tester::forwardTime(dbFilenameAlice, 2);
+               aliceManager = std::make_unique<LimeManager>(dbFilenameAlice, 
X3DHServerPost);
+               aliceManager->update(*aliceDeviceId, callback, 125, 25);
                
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success, 
++expected_success,lime_tester::wait_for_timeout));
                BC_ASSERT_EQUAL((int)lime_tester::get_OPks(dbFilenameAlice, 
*aliceDeviceId), 300, int, "%d");
 
                // forward time by OPK_limboTime_days
                aliceManager=nullptr; // destroy manager before modifying DB
                lime_tester::forwardTime(dbFilenameAlice, 
lime::settings::OPk_limboTime_days+1);
-               aliceManager = std::unique_ptr<LimeManager>(new 
LimeManager(dbFilenameAlice, X3DHServerPost));
+               aliceManager = std::make_unique<LimeManager>(dbFilenameAlice, 
X3DHServerPost);
 
                // update one last time, with correct values, server already 
holds 200 keys
                // so the only effect would be to remove the OPk keys status 
was set to dispatch before we forward the time
                // We now hold 200 keys
-               aliceManager->update(callback, 125, 25);
+               aliceManager->update(*aliceDeviceId, callback, 125, 25);
                
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success, 
++expected_success,lime_tester::wait_for_timeout));
                BC_ASSERT_EQUAL((int)lime_tester::get_OPks(dbFilenameAlice, 
*aliceDeviceId), 200, int, "%d");
 
@@ -455,7 +464,8 @@
                        aliceManager->encrypt(*aliceDeviceId2, 
make_shared<const std::string>("friends"), recipients, message, cipherMessage, 
callback);
                        
BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success,++expected_success,lime_tester::wait_for_timeout));
                        receivedMessage.clear();
-                       BC_ASSERT_TRUE(aliceManager->decrypt(*aliceDeviceId, 
"friends", *aliceDeviceId2, (*recipients)[0].DRmessage, *cipherMessage, 
receivedMessage) == lime::PeerDeviceStatus::untrusted);
+                       // alice2 is a local device for alice, so it is trusted
+                       BC_ASSERT_TRUE(aliceManager->decrypt(*aliceDeviceId, 
"friends", *aliceDeviceId2, (*recipients)[0].DRmessage, *cipherMessage, 
receivedMessage) == lime::PeerDeviceStatus::trusted);
                        receivedMessageString = 
std::string{receivedMessage.begin(), receivedMessage.end()};
                        BC_ASSERT_TRUE(receivedMessageString == 
lime_tester::messages_pattern[2*i+1]);
 

++++++ set_current_version.patch ++++++
--- /var/tmp/diff_new_pack.Ipl6ou/_old  2023-06-29 17:28:44.094402208 +0200
+++ /var/tmp/diff_new_pack.Ipl6ou/_new  2023-06-29 17:28:44.098402233 +0200
@@ -5,7 +5,7 @@
  endif()
  
 -project(lime VERSION 5.2.0 LANGUAGES ${LANGUAGES_LIST})
-+project(lime VERSION 5.2.49 LANGUAGES ${LANGUAGES_LIST})
++project(lime VERSION 5.2.73 LANGUAGES ${LANGUAGES_LIST})
  
  set(LIME_SO_VERSION "0")
  set(LIME_VERSION ${PROJECT_VERSION})

Reply via email to