summaryrefslogtreecommitdiff
path: root/protocols/VKontakte/src/misc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/VKontakte/src/misc.cpp')
-rw-r--r--protocols/VKontakte/src/misc.cpp256
1 files changed, 118 insertions, 138 deletions
diff --git a/protocols/VKontakte/src/misc.cpp b/protocols/VKontakte/src/misc.cpp
index a0e49f8cce..95870c2a7a 100644
--- a/protocols/VKontakte/src/misc.cpp
+++ b/protocols/VKontakte/src/misc.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2013-24 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2013-25 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -146,6 +146,12 @@ void CVkProto::CheckUpdate()
bIint64IDCompatibility = true;
}
+ if (getDword("LastAccessTokenTime", 0) < 1740009600)
+ ClearAccessToken();
+
+ delSetting("Login");
+ delSetting("Password");
+
}
//////////////////////// bIint64IDCompatibility /////////////////////////////////////////
@@ -231,13 +237,6 @@ void CVkProto::ClearAccessToken()
ShutdownSession();
}
-wchar_t* CVkProto::GetUserStoredPassword()
-{
- debugLogA("CVkProto::GetUserStoredPassword");
- ptrA szRawPass(getStringA("Password"));
- return (szRawPass != nullptr) ? mir_utf8decodeW(szRawPass) : nullptr;
-}
-
void CVkProto::SetAllContactStatuses(int iStatus)
{
debugLogA("CVkProto::SetAllContactStatuses (%d)", iStatus);
@@ -390,16 +389,24 @@ bool CVkProto::CheckJsonResult(AsyncHttpRequest *pReq, const JSONNode &jnNode)
MsgPopup(TranslateT("Access denied! Data will not be sent or received."), TranslateT("Error"), true);
break;
case VKERR_CAPTCHA_NEEDED:
- ApplyCaptcha(pReq, jnError);
+ if (!pReq)
+ return false;
+
+ if (!ApplyCaptcha(pReq, jnError))
+ if(!pReq->m_iRetry) {
+ CMStringW wszMsg(FORMAT, TranslateT("Error %d. Data will not be sent or received."), iErrorCode);
+ wszMsg += "\n";
+ wszMsg += TranslateT("Captcha processing error.");
+ MsgPopup(wszMsg, TranslateT("Error"), true);
+ debugLogA("CVkProto::CheckJsonResult Captcha processing error");
+ }
+
break;
case VKERR_VALIDATION_REQUIRED: // Validation Required
MsgPopup(TranslateT("You have to validate your account before you can use VK in Miranda NG"), TranslateT("Error"), true);
if (jnRedirectUri) {
T2Utf szRedirectUri(jnRedirectUri.as_mstring());
- AsyncHttpRequest *pRedirectReq = new AsyncHttpRequest(this, REQUEST_GET, szRedirectUri, false, &CVkProto::OnOAuthAuthorize);
- pRedirectReq->m_bApiReq = false;
- pRedirectReq->bIsMainConn = true;
- Push(pRedirectReq);
+ LogIn(szRedirectUri);
}
break;
case VKERR_FLOOD_CONTROL:
@@ -408,12 +415,13 @@ bool CVkProto::CheckJsonResult(AsyncHttpRequest *pReq, const JSONNode &jnNode)
case VKERR_UNKNOWN:
case VKERR_TOO_MANY_REQ_PER_SEC:
+ if (pReq->m_priority == AsyncHttpRequest::rpCaptcha)
+ break;
+ __fallthrough;
case VKERR_INTERNAL_SERVER_ERR:
if (pReq->m_iRetry > 0) {
pReq->bNeedsRestart = true;
- Sleep(1000); //Pause for fix err
- debugLogA("CVkProto::CheckJsonResult Retry = %d", pReq->m_iRetry);
- pReq->m_iRetry--;
+ debugLogA("CVkProto::CheckJsonResult Retry = %d", (MAX_RETRIES - pReq->m_iRetry + 1));
}
else {
CMStringW wszMsg(FORMAT, TranslateT("Error %d. Data will not be sent or received."), iErrorCode);
@@ -468,115 +476,6 @@ void CVkProto::OnReceiveSmth(MHttpResponse *reply, AsyncHttpRequest *pReq)
/////////////////////////////////////////////////////////////////////////////////////////
// Quick & dirty form parser
-static CMStringA getAttr(char *szSrc, LPCSTR szAttrName)
-{
- char *pEnd = strchr(szSrc, '>');
- if (pEnd == nullptr)
- return "";
-
- *pEnd = 0;
-
- char *p1 = strstr(szSrc, szAttrName);
- if (p1 == nullptr) {
- *pEnd = '>';
- return "";
- }
-
- p1 += mir_strlen(szAttrName);
- if (p1[0] != '=' || p1[1] != '\"') {
- *pEnd = '>';
- return "";
- }
-
- p1 += 2;
- char *p2 = strchr(p1, '\"');
- *pEnd = '>';
- if (p2 == nullptr)
- return "";
-
- return CMStringA(p1, (int)(p2 - p1));
-}
-
-bool CVkProto::AutoFillForm(char *pBody, CMStringA &szAction, CMStringA& szResult)
-{
- debugLogA("CVkProto::AutoFillForm");
- szResult.Empty();
-
- char *pFormBeg = strstr(pBody, "<form ");
- if (pFormBeg == nullptr)
- return false;
-
- char *pFormEnd = strstr(pFormBeg, "</form>");
- if (pFormEnd == nullptr)
- return false;
-
- *pFormEnd = 0;
-
- szAction = getAttr(pFormBeg, "action");
-
- CMStringA result;
- char *pFieldBeg = pFormBeg;
- while (true) {
- if ((pFieldBeg = strstr(pFieldBeg + 1, "<input ")) == nullptr)
- break;
-
- CMStringA type = getAttr(pFieldBeg, "type");
- if (type != "submit") {
- CMStringA name = getAttr(pFieldBeg, "name");
- CMStringA value = getAttr(pFieldBeg, "value");
- if (name == "email")
- value = (char*)T2Utf(ptrW(getWStringA("Login")));
- else if (name == "pass")
- value = (char*)T2Utf(ptrW(GetUserStoredPassword()));
- else if (name == "captcha_key") {
- char *pCaptchaBeg = strstr(pFormBeg, "<img id=\"captcha\"");
- if (!pCaptchaBeg)
- pCaptchaBeg = strstr(pFormBeg, "<img src=\"/captcha.php");
-
- if (pCaptchaBeg)
- if (!RunCaptchaForm(getAttr(pCaptchaBeg, "src"), value))
- return false;
- }
- else if (name == "code") {
- char szPrefixTel[10], szSufixTel[10];
- CMStringW wszTitle;
- char *pPhonePref = strstr(pFormBeg, "<span class=\"field_prefix\">");
- if (pPhonePref && sscanf(pPhonePref, "<span class=\"field_prefix\">%[^<]", szPrefixTel) == 1) {
- pPhonePref = strstr(pPhonePref + 1, "<span class=\"field_prefix\">&nbsp;");
- if (pPhonePref && sscanf(pPhonePref, "<span class=\"field_prefix\">&nbsp;%[^<]", szSufixTel) == 1) {
- wszTitle.Format(TranslateT("Enter the missing digits between %s and %s of the phone number linked to your account"),
- ptrW(mir_a2u(szPrefixTel)).get(), ptrW(mir_a2u(szSufixTel)).get());
- MessageBoxW(nullptr, wszTitle, TranslateT("Attention!"), MB_ICONWARNING | MB_OK);
- }
- }
-
- value = RunConfirmationCode(wszTitle);
- if (value.IsEmpty())
- return false;
- }
-
- if (!result.IsEmpty())
- result.AppendChar('&');
- result += name + "=";
- result += mir_urlEncode(value);
- }
- }
-
- szResult = result;
- debugLogA("CVkProto::AutoFillForm result = \"%s\"", szResult.c_str());
- return true;
-}
-
-CMStringW CVkProto::RunConfirmationCode(LPCWSTR pwszTitle)
-{
- ENTER_STRING pForm = {};
- pForm.type = 0;
- CMStringW wszTitle(FORMAT, L"%s: %s", m_tszUserName, IsEmpty(pwszTitle) ? TranslateT("Enter confirmation code") : pwszTitle);
- pForm.caption = wszTitle;
- pForm.szModuleName = m_szModuleName;
- pForm.szDataPrefix = "confirmcode_";
- return (!EnterString(&pForm)) ? CMStringW() : CMStringW(ptrW(pForm.ptszResult));
-}
CMStringW CVkProto::RunRenameNick(LPCWSTR pwszOldName)
{
@@ -593,13 +492,20 @@ CMStringW CVkProto::RunRenameNick(LPCWSTR pwszOldName)
void CVkProto::GrabCookies(MHttpResponse *nhr, CMStringA szDefDomain)
{
- debugLogA("CVkProto::GrabCookies");
+ if (!nhr)
+ return;
for (auto &hdr : *nhr) {
if (_stricmp(hdr->szName, "Set-cookie"))
continue;
CMStringA szValue = hdr->szValue, szCookieName, szCookieVal, szDomain;
+
+ CMStringA szLogValue(szValue);
+ if (!IsEmpty(m_szAccessToken))
+ szLogValue.Replace(m_szAccessToken, "*secret*");
+ debugLogA("CVkProto::GrabCookies: %s", szLogValue.c_str());
+
int iStart = 0;
while (true) {
bool bFirstToken = (iStart == 0);
@@ -624,20 +530,23 @@ void CVkProto::GrabCookies(MHttpResponse *nhr, CMStringA szDefDomain)
for (auto &it : m_cookies)
if (it->m_name == szCookieName) {
bFound = true;
- if (szCookieVal == "DELETED")
+ if (CMStringA(szCookieVal).MakeUpper() == "DELETED")
m_cookies.remove(it);
else
it->m_value = szCookieVal;
break;
}
- if (!bFound && szCookieVal != "DELETED")
+ if (!bFound && CMStringA(szCookieVal).MakeUpper() != "DELETED")
m_cookies.insert(new CVkCookie(szCookieName, szCookieVal, szDomain));
+
}
}
+
+ SaveCookies();
}
-void CVkProto::ApplyCookies(AsyncHttpRequest *pReq)
+void CVkProto::ApplyCookies(MHttpRequest *pReq)
{
debugLogA("CVkProto::ApplyCookies");
CMStringA szCookie;
@@ -653,10 +562,68 @@ void CVkProto::ApplyCookies(AsyncHttpRequest *pReq)
szCookie.Append(it->m_value);
}
- if (!szCookie.IsEmpty())
+ if (!szCookie.IsEmpty()) {
pReq->AddHeader("Cookie", szCookie);
+ }
}
+void CVkProto::SaveCookies()
+{
+ CMStringA szCookie;
+
+ for (auto& it : m_cookies) {
+ if (!szCookie.IsEmpty())
+ szCookie.Append("; ");
+ szCookie.Append(it->m_name);
+ szCookie.AppendChar('=');
+ szCookie.Append(it->m_value);
+ szCookie.AppendChar('=');
+ szCookie.Append(it->m_domain);
+ }
+
+ if (!szCookie.IsEmpty())
+ setString("Cookie", szCookie);
+
+ if (!IsEmpty(m_szAccessToken))
+ szCookie.Replace(m_szAccessToken, "*secret*");
+
+ debugLogA("CVkProto::SaveCookies: %s", szCookie.c_str());
+}
+
+void CVkProto::LoadCookies()
+{
+ debugLogA("CVkProto::LoadCookies");
+ CMStringA szCookies = getStringA("Cookie");
+ if (szCookies.IsEmpty())
+ return;
+
+ CMStringA szCookieName, szCookieDomain, szCookieValue;
+ szCookies.AppendChar(';');
+
+ int iStart = 0;
+ while (true) {
+ CMStringA szToken = szCookies.Tokenize(";", iStart).Trim();
+ if (iStart == -1)
+ break;
+
+ int iStart2 = 0;
+
+ szCookieName = szToken.Tokenize("=", iStart2);
+ if (iStart2 == -1)
+ continue;
+
+ szCookieValue = szToken.Tokenize("=", iStart2);
+ if (iStart2 == -1)
+ continue;
+
+ szCookieDomain = szToken.Tokenize("=", iStart2);
+ if (iStart2 == -1)
+ continue;
+
+ m_cookies.insert(new CVkCookie(szCookieName, szCookieValue, szCookieDomain));
+ }
+
+}
/////////////////////////////////////////////////////////////////////////////////////////
bool CVkProto::IsAuthContactLater(MCONTACT hContact)
@@ -719,7 +686,7 @@ void CVkProto::DBAddAuthRequest(const MCONTACT hContact, bool added)
DBEVENTINFO dbei = {};
dbei.szModule = m_szModuleName;
- dbei.timestamp = (uint32_t)time(0);
+ dbei.iTimestamp = (uint32_t)time(0);
dbei.flags = DBEF_UTF;
dbei.eventType = added ? EVENTTYPE_ADDED : EVENTTYPE_AUTHREQUEST;
dbei.cbBlob = blob.size();
@@ -1378,10 +1345,14 @@ CMStringW CVkProto::GetAttachmentDescr(const JSONNode &jnAttachments, BBCSupport
continue;
CMStringW wszUrl(jnGraffiti["url"].as_mstring());
+ CMStringW wszImgUrl(wszUrl);
+
+ if (m_vkOptions.bBBCNewStorySupport)
+ wszUrl = GetVkFileItem(wszImgUrl, hContact, iMessageId);
res.AppendFormat(L"%s\n\t%s",
SetBBCString(TranslateT("Graffiti"), iBBC, vkbbcUrl, wszUrl).c_str(),
- SetBBCString(wszUrl, bbcBasic, vkbbcImg).c_str()
+ SetBBCString(wszImgUrl, iBBC, vkbbcImg).c_str()
);
}
else if (wszType == L"video") {
@@ -1575,8 +1546,11 @@ CMStringW CVkProto::GetAttachmentDescr(const JSONNode &jnAttachments, BBCSupport
wszUrl = wszLink.IsEmpty() ? (wszLink128.IsEmpty() ? wszLinkLast : wszLink128) : wszLink;
- if (!m_vkOptions.bStikersAsSmileys)
+ if (!m_vkOptions.bStikersAsSmileys) {
+ if(m_vkOptions.bBBCNewStorySupport)
+ wszUrl = GetVkFileItem(wszUrl, hContact, iMessageId);
res += SetBBCString(wszUrl, iBBC, vkbbcImg);
+ }
else if (m_vkOptions.bUseStikersAsStaticSmileys)
res.AppendFormat(L"[sticker:%d]", iStickerId);
else {
@@ -1649,10 +1623,13 @@ CMStringW CVkProto::GetAttachmentDescr(const JSONNode &jnAttachments, BBCSupport
SetBBCString(TranslateT("Product"), iBBC, vkbbcB).c_str(),
SetBBCString(wszTitle.IsEmpty() ? TranslateT("Link") : wszTitle, iBBC, vkbbcUrl, wszUrl).c_str());
- if (!wszPhoto.IsEmpty())
+ if (!wszPhoto.IsEmpty()) {
+ if (m_vkOptions.bBBCNewStorySupport)
+ wszPhoto = GetVkFileItem(wszPhoto, hContact, iMessageId);
res.AppendFormat(L"\n\t%s: %s",
SetBBCString(TranslateT("Photo"), iBBC, vkbbcB).c_str(),
SetBBCString(wszPhoto, iBBC, vkbbcImg).c_str());
+ }
if (jnMarket["price"] && jnMarket["price"]["text"])
res.AppendFormat(L"\n\t%s: %s",
@@ -1679,8 +1656,11 @@ CMStringW CVkProto::GetAttachmentDescr(const JSONNode &jnAttachments, BBCSupport
continue;
res += SetBBCString(TranslateT("Gift"), iBBC, vkbbcUrl, wszLink);
- if (m_vkOptions.iIMGBBCSupport && iBBC != bbcNo)
+ if (m_vkOptions.iIMGBBCSupport && iBBC != bbcNo) {
+ if (m_vkOptions.bBBCNewStorySupport)
+ wszLink = GetVkFileItem(wszLink, hContact, iMessageId);
res.AppendFormat(L"\n\t%s", SetBBCString(wszLink, iBBC, vkbbcImg).c_str());
+ }
}
else {
res.AppendFormat(TranslateT("Unsupported or unknown attachment type: %s"), SetBBCString(wszType, iBBC, vkbbcB).c_str());
@@ -1949,7 +1929,7 @@ void CVkProto::AddVkDeactivateEvent(MCONTACT hContact, CMStringW& wszType)
DBEVENTINFO dbei = {};
dbei.szModule = m_szModuleName;
- dbei.timestamp = time(0);
+ dbei.iTimestamp = time(0);
dbei.eventType = VK_USER_DEACTIVATE_ACTION;
ptrA pszDescription(mir_utf8encode(vkDeactivateEvent[iDEIdx].szDescription));
dbei.cbBlob = (uint32_t)mir_strlen(pszDescription) + 1;
@@ -1982,7 +1962,7 @@ MEVENT CVkProto::GetMessageFromDb(const char *szMessageId, time_t& tTimeStamp, C
DB::EventInfo dbei(hDbEvent);
wszMsg = ptrW(mir_utf8decodeW((char*)dbei.pBlob));
- tTimeStamp = dbei.timestamp;
+ tTimeStamp = dbei.getUnixtime();
return hDbEvent;
}
@@ -2010,7 +1990,7 @@ bool CVkProto::IsMessageExist(VKMessageID_t iMessageId, VKMesType vkType)
if(db_event_get(hDbEvent, &dbei))
return false;
- return ((vkType == vkOUT) == (bool)(dbei.flags & DBEF_SENT));
+ return ((vkType == vkOUT) == dbei.bSent);
}
CMStringW CVkProto::UserProfileUrl(VKUserID_t iUserId)