Merge remote-tracking branch 'miracl/master'
diff --git a/src/mpin_sdk.cpp b/src/mpin_sdk.cpp
index 9077fac..cf37779 100644
--- a/src/mpin_sdk.cpp
+++ b/src/mpin_sdk.cpp
@@ -661,7 +661,7 @@
     }
 
     m_context = ctx;
-    m_customHeaders = customHeaders;
+    m_customHeaders.PutAll(customHeaders);
 
     if(ctx->GetMPinCryptoType() == CRYPTO_NON_TEE)
     {
@@ -703,6 +703,11 @@
     return SetBackend(backend, rpsPrefix);
 }
 
+void MPinSDK::SetClientId(const String& clientId)
+{
+    m_customHeaders["X-MIRACL-Client-ID"] = clientId;
+}
+
 void MPinSDK::Destroy()
 {
     if(!IsInitilized())
@@ -716,6 +721,8 @@
     m_crypto = NULL;
     m_context = NULL;
 
+    m_customHeaders.clear();
+
     m_state = NOT_INITIALIZED;
 }
 
@@ -1118,6 +1125,16 @@
     return s;
 }
 
+Status MPinSDK::FinishAuthenticationMFA(INOUT UserPtr user, const String& pin, OUT String& authzCode)
+{
+    util::JsonObject authResult;
+
+    Status s = FinishAuthenticationImpl(user, pin, "", NULL, authResult);
+
+    authzCode = authResult.GetStringParam("code");
+    return s;
+}
+
 Status MPinSDK::FinishAuthenticationImpl(INOUT UserPtr user, const String& pin, const String& accessNumber, OUT String *otp, OUT util::JsonObject& authResultData)
 {
     Status s = CheckIfBackendIsSet();
diff --git a/src/mpin_sdk.h b/src/mpin_sdk.h
index 6785143..5d29199 100644
--- a/src/mpin_sdk.h
+++ b/src/mpin_sdk.h
@@ -241,6 +241,7 @@
     ~MPinSDK();
     Status Init(const StringMap& config, IN IContext* ctx);
     Status Init(const StringMap& config, IN IContext* ctx, const StringMap& customHeaders);
+    void SetClientId(const String& clientId);
     void Destroy();
     void ClearUsers();
 
@@ -259,6 +260,7 @@
     Status FinishAuthentication(INOUT UserPtr user, const String& pin, OUT String& authResultData);
     Status FinishAuthenticationOTP(INOUT UserPtr user, const String& pin, OUT OTP& otp);
     Status FinishAuthenticationAN(INOUT UserPtr user, const String& pin, const String& accessNumber);
+    Status FinishAuthenticationMFA(INOUT UserPtr user, const String& pin, OUT String& authzCode);
 
     Status GetSessionDetails(const String& accessCode, OUT SessionDetails& sessionDetails);
 
diff --git a/src/utils.cpp b/src/utils.cpp
index 4e70298..59a7664 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -282,6 +282,14 @@
     return true;
 }
 
+void StringMap::PutAll(const StringMap& other)
+{
+    for (StringMap::const_iterator i = other.begin(); i != other.end(); ++i)
+    {
+        (*this)[i->first] = i->second;
+    }
+}
+
 const char * StringMap::Get(const String& key) const
 {
     const_iterator i = find(key);
diff --git a/src/utils.h b/src/utils.h
index 20ae803..25569fe 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -86,6 +86,7 @@
     StringMap(const json::Object& object);
     json::Object ToJsonObject() const;
     bool Put(const String& key, const String& value);
+    void PutAll(const StringMap& other);
     const char * Get(const String& key) const;
 };