I am using Edge browser component of Delphi 11.1 in order to automate a navigation process. The problem is that at the start of the navigation process I get the Message "Your connection isn't private" & the whole process stops until I press the button "Advanced" & the button "Continue to 1xx.xx.xx.xx (unsafe)"!
I have to mention that when I navigate to this intranet site via Windows Edge Browser I do not get that Message since I have uploaded the certificate of this site & I have also added it to the exceptions of Edge browser.
I think that I have to set it somehow the "InsecurePrivateNetworkRequestsAllowed" property to true but I cannot find the way or to upload somehow the certificate to Delphi's Edge browser component.
Any Ideas?
Thank you.
Insecure connection warning can be bypassed by clicking on the Proceed link.
Below there is a code sample:
procedure TForm1.EdgeBrowserNavigationCompleted(Sender: TCustomEdgeBrowser;
IsSuccess: Boolean; WebErrorStatus: TOleEnum);
resourcestring
scProceed =
'function run() { ' +
' var e = document.getElementById("proceed-link"); ' +
' if (e) e.click(); ' +
'} run();';
begin
if not IsSuccess and (WebErrorStatus = COREWEBVIEW2_WEB_ERROR_STATUS_CERTIFICATE_IS_INVALID) then
EdgeBrowser.ExecuteScript(scProceed);
end;
Another way is to control the WebView2 behaviour using CoreWebView2EnvironmentOptions.AdditionalBrowserArguments. Some of arguments are documented here.
Currently, Delphi 11.1 does not allow you to manage them using some component/interface, but such options could be set using WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS environement varialble before WebView initialization:
procedure TForm1.FormCreate(Sender: TObject);
begin
SetEnvironmentVariable('WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS',
'--ignore-certificate-errors');
EdgeBrowser.CreateWebView;
end;
Note, this option could be removed in future because of security concerns and sporadic debates on it.
Related
Using TRESTClient components I have added the ability of my app CW_EPG to access the SchedulesDirect.org JSON database under Windows 7 and higher, but running the app in Windows XP produces only the following error upon attempting to access the site: Error: REST request failed: Error sending data: (12007) The server name or address could not be resolved. I've tried enabling/disabling various of the controls listed in the Object Inspector, but have not succeeded in changing that error message. Am I missing something or is this Rio subsystem just incompatible with XP?
FWIW, here's the relevant code segment (the base URL is set in Object Inspector for RESTClient1 to https://json.schedulesdirect.org/20141201):
RESTRequest1.ClearBody;
RESTRequest1.AddBody('{"username":"' + userID
+ '", "password":"' + THashSHA1.GetHashString(userPass) +
'"}',ctTEXT_PLAIN);
RESTRequest1.Method := rmPOST;
RESTRequest1.Resource := 'token';
RESTResponse1.RootElement := '';
try
RESTRequest1.Execute;
except on E:Exception do
begin
ShowMessage('Error: ' + E.Message);
exit;
end;
end;
It seems that TRESTClient will work in Windows XP, but only after one has applied the hacks to "spoof" an XP POSReady installation and thereby enable TLS 1.1 and 1.2. See, e.g., this page: https://msfn.org/board/topic/178092-enable-tls-11-and-12-in-windows-xp-correctly/
BTW, #Remy Lebeau, Embarcadero's remote debugger also fails to work on my XP VM, which I thought likely due to its being a stripped down "nLite" XP installation. However, I have now constructed a full XP-SP3 (POSReady) VM and the remote debugger (paserver) also fails on that installation looking for a non-existent entry point in KERNEL32.dll.
I'm using Delphi 10.1 Berlin Update 2 Enterprise and the DataSnap client/server REST framework.
If I run the app without debugging and invoke a method the user isn't authorized to invoke, the code runs without any exception and the method returns a null response.
When interactively debugging a call on the client to a DataSnap server method, I get two popup exceptions regarding "unauthorized".
The first bubbles up and is replaced by the second.
The second exception gets "eaten" and the session/connection simply closed and then the method returns a blank result (e.g. a zero if the return type is integer, and an empty string for a string return type).
This is happening in the following section of code near the end of the ExecuteRequest method in the Datasnap.DSClientRest unit:
except
on E: TDSRestProtocolException do
LSessionExpired;
end;
Why are these exceptions (e.g. TDSRestProtocolException) not reaching my code?
I kind of think this is new to Update 2, and I remember seeing those exceptions bubble up to my code prior to Update 2.
Attached is a skeleton example (standard example generated by Delphi wizards) that demonstrates the issue - click the button and you get "" instead of "4321" because the user isn't authorized - but no runtime exception.
I'm new to DataSnap, so bear with me :-)
Thanks in advance for helpful responses =)
This is happening due to DSAuthenticationManager1 component added to webmodule of the server and client side is failing to authenticate.
Please go through this to check how to work with authentication
Adding Authentication and Authorization
Well..I'm not sure but try providing username and password to DSRestConnection1 component before the instance of server methods gets created
procedure TClientModule1.TestCon(aUsername, aPassword: string);
var
lServerMethodsClient : TServerMethodsClient;
begin
DSRestConnection1.UserName := aUsername;
DSRestConnection1.Password := aPassword;
lServerMethodsClient:=TServerMethodsClient.Create(DSRestConnection1);
end;
and try to call this functn from ur clientform
procedure TF_ClientForm.Button1Click(Sender: TObject);
begin
ClientModule1.TestCon(EdtUsername.Text, EdtPassword.Text);
end;
Maybe a little late but this morning I've had a deep dive into this because, after upgrading from Delphi XE6 to Tokyo 10.2, applications where I used the TDSRestConnection component got broken. Although I supplied the correct username and password, they did not appear in the TDSAuthenticationManager.OnUserAuthenticate event.
The 'problem' has to do with the new System.Net.HttpClient implementation.
To make a long story short (or a little bit less long):
The client component does not send the credentials until the receiving server demands one by sending a 401 response. After receiving this (properly formatted) response the client looks at de TDSConnection credentials en tries again. At the client side a complete list of urls with credential requirements is maintaned so repetitive calls to the same url go 'smoother'.
I added this code to the server's WebModule (where the TDSRESTWebDispatcher resides) which solved my problems:
procedure TwbmMain.WebModuleBeforeDispatch(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
LAuthorization: string;
begin
inherited;
if Request.PathInfo.StartsWith('/datasnap/') then
begin
LAuthorization := TNetEncoding.Base64.Decode(Request.Authorization.Replace('Basic ', ''));
if LAuthorization.IsEmpty then
begin
Response.StatusCode := 401;
Response.WWWAuthenticate := 'Basic';
Handled := True;
end;
end;
end;
Because my applications provides some downloadable items like a logo etc., I limited the check to just those URLs that have anything to do with datasnap.
Hope this is useful to others!
I have XE8 and the version of InterbaseXE7 that comes with it installed on two machines, A & B. Using IBX or DBX I can connect to the IB server running on the same machine and access its databases without any problem. Btw, I am not a regular IB user.
I had no luck at all connecting from a Delphi app on machine A to an IB database on machine B: I got all manner of errors including a mystifying one about not being able to find the file specified (despite doing a DIR from a CMD prompt to verify that I had the name right) until I discovered that in those circumstances (connecting to a remote server), the database name has to be capitalized in the Delphi app on A exactly as it is on the db host B.
So, assuming there is no way to configure IB and/or IBX to avoid this case-sensitivity, how can I programmatically retrieve a list of the database names, correctly capitalized, on B (assuming I have no access to B's file-system) from a Delphi app on A?
I've tried using the TIBServerProperties component to do this but using code like this:
procedure TForm1.btnPropertiesClick(Sender: TObject);
var
S : String;
begin
IBServerProperties1.Active := True;
IBServerProperties1.FetchDatabaseInfo;
S := IBServerProperties1.DatabaseInfo.DbName[0];
Caption := S;
end;
, the database names are returned from the IB host server in all capitals, which obviously doesn't solve the problem of finding their correct capitalizations.
It turns out that the TIBServerProperties can get DB Aliases from a remote server with the correct capitalization, but not using the DatabaseInfo property. The information can be obtained from its AliasInfo property instead (one of those things that's kind-of obvious with the benefit of hindsight), as shown below.
procedure TForm1.btnPropertiesClick(Sender: TObject);
var
S : String;
i : Integer;
begin
IBServerProperties1.Active := True;
IBServerProperties1.FetchAliasInfo;
for i :=0 to IBServerProperties1.AliasCount - 1 do begin
S := IBServerProperties1.AliasInfo[i].Alias; // <- the .Alias has the
// same capitalization as on the server
S := S + ' ' + IBServerProperties1.AliasInfo[i].DBPath;
Memo2.Lines.Add(S);
end;
end;
, which is good enough for my immediate purpose.
I'd still be interested to know, though, if there is an IB configuration parameter or similar that avoids the case-sensitivity that provoked my q.
Looking to get my delphi app to log into a website, navigate to a page, and automatically download certain files, the solution at How do I keep an embedded browser from prompting where to save a downloaded file?, helped a great deal with the file download.
The final problem is the last step on navigating opens in a popup window, there are plenty of solutions out there to capture popup windows by implementing TWebBrowser.NewWindow2 but none of these events seem to work with the above code, something to do with how twebbrowser.invokeevent in the above code works maybe?
If I use invokeveent and the dispID of 273(newwindow3) to call a function I can twebbwowser.navigate() a second webbrowser to the url of the popupwindow.
My problem is the popup window has basicly one line of javascript "document.print(parent.parent.opener.thefunction())" the second twebbrowser has no reference to its parent so this fails.
I can see two possible solutions, get the TWebBrowser.NewWindow2 or 3 to trigger, fix the code sample bellow, LVarArray[0] {const IDispatch}, is null for some reason.
procedure TWebBrowser.InvokeEvent(ADispID: TDispID; var AParams: TDispParams);
// DispID 250 is the BeforeNavigate2 dispinterface and to the FFileSource here
// is stored the URL parameter (for cases, when the IDownloadManager::Download
// won't redirect the URL and pass empty string to the pszRedir)
//showmessage('test');
var
ArgCount : Integer;
LVarArray : Array of OleVariant;
LIndex : Integer;
begin
inherited;
ArgCount := AParams.cArgs;
SetLength(LVarArray, ArgCount);
for LIndex := Low(LVarArray) to High(LVarArray) do
LVarArray[High(LVarArray)-LIndex] := OleVariant(TDispParams(AParams).rgvarg^[LIndex]);
case ADispID of
250: FFileSource := OleVariant(AParams.rgvarg^[5]);
273: DoNewWindow3(Self,
LVarArray[0] {const IDispatch},
WordBool((TVarData(LVarArray[1]).VPointer)^) {var WordBool},
LVarArray[2] {const OleVariant},
LVarArray[3] {const OleVariant},
LVarArray[4] {const OleVariant});
end;
end;
I'm not going to answer your question directly because I think you've asked the wrong question. You are trying to download files over the internet without any GUI being shown to the user. As such, an embedded browser is simply the wrong solution.
Rather than trying to suppress popup dialogs, use a tool that never shows popup dialogs. What I believe you should be doing is downloading the files using direct HTTP download. There are many different ways to achieve that. For example, an extremely convenient method, available out of the box with Delphi, is to use Indy. I believe that the component you need is TIdHttp.
I'm making a validation in my Inno Setup installer to check whether or not a Microsoft update is installed on the machine, if not, I'm showing a simple message box telling the user that the update is required, this is the message code:
MsgBox(
'Your system requires an update supplied by Microsoft. ' +
'Please follow this link to install it: ' +
'http://www.microsoft.com/downloads/details.aspx?FamilyID=1B0BFB35-C252-43CC-8A2A-6A64D6AC4670&displaylang=en',
mbInformation, MB_OK);
I want to make the URL an hyperlink to the web page, but I haven't been able to figure it out how, it is possible in Inno Setup to add text as an hyperlink?
Thanks.
The MsgBox() function in Inno Setup is a wrapper for the standard Windows MessageBox() function, which AFAIK doesn't support embedded links, so it's not possible to simply show the link there.
What you could do however is to notify the user that the update is required, and ask them whether to open the link in the default browser. Something like:
function InitializeSetup(): Boolean;
var
ErrCode: integer;
begin
if MsgBox('Your system requires an update supplied by Microsoft. Would you like to visit the download page now?', mbConfirmation, MB_YESNO) = IDYES
then begin
ShellExec('open', 'http://www.microsoft.com/downloads/details.aspx?FamilyID=1B0BFB35-C252-43CC-8A2A-6A64D6AC4670&displaylang=en',
'', '', SW_SHOW, ewNoWait, ErrCode);
end;
Result := False;
end;
This code will abort the installation, but you could create a custom page instead which checks whether the update has been installed, and otherwise prevents navigation to the next page. This would only work if the update can be installed without a system restart, though.