-
Content Count
163 -
Joined
-
Last visited
-
Days Won
3
rvk last won the day on June 28
rvk had the most liked content!
Community Reputation
46 ExcellentTechnical Information
-
Delphi-Version
Delphi 10.2 Tokyo
Recent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
-
RTF Roulette: The Hidden Dangers of Storing Rich Text in VARCHAR Fields
-
function EditStreamInCallback(dwCookie: Longint; pbBuff: PByte; cb: Longint; var pcb: Longint): dword; stdcall; const E_FAIL = dword($80004005); var theStream: TStream; dataAvail: Longint; begin theStream := TStream(dwCookie); with theStream do begin dataAvail := Size - Position; Result := 0; { assume everything is ok } if dataAvail <= cb then begin pcb := read(pbBuff^, dataAvail); if pcb <> dataAvail then { couldnt read req. amount of bytes } Result := E_FAIL; end else begin pcb := read(pbBuff^, cb); if pcb <> cb then Result := E_FAIL; end; end; end; function EditStreamOutCallback(dwCookie: Longint; pbBuff: PByte; cb: Longint; var pcb: Longint): dword; stdcall; var theStream: TStream; begin theStream := TStream(dwCookie); with theStream do begin if cb > 0 then pcb := write(pbBuff^, cb); Result := 0; end; end; procedure GetRTFSelection(aRichEdit: TJvRichEdit; intoStream: TStream); var editstream: TEditStream; begin with editstream do begin dwCookie := Longint(intoStream); dwError := 0; pfnCallback := @EditStreamOutCallback; end; aRichEdit.Perform(EM_STREAMOUT, SF_RTF or SFF_SELECTION, LParam(@editstream)); end; procedure PutRTFSelection(aRichEdit: TJvRichEdit; sourceStream: TStream); var editstream: TEditStream; begin with editstream do begin dwCookie := Longint(sourceStream); dwError := 0; pfnCallback := @EditStreamInCallback; end; aRichEdit.Perform(EM_STREAMIN, SF_RTF or SFF_SELECTION, LParam(@editstream)); end; function GetRTF(RE: TJvRichEdit; Selection: Boolean = false): string; var strStream: TStringStream; begin strStream := TStringStream.Create(''); try if Selection then begin GetRTFSelection(RE, strStream); Result := strStream.DataString; end else begin RE.PlainText := false; RE.Lines.SaveToStream(strStream); Result := strStream.DataString; end; finally strStream.Free end; end; procedure SetRTF(var RE: TJvRichEdit; S: string); var strStream: TStringStream; begin strStream := TStringStream.Create(''); try strStream.WriteString(S); strStream.Position := 0; RE.PlainText := false; RE.Lines.LoadFromStream(strStream); finally strStream.Free end; end; GetRTF/SetRTF for the complete content of TRichEdit (I use TJvRichEdit but you can change that to TRichEdit). GetRTFSelection/SetRTFSelection for only the selected content. With ExecSQL you don't work with dataaware components. The you can just use TField.AsString for the parameterized select/update/insert. TRichEdit is not dataaware. When you want to work with data-aware components like TDBRichEdit, you don't need to use ExecSQL. You can just do SELECT and fill in the UpdateSQL Object with INSERT/UPDATE/DELETE statements. Then in code you only have to do TQuery.Open (for the SELECT). Your TDBRichEdit will be automatically filled. When you do TQuery.Edit you enter edit mode (or you can do TQuery.Insert to insert a new record). After you are ready, you do TQuery.Post and the records (including the content of TDBRichEdit) is saved. (don't forget to Commit the transaction)
-
Surely after using VPN... you could use RDP over that VPN. What is the reason one client can't open the application over RDP anymore? I hope you have RDP behind a VPN? (just recently got a customer with open RDP port, which had his server ransomware'd). If it's just port-restriction at client side, you could try VPN over 443/https port and then use the RDP app.
-
Correct. That's why I use BLOB. (in Firebird BLOB SUB_TYPE 0 SEGMENT SIZE 80) (In Firebird you could also use SUB_TYPE 1 to let the DB treat it as text blob, but then you would need to make sure the char set is correct.) Then... I don't use the TBlobField(TField).LoadFromStream etc. for just RTF text (where I do for dropping random attachment and files in the DB). I use my own GetRTF(RichEdit1) and GetRTFSelection which retrieve the raw RTF and then use the normal TField.asString via parameterized update/insert queries. But... there is also a TDBRichEdit which should handle this automatically (I create my own TMyDBRichEdit for also handling some extras). So... when you have a visual richedit on screen, use the TDBRichEdit. When you need to store and read without visual richedit, use a GetRTF/SetRTF function. Don't show RTF in a grid as column (when you would use varchar). Because of the encoding it's not for reading directly anyways.
-
Google OAuth2, "username and password not accepted" when sending
rvk replied to emileverh's topic in Network, Cloud and Web
I'm beginning to think that using the limited scope gmail.send isn't allowed for SMTP sending. https://developers.google.com/gmail/imap/xoauth2-protocol There you see the remark (second point) "migrate to the Gmail API and use more granular restricted scopes". So for the limited scopes you would need to use the GMail API and not the SMTP service (?) For SMTP access I still use App passwords (which still work fine). For OAuth2 access with limited gmail.send and gmail.compose I use the GMail API at https://gmail.googleapis.com/upload/gmail/v1/users/{userId}/drafts/send (with attachments). You can either use drafts/send or messages/send method via the GMail API. https://developers.google.com/gmail/api/guides/sending Maybe someone else can confirm the above (that gmail.send scope can't be used with the smtp service). I already see here that it is confirmed on stackoverflow. https://stackoverflow.com/questions/39161914/using-gmail-send-scope-with-smtp-msa -
Google OAuth2, "username and password not accepted" when sending
rvk replied to emileverh's topic in Network, Cloud and Web
BTW. For the mentioned library... the same issue is described here: https://github.com/geoffsmith82/GmailAuthSMTP/issues/19 -
Google OAuth2, "username and password not accepted" when sending
rvk replied to emileverh's topic in Network, Cloud and Web
If you didn't go through the CASA Tier 2 then you are still in "Testing" phase. But that's ok and indeed perhaps off topic. Did you add scope https://www.googleapis.com/auth/gmail.send when asking for authentication? I know you said you added it to your consent screen but you also need to provide that scope (in your code) when going through the OAuth2 process. And second... when entering the consent screen, you need to CHECK the "Allow send" checkbox. It's not checked by default (and if you forget it, you won't have direct send access). I just did this myself again in my program and both my compose draft and send mail checkboxes where not checked by default. (I don't use the Indy components but Synapse but that shouldn't matter for above issues.) -
Google OAuth2, "username and password not accepted" when sending
rvk replied to emileverh's topic in Network, Cloud and Web
Did you also pass the "CASA Tier 2 security assessment" for your application? Can you provide the steps? I tried this a few years ago but they didn't provide any documentation as how to pass this. Tier 2 was only documented for online environments and Android Apps (where I would need to provide my app so they could test it). But I have an offline Windows application (which they don't seem to take into account). I finally gave up on the verification process. (I still get the "not verified" before entering the authentication screen) Or are you just in the test-phase where you can have a limited number of users (also normally used for internal testing)? (And also have the "not verified" screen) Regarding the error... I've only used the "AUTHENTICATE XOAUTH2" command with IMAP access to gMail. I see this library tries to do a user Bearer token. Did you try creating a new refresh-token (so going through the consent screen again)? -
What color banner does it show then if you start up those programs? I'm sure it's not this (below) blue banner because there is no verified producer name. So it will still show you the other yellow banner. It won't prompt smartscreen because that's something different. But it will probably you that install screen with yellow banner and no certificate warning. But yes, you need to adjust your workflow now to incorporate the new certificate
-
Maybe that's true for the full blue screen (where you need to tap more info). I don't think it's true for the install screens you showed in that article (blue banner for valid and yellow for invalid or not present). At least it shouldn't because that screen shouldn't get the info from smartscreen but directly from the certificate in the executable.
-
Not if used on a new computer. I don't know what happens on existing computers. But it's never wise to not sign with a timeserver. And maybe it passes smartscreen during download but it will not give you the blue screen when installing but a yellow screen promoting the expired certificate.
-
Yep. Then you can take that article down because it's based on old information. You can't do it like that anymore with new issued certificates. And you signed with the old certificate in that article. Also... all you previously signed exes will complain after that date. That's why you need to sign with a timeserver so those exes will keep working, even after the date of expiration of the certificate with which you signed.
-
O wow, then you didn't even signed with a timeserver with timestamp (which means the signed exe will complain when the certificate expires). Normally you sign with the timeserver so the exe will be usable also after your certificate expires. You just can't sign new exe anymore with an expired certificate. Because you didn't, and don't seem to be able to go to the real certificate, it leads me te believe you didn't even check things. Now do the same as before (right click exe, properties, certificate tab) but now click a SHA256 and click Details. Then click View certificate. There you have "Issued to", "Issued by" but also "Valid from/to". What are the dates there?
-
No, you need to right click the file and go to properties. Choose the certificate tab and see if it had the new certificate. That command just shows you still have a valid verificatie but that could still be the certificate which you can't use anymore after the spring to sign new files after that.
-
Can you check the actually signed exe file? Did it really contain the new certificate. I still have a feeling you are working with old files because the new method shouldn't allow token-less certificates anymore. So the old pfx isn't allowed anymore after it expires. https://knowledge.digicert.com/general-information/new-private-key-storage-requirement-for-standard-code-signing-certificates-november-2022 That mail is from the old way of doing things before 2023. So if you used the pfx from there... Then that's not going to work anymore after the certification expires in a few months.