Sfoglia il codice sorgente

Code cleanup, sealing classes (it works faster)

master
parent
commit
e6a7e4a56c
100 ha cambiato i file con 3926 aggiunte e 5027 eliminazioni
  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 Vedi File

<?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 Vedi File


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

{
"ExpandedNodes": [
""
],
"PreviewInSolutionExplorer": false
}

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


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


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


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


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


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


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


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


BIN
.vs/slnx.sqlite Vedi File


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

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 Vedi File

using System; 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 Vedi File

using AutoMapper; using AutoMapper;
using Microsoft.Extensions.DependencyInjection; 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 Vedi File

using AutoMapper; 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.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 Vedi File


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 Vedi File

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 Vedi File

using System;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; 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 Vedi File

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using SecureSharing.Business.Dtos; using SecureSharing.Business.Dtos;
using SecureSharing.Business.Infrastructure; 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 Vedi File

<Project Sdk="Microsoft.NET.Sdk"> <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> </Project>

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

using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;

using AutoMapper; using AutoMapper;
using Microsoft.EntityFrameworkCore;
using SecureSharing.Business.Dtos; using SecureSharing.Business.Dtos;
using SecureSharing.Business.Infrastructure;
using SecureSharing.Business.Interfaces; using SecureSharing.Business.Interfaces;
using SecureSharing.Data.Data; using SecureSharing.Data.Data;
using SecureSharing.Data.DbContexts; 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 Vedi File

using System; 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 Vedi File

using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;

using SecureSharing.Data.Data; 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 Vedi File

using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; 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 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 Vedi File

<Project Sdk="Microsoft.NET.Sdk"> <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> </Project>

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

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 Vedi File

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


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

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

using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text.Encodings.Web;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging; 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(); 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 Vedi File

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


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

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

using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Microsoft.AspNetCore.WebUtilities; using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging; 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 Vedi File



<h1>@ViewData["Title"]</h1> <h1>@ViewData["Title"]</h1>
<h4>Reset your password.</h4> <h4>Reset your password.</h4>
<hr />
<hr/>
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">
<form method="post"> <form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div> <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"> <div class="form-group">
<label asp-for="Input.Email"></label> <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> <span asp-validation-for="Input.Email" class="text-danger"></span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="Input.Password"></label> <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> <span asp-validation-for="Input.Password" class="text-danger"></span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="Input.ConfirmPassword"></label> <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> <span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
</div> </div>
<button type="submit" class="btn btn-primary">Reset</button> <button type="submit" class="btn btn-primary">Reset</button>
</div> </div>


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

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

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.Threading.Tasks;
using System.Web;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages; 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 Vedi File

crossorigin="anonymous" crossorigin="anonymous"
integrity="sha384-ifv0TYDWxBHzvAk2Z0n8R434FL1Rlv/Av18DXE43N/1rvHyOG4izKst0f2iSLdds"> integrity="sha384-ifv0TYDWxBHzvAk2Z0n8R434FL1Rlv/Av18DXE43N/1rvHyOG4izKst0f2iSLdds">
</script> </script>
</environment>
</environment>

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

@using Microsoft.AspNetCore.Identity @using Microsoft.AspNetCore.Identity
@using SecureSharing.Areas.Identity @using SecureSharing.Areas.Identity
@using SecureSharing.Areas.Identity.Pages @using SecureSharing.Areas.Identity.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

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


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

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

using Microsoft.AspNetCore.Authorization;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using SecureSharing.Business.Dtos; 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.Business.Interfaces;
using SecureSharing.Infrastructure; 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 Vedi File

using SecureSharing.Business.Dtos;
using System.Threading.Tasks;
using SecureSharing.Models; 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 Vedi File

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System;
using System.Net; using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json; using Newtonsoft.Json;
using Serilog; 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 Vedi File

using SecureSharing.Business.Dtos;
using System;
using System.Threading.Tasks;
using SecureSharing.Business.Interfaces; using SecureSharing.Business.Interfaces;
using SecureSharing.Models; 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 Vedi File

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 Vedi File

using System; 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 Vedi File

using SecureSharing.Business.Infrastructure; 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 Vedi File

using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting; 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 Vedi File

https://go.microsoft.com/fwlink/?LinkID=208121. https://go.microsoft.com/fwlink/?LinkID=208121.
--> -->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <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> </Project>

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

by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121. 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"> <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> </Project>

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

using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Concurrent;
using Microsoft.Extensions.DependencyInjection;
using Quartz; using Quartz;
using Quartz.Spi; 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 Vedi File

using System; 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) 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 Vedi File

using Microsoft.Extensions.Hosting;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Quartz; using Quartz;
using Quartz.Spi; 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, 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()) .WithIdentity(jobMetadata.JobId.ToString())
.WithCronSchedule(jobMetadata.CronExpression) .WithCronSchedule(jobMetadata.CronExpression)
.WithDescription($"{jobMetadata.JobName}") .WithDescription($"{jobMetadata.JobName}")
.Build(); .Build();
}
private IJobDetail CreateJob(JobMetadata jobMetadata)
{
return JobBuilder
}

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

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

using SecureSharing.Business.Interfaces;
using Quartz;
using System;
using System;
using System.Threading.Tasks; 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 Vedi File

<Project Sdk="Microsoft.NET.Sdk.Web"> <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> </Project>

+ 62
- 69
SecureSharing/Startup.cs Vedi File

using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Quartz;
using Quartz.Impl;
using Quartz.Spi;
using SecureSharing.Business.Infrastructure; using SecureSharing.Business.Infrastructure;
using SecureSharing.Business.Infrastructure.Extensions; using SecureSharing.Business.Infrastructure.Extensions;
using SecureSharing.Business.Infrastructure.Settings; using SecureSharing.Business.Infrastructure.Settings;
using SecureSharing.Infrastructure; using SecureSharing.Infrastructure;
using SecureSharing.Infrastructure.Middleware; using SecureSharing.Infrastructure.Middleware;
using SecureSharing.Quartz; 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 => .AddGoogle(options =>
{ {
options.ClientId = Configuration.GetSection("EmailSettings").GetSection("ClientId").Value; options.ClientId = Configuration.GetSection("EmailSettings").GetSection("ClientId").Value;
}); });




// 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 Vedi File



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


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




</div>
</div>

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


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


<div class="text-center"> <div class="text-center">


@if(!Model.IsValid)
@if (!Model.IsValid)
{ {
<p>This link has expired</p> <p>This link has expired</p>
} }
else 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> <div>
@if(Model.TimeLeft != null)
@if (Model.TimeLeft != null)
{ {
var time = Model.TimeLeft.Value; 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> <p>This message will expire in: @time.ToString("%d") days @time.ToString("%h") hours @time.ToString("%m") minutes</p>
} }
<p>This message will expire when you leave this page</p> <p>This message will expire when you leave this page</p>
} }
</div> </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> <a class="btn btn-light" asp-controller="Home" asp-action="Index">Back</a>


</div>
</div>

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

} }
<h1>@ViewData["Title"]</h1> <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 Vedi File

It can result in displaying sensitive information from exceptions to end users. 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> 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. and restarting the app.
</p>
</p>

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

<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <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> <title>@ViewData["Title"] - SecureSharing</title>
<!-- Google Font: Source Sans Pro --> <!-- Google Font: Source Sans Pro -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback"> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
<link rel="stylesheet" href="~/plugins/summernote/summernote-bs4.min.css"> <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"> <link rel="stylesheet" href="~/css/site.css">
</head> </head>
<body class="hold-transition layout-fixed"> <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>
</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> </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) $.widget.bridge('uibutton', $.ui.button)
</script> </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> </body>
</html>
</html>

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

<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script> <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 Vedi File

@using SecureSharing @using SecureSharing
@using SecureSharing.Models @using SecureSharing.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

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

@{ @{
Layout = "_Layout"; Layout = "_Layout";
}
}

+ 0
- 2
SecureSharing/appsettings.json Vedi File

{ {
"AllowedHosts": "*", "AllowedHosts": "*",
"ConnectionStrings": { "ConnectionStrings": {
"DefaultConnection": "data source=(localdb)\\MSSQLLocalDB; initial catalog=Test;Integrated Security=True" "DefaultConnection": "data source=(localdb)\\MSSQLLocalDB; initial catalog=Test;Integrated Security=True"

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

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

'use strict' 'use strict'


module.exports = { 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 Vedi File

'use strict' 'use strict'


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


const pkg = require('../../package') const pkg = require('../../package')
const year = new Date().getFullYear() const year = new Date().getFullYear()
*/` */`


module.exports = { 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 Vedi File

import Treeview from './Treeview' import Treeview from './Treeview'


export { 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 Vedi File

const SELECTOR_DATA_REFRESH = '[data-card-widget="card-refresh"]' const SELECTOR_DATA_REFRESH = '[data-card-widget="card-refresh"]'


const Default = { 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 { 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()
}
} }
}
} }


/** /**
*/ */


$(document).on('click', SELECTOR_DATA_REFRESH, function (event) { $(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))
})
}) })


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


export default CardRefresh export default CardRefresh

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

const SELECTOR_CARD_FOOTER = '.card-footer' const SELECTOR_CARD_FOOTER = '.card-footer'


const Default = { 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 { 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()
})
} }
}
} }


/** /**
*/ */


$(document).on('click', SELECTOR_DATA_COLLAPSE, function (event) { $(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) { $(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) { $(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')
}) })


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


export default CardWidget export default CardWidget

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

const CLASS_NAME_FOOTER_XL_FIXED = 'layout-xl-footer-fixed' const CLASS_NAME_FOOTER_XL_FIXED = 'layout-xl-footer-fixed'


const Default = { 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
} }


/** /**
*/ */


class ControlSidebar { 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() 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
}
})
}
}
} }


/** /**
* ==================================================== * ====================================================
*/ */
$(document).on('click', SELECTOR_DATA_TOGGLE, function (event) { $(document).on('click', SELECTOR_DATA_TOGGLE, function (event) {
event.preventDefault()
event.preventDefault()


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


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


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


export default ControlSidebar export default ControlSidebar

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

*/ */


class DirectChat { 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))
}
} }


/** /**
*/ */


$(document).on('click', SELECTOR_DATA_TOGGLE, function (event) { $(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')
}) })


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


export default DirectChat export default DirectChat

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

*/ */


class Dropdown { 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
})
}
}
} }


/** /**
*/ */


$(`${SELECTOR_DROPDOWN_MENU} ${SELECTOR_DROPDOWN_TOGGLE}`).on('click', function (event) { $(`${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 => { $(`${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)
}) })


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


export default Dropdown export default Dropdown

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

import $ from 'jquery' import $ from 'jquery'


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


const NAME = 'ExpandableTable' const NAME = 'ExpandableTable'
const DATA_KEY = 'lte.expandableTable' const DATA_KEY = 'lte.expandableTable'
const SELECTOR_ARIA_ATTR = 'aria-expanded' const SELECTOR_ARIA_ATTR = 'aria-expanded'


/** /**
* Class Definition
* ====================================================
*/
* Class Definition
* ====================================================
*/
class ExpandableTable { 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 () { $(SELECTOR_TABLE).ready(function () {
ExpandableTable._jQueryInterface.call($(this), 'init')
ExpandableTable._jQueryInterface.call($(this), 'init')
}) })


$(document).on('click', SELECTOR_DATA_TOGGLE, function () { $(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] = ExpandableTable._jQueryInterface
$.fn[NAME].Constructor = ExpandableTable $.fn[NAME].Constructor = ExpandableTable
$.fn[NAME].noConflict = function () { $.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return ExpandableTable._jQueryInterface
$.fn[NAME] = JQUERY_NO_CONFLICT
return ExpandableTable._jQueryInterface
} }


export default ExpandableTable export default ExpandableTable

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

const SELECTOR_ICON = `${SELECTOR_DATA_WIDGET} i` const SELECTOR_ICON = `${SELECTOR_DATA_WIDGET} i`


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


/** /**
*/ */


class Fullscreen { 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 () { $(document).on('click', SELECTOR_DATA_WIDGET, function () {
Fullscreen._jQueryInterface.call($(this), 'toggle')
Fullscreen._jQueryInterface.call($(this), 'toggle')
}) })


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


export default Fullscreen export default Fullscreen

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

const CLASS_NAME_FULLSCREEN_MODE = 'iframe-mode-fullscreen' const CLASS_NAME_FULLSCREEN_MODE = 'iframe-mode-fullscreen'


const Default = { 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'
} }


/** /**
*/ */


class IFrame { 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)
}
}
} }
}
} }


/** /**
*/ */


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


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


export default IFrame export default IFrame

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

const CLASS_NAME_CONTROL_SIDEBAR_OPEN = 'control-sidebar-open' const CLASS_NAME_CONTROL_SIDEBAR_OPEN = 'control-sidebar-open'


const Default = { 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
} }


/** /**
*/ */


class Layout { 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() 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(() => { 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'
}
} }


/** /**
*/ */


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


$(`${SELECTOR_SIDEBAR} a`) $(`${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 * jQuery API
$.fn[NAME] = Layout._jQueryInterface $.fn[NAME] = Layout._jQueryInterface
$.fn[NAME].Constructor = Layout $.fn[NAME].Constructor = Layout
$.fn[NAME].noConflict = function () { $.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Layout._jQueryInterface
$.fn[NAME] = JQUERY_NO_CONFLICT
return Layout._jQueryInterface
} }


export default Layout export default Layout

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

const CLASS_NAME_OPEN = 'navbar-search-open' const CLASS_NAME_OPEN = 'navbar-search-open'


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


/** /**
*/ */


class NavbarSearch { 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()
}
}
} }


/** /**
* ==================================================== * ====================================================
*/ */
$(document).on('click', SELECTOR_TOGGLE_BUTTON, event => { $(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')
}) })


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


export default NavbarSearch export default NavbarSearch

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

const CLASS_NAME_CLOSED = 'sidebar-closed' const CLASS_NAME_CLOSED = 'sidebar-closed'


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


/** /**
*/ */


class PushMenu { 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)
}
} }


/** /**
*/ */


$(document).on('click', SELECTOR_TOGGLE_BUTTON, event => { $(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', () => { $(window).on('load', () => {
PushMenu._jQueryInterface.call($(SELECTOR_TOGGLE_BUTTON))
PushMenu._jQueryInterface.call($(SELECTOR_TOGGLE_BUTTON))
}) })


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


export default PushMenu export default PushMenu

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

* -------------------------------------------- * --------------------------------------------
*/ */


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


/** /**
* Constants * Constants
const SELECTOR_SEARCH_RESULTS_GROUP = `${SELECTOR_SEARCH_RESULTS} .${CLASS_NAME_LIST_GROUP}` const SELECTOR_SEARCH_RESULTS_GROUP = `${SELECTOR_SEARCH_RESULTS} .${CLASS_NAME_LIST_GROUP}`


const Default = { 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 = [] const SearchItems = []
*/ */


class SidebarSearch { 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, '#', []))
} }
}
} }


/** /**
* ==================================================== * ====================================================
*/ */
$(document).on('click', SELECTOR_SEARCH_BUTTON, event => { $(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 => { $(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 => { $(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', () => { $(window).on('load', () => {
SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'init')
SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'init')
}) })


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


export default SidebarSearch export default SidebarSearch

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

const POSITION_BOTTOM_LEFT = 'bottomLeft' const POSITION_BOTTOM_LEFT = 'bottomLeft'


const Default = { 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
} }


/** /**
* ==================================================== * ====================================================
*/ */
class Toasts { 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')
}
}
} }


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


export default Toasts export default Toasts

+ 52
- 52
SecureSharing/wwwroot/build/js/TodoList.js Vedi File

const CLASS_NAME_TODO_LIST_DONE = 'done' const CLASS_NAME_TODO_LIST_DONE = 'done'


const Default = { const Default = {
onCheck(item) {
return item
},
onUnCheck(item) {
return item
}
onCheck(item) {
return item
},
onUnCheck(item) {
return item
}
} }


/** /**
*/ */


class TodoList { 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))
})
}
} }


/** /**
*/ */


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


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


export default TodoList export default TodoList

+ 89
- 89
SecureSharing/wwwroot/build/js/Treeview.js Vedi File

const CLASS_NAME_SIDEBAR_COLLAPSED = 'sidebar-collapse' const CLASS_NAME_SIDEBAR_COLLAPSED = 'sidebar-collapse'


const Default = { 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"]'
} }


/** /**
* ==================================================== * ====================================================
*/ */
class Treeview { 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')
}
}
} }


/** /**
*/ */


$(window).on(EVENT_LOAD_DATA_API, () => { $(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')
})
}) })


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


export default Treeview export default Treeview

+ 42
- 42
SecureSharing/wwwroot/build/npm/DocsPlugins.js Vedi File

'use strict' 'use strict'


const Plugins = [ 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 module.exports = Plugins

+ 39
- 39
SecureSharing/wwwroot/build/npm/DocsPublish.js Vedi File

const Plugins = require('./DocsPlugins') const Plugins = require('./DocsPlugins')


class Publish { 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() (new Publish()).run()

+ 442
- 442
SecureSharing/wwwroot/build/npm/Plugins.js Vedi File

'use strict' 'use strict'


const Plugins = [ 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 module.exports = Plugins

+ 42
- 42
SecureSharing/wwwroot/build/npm/Publish.js Vedi File

const Plugins = require('./Plugins') const Plugins = require('./Plugins')


class Publish { 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() (new Publish()).run()

+ 39
- 39
SecureSharing/wwwroot/build/npm/vnu-jar.js Vedi File

const vnu = require('vnu-jar') const vnu = require('vnu-jar')


childProcess.exec('java -version', (error, stdout, stderr) => { 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 Vedi File

&__shake { &__shake {
animation: shake 1500ms; animation: shake 1500ms;
} }

&__wobble { &__wobble {
animation: wobble 1500ms; animation: wobble 1500ms;
} }

+ 552
- 552
SecureSharing/wwwroot/build/scss/_bootstrap-variables.scss
File diff soppresso perché troppo grande
Vedi File


+ 1
- 0
SecureSharing/wwwroot/build/scss/_buttons.scss Vedi File

border-color: lighten($gray-600, 2.5%); border-color: lighten($gray-600, 2.5%);
} }
} }

.btn-light { .btn-light {
background-color: lighten($dark, 7.5%); background-color: lighten($dark, 7.5%);
color: $white; color: $white;

+ 9
- 3
SecureSharing/wwwroot/build/scss/_cards.scss Vedi File

.card-header, .card-header,
.card-body, .card-body,
.card-footer { .card-footer {
@include clearfix ();
@include clearfix();
} }


// Box header // Box header
} }


.chart-legend { .chart-legend {
@include list-unstyled ();
@include list-unstyled();
margin: 10px 0; margin: 10px 0;


> li { > li {
background-color: $gray-100; background-color: $gray-100;


.card-comment { .card-comment {
@include clearfix ();
@include clearfix();
border-bottom: 1px solid $gray-200; border-bottom: 1px solid $gray-200;
padding: 8px 0; padding: 8px 0;


background-color: lighten($dark, 5%); background-color: lighten($dark, 5%);
color: $white; color: $white;
} }

.nav.flex-column > li { .nav.flex-column > li {
border-bottom-color: $gray-600; border-bottom-color: $gray-600;
} }

.card-footer { .card-footer {
background-color: rgba($black, .1); background-color: rgba($black, .1);
} }

&.card-outline-tabs .card-header a:hover { &.card-outline-tabs .card-header a:hover {
border-color: $gray-600; border-color: $gray-600;
border-bottom-color: transparent; border-bottom-color: transparent;
} }

&:not(.card-outline) > .card-header a.active { &:not(.card-outline) > .card-header a.active {
color: $white; color: $white;
} }


.card-comments { .card-comments {
background-color: lighten($dark, 1.25%); background-color: lighten($dark, 1.25%);

.username { .username {
color: $gray-400; color: $gray-400;
} }

.card-comment { .card-comment {
border-bottom-color: lighten($dark, 7.5%); border-bottom-color: lighten($dark, 7.5%);
} }

+ 1
- 0
SecureSharing/wwwroot/build/scss/_carousel.scss Vedi File

.carousel-control-prev & { .carousel-control-prev & {
margin-left: -20px; margin-left: -20px;
} }

.carousel-control-next & { .carousel-control-next & {
margin-right: 20px; margin-right: 20px;
} }

+ 1
- 0
SecureSharing/wwwroot/build/scss/_colors.scss Vedi File

background-color: lighten($dark, 7.5%) !important; background-color: lighten($dark, 7.5%) !important;
color: $white !important; color: $white !important;
} }

.text-black, .text-black,
.text-dark, .text-dark,
.link-black, .link-black,

+ 5
- 3
SecureSharing/wwwroot/build/scss/_direct-chat.scss Vedi File

} }


.direct-chat-msg { .direct-chat-msg {
@include clearfix ();
@include clearfix();
margin-bottom: 10px; margin-bottom: 10px;
} }




//Contacts list -- for displaying contacts in direct chat contacts pane //Contacts list -- for displaying contacts in direct chat contacts pane
.contacts-list { .contacts-list {
@include list-unstyled ();
@include list-unstyled();


> li { > li {
@include clearfix ();
@include clearfix();
border-bottom: 1px solid rgba($black, .2); border-bottom: 1px solid rgba($black, .2);
margin: 0; margin: 0;
padding: 10px; padding: 10px;
border-right-color: lighten($dark, 10%); border-right-color: lighten($dark, 10%);
} }
} }

.direct-chat-timestamp { .direct-chat-timestamp {
color: $gray-500; color: $gray-500;
} }

.right > .direct-chat-text { .right > .direct-chat-text {
&::after, &::after,
&::before { &::before {

+ 11
- 3
SecureSharing/wwwroot/build/scss/_dropdown.scss Vedi File

position: relative; position: relative;


> a::after { > a::after {
@include caret-right ();
@include caret-right();
float: right; float: right;
margin-left: .5rem; margin-left: .5rem;
margin-top: .5rem; margin-top: .5rem;
.navbar-custom-menu > .navbar-nav { .navbar-custom-menu > .navbar-nav {
> li { > li {
position: relative; position: relative;

> .dropdown-menu { > .dropdown-menu {
position: absolute; position: absolute;
right: 0; right: 0;
@include media-breakpoint-down(sm) { @include media-breakpoint-down(sm) {
.navbar-custom-menu > .navbar-nav { .navbar-custom-menu > .navbar-nav {
float: right; float: right;

> li { > li {
position: static; position: static;

> .dropdown-menu { > .dropdown-menu {
position: absolute; position: absolute;
right: 5%; right: 5%;


// Menu Body // Menu Body
> .user-body { > .user-body {
@include clearfix ();
@include clearfix();
border-bottom: 1px solid $gray-700; border-bottom: 1px solid $gray-700;
border-top: 1px solid $gray-300; border-top: 1px solid $gray-300;
padding: 15px; padding: 15px;


// Menu Footer // Menu Footer
> .user-footer { > .user-footer {
@include clearfix ();
@include clearfix();
background-color: $gray-100; background-color: $gray-100;
padding: 10px; padding: 10px;


background-color: $dark; background-color: $dark;
color: $white; color: $white;
} }

.dropdown-item { .dropdown-item {
color: $white; color: $white;


background-color: lighten($dark, 5%); background-color: lighten($dark, 5%);
} }
} }

.dropdown-divider { .dropdown-divider {
border-color: $gray-600; border-color: $gray-600;
} }
background-color: lighten($dark, 5%); background-color: lighten($dark, 5%);
color: $gray-300; color: $gray-300;
} }

&:focus { &:focus {
background-color: lighten($dark, 7.5%); background-color: lighten($dark, 7.5%);
} }
} }
} }

> .user-body { > .user-body {
border-color: $gray-600; border-color: $gray-600;
} }

> .user-body a { > .user-body a {
background-color: transparent !important; background-color: transparent !important;
color: $white !important; color: $white !important;

+ 8
- 0
SecureSharing/wwwroot/build/scss/_forms.scss Vedi File

&.border-width-2 { &.border-width-2 {
border-bottom-width: 2px; border-bottom-width: 2px;
} }

&.border-width-3 { &.border-width-3 {
border-bottom-width: 3px; border-bottom-width: 3px;
} }
background-color: transparent !important; background-color: transparent !important;
box-shadow: none; box-shadow: none;
} }

&:checked ~ .custom-control-label::before { &:checked ~ .custom-control-label::before {
@include gradient-bg(transparent); @include gradient-bg(transparent);
} }
border: 1px solid lighten($sidebar-dark-bg, 15%); border: 1px solid lighten($sidebar-dark-bg, 15%);
color: lighten(color-yiq(lighten($sidebar-dark-bg, 5%)), 15%); color: lighten(color-yiq(lighten($sidebar-dark-bg, 5%)), 15%);
} }

.btn-navbar { .btn-navbar {
&:hover { &:hover {
background-color: lighten($sidebar-dark-bg, 7.5%); background-color: lighten($sidebar-dark-bg, 7.5%);
} }

&:focus { &:focus {
background-color: lighten($sidebar-dark-bg, 10%); background-color: lighten($sidebar-dark-bg, 10%);
} }
background-color: $dark; background-color: $dark;
color: $white; color: $white;
} }

.form-control:not(.form-control-navbar):not(.form-control-sidebar):not(.is-invalid):not(:focus), .form-control:not(.form-control-navbar):not(.form-control-sidebar):not(.is-invalid):not(:focus),
.custom-file-label, .custom-file-label,
.custom-file-label::after { .custom-file-label::after {
border-color: $gray-600; border-color: $gray-600;
} }

select { select {
background-color: $dark; background-color: $dark;
color: $white; color: $white;
&::-webkit-slider-runnable-track { &::-webkit-slider-runnable-track {
background-color: lighten($dark, 7.5%); background-color: lighten($dark, 7.5%);
} }

&::-moz-range-track { &::-moz-range-track {
background-color: lighten($dark, 7.5%); background-color: lighten($dark, 7.5%);
} }

&::-ms-track { &::-ms-track {
background-color: lighten($dark, 7.5%); background-color: lighten($dark, 7.5%);
} }

+ 2
- 0
SecureSharing/wwwroot/build/scss/_layout.scss Vedi File

color: $gray-500; color: $gray-500;
} }
} }

.main-footer { .main-footer {
background-color: $dark; background-color: $dark;
border-color: lighten($dark, 10%); border-color: lighten($dark, 10%);
} }

.content-wrapper { .content-wrapper {
background-color: lighten($dark, 7.5%); background-color: lighten($dark, 7.5%);
color: $white; color: $white;

+ 5
- 3
SecureSharing/wwwroot/build/scss/_main-sidebar.scss Vedi File

// Hover and active states // Hover and active states
&.menu-open > .nav-link, &.menu-open > .nav-link,
&:hover > .nav-link, &:hover > .nav-link,
> .nav-link:focus {
> .nav-link:focus {
background-color: $sidebar-dark-hover-bg; background-color: $sidebar-dark-hover-bg;
color: $sidebar-dark-hover-color; color: $sidebar-dark-hover-color;
} }
} }


&.active { &.active {
> .nav-icon{
> .nav-icon {
margin-left: .36rem; margin-left: .36rem;
} }
} }
} }


&.active { &.active {
> .nav-icon{
> .nav-icon {
margin-left: calc(.75rem - 3px); margin-left: calc(.75rem - 3px);
} }
} }
width: 100%; width: 100%;
flex-wrap: nowrap; flex-wrap: nowrap;
} }

.sidebar nav .form-inline { .sidebar nav .form-inline {
margin-bottom: .2rem; margin-bottom: .2rem;
} }
&.sidebar-collapse .main-sidebar { &.sidebar-collapse .main-sidebar {
margin-left: 0; margin-left: 0;
} }

.content-wrapper, .content-wrapper,
.main-header, .main-header,
.main-footer { .main-footer {

+ 6
- 0
SecureSharing/wwwroot/build/scss/_miscellaneous.scss Vedi File

// Box overlay for LOADING STATE effect on Tab Panels // Box overlay for LOADING STATE effect on Tab Panels
> .overlay-wrapper { > .overlay-wrapper {
position: relative; position: relative;

> .overlay { > .overlay {
border-top-left-radius: 0; border-top-left-radius: 0;
border-top-right-radius: 0; border-top-right-radius: 0;
a:not(.btn):hover { a:not(.btn):hover {
color: lighten($link-color, 10%); color: lighten($link-color, 10%);
} }

.attachment-block { .attachment-block {
background-color: lighten($dark, 3.75%); background-color: lighten($dark, 3.75%);


color: $gray-400; color: $gray-400;
} }
} }

blockquote { blockquote {
background-color: lighten($dark, 5%); background-color: lighten($dark, 5%);


} }
} }
} }

.close, .close,
.mailbox-attachment-close { .mailbox-attachment-close {
color: $gray-500; color: $gray-500;
text-shadow: 0 1px 0 $gray-700; text-shadow: 0 1px 0 $gray-700;
} }

.tab-custom-content { .tab-custom-content {
border-color: $gray-600; border-color: $gray-600;
} }

.list-group-item { .list-group-item {
background-color: $dark; background-color: $dark;
border-color: $gray-600; border-color: $gray-600;

+ 2
- 0
SecureSharing/wwwroot/build/scss/_modals.scss Vedi File

.modal-footer { .modal-footer {
border-color: $gray-600; border-color: $gray-600;
} }

.modal-content { .modal-content {
background-color: $dark; background-color: $dark;


.modal-footer { .modal-footer {
border-color: $gray-600; border-color: $gray-600;
} }

.close { .close {
color: $dark !important; color: $dark !important;
text-shadow: 0 1px 0 $gray-700 !important; text-shadow: 0 1px 0 $gray-700 !important;

+ 5
- 2
SecureSharing/wwwroot/build/scss/_navs.scss Vedi File

border-top-right-radius: 0; border-top-right-radius: 0;
margin-right: -$nav-tabs-border-width; margin-right: -$nav-tabs-border-width;


@include hover-focus () {
@include hover-focus() {
border-color: $gray-200 transparent $gray-200 $gray-200; border-color: $gray-200 transparent $gray-200 $gray-200;
} }
} }
border-top-right-radius: $nav-tabs-border-radius; border-top-right-radius: $nav-tabs-border-radius;
margin-left: -$nav-tabs-border-width; margin-left: -$nav-tabs-border-width;


@include hover-focus () {
@include hover-focus() {
border-color: $gray-200 $gray-200 $gray-200 transparent; border-color: $gray-200 $gray-200 $gray-200 transparent;
} }
} }
&:hover { &:hover {
border-color: lighten($dark, 15%) transparent lighten($dark, 15%) lighten($dark, 15%); border-color: lighten($dark, 15%) transparent lighten($dark, 15%) lighten($dark, 15%);
} }

&:focus, &:focus,
&:hover { &:hover {
background-color: lighten($dark, 5%); background-color: lighten($dark, 5%);
} }
} }

&.nav-tabs-right { &.nav-tabs-right {
border-color: lighten($dark, 15%); border-color: lighten($dark, 15%);

.nav-link { .nav-link {
&.active, &.active,
&:focus, &:focus,

+ 5
- 0
SecureSharing/wwwroot/build/scss/_pagination.scss Vedi File

flex-direction: column; flex-direction: column;
box-shadow: none; box-shadow: none;
} }

&:first-child, &:first-child,
&:last-child { &:last-child {
.page-link { .page-link {
font-size: $font-size-lg; font-size: $font-size-lg;
} }
} }

.page-month { .page-month {
margin-bottom: 0; margin-bottom: 0;
font-size: $font-size-lg; font-size: $font-size-lg;
font-weight: $font-weight-bold; font-weight: $font-weight-bold;
} }

.page-year { .page-year {
margin-bottom: 0; margin-bottom: 0;
} }
font-size: ($font-size-lg * 1.25); font-size: ($font-size-lg * 1.25);
} }
} }

&.pagination-sm { &.pagination-sm {
.page-month { .page-month {
font-size: ($font-size-base); font-size: ($font-size-base);
} }
} }
} }

&:not(.active) { &:not(.active) {
.page-link { .page-link {
background-color: $dark; background-color: $dark;

+ 0
- 0
SecureSharing/wwwroot/build/scss/_products.scss Vedi File


Dato che sono stati cambiati molti file in questo diff, alcuni di essi non verranno mostrati

Loading…
Annulla
Salva