Compare commits
	
		
			No commits in common. "main" and "fixes/principal-onboarding" have entirely different histories.
		
	
	
		
			main
			...
			fixes/prin
		
	
		
							
								
								
									
										367
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,367 @@ | |||||||
|  | ## Ignore Visual Studio temporary files, build results, and | ||||||
|  | ## files generated by popular Visual Studio add-ons. | ||||||
|  | ## | ||||||
|  | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore | ||||||
|  | 
 | ||||||
|  | # User-specific files | ||||||
|  | *.rsuser | ||||||
|  | *.suo | ||||||
|  | *.user | ||||||
|  | *.userosscache | ||||||
|  | *.sln.docstates | ||||||
|  | 
 | ||||||
|  | # User-specific files (MonoDevelop/Xamarin Studio) | ||||||
|  | *.userprefs | ||||||
|  | 
 | ||||||
|  | # Mono auto generated files | ||||||
|  | mono_crash.* | ||||||
|  | 
 | ||||||
|  | # Build results | ||||||
|  | [Dd]ebug/ | ||||||
|  | [Dd]ebugPublic/ | ||||||
|  | [Rr]elease/ | ||||||
|  | [Rr]eleases/ | ||||||
|  | x64/ | ||||||
|  | x86/ | ||||||
|  | [Ww][Ii][Nn]32/ | ||||||
|  | [Aa][Rr][Mm]/ | ||||||
|  | [Aa][Rr][Mm]64/ | ||||||
|  | bld/ | ||||||
|  | [Bb]in/ | ||||||
|  | [Oo]bj/ | ||||||
|  | [Ll]og/ | ||||||
|  | [Ll]ogs/ | ||||||
|  | 
 | ||||||
|  | # Visual Studio 2015/2017 cache/options directory | ||||||
|  | .vs/ | ||||||
|  | # Uncomment if you have tasks that create the project's static files in wwwroot | ||||||
|  | #wwwroot/ | ||||||
|  | 
 | ||||||
|  | # Visual Studio 2017 auto generated files | ||||||
|  | Generated\ Files/ | ||||||
|  | 
 | ||||||
|  | # MSTest test Results | ||||||
|  | [Tt]est[Rr]esult*/ | ||||||
|  | [Bb]uild[Ll]og.* | ||||||
|  | 
 | ||||||
|  | # NUnit | ||||||
|  | *.VisualState.xml | ||||||
|  | TestResult.xml | ||||||
|  | nunit-*.xml | ||||||
|  | 
 | ||||||
|  | # Build Results of an ATL Project | ||||||
|  | [Dd]ebugPS/ | ||||||
|  | [Rr]eleasePS/ | ||||||
|  | dlldata.c | ||||||
|  | 
 | ||||||
|  | # Benchmark Results | ||||||
|  | BenchmarkDotNet.Artifacts/ | ||||||
|  | 
 | ||||||
|  | # .NET Core | ||||||
|  | project.lock.json | ||||||
|  | project.fragment.lock.json | ||||||
|  | artifacts/ | ||||||
|  | 
 | ||||||
|  | # ASP.NET Scaffolding | ||||||
|  | ScaffoldingReadMe.txt | ||||||
|  | 
 | ||||||
|  | # StyleCop | ||||||
|  | StyleCopReport.xml | ||||||
|  | 
 | ||||||
|  | # Files built by Visual Studio | ||||||
|  | *_i.c | ||||||
|  | *_p.c | ||||||
|  | *_h.h | ||||||
|  | *.ilk | ||||||
|  | *.meta | ||||||
|  | *.obj | ||||||
|  | *.iobj | ||||||
|  | *.pch | ||||||
|  | *.pdb | ||||||
|  | *.ipdb | ||||||
|  | *.pgc | ||||||
|  | *.pgd | ||||||
|  | *.rsp | ||||||
|  | *.sbr | ||||||
|  | *.tlb | ||||||
|  | *.tli | ||||||
|  | *.tlh | ||||||
|  | *.tmp | ||||||
|  | *.tmp_proj | ||||||
|  | *_wpftmp.csproj | ||||||
|  | *.log | ||||||
|  | *.vspscc | ||||||
|  | *.vssscc | ||||||
|  | .builds | ||||||
|  | *.pidb | ||||||
|  | *.svclog | ||||||
|  | *.scc | ||||||
|  | 
 | ||||||
|  | # Chutzpah Test files | ||||||
|  | _Chutzpah* | ||||||
|  | 
 | ||||||
|  | # Visual C++ cache files | ||||||
|  | ipch/ | ||||||
|  | *.aps | ||||||
|  | *.ncb | ||||||
|  | *.opendb | ||||||
|  | *.opensdf | ||||||
|  | *.sdf | ||||||
|  | *.cachefile | ||||||
|  | *.VC.db | ||||||
|  | *.VC.VC.opendb | ||||||
|  | 
 | ||||||
|  | # Visual Studio profiler | ||||||
|  | *.psess | ||||||
|  | *.vsp | ||||||
|  | *.vspx | ||||||
|  | *.sap | ||||||
|  | 
 | ||||||
|  | # Visual Studio Trace Files | ||||||
|  | *.e2e | ||||||
|  | 
 | ||||||
|  | # TFS 2012 Local Workspace | ||||||
|  | $tf/ | ||||||
|  | 
 | ||||||
|  | # Guidance Automation Toolkit | ||||||
|  | *.gpState | ||||||
|  | 
 | ||||||
|  | # ReSharper is a .NET coding add-in | ||||||
|  | _ReSharper*/ | ||||||
|  | *.[Rr]e[Ss]harper | ||||||
|  | *.DotSettings.user | ||||||
|  | 
 | ||||||
|  | # TeamCity is a build add-in | ||||||
|  | _TeamCity* | ||||||
|  | 
 | ||||||
|  | # DotCover is a Code Coverage Tool | ||||||
|  | *.dotCover | ||||||
|  | 
 | ||||||
|  | # AxoCover is a Code Coverage Tool | ||||||
|  | .axoCover/* | ||||||
|  | !.axoCover/settings.json | ||||||
|  | 
 | ||||||
|  | # Coverlet is a free, cross platform Code Coverage Tool | ||||||
|  | coverage*.json | ||||||
|  | coverage*.xml | ||||||
|  | coverage*.info | ||||||
|  | 
 | ||||||
|  | # Visual Studio code coverage results | ||||||
|  | *.coverage | ||||||
|  | *.coveragexml | ||||||
|  | 
 | ||||||
|  | # NCrunch | ||||||
|  | _NCrunch_* | ||||||
|  | .*crunch*.local.xml | ||||||
|  | nCrunchTemp_* | ||||||
|  | 
 | ||||||
|  | # MightyMoose | ||||||
|  | *.mm.* | ||||||
|  | AutoTest.Net/ | ||||||
|  | 
 | ||||||
|  | # Web workbench (sass) | ||||||
|  | .sass-cache/ | ||||||
|  | 
 | ||||||
|  | # Installshield output folder | ||||||
|  | [Ee]xpress/ | ||||||
|  | 
 | ||||||
|  | # DocProject is a documentation generator add-in | ||||||
|  | DocProject/buildhelp/ | ||||||
|  | DocProject/Help/*.HxT | ||||||
|  | DocProject/Help/*.HxC | ||||||
|  | DocProject/Help/*.hhc | ||||||
|  | DocProject/Help/*.hhk | ||||||
|  | DocProject/Help/*.hhp | ||||||
|  | DocProject/Help/Html2 | ||||||
|  | DocProject/Help/html | ||||||
|  | 
 | ||||||
|  | # Click-Once directory | ||||||
|  | publish/ | ||||||
|  | 
 | ||||||
|  | # Publish Web Output | ||||||
|  | *.[Pp]ublish.xml | ||||||
|  | *.azurePubxml | ||||||
|  | # Note: Comment the next line if you want to checkin your web deploy settings, | ||||||
|  | # but database connection strings (with potential passwords) will be unencrypted | ||||||
|  | *.pubxml | ||||||
|  | *.publishproj | ||||||
|  | 
 | ||||||
|  | # Microsoft Azure Web App publish settings. Comment the next line if you want to | ||||||
|  | # checkin your Azure Web App publish settings, but sensitive information contained | ||||||
|  | # in these scripts will be unencrypted | ||||||
|  | PublishScripts/ | ||||||
|  | 
 | ||||||
|  | # NuGet Packages | ||||||
|  | *.nupkg | ||||||
|  | # NuGet Symbol Packages | ||||||
|  | *.snupkg | ||||||
|  | # The packages folder can be ignored because of Package Restore | ||||||
|  | **/[Pp]ackages/* | ||||||
|  | # except build/, which is used as an MSBuild target. | ||||||
|  | !**/[Pp]ackages/build/ | ||||||
|  | # Uncomment if necessary however generally it will be regenerated when needed | ||||||
|  | #!**/[Pp]ackages/repositories.config | ||||||
|  | # NuGet v3's project.json files produces more ignorable files | ||||||
|  | *.nuget.props | ||||||
|  | *.nuget.targets | ||||||
|  | 
 | ||||||
|  | # Microsoft Azure Build Output | ||||||
|  | csx/ | ||||||
|  | *.build.csdef | ||||||
|  | 
 | ||||||
|  | # Microsoft Azure Emulator | ||||||
|  | ecf/ | ||||||
|  | rcf/ | ||||||
|  | 
 | ||||||
|  | # Windows Store app package directories and files | ||||||
|  | AppPackages/ | ||||||
|  | BundleArtifacts/ | ||||||
|  | Package.StoreAssociation.xml | ||||||
|  | _pkginfo.txt | ||||||
|  | *.appx | ||||||
|  | *.appxbundle | ||||||
|  | *.appxupload | ||||||
|  | 
 | ||||||
|  | # Visual Studio cache files | ||||||
|  | # files ending in .cache can be ignored | ||||||
|  | *.[Cc]ache | ||||||
|  | # but keep track of directories ending in .cache | ||||||
|  | !?*.[Cc]ache/ | ||||||
|  | 
 | ||||||
|  | # Others | ||||||
|  | ClientBin/ | ||||||
|  | ~$* | ||||||
|  | *~ | ||||||
|  | *.dbmdl | ||||||
|  | *.dbproj.schemaview | ||||||
|  | *.jfm | ||||||
|  | *.pfx | ||||||
|  | *.publishsettings | ||||||
|  | orleans.codegen.cs | ||||||
|  | 
 | ||||||
|  | # Including strong name files can present a security risk | ||||||
|  | # (https://github.com/github/gitignore/pull/2483#issue-259490424) | ||||||
|  | #*.snk | ||||||
|  | 
 | ||||||
|  | # Since there are multiple workflows, uncomment next line to ignore bower_components | ||||||
|  | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) | ||||||
|  | #bower_components/ | ||||||
|  | 
 | ||||||
|  | # RIA/Silverlight projects | ||||||
|  | Generated_Code/ | ||||||
|  | 
 | ||||||
|  | # Backup & report files from converting an old project file | ||||||
|  | # to a newer Visual Studio version. Backup files are not needed, | ||||||
|  | # because we have git ;-) | ||||||
|  | _UpgradeReport_Files/ | ||||||
|  | Backup*/ | ||||||
|  | UpgradeLog*.XML | ||||||
|  | UpgradeLog*.htm | ||||||
|  | ServiceFabricBackup/ | ||||||
|  | *.rptproj.bak | ||||||
|  | 
 | ||||||
|  | # SQL Server files | ||||||
|  | *.mdf | ||||||
|  | *.ldf | ||||||
|  | *.ndf | ||||||
|  | 
 | ||||||
|  | # Business Intelligence projects | ||||||
|  | *.rdl.data | ||||||
|  | *.bim.layout | ||||||
|  | *.bim_*.settings | ||||||
|  | *.rptproj.rsuser | ||||||
|  | *- [Bb]ackup.rdl | ||||||
|  | *- [Bb]ackup ([0-9]).rdl | ||||||
|  | *- [Bb]ackup ([0-9][0-9]).rdl | ||||||
|  | 
 | ||||||
|  | # Microsoft Fakes | ||||||
|  | FakesAssemblies/ | ||||||
|  | 
 | ||||||
|  | # GhostDoc plugin setting file | ||||||
|  | *.GhostDoc.xml | ||||||
|  | 
 | ||||||
|  | # Node.js Tools for Visual Studio | ||||||
|  | .ntvs_analysis.dat | ||||||
|  | node_modules/ | ||||||
|  | 
 | ||||||
|  | # Visual Studio 6 build log | ||||||
|  | *.plg | ||||||
|  | 
 | ||||||
|  | # Visual Studio 6 workspace options file | ||||||
|  | *.opt | ||||||
|  | 
 | ||||||
|  | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) | ||||||
|  | *.vbw | ||||||
|  | 
 | ||||||
|  | # Visual Studio LightSwitch build output | ||||||
|  | **/*.HTMLClient/GeneratedArtifacts | ||||||
|  | **/*.DesktopClient/GeneratedArtifacts | ||||||
|  | **/*.DesktopClient/ModelManifest.xml | ||||||
|  | **/*.Server/GeneratedArtifacts | ||||||
|  | **/*.Server/ModelManifest.xml | ||||||
|  | _Pvt_Extensions | ||||||
|  | 
 | ||||||
|  | # Paket dependency manager | ||||||
|  | .paket/paket.exe | ||||||
|  | paket-files/ | ||||||
|  | 
 | ||||||
|  | # FAKE - F# Make | ||||||
|  | .fake/ | ||||||
|  | 
 | ||||||
|  | # CodeRush personal settings | ||||||
|  | .cr/personal | ||||||
|  | 
 | ||||||
|  | # Python Tools for Visual Studio (PTVS) | ||||||
|  | __pycache__/ | ||||||
|  | *.pyc | ||||||
|  | 
 | ||||||
|  | # Cake - Uncomment if you are using it | ||||||
|  | # tools/** | ||||||
|  | # !tools/packages.config | ||||||
|  | 
 | ||||||
|  | # Tabs Studio | ||||||
|  | *.tss | ||||||
|  | 
 | ||||||
|  | # Telerik's JustMock configuration file | ||||||
|  | *.jmconfig | ||||||
|  | 
 | ||||||
|  | # BizTalk build output | ||||||
|  | *.btp.cs | ||||||
|  | *.btm.cs | ||||||
|  | *.odx.cs | ||||||
|  | *.xsd.cs | ||||||
|  | 
 | ||||||
|  | # OpenCover UI analysis results | ||||||
|  | OpenCover/ | ||||||
|  | 
 | ||||||
|  | # Azure Stream Analytics local run output | ||||||
|  | ASALocalRun/ | ||||||
|  | 
 | ||||||
|  | # MSBuild Binary and Structured Log | ||||||
|  | *.binlog | ||||||
|  | 
 | ||||||
|  | # NVidia Nsight GPU debugger configuration file | ||||||
|  | *.nvuser | ||||||
|  | 
 | ||||||
|  | # MFractors (Xamarin productivity tool) working folder | ||||||
|  | .mfractor/ | ||||||
|  | 
 | ||||||
|  | # Local History for Visual Studio | ||||||
|  | .localhistory/ | ||||||
|  | 
 | ||||||
|  | # BeatPulse healthcheck temp database | ||||||
|  | healthchecksdb | ||||||
|  | 
 | ||||||
|  | # Backup folder for Package Reference Convert tool in Visual Studio 2017 | ||||||
|  | MigrationBackup/ | ||||||
|  | 
 | ||||||
|  | # Ionide (cross platform F# VS Code tools) working folder | ||||||
|  | .ionide/ | ||||||
|  | 
 | ||||||
|  | # Fody - auto-generated XML schema | ||||||
|  | FodyWeavers.xsd | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | .parcel*/ | ||||||
|  | /EnotaryoPH/EnotaryoPH.Web/wwwroot/dist | ||||||
|  | /EnotaryoPH/EnotaryoPH.Web/dist/ | ||||||
							
								
								
									
										286
									
								
								EnotaryoPH/.editorconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										286
									
								
								EnotaryoPH/.editorconfig
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,286 @@ | |||||||
|  | # Remove the line below if you want to inherit .editorconfig settings from higher directories | ||||||
|  | root = true | ||||||
|  | 
 | ||||||
|  | # C# files | ||||||
|  | [*.cs] | ||||||
|  | 
 | ||||||
|  | #### Core EditorConfig Options #### | ||||||
|  | 
 | ||||||
|  | # Indentation and spacing | ||||||
|  | indent_size = 4 | ||||||
|  | indent_style = space | ||||||
|  | tab_width = 4 | ||||||
|  | 
 | ||||||
|  | # New line preferences | ||||||
|  | end_of_line = crlf | ||||||
|  | insert_final_newline = false | ||||||
|  | 
 | ||||||
|  | #### .NET Code Actions #### | ||||||
|  | 
 | ||||||
|  | # Type members | ||||||
|  | dotnet_hide_advanced_members = false | ||||||
|  | dotnet_member_insertion_location = with_other_members_of_the_same_kind | ||||||
|  | dotnet_property_generation_behavior = prefer_auto_properties | ||||||
|  | 
 | ||||||
|  | # Symbol search | ||||||
|  | dotnet_search_reference_assemblies = true | ||||||
|  | 
 | ||||||
|  | #### .NET Coding Conventions #### | ||||||
|  | 
 | ||||||
|  | # Organize usings | ||||||
|  | dotnet_separate_import_directive_groups = false | ||||||
|  | dotnet_sort_system_directives_first = true | ||||||
|  | file_header_template = unset | ||||||
|  | 
 | ||||||
|  | # this. and Me. preferences | ||||||
|  | dotnet_style_qualification_for_event = false | ||||||
|  | dotnet_style_qualification_for_field = false | ||||||
|  | dotnet_style_qualification_for_method = false | ||||||
|  | dotnet_style_qualification_for_property = false | ||||||
|  | 
 | ||||||
|  | # Language keywords vs BCL types preferences | ||||||
|  | dotnet_style_predefined_type_for_locals_parameters_members = true | ||||||
|  | dotnet_style_predefined_type_for_member_access = true | ||||||
|  | 
 | ||||||
|  | # Parentheses preferences | ||||||
|  | dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:error | ||||||
|  | dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:error | ||||||
|  | dotnet_style_parentheses_in_other_operators = never_if_unnecessary | ||||||
|  | dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:error | ||||||
|  | 
 | ||||||
|  | # Modifier preferences | ||||||
|  | dotnet_style_require_accessibility_modifiers = for_non_interface_members | ||||||
|  | 
 | ||||||
|  | # Expression-level preferences | ||||||
|  | dotnet_prefer_system_hash_code = true | ||||||
|  | dotnet_style_coalesce_expression = true:error | ||||||
|  | dotnet_style_collection_initializer = true:error | ||||||
|  | dotnet_style_explicit_tuple_names = true:error | ||||||
|  | dotnet_style_namespace_match_folder = true | ||||||
|  | dotnet_style_null_propagation = true:error | ||||||
|  | dotnet_style_object_initializer = true:error | ||||||
|  | dotnet_style_operator_placement_when_wrapping = beginning_of_line | ||||||
|  | dotnet_style_prefer_auto_properties = true:error | ||||||
|  | dotnet_style_prefer_collection_expression = when_types_loosely_match | ||||||
|  | dotnet_style_prefer_compound_assignment = true | ||||||
|  | dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion | ||||||
|  | dotnet_style_prefer_conditional_expression_over_return = true:error | ||||||
|  | dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed | ||||||
|  | dotnet_style_prefer_inferred_anonymous_type_member_names = true:error | ||||||
|  | dotnet_style_prefer_inferred_tuple_names = true | ||||||
|  | dotnet_style_prefer_is_null_check_over_reference_equality_method = true:error | ||||||
|  | dotnet_style_prefer_simplified_boolean_expressions = true:error | ||||||
|  | dotnet_style_prefer_simplified_interpolation = true | ||||||
|  | 
 | ||||||
|  | # Field preferences | ||||||
|  | dotnet_style_readonly_field = true:warning | ||||||
|  | 
 | ||||||
|  | # Parameter preferences | ||||||
|  | dotnet_code_quality_unused_parameters = all:warning | ||||||
|  | 
 | ||||||
|  | # Suppression preferences | ||||||
|  | dotnet_remove_unnecessary_suppression_exclusions = none | ||||||
|  | 
 | ||||||
|  | # New line preferences | ||||||
|  | dotnet_style_allow_multiple_blank_lines_experimental = false:error | ||||||
|  | dotnet_style_allow_statement_immediately_after_block_experimental = true | ||||||
|  | 
 | ||||||
|  | #### C# Coding Conventions #### | ||||||
|  | 
 | ||||||
|  | # var preferences | ||||||
|  | csharp_style_var_elsewhere = true:suggestion | ||||||
|  | csharp_style_var_for_built_in_types = true | ||||||
|  | csharp_style_var_when_type_is_apparent = true:error | ||||||
|  | 
 | ||||||
|  | # Expression-bodied members | ||||||
|  | csharp_style_expression_bodied_accessors = true:error | ||||||
|  | csharp_style_expression_bodied_constructors = true:error | ||||||
|  | csharp_style_expression_bodied_indexers = true:error | ||||||
|  | csharp_style_expression_bodied_lambdas = true:error | ||||||
|  | csharp_style_expression_bodied_local_functions = when_on_single_line:error | ||||||
|  | csharp_style_expression_bodied_methods = true:error | ||||||
|  | csharp_style_expression_bodied_operators = true:error | ||||||
|  | csharp_style_expression_bodied_properties = true:error | ||||||
|  | 
 | ||||||
|  | # Pattern matching preferences | ||||||
|  | csharp_style_pattern_matching_over_as_with_null_check = true:error | ||||||
|  | csharp_style_pattern_matching_over_is_with_cast_check = true:error | ||||||
|  | csharp_style_prefer_extended_property_pattern = true | ||||||
|  | csharp_style_prefer_not_pattern = true:error | ||||||
|  | csharp_style_prefer_pattern_matching = true:error | ||||||
|  | csharp_style_prefer_switch_expression = true:error | ||||||
|  | 
 | ||||||
|  | # Null-checking preferences | ||||||
|  | csharp_style_conditional_delegate_call = true:error | ||||||
|  | 
 | ||||||
|  | # Modifier preferences | ||||||
|  | csharp_prefer_static_anonymous_function = true | ||||||
|  | csharp_prefer_static_local_function = true | ||||||
|  | csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async | ||||||
|  | csharp_style_prefer_readonly_struct = true:warning | ||||||
|  | csharp_style_prefer_readonly_struct_member = true | ||||||
|  | 
 | ||||||
|  | # Code-block preferences | ||||||
|  | csharp_prefer_braces = true:error | ||||||
|  | csharp_prefer_simple_using_statement = true:error | ||||||
|  | csharp_prefer_system_threading_lock = true | ||||||
|  | csharp_style_namespace_declarations = block_scoped | ||||||
|  | csharp_style_prefer_method_group_conversion = true:error | ||||||
|  | csharp_style_prefer_primary_constructors = true | ||||||
|  | csharp_style_prefer_top_level_statements = true | ||||||
|  | 
 | ||||||
|  | # Expression-level preferences | ||||||
|  | csharp_prefer_simple_default_expression = true:error | ||||||
|  | csharp_style_deconstructed_variable_declaration = true:error | ||||||
|  | csharp_style_implicit_object_creation_when_type_is_apparent = true:error | ||||||
|  | csharp_style_inlined_variable_declaration = true:error | ||||||
|  | csharp_style_prefer_index_operator = true:error | ||||||
|  | csharp_style_prefer_local_over_anonymous_function = true | ||||||
|  | csharp_style_prefer_null_check_over_type_check = true:error | ||||||
|  | csharp_style_prefer_range_operator = true:error | ||||||
|  | csharp_style_prefer_tuple_swap = true:error | ||||||
|  | csharp_style_prefer_utf8_string_literals = true | ||||||
|  | csharp_style_throw_expression = true | ||||||
|  | csharp_style_unused_value_assignment_preference = discard_variable | ||||||
|  | csharp_style_unused_value_expression_statement_preference = discard_variable | ||||||
|  | 
 | ||||||
|  | # 'using' directive preferences | ||||||
|  | csharp_using_directive_placement = outside_namespace:error | ||||||
|  | 
 | ||||||
|  | # New line preferences | ||||||
|  | csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true | ||||||
|  | csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true | ||||||
|  | csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true | ||||||
|  | csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false:error | ||||||
|  | csharp_style_allow_embedded_statements_on_same_line_experimental = true | ||||||
|  | 
 | ||||||
|  | #### C# Formatting Rules #### | ||||||
|  | 
 | ||||||
|  | # New line preferences | ||||||
|  | csharp_new_line_before_catch = true | ||||||
|  | csharp_new_line_before_else = true | ||||||
|  | csharp_new_line_before_finally = true | ||||||
|  | csharp_new_line_before_members_in_anonymous_types = true | ||||||
|  | csharp_new_line_before_members_in_object_initializers = true | ||||||
|  | csharp_new_line_before_open_brace = all | ||||||
|  | csharp_new_line_between_query_expression_clauses = true | ||||||
|  | 
 | ||||||
|  | # Indentation preferences | ||||||
|  | csharp_indent_block_contents = true | ||||||
|  | csharp_indent_braces = false | ||||||
|  | csharp_indent_case_contents = true | ||||||
|  | csharp_indent_case_contents_when_block = true | ||||||
|  | csharp_indent_labels = one_less_than_current | ||||||
|  | csharp_indent_switch_labels = true | ||||||
|  | 
 | ||||||
|  | # Space preferences | ||||||
|  | csharp_space_after_cast = false | ||||||
|  | csharp_space_after_colon_in_inheritance_clause = true | ||||||
|  | csharp_space_after_comma = true | ||||||
|  | csharp_space_after_dot = false | ||||||
|  | csharp_space_after_keywords_in_control_flow_statements = true | ||||||
|  | csharp_space_after_semicolon_in_for_statement = true | ||||||
|  | csharp_space_around_binary_operators = before_and_after | ||||||
|  | csharp_space_around_declaration_statements = false | ||||||
|  | csharp_space_before_colon_in_inheritance_clause = true | ||||||
|  | csharp_space_before_comma = false | ||||||
|  | csharp_space_before_dot = false | ||||||
|  | csharp_space_before_open_square_brackets = false | ||||||
|  | csharp_space_before_semicolon_in_for_statement = false | ||||||
|  | csharp_space_between_empty_square_brackets = false | ||||||
|  | csharp_space_between_method_call_empty_parameter_list_parentheses = false | ||||||
|  | csharp_space_between_method_call_name_and_opening_parenthesis = false | ||||||
|  | csharp_space_between_method_call_parameter_list_parentheses = false | ||||||
|  | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false | ||||||
|  | csharp_space_between_method_declaration_name_and_open_parenthesis = false | ||||||
|  | csharp_space_between_method_declaration_parameter_list_parentheses = false | ||||||
|  | csharp_space_between_parentheses = false | ||||||
|  | csharp_space_between_square_brackets = false | ||||||
|  | 
 | ||||||
|  | # Wrapping preferences | ||||||
|  | csharp_preserve_single_line_blocks = true | ||||||
|  | csharp_preserve_single_line_statements = false | ||||||
|  | 
 | ||||||
|  | #### Naming styles #### | ||||||
|  | 
 | ||||||
|  | # Naming rules | ||||||
|  | 
 | ||||||
|  | dotnet_naming_rule.private_or_internal_readonly_field_should_be_begins_with__.severity = warning | ||||||
|  | dotnet_naming_rule.private_or_internal_readonly_field_should_be_begins_with__.symbols = private_or_internal_readonly_field | ||||||
|  | dotnet_naming_rule.private_or_internal_readonly_field_should_be_begins_with__.style = begins_with__ | ||||||
|  | 
 | ||||||
|  | dotnet_naming_rule.private_or_internal_field_should_be_begins_with__.severity = warning | ||||||
|  | dotnet_naming_rule.private_or_internal_field_should_be_begins_with__.symbols = private_or_internal_field | ||||||
|  | dotnet_naming_rule.private_or_internal_field_should_be_begins_with__.style = begins_with__ | ||||||
|  | 
 | ||||||
|  | dotnet_naming_rule.private_or_internal_static_field_should_be_begins_with__.severity = warning | ||||||
|  | dotnet_naming_rule.private_or_internal_static_field_should_be_begins_with__.symbols = private_or_internal_static_field | ||||||
|  | dotnet_naming_rule.private_or_internal_static_field_should_be_begins_with__.style = begins_with__ | ||||||
|  | 
 | ||||||
|  | dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion | ||||||
|  | dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface | ||||||
|  | dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i | ||||||
|  | 
 | ||||||
|  | dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion | ||||||
|  | dotnet_naming_rule.types_should_be_pascal_case.symbols = types | ||||||
|  | dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case | ||||||
|  | 
 | ||||||
|  | dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion | ||||||
|  | dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members | ||||||
|  | dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case | ||||||
|  | 
 | ||||||
|  | dotnet_naming_rule.enum_should_be_ends_with_enum.severity = warning | ||||||
|  | dotnet_naming_rule.enum_should_be_ends_with_enum.symbols = enum | ||||||
|  | dotnet_naming_rule.enum_should_be_ends_with_enum.style = ends_with_enum | ||||||
|  | 
 | ||||||
|  | # Symbol specifications | ||||||
|  | 
 | ||||||
|  | dotnet_naming_symbols.interface.applicable_kinds = interface | ||||||
|  | dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected | ||||||
|  | dotnet_naming_symbols.interface.required_modifiers =  | ||||||
|  | 
 | ||||||
|  | dotnet_naming_symbols.enum.applicable_kinds = enum | ||||||
|  | dotnet_naming_symbols.enum.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected | ||||||
|  | dotnet_naming_symbols.enum.required_modifiers =  | ||||||
|  | 
 | ||||||
|  | dotnet_naming_symbols.private_or_internal_field.applicable_kinds = field | ||||||
|  | dotnet_naming_symbols.private_or_internal_field.applicable_accessibilities = internal, private, private_protected | ||||||
|  | dotnet_naming_symbols.private_or_internal_field.required_modifiers =  | ||||||
|  | 
 | ||||||
|  | dotnet_naming_symbols.private_or_internal_static_field.applicable_kinds = field | ||||||
|  | dotnet_naming_symbols.private_or_internal_static_field.applicable_accessibilities = internal, private, private_protected | ||||||
|  | dotnet_naming_symbols.private_or_internal_static_field.required_modifiers = static | ||||||
|  | 
 | ||||||
|  | dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum | ||||||
|  | dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected | ||||||
|  | dotnet_naming_symbols.types.required_modifiers =  | ||||||
|  | 
 | ||||||
|  | dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method | ||||||
|  | dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected | ||||||
|  | dotnet_naming_symbols.non_field_members.required_modifiers =  | ||||||
|  | 
 | ||||||
|  | dotnet_naming_symbols.private_or_internal_readonly_field.applicable_kinds = field | ||||||
|  | dotnet_naming_symbols.private_or_internal_readonly_field.applicable_accessibilities = internal, private, private_protected | ||||||
|  | dotnet_naming_symbols.private_or_internal_readonly_field.required_modifiers = readonly | ||||||
|  | 
 | ||||||
|  | # Naming styles | ||||||
|  | 
 | ||||||
|  | dotnet_naming_style.pascal_case.required_prefix =  | ||||||
|  | dotnet_naming_style.pascal_case.required_suffix =  | ||||||
|  | dotnet_naming_style.pascal_case.word_separator =  | ||||||
|  | dotnet_naming_style.pascal_case.capitalization = pascal_case | ||||||
|  | 
 | ||||||
|  | dotnet_naming_style.begins_with_i.required_prefix = I | ||||||
|  | dotnet_naming_style.begins_with_i.required_suffix =  | ||||||
|  | dotnet_naming_style.begins_with_i.word_separator =  | ||||||
|  | dotnet_naming_style.begins_with_i.capitalization = pascal_case | ||||||
|  | 
 | ||||||
|  | dotnet_naming_style.begins_with__.required_prefix = _ | ||||||
|  | dotnet_naming_style.begins_with__.required_suffix =  | ||||||
|  | dotnet_naming_style.begins_with__.word_separator =  | ||||||
|  | dotnet_naming_style.begins_with__.capitalization = camel_case | ||||||
|  | 
 | ||||||
|  | dotnet_naming_style.ends_with_enum.required_prefix =  | ||||||
|  | dotnet_naming_style.ends_with_enum.required_suffix = Enum | ||||||
|  | dotnet_naming_style.ends_with_enum.word_separator =  | ||||||
|  | dotnet_naming_style.ends_with_enum.capitalization = pascal_case | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | namespace EnotaryoPH.Data.Constants | ||||||
|  | { | ||||||
|  |     public enum DocumentSigningStatus | ||||||
|  |     { | ||||||
|  |         New = 0, | ||||||
|  |         ReadyForSigning = 10, | ||||||
|  |         Signed = 20 | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										8
									
								
								EnotaryoPH/EnotaryoPH.Data/Constants/LawyerStatus.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								EnotaryoPH/EnotaryoPH.Data/Constants/LawyerStatus.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | namespace EnotaryoPH.Data.Constants | ||||||
|  | { | ||||||
|  |     public enum LawyerStatus | ||||||
|  |     { | ||||||
|  |         New = 0, | ||||||
|  |         FingerprintScanned = 5 | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										40
									
								
								EnotaryoPH/EnotaryoPH.Data/Constants/NotaryoEvent.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								EnotaryoPH/EnotaryoPH.Data/Constants/NotaryoEvent.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | |||||||
|  | namespace EnotaryoPH.Data.Constants | ||||||
|  | { | ||||||
|  |     public enum NotaryoEvent | ||||||
|  |     { | ||||||
|  |         Unknown = 0, | ||||||
|  |         PrincipalRegistered = 1, | ||||||
|  |         SignatoryRegistered = 2, | ||||||
|  |         WitnessRegistered = 3, | ||||||
|  |         LawyerRegistered = 4, | ||||||
|  |         LawyerFingerprintScanned = 5, | ||||||
|  | 
 | ||||||
|  |         IdentificationDocumentUploaded = 10, | ||||||
|  | 
 | ||||||
|  |         SelfiePassed = 15, | ||||||
|  |         SelfieFailed = 16, | ||||||
|  | 
 | ||||||
|  |         DocumentUploaded = 20, | ||||||
|  | 
 | ||||||
|  |         LawyerSelected = 30, | ||||||
|  | 
 | ||||||
|  |         TransactionSubmitted = 40, | ||||||
|  |         TransactionApproved = 41, | ||||||
|  |         TransactionRejected = 42, | ||||||
|  | 
 | ||||||
|  |         OTPSent = 45, | ||||||
|  |         OTPVerified = 46, | ||||||
|  | 
 | ||||||
|  |         VideoConferenceStarted = 50, | ||||||
|  |         VideoRecordingStarted = 51, | ||||||
|  |         VideoRecordingStopped = 52, | ||||||
|  | 
 | ||||||
|  |         SignatoryApproved = 61, | ||||||
|  |         WitnessApproved = 62, | ||||||
|  | 
 | ||||||
|  |         PaymentReceived = 70, | ||||||
|  |         PaymentFailed = 71, | ||||||
|  | 
 | ||||||
|  |         TransactionCompleted = 100 | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								EnotaryoPH/EnotaryoPH.Data/Constants/SignatoryStatus.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								EnotaryoPH/EnotaryoPH.Data/Constants/SignatoryStatus.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | namespace EnotaryoPH.Data.Constants | ||||||
|  | { | ||||||
|  |     public enum SignatoryStatus | ||||||
|  |     { | ||||||
|  |         New = 0, | ||||||
|  |         EmailSent = 1, | ||||||
|  |         Registered = 2, | ||||||
|  |         FaceMatch = 3, | ||||||
|  |         Approved = 4, | ||||||
|  |         Rejected = 5, | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								EnotaryoPH/EnotaryoPH.Data/Constants/SignatoryType.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								EnotaryoPH/EnotaryoPH.Data/Constants/SignatoryType.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | namespace EnotaryoPH.Data.Constants | ||||||
|  | { | ||||||
|  |     public enum SignatoryType | ||||||
|  |     { | ||||||
|  |         Unknown = 0, | ||||||
|  |         Principal = 1, | ||||||
|  |         Witness = 2 | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										14
									
								
								EnotaryoPH/EnotaryoPH.Data/Constants/TransactionState.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								EnotaryoPH/EnotaryoPH.Data/Constants/TransactionState.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | namespace EnotaryoPH.Data.Constants | ||||||
|  | { | ||||||
|  |     public enum TransactionState | ||||||
|  |     { | ||||||
|  |         New = 0, | ||||||
|  |         SelfiePassed = 1, | ||||||
|  |         DocumentUploaded = 2, | ||||||
|  |         Submitted = 3, | ||||||
|  |         Accepted = 4, | ||||||
|  |         Approved = 5, | ||||||
|  |         Rejected = 6, | ||||||
|  |         Completed = 100 | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								EnotaryoPH/EnotaryoPH.Data/Constants/UserType.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								EnotaryoPH/EnotaryoPH.Data/Constants/UserType.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | namespace EnotaryoPH.Data.Constants | ||||||
|  | { | ||||||
|  |     public enum UserType | ||||||
|  |     { | ||||||
|  |         Principal = 0, | ||||||
|  |         Witness = 1, | ||||||
|  |         Notary = 2, | ||||||
|  |         SuperUser = 10, | ||||||
|  |         Administrator = 100 | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,11 @@ | |||||||
|  | namespace EnotaryoPH.Data.Constants | ||||||
|  | { | ||||||
|  |     public enum VideoConferenceStatus | ||||||
|  |     { | ||||||
|  |         New = 0, | ||||||
|  |         InProgress = 1, | ||||||
|  |         Expired = 49, | ||||||
|  |         Abandoned = 50, | ||||||
|  |         Completed = 100 | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,10 @@ | |||||||
|  | namespace EnotaryoPH.Data.Constants | ||||||
|  | { | ||||||
|  |     public enum VideoRecordingLocationType | ||||||
|  |     { | ||||||
|  |         Unknown = 0, | ||||||
|  |         LocalFolder = 1, | ||||||
|  |         SharedFolder = 2, | ||||||
|  |         AzureBlob = 3 | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								EnotaryoPH/EnotaryoPH.Data/EnotaryoPH.Data.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								EnotaryoPH/EnotaryoPH.Data/EnotaryoPH.Data.csproj
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | <Project Sdk="Microsoft.NET.Sdk"> | ||||||
|  | 
 | ||||||
|  |   <PropertyGroup> | ||||||
|  |     <TargetFramework>net9.0</TargetFramework> | ||||||
|  |     <ImplicitUsings>enable</ImplicitUsings> | ||||||
|  |     <Nullable>enable</Nullable> | ||||||
|  |   </PropertyGroup> | ||||||
|  | 
 | ||||||
|  |   <ItemGroup> | ||||||
|  |     <PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0" /> | ||||||
|  |     <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.0" /> | ||||||
|  |     <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.2" /> | ||||||
|  |   </ItemGroup> | ||||||
|  | 
 | ||||||
|  | </Project> | ||||||
							
								
								
									
										29
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/ErrorLog.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/ErrorLog.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("ErrorLogs")] | ||||||
|  |     public class ErrorLog | ||||||
|  |     { | ||||||
|  |         [Column("ErrorLogID")] | ||||||
|  |         public int ErrorLogID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Message")] | ||||||
|  |         public string Message { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("CreatedOn")] | ||||||
|  |         public DateTime? CreatedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Severity")] | ||||||
|  |         public string? Severity { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Exception")] | ||||||
|  |         public string? Exception { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Stacktrace")] | ||||||
|  |         public string? Stacktrace { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("ErrorLog_UID")] | ||||||
|  |         public Guid? ErrorLog_UID { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										35
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/EventLog.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/EventLog.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("EventLogs")] | ||||||
|  |     public class EventLog | ||||||
|  |     { | ||||||
|  |         [Column("EventLogID")] | ||||||
|  |         public int EventLogID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("StreamID")] | ||||||
|  |         public string StreamID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("LogType")] | ||||||
|  |         public string LogType { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("LogDate")] | ||||||
|  |         public DateTime? LogDate { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("UserID")] | ||||||
|  |         public int? UserID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Payload")] | ||||||
|  |         public string Payload { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Description")] | ||||||
|  |         public string? Description { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("EventLog_UID")] | ||||||
|  |         public Guid? EventLog_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [ForeignKey("UserID")] | ||||||
|  |         public User User { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,52 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("IdentificationDocuments")] | ||||||
|  |     public class IdentificationDocument | ||||||
|  |     { | ||||||
|  |         [Column("IdentificationDocumentID")] | ||||||
|  |         public int IdentificationDocumentID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Type")] | ||||||
|  |         public string Type { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("ExpirationDate")] | ||||||
|  |         public DateTime ExpirationDate { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Filename")] | ||||||
|  |         public string Filename { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("File")] | ||||||
|  |         public byte[] File { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("UploadedOn")] | ||||||
|  |         public DateTime UploadedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("UserID")] | ||||||
|  |         public int UserID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("IsDeleted")] | ||||||
|  |         public bool? IsDeleted { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("IdNumber")] | ||||||
|  |         public string IdNumber { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("PlaceIssued")] | ||||||
|  |         public string PlaceIssued { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("DateIssued")] | ||||||
|  |         public DateTime DateIssued { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("CreatedOn")] | ||||||
|  |         public DateTime? CreatedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("IdentificationDocument_UID")] | ||||||
|  |         public Guid? IdentificationDocument_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [ForeignKey("UserID")] | ||||||
|  |         public User User { get; set; } | ||||||
|  | 
 | ||||||
|  |         public List<TransactionSelfie> TransactionSelfie { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										61
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/Lawyer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/Lawyer.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("Lawyers")] | ||||||
|  |     public class Lawyer | ||||||
|  |     { | ||||||
|  |         [Column("CommissionExpiration")] | ||||||
|  |         public DateTime? CommissionExpiration { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("CommissionLocation")] | ||||||
|  |         public string? CommissionLocation { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("CommissionNumber")] | ||||||
|  |         public string? CommissionNumber { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("CreatedOn")] | ||||||
|  |         public DateTime? CreatedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("IBPNumber")] | ||||||
|  |         public string? IBPNumber { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Lawyer_UID")] | ||||||
|  |         public Guid? Lawyer_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("LawyerID")] | ||||||
|  |         public int LawyerID { get; set; } | ||||||
|  | 
 | ||||||
|  |         public List<LawyerVideoConferenceSchedule> LawyerVideoConferenceSchedules { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("MCLEComplianceNumber")] | ||||||
|  |         public string? MCLEComplianceNumber { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("MCLEDate")] | ||||||
|  |         public DateTime? MCLEDate { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("OfficeAddress")] | ||||||
|  |         public string? OfficeAddress { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("PTRDate")] | ||||||
|  |         public DateTime? PTRDate { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("PTRlocation")] | ||||||
|  |         public string? PTRlocation { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("PTRNumber")] | ||||||
|  |         public string? PTRNumber { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Rollnumber")] | ||||||
|  |         public string? Rollnumber { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Status")] | ||||||
|  |         public string? Status { get; set; } | ||||||
|  | 
 | ||||||
|  |         [ForeignKey("UserID")] | ||||||
|  |         public User User { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("UserID")] | ||||||
|  |         public int UserID { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,56 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("LawyerVideoConferenceParticipants")] | ||||||
|  |     public class LawyerVideoConferenceParticipant | ||||||
|  |     { | ||||||
|  |         [Column("CreatedOn")] | ||||||
|  |         public DateTime? CreatedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Device")] | ||||||
|  |         public string? Device { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("IPAddress")] | ||||||
|  |         public string? IPAddress { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Latitude")] | ||||||
|  |         public decimal? Latitude { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("LawyerVideoConferenceParticipant_UID")] | ||||||
|  |         public Guid? LawyerVideoConferenceParticipant_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("LawyerVideoConferenceParticipantID")] | ||||||
|  |         public int LawyerVideoConferenceParticipantID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [ForeignKey("LawyerVideoConferenceScheduleID")] | ||||||
|  |         public LawyerVideoConferenceSchedule LawyerVideoConferenceSchedule { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("LawyerVideoConferenceScheduleID")] | ||||||
|  |         public int LawyerVideoConferenceScheduleID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Longitude")] | ||||||
|  |         public decimal? Longitude { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("MeetingRoomTokenID")] | ||||||
|  |         public string? MeetingRoomTokenID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("MeetingRoomUserID")] | ||||||
|  |         public string? MeetingRoomUserID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("OTPEntered")] | ||||||
|  |         public string? OTPEntered { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("OTPHash")] | ||||||
|  |         public string? OTPHash { get; set; } | ||||||
|  | 
 | ||||||
|  |         [ForeignKey("ParticipantID")] | ||||||
|  |         public User Participant { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("ParticipantID")] | ||||||
|  |         public int? ParticipantID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Status")] | ||||||
|  |         public string? Status { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,54 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("LawyerVideoConferenceSchedule")] | ||||||
|  |     public class LawyerVideoConferenceSchedule | ||||||
|  |     { | ||||||
|  |         [Column("CreatedOn")] | ||||||
|  |         public DateTime? CreatedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [ForeignKey("LawyerID")] | ||||||
|  |         public Lawyer Lawyer { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("LawyerID")] | ||||||
|  |         public int LawyerID { get; set; } | ||||||
|  | 
 | ||||||
|  |         public List<LawyerVideoConferenceParticipant> LawyerVideoConferenceParticipants { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("LawyerVideoConferenceSchedule_UID")] | ||||||
|  |         public Guid LawyerVideoConferenceSchedule_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("LawyerVideoConferenceScheduleID")] | ||||||
|  |         public int LawyerVideoConferenceScheduleID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("MeetingDate")] | ||||||
|  |         public DateTime MeetingDate { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("MeetingRoomID")] | ||||||
|  |         public string? MeetingRoomID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("MeetingRoomTokenID")] | ||||||
|  |         public string? MeetingRoomTokenID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("MeetingRoomUserID")] | ||||||
|  |         public string? MeetingRoomUserID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("RecordingID")] | ||||||
|  |         public string? RecordingID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("ServerCallID")] | ||||||
|  |         public string? ServerCallID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Status")] | ||||||
|  |         public string? Status { get; set; } | ||||||
|  | 
 | ||||||
|  |         [ForeignKey("TransactionID")] | ||||||
|  |         public Transaction Transaction { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionID")] | ||||||
|  |         public int TransactionID { get; set; } | ||||||
|  | 
 | ||||||
|  |         public VideoRecording VideoRecording { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										31
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/LookupData.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/LookupData.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("LookupData")] | ||||||
|  |     public class LookupData | ||||||
|  |     { | ||||||
|  |         [Column("Category")] | ||||||
|  |         public string? Category { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("CreatedOn")] | ||||||
|  |         public DateTime? CreatedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Description")] | ||||||
|  |         public string? Description { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("LookupData_UID")] | ||||||
|  |         public Guid LookupData_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("LookupDataID")] | ||||||
|  |         public int LookupDataID { get; set; } | ||||||
|  | 
 | ||||||
|  |         public List<LookupDataValue> LookupDataValues { get; set; } = []; | ||||||
|  | 
 | ||||||
|  |         [Column("Name")] | ||||||
|  |         public string Name { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("ParentCategory")] | ||||||
|  |         public string? ParentCategory { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										32
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/LookupDataValue.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/LookupDataValue.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("LookupDataValues")] | ||||||
|  |     public class LookupDataValue | ||||||
|  |     { | ||||||
|  |         [Column("LookupDataValueID")] | ||||||
|  |         public int LookupDataValueID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("LookupDataValue_UID")] | ||||||
|  |         public Guid LookupDataValue_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("LookupDataID")] | ||||||
|  |         public int? LookupDataID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Value")] | ||||||
|  |         public string Value { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Title")] | ||||||
|  |         public string? Title { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("SortOrder")] | ||||||
|  |         public int? SortOrder { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("CreatedOn")] | ||||||
|  |         public DateTime? CreatedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [ForeignKey("LookupDataID")] | ||||||
|  |         public LookupData LookupData { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										29
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/Template.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/Template.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("Templates")] | ||||||
|  |     public class Template | ||||||
|  |     { | ||||||
|  |         [Column("TemplateID")] | ||||||
|  |         public int TemplateID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Name")] | ||||||
|  |         public string Name { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Description")] | ||||||
|  |         public string? Description { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Pagecount")] | ||||||
|  |         public int? Pagecount { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("CreatedOn")] | ||||||
|  |         public DateTime? CreatedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TemplateUrl")] | ||||||
|  |         public string? TemplateUrl { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Template_UID")] | ||||||
|  |         public Guid? Template_UID { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										52
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/Transaction.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/Transaction.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("Transactions")] | ||||||
|  |     public class Transaction | ||||||
|  |     { | ||||||
|  |         [Column("CreatedOn")] | ||||||
|  |         public DateTime? CreatedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("IsRecorded")] | ||||||
|  |         public bool? IsRecorded { get; set; } | ||||||
|  | 
 | ||||||
|  |         [ForeignKey("LawyerID")] | ||||||
|  |         public Lawyer Lawyer { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("LawyerID")] | ||||||
|  |         public int? LawyerID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [ForeignKey("PreferredLawyerID")] | ||||||
|  |         public Lawyer PreferredLawyer { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("PreferredLawyerID")] | ||||||
|  |         public int? PreferredLawyerID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [ForeignKey("PrincipalID")] | ||||||
|  |         public User Principal { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("PrincipalID")] | ||||||
|  |         public int PrincipalID { get; set; } | ||||||
|  | 
 | ||||||
|  |         public LawyerVideoConferenceSchedule Schedule { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Status")] | ||||||
|  |         public string Status { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Transaction_UID")] | ||||||
|  |         public Guid? Transaction_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionDate")] | ||||||
|  |         public DateTime TransactionDate { get; set; } | ||||||
|  | 
 | ||||||
|  |         public TransactionDocument TransactionDocument { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionID")] | ||||||
|  |         public int TransactionID { get; set; } | ||||||
|  | 
 | ||||||
|  |         public List<TransactionSelfie> TransactionSelfies { get; set; } | ||||||
|  | 
 | ||||||
|  |         public List<TransactionSignatory> TransactionSignatories { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,26 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("TransactionDeclineReasons")] | ||||||
|  |     public class TransactionDeclineReason | ||||||
|  |     { | ||||||
|  |         [Column("TransactionDeclineReasonID")] | ||||||
|  |         public int TransactionDeclineReasonID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionID")] | ||||||
|  |         public int TransactionID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Reason")] | ||||||
|  |         public string Reason { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("LawyerID")] | ||||||
|  |         public int LawyerID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("CreatedOn")] | ||||||
|  |         public DateTime? CreatedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionDeclineReason_UID")] | ||||||
|  |         public Guid? TransactionDeclineReason_UID { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										38
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/TransactionDocument.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/TransactionDocument.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("TransactionDocuments")] | ||||||
|  |     public class TransactionDocument | ||||||
|  |     { | ||||||
|  |         [Column("CreatedOn")] | ||||||
|  |         public DateTime? CreatedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("DocumentType")] | ||||||
|  |         public string DocumentType { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("File")] | ||||||
|  |         public byte[] File { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Filename")] | ||||||
|  |         public string Filename { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Notes")] | ||||||
|  |         public string? Notes { get; set; } | ||||||
|  | 
 | ||||||
|  |         [ForeignKey("TransactionID")] | ||||||
|  |         public Transaction Transaction { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionDocument_UID")] | ||||||
|  |         public Guid? TransactionDocument_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionDocumentID")] | ||||||
|  |         public int TransactionDocumentID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionID")] | ||||||
|  |         public int TransactionID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("UploadedOn")] | ||||||
|  |         public DateTime UploadedOn { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										47
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/TransactionNotary.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/TransactionNotary.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("TransactionNotary")] | ||||||
|  |     public class TransactionNotary | ||||||
|  |     { | ||||||
|  |         [Column("TransactionNotaryID")] | ||||||
|  |         public int TransactionNotaryID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionID")] | ||||||
|  |         public int TransactionID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("DocNumber")] | ||||||
|  |         public string? DocNumber { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("BookNumber")] | ||||||
|  |         public string? BookNumber { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("PageNumber")] | ||||||
|  |         public string? PageNumber { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Series")] | ||||||
|  |         public string? Series { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("SignedOn")] | ||||||
|  |         public DateTime? SignedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Remarks")] | ||||||
|  |         public string? Remarks { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("LawyerID")] | ||||||
|  |         public int LawyerID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("CertificateType")] | ||||||
|  |         public string? CertificateType { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TemplateID")] | ||||||
|  |         public int? TemplateID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("PageCount")] | ||||||
|  |         public int? PageCount { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionNotary_UID")] | ||||||
|  |         public Guid? TransactionNotary_UID { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										50
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/TransactionOTP.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/TransactionOTP.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("TransactionOTP")] | ||||||
|  |     public class TransactionOTP | ||||||
|  |     { | ||||||
|  |         [Column("TransactionOTPID")] | ||||||
|  |         public int TransactionOTPID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionID")] | ||||||
|  |         public int TransactionID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("VerifiedOn")] | ||||||
|  |         public DateTime VerifiedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("PrintCoords")] | ||||||
|  |         public string PrintCoords { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Status")] | ||||||
|  |         public string Status { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("UserID")] | ||||||
|  |         public int UserID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionOTP_UID")] | ||||||
|  |         public Guid? TransactionOTP_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("OTPHash")] | ||||||
|  |         public string OTPHash { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("OTPUserInput")] | ||||||
|  |         public string? OTPUserInput { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("IPAddress")] | ||||||
|  |         public string? IPAddress { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Longitude")] | ||||||
|  |         public int? Longitude { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Lattitude")] | ||||||
|  |         public int? Lattitude { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Device")] | ||||||
|  |         public string? Device { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("File_Liveness")] | ||||||
|  |         public byte[]? File_Liveness { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										35
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/TransactionSelfie.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/TransactionSelfie.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("TransactionSelfies")] | ||||||
|  |     public class TransactionSelfie | ||||||
|  |     { | ||||||
|  |         [Column("TransactionSelfieID")] | ||||||
|  |         public int TransactionSelfieID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionID")] | ||||||
|  |         public int? TransactionID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("IdentificationDocumentID")] | ||||||
|  |         public int? IdentificationDocumentID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("File")] | ||||||
|  |         public byte[] File { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("CreatedOn")] | ||||||
|  |         public DateTime? CreatedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionSelfie_UID")] | ||||||
|  |         public Guid? TransactionSelfie_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("UserID")] | ||||||
|  |         public int UserID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [ForeignKey("UserID")] | ||||||
|  |         public User User { get; set; } | ||||||
|  | 
 | ||||||
|  |         [ForeignKey("TransactionID")] | ||||||
|  |         public Transaction Transaction { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,26 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("TransactionSignatoryDeclineReasons")] | ||||||
|  |     public class TransactionSignatoryDeclineReason | ||||||
|  |     { | ||||||
|  |         [Column("TransactionSignatoryDeclineReasonID")] | ||||||
|  |         public int TransactionSignatoryDeclineReasonID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("UserID")] | ||||||
|  |         public int UserID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("DeclineReason")] | ||||||
|  |         public string DeclineReason { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("CreatedOn")] | ||||||
|  |         public DateTime? CreatedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionSignatoryDeclineReason_UID")] | ||||||
|  |         public Guid TransactionSignatoryDeclineReason_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionID")] | ||||||
|  |         public int TransactionID { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										41
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/Transactionsignatory.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/Transactionsignatory.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("TransactionSignatories")] | ||||||
|  |     public class TransactionSignatory | ||||||
|  |     { | ||||||
|  |         [Column("CreatedOn")] | ||||||
|  |         public DateTime? CreatedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Email")] | ||||||
|  |         public string Email { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("InvitationCode")] | ||||||
|  |         public string InvitationCode { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Status")] | ||||||
|  |         public string Status { get; set; } | ||||||
|  | 
 | ||||||
|  |         [ForeignKey("TransactionID")] | ||||||
|  |         public Transaction Transaction { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionID")] | ||||||
|  |         public int TransactionID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionSignatory_UID")] | ||||||
|  |         public Guid? TransactionSignatory_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("TransactionSignatoryID")] | ||||||
|  |         public int TransactionSignatoryID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Type")] | ||||||
|  |         public string Type { get; set; } | ||||||
|  | 
 | ||||||
|  |         [ForeignKey("UserID")] | ||||||
|  |         public User? User { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("UserID")] | ||||||
|  |         public int? UserID { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										58
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/User.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/User.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("Users")] | ||||||
|  |     public class User | ||||||
|  |     { | ||||||
|  |         [Column("BirthDate")] | ||||||
|  |         public DateTime BirthDate { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("CreatedOn")] | ||||||
|  |         public DateTime? CreatedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Email")] | ||||||
|  |         public string Email { get; set; } | ||||||
|  | 
 | ||||||
|  |         public List<EventLog> EventLogs { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Firstname")] | ||||||
|  |         public string? Firstname { get; set; } | ||||||
|  | 
 | ||||||
|  |         [NotMapped] | ||||||
|  |         public string Fullname => $"{Firstname} {Lastname}".Trim(); | ||||||
|  | 
 | ||||||
|  |         public List<IdentificationDocument> IdentificationDocuments { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Lastname")] | ||||||
|  |         public string? Lastname { get; set; } | ||||||
|  | 
 | ||||||
|  |         public List<LawyerVideoConferenceParticipant> LawyerVideoConferenceParticipants { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Middlename")] | ||||||
|  |         public string? Middlename { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("PasswordHash")] | ||||||
|  |         public string PasswordHash { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("PhoneNumber")] | ||||||
|  |         public string? PhoneNumber { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Prefix")] | ||||||
|  |         public string? Prefix { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Role")] | ||||||
|  |         public string? Role { get; set; } | ||||||
|  | 
 | ||||||
|  |         public List<TransactionSignatory> Signatories { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Suffix")] | ||||||
|  |         public string? Suffix { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("User_UID")] | ||||||
|  |         public Guid? User_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("UserID")] | ||||||
|  |         public int UserID { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										32
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/VideoRecording.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								EnotaryoPH/EnotaryoPH.Data/Entities/VideoRecording.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations.Schema; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Entities | ||||||
|  | { | ||||||
|  |     [Table("VideoRecordings")] | ||||||
|  |     public class VideoRecording | ||||||
|  |     { | ||||||
|  |         [Column("CreatedOn")] | ||||||
|  |         public DateTime? CreatedOn { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("LocationType")] | ||||||
|  |         public string? LocationType { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Metadata")] | ||||||
|  |         public string? Metadata { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("Path")] | ||||||
|  |         public string? Path { get; set; } | ||||||
|  | 
 | ||||||
|  |         [ForeignKey("VideoConferenceScheduleID")] | ||||||
|  |         public LawyerVideoConferenceSchedule VideoConferenceSchedule { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("VideoConferenceScheduleID")] | ||||||
|  |         public int VideoConferenceScheduleID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("VideoRecording_UID")] | ||||||
|  |         public Guid? VideoRecording_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Column("VideoRecordingID")] | ||||||
|  |         public int VideoRecordingID { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,44 @@ | |||||||
|  | using Microsoft.EntityFrameworkCore; | ||||||
|  | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data.Extensions | ||||||
|  | { | ||||||
|  |     public static class ModelBuilderExtension | ||||||
|  |     { | ||||||
|  |         public static ModelBuilder UseValueConverterForType<T>(this ModelBuilder modelBuilder, ValueConverter converter) => modelBuilder.UseValueConverterForType(typeof(T), converter); | ||||||
|  | 
 | ||||||
|  |         public static ModelBuilder UseValueConverterForType(this ModelBuilder modelBuilder, Type type, ValueConverter converter) | ||||||
|  |         { | ||||||
|  |             foreach (var entityType in modelBuilder.Model.GetEntityTypes()) | ||||||
|  |             { | ||||||
|  |                 // note that entityType.GetProperties() will throw an exception, so we have to use reflection | ||||||
|  |                 var properties = entityType.ClrType.GetProperties().Where(p => p.PropertyType == type); | ||||||
|  | 
 | ||||||
|  |                 foreach (var property in properties) | ||||||
|  |                 { | ||||||
|  |                     modelBuilder.Entity(entityType.Name).Property(property.Name) | ||||||
|  |                         .HasConversion(converter); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return modelBuilder; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public class DateTimeKindValueConverter : ValueConverter<DateTime, DateTime> | ||||||
|  |         { | ||||||
|  |             public DateTimeKindValueConverter(DateTimeKind kind, ConverterMappingHints mappingHints = null) | ||||||
|  |                 : base( | ||||||
|  |                     v => v.ToUniversalTime(), | ||||||
|  |                     v => DateTime.SpecifyKind(v, kind), | ||||||
|  |                     mappingHints) | ||||||
|  |             { | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static void SetDefaultDateTimeKind(this ModelBuilder modelBuilder, DateTimeKind kind) | ||||||
|  |         { | ||||||
|  |             modelBuilder.UseValueConverterForType<DateTime>(new DateTimeKindValueConverter(kind)); | ||||||
|  |             modelBuilder.UseValueConverterForType<DateTime?>(new DateTimeKindValueConverter(kind)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										55
									
								
								EnotaryoPH/EnotaryoPH.Data/NotaryoDBContext.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								EnotaryoPH/EnotaryoPH.Data/NotaryoDBContext.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | |||||||
|  | using EnotaryoPH.Data.Entities; | ||||||
|  | using EnotaryoPH.Data.Extensions; | ||||||
|  | using Microsoft.EntityFrameworkCore; | ||||||
|  | using Microsoft.Extensions.Configuration; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Data | ||||||
|  | { | ||||||
|  |     public class NotaryoDBContext : DbContext | ||||||
|  |     { | ||||||
|  |         private readonly IConfiguration _configuration; | ||||||
|  | 
 | ||||||
|  |         public NotaryoDBContext(IConfiguration configuration, DbContextOptions<NotaryoDBContext> Options) : base(Options) => _configuration = configuration; | ||||||
|  | 
 | ||||||
|  |         protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseNpgsql(_configuration.GetConnectionString("NotaryoDatabase")); | ||||||
|  | 
 | ||||||
|  |         protected override void OnModelCreating(ModelBuilder modelBuilder) | ||||||
|  |         { | ||||||
|  |             modelBuilder.SetDefaultDateTimeKind(DateTimeKind.Utc); | ||||||
|  |             base.OnModelCreating(modelBuilder); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public DbSet<ErrorLog> ErrorLogs { get; set; } | ||||||
|  |         public DbSet<EventLog> EventLogs { get; set; } | ||||||
|  |         public DbSet<IdentificationDocument> IdentificationDocuments { get; set; } | ||||||
|  |         public DbSet<Lawyer> Lawyers { get; set; } | ||||||
|  |         public DbSet<LawyerVideoConferenceParticipant> LawyerVideoConferenceParticipants { get; set; } | ||||||
|  |         public DbSet<LawyerVideoConferenceSchedule> LawyerVideoConferenceSchedules { get; set; } | ||||||
|  |         public DbSet<LookupData> LookupData { get; set; } | ||||||
|  |         public DbSet<LookupDataValue> LookupDataValues { get; set; } | ||||||
|  |         public DbSet<Template> Templates { get; set; } | ||||||
|  |         public DbSet<TransactionDeclineReason> TransactionDeclineReasons { get; set; } | ||||||
|  |         public DbSet<TransactionDocument> TransactionDocuments { get; set; } | ||||||
|  |         public DbSet<TransactionNotary> TransactionNotaries { get; set; } | ||||||
|  |         public DbSet<TransactionOTP> TransactionOTPs { get; set; } | ||||||
|  |         public DbSet<Transaction> Transactions { get; set; } | ||||||
|  |         public DbSet<TransactionSelfie> TransactionSelfies { get; set; } | ||||||
|  |         public DbSet<TransactionSignatory> TransactionSignatories { get; set; } | ||||||
|  |         public DbSet<TransactionSignatoryDeclineReason> TransactionSignatoryDeclineReasons { get; set; } | ||||||
|  |         public DbSet<User> Users { get; set; } | ||||||
|  |         public DbSet<VideoRecording> VideoRecordings { get; set; } | ||||||
|  | 
 | ||||||
|  |         public TEntity UpdateOrCreate<TEntity>(TEntity entity) where TEntity : class | ||||||
|  |         { | ||||||
|  |             if (Entry(entity).State == EntityState.Detached) | ||||||
|  |             { | ||||||
|  |                 Set<TEntity>().Add(entity); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 Set<TEntity>().Update(entity); | ||||||
|  |             } | ||||||
|  |             return entity; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,36 @@ | |||||||
|  | <Project Sdk="Microsoft.NET.Sdk"> | ||||||
|  | 
 | ||||||
|  |   <PropertyGroup> | ||||||
|  |     <OutputType>Exe</OutputType> | ||||||
|  |     <TargetFramework>net9.0</TargetFramework> | ||||||
|  |     <ImplicitUsings>enable</ImplicitUsings> | ||||||
|  |     <Nullable>enable</Nullable> | ||||||
|  |     <UserSecretsId>d6cabec2-f14e-40aa-b2ef-90a832d8e1e4</UserSecretsId> | ||||||
|  |   </PropertyGroup> | ||||||
|  | 
 | ||||||
|  |   <ItemGroup> | ||||||
|  |     <None Remove="Scripts\01_Schema.sql" /> | ||||||
|  |   </ItemGroup> | ||||||
|  | 
 | ||||||
|  |   <ItemGroup> | ||||||
|  |     <EmbeddedResource Include="Scripts\04_EventLog_StreamID.sql" /> | ||||||
|  |     <EmbeddedResource Include="Scripts\03_UserTracker.sql" /> | ||||||
|  |     <EmbeddedResource Include="Scripts\02_SeedLookupData.sql" /> | ||||||
|  |     <EmbeddedResource Include="Scripts\01_Schema.sql" /> | ||||||
|  |   </ItemGroup> | ||||||
|  | 
 | ||||||
|  |   <ItemGroup> | ||||||
|  |     <PackageReference Include="dbup-core" Version="6.0.4" /> | ||||||
|  |     <PackageReference Include="dbup-postgresql" Version="6.0.3" /> | ||||||
|  |     <PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.4" /> | ||||||
|  |     <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.4" /> | ||||||
|  |     <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.4" /> | ||||||
|  |   </ItemGroup> | ||||||
|  | 
 | ||||||
|  |   <ItemGroup> | ||||||
|  |     <None Update="appsettings.json"> | ||||||
|  |       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||||||
|  |     </None> | ||||||
|  |   </ItemGroup> | ||||||
|  | 
 | ||||||
|  | </Project> | ||||||
							
								
								
									
										57
									
								
								EnotaryoPH/EnotaryoPH.DbMigration/Program.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								EnotaryoPH/EnotaryoPH.DbMigration/Program.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | |||||||
|  | using System.Reflection; | ||||||
|  | using DbUp; | ||||||
|  | using Microsoft.Extensions.Configuration; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.DbMigration | ||||||
|  | { | ||||||
|  |     internal class Program | ||||||
|  |     { | ||||||
|  |         private static int Main(string[] args) | ||||||
|  |         { | ||||||
|  |             Console.ForegroundColor = ConsoleColor.Yellow; | ||||||
|  | 
 | ||||||
|  |             var config = new ConfigurationBuilder() | ||||||
|  |                 .AddJsonFile("appsettings.json") | ||||||
|  |                 .Build(); | ||||||
|  |             var connectionString = | ||||||
|  |                 args.FirstOrDefault() | ||||||
|  |                 ?? config.GetConnectionString("DbUpConnection"); | ||||||
|  | 
 | ||||||
|  |             var upgrader = | ||||||
|  |                 DeployChanges.To | ||||||
|  |                     .PostgresqlDatabase(connectionString) | ||||||
|  |                     .WithVariablesDisabled() | ||||||
|  |                     .WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly()) | ||||||
|  |                     .LogToConsole() | ||||||
|  |                     .Build(); | ||||||
|  | 
 | ||||||
|  |             if (upgrader.TryConnect(out var err)) | ||||||
|  |             { | ||||||
|  |                 var result = upgrader.PerformUpgrade(); | ||||||
|  | 
 | ||||||
|  |                 if (!result.Successful) | ||||||
|  |                 { | ||||||
|  |                     Console.ForegroundColor = ConsoleColor.Red; | ||||||
|  |                     Console.WriteLine(result.Error); | ||||||
|  |                     Console.ResetColor(); | ||||||
|  | #if DEBUG | ||||||
|  |                     Console.ReadLine(); | ||||||
|  | #endif | ||||||
|  |                     return -1; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 Console.ForegroundColor = ConsoleColor.Red; | ||||||
|  |                 Console.WriteLine($"Cannot Connect: '{err}'"); | ||||||
|  |                 Console.ResetColor(); | ||||||
|  |                 return -1; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             Console.ForegroundColor = ConsoleColor.Green; | ||||||
|  |             Console.WriteLine("Success!"); | ||||||
|  |             Console.ResetColor(); | ||||||
|  |             return 0; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										715
									
								
								EnotaryoPH/EnotaryoPH.DbMigration/Scripts/01_Schema.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										715
									
								
								EnotaryoPH/EnotaryoPH.DbMigration/Scripts/01_Schema.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,715 @@ | |||||||
|  |  | ||||||
|  | 
 | ||||||
|  | CREATE EXTENSION if not EXISTS "uuid-ossp" | ||||||
|  | 	SCHEMA "public" | ||||||
|  | 	VERSION "1.1"; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- DROP SCHEMA public; | ||||||
|  | 
 | ||||||
|  | CREATE SCHEMA IF NOT EXISTS public AUTHORIZATION pg_database_owner; | ||||||
|  | 
 | ||||||
|  | -- DROP SEQUENCE "LawyerVideoConferenceParticip_LawyerVideoConferenceParticip_seq"; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE "LawyerVideoConferenceParticip_LawyerVideoConferenceParticip_seq" | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 9223372036854775807 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE; | ||||||
|  | -- DROP SEQUENCE "LawyerVideoConferenceSchedule_LawyerVideoConferenceSchedule_seq"; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE "LawyerVideoConferenceSchedule_LawyerVideoConferenceSchedule_seq" | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 9223372036854775807 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE; | ||||||
|  | -- DROP SEQUENCE "LookupDataValues_LookupDataValueID_seq"; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE "LookupDataValues_LookupDataValueID_seq" | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 9223372036854775807 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE; | ||||||
|  | -- DROP SEQUENCE "LookupData_LookupDataID_seq"; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE "LookupData_LookupDataID_seq" | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 9223372036854775807 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE; | ||||||
|  | -- DROP SEQUENCE "TransactionDeclineReasons_TransactionDeclineReasonID_seq"; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE "TransactionDeclineReasons_TransactionDeclineReasonID_seq" | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 9223372036854775807 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE; | ||||||
|  | -- DROP SEQUENCE "TransactionSelfies_TransactionSelfieID_seq"; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE "TransactionSelfies_TransactionSelfieID_seq" | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 9223372036854775807 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE; | ||||||
|  | -- DROP SEQUENCE "TransactionSignatoryDeclineRe_TransactionSignatoryDeclineRe_seq"; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE "TransactionSignatoryDeclineRe_TransactionSignatoryDeclineRe_seq" | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 9223372036854775807 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE; | ||||||
|  | -- DROP SEQUENCE "VideoRecordings_VideoRecordingID_seq"; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE "VideoRecordings_VideoRecordingID_seq" | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 9223372036854775807 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE; | ||||||
|  | -- DROP SEQUENCE errorlogs_errorlogid_seq; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE errorlogs_errorlogid_seq | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 9223372036854775807 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE; | ||||||
|  | -- DROP SEQUENCE eventlogs_eventlogid_seq; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE eventlogs_eventlogid_seq | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 9223372036854775807 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE; | ||||||
|  | -- DROP SEQUENCE identificationdocuments_identificationdocumentid_seq; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE identificationdocuments_identificationdocumentid_seq | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 9223372036854775807 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE; | ||||||
|  | -- DROP SEQUENCE lawyers_lawyerid_seq; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE lawyers_lawyerid_seq | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 9223372036854775807 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE; | ||||||
|  | -- DROP SEQUENCE templates_templateid_seq; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE templates_templateid_seq | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 2147483647 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE; | ||||||
|  | -- DROP SEQUENCE transactiondocuments_transactiondocumentid_seq; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE transactiondocuments_transactiondocumentid_seq | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 9223372036854775807 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE; | ||||||
|  | -- DROP SEQUENCE transactionnotary_transactionnotaryid_seq; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE transactionnotary_transactionnotaryid_seq | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 9223372036854775807 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE; | ||||||
|  | -- DROP SEQUENCE transactionotp_transactionotpid_seq; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE transactionotp_transactionotpid_seq | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 9223372036854775807 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE; | ||||||
|  | -- DROP SEQUENCE transactions_transactionid_seq; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE transactions_transactionid_seq | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 9223372036854775807 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE; | ||||||
|  | -- DROP SEQUENCE transactionsignatories_transactionsignatoryid_seq; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE transactionsignatories_transactionsignatoryid_seq | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 9223372036854775807 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE; | ||||||
|  | -- DROP SEQUENCE users_userid_seq; | ||||||
|  | 
 | ||||||
|  | CREATE SEQUENCE users_userid_seq | ||||||
|  | 	INCREMENT BY 1 | ||||||
|  | 	MINVALUE 1 | ||||||
|  | 	MAXVALUE 9223372036854775807 | ||||||
|  | 	START 1 | ||||||
|  | 	CACHE 1 | ||||||
|  | 	NO CYCLE;-- public."ErrorLogs" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "ErrorLogs"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "ErrorLogs" ( | ||||||
|  | 	"ErrorLogID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"Message" varchar NOT NULL, | ||||||
|  | 	"CreatedOn" timestamp DEFAULT now() NULL, | ||||||
|  | 	"Severity" varchar NULL, | ||||||
|  | 	"Exception" varchar NULL, | ||||||
|  | 	"Stacktrace" varchar NULL, | ||||||
|  | 	"ErrorLog_UID" uuid DEFAULT uuid_generate_v4() NULL, | ||||||
|  | 	CONSTRAINT errorlogs_pk PRIMARY KEY ("ErrorLogID") | ||||||
|  | ); | ||||||
|  | CREATE INDEX "ErrorLogs_CreatedOn_IDX" ON public."ErrorLogs" USING btree ("CreatedOn" DESC); | ||||||
|  | CREATE UNIQUE INDEX "ErrorLogs_ErrorLog_UID_IDX" ON public."ErrorLogs" USING btree ("ErrorLog_UID"); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."LookupData" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "LookupData"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "LookupData" ( | ||||||
|  | 	"LookupDataID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"LookupData_UID" uuid DEFAULT uuid_generate_v4() NOT NULL, | ||||||
|  | 	"Category" varchar NULL, | ||||||
|  | 	"ParentCategory" varchar NULL, | ||||||
|  | 	"Name" varchar NOT NULL, | ||||||
|  | 	"Description" varchar NULL, | ||||||
|  | 	"CreatedOn" timestamp DEFAULT now() NULL, | ||||||
|  | 	CONSTRAINT "LookupData_pk" PRIMARY KEY ("LookupDataID"), | ||||||
|  | 	CONSTRAINT "LookupData_unique" UNIQUE ("LookupData_UID") | ||||||
|  | ); | ||||||
|  | CREATE UNIQUE INDEX "LookupData_Name_Category_IDX" ON public."LookupData" USING btree ("Name", "Category"); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."Templates" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "Templates"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "Templates" ( | ||||||
|  | 	"TemplateID" int4 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"Name" varchar NOT NULL, | ||||||
|  | 	"Description" varchar NULL, | ||||||
|  | 	"Pagecount" int4 NULL, | ||||||
|  | 	"CreatedOn" timestamp DEFAULT now() NULL, | ||||||
|  | 	"TemplateUrl" varchar NULL, | ||||||
|  | 	"Template_UID" uuid DEFAULT uuid_generate_v4() NULL, | ||||||
|  | 	CONSTRAINT templates_pk PRIMARY KEY ("TemplateID") | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."Users" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "Users"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "Users" ( | ||||||
|  | 	"UserID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"Email" varchar NOT NULL, | ||||||
|  | 	"PasswordHash" varchar NOT NULL, | ||||||
|  | 	"PhoneNumber" varchar NULL, | ||||||
|  | 	"Firstname" varchar NULL, | ||||||
|  | 	"Lastname" varchar NULL, | ||||||
|  | 	"CreatedOn" timestamp DEFAULT now() NULL, | ||||||
|  | 	"User_UID" uuid DEFAULT uuid_generate_v4() NULL, | ||||||
|  | 	"Role" varchar DEFAULT 'user'::character varying NULL, | ||||||
|  | 	"BirthDate" date NOT NULL, | ||||||
|  | 	"Middlename" varchar NULL, | ||||||
|  | 	"Suffix" varchar NULL, | ||||||
|  | 	"Prefix" varchar NULL, | ||||||
|  | 	CONSTRAINT users_pk PRIMARY KEY ("UserID"), | ||||||
|  | 	CONSTRAINT users_unique_email UNIQUE ("Email"), | ||||||
|  | 	CONSTRAINT users_unique_uid UNIQUE ("User_UID") | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."EventLogs" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "EventLogs"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "EventLogs" ( | ||||||
|  | 	"EventLogID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"StreamID" int8 NOT NULL, | ||||||
|  | 	"LogType" varchar NOT NULL, | ||||||
|  | 	"LogDate" time DEFAULT now() NULL, | ||||||
|  | 	"UserID" int8 NULL, | ||||||
|  | 	"Payload" varchar NOT NULL, | ||||||
|  | 	"Description" varchar NULL, | ||||||
|  | 	"EventLog_UID" uuid DEFAULT uuid_generate_v4() NULL, | ||||||
|  | 	CONSTRAINT eventlogs_pk PRIMARY KEY ("EventLogID"), | ||||||
|  | 	CONSTRAINT eventlogs_users_fk FOREIGN KEY ("UserID") REFERENCES "Users"("UserID") | ||||||
|  | ); | ||||||
|  | CREATE UNIQUE INDEX "EventLogs_EventLog_UID_IDX" ON public."EventLogs" USING btree ("EventLog_UID"); | ||||||
|  | CREATE INDEX "EventLogs_LogDate_IDX" ON public."EventLogs" USING btree ("LogDate" DESC); | ||||||
|  | CREATE INDEX "EventLogs_StreamID_IDX" ON public."EventLogs" USING btree ("StreamID"); | ||||||
|  | CREATE INDEX "EventLogs_UserID_IDX" ON public."EventLogs" USING btree ("UserID"); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."IdentificationDocuments" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "IdentificationDocuments"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "IdentificationDocuments" ( | ||||||
|  | 	"IdentificationDocumentID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"Type" varchar NOT NULL, | ||||||
|  | 	"ExpirationDate" date NOT NULL, | ||||||
|  | 	"Filename" varchar NOT NULL, | ||||||
|  | 	"File" bytea NOT NULL, | ||||||
|  | 	"UserID" int8 NOT NULL, | ||||||
|  | 	"IdNumber" varchar NOT NULL, | ||||||
|  | 	"PlaceIssued" varchar NOT NULL, | ||||||
|  | 	"DateIssued" date NOT NULL, | ||||||
|  | 	"CreatedOn" timestamp DEFAULT now() NOT NULL, | ||||||
|  | 	"IdentificationDocument_UID" uuid DEFAULT uuid_generate_v4() NOT NULL, | ||||||
|  | 	"IsDeleted" bool NULL, | ||||||
|  | 	"UploadedOn" timestamp NOT NULL, | ||||||
|  | 	CONSTRAINT identificationdocuments_pk PRIMARY KEY ("IdentificationDocumentID"), | ||||||
|  | 	CONSTRAINT identificationdocuments_users_fk FOREIGN KEY ("UserID") REFERENCES "Users"("UserID") | ||||||
|  | ); | ||||||
|  | CREATE UNIQUE INDEX "IdentificationDocuments_IdentificationDocument_UID_IDX" ON public."IdentificationDocuments" USING btree ("IdentificationDocument_UID"); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."Lawyers" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "Lawyers"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "Lawyers" ( | ||||||
|  | 	"LawyerID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"Rollnumber" varchar NULL, | ||||||
|  | 	"IBPNumber" varchar NULL, | ||||||
|  | 	"MCLEComplianceNumber" varchar NULL, | ||||||
|  | 	"MCLEDate" date NULL, | ||||||
|  | 	"PTRNumber" varchar NULL, | ||||||
|  | 	"PTRDate" date NULL, | ||||||
|  | 	"PTRlocation" varchar NULL, | ||||||
|  | 	"OfficeAddress" varchar NULL, | ||||||
|  | 	"UserID" int8 NOT NULL, | ||||||
|  | 	"Lawyer_UID" uuid DEFAULT uuid_generate_v4() NULL, | ||||||
|  | 	"CreatedOn" timestamp DEFAULT now() NULL, | ||||||
|  | 	"CommissionNumber" varchar NULL, | ||||||
|  | 	"CommissionLocation" varchar NULL, | ||||||
|  | 	"CommissionExpiration" date NULL, | ||||||
|  | 	"Status" varchar DEFAULT 'Registered'::character varying NULL, | ||||||
|  | 	CONSTRAINT lawyers_pk PRIMARY KEY ("LawyerID"), | ||||||
|  | 	CONSTRAINT lawyers_users_fk FOREIGN KEY ("UserID") REFERENCES "Users"("UserID") | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."LookupDataValues" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "LookupDataValues"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "LookupDataValues" ( | ||||||
|  | 	"LookupDataValueID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"LookupDataValue_UID" uuid DEFAULT uuid_generate_v4() NOT NULL, | ||||||
|  | 	"LookupDataID" int8 NULL, | ||||||
|  | 	"Value" varchar NOT NULL, | ||||||
|  | 	"Title" varchar NULL, | ||||||
|  | 	"SortOrder" int4 NULL, | ||||||
|  | 	"CreatedOn" timestamp DEFAULT now() NULL, | ||||||
|  | 	CONSTRAINT "LookupDataValues_pk" PRIMARY KEY ("LookupDataValueID"), | ||||||
|  | 	CONSTRAINT "LookupDataValues_unique" UNIQUE ("LookupDataValue_UID"), | ||||||
|  | 	CONSTRAINT "LookupDataValues_LookupData_FK" FOREIGN KEY ("LookupDataID") REFERENCES "LookupData"("LookupDataID") | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."Transactions" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "Transactions"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "Transactions" ( | ||||||
|  | 	"TransactionID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"TransactionDate" date NOT NULL, | ||||||
|  | 	"PrincipalID" int8 NOT NULL, | ||||||
|  | 	"Status" varchar NOT NULL, | ||||||
|  | 	"CreatedOn" timestamp DEFAULT now() NULL, | ||||||
|  | 	"Transaction_UID" uuid DEFAULT uuid_generate_v4() NULL, | ||||||
|  | 	"PreferredLawyerID" int8 NULL, | ||||||
|  | 	"LawyerID" int8 NULL, | ||||||
|  | 	"IsRecorded" bool NULL, | ||||||
|  | 	CONSTRAINT transactions_pk PRIMARY KEY ("TransactionID"), | ||||||
|  | 	CONSTRAINT "Transactions_Lawyers_FK" FOREIGN KEY ("LawyerID") REFERENCES "Lawyers"("LawyerID"), | ||||||
|  | 	CONSTRAINT "Transactions_PreferredLawyers_FK" FOREIGN KEY ("PreferredLawyerID") REFERENCES "Lawyers"("LawyerID"), | ||||||
|  | 	CONSTRAINT "Transactions_Users_FK" FOREIGN KEY ("PrincipalID") REFERENCES "Users"("UserID") | ||||||
|  | ); | ||||||
|  | CREATE INDEX "Transactions_TransactionDate_IDX" ON public."Transactions" USING btree ("TransactionDate" DESC); | ||||||
|  | CREATE UNIQUE INDEX "Transactions_Transaction_UID_IDX" ON public."Transactions" USING btree ("Transaction_UID"); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."LawyerVideoConferenceSchedule" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "LawyerVideoConferenceSchedule"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "LawyerVideoConferenceSchedule" ( | ||||||
|  | 	"LawyerVideoConferenceScheduleID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"LawyerID" int8 NOT NULL, | ||||||
|  | 	"TransactionID" int8 NOT NULL, | ||||||
|  | 	"MeetingDate" timestamp NOT NULL, | ||||||
|  | 	"CreatedOn" timestamp DEFAULT now() NULL, | ||||||
|  | 	"LawyerVideoConferenceSchedule_UID" uuid DEFAULT uuid_generate_v4() NULL, | ||||||
|  | 	"Status" varchar NULL, | ||||||
|  | 	"MeetingRoomID" varchar NULL, | ||||||
|  | 	"MeetingRoomTokenID" varchar NULL, | ||||||
|  | 	"MeetingRoomUserID" varchar NULL, | ||||||
|  | 	"ServerCallID" varchar NULL, | ||||||
|  | 	"RecordingID" varchar NULL, | ||||||
|  | 	CONSTRAINT "LawyerVideoConferenceSchedule_pk" PRIMARY KEY ("LawyerVideoConferenceScheduleID"), | ||||||
|  | 	CONSTRAINT "LawyerVideoConferenceSchedule_unique" UNIQUE ("LawyerVideoConferenceSchedule_UID"), | ||||||
|  | 	CONSTRAINT "LawyerVideoConferenceSchedule_Lawyers_FK" FOREIGN KEY ("LawyerID") REFERENCES "Lawyers"("LawyerID"), | ||||||
|  | 	CONSTRAINT "LawyerVideoConferenceSchedule_Transactions_FK" FOREIGN KEY ("TransactionID") REFERENCES "Transactions"("TransactionID") | ||||||
|  | ); | ||||||
|  | CREATE INDEX "LawyerVideoConferenceSchedule_RecordingID_IDX" ON public."LawyerVideoConferenceSchedule" USING btree ("RecordingID"); | ||||||
|  | CREATE INDEX "LawyerVideoConferenceSchedule_TransactionID_IDX" ON public."LawyerVideoConferenceSchedule" USING btree ("TransactionID"); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."TransactionDeclineReasons" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "TransactionDeclineReasons"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "TransactionDeclineReasons" ( | ||||||
|  | 	"TransactionDeclineReasonID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"TransactionID" int8 NOT NULL, | ||||||
|  | 	"Reason" varchar NOT NULL, | ||||||
|  | 	"LawyerID" int8 NOT NULL, | ||||||
|  | 	"CreatedOn" timestamp DEFAULT now() NULL, | ||||||
|  | 	"TransactionDeclineReason_UID" uuid DEFAULT uuid_generate_v4() NULL, | ||||||
|  | 	CONSTRAINT "TransactionDeclineReasons_pk" PRIMARY KEY ("TransactionDeclineReasonID"), | ||||||
|  | 	CONSTRAINT "TransactionDeclineReasons_Lawyers_FK" FOREIGN KEY ("LawyerID") REFERENCES "Lawyers"("LawyerID"), | ||||||
|  | 	CONSTRAINT "TransactionDeclineReasons_Transactions_FK" FOREIGN KEY ("TransactionID") REFERENCES "Transactions"("TransactionID") | ||||||
|  | ); | ||||||
|  | CREATE UNIQUE INDEX "TransactionDeclineReasons_TransactionDeclineReason_UID_IDX" ON public."TransactionDeclineReasons" USING btree ("TransactionDeclineReason_UID"); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."TransactionDocuments" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "TransactionDocuments"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "TransactionDocuments" ( | ||||||
|  | 	"TransactionDocumentID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"TransactionID" int8 NOT NULL, | ||||||
|  | 	"Filename" varchar NOT NULL, | ||||||
|  | 	"Notes" varchar NULL, | ||||||
|  | 	"File" bytea NOT NULL, | ||||||
|  | 	"UploadedOn" timestamp NOT NULL, | ||||||
|  | 	"CreatedOn" timestamp DEFAULT now() NULL, | ||||||
|  | 	"TransactionDocument_UID" uuid DEFAULT uuid_generate_v4() NULL, | ||||||
|  | 	"DocumentType" varchar NOT NULL, | ||||||
|  | 	CONSTRAINT transactiondocuments_pk PRIMARY KEY ("TransactionDocumentID"), | ||||||
|  | 	CONSTRAINT transactiondocuments_transactions_fk FOREIGN KEY ("TransactionID") REFERENCES "Transactions"("TransactionID") | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."TransactionNotary" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "TransactionNotary"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "TransactionNotary" ( | ||||||
|  | 	"TransactionNotaryID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"TransactionID" int8 NOT NULL, | ||||||
|  | 	"DocNumber" varchar NULL, | ||||||
|  | 	"BookNumber" varchar NULL, | ||||||
|  | 	"PageNumber" varchar NULL, | ||||||
|  | 	"Series" varchar NULL, | ||||||
|  | 	"SignedOn" date NULL, | ||||||
|  | 	"Remarks" varchar NULL, | ||||||
|  | 	"LawyerID" int8 NOT NULL, | ||||||
|  | 	"CertificateType" varchar NULL, | ||||||
|  | 	"TemplateID" int4 NULL, | ||||||
|  | 	"PageCount" int4 NULL, | ||||||
|  | 	"TransactionNotary_UID" uuid DEFAULT uuid_generate_v4() NULL, | ||||||
|  | 	CONSTRAINT transactionnotary_pk PRIMARY KEY ("TransactionNotaryID"), | ||||||
|  | 	CONSTRAINT transactionnotary_lawyers_fk FOREIGN KEY ("LawyerID") REFERENCES "Lawyers"("LawyerID"), | ||||||
|  | 	CONSTRAINT transactionnotary_templates_fk FOREIGN KEY ("TemplateID") REFERENCES "Templates"("TemplateID"), | ||||||
|  | 	CONSTRAINT transactionnotary_transactions_fk FOREIGN KEY ("TransactionID") REFERENCES "Transactions"("TransactionID") | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."TransactionOTP" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "TransactionOTP"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "TransactionOTP" ( | ||||||
|  | 	"TransactionOTPID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"TransactionID" int8 NOT NULL, | ||||||
|  | 	"VerifiedOn" time NOT NULL, | ||||||
|  | 	"PrintCoords" varchar NOT NULL, | ||||||
|  | 	"Status" varchar NOT NULL, | ||||||
|  | 	"UserID" int8 NOT NULL, | ||||||
|  | 	"TransactionOTP_UID" uuid DEFAULT uuid_generate_v4() NULL, | ||||||
|  | 	"OTPHash" varchar NOT NULL, | ||||||
|  | 	"OTPUserInput" varchar NULL, | ||||||
|  | 	"IPAddress" varchar NULL, | ||||||
|  | 	"Longitude" numeric NULL, | ||||||
|  | 	"Lattitude" numeric NULL, | ||||||
|  | 	"Device" varchar NULL, | ||||||
|  | 	"File_Liveness" bytea NULL, | ||||||
|  | 	CONSTRAINT transactionotp_pk PRIMARY KEY ("TransactionOTPID"), | ||||||
|  | 	CONSTRAINT "TransactionOTP_Users_FK" FOREIGN KEY ("UserID") REFERENCES "Users"("UserID"), | ||||||
|  | 	CONSTRAINT transactionotp_transactions_fk FOREIGN KEY ("TransactionID") REFERENCES "Transactions"("TransactionID") | ||||||
|  | ); | ||||||
|  | CREATE INDEX "TransactionOTP_TransactionID_IDX" ON public."TransactionOTP" USING btree ("TransactionID"); | ||||||
|  | CREATE UNIQUE INDEX "TransactionOTP_TransactionOTP_UID_IDX" ON public."TransactionOTP" USING btree ("TransactionOTP_UID"); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."TransactionSelfies" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "TransactionSelfies"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "TransactionSelfies" ( | ||||||
|  | 	"TransactionSelfieID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"TransactionID" int8 NULL, | ||||||
|  | 	"IdentificationDocumentID" int8 NULL, | ||||||
|  | 	"File" bytea NOT NULL, | ||||||
|  | 	"CreatedOn" timestamp DEFAULT now() NULL, | ||||||
|  | 	"TransactionSelfie_UID" uuid DEFAULT uuid_generate_v4() NULL, | ||||||
|  | 	"UserID" int8 NOT NULL, | ||||||
|  | 	CONSTRAINT "TransactionSelfies_pk" PRIMARY KEY ("TransactionSelfieID"), | ||||||
|  | 	CONSTRAINT "TransactionSelfies_IdentificationDocuments_FK" FOREIGN KEY ("IdentificationDocumentID") REFERENCES "IdentificationDocuments"("IdentificationDocumentID"), | ||||||
|  | 	CONSTRAINT "TransactionSelfies_Transactions_FK" FOREIGN KEY ("TransactionID") REFERENCES "Transactions"("TransactionID"), | ||||||
|  | 	CONSTRAINT "TransactionSelfies_Users_FK" FOREIGN KEY ("UserID") REFERENCES "Users"("UserID") | ||||||
|  | ); | ||||||
|  | CREATE UNIQUE INDEX "TransactionSelfies_TransactionSelfie_UID_IDX" ON public."TransactionSelfies" USING btree ("TransactionSelfie_UID"); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."TransactionSignatories" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "TransactionSignatories"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "TransactionSignatories" ( | ||||||
|  | 	"TransactionSignatoryID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"TransactionID" int8 NOT NULL, | ||||||
|  | 	"UserID" int8 NULL, | ||||||
|  | 	"CreatedOn" timestamp DEFAULT now() NULL, | ||||||
|  | 	"Status" varchar NOT NULL, | ||||||
|  | 	"Email" varchar NOT NULL, | ||||||
|  | 	"Type" varchar NOT NULL, | ||||||
|  | 	"TransactionSignatory_UID" uuid DEFAULT uuid_generate_v4() NULL, | ||||||
|  | 	"InvitationCode" varchar NOT NULL, | ||||||
|  | 	CONSTRAINT transactionsignatories_pk PRIMARY KEY ("TransactionSignatoryID"), | ||||||
|  | 	CONSTRAINT transactionsignatories_transactions_fk FOREIGN KEY ("TransactionID") REFERENCES "Transactions"("TransactionID"), | ||||||
|  | 	CONSTRAINT transactionsignatories_users_fk FOREIGN KEY ("UserID") REFERENCES "Users"("UserID") | ||||||
|  | ); | ||||||
|  | CREATE INDEX "TransactionSignatories_InvitationCode_IDX" ON public."TransactionSignatories" USING btree ("InvitationCode"); | ||||||
|  | CREATE INDEX "TransactionSignatories_TransactionID_IDX" ON public."TransactionSignatories" USING btree ("TransactionID", "Email"); | ||||||
|  | CREATE UNIQUE INDEX "TransactionSignatories_TransactionSignatory_UID_IDX" ON public."TransactionSignatories" USING btree ("TransactionSignatory_UID"); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."TransactionSignatoryDeclineReasons" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "TransactionSignatoryDeclineReasons"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "TransactionSignatoryDeclineReasons" ( | ||||||
|  | 	"TransactionSignatoryDeclineReasonID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"UserID" int8 NOT NULL, | ||||||
|  | 	"DeclineReason" varchar NOT NULL, | ||||||
|  | 	"CreatedOn" timestamp DEFAULT now() NULL, | ||||||
|  | 	"TransactionSignatoryDeclineReason_UID" uuid DEFAULT uuid_generate_v4() NOT NULL, | ||||||
|  | 	"TransactionID" int8 NOT NULL, | ||||||
|  | 	"TransactionSignatoryID" int8 NULL, | ||||||
|  | 	CONSTRAINT "TransactionSignatoryDeclineReasons_pk" PRIMARY KEY ("TransactionSignatoryDeclineReasonID"), | ||||||
|  | 	CONSTRAINT "TransactionSignatoryDeclineReasons_unique" UNIQUE ("TransactionSignatoryDeclineReason_UID"), | ||||||
|  | 	CONSTRAINT "TransactionSignatoryDeclineReasons_TransactionSignatories_FK" FOREIGN KEY ("TransactionSignatoryID") REFERENCES "TransactionSignatories"("TransactionSignatoryID"), | ||||||
|  | 	CONSTRAINT "TransactionSignatoryDeclineReasons_Users_FK" FOREIGN KEY ("UserID") REFERENCES "Users"("UserID") | ||||||
|  | ); | ||||||
|  | CREATE INDEX "TransactionSignatoryDeclineReasons_UserID_IDX" ON public."TransactionSignatoryDeclineReasons" USING btree ("UserID", "TransactionID"); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."VideoRecordings" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "VideoRecordings"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "VideoRecordings" ( | ||||||
|  | 	"VideoRecordingID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"VideoConferenceScheduleID" int8 NOT NULL, | ||||||
|  | 	"Path" varchar NOT NULL, | ||||||
|  | 	"LocationType" varchar NOT NULL, | ||||||
|  | 	"CreatedOn" timestamp DEFAULT now() NULL, | ||||||
|  | 	"VideoRecording_UID" uuid DEFAULT uuid_generate_v4() NULL, | ||||||
|  | 	CONSTRAINT "VideoRecordings_pk" PRIMARY KEY ("VideoRecordingID"), | ||||||
|  | 	CONSTRAINT "VideoRecordings_unique" UNIQUE ("VideoConferenceScheduleID"), | ||||||
|  | 	CONSTRAINT "VideoRecordings_unique_UID" UNIQUE ("VideoRecording_UID"), | ||||||
|  | 	CONSTRAINT "VideoRecordings_LawyerVideoConferenceSchedule_FK" FOREIGN KEY ("VideoConferenceScheduleID") REFERENCES "LawyerVideoConferenceSchedule"("LawyerVideoConferenceScheduleID") | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."LawyerVideoConferenceParticipants" definition | ||||||
|  | 
 | ||||||
|  | -- Drop table | ||||||
|  | 
 | ||||||
|  | -- DROP TABLE "LawyerVideoConferenceParticipants"; | ||||||
|  | 
 | ||||||
|  | CREATE TABLE "LawyerVideoConferenceParticipants" ( | ||||||
|  | 	"LawyerVideoConferenceParticipantID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"LawyerVideoConferenceScheduleID" int8 NOT NULL, | ||||||
|  | 	"ParticipantID" int8 NOT NULL, | ||||||
|  | 	"Status" varchar NULL, | ||||||
|  | 	"CreatedOn" timestamp DEFAULT now() NULL, | ||||||
|  | 	"LawyerVideoConferenceParticipant_UID" uuid DEFAULT uuid_generate_v4() NULL, | ||||||
|  | 	"MeetingRoomTokenID" varchar NULL, | ||||||
|  | 	"MeetingRoomUserID" varchar NULL, | ||||||
|  | 	CONSTRAINT "LawyerVideoConferenceParticipants_pk" PRIMARY KEY ("LawyerVideoConferenceParticipantID"), | ||||||
|  | 	CONSTRAINT "LawyerVideoConferenceParticipants_LawyerVideoConferenceSchedule" FOREIGN KEY ("LawyerVideoConferenceScheduleID") REFERENCES "LawyerVideoConferenceSchedule"("LawyerVideoConferenceScheduleID"), | ||||||
|  | 	CONSTRAINT "LawyerVideoConferenceParticipants_Users_FK" FOREIGN KEY ("ParticipantID") REFERENCES "Users"("UserID") | ||||||
|  | ); | ||||||
|  | CREATE UNIQUE INDEX "LawyerVideoConferenceParticipants_LawyerVideoConferenceParticip" ON public."LawyerVideoConferenceParticipants" USING btree ("LawyerVideoConferenceParticipant_UID"); | ||||||
|  | CREATE UNIQUE INDEX "LawyerVideoConferenceParticipants_LawyerVideoConferenceSchedule" ON public."LawyerVideoConferenceParticipants" USING btree ("LawyerVideoConferenceScheduleID", "ParticipantID"); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- DROP FUNCTION public.uuid_generate_v1(); | ||||||
|  | 
 | ||||||
|  | CREATE OR REPLACE FUNCTION public.uuid_generate_v1() | ||||||
|  |  RETURNS uuid | ||||||
|  |  LANGUAGE c | ||||||
|  |  PARALLEL SAFE STRICT | ||||||
|  | AS '$libdir/uuid-ossp', $function$uuid_generate_v1$function$ | ||||||
|  | ; | ||||||
|  | 
 | ||||||
|  | -- DROP FUNCTION public.uuid_generate_v1mc(); | ||||||
|  | 
 | ||||||
|  | CREATE OR REPLACE FUNCTION public.uuid_generate_v1mc() | ||||||
|  |  RETURNS uuid | ||||||
|  |  LANGUAGE c | ||||||
|  |  PARALLEL SAFE STRICT | ||||||
|  | AS '$libdir/uuid-ossp', $function$uuid_generate_v1mc$function$ | ||||||
|  | ; | ||||||
|  | 
 | ||||||
|  | -- DROP FUNCTION public.uuid_generate_v3(uuid, text); | ||||||
|  | 
 | ||||||
|  | CREATE OR REPLACE FUNCTION public.uuid_generate_v3(namespace uuid, name text) | ||||||
|  |  RETURNS uuid | ||||||
|  |  LANGUAGE c | ||||||
|  |  IMMUTABLE PARALLEL SAFE STRICT | ||||||
|  | AS '$libdir/uuid-ossp', $function$uuid_generate_v3$function$ | ||||||
|  | ; | ||||||
|  | 
 | ||||||
|  | -- DROP FUNCTION public.uuid_generate_v4(); | ||||||
|  | 
 | ||||||
|  | CREATE OR REPLACE FUNCTION public.uuid_generate_v4() | ||||||
|  |  RETURNS uuid | ||||||
|  |  LANGUAGE c | ||||||
|  |  PARALLEL SAFE STRICT | ||||||
|  | AS '$libdir/uuid-ossp', $function$uuid_generate_v4$function$ | ||||||
|  | ; | ||||||
|  | 
 | ||||||
|  | -- DROP FUNCTION public.uuid_generate_v5(uuid, text); | ||||||
|  | 
 | ||||||
|  | CREATE OR REPLACE FUNCTION public.uuid_generate_v5(namespace uuid, name text) | ||||||
|  |  RETURNS uuid | ||||||
|  |  LANGUAGE c | ||||||
|  |  IMMUTABLE PARALLEL SAFE STRICT | ||||||
|  | AS '$libdir/uuid-ossp', $function$uuid_generate_v5$function$ | ||||||
|  | ; | ||||||
|  | 
 | ||||||
|  | -- DROP FUNCTION public.uuid_nil(); | ||||||
|  | 
 | ||||||
|  | CREATE OR REPLACE FUNCTION public.uuid_nil() | ||||||
|  |  RETURNS uuid | ||||||
|  |  LANGUAGE c | ||||||
|  |  IMMUTABLE PARALLEL SAFE STRICT | ||||||
|  | AS '$libdir/uuid-ossp', $function$uuid_nil$function$ | ||||||
|  | ; | ||||||
|  | 
 | ||||||
|  | -- DROP FUNCTION public.uuid_ns_dns(); | ||||||
|  | 
 | ||||||
|  | CREATE OR REPLACE FUNCTION public.uuid_ns_dns() | ||||||
|  |  RETURNS uuid | ||||||
|  |  LANGUAGE c | ||||||
|  |  IMMUTABLE PARALLEL SAFE STRICT | ||||||
|  | AS '$libdir/uuid-ossp', $function$uuid_ns_dns$function$ | ||||||
|  | ; | ||||||
|  | 
 | ||||||
|  | -- DROP FUNCTION public.uuid_ns_oid(); | ||||||
|  | 
 | ||||||
|  | CREATE OR REPLACE FUNCTION public.uuid_ns_oid() | ||||||
|  |  RETURNS uuid | ||||||
|  |  LANGUAGE c | ||||||
|  |  IMMUTABLE PARALLEL SAFE STRICT | ||||||
|  | AS '$libdir/uuid-ossp', $function$uuid_ns_oid$function$ | ||||||
|  | ; | ||||||
|  | 
 | ||||||
|  | -- DROP FUNCTION public.uuid_ns_url(); | ||||||
|  | 
 | ||||||
|  | CREATE OR REPLACE FUNCTION public.uuid_ns_url() | ||||||
|  |  RETURNS uuid | ||||||
|  |  LANGUAGE c | ||||||
|  |  IMMUTABLE PARALLEL SAFE STRICT | ||||||
|  | AS '$libdir/uuid-ossp', $function$uuid_ns_url$function$ | ||||||
|  | ; | ||||||
|  | 
 | ||||||
|  | -- DROP FUNCTION public.uuid_ns_x500(); | ||||||
|  | 
 | ||||||
|  | CREATE OR REPLACE FUNCTION public.uuid_ns_x500() | ||||||
|  |  RETURNS uuid | ||||||
|  |  LANGUAGE c | ||||||
|  |  IMMUTABLE PARALLEL SAFE STRICT | ||||||
|  | AS '$libdir/uuid-ossp', $function$uuid_ns_x500$function$ | ||||||
|  | ; | ||||||
| @ -0,0 +1,74 @@ | |||||||
|  | DO $$ | ||||||
|  | 
 | ||||||
|  | DECLARE doc_type_id INTEGER; | ||||||
|  | DECLARE id_type_id INTEGER; | ||||||
|  | 
 | ||||||
|  | BEGIN | ||||||
|  | 	 | ||||||
|  | 	INSERT INTO "LookupData" ("Name") | ||||||
|  | 	VALUES | ||||||
|  | 	('Document Types'), | ||||||
|  | 	('Identification Types'); | ||||||
|  | 	 | ||||||
|  | 
 | ||||||
|  | 	 | ||||||
|  | 	SELECT "LookupDataID" INTO doc_type_id FROM "LookupData" WHERE "Name" = 'Document Types' LIMIT 1; | ||||||
|  | 	 | ||||||
|  | 	-- Now insert into LookupDataValues using the retrieved ID | ||||||
|  | 	INSERT INTO "LookupDataValues" ("LookupDataID", "Value") | ||||||
|  | 	VALUES (doc_type_id, 'Affidavit of Acknowledgement of a Child'), | ||||||
|  | 	        (doc_type_id, 'Affidavit of Undertaking'), | ||||||
|  | 	        (doc_type_id, 'Affidavit of service'), | ||||||
|  | 	        (doc_type_id, 'Affidavits'), | ||||||
|  | 	        (doc_type_id, 'Bid docs'), | ||||||
|  | 	        (doc_type_id, 'Biodata'), | ||||||
|  | 	        (doc_type_id, 'Certification against non-forum shopping'), | ||||||
|  | 	        (doc_type_id, 'Certification of Compliance Officer'), | ||||||
|  | 	        (doc_type_id, 'Contract of Lease'), | ||||||
|  | 	        (doc_type_id, 'Deed of Absolute Sale'), | ||||||
|  | 	        (doc_type_id, 'Deed of Assignment'), | ||||||
|  | 	        (doc_type_id, 'Extrajudicial Partition'), | ||||||
|  | 	        (doc_type_id, 'FCFS/LCFS'), | ||||||
|  | 	        (doc_type_id, 'FCIF/LCIF'), | ||||||
|  | 	        (doc_type_id, 'GIS'), | ||||||
|  | 	        (doc_type_id, 'LGU business permit application form'), | ||||||
|  | 	        (doc_type_id, 'Loan Agreement'), | ||||||
|  | 	        (doc_type_id, 'Personal Data Sheet'), | ||||||
|  | 	        (doc_type_id, 'Proxy forms'), | ||||||
|  | 	        (doc_type_id, 'Quitclaims'), | ||||||
|  | 	        (doc_type_id, 'SALN'), | ||||||
|  | 	        (doc_type_id, 'Secretary’s Certificate'), | ||||||
|  | 	        (doc_type_id, 'Service Agreements'), | ||||||
|  | 	        (doc_type_id, 'Settlement Agreement'), | ||||||
|  | 	        (doc_type_id, 'Special Power of Attorney'), | ||||||
|  | 	        (doc_type_id, 'Verification of pleadings'), | ||||||
|  | 	        (doc_type_id, 'Wills'); | ||||||
|  | 	 | ||||||
|  | 	SELECT "LookupDataID" INTO id_type_id FROM "LookupData" WHERE "Name" = 'Identification Types' LIMIT 1; | ||||||
|  | 	 | ||||||
|  | 	-- Now insert into LookupDataValues using the retrieved ID | ||||||
|  | 	INSERT INTO "LookupDataValues" ("LookupDataID", "Value") | ||||||
|  | 	VALUES (id_type_id, 'Administration (OWWA) ID'), | ||||||
|  | 	        (id_type_id, 'Alien Certificate of Registration'), | ||||||
|  | 	        (id_type_id, 'Certification from the National Council for the Welfare of Disabled Persons (NCWDP)'), | ||||||
|  | 	        (id_type_id, 'Department of Social Welfare and Development (DSWD) certification'), | ||||||
|  | 	        (id_type_id, 'Driver''s license'), | ||||||
|  | 	        (id_type_id, 'Government Office ID'), | ||||||
|  | 	        (id_type_id, 'Government Service and Insurance System (GSIS) e-card'), | ||||||
|  | 	        (id_type_id, 'Immigrant Certificate of Registration'), | ||||||
|  | 	        (id_type_id, 'Integrated Bar of the Philippines (IBP) ID'), | ||||||
|  | 	        (id_type_id, 'National Bureau of Investigation (NBI) clearance'), | ||||||
|  | 	        (id_type_id, 'Overseas Filipino Worker (OFW) ID'), | ||||||
|  | 	        (id_type_id, 'Overseas Workers Welfare Administration (OWWA) ID'), | ||||||
|  | 	        (id_type_id, 'Passport'), | ||||||
|  | 	        (id_type_id, 'PhilHealth card'), | ||||||
|  | 	        (id_type_id, 'Police clearance'), | ||||||
|  | 	        (id_type_id, 'Postal ID'), | ||||||
|  | 	        (id_type_id, 'Professional Regulations Commission (PRC) ID'), | ||||||
|  | 	        (id_type_id, 'Seaman''s book'), | ||||||
|  | 	        (id_type_id, 'Senior citizen card'), | ||||||
|  | 	        (id_type_id, 'Social Security System (SSS) card'), | ||||||
|  | 	        (id_type_id, 'Tax Identification Number (TIN) ID'), | ||||||
|  | 	        (id_type_id, 'Unified Multi-Purpose ID (UMID) Card'), | ||||||
|  | 	        (id_type_id, 'Voter''s ID'); | ||||||
|  | END $$; | ||||||
							
								
								
									
										45
									
								
								EnotaryoPH/EnotaryoPH.DbMigration/Scripts/03_UserTracker.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								EnotaryoPH/EnotaryoPH.DbMigration/Scripts/03_UserTracker.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | BEGIN TRANSACTION; | ||||||
|  | 
 | ||||||
|  | ALTER TABLE "LawyerVideoConferenceParticipants" | ||||||
|  | ADD COLUMN IF NOT EXISTS "Device" VARCHAR(255); | ||||||
|  | 
 | ||||||
|  | ALTER TABLE "LawyerVideoConferenceParticipants" | ||||||
|  | ADD COLUMN IF NOT EXISTS "IPAddress" VARCHAR(45); | ||||||
|  | 
 | ||||||
|  | ALTER TABLE "LawyerVideoConferenceParticipants" | ||||||
|  | ADD COLUMN IF NOT EXISTS "Latitude" DECIMAL(10, 6); | ||||||
|  | 
 | ||||||
|  | ALTER TABLE "LawyerVideoConferenceParticipants" | ||||||
|  | ADD COLUMN IF NOT EXISTS "Longitude" DECIMAL(10, 6); | ||||||
|  | 
 | ||||||
|  | ALTER TABLE "LawyerVideoConferenceParticipants" | ||||||
|  | ADD COLUMN IF NOT EXISTS "OTPEntered" VARCHAR(100); | ||||||
|  | 
 | ||||||
|  | ALTER TABLE "LawyerVideoConferenceParticipants" | ||||||
|  | ADD COLUMN IF NOT EXISTS "OTPHash" VARCHAR(255); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | CREATE TABLE IF NOT EXISTS "UserLogins" ( | ||||||
|  | 	"UserLoginID" int8 GENERATED ALWAYS AS IDENTITY( INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1 NO CYCLE) NOT NULL, | ||||||
|  | 	"Failed" bool NULL, | ||||||
|  | 	"IPAddress" varchar NULL, | ||||||
|  | 	"Device" varchar NULL, | ||||||
|  | 	"Longitude" float8 NULL, | ||||||
|  | 	"Latitude" float8 NULL, | ||||||
|  | 	"UsegLogin_UID" uuid DEFAULT uuid_generate_v4() NOT NULL, | ||||||
|  | 	"UserID" int8 NULL, | ||||||
|  | 	"CreatedOn" timestamp DEFAULT now() NULL, | ||||||
|  | 	CONSTRAINT "UserLogins_pk" PRIMARY KEY ("UserLoginID"), | ||||||
|  | 	CONSTRAINT "UserLogins_unique" UNIQUE ("UsegLogin_UID") | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -- public."UserLogins" foreign keys | ||||||
|  | 
 | ||||||
|  | ALTER TABLE public."UserLogins" ADD CONSTRAINT "UserLogins_Users_FK" FOREIGN KEY ("UserID") REFERENCES "Users"("UserID"); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | COMMIT TRANSACTION; | ||||||
| @ -0,0 +1,19 @@ | |||||||
|  | BEGIN TRANSACTION; | ||||||
|  | 
 | ||||||
|  | -- Create a new column with the desired data type | ||||||
|  | ALTER TABLE "EventLogs" | ||||||
|  | ADD COLUMN IF NOT EXISTS "NewStreamID" VARCHAR(255) NOT NULL; | ||||||
|  | 
 | ||||||
|  | -- Update values in the new column (cast the original int8 to varchar) | ||||||
|  | UPDATE "EventLogs" | ||||||
|  | SET "NewStreamID" = CAST("StreamID" AS VARCHAR); | ||||||
|  | 
 | ||||||
|  | -- Drop the original column (keeping only valid data) | ||||||
|  | ALTER TABLE "EventLogs" | ||||||
|  | DROP COLUMN "StreamID"; | ||||||
|  | 
 | ||||||
|  | -- Rename the new column to the original name | ||||||
|  | ALTER TABLE "EventLogs" | ||||||
|  | RENAME COLUMN "NewStreamID" TO "StreamID"; | ||||||
|  | 
 | ||||||
|  | COMMIT TRANSACTION; | ||||||
							
								
								
									
										5
									
								
								EnotaryoPH/EnotaryoPH.DbMigration/appsettings.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								EnotaryoPH/EnotaryoPH.DbMigration/appsettings.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | { | ||||||
|  |     "ConnectionStrings": { | ||||||
|  |         "DbUpConnection": "secret" | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,301 @@ | |||||||
|  | import { AzureCommunicationTokenCredential, createIdentifierFromRawId } from '@azure/communication-common'; | ||||||
|  | import { CallClient, LocalVideoStream, VideoStreamRenderer } from '@azure/communication-calling'; | ||||||
|  | 
 | ||||||
|  | class VideoCall { | ||||||
|  |   constructor() { | ||||||
|  |     //this.isLocalVideoStartedChangedCallback = null;
 | ||||||
|  |     //this.localVideoStreamsUpdatedCallback = null;
 | ||||||
|  |     //this.onCreateLocalVideoStreamCallback = null;
 | ||||||
|  |     this.onGetServerCallIDCallback = null; | ||||||
|  |     //this.remoteParticipantStateChangedCallback = null;
 | ||||||
|  |     //this.remoteParticipantsUpdatedCallback = null;
 | ||||||
|  |     //this.remoteVideoIsAvailableChangedCallback = null;
 | ||||||
|  |     this.stateChangedCallback = null; | ||||||
|  |     this.callEndedCallback = null; | ||||||
|  |     this.participantsJoinedCallback = null; | ||||||
|  |     this.callsUpdatedCallback = null; | ||||||
|  | 
 | ||||||
|  |     this.callAdapter = null; | ||||||
|  |     this.videoContainer = null; | ||||||
|  |     this.displayName = null; | ||||||
|  |     this.roomID = null; | ||||||
|  |     this.token = null; | ||||||
|  |     this.userID = null; | ||||||
|  | 
 | ||||||
|  |     this.onFetchParticipantMenuItemsCallback = null; | ||||||
|  |     this.onFetchCustomButtonPropsCallbacks = []; | ||||||
|  |     this.onAddParticipantCallback = null; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   async init(options) { | ||||||
|  |     let self = this; | ||||||
|  |     this.stateChangedCallback = options.stateChangedCallback; | ||||||
|  |     /*this.remoteParticipantsUpdatedCallback = options.remoteParticipantsUpdated;*/ | ||||||
|  |     /*this.isLocalVideoStartedChangedCallback = options.isLocalVideoStartedChanged;*/ | ||||||
|  |     /*this.localVideoStreamsUpdatedCallback = options.localVideoStreamsUpdated;*/ | ||||||
|  |     this.idChangedCallback = options.idChanged; | ||||||
|  |     //this.onCreateLocalVideoStreamCallback = options.onCreateLocalVideoStream;
 | ||||||
|  |     //this.remoteParticipantStateChangedCallback = options.remoteParticipantStateChanged;
 | ||||||
|  |     //this.remoteVideoIsAvailableChangedCallback = options.remoteVideoIsAvailableChanged;
 | ||||||
|  |     this.onGetServerCallIDCallback = options.onGetServerCallIDCallback; | ||||||
|  |     this.callEndedCallback = options.callEndedCallback; | ||||||
|  |     this.participantsJoinedCallback = options.participantsJoinedCallback; | ||||||
|  |     this.onFetchParticipantMenuItemsCallback = options.onFetchParticipantMenuItemsCallback; | ||||||
|  |     this.onFetchCustomButtonPropsCallbacks = options.onFetchCustomButtonPropsCallbacks || []; | ||||||
|  |     this.onAddParticipantCallback = options.onAddParticipantCallback; | ||||||
|  | 
 | ||||||
|  |     this.callAdapter = options.callAdapter; | ||||||
|  |     this.videoContainer = options.videoContainer; | ||||||
|  |     this.displayName = options.displayName; | ||||||
|  |     this.roomID = options.roomID; | ||||||
|  |     this.token = options.token; | ||||||
|  |     this.userID = options.userID; | ||||||
|  | 
 | ||||||
|  |     this.serverCallId; | ||||||
|  | 
 | ||||||
|  |     const callControls = { | ||||||
|  |       // Hide all default buttons
 | ||||||
|  |       cameraButton: true, | ||||||
|  |       endCallButton: false, | ||||||
|  |       microphoneButton: false, | ||||||
|  |       participantsButton: true, | ||||||
|  |       screenShareButton: false, | ||||||
|  |       devicesButton: false, | ||||||
|  |       moreButton: false, | ||||||
|  |       raiseHandButton: false, | ||||||
|  |       reactionButton: false, | ||||||
|  |       dtmfDialerButton: false, | ||||||
|  |       holdButton: false, | ||||||
|  |       peopleButton: false, | ||||||
|  |       exitSpotlightButton: false, | ||||||
|  |       captionsButton: false, | ||||||
|  |       galleryControlsButton: false, | ||||||
|  |       teamsMeetingPhoneCallButton: false, | ||||||
|  |       displayType: 'compact', | ||||||
|  | 
 | ||||||
|  |       // Hide the entire control bar if needed
 | ||||||
|  |       onFetchCustomButtonProps: this.onFetchCustomButtonPropsCallbacks | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); | ||||||
|  |     const callCompositeProps = { | ||||||
|  |       callControls: callControls, | ||||||
|  |       formFactor: isMobile ? 'mobile' : 'desktop', | ||||||
|  |       onFetchParticipantMenuItems: this.onFetchParticipantMenuItemsCallback, | ||||||
|  |       options: { | ||||||
|  |         callControls: callControls | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     const adapterArgs = { | ||||||
|  |       userId: createIdentifierFromRawId(this.userID), | ||||||
|  |       //credential: new AzureCommunicationTokenCredential(this.token),
 | ||||||
|  |       token: this.token, | ||||||
|  |       displayName: this.displayName, | ||||||
|  |       locator: { roomId: this.roomID }, | ||||||
|  |       callAdapterOptions: {}, | ||||||
|  |       callCompositeOptions: callCompositeProps | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     this.callAdapter = await callComposite.loadCallComposite( | ||||||
|  |       adapterArgs, | ||||||
|  |       this.videoContainer, // container element,
 | ||||||
|  |       callCompositeProps | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     //this.callAdapter.callAgent.on("callsUpdated", function (e) {
 | ||||||
|  |     //  e.added.forEach((addedCall) => {
 | ||||||
|  |     //    addedCall.on('stateChanged', (state) => this.stateChanged(addedCall));
 | ||||||
|  |     //  });
 | ||||||
|  |     //});
 | ||||||
|  | 
 | ||||||
|  |     this.callAdapter.on("callIdChanged", function (e) { | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     this.callAdapter.onStateChange(state => { | ||||||
|  |       if (state.call?.info && !this.serverCallId) { | ||||||
|  |         state.call.info.getServerCallId().then(result => { | ||||||
|  |           this.serverCallId = result; | ||||||
|  |           this.onGetServerCallIDCallback?.(result); | ||||||
|  |         }).catch(err => { | ||||||
|  |           console.log(err); | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     this.callAdapter.on("callEnded", function (e) { | ||||||
|  |       self.callEndedCallback?.(e); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     this.callAdapter.on("participantsJoined", function (e, f) { | ||||||
|  |       self.participantsJoinedCallback?.(e, f); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     this.callAdapter.on("onAddParticipant", function (e, f) { | ||||||
|  |       self.onAddParticipantCallback?.(e, f); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     //CallEnded
 | ||||||
|  | 
 | ||||||
|  |     return this.callAdapter; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   //stopLocalVideo() {
 | ||||||
|  |   //  if (this.call) {
 | ||||||
|  |   //    this.call.stopVideo(this.localVideoStream);
 | ||||||
|  |   //  }
 | ||||||
|  |   //}
 | ||||||
|  | 
 | ||||||
|  |   async joinRoom() { | ||||||
|  |     await this.callAdapter?.joinCall({ | ||||||
|  |       microphoneOn: true, | ||||||
|  |       cameraOn: true | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   async stopCall(forEveryone = false) { | ||||||
|  |     await this.callAdapter?.leaveCall(forEveryone); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   //async subscribeToCall(call) {
 | ||||||
|  |   //  try {
 | ||||||
|  |   //    call.on('idChanged', () => {
 | ||||||
|  |   //      this.idChanged?.(call.id);
 | ||||||
|  |   //    });
 | ||||||
|  |   //    call.on('stateChanged', async () => {
 | ||||||
|  |   //      this.stateChangedCallback?.(call.state);
 | ||||||
|  |   //    });
 | ||||||
|  |   //    call.on('isLocalVideoStartedChanged', () => {
 | ||||||
|  |   //      this.isLocalVideoStartedChanged?.(call.isLocalVideoStarted);
 | ||||||
|  |   //    });
 | ||||||
|  |   //    call.on('localVideoStreamsUpdated', e => {
 | ||||||
|  |   //      this.localVideoStreamsUpdated?.(e);
 | ||||||
|  |   //    });
 | ||||||
|  | 
 | ||||||
|  |   //    // Subscribe to the call's 'remoteParticipantsUpdated' event to be
 | ||||||
|  |   //    // notified when new participants are added to the call or removed from the call.
 | ||||||
|  |   //    call.on('remoteParticipantsUpdated', e => {
 | ||||||
|  |   //      this.remoteParticipantsUpdated?.(e);
 | ||||||
|  | 
 | ||||||
|  |   //      e.added.forEach(remoteParticipant => {
 | ||||||
|  |   //        this.subscribeToRemoteParticipant(remoteParticipant)
 | ||||||
|  |   //      });
 | ||||||
|  |   //      // Unsubscribe from participants that are removed from the call
 | ||||||
|  |   //      e.removed.forEach(remoteParticipant => {
 | ||||||
|  |   //        console.log('Remote participant removed from the call.');
 | ||||||
|  |   //      });
 | ||||||
|  |   //    });
 | ||||||
|  | 
 | ||||||
|  |   //    call.localVideoStreams.forEach(async (lvs) => {
 | ||||||
|  |   //      this.localVideoStream = lvs;
 | ||||||
|  |   //      await this.displayLocalVideoStream(lvs);
 | ||||||
|  |   //    });
 | ||||||
|  | 
 | ||||||
|  |   //    // Inspect the call's current remote participants and subscribe to them.
 | ||||||
|  |   //    call.remoteParticipants.forEach(remoteParticipant => {
 | ||||||
|  |   //      this.subscribeToRemoteParticipant(remoteParticipant);
 | ||||||
|  |   //    });
 | ||||||
|  |   //  } catch (error) {
 | ||||||
|  |   //    console.error(error);
 | ||||||
|  |   //  }
 | ||||||
|  |   //}
 | ||||||
|  | 
 | ||||||
|  |   //subscribeToRemoteParticipant(remoteParticipant) {
 | ||||||
|  |   //  try {
 | ||||||
|  |   //    // Inspect the initial remoteParticipant.state value.
 | ||||||
|  |   //    console.log(`Remote participant state: ${remoteParticipant.state}`);
 | ||||||
|  |   //    // Subscribe to remoteParticipant's 'stateChanged' event for value changes.
 | ||||||
|  |   //    remoteParticipant.on('stateChanged', () => {
 | ||||||
|  |   //      console.log(`Remote participant state changed: ${remoteParticipant.state}`, JSON.stringify(remoteParticipant));
 | ||||||
|  |   //      this.remoteParticipantStateChanged?.(remoteParticipant.state);
 | ||||||
|  |   //    });
 | ||||||
|  | 
 | ||||||
|  |   //    // Inspect the remoteParticipants's current videoStreams and subscribe to them.
 | ||||||
|  |   //    remoteParticipant.videoStreams.forEach(remoteVideoStream => {
 | ||||||
|  |   //      this.subscribeToRemoteVideoStream(remoteVideoStream);
 | ||||||
|  |   //    });
 | ||||||
|  |   //    // Subscribe to the remoteParticipant's 'videoStreamsUpdated' event to be
 | ||||||
|  |   //    // notified when the remoteParticipant adds new videoStreams and removes video streams.
 | ||||||
|  |   //    remoteParticipant.on('videoStreamsUpdated', e => {
 | ||||||
|  |   //      // Subscribe to new remote participant's video streams that were added.
 | ||||||
|  |   //      e.added.forEach(remoteVideoStream => {
 | ||||||
|  |   //        this.subscribeToRemoteVideoStream(remoteVideoStream);
 | ||||||
|  |   //      });
 | ||||||
|  |   //      // Unsubscribe from remote participant's video streams that were removed.
 | ||||||
|  |   //      e.removed.forEach(remoteVideoStream => {
 | ||||||
|  |   //        console.log('Remote participant video stream was removed.');
 | ||||||
|  |   //      })
 | ||||||
|  |   //    });
 | ||||||
|  |   //  } catch (error) {
 | ||||||
|  |   //    console.error(error);
 | ||||||
|  |   //  }
 | ||||||
|  |   //}
 | ||||||
|  | 
 | ||||||
|  |   //async subscribeToRemoteVideoStream(remoteVideoStream) {
 | ||||||
|  |   //  let renderer = new VideoStreamRenderer(remoteVideoStream);
 | ||||||
|  |   //  let view;
 | ||||||
|  | 
 | ||||||
|  |   //  const createView = async () => {
 | ||||||
|  |   //    // Create a renderer view for the remote video stream.
 | ||||||
|  |   //    view = await renderer.createView();
 | ||||||
|  |   //    this.remoteVideoIsAvailableChanged?.({
 | ||||||
|  |   //      isAvailable: remoteVideoStream.isAvailable,
 | ||||||
|  |   //      participantId: remoteVideoStream.tsParticipantId,
 | ||||||
|  |   //      el: view.target
 | ||||||
|  |   //    });
 | ||||||
|  |   //  }
 | ||||||
|  | 
 | ||||||
|  |   //  // Remote participant has switched video on/off
 | ||||||
|  |   //  remoteVideoStream.on('isAvailableChanged', async () => {
 | ||||||
|  |   //    try {
 | ||||||
|  |   //      if (remoteVideoStream.isAvailable) {
 | ||||||
|  |   //        await createView();
 | ||||||
|  |   //      } else {
 | ||||||
|  |   //        view?.dispose();
 | ||||||
|  |   //      }
 | ||||||
|  |   //    } catch (e) {
 | ||||||
|  |   //      console.error(e);
 | ||||||
|  |   //    }
 | ||||||
|  |   //  });
 | ||||||
|  | 
 | ||||||
|  |   //  // Remote participant has video on initially.
 | ||||||
|  |   //  if (remoteVideoStream.isAvailable) {
 | ||||||
|  |   //    try {
 | ||||||
|  |   //      await createView();
 | ||||||
|  |   //    } catch (e) {
 | ||||||
|  |   //      console.error(e);
 | ||||||
|  |   //    }
 | ||||||
|  |   //  }
 | ||||||
|  |   //}
 | ||||||
|  | 
 | ||||||
|  |   //async createLocalVideoStream() {
 | ||||||
|  |   //  const camera = (await this.deviceManager.getCameras())[0];
 | ||||||
|  |   //  if (camera) {
 | ||||||
|  |   //    return new LocalVideoStream(camera);
 | ||||||
|  |   //  } else {
 | ||||||
|  |   //    console.error(`No camera device found on the system`);
 | ||||||
|  |   //  }
 | ||||||
|  |   //}
 | ||||||
|  | 
 | ||||||
|  |   leaveRoom() { | ||||||
|  |     if (this.call) { | ||||||
|  |       this.call.hangUp(); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   //createIdentifierFromRawId(rawId) {
 | ||||||
|  |   //  return createIdentifierFromRawId(rawId);
 | ||||||
|  |   //}
 | ||||||
|  | 
 | ||||||
|  |   //async displayLocalVideoStream(lvs) {
 | ||||||
|  |   //  try {
 | ||||||
|  |   //    let localVideoStreamRenderer = new VideoStreamRenderer(lvs);
 | ||||||
|  |   //    const view = await localVideoStreamRenderer.createView();
 | ||||||
|  |   //    this.onCreateLocalVideoStream?.(view.target);
 | ||||||
|  |   //  } catch (error) {
 | ||||||
|  |   //    console.error(error);
 | ||||||
|  |   //  }
 | ||||||
|  |   //}
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default VideoCall; | ||||||
| @ -0,0 +1,38 @@ | |||||||
|  | function _confirm({ message, title, callbackyes, callbackno, yesLabel, noLabel }) { | ||||||
|  |   const dialogTemplate = jfa.page.getDialogTemplate().content; | ||||||
|  | 
 | ||||||
|  |   let spanTitle = dialogTemplate.querySelector(".modal__title__text"); | ||||||
|  |   spanTitle.textContent = title || "Confirm"; | ||||||
|  | 
 | ||||||
|  |   let bodyMessage = dialogTemplate.querySelector(".modal__body-message"); | ||||||
|  |   bodyMessage.textContent = message; | ||||||
|  | 
 | ||||||
|  |   const dialog = dialogTemplate.querySelector("#dialog-container"); | ||||||
|  |   const modal = bootstrap.Modal.getOrCreateInstance(dialog); | ||||||
|  | 
 | ||||||
|  |   let buttonNo = dialogTemplate.querySelector(".modal__footer__button-no"); | ||||||
|  |   if (noLabel) { | ||||||
|  |     buttonNo.textContent = noLabel; | ||||||
|  |   } | ||||||
|  |   buttonNo.addEventListener("click", function () { | ||||||
|  |     buttonNo.blur(); | ||||||
|  |     modal.hide(); | ||||||
|  |     callbackno?.(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   let buttonYes = dialogTemplate.querySelector(".modal__footer__button-yes"); | ||||||
|  |   if (yesLabel) { | ||||||
|  |     buttonYes.textContent = yesLabel; | ||||||
|  |   } | ||||||
|  |   buttonYes.addEventListener("click", function () { | ||||||
|  |     buttonYes.blur(); | ||||||
|  |     modal.hide(); | ||||||
|  |     callbackyes?.(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   modal.show(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default { | ||||||
|  |   confirm: _confirm | ||||||
|  | }; | ||||||
							
								
								
									
										32
									
								
								EnotaryoPH/EnotaryoPH.Web/Assets/js/Page/_Page.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								EnotaryoPH/EnotaryoPH.Web/Assets/js/Page/_Page.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  |   function _getAlertContainer() { | ||||||
|  |     return document.getElementById("ContainerAlert"); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function _getAlertTemplate() { | ||||||
|  |     return document.getElementById("AlertTemplate").cloneNode(true); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function _getAntiForgeryToken() { | ||||||
|  |     return window.top.document.querySelector("[name='__RequestVerificationToken']")?.value; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function _getDialogContainer() { | ||||||
|  |     return document.getElementById("ContainerDialog").cloneNode(true); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function _getDialogTemplate() { | ||||||
|  |     return document.getElementById("DialogTemplate").cloneNode(true); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function reload() { | ||||||
|  |     window.location.reload(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default { | ||||||
|  |   getAlertContainer: _getAlertContainer, | ||||||
|  |   getAlertTemplate: _getAlertTemplate, | ||||||
|  |   getAntiForgeryToken: _getAntiForgeryToken, | ||||||
|  |   getDialogContainer: _getDialogContainer, | ||||||
|  |   getDialogTemplate: _getDialogTemplate, | ||||||
|  |   reload: reload | ||||||
|  | }; | ||||||
| @ -0,0 +1,36 @@ | |||||||
|  |  | ||||||
|  | function disable(element) { | ||||||
|  |   if (!element) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   element.disabled = true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function enable(element) { | ||||||
|  |   if (!element) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   element.disabled = false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function hide(element) { | ||||||
|  |   if (!element) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   element.hidden = true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function show(element, suppressEvent) { | ||||||
|  |   if (!element) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   element.hidden = false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default { | ||||||
|  |   disable: disable, | ||||||
|  |   enable: enable, | ||||||
|  |   hide: hide, | ||||||
|  |   show: show | ||||||
|  | }; | ||||||
| @ -0,0 +1,26 @@ | |||||||
|  |  | ||||||
|  | async function del(url, data) { | ||||||
|  |   return await _fetch(url, data, "DELETE"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function _fetch(url, data, method) { | ||||||
|  |   const response = await fetch(url, { | ||||||
|  |     method: method, | ||||||
|  |     headers: { | ||||||
|  |       'Accept': 'application/json', | ||||||
|  |       'Content-Type': 'application/json', | ||||||
|  |       'RequestVerificationToken': jfa.page.getAntiForgeryToken() | ||||||
|  |     }, | ||||||
|  |     body: data ? JSON.stringify(data) : data | ||||||
|  |   }); | ||||||
|  |   return response; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function post(url, data) { | ||||||
|  |   return await _fetch(url, data, "POST"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default { | ||||||
|  |   delete: del, | ||||||
|  |   post: post | ||||||
|  | }; | ||||||
| @ -0,0 +1,16 @@ | |||||||
|  | function getCurrentURL() { | ||||||
|  |   return new URL(window.location.origin + window.location.pathname); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function getCurrentURLWithHandler(handler) { | ||||||
|  |   let url = getCurrentURL(); | ||||||
|  |   url.searchParams.append("handler", handler); | ||||||
|  |   return url; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default { | ||||||
|  |   getCurrentURL: getCurrentURL, | ||||||
|  |   getCurrentURLWithHandler: getCurrentURLWithHandler | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
							
								
								
									
										25
									
								
								EnotaryoPH/EnotaryoPH.Web/Assets/js/_Jfa.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								EnotaryoPH/EnotaryoPH.Web/Assets/js/_Jfa.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | import page from "../../Assets/js/Page/_Page.js"; | ||||||
|  | import routing from "../../Assets/js/Utilities/Routing/_Routing.js"; | ||||||
|  | import element from "../../Assets/js/Utilities/Element/_Element.js"; | ||||||
|  | import request from "../../Assets/js/Utilities/Request/_Request.js"; | ||||||
|  | import dialog from "../../Assets/js/Components/Dialog/_Dialog.js"; | ||||||
|  | import videocall from "../../Assets/js/Communication/VideoCall/_VideoCall.js"; | ||||||
|  | 
 | ||||||
|  | const jfa = { | ||||||
|  |   components: { | ||||||
|  |     dialog | ||||||
|  |   }, | ||||||
|  |   utilities: { | ||||||
|  |     routing, | ||||||
|  |     element, | ||||||
|  |     request | ||||||
|  |   }, | ||||||
|  |   page, | ||||||
|  |   communication: { | ||||||
|  |     videocall: new videocall() | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | export default { jfa }; | ||||||
|  | window.jfa = jfa; | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Exceptions | ||||||
|  | { | ||||||
|  |     public class InvalidConfigurationException : Exception | ||||||
|  |     { | ||||||
|  |         public InvalidConfigurationException(string configurationName, object value) : base($"Invalid value '{value}' for configuration '{configurationName}'.") | ||||||
|  |         { | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,39 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Exceptions | ||||||
|  | { | ||||||
|  |     public class NoDataException : Exception | ||||||
|  |     { | ||||||
|  |         public NoDataException(string typeName, object id) : base($"No data found for {typeName} with id = '{id}'.") | ||||||
|  |         { | ||||||
|  |             TypeName = typeName; | ||||||
|  |             ID = id; | ||||||
|  |             Key = string.Empty; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public NoDataException(string typeName, object id, string key) : base($"No data found for {typeName} with {key} = '{id}'.") | ||||||
|  |         { | ||||||
|  |             TypeName = typeName; | ||||||
|  |             ID = id; | ||||||
|  |             Key = key; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static void ThrowIfNull(object data, string typeName, object id) | ||||||
|  |         { | ||||||
|  |             if (data == null) | ||||||
|  |             { | ||||||
|  |                 throw new NoDataException(typeName, id); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static void ThrowIfNull(object data, string typeName, object id, string key) | ||||||
|  |         { | ||||||
|  |             if (data == null) | ||||||
|  |             { | ||||||
|  |                 throw new NoDataException(typeName, id, key); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public object ID { get; private set; } | ||||||
|  |         public string Key { get; private set; } | ||||||
|  |         public string TypeName { get; private set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Extensions | ||||||
|  | { | ||||||
|  |     public static class DateTimeExtensions | ||||||
|  |     { | ||||||
|  |         public static DateTime ToUTC(this DateTime? dte) => dte.GetValueOrDefault().ToUTC(); | ||||||
|  | 
 | ||||||
|  |         public static DateTime ToUTC(this DateTime dte) => new(dte.Ticks, DateTimeKind.Utc); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,40 @@ | |||||||
|  | using System.Buffers.Text; | ||||||
|  | using System.Runtime.InteropServices; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Common.Extensions | ||||||
|  | { | ||||||
|  |     public static class GuidExtensions | ||||||
|  |     { | ||||||
|  |         private const char Dash = '-'; | ||||||
|  |         private const byte ForwardSlashByte = (byte)'/'; | ||||||
|  |         private const byte PlusByte = (byte)'+'; | ||||||
|  |         private const char Underscore = '_'; | ||||||
|  | 
 | ||||||
|  |         public static string ToBase64String(this Guid guid) | ||||||
|  |         { | ||||||
|  |             Span<byte> guidBytes = stackalloc byte[16]; | ||||||
|  |             Span<byte> encodedBytes = stackalloc byte[24]; | ||||||
|  | 
 | ||||||
|  |             MemoryMarshal.TryWrite(guidBytes, ref guid); // write bytes from the Guid | ||||||
|  |             Base64.EncodeToUtf8(guidBytes, encodedBytes, out _, out _); | ||||||
|  | 
 | ||||||
|  |             Span<char> chars = stackalloc char[22]; | ||||||
|  | 
 | ||||||
|  |             // replace any characters which are not URL safe | ||||||
|  |             // skip the final two bytes as these will be '==' padding we don't need | ||||||
|  |             for (var i = 0; i < 22; i++) | ||||||
|  |             { | ||||||
|  |                 chars[i] = encodedBytes[i] switch | ||||||
|  |                 { | ||||||
|  |                     ForwardSlashByte => Dash, | ||||||
|  |                     PlusByte => Underscore, | ||||||
|  |                     _ => (char)encodedBytes[i], | ||||||
|  |                 }; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             var final = new string(chars); | ||||||
|  | 
 | ||||||
|  |             return final; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Extensions | ||||||
|  | { | ||||||
|  |     public static class IEnumerableExtensions | ||||||
|  |     { | ||||||
|  |         public static IEnumerable<T> ToSafeEnumerable<T>(this IEnumerable<T> enumerable) => enumerable ?? Enumerable.Empty<T>(); | ||||||
|  | 
 | ||||||
|  |         public static List<T> ToSafeList<T>(this IEnumerable<T> enumerable) => enumerable?.ToList() ?? []; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,20 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Extensions | ||||||
|  | { | ||||||
|  |     public static class IFormFileExtensions | ||||||
|  |     { | ||||||
|  |         public static string ToBase64StringUrl(this IFormFile file) => $"data:image/jpg;base64,{file.ToBase64String()}"; | ||||||
|  | 
 | ||||||
|  |         public static string ToBase64String(this IFormFile file) | ||||||
|  |         { | ||||||
|  |             if (file == null || file.Length == 0) | ||||||
|  |             { | ||||||
|  |                 throw new ArgumentNullException(nameof(file)); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             using var memoryStream = new MemoryStream(); | ||||||
|  |             file.CopyTo(memoryStream); | ||||||
|  |             var fileBytes = memoryStream.ToArray(); | ||||||
|  |             return Convert.ToBase64String(fileBytes); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,11 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Extensions | ||||||
|  | { | ||||||
|  |     public static class ObjectExtensions | ||||||
|  |     { | ||||||
|  |         public static int ToInteger(this object obj) | ||||||
|  |         { | ||||||
|  |             int.TryParse(obj.ToString(), out var result); | ||||||
|  |             return result; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,45 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Extensions | ||||||
|  | { | ||||||
|  |     public static class StringExtensions | ||||||
|  |     { | ||||||
|  |         private const char EqualsChar = '='; | ||||||
|  |         private const char Plus = '+'; | ||||||
|  |         private const char Slash = '/'; | ||||||
|  | 
 | ||||||
|  |         public static string DefaultIfEmpty(this string s, string defaultValue) => !string.IsNullOrWhiteSpace(s) ? s : defaultValue ?? string.Empty; | ||||||
|  | 
 | ||||||
|  |         public static bool IsInList(this string s, params string[] list) => list.Contains(s, StringComparer.OrdinalIgnoreCase); | ||||||
|  | 
 | ||||||
|  |         public static bool IsInList<T>(this string stringValue, IEnumerable<T> listOfEnums) where T : struct, Enum => Enum.TryParse(stringValue, out T enumValue) && listOfEnums.Contains(enumValue); | ||||||
|  | 
 | ||||||
|  |         public static bool IsInList<T>(this string stringValue, params T[] listOfEnums) where T : struct, Enum => Enum.TryParse(stringValue, out T enumValue) && listOfEnums.Contains(enumValue); | ||||||
|  | 
 | ||||||
|  |         public static string NullIfWhiteSpace(this string s) => string.IsNullOrWhiteSpace(s) ? null : s; | ||||||
|  | 
 | ||||||
|  |         public static Guid ToGuidFromBase64(this string s) | ||||||
|  |         { | ||||||
|  |             if (s.Length != 22) | ||||||
|  |             { | ||||||
|  |                 return Guid.Empty; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             var id = s.AsSpan(); | ||||||
|  |             Span<char> base64Chars = stackalloc char[24]; | ||||||
|  |             for (var i = 0; i < 22; i++) | ||||||
|  |             { | ||||||
|  |                 base64Chars[i] = id[i] switch | ||||||
|  |                 { | ||||||
|  |                     '-' => Slash, | ||||||
|  |                     '_' => Plus, | ||||||
|  |                     _ => id[i] | ||||||
|  |                 }; | ||||||
|  |             } | ||||||
|  |             base64Chars[22] = EqualsChar; | ||||||
|  |             base64Chars[23] = EqualsChar; | ||||||
|  | 
 | ||||||
|  |             Span<byte> idBytes = stackalloc byte[16]; | ||||||
|  |             Convert.TryFromBase64Chars(base64Chars, idBytes, out _); | ||||||
|  |             return new Guid(idBytes); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								EnotaryoPH/EnotaryoPH.Web/Common/Helpers/FullName.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								EnotaryoPH/EnotaryoPH.Web/Common/Helpers/FullName.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | using System.Runtime.CompilerServices; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Common.Helpers | ||||||
|  | { | ||||||
|  |     public static class FullName | ||||||
|  |     { | ||||||
|  |         public static string Of<T>(T _, [CallerArgumentExpression("_")] string fullName = "") => fullName; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								EnotaryoPH/EnotaryoPH.Web/Common/Hubs/NotificationHub.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								EnotaryoPH/EnotaryoPH.Web/Common/Hubs/NotificationHub.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | using Microsoft.AspNetCore.SignalR; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Common.Hubs | ||||||
|  | { | ||||||
|  |     public class NotificationHub : Hub | ||||||
|  |     { | ||||||
|  |         public async Task NotifyUserAsync(string user_UID, string message) => await Clients.All.SendAsync("ReceiveNotaryNotification", user_UID, message); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,85 @@ | |||||||
|  | using System.Text; | ||||||
|  | using System.Text.Json; | ||||||
|  | using Azure.Communication.CallAutomation; | ||||||
|  | using Azure.Storage.Queues; | ||||||
|  | using Coravel.Invocable; | ||||||
|  | using EnotaryoPH.Data; | ||||||
|  | using EnotaryoPH.Data.Entities; | ||||||
|  | using EnotaryoPH.Web.Common.Jobs.Models; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Common.Jobs | ||||||
|  | { | ||||||
|  |     public class CheckRecordingAvailabilityInvocable : IInvocable | ||||||
|  |     { | ||||||
|  |         private readonly QueueClient _queueClient; | ||||||
|  |         private readonly CallAutomationClient _callAutomationClient; | ||||||
|  |         private readonly IConfiguration _configuration; | ||||||
|  |         private readonly IServiceScopeFactory _serviceScopeFactory; | ||||||
|  | 
 | ||||||
|  |         public CheckRecordingAvailabilityInvocable(QueueClient queueClient, CallAutomationClient callAutomationClient, IConfiguration configuration, IServiceScopeFactory serviceScopeFactory) | ||||||
|  |         { | ||||||
|  |             _queueClient = queueClient; | ||||||
|  |             _callAutomationClient = callAutomationClient; | ||||||
|  |             _configuration = configuration; | ||||||
|  |             _serviceScopeFactory = serviceScopeFactory; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public async Task Invoke() | ||||||
|  |         { | ||||||
|  |             var message = await _queueClient.ReceiveMessageAsync(); | ||||||
|  |             if (message?.Value == null) | ||||||
|  |             { | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             var base64EncodedData = message.Value.Body.ToString(); | ||||||
|  |             var base64EncodedBytes = Convert.FromBase64String(base64EncodedData); | ||||||
|  |             var options = new JsonSerializerOptions | ||||||
|  |             { | ||||||
|  |                 PropertyNameCaseInsensitive = true | ||||||
|  |             }; | ||||||
|  |             var json = Encoding.UTF8.GetString(base64EncodedBytes); | ||||||
|  |             var model = JsonSerializer.Deserialize<RecordingFileStatusUpdatedModel>(json, options); | ||||||
|  |             if (model?.Data?.RecordingStorageInfo?.RecordingChunks?.Count > 0) | ||||||
|  |             { | ||||||
|  |                 var dbContext = _serviceScopeFactory.CreateScope().ServiceProvider.GetRequiredService<NotaryoDBContext>(); | ||||||
|  |                 model.Data.RecordingStorageInfo.RecordingChunks.ForEach(async chunk => | ||||||
|  |                 { | ||||||
|  |                     var path = _configuration.GetValue<string>("VideoRecordingsLocation"); | ||||||
|  |                     if (!Path.Exists(path)) | ||||||
|  |                     { | ||||||
|  |                         Directory.CreateDirectory(path); | ||||||
|  |                     } | ||||||
|  |                     var fileName = Path.Combine(path, $"{chunk.DocumentId}-{chunk.Index}.mp4"); | ||||||
|  |                     if (File.Exists(fileName)) | ||||||
|  |                     { | ||||||
|  |                         File.Move(fileName, fileName.Replace(".mp4", $"_{DateTime.UtcNow.ToString("yyyy-MM-dd-HH-mm-dd")}.mp4")); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     using var memoryStream = new MemoryStream(); | ||||||
|  |                     await _callAutomationClient | ||||||
|  |                         .GetCallRecording().DownloadToAsync(new Uri(chunk.ContentLocation), fileName); | ||||||
|  | 
 | ||||||
|  |                     var schedule = dbContext.LawyerVideoConferenceSchedules.FirstOrDefault(sched => sched.RecordingID == model.Data.RecordingId); | ||||||
|  |                     if (schedule != null) | ||||||
|  |                     { | ||||||
|  |                         if (schedule.VideoRecording == null) | ||||||
|  |                         { | ||||||
|  |                             schedule.VideoRecording = new VideoRecording | ||||||
|  |                             { | ||||||
|  |                                 CreatedOn = DateTime.UtcNow, | ||||||
|  |                                 LocationType = nameof(VideoRecordingLocationType.LocalFolder), | ||||||
|  |                                 VideoConferenceScheduleID = schedule.LawyerVideoConferenceScheduleID, | ||||||
|  |                                 VideoRecording_UID = Guid.CreateVersion7(DateTime.UtcNow) | ||||||
|  |                             }; | ||||||
|  |                         } | ||||||
|  |                         schedule.VideoRecording.Path = fileName; | ||||||
|  |                         schedule.VideoRecording.Metadata = JsonSerializer.Serialize(json); | ||||||
|  |                         dbContext.UpdateOrCreate(schedule); | ||||||
|  |                         dbContext.SaveChanges(); | ||||||
|  |                     } | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |             await _queueClient.DeleteMessageAsync(message.Value.MessageId, message.Value.PopReceipt); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								EnotaryoPH/EnotaryoPH.Web/Common/Jobs/Models/Data.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								EnotaryoPH/EnotaryoPH.Web/Common/Jobs/Models/Data.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Jobs.Models | ||||||
|  | { | ||||||
|  |     public class Data | ||||||
|  |     { | ||||||
|  |         public int RecordingDurationMs { get; set; } | ||||||
|  |         public string RecordingId { get; set; } | ||||||
|  |         public DateTime RecordingStartTime { get; set; } | ||||||
|  |         public RecordingStorageInfo RecordingStorageInfo { get; set; } | ||||||
|  |         public string SessionEndReason { get; set; } | ||||||
|  |         public string StorageType { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,8 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Jobs.Models | ||||||
|  | { | ||||||
|  |     public class OTPEmailModel | ||||||
|  |     { | ||||||
|  |         public Dictionary<Guid, string> ParticipantOTP { get; set; } | ||||||
|  |         public Guid Transaction_UID { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,12 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Jobs.Models | ||||||
|  | { | ||||||
|  |     public class RecordingChunk | ||||||
|  |     { | ||||||
|  |         public string ContentLocation { get; set; } | ||||||
|  |         public string DeleteLocation { get; set; } | ||||||
|  |         public string DocumentId { get; set; } | ||||||
|  |         public string EndReason { get; set; } | ||||||
|  |         public int Index { get; set; } | ||||||
|  |         public string MetadataLocation { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,14 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Jobs.Models | ||||||
|  | { | ||||||
|  |     public class RecordingFileStatusUpdatedModel | ||||||
|  |     { | ||||||
|  |         public Data Data { get; set; } | ||||||
|  |         public string DataVersion { get; set; } | ||||||
|  |         public DateTime EventTime { get; set; } | ||||||
|  |         public string EventType { get; set; } | ||||||
|  |         public string Id { get; set; } | ||||||
|  |         public string MetadataVersion { get; set; } | ||||||
|  |         public string Subject { get; set; } | ||||||
|  |         public string Topic { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,7 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Jobs.Models | ||||||
|  | { | ||||||
|  |     public class RecordingStorageInfo | ||||||
|  |     { | ||||||
|  |         public List<RecordingChunk> RecordingChunks { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,75 @@ | |||||||
|  | using Coravel.Invocable; | ||||||
|  | using Coravel.Mailer.Mail.Interfaces; | ||||||
|  | using EnotaryoPH.Data; | ||||||
|  | using EnotaryoPH.Web.Common.Jobs.Models; | ||||||
|  | using EnotaryoPH.Web.Common.Models; | ||||||
|  | using EnotaryoPH.Web.Mailables; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Common.Jobs | ||||||
|  | { | ||||||
|  |     public class OneTimePasswordInvocable : IInvocable, IInvocableWithPayload<OTPEmailModel> | ||||||
|  |     { | ||||||
|  |         private readonly IMailer _mailer; | ||||||
|  |         private readonly NotaryoDBContext _notaryoDBContext; | ||||||
|  |         private readonly Settings _settings; | ||||||
|  |         private readonly IPasswordService _passwordService; | ||||||
|  |         private readonly IEventService _eventService; | ||||||
|  | 
 | ||||||
|  |         public OneTimePasswordInvocable(IMailer mailer, NotaryoDBContext notaryoDBContext, Settings settings, IPasswordService passwordService, IEventService eventService) | ||||||
|  |         { | ||||||
|  |             _mailer = mailer; | ||||||
|  |             _notaryoDBContext = notaryoDBContext; | ||||||
|  |             _settings = settings; | ||||||
|  |             _passwordService = passwordService; | ||||||
|  |             _eventService = eventService; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public OTPEmailModel Payload { get; set; } | ||||||
|  | 
 | ||||||
|  |         public async Task Invoke() | ||||||
|  |         { | ||||||
|  |             var schedule = _notaryoDBContext.LawyerVideoConferenceSchedules | ||||||
|  |                 .AsNoTracking() | ||||||
|  |                 .Include(sched => sched.Transaction) | ||||||
|  |                 .ThenInclude(transaction => transaction.TransactionDocument) | ||||||
|  |                 .Include(sched => sched.Transaction) | ||||||
|  |                 .ThenInclude(transaction => transaction.Lawyer) | ||||||
|  |                 .ThenInclude(lawyer => lawyer.User) | ||||||
|  |                 .Include(sched => sched.LawyerVideoConferenceParticipants) | ||||||
|  |                 .ThenInclude(participant => participant.Participant) | ||||||
|  |                 .FirstOrDefault(sched => sched.Transaction.Transaction_UID == Payload.Transaction_UID); | ||||||
|  | 
 | ||||||
|  |             if (schedule == null) | ||||||
|  |             { | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             var participantDic = schedule.LawyerVideoConferenceParticipants.ToDictionary(p => p.LawyerVideoConferenceParticipant_UID.GetValueOrDefault(), p => p); | ||||||
|  |             foreach (var otp in Payload.ParticipantOTP) | ||||||
|  |             { | ||||||
|  |                 if (!participantDic.ContainsKey(otp.Key)) | ||||||
|  |                 { | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  |                 var participant = participantDic[otp.Key]; | ||||||
|  | 
 | ||||||
|  |                 var emailViewModel = new OneTimePasswordViewModel | ||||||
|  |                 { | ||||||
|  |                     DocumentType = schedule.Transaction.TransactionDocument.DocumentType, | ||||||
|  |                     Email = participant.Participant.Email, | ||||||
|  |                     OTP = otp.Value, | ||||||
|  |                     ParticipantName = participant.Participant.Fullname, | ||||||
|  |                     LawyerName = schedule.Transaction.Lawyer.User.Fullname, | ||||||
|  |                     MeetingRoomURL = $"{_settings.BaseUrl}/Participant/VideoCall/Room/{schedule.Transaction.Transaction_UID}", | ||||||
|  |                 }; | ||||||
|  |                 await _mailer.SendAsync(new OneTimePasswordMailable(emailViewModel)); | ||||||
|  |                 await _eventService.LogAsync(NotaryoEvent.OTPSent, Payload.Transaction_UID, new | ||||||
|  |                 { | ||||||
|  |                     emailViewModel.Email, | ||||||
|  |                     emailViewModel.ParticipantName, | ||||||
|  |                     emailViewModel.MeetingRoomURL | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,49 @@ | |||||||
|  | using Coravel.Invocable; | ||||||
|  | using Coravel.Mailer.Mail.Interfaces; | ||||||
|  | using EnotaryoPH.Data; | ||||||
|  | using EnotaryoPH.Web.Common.Models; | ||||||
|  | using EnotaryoPH.Web.Mailables; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Common.Jobs | ||||||
|  | { | ||||||
|  |     public class SignatoryInvitationInvocable : IInvocable, IInvocableWithPayload<Guid> | ||||||
|  |     { | ||||||
|  |         private readonly IMailer _mailer; | ||||||
|  |         private readonly NotaryoDBContext _notaryoDBContext; | ||||||
|  |         private readonly Settings _settings; | ||||||
|  | 
 | ||||||
|  |         public SignatoryInvitationInvocable(IMailer mailer, NotaryoDBContext notaryoDBContext, Settings settings) | ||||||
|  |         { | ||||||
|  |             _mailer = mailer; | ||||||
|  |             _notaryoDBContext = notaryoDBContext; | ||||||
|  |             _settings = settings; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public Guid Payload { get; set; } | ||||||
|  | 
 | ||||||
|  |         public async Task Invoke() | ||||||
|  |         { | ||||||
|  |             var signatory = _notaryoDBContext | ||||||
|  |                 .TransactionSignatories | ||||||
|  |                 .Include(e => e.Transaction) | ||||||
|  |                 .ThenInclude(t => t.Principal) | ||||||
|  |                 .FirstOrDefault(e => e.TransactionSignatory_UID == Payload); | ||||||
|  | 
 | ||||||
|  |             var user = signatory.Transaction.Principal; | ||||||
|  |             var name = $"{user.Firstname} {user.Lastname}".NullIfWhiteSpace() ?? user.Email; | ||||||
|  |             var invitationCode = new Guid(signatory.InvitationCode).ToBase64String(); | ||||||
|  | 
 | ||||||
|  |             await _mailer.SendAsync(new SignatoryInvitationMailable(new SignatoryViewModel | ||||||
|  |             { | ||||||
|  |                 Email = signatory.Email, | ||||||
|  |                 InvitationURL = $"{_settings.BaseUrl}/Participant/Registration/{invitationCode}", | ||||||
|  |                 MainPrincipalName = name, | ||||||
|  |                 SignatoryType = signatory.Type | ||||||
|  |             })); | ||||||
|  | 
 | ||||||
|  |             signatory.Status = nameof(SignatoryStatus.EmailSent); | ||||||
|  |             _notaryoDBContext.TransactionSignatories.Update(signatory); | ||||||
|  |             _notaryoDBContext.SaveChanges(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,56 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations; | ||||||
|  | using EnotaryoPH.Data.Entities; | ||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  | using Microsoft.AspNetCore.Mvc.Rendering; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Common.Models | ||||||
|  | { | ||||||
|  |     public class IdentificationDocumentModel | ||||||
|  |     { | ||||||
|  |         public IdentificationDocumentModel() | ||||||
|  |         { } | ||||||
|  | 
 | ||||||
|  |         public IdentificationDocumentModel(IdentificationDocument document) | ||||||
|  |         { | ||||||
|  |             using var stream = new MemoryStream(document.File); | ||||||
|  |             File = new FormFile(stream, 0, stream.Length, document.Filename, document.Filename); | ||||||
|  |             ExpirationDate = document.ExpirationDate; | ||||||
|  |             DateIssued = document.DateIssued; | ||||||
|  |             PlaceIssued = document.PlaceIssued; | ||||||
|  |             IdNumber = document.IdNumber; | ||||||
|  |             Filename = document.Filename; | ||||||
|  |             ImageBase64Url = File.ToBase64StringUrl(); | ||||||
|  |             IdentificationType = document.Type; | ||||||
|  |             IdentificationDocument_UID = document.IdentificationDocument_UID.GetValueOrDefault(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         [BindProperty] | ||||||
|  |         public DateTime? DateIssued { get; set; } | ||||||
|  | 
 | ||||||
|  |         [BindProperty] | ||||||
|  |         public DateTime? ExpirationDate { get; set; } | ||||||
|  | 
 | ||||||
|  |         [BindProperty, Required] | ||||||
|  |         public IFormFile File { get; set; } | ||||||
|  | 
 | ||||||
|  |         [BindProperty] | ||||||
|  |         public string? Filename { get; set; } | ||||||
|  | 
 | ||||||
|  |         [BindProperty] | ||||||
|  |         public Guid IdentificationDocument_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [BindProperty] | ||||||
|  |         public string IdentificationType { get; set; } | ||||||
|  | 
 | ||||||
|  |         public List<SelectListItem>? IdentificationTypes { get; set; } | ||||||
|  | 
 | ||||||
|  |         [BindProperty] | ||||||
|  |         public string IdNumber { get; set; } | ||||||
|  | 
 | ||||||
|  |         [BindProperty] | ||||||
|  |         public string? ImageBase64Url { get; set; } | ||||||
|  | 
 | ||||||
|  |         [BindProperty] | ||||||
|  |         public string PlaceIssued { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,39 @@ | |||||||
|  | using EnotaryoPH.Data.Entities; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Common.Models | ||||||
|  | { | ||||||
|  |     internal static class IdentificationDocumentModelMapper | ||||||
|  |     { | ||||||
|  |         internal static IdentificationDocument ToEntity(this IdentificationDocumentModel model, int userID) | ||||||
|  |         { | ||||||
|  |             var now = DateTime.UtcNow; | ||||||
|  |             var entity = new IdentificationDocument | ||||||
|  |             { | ||||||
|  |                 UploadedOn = now, | ||||||
|  |                 UserID = userID, | ||||||
|  |                 IdentificationDocument_UID = Guid.CreateVersion7(now), | ||||||
|  |                 CreatedOn = now | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             return model.ToEntity(entity); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         internal static IdentificationDocument ToEntity(this IdentificationDocumentModel model, IdentificationDocument entity) | ||||||
|  |         { | ||||||
|  |             ArgumentNullException.ThrowIfNull(model.File); | ||||||
|  | 
 | ||||||
|  |             entity.ExpirationDate = model.ExpirationDate.ToUTC(); | ||||||
|  |             entity.DateIssued = model.DateIssued.ToUTC(); | ||||||
|  |             entity.PlaceIssued = model.PlaceIssued; | ||||||
|  |             entity.IdNumber = model.IdNumber; | ||||||
|  |             entity.Type = model.IdentificationType; | ||||||
|  | 
 | ||||||
|  |             var file = model.File; | ||||||
|  |             entity.Filename = file.FileName; | ||||||
|  |             var stream = new MemoryStream((int)file.Length); | ||||||
|  |             file.CopyTo(stream); | ||||||
|  |             entity.File = stream.ToArray(); | ||||||
|  |             return entity; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								EnotaryoPH/EnotaryoPH.Web/Common/Models/Settings.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								EnotaryoPH/EnotaryoPH.Web/Common/Models/Settings.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Models | ||||||
|  | { | ||||||
|  |     public class Settings | ||||||
|  |     { | ||||||
|  |         public string BaseUrl { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,30 @@ | |||||||
|  | using System.Security.Claims; | ||||||
|  | using System.Security.Principal; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Common.Services | ||||||
|  | { | ||||||
|  |     public class CurrentUserService : ICurrentUserService | ||||||
|  |     { | ||||||
|  |         private readonly ClaimsIdentity _user; | ||||||
|  | 
 | ||||||
|  |         public CurrentUserService(IPrincipal principal) => _user = principal.Identity as ClaimsIdentity; | ||||||
|  | 
 | ||||||
|  |         public string? GetEmail() => _user.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Email)?.Value; | ||||||
|  | 
 | ||||||
|  |         public string? GetRole() => _user.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Role)?.Value; | ||||||
|  | 
 | ||||||
|  |         public Guid GetUser_UID() | ||||||
|  |         { | ||||||
|  |             if (_user == null) | ||||||
|  |             { | ||||||
|  |                 return Guid.Empty; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             var uid = _user.Claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier)?.Value; | ||||||
|  |             Guid.TryParse(uid, out var user_UID); | ||||||
|  |             return user_UID; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public bool IsAuthenticated() => _user?.IsAuthenticated ?? false; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										63
									
								
								EnotaryoPH/EnotaryoPH.Web/Common/Services/EventService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								EnotaryoPH/EnotaryoPH.Web/Common/Services/EventService.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | |||||||
|  | using System.Text.Json; | ||||||
|  | using EnotaryoPH.Data; | ||||||
|  | using EnotaryoPH.Data.Entities; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Common.Services | ||||||
|  | { | ||||||
|  |     public class EventService : IEventService | ||||||
|  |     { | ||||||
|  |         private readonly NotaryoDBContext _dBContext; | ||||||
|  |         private readonly INotificationService _notificationService; | ||||||
|  | 
 | ||||||
|  |         public EventService(NotaryoDBContext dBContext, INotificationService notificationService) | ||||||
|  |         { | ||||||
|  |             _dBContext = dBContext; | ||||||
|  |             _notificationService = notificationService; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public Task LogAsync(NotaryoEvent notaryoEvent, object entityId) => LogAsync(notaryoEvent, entityId, null); | ||||||
|  | 
 | ||||||
|  |         public async Task LogAsync(NotaryoEvent notaryoEvent, List<object> entityIds, object payLoad) | ||||||
|  |         { | ||||||
|  |             foreach (var entityId in entityIds) | ||||||
|  |             { | ||||||
|  |                 await LogAsync(notaryoEvent, entityId, payLoad); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public async Task LogAsync(NotaryoEvent notaryoEvent, object entityId, object payLoad) | ||||||
|  |         { | ||||||
|  |             var logItem = new EventLog | ||||||
|  |             { | ||||||
|  |                 Description = $"Event: {notaryoEvent}, Entity: {entityId}", | ||||||
|  |                 EventLog_UID = Guid.CreateVersion7(DateTime.UtcNow), | ||||||
|  |                 LogDate = DateTime.UtcNow, | ||||||
|  |                 LogType = notaryoEvent.ToString(), | ||||||
|  |                 Payload = payLoad != null ? JsonSerializer.Serialize(payLoad) : null, | ||||||
|  |                 StreamID = entityId.ToString(), | ||||||
|  |             }; | ||||||
|  |             if (notaryoEvent == NotaryoEvent.TransactionApproved) | ||||||
|  |             { | ||||||
|  |                 var transaction = _dBContext.Transactions.AsNoTracking() | ||||||
|  |                     .Include(t => t.TransactionSignatories) | ||||||
|  |                     .ThenInclude(ts => ts.User) | ||||||
|  |                     .Include(t => t.Lawyer) | ||||||
|  |                     .ThenInclude(l => l.User) | ||||||
|  |                     .Include(t => t.Principal) | ||||||
|  |                     .Include(t => t.TransactionDocument) | ||||||
|  |                     .FirstOrDefault(t => t.TransactionID == entityId.ToInteger()); | ||||||
|  |                 logItem.Description = $"Transaction {entityId} has been approved."; | ||||||
|  |                 if (transaction != null) | ||||||
|  |                 { | ||||||
|  |                     var message = $"The document {transaction.TransactionDocument.DocumentType} has been approved."; | ||||||
|  |                     var allUsers = transaction.TransactionSignatories.ConvertAll(ts => ts.User.Email); | ||||||
|  |                     allUsers.Add(transaction.Lawyer.User.Email); | ||||||
|  |                     allUsers.Add(transaction.Principal.Email); | ||||||
|  |                     await _notificationService.NotifyUsersAsync(message, allUsers.ToArray()); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             _dBContext.Add(logItem); | ||||||
|  |             _dBContext.SaveChanges(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Services | ||||||
|  | { | ||||||
|  |     public interface ICurrentUserService | ||||||
|  |     { | ||||||
|  |         string? GetEmail(); | ||||||
|  | 
 | ||||||
|  |         string? GetRole(); | ||||||
|  | 
 | ||||||
|  |         Guid GetUser_UID(); | ||||||
|  | 
 | ||||||
|  |         bool IsAuthenticated(); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								EnotaryoPH/EnotaryoPH.Web/Common/Services/IEventService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								EnotaryoPH/EnotaryoPH.Web/Common/Services/IEventService.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Services | ||||||
|  | { | ||||||
|  |     public interface IEventService | ||||||
|  |     { | ||||||
|  |         Task LogAsync(NotaryoEvent notaryoEvent, List<object> entityIds, object payLoad); | ||||||
|  | 
 | ||||||
|  |         Task LogAsync(NotaryoEvent notaryoEvent, object entityId); | ||||||
|  | 
 | ||||||
|  |         Task LogAsync(NotaryoEvent notaryoEvent, object entityId, object payLoad); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,10 @@ | |||||||
|  |  | ||||||
|  | namespace EnotaryoPH.Web.Common.Services | ||||||
|  | { | ||||||
|  |     public interface INotificationService | ||||||
|  |     { | ||||||
|  |         Task NotifyAllAsync(string message); | ||||||
|  |         Task NotifyUserAsync(string message, string userID); | ||||||
|  |         Task NotifyUsersAsync(string message, params string[] userIDs); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Services | ||||||
|  | { | ||||||
|  |     public interface IPasswordService | ||||||
|  |     { | ||||||
|  |         string HashPassword(string password); | ||||||
|  | 
 | ||||||
|  |         bool VerifyHashedPassword(string hashedPassword, string providedPassword); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Services | ||||||
|  | { | ||||||
|  |     public interface ISignInService | ||||||
|  |     { | ||||||
|  |         Task SignInAsync(UserLogin userLogin); | ||||||
|  | 
 | ||||||
|  |         Task SignOutAsync(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,17 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Services | ||||||
|  | { | ||||||
|  |     public interface IVideoConferenceService | ||||||
|  |     { | ||||||
|  |         Task ApproveTransactionAsync(Guid transaction_UID); | ||||||
|  | 
 | ||||||
|  |         bool CanStart(Guid transaction_UID); | ||||||
|  | 
 | ||||||
|  |         Guid GetUIDByTransactionUID(Guid transaction_UID); | ||||||
|  | 
 | ||||||
|  |         bool HasExpired(Guid transaction_UID); | ||||||
|  | 
 | ||||||
|  |         Task<Guid> StartAsync(Guid transaction_UID); | ||||||
|  | 
 | ||||||
|  |         Task StartRecordingAsync(Guid transaction_UID, string serverCallID); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,18 @@ | |||||||
|  | using EnotaryoPH.Web.Common.Hubs; | ||||||
|  | using Microsoft.AspNetCore.SignalR; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Common.Services | ||||||
|  | { | ||||||
|  |     public class NotificationService : INotificationService | ||||||
|  |     { | ||||||
|  |         private readonly IHubContext<NotificationHub> _hubContext; | ||||||
|  | 
 | ||||||
|  |         public NotificationService(IHubContext<NotificationHub> hubContext) => _hubContext = hubContext; | ||||||
|  | 
 | ||||||
|  |         public async Task NotifyAllAsync(string message) => await _hubContext.Clients.All.SendAsync("ReceiveUserNotification", message); | ||||||
|  | 
 | ||||||
|  |         public async Task NotifyUserAsync(string message, string userID) => await NotifyUsersAsync(message, userID); | ||||||
|  | 
 | ||||||
|  |         public async Task NotifyUsersAsync(string message, params string[] userIDs) => await _hubContext.Clients.Users(userIDs).SendAsync("ReceiveUserNotification", message); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										98
									
								
								EnotaryoPH/EnotaryoPH.Web/Common/Services/PasswordService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								EnotaryoPH/EnotaryoPH.Web/Common/Services/PasswordService.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,98 @@ | |||||||
|  | using System.Security.Cryptography; | ||||||
|  | using Microsoft.AspNetCore.Cryptography.KeyDerivation; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Common.Services | ||||||
|  | { | ||||||
|  |     public class PasswordService : IPasswordService | ||||||
|  |     { | ||||||
|  |         private readonly int _iterCount = 100_000; | ||||||
|  |         private readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create(); | ||||||
|  | 
 | ||||||
|  |         public string HashPassword(string password) => Convert.ToBase64String(HashPasswordV3(password, _rng)); | ||||||
|  | 
 | ||||||
|  |         public bool VerifyHashedPassword(string hashedPassword, string providedPassword) | ||||||
|  |         { | ||||||
|  |             var decodedHashedPassword = Convert.FromBase64String(hashedPassword); | ||||||
|  |             return VerifyHashedPasswordV3(decodedHashedPassword, providedPassword, out var embeddedIterCount, out var prf); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private static byte[] HashPasswordV3(string password, RandomNumberGenerator rng, KeyDerivationPrf prf, int iterCount, int saltSize, int numBytesRequested) | ||||||
|  |         { | ||||||
|  |             // Produce a version 3 (see comment above) text hash. | ||||||
|  |             var salt = new byte[saltSize]; | ||||||
|  |             rng.GetBytes(salt); | ||||||
|  |             var subkey = KeyDerivation.Pbkdf2(password, salt, prf, iterCount, numBytesRequested); | ||||||
|  | 
 | ||||||
|  |             var outputBytes = new byte[13 + salt.Length + subkey.Length]; | ||||||
|  |             outputBytes[0] = 0x01; // format marker | ||||||
|  |             WriteNetworkByteOrder(outputBytes, 1, (uint)prf); | ||||||
|  |             WriteNetworkByteOrder(outputBytes, 5, (uint)iterCount); | ||||||
|  |             WriteNetworkByteOrder(outputBytes, 9, (uint)saltSize); | ||||||
|  |             Buffer.BlockCopy(salt, 0, outputBytes, 13, salt.Length); | ||||||
|  |             Buffer.BlockCopy(subkey, 0, outputBytes, 13 + saltSize, subkey.Length); | ||||||
|  |             return outputBytes; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private static uint ReadNetworkByteOrder(byte[] buffer, int offset) | ||||||
|  |             => ((uint)(buffer[offset + 0]) << 24) | ||||||
|  |                 | ((uint)(buffer[offset + 1]) << 16) | ||||||
|  |                 | ((uint)(buffer[offset + 2]) << 8) | ||||||
|  |                 | buffer[offset + 3]; | ||||||
|  | 
 | ||||||
|  |         private static bool VerifyHashedPasswordV3(byte[] hashedPassword, string password, out int iterCount, out KeyDerivationPrf prf) | ||||||
|  |         { | ||||||
|  |             iterCount = default; | ||||||
|  |             prf = default; | ||||||
|  | 
 | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 // Read header information | ||||||
|  |                 prf = (KeyDerivationPrf)ReadNetworkByteOrder(hashedPassword, 1); | ||||||
|  |                 iterCount = (int)ReadNetworkByteOrder(hashedPassword, 5); | ||||||
|  |                 var saltLength = (int)ReadNetworkByteOrder(hashedPassword, 9); | ||||||
|  | 
 | ||||||
|  |                 // Read the salt: must be >= 128 bits | ||||||
|  |                 if (saltLength < 128 / 8) | ||||||
|  |                 { | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  |                 var salt = new byte[saltLength]; | ||||||
|  |                 Buffer.BlockCopy(hashedPassword, 13, salt, 0, salt.Length); | ||||||
|  | 
 | ||||||
|  |                 // Read the subkey (the rest of the payload): must be >= 128 bits | ||||||
|  |                 var subkeyLength = hashedPassword.Length - 13 - salt.Length; | ||||||
|  |                 if (subkeyLength < 128 / 8) | ||||||
|  |                 { | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  |                 var expectedSubkey = new byte[subkeyLength]; | ||||||
|  |                 Buffer.BlockCopy(hashedPassword, 13 + salt.Length, expectedSubkey, 0, expectedSubkey.Length); | ||||||
|  | 
 | ||||||
|  |                 // Hash the incoming password and verify it | ||||||
|  |                 var actualSubkey = KeyDerivation.Pbkdf2(password, salt, prf, iterCount, subkeyLength); | ||||||
|  |                 return CryptographicOperations.FixedTimeEquals(actualSubkey, expectedSubkey); | ||||||
|  |             } | ||||||
|  |             catch | ||||||
|  |             { | ||||||
|  |                 // This should never occur except in the case of a malformed payload, where | ||||||
|  |                 // we might go off the end of the array. Regardless, a malformed payload | ||||||
|  |                 // implies verification failed. | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private static void WriteNetworkByteOrder(byte[] buffer, int offset, uint value) | ||||||
|  |         { | ||||||
|  |             buffer[offset + 0] = (byte)(value >> 24); | ||||||
|  |             buffer[offset + 1] = (byte)(value >> 16); | ||||||
|  |             buffer[offset + 2] = (byte)(value >> 8); | ||||||
|  |             buffer[offset + 3] = (byte)(value >> 0); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private byte[] HashPasswordV3(string password, RandomNumberGenerator rng) => HashPasswordV3(password, rng, | ||||||
|  |                                                 prf: KeyDerivationPrf.HMACSHA512, | ||||||
|  |                 iterCount: _iterCount, | ||||||
|  |                 saltSize: 128 / 8, | ||||||
|  |                 numBytesRequested: 256 / 8); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										38
									
								
								EnotaryoPH/EnotaryoPH.Web/Common/Services/SignInService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								EnotaryoPH/EnotaryoPH.Web/Common/Services/SignInService.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | |||||||
|  | using System.Security.Claims; | ||||||
|  | using Microsoft.AspNetCore.Authentication; | ||||||
|  | using Microsoft.AspNetCore.Authentication.Cookies; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Common.Services | ||||||
|  | { | ||||||
|  |     public class SignInService : ISignInService | ||||||
|  |     { | ||||||
|  |         private readonly IHttpContextAccessor _httpContextAccessor; | ||||||
|  | 
 | ||||||
|  |         public SignInService(IHttpContextAccessor httpContextAccessor) => _httpContextAccessor = httpContextAccessor; | ||||||
|  | 
 | ||||||
|  |         public async Task SignInAsync(UserLogin userLogin) | ||||||
|  |         { | ||||||
|  |             ArgumentException.ThrowIfNullOrWhiteSpace(userLogin.Email); | ||||||
|  |             ArgumentException.ThrowIfNullOrWhiteSpace(userLogin.Role); | ||||||
|  |             ArgumentOutOfRangeException.ThrowIfEqual(Guid.Empty, userLogin.User_UID); | ||||||
|  | 
 | ||||||
|  |             var claims = new List<Claim> | ||||||
|  |             { | ||||||
|  |                 new(ClaimTypes.NameIdentifier, userLogin.User_UID.ToString()), | ||||||
|  |                 new(ClaimTypes.Name, userLogin.Email), | ||||||
|  |                 new(ClaimTypes.Email, userLogin.Email), | ||||||
|  |                 new(ClaimTypes.Role, userLogin.Role!) | ||||||
|  |             }; | ||||||
|  |             var claimsIdentity = new ClaimsIdentity( | ||||||
|  |                 claims, CookieAuthenticationDefaults.AuthenticationScheme); | ||||||
|  |             var authProperties = new AuthenticationProperties(); | ||||||
|  | 
 | ||||||
|  |             await _httpContextAccessor.HttpContext.SignInAsync( | ||||||
|  |                 CookieAuthenticationDefaults.AuthenticationScheme, | ||||||
|  |                 new ClaimsPrincipal(claimsIdentity), | ||||||
|  |                 authProperties); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public async Task SignOutAsync() => await _httpContextAccessor.HttpContext.SignOutAsync(); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								EnotaryoPH/EnotaryoPH.Web/Common/Services/UserLogin.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								EnotaryoPH/EnotaryoPH.Web/Common/Services/UserLogin.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | namespace EnotaryoPH.Web.Common.Services | ||||||
|  | { | ||||||
|  |     public class UserLogin | ||||||
|  |     { | ||||||
|  |         public string Email { get; set; } | ||||||
|  |         public string Role { get; set; } | ||||||
|  |         public Guid User_UID { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,285 @@ | |||||||
|  | using System.Security.Cryptography; | ||||||
|  | using Azure; | ||||||
|  | using Azure.Communication; | ||||||
|  | using Azure.Communication.CallAutomation; | ||||||
|  | using Azure.Communication.Identity; | ||||||
|  | using Azure.Communication.Rooms; | ||||||
|  | using Coravel.Queuing.Interfaces; | ||||||
|  | using EnotaryoPH.Data; | ||||||
|  | using EnotaryoPH.Data.Entities; | ||||||
|  | using EnotaryoPH.Web.Common.Jobs; | ||||||
|  | using EnotaryoPH.Web.Common.Jobs.Models; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Common.Services | ||||||
|  | { | ||||||
|  |     public class VideoConferenceService : IVideoConferenceService | ||||||
|  |     { | ||||||
|  |         private const int VideoConferenceExpirationInHours = 2; | ||||||
|  | 
 | ||||||
|  |         private readonly CallAutomationClient _callAutomationClient; | ||||||
|  |         private readonly CommunicationIdentityClient _communicationIdentityClient; | ||||||
|  |         private readonly IConfiguration _configuration; | ||||||
|  |         private readonly NotaryoDBContext _dbContext; | ||||||
|  |         private readonly IEventService _eventService; | ||||||
|  |         private readonly IPasswordService _passwordService; | ||||||
|  |         private readonly IQueue _queue; | ||||||
|  |         private readonly RoomsClient _roomsClient; | ||||||
|  | 
 | ||||||
|  |         public VideoConferenceService(NotaryoDBContext dbContext, CommunicationIdentityClient communicationIdentityClient, RoomsClient roomsClient, CallAutomationClient callAutomationClient, IConfiguration configuration, IEventService eventService, IPasswordService passwordService, IQueue queue) | ||||||
|  |         { | ||||||
|  |             _dbContext = dbContext; | ||||||
|  |             _communicationIdentityClient = communicationIdentityClient; | ||||||
|  |             _roomsClient = roomsClient; | ||||||
|  |             _callAutomationClient = callAutomationClient; | ||||||
|  |             _configuration = configuration; | ||||||
|  |             _eventService = eventService; | ||||||
|  |             _passwordService = passwordService; | ||||||
|  |             _queue = queue; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public async Task ApproveTransactionAsync(Guid transaction_UID) | ||||||
|  |         { | ||||||
|  |             var transaction = _dbContext.Transactions | ||||||
|  |                 .Include(t => t.TransactionSignatories) | ||||||
|  |                 .ThenInclude(ts => ts.User) | ||||||
|  |                 .Include(t => t.Schedule) | ||||||
|  |                 .Include(t => t.Lawyer) | ||||||
|  |                 .ThenInclude(l => l.User) | ||||||
|  |                 .Include(t => t.Principal) | ||||||
|  |                 .FirstOrDefault(t => t.Transaction_UID == transaction_UID); | ||||||
|  |             NoDataException.ThrowIfNull(transaction, nameof(Transaction), transaction_UID); | ||||||
|  |             transaction.Status = nameof(TransactionState.Approved); | ||||||
|  |             transaction.TransactionSignatories.ForEach(ts => ts.Status = nameof(SignatoryStatus.Approved)); | ||||||
|  |             transaction.Schedule.Status = nameof(VideoConferenceStatus.Completed); | ||||||
|  |             _dbContext.Update(transaction); | ||||||
|  |             _dbContext.SaveChanges(); | ||||||
|  | 
 | ||||||
|  |             await Task.WhenAll( | ||||||
|  |                 _eventService.LogAsync(NotaryoEvent.TransactionApproved, transaction_UID), | ||||||
|  |                 StopRecordingAsync(transaction.Schedule) | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public bool CanStart(Guid transaction_UID) | ||||||
|  |         { | ||||||
|  |             if (transaction_UID == Guid.Empty) | ||||||
|  |             { | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             var transactionEntity = _dbContext.Transactions | ||||||
|  |                 .AsNoTracking() | ||||||
|  |                 .Include(t => t.TransactionSignatories) | ||||||
|  |                 .FirstOrDefault(t => t.Transaction_UID == transaction_UID); | ||||||
|  |             if (transactionEntity == null) | ||||||
|  |             { | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             var isReadyForVideoCall = transactionEntity.TransactionSignatories.All(signatory => signatory.Status == nameof(SignatoryStatus.FaceMatch)); | ||||||
|  |             var isAcceptedByLawyer = transactionEntity.Status == nameof(TransactionState.Accepted) && transactionEntity.LawyerID > 0; | ||||||
|  |             return isReadyForVideoCall && isAcceptedByLawyer; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public Guid GetUIDByTransactionUID(Guid transaction_UID) | ||||||
|  |         { | ||||||
|  |             var transactionEntity = _dbContext.Transactions | ||||||
|  |                 .AsNoTracking() | ||||||
|  |                 .FirstOrDefault(t => t.Transaction_UID == transaction_UID); | ||||||
|  |             if (transactionEntity == null) | ||||||
|  |             { | ||||||
|  |                 return Guid.Empty; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             var schedule = _dbContext.LawyerVideoConferenceSchedules.AsNoTracking().FirstOrDefault(sched => sched.TransactionID == transactionEntity.TransactionID); | ||||||
|  |             return schedule == null ? Guid.Empty : schedule.LawyerVideoConferenceSchedule_UID; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public bool HasExpired(Guid transaction_UID) | ||||||
|  |         { | ||||||
|  |             var transactionEntity = _dbContext.Transactions | ||||||
|  |                 .Include(t => t.TransactionSignatories) | ||||||
|  |                 .FirstOrDefault(t => t.Transaction_UID == transaction_UID); | ||||||
|  |             if (transactionEntity == null) | ||||||
|  |             { | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |             var schedule = _dbContext.LawyerVideoConferenceSchedules.FirstOrDefault(sched => sched.TransactionID == transactionEntity.TransactionID); | ||||||
|  |             if (schedule == null) | ||||||
|  |             { | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |             if (schedule.Status == nameof(VideoConferenceStatus.Expired)) | ||||||
|  |             { | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  |             if ((DateTime.UtcNow - schedule.MeetingDate).TotalHours > VideoConferenceExpirationInHours) | ||||||
|  |             { | ||||||
|  |                 if (!schedule.Status?.IsInList(VideoConferenceStatus.Abandoned, VideoConferenceStatus.Completed) ?? false) | ||||||
|  |                 { | ||||||
|  |                     schedule.Status = nameof(VideoConferenceStatus.Expired); | ||||||
|  |                     _dbContext.Update(schedule); | ||||||
|  |                     _dbContext.SaveChanges(); | ||||||
|  |                 } | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public async Task<Guid> StartAsync(Guid transaction_UID) | ||||||
|  |         { | ||||||
|  |             if (!CanStart(transaction_UID)) | ||||||
|  |             { | ||||||
|  |                 throw new ArgumentException("Transaction is not ready for video conference."); | ||||||
|  |             } | ||||||
|  |             var schedule = GetOrCreateNewSchedule(transaction_UID); | ||||||
|  |             if (schedule.Status == nameof(VideoConferenceStatus.New)) | ||||||
|  |             { | ||||||
|  |                 await CreateMeetingRoomAsync(schedule); | ||||||
|  |                 await CreateAndEmailOTPAsync(schedule); | ||||||
|  |                 _dbContext.UpdateOrCreate(schedule); | ||||||
|  |                 _dbContext.SaveChanges(); | ||||||
|  |             } | ||||||
|  |             return schedule.LawyerVideoConferenceSchedule_UID; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public async Task StartRecordingAsync(Guid transaction_UID, string serverCallID) | ||||||
|  |         { | ||||||
|  |             var transactionEntity = _dbContext.Transactions | ||||||
|  |                 .Include(t => t.TransactionSignatories) | ||||||
|  |                 .Single(t => t.Transaction_UID == transaction_UID); | ||||||
|  |             NoDataException.ThrowIfNull(transactionEntity, nameof(Transaction), transaction_UID); | ||||||
|  | 
 | ||||||
|  |             var schedule = _dbContext.LawyerVideoConferenceSchedules | ||||||
|  |                 .FirstOrDefault(sched => sched.TransactionID == transactionEntity.TransactionID); | ||||||
|  |             NoDataException.ThrowIfNull(schedule, nameof(LawyerVideoConferenceSchedule), transactionEntity.TransactionID, FullName.Of(transactionEntity.TransactionID)); | ||||||
|  | 
 | ||||||
|  |             if (string.IsNullOrEmpty(schedule.RecordingID)) | ||||||
|  |             { | ||||||
|  |                 schedule.RecordingID = await StartRecordingAsync(serverCallID); | ||||||
|  |                 schedule.ServerCallID = serverCallID; | ||||||
|  |                 _dbContext.Update(schedule); | ||||||
|  |                 _dbContext.SaveChanges(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private async Task CreateAndEmailOTPAsync(LawyerVideoConferenceSchedule schedule) | ||||||
|  |         { | ||||||
|  |             var participantOTP = new Dictionary<Guid, string>(); | ||||||
|  |             const string validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | ||||||
|  |             foreach (var participant in schedule.LawyerVideoConferenceParticipants) | ||||||
|  |             { | ||||||
|  |                 var otp = RandomNumberGenerator.GetString(validChars, 5); | ||||||
|  |                 participant.OTPHash = _passwordService.HashPassword(otp); | ||||||
|  |                 participantOTP.Add(participant.LawyerVideoConferenceParticipant_UID.GetValueOrDefault(), otp); | ||||||
|  |             } | ||||||
|  |             _queue.QueueInvocableWithPayload<OneTimePasswordInvocable, OTPEmailModel>(new OTPEmailModel | ||||||
|  |             { | ||||||
|  |                 ParticipantOTP = participantOTP, | ||||||
|  |                 Transaction_UID = schedule.Transaction.Transaction_UID.GetValueOrDefault() | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private async Task CreateMeetingRoomAsync(LawyerVideoConferenceSchedule schedule) | ||||||
|  |         { | ||||||
|  |             var roomParticipants = new List<RoomParticipant>(); | ||||||
|  |             foreach (var participant in schedule.LawyerVideoConferenceParticipants.ToSafeList()) | ||||||
|  |             { | ||||||
|  |                 var attendee = await _communicationIdentityClient.CreateUserAsync(); | ||||||
|  |                 participant.MeetingRoomTokenID = await GetTokenResponseAsync(attendee); | ||||||
|  |                 participant.MeetingRoomUserID = attendee.Value.Id; | ||||||
|  |                 roomParticipants.Add(new RoomParticipant(attendee) { Role = ParticipantRole.Attendee }); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             var presenter = await _communicationIdentityClient.CreateUserAsync(); | ||||||
|  |             schedule.MeetingRoomTokenID = await GetTokenResponseAsync(presenter); | ||||||
|  |             schedule.MeetingRoomUserID = presenter.Value.Id; | ||||||
|  |             roomParticipants.Add(new RoomParticipant(presenter) { Role = ParticipantRole.Presenter }); | ||||||
|  | 
 | ||||||
|  |             CommunicationRoom room = await _roomsClient.CreateRoomAsync(DateTime.Now, DateTime.Now.AddHours(2), roomParticipants); | ||||||
|  |             schedule.MeetingRoomID = room.Id; | ||||||
|  |             schedule.Status = nameof(VideoConferenceStatus.InProgress); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private LawyerVideoConferenceSchedule GetOrCreateNewSchedule(Guid transaction_UID) | ||||||
|  |         { | ||||||
|  |             var transactionEntity = _dbContext.Transactions | ||||||
|  |                 .Include(t => t.TransactionSignatories) | ||||||
|  |                 .Single(t => t.Transaction_UID == transaction_UID); | ||||||
|  | 
 | ||||||
|  |             var schedule = _dbContext.LawyerVideoConferenceSchedules | ||||||
|  |                 .Include(sched => sched.Transaction) | ||||||
|  |                 .FirstOrDefault(sched => sched.TransactionID == transactionEntity.TransactionID); | ||||||
|  |             if (schedule != null) | ||||||
|  |             { | ||||||
|  |                 return schedule; | ||||||
|  |             } | ||||||
|  |             schedule = new LawyerVideoConferenceSchedule | ||||||
|  |             { | ||||||
|  |                 LawyerVideoConferenceSchedule_UID = Guid.CreateVersion7(DateTime.UtcNow), | ||||||
|  |                 CreatedOn = DateTime.UtcNow, | ||||||
|  |                 LawyerID = transactionEntity.LawyerID.GetValueOrDefault(), | ||||||
|  |                 TransactionID = transactionEntity.TransactionID, | ||||||
|  |                 Status = nameof(VideoConferenceStatus.New) | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             var participants = transactionEntity.TransactionSignatories.ConvertAll(signatory => new LawyerVideoConferenceParticipant | ||||||
|  |             { | ||||||
|  |                 CreatedOn = DateTime.UtcNow, | ||||||
|  |                 Status = nameof(VideoConferenceStatus.New), | ||||||
|  |                 LawyerVideoConferenceParticipant_UID = Guid.CreateVersion7(DateTime.UtcNow), | ||||||
|  |                 ParticipantID = signatory.UserID | ||||||
|  |             }); | ||||||
|  |             participants.Add(new LawyerVideoConferenceParticipant | ||||||
|  |             { | ||||||
|  |                 CreatedOn = DateTime.UtcNow, | ||||||
|  |                 Status = nameof(VideoConferenceStatus.New), | ||||||
|  |                 LawyerVideoConferenceParticipant_UID = Guid.CreateVersion7(DateTime.UtcNow), | ||||||
|  |                 ParticipantID = transactionEntity.PrincipalID, | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |             schedule.MeetingDate = DateTime.UtcNow; | ||||||
|  |             schedule.LawyerVideoConferenceParticipants = participants.ToList(); | ||||||
|  |             schedule.Transaction = transactionEntity; | ||||||
|  |             return schedule; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private async Task<string> GetTokenResponseAsync(Response<CommunicationUserIdentifier> user) | ||||||
|  |         { | ||||||
|  |             var tokenResponse = await _communicationIdentityClient.GetTokenAsync(user, new[] { CommunicationTokenScope.VoIP }); | ||||||
|  |             return tokenResponse.Value.Token; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private async Task<string> StartRecordingAsync(string serverCallID) | ||||||
|  |         { | ||||||
|  |             ArgumentException.ThrowIfNullOrWhiteSpace(serverCallID); | ||||||
|  |             CallLocator callLocator = new ServerCallLocator(serverCallID); | ||||||
|  |             var uri = _configuration.GetValue<string>("UriRecordingBlobContainer") ?? string.Empty; | ||||||
|  |             var recordingResult = await _callAutomationClient | ||||||
|  |                 .GetCallRecording().StartAsync(new StartRecordingOptions(callLocator) | ||||||
|  |                 { | ||||||
|  |                     RecordingContent = RecordingContent.AudioVideo, | ||||||
|  |                     RecordingStorage = RecordingStorage.CreateAzureBlobContainerRecordingStorage(new Uri(uri)), | ||||||
|  |                     RecordingFormat = RecordingFormat.Mp4 | ||||||
|  |                 }); | ||||||
|  |             return recordingResult.Value.RecordingId; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private async Task StopRecordingAsync(LawyerVideoConferenceSchedule schedule) | ||||||
|  |         { | ||||||
|  |             if (string.IsNullOrEmpty(schedule.ServerCallID)) | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine("ServerCallID is not set for this transaction."); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (string.IsNullOrEmpty(schedule.RecordingID)) | ||||||
|  |             { | ||||||
|  |                 Console.WriteLine("Recording ID is not set for this transaction."); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             await _callAutomationClient.GetCallRecording().StopAsync(schedule.RecordingID); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										44
									
								
								EnotaryoPH/EnotaryoPH.Web/EnotaryoPH.Web.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								EnotaryoPH/EnotaryoPH.Web/EnotaryoPH.Web.csproj
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | |||||||
|  | <Project Sdk="Microsoft.NET.Sdk.Web"> | ||||||
|  | 
 | ||||||
|  | 	<PropertyGroup> | ||||||
|  | 		<TargetFramework>net9.0</TargetFramework> | ||||||
|  | 		<Nullable>enable</Nullable> | ||||||
|  | 		<ImplicitUsings>enable</ImplicitUsings> | ||||||
|  | 		<UserSecretsId>4082ec67-5a76-4239-b16a-4ab16e73b32a</UserSecretsId> | ||||||
|  | 	</PropertyGroup> | ||||||
|  | 
 | ||||||
|  | 	<ItemGroup> | ||||||
|  | 		<PackageReference Include="Azure.Communication.CallAutomation" Version="1.3.0" /> | ||||||
|  | 		<PackageReference Include="Azure.Communication.Identity" Version="1.3.1" /> | ||||||
|  | 		<PackageReference Include="Azure.Communication.Rooms" Version="1.1.1" /> | ||||||
|  | 		<PackageReference Include="Azure.Storage.Queues" Version="12.22.0" /> | ||||||
|  | 		<PackageReference Include="CompreFace.NET.Sdk" Version="1.0.2" /> | ||||||
|  | 		<PackageReference Include="Coravel" Version="6.0.2" /> | ||||||
|  | 		<PackageReference Include="Coravel.Mailer" Version="7.1.0" /> | ||||||
|  | 		<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="8.0.14" /> | ||||||
|  | 		<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.2.0" /> | ||||||
|  | 		<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.1" /> | ||||||
|  | 		<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.1" /> | ||||||
|  | 		<PackageReference Include="MimeKit" Version="4.9.0" /> | ||||||
|  | 		<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> | ||||||
|  | 		<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.3" /> | ||||||
|  | 		<PackageReference Include="Syncfusion.DocIO.Net.Core" Version="28.2.12" /> | ||||||
|  | 		<PackageReference Include="Syncfusion.EJ2.AspNet.Core" Version="28.2.12" /> | ||||||
|  | 		<PackageReference Include="Syncfusion.EJ2.PdfViewer.AspNet.Core" Version="28.2.12" /> | ||||||
|  | 		<PackageReference Include="Syncfusion.Licensing" Version="28.2.12" /> | ||||||
|  | 		<PackageReference Include="System.Text.Json" Version="9.0.1" /> | ||||||
|  | 	</ItemGroup> | ||||||
|  | 
 | ||||||
|  | 	<ItemGroup> | ||||||
|  | 		<ProjectReference Include="..\EnotaryoPH.Data\EnotaryoPH.Data.csproj" /> | ||||||
|  | 	</ItemGroup> | ||||||
|  | 
 | ||||||
|  | 	<ItemGroup> | ||||||
|  | 	  <Folder Include="wwwroot\lib\jquery.unobtrusive-ajax\" /> | ||||||
|  | 	  <Folder Include="wwwroot\lib\signalr\" /> | ||||||
|  | 	</ItemGroup> | ||||||
|  | 
 | ||||||
|  | 	<Target Name="ParcelBuild" BeforeTargets="Build"> | ||||||
|  | 		<Exec Command="npm run build" /> | ||||||
|  | 	</Target> | ||||||
|  | </Project> | ||||||
| @ -0,0 +1,16 @@ | |||||||
|  | using Coravel.Mailer.Mail; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Mailables | ||||||
|  | { | ||||||
|  |     public class OneTimePasswordMailable : Mailable<OneTimePasswordViewModel> | ||||||
|  |     { | ||||||
|  |         private readonly OneTimePasswordViewModel _model; | ||||||
|  | 
 | ||||||
|  |         public OneTimePasswordMailable(OneTimePasswordViewModel model) => _model = model; | ||||||
|  | 
 | ||||||
|  |         public override void Build() => this | ||||||
|  |             .To(_model.Email) | ||||||
|  |             .From("noreply@enotaryoph.com") | ||||||
|  |             .View("~/Views/Mail/OneTimePassword.cshtml", _model); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,12 @@ | |||||||
|  | namespace EnotaryoPH.Web.Mailables | ||||||
|  | { | ||||||
|  |     public class OneTimePasswordViewModel | ||||||
|  |     { | ||||||
|  |         public string DocumentType { get; set; } | ||||||
|  |         public string Email { get; set; } | ||||||
|  |         public string LawyerName { get; set; } | ||||||
|  |         public string MeetingRoomURL { get; set; } | ||||||
|  |         public string OTP { get; set; } | ||||||
|  |         public string ParticipantName { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,16 @@ | |||||||
|  | using Coravel.Mailer.Mail; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Mailables | ||||||
|  | { | ||||||
|  |     public class SignatoryInvitationMailable : Mailable<SignatoryViewModel> | ||||||
|  |     { | ||||||
|  |         private readonly SignatoryViewModel _model; | ||||||
|  | 
 | ||||||
|  |         public SignatoryInvitationMailable(SignatoryViewModel model) => _model = model; | ||||||
|  | 
 | ||||||
|  |         public override void Build() => this | ||||||
|  |             .To(_model.Email) | ||||||
|  |             .From("noreply@enotaryoph.com") | ||||||
|  |             .View("~/Views/Mail/SignatoryInvitation.cshtml", _model); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										10
									
								
								EnotaryoPH/EnotaryoPH.Web/Mailables/SignatoryViewModel.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								EnotaryoPH/EnotaryoPH.Web/Mailables/SignatoryViewModel.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | namespace EnotaryoPH.Web.Mailables | ||||||
|  | { | ||||||
|  |     public class SignatoryViewModel | ||||||
|  |     { | ||||||
|  |         public string Email { get; set; } | ||||||
|  |         public string InvitationURL { get; set; } | ||||||
|  |         public string MainPrincipalName { get; set; } | ||||||
|  |         public string SignatoryType { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										32
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/404.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/404.cshtml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | @page | ||||||
|  | @{ | ||||||
|  |     Layout = "_Blank"; | ||||||
|  | } | ||||||
|  | <body> | ||||||
|  |     <header></header> | ||||||
|  |     <div class="container" style="max-width: 1000px;font-weight: bold;"> | ||||||
|  |         <nav class="navbar navbar-expand-md bg-body py-3"> | ||||||
|  |             <div class="container"> | ||||||
|  |                 <a class="navbar-brand d-flex align-items-center" href="/"> | ||||||
|  |                     <span class="bs-icon-sm bs-icon-rounded d-flex justify-content-center align-items-center bs-icon" style="border-radius: 0px;"> | ||||||
|  |                         <svg class="bi bi-pen-fill" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16"> | ||||||
|  |                             <path d="m13.498.795.149-.149a1.207 1.207 0 1 1 1.707 1.708l-.149.148a1.5 1.5 0 0 1-.059 2.059L4.854 14.854a.5.5 0 0 1-.233.131l-4 1a.5.5 0 0 1-.606-.606l1-4a.5.5 0 0 1 .131-.232l9.642-9.642a.5.5 0 0 0-.642.056L6.854 4.854a.5.5 0 1 1-.708-.708L9.44.854A1.5 1.5 0 0 1 11.5.796a1.5 1.5 0 0 1 1.998-.001"></path> | ||||||
|  |                         </svg> | ||||||
|  |                     </span><span>eNotaryo PH</span> | ||||||
|  |                 </a> | ||||||
|  |             </div> | ||||||
|  |         </nav> | ||||||
|  |         <div class="text-center"> | ||||||
|  |             <div class="row text-center pt-4"> | ||||||
|  |                 <div class="col col-12 col-lg-10 mx-auto"> | ||||||
|  |                     <div class="text-center position-relative"><img class="img-fluid" src="images/404.jpg" /></div> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  |     <footer class="mt-5"> | ||||||
|  |         <div class="container" style="max-width: 1000px;"> | ||||||
|  |             <p class="text-center text-md-start">Copyright <span style="color: rgba(18, 22, 67, 0.75);">©</span> 2025 eNotaryoPH</p> | ||||||
|  |         </div> | ||||||
|  |     </footer> | ||||||
|  | </body> | ||||||
							
								
								
									
										32
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/500.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/500.cshtml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | @page | ||||||
|  | @{ | ||||||
|  |     Layout = "_Blank"; | ||||||
|  | } | ||||||
|  | <body> | ||||||
|  |     <header></header> | ||||||
|  |     <div class="container" style="max-width: 1000px;font-weight: bold;"> | ||||||
|  |         <nav class="navbar navbar-expand-md bg-body py-3"> | ||||||
|  |             <div class="container"> | ||||||
|  |                 <a class="navbar-brand d-flex align-items-center" href="/"> | ||||||
|  |                     <span class="bs-icon-sm bs-icon-rounded d-flex justify-content-center align-items-center bs-icon" style="border-radius: 0px;"> | ||||||
|  |                         <svg class="bi bi-pen-fill" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16"> | ||||||
|  |                             <path d="m13.498.795.149-.149a1.207 1.207 0 1 1 1.707 1.708l-.149.148a1.5 1.5 0 0 1-.059 2.059L4.854 14.854a.5.5 0 0 1-.233.131l-4 1a.5.5 0 0 1-.606-.606l1-4a.5.5 0 0 1 .131-.232l9.642-9.642a.5.5 0 0 0-.642.056L6.854 4.854a.5.5 0 1 1-.708-.708L9.44.854A1.5 1.5 0 0 1 11.5.796a1.5 1.5 0 0 1 1.998-.001"></path> | ||||||
|  |                         </svg> | ||||||
|  |                     </span><span>eNotaryo PH</span> | ||||||
|  |                 </a><button class="navbar-toggler" data-bs-toggle="collapse"><span class="visually-hidden">Toggle navigation</span><span class="navbar-toggler-icon"></span></button> | ||||||
|  |             </div> | ||||||
|  |         </nav> | ||||||
|  |         <div class="text-center"> | ||||||
|  |             <div class="row text-center pt-4"> | ||||||
|  |                 <div class="col col-12 col-lg-10 mx-auto"> | ||||||
|  |                     <div class="text-center position-relative"><img class="img-fluid" src="images/500.jpg" /></div> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  |     <footer class="mt-5"> | ||||||
|  |         <div class="container" style="max-width: 1000px;"> | ||||||
|  |             <p class="text-center text-md-start">Copyright <span style="color: rgba(18, 22, 67, 0.75);">©</span> 2025 eNotaryoPH</p> | ||||||
|  |         </div> | ||||||
|  |     </footer> | ||||||
|  | </body> | ||||||
							
								
								
									
										8
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/About.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/About.cshtml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | @page | ||||||
|  | @model EnotaryoPH.Web.Pages.AboutModel | ||||||
|  | @{ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | <div class="container text-center p-5 my-auto" style="max-width: 1000px;font-weight: bold;"> | ||||||
|  |     <h2>This website is brought to you with ❤️ by <a href="https://jfaquinojr.com">Mang Jose</a>.</h2> | ||||||
|  | </div> | ||||||
							
								
								
									
										12
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/About.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/About.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  | using Microsoft.AspNetCore.Mvc.RazorPages; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Pages | ||||||
|  | { | ||||||
|  |     public class AboutModel : PageModel | ||||||
|  |     { | ||||||
|  |         public void OnGet() | ||||||
|  |         { | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,32 @@ | |||||||
|  | using EnotaryoPH.Data; | ||||||
|  | using EnotaryoPH.Web.Common.Models; | ||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  | using Microsoft.AspNetCore.Mvc.RazorPages; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Pages | ||||||
|  | { | ||||||
|  |     public abstract class BaseIdentificationDocumentPageModel : PageModel | ||||||
|  |     { | ||||||
|  |         protected readonly NotaryoDBContext _notaryoDBContext; | ||||||
|  | 
 | ||||||
|  |         protected BaseIdentificationDocumentPageModel(NotaryoDBContext notaryoDBContext) => _notaryoDBContext = notaryoDBContext; | ||||||
|  | 
 | ||||||
|  |         protected void CreateIdentificationDocument(Guid user_UID) | ||||||
|  |         { | ||||||
|  |             ArgumentOutOfRangeException.ThrowIfEqual(Guid.Empty, user_UID); | ||||||
|  |             var user = _notaryoDBContext.Users.AsNoTracking().FirstOrDefault(u => u.User_UID == user_UID) ?? throw new ArgumentException("User does not exist."); | ||||||
|  |             var entity = NewIdentificationDocument.ToEntity(user.UserID); | ||||||
|  |             _notaryoDBContext.Add(entity); | ||||||
|  |             _notaryoDBContext.SaveChanges(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         [BindProperty(SupportsGet = true)] | ||||||
|  |         public Guid IdentificationDocument_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [BindProperty] | ||||||
|  |         public IdentificationDocumentModel NewIdentificationDocument { get; set; } | ||||||
|  | 
 | ||||||
|  |         [BindProperty] | ||||||
|  |         public bool UploadNewIdentification { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										148
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/BaseTakeSelfiePageModel.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/BaseTakeSelfiePageModel.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,148 @@ | |||||||
|  | using EnotaryoPH.Data; | ||||||
|  | using EnotaryoPH.Data.Entities; | ||||||
|  | using Exadel.Compreface.Clients.CompreFaceClient; | ||||||
|  | using Exadel.Compreface.DTOs.FaceVerificationDTOs.FaceVerification; | ||||||
|  | using Exadel.Compreface.Services; | ||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  | using Microsoft.AspNetCore.Mvc.RazorPages; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Pages | ||||||
|  | { | ||||||
|  |     public class BaseTakeSelfiePageModel : PageModel | ||||||
|  |     { | ||||||
|  |         protected readonly NotaryoDBContext _notaryoDBContext; | ||||||
|  |         private readonly ICompreFaceClient _compreFaceClient; | ||||||
|  |         private readonly IConfiguration _configuration; | ||||||
|  |         private readonly ICurrentUserService _currentUserService; | ||||||
|  |         private Transaction _transactionEntity; | ||||||
|  |         private User _user; | ||||||
|  | 
 | ||||||
|  |         public BaseTakeSelfiePageModel(NotaryoDBContext notaryoDBContext, ICurrentUserService currentUserService, ICompreFaceClient compreFaceClient, IConfiguration configuration) | ||||||
|  |         { | ||||||
|  |             _notaryoDBContext = notaryoDBContext; | ||||||
|  |             _currentUserService = currentUserService; | ||||||
|  |             _compreFaceClient = compreFaceClient; | ||||||
|  |             _configuration = configuration; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         protected async Task<bool> PostAsync() | ||||||
|  |         { | ||||||
|  |             var selfieImage = Convert.FromBase64String(SelfieBase64Image.Split(",")[1]) ?? []; | ||||||
|  |             var identificationDocument = _notaryoDBContext.IdentificationDocuments.First(e => e.UserID == CurrentUser.UserID); | ||||||
|  |             var faceMatches = await VerifySelfieAsync(selfieImage, identificationDocument); | ||||||
|  | 
 | ||||||
|  |             var isMatchSuccess = faceMatches.Any(); | ||||||
|  |             if (isMatchSuccess) | ||||||
|  |             { | ||||||
|  |                 var signatory = _notaryoDBContext.TransactionSignatories.Include(ts => ts.Transaction).FirstOrDefault(x => x.UserID == CurrentUser.UserID); | ||||||
|  |                 if (signatory != null) | ||||||
|  |                 { | ||||||
|  |                     signatory.Status = nameof(SignatoryStatus.FaceMatch); | ||||||
|  |                     _notaryoDBContext.Update(signatory); | ||||||
|  |                     _transactionEntity = signatory.Transaction; | ||||||
|  |                     Transaction_UID = _transactionEntity.Transaction_UID.Value; | ||||||
|  |                 } | ||||||
|  |                 else if (!CurrentUser.Role.IsInList(nameof(UserType.Principal), nameof(UserType.SuperUser), nameof(UserType.Administrator))) | ||||||
|  |                 { | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if (CurrentTransaction.TransactionID == 0) | ||||||
|  |                 { | ||||||
|  |                     var newTransaction = new Transaction | ||||||
|  |                     { | ||||||
|  |                         Transaction_UID = Guid.CreateVersion7(DateTime.UtcNow), | ||||||
|  |                         CreatedOn = DateTime.UtcNow, | ||||||
|  |                         TransactionDate = DateTime.UtcNow, | ||||||
|  |                         Status = nameof(TransactionState.New), | ||||||
|  |                         PrincipalID = CurrentUser.UserID | ||||||
|  |                     }; | ||||||
|  |                     _notaryoDBContext.Add(CurrentTransaction); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 var selfieEntity = CreateOrUpdateSelfie(selfieImage); | ||||||
|  |                 selfieEntity.Transaction = CurrentTransaction; | ||||||
|  |                 selfieEntity.IdentificationDocumentID = identificationDocument.IdentificationDocumentID; | ||||||
|  |                 _notaryoDBContext.UpdateOrCreate(selfieEntity); | ||||||
|  |                 _notaryoDBContext.SaveChanges(); | ||||||
|  |             } | ||||||
|  |             return isMatchSuccess; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private TransactionSelfie CreateOrUpdateSelfie(byte[] selfieImage) | ||||||
|  |         { | ||||||
|  |             TransactionSelfie selfieEntity; | ||||||
|  |             if (TransactionSelfie_UID == Guid.Empty) | ||||||
|  |             { | ||||||
|  |                 selfieEntity = new TransactionSelfie | ||||||
|  |                 { | ||||||
|  |                     CreatedOn = DateTime.UtcNow, | ||||||
|  |                     TransactionSelfie_UID = Guid.CreateVersion7(DateTime.UtcNow), | ||||||
|  |                     UserID = CurrentUser.UserID, | ||||||
|  |                     TransactionID = CurrentTransaction.TransactionID, | ||||||
|  |                 }; | ||||||
|  |                 TransactionSelfie_UID = selfieEntity.TransactionSelfie_UID.Value; | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 selfieEntity = _notaryoDBContext.TransactionSelfies.FirstOrDefault(e => e.TransactionSelfie_UID == TransactionSelfie_UID); | ||||||
|  |             } | ||||||
|  |             selfieEntity.File = Convert.FromBase64String(SelfieBase64Image.Split(",")[1]); | ||||||
|  |             return selfieEntity; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private async Task<IEnumerable<FaceMatches>> VerifySelfieAsync(byte[] selfieImage, IdentificationDocument identificationDocument) | ||||||
|  |         { | ||||||
|  |             var selfiePath = Path.Combine(Path.GetTempPath(), "Selfies"); | ||||||
|  |             if (!Directory.Exists(selfiePath)) | ||||||
|  |             { | ||||||
|  |                 Directory.CreateDirectory(selfiePath); | ||||||
|  |             } | ||||||
|  |             var identificationDocumentPath = Path.Combine(selfiePath, $"{identificationDocument.IdentificationDocument_UID}.jpg"); | ||||||
|  | 
 | ||||||
|  |             var apiKey = _configuration.GetValue<string>("CompreFaceConfig:APIKey"); | ||||||
|  |             var client = _compreFaceClient.GetCompreFaceService<VerificationService>(apiKey); | ||||||
|  |             var faceVerificationRequest = new FaceVerificationRequestByBytes() | ||||||
|  |             { | ||||||
|  |                 SourceImageInBytes = selfieImage, | ||||||
|  |                 TargetImageInBytes = identificationDocument.File, | ||||||
|  |                 DetProbThreshold = 0.81m, | ||||||
|  |                 Limit = 1, | ||||||
|  |                 Status = false, | ||||||
|  |                 FacePlugins = [] | ||||||
|  |             }; | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 var result = await client.VerifyAsync(faceVerificationRequest); | ||||||
|  |                 var faceMatches = result.Result.SelectMany(x => x.FaceMatches); | ||||||
|  |                 return faceMatches; | ||||||
|  |             } | ||||||
|  |             catch (Exception) | ||||||
|  |             { | ||||||
|  |                 return Enumerable.Empty<FaceMatches>(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         [BindProperty] | ||||||
|  |         public string SelfieBase64Image { get; set; } | ||||||
|  | 
 | ||||||
|  |         [BindProperty(SupportsGet = true)] | ||||||
|  |         public Guid Transaction_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         [BindProperty(SupportsGet = true)] | ||||||
|  |         public Guid TransactionSelfie_UID { get; set; } | ||||||
|  | 
 | ||||||
|  |         protected User CurrentUser => _user ??= _notaryoDBContext.Users.AsNoTracking().First(x => x.User_UID == _currentUserService.GetUser_UID()); | ||||||
|  | 
 | ||||||
|  |         protected Transaction CurrentTransaction => _transactionEntity | ||||||
|  |             ??= _notaryoDBContext.Transactions.AsNoTracking().FirstOrDefault(x => x.Transaction_UID == Transaction_UID) | ||||||
|  |             ?? new Transaction | ||||||
|  |             { | ||||||
|  |                 Transaction_UID = Guid.CreateVersion7(DateTime.UtcNow), | ||||||
|  |                 CreatedOn = DateTime.UtcNow, | ||||||
|  |                 TransactionDate = DateTime.UtcNow, | ||||||
|  |                 Status = nameof(TransactionState.New), | ||||||
|  |                 PrincipalID = CurrentUser.UserID | ||||||
|  |             }; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										26
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/Error.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/Error.cshtml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | @page "{statusCode}" | ||||||
|  | @model ErrorModel | ||||||
|  | @{ | ||||||
|  |     ViewData["Title"] = "Error"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | <h1 class="text-danger">Error.</h1> | ||||||
|  | <h2 class="text-danger">An error occurred while processing your request.</h2> | ||||||
|  | 
 | ||||||
|  | @if (Model.ShowRequestId) | ||||||
|  | { | ||||||
|  |     <p> | ||||||
|  |         <strong>Request ID:</strong> <code>@Model.RequestId</code> | ||||||
|  |     </p> | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | <h3>Development Mode</h3> | ||||||
|  | <p> | ||||||
|  |     Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred. | ||||||
|  | </p> | ||||||
|  | <p> | ||||||
|  |     <strong>The Development environment shouldn't be enabled for deployed applications.</strong> | ||||||
|  |     It can result in displaying sensitive information from exceptions to end users. | ||||||
|  |     For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong> | ||||||
|  |     and restarting the app. | ||||||
|  | </p> | ||||||
							
								
								
									
										38
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/Error.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/Error.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | |||||||
|  | using System.Diagnostics; | ||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  | using Microsoft.AspNetCore.Mvc.RazorPages; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Pages | ||||||
|  | { | ||||||
|  |     [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] | ||||||
|  |     [IgnoreAntiforgeryToken] | ||||||
|  |     public class ErrorModel : PageModel | ||||||
|  |     { | ||||||
|  |         private readonly ILogger<ErrorModel> _logger; | ||||||
|  | 
 | ||||||
|  |         public ErrorModel(ILogger<ErrorModel> logger) => _logger = logger; | ||||||
|  | 
 | ||||||
|  |         public IActionResult OnGet() | ||||||
|  |         { | ||||||
|  |             RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; | ||||||
|  | 
 | ||||||
|  |             if (StatusCode == "404") | ||||||
|  |             { | ||||||
|  |                 return Redirect("/404"); | ||||||
|  |             } | ||||||
|  |             else if (StatusCode == "500") | ||||||
|  |             { | ||||||
|  |                 return Redirect("/500"); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return Page(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public string? RequestId { get; set; } | ||||||
|  | 
 | ||||||
|  |         public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); | ||||||
|  | 
 | ||||||
|  |         [FromRoute] | ||||||
|  |         public string StatusCode { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										4
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/ForgotPassword.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/ForgotPassword.cshtml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | @page | ||||||
|  | @model EnotaryoPH.Web.Pages.ForgotPasswordModel | ||||||
|  | @{ | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/ForgotPassword.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/ForgotPassword.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  | using Microsoft.AspNetCore.Mvc.RazorPages; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Pages | ||||||
|  | { | ||||||
|  |     public class ForgotPasswordModel : PageModel | ||||||
|  |     { | ||||||
|  |         public void OnGet() | ||||||
|  |         { | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										133
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/Index.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/Index.cshtml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,133 @@ | |||||||
|  | @page | ||||||
|  | @model IndexModel | ||||||
|  | @{ | ||||||
|  |     ViewData["Title"] = "Notarize Documents Online"; | ||||||
|  |     Layout = "_Blank"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     <header></header> | ||||||
|  |     <div class="container" style="max-width: 1000px;font-weight: bold;"> | ||||||
|  |         <nav class="navbar navbar-expand-md bg-body py-3"> | ||||||
|  |             <div class="container"> | ||||||
|  |                 <a class="navbar-brand d-flex align-items-center" href="#"> | ||||||
|  |                     <span class="bs-icon-sm bs-icon-rounded d-flex justify-content-center align-items-center bs-icon" style="border-radius: 0px;"> | ||||||
|  |                         <svg class="bi bi-pen-fill" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16"> | ||||||
|  |                             <path d="m13.498.795.149-.149a1.207 1.207 0 1 1 1.707 1.708l-.149.148a1.5 1.5 0 0 1-.059 2.059L4.854 14.854a.5.5 0 0 1-.233.131l-4 1a.5.5 0 0 1-.606-.606l1-4a.5.5 0 0 1 .131-.232l9.642-9.642a.5.5 0 0 0-.642.056L6.854 4.854a.5.5 0 1 1-.708-.708L9.44.854A1.5 1.5 0 0 1 11.5.796a1.5 1.5 0 0 1 1.998-.001"></path> | ||||||
|  |                         </svg> | ||||||
|  |                     </span><span>eNotaryo PH</span> | ||||||
|  |                 </a><button class="navbar-toggler" data-bs-toggle="collapse" data-bs-target="#navcol-3"><span class="visually-hidden">Toggle navigation</span><span class="navbar-toggler-icon"></span></button> | ||||||
|  |                 <div id="navcol-3" class="collapse navbar-collapse"> | ||||||
|  |                     <ul class="navbar-nav mx-auto"> | ||||||
|  |                         <li class="nav-item"><a class="nav-link active" href="/">Home</a></li> | ||||||
|  |                         <li class="nav-item"></li> | ||||||
|  |                         <li class="nav-item"><a class="nav-link" href="#HowItWorks">How it works</a></li> | ||||||
|  |                         <li class="nav-item"><a class="nav-link" href="#Contact">Contact</a></li> | ||||||
|  |                     </ul> | ||||||
|  |                     <a href="/login" class="btn btn-primary">Login</a> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </nav> | ||||||
|  |         <div class="text-center"> | ||||||
|  |             <div class="row text-center pt-4"> | ||||||
|  |                 <div class="col mx-auto col-md-8"> | ||||||
|  |                     <h1 class="display-4 fw-bold mb-5"><strong><span style="color: rgb(18, 22, 67);">Notarize your documents from the </span></strong><span class="underline">comfort</span><strong><span style="color: rgb(18, 22, 67);"> of your home or office </span></strong></h1> | ||||||
|  |                     <div></div> | ||||||
|  |                     <p class="fs-5 text-muted mb-5">Subscribe to our newsletter to get the latest updates.</p> | ||||||
|  |                     <form class="d-flex justify-content-center flex-wrap"> | ||||||
|  |                         <div class="shadow-lg mb-3"><input class="form-control" type="email" placeholder="Your Email" /></div> | ||||||
|  |                         <div class="shadow-lg mb-3"><button class="btn btn-primary disabled" type="button">Subscribe</button></div> | ||||||
|  |                     </form> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="col col-12 col-lg-10 mx-auto"> | ||||||
|  |                     <div class="text-center position-relative"><img class="img-fluid" src="images/landing_02.png" /></div> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  |     <section class="mt-5"> | ||||||
|  |         <div class="container" style="max-width: 1000px;"> | ||||||
|  |             <h3 id="HowItWorks" class="display-6 fw-bold text-center">How Does It Work?</h3> | ||||||
|  |             <div class="row"> | ||||||
|  |                 <div class="col d-flex"> | ||||||
|  |                     <div class="card"> | ||||||
|  |                         <div class="card-body m-4"> | ||||||
|  |                             <div class="text-start py-3"> | ||||||
|  |                                 <svg class="bi bi-camera fs-1 text-start" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16"> | ||||||
|  |                                     <path d="M15 12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1h1.172a3 3 0 0 0 2.12-.879l.83-.828A1 1 0 0 1 6.827 3h2.344a1 1 0 0 1 .707.293l.828.828A3 3 0 0 0 12.828 5H14a1 1 0 0 1 1 1zM2 4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2h-1.172a2 2 0 0 1-1.414-.586l-.828-.828A2 2 0 0 0 9.172 2H6.828a2 2 0 0 0-1.414.586l-.828.828A2 2 0 0 1 3.172 4z"></path> | ||||||
|  |                                     <path d="M8 11a2.5 2.5 0 1 1 0-5 2.5 2.5 0 0 1 0 5m0 1a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7M3 6.5a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0"></path> | ||||||
|  |                                 </svg> | ||||||
|  |                             </div> | ||||||
|  |                             <h4 class="card-title">Take a Selfie</h4> | ||||||
|  |                             <h6 class="text-muted card-subtitle mb-2">Use your phone or web camera</h6> | ||||||
|  |                             <p class="card-text">Sit back and relax while our facial recognition system analyze your identification.</p><a class="card-link btn-sm" href="#"> | ||||||
|  |                                 Learn More | ||||||
|  |                                 <svg class="bi bi-arrow-right" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16"> | ||||||
|  |                                     <path fill-rule="evenodd" d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8"></path> | ||||||
|  |                                 </svg> | ||||||
|  |                             </a> | ||||||
|  |                         </div> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="col d-flex"> | ||||||
|  |                     <div class="card"> | ||||||
|  |                         <div class="card-body m-4"> | ||||||
|  |                             <div class="text-start py-3"> | ||||||
|  |                                 <svg class="bi bi-cloud-upload fs-1 text-start" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16"> | ||||||
|  |                                     <path fill-rule="evenodd" d="M4.406 1.342A5.53 5.53 0 0 1 8 0c2.69 0 4.923 2 5.166 4.579C14.758 4.804 16 6.137 16 7.773 16 9.569 14.502 11 12.687 11H10a.5.5 0 0 1 0-1h2.688C13.979 10 15 8.988 15 7.773c0-1.216-1.02-2.228-2.313-2.228h-.5v-.5C12.188 2.825 10.328 1 8 1a4.53 4.53 0 0 0-2.941 1.1c-.757.652-1.153 1.438-1.153 2.055v.448l-.445.049C2.064 4.805 1 5.952 1 7.318 1 8.785 2.23 10 3.781 10H6a.5.5 0 0 1 0 1H3.781C1.708 11 0 9.366 0 7.318c0-1.763 1.266-3.223 2.942-3.593.143-.863.698-1.723 1.464-2.383z"></path> | ||||||
|  |                                     <path fill-rule="evenodd" d="M7.646 4.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 5.707V14.5a.5.5 0 0 1-1 0V5.707L5.354 7.854a.5.5 0 1 1-.708-.708z"></path> | ||||||
|  |                                 </svg> | ||||||
|  |                             </div> | ||||||
|  |                             <h4 class="card-title">Upload the document</h4> | ||||||
|  |                             <h6 class="text-muted card-subtitle mb-2">PDF and MS Word Documents</h6> | ||||||
|  |                             <p class="card-text">Simply upload your document and enter the necessary information and we will book an available notary public for you.</p><a class="card-link btn-sm" href="#"> | ||||||
|  |                                 Learn More | ||||||
|  |                                 <svg class="bi bi-arrow-right" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16"> | ||||||
|  |                                     <path fill-rule="evenodd" d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8"></path> | ||||||
|  |                                 </svg> | ||||||
|  |                             </a> | ||||||
|  |                         </div> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="col d-flex"> | ||||||
|  |                     <div class="card"> | ||||||
|  |                         <div class="card-body m-4"> | ||||||
|  |                             <div class="text-start py-3"> | ||||||
|  |                                 <svg class="bi bi-camera-video fs-1 text-start" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16"> | ||||||
|  |                                     <path fill-rule="evenodd" d="M0 5a2 2 0 0 1 2-2h7.5a2 2 0 0 1 1.983 1.738l3.11-1.382A1 1 0 0 1 16 4.269v7.462a1 1 0 0 1-1.406.913l-3.111-1.382A2 2 0 0 1 9.5 13H2a2 2 0 0 1-2-2zm11.5 5.175 3.5 1.556V4.269l-3.5 1.556zM2 4a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h7.5a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1z"></path> | ||||||
|  |                                 </svg> | ||||||
|  |                             </div> | ||||||
|  |                             <h4 class="card-title">Video Conference</h4> | ||||||
|  |                             <h6 class="text-muted card-subtitle mb-2">Meet with Notary Public</h6> | ||||||
|  |                             <p class="card-text">The final step is to talk to our notary public team. Once payment has been settled, you can now download the notarized document.</p><a class="card-link btn-sm" href="#"> | ||||||
|  |                                 Learn More | ||||||
|  |                                 <svg class="bi bi-arrow-right" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16"> | ||||||
|  |                                     <path fill-rule="evenodd" d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8"></path> | ||||||
|  |                                 </svg> | ||||||
|  |                             </a> | ||||||
|  |                         </div> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </section> | ||||||
|  |     <section class="mt-5"> | ||||||
|  |         <div class="container" style="max-width: 1000px;"> | ||||||
|  |             <h3 id="Contact" class="display-6 fw-bold text-center">Got Any Questions?</h3> | ||||||
|  |             <div class="row"> | ||||||
|  |                 <div class="col col-md-8 col-xl-6 mx-auto text-center"> | ||||||
|  |                     <form class="p-3 p-xl-4"> | ||||||
|  |                         <div class="mb-3"><input class="form-control shadow" type="text" placeholder="Name" /></div> | ||||||
|  |                         <div class="mb-3"><input class="form-control shadow" type="email" placeholder="Email" /></div> | ||||||
|  |                         <div class="mb-3"><textarea class="form-control shadow" placeholder="Message" rows="4"></textarea></div> | ||||||
|  |                         <div><button class="btn btn-primary d-block w-100 shadow-lg" type="button">Submit</button></div> | ||||||
|  |                     </form> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </section> | ||||||
|  |     <footer class="mt-5"> | ||||||
|  |         <div class="container" style="max-width: 1000px;"> | ||||||
|  |             <p class="text-center text-md-start">Copyright <span style="color: rgba(18, 22, 67, 0.75);">©</span> 2025 eNotaryoPH</p> | ||||||
|  |         </div> | ||||||
|  |     </footer> | ||||||
							
								
								
									
										48
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/Index.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/Index.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  | using Microsoft.AspNetCore.Mvc.RazorPages; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Pages | ||||||
|  | { | ||||||
|  |     public class IndexModel : PageModel | ||||||
|  |     { | ||||||
|  |         private readonly ICurrentUserService _currentUserService; | ||||||
|  |         private readonly INotificationService _notificationService; | ||||||
|  |         private readonly IEventService _eventService; | ||||||
|  | 
 | ||||||
|  |         public IndexModel(ICurrentUserService currentUserService, INotificationService notificationService, IEventService eventService) | ||||||
|  |         { | ||||||
|  |             _currentUserService = currentUserService; | ||||||
|  |             _notificationService = notificationService; | ||||||
|  |             _eventService = eventService; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public IActionResult OnGet() | ||||||
|  |         { | ||||||
|  |             if (_currentUserService.IsAuthenticated() == false) | ||||||
|  |             { | ||||||
|  |                 return Page(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             var role = _currentUserService.GetRole(); | ||||||
|  |             if (role == nameof(UserType.Principal)) | ||||||
|  |             { | ||||||
|  |                 return RedirectToPage("/Principal/Dashboard/Dashboard"); | ||||||
|  |             } | ||||||
|  |             else if (role == nameof(UserType.Notary)) | ||||||
|  |             { | ||||||
|  |                 return RedirectToPage("/Notary/Dashboard/Dashboard"); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return Page(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public async Task<IActionResult> OnPostAsync() | ||||||
|  |         { | ||||||
|  |             var message = new { Message = "the quick brown fox jumps over the lazy dog." }; | ||||||
|  | 
 | ||||||
|  |             await _eventService.LogAsync(NotaryoEvent.TransactionApproved, new Guid("0195dfd2-9048-77f1-9d9d-974828cb3e68")); | ||||||
|  |             //await _notificationService.NotifyUserAsync("admin@enotaryo.ph", JsonSerializer.Serialize(message)); | ||||||
|  |             return Redirect("/"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										36
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/Login.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/Login.cshtml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | @page | ||||||
|  | @model EnotaryoPH.Web.Pages.LoginModel | ||||||
|  | @{ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | <div class="container"> | ||||||
|  |     <h1 class="my-4">Login</h1> | ||||||
|  |     <div class="row"> | ||||||
|  |         <div class="col"> | ||||||
|  |             <div class="alert alert-danger alert-validation"> | ||||||
|  |                 @Html.ValidationSummary() | ||||||
|  |             </div> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  |     <div class="row"> | ||||||
|  |         <div class="col-12 col-md-8 col-lg-6 col-xl-5"> | ||||||
|  |             <form method="post"> | ||||||
|  |                 <div class="row"> | ||||||
|  |                     <div class="col"><label class="form-label" for="Email">Email</label><input id="Email" class="form-control mb-3" type="email" asp-for="Email" required /></div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="row"> | ||||||
|  |                     <div class="col"><label class="form-label" for="Password">Password</label><input id="Password" class="form-control mb-3" type="password" asp-for="Password" required /></div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="row mt-3 mb-0"> | ||||||
|  |                     <div class="col"> | ||||||
|  |                         <button class="btn btn-primary btn-lg" type="submit">Login</button> | ||||||
|  |                         <a href="/Register" class="btn btn-outline-primary btn-lg ms-1" type="button">Register </a> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="row mb-5 mt-2"> | ||||||
|  |                     <div class="col"><a href="#">Forgot password?</a></div> | ||||||
|  |                 </div> | ||||||
|  |             </form> | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
							
								
								
									
										69
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/Login.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								EnotaryoPH/EnotaryoPH.Web/Pages/Login.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,69 @@ | |||||||
|  | using System.ComponentModel.DataAnnotations; | ||||||
|  | using EnotaryoPH.Data; | ||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  | using Microsoft.AspNetCore.Mvc.RazorPages; | ||||||
|  | 
 | ||||||
|  | namespace EnotaryoPH.Web.Pages | ||||||
|  | { | ||||||
|  |     public class LoginModel : PageModel | ||||||
|  |     { | ||||||
|  |         private readonly NotaryoDBContext _notaryoDBContext; | ||||||
|  |         private readonly ISignInService _signInService; | ||||||
|  |         private readonly IPasswordService _passwordService; | ||||||
|  | 
 | ||||||
|  |         public LoginModel(IPasswordService passwordService, NotaryoDBContext notaryoDBContext, ISignInService signInService) | ||||||
|  |         { | ||||||
|  |             _passwordService = passwordService; | ||||||
|  |             _notaryoDBContext = notaryoDBContext; | ||||||
|  |             _signInService = signInService; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public async Task<IActionResult> OnGetAsync() => Page(); | ||||||
|  | 
 | ||||||
|  |         public async Task<IActionResult> OnGetLogoutAsync() | ||||||
|  |         { | ||||||
|  |             await _signInService.SignOutAsync(); | ||||||
|  |             return RedirectToPage("/Login"); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public async Task<IActionResult> OnPostAsync() | ||||||
|  |         { | ||||||
|  |             if (!ModelState.IsValid) | ||||||
|  |             { | ||||||
|  |                 return Page(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             var user = _notaryoDBContext.Users.FirstOrDefault(u => EF.Functions.Like(u.Email, Email)); | ||||||
|  |             if (user == null) | ||||||
|  |             { | ||||||
|  |                 ModelState.AddModelError("", "Invalid Email or Password"); | ||||||
|  |                 return Page(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (!_passwordService.VerifyHashedPassword(user.PasswordHash, Password)) | ||||||
|  |             { | ||||||
|  |                 ModelState.AddModelError("", "Invalid Email or Password"); | ||||||
|  |                 return Page(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             await _signInService.SignInAsync(new UserLogin | ||||||
|  |             { | ||||||
|  |                 Email = user.Email, | ||||||
|  |                 Role = user.Role, | ||||||
|  |                 User_UID = user.User_UID.Value | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |             var returnUrl = Request.Query["ReturnUrl"].ToString() ?? string.Empty; | ||||||
|  |             return Redirect(string.IsNullOrEmpty(returnUrl) ? "/" : returnUrl); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         [Required] | ||||||
|  |         [EmailAddress] | ||||||
|  |         [BindProperty] | ||||||
|  |         public string Email { get; set; } | ||||||
|  | 
 | ||||||
|  |         [Required] | ||||||
|  |         [BindProperty] | ||||||
|  |         public string Password { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user