From a03b07b99dc46d6026874d3ce984c6c858ebf0a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Sat, 19 Apr 2025 17:03:59 -0300 Subject: [PATCH 01/12] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e3ff83b..3ff95c9 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@
-## ▶️ Vídeos de criação do projeto no Youtube +## ▶️ Vídeos da criação do projeto no Youtube - [Delphi Web #01 - Apresentação e início da criação do back-end](https://www.youtube.com/watch?v=qrFUxkFV0vQ&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=1) - [Delphi Web #02 - Endpoint | Verbo Get | Get e List | Consultando dados na API](https://www.youtube.com/watch?v=j5RoRTDNx3o&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=2) - [Delphi Web #03 - Inserindo dados na API Rest | Verbos HTTP Post, Put e Delete | Postman](https://www.youtube.com/watch?v=dt23lMZmLpw&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=3) @@ -44,6 +44,7 @@ - [Delphi Web #13 - Post e Put com dados do formulário popup](https://www.youtube.com/watch?v=CpeKncJJ1wo&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=13) - [Delphi Web #14 - Ajustes no template Bootstrap](https://www.youtube.com/watch?v=xoStVXAkKGc&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=14) - [Delphi Web #15 - FNC Data Grid - Exibindo dados](https://www.youtube.com/watch?v=lKvuE54d4X0&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=15) +- [Delphi Web #16 - Desenvolvendo Web de forma RAD - Web Form Designer](https://www.youtube.com/watch?v=z5h350NwFso&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=16)
From 7f73013c3b2057ae861e71f2293003254db701d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Sat, 19 Apr 2025 17:20:13 -0300 Subject: [PATCH 02/12] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3ff95c9..4c7b4b5 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ - [Delphi Web #14 - Ajustes no template Bootstrap](https://www.youtube.com/watch?v=xoStVXAkKGc&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=14) - [Delphi Web #15 - FNC Data Grid - Exibindo dados](https://www.youtube.com/watch?v=lKvuE54d4X0&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=15) - [Delphi Web #16 - Desenvolvendo Web de forma RAD - Web Form Designer](https://www.youtube.com/watch?v=z5h350NwFso&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=16) + - [Repositório do projeto de demonstração do Web Form Designer](https://github.com/Code4Delphi/Web-Form-Designer)
From 0f06a2948f1352ea51c5425649255bc96cd1ff0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Fri, 25 Apr 2025 00:29:10 -0300 Subject: [PATCH 03/12] aula-17-parte-01-02 --- DelphiWebGroup.groupproj | 18 +- ServerAuth/ServerAuth.dpr | 16 + ServerAuth/ServerAuth.dproj | 1120 +++++++++++++++++++++++ ServerAuth/ServerAuth.res | Bin 0 -> 154804 bytes ServerAuth/Src/ServerAuth.Main.View.dfm | 49 + ServerAuth/Src/ServerAuth.Main.View.pas | 82 ++ ServerAuth/Src/ServerAuth.XData.DM.dfm | 16 + ServerAuth/Src/ServerAuth.XData.DM.pas | 28 + 8 files changed, 1326 insertions(+), 3 deletions(-) create mode 100644 ServerAuth/ServerAuth.dpr create mode 100644 ServerAuth/ServerAuth.dproj create mode 100644 ServerAuth/ServerAuth.res create mode 100644 ServerAuth/Src/ServerAuth.Main.View.dfm create mode 100644 ServerAuth/Src/ServerAuth.Main.View.pas create mode 100644 ServerAuth/Src/ServerAuth.XData.DM.dfm create mode 100644 ServerAuth/Src/ServerAuth.XData.DM.pas diff --git a/DelphiWebGroup.groupproj b/DelphiWebGroup.groupproj index 5f167e3..a918b6a 100644 --- a/DelphiWebGroup.groupproj +++ b/DelphiWebGroup.groupproj @@ -9,6 +9,9 @@ + + + Default.Personality.12 @@ -35,14 +38,23 @@ + + + + + + + + + - + - + - + diff --git a/ServerAuth/ServerAuth.dpr b/ServerAuth/ServerAuth.dpr new file mode 100644 index 0000000..1e4f5d8 --- /dev/null +++ b/ServerAuth/ServerAuth.dpr @@ -0,0 +1,16 @@ +program ServerAuth; + +uses + Vcl.Forms, + ServerAuth.Main.View in 'Src\ServerAuth.Main.View.pas' {ServerAuthMainView}, + ServerAuth.XData.DM in 'Src\ServerAuth.XData.DM.pas' {ServerAuthXDataDM: TDataModule}; + +{$R *.res} + +begin + Application.Initialize; + Application.MainFormOnTaskbar := True; + Application.CreateForm(TServerAuthXDataDM, ServerAuthXDataDM); + Application.CreateForm(TServerAuthMainView, ServerAuthMainView); + Application.Run; +end. diff --git a/ServerAuth/ServerAuth.dproj b/ServerAuth/ServerAuth.dproj new file mode 100644 index 0000000..f415e3d --- /dev/null +++ b/ServerAuth/ServerAuth.dproj @@ -0,0 +1,1120 @@ + + + {79CF7CA6-4D5B-496E-A39D-A4381CDA2C38} + 20.2 + VCL + True + Debug + Win32 + ServerAuth + 3 + Application + ServerAuth.dpr + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png + ServerAuth + + + vclwinx;DataSnapServer;ACBr_BPeDabpeESCPOS;ACBr_TCP;ACBr_ONE;ACBr_NFCom;fs29;fmx;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;bsfd103Rio;ACBr_OpenSSL;appanalytics;IndyProtocols;vclx;Skia.Package.RTL;aurelius;dbxcds;vcledge;FMX_FlexCel_Components;FmxTeeUI;VCLTMSFNCChartPkgDXE15;ACBr_BoletoRL;FlexCel_Pdf;DBXFirebirdDriver;ACBr_CTeDacteFR;FMXTMSFNCChartPkgDXE15;ACBr_NFCeECFVirtual;ACBr_DCeDACERL;FireDACSqliteDriver;DbxClientDriver;soapmidas;ACBr_NF3eDANF3eESCPOS;TeeUI;ACBr_PagFor;dbexpress;ACBr_Reinf;ACBr_NFSeXDanfseFPDF;inet;ACBr_BoletoFPDF;vcltouch;FMX_FlexCel_Core;FireDACDBXDriver;ACBr_NF3eDANF3eRL;fmxdae;tmsbcl;VCL_FlexCel_Core;CustomIPTransport;FireDACMSSQLDriver;C4DDateEdit;ZCore;ACBr_NFSeX;ZParseSql;C4DWizard;ACBr_NFe;frxPDF29;ACBr_CTeDacteRL;C4DMaskEdit;IndySystem;ACBr_Diversos;ACBr_GNREGuiaRL;BossExperts;frxe29;ZipMasterR;ACBr_NFSeXDanfseRL;ACBr_SAT;ACBr_CIOT;VirtualTreesR;ACBr_TEFD;fsDB29;VDOPrint;vclFireDAC;ACBr_SPED;ACBr_CTe;ACBr_SATWS;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;DelphiAIDeveloper;ACBr_SEF2;ACBr_LCDPR;ACBr_SATExtratoFPDF;FlexCel_Render;ZComponent;bindcompdbx;rtl;FireDACMySQLDriver;ACBr_NFeDanfeFR;ACBr_DCe;VCL_FlexCel_Components;frce;ACBr_BPe;DBXSqliteDriver;ACBr_Sintegra;DBXSybaseASEDriver;TMSWEBCorePkgDXE15;ACBr_Serial;ACBr_Comum;ACBr_MDFe;ACBr_NFeDanfeESCPOS;vclimg;DataSnapFireDAC;inetdbxpress;FireDAC;xmlrtl;dsnap;xdata;FireDACDb2Driver;DBXOracleDriver;DBXInformixDriver;ACBr_SATECFVirtual;fmxobj;bindcompvclsmp;DataSnapNativeClient;frx29;ACBr_SATExtratoFR;DatasnapConnectorsFreePascal;FMXTMSFNCUIPackPkgDXE15;frxIntIOIndy29;ACBr_NF3e;ACBr_PAF;ACBr_OpenDelivery;ACBr_NFeDanfeFPDF;ACBr_MDFeDamdfeFR;TMSFNCCorePkgDXE15;ACBr_SPEDImportar;FMXTMSFNCCorePkgDXE15;emshosting;sparkle;MSNPopUp_D104;frxDB29;FireDACCommonDriver;ACBr_ADRCST;ACBr_MTER;IndyIPClient;frxHTML29;bindcompvclwinx;ACBr_Convenio115;emsedge;bindcompfmx;inetdb;FireDACASADriver;ACBr_LFD;Tee;vclactnband;fmxFireDAC;FireDACInfxDriver;DBXMySQLDriver;fsADO29;VclSmp;ACBr_Ponto;DataSnapCommon;fmxase;DBXOdbcDriver;dbrtl;FireDACOracleDriver;Skia.Package.FMX;ACBre_Social;TeeDB;FlexCel_XlsAdapter;FireDACMSAccDriver;frxcs29;DataSnapIndy10ServerTransport;DataSnapConnectors;ACBr_ANe;ACBr_SATExtratoRL;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;ACBR_DeSTDA;PngComponentsD;ACBr_GNRE;ACBr_EDI;FireDACTDataDriver;Skia.Package.VCL;VCLTMSFNCUIPackPkgDXE15;vcldb;ACBr_Integrador;ACBr_PIXCD;FlexCel_Core;ACBr_BoletoFR;bindcomp;inetstn;IndyCore;RESTBackendComponents;ZPlain;frxIntIO29;FireDACADSDriver;RESTComponents;ACBr_NFSeXDANFSeFR;IndyIPServer;vcl;dsnapxml;adortl;dsnapcon;DataSnapClient;DataSnapProviderClient;ACBr_MDFeDamdfeRL;frxADO29;DBXDb2Driver;ACBr_Boleto;emsclientfiredac;FireDACPgDriver;FireDACDSDriver;ACBr_BlocoX;ACBrBaaS;tethering;ACBr_SATExtratoESCPOS;ZDbc;bindcompvcl;ACBr_GTIN;CloudService;DBXSybaseASADriver;ACBr_OFX;ACBr_PAFNFCe;FMXTee;ACBr_DebitoAutomatico;ACBr_NFeDanfeRL;TMSWEBCorePkgLibDXE15;DSPack_DXE2;ACBr_GNREGuiaFR;VCLTMSFNCCorePkgDXE15;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + $(BDS)\bin\default_app.manifest + + + vclwinx;DataSnapServer;fmx;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;appanalytics;IndyProtocols;vclx;dbxcds;vcledge;FMX_FlexCel_Components;FmxTeeUI;VCLTMSFNCChartPkgDXE15;FlexCel_Pdf;DBXFirebirdDriver;FMXTMSFNCChartPkgDXE15;FireDACSqliteDriver;DbxClientDriver;soapmidas;TeeUI;dbexpress;inet;vcltouch;FMX_FlexCel_Core;FireDACDBXDriver;fmxdae;VCL_FlexCel_Core;CustomIPTransport;FireDACMSSQLDriver;ZCore;ZParseSql;IndySystem;ZipMasterR;VirtualTreesR;vclFireDAC;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;FlexCel_Render;ZComponent;bindcompdbx;rtl;FireDACMySQLDriver;VCL_FlexCel_Components;DBXSqliteDriver;DBXSybaseASEDriver;vclimg;DataSnapFireDAC;inetdbxpress;FireDAC;xmlrtl;dsnap;FireDACDb2Driver;DBXOracleDriver;DBXInformixDriver;fmxobj;bindcompvclsmp;DataSnapNativeClient;DatasnapConnectorsFreePascal;FMXTMSFNCUIPackPkgDXE15;TMSFNCCorePkgDXE15;FMXTMSFNCCorePkgDXE15;emshosting;FireDACCommonDriver;IndyIPClient;bindcompvclwinx;emsedge;bindcompfmx;inetdb;FireDACASADriver;Tee;vclactnband;fmxFireDAC;FireDACInfxDriver;DBXMySQLDriver;VclSmp;DataSnapCommon;fmxase;DBXOdbcDriver;dbrtl;FireDACOracleDriver;TeeDB;FlexCel_XlsAdapter;FireDACMSAccDriver;DataSnapIndy10ServerTransport;DataSnapConnectors;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;PngComponentsD;FireDACTDataDriver;Skia.Package.VCL;VCLTMSFNCUIPackPkgDXE15;vcldb;FlexCel_Core;bindcomp;inetstn;IndyCore;RESTBackendComponents;ZPlain;FireDACADSDriver;RESTComponents;IndyIPServer;vcl;dsnapxml;adortl;dsnapcon;DataSnapClient;DataSnapProviderClient;DBXDb2Driver;emsclientfiredac;FireDACPgDriver;FireDACDSDriver;tethering;ZDbc;bindcompvcl;CloudService;DBXSybaseASADriver;FMXTee;DSPack_DXE2;VCLTMSFNCCorePkgDXE15;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + $(BDS)\bin\default_app.manifest + + + DEBUG;$(DCC_Define) + true + false + true + true + true + true + true + + + false + PerMonitorV2 + true + 1033 + + + PerMonitorV2 + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + PerMonitorV2 + + + PerMonitorV2 + + + + MainSource + + +
ServerAuthMainView
+ dfm +
+ +
ServerAuthXDataDM
+ dfm + TDataModule +
+ + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + +
+ + Delphi.Personality.12 + Application + + + + ServerAuth.dpr + + + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + + + ServerAuth.exe + true + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v21 + 1 + + + res\drawable-anydpi-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values-v31 + 1 + + + res\values-v31 + 1 + + + + + res\drawable-anydpi-v26 + 1 + + + res\drawable-anydpi-v26 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v33 + 1 + + + res\drawable-anydpi-v33 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-night-v21 + 1 + + + res\values-night-v21 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable-anydpi-v24 + 1 + + + res\drawable-anydpi-v24 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-night-anydpi-v21 + 1 + + + res\drawable-night-anydpi-v21 + 1 + + + + + res\drawable-anydpi-v31 + 1 + + + res\drawable-anydpi-v31 + 1 + + + + + res\drawable-night-anydpi-v31 + 1 + + + res\drawable-night-anydpi-v31 + 1 + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + 0 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + ..\ + 1 + + + + + Contents + 1 + + + Contents + 1 + + + Contents + 1 + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + ..\ + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen + 64 + + + ..\$(PROJECTNAME).launchscreen + 64 + + + + + 1 + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + + + + + + + + + + + + + True + True + + + 12 + + + + +
diff --git a/ServerAuth/ServerAuth.res b/ServerAuth/ServerAuth.res new file mode 100644 index 0000000000000000000000000000000000000000..089da624e4893af3f6950832e8b6025c01e967c8 GIT binary patch literal 154804 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 V-1UpNKB6-|>4QJa{U|pu{Xc=Q%OL;& literal 0 HcmV?d00001 diff --git a/ServerAuth/Src/ServerAuth.Main.View.dfm b/ServerAuth/Src/ServerAuth.Main.View.dfm new file mode 100644 index 0000000..bf7de8e --- /dev/null +++ b/ServerAuth/Src/ServerAuth.Main.View.dfm @@ -0,0 +1,49 @@ +object ServerAuthMainView: TServerAuthMainView + Left = 0 + Top = 0 + Caption = 'ServerAuthMainView' + ClientHeight = 304 + ClientWidth = 577 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Segoe UI' + Font.Style = [] + OnCreate = FormCreate + TextHeight = 15 + object btnStart: TButton + Left = 24 + Top = 16 + Width = 75 + Height = 25 + Caption = 'Start' + TabOrder = 0 + OnClick = btnStartClick + end + object btnStop: TButton + Left = 105 + Top = 16 + Width = 75 + Height = 25 + Caption = 'Stop' + TabOrder = 1 + OnClick = btnStopClick + end + object mmLog: TMemo + Left = 24 + Top = 64 + Width = 505 + Height = 185 + ScrollBars = ssVertical + TabOrder = 2 + end + object btnSwaggerDocumentacao: TButton + Left = 278 + Top = 16 + Width = 193 + Height = 25 + Caption = 'Abrir documenta'#231#227'o Swagger' + TabOrder = 3 + end +end diff --git a/ServerAuth/Src/ServerAuth.Main.View.pas b/ServerAuth/Src/ServerAuth.Main.View.pas new file mode 100644 index 0000000..ff0e141 --- /dev/null +++ b/ServerAuth/Src/ServerAuth.Main.View.pas @@ -0,0 +1,82 @@ +unit ServerAuth.Main.View; + +interface + +uses + Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, + Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, + ServerAuth.XData.DM; + +type + TServerAuthMainView = class(TForm) + btnStart: TButton; + btnStop: TButton; + mmLog: TMemo; + btnSwaggerDocumentacao: TButton; + procedure FormCreate(Sender: TObject); + procedure btnStartClick(Sender: TObject); + procedure btnStopClick(Sender: TObject); + private + procedure AtualizarTela; + procedure btnSwaggerDocumentacaoClick(Sender: TObject); + function GetServerBaseUrl: string; + { Private declarations } + public + { Public declarations } + end; + +var + ServerAuthMainView: TServerAuthMainView; + +implementation + +{$R *.dfm} + +procedure TServerAuthMainView.FormCreate(Sender: TObject); +begin + ReportMemoryLeaksOnShutdown := True; + Self.AtualizarTela; +end; + +function TServerAuthMainView.GetServerBaseUrl: string; +const + HTTP = 'http://+'; + HTTP_LOCALHOST = 'http://localhost'; +begin + Result := ServerAuthXDataDM.XDataServer1.BaseUrl.Replace(HTTP, HTTP_LOCALHOST, [rfIgnoreCase]); +end; + +procedure TServerAuthMainView.AtualizarTela; +begin + btnStop.Enabled := ServerAuthXDataDM.SparkleHttpSysDispatcher1.Active; + btnStart.Enabled := not btnStop.Enabled; + + if ServerAuthXDataDM.SparkleHttpSysDispatcher1.Active then + begin + mmLog.Lines.Add('Servidor iniciado em:'); + mmLog.Lines.Add(Self.GetServerBaseUrl); + mmLog.Lines.Add(Self.GetServerBaseUrl + '/ClientesService/'); + end + else + mmLog.Lines.Add('Servidor parado'); +end; + +procedure TServerAuthMainView.btnStartClick(Sender: TObject); +begin + ServerAuthXDataDM.SparkleHttpSysDispatcher1.Start; + Self.AtualizarTela; +end; + +procedure TServerAuthMainView.btnStopClick(Sender: TObject); +begin + ServerAuthXDataDM.SparkleHttpSysDispatcher1.Stop; + Self.AtualizarTela; +end; + +procedure TServerAuthMainView.btnSwaggerDocumentacaoClick(Sender: TObject); +begin + //ShellExecute(Handle, 'open', PChar(Self.GetServerBaseUrl + '/swaggerui'), nil, nil, SW_SHOWNORMAL); +end; + + +end. diff --git a/ServerAuth/Src/ServerAuth.XData.DM.dfm b/ServerAuth/Src/ServerAuth.XData.DM.dfm new file mode 100644 index 0000000..63dbfc4 --- /dev/null +++ b/ServerAuth/Src/ServerAuth.XData.DM.dfm @@ -0,0 +1,16 @@ +object ServerAuthXDataDM: TServerAuthXDataDM + Height = 480 + Width = 640 + object SparkleHttpSysDispatcher1: TSparkleHttpSysDispatcher + Active = True + Left = 136 + Top = 80 + end + object XDataServer1: TXDataServer + BaseUrl = 'http://+:2001/tms/auth' + Dispatcher = SparkleHttpSysDispatcher1 + EntitySetPermissions = <> + Left = 136 + Top = 144 + end +end diff --git a/ServerAuth/Src/ServerAuth.XData.DM.pas b/ServerAuth/Src/ServerAuth.XData.DM.pas new file mode 100644 index 0000000..6efb1b8 --- /dev/null +++ b/ServerAuth/Src/ServerAuth.XData.DM.pas @@ -0,0 +1,28 @@ +unit ServerAuth.XData.DM; + +interface + +uses + System.SysUtils, System.Classes, Sparkle.HttpServer.Module, Sparkle.HttpServer.Context, XData.Server.Module, + Sparkle.Comp.Server, XData.Comp.Server, Sparkle.Comp.HttpSysDispatcher; + +type + TServerAuthXDataDM = class(TDataModule) + SparkleHttpSysDispatcher1: TSparkleHttpSysDispatcher; + XDataServer1: TXDataServer; + private + { Private declarations } + public + { Public declarations } + end; + +var + ServerAuthXDataDM: TServerAuthXDataDM; + +implementation + +{%CLASSGROUP 'Vcl.Controls.TControl'} + +{$R *.dfm} + +end. From b25d3ebce6bc2c63d20227e7a572fbf96fc32df3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Fri, 25 Apr 2025 08:25:32 -0300 Subject: [PATCH 04/12] aula-17-parte03 --- ServerAuth/ServerAuth.dpr | 4 +- ServerAuth/ServerAuth.dproj | 2 + ServerAuth/Src/LoginService/LoginService.pas | 21 ++++++++ .../LoginServiceImplementation.pas | 52 +++++++++++++++++++ ServerAuth/Src/ServerAuth.Main.View.pas | 2 +- 5 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 ServerAuth/Src/LoginService/LoginService.pas create mode 100644 ServerAuth/Src/LoginService/LoginServiceImplementation.pas diff --git a/ServerAuth/ServerAuth.dpr b/ServerAuth/ServerAuth.dpr index 1e4f5d8..0da9021 100644 --- a/ServerAuth/ServerAuth.dpr +++ b/ServerAuth/ServerAuth.dpr @@ -3,7 +3,9 @@ program ServerAuth; uses Vcl.Forms, ServerAuth.Main.View in 'Src\ServerAuth.Main.View.pas' {ServerAuthMainView}, - ServerAuth.XData.DM in 'Src\ServerAuth.XData.DM.pas' {ServerAuthXDataDM: TDataModule}; + ServerAuth.XData.DM in 'Src\ServerAuth.XData.DM.pas' {ServerAuthXDataDM: TDataModule}, + LoginService in 'Src\LoginService\LoginService.pas', + LoginServiceImplementation in 'Src\LoginService\LoginServiceImplementation.pas'; {$R *.res} diff --git a/ServerAuth/ServerAuth.dproj b/ServerAuth/ServerAuth.dproj index f415e3d..a85186d 100644 --- a/ServerAuth/ServerAuth.dproj +++ b/ServerAuth/ServerAuth.dproj @@ -134,6 +134,8 @@ dfm TDataModule + + Base diff --git a/ServerAuth/Src/LoginService/LoginService.pas b/ServerAuth/Src/LoginService/LoginService.pas new file mode 100644 index 0000000..997a2a0 --- /dev/null +++ b/ServerAuth/Src/LoginService/LoginService.pas @@ -0,0 +1,21 @@ +unit LoginService; + +interface + +uses + XData.Service.Common; + +type + [ServiceContract] + ILoginService = interface(IInvokable) + ['{B9EC981F-FFC0-4171-8E46-8CAA2D301B21}'] + [HttpPost, Route('')] + function Login(const User, Password: string): string; + end; + +implementation + +initialization + RegisterServiceType(TypeInfo(ILoginService)); + +end. diff --git a/ServerAuth/Src/LoginService/LoginServiceImplementation.pas b/ServerAuth/Src/LoginService/LoginServiceImplementation.pas new file mode 100644 index 0000000..98884e9 --- /dev/null +++ b/ServerAuth/Src/LoginService/LoginServiceImplementation.pas @@ -0,0 +1,52 @@ +unit LoginServiceImplementation; + +interface + +uses + System.SysUtils, + XData.Server.Module, + XData.Service.Common, + LoginService, + Bcl.JOSE.Core.Builder, + Bcl.Jose.Core.JWA, + Bcl.JOSE.Core.JWT, + Bcl.JOSE.Core.JWK; + +type + [ServiceImplementation] + TLoginService = class(TInterfacedObject, ILoginService) + private + function Login(const User, Password: string): string; + end; + +implementation + +function TLoginService.Login(const User, Password: string): string; +var + JWT: TJWT; +begin + if (User <> 'admin') or (Password <> 'admin') then + raise Exception.Create('Usurio ou senha invlidos'); + + JWT := TJWT.Create; + try + //CLAIMS RESERVADAS + JWT.Claims.Issuer := 'Code4Delphi'; + JWT.Claims.Subject := '123'; + JWT.Claims.Expiration := Now + 100; + + //MINHAS CLAIMS + JWT.Claims.SetClaimOfType('usuario', User); + JWT.Claims.SetClaimOfType('admin', True); + JWT.Claims.SetClaimOfType('teste', 'asdf'); + + Result := TJOSE.SHA256CompactToken('sua-chave-secreta', JWT); + finally + JWT.Free; + end; +end; + +initialization + RegisterServiceType(TLoginService); + +end. diff --git a/ServerAuth/Src/ServerAuth.Main.View.pas b/ServerAuth/Src/ServerAuth.Main.View.pas index ff0e141..aba857c 100644 --- a/ServerAuth/Src/ServerAuth.Main.View.pas +++ b/ServerAuth/Src/ServerAuth.Main.View.pas @@ -55,7 +55,7 @@ procedure TServerAuthMainView.AtualizarTela; begin mmLog.Lines.Add('Servidor iniciado em:'); mmLog.Lines.Add(Self.GetServerBaseUrl); - mmLog.Lines.Add(Self.GetServerBaseUrl + '/ClientesService/'); + mmLog.Lines.Add(Self.GetServerBaseUrl + '/LoginService/'); end else mmLog.Lines.Add('Servidor parado'); From ede05c1b2a02a19e16c3c39593fb6d9c37ebd198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Fri, 25 Apr 2025 17:46:24 -0300 Subject: [PATCH 05/12] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 4c7b4b5..9c3f0ef 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,8 @@ - [Delphi Web #15 - FNC Data Grid - Exibindo dados](https://www.youtube.com/watch?v=lKvuE54d4X0&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=15) - [Delphi Web #16 - Desenvolvendo Web de forma RAD - Web Form Designer](https://www.youtube.com/watch?v=z5h350NwFso&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=16) - [Repositório do projeto de demonstração do Web Form Designer](https://github.com/Code4Delphi/Web-Form-Designer) + - [Delphi Web #17 - O que é e como usar JWT no Delphi](https://www.youtube.com/watch?v=uYTB_q-C0MY&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=17) + - [Postagem no blog com tudo que você precisa saber sobre JWT no Delphi](https://code4delphi.com.br/blog/jwt-no-delphi-o-que-e-e-como-utilizar/)
From 33974989d3266c32a5a6393a3161e48b76f6b996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Thu, 1 May 2025 00:03:47 -0300 Subject: [PATCH 06/12] bk/inicio-video-18 --- ClientWeb/Src/Main.View.dfm | 1 + ClientWeb/Src/Main.View.pas | 29 ++++++++++++++++++++++--- Server/Src/XData.DM.pas | 4 +++- ServerAuth/Src/ServerAuth.Main.View.dfm | 10 +++++---- ServerAuth/Src/ServerAuth.Main.View.pas | 20 +++++++++++------ ServerAuth/Src/ServerAuth.XData.DM.dfm | 3 ++- 6 files changed, 51 insertions(+), 16 deletions(-) diff --git a/ClientWeb/Src/Main.View.dfm b/ClientWeb/Src/Main.View.dfm index 13c3361..3f92b90 100644 --- a/ClientWeb/Src/Main.View.dfm +++ b/ClientWeb/Src/Main.View.dfm @@ -175,6 +175,7 @@ object MainView: TMainView HeightPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000 OnClick = btnDeleteClick + ExplicitLeft = 729 end end object TMSFNCDataGrid1: TTMSFNCDataGrid diff --git a/ClientWeb/Src/Main.View.pas b/ClientWeb/Src/Main.View.pas index 1a20b5a..5c4b934 100644 --- a/ClientWeb/Src/Main.View.pas +++ b/ClientWeb/Src/Main.View.pas @@ -21,9 +21,20 @@ interface XData.Web.Connection, WEBLib.DB, JS, - Clientes.Cadastrar.View, VCL.TMSFNCTypes, VCL.TMSFNCUtils, VCL.TMSFNCGraphics, VCL.TMSFNCGraphicsTypes, System.Rtti, - VCL.TMSFNCDataGridCell, VCL.TMSFNCDataGridData, VCL.TMSFNCDataGridBase, VCL.TMSFNCDataGridCore, - VCL.TMSFNCDataGridRenderer, VCL.TMSFNCCustomControl, VCL.TMSFNCDataGrid, VCL.TMSFNCCustomComponent, + Clientes.Cadastrar.View, + VCL.TMSFNCTypes, + VCL.TMSFNCUtils, + VCL.TMSFNCGraphics, + VCL.TMSFNCGraphicsTypes, + System.Rtti, + VCL.TMSFNCDataGridCell, + VCL.TMSFNCDataGridData, + VCL.TMSFNCDataGridBase, + VCL.TMSFNCDataGridCore, + VCL.TMSFNCDataGridRenderer, + VCL.TMSFNCCustomControl, + VCL.TMSFNCDataGrid, + VCL.TMSFNCCustomComponent, VCL.TMSFNCDataGridDatabaseAdapter; type @@ -142,6 +153,9 @@ procedure TMainView.btnGetNomeClick(Sender: TObject); Exit; end; + if not XDataWebConnection1.Connected then + XDataWebConnection1.Open; + LResponse := TAwait.Exec( XDataWebClient1.RawInvokeAsync('IClientesService.GetNome', [StrToIntDef(edtCodigo.Text, 0)])); @@ -159,6 +173,9 @@ procedure TMainView.btnGetClick(Sender: TObject); Exit; end; + if not XDataWebConnection1.Connected then + XDataWebConnection1.Open; + LResponse := TAwait.Exec( XDataWebClient1.RawInvokeAsync('IClientesService.Get', [StrToIntDef(edtCodigo.Text, 0)])); @@ -180,6 +197,9 @@ procedure TMainView.btnListarClick(Sender: TObject); var LResponse: TXDataClientResponse; begin + if not XDataWebConnection1.Connected then + XDataWebConnection1.Open; + LResponse := TAwait.Exec( XDataWebClient1.RawInvokeAsync('IClientesService.List', [])); @@ -200,6 +220,9 @@ procedure TMainView.btnDeleteClick(Sender: TObject); var LResponse: TXDataClientResponse; begin + if not XDataWebConnection1.Connected then + XDataWebConnection1.Open; + if await(TModalResult, MessageDlgAsync('Confirma realmente deletar o registro?', mtConfirmation, [mbYes, mbNo])) <> mrYes then Exit; diff --git a/Server/Src/XData.DM.pas b/Server/Src/XData.DM.pas index fa5d414..b8b03df 100644 --- a/Server/Src/XData.DM.pas +++ b/Server/Src/XData.DM.pas @@ -10,7 +10,9 @@ interface XData.Server.Module, Sparkle.Comp.Server, Sparkle.Comp.HttpSysDispatcher, - XData.Comp.Server, Sparkle.Comp.CompressMiddleware, Sparkle.Comp.CorsMiddleware; + XData.Comp.Server, + Sparkle.Comp.CompressMiddleware, + Sparkle.Comp.CorsMiddleware; type TXDataDM = class(TDataModule) diff --git a/ServerAuth/Src/ServerAuth.Main.View.dfm b/ServerAuth/Src/ServerAuth.Main.View.dfm index bf7de8e..12a1358 100644 --- a/ServerAuth/Src/ServerAuth.Main.View.dfm +++ b/ServerAuth/Src/ServerAuth.Main.View.dfm @@ -2,14 +2,15 @@ object ServerAuthMainView: TServerAuthMainView Left = 0 Top = 0 Caption = 'ServerAuthMainView' - ClientHeight = 304 - ClientWidth = 577 + ClientHeight = 343 + ClientWidth = 545 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -12 Font.Name = 'Segoe UI' Font.Style = [] + Position = poScreenCenter OnCreate = FormCreate TextHeight = 15 object btnStart: TButton @@ -34,16 +35,17 @@ object ServerAuthMainView: TServerAuthMainView Left = 24 Top = 64 Width = 505 - Height = 185 + Height = 257 ScrollBars = ssVertical TabOrder = 2 end object btnSwaggerDocumentacao: TButton - Left = 278 + Left = 336 Top = 16 Width = 193 Height = 25 Caption = 'Abrir documenta'#231#227'o Swagger' TabOrder = 3 + OnClick = btnSwaggerDocumentacaoClick end end diff --git a/ServerAuth/Src/ServerAuth.Main.View.pas b/ServerAuth/Src/ServerAuth.Main.View.pas index aba857c..402098e 100644 --- a/ServerAuth/Src/ServerAuth.Main.View.pas +++ b/ServerAuth/Src/ServerAuth.Main.View.pas @@ -3,8 +3,17 @@ interface uses - Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, - Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, + Winapi.Windows, + Winapi.Messages, + System.SysUtils, + System.Variants, + System.Classes, + ShellAPI, + Vcl.Graphics, + Vcl.Controls, + Vcl.Forms, + Vcl.Dialogs, + Vcl.StdCtrls, ServerAuth.XData.DM; type @@ -16,13 +25,11 @@ TServerAuthMainView = class(TForm) procedure FormCreate(Sender: TObject); procedure btnStartClick(Sender: TObject); procedure btnStopClick(Sender: TObject); + procedure btnSwaggerDocumentacaoClick(Sender: TObject); private procedure AtualizarTela; - procedure btnSwaggerDocumentacaoClick(Sender: TObject); function GetServerBaseUrl: string; - { Private declarations } public - { Public declarations } end; var @@ -75,8 +82,7 @@ procedure TServerAuthMainView.btnStopClick(Sender: TObject); procedure TServerAuthMainView.btnSwaggerDocumentacaoClick(Sender: TObject); begin - //ShellExecute(Handle, 'open', PChar(Self.GetServerBaseUrl + '/swaggerui'), nil, nil, SW_SHOWNORMAL); + ShellExecute(Handle, 'open', PChar(Self.GetServerBaseUrl + '/swaggerui'), nil, nil, SW_SHOWNORMAL); end; - end. diff --git a/ServerAuth/Src/ServerAuth.XData.DM.dfm b/ServerAuth/Src/ServerAuth.XData.DM.dfm index 63dbfc4..35a04cf 100644 --- a/ServerAuth/Src/ServerAuth.XData.DM.dfm +++ b/ServerAuth/Src/ServerAuth.XData.DM.dfm @@ -2,7 +2,6 @@ object ServerAuthXDataDM: TServerAuthXDataDM Height = 480 Width = 640 object SparkleHttpSysDispatcher1: TSparkleHttpSysDispatcher - Active = True Left = 136 Top = 80 end @@ -10,6 +9,8 @@ object ServerAuthXDataDM: TServerAuthXDataDM BaseUrl = 'http://+:2001/tms/auth' Dispatcher = SparkleHttpSysDispatcher1 EntitySetPermissions = <> + SwaggerOptions.Enabled = True + SwaggerUIOptions.Enabled = True Left = 136 Top = 144 end From bf8473675d5242350fc5d141d8d1b27456e4f740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Thu, 1 May 2025 00:45:09 -0300 Subject: [PATCH 07/12] Update LoginServiceImplementation.pas --- ServerAuth/Src/LoginService/LoginServiceImplementation.pas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ServerAuth/Src/LoginService/LoginServiceImplementation.pas b/ServerAuth/Src/LoginService/LoginServiceImplementation.pas index 98884e9..e337d75 100644 --- a/ServerAuth/Src/LoginService/LoginServiceImplementation.pas +++ b/ServerAuth/Src/LoginService/LoginServiceImplementation.pas @@ -40,7 +40,7 @@ function TLoginService.Login(const User, Password: string): string; JWT.Claims.SetClaimOfType('admin', True); JWT.Claims.SetClaimOfType('teste', 'asdf'); - Result := TJOSE.SHA256CompactToken('sua-chave-secreta', JWT); + Result := TJOSE.SHA256CompactToken('sua-chave-secreta-1234567890-12345', JWT); finally JWT.Free; end; From 4901ffa2ad9d45e9955380f4d61e178117f78e39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Thu, 1 May 2025 00:50:42 -0300 Subject: [PATCH 08/12] aula18-parte01 --- Server/Src/XData.DM.dfm | 4 ++++ Server/Src/XData.DM.pas | 11 ++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Server/Src/XData.DM.dfm b/Server/Src/XData.DM.dfm index d27f8ac..716ddeb 100644 --- a/Server/Src/XData.DM.dfm +++ b/Server/Src/XData.DM.dfm @@ -13,6 +13,10 @@ object XDataDM: TXDataDM end object XDataServer1Compress: TSparkleCompressMiddleware end + object XDataServer1JWT: TSparkleJwtMiddleware + ForbidAnonymousAccess = True + OnGetSecretEx = XDataServer1JWTGetSecretEx + end end object SparkleHttpSysDispatcher1: TSparkleHttpSysDispatcher Left = 128 diff --git a/Server/Src/XData.DM.pas b/Server/Src/XData.DM.pas index b8b03df..9060de4 100644 --- a/Server/Src/XData.DM.pas +++ b/Server/Src/XData.DM.pas @@ -12,7 +12,7 @@ interface Sparkle.Comp.HttpSysDispatcher, XData.Comp.Server, Sparkle.Comp.CompressMiddleware, - Sparkle.Comp.CorsMiddleware; + Sparkle.Comp.CorsMiddleware, Sparkle.Comp.JwtMiddleware; type TXDataDM = class(TDataModule) @@ -20,6 +20,9 @@ TXDataDM = class(TDataModule) SparkleHttpSysDispatcher1: TSparkleHttpSysDispatcher; XDataServer1CORS: TSparkleCorsMiddleware; XDataServer1Compress: TSparkleCompressMiddleware; + XDataServer1JWT: TSparkleJwtMiddleware; + procedure XDataServer1JWTGetSecretEx(Sender: TObject; const JWT: TJWT; Context: THttpServerContext; + var Secret: TBytes); private public @@ -35,4 +38,10 @@ implementation {$R *.dfm} +procedure TXDataDM.XDataServer1JWTGetSecretEx(Sender: TObject; const JWT: TJWT; Context: THttpServerContext; + var Secret: TBytes); +begin + Secret := TEncoding.UTF8.GetBytes('sua-chave-secreta-1234567890-12345'); +end; + end. From ef68514fd9f62e7b63ce63241400d7f79383e0d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Thu, 1 May 2025 00:59:41 -0300 Subject: [PATCH 09/12] aula18-parte02 --- ClientWeb/Src/Login.View.dfm | 12 ++++++++++++ ClientWeb/Src/Login.View.pas | 30 ++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/ClientWeb/Src/Login.View.dfm b/ClientWeb/Src/Login.View.dfm index d347c3b..e8dfa69 100644 --- a/ClientWeb/Src/Login.View.dfm +++ b/ClientWeb/Src/Login.View.dfm @@ -61,4 +61,16 @@ object LoginView: TLoginView HeightPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000 end + object XDataWebConnection1: TXDataWebConnection + URL = 'http://localhost:2001/tms/auth/' + Connected = True + Left = 72 + Top = 16 + end + object XDataWebClient1: TXDataWebClient + Connection = XDataWebConnection1 + OnError = XDataWebClient1Error + Left = 216 + Top = 16 + end end diff --git a/ClientWeb/Src/Login.View.pas b/ClientWeb/Src/Login.View.pas index 95fe007..bdf73aa 100644 --- a/ClientWeb/Src/Login.View.pas +++ b/ClientWeb/Src/Login.View.pas @@ -14,7 +14,7 @@ interface Vcl.Controls, Vcl.StdCtrls, WEBLib.StdCtrls, - Main.View; + Main.View, XData.Web.Client, XData.Web.Connection; type TLoginView = class(TWebForm) @@ -23,11 +23,14 @@ TLoginView = class(TWebForm) edtSenha: TWebEdit; btnEntrar: TWebButton; ckLembrarMe: TWebCheckBox; + XDataWebConnection1: TXDataWebConnection; + XDataWebClient1: TXDataWebClient; procedure btnEntrarClick(Sender: TObject); procedure WebFormShow(Sender: TObject); procedure edtLoginKeyPress(Sender: TObject; var Key: Char); procedure edtSenhaKeyPress(Sender: TObject; var Key: Char); procedure WebFormCreate(Sender: TObject); + procedure XDataWebClient1Error(Error: TXDataClientError); private public @@ -52,6 +55,16 @@ procedure TLoginView.WebFormShow(Sender: TObject); edtLogin.SetFocus; end; +procedure TLoginView.XDataWebClient1Error(Error: TXDataClientError); +begin + ShowMessage( + 'StatusCode: ' + Error.StatusCode.ToString + sLineBreak + + 'RequestUrl: ' + Error.RequestUrl + sLineBreak + + 'RequestId: ' + Error.RequestId + sLineBreak + + 'ErrorCode: ' + Error.ErrorCode + sLineBreak + + 'ErrorMessage: ' + Error.ErrorMessage); +end; + procedure TLoginView.edtLoginKeyPress(Sender: TObject; var Key: Char); begin if Key = #13 then @@ -65,18 +78,23 @@ procedure TLoginView.edtSenhaKeyPress(Sender: TObject; var Key: Char); end; procedure TLoginView.btnEntrarClick(Sender: TObject); +var + LResponse: TXDataClientResponse; begin - if edtLogin.Text <> 'admin' then + if Trim(edtLogin.Text).IsEmpty or Trim(edtSenha.Text).IsEmpty then begin - ShowMessage('Login invlido'); + ShowMessage('Login e senha devem ser informados'); edtLogin.SetFocus; Exit; end; - if edtSenha.Text <> 'admin' then + LResponse := TAwait.Exec( + XDataWebClient1.RawInvokeAsync('ILoginService.Login', [edtLogin.Text, edtSenha.Text])); + + if LResponse.StatusCode <> 200 then begin - ShowMessage('Senha invlido'); - edtSenha.SetFocus; + ShowMessage('Login ou senha informados so invlidos'); + edtLogin.SetFocus; Exit; end; From fbaee0fe73aeedc73aac2816f18d90701b61271d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= Date: Thu, 1 May 2025 04:14:54 -0300 Subject: [PATCH 10/12] feature/aula-18 --- ClientWeb/ClientWeb.dpr | 3 ++- ClientWeb/ClientWeb.dproj | 1 + ClientWeb/Src/Configs.pas | 10 ++++++++++ ClientWeb/Src/Login.View.pas | 16 +++++++++++++--- ClientWeb/Src/Main.View.dfm | 3 ++- ClientWeb/Src/Main.View.pas | 15 ++++++++++++++- Server/Src/XData.DM.dfm | 1 + Server/Src/XData.DM.pas | 7 +++++++ ServerAuth/Src/ServerAuth.XData.DM.dfm | 4 ++++ ServerAuth/Src/ServerAuth.XData.DM.pas | 16 ++++++++++++---- 10 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 ClientWeb/Src/Configs.pas diff --git a/ClientWeb/ClientWeb.dpr b/ClientWeb/ClientWeb.dpr index a0ec3f3..3c72d6a 100644 --- a/ClientWeb/ClientWeb.dpr +++ b/ClientWeb/ClientWeb.dpr @@ -7,7 +7,8 @@ uses WEBLib.Forms, Main.View in 'Src\Main.View.pas' {MainView: TWebForm} {*.html}, Login.View in 'Src\Login.View.pas' {LoginView: TWebForm} {*.html}, - Clientes.Cadastrar.View in 'Src\ClientesCadastrar\Clientes.Cadastrar.View.pas' {ClientesCadastrarView: TWebForm} {*.html}; + Clientes.Cadastrar.View in 'Src\ClientesCadastrar\Clientes.Cadastrar.View.pas' {ClientesCadastrarView: TWebForm} {*.html}, + Configs in 'Src\Configs.pas'; {$R *.res} diff --git a/ClientWeb/ClientWeb.dproj b/ClientWeb/ClientWeb.dproj index d92705b..d8490ab 100644 --- a/ClientWeb/ClientWeb.dproj +++ b/ClientWeb/ClientWeb.dproj @@ -123,6 +123,7 @@ dfm TWebForm
+ diff --git a/ClientWeb/Src/Configs.pas b/ClientWeb/Src/Configs.pas new file mode 100644 index 0000000..38693da --- /dev/null +++ b/ClientWeb/Src/Configs.pas @@ -0,0 +1,10 @@ +unit Configs; + +interface + +var + Configs_Token: string; + +implementation + +end. diff --git a/ClientWeb/Src/Login.View.pas b/ClientWeb/Src/Login.View.pas index bdf73aa..1aaff1c 100644 --- a/ClientWeb/Src/Login.View.pas +++ b/ClientWeb/Src/Login.View.pas @@ -5,7 +5,6 @@ interface uses System.SysUtils, System.Classes, - JS, Web, WEBLib.Graphics, WEBLib.Controls, @@ -13,8 +12,7 @@ interface WEBLib.Dialogs, Vcl.Controls, Vcl.StdCtrls, - WEBLib.StdCtrls, - Main.View, XData.Web.Client, XData.Web.Connection; + WEBLib.StdCtrls, Main.View, XData.Web.Client, XData.Web.Connection, JS, Configs; type TLoginView = class(TWebForm) @@ -23,8 +21,10 @@ TLoginView = class(TWebForm) edtSenha: TWebEdit; btnEntrar: TWebButton; ckLembrarMe: TWebCheckBox; + [Async] XDataWebConnection1: TXDataWebConnection; XDataWebClient1: TXDataWebClient; + [Async] procedure btnEntrarClick(Sender: TObject); procedure WebFormShow(Sender: TObject); procedure edtLoginKeyPress(Sender: TObject; var Key: Char); @@ -98,6 +98,16 @@ procedure TLoginView.btnEntrarClick(Sender: TObject); Exit; end; + Configs_Token := string(TJSObject(LResponse.Result)['value']); + if Configs_Token.Trim.IsEmpty then + begin + ShowMessage('Token no pode ser recuperado'); + edtLogin.SetFocus; + Exit; + end; + + ShowMessage('Token: ' + Configs_Token); + MainView := TMainView.CreateNew; MainView.ShowModal; end; diff --git a/ClientWeb/Src/Main.View.dfm b/ClientWeb/Src/Main.View.dfm index 3f92b90..5c37a58 100644 --- a/ClientWeb/Src/Main.View.dfm +++ b/ClientWeb/Src/Main.View.dfm @@ -175,7 +175,6 @@ object MainView: TMainView HeightPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000 OnClick = btnDeleteClick - ExplicitLeft = 729 end end object TMSFNCDataGrid1: TTMSFNCDataGrid @@ -917,6 +916,8 @@ object MainView: TMainView end object XDataWebConnection1: TXDataWebConnection URL = 'http://localhost:8000/tms/xdata' + OnError = XDataWebConnection1Error + OnRequest = XDataWebConnection1Request Left = 96 Top = 16 end diff --git a/ClientWeb/Src/Main.View.pas b/ClientWeb/Src/Main.View.pas index 5c4b934..e752094 100644 --- a/ClientWeb/Src/Main.View.pas +++ b/ClientWeb/Src/Main.View.pas @@ -35,7 +35,8 @@ interface VCL.TMSFNCCustomControl, VCL.TMSFNCDataGrid, VCL.TMSFNCCustomComponent, - VCL.TMSFNCDataGridDatabaseAdapter; + VCL.TMSFNCDataGridDatabaseAdapter, + Configs; type TMainView = class(TWebForm) @@ -84,6 +85,8 @@ TMainView = class(TWebForm) [Async] procedure btnDeleteClick(Sender: TObject); procedure XDataWebClient1Error(Error: TXDataClientError); + procedure XDataWebConnection1Error(Error: TXDataWebConnectionError); + procedure XDataWebConnection1Request(Args: TXDataWebConnectionRequest); private function GetClientePreenchido(const AView: TClientesCadastrarView): TJSObject; public @@ -142,6 +145,16 @@ procedure TMainView.XDataWebClient1Error(Error: TXDataClientError); 'ErrorMessage: ' + Error.ErrorMessage); end; +procedure TMainView.XDataWebConnection1Error(Error: TXDataWebConnectionError); +begin + ShowMessage('StatusCode: ' + Error.ErrorMessage); +end; + +procedure TMainView.XDataWebConnection1Request(Args: TXDataWebConnectionRequest); +begin + Args.Request.Headers.SetValue('Authorization', 'Bearer ' + Configs_Token); +end; + procedure TMainView.btnGetNomeClick(Sender: TObject); var LResponse: TXDataClientResponse; diff --git a/Server/Src/XData.DM.dfm b/Server/Src/XData.DM.dfm index 716ddeb..46971e3 100644 --- a/Server/Src/XData.DM.dfm +++ b/Server/Src/XData.DM.dfm @@ -16,6 +16,7 @@ object XDataDM: TXDataDM object XDataServer1JWT: TSparkleJwtMiddleware ForbidAnonymousAccess = True OnGetSecretEx = XDataServer1JWTGetSecretEx + OnForbidRequest = XDataServer1JWTForbidRequest end end object SparkleHttpSysDispatcher1: TSparkleHttpSysDispatcher diff --git a/Server/Src/XData.DM.pas b/Server/Src/XData.DM.pas index 9060de4..a3677aa 100644 --- a/Server/Src/XData.DM.pas +++ b/Server/Src/XData.DM.pas @@ -23,6 +23,7 @@ TXDataDM = class(TDataModule) XDataServer1JWT: TSparkleJwtMiddleware; procedure XDataServer1JWTGetSecretEx(Sender: TObject; const JWT: TJWT; Context: THttpServerContext; var Secret: TBytes); + procedure XDataServer1JWTForbidRequest(Sender: TObject; Context: THttpServerContext; var Forbid: Boolean); private public @@ -38,6 +39,12 @@ implementation {$R *.dfm} +procedure TXDataDM.XDataServer1JWTForbidRequest(Sender: TObject; Context: THttpServerContext; var Forbid: Boolean); +begin + if Context.Request.Uri.AbsolutePath.Contains('swagger') then + Forbid := False; +end; + procedure TXDataDM.XDataServer1JWTGetSecretEx(Sender: TObject; const JWT: TJWT; Context: THttpServerContext; var Secret: TBytes); begin diff --git a/ServerAuth/Src/ServerAuth.XData.DM.dfm b/ServerAuth/Src/ServerAuth.XData.DM.dfm index 35a04cf..b702148 100644 --- a/ServerAuth/Src/ServerAuth.XData.DM.dfm +++ b/ServerAuth/Src/ServerAuth.XData.DM.dfm @@ -13,5 +13,9 @@ object ServerAuthXDataDM: TServerAuthXDataDM SwaggerUIOptions.Enabled = True Left = 136 Top = 144 + object XDataServer1CORS: TSparkleCorsMiddleware + end + object XDataServer1Compress: TSparkleCompressMiddleware + end end end diff --git a/ServerAuth/Src/ServerAuth.XData.DM.pas b/ServerAuth/Src/ServerAuth.XData.DM.pas index 6efb1b8..4458b08 100644 --- a/ServerAuth/Src/ServerAuth.XData.DM.pas +++ b/ServerAuth/Src/ServerAuth.XData.DM.pas @@ -3,17 +3,25 @@ interface uses - System.SysUtils, System.Classes, Sparkle.HttpServer.Module, Sparkle.HttpServer.Context, XData.Server.Module, - Sparkle.Comp.Server, XData.Comp.Server, Sparkle.Comp.HttpSysDispatcher; + System.SysUtils, + System.Classes, + Sparkle.HttpServer.Module, + Sparkle.HttpServer.Context, + XData.Server.Module, + Sparkle.Comp.Server, + XData.Comp.Server, + Sparkle.Comp.HttpSysDispatcher, Sparkle.Comp.CompressMiddleware, Sparkle.Comp.CorsMiddleware; type TServerAuthXDataDM = class(TDataModule) SparkleHttpSysDispatcher1: TSparkleHttpSysDispatcher; XDataServer1: TXDataServer; + XDataServer1CORS: TSparkleCorsMiddleware; + XDataServer1Compress: TSparkleCompressMiddleware; private - { Private declarations } + public - { Public declarations } + end; var From 67d7666c6e21b23827b003effe8b00d2cda7433b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Thu, 1 May 2025 04:47:03 -0300 Subject: [PATCH 11/12] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9c3f0ef..8c18790 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ - [Repositório do projeto de demonstração do Web Form Designer](https://github.com/Code4Delphi/Web-Form-Designer) - [Delphi Web #17 - O que é e como usar JWT no Delphi](https://www.youtube.com/watch?v=uYTB_q-C0MY&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=17) - [Postagem no blog com tudo que você precisa saber sobre JWT no Delphi](https://code4delphi.com.br/blog/jwt-no-delphi-o-que-e-e-como-utilizar/) + - [Delphi Web #18 - O que é e como usar JWT no Delphi - Middleware JWT](https://www.youtube.com/watch?v=uYTB_q-C0MY&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=18)
From eff1faed70c1d767f86e1976c573e64dcfd84366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Cardoso?= <33873267+Cesar4D@users.noreply.github.com> Date: Thu, 1 May 2025 04:47:37 -0300 Subject: [PATCH 12/12] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8c18790..81d9477 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ - [Repositório do projeto de demonstração do Web Form Designer](https://github.com/Code4Delphi/Web-Form-Designer) - [Delphi Web #17 - O que é e como usar JWT no Delphi](https://www.youtube.com/watch?v=uYTB_q-C0MY&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=17) - [Postagem no blog com tudo que você precisa saber sobre JWT no Delphi](https://code4delphi.com.br/blog/jwt-no-delphi-o-que-e-e-como-utilizar/) - - [Delphi Web #18 - O que é e como usar JWT no Delphi - Middleware JWT](https://www.youtube.com/watch?v=uYTB_q-C0MY&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=18) + - [Delphi Web #18 - O que é e como usar JWT no Delphi - Middleware JWT](https://www.youtube.com/watch?v=Jgo9vx5La_0&list=PLLHSz4dOnnN39OimL44gj6CthKx54MNlY&index=18)