Browse Source

Code cleanup, sealing classes (it works faster)

master
radivoje.milutinovic 3 years ago
parent
commit
e6a7e4a56c
100 changed files with 3926 additions and 5027 deletions
  1. 0
    986
      .vs/MVCTemplate/config/applicationhost.config
  2. BIN
      .vs/MVCTemplate/v16/.suo
  3. 0
    6
      .vs/VSWorkspaceState.json
  4. BIN
      .vs/secure-sharing/FileContentIndex/0142d46e-c874-48b6-a8bb-ba48dcab8e67.vsidx
  5. BIN
      .vs/secure-sharing/FileContentIndex/09d2b585-d5cd-4057-9f1d-b020854c4003.vsidx
  6. BIN
      .vs/secure-sharing/FileContentIndex/3cb2fa75-118b-414e-8063-de2329515561.vsidx
  7. BIN
      .vs/secure-sharing/FileContentIndex/633da2f3-a40c-42fa-b4ab-f69482a83eac.vsidx
  8. BIN
      .vs/secure-sharing/FileContentIndex/8c195695-7fcc-4dd9-b9c4-4b36d989bc8e.vsidx
  9. BIN
      .vs/secure-sharing/FileContentIndex/fc609bc4-e013-40a1-86f2-f485881d162a.vsidx
  10. 0
    0
      .vs/secure-sharing/FileContentIndex/read.lock
  11. BIN
      .vs/secure-sharing/v17/.suo
  12. BIN
      .vs/slnx.sqlite
  13. 4
    11
      SecureSharing.Business/Dtos/BaseDto.cs
  14. 7
    13
      SecureSharing.Business/Dtos/MessageDto.cs
  15. 10
    21
      SecureSharing.Business/Infrastructure/Extensions/StartupExtensions.cs
  16. 7
    13
      SecureSharing.Business/Infrastructure/MapperProfile.cs
  17. 8
    10
      SecureSharing.Business/Infrastructure/PeriodOfValidity.cs
  18. 11
    12
      SecureSharing.Business/Infrastructure/Settings/EmailSettings.cs
  19. 18
    18
      SecureSharing.Business/Infrastructure/StartupConfiguration.cs
  20. 12
    16
      SecureSharing.Business/Interfaces/IMessageService.cs
  21. 15
    15
      SecureSharing.Business/SecureSharing.Business.csproj
  22. 79
    79
      SecureSharing.Business/Services/MessageService.cs
  23. 7
    12
      SecureSharing.Data/Data/Message.cs
  24. 7
    14
      SecureSharing.Data/DbContexts/AppDbContext.cs
  25. 13
    20
      SecureSharing.Data/Extensions/StartupExtensions.cs
  26. 17
    17
      SecureSharing.Data/SecureSharing.Data.csproj
  27. 9
    16
      SecureSharing/Areas/Identity/IdentityHostingStartup.cs
  28. 7
    7
      SecureSharing/Areas/Identity/Pages/Account/Login.cshtml
  29. 64
    79
      SecureSharing/Areas/Identity/Pages/Account/Login.cshtml.cs
  30. 7
    7
      SecureSharing/Areas/Identity/Pages/Account/Register.cshtml
  31. 79
    85
      SecureSharing/Areas/Identity/Pages/Account/Register.cshtml.cs
  32. 7
    7
      SecureSharing/Areas/Identity/Pages/Account/ResetPassword.cshtml
  33. 47
    69
      SecureSharing/Areas/Identity/Pages/Account/ResetPassword.cshtml.cs
  34. 1
    1
      SecureSharing/Areas/Identity/Pages/_ValidationScriptsPartial.cshtml
  35. 1
    1
      SecureSharing/Areas/Identity/Pages/_ViewImports.cshtml
  36. 2
    3
      SecureSharing/Areas/Identity/Pages/_ViewStart.cshtml
  37. 44
    54
      SecureSharing/Controllers/HomeController.cs
  38. 7
    9
      SecureSharing/Infrastructure/IModelFactory.cs
  39. 53
    55
      SecureSharing/Infrastructure/Middleware/ExceptionHandlingMiddleware.cs
  40. 40
    46
      SecureSharing/Infrastructure/ModelFactory.cs
  41. 5
    8
      SecureSharing/Models/ErrorViewModel.cs
  42. 9
    10
      SecureSharing/Models/LinkModel.cs
  43. 8
    15
      SecureSharing/Models/MessageModel.cs
  44. 11
    19
      SecureSharing/Program.cs
  45. 10
    10
      SecureSharing/Properties/PublishProfiles/FolderProfile.pubxml
  46. 18
    18
      SecureSharing/Properties/PublishProfiles/IISProfile.pubxml
  47. 38
    42
      SecureSharing/Quartz/JobFactory.cs
  48. 15
    15
      SecureSharing/Quartz/JobMetadata.cs
  49. 45
    40
      SecureSharing/Quartz/JobsService.cs
  50. 19
    19
      SecureSharing/Quartz/MessageDeletionJob.cs
  51. 30
    30
      SecureSharing/SecureSharing.csproj
  52. 62
    69
      SecureSharing/Startup.cs
  53. 9
    10
      SecureSharing/Views/Home/Index.cshtml
  54. 13
    15
      SecureSharing/Views/Home/Link.cshtml
  55. 1
    1
      SecureSharing/Views/Home/Privacy.cshtml
  56. 1
    1
      SecureSharing/Views/Shared/Error.cshtml
  57. 60
    61
      SecureSharing/Views/Shared/_Layout.cshtml
  58. 1
    1
      SecureSharing/Views/Shared/_ValidationScriptsPartial.cshtml
  59. 1
    1
      SecureSharing/Views/_ViewImports.cshtml
  60. 1
    1
      SecureSharing/Views/_ViewStart.cshtml
  61. 0
    2
      SecureSharing/appsettings.json
  62. 13
    13
      SecureSharing/wwwroot/build/config/postcss.config.js
  63. 18
    18
      SecureSharing/wwwroot/build/config/rollup.config.js
  64. 15
    15
      SecureSharing/wwwroot/build/js/AdminLTE.js
  65. 79
    78
      SecureSharing/wwwroot/build/js/CardRefresh.js
  66. 139
    139
      SecureSharing/wwwroot/build/js/CardWidget.js
  67. 207
    207
      SecureSharing/wwwroot/build/js/ControlSidebar.js
  68. 24
    24
      SecureSharing/wwwroot/build/js/DirectChat.js
  69. 74
    74
      SecureSharing/wwwroot/build/js/Dropdown.js
  70. 68
    68
      SecureSharing/wwwroot/build/js/ExpandableTable.js
  71. 58
    58
      SecureSharing/wwwroot/build/js/Fullscreen.js
  72. 302
    302
      SecureSharing/wwwroot/build/js/IFrame.js
  73. 156
    156
      SecureSharing/wwwroot/build/js/Layout.js
  74. 46
    46
      SecureSharing/wwwroot/build/js/NavbarSearch.js
  75. 123
    123
      SecureSharing/wwwroot/build/js/PushMenu.js
  76. 187
    187
      SecureSharing/wwwroot/build/js/SidebarSearch.js
  77. 118
    118
      SecureSharing/wwwroot/build/js/Toasts.js
  78. 52
    52
      SecureSharing/wwwroot/build/js/TodoList.js
  79. 89
    89
      SecureSharing/wwwroot/build/js/Treeview.js
  80. 42
    42
      SecureSharing/wwwroot/build/npm/DocsPlugins.js
  81. 39
    39
      SecureSharing/wwwroot/build/npm/DocsPublish.js
  82. 442
    442
      SecureSharing/wwwroot/build/npm/Plugins.js
  83. 42
    42
      SecureSharing/wwwroot/build/npm/Publish.js
  84. 39
    39
      SecureSharing/wwwroot/build/npm/vnu-jar.js
  85. 1
    0
      SecureSharing/wwwroot/build/scss/_animation-effects.scss
  86. 552
    552
      SecureSharing/wwwroot/build/scss/_bootstrap-variables.scss
  87. 1
    0
      SecureSharing/wwwroot/build/scss/_buttons.scss
  88. 9
    3
      SecureSharing/wwwroot/build/scss/_cards.scss
  89. 1
    0
      SecureSharing/wwwroot/build/scss/_carousel.scss
  90. 1
    0
      SecureSharing/wwwroot/build/scss/_colors.scss
  91. 5
    3
      SecureSharing/wwwroot/build/scss/_direct-chat.scss
  92. 11
    3
      SecureSharing/wwwroot/build/scss/_dropdown.scss
  93. 8
    0
      SecureSharing/wwwroot/build/scss/_forms.scss
  94. 2
    0
      SecureSharing/wwwroot/build/scss/_layout.scss
  95. 5
    3
      SecureSharing/wwwroot/build/scss/_main-sidebar.scss
  96. 6
    0
      SecureSharing/wwwroot/build/scss/_miscellaneous.scss
  97. 2
    0
      SecureSharing/wwwroot/build/scss/_modals.scss
  98. 5
    2
      SecureSharing/wwwroot/build/scss/_navs.scss
  99. 5
    0
      SecureSharing/wwwroot/build/scss/_pagination.scss
  100. 0
    0
      SecureSharing/wwwroot/build/scss/_products.scss

+ 0
- 986
.vs/MVCTemplate/config/applicationhost.config View File

@@ -1,986 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

IIS configuration sections.

For schema documentation, see
%IIS_BIN%\config\schema\IIS_schema.xml.
Please make a backup of this file before making any changes to it.

NOTE: The following environment variables are available to be used
within this file and are understood by the IIS Express.

%IIS_USER_HOME% - The IIS Express home directory for the user
%IIS_SITES_HOME% - The default home directory for sites
%IIS_BIN% - The location of the IIS Express binaries
%SYSTEMDRIVE% - The drive letter of %IIS_BIN%

-->
<configuration>
<!--

The <configSections> section controls the registration of sections.
Section is the basic unit of deployment, locking, searching and
containment for configuration settings.
Every section belongs to one section group.
A section group is a container of logically-related sections.
Sections cannot be nested.
Section groups may be nested.
<section
name="" [Required, Collection Key] [XML name of the section]
allowDefinition="Everywhere" [MachineOnly|MachineToApplication|AppHostOnly|Everywhere] [Level where it can be set]
overrideModeDefault="Allow" [Allow|Deny] [Default delegation mode]
allowLocation="true" [true|false] [Allowed in location tags]
/>
The recommended way to unlock sections is by using a location tag:
<location path="Default Web Site" overrideMode="Allow">
<system.webServer>
<asp />
</system.webServer>
</location>

-->
<configSections>
<sectionGroup name="system.applicationHost">
<section name="applicationPools" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
<section name="configHistory" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
<section name="customMetadata" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
<section name="listenerAdapters" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
<section name="log" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
<section name="serviceAutoStartProviders" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
<section name="sites" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
<section name="webLimits" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
</sectionGroup>
<sectionGroup name="system.webServer">
<section name="asp" overrideModeDefault="Deny" />
<section name="caching" overrideModeDefault="Allow" />
<section name="cgi" overrideModeDefault="Deny" />
<section name="defaultDocument" overrideModeDefault="Allow" />
<section name="directoryBrowse" overrideModeDefault="Allow" />
<section name="fastCgi" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
<section name="globalModules" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
<section name="handlers" overrideModeDefault="Deny" />
<section name="httpCompression" overrideModeDefault="Allow" allowDefinition="Everywhere" />
<section name="httpErrors" overrideModeDefault="Allow" />
<section name="httpLogging" overrideModeDefault="Deny" />
<section name="httpProtocol" overrideModeDefault="Allow" />
<section name="httpRedirect" overrideModeDefault="Allow" />
<section name="httpTracing" overrideModeDefault="Deny" />
<section name="isapiFilters" allowDefinition="MachineToApplication" overrideModeDefault="Deny" />
<section name="modules" allowDefinition="MachineToApplication" overrideModeDefault="Deny" />
<section name="applicationInitialization" allowDefinition="MachineToApplication" overrideModeDefault="Allow" />
<section name="odbcLogging" overrideModeDefault="Deny" />
<sectionGroup name="security">
<section name="access" overrideModeDefault="Deny" />
<section name="applicationDependencies" overrideModeDefault="Deny" />
<sectionGroup name="authentication">
<section name="anonymousAuthentication" overrideModeDefault="Deny" />
<section name="basicAuthentication" overrideModeDefault="Deny" />
<section name="clientCertificateMappingAuthentication" overrideModeDefault="Deny" />
<section name="digestAuthentication" overrideModeDefault="Deny" />
<section name="iisClientCertificateMappingAuthentication" overrideModeDefault="Deny" />
<section name="windowsAuthentication" overrideModeDefault="Deny" />
</sectionGroup>
<section name="authorization" overrideModeDefault="Allow" />
<section name="ipSecurity" overrideModeDefault="Deny" />
<section name="dynamicIpSecurity" overrideModeDefault="Deny" />
<section name="isapiCgiRestriction" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />
<section name="requestFiltering" overrideModeDefault="Allow" />
</sectionGroup>
<section name="serverRuntime" overrideModeDefault="Deny" />
<section name="serverSideInclude" overrideModeDefault="Deny" />
<section name="staticContent" overrideModeDefault="Allow" />
<sectionGroup name="tracing">
<section name="traceFailedRequests" overrideModeDefault="Allow" />
<section name="traceProviderDefinitions" overrideModeDefault="Deny" />
</sectionGroup>
<section name="urlCompression" overrideModeDefault="Allow" />
<section name="validation" overrideModeDefault="Allow" />
<sectionGroup name="webdav">
<section name="globalSettings" overrideModeDefault="Deny" />
<section name="authoring" overrideModeDefault="Deny" />
<section name="authoringRules" overrideModeDefault="Deny" />
</sectionGroup>
<sectionGroup name="rewrite">
<section name="allowedServerVariables" overrideModeDefault="Deny" />
<section name="rules" overrideModeDefault="Allow" />
<section name="outboundRules" overrideModeDefault="Allow" />
<section name="globalRules" overrideModeDefault="Deny" allowDefinition="AppHostOnly" />
<section name="providers" overrideModeDefault="Allow" />
<section name="rewriteMaps" overrideModeDefault="Allow" />
</sectionGroup>
<section name="webSocket" overrideModeDefault="Deny" />
<section name="aspNetCore" overrideModeDefault="Allow" />
</sectionGroup>
</configSections>
<configProtectedData>
<providers>
<add name="IISWASOnlyRsaProvider" type="" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" keyContainerName="iisWasKey" cspProviderName="" useMachineContainer="true" useOAEP="false" />
<add name="AesProvider" type="Microsoft.ApplicationHost.AesProtectedConfigurationProvider" description="Uses an AES session key to encrypt and decrypt" keyContainerName="iisConfigurationKey" cspProviderName="" useOAEP="false" useMachineContainer="true" sessionKey="AQIAAA5mAAAApAAA/HKxkz6alrlAPez0IUgujj/6k3WxCDriHp6jvpv3yEZmo7h6SMzGLxo4mTrIQVHSkB7tmElHKfUFTzE2BWF7nFWHY6Z6qmGBauFzwJMwESjril7Gjz69RBFH259HQ6aRDq9Xfx7U7H4HtdmnKNqGjgl/hwPQBGeIlWiDh+sYv3vKB0QU971tjX6H2B+9armlnC8UOuA6JYMDMI/VLLL16sng0fWAy5JYe0YVABVjiAWDW264RZW9Tr1Oax4qHZKg+SdjULxeOc2YmpX+d0yeITo1HkPF1hN1gHpIPIUDo05ilHUNfR3OkjVCIQK4cFKCq1s8NH+y+13MxUC4Fn1AlQ==" />
<add name="IISWASOnlyAesProvider" type="Microsoft.ApplicationHost.AesProtectedConfigurationProvider" description="Uses an AES session key to encrypt and decrypt" keyContainerName="iisWasKey" cspProviderName="" useOAEP="false" useMachineContainer="true" sessionKey="AQIAAA5mAAAApAAALmU8lTC+v2qtfQiiiquvvLpUQqKLEXs+jSKoWCM/uPhyB++k4dwug19mGidNK5FYiWK2KYE1yhjVJcbp12E98Q0R2nT7eBiCMY2JairxQ591rqABK7keGaIjwH7PwGzSpILl3RJ4YFvJ/7ZXEJxeDZIjW8ZxWVXx+/VyHs9U3WguLEkgMUX3jrxJi8LouxaIVPJAv/YQ1ZCWs8zImitxX/C/7o7yaIxznfsN5nGQzQfpUDPeby99aw2zPVTtZI2LaWIBON8guABvZ6JtJVDWmfdK6sodbnwdZkr6/Z2rfvamT1dC1SpQrGG7ulR/f9/GXvCaW10ZVKxekBF/CYlNMg==" />
</providers>
</configProtectedData>
<system.applicationHost>
<applicationPools>
<add name="Clr4IntegratedAppPool" managedRuntimeVersion="v4.0" managedPipelineMode="Integrated" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" />
<add name="Clr4ClassicAppPool" managedRuntimeVersion="v4.0" managedPipelineMode="Classic" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" />
<add name="Clr2IntegratedAppPool" managedRuntimeVersion="v2.0" managedPipelineMode="Integrated" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" />
<add name="Clr2ClassicAppPool" managedRuntimeVersion="v2.0" managedPipelineMode="Classic" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" />
<add name="UnmanagedClassicAppPool" managedRuntimeVersion="" managedPipelineMode="Classic" autoStart="true" />
<add name="MVCTemplate AppPool" managedRuntimeVersion="" />
<applicationPoolDefaults managedRuntimeVersion="v4.0">
<processModel loadUserProfile="true" setProfileEnvironment="false" />
</applicationPoolDefaults>
</applicationPools>
<!--

The <listenerAdapters> section defines the protocols with which the
Windows Process Activation Service (WAS) binds.

-->
<listenerAdapters>
<add name="http" />
</listenerAdapters>
<sites>
<site name="WebSite1" id="1" serverAutoStart="true">
<application path="/">
<virtualDirectory path="/" physicalPath="%IIS_SITES_HOME%\WebSite1" />
</application>
<bindings>
<binding protocol="http" bindingInformation=":8080:localhost" />
</bindings>
</site>
<site name="MVCTemplate" id="2">
<application path="/" applicationPool="MVCTemplate AppPool">
<virtualDirectory path="/" physicalPath="C:\Users\julija.stojkovic\source\repos\secure-sharing\MVCTemplate" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:24744:localhost" />
<binding protocol="https" bindingInformation="*:44336:localhost" />
</bindings>
</site>
<siteDefaults>
<!-- To enable logging, please change the below attribute "enabled" to "true" -->
<logFile logFormat="W3C" directory="%AppData%\Microsoft\IISExpressLogs" enabled="false" />
<traceFailedRequestsLogging directory="%AppData%\Microsoft" enabled="false" maxLogFileSizeKB="1024" />
</siteDefaults>
<applicationDefaults applicationPool="Clr4IntegratedAppPool" />
<virtualDirectoryDefaults allowSubDirConfig="true" />
</sites>
<webLimits />
</system.applicationHost>
<system.webServer>
<serverRuntime />
<asp scriptErrorSentToBrowser="true">
<cache diskTemplateCacheDirectory="%TEMP%\iisexpress\ASP Compiled Templates" />
<limits />
</asp>
<caching enabled="true" enableKernelCache="true"></caching>
<cgi />
<defaultDocument enabled="true">
<files>
<add value="Default.htm" />
<add value="Default.asp" />
<add value="index.htm" />
<add value="index.html" />
<add value="iisstart.htm" />
<add value="default.aspx" />
</files>
</defaultDocument>
<directoryBrowse enabled="false" />
<fastCgi />
<!--

The <globalModules> section defines all native-code modules.
To enable a module, specify it in the <modules> section.

-->
<globalModules>
<add name="HttpLoggingModule" image="%IIS_BIN%\loghttp.dll" />
<add name="UriCacheModule" image="%IIS_BIN%\cachuri.dll" />
<add name="TokenCacheModule" image="%IIS_BIN%\cachtokn.dll" />
<add name="DynamicCompressionModule" image="%IIS_BIN%\compdyn.dll" />
<add name="StaticCompressionModule" image="%IIS_BIN%\compstat.dll" />
<add name="DefaultDocumentModule" image="%IIS_BIN%\defdoc.dll" />
<add name="DirectoryListingModule" image="%IIS_BIN%\dirlist.dll" />
<add name="ProtocolSupportModule" image="%IIS_BIN%\protsup.dll" />
<add name="HttpRedirectionModule" image="%IIS_BIN%\redirect.dll" />
<add name="ServerSideIncludeModule" image="%IIS_BIN%\iis_ssi.dll" />
<add name="StaticFileModule" image="%IIS_BIN%\static.dll" />
<add name="AnonymousAuthenticationModule" image="%IIS_BIN%\authanon.dll" />
<add name="CertificateMappingAuthenticationModule" image="%IIS_BIN%\authcert.dll" />
<add name="UrlAuthorizationModule" image="%IIS_BIN%\urlauthz.dll" />
<add name="BasicAuthenticationModule" image="%IIS_BIN%\authbas.dll" />
<add name="WindowsAuthenticationModule" image="%IIS_BIN%\authsspi.dll" />
<add name="IISCertificateMappingAuthenticationModule" image="%IIS_BIN%\authmap.dll" />
<add name="IpRestrictionModule" image="%IIS_BIN%\iprestr.dll" />
<add name="DynamicIpRestrictionModule" image="%IIS_BIN%\diprestr.dll" />
<add name="RequestFilteringModule" image="%IIS_BIN%\modrqflt.dll" />
<add name="CustomLoggingModule" image="%IIS_BIN%\logcust.dll" />
<add name="CustomErrorModule" image="%IIS_BIN%\custerr.dll" />
<add name="FailedRequestsTracingModule" image="%IIS_BIN%\iisfreb.dll" />
<add name="RequestMonitorModule" image="%IIS_BIN%\iisreqs.dll" />
<add name="IsapiModule" image="%IIS_BIN%\isapi.dll" />
<add name="IsapiFilterModule" image="%IIS_BIN%\filter.dll" />
<add name="CgiModule" image="%IIS_BIN%\cgi.dll" />
<add name="FastCgiModule" image="%IIS_BIN%\iisfcgi.dll" />
<!-- <add name="WebDAVModule" image="%IIS_BIN%\webdav.dll" /> -->
<add name="RewriteModule" image="%IIS_BIN%\rewrite.dll" />
<add name="ConfigurationValidationModule" image="%IIS_BIN%\validcfg.dll" />
<add name="WebSocketModule" image="%IIS_BIN%\iiswsock.dll" />
<add name="WebMatrixSupportModule" image="%IIS_BIN%\webmatrixsup.dll" />
<add name="ManagedEngine" image="%windir%\Microsoft.NET\Framework\v2.0.50727\webengine.dll" preCondition="integratedMode,runtimeVersionv2.0,bitness32" />
<add name="ManagedEngine64" image="%windir%\Microsoft.NET\Framework64\v2.0.50727\webengine.dll" preCondition="integratedMode,runtimeVersionv2.0,bitness64" />
<add name="ManagedEngineV4.0_32bit" image="%windir%\Microsoft.NET\Framework\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness32" />
<add name="ManagedEngineV4.0_64bit" image="%windir%\Microsoft.NET\Framework64\v4.0.30319\webengine4.dll" preCondition="integratedMode,runtimeVersionv4.0,bitness64" />
<add name="ApplicationInitializationModule" image="%IIS_BIN%\warmup.dll" />
<add name="AspNetCoreModuleV2" image="%IIS_BIN%\Asp.Net Core Module\V2\aspnetcorev2.dll" />
</globalModules>
<httpCompression directory="%TEMP%">
<scheme name="gzip" dll="%IIS_BIN%\gzip.dll" />
<dynamicTypes>
<add mimeType="text/*" enabled="true" />
<add mimeType="message/*" enabled="true" />
<add mimeType="application/x-javascript" enabled="true" />
<add mimeType="application/javascript" enabled="true" />
<add mimeType="*/*" enabled="false" />
</dynamicTypes>
<staticTypes>
<add mimeType="text/*" enabled="true" />
<add mimeType="message/*" enabled="true" />
<add mimeType="application/javascript" enabled="true" />
<add mimeType="application/atom+xml" enabled="true" />
<add mimeType="application/xaml+xml" enabled="true" />
<add mimeType="image/svg+xml" enabled="true" />
<add mimeType="*/*" enabled="false" />
</staticTypes>
</httpCompression>
<httpErrors lockAttributes="allowAbsolutePathsWhenDelegated,defaultPath">
<error statusCode="401" prefixLanguageFilePath="%IIS_BIN%\custerr" path="401.htm" />
<error statusCode="403" prefixLanguageFilePath="%IIS_BIN%\custerr" path="403.htm" />
<error statusCode="404" prefixLanguageFilePath="%IIS_BIN%\custerr" path="404.htm" />
<error statusCode="405" prefixLanguageFilePath="%IIS_BIN%\custerr" path="405.htm" />
<error statusCode="406" prefixLanguageFilePath="%IIS_BIN%\custerr" path="406.htm" />
<error statusCode="412" prefixLanguageFilePath="%IIS_BIN%\custerr" path="412.htm" />
<error statusCode="500" prefixLanguageFilePath="%IIS_BIN%\custerr" path="500.htm" />
<error statusCode="501" prefixLanguageFilePath="%IIS_BIN%\custerr" path="501.htm" />
<error statusCode="502" prefixLanguageFilePath="%IIS_BIN%\custerr" path="502.htm" />
</httpErrors>
<httpLogging dontLog="false" />
<httpProtocol>
<customHeaders>
<clear />
<add name="X-Powered-By" value="ASP.NET" />
</customHeaders>
<redirectHeaders>
<clear />
</redirectHeaders>
</httpProtocol>
<httpRedirect enabled="false" />
<httpTracing />
<isapiFilters>
<filter name="ASP.Net_2.0.50727-64" path="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_filter.dll" enableCache="true" preCondition="bitness64,runtimeVersionv2.0" />
<filter name="ASP.Net_2.0.50727.0" path="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_filter.dll" enableCache="true" preCondition="bitness32,runtimeVersionv2.0" />
<filter name="ASP.Net_2.0_for_v1.1" path="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_filter.dll" enableCache="true" preCondition="runtimeVersionv1.1" />
<filter name="ASP.Net_4.0_32bit" path="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_filter.dll" enableCache="true" preCondition="bitness32,runtimeVersionv4.0" />
<filter name="ASP.Net_4.0_64bit" path="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_filter.dll" enableCache="true" preCondition="bitness64,runtimeVersionv4.0" />
</isapiFilters>
<odbcLogging />
<security>
<access sslFlags="None" />
<applicationDependencies>
<application name="Active Server Pages" groupId="ASP" />
</applicationDependencies>
<authentication>
<anonymousAuthentication enabled="true" userName="" />
<basicAuthentication enabled="false" />
<clientCertificateMappingAuthentication enabled="false" />
<digestAuthentication enabled="false" />
<iisClientCertificateMappingAuthentication enabled="false"></iisClientCertificateMappingAuthentication>
<windowsAuthentication enabled="false">
<providers>
<add value="Negotiate" />
<add value="NTLM" />
</providers>
</windowsAuthentication>
</authentication>
<authorization>
<add accessType="Allow" users="*" />
</authorization>
<ipSecurity allowUnlisted="true" />
<isapiCgiRestriction notListedIsapisAllowed="true" notListedCgisAllowed="true">
<add path="%windir%\Microsoft.NET\Framework64\v4.0.30319\webengine4.dll" allowed="true" groupId="ASP.NET_v4.0" description="ASP.NET_v4.0" />
<add path="%windir%\Microsoft.NET\Framework\v4.0.30319\webengine4.dll" allowed="true" groupId="ASP.NET_v4.0" description="ASP.NET_v4.0" />
<add path="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" allowed="true" groupId="ASP.NET v2.0.50727" description="ASP.NET v2.0.50727" />
<add path="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" allowed="true" groupId="ASP.NET v2.0.50727" description="ASP.NET v2.0.50727" />
</isapiCgiRestriction>
<requestFiltering>
<fileExtensions allowUnlisted="true" applyToWebDAV="true">
<add fileExtension=".asa" allowed="false" />
<add fileExtension=".asax" allowed="false" />
<add fileExtension=".ascx" allowed="false" />
<add fileExtension=".master" allowed="false" />
<add fileExtension=".skin" allowed="false" />
<add fileExtension=".browser" allowed="false" />
<add fileExtension=".sitemap" allowed="false" />
<add fileExtension=".config" allowed="false" />
<add fileExtension=".cs" allowed="false" />
<add fileExtension=".csproj" allowed="false" />
<add fileExtension=".vb" allowed="false" />
<add fileExtension=".vbproj" allowed="false" />
<add fileExtension=".webinfo" allowed="false" />
<add fileExtension=".licx" allowed="false" />
<add fileExtension=".resx" allowed="false" />
<add fileExtension=".resources" allowed="false" />
<add fileExtension=".mdb" allowed="false" />
<add fileExtension=".vjsproj" allowed="false" />
<add fileExtension=".java" allowed="false" />
<add fileExtension=".jsl" allowed="false" />
<add fileExtension=".ldb" allowed="false" />
<add fileExtension=".dsdgm" allowed="false" />
<add fileExtension=".ssdgm" allowed="false" />
<add fileExtension=".lsad" allowed="false" />
<add fileExtension=".ssmap" allowed="false" />
<add fileExtension=".cd" allowed="false" />
<add fileExtension=".dsprototype" allowed="false" />
<add fileExtension=".lsaprototype" allowed="false" />
<add fileExtension=".sdm" allowed="false" />
<add fileExtension=".sdmDocument" allowed="false" />
<add fileExtension=".mdf" allowed="false" />
<add fileExtension=".ldf" allowed="false" />
<add fileExtension=".ad" allowed="false" />
<add fileExtension=".dd" allowed="false" />
<add fileExtension=".ldd" allowed="false" />
<add fileExtension=".sd" allowed="false" />
<add fileExtension=".adprototype" allowed="false" />
<add fileExtension=".lddprototype" allowed="false" />
<add fileExtension=".exclude" allowed="false" />
<add fileExtension=".refresh" allowed="false" />
<add fileExtension=".compiled" allowed="false" />
<add fileExtension=".msgx" allowed="false" />
<add fileExtension=".vsdisco" allowed="false" />
<add fileExtension=".rules" allowed="false" />
</fileExtensions>
<verbs allowUnlisted="true" applyToWebDAV="true" />
<hiddenSegments applyToWebDAV="true">
<add segment="web.config" />
<add segment="bin" />
<add segment="App_code" />
<add segment="App_GlobalResources" />
<add segment="App_LocalResources" />
<add segment="App_WebReferences" />
<add segment="App_Data" />
<add segment="App_Browsers" />
</hiddenSegments>
</requestFiltering>
</security>
<serverSideInclude ssiExecDisable="false" />
<staticContent lockAttributes="isDocFooterFileName">
<mimeMap fileExtension=".323" mimeType="text/h323" />
<mimeMap fileExtension=".3g2" mimeType="video/3gpp2" />
<mimeMap fileExtension=".3gp2" mimeType="video/3gpp2" />
<mimeMap fileExtension=".3gp" mimeType="video/3gpp" />
<mimeMap fileExtension=".3gpp" mimeType="video/3gpp" />
<mimeMap fileExtension=".aac" mimeType="audio/aac" />
<mimeMap fileExtension=".aaf" mimeType="application/octet-stream" />
<mimeMap fileExtension=".aca" mimeType="application/octet-stream" />
<mimeMap fileExtension=".accdb" mimeType="application/msaccess" />
<mimeMap fileExtension=".accde" mimeType="application/msaccess" />
<mimeMap fileExtension=".accdt" mimeType="application/msaccess" />
<mimeMap fileExtension=".acx" mimeType="application/internet-property-stream" />
<mimeMap fileExtension=".adt" mimeType="audio/vnd.dlna.adts" />
<mimeMap fileExtension=".adts" mimeType="audio/vnd.dlna.adts" />
<mimeMap fileExtension=".afm" mimeType="application/octet-stream" />
<mimeMap fileExtension=".ai" mimeType="application/postscript" />
<mimeMap fileExtension=".aif" mimeType="audio/x-aiff" />
<mimeMap fileExtension=".aifc" mimeType="audio/aiff" />
<mimeMap fileExtension=".aiff" mimeType="audio/aiff" />
<mimeMap fileExtension=".appcache" mimeType="text/cache-manifest" />
<mimeMap fileExtension=".application" mimeType="application/x-ms-application" />
<mimeMap fileExtension=".art" mimeType="image/x-jg" />
<mimeMap fileExtension=".asd" mimeType="application/octet-stream" />
<mimeMap fileExtension=".asf" mimeType="video/x-ms-asf" />
<mimeMap fileExtension=".asi" mimeType="application/octet-stream" />
<mimeMap fileExtension=".asm" mimeType="text/plain" />
<mimeMap fileExtension=".asr" mimeType="video/x-ms-asf" />
<mimeMap fileExtension=".asx" mimeType="video/x-ms-asf" />
<mimeMap fileExtension=".atom" mimeType="application/atom+xml" />
<mimeMap fileExtension=".au" mimeType="audio/basic" />
<mimeMap fileExtension=".avi" mimeType="video/avi" />
<mimeMap fileExtension=".axs" mimeType="application/olescript" />
<mimeMap fileExtension=".bas" mimeType="text/plain" />
<mimeMap fileExtension=".bcpio" mimeType="application/x-bcpio" />
<mimeMap fileExtension=".bin" mimeType="application/octet-stream" />
<mimeMap fileExtension=".bmp" mimeType="image/bmp" />
<mimeMap fileExtension=".c" mimeType="text/plain" />
<mimeMap fileExtension=".cab" mimeType="application/vnd.ms-cab-compressed" />
<mimeMap fileExtension=".calx" mimeType="application/vnd.ms-office.calx" />
<mimeMap fileExtension=".cat" mimeType="application/vnd.ms-pki.seccat" />
<mimeMap fileExtension=".cdf" mimeType="application/x-cdf" />
<mimeMap fileExtension=".chm" mimeType="application/octet-stream" />
<mimeMap fileExtension=".class" mimeType="application/x-java-applet" />
<mimeMap fileExtension=".clp" mimeType="application/x-msclip" />
<mimeMap fileExtension=".cmx" mimeType="image/x-cmx" />
<mimeMap fileExtension=".cnf" mimeType="text/plain" />
<mimeMap fileExtension=".cod" mimeType="image/cis-cod" />
<mimeMap fileExtension=".cpio" mimeType="application/x-cpio" />
<mimeMap fileExtension=".cpp" mimeType="text/plain" />
<mimeMap fileExtension=".crd" mimeType="application/x-mscardfile" />
<mimeMap fileExtension=".crl" mimeType="application/pkix-crl" />
<mimeMap fileExtension=".crt" mimeType="application/x-x509-ca-cert" />
<mimeMap fileExtension=".csh" mimeType="application/x-csh" />
<mimeMap fileExtension=".css" mimeType="text/css" />
<mimeMap fileExtension=".csv" mimeType="application/octet-stream" />
<mimeMap fileExtension=".cur" mimeType="application/octet-stream" />
<mimeMap fileExtension=".dcr" mimeType="application/x-director" />
<mimeMap fileExtension=".deploy" mimeType="application/octet-stream" />
<mimeMap fileExtension=".der" mimeType="application/x-x509-ca-cert" />
<mimeMap fileExtension=".dib" mimeType="image/bmp" />
<mimeMap fileExtension=".dir" mimeType="application/x-director" />
<mimeMap fileExtension=".disco" mimeType="text/xml" />
<mimeMap fileExtension=".dll" mimeType="application/x-msdownload" />
<mimeMap fileExtension=".dll.config" mimeType="text/xml" />
<mimeMap fileExtension=".dlm" mimeType="text/dlm" />
<mimeMap fileExtension=".doc" mimeType="application/msword" />
<mimeMap fileExtension=".docm" mimeType="application/vnd.ms-word.document.macroEnabled.12" />
<mimeMap fileExtension=".docx" mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
<mimeMap fileExtension=".dot" mimeType="application/msword" />
<mimeMap fileExtension=".dotm" mimeType="application/vnd.ms-word.template.macroEnabled.12" />
<mimeMap fileExtension=".dotx" mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.template" />
<mimeMap fileExtension=".dsp" mimeType="application/octet-stream" />
<mimeMap fileExtension=".dtd" mimeType="text/xml" />
<mimeMap fileExtension=".dvi" mimeType="application/x-dvi" />
<mimeMap fileExtension=".dvr-ms" mimeType="video/x-ms-dvr" />
<mimeMap fileExtension=".dwf" mimeType="drawing/x-dwf" />
<mimeMap fileExtension=".dwp" mimeType="application/octet-stream" />
<mimeMap fileExtension=".dxr" mimeType="application/x-director" />
<mimeMap fileExtension=".eml" mimeType="message/rfc822" />
<mimeMap fileExtension=".emz" mimeType="application/octet-stream" />
<mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
<mimeMap fileExtension=".eps" mimeType="application/postscript" />
<mimeMap fileExtension=".esd" mimeType="application/vnd.ms-cab-compressed" />
<mimeMap fileExtension=".etx" mimeType="text/x-setext" />
<mimeMap fileExtension=".evy" mimeType="application/envoy" />
<mimeMap fileExtension=".exe" mimeType="application/octet-stream" />
<mimeMap fileExtension=".exe.config" mimeType="text/xml" />
<mimeMap fileExtension=".fdf" mimeType="application/vnd.fdf" />
<mimeMap fileExtension=".fif" mimeType="application/fractals" />
<mimeMap fileExtension=".fla" mimeType="application/octet-stream" />
<mimeMap fileExtension=".flr" mimeType="x-world/x-vrml" />
<mimeMap fileExtension=".flv" mimeType="video/x-flv" />
<mimeMap fileExtension=".gif" mimeType="image/gif" />
<mimeMap fileExtension=".glb" mimeType="model/gltf-binary" />
<mimeMap fileExtension=".gtar" mimeType="application/x-gtar" />
<mimeMap fileExtension=".gz" mimeType="application/x-gzip" />
<mimeMap fileExtension=".h" mimeType="text/plain" />
<mimeMap fileExtension=".hdf" mimeType="application/x-hdf" />
<mimeMap fileExtension=".hdml" mimeType="text/x-hdml" />
<mimeMap fileExtension=".hhc" mimeType="application/x-oleobject" />
<mimeMap fileExtension=".hhk" mimeType="application/octet-stream" />
<mimeMap fileExtension=".hhp" mimeType="application/octet-stream" />
<mimeMap fileExtension=".hlp" mimeType="application/winhlp" />
<mimeMap fileExtension=".hqx" mimeType="application/mac-binhex40" />
<mimeMap fileExtension=".hta" mimeType="application/hta" />
<mimeMap fileExtension=".htc" mimeType="text/x-component" />
<mimeMap fileExtension=".htm" mimeType="text/html" />
<mimeMap fileExtension=".html" mimeType="text/html" />
<mimeMap fileExtension=".htt" mimeType="text/webviewhtml" />
<mimeMap fileExtension=".hxt" mimeType="text/html" />
<mimeMap fileExtension=".ico" mimeType="image/x-icon" />
<mimeMap fileExtension=".ics" mimeType="text/calendar" />
<mimeMap fileExtension=".ief" mimeType="image/ief" />
<mimeMap fileExtension=".iii" mimeType="application/x-iphone" />
<mimeMap fileExtension=".inf" mimeType="application/octet-stream" />
<mimeMap fileExtension=".ins" mimeType="application/x-internet-signup" />
<mimeMap fileExtension=".isp" mimeType="application/x-internet-signup" />
<mimeMap fileExtension=".IVF" mimeType="video/x-ivf" />
<mimeMap fileExtension=".jar" mimeType="application/java-archive" />
<mimeMap fileExtension=".java" mimeType="application/octet-stream" />
<mimeMap fileExtension=".jck" mimeType="application/liquidmotion" />
<mimeMap fileExtension=".jcz" mimeType="application/liquidmotion" />
<mimeMap fileExtension=".jfif" mimeType="image/pjpeg" />
<mimeMap fileExtension=".jpb" mimeType="application/octet-stream" />
<mimeMap fileExtension=".jpe" mimeType="image/jpeg" />
<mimeMap fileExtension=".jpeg" mimeType="image/jpeg" />
<mimeMap fileExtension=".jpg" mimeType="image/jpeg" />
<mimeMap fileExtension=".js" mimeType="application/javascript" />
<mimeMap fileExtension=".json" mimeType="application/json" />
<mimeMap fileExtension=".jsonld" mimeType="application/ld+json" />
<mimeMap fileExtension=".jsx" mimeType="text/jscript" />
<mimeMap fileExtension=".latex" mimeType="application/x-latex" />
<mimeMap fileExtension=".less" mimeType="text/css" />
<mimeMap fileExtension=".lit" mimeType="application/x-ms-reader" />
<mimeMap fileExtension=".lpk" mimeType="application/octet-stream" />
<mimeMap fileExtension=".lsf" mimeType="video/x-la-asf" />
<mimeMap fileExtension=".lsx" mimeType="video/x-la-asf" />
<mimeMap fileExtension=".lzh" mimeType="application/octet-stream" />
<mimeMap fileExtension=".m13" mimeType="application/x-msmediaview" />
<mimeMap fileExtension=".m14" mimeType="application/x-msmediaview" />
<mimeMap fileExtension=".m1v" mimeType="video/mpeg" />
<mimeMap fileExtension=".m2ts" mimeType="video/vnd.dlna.mpeg-tts" />
<mimeMap fileExtension=".m3u" mimeType="audio/x-mpegurl" />
<mimeMap fileExtension=".m4a" mimeType="audio/mp4" />
<mimeMap fileExtension=".m4v" mimeType="video/mp4" />
<mimeMap fileExtension=".man" mimeType="application/x-troff-man" />
<mimeMap fileExtension=".manifest" mimeType="application/x-ms-manifest" />
<mimeMap fileExtension=".map" mimeType="text/plain" />
<mimeMap fileExtension=".mdb" mimeType="application/x-msaccess" />
<mimeMap fileExtension=".mdp" mimeType="application/octet-stream" />
<mimeMap fileExtension=".me" mimeType="application/x-troff-me" />
<mimeMap fileExtension=".mht" mimeType="message/rfc822" />
<mimeMap fileExtension=".mhtml" mimeType="message/rfc822" />
<mimeMap fileExtension=".mid" mimeType="audio/mid" />
<mimeMap fileExtension=".midi" mimeType="audio/mid" />
<mimeMap fileExtension=".mix" mimeType="application/octet-stream" />
<mimeMap fileExtension=".mmf" mimeType="application/x-smaf" />
<mimeMap fileExtension=".mno" mimeType="text/xml" />
<mimeMap fileExtension=".mny" mimeType="application/x-msmoney" />
<mimeMap fileExtension=".mov" mimeType="video/quicktime" />
<mimeMap fileExtension=".movie" mimeType="video/x-sgi-movie" />
<mimeMap fileExtension=".mp2" mimeType="video/mpeg" />
<mimeMap fileExtension=".mp3" mimeType="audio/mpeg" />
<mimeMap fileExtension=".mp4" mimeType="video/mp4" />
<mimeMap fileExtension=".mp4v" mimeType="video/mp4" />
<mimeMap fileExtension=".mpa" mimeType="video/mpeg" />
<mimeMap fileExtension=".mpe" mimeType="video/mpeg" />
<mimeMap fileExtension=".mpeg" mimeType="video/mpeg" />
<mimeMap fileExtension=".mpg" mimeType="video/mpeg" />
<mimeMap fileExtension=".mpp" mimeType="application/vnd.ms-project" />
<mimeMap fileExtension=".mpv2" mimeType="video/mpeg" />
<mimeMap fileExtension=".ms" mimeType="application/x-troff-ms" />
<mimeMap fileExtension=".msi" mimeType="application/octet-stream" />
<mimeMap fileExtension=".mso" mimeType="application/octet-stream" />
<mimeMap fileExtension=".mvb" mimeType="application/x-msmediaview" />
<mimeMap fileExtension=".mvc" mimeType="application/x-miva-compiled" />
<mimeMap fileExtension=".nc" mimeType="application/x-netcdf" />
<mimeMap fileExtension=".nsc" mimeType="video/x-ms-asf" />
<mimeMap fileExtension=".nws" mimeType="message/rfc822" />
<mimeMap fileExtension=".ocx" mimeType="application/octet-stream" />
<mimeMap fileExtension=".oda" mimeType="application/oda" />
<mimeMap fileExtension=".odc" mimeType="text/x-ms-odc" />
<mimeMap fileExtension=".ods" mimeType="application/oleobject" />
<mimeMap fileExtension=".oga" mimeType="audio/ogg" />
<mimeMap fileExtension=".ogg" mimeType="video/ogg" />
<mimeMap fileExtension=".ogv" mimeType="video/ogg" />
<mimeMap fileExtension=".one" mimeType="application/onenote" />
<mimeMap fileExtension=".onea" mimeType="application/onenote" />
<mimeMap fileExtension=".onetoc" mimeType="application/onenote" />
<mimeMap fileExtension=".onetoc2" mimeType="application/onenote" />
<mimeMap fileExtension=".onetmp" mimeType="application/onenote" />
<mimeMap fileExtension=".onepkg" mimeType="application/onenote" />
<mimeMap fileExtension=".osdx" mimeType="application/opensearchdescription+xml" />
<mimeMap fileExtension=".otf" mimeType="font/otf" />
<mimeMap fileExtension=".p10" mimeType="application/pkcs10" />
<mimeMap fileExtension=".p12" mimeType="application/x-pkcs12" />
<mimeMap fileExtension=".p7b" mimeType="application/x-pkcs7-certificates" />
<mimeMap fileExtension=".p7c" mimeType="application/pkcs7-mime" />
<mimeMap fileExtension=".p7m" mimeType="application/pkcs7-mime" />
<mimeMap fileExtension=".p7r" mimeType="application/x-pkcs7-certreqresp" />
<mimeMap fileExtension=".p7s" mimeType="application/pkcs7-signature" />
<mimeMap fileExtension=".pbm" mimeType="image/x-portable-bitmap" />
<mimeMap fileExtension=".pcx" mimeType="application/octet-stream" />
<mimeMap fileExtension=".pcz" mimeType="application/octet-stream" />
<mimeMap fileExtension=".pdf" mimeType="application/pdf" />
<mimeMap fileExtension=".pfb" mimeType="application/octet-stream" />
<mimeMap fileExtension=".pfm" mimeType="application/octet-stream" />
<mimeMap fileExtension=".pfx" mimeType="application/x-pkcs12" />
<mimeMap fileExtension=".pgm" mimeType="image/x-portable-graymap" />
<mimeMap fileExtension=".pko" mimeType="application/vnd.ms-pki.pko" />
<mimeMap fileExtension=".pma" mimeType="application/x-perfmon" />
<mimeMap fileExtension=".pmc" mimeType="application/x-perfmon" />
<mimeMap fileExtension=".pml" mimeType="application/x-perfmon" />
<mimeMap fileExtension=".pmr" mimeType="application/x-perfmon" />
<mimeMap fileExtension=".pmw" mimeType="application/x-perfmon" />
<mimeMap fileExtension=".png" mimeType="image/png" />
<mimeMap fileExtension=".pnm" mimeType="image/x-portable-anymap" />
<mimeMap fileExtension=".pnz" mimeType="image/png" />
<mimeMap fileExtension=".pot" mimeType="application/vnd.ms-powerpoint" />
<mimeMap fileExtension=".potm" mimeType="application/vnd.ms-powerpoint.template.macroEnabled.12" />
<mimeMap fileExtension=".potx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.template" />
<mimeMap fileExtension=".ppam" mimeType="application/vnd.ms-powerpoint.addin.macroEnabled.12" />
<mimeMap fileExtension=".ppm" mimeType="image/x-portable-pixmap" />
<mimeMap fileExtension=".pps" mimeType="application/vnd.ms-powerpoint" />
<mimeMap fileExtension=".ppsm" mimeType="application/vnd.ms-powerpoint.slideshow.macroEnabled.12" />
<mimeMap fileExtension=".ppsx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.slideshow" />
<mimeMap fileExtension=".ppt" mimeType="application/vnd.ms-powerpoint" />
<mimeMap fileExtension=".pptm" mimeType="application/vnd.ms-powerpoint.presentation.macroEnabled.12" />
<mimeMap fileExtension=".pptx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation" />
<mimeMap fileExtension=".prf" mimeType="application/pics-rules" />
<mimeMap fileExtension=".prm" mimeType="application/octet-stream" />
<mimeMap fileExtension=".prx" mimeType="application/octet-stream" />
<mimeMap fileExtension=".ps" mimeType="application/postscript" />
<mimeMap fileExtension=".psd" mimeType="application/octet-stream" />
<mimeMap fileExtension=".psm" mimeType="application/octet-stream" />
<mimeMap fileExtension=".psp" mimeType="application/octet-stream" />
<mimeMap fileExtension=".pub" mimeType="application/x-mspublisher" />
<mimeMap fileExtension=".qt" mimeType="video/quicktime" />
<mimeMap fileExtension=".qtl" mimeType="application/x-quicktimeplayer" />
<mimeMap fileExtension=".qxd" mimeType="application/octet-stream" />
<mimeMap fileExtension=".ra" mimeType="audio/x-pn-realaudio" />
<mimeMap fileExtension=".ram" mimeType="audio/x-pn-realaudio" />
<mimeMap fileExtension=".rar" mimeType="application/octet-stream" />
<mimeMap fileExtension=".ras" mimeType="image/x-cmu-raster" />
<mimeMap fileExtension=".rf" mimeType="image/vnd.rn-realflash" />
<mimeMap fileExtension=".rgb" mimeType="image/x-rgb" />
<mimeMap fileExtension=".rm" mimeType="application/vnd.rn-realmedia" />
<mimeMap fileExtension=".rmi" mimeType="audio/mid" />
<mimeMap fileExtension=".roff" mimeType="application/x-troff" />
<mimeMap fileExtension=".rpm" mimeType="audio/x-pn-realaudio-plugin" />
<mimeMap fileExtension=".rtf" mimeType="application/rtf" />
<mimeMap fileExtension=".rtx" mimeType="text/richtext" />
<mimeMap fileExtension=".scd" mimeType="application/x-msschedule" />
<mimeMap fileExtension=".sct" mimeType="text/scriptlet" />
<mimeMap fileExtension=".sea" mimeType="application/octet-stream" />
<mimeMap fileExtension=".setpay" mimeType="application/set-payment-initiation" />
<mimeMap fileExtension=".setreg" mimeType="application/set-registration-initiation" />
<mimeMap fileExtension=".sgml" mimeType="text/sgml" />
<mimeMap fileExtension=".sh" mimeType="application/x-sh" />
<mimeMap fileExtension=".shar" mimeType="application/x-shar" />
<mimeMap fileExtension=".sit" mimeType="application/x-stuffit" />
<mimeMap fileExtension=".sldm" mimeType="application/vnd.ms-powerpoint.slide.macroEnabled.12" />
<mimeMap fileExtension=".sldx" mimeType="application/vnd.openxmlformats-officedocument.presentationml.slide" />
<mimeMap fileExtension=".smd" mimeType="audio/x-smd" />
<mimeMap fileExtension=".smi" mimeType="application/octet-stream" />
<mimeMap fileExtension=".smx" mimeType="audio/x-smd" />
<mimeMap fileExtension=".smz" mimeType="audio/x-smd" />
<mimeMap fileExtension=".snd" mimeType="audio/basic" />
<mimeMap fileExtension=".snp" mimeType="application/octet-stream" />
<mimeMap fileExtension=".spc" mimeType="application/x-pkcs7-certificates" />
<mimeMap fileExtension=".spl" mimeType="application/futuresplash" />
<mimeMap fileExtension=".spx" mimeType="audio/ogg" />
<mimeMap fileExtension=".src" mimeType="application/x-wais-source" />
<mimeMap fileExtension=".ssm" mimeType="application/streamingmedia" />
<mimeMap fileExtension=".sst" mimeType="application/vnd.ms-pki.certstore" />
<mimeMap fileExtension=".stl" mimeType="application/vnd.ms-pki.stl" />
<mimeMap fileExtension=".sv4cpio" mimeType="application/x-sv4cpio" />
<mimeMap fileExtension=".sv4crc" mimeType="application/x-sv4crc" />
<mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
<mimeMap fileExtension=".svgz" mimeType="image/svg+xml" />
<mimeMap fileExtension=".swf" mimeType="application/x-shockwave-flash" />
<mimeMap fileExtension=".t" mimeType="application/x-troff" />
<mimeMap fileExtension=".tar" mimeType="application/x-tar" />
<mimeMap fileExtension=".tcl" mimeType="application/x-tcl" />
<mimeMap fileExtension=".tex" mimeType="application/x-tex" />
<mimeMap fileExtension=".texi" mimeType="application/x-texinfo" />
<mimeMap fileExtension=".texinfo" mimeType="application/x-texinfo" />
<mimeMap fileExtension=".tgz" mimeType="application/x-compressed" />
<mimeMap fileExtension=".thmx" mimeType="application/vnd.ms-officetheme" />
<mimeMap fileExtension=".thn" mimeType="application/octet-stream" />
<mimeMap fileExtension=".tif" mimeType="image/tiff" />
<mimeMap fileExtension=".tiff" mimeType="image/tiff" />
<mimeMap fileExtension=".toc" mimeType="application/octet-stream" />
<mimeMap fileExtension=".tr" mimeType="application/x-troff" />
<mimeMap fileExtension=".trm" mimeType="application/x-msterminal" />
<mimeMap fileExtension=".ts" mimeType="video/vnd.dlna.mpeg-tts" />
<mimeMap fileExtension=".tsv" mimeType="text/tab-separated-values" />
<mimeMap fileExtension=".ttf" mimeType="application/octet-stream" />
<mimeMap fileExtension=".tts" mimeType="video/vnd.dlna.mpeg-tts" />
<mimeMap fileExtension=".txt" mimeType="text/plain" />
<mimeMap fileExtension=".u32" mimeType="application/octet-stream" />
<mimeMap fileExtension=".uls" mimeType="text/iuls" />
<mimeMap fileExtension=".ustar" mimeType="application/x-ustar" />
<mimeMap fileExtension=".vbs" mimeType="text/vbscript" />
<mimeMap fileExtension=".vcf" mimeType="text/x-vcard" />
<mimeMap fileExtension=".vcs" mimeType="text/plain" />
<mimeMap fileExtension=".vdx" mimeType="application/vnd.ms-visio.viewer" />
<mimeMap fileExtension=".vml" mimeType="text/xml" />
<mimeMap fileExtension=".vsd" mimeType="application/vnd.visio" />
<mimeMap fileExtension=".vss" mimeType="application/vnd.visio" />
<mimeMap fileExtension=".vst" mimeType="application/vnd.visio" />
<mimeMap fileExtension=".vsto" mimeType="application/x-ms-vsto" />
<mimeMap fileExtension=".vsw" mimeType="application/vnd.visio" />
<mimeMap fileExtension=".vsx" mimeType="application/vnd.visio" />
<mimeMap fileExtension=".vtx" mimeType="application/vnd.visio" />
<mimeMap fileExtension=".wasm" mimeType="application/wasm" />
<mimeMap fileExtension=".wav" mimeType="audio/wav" />
<mimeMap fileExtension=".wax" mimeType="audio/x-ms-wax" />
<mimeMap fileExtension=".wbmp" mimeType="image/vnd.wap.wbmp" />
<mimeMap fileExtension=".wcm" mimeType="application/vnd.ms-works" />
<mimeMap fileExtension=".wdb" mimeType="application/vnd.ms-works" />
<mimeMap fileExtension=".webm" mimeType="video/webm" />
<mimeMap fileExtension=".wks" mimeType="application/vnd.ms-works" />
<mimeMap fileExtension=".wm" mimeType="video/x-ms-wm" />
<mimeMap fileExtension=".wma" mimeType="audio/x-ms-wma" />
<mimeMap fileExtension=".wmd" mimeType="application/x-ms-wmd" />
<mimeMap fileExtension=".wmf" mimeType="application/x-msmetafile" />
<mimeMap fileExtension=".wml" mimeType="text/vnd.wap.wml" />
<mimeMap fileExtension=".wmlc" mimeType="application/vnd.wap.wmlc" />
<mimeMap fileExtension=".wmls" mimeType="text/vnd.wap.wmlscript" />
<mimeMap fileExtension=".wmlsc" mimeType="application/vnd.wap.wmlscriptc" />
<mimeMap fileExtension=".wmp" mimeType="video/x-ms-wmp" />
<mimeMap fileExtension=".wmv" mimeType="video/x-ms-wmv" />
<mimeMap fileExtension=".wmx" mimeType="video/x-ms-wmx" />
<mimeMap fileExtension=".wmz" mimeType="application/x-ms-wmz" />
<mimeMap fileExtension=".woff" mimeType="font/x-woff" />
<mimeMap fileExtension=".woff2" mimeType="application/font-woff2" />
<mimeMap fileExtension=".wps" mimeType="application/vnd.ms-works" />
<mimeMap fileExtension=".wri" mimeType="application/x-mswrite" />
<mimeMap fileExtension=".wrl" mimeType="x-world/x-vrml" />
<mimeMap fileExtension=".wrz" mimeType="x-world/x-vrml" />
<mimeMap fileExtension=".wsdl" mimeType="text/xml" />
<mimeMap fileExtension=".wtv" mimeType="video/x-ms-wtv" />
<mimeMap fileExtension=".wvx" mimeType="video/x-ms-wvx" />
<mimeMap fileExtension=".x" mimeType="application/directx" />
<mimeMap fileExtension=".xaf" mimeType="x-world/x-vrml" />
<mimeMap fileExtension=".xaml" mimeType="application/xaml+xml" />
<mimeMap fileExtension=".xap" mimeType="application/x-silverlight-app" />
<mimeMap fileExtension=".xbap" mimeType="application/x-ms-xbap" />
<mimeMap fileExtension=".xbm" mimeType="image/x-xbitmap" />
<mimeMap fileExtension=".xdr" mimeType="text/plain" />
<mimeMap fileExtension=".xht" mimeType="application/xhtml+xml" />
<mimeMap fileExtension=".xhtml" mimeType="application/xhtml+xml" />
<mimeMap fileExtension=".xla" mimeType="application/vnd.ms-excel" />
<mimeMap fileExtension=".xlam" mimeType="application/vnd.ms-excel.addin.macroEnabled.12" />
<mimeMap fileExtension=".xlc" mimeType="application/vnd.ms-excel" />
<mimeMap fileExtension=".xlm" mimeType="application/vnd.ms-excel" />
<mimeMap fileExtension=".xls" mimeType="application/vnd.ms-excel" />
<mimeMap fileExtension=".xlsb" mimeType="application/vnd.ms-excel.sheet.binary.macroEnabled.12" />
<mimeMap fileExtension=".xlsm" mimeType="application/vnd.ms-excel.sheet.macroEnabled.12" />
<mimeMap fileExtension=".xlsx" mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
<mimeMap fileExtension=".xlt" mimeType="application/vnd.ms-excel" />
<mimeMap fileExtension=".xltm" mimeType="application/vnd.ms-excel.template.macroEnabled.12" />
<mimeMap fileExtension=".xltx" mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.template" />
<mimeMap fileExtension=".xlw" mimeType="application/vnd.ms-excel" />
<mimeMap fileExtension=".xml" mimeType="text/xml" />
<mimeMap fileExtension=".xof" mimeType="x-world/x-vrml" />
<mimeMap fileExtension=".xpm" mimeType="image/x-xpixmap" />
<mimeMap fileExtension=".xps" mimeType="application/vnd.ms-xpsdocument" />
<mimeMap fileExtension=".xsd" mimeType="text/xml" />
<mimeMap fileExtension=".xsf" mimeType="text/xml" />
<mimeMap fileExtension=".xsl" mimeType="text/xml" />
<mimeMap fileExtension=".xslt" mimeType="text/xml" />
<mimeMap fileExtension=".xsn" mimeType="application/octet-stream" />
<mimeMap fileExtension=".xtp" mimeType="application/octet-stream" />
<mimeMap fileExtension=".xwd" mimeType="image/x-xwindowdump" />
<mimeMap fileExtension=".z" mimeType="application/x-compress" />
<mimeMap fileExtension=".zip" mimeType="application/x-zip-compressed" />
</staticContent>
<tracing>
<traceFailedRequests>
<add path="*">
<traceAreas>
<add provider="ASP" verbosity="Verbose" />
<add provider="ASPNET" areas="Infrastructure,Module,Page,AppServices" verbosity="Verbose" />
<add provider="ISAPI Extension" verbosity="Verbose" />
<add provider="WWW Server" areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module,Rewrite,WebSocket" verbosity="Verbose" />
</traceAreas>
<failureDefinitions statusCodes="200-999" />
</add>
</traceFailedRequests>
<traceProviderDefinitions>
<add name="WWW Server" guid="{3a2a4e84-4c21-4981-ae10-3fda0d9b0f83}">
<areas>
<clear />
<add name="Authentication" value="2" />
<add name="Security" value="4" />
<add name="Filter" value="8" />
<add name="StaticFile" value="16" />
<add name="CGI" value="32" />
<add name="Compression" value="64" />
<add name="Cache" value="128" />
<add name="RequestNotifications" value="256" />
<add name="Module" value="512" />
<add name="Rewrite" value="1024" />
<add name="FastCGI" value="4096" />
<add name="WebSocket" value="16384" />
<add name="ANCM" value="65536" />
</areas>
</add>
<add name="ASP" guid="{06b94d9a-b15e-456e-a4ef-37c984a2cb4b}">
<areas>
<clear />
</areas>
</add>
<add name="ISAPI Extension" guid="{a1c2040e-8840-4c31-ba11-9871031a19ea}">
<areas>
<clear />
</areas>
</add>
<add name="ASPNET" guid="{AFF081FE-0247-4275-9C4E-021F3DC1DA35}">
<areas>
<add name="Infrastructure" value="1" />
<add name="Module" value="2" />
<add name="Page" value="4" />
<add name="AppServices" value="8" />
</areas>
</add>
</traceProviderDefinitions>
</tracing>
<urlCompression />
<validation />
<webdav>
<globalSettings>
<propertyStores>
<add name="webdav_simple_prop" image="%IIS_BIN%\webdav_simple_prop.dll" image32="%IIS_BIN%\webdav_simple_prop.dll" />
</propertyStores>
<lockStores>
<add name="webdav_simple_lock" image="%IIS_BIN%\webdav_simple_lock.dll" image32="%IIS_BIN%\webdav_simple_lock.dll" />
</lockStores>
</globalSettings>
<authoring>
<locks enabled="true" lockStore="webdav_simple_lock" />
</authoring>
<authoringRules />
</webdav>
<webSocket />
<applicationInitialization />
</system.webServer>
<location path="" overrideMode="Allow">
<system.webServer>
<modules>
<add name="IsapiFilterModule" lockItem="true" />
<add name="BasicAuthenticationModule" lockItem="true" />
<add name="IsapiModule" lockItem="true" />
<add name="HttpLoggingModule" lockItem="true" />
<add name="DynamicCompressionModule" lockItem="true" />
<add name="StaticCompressionModule" lockItem="true" />
<add name="DefaultDocumentModule" lockItem="true" />
<add name="DirectoryListingModule" lockItem="true" />
<add name="ProtocolSupportModule" lockItem="true" />
<add name="HttpRedirectionModule" lockItem="true" />
<add name="ServerSideIncludeModule" lockItem="true" />
<add name="StaticFileModule" lockItem="true" />
<add name="AnonymousAuthenticationModule" lockItem="true" />
<add name="CertificateMappingAuthenticationModule" lockItem="true" />
<add name="UrlAuthorizationModule" lockItem="true" />
<add name="WindowsAuthenticationModule" lockItem="true" />
<add name="IISCertificateMappingAuthenticationModule" lockItem="true" />
<add name="WebMatrixSupportModule" lockItem="true" />
<add name="IpRestrictionModule" lockItem="true" />
<add name="DynamicIpRestrictionModule" lockItem="true" />
<add name="RequestFilteringModule" lockItem="true" />
<add name="CustomLoggingModule" lockItem="true" />
<add name="CustomErrorModule" lockItem="true" />
<add name="FailedRequestsTracingModule" lockItem="true" />
<add name="CgiModule" lockItem="true" />
<add name="FastCgiModule" lockItem="true" />
<!-- <add name="WebDAVModule" /> -->
<add name="RewriteModule" />
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule" preCondition="managedHandler" />
<add name="Session" type="System.Web.SessionState.SessionStateModule" preCondition="managedHandler" />
<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" preCondition="managedHandler" />
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" preCondition="managedHandler" />
<add name="DefaultAuthentication" type="System.Web.Security.DefaultAuthenticationModule" preCondition="managedHandler" />
<add name="RoleManager" type="System.Web.Security.RoleManagerModule" preCondition="managedHandler" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="managedHandler" />
<add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" preCondition="managedHandler" />
<add name="AnonymousIdentification" type="System.Web.Security.AnonymousIdentificationModule" preCondition="managedHandler" />
<add name="Profile" type="System.Web.Profile.ProfileModule" preCondition="managedHandler" />
<add name="UrlMappingsModule" type="System.Web.UrlMappingsModule" preCondition="managedHandler" />
<add name="ApplicationInitializationModule" lockItem="true" />
<add name="WebSocketModule" lockItem="true" />
<add name="ServiceModel-4.0" type="System.ServiceModel.Activation.ServiceHttpModule,System.ServiceModel.Activation,Version=4.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler,runtimeVersionv4.0" />
<add name="ConfigurationValidationModule" lockItem="true" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="managedHandler,runtimeVersionv4.0" />
<add name="ScriptModule-4.0" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler,runtimeVersionv4.0" />
<add name="AspNetCoreModuleV2" lockItem="true" />
</modules>
<handlers accessPolicy="Read, Script">
<!-- <add name="WebDAV" path="*" verb="PROPFIND,PROPPATCH,MKCOL,PUT,COPY,DELETE,MOVE,LOCK,UNLOCK" modules="WebDAVModule" resourceType="Unspecified" requireAccess="None" /> -->
<add name="AXD-ISAPI-4.0_64bit" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="PageHandlerFactory-ISAPI-4.0_64bit" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="SimpleHandlerFactory-ISAPI-4.0_64bit" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="WebServiceHandlerFactory-ISAPI-4.0_64bit" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="HttpRemotingHandlerFactory-rem-ISAPI-4.0_64bit" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="HttpRemotingHandlerFactory-soap-ISAPI-4.0_64bit" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="svc-ISAPI-4.0_64bit" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
<add name="rules-ISAPI-4.0_64bit" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
<add name="xoml-ISAPI-4.0_64bit" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
<add name="xamlx-ISAPI-4.0_64bit" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
<add name="aspq-ISAPI-4.0_64bit" path="*.aspq" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="cshtm-ISAPI-4.0_64bit" path="*.cshtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="cshtml-ISAPI-4.0_64bit" path="*.cshtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="vbhtm-ISAPI-4.0_64bit" path="*.vbhtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="vbhtml-ISAPI-4.0_64bit" path="*.vbhtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="AXD-ISAPI-4.0_32bit" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="PageHandlerFactory-ISAPI-4.0_32bit" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="SimpleHandlerFactory-ISAPI-4.0_32bit" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="WebServiceHandlerFactory-ISAPI-4.0_32bit" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="HttpRemotingHandlerFactory-rem-ISAPI-4.0_32bit" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="HttpRemotingHandlerFactory-soap-ISAPI-4.0_32bit" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="svc-ISAPI-4.0_32bit" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
<add name="rules-ISAPI-4.0_32bit" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
<add name="xoml-ISAPI-4.0_32bit" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
<add name="xamlx-ISAPI-4.0_32bit" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
<add name="aspq-ISAPI-4.0_32bit" path="*.aspq" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="cshtm-ISAPI-4.0_32bit" path="*.cshtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="cshtml-ISAPI-4.0_32bit" path="*.cshtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="vbhtm-ISAPI-4.0_32bit" path="*.vbhtm" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="vbhtml-ISAPI-4.0_32bit" path="*.vbhtml" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="TraceHandler-Integrated-4.0" path="trace.axd" verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TraceHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="WebAdminHandler-Integrated-4.0" path="WebAdmin.axd" verb="GET,DEBUG" type="System.Web.Handlers.WebAdminHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="AssemblyResourceLoader-Integrated-4.0" path="WebResource.axd" verb="GET,DEBUG" type="System.Web.Handlers.AssemblyResourceLoader" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="PageHandlerFactory-Integrated-4.0" path="*.aspx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.PageHandlerFactory" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="SimpleHandlerFactory-Integrated-4.0" path="*.ashx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.SimpleHandlerFactory" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="WebServiceHandlerFactory-Integrated-4.0" path="*.asmx" verb="GET,HEAD,POST,DEBUG" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="HttpRemotingHandlerFactory-rem-Integrated-4.0" path="*.rem" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="HttpRemotingHandlerFactory-soap-Integrated-4.0" path="*.soap" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="svc-Integrated-4.0" path="*.svc" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="rules-Integrated-4.0" path="*.rules" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="xoml-Integrated-4.0" path="*.xoml" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="xamlx-Integrated-4.0" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" type="System.Xaml.Hosting.XamlHttpHandlerFactory, System.Xaml.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="aspq-Integrated-4.0" path="*.aspq" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="cshtm-Integrated-4.0" path="*.cshtm" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="cshtml-Integrated-4.0" path="*.cshtml" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="vbhtm-Integrated-4.0" path="*.vbhtm" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="vbhtml-Integrated-4.0" path="*.vbhtml" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="ScriptHandlerFactoryAppServices-Integrated-4.0" path="*_AppService.axd" verb="*" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="ScriptResourceIntegrated-4.0" path="*ScriptResource.axd" verb="GET,HEAD" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="ASPClassic" path="*.asp" verb="GET,HEAD,POST" modules="IsapiModule" scriptProcessor="%IIS_BIN%\asp.dll" resourceType="File" />
<add name="SecurityCertificate" path="*.cer" verb="GET,HEAD,POST" modules="IsapiModule" scriptProcessor="%IIS_BIN%\asp.dll" resourceType="File" />
<add name="ISAPI-dll" path="*.dll" verb="*" modules="IsapiModule" resourceType="File" requireAccess="Execute" allowPathInfo="true" />
<add name="TraceHandler-Integrated" path="trace.axd" verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TraceHandler" preCondition="integratedMode,runtimeVersionv2.0" />
<add name="WebAdminHandler-Integrated" path="WebAdmin.axd" verb="GET,DEBUG" type="System.Web.Handlers.WebAdminHandler" preCondition="integratedMode,runtimeVersionv2.0" />
<add name="AssemblyResourceLoader-Integrated" path="WebResource.axd" verb="GET,DEBUG" type="System.Web.Handlers.AssemblyResourceLoader" preCondition="integratedMode,runtimeVersionv2.0" />
<add name="PageHandlerFactory-Integrated" path="*.aspx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.PageHandlerFactory" preCondition="integratedMode,runtimeVersionv2.0" />
<add name="SimpleHandlerFactory-Integrated" path="*.ashx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.SimpleHandlerFactory" preCondition="integratedMode,runtimeVersionv2.0" />
<add name="WebServiceHandlerFactory-Integrated" path="*.asmx" verb="GET,HEAD,POST,DEBUG" type="System.Web.Services.Protocols.WebServiceHandlerFactory,System.Web.Services,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" preCondition="integratedMode,runtimeVersionv2.0" />
<add name="HttpRemotingHandlerFactory-rem-Integrated" path="*.rem" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory,System.Runtime.Remoting,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" />
<add name="HttpRemotingHandlerFactory-soap-Integrated" path="*.soap" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory,System.Runtime.Remoting,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" />
<add name="AXD-ISAPI-2.0" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
<add name="PageHandlerFactory-ISAPI-2.0" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
<add name="SimpleHandlerFactory-ISAPI-2.0" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
<add name="WebServiceHandlerFactory-ISAPI-2.0" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
<add name="HttpRemotingHandlerFactory-rem-ISAPI-2.0" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
<add name="HttpRemotingHandlerFactory-soap-ISAPI-2.0" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
<add name="AXD-ISAPI-2.0-64" path="*.axd" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
<add name="PageHandlerFactory-ISAPI-2.0-64" path="*.aspx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
<add name="SimpleHandlerFactory-ISAPI-2.0-64" path="*.ashx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
<add name="WebServiceHandlerFactory-ISAPI-2.0-64" path="*.asmx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
<add name="HttpRemotingHandlerFactory-rem-ISAPI-2.0-64" path="*.rem" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
<add name="HttpRemotingHandlerFactory-soap-ISAPI-2.0-64" path="*.soap" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" responseBufferLimit="0" />
<add name="CGI-exe" path="*.exe" verb="*" modules="CgiModule" resourceType="File" requireAccess="Execute" allowPathInfo="true" />
<add name="SSINC-stm" path="*.stm" verb="GET,HEAD,POST" modules="ServerSideIncludeModule" resourceType="File" />
<add name="SSINC-shtm" path="*.shtm" verb="GET,HEAD,POST" modules="ServerSideIncludeModule" resourceType="File" />
<add name="SSINC-shtml" path="*.shtml" verb="GET,HEAD,POST" modules="ServerSideIncludeModule" resourceType="File" />
<add name="TRACEVerbHandler" path="*" verb="TRACE" modules="ProtocolSupportModule" requireAccess="None" />
<add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" requireAccess="None" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="0" />
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
</handlers>
</system.webServer>
</location>
<location path="MVCTemplate" inheritInChildApplications="false">
<system.webServer>
<modules>
<remove name="WebMatrixSupportModule" />
</modules>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" stdoutLogEnabled="false" hostingModel="InProcess" startupTimeLimit="3600" requestTimeout="23:00:00" />
<httpCompression>
<dynamicTypes>
<add mimeType="text/event-stream" enabled="false" />
</dynamicTypes>
</httpCompression>
</system.webServer>
</location>
</configuration>

BIN
.vs/MVCTemplate/v16/.suo View File


+ 0
- 6
.vs/VSWorkspaceState.json View File

@@ -1,6 +0,0 @@
{
"ExpandedNodes": [
""
],
"PreviewInSolutionExplorer": false
}

BIN
.vs/secure-sharing/FileContentIndex/0142d46e-c874-48b6-a8bb-ba48dcab8e67.vsidx View File


BIN
.vs/secure-sharing/FileContentIndex/09d2b585-d5cd-4057-9f1d-b020854c4003.vsidx View File


BIN
.vs/secure-sharing/FileContentIndex/3cb2fa75-118b-414e-8063-de2329515561.vsidx View File


BIN
.vs/secure-sharing/FileContentIndex/633da2f3-a40c-42fa-b4ab-f69482a83eac.vsidx View File


BIN
.vs/secure-sharing/FileContentIndex/8c195695-7fcc-4dd9-b9c4-4b36d989bc8e.vsidx View File


BIN
.vs/secure-sharing/FileContentIndex/fc609bc4-e013-40a1-86f2-f485881d162a.vsidx View File


+ 0
- 0
.vs/secure-sharing/FileContentIndex/read.lock View File


BIN
.vs/secure-sharing/v17/.suo View File


BIN
.vs/slnx.sqlite View File


+ 4
- 11
SecureSharing.Business/Dtos/BaseDto.cs View File

@@ -1,13 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SecureSharing.Business.Dtos;

namespace SecureSharing.Business.Dtos
public class BaseDto
{
public class BaseDto
{
public int Id { get; set; }
}
}
public int Id { get; set; }
}

+ 7
- 13
SecureSharing.Business/Dtos/MessageDto.cs View File

@@ -1,17 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SecureSharing.Business.Dtos
{
public class MessageDto:BaseDto
{
public string Text { get; set; }
public bool IsValid { get; set; } = true;
namespace SecureSharing.Business.Dtos;

public DateTime? ExpiryDate { get; set; }
public sealed class MessageDto : BaseDto
{
public string Text { get; set; }
public bool IsValid { get; set; } = true;

}
}
public DateTime? ExpiryDate { get; set; }
}

+ 10
- 21
SecureSharing.Business/Infrastructure/Extensions/StartupExtensions.cs View File

@@ -1,33 +1,22 @@
using AutoMapper;
using Microsoft.Extensions.DependencyInjection;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SecureSharing.Business.Infrastructure.Extensions;

namespace SecureSharing.Business.Infrastructure.Extensions
public sealed class StartupExtensions
{
public class StartupExtensions
public static void ConfigureServices(IServiceCollection services)
{
public static void ConfigureServices(IServiceCollection services)
{
Data.Extensions.StartupExtensions.ConfigureServices(services);
Data.Extensions.StartupExtensions.ConfigureServices(services);


// TODO: add all missing services
// TODO: add all missing services

var mapperConfiguration = new MapperConfiguration(mc =>
{
mc.AddProfile(new MapperProfile());
});
var mapperConfiguration = new MapperConfiguration(mc => { mc.AddProfile(new MapperProfile()); });

IMapper mapper = mapperConfiguration.CreateMapper();
services.AddSingleton(mapper);
var mapper = mapperConfiguration.CreateMapper();
services.AddSingleton(mapper);

//services.AddLocalization(options => options.ResourcesPath = "Infrastructure/Resources");

}
//services.AddLocalization(options => options.ResourcesPath = "Infrastructure/Resources");
}
}
}

+ 7
- 13
SecureSharing.Business/Infrastructure/MapperProfile.cs View File

@@ -1,19 +1,13 @@
using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SecureSharing.Data.Data;
using SecureSharing.Business.Dtos;
using SecureSharing.Data.Data;

namespace SecureSharing.Business.Infrastructure;

namespace SecureSharing.Business.Infrastructure
public sealed class MapperProfile : Profile
{
public class MapperProfile : Profile
public MapperProfile()
{
public MapperProfile()
{
CreateMap<Message, MessageDto>().ReverseMap();
}
CreateMap<Message, MessageDto>().ReverseMap();
}
}
}

+ 8
- 10
SecureSharing.Business/Infrastructure/PeriodOfValidity.cs View File

@@ -1,11 +1,9 @@

namespace SecureSharing.Business.Infrastructure
namespace SecureSharing.Business.Infrastructure;

public enum PeriodOfValidity
{
public enum PeriodOfValidity
{
ONE_TIME,
ONE_HOUR,
ONE_DAY,
ONE_WEEK
}
}
ONE_TIME,
ONE_HOUR,
ONE_DAY,
ONE_WEEK
}

+ 11
- 12
SecureSharing.Business/Infrastructure/Settings/EmailSettings.cs View File

@@ -1,13 +1,12 @@
namespace SecureSharing.Business.Infrastructure.Settings
namespace SecureSharing.Business.Infrastructure.Settings;

public sealed class EmailSettings
{
public class EmailSettings
{
public string SmtpServer { get; set; }
public int SmtpPort { get; set; }
public bool SmtpUseSSL { get; set; }
public string SmtpUsername { get; set; }
public string SmtpPassword { get; set; }
public string SmtpFrom { get; set; }
public string SmtpFromName { get; set; }
}
}
public string SmtpServer { get; set; }
public int SmtpPort { get; set; }
public bool SmtpUseSSL { get; set; }
public string SmtpUsername { get; set; }
public string SmtpPassword { get; set; }
public string SmtpFrom { get; set; }
public string SmtpFromName { get; set; }
}

+ 18
- 18
SecureSharing.Business/Infrastructure/StartupConfiguration.cs View File

@@ -1,29 +1,29 @@
using System;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;

namespace SecureSharing.Business.Infrastructure
namespace SecureSharing.Business.Infrastructure;

public sealed class StartupConfiguration
{
public class StartupConfiguration
public static TConfig ConfigureStartupConfig<TConfig>(IServiceCollection services, IConfiguration configuration)
where TConfig : class, new()
{
public static TConfig ConfigureStartupConfig<TConfig>(IServiceCollection services, IConfiguration configuration) where TConfig : class, new()
{
if (services == null)
throw new ArgumentNullException(nameof(services));
if (services == null)
throw new ArgumentNullException(nameof(services));

if (configuration == null)
throw new ArgumentNullException(nameof(configuration));
if (configuration == null)
throw new ArgumentNullException(nameof(configuration));

//create instance of config
var config = new TConfig();
var classType = typeof(TConfig);
//bind it to the appropriate section of configuration
configuration.Bind(classType.Name, config);
//create instance of config
var config = new TConfig();
var classType = typeof(TConfig);
//bind it to the appropriate section of configuration
configuration.Bind(classType.Name, config);

//and register it as a service
services.AddSingleton(config);
//and register it as a service
services.AddSingleton(config);

return config;
}
return config;
}
}

+ 12
- 16
SecureSharing.Business/Interfaces/IMessageService.cs View File

@@ -1,23 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
using SecureSharing.Business.Dtos;
using SecureSharing.Business.Infrastructure;

namespace SecureSharing.Business.Interfaces
namespace SecureSharing.Business.Interfaces;

public interface IMessageService
{
public interface IMessageService
{
public Task<IEnumerable<MessageDto>> GetAll();
public Task<int> Create(MessageDto messageDto, PeriodOfValidity chosenPeriod);
public Task DeleteExpiredMessages();
public Task InvalidateMessage(int id);
public Task Update(MessageDto messageDto);
public Task<IEnumerable<MessageDto>> GetAll();
public Task<int> Create(MessageDto messageDto, PeriodOfValidity chosenPeriod);
public Task DeleteExpiredMessages();
public Task InvalidateMessage(int id);
public Task Update(MessageDto messageDto);

public Task<MessageDto> GetById(int messageDto);
public Task<MessageDto> GetById(int messageDto);

public Task<bool> Delete(int messageDto);
}
}
public Task<bool> Delete(int messageDto);
}

+ 15
- 15
SecureSharing.Business/SecureSharing.Business.csproj View File

@@ -1,21 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>SecureSharing.Business</RootNamespace>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>SecureSharing.Business</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AutoMapper" Version="11.0.1" />
<PackageReference Include="MailKit" Version="3.4.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="11.0.1"/>
<PackageReference Include="MailKit" Version="3.4.1"/>
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="6.0.9"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9"/>
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0"/>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0"/>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\SecureSharing.Data\SecureSharing.Data.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SecureSharing.Data\SecureSharing.Data.csproj"/>
</ItemGroup>

</Project>

+ 79
- 79
SecureSharing.Business/Services/MessageService.cs View File

@@ -1,106 +1,106 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using AutoMapper;
using Microsoft.EntityFrameworkCore;
using SecureSharing.Business.Dtos;
using SecureSharing.Business.Infrastructure;
using SecureSharing.Business.Interfaces;
using SecureSharing.Data.Data;
using SecureSharing.Data.DbContexts;
using Microsoft.EntityFrameworkCore;
using SecureSharing.Business.Infrastructure;

namespace SecureSharing.Business.Services
namespace SecureSharing.Business.Services;

public sealed class MessageService : IMessageService
{
public class MessageService:IMessageService
private readonly AppDbContext _dbContext;
private readonly IMapper _mapper;

public MessageService(AppDbContext dbContext, IMapper mapper)
{
private readonly AppDbContext _dbContext;
private readonly IMapper _mapper;
public MessageService(AppDbContext dbContext, IMapper mapper)
{
_dbContext = dbContext;
_mapper = mapper;
}
public async Task<int> Create(MessageDto messageDto, PeriodOfValidity chosenPeriod)
{
Message message = _mapper.Map<Message>(messageDto);
switch (chosenPeriod)
{
case (PeriodOfValidity.ONE_TIME):
message.ExpiryDate = null;
break;
case PeriodOfValidity.ONE_DAY:
message.ExpiryDate = DateTime.UtcNow.AddMinutes(1);
break;
case PeriodOfValidity.ONE_HOUR:
message.ExpiryDate = DateTime.UtcNow.AddHours(1);
break;
case PeriodOfValidity.ONE_WEEK:
message.ExpiryDate = DateTime.UtcNow.AddDays(7);
break;
default:
message.ExpiryDate = null;
break;
}
await _dbContext.Messages.AddAsync(message);
await _dbContext.SaveChangesAsync();
return message.Id;
}
_dbContext = dbContext;
_mapper = mapper;
}

public async Task DeleteExpiredMessages()
public async Task<int> Create(MessageDto messageDto, PeriodOfValidity chosenPeriod)
{
var message = _mapper.Map<Message>(messageDto);
switch (chosenPeriod)
{
var result = await _dbContext.Messages.Where(m =>(m.ExpiryDate != null && m.ExpiryDate <= DateTime.UtcNow)||(!m.IsValid) ).ToListAsync();
_dbContext.RemoveRange(result);
await _dbContext.SaveChangesAsync();
case PeriodOfValidity.ONE_TIME:
message.ExpiryDate = null;
break;
case PeriodOfValidity.ONE_DAY:
message.ExpiryDate = DateTime.UtcNow.AddMinutes(1);
break;
case PeriodOfValidity.ONE_HOUR:
message.ExpiryDate = DateTime.UtcNow.AddHours(1);
break;
case PeriodOfValidity.ONE_WEEK:
message.ExpiryDate = DateTime.UtcNow.AddDays(7);
break;
default:
message.ExpiryDate = null;
break;
}

public async Task InvalidateMessage(int id)
{
var message = await _dbContext.Messages.Where(m => m.Id == id).FirstOrDefaultAsync();
message.IsValid = false;
await _dbContext.SaveChangesAsync();
}
await _dbContext.Messages.AddAsync(message);
await _dbContext.SaveChangesAsync();
return message.Id;
}

public async Task DeleteExpiredMessages()
{
var result = await _dbContext.Messages
.Where(m => (m.ExpiryDate != null && m.ExpiryDate <= DateTime.UtcNow) || !m.IsValid).ToListAsync();
_dbContext.RemoveRange(result);
await _dbContext.SaveChangesAsync();
}

public async Task InvalidateMessage(int id)
{
var message = await _dbContext.Messages.Where(m => m.Id == id).FirstOrDefaultAsync();
message.IsValid = false;
await _dbContext.SaveChangesAsync();
}


public async Task<bool> Delete(int messageId)
public async Task<bool> Delete(int messageId)
{
var messageDto = await GetById(messageId);
if (messageDto == null) return false;
_dbContext.Set<Message>().Remove(_mapper.Map<Message>(messageDto));
try
{
MessageDto messageDto = await GetById(messageId);
if (messageDto == null) return false;
_dbContext.Set<Message>().Remove(_mapper.Map<Message>(messageDto));
try
{
await _dbContext.SaveChangesAsync();

}
catch (Microsoft.EntityFrameworkCore.DbUpdateException)
{
return false;
}
return true;
await _dbContext.SaveChangesAsync();
}

public async Task<IEnumerable<MessageDto>> GetAll()
catch (DbUpdateException)
{
var result = await _dbContext.Messages.AsNoTracking().ToListAsync();
var mappedResult = _mapper.Map<IEnumerable<MessageDto>>(result);
return mappedResult;
return false;
}

return true;
}

public async Task<MessageDto> GetById(int messageId)
{
var result = await _dbContext.Messages.AsNoTracking().FirstOrDefaultAsync(x => x.Id == messageId);
var mappedResult = _mapper.Map<MessageDto>(result);
return mappedResult;
}
public async Task<IEnumerable<MessageDto>> GetAll()
{
var result = await _dbContext.Messages.AsNoTracking().ToListAsync();
var mappedResult = _mapper.Map<IEnumerable<MessageDto>>(result);
return mappedResult;
}

public async Task Update(MessageDto messageDto)
{
var a = _dbContext.Messages.Update(_mapper.Map<Message>(messageDto));
await _dbContext.SaveChangesAsync();
}

public async Task<MessageDto> GetById(int messageId)
{
var result = await _dbContext.Messages.AsNoTracking().FirstOrDefaultAsync(x => x.Id == messageId);
var mappedResult = _mapper.Map<MessageDto>(result);
return mappedResult;
}

public async Task Update(MessageDto messageDto)
{
var a = _dbContext.Messages.Update(_mapper.Map<Message>(messageDto));
await _dbContext.SaveChangesAsync();
}
}
}

+ 7
- 12
SecureSharing.Data/Data/Message.cs View File

@@ -1,15 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SecureSharing.Data.Data
namespace SecureSharing.Data.Data;

public sealed class Message : BaseEntity
{
public class Message:BaseEntity
{
public string Text { get; set; }
public bool IsValid { get; set; }
public DateTime? ExpiryDate { get; set; }
}
}
public string Text { get; set; }
public bool IsValid { get; set; }
public DateTime? ExpiryDate { get; set; }
}

+ 7
- 14
SecureSharing.Data/DbContexts/AppDbContext.cs View File

@@ -1,21 +1,14 @@
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;

using SecureSharing.Data.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SecureSharing.Data.DbContexts
namespace SecureSharing.Data.DbContexts;

public sealed class AppDbContext : IdentityDbContext
{
public class AppDbContext : IdentityDbContext
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

public DbSet<Message> Messages { get; set; }


}
}

public DbSet<Message> Messages { get; set; }
}

+ 13
- 20
SecureSharing.Data/Extensions/StartupExtensions.cs View File

@@ -1,26 +1,19 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using SecureSharing.Data.DbContexts;
using Microsoft.AspNetCore.Identity;

namespace SecureSharing.Data.Extensions
namespace SecureSharing.Data.Extensions;

public sealed class StartupExtensions
{
public class StartupExtensions
public static void ConfigureServices(IServiceCollection services)
{
public static void ConfigureServices(IServiceCollection services)
{
var configuration = new ConfigurationBuilder()
.AddJsonFile(path: "appsettings.json")
.Build();
services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(
configuration.GetConnectionString("DefaultConnection")));
}
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(
configuration.GetConnectionString("DefaultConnection")));
}
}
}

+ 17
- 17
SecureSharing.Data/SecureSharing.Data.csproj View File

@@ -1,22 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>SecureSharing.Data</RootNamespace>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>SecureSharing.Data</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AutoMapper" Version="11.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="6.0.9" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="11.0.1"/>
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="6.0.9"/>
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.9"/>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.9"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1"/>
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0"/>
</ItemGroup>

</Project>

+ 9
- 16
SecureSharing/Areas/Identity/IdentityHostingStartup.cs View File

@@ -1,21 +1,14 @@
using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using SecureSharing.Data.DbContexts;
using Microsoft.AspNetCore.Hosting;
using SecureSharing.Areas.Identity;

[assembly: HostingStartup(typeof(SecureSharing.Areas.Identity.IdentityHostingStartup))]
namespace SecureSharing.Areas.Identity
[assembly: HostingStartup(typeof(IdentityHostingStartup))]

namespace SecureSharing.Areas.Identity;

public sealed class IdentityHostingStartup : IHostingStartup
{
public class IdentityHostingStartup : IHostingStartup
public void Configure(IWebHostBuilder builder)
{
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices((context, services) => {
});
}
builder.ConfigureServices((context, services) => { });
}
}

+ 7
- 7
SecureSharing/Areas/Identity/Pages/Account/Login.cshtml View File

@@ -11,22 +11,22 @@
<section>
<form id="account" method="post">
<h4>Use a local account to log in.</h4>
<hr />
<hr/>
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" />
<input asp-for="Input.Email" class="form-control"/>
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.Password"></label>
<input asp-for="Input.Password" class="form-control" />
<input asp-for="Input.Password" class="form-control"/>
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
<div class="form-group">
<div class="checkbox">
<label asp-for="Input.RememberMe">
<input asp-for="Input.RememberMe" />
<input asp-for="Input.RememberMe"/>
@Html.DisplayNameFor(m => m.Input.RememberMe)
</label>
</div>
@@ -51,7 +51,7 @@
<div class="col-md-6 col-md-offset-2">
<section>
<h4>Use another service to log in.</h4>
<hr />
<hr/>
@{
if ((Model.ExternalLogins?.Count ?? 0) == 0)
{
@@ -81,5 +81,5 @@
</div>

@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
<partial name="_ValidationScriptsPartial"/>
}

+ 64
- 79
SecureSharing/Areas/Identity/Pages/Account/Login.cshtml.cs View File

@@ -1,110 +1,95 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;

namespace SecureSharing.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class LoginModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly ILogger<LoginModel> _logger;
namespace SecureSharing.Areas.Identity.Pages.Account;

public LoginModel(SignInManager<IdentityUser> signInManager,
ILogger<LoginModel> logger,
UserManager<IdentityUser> userManager)
{
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
}
[AllowAnonymous]
public sealed class LoginModel : PageModel
{
private readonly ILogger<LoginModel> _logger;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<IdentityUser> _userManager;

[BindProperty]
public InputModel Input { get; set; }
public LoginModel(SignInManager<IdentityUser> signInManager,
ILogger<LoginModel> logger,
UserManager<IdentityUser> userManager)
{
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
}

public IList<AuthenticationScheme> ExternalLogins { get; set; }
[BindProperty] public InputModel Input { get; set; }

public string ReturnUrl { get; set; }
public IList<AuthenticationScheme> ExternalLogins { get; set; }

[TempData]
public string ErrorMessage { get; set; }
public string ReturnUrl { get; set; }

public class InputModel
{
[Required]
[EmailAddress]
public string Email { get; set; }
[TempData] public string ErrorMessage { get; set; }

[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
public async Task OnGetAsync(string returnUrl = null)
{
if (!string.IsNullOrEmpty(ErrorMessage)) ModelState.AddModelError(string.Empty, ErrorMessage);

[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
returnUrl ??= Url.Content("~/");

public async Task OnGetAsync(string returnUrl = null)
{
if (!string.IsNullOrEmpty(ErrorMessage))
{
ModelState.AddModelError(string.Empty, ErrorMessage);
}
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);

returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();

// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
ReturnUrl = returnUrl;
}

ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/");

ReturnUrl = returnUrl;
}
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
if (ModelState.IsValid)
{
returnUrl ??= Url.Content("~/");
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, false);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return LocalRedirect(returnUrl);
}

ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
if (result.RequiresTwoFactor)
return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, Input.RememberMe });
if (result.IsLockedOut)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return LocalRedirect(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning("User account locked out.");
return RedirectToPage("./Lockout");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return Page();
}
_logger.LogWarning("User account locked out.");
return RedirectToPage("./Lockout");
}

// If we got this far, something failed, redisplay form
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return Page();
}

// If we got this far, something failed, redisplay form
return Page();
}

public sealed class InputModel
{
[Required] [EmailAddress] public string Email { get; set; }

[Required]
[DataType(DataType.Password)]
public string Password { get; set; }

[Display(Name = "Remember me?")] public bool RememberMe { get; set; }
}
}
}

+ 7
- 7
SecureSharing/Areas/Identity/Pages/Account/Register.cshtml View File

@@ -10,21 +10,21 @@
<div class="col-md-4">
<form asp-route-returnUrl="@Model.ReturnUrl" method="post">
<h4>Create a new account.</h4>
<hr />
<hr/>
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" />
<input asp-for="Input.Email" class="form-control"/>
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.Password"></label>
<input asp-for="Input.Password" class="form-control" />
<input asp-for="Input.Password" class="form-control"/>
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.ConfirmPassword"></label>
<input asp-for="Input.ConfirmPassword" class="form-control" />
<input asp-for="Input.ConfirmPassword" class="form-control"/>
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary">Register</button>
@@ -33,7 +33,7 @@
<div class="col-md-6 col-md-offset-2">
<section>
<h4>Use another service to register.</h4>
<hr />
<hr/>
@{
if ((Model.ExternalLogins?.Count ?? 0) == 0)
{
@@ -63,5 +63,5 @@
</div>

@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
<partial name="_ValidationScriptsPartial"/>
}

+ 79
- 85
SecureSharing/Areas/Identity/Pages/Account/Register.cshtml.cs View File

@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
@@ -14,101 +13,96 @@ using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging;

namespace SecureSharing.Areas.Identity.Pages.Account
namespace SecureSharing.Areas.Identity.Pages.Account;

[AllowAnonymous]
public sealed class RegisterModel : PageModel
{
[AllowAnonymous]
public class RegisterModel : PageModel
private readonly IEmailSender _emailSender;
private readonly ILogger<RegisterModel> _logger;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<IdentityUser> _userManager;

public RegisterModel(
UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager,
ILogger<RegisterModel> logger,
IEmailSender emailSender)
{
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<IdentityUser> _userManager;
private readonly ILogger<RegisterModel> _logger;
private readonly IEmailSender _emailSender;

public RegisterModel(
UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager,
ILogger<RegisterModel> logger,
IEmailSender emailSender)
{
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
_emailSender = emailSender;
}
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
_emailSender = emailSender;
}

[BindProperty]
public InputModel Input { get; set; }
[BindProperty] public InputModel Input { get; set; }

public string ReturnUrl { get; set; }
public string ReturnUrl { get; set; }

public IList<AuthenticationScheme> ExternalLogins { get; set; }
public IList<AuthenticationScheme> ExternalLogins { get; set; }

public class InputModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }

[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }

[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}

public async Task OnGetAsync(string returnUrl = null)
{
ReturnUrl = returnUrl;
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
}
public async Task OnGetAsync(string returnUrl = null)
{
ReturnUrl = returnUrl;
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
}

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
var result = await _userManager.CreateAsync(user, Input.Password);
if (result.Succeeded)
{
var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
var result = await _userManager.CreateAsync(user, Input.Password);
if (result.Succeeded)
{
_logger.LogInformation("User created a new account with password.");

var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = user.Id, code = code, returnUrl = returnUrl },
protocol: Request.Scheme);

await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");

if (_userManager.Options.SignIn.RequireConfirmedAccount)
{
return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl = returnUrl });
}
else
{
await _signInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
}
foreach (var error in result.Errors)
_logger.LogInformation("User created a new account with password.");

var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
null,
new { area = "Identity", userId = user.Id, code, returnUrl },
Request.Scheme);

await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");

if (_userManager.Options.SignIn.RequireConfirmedAccount)
{
ModelState.AddModelError(string.Empty, error.Description);
return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl });
}

await _signInManager.SignInAsync(user, false);
return LocalRedirect(returnUrl);
}

// If we got this far, something failed, redisplay form
return Page();
foreach (var error in result.Errors) ModelState.AddModelError(string.Empty, error.Description);
}

// If we got this far, something failed, redisplay form
return Page();
}

public sealed class InputModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }

[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.",
MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }

[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
}
}

+ 7
- 7
SecureSharing/Areas/Identity/Pages/Account/ResetPassword.cshtml View File

@@ -6,25 +6,25 @@

<h1>@ViewData["Title"]</h1>
<h4>Reset your password.</h4>
<hr />
<hr/>
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input asp-for="Input.Code" type="hidden" />
<input asp-for="Input.Code" type="hidden"/>
<div class="form-group">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" />
<input asp-for="Input.Email" class="form-control"/>
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.Password"></label>
<input asp-for="Input.Password" class="form-control" />
<input asp-for="Input.Password" class="form-control"/>
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.ConfirmPassword"></label>
<input asp-for="Input.ConfirmPassword" class="form-control" />
<input asp-for="Input.ConfirmPassword" class="form-control"/>
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary">Reset</button>
@@ -33,5 +33,5 @@
</div>

@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
<partial name="_ValidationScriptsPartial"/>
}

+ 47
- 69
SecureSharing/Areas/Identity/Pages/Account/ResetPassword.cshtml.cs View File

@@ -1,91 +1,69 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;

namespace SecureSharing.Areas.Identity.Pages.Account
namespace SecureSharing.Areas.Identity.Pages.Account;

[AllowAnonymous]
public sealed class ResetPasswordModel : PageModel
{
[AllowAnonymous]
public class ResetPasswordModel : PageModel
private readonly UserManager<IdentityUser> _userManager;

public ResetPasswordModel(UserManager<IdentityUser> userManager)
{
private readonly UserManager<IdentityUser> _userManager;
_userManager = userManager;
}

[BindProperty] public InputModel Input { get; set; }

public ResetPasswordModel(UserManager<IdentityUser> userManager)
public IActionResult OnGet(string code = null)
{
if (code == null)
{
_userManager = userManager;
return BadRequest("A code must be supplied for password reset.");
}

[BindProperty]
public InputModel Input { get; set; }

public class InputModel
Input = new InputModel
{
[Required]
[EmailAddress]
public string Email { get; set; }
Code = code
};
return Page();
}

[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
public string Password { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid) return Page();

[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
var user = await _userManager.FindByEmailAsync(Input.Email);
if (user == null)
// Don't reveal that the user does not exist
return RedirectToPage("./ResetPasswordConfirmation");

public string Code { get; set; }
}
var result = await _userManager.ResetPasswordAsync(user, Input.Code, Input.Password);
if (result.Succeeded) return RedirectToPage("./ResetPasswordConfirmation");

public IActionResult OnGet(string code = null)
{
if (code == null)
{
return BadRequest("A code must be supplied for password reset.");
}
else
{
Input = new InputModel
{
Code = code
};
return Page();
}
}
foreach (var error in result.Errors) ModelState.AddModelError(string.Empty, error.Description);
return Page();
}

public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
public sealed class InputModel
{
[Required] [EmailAddress] public string Email { get; set; }

var user = await _userManager.FindByEmailAsync(Input.Email);
if (user == null)
{
// Don't reveal that the user does not exist
return RedirectToPage("./ResetPasswordConfirmation");
}
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.",
MinimumLength = 6)]
[DataType(DataType.Password)]
public string Password { get; set; }

var result = await _userManager.ResetPasswordAsync(user, Input.Code, Input.Password);
if (result.Succeeded)
{
return RedirectToPage("./ResetPasswordConfirmation");
}
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }

foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
return Page();
}
public string Code { get; set; }
}
}
}

+ 1
- 1
SecureSharing/Areas/Identity/Pages/_ValidationScriptsPartial.cshtml View File

@@ -15,4 +15,4 @@
crossorigin="anonymous"
integrity="sha384-ifv0TYDWxBHzvAk2Z0n8R434FL1Rlv/Av18DXE43N/1rvHyOG4izKst0f2iSLdds">
</script>
</environment>
</environment>

+ 1
- 1
SecureSharing/Areas/Identity/Pages/_ViewImports.cshtml View File

@@ -1,4 +1,4 @@
@using Microsoft.AspNetCore.Identity
@using SecureSharing.Areas.Identity
@using SecureSharing.Areas.Identity.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

+ 2
- 3
SecureSharing/Areas/Identity/Pages/_ViewStart.cshtml View File

@@ -1,4 +1,3 @@

@{
@{
Layout = "/Views/Shared/_Layout.cshtml";
}
}

+ 44
- 54
SecureSharing/Controllers/HomeController.cs View File

@@ -1,63 +1,53 @@
using Microsoft.AspNetCore.Authorization;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using SecureSharing.Business.Dtos;
using SecureSharing.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using SecureSharing.Business.Interfaces;
using SecureSharing.Infrastructure;
using SecureSharing.Models;

namespace SecureSharing.Controllers;

namespace SecureSharing.Controllers
[Authorize]
public sealed class HomeController : Controller
{
[Authorize]
public class HomeController : Controller
private readonly ILogger<HomeController> _logger;
private readonly IMessageService _messageService;
private readonly IModelFactory _modelFactory;


public HomeController(ILogger<HomeController> logger, IMessageService messageService, IModelFactory modelFactory)
{
_logger = logger;
_messageService = messageService;
_modelFactory = modelFactory;
}

public IActionResult Index()
{
return View();
}


[HttpPost]
public async Task<IActionResult> CreateMessage(MessageModel model)
{
var message = new MessageDto { Text = model.Text };
var id = await _messageService.Create(message, model.ChosenPeriod);
return RedirectToAction("Link", "Home", new { id, share = true });
}

[HttpGet]
public async Task<IActionResult> Link(int id, bool? share)
{
var model = await _modelFactory.PrepareLinkVM(id, share);
return View(model);
}


public IActionResult Privacy()
{
private readonly ILogger<HomeController> _logger;
private readonly IMessageService _messageService;
private readonly IModelFactory _modelFactory;


public HomeController(ILogger<HomeController> logger, IMessageService messageService, IModelFactory modelFactory)
{
_logger = logger;
_messageService = messageService;
_modelFactory = modelFactory;
}

public IActionResult Index()
{
return View();
}


[HttpPost]
public async Task<IActionResult> CreateMessage(MessageModel model)
{
MessageDto message = new MessageDto { Text = model.Text};
int id = await _messageService.Create(message, model.ChosenPeriod);
return RedirectToAction("Link", "Home", new { id = id, share = true });
}

[HttpGet]
public async Task<IActionResult> Link(int id, bool? share)
{
var model = await _modelFactory.PrepareLinkVM(id, share);
return View(model);
}



public IActionResult Privacy()
{
return View();
}
return View();
}
}
}

+ 7
- 9
SecureSharing/Infrastructure/IModelFactory.cs View File

@@ -1,12 +1,10 @@
using SecureSharing.Business.Dtos;
using System.Threading.Tasks;
using SecureSharing.Models;
using System.Threading.Tasks;

namespace SecureSharing.Infrastructure
namespace SecureSharing.Infrastructure;

public interface IModelFactory
{
public interface IModelFactory
{
//public MessageModel PrepareMessageVM(MessageDto message);
public Task<LinkModel> PrepareLinkVM(int id, bool? share);
}
}
//public MessageModel PrepareMessageVM(MessageDto message);
public Task<LinkModel> PrepareLinkVM(int id, bool? share);
}

+ 53
- 55
SecureSharing/Infrastructure/Middleware/ExceptionHandlingMiddleware.cs View File

@@ -1,66 +1,64 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using Serilog;

namespace SecureSharing.Infrastructure.Middleware
{
public class ExceptionHandlingMiddleware
{
private RequestDelegate nextRequestDelegate;
private IWebHostEnvironment environment;
namespace SecureSharing.Infrastructure.Middleware;

public ExceptionHandlingMiddleware(
RequestDelegate nextRequestDelegate,
IWebHostEnvironment environment
)
{
this.nextRequestDelegate = nextRequestDelegate ?? throw new ArgumentNullException(nameof(nextRequestDelegate));
this.environment = environment ?? throw new ArgumentNullException(nameof(environment));
}
public sealed class ExceptionHandlingMiddleware
{
private IWebHostEnvironment environment;
private readonly RequestDelegate nextRequestDelegate;

public async Task Invoke(HttpContext context)
{
try
{
context.TraceIdentifier = Guid.NewGuid().ToString();
await this.nextRequestDelegate(context);
}
catch (Exception ex)
{
await this.HandleGlobalExceptionAsync(context, ex);
}
}
public ExceptionHandlingMiddleware(
RequestDelegate nextRequestDelegate,
IWebHostEnvironment environment
)
{
this.nextRequestDelegate = nextRequestDelegate ?? throw new ArgumentNullException(nameof(nextRequestDelegate));
this.environment = environment ?? throw new ArgumentNullException(nameof(environment));
}

private async Task HandleGlobalExceptionAsync(HttpContext context, Exception ex)
{
public async Task Invoke(HttpContext context)
{
try
{
context.TraceIdentifier = Guid.NewGuid().ToString();
await nextRequestDelegate(context);
}
catch (Exception ex)
{
await HandleGlobalExceptionAsync(context, ex);
}
}

try
{
await this.WriteResponseAsync(context, HttpStatusCode.InternalServerError, JsonConvert.SerializeObject(ex.Message));
}
catch (Exception e)
{
await this.WriteResponseAsync(context, HttpStatusCode.InternalServerError, JsonConvert.SerializeObject(e.Message));
}
private async Task HandleGlobalExceptionAsync(HttpContext context, Exception ex)
{
try
{
await WriteResponseAsync(context, HttpStatusCode.InternalServerError,
JsonConvert.SerializeObject(ex.Message));
}
catch (Exception e)
{
await WriteResponseAsync(context, HttpStatusCode.InternalServerError,
JsonConvert.SerializeObject(e.Message));
}

var logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.File(@"AppData\Errors\log-.log", rollingInterval: RollingInterval.Day)
.CreateLogger();
logger.Error(ex, "Unhandled Exception"/* - Detected UserId: {UserId}" /*, context.User.GetUserId()*/);
}
var logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.File(@"AppData\Errors\log-.log", rollingInterval: RollingInterval.Day)
.CreateLogger();
logger.Error(ex, "Unhandled Exception" /* - Detected UserId: {UserId}" /*, context.User.GetUserId()*/);
}

private async Task WriteResponseAsync(HttpContext context, HttpStatusCode code, string jsonResponse)
{
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)code;
await context.Response.WriteAsync(jsonResponse);
}
}
}
private async Task WriteResponseAsync(HttpContext context, HttpStatusCode code, string jsonResponse)
{
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)code;
await context.Response.WriteAsync(jsonResponse);
}
}

+ 40
- 46
SecureSharing/Infrastructure/ModelFactory.cs View File

@@ -1,65 +1,59 @@
using SecureSharing.Business.Dtos;
using System;
using System.Threading.Tasks;
using SecureSharing.Business.Interfaces;
using SecureSharing.Models;
using System;
using System.Threading.Tasks;

namespace SecureSharing.Infrastructure
namespace SecureSharing.Infrastructure;

public sealed class ModelFactory : IModelFactory
{
public class ModelFactory : IModelFactory
private readonly IMessageService _messageService;

public ModelFactory(IMessageService messageService)
{
_messageService = messageService;
}

private readonly IMessageService _messageService;
public async Task<LinkModel> PrepareLinkVM(int id, bool? share)
{
//share is true when the link is created

public ModelFactory(IMessageService messageService)
LinkModel model = null;
try
{
_messageService = messageService;
}
var message = await _messageService.GetById(id);

public async Task<LinkModel> PrepareLinkVM(int id, bool? share)
{
//share is true when the link is created
model = new LinkModel { message = new MessageModel { Id = id, Text = message.Text }, Share = share };
model.IsValid = message.IsValid;

LinkModel model = null;
try
if (model.IsValid)
{
MessageDto message = await _messageService.GetById(id);

model = new LinkModel { message = new MessageModel { Id = id, Text = message.Text }, Share = share };
model.IsValid = message.IsValid;

if (model.IsValid)
if (message.ExpiryDate != null)
{
if (message.ExpiryDate != null)
model.TimeLeft = message.ExpiryDate - DateTime.UtcNow;
if (message.ExpiryDate <= DateTime.UtcNow)
{
model.TimeLeft = message.ExpiryDate - DateTime.UtcNow;
if (message.ExpiryDate <= DateTime.UtcNow)
{
await _messageService.InvalidateMessage(message.Id);
model.IsValid = false;
}
}
else
{
//ONE_TIME sharing: make the message invalid now so that it can't be accessed next time
if (share == null || share.Value == false)
{
await _messageService.InvalidateMessage(message.Id);
}
await _messageService.InvalidateMessage(message.Id);
model.IsValid = false;
}
}
else
{
//ONE_TIME sharing: make the message invalid now so that it can't be accessed next time
if (share == null || share.Value == false) await _messageService.InvalidateMessage(message.Id);
}
}
catch (Exception e)
{
model = new LinkModel { IsValid = false };
}

return model;
}
catch (Exception e)
{
model = new LinkModel { IsValid = false };
}

//public MessageModel PrepareMessageVM(MessageDto message)
//{
// throw new System.NotImplementedException();
//}
return model;
}
}

//public MessageModel PrepareMessageVM(MessageDto message)
//{
// throw new System.NotImplementedException();
//}
}

+ 5
- 8
SecureSharing/Models/ErrorViewModel.cs View File

@@ -1,11 +1,8 @@
using System;
namespace SecureSharing.Models;

namespace SecureSharing.Models
public sealed class ErrorViewModel
{
public class ErrorViewModel
{
public string RequestId { get; set; }
public string RequestId { get; set; }

public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}

+ 9
- 10
SecureSharing/Models/LinkModel.cs View File

@@ -1,14 +1,13 @@
using System;

namespace SecureSharing.Models
namespace SecureSharing.Models;

public sealed class LinkModel
{
public class LinkModel
{
public string Link { get; set; }
public MessageModel message { get; set; }
public bool? Share { get; set; }
public TimeSpan? TimeLeft { get; set; }
public string Link { get; set; }
public MessageModel message { get; set; }
public bool? Share { get; set; }
public TimeSpan? TimeLeft { get; set; }

public bool IsValid { get; set; }
}
}
public bool IsValid { get; set; }
}

+ 8
- 15
SecureSharing/Models/MessageModel.cs View File

@@ -1,19 +1,12 @@
using SecureSharing.Business.Infrastructure;
using System;
using System.Collections.Generic;

namespace SecureSharing.Models
{

public class MessageModel
{

public int Id { get; set; }
public string Text { get; set; }
public PeriodOfValidity ChosenPeriod { get; set; }

// public Dictionary<int, string> AvailablePeriods { get; set; }
namespace SecureSharing.Models;

public sealed class MessageModel
{
public int Id { get; set; }
public string Text { get; set; }
public PeriodOfValidity ChosenPeriod { get; set; }

}
}
// public Dictionary<int, string> AvailablePeriods { get; set; }
}

+ 11
- 19
SecureSharing/Program.cs View File

@@ -1,26 +1,18 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace SecureSharing
namespace SecureSharing;

public sealed class Program
{
public class Program
public static void Main(string[] args)
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
}
}
}

+ 10
- 10
SecureSharing/Properties/PublishProfiles/FolderProfile.pubxml View File

@@ -3,14 +3,14 @@
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<DeleteExistingFiles>False</DeleteExistingFiles>
<ExcludeApp_Data>False</ExcludeApp_Data>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<PublishProvider>FileSystem</PublishProvider>
<PublishUrl>D:\Publish\ScreeningTestApp</PublishUrl>
<WebPublishMethod>FileSystem</WebPublishMethod>
</PropertyGroup>
<PropertyGroup>
<DeleteExistingFiles>False</DeleteExistingFiles>
<ExcludeApp_Data>False</ExcludeApp_Data>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<PublishProvider>FileSystem</PublishProvider>
<PublishUrl>D:\Publish\ScreeningTestApp</PublishUrl>
<WebPublishMethod>FileSystem</WebPublishMethod>
</PropertyGroup>
</Project>

+ 18
- 18
SecureSharing/Properties/PublishProfiles/IISProfile.pubxml View File

@@ -4,22 +4,22 @@ This file is used by the publish/package process of your Web project. You can cu
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<ExcludeApp_Data>False</ExcludeApp_Data>
<ProjectGuid>495fb586-0b0f-4368-87a3-c13444149d2a</ProjectGuid>
<SelfContained>false</SelfContained>
<MSDeployServiceURL>dg00</MSDeployServiceURL>
<DeployIisAppPath>ScreeningTestApp</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>True</EnableMSDeployBackup>
<UserName>nenad.stojanovic@dilig.net</UserName>
<_SavePWD>True</_SavePWD>
</PropertyGroup>
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish/>
<ExcludeApp_Data>False</ExcludeApp_Data>
<ProjectGuid>495fb586-0b0f-4368-87a3-c13444149d2a</ProjectGuid>
<SelfContained>false</SelfContained>
<MSDeployServiceURL>dg00</MSDeployServiceURL>
<DeployIisAppPath>ScreeningTestApp</DeployIisAppPath>
<RemoteSitePhysicalPath/>
<SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>True</EnableMSDeployBackup>
<UserName>nenad.stojanovic@dilig.net</UserName>
<_SavePWD>True</_SavePWD>
</PropertyGroup>
</Project>

+ 38
- 42
SecureSharing/Quartz/JobFactory.cs View File

@@ -1,57 +1,53 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Concurrent;
using Microsoft.Extensions.DependencyInjection;
using Quartz;
using Quartz.Spi;
using System;
using System.Collections.Concurrent;

namespace SecureSharing.Quartz
namespace SecureSharing.Quartz;

public class JobFactory : IJobFactory
{
public class JobFactory : IJobFactory
protected readonly ConcurrentDictionary<IJob, IServiceScope> _scopes = new();
protected readonly IServiceProvider _serviceProvider;

public JobFactory(IServiceProvider serviceProvider)
{
protected readonly IServiceProvider _serviceProvider;
_serviceProvider = serviceProvider;
}

protected readonly ConcurrentDictionary<IJob, IServiceScope> _scopes = new ConcurrentDictionary<IJob, IServiceScope>();
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
var scope = _serviceProvider.CreateScope();
IJob job;

public JobFactory(IServiceProvider serviceProvider)
try
{
_serviceProvider = serviceProvider;
job = scope.ServiceProvider.GetRequiredService(bundle.JobDetail.JobType) as IJob;
}

public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
catch
{
var scope = _serviceProvider.CreateScope();
IJob job;

try
{
job = scope.ServiceProvider.GetRequiredService(bundle.JobDetail.JobType) as IJob;
}
catch
{
// Failed to create the job -> ensure scope gets disposed
scope.Dispose();
throw;
}

// Add scope to dictionary so we can dispose it once the job finishes
if (!_scopes.TryAdd(job, scope))
{
// Failed to track DI scope -> ensure scope gets disposed
scope.Dispose();
throw new Exception("Failed to track DI scope");
}

return job;
// Failed to create the job -> ensure scope gets disposed
scope.Dispose();
throw;
}

public void ReturnJob(IJob job)
// Add scope to dictionary so we can dispose it once the job finishes
if (!_scopes.TryAdd(job, scope))
{
if (_scopes.TryRemove(job, out var scope))
{
// The Dispose() method ends the scope lifetime.
// Once Dispose is called, any scoped services that have been resolved from ServiceProvider will be disposed.
scope.Dispose();
}
// Failed to track DI scope -> ensure scope gets disposed
scope.Dispose();
throw new Exception("Failed to track DI scope");
}

return job;
}

public void ReturnJob(IJob job)
{
if (_scopes.TryRemove(job, out var scope))
// The Dispose() method ends the scope lifetime.
// Once Dispose is called, any scoped services that have been resolved from ServiceProvider will be disposed.
scope.Dispose();
}
}
}

+ 15
- 15
SecureSharing/Quartz/JobMetadata.cs View File

@@ -1,20 +1,20 @@
using System;

namespace SecureSharing.Quartz
namespace SecureSharing.Quartz;

public sealed class JobMetadata
{
public class JobMetadata
{
public Guid JobId { get; set; }
public Type JobType { get; }
public string JobName { get; }
public string CronExpression { get; }
public JobMetadata(Type jobType,
public JobMetadata(Type jobType,
string cronExpression)
{
//JobId = Id;
JobType = jobType;
//JobName = jobName;
CronExpression = cronExpression;
}
{
//JobId = Id;
JobType = jobType;
//JobName = jobName;
CronExpression = cronExpression;
}
}

public Guid JobId { get; set; }
public Type JobType { get; }
public string JobName { get; }
public string CronExpression { get; }
}

+ 45
- 40
SecureSharing/Quartz/JobsService.cs View File

@@ -1,54 +1,59 @@
using Microsoft.Extensions.Hosting;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Quartz;
using Quartz.Spi;
using System.Threading;
using System.Threading.Tasks;

namespace SecureSharing.Quartz
namespace SecureSharing.Quartz;

public sealed class JobsService : IHostedService
{
public class JobsService: IHostedService
{
private readonly ISchedulerFactory schedulerFactory;
private readonly IJobFactory jobFactory;
private readonly JobMetadata jobMetadata;
public JobsService(ISchedulerFactory
private readonly IJobFactory jobFactory;
private readonly JobMetadata jobMetadata;
private readonly ISchedulerFactory schedulerFactory;

public JobsService(ISchedulerFactory
schedulerFactory,
JobMetadata jobMetadata,
IJobFactory jobFactory)
{
this.schedulerFactory = schedulerFactory;
this.jobMetadata = jobMetadata;
this.jobFactory = jobFactory;
}
public IScheduler Scheduler { get; set; }
public async Task StartAsync(CancellationToken cancellationToken)
{
Scheduler = await schedulerFactory.GetScheduler();
Scheduler.JobFactory = jobFactory;
var job = CreateJob(jobMetadata);
var trigger = CreateTrigger(jobMetadata);
await Scheduler.ScheduleJob(job, trigger, cancellationToken);
await Scheduler.Start(cancellationToken);
}
public async Task StopAsync(CancellationToken cancellationToken)
{
await Scheduler?.Shutdown(cancellationToken);
}
private ITrigger CreateTrigger(JobMetadata jobMetadata)
{
return TriggerBuilder.Create()
JobMetadata jobMetadata,
IJobFactory jobFactory)
{
this.schedulerFactory = schedulerFactory;
this.jobMetadata = jobMetadata;
this.jobFactory = jobFactory;
}

public IScheduler Scheduler { get; set; }

public async Task StartAsync(CancellationToken cancellationToken)
{
Scheduler = await schedulerFactory.GetScheduler();
Scheduler.JobFactory = jobFactory;
var job = CreateJob(jobMetadata);
var trigger = CreateTrigger(jobMetadata);
await Scheduler.ScheduleJob(job, trigger, cancellationToken);
await Scheduler.Start(cancellationToken);
}

public async Task StopAsync(CancellationToken cancellationToken)
{
await Scheduler?.Shutdown(cancellationToken);
}

private ITrigger CreateTrigger(JobMetadata jobMetadata)
{
return TriggerBuilder.Create()
.WithIdentity(jobMetadata.JobId.ToString())
.WithCronSchedule(jobMetadata.CronExpression)
.WithDescription($"{jobMetadata.JobName}")
.Build();
}
private IJobDetail CreateJob(JobMetadata jobMetadata)
{
return JobBuilder
}

private IJobDetail CreateJob(JobMetadata jobMetadata)
{
return JobBuilder
.Create(jobMetadata.JobType)
.WithIdentity(jobMetadata.JobId.ToString())
.WithDescription($"{jobMetadata.JobName}")
.Build();
}
}
}
}

+ 19
- 19
SecureSharing/Quartz/MessageDeletionJob.cs View File

@@ -1,28 +1,28 @@
using SecureSharing.Business.Interfaces;
using Quartz;
using System;
using System;
using System.Threading.Tasks;
using Quartz;
using SecureSharing.Business.Interfaces;

namespace SecureSharing.Quartz
namespace SecureSharing.Quartz;

public sealed class MessageDeletionJob : IJob
{
public class MessageDeletionJob:IJob
private readonly IMessageService _messageService;

public MessageDeletionJob(IMessageService messageService)
{
_messageService = messageService;
}

public async Task Execute(IJobExecutionContext context)
{
private readonly IMessageService _messageService;
public MessageDeletionJob(IMessageService messageService)
try
{
_messageService = messageService;
await _messageService.DeleteExpiredMessages();
}
public async Task Execute(IJobExecutionContext context)
catch (Exception ex)
{
try
{
await _messageService.DeleteExpiredMessages();
}
catch (Exception ex)
{
/*Log*/
}
return;
/*Log*/
}
}
}
}

+ 30
- 30
SecureSharing/SecureSharing.csproj View File

@@ -1,37 +1,37 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<CopyRefAssembliesToPublishDirectory>false</CopyRefAssembliesToPublishDirectory>
<RootNamespace>SecureSharing</RootNamespace>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<CopyRefAssembliesToPublishDirectory>false</CopyRefAssembliesToPublishDirectory>
<RootNamespace>SecureSharing</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AutoMapper" Version="11.0.1" />
<PackageReference Include="Microsoft.AspNet.Identity.Core" Version="2.2.3" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="6.0.9" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.9" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.9" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.9" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Quartz" Version="3.5.0" />
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="Serilog.AspNetCore" Version="6.0.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="11.0.1"/>
<PackageReference Include="Microsoft.AspNet.Identity.Core" Version="2.2.3"/>
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="6.0.9"/>
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.9"/>
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.9"/>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.9"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.9"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.9"/>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1"/>
<PackageReference Include="Quartz" Version="3.5.0"/>
<PackageReference Include="Serilog" Version="2.12.0"/>
<PackageReference Include="Serilog.AspNetCore" Version="6.0.1"/>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\SecureSharing.Business\SecureSharing.Business.csproj" />
<ProjectReference Include="..\SecureSharing.Data\SecureSharing.Data.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SecureSharing.Business\SecureSharing.Business.csproj"/>
<ProjectReference Include="..\SecureSharing.Data\SecureSharing.Data.csproj"/>
</ItemGroup>

<ItemGroup>
<Folder Include="AppData\Errors\" />
</ItemGroup>
<ItemGroup>
<Folder Include="AppData\Errors\"/>
</ItemGroup>

</Project>

+ 62
- 69
SecureSharing/Startup.cs View File

@@ -1,10 +1,12 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Quartz;
using Quartz.Impl;
using Quartz.Spi;
using SecureSharing.Business.Infrastructure;
using SecureSharing.Business.Infrastructure.Extensions;
using SecureSharing.Business.Infrastructure.Settings;
@@ -14,41 +16,34 @@ using SecureSharing.Data.DbContexts;
using SecureSharing.Infrastructure;
using SecureSharing.Infrastructure.Middleware;
using SecureSharing.Quartz;
using Quartz;
using Quartz.Impl;
using Quartz.Spi;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace SecureSharing
namespace SecureSharing;

public sealed class Startup
{
public class Startup
public Startup(IConfiguration configuration)
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
Configuration = configuration;
}

public IConfiguration Configuration { get; }
public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
StartupConfiguration.ConfigureStartupConfig<EmailSettings>(services, Configuration);
services.AddControllersWithViews();
services.AddRazorPages();
StartupExtensions.ConfigureServices(services);
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = false)
.AddDefaultUI()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<AppDbContext>();
services.AddScoped<IMessageService, MessageService>();
services.AddScoped<IModelFactory, ModelFactory>();
services.AddAuthentication()
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
StartupConfiguration.ConfigureStartupConfig<EmailSettings>(services, Configuration);
services.AddControllersWithViews();
services.AddRazorPages();
StartupExtensions.ConfigureServices(services);
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = false)
.AddDefaultUI()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<AppDbContext>();
services.AddScoped<IMessageService, MessageService>();
services.AddScoped<IModelFactory, ModelFactory>();
services.AddAuthentication()
.AddGoogle(options =>
{
options.ClientId = Configuration.GetSection("EmailSettings").GetSection("ClientId").Value;
@@ -56,51 +51,49 @@ namespace SecureSharing
});


// Add Quartz services
services.AddSingleton<IJobFactory, JobFactory>();
services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();

// Add our jobs
services.AddScoped<MessageDeletionJob>();
services.AddSingleton(new JobMetadata(
jobType: typeof(MessageDeletionJob),
cronExpression: "0 0 12 * * ?"));
// Add Quartz services
services.AddSingleton<IJobFactory, JobFactory>();
services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();

// Add our jobs
services.AddScoped<MessageDeletionJob>();
services.AddSingleton(new JobMetadata(
typeof(MessageDeletionJob),
"0 0 12 * * ?"));


services.AddHostedService<JobsService>();
services.AddHostedService<JobsService>();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
else
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}

app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseMiddleware(typeof(ExceptionHandlingMiddleware));
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
app.UseMiddleware(typeof(ExceptionHandlingMiddleware));

app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
"default",
"{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
}
}

+ 9
- 10
SecureSharing/Views/Home/Index.cshtml View File

@@ -6,26 +6,25 @@

<div class="text-center">
<form method="post" asp-controller="Home" asp-action="CreateMessage">
<input asp-for="Text" />
<input asp-for="Text"/>
<br>

<input type="radio" asp-for="ChosenPeriod" value="@PeriodOfValidity.ONE_TIME" /> ONE TIME

<input type="radio" asp-for="ChosenPeriod" value="@PeriodOfValidity.ONE_TIME"/> ONE TIME
<br>

<input type="radio" asp-for="ChosenPeriod" value="@PeriodOfValidity.ONE_HOUR" /> ONE HOUR
<input type="radio" asp-for="ChosenPeriod" value="@PeriodOfValidity.ONE_HOUR"/> ONE HOUR
<br>

<input type="radio" asp-for="ChosenPeriod" value="@PeriodOfValidity.ONE_DAY" /> ONE DAY
<input type="radio" asp-for="ChosenPeriod" value="@PeriodOfValidity.ONE_DAY"/> ONE DAY
<br>

<input type="radio" asp-for="ChosenPeriod" value="@PeriodOfValidity.ONE_WEEK" /> SEVEN DAYS
<input type="radio" asp-for="ChosenPeriod" value="@PeriodOfValidity.ONE_WEEK"/> SEVEN DAYS
<br>

<button class = " btn btn-light" type="submit">Send</button>
<button class=" btn btn-light" type="submit">Send</button>
</form>
<br>
<br>


</div>
</div>

+ 13
- 15
SecureSharing/Views/Home/Link.cshtml View File

@@ -1,27 +1,27 @@

@{
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@model LinkModel

<div class="text-center">

@if(!Model.IsValid)
@if (!Model.IsValid)
{
<p>This link has expired</p>
}
else
{
@if(Model.Share == true)
@if (Model.Share == true)
{
@Url.Action("Link", "Home", new { id = Model.message.Id }, "https")
}
else
{
@Url.Action(action: "Link", controller: "Home", values: new { id = @Model.message.Id }, protocol: "https")
}else{

<div>
@if(Model.TimeLeft != null)
@if (Model.TimeLeft != null)
{
var time = Model.TimeLeft.Value;
if(time.Days > 0)
if (time.Days > 0)
{
<p>This message will expire in: @time.ToString("%d") days @time.ToString("%h") hours @time.ToString("%m") minutes</p>
}
@@ -35,15 +35,13 @@
<p>This message will expire when you leave this page</p>
}
</div>

}


<div>
Message: @Model.message.Text
</div>
<div>
Message: @Model.message.Text
</div>
}
<a class="btn btn-light" asp-controller="Home" asp-action="Index">Back</a>

</div>
</div>

+ 1
- 1
SecureSharing/Views/Home/Privacy.cshtml View File

@@ -3,4 +3,4 @@
}
<h1>@ViewData["Title"]</h1>

<p>Use this page to detail your site's privacy policy.</p>
<p>Use this page to detail your site's privacy policy.</p>

+ 1
- 1
SecureSharing/Views/Shared/Error.cshtml View File

@@ -22,4 +22,4 @@
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>
</p>

+ 60
- 61
SecureSharing/Views/Shared/_Layout.cshtml View File

@@ -5,8 +5,8 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>@ViewData["Title"] - SecureSharing</title>
<!-- Google Font: Source Sans Pro -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
@@ -30,82 +30,81 @@
<link rel="stylesheet" href="~/plugins/summernote/summernote-bs4.min.css">


<link href="~/lib/jquery-confirm/jquery-confirm.min.css" rel="stylesheet" />

<link href="~/lib/jquery-confirm/jquery-confirm.min.css" rel="stylesheet"/>


<link rel="stylesheet" href="~/css/site.css">
</head>
<body class="hold-transition layout-fixed">
<noscript><p>Your browser does not support JavaScript. You need it enabled to do testing.</p></noscript>
<noscript>
<p>Your browser does not support JavaScript. You need it enabled to do testing.</p>
</noscript>

<div class="wrapper">
<div class="wrapper">

<div class="content-wrapper default-layout">
<section class="content">
<main role="main" class="pb-3">
<div class="content-fluid">
<div>&nbsp;</div>
<div class="card">
<div class="card-body">
@RenderBody()
</div>
<div class="content-wrapper default-layout">
<section class="content">
<main role="main" class="pb-3">
<div class="content-fluid">
<div>&nbsp;</div>
<div class="card">
<div class="card-body">
@RenderBody()
</div>
</div>
</main>
</section>
</div>
<footer class="main-footer ml-0">
<strong>Copyright &copy; 2021 <a href="https://dilig.net/">Diligent Software</a>.</strong>
All rights reserved.
<div class="float-right d-none d-sm-inline-block">
<b>Version</b> 1.0.0-alpha
</div>
</footer>
</div>
</main>
</section>
</div>
<!-- jQuery -->
<script src="~/plugins/jquery/jquery.min.js"></script>
<!-- jQuery UI 1.11.4 -->
<script src="~/plugins/jquery-ui/jquery-ui.min.js"></script>
<!-- Resolve conflict in jQuery UI tooltip with Bootstrap tooltip -->
<script>
<footer class="main-footer ml-0">
<strong>Copyright &copy; 2021 <a href="https://dilig.net/">Diligent Software</a>.</strong>
All rights reserved.
<div class="float-right d-none d-sm-inline-block">
<b>Version</b> 1.0.0-alpha
</div>
</footer>
</div>
<!-- jQuery -->
<script src="~/plugins/jquery/jquery.min.js"></script>
<!-- jQuery UI 1.11.4 -->
<script src="~/plugins/jquery-ui/jquery-ui.min.js"></script>
<!-- Resolve conflict in jQuery UI tooltip with Bootstrap tooltip -->
<script>
$.widget.bridge('uibutton', $.ui.button)
</script>
<!-- Bootstrap 4 -->
<script src="~/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- ChartJS -->
<script src="~/plugins/chart.js/Chart.min.js"></script>
<!-- Sparkline -->
<script src="~/plugins/sparklines/sparkline.js"></script>
<!-- JQVMap -->
<script src="~/plugins/jqvmap/jquery.vmap.min.js"></script>
<script src="~/plugins/jqvmap/maps/jquery.vmap.usa.js"></script>
<!-- jQuery Knob Chart -->
<script src="~/plugins/jquery-knob/jquery.knob.min.js"></script>
<!-- daterangepicker -->
<script src="~/plugins/moment/moment.min.js"></script>
<script src="~/plugins/daterangepicker/daterangepicker.js"></script>
<!-- Tempusdominus Bootstrap 4 -->
<script src="~/plugins/tempusdominus-bootstrap-4/js/tempusdominus-bootstrap-4.min.js"></script>
<!-- Summernote -->
<script src="~/plugins/summernote/summernote-bs4.min.js"></script>
<!-- overlayScrollbars -->
<script src="~/plugins/overlayScrollbars/js/jquery.overlayScrollbars.min.js"></script>
<!-- AdminLTE App -->
<script src="~/dist/js/adminlte.js"></script>
<!-- Bootstrap 4 -->
<script src="~/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- ChartJS -->
<script src="~/plugins/chart.js/Chart.min.js"></script>
<!-- Sparkline -->
<script src="~/plugins/sparklines/sparkline.js"></script>
<!-- JQVMap -->
<script src="~/plugins/jqvmap/jquery.vmap.min.js"></script>
<script src="~/plugins/jqvmap/maps/jquery.vmap.usa.js"></script>
<!-- jQuery Knob Chart -->
<script src="~/plugins/jquery-knob/jquery.knob.min.js"></script>
<!-- daterangepicker -->
<script src="~/plugins/moment/moment.min.js"></script>
<script src="~/plugins/daterangepicker/daterangepicker.js"></script>
<!-- Tempusdominus Bootstrap 4 -->
<script src="~/plugins/tempusdominus-bootstrap-4/js/tempusdominus-bootstrap-4.min.js"></script>
<!-- Summernote -->
<script src="~/plugins/summernote/summernote-bs4.min.js"></script>
<!-- overlayScrollbars -->
<script src="~/plugins/overlayScrollbars/js/jquery.overlayScrollbars.min.js"></script>
<!-- AdminLTE App -->
<script src="~/dist/js/adminlte.js"></script>


<!-- JQery Confirm -->

<!-- JQery Confirm -->
<script src="~/lib/alertifyjs/alertify.min.js"></script>
<script src="~/lib/blockUI/jquery.blockUI.js"></script>

<script src="~/lib/alertifyjs/alertify.min.js"></script>
<script src="~/lib/blockUI/jquery.blockUI.js"></script>

<script src="~/js/site.js" asp-append-version="true"></script>

<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
@await RenderSectionAsync("Scripts", false)

</body>
</html>
</html>

+ 1
- 1
SecureSharing/Views/Shared/_ValidationScriptsPartial.cshtml View File

@@ -1,2 +1,2 @@
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

+ 1
- 1
SecureSharing/Views/_ViewImports.cshtml View File

@@ -1,3 +1,3 @@
@using SecureSharing
@using SecureSharing.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

+ 1
- 1
SecureSharing/Views/_ViewStart.cshtml View File

@@ -1,3 +1,3 @@
@{
Layout = "_Layout";
}
}

+ 0
- 2
SecureSharing/appsettings.json View File

@@ -1,9 +1,7 @@
{
"AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "data source=(localdb)\\MSSQLLocalDB; initial catalog=Test;Integrated Security=True"

},
"Logging": {
"LogLevel": {

+ 13
- 13
SecureSharing/wwwroot/build/config/postcss.config.js View File

@@ -1,17 +1,17 @@
'use strict'

module.exports = {
map: {
inline: false,
annotation: true,
sourcesContent: true
},
plugins: [
require('postcss-scrollbar')({
edgeAutohide: true
}),
require('autoprefixer')({
cascade: false
})
]
map: {
inline: false,
annotation: true,
sourcesContent: true
},
plugins: [
require('postcss-scrollbar')({
edgeAutohide: true
}),
require('autoprefixer')({
cascade: false
})
]
}

+ 18
- 18
SecureSharing/wwwroot/build/config/rollup.config.js View File

@@ -1,6 +1,6 @@
'use strict'

const { babel } = require('@rollup/plugin-babel')
const {babel} = require('@rollup/plugin-babel')

const pkg = require('../../package')
const year = new Date().getFullYear()
@@ -11,22 +11,22 @@ const banner = `/*!
*/`

module.exports = {
input: 'build/js/AdminLTE.js',
output: {
banner,
file: 'dist/js/adminlte.js',
format: 'umd',
globals: {
jquery: 'jQuery'
input: 'build/js/AdminLTE.js',
output: {
banner,
file: 'dist/js/adminlte.js',
format: 'umd',
globals: {
jquery: 'jQuery'
},
name: 'adminlte'
},
name: 'adminlte'
},
external: ['jquery'],
plugins: [
babel({
exclude: 'node_modules/**',
// Include the helpers in the bundle, at most one copy of each
babelHelpers: 'bundled'
})
]
external: ['jquery'],
plugins: [
babel({
exclude: 'node_modules/**',
// Include the helpers in the bundle, at most one copy of each
babelHelpers: 'bundled'
})
]
}

+ 15
- 15
SecureSharing/wwwroot/build/js/AdminLTE.js View File

@@ -15,19 +15,19 @@ import TodoList from './TodoList'
import Treeview from './Treeview'

export {
CardRefresh,
CardWidget,
ControlSidebar,
DirectChat,
Dropdown,
ExpandableTable,
Fullscreen,
IFrame,
Layout,
PushMenu,
SidebarSearch,
NavbarSearch,
Toasts,
TodoList,
Treeview
CardRefresh,
CardWidget,
ControlSidebar,
DirectChat,
Dropdown,
ExpandableTable,
Fullscreen,
IFrame,
Layout,
PushMenu,
SidebarSearch,
NavbarSearch,
Toasts,
TodoList,
Treeview
}

+ 79
- 78
SecureSharing/wwwroot/build/js/CardRefresh.js View File

@@ -27,96 +27,97 @@ const SELECTOR_CARD = `.${CLASS_NAME_CARD}`
const SELECTOR_DATA_REFRESH = '[data-card-widget="card-refresh"]'

const Default = {
source: '',
sourceSelector: '',
params: {},
trigger: SELECTOR_DATA_REFRESH,
content: '.card-body',
loadInContent: true,
loadOnInit: true,
responseType: '',
overlayTemplate: '<div class="overlay"><i class="fas fa-2x fa-sync-alt fa-spin"></i></div>',
onLoadStart() {},
onLoadDone(response) {
return response
}
source: '',
sourceSelector: '',
params: {},
trigger: SELECTOR_DATA_REFRESH,
content: '.card-body',
loadInContent: true,
loadOnInit: true,
responseType: '',
overlayTemplate: '<div class="overlay"><i class="fas fa-2x fa-sync-alt fa-spin"></i></div>',
onLoadStart() {
},
onLoadDone(response) {
return response
}
}

class CardRefresh {
constructor(element, settings) {
this._element = element
this._parent = element.parents(SELECTOR_CARD).first()
this._settings = $.extend({}, Default, settings)
this._overlay = $(this._settings.overlayTemplate)
if (element.hasClass(CLASS_NAME_CARD)) {
this._parent = element
}
constructor(element, settings) {
this._element = element
this._parent = element.parents(SELECTOR_CARD).first()
this._settings = $.extend({}, Default, settings)
this._overlay = $(this._settings.overlayTemplate)
if (element.hasClass(CLASS_NAME_CARD)) {
this._parent = element
}

if (this._settings.source === '') {
throw new Error('Source url was not defined. Please specify a url in your CardRefresh source option.')
if (this._settings.source === '') {
throw new Error('Source url was not defined. Please specify a url in your CardRefresh source option.')
}
}
}

load() {
this._addOverlay()
this._settings.onLoadStart.call($(this))
static _jQueryInterface(config) {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())

$.get(this._settings.source, this._settings.params, response => {
if (this._settings.loadInContent) {
if (this._settings.sourceSelector !== '') {
response = $(response).find(this._settings.sourceSelector).html()
if (!data) {
data = new CardRefresh($(this), _options)
$(this).data(DATA_KEY, typeof config === 'string' ? data : config)
}

this._parent.find(this._settings.content).html(response)
}
this._settings.onLoadDone.call($(this), response)
this._removeOverlay()
}, this._settings.responseType !== '' && this._settings.responseType)
if (typeof config === 'string' && /load/.test(config)) {
data[config]()
} else {
data._init($(this))
}
}

$(this._element).trigger($.Event(EVENT_LOADED))
}
load() {
this._addOverlay()
this._settings.onLoadStart.call($(this))

_addOverlay() {
this._parent.append(this._overlay)
$(this._element).trigger($.Event(EVENT_OVERLAY_ADDED))
}
$.get(this._settings.source, this._settings.params, response => {
if (this._settings.loadInContent) {
if (this._settings.sourceSelector !== '') {
response = $(response).find(this._settings.sourceSelector).html()
}

_removeOverlay() {
this._parent.find(this._overlay).remove()
$(this._element).trigger($.Event(EVENT_OVERLAY_REMOVED))
}
this._parent.find(this._settings.content).html(response)
}

// Private
this._settings.onLoadDone.call($(this), response)
this._removeOverlay()
}, this._settings.responseType !== '' && this._settings.responseType)

_init() {
$(this).find(this._settings.trigger).on('click', () => {
this.load()
})

if (this._settings.loadOnInit) {
this.load()
$(this._element).trigger($.Event(EVENT_LOADED))
}
}

// Static
_addOverlay() {
this._parent.append(this._overlay)
$(this._element).trigger($.Event(EVENT_OVERLAY_ADDED))
}

static _jQueryInterface(config) {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())
// Private

if (!data) {
data = new CardRefresh($(this), _options)
$(this).data(DATA_KEY, typeof config === 'string' ? data : config)
_removeOverlay() {
this._parent.find(this._overlay).remove()
$(this._element).trigger($.Event(EVENT_OVERLAY_REMOVED))
}

if (typeof config === 'string' && /load/.test(config)) {
data[config]()
} else {
data._init($(this))
// Static

_init() {
$(this).find(this._settings.trigger).on('click', () => {
this.load()
})

if (this._settings.loadOnInit) {
this.load()
}
}
}
}

/**
@@ -125,17 +126,17 @@ class CardRefresh {
*/

$(document).on('click', SELECTOR_DATA_REFRESH, function (event) {
if (event) {
event.preventDefault()
}
if (event) {
event.preventDefault()
}

CardRefresh._jQueryInterface.call($(this), 'load')
CardRefresh._jQueryInterface.call($(this), 'load')
})

$(() => {
$(SELECTOR_DATA_REFRESH).each(function () {
CardRefresh._jQueryInterface.call($(this))
})
$(SELECTOR_DATA_REFRESH).each(function () {
CardRefresh._jQueryInterface.call($(this))
})
})

/**
@@ -146,8 +147,8 @@ $(() => {
$.fn[NAME] = CardRefresh._jQueryInterface
$.fn[NAME].Constructor = CardRefresh
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return CardRefresh._jQueryInterface
$.fn[NAME] = JQUERY_NO_CONFLICT
return CardRefresh._jQueryInterface
}

export default CardRefresh

+ 139
- 139
SecureSharing/wwwroot/build/js/CardWidget.js View File

@@ -39,159 +39,159 @@ const SELECTOR_CARD_BODY = '.card-body'
const SELECTOR_CARD_FOOTER = '.card-footer'

const Default = {
animationSpeed: 'normal',
collapseTrigger: SELECTOR_DATA_COLLAPSE,
removeTrigger: SELECTOR_DATA_REMOVE,
maximizeTrigger: SELECTOR_DATA_MAXIMIZE,
collapseIcon: 'fa-minus',
expandIcon: 'fa-plus',
maximizeIcon: 'fa-expand',
minimizeIcon: 'fa-compress'
animationSpeed: 'normal',
collapseTrigger: SELECTOR_DATA_COLLAPSE,
removeTrigger: SELECTOR_DATA_REMOVE,
maximizeTrigger: SELECTOR_DATA_MAXIMIZE,
collapseIcon: 'fa-minus',
expandIcon: 'fa-plus',
maximizeIcon: 'fa-expand',
minimizeIcon: 'fa-compress'
}

class CardWidget {
constructor(element, settings) {
this._element = element
this._parent = element.parents(SELECTOR_CARD).first()
constructor(element, settings) {
this._element = element
this._parent = element.parents(SELECTOR_CARD).first()

if (element.hasClass(CLASS_NAME_CARD)) {
this._parent = element
if (element.hasClass(CLASS_NAME_CARD)) {
this._parent = element
}

this._settings = $.extend({}, Default, settings)
}

this._settings = $.extend({}, Default, settings)
}
static _jQueryInterface(config) {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())

collapse() {
this._parent.addClass(CLASS_NAME_COLLAPSING).children(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`)
.slideUp(this._settings.animationSpeed, () => {
this._parent.addClass(CLASS_NAME_COLLAPSED).removeClass(CLASS_NAME_COLLAPSING)
})
if (!data) {
data = new CardWidget($(this), _options)
$(this).data(DATA_KEY, typeof config === 'string' ? data : config)
}

this._parent.find(`> ${SELECTOR_CARD_HEADER} ${this._settings.collapseTrigger} .${this._settings.collapseIcon}`)
.addClass(this._settings.expandIcon)
.removeClass(this._settings.collapseIcon)
if (typeof config === 'string' && /collapse|expand|remove|toggle|maximize|minimize|toggleMaximize/.test(config)) {
data[config]()
} else if (typeof config === 'object') {
data._init($(this))
}
}

this._element.trigger($.Event(EVENT_COLLAPSED), this._parent)
}
collapse() {
this._parent.addClass(CLASS_NAME_COLLAPSING).children(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`)
.slideUp(this._settings.animationSpeed, () => {
this._parent.addClass(CLASS_NAME_COLLAPSED).removeClass(CLASS_NAME_COLLAPSING)
})

expand() {
this._parent.addClass(CLASS_NAME_EXPANDING).children(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`)
.slideDown(this._settings.animationSpeed, () => {
this._parent.removeClass(CLASS_NAME_COLLAPSED).removeClass(CLASS_NAME_EXPANDING)
})
this._parent.find(`> ${SELECTOR_CARD_HEADER} ${this._settings.collapseTrigger} .${this._settings.collapseIcon}`)
.addClass(this._settings.expandIcon)
.removeClass(this._settings.collapseIcon)

this._parent.find(`> ${SELECTOR_CARD_HEADER} ${this._settings.collapseTrigger} .${this._settings.expandIcon}`)
.addClass(this._settings.collapseIcon)
.removeClass(this._settings.expandIcon)
this._element.trigger($.Event(EVENT_COLLAPSED), this._parent)
}

this._element.trigger($.Event(EVENT_EXPANDED), this._parent)
}
expand() {
this._parent.addClass(CLASS_NAME_EXPANDING).children(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`)
.slideDown(this._settings.animationSpeed, () => {
this._parent.removeClass(CLASS_NAME_COLLAPSED).removeClass(CLASS_NAME_EXPANDING)
})

remove() {
this._parent.slideUp()
this._element.trigger($.Event(EVENT_REMOVED), this._parent)
}
this._parent.find(`> ${SELECTOR_CARD_HEADER} ${this._settings.collapseTrigger} .${this._settings.expandIcon}`)
.addClass(this._settings.collapseIcon)
.removeClass(this._settings.expandIcon)

toggle() {
if (this._parent.hasClass(CLASS_NAME_COLLAPSED)) {
this.expand()
return
this._element.trigger($.Event(EVENT_EXPANDED), this._parent)
}

this.collapse()
}

maximize() {
this._parent.find(`${this._settings.maximizeTrigger} .${this._settings.maximizeIcon}`)
.addClass(this._settings.minimizeIcon)
.removeClass(this._settings.maximizeIcon)
this._parent.css({
height: this._parent.height(),
width: this._parent.width(),
transition: 'all .15s'
}).delay(150).queue(function () {
const $element = $(this)

$element.addClass(CLASS_NAME_MAXIMIZED)
$('html').addClass(CLASS_NAME_MAXIMIZED)
if ($element.hasClass(CLASS_NAME_COLLAPSED)) {
$element.addClass(CLASS_NAME_WAS_COLLAPSED)
}

$element.dequeue()
})

this._element.trigger($.Event(EVENT_MAXIMIZED), this._parent)
}

minimize() {
this._parent.find(`${this._settings.maximizeTrigger} .${this._settings.minimizeIcon}`)
.addClass(this._settings.maximizeIcon)
.removeClass(this._settings.minimizeIcon)
this._parent.css('cssText', `height: ${this._parent[0].style.height} !important; width: ${this._parent[0].style.width} !important; transition: all .15s;`
).delay(10).queue(function () {
const $element = $(this)

$element.removeClass(CLASS_NAME_MAXIMIZED)
$('html').removeClass(CLASS_NAME_MAXIMIZED)
$element.css({
height: 'inherit',
width: 'inherit'
})
if ($element.hasClass(CLASS_NAME_WAS_COLLAPSED)) {
$element.removeClass(CLASS_NAME_WAS_COLLAPSED)
}

$element.dequeue()
})

this._element.trigger($.Event(EVENT_MINIMIZED), this._parent)
}

toggleMaximize() {
if (this._parent.hasClass(CLASS_NAME_MAXIMIZED)) {
this.minimize()
return
remove() {
this._parent.slideUp()
this._element.trigger($.Event(EVENT_REMOVED), this._parent)
}

this.maximize()
}
toggle() {
if (this._parent.hasClass(CLASS_NAME_COLLAPSED)) {
this.expand()
return
}

// Private
this.collapse()
}

_init(card) {
this._parent = card
maximize() {
this._parent.find(`${this._settings.maximizeTrigger} .${this._settings.maximizeIcon}`)
.addClass(this._settings.minimizeIcon)
.removeClass(this._settings.maximizeIcon)
this._parent.css({
height: this._parent.height(),
width: this._parent.width(),
transition: 'all .15s'
}).delay(150).queue(function () {
const $element = $(this)

$element.addClass(CLASS_NAME_MAXIMIZED)
$('html').addClass(CLASS_NAME_MAXIMIZED)
if ($element.hasClass(CLASS_NAME_COLLAPSED)) {
$element.addClass(CLASS_NAME_WAS_COLLAPSED)
}

$element.dequeue()
})

this._element.trigger($.Event(EVENT_MAXIMIZED), this._parent)
}

$(this).find(this._settings.collapseTrigger).click(() => {
this.toggle()
})
minimize() {
this._parent.find(`${this._settings.maximizeTrigger} .${this._settings.minimizeIcon}`)
.addClass(this._settings.maximizeIcon)
.removeClass(this._settings.minimizeIcon)
this._parent.css('cssText', `height: ${this._parent[0].style.height} !important; width: ${this._parent[0].style.width} !important; transition: all .15s;`
).delay(10).queue(function () {
const $element = $(this)

$element.removeClass(CLASS_NAME_MAXIMIZED)
$('html').removeClass(CLASS_NAME_MAXIMIZED)
$element.css({
height: 'inherit',
width: 'inherit'
})
if ($element.hasClass(CLASS_NAME_WAS_COLLAPSED)) {
$element.removeClass(CLASS_NAME_WAS_COLLAPSED)
}

$element.dequeue()
})

this._element.trigger($.Event(EVENT_MINIMIZED), this._parent)
}

$(this).find(this._settings.maximizeTrigger).click(() => {
this.toggleMaximize()
})
// Private

$(this).find(this._settings.removeTrigger).click(() => {
this.remove()
})
}
toggleMaximize() {
if (this._parent.hasClass(CLASS_NAME_MAXIMIZED)) {
this.minimize()
return
}

// Static
this.maximize()
}

static _jQueryInterface(config) {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())
// Static

if (!data) {
data = new CardWidget($(this), _options)
$(this).data(DATA_KEY, typeof config === 'string' ? data : config)
}
_init(card) {
this._parent = card

$(this).find(this._settings.collapseTrigger).click(() => {
this.toggle()
})

$(this).find(this._settings.maximizeTrigger).click(() => {
this.toggleMaximize()
})

if (typeof config === 'string' && /collapse|expand|remove|toggle|maximize|minimize|toggleMaximize/.test(config)) {
data[config]()
} else if (typeof config === 'object') {
data._init($(this))
$(this).find(this._settings.removeTrigger).click(() => {
this.remove()
})
}
}
}

/**
@@ -200,27 +200,27 @@ class CardWidget {
*/

$(document).on('click', SELECTOR_DATA_COLLAPSE, function (event) {
if (event) {
event.preventDefault()
}
if (event) {
event.preventDefault()
}

CardWidget._jQueryInterface.call($(this), 'toggle')
CardWidget._jQueryInterface.call($(this), 'toggle')
})

$(document).on('click', SELECTOR_DATA_REMOVE, function (event) {
if (event) {
event.preventDefault()
}
if (event) {
event.preventDefault()
}

CardWidget._jQueryInterface.call($(this), 'remove')
CardWidget._jQueryInterface.call($(this), 'remove')
})

$(document).on('click', SELECTOR_DATA_MAXIMIZE, function (event) {
if (event) {
event.preventDefault()
}
if (event) {
event.preventDefault()
}

CardWidget._jQueryInterface.call($(this), 'toggleMaximize')
CardWidget._jQueryInterface.call($(this), 'toggleMaximize')
})

/**
@@ -231,8 +231,8 @@ $(document).on('click', SELECTOR_DATA_MAXIMIZE, function (event) {
$.fn[NAME] = CardWidget._jQueryInterface
$.fn[NAME].Constructor = CardWidget
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return CardWidget._jQueryInterface
$.fn[NAME] = JQUERY_NO_CONFLICT
return CardWidget._jQueryInterface
}

export default CardWidget

+ 207
- 207
SecureSharing/wwwroot/build/js/ControlSidebar.js View File

@@ -42,10 +42,10 @@ const CLASS_NAME_FOOTER_LG_FIXED = 'layout-lg-footer-fixed'
const CLASS_NAME_FOOTER_XL_FIXED = 'layout-xl-footer-fixed'

const Default = {
controlsidebarSlide: true,
scrollbarTheme: 'os-theme-light',
scrollbarAutoHide: 'l',
target: SELECTOR_CONTROL_SIDEBAR
controlsidebarSlide: true,
scrollbarTheme: 'os-theme-light',
scrollbarAutoHide: 'l',
target: SELECTOR_CONTROL_SIDEBAR
}

/**
@@ -54,242 +54,242 @@ const Default = {
*/

class ControlSidebar {
constructor(element, config) {
this._element = element
this._config = config
}

// Public

collapse() {
const $body = $('body')
const $html = $('html')
const { target } = this._config

// Show the control sidebar
if (this._config.controlsidebarSlide) {
$html.addClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE)
$body.removeClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE).delay(300).queue(function () {
$(target).hide()
$html.removeClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE)
$(this).dequeue()
})
} else {
$body.removeClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN)
constructor(element, config) {
this._element = element
this._config = config
}

$(this._element).trigger($.Event(EVENT_COLLAPSED))
}
// Public

show() {
const $body = $('body')
const $html = $('html')
static _jQueryInterface(operation) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())

// Collapse the control sidebar
if (this._config.controlsidebarSlide) {
$html.addClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE)
$(this._config.target).show().delay(10).queue(function () {
$body.addClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE).delay(300).queue(function () {
$html.removeClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE)
$(this).dequeue()
if (!data) {
data = new ControlSidebar(this, _options)
$(this).data(DATA_KEY, data)
}

if (data[operation] === 'undefined') {
throw new Error(`${operation} is not a function`)
}

data[operation]()
})
$(this).dequeue()
})
} else {
$body.addClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN)
}

this._fixHeight()
this._fixScrollHeight()
collapse() {
const $body = $('body')
const $html = $('html')
const {target} = this._config

// Show the control sidebar
if (this._config.controlsidebarSlide) {
$html.addClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE)
$body.removeClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE).delay(300).queue(function () {
$(target).hide()
$html.removeClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE)
$(this).dequeue()
})
} else {
$body.removeClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN)
}

$(this._element).trigger($.Event(EVENT_COLLAPSED))
}

$(this._element).trigger($.Event(EVENT_EXPANDED))
}
show() {
const $body = $('body')
const $html = $('html')

// Collapse the control sidebar
if (this._config.controlsidebarSlide) {
$html.addClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE)
$(this._config.target).show().delay(10).queue(function () {
$body.addClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE).delay(300).queue(function () {
$html.removeClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE)
$(this).dequeue()
})
$(this).dequeue()
})
} else {
$body.addClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN)
}

toggle() {
const $body = $('body')
const shouldClose = $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) ||
$body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE)
this._fixHeight()
this._fixScrollHeight()

if (shouldClose) {
// Close the control sidebar
this.collapse()
} else {
// Open the control sidebar
this.show()
$(this._element).trigger($.Event(EVENT_EXPANDED))
}
}

// Private
// Private

_init() {
const $body = $('body')
const shouldNotHideAll = $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) ||
$body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE)
toggle() {
const $body = $('body')
const shouldClose = $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) ||
$body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE)

if (shouldNotHideAll) {
$(SELECTOR_CONTROL_SIDEBAR).not(this._config.target).hide()
$(this._config.target).css('display', 'block')
} else {
$(SELECTOR_CONTROL_SIDEBAR).hide()
if (shouldClose) {
// Close the control sidebar
this.collapse()
} else {
// Open the control sidebar
this.show()
}
}

this._fixHeight()
this._fixScrollHeight()
_init() {
const $body = $('body')
const shouldNotHideAll = $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) ||
$body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE)

$(window).resize(() => {
this._fixHeight()
this._fixScrollHeight()
})

$(window).scroll(() => {
const $body = $('body')
const shouldFixHeight = $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) ||
$body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE)
if (shouldNotHideAll) {
$(SELECTOR_CONTROL_SIDEBAR).not(this._config.target).hide()
$(this._config.target).css('display', 'block')
} else {
$(SELECTOR_CONTROL_SIDEBAR).hide()
}

if (shouldFixHeight) {
this._fixHeight()
this._fixScrollHeight()
}
})
}

_isNavbarFixed() {
const $body = $('body')
return (
$body.hasClass(CLASS_NAME_NAVBAR_FIXED) ||
$body.hasClass(CLASS_NAME_NAVBAR_SM_FIXED) ||
$body.hasClass(CLASS_NAME_NAVBAR_MD_FIXED) ||
$body.hasClass(CLASS_NAME_NAVBAR_LG_FIXED) ||
$body.hasClass(CLASS_NAME_NAVBAR_XL_FIXED)
)
}

_isFooterFixed() {
const $body = $('body')
return (
$body.hasClass(CLASS_NAME_FOOTER_FIXED) ||
$body.hasClass(CLASS_NAME_FOOTER_SM_FIXED) ||
$body.hasClass(CLASS_NAME_FOOTER_MD_FIXED) ||
$body.hasClass(CLASS_NAME_FOOTER_LG_FIXED) ||
$body.hasClass(CLASS_NAME_FOOTER_XL_FIXED)
)
}

_fixScrollHeight() {
const $body = $('body')
const $controlSidebar = $(this._config.target)

if (!$body.hasClass(CLASS_NAME_LAYOUT_FIXED)) {
return
}

const heights = {
scroll: $(document).height(),
window: $(window).height(),
header: $(SELECTOR_HEADER).outerHeight(),
footer: $(SELECTOR_FOOTER).outerHeight()
}
const positions = {
bottom: Math.abs((heights.window + $(window).scrollTop()) - heights.scroll),
top: $(window).scrollTop()
}
$(window).resize(() => {
this._fixHeight()
this._fixScrollHeight()
})

const navbarFixed = this._isNavbarFixed() && $(SELECTOR_HEADER).css('position') === 'fixed'

const footerFixed = this._isFooterFixed() && $(SELECTOR_FOOTER).css('position') === 'fixed'

const $controlsidebarContent = $(`${this._config.target}, ${this._config.target} ${SELECTOR_CONTROL_SIDEBAR_CONTENT}`)

if (positions.top === 0 && positions.bottom === 0) {
$controlSidebar.css({
bottom: heights.footer,
top: heights.header
})
$controlsidebarContent.css('height', heights.window - (heights.header + heights.footer))
} else if (positions.bottom <= heights.footer) {
if (footerFixed === false) {
const top = heights.header - positions.top
$controlSidebar.css('bottom', heights.footer - positions.bottom).css('top', top >= 0 ? top : 0)
$controlsidebarContent.css('height', heights.window - (heights.footer - positions.bottom))
} else {
$controlSidebar.css('bottom', heights.footer)
}
} else if (positions.top <= heights.header) {
if (navbarFixed === false) {
$controlSidebar.css('top', heights.header - positions.top)
$controlsidebarContent.css('height', heights.window - (heights.header - positions.top))
} else {
$controlSidebar.css('top', heights.header)
}
} else if (navbarFixed === false) {
$controlSidebar.css('top', 0)
$controlsidebarContent.css('height', heights.window)
} else {
$controlSidebar.css('top', heights.header)
}
$(window).scroll(() => {
const $body = $('body')
const shouldFixHeight = $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) ||
$body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE)

if (footerFixed && navbarFixed) {
$controlsidebarContent.css('height', '100%')
$controlSidebar.css('height', '')
} else if (footerFixed || navbarFixed) {
$controlsidebarContent.css('height', '100%')
$controlsidebarContent.css('height', '')
if (shouldFixHeight) {
this._fixScrollHeight()
}
})
}
}

_fixHeight() {
const $body = $('body')
const $controlSidebar = $(`${this._config.target} ${SELECTOR_CONTROL_SIDEBAR_CONTENT}`)

if (!$body.hasClass(CLASS_NAME_LAYOUT_FIXED)) {
$controlSidebar.attr('style', '')
return
_isNavbarFixed() {
const $body = $('body')
return (
$body.hasClass(CLASS_NAME_NAVBAR_FIXED) ||
$body.hasClass(CLASS_NAME_NAVBAR_SM_FIXED) ||
$body.hasClass(CLASS_NAME_NAVBAR_MD_FIXED) ||
$body.hasClass(CLASS_NAME_NAVBAR_LG_FIXED) ||
$body.hasClass(CLASS_NAME_NAVBAR_XL_FIXED)
)
}

const heights = {
window: $(window).height(),
header: $(SELECTOR_HEADER).outerHeight(),
footer: $(SELECTOR_FOOTER).outerHeight()
_isFooterFixed() {
const $body = $('body')
return (
$body.hasClass(CLASS_NAME_FOOTER_FIXED) ||
$body.hasClass(CLASS_NAME_FOOTER_SM_FIXED) ||
$body.hasClass(CLASS_NAME_FOOTER_MD_FIXED) ||
$body.hasClass(CLASS_NAME_FOOTER_LG_FIXED) ||
$body.hasClass(CLASS_NAME_FOOTER_XL_FIXED)
)
}

let sidebarHeight = heights.window - heights.header
_fixScrollHeight() {
const $body = $('body')
const $controlSidebar = $(this._config.target)

if (this._isFooterFixed() && $(SELECTOR_FOOTER).css('position') === 'fixed') {
sidebarHeight = heights.window - heights.header - heights.footer
}
if (!$body.hasClass(CLASS_NAME_LAYOUT_FIXED)) {
return
}

$controlSidebar.css('height', sidebarHeight)
const heights = {
scroll: $(document).height(),
window: $(window).height(),
header: $(SELECTOR_HEADER).outerHeight(),
footer: $(SELECTOR_FOOTER).outerHeight()
}
const positions = {
bottom: Math.abs((heights.window + $(window).scrollTop()) - heights.scroll),
top: $(window).scrollTop()
}

const navbarFixed = this._isNavbarFixed() && $(SELECTOR_HEADER).css('position') === 'fixed'

const footerFixed = this._isFooterFixed() && $(SELECTOR_FOOTER).css('position') === 'fixed'

const $controlsidebarContent = $(`${this._config.target}, ${this._config.target} ${SELECTOR_CONTROL_SIDEBAR_CONTENT}`)

if (positions.top === 0 && positions.bottom === 0) {
$controlSidebar.css({
bottom: heights.footer,
top: heights.header
})
$controlsidebarContent.css('height', heights.window - (heights.header + heights.footer))
} else if (positions.bottom <= heights.footer) {
if (footerFixed === false) {
const top = heights.header - positions.top
$controlSidebar.css('bottom', heights.footer - positions.bottom).css('top', top >= 0 ? top : 0)
$controlsidebarContent.css('height', heights.window - (heights.footer - positions.bottom))
} else {
$controlSidebar.css('bottom', heights.footer)
}
} else if (positions.top <= heights.header) {
if (navbarFixed === false) {
$controlSidebar.css('top', heights.header - positions.top)
$controlsidebarContent.css('height', heights.window - (heights.header - positions.top))
} else {
$controlSidebar.css('top', heights.header)
}
} else if (navbarFixed === false) {
$controlSidebar.css('top', 0)
$controlsidebarContent.css('height', heights.window)
} else {
$controlSidebar.css('top', heights.header)
}

if (typeof $.fn.overlayScrollbars !== 'undefined') {
$controlSidebar.overlayScrollbars({
className: this._config.scrollbarTheme,
sizeAutoCapable: true,
scrollbars: {
autoHide: this._config.scrollbarAutoHide,
clickScrolling: true
if (footerFixed && navbarFixed) {
$controlsidebarContent.css('height', '100%')
$controlSidebar.css('height', '')
} else if (footerFixed || navbarFixed) {
$controlsidebarContent.css('height', '100%')
$controlsidebarContent.css('height', '')
}
})
}
}

// Static
// Static

static _jQueryInterface(operation) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())
_fixHeight() {
const $body = $('body')
const $controlSidebar = $(`${this._config.target} ${SELECTOR_CONTROL_SIDEBAR_CONTENT}`)

if (!data) {
data = new ControlSidebar(this, _options)
$(this).data(DATA_KEY, data)
}
if (!$body.hasClass(CLASS_NAME_LAYOUT_FIXED)) {
$controlSidebar.attr('style', '')
return
}

const heights = {
window: $(window).height(),
header: $(SELECTOR_HEADER).outerHeight(),
footer: $(SELECTOR_FOOTER).outerHeight()
}

if (data[operation] === 'undefined') {
throw new Error(`${operation} is not a function`)
}
let sidebarHeight = heights.window - heights.header

data[operation]()
})
}
if (this._isFooterFixed() && $(SELECTOR_FOOTER).css('position') === 'fixed') {
sidebarHeight = heights.window - heights.header - heights.footer
}

$controlSidebar.css('height', sidebarHeight)

if (typeof $.fn.overlayScrollbars !== 'undefined') {
$controlSidebar.overlayScrollbars({
className: this._config.scrollbarTheme,
sizeAutoCapable: true,
scrollbars: {
autoHide: this._config.scrollbarAutoHide,
clickScrolling: true
}
})
}
}
}

/**
@@ -298,13 +298,13 @@ class ControlSidebar {
* ====================================================
*/
$(document).on('click', SELECTOR_DATA_TOGGLE, function (event) {
event.preventDefault()
event.preventDefault()

ControlSidebar._jQueryInterface.call($(this), 'toggle')
ControlSidebar._jQueryInterface.call($(this), 'toggle')
})

$(document).ready(() => {
ControlSidebar._jQueryInterface.call($(SELECTOR_DATA_TOGGLE), '_init')
ControlSidebar._jQueryInterface.call($(SELECTOR_DATA_TOGGLE), '_init')
})

/**
@@ -315,8 +315,8 @@ $(document).ready(() => {
$.fn[NAME] = ControlSidebar._jQueryInterface
$.fn[NAME].Constructor = ControlSidebar
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return ControlSidebar._jQueryInterface
$.fn[NAME] = JQUERY_NO_CONFLICT
return ControlSidebar._jQueryInterface
}

export default ControlSidebar

+ 24
- 24
SecureSharing/wwwroot/build/js/DirectChat.js View File

@@ -30,29 +30,29 @@ const CLASS_NAME_DIRECT_CHAT_OPEN = 'direct-chat-contacts-open'
*/

class DirectChat {
constructor(element) {
this._element = element
}
constructor(element) {
this._element = element
}

toggle() {
$(this._element).parents(SELECTOR_DIRECT_CHAT).first().toggleClass(CLASS_NAME_DIRECT_CHAT_OPEN)
$(this._element).trigger($.Event(EVENT_TOGGLED))
}
static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)

// Static
if (!data) {
data = new DirectChat($(this))
$(this).data(DATA_KEY, data)
}

static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
data[config]()
})
}

if (!data) {
data = new DirectChat($(this))
$(this).data(DATA_KEY, data)
}
// Static

data[config]()
})
}
toggle() {
$(this._element).parents(SELECTOR_DIRECT_CHAT).first().toggleClass(CLASS_NAME_DIRECT_CHAT_OPEN)
$(this._element).trigger($.Event(EVENT_TOGGLED))
}
}

/**
@@ -62,11 +62,11 @@ class DirectChat {
*/

$(document).on('click', SELECTOR_DATA_TOGGLE, function (event) {
if (event) {
event.preventDefault()
}
if (event) {
event.preventDefault()
}

DirectChat._jQueryInterface.call($(this), 'toggle')
DirectChat._jQueryInterface.call($(this), 'toggle')
})

/**
@@ -77,8 +77,8 @@ $(document).on('click', SELECTOR_DATA_TOGGLE, function (event) {
$.fn[NAME] = DirectChat._jQueryInterface
$.fn[NAME].Constructor = DirectChat
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return DirectChat._jQueryInterface
$.fn[NAME] = JQUERY_NO_CONFLICT
return DirectChat._jQueryInterface
}

export default DirectChat

+ 74
- 74
SecureSharing/wwwroot/build/js/Dropdown.js View File

@@ -33,78 +33,78 @@ const Default = {}
*/

class Dropdown {
constructor(element, config) {
this._config = config
this._element = element
}

// Public

toggleSubmenu() {
this._element.siblings().show().toggleClass('show')

if (!this._element.next().hasClass('show')) {
this._element.parents(SELECTOR_DROPDOWN_MENU).first().find('.show').removeClass('show').hide()
constructor(element, config) {
this._config = config
this._element = element
}

this._element.parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', () => {
$('.dropdown-submenu .show').removeClass('show').hide()
})
}
// Public

fixPosition() {
const $element = $(SELECTOR_DROPDOWN_MENU_ACTIVE)
static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _config = $.extend({}, Default, $(this).data())

if ($element.length === 0) {
return
}
if (!data) {
data = new Dropdown($(this), _config)
$(this).data(DATA_KEY, data)
}

if ($element.hasClass(CLASS_NAME_DROPDOWN_RIGHT)) {
$element.css({
left: 'inherit',
right: 0
})
} else {
$element.css({
left: 0,
right: 'inherit'
})
if (config === 'toggleSubmenu' || config === 'fixPosition') {
data[config]()
}
})
}

const offset = $element.offset()
const width = $element.width()
const visiblePart = $(window).width() - offset.left

if (offset.left < 0) {
$element.css({
left: 'inherit',
right: offset.left - 5
})
} else if (visiblePart < width) {
$element.css({
left: 'inherit',
right: 0
})
}
}
toggleSubmenu() {
this._element.siblings().show().toggleClass('show')

// Static
if (!this._element.next().hasClass('show')) {
this._element.parents(SELECTOR_DROPDOWN_MENU).first().find('.show').removeClass('show').hide()
}

static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _config = $.extend({}, Default, $(this).data())

if (!data) {
data = new Dropdown($(this), _config)
$(this).data(DATA_KEY, data)
}
this._element.parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', () => {
$('.dropdown-submenu .show').removeClass('show').hide()
})
}

if (config === 'toggleSubmenu' || config === 'fixPosition') {
data[config]()
}
})
}
// Static

fixPosition() {
const $element = $(SELECTOR_DROPDOWN_MENU_ACTIVE)

if ($element.length === 0) {
return
}

if ($element.hasClass(CLASS_NAME_DROPDOWN_RIGHT)) {
$element.css({
left: 'inherit',
right: 0
})
} else {
$element.css({
left: 0,
right: 'inherit'
})
}

const offset = $element.offset()
const width = $element.width()
const visiblePart = $(window).width() - offset.left

if (offset.left < 0) {
$element.css({
left: 'inherit',
right: offset.left - 5
})
} else if (visiblePart < width) {
$element.css({
left: 'inherit',
right: 0
})
}
}
}

/**
@@ -113,22 +113,22 @@ class Dropdown {
*/

$(`${SELECTOR_DROPDOWN_MENU} ${SELECTOR_DROPDOWN_TOGGLE}`).on('click', function (event) {
event.preventDefault()
event.stopPropagation()
event.preventDefault()
event.stopPropagation()

Dropdown._jQueryInterface.call($(this), 'toggleSubmenu')
Dropdown._jQueryInterface.call($(this), 'toggleSubmenu')
})

$(`${SELECTOR_NAVBAR} ${SELECTOR_DROPDOWN_TOGGLE}`).on('click', event => {
event.preventDefault()
event.preventDefault()

if ($(event.target).parent().hasClass(CLASS_NAME_DROPDOWN_SUBMENU)) {
return
}
if ($(event.target).parent().hasClass(CLASS_NAME_DROPDOWN_SUBMENU)) {
return
}

setTimeout(function () {
Dropdown._jQueryInterface.call($(this), 'fixPosition')
}, 1)
setTimeout(function () {
Dropdown._jQueryInterface.call($(this), 'fixPosition')
}, 1)
})

/**
@@ -139,8 +139,8 @@ $(`${SELECTOR_NAVBAR} ${SELECTOR_DROPDOWN_TOGGLE}`).on('click', event => {
$.fn[NAME] = Dropdown._jQueryInterface
$.fn[NAME].Constructor = Dropdown
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Dropdown._jQueryInterface
$.fn[NAME] = JQUERY_NO_CONFLICT
return Dropdown._jQueryInterface
}

export default Dropdown

+ 68
- 68
SecureSharing/wwwroot/build/js/ExpandableTable.js View File

@@ -8,9 +8,9 @@
import $ from 'jquery'

/**
* Constants
* ====================================================
*/
* Constants
* ====================================================
*/

const NAME = 'ExpandableTable'
const DATA_KEY = 'lte.expandableTable'
@@ -26,91 +26,91 @@ const SELECTOR_DATA_TOGGLE = '[data-widget="expandable-table"]'
const SELECTOR_ARIA_ATTR = 'aria-expanded'

/**
* Class Definition
* ====================================================
*/
* Class Definition
* ====================================================
*/
class ExpandableTable {
constructor(element, options) {
this._options = options
this._element = element
}

// Public

init() {
$(SELECTOR_DATA_TOGGLE).each((_, $header) => {
const $type = $($header).attr(SELECTOR_ARIA_ATTR)
const $body = $($header).next(SELECTOR_EXPANDABLE_BODY).children().first().children()
if ($type === 'true') {
$body.show()
} else if ($type === 'false') {
$body.hide()
$body.parent().parent().addClass('d-none')
}
})
}

toggleRow() {
const $element = this._element
const time = 500
const $type = $element.attr(SELECTOR_ARIA_ATTR)
const $body = $element.next(SELECTOR_EXPANDABLE_BODY).children().first().children()

$body.stop()
if ($type === 'true') {
$body.slideUp(time, () => {
$element.next(SELECTOR_EXPANDABLE_BODY).addClass('d-none')
})
$element.attr(SELECTOR_ARIA_ATTR, 'false')
$element.trigger($.Event(EVENT_COLLAPSED))
} else if ($type === 'false') {
$element.next(SELECTOR_EXPANDABLE_BODY).removeClass('d-none')
$body.slideDown(time)
$element.attr(SELECTOR_ARIA_ATTR, 'true')
$element.trigger($.Event(EVENT_EXPANDED))
constructor(element, options) {
this._options = options
this._element = element
}
}

// Static
// Public

static _jQueryInterface(operation) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
static _jQueryInterface(operation) {
return this.each(function () {
let data = $(this).data(DATA_KEY)

if (!data) {
data = new ExpandableTable($(this))
$(this).data(DATA_KEY, data)
}
if (!data) {
data = new ExpandableTable($(this))
$(this).data(DATA_KEY, data)
}

if (typeof operation === 'string' && /init|toggleRow/.test(operation)) {
data[operation]()
}
})
}
if (typeof operation === 'string' && /init|toggleRow/.test(operation)) {
data[operation]()
}
})
}

init() {
$(SELECTOR_DATA_TOGGLE).each((_, $header) => {
const $type = $($header).attr(SELECTOR_ARIA_ATTR)
const $body = $($header).next(SELECTOR_EXPANDABLE_BODY).children().first().children()
if ($type === 'true') {
$body.show()
} else if ($type === 'false') {
$body.hide()
$body.parent().parent().addClass('d-none')
}
})
}

// Static

toggleRow() {
const $element = this._element
const time = 500
const $type = $element.attr(SELECTOR_ARIA_ATTR)
const $body = $element.next(SELECTOR_EXPANDABLE_BODY).children().first().children()

$body.stop()
if ($type === 'true') {
$body.slideUp(time, () => {
$element.next(SELECTOR_EXPANDABLE_BODY).addClass('d-none')
})
$element.attr(SELECTOR_ARIA_ATTR, 'false')
$element.trigger($.Event(EVENT_COLLAPSED))
} else if ($type === 'false') {
$element.next(SELECTOR_EXPANDABLE_BODY).removeClass('d-none')
$body.slideDown(time)
$element.attr(SELECTOR_ARIA_ATTR, 'true')
$element.trigger($.Event(EVENT_EXPANDED))
}
}
}

/**
* Data API
* ====================================================
*/
* Data API
* ====================================================
*/
$(SELECTOR_TABLE).ready(function () {
ExpandableTable._jQueryInterface.call($(this), 'init')
ExpandableTable._jQueryInterface.call($(this), 'init')
})

$(document).on('click', SELECTOR_DATA_TOGGLE, function () {
ExpandableTable._jQueryInterface.call($(this), 'toggleRow')
ExpandableTable._jQueryInterface.call($(this), 'toggleRow')
})

/**
* jQuery API
* ====================================================
*/
* jQuery API
* ====================================================
*/

$.fn[NAME] = ExpandableTable._jQueryInterface
$.fn[NAME].Constructor = ExpandableTable
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return ExpandableTable._jQueryInterface
$.fn[NAME] = JQUERY_NO_CONFLICT
return ExpandableTable._jQueryInterface
}

export default ExpandableTable

+ 58
- 58
SecureSharing/wwwroot/build/js/Fullscreen.js View File

@@ -20,8 +20,8 @@ const SELECTOR_DATA_WIDGET = '[data-widget="fullscreen"]'
const SELECTOR_ICON = `${SELECTOR_DATA_WIDGET} i`

const Default = {
minimizeIcon: 'fa-compress-arrows-alt',
maximizeIcon: 'fa-expand-arrows-alt'
minimizeIcon: 'fa-compress-arrows-alt',
maximizeIcon: 'fa-expand-arrows-alt'
}

/**
@@ -30,76 +30,76 @@ const Default = {
*/

class Fullscreen {
constructor(_element, _options) {
this.element = _element
this.options = $.extend({}, Default, _options)
}

// Public

toggle() {
if (document.fullscreenElement ||
document.mozFullScreenElement ||
document.webkitFullscreenElement ||
document.msFullscreenElement) {
this.windowed()
} else {
this.fullscreen()
}
}

fullscreen() {
if (document.documentElement.requestFullscreen) {
document.documentElement.requestFullscreen()
} else if (document.documentElement.webkitRequestFullscreen) {
document.documentElement.webkitRequestFullscreen()
} else if (document.documentElement.msRequestFullscreen) {
document.documentElement.msRequestFullscreen()
constructor(_element, _options) {
this.element = _element
this.options = $.extend({}, Default, _options)
}

$(SELECTOR_ICON).removeClass(this.options.maximizeIcon).addClass(this.options.minimizeIcon)
}
// Public

windowed() {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen()
} else if (document.msExitFullscreen) {
document.msExitFullscreen()
}
static _jQueryInterface(config) {
let data = $(this).data(DATA_KEY)

$(SELECTOR_ICON).removeClass(this.options.minimizeIcon).addClass(this.options.maximizeIcon)
}
if (!data) {
data = $(this).data()
}

// Static
const _options = $.extend({}, Default, typeof config === 'object' ? config : data)
const plugin = new Fullscreen($(this), _options)

static _jQueryInterface(config) {
let data = $(this).data(DATA_KEY)
$(this).data(DATA_KEY, typeof config === 'object' ? config : data)

if (!data) {
data = $(this).data()
if (typeof config === 'string' && /toggle|fullscreen|windowed/.test(config)) {
plugin[config]()
} else {
plugin.init()
}
}

const _options = $.extend({}, Default, typeof config === 'object' ? config : data)
const plugin = new Fullscreen($(this), _options)
toggle() {
if (document.fullscreenElement ||
document.mozFullScreenElement ||
document.webkitFullscreenElement ||
document.msFullscreenElement) {
this.windowed()
} else {
this.fullscreen()
}
}

$(this).data(DATA_KEY, typeof config === 'object' ? config : data)
fullscreen() {
if (document.documentElement.requestFullscreen) {
document.documentElement.requestFullscreen()
} else if (document.documentElement.webkitRequestFullscreen) {
document.documentElement.webkitRequestFullscreen()
} else if (document.documentElement.msRequestFullscreen) {
document.documentElement.msRequestFullscreen()
}

if (typeof config === 'string' && /toggle|fullscreen|windowed/.test(config)) {
plugin[config]()
} else {
plugin.init()
$(SELECTOR_ICON).removeClass(this.options.maximizeIcon).addClass(this.options.minimizeIcon)
}

// Static

windowed() {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen()
} else if (document.msExitFullscreen) {
document.msExitFullscreen()
}

$(SELECTOR_ICON).removeClass(this.options.minimizeIcon).addClass(this.options.maximizeIcon)
}
}
}

/**
* Data API
* ====================================================
*/
* Data API
* ====================================================
*/
$(document).on('click', SELECTOR_DATA_WIDGET, function () {
Fullscreen._jQueryInterface.call($(this), 'toggle')
Fullscreen._jQueryInterface.call($(this), 'toggle')
})

/**
@@ -110,8 +110,8 @@ $(document).on('click', SELECTOR_DATA_WIDGET, function () {
$.fn[NAME] = Fullscreen._jQueryInterface
$.fn[NAME].Constructor = Fullscreen
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Fullscreen._jQueryInterface
$.fn[NAME] = JQUERY_NO_CONFLICT
return Fullscreen._jQueryInterface
}

export default Fullscreen

+ 302
- 302
SecureSharing/wwwroot/build/js/IFrame.js View File

@@ -39,25 +39,25 @@ const CLASS_NAME_IFRAME_MODE = 'iframe-mode'
const CLASS_NAME_FULLSCREEN_MODE = 'iframe-mode-fullscreen'

const Default = {
onTabClick(item) {
return item
},
onTabChanged(item) {
return item
},
onTabCreated(item) {
return item
},
autoIframeMode: true,
autoItemActive: true,
autoShowNewTab: true,
allowDuplicates: false,
loadingScreen: true,
useNavbarItems: true,
scrollOffset: 40,
scrollBehaviorSwap: false,
iconMaximize: 'fa-expand',
iconMinimize: 'fa-compress'
onTabClick(item) {
return item
},
onTabChanged(item) {
return item
},
onTabCreated(item) {
return item
},
autoIframeMode: true,
autoItemActive: true,
autoShowNewTab: true,
allowDuplicates: false,
loadingScreen: true,
useNavbarItems: true,
scrollOffset: 40,
scrollBehaviorSwap: false,
iconMaximize: 'fa-expand',
iconMinimize: 'fa-compress'
}

/**
@@ -66,327 +66,327 @@ const Default = {
*/

class IFrame {
constructor(element, config) {
this._config = config
this._element = element
constructor(element, config) {
this._config = config
this._element = element

this._init()
}
this._init()
}

// Public
// Public

onTabClick(item) {
this._config.onTabClick(item)
}
static _jQueryInterface(operation, ...args) {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())

onTabChanged(item) {
this._config.onTabChanged(item)
}
if (!data) {
data = new IFrame(this, _options)
$(this).data(DATA_KEY, data)
}

onTabCreated(item) {
this._config.onTabCreated(item)
}
if (typeof operation === 'string' && /createTab|openTabSidebar|switchTab|removeActiveTab/.test(operation)) {
data[operation](...args)
}
}

createTab(title, link, uniqueName, autoOpen) {
let tabId = `panel-${uniqueName}`
let navId = `tab-${uniqueName}`
onTabClick(item) {
this._config.onTabClick(item)
}

if (this._config.allowDuplicates) {
tabId += `-${Math.floor(Math.random() * 1000)}`
navId += `-${Math.floor(Math.random() * 1000)}`
onTabChanged(item) {
this._config.onTabChanged(item)
}

const newNavItem = `<li class="nav-item" role="presentation"><a href="#" class="btn-iframe-close" data-widget="iframe-close" data-type="only-this"><i class="fas fa-times"></i></a><a class="nav-link" data-toggle="row" id="${navId}" href="#${tabId}" role="tab" aria-controls="${tabId}" aria-selected="false">${title}</a></li>`
$(SELECTOR_TAB_NAVBAR_NAV).append(unescape(escape(newNavItem)))
onTabCreated(item) {
this._config.onTabCreated(item)
}

const newTabItem = `<div class="tab-pane fade" id="${tabId}" role="tabpanel" aria-labelledby="${navId}"><iframe src="${link}"></iframe></div>`
$(SELECTOR_TAB_CONTENT).append(unescape(escape(newTabItem)))
createTab(title, link, uniqueName, autoOpen) {
let tabId = `panel-${uniqueName}`
let navId = `tab-${uniqueName}`

if (this._config.allowDuplicates) {
tabId += `-${Math.floor(Math.random() * 1000)}`
navId += `-${Math.floor(Math.random() * 1000)}`
}

const newNavItem = `<li class="nav-item" role="presentation"><a href="#" class="btn-iframe-close" data-widget="iframe-close" data-type="only-this"><i class="fas fa-times"></i></a><a class="nav-link" data-toggle="row" id="${navId}" href="#${tabId}" role="tab" aria-controls="${tabId}" aria-selected="false">${title}</a></li>`
$(SELECTOR_TAB_NAVBAR_NAV).append(unescape(escape(newNavItem)))

const newTabItem = `<div class="tab-pane fade" id="${tabId}" role="tabpanel" aria-labelledby="${navId}"><iframe src="${link}"></iframe></div>`
$(SELECTOR_TAB_CONTENT).append(unescape(escape(newTabItem)))

if (autoOpen) {
if (this._config.loadingScreen) {
const $loadingScreen = $(SELECTOR_TAB_LOADING)
$loadingScreen.fadeIn()
$(`${tabId} iframe`).ready(() => {
if (typeof this._config.loadingScreen === 'number') {
this.switchTab(`#${navId}`)
setTimeout(() => {
$loadingScreen.fadeOut()
}, this._config.loadingScreen)
} else {
this.switchTab(`#${navId}`)
$loadingScreen.fadeOut()
}
})
} else {
this.switchTab(`#${navId}`)
}
}

this.onTabCreated($(`#${navId}`))
}

if (autoOpen) {
if (this._config.loadingScreen) {
const $loadingScreen = $(SELECTOR_TAB_LOADING)
$loadingScreen.fadeIn()
$(`${tabId} iframe`).ready(() => {
if (typeof this._config.loadingScreen === 'number') {
this.switchTab(`#${navId}`)
setTimeout(() => {
$loadingScreen.fadeOut()
}, this._config.loadingScreen)
} else {
this.switchTab(`#${navId}`)
$loadingScreen.fadeOut()
}
})
} else {
this.switchTab(`#${navId}`)
}
openTabSidebar(item, autoOpen = this._config.autoShowNewTab) {
let $item = $(item).clone()
if ($item.attr('href') === undefined) {
$item = $(item).parent('a').clone()
}

$item.find('.right, .search-path').remove()
let title = $item.find('p').text()
if (title === '') {
title = $item.text()
}

const link = $item.attr('href')
if (link === '#' || link === '' || link === undefined) {
return
}

const uniqueName = link.replace('./', '').replace(/["&'./:=?[\]]/gi, '-').replace(/(--)/gi, '')
const navId = `tab-${uniqueName}`

if (!this._config.allowDuplicates && $(`#${navId}`).length > 0) {
return this.switchTab(`#${navId}`)
}

if ((!this._config.allowDuplicates && $(`#${navId}`).length === 0) || this._config.allowDuplicates) {
this.createTab(title, link, uniqueName, autoOpen)
}
}

this.onTabCreated($(`#${navId}`))
}
switchTab(item) {
const $item = $(item)
const tabId = $item.attr('href')

openTabSidebar(item, autoOpen = this._config.autoShowNewTab) {
let $item = $(item).clone()
if ($item.attr('href') === undefined) {
$item = $(item).parent('a').clone()
}
$(SELECTOR_TAB_EMPTY).hide()
$(`${SELECTOR_TAB_NAVBAR_NAV} .active`).tab('dispose').removeClass('active')
this._fixHeight()

$item.tab('show')
$item.parents('li').addClass('active')
this.onTabChanged($item)

$item.find('.right, .search-path').remove()
let title = $item.find('p').text()
if (title === '') {
title = $item.text()
if (this._config.autoItemActive) {
this._setItemActive($(`${tabId} iframe`).attr('src'))
}
}

const link = $item.attr('href')
if (link === '#' || link === '' || link === undefined) {
return
removeActiveTab(type, element) {
if (type == 'all') {
$(SELECTOR_TAB_NAVBAR_NAV_ITEM).remove()
$(SELECTOR_TAB_PANE).remove()
$(SELECTOR_TAB_EMPTY).show()
} else if (type == 'all-other') {
$(`${SELECTOR_TAB_NAVBAR_NAV_ITEM}:not(.active)`).remove()
$(`${SELECTOR_TAB_PANE}:not(.active)`).remove()
} else if (type == 'only-this') {
const $navClose = $(element)
const $navItem = $navClose.parent('.nav-item')
const $navItemParent = $navItem.parent()
const navItemIndex = $navItem.index()
const tabId = $navClose.siblings('.nav-link').attr('aria-controls')
$navItem.remove()
$(`#${tabId}`).remove()
if ($(SELECTOR_TAB_CONTENT).children().length == $(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).length) {
$(SELECTOR_TAB_EMPTY).show()
} else {
const prevNavItemIndex = navItemIndex - 1
this.switchTab($navItemParent.children().eq(prevNavItemIndex).find('a.nav-link'))
}
} else {
const $navItem = $(`${SELECTOR_TAB_NAVBAR_NAV_ITEM}.active`)
const $navItemParent = $navItem.parent()
const navItemIndex = $navItem.index()
$navItem.remove()
$(`${SELECTOR_TAB_PANE}.active`).remove()
if ($(SELECTOR_TAB_CONTENT).children().length == $(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).length) {
$(SELECTOR_TAB_EMPTY).show()
} else {
const prevNavItemIndex = navItemIndex - 1
this.switchTab($navItemParent.children().eq(prevNavItemIndex).find('a.nav-link'))
}
}
}

const uniqueName = link.replace('./', '').replace(/["&'./:=?[\]]/gi, '-').replace(/(--)/gi, '')
const navId = `tab-${uniqueName}`
// Private

toggleFullscreen() {
if ($('body').hasClass(CLASS_NAME_FULLSCREEN_MODE)) {
$(`${SELECTOR_DATA_TOGGLE_FULLSCREEN} i`).removeClass(this._config.iconMinimize).addClass(this._config.iconMaximize)
$('body').removeClass(CLASS_NAME_FULLSCREEN_MODE)
$(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).height('auto')
$(SELECTOR_CONTENT_WRAPPER).height('auto')
$(SELECTOR_CONTENT_IFRAME).height('auto')
} else {
$(`${SELECTOR_DATA_TOGGLE_FULLSCREEN} i`).removeClass(this._config.iconMaximize).addClass(this._config.iconMinimize)
$('body').addClass(CLASS_NAME_FULLSCREEN_MODE)
}

$(window).trigger('resize')
this._fixHeight(true)
}

if (!this._config.allowDuplicates && $(`#${navId}`).length > 0) {
return this.switchTab(`#${navId}`)
_init() {
if (window.frameElement && this._config.autoIframeMode) {
$('body').addClass(CLASS_NAME_IFRAME_MODE)
} else if ($(SELECTOR_CONTENT_WRAPPER).hasClass(CLASS_NAME_IFRAME_MODE)) {
if ($(SELECTOR_TAB_CONTENT).children().length > 2) {
const $el = $(`${SELECTOR_TAB_PANE}:first-child`)
$el.show()
this._setItemActive($el.find('iframe').attr('src'))
}

this._setupListeners()
this._fixHeight(true)
}
}

if ((!this._config.allowDuplicates && $(`#${navId}`).length === 0) || this._config.allowDuplicates) {
this.createTab(title, link, uniqueName, autoOpen)
_navScroll(offset) {
const leftPos = $(SELECTOR_TAB_NAVBAR_NAV).scrollLeft()
$(SELECTOR_TAB_NAVBAR_NAV).animate({scrollLeft: (leftPos + offset)}, 250, 'linear')
}
}

switchTab(item) {
const $item = $(item)
const tabId = $item.attr('href')
_setupListeners() {
$(window).on('resize', () => {
setTimeout(() => {
this._fixHeight()
}, 1)
})
$(document).on('click', `${SELECTOR_SIDEBAR_MENU_ITEM}, ${SELECTOR_SIDEBAR_SEARCH_ITEM}`, e => {
e.preventDefault()
this.openTabSidebar(e.target)
})

$(SELECTOR_TAB_EMPTY).hide()
$(`${SELECTOR_TAB_NAVBAR_NAV} .active`).tab('dispose').removeClass('active')
this._fixHeight()
if (this._config.useNavbarItems) {
$(document).on('click', `${SELECTOR_HEADER_MENU_ITEM}, ${SELECTOR_HEADER_DROPDOWN_ITEM}`, e => {
e.preventDefault()
this.openTabSidebar(e.target)
})
}

$(document).on('click', SELECTOR_TAB_NAVBAR_NAV_LINK, e => {
e.preventDefault()
this.onTabClick(e.target)
this.switchTab(e.target)
})
$(document).on('click', SELECTOR_TAB_NAVBAR_NAV_LINK, e => {
e.preventDefault()
this.onTabClick(e.target)
this.switchTab(e.target)
})
$(document).on('click', SELECTOR_DATA_TOGGLE_CLOSE, e => {
e.preventDefault()
let {target} = e

$item.tab('show')
$item.parents('li').addClass('active')
this.onTabChanged($item)
if (target.nodeName == 'I') {
target = e.target.offsetParent
}

if (this._config.autoItemActive) {
this._setItemActive($(`${tabId} iframe`).attr('src'))
}
}

removeActiveTab(type, element) {
if (type == 'all') {
$(SELECTOR_TAB_NAVBAR_NAV_ITEM).remove()
$(SELECTOR_TAB_PANE).remove()
$(SELECTOR_TAB_EMPTY).show()
} else if (type == 'all-other') {
$(`${SELECTOR_TAB_NAVBAR_NAV_ITEM}:not(.active)`).remove()
$(`${SELECTOR_TAB_PANE}:not(.active)`).remove()
} else if (type == 'only-this') {
const $navClose = $(element)
const $navItem = $navClose.parent('.nav-item')
const $navItemParent = $navItem.parent()
const navItemIndex = $navItem.index()
const tabId = $navClose.siblings('.nav-link').attr('aria-controls')
$navItem.remove()
$(`#${tabId}`).remove()
if ($(SELECTOR_TAB_CONTENT).children().length == $(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).length) {
$(SELECTOR_TAB_EMPTY).show()
} else {
const prevNavItemIndex = navItemIndex - 1
this.switchTab($navItemParent.children().eq(prevNavItemIndex).find('a.nav-link'))
}
} else {
const $navItem = $(`${SELECTOR_TAB_NAVBAR_NAV_ITEM}.active`)
const $navItemParent = $navItem.parent()
const navItemIndex = $navItem.index()
$navItem.remove()
$(`${SELECTOR_TAB_PANE}.active`).remove()
if ($(SELECTOR_TAB_CONTENT).children().length == $(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).length) {
$(SELECTOR_TAB_EMPTY).show()
} else {
const prevNavItemIndex = navItemIndex - 1
this.switchTab($navItemParent.children().eq(prevNavItemIndex).find('a.nav-link'))
}
}
}

toggleFullscreen() {
if ($('body').hasClass(CLASS_NAME_FULLSCREEN_MODE)) {
$(`${SELECTOR_DATA_TOGGLE_FULLSCREEN} i`).removeClass(this._config.iconMinimize).addClass(this._config.iconMaximize)
$('body').removeClass(CLASS_NAME_FULLSCREEN_MODE)
$(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).height('auto')
$(SELECTOR_CONTENT_WRAPPER).height('auto')
$(SELECTOR_CONTENT_IFRAME).height('auto')
} else {
$(`${SELECTOR_DATA_TOGGLE_FULLSCREEN} i`).removeClass(this._config.iconMaximize).addClass(this._config.iconMinimize)
$('body').addClass(CLASS_NAME_FULLSCREEN_MODE)
}
this.removeActiveTab(target.attributes['data-type'] ? target.attributes['data-type'].nodeValue : null, target)
})
$(document).on('click', SELECTOR_DATA_TOGGLE_FULLSCREEN, e => {
e.preventDefault()
this.toggleFullscreen()
})
let mousedown = false
let mousedownInterval = null
$(document).on('mousedown', SELECTOR_DATA_TOGGLE_SCROLL_LEFT, e => {
e.preventDefault()
clearInterval(mousedownInterval)

$(window).trigger('resize')
this._fixHeight(true)
}
let {scrollOffset} = this._config

// Private
if (!this._config.scrollBehaviorSwap) {
scrollOffset = -scrollOffset
}

_init() {
if (window.frameElement && this._config.autoIframeMode) {
$('body').addClass(CLASS_NAME_IFRAME_MODE)
} else if ($(SELECTOR_CONTENT_WRAPPER).hasClass(CLASS_NAME_IFRAME_MODE)) {
if ($(SELECTOR_TAB_CONTENT).children().length > 2) {
const $el = $(`${SELECTOR_TAB_PANE}:first-child`)
$el.show()
this._setItemActive($el.find('iframe').attr('src'))
}
mousedown = true
this._navScroll(scrollOffset)

this._setupListeners()
this._fixHeight(true)
}
}
mousedownInterval = setInterval(() => {
this._navScroll(scrollOffset)
}, 250)
})
$(document).on('mousedown', SELECTOR_DATA_TOGGLE_SCROLL_RIGHT, e => {
e.preventDefault()
clearInterval(mousedownInterval)

_navScroll(offset) {
const leftPos = $(SELECTOR_TAB_NAVBAR_NAV).scrollLeft()
$(SELECTOR_TAB_NAVBAR_NAV).animate({ scrollLeft: (leftPos + offset) }, 250, 'linear')
}
let {scrollOffset} = this._config

_setupListeners() {
$(window).on('resize', () => {
setTimeout(() => {
this._fixHeight()
}, 1)
})
$(document).on('click', `${SELECTOR_SIDEBAR_MENU_ITEM}, ${SELECTOR_SIDEBAR_SEARCH_ITEM}`, e => {
e.preventDefault()
this.openTabSidebar(e.target)
})

if (this._config.useNavbarItems) {
$(document).on('click', `${SELECTOR_HEADER_MENU_ITEM}, ${SELECTOR_HEADER_DROPDOWN_ITEM}`, e => {
e.preventDefault()
this.openTabSidebar(e.target)
})
}
if (this._config.scrollBehaviorSwap) {
scrollOffset = -scrollOffset
}

mousedown = true
this._navScroll(scrollOffset)

$(document).on('click', SELECTOR_TAB_NAVBAR_NAV_LINK, e => {
e.preventDefault()
this.onTabClick(e.target)
this.switchTab(e.target)
})
$(document).on('click', SELECTOR_TAB_NAVBAR_NAV_LINK, e => {
e.preventDefault()
this.onTabClick(e.target)
this.switchTab(e.target)
})
$(document).on('click', SELECTOR_DATA_TOGGLE_CLOSE, e => {
e.preventDefault()
let { target } = e

if (target.nodeName == 'I') {
target = e.target.offsetParent
}

this.removeActiveTab(target.attributes['data-type'] ? target.attributes['data-type'].nodeValue : null, target)
})
$(document).on('click', SELECTOR_DATA_TOGGLE_FULLSCREEN, e => {
e.preventDefault()
this.toggleFullscreen()
})
let mousedown = false
let mousedownInterval = null
$(document).on('mousedown', SELECTOR_DATA_TOGGLE_SCROLL_LEFT, e => {
e.preventDefault()
clearInterval(mousedownInterval)

let { scrollOffset } = this._config

if (!this._config.scrollBehaviorSwap) {
scrollOffset = -scrollOffset
}

mousedown = true
this._navScroll(scrollOffset)

mousedownInterval = setInterval(() => {
this._navScroll(scrollOffset)
}, 250)
})
$(document).on('mousedown', SELECTOR_DATA_TOGGLE_SCROLL_RIGHT, e => {
e.preventDefault()
clearInterval(mousedownInterval)

let { scrollOffset } = this._config

if (this._config.scrollBehaviorSwap) {
scrollOffset = -scrollOffset
}

mousedown = true
this._navScroll(scrollOffset)

mousedownInterval = setInterval(() => {
this._navScroll(scrollOffset)
}, 250)
})
$(document).on('mouseup', () => {
if (mousedown) {
mousedown = false
clearInterval(mousedownInterval)
mousedownInterval = null
}
})
}

_setItemActive(href) {
$(`${SELECTOR_SIDEBAR_MENU_ITEM}, ${SELECTOR_HEADER_DROPDOWN_ITEM}`).removeClass('active')
$(SELECTOR_HEADER_MENU_ITEM).parent().removeClass('active')

const $headerMenuItem = $(`${SELECTOR_HEADER_MENU_ITEM}[href$="${href}"]`)
const $headerDropdownItem = $(`${SELECTOR_HEADER_DROPDOWN_ITEM}[href$="${href}"]`)
const $sidebarMenuItem = $(`${SELECTOR_SIDEBAR_MENU_ITEM}[href$="${href}"]`)

$headerMenuItem.each((i, e) => {
$(e).parent().addClass('active')
})
$headerDropdownItem.each((i, e) => {
$(e).addClass('active')
})
$sidebarMenuItem.each((i, e) => {
$(e).addClass('active')
$(e).parents('.nav-treeview').prevAll('.nav-link').addClass('active')
})
}

_fixHeight(tabEmpty = false) {
if ($('body').hasClass(CLASS_NAME_FULLSCREEN_MODE)) {
const windowHeight = $(window).height()
const navbarHeight = $(SELECTOR_TAB_NAV).outerHeight()
$(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}, ${SELECTOR_CONTENT_IFRAME}`).height(windowHeight - navbarHeight)
$(SELECTOR_CONTENT_WRAPPER).height(windowHeight)
} else {
const contentWrapperHeight = parseFloat($(SELECTOR_CONTENT_WRAPPER).css('height'))
const navbarHeight = $(SELECTOR_TAB_NAV).outerHeight()
if (tabEmpty == true) {
setTimeout(() => {
$(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).height(contentWrapperHeight - navbarHeight)
}, 50)
} else {
$(SELECTOR_CONTENT_IFRAME).height(contentWrapperHeight - navbarHeight)
}
mousedownInterval = setInterval(() => {
this._navScroll(scrollOffset)
}, 250)
})
$(document).on('mouseup', () => {
if (mousedown) {
mousedown = false
clearInterval(mousedownInterval)
mousedownInterval = null
}
})
}
}

// Static
_setItemActive(href) {
$(`${SELECTOR_SIDEBAR_MENU_ITEM}, ${SELECTOR_HEADER_DROPDOWN_ITEM}`).removeClass('active')
$(SELECTOR_HEADER_MENU_ITEM).parent().removeClass('active')

static _jQueryInterface(operation, ...args) {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())
const $headerMenuItem = $(`${SELECTOR_HEADER_MENU_ITEM}[href$="${href}"]`)
const $headerDropdownItem = $(`${SELECTOR_HEADER_DROPDOWN_ITEM}[href$="${href}"]`)
const $sidebarMenuItem = $(`${SELECTOR_SIDEBAR_MENU_ITEM}[href$="${href}"]`)

if (!data) {
data = new IFrame(this, _options)
$(this).data(DATA_KEY, data)
$headerMenuItem.each((i, e) => {
$(e).parent().addClass('active')
})
$headerDropdownItem.each((i, e) => {
$(e).addClass('active')
})
$sidebarMenuItem.each((i, e) => {
$(e).addClass('active')
$(e).parents('.nav-treeview').prevAll('.nav-link').addClass('active')
})
}

if (typeof operation === 'string' && /createTab|openTabSidebar|switchTab|removeActiveTab/.test(operation)) {
data[operation](...args)
// Static

_fixHeight(tabEmpty = false) {
if ($('body').hasClass(CLASS_NAME_FULLSCREEN_MODE)) {
const windowHeight = $(window).height()
const navbarHeight = $(SELECTOR_TAB_NAV).outerHeight()
$(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}, ${SELECTOR_CONTENT_IFRAME}`).height(windowHeight - navbarHeight)
$(SELECTOR_CONTENT_WRAPPER).height(windowHeight)
} else {
const contentWrapperHeight = parseFloat($(SELECTOR_CONTENT_WRAPPER).css('height'))
const navbarHeight = $(SELECTOR_TAB_NAV).outerHeight()
if (tabEmpty == true) {
setTimeout(() => {
$(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).height(contentWrapperHeight - navbarHeight)
}, 50)
} else {
$(SELECTOR_CONTENT_IFRAME).height(contentWrapperHeight - navbarHeight)
}
}
}
}
}

/**
@@ -395,7 +395,7 @@ class IFrame {
*/

$(window).on('load', () => {
IFrame._jQueryInterface.call($(SELECTOR_DATA_TOGGLE))
IFrame._jQueryInterface.call($(SELECTOR_DATA_TOGGLE))
})

/**
@@ -406,8 +406,8 @@ $(window).on('load', () => {
$.fn[NAME] = IFrame._jQueryInterface
$.fn[NAME].Constructor = IFrame
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return IFrame._jQueryInterface
$.fn[NAME] = JQUERY_NO_CONFLICT
return IFrame._jQueryInterface
}

export default IFrame

+ 156
- 156
SecureSharing/wwwroot/build/js/Layout.js View File

@@ -35,12 +35,12 @@ const CLASS_NAME_CONTROL_SIDEBAR_SLIDE_OPEN = 'control-sidebar-slide-open'
const CLASS_NAME_CONTROL_SIDEBAR_OPEN = 'control-sidebar-open'

const Default = {
scrollbarTheme: 'os-theme-light',
scrollbarAutoHide: 'l',
panelAutoHeight: true,
panelAutoHeightMode: 'min-height',
preloadDuration: 200,
loginRegisterAutoHeight: true
scrollbarTheme: 'os-theme-light',
scrollbarAutoHide: 'l',
panelAutoHeight: true,
panelAutoHeightMode: 'min-height',
preloadDuration: 200,
loginRegisterAutoHeight: true
}

/**
@@ -49,180 +49,180 @@ const Default = {
*/

class Layout {
constructor(element, config) {
this._config = config
this._element = element
}
constructor(element, config) {
this._config = config
this._element = element
}

// Public
// Public

fixLayoutHeight(extra = null) {
const $body = $('body')
let controlSidebar = 0
static _jQueryInterface(config = '') {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())

if ($body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE_OPEN) || $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) || extra === 'control_sidebar') {
controlSidebar = $(SELECTOR_CONTROL_SIDEBAR_CONTENT).outerHeight()
}
if (!data) {
data = new Layout($(this), _options)
$(this).data(DATA_KEY, data)
}

const heights = {
window: $(window).height(),
header: $(SELECTOR_HEADER).length > 0 ? $(SELECTOR_HEADER).outerHeight() : 0,
footer: $(SELECTOR_FOOTER).length > 0 ? $(SELECTOR_FOOTER).outerHeight() : 0,
sidebar: $(SELECTOR_SIDEBAR).length > 0 ? $(SELECTOR_SIDEBAR).height() : 0,
controlSidebar
if (config === 'init' || config === '') {
data._init()
} else if (config === 'fixLayoutHeight' || config === 'fixLoginRegisterHeight') {
data[config]()
}
})
}

const max = this._max(heights)
let offset = this._config.panelAutoHeight
fixLayoutHeight(extra = null) {
const $body = $('body')
let controlSidebar = 0

if (offset === true) {
offset = 0
}
if ($body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE_OPEN) || $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) || extra === 'control_sidebar') {
controlSidebar = $(SELECTOR_CONTROL_SIDEBAR_CONTENT).outerHeight()
}

const $contentSelector = $(SELECTOR_CONTENT)
const heights = {
window: $(window).height(),
header: $(SELECTOR_HEADER).length > 0 ? $(SELECTOR_HEADER).outerHeight() : 0,
footer: $(SELECTOR_FOOTER).length > 0 ? $(SELECTOR_FOOTER).outerHeight() : 0,
sidebar: $(SELECTOR_SIDEBAR).length > 0 ? $(SELECTOR_SIDEBAR).height() : 0,
controlSidebar
}

if (offset !== false) {
if (max === heights.controlSidebar) {
$contentSelector.css(this._config.panelAutoHeightMode, (max + offset))
} else if (max === heights.window) {
$contentSelector.css(this._config.panelAutoHeightMode, (max + offset) - heights.header - heights.footer)
} else {
$contentSelector.css(this._config.panelAutoHeightMode, (max + offset) - heights.header)
}
const max = this._max(heights)
let offset = this._config.panelAutoHeight

if (this._isFooterFixed()) {
$contentSelector.css(this._config.panelAutoHeightMode, parseFloat($contentSelector.css(this._config.panelAutoHeightMode)) + heights.footer)
}
}
if (offset === true) {
offset = 0
}

if (!$body.hasClass(CLASS_NAME_LAYOUT_FIXED)) {
return
}
const $contentSelector = $(SELECTOR_CONTENT)

if (typeof $.fn.overlayScrollbars !== 'undefined') {
$(SELECTOR_SIDEBAR).overlayScrollbars({
className: this._config.scrollbarTheme,
sizeAutoCapable: true,
scrollbars: {
autoHide: this._config.scrollbarAutoHide,
clickScrolling: true
}
})
} else {
$(SELECTOR_SIDEBAR).css('overflow-y', 'auto')
}
}
if (offset !== false) {
if (max === heights.controlSidebar) {
$contentSelector.css(this._config.panelAutoHeightMode, (max + offset))
} else if (max === heights.window) {
$contentSelector.css(this._config.panelAutoHeightMode, (max + offset) - heights.header - heights.footer)
} else {
$contentSelector.css(this._config.panelAutoHeightMode, (max + offset) - heights.header)
}

fixLoginRegisterHeight() {
const $body = $('body')
const $selector = $(`${SELECTOR_LOGIN_BOX}, ${SELECTOR_REGISTER_BOX}`)
if (this._isFooterFixed()) {
$contentSelector.css(this._config.panelAutoHeightMode, parseFloat($contentSelector.css(this._config.panelAutoHeightMode)) + heights.footer)
}
}

if ($selector.length === 0) {
$body.css('height', 'auto')
$('html').css('height', 'auto')
} else {
const boxHeight = $selector.height()
if (!$body.hasClass(CLASS_NAME_LAYOUT_FIXED)) {
return
}

if ($body.css(this._config.panelAutoHeightMode) !== boxHeight) {
$body.css(this._config.panelAutoHeightMode, boxHeight)
}
if (typeof $.fn.overlayScrollbars !== 'undefined') {
$(SELECTOR_SIDEBAR).overlayScrollbars({
className: this._config.scrollbarTheme,
sizeAutoCapable: true,
scrollbars: {
autoHide: this._config.scrollbarAutoHide,
clickScrolling: true
}
})
} else {
$(SELECTOR_SIDEBAR).css('overflow-y', 'auto')
}
}
}

// Private
// Private

_init() {
// Activate layout height watcher
this.fixLayoutHeight()
fixLoginRegisterHeight() {
const $body = $('body')
const $selector = $(`${SELECTOR_LOGIN_BOX}, ${SELECTOR_REGISTER_BOX}`)

if (this._config.loginRegisterAutoHeight === true) {
this.fixLoginRegisterHeight()
} else if (this._config.loginRegisterAutoHeight === parseInt(this._config.loginRegisterAutoHeight, 10)) {
setInterval(this.fixLoginRegisterHeight, this._config.loginRegisterAutoHeight)
}
if ($selector.length === 0) {
$body.css('height', 'auto')
$('html').css('height', 'auto')
} else {
const boxHeight = $selector.height()

$(SELECTOR_SIDEBAR)
.on('collapsed.lte.treeview expanded.lte.treeview', () => {
this.fixLayoutHeight()
})

$(SELECTOR_MAIN_SIDEBAR)
.on('mouseenter mouseleave', () => {
if ($('body').hasClass(CLASS_NAME_SIDEBAR_COLLAPSED)) {
this.fixLayoutHeight()
if ($body.css(this._config.panelAutoHeightMode) !== boxHeight) {
$body.css(this._config.panelAutoHeightMode, boxHeight)
}
}
})

$(SELECTOR_PUSHMENU_BTN)
.on('collapsed.lte.pushmenu shown.lte.pushmenu', () => {
setTimeout(() => {
this.fixLayoutHeight()
}, 300)
})
}

$(SELECTOR_CONTROL_SIDEBAR_BTN)
.on('collapsed.lte.controlsidebar', () => {
_init() {
// Activate layout height watcher
this.fixLayoutHeight()
})
.on('expanded.lte.controlsidebar', () => {
this.fixLayoutHeight('control_sidebar')
})

$(window).resize(() => {
this.fixLayoutHeight()
})
if (this._config.loginRegisterAutoHeight === true) {
this.fixLoginRegisterHeight()
} else if (this._config.loginRegisterAutoHeight === parseInt(this._config.loginRegisterAutoHeight, 10)) {
setInterval(this.fixLoginRegisterHeight, this._config.loginRegisterAutoHeight)
}

setTimeout(() => {
$('body.hold-transition').removeClass('hold-transition')
}, 50)
$(SELECTOR_SIDEBAR)
.on('collapsed.lte.treeview expanded.lte.treeview', () => {
this.fixLayoutHeight()
})

$(SELECTOR_MAIN_SIDEBAR)
.on('mouseenter mouseleave', () => {
if ($('body').hasClass(CLASS_NAME_SIDEBAR_COLLAPSED)) {
this.fixLayoutHeight()
}
})

$(SELECTOR_PUSHMENU_BTN)
.on('collapsed.lte.pushmenu shown.lte.pushmenu', () => {
setTimeout(() => {
this.fixLayoutHeight()
}, 300)
})

$(SELECTOR_CONTROL_SIDEBAR_BTN)
.on('collapsed.lte.controlsidebar', () => {
this.fixLayoutHeight()
})
.on('expanded.lte.controlsidebar', () => {
this.fixLayoutHeight('control_sidebar')
})

$(window).resize(() => {
this.fixLayoutHeight()
})

setTimeout(() => {
const $preloader = $(SELECTOR_PRELOADER)
if ($preloader) {
$preloader.css('height', 0)
setTimeout(() => {
$preloader.children().hide()
}, 200)
}
}, this._config.preloadDuration)
}

_max(numbers) {
// Calculate the maximum number in a list
let max = 0

Object.keys(numbers).forEach(key => {
if (numbers[key] > max) {
max = numbers[key]
}
})
$('body.hold-transition').removeClass('hold-transition')
}, 50)

return max
}
setTimeout(() => {
const $preloader = $(SELECTOR_PRELOADER)
if ($preloader) {
$preloader.css('height', 0)
setTimeout(() => {
$preloader.children().hide()
}, 200)
}
}, this._config.preloadDuration)
}

_isFooterFixed() {
return $(SELECTOR_FOOTER).css('position') === 'fixed'
}
_max(numbers) {
// Calculate the maximum number in a list
let max = 0

// Static
Object.keys(numbers).forEach(key => {
if (numbers[key] > max) {
max = numbers[key]
}
})

static _jQueryInterface(config = '') {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())
return max
}

if (!data) {
data = new Layout($(this), _options)
$(this).data(DATA_KEY, data)
}
// Static

if (config === 'init' || config === '') {
data._init()
} else if (config === 'fixLayoutHeight' || config === 'fixLoginRegisterHeight') {
data[config]()
}
})
}
_isFooterFixed() {
return $(SELECTOR_FOOTER).css('position') === 'fixed'
}
}

/**
@@ -231,16 +231,16 @@ class Layout {
*/

$(window).on('load', () => {
Layout._jQueryInterface.call($('body'))
Layout._jQueryInterface.call($('body'))
})

$(`${SELECTOR_SIDEBAR} a`)
.on('focusin', () => {
$(SELECTOR_MAIN_SIDEBAR).addClass(CLASS_NAME_SIDEBAR_FOCUSED)
})
.on('focusout', () => {
$(SELECTOR_MAIN_SIDEBAR).removeClass(CLASS_NAME_SIDEBAR_FOCUSED)
})
.on('focusin', () => {
$(SELECTOR_MAIN_SIDEBAR).addClass(CLASS_NAME_SIDEBAR_FOCUSED)
})
.on('focusout', () => {
$(SELECTOR_MAIN_SIDEBAR).removeClass(CLASS_NAME_SIDEBAR_FOCUSED)
})

/**
* jQuery API
@@ -250,8 +250,8 @@ $(`${SELECTOR_SIDEBAR} a`)
$.fn[NAME] = Layout._jQueryInterface
$.fn[NAME].Constructor = Layout
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Layout._jQueryInterface
$.fn[NAME] = JQUERY_NO_CONFLICT
return Layout._jQueryInterface
}

export default Layout

+ 46
- 46
SecureSharing/wwwroot/build/js/NavbarSearch.js View File

@@ -23,8 +23,8 @@ const SELECTOR_SEARCH_INPUT = '.form-control'
const CLASS_NAME_OPEN = 'navbar-search-open'

const Default = {
resetOnClose: true,
target: SELECTOR_SEARCH_BLOCK
resetOnClose: true,
target: SELECTOR_SEARCH_BLOCK
}

/**
@@ -33,53 +33,53 @@ const Default = {
*/

class NavbarSearch {
constructor(_element, _options) {
this._element = _element
this._config = $.extend({}, Default, _options)
}
constructor(_element, _options) {
this._element = _element
this._config = $.extend({}, Default, _options)
}

// Public
// Public

open() {
$(this._config.target).css('display', 'flex').hide().fadeIn().addClass(CLASS_NAME_OPEN)
$(`${this._config.target} ${SELECTOR_SEARCH_INPUT}`).focus()
}
static _jQueryInterface(options) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())

close() {
$(this._config.target).fadeOut().removeClass(CLASS_NAME_OPEN)
if (!data) {
data = new NavbarSearch(this, _options)
$(this).data(DATA_KEY, data)
}

if (this._config.resetOnClose) {
$(`${this._config.target} ${SELECTOR_SEARCH_INPUT}`).val('')
}
}
if (!/toggle|close|open/.test(options)) {
throw new Error(`Undefined method ${options}`)
}

toggle() {
if ($(this._config.target).hasClass(CLASS_NAME_OPEN)) {
this.close()
} else {
this.open()
data[options]()
})
}
}

// Static
open() {
$(this._config.target).css('display', 'flex').hide().fadeIn().addClass(CLASS_NAME_OPEN)
$(`${this._config.target} ${SELECTOR_SEARCH_INPUT}`).focus()
}

static _jQueryInterface(options) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())
close() {
$(this._config.target).fadeOut().removeClass(CLASS_NAME_OPEN)

if (!data) {
data = new NavbarSearch(this, _options)
$(this).data(DATA_KEY, data)
}
if (this._config.resetOnClose) {
$(`${this._config.target} ${SELECTOR_SEARCH_INPUT}`).val('')
}
}

if (!/toggle|close|open/.test(options)) {
throw new Error(`Undefined method ${options}`)
}
// Static

data[options]()
})
}
toggle() {
if ($(this._config.target).hasClass(CLASS_NAME_OPEN)) {
this.close()
} else {
this.open()
}
}
}

/**
@@ -87,15 +87,15 @@ class NavbarSearch {
* ====================================================
*/
$(document).on('click', SELECTOR_TOGGLE_BUTTON, event => {
event.preventDefault()
event.preventDefault()

let button = $(event.currentTarget)
let button = $(event.currentTarget)

if (button.data('widget') !== 'navbar-search') {
button = button.closest(SELECTOR_TOGGLE_BUTTON)
}
if (button.data('widget') !== 'navbar-search') {
button = button.closest(SELECTOR_TOGGLE_BUTTON)
}

NavbarSearch._jQueryInterface.call(button, 'toggle')
NavbarSearch._jQueryInterface.call(button, 'toggle')
})

/**
@@ -106,8 +106,8 @@ $(document).on('click', SELECTOR_TOGGLE_BUTTON, event => {
$.fn[NAME] = NavbarSearch._jQueryInterface
$.fn[NAME].Constructor = NavbarSearch
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return NavbarSearch._jQueryInterface
$.fn[NAME] = JQUERY_NO_CONFLICT
return NavbarSearch._jQueryInterface
}

export default NavbarSearch

+ 123
- 123
SecureSharing/wwwroot/build/js/PushMenu.js View File

@@ -31,9 +31,9 @@ const CLASS_NAME_IS_OPENING = 'sidebar-is-opening'
const CLASS_NAME_CLOSED = 'sidebar-closed'

const Default = {
autoCollapseSize: 992,
enableRemember: false,
noTransitionAfterReload: true
autoCollapseSize: 992,
enableRemember: false,
noTransitionAfterReload: true
}

/**
@@ -42,149 +42,149 @@ const Default = {
*/

class PushMenu {
constructor(element, options) {
this._element = element
this._options = $.extend({}, Default, options)
constructor(element, options) {
this._element = element
this._options = $.extend({}, Default, options)

if ($(SELECTOR_OVERLAY).length === 0) {
this._addOverlay()
if ($(SELECTOR_OVERLAY).length === 0) {
this._addOverlay()
}

this._init()
}

this._init()
}
// Public

// Public
static _jQueryInterface(operation) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())

expand() {
const $bodySelector = $(SELECTOR_BODY)
if (!data) {
data = new PushMenu(this, _options)
$(this).data(DATA_KEY, data)
}

if (this._options.autoCollapseSize && $(window).width() <= this._options.autoCollapseSize) {
$bodySelector.addClass(CLASS_NAME_OPEN)
if (typeof operation === 'string' && /collapse|expand|toggle/.test(operation)) {
data[operation]()
}
})
}

$bodySelector.addClass(CLASS_NAME_IS_OPENING).removeClass(`${CLASS_NAME_COLLAPSED} ${CLASS_NAME_CLOSED}`).delay(50).queue(function () {
$bodySelector.removeClass(CLASS_NAME_IS_OPENING)
$(this).dequeue()
})
expand() {
const $bodySelector = $(SELECTOR_BODY)

if (this._options.enableRemember) {
localStorage.setItem(`remember${EVENT_KEY}`, CLASS_NAME_OPEN)
}
if (this._options.autoCollapseSize && $(window).width() <= this._options.autoCollapseSize) {
$bodySelector.addClass(CLASS_NAME_OPEN)
}

$(this._element).trigger($.Event(EVENT_SHOWN))
}
$bodySelector.addClass(CLASS_NAME_IS_OPENING).removeClass(`${CLASS_NAME_COLLAPSED} ${CLASS_NAME_CLOSED}`).delay(50).queue(function () {
$bodySelector.removeClass(CLASS_NAME_IS_OPENING)
$(this).dequeue()
})

collapse() {
const $bodySelector = $(SELECTOR_BODY)
if (this._options.enableRemember) {
localStorage.setItem(`remember${EVENT_KEY}`, CLASS_NAME_OPEN)
}

if (this._options.autoCollapseSize && $(window).width() <= this._options.autoCollapseSize) {
$bodySelector.removeClass(CLASS_NAME_OPEN).addClass(CLASS_NAME_CLOSED)
$(this._element).trigger($.Event(EVENT_SHOWN))
}

$bodySelector.addClass(CLASS_NAME_COLLAPSED)
collapse() {
const $bodySelector = $(SELECTOR_BODY)

if (this._options.enableRemember) {
localStorage.setItem(`remember${EVENT_KEY}`, CLASS_NAME_COLLAPSED)
}
if (this._options.autoCollapseSize && $(window).width() <= this._options.autoCollapseSize) {
$bodySelector.removeClass(CLASS_NAME_OPEN).addClass(CLASS_NAME_CLOSED)
}

$bodySelector.addClass(CLASS_NAME_COLLAPSED)

$(this._element).trigger($.Event(EVENT_COLLAPSED))
}
if (this._options.enableRemember) {
localStorage.setItem(`remember${EVENT_KEY}`, CLASS_NAME_COLLAPSED)
}

toggle() {
if ($(SELECTOR_BODY).hasClass(CLASS_NAME_COLLAPSED)) {
this.expand()
} else {
this.collapse()
$(this._element).trigger($.Event(EVENT_COLLAPSED))
}
}

autoCollapse(resize = false) {
if (!this._options.autoCollapseSize) {
return
toggle() {
if ($(SELECTOR_BODY).hasClass(CLASS_NAME_COLLAPSED)) {
this.expand()
} else {
this.collapse()
}
}

const $bodySelector = $(SELECTOR_BODY)

if ($(window).width() <= this._options.autoCollapseSize) {
if (!$bodySelector.hasClass(CLASS_NAME_OPEN)) {
this.collapse()
}
} else if (resize === true) {
if ($bodySelector.hasClass(CLASS_NAME_OPEN)) {
$bodySelector.removeClass(CLASS_NAME_OPEN)
} else if ($bodySelector.hasClass(CLASS_NAME_CLOSED)) {
this.expand()
}
autoCollapse(resize = false) {
if (!this._options.autoCollapseSize) {
return
}

const $bodySelector = $(SELECTOR_BODY)

if ($(window).width() <= this._options.autoCollapseSize) {
if (!$bodySelector.hasClass(CLASS_NAME_OPEN)) {
this.collapse()
}
} else if (resize === true) {
if ($bodySelector.hasClass(CLASS_NAME_OPEN)) {
$bodySelector.removeClass(CLASS_NAME_OPEN)
} else if ($bodySelector.hasClass(CLASS_NAME_CLOSED)) {
this.expand()
}
}
}
}

remember() {
if (!this._options.enableRemember) {
return
// Private

remember() {
if (!this._options.enableRemember) {
return
}

const $body = $('body')
const toggleState = localStorage.getItem(`remember${EVENT_KEY}`)

if (toggleState === CLASS_NAME_COLLAPSED) {
if (this._options.noTransitionAfterReload) {
$body.addClass('hold-transition').addClass(CLASS_NAME_COLLAPSED).delay(50).queue(function () {
$(this).removeClass('hold-transition')
$(this).dequeue()
})
} else {
$body.addClass(CLASS_NAME_COLLAPSED)
}
} else if (this._options.noTransitionAfterReload) {
$body.addClass('hold-transition').removeClass(CLASS_NAME_COLLAPSED).delay(50).queue(function () {
$(this).removeClass('hold-transition')
$(this).dequeue()
})
} else {
$body.removeClass(CLASS_NAME_COLLAPSED)
}
}

const $body = $('body')
const toggleState = localStorage.getItem(`remember${EVENT_KEY}`)
_init() {
this.remember()
this.autoCollapse()

if (toggleState === CLASS_NAME_COLLAPSED) {
if (this._options.noTransitionAfterReload) {
$body.addClass('hold-transition').addClass(CLASS_NAME_COLLAPSED).delay(50).queue(function () {
$(this).removeClass('hold-transition')
$(this).dequeue()
$(window).resize(() => {
this.autoCollapse(true)
})
} else {
$body.addClass(CLASS_NAME_COLLAPSED)
}
} else if (this._options.noTransitionAfterReload) {
$body.addClass('hold-transition').removeClass(CLASS_NAME_COLLAPSED).delay(50).queue(function () {
$(this).removeClass('hold-transition')
$(this).dequeue()
})
} else {
$body.removeClass(CLASS_NAME_COLLAPSED)
}
}

// Private

_init() {
this.remember()
this.autoCollapse()

$(window).resize(() => {
this.autoCollapse(true)
})
}
// Static

_addOverlay() {
const overlay = $('<div />', {
id: 'sidebar-overlay'
})

overlay.on('click', () => {
this.collapse()
})

$(SELECTOR_WRAPPER).append(overlay)
}

// Static

static _jQueryInterface(operation) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())
_addOverlay() {
const overlay = $('<div />', {
id: 'sidebar-overlay'
})

if (!data) {
data = new PushMenu(this, _options)
$(this).data(DATA_KEY, data)
}
overlay.on('click', () => {
this.collapse()
})

if (typeof operation === 'string' && /collapse|expand|toggle/.test(operation)) {
data[operation]()
}
})
}
$(SELECTOR_WRAPPER).append(overlay)
}
}

/**
@@ -193,19 +193,19 @@ class PushMenu {
*/

$(document).on('click', SELECTOR_TOGGLE_BUTTON, event => {
event.preventDefault()
event.preventDefault()

let button = event.currentTarget
let button = event.currentTarget

if ($(button).data('widget') !== 'pushmenu') {
button = $(button).closest(SELECTOR_TOGGLE_BUTTON)
}
if ($(button).data('widget') !== 'pushmenu') {
button = $(button).closest(SELECTOR_TOGGLE_BUTTON)
}

PushMenu._jQueryInterface.call($(button), 'toggle')
PushMenu._jQueryInterface.call($(button), 'toggle')
})

$(window).on('load', () => {
PushMenu._jQueryInterface.call($(SELECTOR_TOGGLE_BUTTON))
PushMenu._jQueryInterface.call($(SELECTOR_TOGGLE_BUTTON))
})

/**
@@ -216,8 +216,8 @@ $(window).on('load', () => {
$.fn[NAME] = PushMenu._jQueryInterface
$.fn[NAME].Constructor = PushMenu
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return PushMenu._jQueryInterface
$.fn[NAME] = JQUERY_NO_CONFLICT
return PushMenu._jQueryInterface
}

export default PushMenu

+ 187
- 187
SecureSharing/wwwroot/build/js/SidebarSearch.js View File

@@ -5,7 +5,7 @@
* --------------------------------------------
*/

import $, { trim } from 'jquery'
import $, {trim} from 'jquery'

/**
* Constants
@@ -35,13 +35,13 @@ const SELECTOR_SEARCH_RESULTS = `.${CLASS_NAME_SEARCH_RESULTS}`
const SELECTOR_SEARCH_RESULTS_GROUP = `${SELECTOR_SEARCH_RESULTS} .${CLASS_NAME_LIST_GROUP}`

const Default = {
arrowSign: '->',
minLength: 3,
maxResults: 7,
highlightName: true,
highlightPath: false,
highlightClass: 'text-light',
notFoundText: 'No element found!'
arrowSign: '->',
minLength: 3,
maxResults: 7,
highlightName: true,
highlightPath: false,
highlightClass: 'text-light',
notFoundText: 'No element found!'
}

const SearchItems = []
@@ -52,179 +52,179 @@ const SearchItems = []
*/

class SidebarSearch {
constructor(_element, _options) {
this.element = _element
this.options = $.extend({}, Default, _options)
this.items = []
}

// Public

init() {
if ($(SELECTOR_DATA_WIDGET).length === 0) {
return
constructor(_element, _options) {
this.element = _element
this.options = $.extend({}, Default, _options)
this.items = []
}

if ($(SELECTOR_DATA_WIDGET).next(SELECTOR_SEARCH_RESULTS).length === 0) {
$(SELECTOR_DATA_WIDGET).after(
$('<div />', { class: CLASS_NAME_SEARCH_RESULTS })
)
}
// Public

if ($(SELECTOR_SEARCH_RESULTS).children(SELECTOR_SEARCH_LIST_GROUP).length === 0) {
$(SELECTOR_SEARCH_RESULTS).append(
$('<div />', { class: CLASS_NAME_LIST_GROUP })
)
}
static _jQueryInterface(config) {
let data = $(this).data(DATA_KEY)

this._addNotFound()
if (!data) {
data = $(this).data()
}

$(SELECTOR_SIDEBAR).children().each((i, child) => {
this._parseItem(child)
})
}
const _options = $.extend({}, Default, typeof config === 'object' ? config : data)
const plugin = new SidebarSearch($(this), _options)

search() {
const searchValue = $(SELECTOR_SEARCH_INPUT).val().toLowerCase()
if (searchValue.length < this.options.minLength) {
$(SELECTOR_SEARCH_RESULTS_GROUP).empty()
this._addNotFound()
this.close()
return
}

const searchResults = SearchItems.filter(item => (item.name).toLowerCase().includes(searchValue))
const endResults = $(searchResults.slice(0, this.options.maxResults))
$(SELECTOR_SEARCH_RESULTS_GROUP).empty()
$(this).data(DATA_KEY, typeof config === 'object' ? config : data)

if (endResults.length === 0) {
this._addNotFound()
} else {
endResults.each((i, result) => {
$(SELECTOR_SEARCH_RESULTS_GROUP).append(this._renderItem(escape(result.name), escape(result.link), result.path))
})
if (typeof config === 'string' && /init|toggle|close|open|search/.test(config)) {
plugin[config]()
} else {
plugin.init()
}
}

this.open()
}
init() {
if ($(SELECTOR_DATA_WIDGET).length === 0) {
return
}

open() {
$(SELECTOR_DATA_WIDGET).parent().addClass(CLASS_NAME_OPEN)
$(SELECTOR_SEARCH_ICON).removeClass(CLASS_NAME_ICON_SEARCH).addClass(CLASS_NAME_ICON_CLOSE)
}
if ($(SELECTOR_DATA_WIDGET).next(SELECTOR_SEARCH_RESULTS).length === 0) {
$(SELECTOR_DATA_WIDGET).after(
$('<div />', {class: CLASS_NAME_SEARCH_RESULTS})
)
}

close() {
$(SELECTOR_DATA_WIDGET).parent().removeClass(CLASS_NAME_OPEN)
$(SELECTOR_SEARCH_ICON).removeClass(CLASS_NAME_ICON_CLOSE).addClass(CLASS_NAME_ICON_SEARCH)
}
if ($(SELECTOR_SEARCH_RESULTS).children(SELECTOR_SEARCH_LIST_GROUP).length === 0) {
$(SELECTOR_SEARCH_RESULTS).append(
$('<div />', {class: CLASS_NAME_LIST_GROUP})
)
}

toggle() {
if ($(SELECTOR_DATA_WIDGET).parent().hasClass(CLASS_NAME_OPEN)) {
this.close()
} else {
this.open()
}
}
this._addNotFound()

// Private

_parseItem(item, path = []) {
if ($(item).hasClass(CLASS_NAME_HEADER)) {
return
$(SELECTOR_SIDEBAR).children().each((i, child) => {
this._parseItem(child)
})
}

const itemObject = {}
const navLink = $(item).clone().find(`> ${SELECTOR_NAV_LINK}`)
const navTreeview = $(item).clone().find(`> ${SELECTOR_NAV_TREEVIEW}`)

const link = navLink.attr('href')
const name = navLink.find('p').children().remove().end().text()

itemObject.name = this._trimText(name)
itemObject.link = link
itemObject.path = path

if (navTreeview.length === 0) {
SearchItems.push(itemObject)
} else {
const newPath = itemObject.path.concat([itemObject.name])
navTreeview.children().each((i, child) => {
this._parseItem(child, newPath)
})
}
}

_trimText(text) {
return trim(text.replace(/(\r\n|\n|\r)/gm, ' '))
}

_renderItem(name, link, path) {
path = path.join(` ${this.options.arrowSign} `)
name = unescape(name)

if (this.options.highlightName || this.options.highlightPath) {
const searchValue = $(SELECTOR_SEARCH_INPUT).val().toLowerCase()
const regExp = new RegExp(searchValue, 'gi')

if (this.options.highlightName) {
name = name.replace(
regExp,
str => {
return `<strong class="${this.options.highlightClass}">${str}</strong>`
}
)
}

if (this.options.highlightPath) {
path = path.replace(
regExp,
str => {
return `<strong class="${this.options.highlightClass}">${str}</strong>`
}
)
}
search() {
const searchValue = $(SELECTOR_SEARCH_INPUT).val().toLowerCase()
if (searchValue.length < this.options.minLength) {
$(SELECTOR_SEARCH_RESULTS_GROUP).empty()
this._addNotFound()
this.close()
return
}

const searchResults = SearchItems.filter(item => (item.name).toLowerCase().includes(searchValue))
const endResults = $(searchResults.slice(0, this.options.maxResults))
$(SELECTOR_SEARCH_RESULTS_GROUP).empty()

if (endResults.length === 0) {
this._addNotFound()
} else {
endResults.each((i, result) => {
$(SELECTOR_SEARCH_RESULTS_GROUP).append(this._renderItem(escape(result.name), escape(result.link), result.path))
})
}

this.open()
}

const groupItemElement = $('<a/>', {
href: link,
class: 'list-group-item'
})
const searchTitleElement = $('<div/>', {
class: 'search-title'
}).html(name)
const searchPathElement = $('<div/>', {
class: 'search-path'
}).html(path)

groupItemElement.append(searchTitleElement).append(searchPathElement)
open() {
$(SELECTOR_DATA_WIDGET).parent().addClass(CLASS_NAME_OPEN)
$(SELECTOR_SEARCH_ICON).removeClass(CLASS_NAME_ICON_SEARCH).addClass(CLASS_NAME_ICON_CLOSE)
}

return groupItemElement
}
close() {
$(SELECTOR_DATA_WIDGET).parent().removeClass(CLASS_NAME_OPEN)
$(SELECTOR_SEARCH_ICON).removeClass(CLASS_NAME_ICON_CLOSE).addClass(CLASS_NAME_ICON_SEARCH)
}

_addNotFound() {
$(SELECTOR_SEARCH_RESULTS_GROUP).append(this._renderItem(this.options.notFoundText, '#', []))
}
// Private

// Static
toggle() {
if ($(SELECTOR_DATA_WIDGET).parent().hasClass(CLASS_NAME_OPEN)) {
this.close()
} else {
this.open()
}
}

static _jQueryInterface(config) {
let data = $(this).data(DATA_KEY)
_parseItem(item, path = []) {
if ($(item).hasClass(CLASS_NAME_HEADER)) {
return
}

const itemObject = {}
const navLink = $(item).clone().find(`> ${SELECTOR_NAV_LINK}`)
const navTreeview = $(item).clone().find(`> ${SELECTOR_NAV_TREEVIEW}`)

const link = navLink.attr('href')
const name = navLink.find('p').children().remove().end().text()

itemObject.name = this._trimText(name)
itemObject.link = link
itemObject.path = path

if (navTreeview.length === 0) {
SearchItems.push(itemObject)
} else {
const newPath = itemObject.path.concat([itemObject.name])
navTreeview.children().each((i, child) => {
this._parseItem(child, newPath)
})
}
}

if (!data) {
data = $(this).data()
_trimText(text) {
return trim(text.replace(/(\r\n|\n|\r)/gm, ' '))
}

const _options = $.extend({}, Default, typeof config === 'object' ? config : data)
const plugin = new SidebarSearch($(this), _options)
_renderItem(name, link, path) {
path = path.join(` ${this.options.arrowSign} `)
name = unescape(name)

if (this.options.highlightName || this.options.highlightPath) {
const searchValue = $(SELECTOR_SEARCH_INPUT).val().toLowerCase()
const regExp = new RegExp(searchValue, 'gi')

if (this.options.highlightName) {
name = name.replace(
regExp,
str => {
return `<strong class="${this.options.highlightClass}">${str}</strong>`
}
)
}

if (this.options.highlightPath) {
path = path.replace(
regExp,
str => {
return `<strong class="${this.options.highlightClass}">${str}</strong>`
}
)
}
}

const groupItemElement = $('<a/>', {
href: link,
class: 'list-group-item'
})
const searchTitleElement = $('<div/>', {
class: 'search-title'
}).html(name)
const searchPathElement = $('<div/>', {
class: 'search-path'
}).html(path)

groupItemElement.append(searchTitleElement).append(searchPathElement)

return groupItemElement
}

$(this).data(DATA_KEY, typeof config === 'object' ? config : data)
// Static

if (typeof config === 'string' && /init|toggle|close|open|search/.test(config)) {
plugin[config]()
} else {
plugin.init()
_addNotFound() {
$(SELECTOR_SEARCH_RESULTS_GROUP).append(this._renderItem(this.options.notFoundText, '#', []))
}
}
}

/**
@@ -232,55 +232,55 @@ class SidebarSearch {
* ====================================================
*/
$(document).on('click', SELECTOR_SEARCH_BUTTON, event => {
event.preventDefault()
event.preventDefault()

SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'toggle')
SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'toggle')
})

$(document).on('keyup', SELECTOR_SEARCH_INPUT, event => {
if (event.keyCode == 38) {
event.preventDefault()
$(SELECTOR_SEARCH_RESULTS_GROUP).children().last().focus()
return
}
if (event.keyCode == 38) {
event.preventDefault()
$(SELECTOR_SEARCH_RESULTS_GROUP).children().last().focus()
return
}

if (event.keyCode == 40) {
event.preventDefault()
$(SELECTOR_SEARCH_RESULTS_GROUP).children().first().focus()
return
}
if (event.keyCode == 40) {
event.preventDefault()
$(SELECTOR_SEARCH_RESULTS_GROUP).children().first().focus()
return
}

setTimeout(() => {
SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'search')
}, 100)
setTimeout(() => {
SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'search')
}, 100)
})

$(document).on('keydown', SELECTOR_SEARCH_RESULTS_GROUP, event => {
const $focused = $(':focus')
const $focused = $(':focus')

if (event.keyCode == 38) {
event.preventDefault()
if (event.keyCode == 38) {
event.preventDefault()

if ($focused.is(':first-child')) {
$focused.siblings().last().focus()
} else {
$focused.prev().focus()
if ($focused.is(':first-child')) {
$focused.siblings().last().focus()
} else {
$focused.prev().focus()
}
}
}

if (event.keyCode == 40) {
event.preventDefault()
if (event.keyCode == 40) {
event.preventDefault()

if ($focused.is(':last-child')) {
$focused.siblings().first().focus()
} else {
$focused.next().focus()
if ($focused.is(':last-child')) {
$focused.siblings().first().focus()
} else {
$focused.next().focus()
}
}
}
})

$(window).on('load', () => {
SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'init')
SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'init')
})

/**
@@ -291,8 +291,8 @@ $(window).on('load', () => {
$.fn[NAME] = SidebarSearch._jQueryInterface
$.fn[NAME].Constructor = SidebarSearch
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return SidebarSearch._jQueryInterface
$.fn[NAME] = JQUERY_NO_CONFLICT
return SidebarSearch._jQueryInterface
}

export default SidebarSearch

+ 118
- 118
SecureSharing/wwwroot/build/js/Toasts.js View File

@@ -37,21 +37,21 @@ const POSITION_BOTTOM_RIGHT = 'bottomRight'
const POSITION_BOTTOM_LEFT = 'bottomLeft'

const Default = {
position: POSITION_TOP_RIGHT,
fixed: true,
autohide: false,
autoremove: true,
delay: 1000,
fade: true,
icon: null,
image: null,
imageAlt: null,
imageHeight: '25px',
title: null,
subtitle: null,
close: true,
body: null,
class: null
position: POSITION_TOP_RIGHT,
fixed: true,
autohide: false,
autoremove: true,
delay: 1000,
fade: true,
icon: null,
image: null,
imageAlt: null,
imageHeight: '25px',
title: null,
subtitle: null,
close: true,
body: null,
class: null
}

/**
@@ -59,139 +59,139 @@ const Default = {
* ====================================================
*/
class Toasts {
constructor(element, config) {
this._config = config
this._prepareContainer()
constructor(element, config) {
this._config = config
this._prepareContainer()

$('body').trigger($.Event(EVENT_INIT))
}

// Public
$('body').trigger($.Event(EVENT_INIT))
}

create() {
const toast = $('<div class="toast" role="alert" aria-live="assertive" aria-atomic="true"/>')
// Public

toast.data('autohide', this._config.autohide)
toast.data('animation', this._config.fade)
static _jQueryInterface(option, config) {
return this.each(function () {
const _options = $.extend({}, Default, config)
const toast = new Toasts($(this), _options)

if (this._config.class) {
toast.addClass(this._config.class)
if (option === 'create') {
toast[option]()
}
})
}

if (this._config.delay && this._config.delay != 500) {
toast.data('delay', this._config.delay)
}
// Static

const toastHeader = $('<div class="toast-header">')
create() {
const toast = $('<div class="toast" role="alert" aria-live="assertive" aria-atomic="true"/>')

if (this._config.image != null) {
const toastImage = $('<img />').addClass('rounded mr-2').attr('src', this._config.image).attr('alt', this._config.imageAlt)
toast.data('autohide', this._config.autohide)
toast.data('animation', this._config.fade)

if (this._config.imageHeight != null) {
toastImage.height(this._config.imageHeight).width('auto')
}
if (this._config.class) {
toast.addClass(this._config.class)
}

toastHeader.append(toastImage)
}
if (this._config.delay && this._config.delay != 500) {
toast.data('delay', this._config.delay)
}

if (this._config.icon != null) {
toastHeader.append($('<i />').addClass('mr-2').addClass(this._config.icon))
}
const toastHeader = $('<div class="toast-header">')

if (this._config.title != null) {
toastHeader.append($('<strong />').addClass('mr-auto').html(this._config.title))
}
if (this._config.image != null) {
const toastImage = $('<img />').addClass('rounded mr-2').attr('src', this._config.image).attr('alt', this._config.imageAlt)

if (this._config.subtitle != null) {
toastHeader.append($('<small />').html(this._config.subtitle))
}
if (this._config.imageHeight != null) {
toastImage.height(this._config.imageHeight).width('auto')
}

if (this._config.close == true) {
const toastClose = $('<button data-dismiss="toast" />').attr('type', 'button').addClass('ml-2 mb-1 close').attr('aria-label', 'Close').append('<span aria-hidden="true">&times;</span>')
toastHeader.append(toastImage)
}

if (this._config.title == null) {
toastClose.toggleClass('ml-2 ml-auto')
}
if (this._config.icon != null) {
toastHeader.append($('<i />').addClass('mr-2').addClass(this._config.icon))
}

toastHeader.append(toastClose)
}
if (this._config.title != null) {
toastHeader.append($('<strong />').addClass('mr-auto').html(this._config.title))
}

toast.append(toastHeader)
if (this._config.subtitle != null) {
toastHeader.append($('<small />').html(this._config.subtitle))
}

if (this._config.body != null) {
toast.append($('<div class="toast-body" />').html(this._config.body))
}
if (this._config.close == true) {
const toastClose = $('<button data-dismiss="toast" />').attr('type', 'button').addClass('ml-2 mb-1 close').attr('aria-label', 'Close').append('<span aria-hidden="true">&times;</span>')

$(this._getContainerId()).prepend(toast)
if (this._config.title == null) {
toastClose.toggleClass('ml-2 ml-auto')
}

const $body = $('body')
toastHeader.append(toastClose)
}

$body.trigger($.Event(EVENT_CREATED))
toast.toast('show')
toast.append(toastHeader)

if (this._config.autoremove) {
toast.on('hidden.bs.toast', function () {
$(this).delay(200).remove()
$body.trigger($.Event(EVENT_REMOVED))
})
}
}
if (this._config.body != null) {
toast.append($('<div class="toast-body" />').html(this._config.body))
}

// Static
$(this._getContainerId()).prepend(toast)

_getContainerId() {
if (this._config.position == POSITION_TOP_RIGHT) {
return SELECTOR_CONTAINER_TOP_RIGHT
}
const $body = $('body')

if (this._config.position == POSITION_TOP_LEFT) {
return SELECTOR_CONTAINER_TOP_LEFT
}
$body.trigger($.Event(EVENT_CREATED))
toast.toast('show')

if (this._config.position == POSITION_BOTTOM_RIGHT) {
return SELECTOR_CONTAINER_BOTTOM_RIGHT
if (this._config.autoremove) {
toast.on('hidden.bs.toast', function () {
$(this).delay(200).remove()
$body.trigger($.Event(EVENT_REMOVED))
})
}
}

if (this._config.position == POSITION_BOTTOM_LEFT) {
return SELECTOR_CONTAINER_BOTTOM_LEFT
}
}

_prepareContainer() {
if ($(this._getContainerId()).length === 0) {
const container = $('<div />').attr('id', this._getContainerId().replace('#', ''))
if (this._config.position == POSITION_TOP_RIGHT) {
container.addClass(CLASS_NAME_TOP_RIGHT)
} else if (this._config.position == POSITION_TOP_LEFT) {
container.addClass(CLASS_NAME_TOP_LEFT)
} else if (this._config.position == POSITION_BOTTOM_RIGHT) {
container.addClass(CLASS_NAME_BOTTOM_RIGHT)
} else if (this._config.position == POSITION_BOTTOM_LEFT) {
container.addClass(CLASS_NAME_BOTTOM_LEFT)
}

$('body').append(container)
}
_getContainerId() {
if (this._config.position == POSITION_TOP_RIGHT) {
return SELECTOR_CONTAINER_TOP_RIGHT
}

if (this._config.fixed) {
$(this._getContainerId()).addClass('fixed')
} else {
$(this._getContainerId()).removeClass('fixed')
}
}
if (this._config.position == POSITION_TOP_LEFT) {
return SELECTOR_CONTAINER_TOP_LEFT
}

// Static
if (this._config.position == POSITION_BOTTOM_RIGHT) {
return SELECTOR_CONTAINER_BOTTOM_RIGHT
}

static _jQueryInterface(option, config) {
return this.each(function () {
const _options = $.extend({}, Default, config)
const toast = new Toasts($(this), _options)
if (this._config.position == POSITION_BOTTOM_LEFT) {
return SELECTOR_CONTAINER_BOTTOM_LEFT
}
}

if (option === 'create') {
toast[option]()
}
})
}
// Static

_prepareContainer() {
if ($(this._getContainerId()).length === 0) {
const container = $('<div />').attr('id', this._getContainerId().replace('#', ''))
if (this._config.position == POSITION_TOP_RIGHT) {
container.addClass(CLASS_NAME_TOP_RIGHT)
} else if (this._config.position == POSITION_TOP_LEFT) {
container.addClass(CLASS_NAME_TOP_LEFT)
} else if (this._config.position == POSITION_BOTTOM_RIGHT) {
container.addClass(CLASS_NAME_BOTTOM_RIGHT)
} else if (this._config.position == POSITION_BOTTOM_LEFT) {
container.addClass(CLASS_NAME_BOTTOM_LEFT)
}

$('body').append(container)
}

if (this._config.fixed) {
$(this._getContainerId()).addClass('fixed')
} else {
$(this._getContainerId()).removeClass('fixed')
}
}
}

/**
@@ -202,8 +202,8 @@ class Toasts {
$.fn[NAME] = Toasts._jQueryInterface
$.fn[NAME].Constructor = Toasts
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Toasts._jQueryInterface
$.fn[NAME] = JQUERY_NO_CONFLICT
return Toasts._jQueryInterface
}

export default Toasts

+ 52
- 52
SecureSharing/wwwroot/build/js/TodoList.js View File

@@ -20,12 +20,12 @@ const SELECTOR_DATA_TOGGLE = '[data-widget="todo-list"]'
const CLASS_NAME_TODO_LIST_DONE = 'done'

const Default = {
onCheck(item) {
return item
},
onUnCheck(item) {
return item
}
onCheck(item) {
return item
},
onUnCheck(item) {
return item
}
}

/**
@@ -34,64 +34,64 @@ const Default = {
*/

class TodoList {
constructor(element, config) {
this._config = config
this._element = element
constructor(element, config) {
this._config = config
this._element = element

this._init()
}
this._init()
}

// Public
// Public

toggle(item) {
item.parents('li').toggleClass(CLASS_NAME_TODO_LIST_DONE)
if (!$(item).prop('checked')) {
this.unCheck($(item))
return
}
static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)

this.check(item)
}
if (!data) {
data = $(this).data()
}

check(item) {
this._config.onCheck.call(item)
}
const _options = $.extend({}, Default, typeof config === 'object' ? config : data)
const plugin = new TodoList($(this), _options)

unCheck(item) {
this._config.onUnCheck.call(item)
}
$(this).data(DATA_KEY, typeof config === 'object' ? config : data)

// Private
if (config === 'init') {
plugin[config]()
}
})
}

_init() {
const $toggleSelector = this._element
toggle(item) {
item.parents('li').toggleClass(CLASS_NAME_TODO_LIST_DONE)
if (!$(item).prop('checked')) {
this.unCheck($(item))
return
}

$toggleSelector.find('input:checkbox:checked').parents('li').toggleClass(CLASS_NAME_TODO_LIST_DONE)
$toggleSelector.on('change', 'input:checkbox', event => {
this.toggle($(event.target))
})
}
this.check(item)
}

// Static
check(item) {
this._config.onCheck.call(item)
}

static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
// Private

if (!data) {
data = $(this).data()
}
unCheck(item) {
this._config.onUnCheck.call(item)
}

const _options = $.extend({}, Default, typeof config === 'object' ? config : data)
const plugin = new TodoList($(this), _options)
// Static

$(this).data(DATA_KEY, typeof config === 'object' ? config : data)
_init() {
const $toggleSelector = this._element

if (config === 'init') {
plugin[config]()
}
})
}
$toggleSelector.find('input:checkbox:checked').parents('li').toggleClass(CLASS_NAME_TODO_LIST_DONE)
$toggleSelector.on('change', 'input:checkbox', event => {
this.toggle($(event.target))
})
}
}

/**
@@ -100,7 +100,7 @@ class TodoList {
*/

$(window).on('load', () => {
TodoList._jQueryInterface.call($(SELECTOR_DATA_TOGGLE))
TodoList._jQueryInterface.call($(SELECTOR_DATA_TOGGLE))
})

/**
@@ -111,8 +111,8 @@ $(window).on('load', () => {
$.fn[NAME] = TodoList._jQueryInterface
$.fn[NAME].Constructor = TodoList
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return TodoList._jQueryInterface
$.fn[NAME] = JQUERY_NO_CONFLICT
return TodoList._jQueryInterface
}

export default TodoList

+ 89
- 89
SecureSharing/wwwroot/build/js/Treeview.js View File

@@ -32,11 +32,11 @@ const CLASS_NAME_IS_OPENING = 'menu-is-opening'
const CLASS_NAME_SIDEBAR_COLLAPSED = 'sidebar-collapse'

const Default = {
trigger: `${SELECTOR_DATA_WIDGET} ${SELECTOR_LINK}`,
animationSpeed: 300,
accordion: true,
expandSidebar: false,
sidebarButtonSelector: '[data-widget="pushmenu"]'
trigger: `${SELECTOR_DATA_WIDGET} ${SELECTOR_LINK}`,
animationSpeed: 300,
accordion: true,
expandSidebar: false,
sidebarButtonSelector: '[data-widget="pushmenu"]'
}

/**
@@ -44,109 +44,109 @@ const Default = {
* ====================================================
*/
class Treeview {
constructor(element, config) {
this._config = config
this._element = element
}
constructor(element, config) {
this._config = config
this._element = element
}

// Public
// Public

init() {
$(`${SELECTOR_LI}${SELECTOR_OPEN} ${SELECTOR_TREEVIEW_MENU}${SELECTOR_OPEN}`).css('display', 'block')
this._setupListeners()
}
static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())

expand(treeviewMenu, parentLi) {
const expandedEvent = $.Event(EVENT_EXPANDED)
if (!data) {
data = new Treeview($(this), _options)
$(this).data(DATA_KEY, data)
}

if (this._config.accordion) {
const openMenuLi = parentLi.siblings(SELECTOR_OPEN).first()
const openTreeview = openMenuLi.find(SELECTOR_TREEVIEW_MENU).first()
this.collapse(openTreeview, openMenuLi)
if (config === 'init') {
data[config]()
}
})
}

parentLi.addClass(CLASS_NAME_IS_OPENING)
treeviewMenu.stop().slideDown(this._config.animationSpeed, () => {
parentLi.addClass(CLASS_NAME_OPEN)
$(this._element).trigger(expandedEvent)
})

if (this._config.expandSidebar) {
this._expandSidebar()
init() {
$(`${SELECTOR_LI}${SELECTOR_OPEN} ${SELECTOR_TREEVIEW_MENU}${SELECTOR_OPEN}`).css('display', 'block')
this._setupListeners()
}
}

collapse(treeviewMenu, parentLi) {
const collapsedEvent = $.Event(EVENT_COLLAPSED)
expand(treeviewMenu, parentLi) {
const expandedEvent = $.Event(EVENT_EXPANDED)

parentLi.removeClass(`${CLASS_NAME_IS_OPENING} ${CLASS_NAME_OPEN}`)
treeviewMenu.stop().slideUp(this._config.animationSpeed, () => {
$(this._element).trigger(collapsedEvent)
treeviewMenu.find(`${SELECTOR_OPEN} > ${SELECTOR_TREEVIEW_MENU}`).slideUp()
treeviewMenu.find(SELECTOR_OPEN).removeClass(CLASS_NAME_OPEN)
})
}
if (this._config.accordion) {
const openMenuLi = parentLi.siblings(SELECTOR_OPEN).first()
const openTreeview = openMenuLi.find(SELECTOR_TREEVIEW_MENU).first()
this.collapse(openTreeview, openMenuLi)
}

toggle(event) {
const $relativeTarget = $(event.currentTarget)
const $parent = $relativeTarget.parent()
parentLi.addClass(CLASS_NAME_IS_OPENING)
treeviewMenu.stop().slideDown(this._config.animationSpeed, () => {
parentLi.addClass(CLASS_NAME_OPEN)
$(this._element).trigger(expandedEvent)
})

let treeviewMenu = $parent.find(`> ${SELECTOR_TREEVIEW_MENU}`)
if (this._config.expandSidebar) {
this._expandSidebar()
}
}

if (!treeviewMenu.is(SELECTOR_TREEVIEW_MENU)) {
if (!$parent.is(SELECTOR_LI)) {
treeviewMenu = $parent.parent().find(`> ${SELECTOR_TREEVIEW_MENU}`)
}
collapse(treeviewMenu, parentLi) {
const collapsedEvent = $.Event(EVENT_COLLAPSED)

if (!treeviewMenu.is(SELECTOR_TREEVIEW_MENU)) {
return
}
parentLi.removeClass(`${CLASS_NAME_IS_OPENING} ${CLASS_NAME_OPEN}`)
treeviewMenu.stop().slideUp(this._config.animationSpeed, () => {
$(this._element).trigger(collapsedEvent)
treeviewMenu.find(`${SELECTOR_OPEN} > ${SELECTOR_TREEVIEW_MENU}`).slideUp()
treeviewMenu.find(SELECTOR_OPEN).removeClass(CLASS_NAME_OPEN)
})
}

event.preventDefault()
// Private

const parentLi = $relativeTarget.parents(SELECTOR_LI).first()
const isOpen = parentLi.hasClass(CLASS_NAME_OPEN)
toggle(event) {
const $relativeTarget = $(event.currentTarget)
const $parent = $relativeTarget.parent()

if (isOpen) {
this.collapse($(treeviewMenu), parentLi)
} else {
this.expand($(treeviewMenu), parentLi)
}
}
let treeviewMenu = $parent.find(`> ${SELECTOR_TREEVIEW_MENU}`)

// Private
if (!treeviewMenu.is(SELECTOR_TREEVIEW_MENU)) {
if (!$parent.is(SELECTOR_LI)) {
treeviewMenu = $parent.parent().find(`> ${SELECTOR_TREEVIEW_MENU}`)
}

_setupListeners() {
const elementId = this._element.attr('id') !== undefined ? `#${this._element.attr('id')}` : ''
$(document).on('click', `${elementId}${this._config.trigger}`, event => {
this.toggle(event)
})
}
if (!treeviewMenu.is(SELECTOR_TREEVIEW_MENU)) {
return
}
}

_expandSidebar() {
if ($('body').hasClass(CLASS_NAME_SIDEBAR_COLLAPSED)) {
$(this._config.sidebarButtonSelector).PushMenu('expand')
}
}
event.preventDefault()

// Static
const parentLi = $relativeTarget.parents(SELECTOR_LI).first()
const isOpen = parentLi.hasClass(CLASS_NAME_OPEN)

static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())
if (isOpen) {
this.collapse($(treeviewMenu), parentLi)
} else {
this.expand($(treeviewMenu), parentLi)
}
}

if (!data) {
data = new Treeview($(this), _options)
$(this).data(DATA_KEY, data)
}
_setupListeners() {
const elementId = this._element.attr('id') !== undefined ? `#${this._element.attr('id')}` : ''
$(document).on('click', `${elementId}${this._config.trigger}`, event => {
this.toggle(event)
})
}

if (config === 'init') {
data[config]()
}
})
}
// Static

_expandSidebar() {
if ($('body').hasClass(CLASS_NAME_SIDEBAR_COLLAPSED)) {
$(this._config.sidebarButtonSelector).PushMenu('expand')
}
}
}

/**
@@ -155,9 +155,9 @@ class Treeview {
*/

$(window).on(EVENT_LOAD_DATA_API, () => {
$(SELECTOR_DATA_WIDGET).each(function () {
Treeview._jQueryInterface.call($(this), 'init')
})
$(SELECTOR_DATA_WIDGET).each(function () {
Treeview._jQueryInterface.call($(this), 'init')
})
})

/**
@@ -168,8 +168,8 @@ $(window).on(EVENT_LOAD_DATA_API, () => {
$.fn[NAME] = Treeview._jQueryInterface
$.fn[NAME].Constructor = Treeview
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Treeview._jQueryInterface
$.fn[NAME] = JQUERY_NO_CONFLICT
return Treeview._jQueryInterface
}

export default Treeview

+ 42
- 42
SecureSharing/wwwroot/build/npm/DocsPlugins.js View File

@@ -1,48 +1,48 @@
'use strict'

const Plugins = [
// AdminLTE Dist
{
from: 'dist/css/',
to: 'docs/assets/css/'
},
{
from: 'dist/js/',
to: 'docs/assets/js/'
},
// jQuery
{
from: 'node_modules/jquery/dist/',
to: 'docs/assets/plugins/jquery/'
},
// Popper
{
from: 'node_modules/popper.js/dist/',
to: 'docs/assets/plugins/popper/'
},
// Bootstrap
{
from: 'node_modules/bootstrap/dist/js/',
to: 'docs/assets/plugins/bootstrap/js/'
},
// Font Awesome
{
from: 'node_modules/@fortawesome/fontawesome-free/css/',
to: 'docs/assets/plugins/fontawesome-free/css/'
},
{
from: 'node_modules/@fortawesome/fontawesome-free/webfonts/',
to: 'docs/assets/plugins/fontawesome-free/webfonts/'
},
// overlayScrollbars
{
from: 'node_modules/overlayscrollbars/js/',
to: 'docs/assets/plugins/overlayScrollbars/js/'
},
{
from: 'node_modules/overlayscrollbars/css/',
to: 'docs/assets/plugins/overlayScrollbars/css/'
}
// AdminLTE Dist
{
from: 'dist/css/',
to: 'docs/assets/css/'
},
{
from: 'dist/js/',
to: 'docs/assets/js/'
},
// jQuery
{
from: 'node_modules/jquery/dist/',
to: 'docs/assets/plugins/jquery/'
},
// Popper
{
from: 'node_modules/popper.js/dist/',
to: 'docs/assets/plugins/popper/'
},
// Bootstrap
{
from: 'node_modules/bootstrap/dist/js/',
to: 'docs/assets/plugins/bootstrap/js/'
},
// Font Awesome
{
from: 'node_modules/@fortawesome/fontawesome-free/css/',
to: 'docs/assets/plugins/fontawesome-free/css/'
},
{
from: 'node_modules/@fortawesome/fontawesome-free/webfonts/',
to: 'docs/assets/plugins/fontawesome-free/webfonts/'
},
// overlayScrollbars
{
from: 'node_modules/overlayscrollbars/js/',
to: 'docs/assets/plugins/overlayScrollbars/js/'
},
{
from: 'node_modules/overlayscrollbars/css/',
to: 'docs/assets/plugins/overlayScrollbars/css/'
}
]

module.exports = Plugins

+ 39
- 39
SecureSharing/wwwroot/build/npm/DocsPublish.js View File

@@ -8,51 +8,51 @@ const fs = require('fs')
const Plugins = require('./DocsPlugins')

class Publish {
constructor() {
this.options = {
verbose: false
}
constructor() {
this.options = {
verbose: false
}

this.getArguments()
}

getArguments() {
if (process.argv.length > 2) {
const arg = process.argv[2]
switch (arg) {
case '-v':
case '--verbose':
this.options.verbose = true
break
default:
throw new Error(`Unknown option ${arg}`)
}
this.getArguments()
}
}

run() {
// Publish files
Plugins.forEach(module => {
try {
fse.copySync(module.from, module.to, {
// Skip copying dot files
filter(src) {
return !path.basename(src).startsWith('.')
}
})

if (this.options.verbose) {
console.log(`Copied ${module.from} to ${module.to}`)
getArguments() {
if (process.argv.length > 2) {
const arg = process.argv[2]
switch (arg) {
case '-v':
case '--verbose':
this.options.verbose = true
break
default:
throw new Error(`Unknown option ${arg}`)
}
}
} catch (error) {
console.error(`Error: ${error}`)
}
})
}

const insertText = '---\r\nlayout: page\r\ntitle: \r\n---\r\n'
run() {
// Publish files
Plugins.forEach(module => {
try {
fse.copySync(module.from, module.to, {
// Skip copying dot files
filter(src) {
return !path.basename(src).startsWith('.')
}
})

if (this.options.verbose) {
console.log(`Copied ${module.from} to ${module.to}`)
}
} catch (error) {
console.error(`Error: ${error}`)
}
})

const insertText = '---\r\nlayout: page\r\ntitle: \r\n---\r\n'

fs.writeFileSync('docs/how-to-contribute.md', insertText + fs.readFileSync('.github/CONTRIBUTING.md', 'utf8'))
}
fs.writeFileSync('docs/how-to-contribute.md', insertText + fs.readFileSync('.github/CONTRIBUTING.md', 'utf8'))
}
}

(new Publish()).run()

+ 442
- 442
SecureSharing/wwwroot/build/npm/Plugins.js View File

@@ -1,449 +1,449 @@
'use strict'

const Plugins = [
// jQuery
{
from: 'node_modules/jquery/dist',
to: 'plugins/jquery'
},
// Popper
{
from: 'node_modules/popper.js/dist',
to: 'plugins/popper'
},
// Bootstrap
{
from: 'node_modules/bootstrap/dist/js',
to: 'plugins/bootstrap/js'
},
// Font Awesome
{
from: 'node_modules/@fortawesome/fontawesome-free/css',
to: 'plugins/fontawesome-free/css'
},
{
from: 'node_modules/@fortawesome/fontawesome-free/webfonts',
to: 'plugins/fontawesome-free/webfonts'
},
// overlayScrollbars
{
from: 'node_modules/overlayscrollbars/js',
to: 'plugins/overlayScrollbars/js'
},
{
from: 'node_modules/overlayscrollbars/css',
to: 'plugins/overlayScrollbars/css'
},
// Chart.js
{
from: 'node_modules/chart.js/dist/',
to: 'plugins/chart.js'
},
// jQuery UI
{
from: 'node_modules/jquery-ui-dist/',
to: 'plugins/jquery-ui'
},
// Flot
{
from: 'node_modules/flot/dist/es5/',
to: 'plugins/flot'
},
{
from: 'node_modules/flot/source/',
to: 'plugins/flot/plugins'
},
// Summernote
{
from: 'node_modules/summernote/dist/',
to: 'plugins/summernote'
},
// Bootstrap Slider
{
from: 'node_modules/bootstrap-slider/dist/',
to: 'plugins/bootstrap-slider'
},
{
from: 'node_modules/bootstrap-slider/dist/css',
to: 'plugins/bootstrap-slider/css'
},
// Bootstrap Colorpicker
{
from: 'node_modules/bootstrap-colorpicker/dist/js',
to: 'plugins/bootstrap-colorpicker/js'
},
{
from: 'node_modules/bootstrap-colorpicker/dist/css',
to: 'plugins/bootstrap-colorpicker/css'
},
// Tempusdominus Bootstrap 4
{
from: 'node_modules/tempusdominus-bootstrap-4/build/js',
to: 'plugins/tempusdominus-bootstrap-4/js'
},
{
from: 'node_modules/tempusdominus-bootstrap-4/build/css',
to: 'plugins/tempusdominus-bootstrap-4/css'
},
// Moment
{
from: 'node_modules/moment/min',
to: 'plugins/moment'
},
{
from: 'node_modules/moment/locale',
to: 'plugins/moment/locale'
},
// FastClick
{
from: 'node_modules/fastclick/lib',
to: 'plugins/fastclick'
},
// Date Range Picker
{
from: 'node_modules/daterangepicker/',
to: 'plugins/daterangepicker'
},
// DataTables
{
from: 'node_modules/pdfmake/build',
to: 'plugins/pdfmake'
},
{
from: 'node_modules/jszip/dist',
to: 'plugins/jszip'
},
{
from: 'node_modules/datatables.net/js',
to: 'plugins/datatables'
},
{
from: 'node_modules/datatables.net-bs4/js',
to: 'plugins/datatables-bs4/js'
},
{
from: 'node_modules/datatables.net-bs4/css',
to: 'plugins/datatables-bs4/css'
},
{
from: 'node_modules/datatables.net-autofill/js',
to: 'plugins/datatables-autofill/js'
},
{
from: 'node_modules/datatables.net-autofill-bs4/js',
to: 'plugins/datatables-autofill/js'
},
{
from: 'node_modules/datatables.net-autofill-bs4/css',
to: 'plugins/datatables-autofill/css'
},
{
from: 'node_modules/datatables.net-buttons/js',
to: 'plugins/datatables-buttons/js'
},
{
from: 'node_modules/datatables.net-buttons-bs4/js',
to: 'plugins/datatables-buttons/js'
},
{
from: 'node_modules/datatables.net-buttons-bs4/css',
to: 'plugins/datatables-buttons/css'
},
{
from: 'node_modules/datatables.net-colreorder/js',
to: 'plugins/datatables-colreorder/js'
},
{
from: 'node_modules/datatables.net-colreorder-bs4/js',
to: 'plugins/datatables-colreorder/js'
},
{
from: 'node_modules/datatables.net-colreorder-bs4/css',
to: 'plugins/datatables-colreorder/css'
},
{
from: 'node_modules/datatables.net-fixedcolumns/js',
to: 'plugins/datatables-fixedcolumns/js'
},
{
from: 'node_modules/datatables.net-fixedcolumns-bs4/js',
to: 'plugins/datatables-fixedcolumns/js'
},
{
from: 'node_modules/datatables.net-fixedcolumns-bs4/css',
to: 'plugins/datatables-fixedcolumns/css'
},
{
from: 'node_modules/datatables.net-fixedheader/js',
to: 'plugins/datatables-fixedheader/js'
},
{
from: 'node_modules/datatables.net-fixedheader-bs4/js',
to: 'plugins/datatables-fixedheader/js'
},
{
from: 'node_modules/datatables.net-fixedheader-bs4/css',
to: 'plugins/datatables-fixedheader/css'
},
{
from: 'node_modules/datatables.net-keytable/js',
to: 'plugins/datatables-keytable/js'
},
{
from: 'node_modules/datatables.net-keytable-bs4/js',
to: 'plugins/datatables-keytable/js'
},
{
from: 'node_modules/datatables.net-keytable-bs4/css',
to: 'plugins/datatables-keytable/css'
},
{
from: 'node_modules/datatables.net-responsive/js',
to: 'plugins/datatables-responsive/js'
},
{
from: 'node_modules/datatables.net-responsive-bs4/js',
to: 'plugins/datatables-responsive/js'
},
{
from: 'node_modules/datatables.net-responsive-bs4/css',
to: 'plugins/datatables-responsive/css'
},
{
from: 'node_modules/datatables.net-rowgroup/js',
to: 'plugins/datatables-rowgroup/js'
},
{
from: 'node_modules/datatables.net-rowgroup-bs4/js',
to: 'plugins/datatables-rowgroup/js'
},
{
from: 'node_modules/datatables.net-rowgroup-bs4/css',
to: 'plugins/datatables-rowgroup/css'
},
{
from: 'node_modules/datatables.net-rowreorder/js',
to: 'plugins/datatables-rowreorder/js'
},
{
from: 'node_modules/datatables.net-rowreorder-bs4/js',
to: 'plugins/datatables-rowreorder/js'
},
{
from: 'node_modules/datatables.net-rowreorder-bs4/css',
to: 'plugins/datatables-rowreorder/css'
},
{
from: 'node_modules/datatables.net-scroller/js',
to: 'plugins/datatables-scroller/js'
},
{
from: 'node_modules/datatables.net-scroller-bs4/js',
to: 'plugins/datatables-scroller/js'
},
{
from: 'node_modules/datatables.net-scroller-bs4/css',
to: 'plugins/datatables-scroller/css'
},
{
from: 'node_modules/datatables.net-searchbuilder/js',
to: 'plugins/datatables-searchbuilder/js'
},
{
from: 'node_modules/datatables.net-searchbuilder-bs4/js',
to: 'plugins/datatables-searchbuilder/js'
},
{
from: 'node_modules/datatables.net-searchbuilder-bs4/css',
to: 'plugins/datatables-searchbuilder/css'
},
{
from: 'node_modules/datatables.net-searchpanes/js',
to: 'plugins/datatables-searchpanes/js'
},
{
from: 'node_modules/datatables.net-searchpanes-bs4/js',
to: 'plugins/datatables-searchpanes/js'
},
{
from: 'node_modules/datatables.net-searchpanes-bs4/css',
to: 'plugins/datatables-searchpanes/css'
},
{
from: 'node_modules/datatables.net-select/js',
to: 'plugins/datatables-select/js'
},
{
from: 'node_modules/datatables.net-select-bs4/js',
to: 'plugins/datatables-select/js'
},
{
from: 'node_modules/datatables.net-select-bs4/css',
to: 'plugins/datatables-select/css'
},
// jQuery
{
from: 'node_modules/jquery/dist',
to: 'plugins/jquery'
},
// Popper
{
from: 'node_modules/popper.js/dist',
to: 'plugins/popper'
},
// Bootstrap
{
from: 'node_modules/bootstrap/dist/js',
to: 'plugins/bootstrap/js'
},
// Font Awesome
{
from: 'node_modules/@fortawesome/fontawesome-free/css',
to: 'plugins/fontawesome-free/css'
},
{
from: 'node_modules/@fortawesome/fontawesome-free/webfonts',
to: 'plugins/fontawesome-free/webfonts'
},
// overlayScrollbars
{
from: 'node_modules/overlayscrollbars/js',
to: 'plugins/overlayScrollbars/js'
},
{
from: 'node_modules/overlayscrollbars/css',
to: 'plugins/overlayScrollbars/css'
},
// Chart.js
{
from: 'node_modules/chart.js/dist/',
to: 'plugins/chart.js'
},
// jQuery UI
{
from: 'node_modules/jquery-ui-dist/',
to: 'plugins/jquery-ui'
},
// Flot
{
from: 'node_modules/flot/dist/es5/',
to: 'plugins/flot'
},
{
from: 'node_modules/flot/source/',
to: 'plugins/flot/plugins'
},
// Summernote
{
from: 'node_modules/summernote/dist/',
to: 'plugins/summernote'
},
// Bootstrap Slider
{
from: 'node_modules/bootstrap-slider/dist/',
to: 'plugins/bootstrap-slider'
},
{
from: 'node_modules/bootstrap-slider/dist/css',
to: 'plugins/bootstrap-slider/css'
},
// Bootstrap Colorpicker
{
from: 'node_modules/bootstrap-colorpicker/dist/js',
to: 'plugins/bootstrap-colorpicker/js'
},
{
from: 'node_modules/bootstrap-colorpicker/dist/css',
to: 'plugins/bootstrap-colorpicker/css'
},
// Tempusdominus Bootstrap 4
{
from: 'node_modules/tempusdominus-bootstrap-4/build/js',
to: 'plugins/tempusdominus-bootstrap-4/js'
},
{
from: 'node_modules/tempusdominus-bootstrap-4/build/css',
to: 'plugins/tempusdominus-bootstrap-4/css'
},
// Moment
{
from: 'node_modules/moment/min',
to: 'plugins/moment'
},
{
from: 'node_modules/moment/locale',
to: 'plugins/moment/locale'
},
// FastClick
{
from: 'node_modules/fastclick/lib',
to: 'plugins/fastclick'
},
// Date Range Picker
{
from: 'node_modules/daterangepicker/',
to: 'plugins/daterangepicker'
},
// DataTables
{
from: 'node_modules/pdfmake/build',
to: 'plugins/pdfmake'
},
{
from: 'node_modules/jszip/dist',
to: 'plugins/jszip'
},
{
from: 'node_modules/datatables.net/js',
to: 'plugins/datatables'
},
{
from: 'node_modules/datatables.net-bs4/js',
to: 'plugins/datatables-bs4/js'
},
{
from: 'node_modules/datatables.net-bs4/css',
to: 'plugins/datatables-bs4/css'
},
{
from: 'node_modules/datatables.net-autofill/js',
to: 'plugins/datatables-autofill/js'
},
{
from: 'node_modules/datatables.net-autofill-bs4/js',
to: 'plugins/datatables-autofill/js'
},
{
from: 'node_modules/datatables.net-autofill-bs4/css',
to: 'plugins/datatables-autofill/css'
},
{
from: 'node_modules/datatables.net-buttons/js',
to: 'plugins/datatables-buttons/js'
},
{
from: 'node_modules/datatables.net-buttons-bs4/js',
to: 'plugins/datatables-buttons/js'
},
{
from: 'node_modules/datatables.net-buttons-bs4/css',
to: 'plugins/datatables-buttons/css'
},
{
from: 'node_modules/datatables.net-colreorder/js',
to: 'plugins/datatables-colreorder/js'
},
{
from: 'node_modules/datatables.net-colreorder-bs4/js',
to: 'plugins/datatables-colreorder/js'
},
{
from: 'node_modules/datatables.net-colreorder-bs4/css',
to: 'plugins/datatables-colreorder/css'
},
{
from: 'node_modules/datatables.net-fixedcolumns/js',
to: 'plugins/datatables-fixedcolumns/js'
},
{
from: 'node_modules/datatables.net-fixedcolumns-bs4/js',
to: 'plugins/datatables-fixedcolumns/js'
},
{
from: 'node_modules/datatables.net-fixedcolumns-bs4/css',
to: 'plugins/datatables-fixedcolumns/css'
},
{
from: 'node_modules/datatables.net-fixedheader/js',
to: 'plugins/datatables-fixedheader/js'
},
{
from: 'node_modules/datatables.net-fixedheader-bs4/js',
to: 'plugins/datatables-fixedheader/js'
},
{
from: 'node_modules/datatables.net-fixedheader-bs4/css',
to: 'plugins/datatables-fixedheader/css'
},
{
from: 'node_modules/datatables.net-keytable/js',
to: 'plugins/datatables-keytable/js'
},
{
from: 'node_modules/datatables.net-keytable-bs4/js',
to: 'plugins/datatables-keytable/js'
},
{
from: 'node_modules/datatables.net-keytable-bs4/css',
to: 'plugins/datatables-keytable/css'
},
{
from: 'node_modules/datatables.net-responsive/js',
to: 'plugins/datatables-responsive/js'
},
{
from: 'node_modules/datatables.net-responsive-bs4/js',
to: 'plugins/datatables-responsive/js'
},
{
from: 'node_modules/datatables.net-responsive-bs4/css',
to: 'plugins/datatables-responsive/css'
},
{
from: 'node_modules/datatables.net-rowgroup/js',
to: 'plugins/datatables-rowgroup/js'
},
{
from: 'node_modules/datatables.net-rowgroup-bs4/js',
to: 'plugins/datatables-rowgroup/js'
},
{
from: 'node_modules/datatables.net-rowgroup-bs4/css',
to: 'plugins/datatables-rowgroup/css'
},
{
from: 'node_modules/datatables.net-rowreorder/js',
to: 'plugins/datatables-rowreorder/js'
},
{
from: 'node_modules/datatables.net-rowreorder-bs4/js',
to: 'plugins/datatables-rowreorder/js'
},
{
from: 'node_modules/datatables.net-rowreorder-bs4/css',
to: 'plugins/datatables-rowreorder/css'
},
{
from: 'node_modules/datatables.net-scroller/js',
to: 'plugins/datatables-scroller/js'
},
{
from: 'node_modules/datatables.net-scroller-bs4/js',
to: 'plugins/datatables-scroller/js'
},
{
from: 'node_modules/datatables.net-scroller-bs4/css',
to: 'plugins/datatables-scroller/css'
},
{
from: 'node_modules/datatables.net-searchbuilder/js',
to: 'plugins/datatables-searchbuilder/js'
},
{
from: 'node_modules/datatables.net-searchbuilder-bs4/js',
to: 'plugins/datatables-searchbuilder/js'
},
{
from: 'node_modules/datatables.net-searchbuilder-bs4/css',
to: 'plugins/datatables-searchbuilder/css'
},
{
from: 'node_modules/datatables.net-searchpanes/js',
to: 'plugins/datatables-searchpanes/js'
},
{
from: 'node_modules/datatables.net-searchpanes-bs4/js',
to: 'plugins/datatables-searchpanes/js'
},
{
from: 'node_modules/datatables.net-searchpanes-bs4/css',
to: 'plugins/datatables-searchpanes/css'
},
{
from: 'node_modules/datatables.net-select/js',
to: 'plugins/datatables-select/js'
},
{
from: 'node_modules/datatables.net-select-bs4/js',
to: 'plugins/datatables-select/js'
},
{
from: 'node_modules/datatables.net-select-bs4/css',
to: 'plugins/datatables-select/css'
},

// Fullcalendar
{
from: 'node_modules/fullcalendar/',
to: 'plugins/fullcalendar'
},
// icheck bootstrap
{
from: 'node_modules/icheck-bootstrap/',
to: 'plugins/icheck-bootstrap'
},
// inputmask
{
from: 'node_modules/inputmask/dist/',
to: 'plugins/inputmask'
},
// ion-rangeslider
{
from: 'node_modules/ion-rangeslider/',
to: 'plugins/ion-rangeslider'
},
// JQVMap (jqvmap-novulnerability)
{
from: 'node_modules/jqvmap-novulnerability/dist/',
to: 'plugins/jqvmap'
},
// jQuery Mapael
{
from: 'node_modules/jquery-mapael/js/',
to: 'plugins/jquery-mapael'
},
// Raphael
{
from: 'node_modules/raphael/',
to: 'plugins/raphael'
},
// jQuery Mousewheel
{
from: 'node_modules/jquery-mousewheel/',
to: 'plugins/jquery-mousewheel'
},
// jQuery Knob
{
from: 'node_modules/jquery-knob-chif/dist/',
to: 'plugins/jquery-knob'
},
// pace-progress
{
from: 'node_modules/@lgaitan/pace-progress/dist/',
to: 'plugins/pace-progress'
},
// Select2
{
from: 'node_modules/select2/dist/',
to: 'plugins/select2'
},
{
from: 'node_modules/@ttskch/select2-bootstrap4-theme/dist/',
to: 'plugins/select2-bootstrap4-theme'
},
// Sparklines
{
from: 'node_modules/sparklines/source/',
to: 'plugins/sparklines'
},
// SweetAlert2
{
from: 'node_modules/sweetalert2/dist/',
to: 'plugins/sweetalert2'
},
{
from: 'node_modules/@sweetalert2/theme-bootstrap-4/',
to: 'plugins/sweetalert2-theme-bootstrap-4'
},
// Toastr
{
from: 'node_modules/toastr/build/',
to: 'plugins/toastr'
},
// jsGrid
{
from: 'node_modules/jsgrid/dist',
to: 'plugins/jsgrid'
},
{
from: 'node_modules/jsgrid/demos/db.js',
to: 'plugins/jsgrid/demos/db.js'
},
// flag-icon-css
{
from: 'node_modules/flag-icon-css/css',
to: 'plugins/flag-icon-css/css'
},
{
from: 'node_modules/flag-icon-css/flags',
to: 'plugins/flag-icon-css/flags'
},
// bootstrap4-duallistbox
{
from: 'node_modules/bootstrap4-duallistbox/dist',
to: 'plugins/bootstrap4-duallistbox/'
},
// filterizr
{
from: 'node_modules/filterizr/dist',
to: 'plugins/filterizr/'
},
// ekko-lightbox
{
from: 'node_modules/ekko-lightbox/dist',
to: 'plugins/ekko-lightbox/'
},
// bootstrap-switch
{
from: 'node_modules/bootstrap-switch/dist',
to: 'plugins/bootstrap-switch/'
},
// jQuery Validate
{
from: 'node_modules/jquery-validation/dist/',
to: 'plugins/jquery-validation'
},
// bs-custom-file-input
{
from: 'node_modules/bs-custom-file-input/dist/',
to: 'plugins/bs-custom-file-input'
},
// bs-stepper
{
from: 'node_modules/bs-stepper/dist/',
to: 'plugins/bs-stepper'
},
// CodeMirror
{
from: 'node_modules/codemirror/lib/',
to: 'plugins/codemirror'
},
{
from: 'node_modules/codemirror/addon/',
to: 'plugins/codemirror/addon'
},
{
from: 'node_modules/codemirror/keymap/',
to: 'plugins/codemirror/keymap'
},
{
from: 'node_modules/codemirror/mode/',
to: 'plugins/codemirror/mode'
},
{
from: 'node_modules/codemirror/theme/',
to: 'plugins/codemirror/theme'
},
// dropzonejs
{
from: 'node_modules/dropzone/dist/',
to: 'plugins/dropzone'
},
// uPlot
{
from: 'node_modules/uplot/dist/',
to: 'plugins/uplot'
}
// Fullcalendar
{
from: 'node_modules/fullcalendar/',
to: 'plugins/fullcalendar'
},
// icheck bootstrap
{
from: 'node_modules/icheck-bootstrap/',
to: 'plugins/icheck-bootstrap'
},
// inputmask
{
from: 'node_modules/inputmask/dist/',
to: 'plugins/inputmask'
},
// ion-rangeslider
{
from: 'node_modules/ion-rangeslider/',
to: 'plugins/ion-rangeslider'
},
// JQVMap (jqvmap-novulnerability)
{
from: 'node_modules/jqvmap-novulnerability/dist/',
to: 'plugins/jqvmap'
},
// jQuery Mapael
{
from: 'node_modules/jquery-mapael/js/',
to: 'plugins/jquery-mapael'
},
// Raphael
{
from: 'node_modules/raphael/',
to: 'plugins/raphael'
},
// jQuery Mousewheel
{
from: 'node_modules/jquery-mousewheel/',
to: 'plugins/jquery-mousewheel'
},
// jQuery Knob
{
from: 'node_modules/jquery-knob-chif/dist/',
to: 'plugins/jquery-knob'
},
// pace-progress
{
from: 'node_modules/@lgaitan/pace-progress/dist/',
to: 'plugins/pace-progress'
},
// Select2
{
from: 'node_modules/select2/dist/',
to: 'plugins/select2'
},
{
from: 'node_modules/@ttskch/select2-bootstrap4-theme/dist/',
to: 'plugins/select2-bootstrap4-theme'
},
// Sparklines
{
from: 'node_modules/sparklines/source/',
to: 'plugins/sparklines'
},
// SweetAlert2
{
from: 'node_modules/sweetalert2/dist/',
to: 'plugins/sweetalert2'
},
{
from: 'node_modules/@sweetalert2/theme-bootstrap-4/',
to: 'plugins/sweetalert2-theme-bootstrap-4'
},
// Toastr
{
from: 'node_modules/toastr/build/',
to: 'plugins/toastr'
},
// jsGrid
{
from: 'node_modules/jsgrid/dist',
to: 'plugins/jsgrid'
},
{
from: 'node_modules/jsgrid/demos/db.js',
to: 'plugins/jsgrid/demos/db.js'
},
// flag-icon-css
{
from: 'node_modules/flag-icon-css/css',
to: 'plugins/flag-icon-css/css'
},
{
from: 'node_modules/flag-icon-css/flags',
to: 'plugins/flag-icon-css/flags'
},
// bootstrap4-duallistbox
{
from: 'node_modules/bootstrap4-duallistbox/dist',
to: 'plugins/bootstrap4-duallistbox/'
},
// filterizr
{
from: 'node_modules/filterizr/dist',
to: 'plugins/filterizr/'
},
// ekko-lightbox
{
from: 'node_modules/ekko-lightbox/dist',
to: 'plugins/ekko-lightbox/'
},
// bootstrap-switch
{
from: 'node_modules/bootstrap-switch/dist',
to: 'plugins/bootstrap-switch/'
},
// jQuery Validate
{
from: 'node_modules/jquery-validation/dist/',
to: 'plugins/jquery-validation'
},
// bs-custom-file-input
{
from: 'node_modules/bs-custom-file-input/dist/',
to: 'plugins/bs-custom-file-input'
},
// bs-stepper
{
from: 'node_modules/bs-stepper/dist/',
to: 'plugins/bs-stepper'
},
// CodeMirror
{
from: 'node_modules/codemirror/lib/',
to: 'plugins/codemirror'
},
{
from: 'node_modules/codemirror/addon/',
to: 'plugins/codemirror/addon'
},
{
from: 'node_modules/codemirror/keymap/',
to: 'plugins/codemirror/keymap'
},
{
from: 'node_modules/codemirror/mode/',
to: 'plugins/codemirror/mode'
},
{
from: 'node_modules/codemirror/theme/',
to: 'plugins/codemirror/theme'
},
// dropzonejs
{
from: 'node_modules/dropzone/dist/',
to: 'plugins/dropzone'
},
// uPlot
{
from: 'node_modules/uplot/dist/',
to: 'plugins/uplot'
}
]

module.exports = Plugins

+ 42
- 42
SecureSharing/wwwroot/build/npm/Publish.js View File

@@ -7,53 +7,53 @@ const fse = require('fs-extra')
const Plugins = require('./Plugins')

class Publish {
constructor() {
this.options = {
verbose: false
}
constructor() {
this.options = {
verbose: false
}

this.getArguments()
}

getArguments() {
if (process.argv.length > 2) {
const arg = process.argv[2]
switch (arg) {
case '-v':
case '--verbose':
this.options.verbose = true
break
default:
throw new Error(`Unknown option ${arg}`)
}
this.getArguments()
}
}

run() {
// Publish files
Plugins.forEach(module => {
const fseOptions = {
// Skip copying dot files
filter(src) {
return !path.basename(src).startsWith('.')
}
}

try {
if (fse.existsSync(module.from)) {
fse.copySync(module.from, module.to, fseOptions)
} else {
fse.copySync(module.from.replace('node_modules/', '../'), module.to, fseOptions)
getArguments() {
if (process.argv.length > 2) {
const arg = process.argv[2]
switch (arg) {
case '-v':
case '--verbose':
this.options.verbose = true
break
default:
throw new Error(`Unknown option ${arg}`)
}
}
}

if (this.options.verbose) {
console.log(`Copied ${module.from} to ${module.to}`)
}
} catch (error) {
console.error(`Error: ${error}`)
}
})
}
run() {
// Publish files
Plugins.forEach(module => {
const fseOptions = {
// Skip copying dot files
filter(src) {
return !path.basename(src).startsWith('.')
}
}

try {
if (fse.existsSync(module.from)) {
fse.copySync(module.from, module.to, fseOptions)
} else {
fse.copySync(module.from.replace('node_modules/', '../'), module.to, fseOptions)
}

if (this.options.verbose) {
console.log(`Copied ${module.from} to ${module.to}`)
}
} catch (error) {
console.error(`Error: ${error}`)
}
})
}
}

(new Publish()).run()

+ 39
- 39
SecureSharing/wwwroot/build/npm/vnu-jar.js View File

@@ -13,43 +13,43 @@ const childProcess = require('child_process')
const vnu = require('vnu-jar')

childProcess.exec('java -version', (error, stdout, stderr) => {
if (error) {
console.error('Skipping vnu-jar test; Java is missing.')
return
}
const is32bitJava = !/64-Bit/.test(stderr)
// vnu-jar accepts multiple ignores joined with a `|`.
// Also note that the ignores are regular expressions.
const ignores = [
// "autocomplete" is included in <button> and checkboxes and radio <input>s due to
// Firefox's non-standard autocomplete behavior - see https://bugzilla.mozilla.org/show_bug.cgi?id=654072
'Attribute “autocomplete” is only allowed when the input type is.*'
].join('|')
const args = [
'-jar',
vnu,
'--asciiquotes',
'--skip-non-html',
// Ignore the language code warnings
'--no-langdetect',
'--Werror',
`--filterpattern "${ignores}"`,
'./*.html',
'docs_html/',
'pages/'
]
// For the 32-bit Java we need to pass `-Xss512k`
if (is32bitJava) {
args.splice(0, 0, '-Xss512k')
}
return childProcess.spawn('java', args, {
shell: true,
stdio: 'inherit'
})
.on('exit', process.exit)
if (error) {
console.error('Skipping vnu-jar test; Java is missing.')
return
}
const is32bitJava = !/64-Bit/.test(stderr)
// vnu-jar accepts multiple ignores joined with a `|`.
// Also note that the ignores are regular expressions.
const ignores = [
// "autocomplete" is included in <button> and checkboxes and radio <input>s due to
// Firefox's non-standard autocomplete behavior - see https://bugzilla.mozilla.org/show_bug.cgi?id=654072
'Attribute “autocomplete” is only allowed when the input type is.*'
].join('|')
const args = [
'-jar',
vnu,
'--asciiquotes',
'--skip-non-html',
// Ignore the language code warnings
'--no-langdetect',
'--Werror',
`--filterpattern "${ignores}"`,
'./*.html',
'docs_html/',
'pages/'
]
// For the 32-bit Java we need to pass `-Xss512k`
if (is32bitJava) {
args.splice(0, 0, '-Xss512k')
}
return childProcess.spawn('java', args, {
shell: true,
stdio: 'inherit'
})
.on('exit', process.exit)
})

+ 1
- 0
SecureSharing/wwwroot/build/scss/_animation-effects.scss View File

@@ -6,6 +6,7 @@
&__shake {
animation: shake 1500ms;
}

&__wobble {
animation: wobble 1500ms;
}

+ 552
- 552
SecureSharing/wwwroot/build/scss/_bootstrap-variables.scss
File diff suppressed because it is too large
View File


+ 1
- 0
SecureSharing/wwwroot/build/scss/_buttons.scss View File

@@ -127,6 +127,7 @@
border-color: lighten($gray-600, 2.5%);
}
}

.btn-light {
background-color: lighten($dark, 7.5%);
color: $white;

+ 9
- 3
SecureSharing/wwwroot/build/scss/_cards.scss View File

@@ -206,7 +206,7 @@ html.maximized-card {
.card-header,
.card-body,
.card-footer {
@include clearfix ();
@include clearfix();
}

// Box header
@@ -314,7 +314,7 @@ html.maximized-card {
}

.chart-legend {
@include list-unstyled ();
@include list-unstyled();
margin: 10px 0;

> li {
@@ -330,7 +330,7 @@ html.maximized-card {
background-color: $gray-100;

.card-comment {
@include clearfix ();
@include clearfix();
border-bottom: 1px solid $gray-200;
padding: 8px 0;

@@ -498,16 +498,20 @@ html.maximized-card {
background-color: lighten($dark, 5%);
color: $white;
}

.nav.flex-column > li {
border-bottom-color: $gray-600;
}

.card-footer {
background-color: rgba($black, .1);
}

&.card-outline-tabs .card-header a:hover {
border-color: $gray-600;
border-bottom-color: transparent;
}

&:not(.card-outline) > .card-header a.active {
color: $white;
}
@@ -515,9 +519,11 @@ html.maximized-card {

.card-comments {
background-color: lighten($dark, 1.25%);

.username {
color: $gray-400;
}

.card-comment {
border-bottom-color: lighten($dark, 7.5%);
}

+ 1
- 0
SecureSharing/wwwroot/build/scss/_carousel.scss View File

@@ -6,6 +6,7 @@
.carousel-control-prev & {
margin-left: -20px;
}

.carousel-control-next & {
margin-right: 20px;
}

+ 1
- 0
SecureSharing/wwwroot/build/scss/_colors.scss View File

@@ -95,6 +95,7 @@ a.text-muted:hover {
background-color: lighten($dark, 7.5%) !important;
color: $white !important;
}

.text-black,
.text-dark,
.link-black,

+ 5
- 3
SecureSharing/wwwroot/build/scss/_direct-chat.scss View File

@@ -42,7 +42,7 @@
}

.direct-chat-msg {
@include clearfix ();
@include clearfix();
margin-bottom: 10px;
}

@@ -163,10 +163,10 @@

//Contacts list -- for displaying contacts in direct chat contacts pane
.contacts-list {
@include list-unstyled ();
@include list-unstyled();

> li {
@include clearfix ();
@include clearfix();
border-bottom: 1px solid rgba($black, .2);
margin: 0;
padding: 10px;
@@ -234,9 +234,11 @@
border-right-color: lighten($dark, 10%);
}
}

.direct-chat-timestamp {
color: $gray-500;
}

.right > .direct-chat-text {
&::after,
&::before {

+ 11
- 3
SecureSharing/wwwroot/build/scss/_dropdown.scss View File

@@ -58,7 +58,7 @@
position: relative;

> a::after {
@include caret-right ();
@include caret-right();
float: right;
margin-left: .5rem;
margin-top: .5rem;
@@ -125,6 +125,7 @@
.navbar-custom-menu > .navbar-nav {
> li {
position: relative;

> .dropdown-menu {
position: absolute;
right: 0;
@@ -136,8 +137,10 @@
@include media-breakpoint-down(sm) {
.navbar-custom-menu > .navbar-nav {
float: right;

> li {
position: static;

> .dropdown-menu {
position: absolute;
right: 5%;
@@ -196,7 +199,7 @@

// Menu Body
> .user-body {
@include clearfix ();
@include clearfix();
border-bottom: 1px solid $gray-700;
border-top: 1px solid $gray-300;
padding: 15px;
@@ -211,7 +214,7 @@

// Menu Footer
> .user-footer {
@include clearfix ();
@include clearfix();
background-color: $gray-100;
padding: 10px;

@@ -249,6 +252,7 @@
background-color: $dark;
color: $white;
}

.dropdown-item {
color: $white;

@@ -257,6 +261,7 @@
background-color: lighten($dark, 5%);
}
}

.dropdown-divider {
border-color: $gray-600;
}
@@ -274,14 +279,17 @@
background-color: lighten($dark, 5%);
color: $gray-300;
}

&:focus {
background-color: lighten($dark, 7.5%);
}
}
}

> .user-body {
border-color: $gray-600;
}

> .user-body a {
background-color: transparent !important;
color: $white !important;

+ 8
- 0
SecureSharing/wwwroot/build/scss/_forms.scss View File

@@ -284,6 +284,7 @@ body.text-sm {
&.border-width-2 {
border-bottom-width: 2px;
}

&.border-width-3 {
border-bottom-width: 3px;
}
@@ -326,6 +327,7 @@ body.text-sm {
background-color: transparent !important;
box-shadow: none;
}

&:checked ~ .custom-control-label::before {
@include gradient-bg(transparent);
}
@@ -338,10 +340,12 @@ body.text-sm {
border: 1px solid lighten($sidebar-dark-bg, 15%);
color: lighten(color-yiq(lighten($sidebar-dark-bg, 5%)), 15%);
}

.btn-navbar {
&:hover {
background-color: lighten($sidebar-dark-bg, 7.5%);
}

&:focus {
background-color: lighten($sidebar-dark-bg, 10%);
}
@@ -368,11 +372,13 @@ body.text-sm {
background-color: $dark;
color: $white;
}

.form-control:not(.form-control-navbar):not(.form-control-sidebar):not(.is-invalid):not(:focus),
.custom-file-label,
.custom-file-label::after {
border-color: $gray-600;
}

select {
background-color: $dark;
color: $white;
@@ -394,9 +400,11 @@ body.text-sm {
&::-webkit-slider-runnable-track {
background-color: lighten($dark, 7.5%);
}

&::-moz-range-track {
background-color: lighten($dark, 7.5%);
}

&::-ms-track {
background-color: lighten($dark, 7.5%);
}

+ 2
- 0
SecureSharing/wwwroot/build/scss/_layout.scss View File

@@ -689,10 +689,12 @@ body:not(.layout-fixed) {
color: $gray-500;
}
}

.main-footer {
background-color: $dark;
border-color: lighten($dark, 10%);
}

.content-wrapper {
background-color: lighten($dark, 7.5%);
color: $white;

+ 5
- 3
SecureSharing/wwwroot/build/scss/_main-sidebar.scss View File

@@ -390,7 +390,7 @@
// Hover and active states
&.menu-open > .nav-link,
&:hover > .nav-link,
> .nav-link:focus {
> .nav-link:focus {
background-color: $sidebar-dark-hover-bg;
color: $sidebar-dark-hover-color;
}
@@ -767,7 +767,7 @@
}

&.active {
> .nav-icon{
> .nav-icon {
margin-left: .36rem;
}
}
@@ -793,7 +793,7 @@
}

&.active {
> .nav-icon{
> .nav-icon {
margin-left: calc(.75rem - 3px);
}
}
@@ -988,6 +988,7 @@
width: 100%;
flex-wrap: nowrap;
}

.sidebar nav .form-inline {
margin-bottom: .2rem;
}
@@ -997,6 +998,7 @@
&.sidebar-collapse .main-sidebar {
margin-left: 0;
}

.content-wrapper,
.main-header,
.main-footer {

+ 6
- 0
SecureSharing/wwwroot/build/scss/_miscellaneous.scss View File

@@ -296,6 +296,7 @@
// Box overlay for LOADING STATE effect on Tab Panels
> .overlay-wrapper {
position: relative;

> .overlay {
border-top-left-radius: 0;
border-top-right-radius: 0;
@@ -486,6 +487,7 @@ blockquote {
a:not(.btn):hover {
color: lighten($link-color, 10%);
}

.attachment-block {
background-color: lighten($dark, 3.75%);

@@ -493,6 +495,7 @@ blockquote {
color: $gray-400;
}
}

blockquote {
background-color: lighten($dark, 5%);

@@ -526,14 +529,17 @@ blockquote {
}
}
}

.close,
.mailbox-attachment-close {
color: $gray-500;
text-shadow: 0 1px 0 $gray-700;
}

.tab-custom-content {
border-color: $gray-600;
}

.list-group-item {
background-color: $dark;
border-color: $gray-600;

+ 2
- 0
SecureSharing/wwwroot/build/scss/_modals.scss View File

@@ -48,6 +48,7 @@
.modal-footer {
border-color: $gray-600;
}

.modal-content {
background-color: $dark;

@@ -56,6 +57,7 @@
.modal-footer {
border-color: $gray-600;
}

.close {
color: $dark !important;
text-shadow: 0 1px 0 $gray-700 !important;

+ 5
- 2
SecureSharing/wwwroot/build/scss/_navs.scss View File

@@ -30,7 +30,7 @@
border-top-right-radius: 0;
margin-right: -$nav-tabs-border-width;

@include hover-focus () {
@include hover-focus() {
border-color: $gray-200 transparent $gray-200 $gray-200;
}
}
@@ -51,7 +51,7 @@
border-top-right-radius: $nav-tabs-border-radius;
margin-left: -$nav-tabs-border-width;

@include hover-focus () {
@include hover-focus() {
border-color: $gray-200 $gray-200 $gray-200 transparent;
}
}
@@ -126,13 +126,16 @@
&:hover {
border-color: lighten($dark, 15%) transparent lighten($dark, 15%) lighten($dark, 15%);
}

&:focus,
&:hover {
background-color: lighten($dark, 5%);
}
}

&.nav-tabs-right {
border-color: lighten($dark, 15%);

.nav-link {
&.active,
&:focus,

+ 5
- 0
SecureSharing/wwwroot/build/scss/_pagination.scss View File

@@ -13,6 +13,7 @@
flex-direction: column;
box-shadow: none;
}

&:first-child,
&:last-child {
.page-link {
@@ -20,11 +21,13 @@
font-size: $font-size-lg;
}
}

.page-month {
margin-bottom: 0;
font-size: $font-size-lg;
font-weight: $font-weight-bold;
}

.page-year {
margin-bottom: 0;
}
@@ -35,6 +38,7 @@
font-size: ($font-size-lg * 1.25);
}
}

&.pagination-sm {
.page-month {
font-size: ($font-size-base);
@@ -66,6 +70,7 @@
}
}
}

&:not(.active) {
.page-link {
background-color: $dark;

+ 0
- 0
SecureSharing/wwwroot/build/scss/_products.scss View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save