You are not logged in.
Hi.
Recently I swiched to ZeosLib 8.0.0 but I got error (Range Check Error) in:
ExecutePrepared function when calling :
var dbStmt := dbConn.Properties.ExecuteNoResult(sql, Params);
Seems it is ZeosLib error. But I'm not sure.
So I had to go back to ZeosLib 7.2
is it possible to bind parameter by name?
Lsql := 'select invoice_no,tran_date from fin_invoice where cust_code=:cust_code';
dbStmt := dbConn.NewStatementPrepared(LSql, True);
dbStmt.BindTextU(1, '1');
dbStmt.BindByName('cust_code') := '1';
Solved
Thank you.
I watched many videos on YouTube about authentication implementation with C#.
These videos showed an authentication service that allows Swagger users to obtain a JWT token and then click the Authorize button to import it as 'Bearer + JWT'.
I also created a similar service that is accessible in the Swagger section, which completely solved the problem.
Thank you and AB for your help.
Hi
serviceRunningContext^.Request.InBody is not valid json.
this is service method:
function TAuthenticationService.Login(const UserName, Password: RawUTF8): RawJson;
begin
var a := serviceRunningContext^.Request;
var b := TPassakRest(Server).fRestServerAuthentication;
TRestServerAuthenticationJWT(b).Auth(a);
end;body json is:
{
"UserName": "Admin",
"Password": "synopse"
}
serviceRunningContext^.Request.InBody is
{"UserName: "Admin "Password: "synopse
First of all, I put the Swagger.json.mustache file in a "templates" folder next to my REST server executable.
I don't remember where I found the Swagger.json.mustache file and copied it there.
Then, I added this line to my REST server startup procedure:
AddToServerWrapperMethod(MyRestServer,['templates','templates']);
After this step, the URL "http://localhost:8282/root/wrapper/" shows some links and information for me, including the mORMotClient.json file.
I shared my template file here:
https://gist.github.com/a-nouri/6bf970a … dac0a15c8a
I'm new to this and it took me several days to do this simple thing. I need to go back and study more on this. ![]()
thank you!
Finally, I found out how to add the Authorize button to my Swagger template.
I added this to the Swagger.json.mustache file, something like this:
"securityDefinitions": {
"JWTAuth": {
"type": "apiKey",
"name": "Authorization",
"in": "header",
"description": "Enter your JWT token here. Example: Bearer eyJhbGciOiJIUzI1NiIs..."
}
},
"security": [
{
"JWTAuth": []
}
],
Then, I get the JWT token in the Delphi REST debugger or Postman and put it in the Authorization field as:
Bearer eyJhbGciOiJIUzI1...
The difficulty here is that it requires getting the JWT from the REST debugger and pasting it in. I can't find a way to supply the username and password directly on the Swagger page to get the JWT and automate this process.
By the way, this is a big step forward for me.
I learned how to create HTML for displaying Swagger:
html := '''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="SwaggerUI" />
<title>SwaggerUI</title>
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui.css" />
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui-bundle.js" crossorigin></script>
<script>
window.onload = () => {
window.ui = SwaggerUIBundle({
url: '../wrapper/Swagger/mORMotClient.json',
dom_id: '#swagger-ui',
});
};
</script>
</body>
</html>
''';
Done!
Hi everyone!
I am using react as front end.
Is there a way to create json without \uFFF0 char?
mormot documentation:
// - BLOB field value is saved as Base64, in the '"\uFFF0base64encodedbinary"'
// format and contains true BLOB data
procedure ExecutePreparedAndFetchAllAsJson(Expanded: boolean;
out Json: RawUtf8; ReturnedRowCount: PPtrInt = nil);
Thank you
Hi every one.
//var LItemService := aPassakServer.ServiceRegister(TItemService, [TypeInfo(IItemService)], sicPerSession, '4');
var LItemService := aPassakServer.ServiceDefine(TItemService, [IItemService], sicPerSession, '4');
LItemService.ResultAsJsonObjectWithoutResult := True;
LItemService.ByPassAuthentication := False; //We can bypass authenticationwhen I cnahge ServiceRegister to ServiceDefine. ResultAsJsonObjectWithoutResult does not affect and result is:
{
"result": {
"Result": [
{
"cust_code": "0001",
"type": "domestic"
}
}
}
expected result is:
{
"Result": [
{
"cust_code": "0001",
"type": "domestic"
}
}
your gist link is not public.
Sending http://localhost:8282/root/CacheFlush/_ping_ does not renew session!
server start:
https://gist.github.com/a-nouri/48c5806 … 5947366ccd
I debbug it and in:
function TServiceFactoryServer.RenewSession(Ctxt: TRestServerUriContext): integer;
fInstances.Count is 0 !
and fInstanceCreation is sicShared
so function exit.
I don't know why fInstances.Count is zero, but why does this function only work for sicClientDriven, sicPerSession.
Thanks for help
There is no property in mormot cookie for expires. Is this correct way?
procedure TRestServerAuthenticationJWT.SessionCreate(Ctxt: TRestServerUriContext; var User: TAuthUser);
begin
//...
var ExpireStr: RawUtf8;
var ExpireTime := Now + 1;
ExpireStr := DateTimeToHttpDate(ExpireTime);
Ctxt.OutSetCookie := 'JWT=' + Token + '; Expires=' + ExpireStr;
end;I implemented my client and server using your github code, but there are memory leak in internalrequest!
I am using method 2. but I don't undrestand "don't publish the tables as REST"
Thank you.
Is this expected bahaiviour when I use:
TMykRest = class(TRestServerFullMemory)mormot does not retreive users from db or this is bug?
https://synopse.info/forum/profile.php?id=2
I add users to my table in database manager tools (like heidisql, ...).
After many try and error I find that when I delcare:
TMyRest = class(TRestServerDB)It works. but when I use :
TMyRest = class(TRestServerFullMemory)it does not work!
After calling OrmMapExternalAll I add user to my table in jwtauthuser table, but mormot does not add this to internal storage in memory, and when I call Auth URI, I got an error:
{
"errorCode": 403,
"errorText": "Authentication Failed: Unknown user (2)"
}
how can I reload settings? Suppose when service is running I add user to table. How can I retereive users list again?
I find this :
OrmMapExternalAll(MyModel, aDbConnection, []);
and now mormot create jwtauthuser and authgroup tables in mysql database.
I have one problem:
I created jwt rest server and mormot create users and groups in sqlite database.
but I have my own users table in my mysql database too. how can I use my own users and groups tables in my mysql database instead of mormot sqlite database?
This is gist link:
I copied "Swagger.json.mustache" file form somewhere into tempates folder and I don't familiar with that ![]()
I copy some template files to my bin folder and then use swagger this way:
https://petstore.swagger.io/?url=http://localhost:888/root/wrapper/Swagger/mORMotClient.json.txtI saw in other rest service swagger, there are authentication button in the top of page. but for your sample project this button not exists!
How can I enable this option?
Thank you. I will try
I have another question.
Is it possible to create interface based service for authentication and use it in client side?
something like this:
type
IAuthentication = interface(IInvokable)
['{C92DCBEA-C680-40BD-8D9C-3E6F2ED9C9CF}']
procedure GetToken...;
procedure RefershToken...;
procedure IsTokenValid...;
...
end;
Yes. I got it. and now I can find secret.
many thanks!
Hi flydev.
there were a minor bug in your code and I fixed it.
changed function is this:
//function TRestServerAuthenticationJWT.Auth(Ctxt: TRestServerURIContext; const aUserName: RawUTF8): boolean; original
function TRestServerAuthenticationJWT.Auth(Ctxt: TRestServerURIContext): boolean; //chenged
I posted link in gist in my first post of topic.
if I underestand correctly "Create(SHA256(GUIDToRawUTF8(vGUID))" is secret. right?
JWTForUnauthenticatedRequest :=
TJwtHS256.
Create(SHA256(GUIDToRawUTF8(vGUID)), 0, [jrcIssuer, jrcSubject], [],
JWTDefaultTimeout);
Hi AB,
First of all, thank you for the great framework.
I am using the following code for JWT implementation:
https://gist.github.com/a-nouri/c61aef8 … f413b4538f
The code works, and I can retrieve the JWT JSON using the Delphi REST debugger (at http://localhost:8282/root/Auth?UserName=User&Password=synopse):
{
"result": "302102+5B8F237C0D720FD66C3230C054AB161362E8E0FC12136AC3AE8196765B6C2779",
"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXNzaW9ua2V5IjoiMzAyMTAyKzVCOEYyMzdDMEQ3MjBGRDY2QzMyMzBDMDU0QUIxNjEzNjJFOEUwRkMxMjEzNkFDM0FFODE5Njc2NUI2QzI3NzkiLCJpc3MiOiJVc2VyIiwic3ViIjoiand0LmFjY2VzcyIsImV4cCI6MTc1OTY2MjE1MX0.iUQmvtUov2YvB02UnJQkq0RXZNzN0AJzAcUCC4E5kBo"
}However, when I try to validate it on jwt.io, it requires the secret key.
I can't find a way to retrieve the secret, but when debugging the Create method, I can see this value:
893ee7b5d45733a3bb3f8907a46233a3a510f05533de8d50ac10edbc7653f2f8Thanks for your help!
I have huge project implemented by delphi vcl with 600 forms.
I use madexcept to catch and show unhandeded exceptions.
if mormot can handle this. I mean if there is onException Event handler or somthing like this. I can replace it with mormot.
Myabe OnBeforeException event can help.
I also show call stack to end user when exception is unhandeled:
https://gist.github.com/a-nouri/8ddfe5d … 8bdf28ae69
show_error function shows error in form to end user. and then sent to my website and I save unhandedled exceptions in table in web site by php.
Very useful. Thank you so much.
I tried
TAppLog.Family.StackTraceUse := stOnlyManual;
and
TAppLog.Family.LevelStackTrace := [];
with not success!
Is there a way to set TSynLog that don't capture exceptions?
After upgrading to the new version I encountered another problem. madexcept stopped working and to solve the issue I had to use the following option:
TAppLog.Family.Level := [sllInfo, sllWarning]
instead of
TAppLog.Family.Level := LOG_VERBOSE
I actually used mormot logging feature in a Windows desktop project.
Solved with this commit.
Thank you so much
Yes.
type
TClient = record
ConnectionId: THttpServerConnectionID;
ComputerName: string;
end;
TClients = array of TClient;
TInt64DynArray = array of Int64;
FClients := TSynDictionary.Create(TypeInfo(TInt64DynArray), TypeInfo(TClients));Hi AB, many thanks to great framework.
I have
FClients: TSynDictionary;
TSynDictionary.SaveToJson generate below json :
{1:{"ConnectionId":1,"ComputerName":"Test"},2:{"ConnectionId":2,"ComputerName":"Comp"}}
which is not valid json.
how can I remove "{1:","{2:", ... from Result.
TThread.Queue Solved the issue!
EchoFrame method:
procedure TForm2.EchoFrame(Sender: TWebSocketProcess; const Frame: WebSocketFrame);
begin
case Frame.opcode of
focContinuation:
begin
TThread.Synchronize(nil, procedure
begin
Memo1.Lines.Add('connected');
end);
end;
end;
end;I think there is issue in somewhere in mormot.
When lProto.OnIncomingFrame assigned before socket upgrade this function takes 5 seconds to finish
procedure TWebSocketProcess.WaitThreadStarted;
var
endtix: Int64;
begin
endtix := GetTickCount64 + 5000;
repeat
SleepHiRes(0);
until fProcessEnded or
(fState <> wpsCreate) or
(GetTickCount64 > endtix);
end;
Is this bug or abnormal behaviour?
I accidentally changed the position of a line and the problem was solved. But why should this happen?
var
ClientWS : THttpClientWebSockets;
lProto : TWebSocketProtocolEcho;
begin
lProto := TWebSocketProtocolEcho.Create('meow','');
ClientWS := THttpClientWebSockets.Create;
ClientWS.Open('127.0.0.1', '12346');
ClientWS.WebSocketsUpgrade('', '', false, [], lProto, '');
lProto.OnIncomingFrame := EchoFrame; //this line moved hereWhy you don't share it in github. It can help mormot community and make it popular farmework.
I created TWebSocketServer server and TWebSocketProtocolChat. When I connect it with JS it is fast.
But when I connect with below code it takes 5 second to upgrade.
var
ClientWS : THttpClientWebSockets;
lProto : TWebSocketProtocolEcho;
begin
lProto := TWebSocketProtocolEcho.Create('meow','');
lProto.OnIncomingFrame := EchoFrame;
ClientWS := THttpClientWebSockets.Create;
ClientWS.Open('127.0.0.1', '8383');
ClientWS.WebSocketsUpgrade('', '', false, [], lProto, '');Yes. Solved. thanks alot
for creating multiple file I am using multiple classes:
TDbLog = class(TSynLog); // Log for database operations
TApiLog = class(TSynLog); // Log for API calls
Is this correct ?
I can't figure out this code work properly. when I replace myLog1 with TSynLog it works.
var
myLog1,myLog2: TSynLog;
begin
myLog1 := TSynLog.Create();
myLog1.Family.Level := LOG_VERBOSE;
myLog1.Family.DestinationPath := 'D:\SynLog1\';
myLog1.Family.FileExistsAction := acAppend;
myLog1.Log(sllInfo, 'Logging initialized.');
end;I am using FK allways but for show message to end user I use information schema table to find all fk's and then create my own message. It is so easy and it is one function for checking refrential integrity.
this is for mysql:
select REFERENCED_TABLE_NAME,CONSTRAINT_NAME,group_concat(COLUMN_NAME) COLUMN_NAME,
group_concat(REFERENCED_COLUMN_NAME) REFERENCED_COLUMN_NAME,
group_concat(COLUMN_NAME,'=',REFERENCED_COLUMN_NAME) col_ref
from INFORMATION_SCHEMA.KEY_COLUMN_USAGE
where TABLE_SCHEMA = :TABLE_SCHEMA
and TABLE_NAME = :TABLE_NAME
and referenced_column_name is not NULL
group by REFERENCED_TABLE_NAME,CONSTRAINT_NAMEparsing error message can not create understandable message. when user want to delete product number 1 I show this message:
product 1 used in invoice 123 and can not deleted.
invoice 123 is first invoice that used product number 1.