├── .config └── dotnet-tools.json ├── .editorconfig ├── .gitattributes ├── .github ├── FUNDING.yml ├── dependabot.yml ├── issue_template.md ├── lock.yml └── workflows │ ├── build.yml │ ├── codeql.yml │ └── codeql │ └── codeql-config.yml ├── .gitignore ├── ASPNETCore2CookieAuthentication.sln ├── BannedSymbols.txt ├── Directory.Build.props ├── Directory.Packages.props ├── LICENSE.md ├── README.md ├── _buid.cmd ├── common └── AssemblyInfo.cs ├── global.json ├── src ├── ASPNETCore2CookieAuthentication.Common │ └── ASPNETCore2CookieAuthentication.Common.csproj ├── ASPNETCore2CookieAuthentication.DataLayer │ ├── ASPNETCore2CookieAuthentication.DataLayer.csproj │ ├── Context │ │ ├── ApplicationDbContext.cs │ │ ├── ApplicationDbContextFactory.cs │ │ └── IUnitOfWork.cs │ ├── Migrations │ │ ├── .editorconfig │ │ ├── 20230303073041_V2023_03_03_1100.Designer.cs │ │ ├── 20230303073041_V2023_03_03_1100.cs │ │ └── ApplicationDbContextModelSnapshot.cs │ ├── _01-add_migrations.cmd │ └── _02-update_db.cmd ├── ASPNETCore2CookieAuthentication.DomainClasses │ ├── ASPNETCore2CookieAuthentication.DomainClasses.csproj │ ├── Role.cs │ ├── User.cs │ └── UserRole.cs ├── ASPNETCore2CookieAuthentication.Services │ ├── ASPNETCore2CookieAuthentication.Services.csproj │ ├── CookieValidatorService.cs │ ├── CustomRoles.cs │ ├── DbInitializerService.cs │ ├── DeviceDetectionService.cs │ ├── ICookieValidatorService.cs │ ├── IDbInitializerService.cs │ ├── IDeviceDetectionService.cs │ ├── IRolesService.cs │ ├── ISecurityService.cs │ ├── IUsersService.cs │ ├── RolesService.cs │ ├── SecurityService.cs │ └── UsersService.cs └── ASPNETCore2CookieAuthentication.WebApp │ ├── ASPNETCore2CookieAuthentication.WebApp.csproj │ ├── Controllers │ ├── AccountController.cs │ ├── MyProtectedAdminApiController.cs │ └── MyProtectedApiController.cs │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── _0-restore.bat │ ├── _1-dotnet_run.bat │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── libman.json │ └── wwwroot │ ├── favicon.ico │ ├── images │ └── cookieauth.png │ ├── index.html │ └── lib │ ├── bootstrap │ ├── LICENSE │ ├── README.md │ ├── dist │ │ ├── css │ │ │ ├── bootstrap-grid.css │ │ │ ├── bootstrap-grid.css.map │ │ │ ├── bootstrap-grid.min.css │ │ │ ├── bootstrap-grid.min.css.map │ │ │ ├── bootstrap-grid.rtl.css │ │ │ ├── bootstrap-grid.rtl.css.map │ │ │ ├── bootstrap-grid.rtl.min.css │ │ │ ├── bootstrap-grid.rtl.min.css.map │ │ │ ├── bootstrap-reboot.css │ │ │ ├── bootstrap-reboot.css.map │ │ │ ├── bootstrap-reboot.min.css │ │ │ ├── bootstrap-reboot.min.css.map │ │ │ ├── bootstrap-reboot.rtl.css │ │ │ ├── bootstrap-reboot.rtl.css.map │ │ │ ├── bootstrap-reboot.rtl.min.css │ │ │ ├── bootstrap-reboot.rtl.min.css.map │ │ │ ├── bootstrap-utilities.css │ │ │ ├── bootstrap-utilities.css.map │ │ │ ├── bootstrap-utilities.min.css │ │ │ ├── bootstrap-utilities.min.css.map │ │ │ ├── bootstrap-utilities.rtl.css │ │ │ ├── bootstrap-utilities.rtl.css.map │ │ │ ├── bootstrap-utilities.rtl.min.css │ │ │ ├── bootstrap-utilities.rtl.min.css.map │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ ├── bootstrap.min.css │ │ │ ├── bootstrap.min.css.map │ │ │ ├── bootstrap.rtl.css │ │ │ ├── bootstrap.rtl.css.map │ │ │ ├── bootstrap.rtl.min.css │ │ │ └── bootstrap.rtl.min.css.map │ │ └── js │ │ │ ├── bootstrap.bundle.js │ │ │ ├── bootstrap.bundle.js.map │ │ │ ├── bootstrap.bundle.min.js │ │ │ ├── bootstrap.bundle.min.js.map │ │ │ ├── bootstrap.esm.js │ │ │ ├── bootstrap.esm.js.map │ │ │ ├── bootstrap.esm.min.js │ │ │ ├── bootstrap.esm.min.js.map │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.js.map │ │ │ ├── bootstrap.min.js │ │ │ └── bootstrap.min.js.map │ ├── js │ │ ├── dist │ │ │ ├── alert.js │ │ │ ├── alert.js.map │ │ │ ├── base-component.js │ │ │ ├── base-component.js.map │ │ │ ├── button.js │ │ │ ├── button.js.map │ │ │ ├── carousel.js │ │ │ ├── carousel.js.map │ │ │ ├── collapse.js │ │ │ ├── collapse.js.map │ │ │ ├── dom │ │ │ │ ├── data.js │ │ │ │ ├── data.js.map │ │ │ │ ├── event-handler.js │ │ │ │ ├── event-handler.js.map │ │ │ │ ├── manipulator.js │ │ │ │ ├── manipulator.js.map │ │ │ │ ├── selector-engine.js │ │ │ │ └── selector-engine.js.map │ │ │ ├── dropdown.js │ │ │ ├── dropdown.js.map │ │ │ ├── modal.js │ │ │ ├── modal.js.map │ │ │ ├── offcanvas.js │ │ │ ├── offcanvas.js.map │ │ │ ├── popover.js │ │ │ ├── popover.js.map │ │ │ ├── scrollspy.js │ │ │ ├── scrollspy.js.map │ │ │ ├── tab.js │ │ │ ├── tab.js.map │ │ │ ├── toast.js │ │ │ ├── toast.js.map │ │ │ ├── tooltip.js │ │ │ ├── tooltip.js.map │ │ │ └── util │ │ │ │ ├── backdrop.js │ │ │ │ ├── backdrop.js.map │ │ │ │ ├── component-functions.js │ │ │ │ ├── component-functions.js.map │ │ │ │ ├── config.js │ │ │ │ ├── config.js.map │ │ │ │ ├── focustrap.js │ │ │ │ ├── focustrap.js.map │ │ │ │ ├── index.js │ │ │ │ ├── index.js.map │ │ │ │ ├── sanitizer.js │ │ │ │ ├── sanitizer.js.map │ │ │ │ ├── scrollbar.js │ │ │ │ ├── scrollbar.js.map │ │ │ │ ├── swipe.js │ │ │ │ ├── swipe.js.map │ │ │ │ ├── template-factory.js │ │ │ │ └── template-factory.js.map │ │ └── src │ │ │ ├── alert.js │ │ │ ├── base-component.js │ │ │ ├── button.js │ │ │ ├── carousel.js │ │ │ ├── collapse.js │ │ │ ├── dom │ │ │ ├── data.js │ │ │ ├── event-handler.js │ │ │ ├── manipulator.js │ │ │ └── selector-engine.js │ │ │ ├── dropdown.js │ │ │ ├── modal.js │ │ │ ├── offcanvas.js │ │ │ ├── popover.js │ │ │ ├── scrollspy.js │ │ │ ├── tab.js │ │ │ ├── toast.js │ │ │ ├── tooltip.js │ │ │ └── util │ │ │ ├── backdrop.js │ │ │ ├── component-functions.js │ │ │ ├── config.js │ │ │ ├── focustrap.js │ │ │ ├── index.js │ │ │ ├── sanitizer.js │ │ │ ├── scrollbar.js │ │ │ ├── swipe.js │ │ │ └── template-factory.js │ ├── package.json │ └── scss │ │ ├── _accordion.scss │ │ ├── _alert.scss │ │ ├── _badge.scss │ │ ├── _breadcrumb.scss │ │ ├── _button-group.scss │ │ ├── _buttons.scss │ │ ├── _card.scss │ │ ├── _carousel.scss │ │ ├── _close.scss │ │ ├── _containers.scss │ │ ├── _dropdown.scss │ │ ├── _forms.scss │ │ ├── _functions.scss │ │ ├── _grid.scss │ │ ├── _helpers.scss │ │ ├── _images.scss │ │ ├── _list-group.scss │ │ ├── _maps.scss │ │ ├── _mixins.scss │ │ ├── _modal.scss │ │ ├── _nav.scss │ │ ├── _navbar.scss │ │ ├── _offcanvas.scss │ │ ├── _pagination.scss │ │ ├── _placeholders.scss │ │ ├── _popover.scss │ │ ├── _progress.scss │ │ ├── _reboot.scss │ │ ├── _root.scss │ │ ├── _spinners.scss │ │ ├── _tables.scss │ │ ├── _toasts.scss │ │ ├── _tooltip.scss │ │ ├── _transitions.scss │ │ ├── _type.scss │ │ ├── _utilities.scss │ │ ├── _variables.scss │ │ ├── bootstrap-grid.scss │ │ ├── bootstrap-reboot.scss │ │ ├── bootstrap-utilities.scss │ │ ├── bootstrap.scss │ │ ├── forms │ │ ├── _floating-labels.scss │ │ ├── _form-check.scss │ │ ├── _form-control.scss │ │ ├── _form-range.scss │ │ ├── _form-select.scss │ │ ├── _form-text.scss │ │ ├── _input-group.scss │ │ ├── _labels.scss │ │ └── _validation.scss │ │ ├── helpers │ │ ├── _clearfix.scss │ │ ├── _color-bg.scss │ │ ├── _colored-links.scss │ │ ├── _position.scss │ │ ├── _ratio.scss │ │ ├── _stacks.scss │ │ ├── _stretched-link.scss │ │ ├── _text-truncation.scss │ │ ├── _visually-hidden.scss │ │ └── _vr.scss │ │ ├── mixins │ │ ├── _alert.scss │ │ ├── _backdrop.scss │ │ ├── _banner.scss │ │ ├── _border-radius.scss │ │ ├── _box-shadow.scss │ │ ├── _breakpoints.scss │ │ ├── _buttons.scss │ │ ├── _caret.scss │ │ ├── _clearfix.scss │ │ ├── _color-scheme.scss │ │ ├── _container.scss │ │ ├── _deprecate.scss │ │ ├── _forms.scss │ │ ├── _gradients.scss │ │ ├── _grid.scss │ │ ├── _image.scss │ │ ├── _list-group.scss │ │ ├── _lists.scss │ │ ├── _pagination.scss │ │ ├── _reset-text.scss │ │ ├── _resize.scss │ │ ├── _table-variants.scss │ │ ├── _text-truncate.scss │ │ ├── _transition.scss │ │ ├── _utilities.scss │ │ └── _visually-hidden.scss │ │ ├── utilities │ │ └── _api.scss │ │ └── vendor │ │ └── _rfs.scss │ └── jquery │ ├── AUTHORS.txt │ ├── LICENSE.txt │ ├── README.md │ ├── bower.json │ ├── dist │ ├── jquery.js │ ├── jquery.min.js │ ├── jquery.min.map │ ├── jquery.slim.js │ ├── jquery.slim.min.js │ └── jquery.slim.min.map │ ├── external │ └── sizzle │ │ ├── LICENSE.txt │ │ └── dist │ │ ├── sizzle.js │ │ ├── sizzle.min.js │ │ └── sizzle.min.map │ ├── package.json │ └── src │ ├── ajax.js │ ├── ajax │ ├── jsonp.js │ ├── load.js │ ├── script.js │ ├── var │ │ ├── location.js │ │ ├── nonce.js │ │ └── rquery.js │ └── xhr.js │ ├── attributes.js │ ├── attributes │ ├── attr.js │ ├── classes.js │ ├── prop.js │ ├── support.js │ └── val.js │ ├── callbacks.js │ ├── core.js │ ├── core │ ├── DOMEval.js │ ├── access.js │ ├── camelCase.js │ ├── init.js │ ├── isAttached.js │ ├── nodeName.js │ ├── parseHTML.js │ ├── parseXML.js │ ├── ready-no-deferred.js │ ├── ready.js │ ├── readyException.js │ ├── stripAndCollapse.js │ ├── support.js │ ├── toType.js │ └── var │ │ └── rsingleTag.js │ ├── css.js │ ├── css │ ├── addGetHookIf.js │ ├── adjustCSS.js │ ├── curCSS.js │ ├── finalPropName.js │ ├── hiddenVisibleSelectors.js │ ├── showHide.js │ ├── support.js │ └── var │ │ ├── cssExpand.js │ │ ├── getStyles.js │ │ ├── isHiddenWithinTree.js │ │ ├── rboxStyle.js │ │ ├── rcustomProp.js │ │ ├── rnumnonpx.js │ │ └── swap.js │ ├── data.js │ ├── data │ ├── Data.js │ └── var │ │ ├── acceptData.js │ │ ├── dataPriv.js │ │ └── dataUser.js │ ├── deferred.js │ ├── deferred │ └── exceptionHook.js │ ├── deprecated.js │ ├── deprecated │ ├── ajax-event-alias.js │ └── event.js │ ├── dimensions.js │ ├── effects.js │ ├── effects │ ├── Tween.js │ └── animatedSelector.js │ ├── event.js │ ├── event │ ├── focusin.js │ ├── support.js │ └── trigger.js │ ├── exports │ ├── amd.js │ └── global.js │ ├── jquery.js │ ├── manipulation.js │ ├── manipulation │ ├── _evalUrl.js │ ├── buildFragment.js │ ├── getAll.js │ ├── setGlobalEval.js │ ├── support.js │ ├── var │ │ ├── rscriptType.js │ │ └── rtagName.js │ └── wrapMap.js │ ├── offset.js │ ├── queue.js │ ├── queue │ └── delay.js │ ├── selector-native.js │ ├── selector-sizzle.js │ ├── selector.js │ ├── serialize.js │ ├── traversing.js │ ├── traversing │ ├── findFilter.js │ └── var │ │ ├── dir.js │ │ ├── rneedsContext.js │ │ └── siblings.js │ ├── var │ ├── ObjectFunctionString.js │ ├── arr.js │ ├── class2type.js │ ├── document.js │ ├── documentElement.js │ ├── flat.js │ ├── fnToString.js │ ├── getProto.js │ ├── hasOwn.js │ ├── indexOf.js │ ├── isFunction.js │ ├── isWindow.js │ ├── pnum.js │ ├── push.js │ ├── rcheckableType.js │ ├── rcssNum.js │ ├── rnothtmlwhite.js │ ├── rtrimCSS.js │ ├── slice.js │ ├── support.js │ ├── toString.js │ └── whitespace.js │ └── wrap.js ├── tag-it.bat └── update-dependencies.bat /.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-ef": { 6 | "version": "9.0.0", 7 | "commands": [ 8 | "dotnet-ef" 9 | ] 10 | }, 11 | "microsoft.web.librarymanager.cli": { 12 | "version": "2.1.175", 13 | "commands": [ 14 | "libman" 15 | ] 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: ['https://www.coffeete.ir/vnasiri', 'https://www.buymeacoffee.com/vahidn'] 13 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: nuget 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | open-pull-requests-limit: 10 8 | groups: 9 | tests: 10 | patterns: ["*"] 11 | update-types: ["minor", "patch"] 12 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | # Summary of the issue 2 | 3 | 4 | 5 | ## Environment 6 | 7 | ``` 8 | .NET Core version: 9 | ``` 10 | 11 | ## Example code/Steps to reproduce: 12 | 13 | ``` 14 | paste your core code 15 | ``` 16 | 17 | ## Output: 18 | 19 | ``` 20 | Exception message: 21 | Full Stack trace: 22 | ``` 23 | 24 | -------------------------------------------------------------------------------- /.github/lock.yml: -------------------------------------------------------------------------------- 1 | daysUntilLock: 90 2 | 3 | skipCreatedBefore: false 4 | 5 | exemptLabels: [] 6 | 7 | lockLabel: false 8 | 9 | lockComment: > 10 | This thread has been automatically locked since there has not been 11 | any recent activity after it was closed. Please open a new issue for 12 | related problems. 13 | 14 | setLockReason: true 15 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: .NET Core Build 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v4 12 | - name: Setup .NET Core 13 | uses: actions/setup-dotnet@v3 14 | with: 15 | dotnet-version: 9.0.x 16 | - name: Build ASPNETCore2CookieAuthentication 17 | run: dotnet build ./src/ASPNETCore2CookieAuthentication.WebApp/ASPNETCore2CookieAuthentication.WebApp.csproj --configuration Release -------------------------------------------------------------------------------- /.github/workflows/codeql/codeql-config.yml: -------------------------------------------------------------------------------- 1 | name: "Security and Quality" 2 | 3 | queries: 4 | - uses: security-and-quality 5 | 6 | query-filters: 7 | - exclude: 8 | id: cs/useless-if-statement 9 | - exclude: 10 | id: cs/empty-block 11 | -------------------------------------------------------------------------------- /BannedSymbols.txt: -------------------------------------------------------------------------------- 1 | # https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.BannedApiAnalyzers/BannedApiAnalyzers.Help.md 2 | P:System.DateTime.Now;Use System.DateTime.UtcNow instead 3 | P:System.DateTimeOffset.Now;Use System.DateTimeOffset.UtcNow instead 4 | P:System.DateTimeOffset.DateTime;Use System.DateTimeOffset.UtcDateTime instead 5 | -------------------------------------------------------------------------------- /Directory.Packages.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Cookie Authentication without ASP.NET Core Identity 9x 2 | =========== 3 | 4 |

5 | 6 | GitHub Actions status 7 | 8 |

9 | 10 | 11 | ![cookieauth](/src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/images/cookieauth.png) 12 | 13 | A cookie based authentication sample for ASP.NET Core 9x without using the Identity system. It includes: 14 | 15 | - Users and Roles tables with a many-to-may relationship. 16 | - A separated EF Core data layer with enabled migrations. 17 | - An EF Core 9x based service layer. 18 | - A Db initializer to seed the default database values. 19 | - An account controller with cookie and DB based login and logout capabilities. 20 | - 2 sample API controllers to show how user-roles can be applied and used. 21 | - A cookie validator service to show how to react to the server side changes to a user's info immediately. -------------------------------------------------------------------------------- /_buid.cmd: -------------------------------------------------------------------------------- 1 | dotnet build 2 | pause -------------------------------------------------------------------------------- /common/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | [assembly: CLSCompliant(false)] 2 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "9.0.100" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.Common/ASPNETCore2CookieAuthentication.Common.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net9.0 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.DataLayer/ASPNETCore2CookieAuthentication.DataLayer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net9.0 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | runtime; build; native; contentfiles; analyzers; buildtransitive 13 | all 14 | 15 | 16 | runtime; build; native; contentfiles; analyzers; buildtransitive 17 | all 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.DataLayer/Context/ApplicationDbContext.cs: -------------------------------------------------------------------------------- 1 | using ASPNETCore2CookieAuthentication.DomainClasses; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace ASPNETCore2CookieAuthentication.DataLayer.Context; 5 | 6 | public class ApplicationDbContext(DbContextOptions options) : DbContext(options), IUnitOfWork 7 | { 8 | public virtual DbSet Users { set; get; } = default!; 9 | 10 | public virtual DbSet Roles { set; get; } = default!; 11 | 12 | public virtual DbSet UserRoles { get; set; } = default!; 13 | 14 | protected override void OnModelCreating(ModelBuilder modelBuilder) 15 | { 16 | ArgumentNullException.ThrowIfNull(modelBuilder); 17 | 18 | // it should be placed here, otherwise it will rewrite the following settings! 19 | base.OnModelCreating(modelBuilder); 20 | 21 | // Custom application mappings 22 | modelBuilder.Entity(entity => 23 | { 24 | entity.Property(e => e.Username).HasMaxLength(maxLength: 450).IsRequired(); 25 | entity.HasIndex(e => e.Username).IsUnique(); 26 | entity.Property(e => e.Password).IsRequired(); 27 | entity.Property(e => e.SerialNumber).HasMaxLength(maxLength: 450); 28 | }); 29 | 30 | modelBuilder.Entity(entity => 31 | { 32 | entity.Property(e => e.Name).HasMaxLength(maxLength: 450).IsRequired(); 33 | entity.HasIndex(e => e.Name).IsUnique(); 34 | }); 35 | 36 | modelBuilder.Entity(entity => 37 | { 38 | entity.HasKey(e => new 39 | { 40 | e.UserId, 41 | e.RoleId 42 | }); 43 | 44 | entity.HasIndex(e => e.UserId); 45 | entity.HasIndex(e => e.RoleId); 46 | entity.Property(e => e.UserId); 47 | entity.Property(e => e.RoleId); 48 | entity.HasOne(d => d.Role).WithMany(p => p.UserRoles).HasForeignKey(d => d.RoleId); 49 | entity.HasOne(d => d.User).WithMany(p => p.UserRoles).HasForeignKey(d => d.UserId); 50 | }); 51 | } 52 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.DataLayer/Context/ApplicationDbContextFactory.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using Microsoft.EntityFrameworkCore.Design; 3 | using Microsoft.Extensions.Configuration; 4 | 5 | namespace ASPNETCore2CookieAuthentication.DataLayer.Context; 6 | 7 | /// 8 | /// Only used by EF Tooling 9 | /// 10 | public class ApplicationDbContextFactory : IDesignTimeDbContextFactory 11 | { 12 | public ApplicationDbContext CreateDbContext(string[] args) 13 | { 14 | var basePath = Directory.GetCurrentDirectory(); 15 | WriteLine($"Using `{basePath}` as the BasePath"); 16 | 17 | var configuration = new ConfigurationBuilder().SetBasePath(basePath) 18 | .AddJsonFile(path: "appsettings.json") 19 | .Build(); 20 | 21 | var builder = new DbContextOptionsBuilder(); 22 | var connectionString = configuration.GetConnectionString(name: "DefaultConnection"); 23 | builder.UseSqlServer(connectionString); 24 | 25 | return new ApplicationDbContext(builder.Options); 26 | } 27 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.DataLayer/Context/IUnitOfWork.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace ASPNETCore2CookieAuthentication.DataLayer.Context; 4 | 5 | public interface IUnitOfWork : IDisposable 6 | { 7 | DbSet Set() where TEntity : class; 8 | 9 | int SaveChanges(bool acceptAllChangesOnSuccess); 10 | int SaveChanges(); 11 | Task SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = new()); 12 | Task SaveChangesAsync(CancellationToken cancellationToken = new()); 13 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.DataLayer/Migrations/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | generated_code = true 3 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.DataLayer/_01-add_migrations.cmd: -------------------------------------------------------------------------------- 1 | dotnet tool update --global dotnet-ef --version 9.0.0 2 | dotnet tool restore 3 | dotnet build 4 | For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c_%%a_%%b) 5 | For /f "tokens=1-2 delims=/:" %%a in ("%TIME: =0%") do (set mytime=%%a%%b) 6 | dotnet ef --verbose migrations --startup-project ../ASPNETCore2CookieAuthentication.WebApp/ add V%mydate%_%mytime% 7 | pause -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.DataLayer/_02-update_db.cmd: -------------------------------------------------------------------------------- 1 | dotnet tool update --global dotnet-ef --version 9.0.0 2 | dotnet tool restore 3 | dotnet build 4 | dotnet ef --startup-project ../ASPNETCore2CookieAuthentication.WebApp/ database update 5 | pause -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.DomainClasses/ASPNETCore2CookieAuthentication.DomainClasses.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net9.0 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.DomainClasses/Role.cs: -------------------------------------------------------------------------------- 1 | namespace ASPNETCore2CookieAuthentication.DomainClasses; 2 | 3 | public class Role 4 | { 5 | public Role() => UserRoles = []; 6 | 7 | public int Id { get; set; } 8 | 9 | public required string Name { get; set; } 10 | 11 | public virtual ICollection UserRoles { get; set; } 12 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.DomainClasses/User.cs: -------------------------------------------------------------------------------- 1 | namespace ASPNETCore2CookieAuthentication.DomainClasses; 2 | 3 | public class User 4 | { 5 | public User() => UserRoles = []; 6 | 7 | public int Id { get; set; } 8 | 9 | public required string Username { get; set; } 10 | 11 | public required string Password { get; set; } 12 | 13 | public string? DisplayName { get; set; } 14 | 15 | public bool IsActive { get; set; } 16 | 17 | public DateTimeOffset? LastLoggedIn { get; set; } 18 | 19 | /// 20 | /// every time the user changes his Password, 21 | /// or an admin changes his Roles or stat/IsActive, 22 | /// create a new `SerialNumber` GUID and store it in the DB. 23 | /// 24 | public string? SerialNumber { get; set; } 25 | 26 | public virtual ICollection UserRoles { get; set; } 27 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.DomainClasses/UserRole.cs: -------------------------------------------------------------------------------- 1 | namespace ASPNETCore2CookieAuthentication.DomainClasses; 2 | 3 | public class UserRole 4 | { 5 | public int UserId { get; set; } 6 | 7 | public int RoleId { get; set; } 8 | 9 | public virtual User User { get; set; } = default!; 10 | 11 | public virtual Role Role { get; set; } = default!; 12 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.Services/ASPNETCore2CookieAuthentication.Services.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net9.0 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.Services/CookieValidatorService.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Claims; 2 | using Microsoft.AspNetCore.Authentication; 3 | using Microsoft.AspNetCore.Authentication.Cookies; 4 | 5 | namespace ASPNETCore2CookieAuthentication.Services; 6 | 7 | public class CookieValidatorService(IUsersService usersService, IDeviceDetectionService deviceDetectionService) 8 | : ICookieValidatorService 9 | { 10 | private readonly IDeviceDetectionService _deviceDetectionService = 11 | deviceDetectionService ?? throw new ArgumentNullException(nameof(deviceDetectionService)); 12 | 13 | private readonly IUsersService 14 | _usersService = usersService ?? throw new ArgumentNullException(nameof(usersService)); 15 | 16 | public async Task ValidateAsync(CookieValidatePrincipalContext context) 17 | { 18 | ArgumentNullException.ThrowIfNull(context); 19 | 20 | var claimsIdentity = context.Principal?.Identity as ClaimsIdentity; 21 | 22 | if (claimsIdentity?.Claims == null || !claimsIdentity.Claims.Any()) 23 | { 24 | // this is not our issued cookie 25 | await HandleUnauthorizedRequest(context); 26 | 27 | return; 28 | } 29 | 30 | if (!_deviceDetectionService.HasUserTokenValidDeviceDetails(claimsIdentity)) 31 | { 32 | // Detected usage of an old token from a new device! Please login again! 33 | await HandleUnauthorizedRequest(context); 34 | 35 | return; 36 | } 37 | 38 | var serialNumberClaim = claimsIdentity.FindFirst(ClaimTypes.SerialNumber); 39 | 40 | if (serialNumberClaim == null) 41 | { 42 | // this is not our issued cookie 43 | await HandleUnauthorizedRequest(context); 44 | 45 | return; 46 | } 47 | 48 | var userIdString = claimsIdentity.FindFirst(ClaimTypes.UserData)?.Value; 49 | 50 | if (!int.TryParse(userIdString, NumberStyles.Number, CultureInfo.InvariantCulture, out var userId)) 51 | { 52 | // this is not our issued cookie 53 | await HandleUnauthorizedRequest(context); 54 | 55 | return; 56 | } 57 | 58 | var user = await _usersService.FindUserAsync(userId); 59 | 60 | if (user == null || !string.Equals(user.SerialNumber, serialNumberClaim.Value, StringComparison.Ordinal) || 61 | !user.IsActive) 62 | { 63 | // user has changed his/her password/roles/stat/IsActive 64 | await HandleUnauthorizedRequest(context); 65 | } 66 | 67 | await _usersService.UpdateUserLastActivityDateAsync(userId); 68 | } 69 | 70 | private static Task HandleUnauthorizedRequest(CookieValidatePrincipalContext context) 71 | { 72 | context.RejectPrincipal(); 73 | 74 | return context.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); 75 | } 76 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.Services/CustomRoles.cs: -------------------------------------------------------------------------------- 1 | namespace ASPNETCore2CookieAuthentication.Services; 2 | 3 | public static class CustomRoles 4 | { 5 | public const string Admin = nameof(Admin); 6 | public const string User = nameof(User); 7 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.Services/DbInitializerService.cs: -------------------------------------------------------------------------------- 1 | using ASPNETCore2CookieAuthentication.DataLayer.Context; 2 | using ASPNETCore2CookieAuthentication.DomainClasses; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.Extensions.DependencyInjection; 5 | 6 | namespace ASPNETCore2CookieAuthentication.Services; 7 | 8 | public class DbInitializerService(IServiceScopeFactory scopeFactory, ISecurityService securityService) 9 | : IDbInitializerService 10 | { 11 | private readonly IServiceScopeFactory _scopeFactory = 12 | scopeFactory ?? throw new ArgumentNullException(nameof(scopeFactory)); 13 | 14 | private readonly ISecurityService _securityService = 15 | securityService ?? throw new ArgumentNullException(nameof(securityService)); 16 | 17 | public void Initialize() 18 | { 19 | using var serviceScope = _scopeFactory.CreateScope(); 20 | 21 | using var context = serviceScope.ServiceProvider.GetService() ?? 22 | throw new InvalidOperationException(message: "context is null"); 23 | 24 | context.Database.Migrate(); 25 | } 26 | 27 | public void SeedData() 28 | { 29 | using var serviceScope = _scopeFactory.CreateScope(); 30 | 31 | using var context = serviceScope.ServiceProvider.GetService() ?? 32 | throw new InvalidOperationException(message: "context is null"); 33 | 34 | // Add default roles 35 | var adminRole = new Role 36 | { 37 | Name = CustomRoles.Admin 38 | }; 39 | 40 | var userRole = new Role 41 | { 42 | Name = CustomRoles.User 43 | }; 44 | 45 | if (!context.Roles.Any()) 46 | { 47 | context.Add(adminRole); 48 | context.Add(userRole); 49 | context.SaveChanges(); 50 | } 51 | 52 | // Add Admin user 53 | if (!context.Users.Any()) 54 | { 55 | var adminUser = new User 56 | { 57 | Username = "Vahid", 58 | DisplayName = "وحيد", 59 | IsActive = true, 60 | LastLoggedIn = null, 61 | Password = _securityService.GetSha256Hash(input: "1234"), 62 | SerialNumber = Guid.NewGuid().ToString(format: "N") 63 | }; 64 | 65 | context.Add(adminUser); 66 | context.SaveChanges(); 67 | 68 | context.Add(new UserRole 69 | { 70 | Role = adminRole, 71 | User = adminUser 72 | }); 73 | 74 | context.Add(new UserRole 75 | { 76 | Role = userRole, 77 | User = adminUser 78 | }); 79 | 80 | context.SaveChanges(); 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.Services/ICookieValidatorService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authentication.Cookies; 2 | 3 | namespace ASPNETCore2CookieAuthentication.Services; 4 | 5 | public interface ICookieValidatorService 6 | { 7 | Task ValidateAsync(CookieValidatePrincipalContext context); 8 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.Services/IDbInitializerService.cs: -------------------------------------------------------------------------------- 1 | namespace ASPNETCore2CookieAuthentication.Services; 2 | 3 | public interface IDbInitializerService 4 | { 5 | /// 6 | /// Applies any pending migrations for the context to the database. 7 | /// Will create the database if it does not already exist. 8 | /// 9 | void Initialize(); 10 | 11 | /// 12 | /// Adds some default values to the Db 13 | /// 14 | void SeedData(); 15 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.Services/IDeviceDetectionService.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Claims; 2 | using Microsoft.AspNetCore.Http; 3 | 4 | namespace ASPNETCore2CookieAuthentication.Services; 5 | 6 | public interface IDeviceDetectionService 7 | { 8 | string GetDeviceDetails(HttpContext? context); 9 | 10 | string GetCurrentRequestDeviceDetails(); 11 | 12 | string GetDeviceDetailsHash(HttpContext? context); 13 | 14 | string GetCurrentRequestDeviceDetailsHash(); 15 | 16 | string? GetUserTokenDeviceDetailsHash(ClaimsIdentity? claimsIdentity); 17 | 18 | string? GetCurrentUserTokenDeviceDetailsHash(); 19 | 20 | bool HasUserTokenValidDeviceDetails(ClaimsIdentity? claimsIdentity); 21 | 22 | bool HasCurrentUserTokenValidDeviceDetails(); 23 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.Services/IRolesService.cs: -------------------------------------------------------------------------------- 1 | using ASPNETCore2CookieAuthentication.DomainClasses; 2 | 3 | namespace ASPNETCore2CookieAuthentication.Services; 4 | 5 | public interface IRolesService 6 | { 7 | Task> FindUserRolesAsync(int userId); 8 | 9 | Task IsUserInRole(int userId, string roleName); 10 | 11 | Task> FindUsersInRoleAsync(string roleName); 12 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.Services/ISecurityService.cs: -------------------------------------------------------------------------------- 1 | namespace ASPNETCore2CookieAuthentication.Services; 2 | 3 | public interface ISecurityService 4 | { 5 | string GetSha256Hash(string input); 6 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.Services/IUsersService.cs: -------------------------------------------------------------------------------- 1 | using ASPNETCore2CookieAuthentication.DomainClasses; 2 | 3 | namespace ASPNETCore2CookieAuthentication.Services; 4 | 5 | public interface IUsersService 6 | { 7 | Task GetSerialNumberAsync(int userId); 8 | 9 | Task FindUserAsync(string username, string password); 10 | 11 | ValueTask FindUserAsync(int userId); 12 | 13 | Task UpdateUserLastActivityDateAsync(int userId); 14 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.Services/RolesService.cs: -------------------------------------------------------------------------------- 1 | using ASPNETCore2CookieAuthentication.DataLayer.Context; 2 | using ASPNETCore2CookieAuthentication.DomainClasses; 3 | using Microsoft.EntityFrameworkCore; 4 | 5 | namespace ASPNETCore2CookieAuthentication.Services; 6 | 7 | public class RolesService : IRolesService 8 | { 9 | private readonly DbSet _roles; 10 | private readonly DbSet _users; 11 | 12 | public RolesService(IUnitOfWork uow) 13 | { 14 | var unitOfWork = uow ?? throw new ArgumentNullException(nameof(uow)); 15 | _roles = unitOfWork.Set(); 16 | _users = unitOfWork.Set(); 17 | } 18 | 19 | public Task> FindUserRolesAsync(int userId) 20 | { 21 | var userRolesQuery = from role in _roles 22 | from userRoles in role.UserRoles 23 | where userRoles.UserId == userId 24 | select role; 25 | 26 | return userRolesQuery.OrderBy(x => x.Name).ToListAsync(); 27 | } 28 | 29 | public async Task IsUserInRole(int userId, string roleName) 30 | { 31 | var userRolesQuery = from role in _roles 32 | where role.Name == roleName 33 | from user in role.UserRoles 34 | where user.UserId == userId 35 | select role; 36 | 37 | var userRole = await userRolesQuery.FirstOrDefaultAsync(); 38 | 39 | return userRole != null; 40 | } 41 | 42 | public Task> FindUsersInRoleAsync(string roleName) 43 | { 44 | var roleUserIdsQuery = from role in _roles 45 | where role.Name == roleName 46 | from user in role.UserRoles 47 | select user.UserId; 48 | 49 | return _users.Where(user => roleUserIdsQuery.Contains(user.Id)).ToListAsync(); 50 | } 51 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.Services/SecurityService.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace ASPNETCore2CookieAuthentication.Services; 4 | 5 | public class SecurityService : ISecurityService 6 | { 7 | public string GetSha256Hash(string input) 8 | { 9 | var byteValue = Encoding.UTF8.GetBytes(input); 10 | var byteHash = SHA256.HashData(byteValue); 11 | 12 | return Convert.ToBase64String(byteHash); 13 | } 14 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.Services/UsersService.cs: -------------------------------------------------------------------------------- 1 | using ASPNETCore2CookieAuthentication.DataLayer.Context; 2 | using ASPNETCore2CookieAuthentication.DomainClasses; 3 | using Microsoft.EntityFrameworkCore; 4 | 5 | namespace ASPNETCore2CookieAuthentication.Services; 6 | 7 | public class UsersService : IUsersService 8 | { 9 | private readonly ISecurityService _securityService; 10 | private readonly IUnitOfWork _uow; 11 | private readonly DbSet _users; 12 | 13 | public UsersService(IUnitOfWork uow, ISecurityService securityService) 14 | { 15 | _uow = uow ?? throw new ArgumentNullException(nameof(uow)); 16 | _users = _uow.Set(); 17 | _securityService = securityService ?? throw new ArgumentNullException(nameof(securityService)); 18 | } 19 | 20 | public ValueTask FindUserAsync(int userId) => _users.FindAsync(userId); 21 | 22 | public Task FindUserAsync(string username, string password) 23 | { 24 | var passwordHash = _securityService.GetSha256Hash(password); 25 | 26 | return _users.FirstOrDefaultAsync(x => x.Username == username && x.Password == passwordHash); 27 | } 28 | 29 | public async Task GetSerialNumberAsync(int userId) 30 | { 31 | var user = await FindUserAsync(userId); 32 | 33 | return user?.SerialNumber; 34 | } 35 | 36 | public async Task UpdateUserLastActivityDateAsync(int userId) 37 | { 38 | var user = await FindUserAsync(userId); 39 | 40 | if (user is null) 41 | { 42 | return; 43 | } 44 | 45 | if (user.LastLoggedIn != null) 46 | { 47 | var updateLastActivityDate = TimeSpan.FromMinutes(value: 2); 48 | var currentUtc = DateTimeOffset.UtcNow; 49 | var timeElapsed = currentUtc.Subtract(user.LastLoggedIn.Value); 50 | 51 | if (timeElapsed < updateLastActivityDate) 52 | { 53 | return; 54 | } 55 | } 56 | 57 | user.LastLoggedIn = DateTimeOffset.UtcNow; 58 | await _uow.SaveChangesAsync(); 59 | } 60 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/ASPNETCore2CookieAuthentication.WebApp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net9.0 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | all 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/Controllers/MyProtectedAdminApiController.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Claims; 2 | using ASPNETCore2CookieAuthentication.Services; 3 | using Microsoft.AspNetCore.Authorization; 4 | using Microsoft.AspNetCore.Mvc; 5 | 6 | namespace ASPNETCore2CookieAuthentication.WebApp.Controllers; 7 | 8 | [ApiController] 9 | [Route(template: "api/[controller]")] 10 | [Authorize(Policy = CustomRoles.Admin)] 11 | public class MyProtectedAdminApiController(IUsersService usersService) : ControllerBase 12 | { 13 | private readonly IUsersService 14 | _usersService = usersService ?? throw new ArgumentNullException(nameof(usersService)); 15 | 16 | [HttpGet] 17 | public async Task Get() 18 | { 19 | var claimsIdentity = User.Identity as ClaimsIdentity; 20 | var userDataClaim = claimsIdentity?.FindFirst(ClaimTypes.UserData); 21 | var userId = userDataClaim?.Value; 22 | 23 | var id = userId is null ? 0 : int.Parse(userId, NumberStyles.Number, CultureInfo.InvariantCulture); 24 | 25 | return Ok(new 26 | { 27 | Id = 1, 28 | Title = "Hello from My Protected Admin Api Controller!", 29 | Username = User.Identity?.Name, 30 | UserData = userId, 31 | TokenSerialNumber = await _usersService.GetSerialNumberAsync(id) 32 | }); 33 | } 34 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/Controllers/MyProtectedApiController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using Microsoft.AspNetCore.Mvc; 3 | 4 | namespace ASPNETCore2CookieAuthentication.WebApp.Controllers; 5 | 6 | [ApiController] 7 | [Route(template: "api/[controller]")] 8 | [Authorize] 9 | public class MyProtectedApiController : ControllerBase 10 | { 11 | [HttpGet] 12 | public IActionResult Get() 13 | => Ok(new 14 | { 15 | Id = 1, 16 | Title = "Hello from My Protected Controller!", 17 | Username = User.Identity?.Name 18 | }); 19 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:3381/", 7 | "sslPort": 44381 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "AngularTemplateDrivenFormsLab": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "https://localhost:5001;http://localhost:5000" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/_0-restore.bat: -------------------------------------------------------------------------------- 1 | rmdir /S /Q bin 2 | rmdir /S /Q obj 3 | dotnet restore 4 | dotnet tool update -g Microsoft.Web.LibraryManager.Cli 5 | libman restore 6 | pause -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/_1-dotnet_run.bat: -------------------------------------------------------------------------------- 1 | dotnet watch run -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Warning" 6 | } 7 | }, 8 | "ConnectionStrings": { 9 | "DefaultConnection": "Data Source=(LocalDB)\\MSSQLLocalDB;Initial Catalog=ASPNETCore7CookieAuthenticationDB;Integrated Security=True;MultipleActiveResultSets=True;" 10 | }, 11 | "LoginCookieExpirationDays": 30 12 | } 13 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/libman.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0", 3 | "defaultProvider": "unpkg", 4 | "libraries": [ 5 | { 6 | "library":"bootstrap@5.2.3", 7 | "destination": "wwwroot/lib/bootstrap" 8 | }, 9 | { 10 | "library":"jquery@3.6.3", 11 | "destination": "wwwroot/lib/jquery" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VahidN/ASPNETCore2CookieAuthentication/0eb126359008e8fb314eb622229cd1bc689c72ec/src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/favicon.ico -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/images/cookieauth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VahidN/ASPNETCore2CookieAuthentication/0eb126359008e8fb314eb622229cd1bc689c72ec/src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/images/cookieauth.png -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2022 Twitter, Inc. 4 | Copyright (c) 2011-2022 The Bootstrap Authors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/js/dist/dom/data.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap data.js v5.2.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */ 6 | (function (global, factory) { 7 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 8 | typeof define === 'function' && define.amd ? define(factory) : 9 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Data = factory()); 10 | })(this, (function () { 'use strict'; 11 | 12 | /** 13 | * -------------------------------------------------------------------------- 14 | * Bootstrap (v5.2.3): dom/data.js 15 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 16 | * -------------------------------------------------------------------------- 17 | */ 18 | 19 | /** 20 | * Constants 21 | */ 22 | const elementMap = new Map(); 23 | const data = { 24 | set(element, key, instance) { 25 | if (!elementMap.has(element)) { 26 | elementMap.set(element, new Map()); 27 | } 28 | 29 | const instanceMap = elementMap.get(element); // make it clear we only want one instance per element 30 | // can be removed later when multiple key/instances are fine to be used 31 | 32 | if (!instanceMap.has(key) && instanceMap.size !== 0) { 33 | // eslint-disable-next-line no-console 34 | console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`); 35 | return; 36 | } 37 | 38 | instanceMap.set(key, instance); 39 | }, 40 | 41 | get(element, key) { 42 | if (elementMap.has(element)) { 43 | return elementMap.get(element).get(key) || null; 44 | } 45 | 46 | return null; 47 | }, 48 | 49 | remove(element, key) { 50 | if (!elementMap.has(element)) { 51 | return; 52 | } 53 | 54 | const instanceMap = elementMap.get(element); 55 | instanceMap.delete(key); // free up element references if there are no instances left for an element 56 | 57 | if (instanceMap.size === 0) { 58 | elementMap.delete(element); 59 | } 60 | } 61 | 62 | }; 63 | 64 | return data; 65 | 66 | })); 67 | //# sourceMappingURL=data.js.map 68 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/js/dist/dom/data.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"data.js","sources":["../../src/dom/data.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): dom/data.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n/**\n * Constants\n */\n\nconst elementMap = new Map()\n\nexport default {\n set(element, key, instance) {\n if (!elementMap.has(element)) {\n elementMap.set(element, new Map())\n }\n\n const instanceMap = elementMap.get(element)\n\n // make it clear we only want one instance per element\n // can be removed later when multiple key/instances are fine to be used\n if (!instanceMap.has(key) && instanceMap.size !== 0) {\n // eslint-disable-next-line no-console\n console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`)\n return\n }\n\n instanceMap.set(key, instance)\n },\n\n get(element, key) {\n if (elementMap.has(element)) {\n return elementMap.get(element).get(key) || null\n }\n\n return null\n },\n\n remove(element, key) {\n if (!elementMap.has(element)) {\n return\n }\n\n const instanceMap = elementMap.get(element)\n\n instanceMap.delete(key)\n\n // free up element references if there are no instances left for an element\n if (instanceMap.size === 0) {\n elementMap.delete(element)\n }\n }\n}\n"],"names":["elementMap","Map","set","element","key","instance","has","instanceMap","get","size","console","error","Array","from","keys","remove","delete"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EAEA,MAAMA,UAAU,GAAG,IAAIC,GAAJ,EAAnB,CAAA;AAEA,eAAe;EACbC,EAAAA,GAAG,CAACC,OAAD,EAAUC,GAAV,EAAeC,QAAf,EAAyB;EAC1B,IAAA,IAAI,CAACL,UAAU,CAACM,GAAX,CAAeH,OAAf,CAAL,EAA8B;EAC5BH,MAAAA,UAAU,CAACE,GAAX,CAAeC,OAAf,EAAwB,IAAIF,GAAJ,EAAxB,CAAA,CAAA;EACD,KAAA;;MAED,MAAMM,WAAW,GAAGP,UAAU,CAACQ,GAAX,CAAeL,OAAf,CAApB,CAL0B;EAQ1B;;EACA,IAAA,IAAI,CAACI,WAAW,CAACD,GAAZ,CAAgBF,GAAhB,CAAD,IAAyBG,WAAW,CAACE,IAAZ,KAAqB,CAAlD,EAAqD;EACnD;EACAC,MAAAA,OAAO,CAACC,KAAR,CAAe,CAAA,4EAAA,EAA8EC,KAAK,CAACC,IAAN,CAAWN,WAAW,CAACO,IAAZ,EAAX,CAA+B,CAAA,CAA/B,CAAkC,CAA/H,CAAA,CAAA,CAAA,CAAA;EACA,MAAA,OAAA;EACD,KAAA;;EAEDP,IAAAA,WAAW,CAACL,GAAZ,CAAgBE,GAAhB,EAAqBC,QAArB,CAAA,CAAA;KAhBW;;EAmBbG,EAAAA,GAAG,CAACL,OAAD,EAAUC,GAAV,EAAe;EAChB,IAAA,IAAIJ,UAAU,CAACM,GAAX,CAAeH,OAAf,CAAJ,EAA6B;QAC3B,OAAOH,UAAU,CAACQ,GAAX,CAAeL,OAAf,EAAwBK,GAAxB,CAA4BJ,GAA5B,CAAA,IAAoC,IAA3C,CAAA;EACD,KAAA;;EAED,IAAA,OAAO,IAAP,CAAA;KAxBW;;EA2BbW,EAAAA,MAAM,CAACZ,OAAD,EAAUC,GAAV,EAAe;EACnB,IAAA,IAAI,CAACJ,UAAU,CAACM,GAAX,CAAeH,OAAf,CAAL,EAA8B;EAC5B,MAAA,OAAA;EACD,KAAA;;EAED,IAAA,MAAMI,WAAW,GAAGP,UAAU,CAACQ,GAAX,CAAeL,OAAf,CAApB,CAAA;EAEAI,IAAAA,WAAW,CAACS,MAAZ,CAAmBZ,GAAnB,EAPmB;;EAUnB,IAAA,IAAIG,WAAW,CAACE,IAAZ,KAAqB,CAAzB,EAA4B;QAC1BT,UAAU,CAACgB,MAAX,CAAkBb,OAAlB,CAAA,CAAA;EACD,KAAA;EACF,GAAA;;EAxCY,CAAf;;;;;;;;"} -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/js/dist/dom/manipulator.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap manipulator.js v5.2.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */ 6 | (function (global, factory) { 7 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 8 | typeof define === 'function' && define.amd ? define(factory) : 9 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Manipulator = factory()); 10 | })(this, (function () { 'use strict'; 11 | 12 | /** 13 | * -------------------------------------------------------------------------- 14 | * Bootstrap (v5.2.3): dom/manipulator.js 15 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 16 | * -------------------------------------------------------------------------- 17 | */ 18 | function normalizeData(value) { 19 | if (value === 'true') { 20 | return true; 21 | } 22 | 23 | if (value === 'false') { 24 | return false; 25 | } 26 | 27 | if (value === Number(value).toString()) { 28 | return Number(value); 29 | } 30 | 31 | if (value === '' || value === 'null') { 32 | return null; 33 | } 34 | 35 | if (typeof value !== 'string') { 36 | return value; 37 | } 38 | 39 | try { 40 | return JSON.parse(decodeURIComponent(value)); 41 | } catch (_unused) { 42 | return value; 43 | } 44 | } 45 | 46 | function normalizeDataKey(key) { 47 | return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`); 48 | } 49 | 50 | const Manipulator = { 51 | setDataAttribute(element, key, value) { 52 | element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value); 53 | }, 54 | 55 | removeDataAttribute(element, key) { 56 | element.removeAttribute(`data-bs-${normalizeDataKey(key)}`); 57 | }, 58 | 59 | getDataAttributes(element) { 60 | if (!element) { 61 | return {}; 62 | } 63 | 64 | const attributes = {}; 65 | const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig')); 66 | 67 | for (const key of bsKeys) { 68 | let pureKey = key.replace(/^bs/, ''); 69 | pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length); 70 | attributes[pureKey] = normalizeData(element.dataset[key]); 71 | } 72 | 73 | return attributes; 74 | }, 75 | 76 | getDataAttribute(element, key) { 77 | return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`)); 78 | } 79 | 80 | }; 81 | 82 | return Manipulator; 83 | 84 | })); 85 | //# sourceMappingURL=manipulator.js.map 86 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/js/dist/util/component-functions.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap component-functions.js v5.2.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */ 6 | (function (global, factory) { 7 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('../dom/event-handler'), require('./index')) : 8 | typeof define === 'function' && define.amd ? define(['exports', '../dom/event-handler', './index'], factory) : 9 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ComponentFunctions = {}, global.EventHandler, global.Index)); 10 | })(this, (function (exports, EventHandler, index) { 'use strict'; 11 | 12 | const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e }; 13 | 14 | const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler); 15 | 16 | /** 17 | * -------------------------------------------------------------------------- 18 | * Bootstrap (v5.2.3): util/component-functions.js 19 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 20 | * -------------------------------------------------------------------------- 21 | */ 22 | 23 | const enableDismissTrigger = (component, method = 'hide') => { 24 | const clickEvent = `click.dismiss${component.EVENT_KEY}`; 25 | const name = component.NAME; 26 | EventHandler__default.default.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) { 27 | if (['A', 'AREA'].includes(this.tagName)) { 28 | event.preventDefault(); 29 | } 30 | 31 | if (index.isDisabled(this)) { 32 | return; 33 | } 34 | 35 | const target = index.getElementFromSelector(this) || this.closest(`.${name}`); 36 | const instance = component.getOrCreateInstance(target); // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method 37 | 38 | instance[method](); 39 | }); 40 | }; 41 | 42 | exports.enableDismissTrigger = enableDismissTrigger; 43 | 44 | Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } }); 45 | 46 | })); 47 | //# sourceMappingURL=component-functions.js.map 48 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/js/dist/util/component-functions.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"component-functions.js","sources":["../../src/util/component-functions.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/component-functions.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler'\nimport { getElementFromSelector, isDisabled } from './index'\n\nconst enableDismissTrigger = (component, method = 'hide') => {\n const clickEvent = `click.dismiss${component.EVENT_KEY}`\n const name = component.NAME\n\n EventHandler.on(document, clickEvent, `[data-bs-dismiss=\"${name}\"]`, function (event) {\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault()\n }\n\n if (isDisabled(this)) {\n return\n }\n\n const target = getElementFromSelector(this) || this.closest(`.${name}`)\n const instance = component.getOrCreateInstance(target)\n\n // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method\n instance[method]()\n })\n}\n\nexport {\n enableDismissTrigger\n}\n"],"names":["enableDismissTrigger","component","method","clickEvent","EVENT_KEY","name","NAME","EventHandler","on","document","event","includes","tagName","preventDefault","isDisabled","target","getElementFromSelector","closest","instance","getOrCreateInstance"],"mappings":";;;;;;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;AAKMA,QAAAA,oBAAoB,GAAG,CAACC,SAAD,EAAYC,MAAM,GAAG,MAArB,KAAgC;EAC3D,EAAA,MAAMC,UAAU,GAAI,CAAA,aAAA,EAAeF,SAAS,CAACG,SAAU,CAAvD,CAAA,CAAA;EACA,EAAA,MAAMC,IAAI,GAAGJ,SAAS,CAACK,IAAvB,CAAA;EAEAC,EAAAA,6BAAY,CAACC,EAAb,CAAgBC,QAAhB,EAA0BN,UAA1B,EAAuC,CAAA,kBAAA,EAAoBE,IAAK,CAAA,EAAA,CAAhE,EAAqE,UAAUK,KAAV,EAAiB;MACpF,IAAI,CAAC,GAAD,EAAM,MAAN,CAAA,CAAcC,QAAd,CAAuB,IAAA,CAAKC,OAA5B,CAAJ,EAA0C;EACxCF,MAAAA,KAAK,CAACG,cAAN,EAAA,CAAA;EACD,KAAA;;EAED,IAAA,IAAIC,gBAAU,CAAC,IAAD,CAAd,EAAsB;EACpB,MAAA,OAAA;EACD,KAAA;;EAED,IAAA,MAAMC,MAAM,GAAGC,4BAAsB,CAAC,IAAD,CAAtB,IAAgC,IAAA,CAAKC,OAAL,CAAc,CAAGZ,CAAAA,EAAAA,IAAK,EAAtB,CAA/C,CAAA;MACA,MAAMa,QAAQ,GAAGjB,SAAS,CAACkB,mBAAV,CAA8BJ,MAA9B,CAAjB,CAVoF;;MAapFG,QAAQ,CAAChB,MAAD,CAAR,EAAA,CAAA;KAbF,CAAA,CAAA;EAeD;;;;;;;;;;"} -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/js/src/alert.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.2.3): alert.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | import { defineJQueryPlugin } from './util/index' 9 | import EventHandler from './dom/event-handler' 10 | import BaseComponent from './base-component' 11 | import { enableDismissTrigger } from './util/component-functions' 12 | 13 | /** 14 | * Constants 15 | */ 16 | 17 | const NAME = 'alert' 18 | const DATA_KEY = 'bs.alert' 19 | const EVENT_KEY = `.${DATA_KEY}` 20 | 21 | const EVENT_CLOSE = `close${EVENT_KEY}` 22 | const EVENT_CLOSED = `closed${EVENT_KEY}` 23 | const CLASS_NAME_FADE = 'fade' 24 | const CLASS_NAME_SHOW = 'show' 25 | 26 | /** 27 | * Class definition 28 | */ 29 | 30 | class Alert extends BaseComponent { 31 | // Getters 32 | static get NAME() { 33 | return NAME 34 | } 35 | 36 | // Public 37 | close() { 38 | const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE) 39 | 40 | if (closeEvent.defaultPrevented) { 41 | return 42 | } 43 | 44 | this._element.classList.remove(CLASS_NAME_SHOW) 45 | 46 | const isAnimated = this._element.classList.contains(CLASS_NAME_FADE) 47 | this._queueCallback(() => this._destroyElement(), this._element, isAnimated) 48 | } 49 | 50 | // Private 51 | _destroyElement() { 52 | this._element.remove() 53 | EventHandler.trigger(this._element, EVENT_CLOSED) 54 | this.dispose() 55 | } 56 | 57 | // Static 58 | static jQueryInterface(config) { 59 | return this.each(function () { 60 | const data = Alert.getOrCreateInstance(this) 61 | 62 | if (typeof config !== 'string') { 63 | return 64 | } 65 | 66 | if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 67 | throw new TypeError(`No method named "${config}"`) 68 | } 69 | 70 | data[config](this) 71 | }) 72 | } 73 | } 74 | 75 | /** 76 | * Data API implementation 77 | */ 78 | 79 | enableDismissTrigger(Alert, 'close') 80 | 81 | /** 82 | * jQuery 83 | */ 84 | 85 | defineJQueryPlugin(Alert) 86 | 87 | export default Alert 88 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/js/src/base-component.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.2.3): base-component.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | import Data from './dom/data' 9 | import { executeAfterTransition, getElement } from './util/index' 10 | import EventHandler from './dom/event-handler' 11 | import Config from './util/config' 12 | 13 | /** 14 | * Constants 15 | */ 16 | 17 | const VERSION = '5.2.3' 18 | 19 | /** 20 | * Class definition 21 | */ 22 | 23 | class BaseComponent extends Config { 24 | constructor(element, config) { 25 | super() 26 | 27 | element = getElement(element) 28 | if (!element) { 29 | return 30 | } 31 | 32 | this._element = element 33 | this._config = this._getConfig(config) 34 | 35 | Data.set(this._element, this.constructor.DATA_KEY, this) 36 | } 37 | 38 | // Public 39 | dispose() { 40 | Data.remove(this._element, this.constructor.DATA_KEY) 41 | EventHandler.off(this._element, this.constructor.EVENT_KEY) 42 | 43 | for (const propertyName of Object.getOwnPropertyNames(this)) { 44 | this[propertyName] = null 45 | } 46 | } 47 | 48 | _queueCallback(callback, element, isAnimated = true) { 49 | executeAfterTransition(callback, element, isAnimated) 50 | } 51 | 52 | _getConfig(config) { 53 | config = this._mergeConfigObj(config, this._element) 54 | config = this._configAfterMerge(config) 55 | this._typeCheckConfig(config) 56 | return config 57 | } 58 | 59 | // Static 60 | static getInstance(element) { 61 | return Data.get(getElement(element), this.DATA_KEY) 62 | } 63 | 64 | static getOrCreateInstance(element, config = {}) { 65 | return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null) 66 | } 67 | 68 | static get VERSION() { 69 | return VERSION 70 | } 71 | 72 | static get DATA_KEY() { 73 | return `bs.${this.NAME}` 74 | } 75 | 76 | static get EVENT_KEY() { 77 | return `.${this.DATA_KEY}` 78 | } 79 | 80 | static eventName(name) { 81 | return `${name}${this.EVENT_KEY}` 82 | } 83 | } 84 | 85 | export default BaseComponent 86 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/js/src/button.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.2.3): button.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | import { defineJQueryPlugin } from './util/index' 9 | import EventHandler from './dom/event-handler' 10 | import BaseComponent from './base-component' 11 | 12 | /** 13 | * Constants 14 | */ 15 | 16 | const NAME = 'button' 17 | const DATA_KEY = 'bs.button' 18 | const EVENT_KEY = `.${DATA_KEY}` 19 | const DATA_API_KEY = '.data-api' 20 | 21 | const CLASS_NAME_ACTIVE = 'active' 22 | const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="button"]' 23 | const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` 24 | 25 | /** 26 | * Class definition 27 | */ 28 | 29 | class Button extends BaseComponent { 30 | // Getters 31 | static get NAME() { 32 | return NAME 33 | } 34 | 35 | // Public 36 | toggle() { 37 | // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method 38 | this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE)) 39 | } 40 | 41 | // Static 42 | static jQueryInterface(config) { 43 | return this.each(function () { 44 | const data = Button.getOrCreateInstance(this) 45 | 46 | if (config === 'toggle') { 47 | data[config]() 48 | } 49 | }) 50 | } 51 | } 52 | 53 | /** 54 | * Data API implementation 55 | */ 56 | 57 | EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => { 58 | event.preventDefault() 59 | 60 | const button = event.target.closest(SELECTOR_DATA_TOGGLE) 61 | const data = Button.getOrCreateInstance(button) 62 | 63 | data.toggle() 64 | }) 65 | 66 | /** 67 | * jQuery 68 | */ 69 | 70 | defineJQueryPlugin(Button) 71 | 72 | export default Button 73 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/js/src/dom/data.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.2.3): dom/data.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | /** 9 | * Constants 10 | */ 11 | 12 | const elementMap = new Map() 13 | 14 | export default { 15 | set(element, key, instance) { 16 | if (!elementMap.has(element)) { 17 | elementMap.set(element, new Map()) 18 | } 19 | 20 | const instanceMap = elementMap.get(element) 21 | 22 | // make it clear we only want one instance per element 23 | // can be removed later when multiple key/instances are fine to be used 24 | if (!instanceMap.has(key) && instanceMap.size !== 0) { 25 | // eslint-disable-next-line no-console 26 | console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`) 27 | return 28 | } 29 | 30 | instanceMap.set(key, instance) 31 | }, 32 | 33 | get(element, key) { 34 | if (elementMap.has(element)) { 35 | return elementMap.get(element).get(key) || null 36 | } 37 | 38 | return null 39 | }, 40 | 41 | remove(element, key) { 42 | if (!elementMap.has(element)) { 43 | return 44 | } 45 | 46 | const instanceMap = elementMap.get(element) 47 | 48 | instanceMap.delete(key) 49 | 50 | // free up element references if there are no instances left for an element 51 | if (instanceMap.size === 0) { 52 | elementMap.delete(element) 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/js/src/dom/manipulator.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.2.3): dom/manipulator.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | function normalizeData(value) { 9 | if (value === 'true') { 10 | return true 11 | } 12 | 13 | if (value === 'false') { 14 | return false 15 | } 16 | 17 | if (value === Number(value).toString()) { 18 | return Number(value) 19 | } 20 | 21 | if (value === '' || value === 'null') { 22 | return null 23 | } 24 | 25 | if (typeof value !== 'string') { 26 | return value 27 | } 28 | 29 | try { 30 | return JSON.parse(decodeURIComponent(value)) 31 | } catch { 32 | return value 33 | } 34 | } 35 | 36 | function normalizeDataKey(key) { 37 | return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`) 38 | } 39 | 40 | const Manipulator = { 41 | setDataAttribute(element, key, value) { 42 | element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value) 43 | }, 44 | 45 | removeDataAttribute(element, key) { 46 | element.removeAttribute(`data-bs-${normalizeDataKey(key)}`) 47 | }, 48 | 49 | getDataAttributes(element) { 50 | if (!element) { 51 | return {} 52 | } 53 | 54 | const attributes = {} 55 | const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig')) 56 | 57 | for (const key of bsKeys) { 58 | let pureKey = key.replace(/^bs/, '') 59 | pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length) 60 | attributes[pureKey] = normalizeData(element.dataset[key]) 61 | } 62 | 63 | return attributes 64 | }, 65 | 66 | getDataAttribute(element, key) { 67 | return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`)) 68 | } 69 | } 70 | 71 | export default Manipulator 72 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/js/src/dom/selector-engine.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.2.3): dom/selector-engine.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | import { isDisabled, isVisible } from '../util/index' 9 | 10 | /** 11 | * Constants 12 | */ 13 | 14 | const SelectorEngine = { 15 | find(selector, element = document.documentElement) { 16 | return [].concat(...Element.prototype.querySelectorAll.call(element, selector)) 17 | }, 18 | 19 | findOne(selector, element = document.documentElement) { 20 | return Element.prototype.querySelector.call(element, selector) 21 | }, 22 | 23 | children(element, selector) { 24 | return [].concat(...element.children).filter(child => child.matches(selector)) 25 | }, 26 | 27 | parents(element, selector) { 28 | const parents = [] 29 | let ancestor = element.parentNode.closest(selector) 30 | 31 | while (ancestor) { 32 | parents.push(ancestor) 33 | ancestor = ancestor.parentNode.closest(selector) 34 | } 35 | 36 | return parents 37 | }, 38 | 39 | prev(element, selector) { 40 | let previous = element.previousElementSibling 41 | 42 | while (previous) { 43 | if (previous.matches(selector)) { 44 | return [previous] 45 | } 46 | 47 | previous = previous.previousElementSibling 48 | } 49 | 50 | return [] 51 | }, 52 | // TODO: this is now unused; remove later along with prev() 53 | next(element, selector) { 54 | let next = element.nextElementSibling 55 | 56 | while (next) { 57 | if (next.matches(selector)) { 58 | return [next] 59 | } 60 | 61 | next = next.nextElementSibling 62 | } 63 | 64 | return [] 65 | }, 66 | 67 | focusableChildren(element) { 68 | const focusables = [ 69 | 'a', 70 | 'button', 71 | 'input', 72 | 'textarea', 73 | 'select', 74 | 'details', 75 | '[tabindex]', 76 | '[contenteditable="true"]' 77 | ].map(selector => `${selector}:not([tabindex^="-"])`).join(',') 78 | 79 | return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el)) 80 | } 81 | } 82 | 83 | export default SelectorEngine 84 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/js/src/popover.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.2.3): popover.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | import { defineJQueryPlugin } from './util/index' 9 | import Tooltip from './tooltip' 10 | 11 | /** 12 | * Constants 13 | */ 14 | 15 | const NAME = 'popover' 16 | 17 | const SELECTOR_TITLE = '.popover-header' 18 | const SELECTOR_CONTENT = '.popover-body' 19 | 20 | const Default = { 21 | ...Tooltip.Default, 22 | content: '', 23 | offset: [0, 8], 24 | placement: 'right', 25 | template: '', 30 | trigger: 'click' 31 | } 32 | 33 | const DefaultType = { 34 | ...Tooltip.DefaultType, 35 | content: '(null|string|element|function)' 36 | } 37 | 38 | /** 39 | * Class definition 40 | */ 41 | 42 | class Popover extends Tooltip { 43 | // Getters 44 | static get Default() { 45 | return Default 46 | } 47 | 48 | static get DefaultType() { 49 | return DefaultType 50 | } 51 | 52 | static get NAME() { 53 | return NAME 54 | } 55 | 56 | // Overrides 57 | _isWithContent() { 58 | return this._getTitle() || this._getContent() 59 | } 60 | 61 | // Private 62 | _getContentForTemplate() { 63 | return { 64 | [SELECTOR_TITLE]: this._getTitle(), 65 | [SELECTOR_CONTENT]: this._getContent() 66 | } 67 | } 68 | 69 | _getContent() { 70 | return this._resolvePossibleFunction(this._config.content) 71 | } 72 | 73 | // Static 74 | static jQueryInterface(config) { 75 | return this.each(function () { 76 | const data = Popover.getOrCreateInstance(this, config) 77 | 78 | if (typeof config !== 'string') { 79 | return 80 | } 81 | 82 | if (typeof data[config] === 'undefined') { 83 | throw new TypeError(`No method named "${config}"`) 84 | } 85 | 86 | data[config]() 87 | }) 88 | } 89 | } 90 | 91 | /** 92 | * jQuery 93 | */ 94 | 95 | defineJQueryPlugin(Popover) 96 | 97 | export default Popover 98 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/js/src/util/component-functions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.2.3): util/component-functions.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | import EventHandler from '../dom/event-handler' 9 | import { getElementFromSelector, isDisabled } from './index' 10 | 11 | const enableDismissTrigger = (component, method = 'hide') => { 12 | const clickEvent = `click.dismiss${component.EVENT_KEY}` 13 | const name = component.NAME 14 | 15 | EventHandler.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) { 16 | if (['A', 'AREA'].includes(this.tagName)) { 17 | event.preventDefault() 18 | } 19 | 20 | if (isDisabled(this)) { 21 | return 22 | } 23 | 24 | const target = getElementFromSelector(this) || this.closest(`.${name}`) 25 | const instance = component.getOrCreateInstance(target) 26 | 27 | // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method 28 | instance[method]() 29 | }) 30 | } 31 | 32 | export { 33 | enableDismissTrigger 34 | } 35 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/js/src/util/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.2.3): util/config.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | import { isElement, toType } from './index' 9 | import Manipulator from '../dom/manipulator' 10 | 11 | /** 12 | * Class definition 13 | */ 14 | 15 | class Config { 16 | // Getters 17 | static get Default() { 18 | return {} 19 | } 20 | 21 | static get DefaultType() { 22 | return {} 23 | } 24 | 25 | static get NAME() { 26 | throw new Error('You have to implement the static method "NAME", for each component!') 27 | } 28 | 29 | _getConfig(config) { 30 | config = this._mergeConfigObj(config) 31 | config = this._configAfterMerge(config) 32 | this._typeCheckConfig(config) 33 | return config 34 | } 35 | 36 | _configAfterMerge(config) { 37 | return config 38 | } 39 | 40 | _mergeConfigObj(config, element) { 41 | const jsonConfig = isElement(element) ? Manipulator.getDataAttribute(element, 'config') : {} // try to parse 42 | 43 | return { 44 | ...this.constructor.Default, 45 | ...(typeof jsonConfig === 'object' ? jsonConfig : {}), 46 | ...(isElement(element) ? Manipulator.getDataAttributes(element) : {}), 47 | ...(typeof config === 'object' ? config : {}) 48 | } 49 | } 50 | 51 | _typeCheckConfig(config, configTypes = this.constructor.DefaultType) { 52 | for (const property of Object.keys(configTypes)) { 53 | const expectedTypes = configTypes[property] 54 | const value = config[property] 55 | const valueType = isElement(value) ? 'element' : toType(value) 56 | 57 | if (!new RegExp(expectedTypes).test(valueType)) { 58 | throw new TypeError( 59 | `${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".` 60 | ) 61 | } 62 | } 63 | } 64 | } 65 | 66 | export default Config 67 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/_alert.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Base styles 3 | // 4 | 5 | .alert { 6 | // scss-docs-start alert-css-vars 7 | --#{$prefix}alert-bg: transparent; 8 | --#{$prefix}alert-padding-x: #{$alert-padding-x}; 9 | --#{$prefix}alert-padding-y: #{$alert-padding-y}; 10 | --#{$prefix}alert-margin-bottom: #{$alert-margin-bottom}; 11 | --#{$prefix}alert-color: inherit; 12 | --#{$prefix}alert-border-color: transparent; 13 | --#{$prefix}alert-border: #{$alert-border-width} solid var(--#{$prefix}alert-border-color); 14 | --#{$prefix}alert-border-radius: #{$alert-border-radius}; 15 | // scss-docs-end alert-css-vars 16 | 17 | position: relative; 18 | padding: var(--#{$prefix}alert-padding-y) var(--#{$prefix}alert-padding-x); 19 | margin-bottom: var(--#{$prefix}alert-margin-bottom); 20 | color: var(--#{$prefix}alert-color); 21 | background-color: var(--#{$prefix}alert-bg); 22 | border: var(--#{$prefix}alert-border); 23 | @include border-radius(var(--#{$prefix}alert-border-radius)); 24 | } 25 | 26 | // Headings for larger alerts 27 | .alert-heading { 28 | // Specified to prevent conflicts of changing $headings-color 29 | color: inherit; 30 | } 31 | 32 | // Provide class for links that match alerts 33 | .alert-link { 34 | font-weight: $alert-link-font-weight; 35 | } 36 | 37 | 38 | // Dismissible alerts 39 | // 40 | // Expand the right padding and account for the close button's positioning. 41 | 42 | .alert-dismissible { 43 | padding-right: $alert-dismissible-padding-r; 44 | 45 | // Adjust close link position 46 | .btn-close { 47 | position: absolute; 48 | top: 0; 49 | right: 0; 50 | z-index: $stretched-link-z-index + 1; 51 | padding: $alert-padding-y * 1.25 $alert-padding-x; 52 | } 53 | } 54 | 55 | 56 | // scss-docs-start alert-modifiers 57 | // Generate contextual modifier classes for colorizing the alert. 58 | 59 | @each $state, $value in $theme-colors { 60 | $alert-background: shift-color($value, $alert-bg-scale); 61 | $alert-border: shift-color($value, $alert-border-scale); 62 | $alert-color: shift-color($value, $alert-color-scale); 63 | 64 | @if (contrast-ratio($alert-background, $alert-color) < $min-contrast-ratio) { 65 | $alert-color: mix($value, color-contrast($alert-background), abs($alert-color-scale)); 66 | } 67 | .alert-#{$state} { 68 | @include alert-variant($alert-background, $alert-border, $alert-color); 69 | } 70 | } 71 | // scss-docs-end alert-modifiers 72 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/_badge.scss: -------------------------------------------------------------------------------- 1 | // Base class 2 | // 3 | // Requires one of the contextual, color modifier classes for `color` and 4 | // `background-color`. 5 | 6 | .badge { 7 | // scss-docs-start badge-css-vars 8 | --#{$prefix}badge-padding-x: #{$badge-padding-x}; 9 | --#{$prefix}badge-padding-y: #{$badge-padding-y}; 10 | @include rfs($badge-font-size, --#{$prefix}badge-font-size); 11 | --#{$prefix}badge-font-weight: #{$badge-font-weight}; 12 | --#{$prefix}badge-color: #{$badge-color}; 13 | --#{$prefix}badge-border-radius: #{$badge-border-radius}; 14 | // scss-docs-end badge-css-vars 15 | 16 | display: inline-block; 17 | padding: var(--#{$prefix}badge-padding-y) var(--#{$prefix}badge-padding-x); 18 | @include font-size(var(--#{$prefix}badge-font-size)); 19 | font-weight: var(--#{$prefix}badge-font-weight); 20 | line-height: 1; 21 | color: var(--#{$prefix}badge-color); 22 | text-align: center; 23 | white-space: nowrap; 24 | vertical-align: baseline; 25 | @include border-radius(var(--#{$prefix}badge-border-radius)); 26 | @include gradient-bg(); 27 | 28 | // Empty badges collapse automatically 29 | &:empty { 30 | display: none; 31 | } 32 | } 33 | 34 | // Quick fix for badges in buttons 35 | .btn .badge { 36 | position: relative; 37 | top: -1px; 38 | } 39 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/_breadcrumb.scss: -------------------------------------------------------------------------------- 1 | .breadcrumb { 2 | // scss-docs-start breadcrumb-css-vars 3 | --#{$prefix}breadcrumb-padding-x: #{$breadcrumb-padding-x}; 4 | --#{$prefix}breadcrumb-padding-y: #{$breadcrumb-padding-y}; 5 | --#{$prefix}breadcrumb-margin-bottom: #{$breadcrumb-margin-bottom}; 6 | @include rfs($breadcrumb-font-size, --#{$prefix}breadcrumb-font-size); 7 | --#{$prefix}breadcrumb-bg: #{$breadcrumb-bg}; 8 | --#{$prefix}breadcrumb-border-radius: #{$breadcrumb-border-radius}; 9 | --#{$prefix}breadcrumb-divider-color: #{$breadcrumb-divider-color}; 10 | --#{$prefix}breadcrumb-item-padding-x: #{$breadcrumb-item-padding-x}; 11 | --#{$prefix}breadcrumb-item-active-color: #{$breadcrumb-active-color}; 12 | // scss-docs-end breadcrumb-css-vars 13 | 14 | display: flex; 15 | flex-wrap: wrap; 16 | padding: var(--#{$prefix}breadcrumb-padding-y) var(--#{$prefix}breadcrumb-padding-x); 17 | margin-bottom: var(--#{$prefix}breadcrumb-margin-bottom); 18 | @include font-size(var(--#{$prefix}breadcrumb-font-size)); 19 | list-style: none; 20 | background-color: var(--#{$prefix}breadcrumb-bg); 21 | @include border-radius(var(--#{$prefix}breadcrumb-border-radius)); 22 | } 23 | 24 | .breadcrumb-item { 25 | // The separator between breadcrumbs (by default, a forward-slash: "/") 26 | + .breadcrumb-item { 27 | padding-left: var(--#{$prefix}breadcrumb-item-padding-x); 28 | 29 | &::before { 30 | float: left; // Suppress inline spacings and underlining of the separator 31 | padding-right: var(--#{$prefix}breadcrumb-item-padding-x); 32 | color: var(--#{$prefix}breadcrumb-divider-color); 33 | content: var(--#{$prefix}breadcrumb-divider, escape-svg($breadcrumb-divider)) #{"/* rtl:"} var(--#{$prefix}breadcrumb-divider, escape-svg($breadcrumb-divider-flipped)) #{"*/"}; 34 | } 35 | } 36 | 37 | &.active { 38 | color: var(--#{$prefix}breadcrumb-item-active-color); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/_close.scss: -------------------------------------------------------------------------------- 1 | // Transparent background and border properties included for button version. 2 | // iOS requires the button element instead of an anchor tag. 3 | // If you want the anchor version, it requires `href="#"`. 4 | // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile 5 | 6 | .btn-close { 7 | box-sizing: content-box; 8 | width: $btn-close-width; 9 | height: $btn-close-height; 10 | padding: $btn-close-padding-y $btn-close-padding-x; 11 | color: $btn-close-color; 12 | background: transparent escape-svg($btn-close-bg) center / $btn-close-width auto no-repeat; // include transparent for button elements 13 | border: 0; // for button elements 14 | @include border-radius(); 15 | opacity: $btn-close-opacity; 16 | 17 | // Override 's hover style 18 | &:hover { 19 | color: $btn-close-color; 20 | text-decoration: none; 21 | opacity: $btn-close-hover-opacity; 22 | } 23 | 24 | &:focus { 25 | outline: 0; 26 | box-shadow: $btn-close-focus-shadow; 27 | opacity: $btn-close-focus-opacity; 28 | } 29 | 30 | &:disabled, 31 | &.disabled { 32 | pointer-events: none; 33 | user-select: none; 34 | opacity: $btn-close-disabled-opacity; 35 | } 36 | } 37 | 38 | .btn-close-white { 39 | filter: $btn-close-white-filter; 40 | } 41 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/_containers.scss: -------------------------------------------------------------------------------- 1 | // Container widths 2 | // 3 | // Set the container width, and override it for fixed navbars in media queries. 4 | 5 | @if $enable-container-classes { 6 | // Single container class with breakpoint max-widths 7 | .container, 8 | // 100% wide container at all breakpoints 9 | .container-fluid { 10 | @include make-container(); 11 | } 12 | 13 | // Responsive containers that are 100% wide until a breakpoint 14 | @each $breakpoint, $container-max-width in $container-max-widths { 15 | .container-#{$breakpoint} { 16 | @extend .container-fluid; 17 | } 18 | 19 | @include media-breakpoint-up($breakpoint, $grid-breakpoints) { 20 | %responsive-container-#{$breakpoint} { 21 | max-width: $container-max-width; 22 | } 23 | 24 | // Extend each breakpoint which is smaller or equal to the current breakpoint 25 | $extend-breakpoint: true; 26 | 27 | @each $name, $width in $grid-breakpoints { 28 | @if ($extend-breakpoint) { 29 | .container#{breakpoint-infix($name, $grid-breakpoints)} { 30 | @extend %responsive-container-#{$breakpoint}; 31 | } 32 | 33 | // Once the current breakpoint is reached, stop extending 34 | @if ($breakpoint == $name) { 35 | $extend-breakpoint: false; 36 | } 37 | } 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/_forms.scss: -------------------------------------------------------------------------------- 1 | @import "forms/labels"; 2 | @import "forms/form-text"; 3 | @import "forms/form-control"; 4 | @import "forms/form-select"; 5 | @import "forms/form-check"; 6 | @import "forms/form-range"; 7 | @import "forms/floating-labels"; 8 | @import "forms/input-group"; 9 | @import "forms/validation"; 10 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/_grid.scss: -------------------------------------------------------------------------------- 1 | // Row 2 | // 3 | // Rows contain your columns. 4 | 5 | @if $enable-grid-classes { 6 | .row { 7 | @include make-row(); 8 | 9 | > * { 10 | @include make-col-ready(); 11 | } 12 | } 13 | } 14 | 15 | @if $enable-cssgrid { 16 | .grid { 17 | display: grid; 18 | grid-template-rows: repeat(var(--#{$prefix}rows, 1), 1fr); 19 | grid-template-columns: repeat(var(--#{$prefix}columns, #{$grid-columns}), 1fr); 20 | gap: var(--#{$prefix}gap, #{$grid-gutter-width}); 21 | 22 | @include make-cssgrid(); 23 | } 24 | } 25 | 26 | 27 | // Columns 28 | // 29 | // Common styles for small and large grid columns 30 | 31 | @if $enable-grid-classes { 32 | @include make-grid-columns(); 33 | } 34 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/_helpers.scss: -------------------------------------------------------------------------------- 1 | @import "helpers/clearfix"; 2 | @import "helpers/color-bg"; 3 | @import "helpers/colored-links"; 4 | @import "helpers/ratio"; 5 | @import "helpers/position"; 6 | @import "helpers/stacks"; 7 | @import "helpers/visually-hidden"; 8 | @import "helpers/stretched-link"; 9 | @import "helpers/text-truncation"; 10 | @import "helpers/vr"; 11 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/_images.scss: -------------------------------------------------------------------------------- 1 | // Responsive images (ensure images don't scale beyond their parents) 2 | // 3 | // This is purposefully opt-in via an explicit class rather than being the default for all ``s. 4 | // We previously tried the "images are responsive by default" approach in Bootstrap v2, 5 | // and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps) 6 | // which weren't expecting the images within themselves to be involuntarily resized. 7 | // See also https://github.com/twbs/bootstrap/issues/18178 8 | .img-fluid { 9 | @include img-fluid(); 10 | } 11 | 12 | 13 | // Image thumbnails 14 | .img-thumbnail { 15 | padding: $thumbnail-padding; 16 | background-color: $thumbnail-bg; 17 | border: $thumbnail-border-width solid $thumbnail-border-color; 18 | @include border-radius($thumbnail-border-radius); 19 | @include box-shadow($thumbnail-box-shadow); 20 | 21 | // Keep them at most 100% wide 22 | @include img-fluid(); 23 | } 24 | 25 | // 26 | // Figures 27 | // 28 | 29 | .figure { 30 | // Ensures the caption's text aligns with the image. 31 | display: inline-block; 32 | } 33 | 34 | .figure-img { 35 | margin-bottom: $spacer * .5; 36 | line-height: 1; 37 | } 38 | 39 | .figure-caption { 40 | @include font-size($figure-caption-font-size); 41 | color: $figure-caption-color; 42 | } 43 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/_maps.scss: -------------------------------------------------------------------------------- 1 | // Re-assigned maps 2 | // 3 | // Placed here so that others can override the default Sass maps and see automatic updates to utilities and more. 4 | 5 | // scss-docs-start theme-colors-rgb 6 | $theme-colors-rgb: map-loop($theme-colors, to-rgb, "$value") !default; 7 | // scss-docs-end theme-colors-rgb 8 | 9 | // Utilities maps 10 | // 11 | // Extends the default `$theme-colors` maps to help create our utilities. 12 | 13 | // Come v6, we'll de-dupe these variables. Until then, for backward compatibility, we keep them to reassign. 14 | // scss-docs-start utilities-colors 15 | $utilities-colors: $theme-colors-rgb !default; 16 | // scss-docs-end utilities-colors 17 | 18 | // scss-docs-start utilities-text-colors 19 | $utilities-text: map-merge( 20 | $utilities-colors, 21 | ( 22 | "black": to-rgb($black), 23 | "white": to-rgb($white), 24 | "body": to-rgb($body-color) 25 | ) 26 | ) !default; 27 | $utilities-text-colors: map-loop($utilities-text, rgba-css-var, "$key", "text") !default; 28 | // scss-docs-end utilities-text-colors 29 | 30 | // scss-docs-start utilities-bg-colors 31 | $utilities-bg: map-merge( 32 | $utilities-colors, 33 | ( 34 | "black": to-rgb($black), 35 | "white": to-rgb($white), 36 | "body": to-rgb($body-bg) 37 | ) 38 | ) !default; 39 | $utilities-bg-colors: map-loop($utilities-bg, rgba-css-var, "$key", "bg") !default; 40 | // scss-docs-end utilities-bg-colors 41 | 42 | // scss-docs-start utilities-border-colors 43 | $utilities-border: map-merge( 44 | $utilities-colors, 45 | ( 46 | "white": to-rgb($white) 47 | ) 48 | ) !default; 49 | $utilities-border-colors: map-loop($utilities-border, rgba-css-var, "$key", "border") !default; 50 | // scss-docs-end utilities-border-colors 51 | 52 | $negative-spacers: if($enable-negative-margins, negativify-map($spacers), null) !default; 53 | 54 | $gutters: $spacers !default; 55 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Toggles 2 | // 3 | // Used in conjunction with global variables to enable certain theme features. 4 | 5 | // Vendor 6 | @import "vendor/rfs"; 7 | 8 | // Deprecate 9 | @import "mixins/deprecate"; 10 | 11 | // Helpers 12 | @import "mixins/breakpoints"; 13 | @import "mixins/color-scheme"; 14 | @import "mixins/image"; 15 | @import "mixins/resize"; 16 | @import "mixins/visually-hidden"; 17 | @import "mixins/reset-text"; 18 | @import "mixins/text-truncate"; 19 | 20 | // Utilities 21 | @import "mixins/utilities"; 22 | 23 | // Components 24 | @import "mixins/alert"; 25 | @import "mixins/backdrop"; 26 | @import "mixins/buttons"; 27 | @import "mixins/caret"; 28 | @import "mixins/pagination"; 29 | @import "mixins/lists"; 30 | @import "mixins/list-group"; 31 | @import "mixins/forms"; 32 | @import "mixins/table-variants"; 33 | 34 | // Skins 35 | @import "mixins/border-radius"; 36 | @import "mixins/box-shadow"; 37 | @import "mixins/gradients"; 38 | @import "mixins/transition"; 39 | 40 | // Layout 41 | @import "mixins/clearfix"; 42 | @import "mixins/container"; 43 | @import "mixins/grid"; 44 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/_placeholders.scss: -------------------------------------------------------------------------------- 1 | .placeholder { 2 | display: inline-block; 3 | min-height: 1em; 4 | vertical-align: middle; 5 | cursor: wait; 6 | background-color: currentcolor; 7 | opacity: $placeholder-opacity-max; 8 | 9 | &.btn::before { 10 | display: inline-block; 11 | content: ""; 12 | } 13 | } 14 | 15 | // Sizing 16 | .placeholder-xs { 17 | min-height: .6em; 18 | } 19 | 20 | .placeholder-sm { 21 | min-height: .8em; 22 | } 23 | 24 | .placeholder-lg { 25 | min-height: 1.2em; 26 | } 27 | 28 | // Animation 29 | .placeholder-glow { 30 | .placeholder { 31 | animation: placeholder-glow 2s ease-in-out infinite; 32 | } 33 | } 34 | 35 | @keyframes placeholder-glow { 36 | 50% { 37 | opacity: $placeholder-opacity-min; 38 | } 39 | } 40 | 41 | .placeholder-wave { 42 | mask-image: linear-gradient(130deg, $black 55%, rgba(0, 0, 0, (1 - $placeholder-opacity-min)) 75%, $black 95%); 43 | mask-size: 200% 100%; 44 | animation: placeholder-wave 2s linear infinite; 45 | } 46 | 47 | @keyframes placeholder-wave { 48 | 100% { 49 | mask-position: -200% 0%; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/_progress.scss: -------------------------------------------------------------------------------- 1 | // Disable animation if transitions are disabled 2 | 3 | // scss-docs-start progress-keyframes 4 | @if $enable-transitions { 5 | @keyframes progress-bar-stripes { 6 | 0% { background-position-x: $progress-height; } 7 | } 8 | } 9 | // scss-docs-end progress-keyframes 10 | 11 | .progress { 12 | // scss-docs-start progress-css-vars 13 | --#{$prefix}progress-height: #{$progress-height}; 14 | @include rfs($progress-font-size, --#{$prefix}progress-font-size); 15 | --#{$prefix}progress-bg: #{$progress-bg}; 16 | --#{$prefix}progress-border-radius: #{$progress-border-radius}; 17 | --#{$prefix}progress-box-shadow: #{$progress-box-shadow}; 18 | --#{$prefix}progress-bar-color: #{$progress-bar-color}; 19 | --#{$prefix}progress-bar-bg: #{$progress-bar-bg}; 20 | --#{$prefix}progress-bar-transition: #{$progress-bar-transition}; 21 | // scss-docs-end progress-css-vars 22 | 23 | display: flex; 24 | height: var(--#{$prefix}progress-height); 25 | overflow: hidden; // force rounded corners by cropping it 26 | @include font-size(var(--#{$prefix}progress-font-size)); 27 | background-color: var(--#{$prefix}progress-bg); 28 | @include border-radius(var(--#{$prefix}progress-border-radius)); 29 | @include box-shadow(var(--#{$prefix}progress-box-shadow)); 30 | } 31 | 32 | .progress-bar { 33 | display: flex; 34 | flex-direction: column; 35 | justify-content: center; 36 | overflow: hidden; 37 | color: var(--#{$prefix}progress-bar-color); 38 | text-align: center; 39 | white-space: nowrap; 40 | background-color: var(--#{$prefix}progress-bar-bg); 41 | @include transition(var(--#{$prefix}progress-bar-transition)); 42 | } 43 | 44 | .progress-bar-striped { 45 | @include gradient-striped(); 46 | background-size: var(--#{$prefix}progress-height) var(--#{$prefix}progress-height); 47 | } 48 | 49 | @if $enable-transitions { 50 | .progress-bar-animated { 51 | animation: $progress-bar-animation-timing progress-bar-stripes; 52 | 53 | @if $enable-reduced-motion { 54 | @media (prefers-reduced-motion: reduce) { 55 | animation: none; 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/_root.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | // Note: Custom variable values only support SassScript inside `#{}`. 3 | 4 | // Colors 5 | // 6 | // Generate palettes for full colors, grays, and theme colors. 7 | 8 | @each $color, $value in $colors { 9 | --#{$prefix}#{$color}: #{$value}; 10 | } 11 | 12 | @each $color, $value in $grays { 13 | --#{$prefix}gray-#{$color}: #{$value}; 14 | } 15 | 16 | @each $color, $value in $theme-colors { 17 | --#{$prefix}#{$color}: #{$value}; 18 | } 19 | 20 | @each $color, $value in $theme-colors-rgb { 21 | --#{$prefix}#{$color}-rgb: #{$value}; 22 | } 23 | 24 | --#{$prefix}white-rgb: #{to-rgb($white)}; 25 | --#{$prefix}black-rgb: #{to-rgb($black)}; 26 | --#{$prefix}body-color-rgb: #{to-rgb($body-color)}; 27 | --#{$prefix}body-bg-rgb: #{to-rgb($body-bg)}; 28 | 29 | // Fonts 30 | 31 | // Note: Use `inspect` for lists so that quoted items keep the quotes. 32 | // See https://github.com/sass/sass/issues/2383#issuecomment-336349172 33 | --#{$prefix}font-sans-serif: #{inspect($font-family-sans-serif)}; 34 | --#{$prefix}font-monospace: #{inspect($font-family-monospace)}; 35 | --#{$prefix}gradient: #{$gradient}; 36 | 37 | // Root and body 38 | // scss-docs-start root-body-variables 39 | @if $font-size-root != null { 40 | --#{$prefix}root-font-size: #{$font-size-root}; 41 | } 42 | --#{$prefix}body-font-family: #{$font-family-base}; 43 | @include rfs($font-size-base, --#{$prefix}body-font-size); 44 | --#{$prefix}body-font-weight: #{$font-weight-base}; 45 | --#{$prefix}body-line-height: #{$line-height-base}; 46 | --#{$prefix}body-color: #{$body-color}; 47 | @if $body-text-align != null { 48 | --#{$prefix}body-text-align: #{$body-text-align}; 49 | } 50 | --#{$prefix}body-bg: #{$body-bg}; 51 | // scss-docs-end root-body-variables 52 | 53 | // scss-docs-start root-border-var 54 | --#{$prefix}border-width: #{$border-width}; 55 | --#{$prefix}border-style: #{$border-style}; 56 | --#{$prefix}border-color: #{$border-color}; 57 | --#{$prefix}border-color-translucent: #{$border-color-translucent}; 58 | 59 | --#{$prefix}border-radius: #{$border-radius}; 60 | --#{$prefix}border-radius-sm: #{$border-radius-sm}; 61 | --#{$prefix}border-radius-lg: #{$border-radius-lg}; 62 | --#{$prefix}border-radius-xl: #{$border-radius-xl}; 63 | --#{$prefix}border-radius-2xl: #{$border-radius-2xl}; 64 | --#{$prefix}border-radius-pill: #{$border-radius-pill}; 65 | // scss-docs-end root-border-var 66 | 67 | --#{$prefix}link-color: #{$link-color}; 68 | --#{$prefix}link-hover-color: #{$link-hover-color}; 69 | 70 | --#{$prefix}code-color: #{$code-color}; 71 | 72 | --#{$prefix}highlight-bg: #{$mark-bg}; 73 | } 74 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/_spinners.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Rotating border 3 | // 4 | 5 | .spinner-grow, 6 | .spinner-border { 7 | display: inline-block; 8 | width: var(--#{$prefix}spinner-width); 9 | height: var(--#{$prefix}spinner-height); 10 | vertical-align: var(--#{$prefix}spinner-vertical-align); 11 | // stylelint-disable-next-line property-disallowed-list 12 | border-radius: 50%; 13 | animation: var(--#{$prefix}spinner-animation-speed) linear infinite var(--#{$prefix}spinner-animation-name); 14 | } 15 | 16 | // scss-docs-start spinner-border-keyframes 17 | @keyframes spinner-border { 18 | to { transform: rotate(360deg) #{"/* rtl:ignore */"}; } 19 | } 20 | // scss-docs-end spinner-border-keyframes 21 | 22 | .spinner-border { 23 | // scss-docs-start spinner-border-css-vars 24 | --#{$prefix}spinner-width: #{$spinner-width}; 25 | --#{$prefix}spinner-height: #{$spinner-height}; 26 | --#{$prefix}spinner-vertical-align: #{$spinner-vertical-align}; 27 | --#{$prefix}spinner-border-width: #{$spinner-border-width}; 28 | --#{$prefix}spinner-animation-speed: #{$spinner-animation-speed}; 29 | --#{$prefix}spinner-animation-name: spinner-border; 30 | // scss-docs-end spinner-border-css-vars 31 | 32 | border: var(--#{$prefix}spinner-border-width) solid currentcolor; 33 | border-right-color: transparent; 34 | } 35 | 36 | .spinner-border-sm { 37 | // scss-docs-start spinner-border-sm-css-vars 38 | --#{$prefix}spinner-width: #{$spinner-width-sm}; 39 | --#{$prefix}spinner-height: #{$spinner-height-sm}; 40 | --#{$prefix}spinner-border-width: #{$spinner-border-width-sm}; 41 | // scss-docs-end spinner-border-sm-css-vars 42 | } 43 | 44 | // 45 | // Growing circle 46 | // 47 | 48 | // scss-docs-start spinner-grow-keyframes 49 | @keyframes spinner-grow { 50 | 0% { 51 | transform: scale(0); 52 | } 53 | 50% { 54 | opacity: 1; 55 | transform: none; 56 | } 57 | } 58 | // scss-docs-end spinner-grow-keyframes 59 | 60 | .spinner-grow { 61 | // scss-docs-start spinner-grow-css-vars 62 | --#{$prefix}spinner-width: #{$spinner-width}; 63 | --#{$prefix}spinner-height: #{$spinner-height}; 64 | --#{$prefix}spinner-vertical-align: #{$spinner-vertical-align}; 65 | --#{$prefix}spinner-animation-speed: #{$spinner-animation-speed}; 66 | --#{$prefix}spinner-animation-name: spinner-grow; 67 | // scss-docs-end spinner-grow-css-vars 68 | 69 | background-color: currentcolor; 70 | opacity: 0; 71 | } 72 | 73 | .spinner-grow-sm { 74 | --#{$prefix}spinner-width: #{$spinner-width-sm}; 75 | --#{$prefix}spinner-height: #{$spinner-height-sm}; 76 | } 77 | 78 | @if $enable-reduced-motion { 79 | @media (prefers-reduced-motion: reduce) { 80 | .spinner-border, 81 | .spinner-grow { 82 | --#{$prefix}spinner-animation-speed: #{$spinner-animation-speed * 2}; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/_toasts.scss: -------------------------------------------------------------------------------- 1 | .toast { 2 | // scss-docs-start toast-css-vars 3 | --#{$prefix}toast-zindex: #{$zindex-toast}; 4 | --#{$prefix}toast-padding-x: #{$toast-padding-x}; 5 | --#{$prefix}toast-padding-y: #{$toast-padding-y}; 6 | --#{$prefix}toast-spacing: #{$toast-spacing}; 7 | --#{$prefix}toast-max-width: #{$toast-max-width}; 8 | @include rfs($toast-font-size, --#{$prefix}toast-font-size); 9 | --#{$prefix}toast-color: #{$toast-color}; 10 | --#{$prefix}toast-bg: #{$toast-background-color}; 11 | --#{$prefix}toast-border-width: #{$toast-border-width}; 12 | --#{$prefix}toast-border-color: #{$toast-border-color}; 13 | --#{$prefix}toast-border-radius: #{$toast-border-radius}; 14 | --#{$prefix}toast-box-shadow: #{$toast-box-shadow}; 15 | --#{$prefix}toast-header-color: #{$toast-header-color}; 16 | --#{$prefix}toast-header-bg: #{$toast-header-background-color}; 17 | --#{$prefix}toast-header-border-color: #{$toast-header-border-color}; 18 | // scss-docs-end toast-css-vars 19 | 20 | width: var(--#{$prefix}toast-max-width); 21 | max-width: 100%; 22 | @include font-size(var(--#{$prefix}toast-font-size)); 23 | color: var(--#{$prefix}toast-color); 24 | pointer-events: auto; 25 | background-color: var(--#{$prefix}toast-bg); 26 | background-clip: padding-box; 27 | border: var(--#{$prefix}toast-border-width) solid var(--#{$prefix}toast-border-color); 28 | box-shadow: var(--#{$prefix}toast-box-shadow); 29 | @include border-radius(var(--#{$prefix}toast-border-radius)); 30 | 31 | &.showing { 32 | opacity: 0; 33 | } 34 | 35 | &:not(.show) { 36 | display: none; 37 | } 38 | } 39 | 40 | .toast-container { 41 | --#{$prefix}toast-zindex: #{$zindex-toast}; 42 | 43 | position: absolute; 44 | z-index: var(--#{$prefix}toast-zindex); 45 | width: max-content; 46 | max-width: 100%; 47 | pointer-events: none; 48 | 49 | > :not(:last-child) { 50 | margin-bottom: var(--#{$prefix}toast-spacing); 51 | } 52 | } 53 | 54 | .toast-header { 55 | display: flex; 56 | align-items: center; 57 | padding: var(--#{$prefix}toast-padding-y) var(--#{$prefix}toast-padding-x); 58 | color: var(--#{$prefix}toast-header-color); 59 | background-color: var(--#{$prefix}toast-header-bg); 60 | background-clip: padding-box; 61 | border-bottom: var(--#{$prefix}toast-border-width) solid var(--#{$prefix}toast-header-border-color); 62 | @include border-top-radius(calc(var(--#{$prefix}toast-border-radius) - var(--#{$prefix}toast-border-width))); 63 | 64 | .btn-close { 65 | margin-right: calc(-.5 * var(--#{$prefix}toast-padding-x)); // stylelint-disable-line function-disallowed-list 66 | margin-left: var(--#{$prefix}toast-padding-x); 67 | } 68 | } 69 | 70 | .toast-body { 71 | padding: var(--#{$prefix}toast-padding-x); 72 | word-wrap: break-word; 73 | } 74 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/_transitions.scss: -------------------------------------------------------------------------------- 1 | .fade { 2 | @include transition($transition-fade); 3 | 4 | &:not(.show) { 5 | opacity: 0; 6 | } 7 | } 8 | 9 | // scss-docs-start collapse-classes 10 | .collapse { 11 | &:not(.show) { 12 | display: none; 13 | } 14 | } 15 | 16 | .collapsing { 17 | height: 0; 18 | overflow: hidden; 19 | @include transition($transition-collapse); 20 | 21 | &.collapse-horizontal { 22 | width: 0; 23 | height: auto; 24 | @include transition($transition-collapse-width); 25 | } 26 | } 27 | // scss-docs-end collapse-classes 28 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/_type.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Headings 3 | // 4 | .h1 { 5 | @extend h1; 6 | } 7 | 8 | .h2 { 9 | @extend h2; 10 | } 11 | 12 | .h3 { 13 | @extend h3; 14 | } 15 | 16 | .h4 { 17 | @extend h4; 18 | } 19 | 20 | .h5 { 21 | @extend h5; 22 | } 23 | 24 | .h6 { 25 | @extend h6; 26 | } 27 | 28 | 29 | .lead { 30 | @include font-size($lead-font-size); 31 | font-weight: $lead-font-weight; 32 | } 33 | 34 | // Type display classes 35 | @each $display, $font-size in $display-font-sizes { 36 | .display-#{$display} { 37 | @include font-size($font-size); 38 | font-family: $display-font-family; 39 | font-style: $display-font-style; 40 | font-weight: $display-font-weight; 41 | line-height: $display-line-height; 42 | } 43 | } 44 | 45 | // 46 | // Emphasis 47 | // 48 | .small { 49 | @extend small; 50 | } 51 | 52 | .mark { 53 | @extend mark; 54 | } 55 | 56 | // 57 | // Lists 58 | // 59 | 60 | .list-unstyled { 61 | @include list-unstyled(); 62 | } 63 | 64 | // Inline turns list items into inline-block 65 | .list-inline { 66 | @include list-unstyled(); 67 | } 68 | .list-inline-item { 69 | display: inline-block; 70 | 71 | &:not(:last-child) { 72 | margin-right: $list-inline-padding; 73 | } 74 | } 75 | 76 | 77 | // 78 | // Misc 79 | // 80 | 81 | // Builds on `abbr` 82 | .initialism { 83 | @include font-size($initialism-font-size); 84 | text-transform: uppercase; 85 | } 86 | 87 | // Blockquotes 88 | .blockquote { 89 | margin-bottom: $blockquote-margin-y; 90 | @include font-size($blockquote-font-size); 91 | 92 | > :last-child { 93 | margin-bottom: 0; 94 | } 95 | } 96 | 97 | .blockquote-footer { 98 | margin-top: -$blockquote-margin-y; 99 | margin-bottom: $blockquote-margin-y; 100 | @include font-size($blockquote-footer-font-size); 101 | color: $blockquote-footer-color; 102 | 103 | &::before { 104 | content: "\2014\00A0"; // em dash, nbsp 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/bootstrap-grid.scss: -------------------------------------------------------------------------------- 1 | @import "mixins/banner"; 2 | @include bsBanner(Grid); 3 | 4 | $include-column-box-sizing: true !default; 5 | 6 | @import "functions"; 7 | @import "variables"; 8 | @import "maps"; 9 | 10 | @import "mixins/lists"; 11 | @import "mixins/breakpoints"; 12 | @import "mixins/container"; 13 | @import "mixins/grid"; 14 | @import "mixins/utilities"; 15 | 16 | @import "vendor/rfs"; 17 | 18 | @import "root"; 19 | 20 | @import "containers"; 21 | @import "grid"; 22 | 23 | @import "utilities"; 24 | // Only use the utilities we need 25 | // stylelint-disable-next-line scss/dollar-variable-default 26 | $utilities: map-get-multiple( 27 | $utilities, 28 | ( 29 | "display", 30 | "order", 31 | "flex", 32 | "flex-direction", 33 | "flex-grow", 34 | "flex-shrink", 35 | "flex-wrap", 36 | "justify-content", 37 | "align-items", 38 | "align-content", 39 | "align-self", 40 | "margin", 41 | "margin-x", 42 | "margin-y", 43 | "margin-top", 44 | "margin-end", 45 | "margin-bottom", 46 | "margin-start", 47 | "negative-margin", 48 | "negative-margin-x", 49 | "negative-margin-y", 50 | "negative-margin-top", 51 | "negative-margin-end", 52 | "negative-margin-bottom", 53 | "negative-margin-start", 54 | "padding", 55 | "padding-x", 56 | "padding-y", 57 | "padding-top", 58 | "padding-end", 59 | "padding-bottom", 60 | "padding-start", 61 | ) 62 | ); 63 | 64 | @import "utilities/api"; 65 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/bootstrap-reboot.scss: -------------------------------------------------------------------------------- 1 | @import "mixins/banner"; 2 | @include bsBanner(Reboot); 3 | 4 | @import "functions"; 5 | @import "variables"; 6 | @import "maps"; 7 | @import "mixins"; 8 | @import "root"; 9 | @import "reboot"; 10 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/bootstrap-utilities.scss: -------------------------------------------------------------------------------- 1 | @import "mixins/banner"; 2 | @include bsBanner(Utilities); 3 | 4 | // Configuration 5 | @import "functions"; 6 | @import "variables"; 7 | @import "maps"; 8 | @import "mixins"; 9 | @import "utilities"; 10 | 11 | // Layout & components 12 | @import "root"; 13 | 14 | // Helpers 15 | @import "helpers"; 16 | 17 | // Utilities 18 | @import "utilities/api"; 19 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/bootstrap.scss: -------------------------------------------------------------------------------- 1 | @import "mixins/banner"; 2 | @include bsBanner(""); 3 | 4 | 5 | // scss-docs-start import-stack 6 | // Configuration 7 | @import "functions"; 8 | @import "variables"; 9 | @import "maps"; 10 | @import "mixins"; 11 | @import "utilities"; 12 | 13 | // Layout & components 14 | @import "root"; 15 | @import "reboot"; 16 | @import "type"; 17 | @import "images"; 18 | @import "containers"; 19 | @import "grid"; 20 | @import "tables"; 21 | @import "forms"; 22 | @import "buttons"; 23 | @import "transitions"; 24 | @import "dropdown"; 25 | @import "button-group"; 26 | @import "nav"; 27 | @import "navbar"; 28 | @import "card"; 29 | @import "accordion"; 30 | @import "breadcrumb"; 31 | @import "pagination"; 32 | @import "badge"; 33 | @import "alert"; 34 | @import "progress"; 35 | @import "list-group"; 36 | @import "close"; 37 | @import "toasts"; 38 | @import "modal"; 39 | @import "tooltip"; 40 | @import "popover"; 41 | @import "carousel"; 42 | @import "spinners"; 43 | @import "offcanvas"; 44 | @import "placeholders"; 45 | 46 | // Helpers 47 | @import "helpers"; 48 | 49 | // Utilities 50 | @import "utilities/api"; 51 | // scss-docs-end import-stack 52 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/forms/_floating-labels.scss: -------------------------------------------------------------------------------- 1 | .form-floating { 2 | position: relative; 3 | 4 | > .form-control, 5 | > .form-control-plaintext, 6 | > .form-select { 7 | height: $form-floating-height; 8 | line-height: $form-floating-line-height; 9 | } 10 | 11 | > label { 12 | position: absolute; 13 | top: 0; 14 | left: 0; 15 | width: 100%; 16 | height: 100%; // allow textareas 17 | padding: $form-floating-padding-y $form-floating-padding-x; 18 | overflow: hidden; 19 | text-align: start; 20 | text-overflow: ellipsis; 21 | white-space: nowrap; 22 | pointer-events: none; 23 | border: $input-border-width solid transparent; // Required for aligning label's text with the input as it affects inner box model 24 | transform-origin: 0 0; 25 | @include transition($form-floating-transition); 26 | } 27 | 28 | > .form-control, 29 | > .form-control-plaintext { 30 | padding: $form-floating-padding-y $form-floating-padding-x; 31 | 32 | &::placeholder { 33 | color: transparent; 34 | } 35 | 36 | &:focus, 37 | &:not(:placeholder-shown) { 38 | padding-top: $form-floating-input-padding-t; 39 | padding-bottom: $form-floating-input-padding-b; 40 | } 41 | // Duplicated because `:-webkit-autofill` invalidates other selectors when grouped 42 | &:-webkit-autofill { 43 | padding-top: $form-floating-input-padding-t; 44 | padding-bottom: $form-floating-input-padding-b; 45 | } 46 | } 47 | 48 | > .form-select { 49 | padding-top: $form-floating-input-padding-t; 50 | padding-bottom: $form-floating-input-padding-b; 51 | } 52 | 53 | > .form-control:focus, 54 | > .form-control:not(:placeholder-shown), 55 | > .form-control-plaintext, 56 | > .form-select { 57 | ~ label { 58 | opacity: $form-floating-label-opacity; 59 | transform: $form-floating-label-transform; 60 | } 61 | } 62 | // Duplicated because `:-webkit-autofill` invalidates other selectors when grouped 63 | > .form-control:-webkit-autofill { 64 | ~ label { 65 | opacity: $form-floating-label-opacity; 66 | transform: $form-floating-label-transform; 67 | } 68 | } 69 | 70 | > .form-control-plaintext { 71 | ~ label { 72 | border-width: $input-border-width 0; // Required to properly position label text - as explained above 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/forms/_form-select.scss: -------------------------------------------------------------------------------- 1 | // Select 2 | // 3 | // Replaces the browser default select with a custom one, mostly pulled from 4 | // https://primer.github.io/. 5 | 6 | .form-select { 7 | display: block; 8 | width: 100%; 9 | padding: $form-select-padding-y $form-select-indicator-padding $form-select-padding-y $form-select-padding-x; 10 | -moz-padding-start: subtract($form-select-padding-x, 3px); // See https://github.com/twbs/bootstrap/issues/32636 11 | font-family: $form-select-font-family; 12 | @include font-size($form-select-font-size); 13 | font-weight: $form-select-font-weight; 14 | line-height: $form-select-line-height; 15 | color: $form-select-color; 16 | background-color: $form-select-bg; 17 | background-image: escape-svg($form-select-indicator); 18 | background-repeat: no-repeat; 19 | background-position: $form-select-bg-position; 20 | background-size: $form-select-bg-size; 21 | border: $form-select-border-width solid $form-select-border-color; 22 | @include border-radius($form-select-border-radius, 0); 23 | @include box-shadow($form-select-box-shadow); 24 | @include transition($form-select-transition); 25 | appearance: none; 26 | 27 | &:focus { 28 | border-color: $form-select-focus-border-color; 29 | outline: 0; 30 | @if $enable-shadows { 31 | @include box-shadow($form-select-box-shadow, $form-select-focus-box-shadow); 32 | } @else { 33 | // Avoid using mixin so we can pass custom focus shadow properly 34 | box-shadow: $form-select-focus-box-shadow; 35 | } 36 | } 37 | 38 | &[multiple], 39 | &[size]:not([size="1"]) { 40 | padding-right: $form-select-padding-x; 41 | background-image: none; 42 | } 43 | 44 | &:disabled { 45 | color: $form-select-disabled-color; 46 | background-color: $form-select-disabled-bg; 47 | border-color: $form-select-disabled-border-color; 48 | } 49 | 50 | // Remove outline from select box in FF 51 | &:-moz-focusring { 52 | color: transparent; 53 | text-shadow: 0 0 0 $form-select-color; 54 | } 55 | } 56 | 57 | .form-select-sm { 58 | padding-top: $form-select-padding-y-sm; 59 | padding-bottom: $form-select-padding-y-sm; 60 | padding-left: $form-select-padding-x-sm; 61 | @include font-size($form-select-font-size-sm); 62 | @include border-radius($form-select-border-radius-sm); 63 | } 64 | 65 | .form-select-lg { 66 | padding-top: $form-select-padding-y-lg; 67 | padding-bottom: $form-select-padding-y-lg; 68 | padding-left: $form-select-padding-x-lg; 69 | @include font-size($form-select-font-size-lg); 70 | @include border-radius($form-select-border-radius-lg); 71 | } 72 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/forms/_form-text.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Form text 3 | // 4 | 5 | .form-text { 6 | margin-top: $form-text-margin-top; 7 | @include font-size($form-text-font-size); 8 | font-style: $form-text-font-style; 9 | font-weight: $form-text-font-weight; 10 | color: $form-text-color; 11 | } 12 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/forms/_labels.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Labels 3 | // 4 | 5 | .form-label { 6 | margin-bottom: $form-label-margin-bottom; 7 | @include font-size($form-label-font-size); 8 | font-style: $form-label-font-style; 9 | font-weight: $form-label-font-weight; 10 | color: $form-label-color; 11 | } 12 | 13 | // For use with horizontal and inline forms, when you need the label (or legend) 14 | // text to align with the form controls. 15 | .col-form-label { 16 | padding-top: add($input-padding-y, $input-border-width); 17 | padding-bottom: add($input-padding-y, $input-border-width); 18 | margin-bottom: 0; // Override the `` default 19 | @include font-size(inherit); // Override the `` default 20 | font-style: $form-label-font-style; 21 | font-weight: $form-label-font-weight; 22 | line-height: $input-line-height; 23 | color: $form-label-color; 24 | } 25 | 26 | .col-form-label-lg { 27 | padding-top: add($input-padding-y-lg, $input-border-width); 28 | padding-bottom: add($input-padding-y-lg, $input-border-width); 29 | @include font-size($input-font-size-lg); 30 | } 31 | 32 | .col-form-label-sm { 33 | padding-top: add($input-padding-y-sm, $input-border-width); 34 | padding-bottom: add($input-padding-y-sm, $input-border-width); 35 | @include font-size($input-font-size-sm); 36 | } 37 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/forms/_validation.scss: -------------------------------------------------------------------------------- 1 | // Form validation 2 | // 3 | // Provide feedback to users when form field values are valid or invalid. Works 4 | // primarily for client-side validation via scoped `:invalid` and `:valid` 5 | // pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for 6 | // server-side validation. 7 | 8 | // scss-docs-start form-validation-states-loop 9 | @each $state, $data in $form-validation-states { 10 | @include form-validation-state($state, $data...); 11 | } 12 | // scss-docs-end form-validation-states-loop 13 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/helpers/_clearfix.scss: -------------------------------------------------------------------------------- 1 | .clearfix { 2 | @include clearfix(); 3 | } 4 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/helpers/_color-bg.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable function-name-case 2 | 3 | // All-caps `RGBA()` function used because of this Sass bug: https://github.com/sass/node-sass/issues/2251 4 | @each $color, $value in $theme-colors { 5 | $color-rgb: to-rgb($value); 6 | .text-bg-#{$color} { 7 | color: color-contrast($value) if($enable-important-utilities, !important, null); 8 | background-color: RGBA($color-rgb, var(--#{$prefix}bg-opacity, 1)) if($enable-important-utilities, !important, null); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/helpers/_colored-links.scss: -------------------------------------------------------------------------------- 1 | @each $color, $value in $theme-colors { 2 | .link-#{$color} { 3 | color: $value !important; // stylelint-disable-line declaration-no-important 4 | 5 | @if $link-shade-percentage != 0 { 6 | &:hover, 7 | &:focus { 8 | color: if(color-contrast($value) == $color-contrast-light, shade-color($value, $link-shade-percentage), tint-color($value, $link-shade-percentage)) !important; // stylelint-disable-line declaration-no-important 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/helpers/_position.scss: -------------------------------------------------------------------------------- 1 | // Shorthand 2 | 3 | .fixed-top { 4 | position: fixed; 5 | top: 0; 6 | right: 0; 7 | left: 0; 8 | z-index: $zindex-fixed; 9 | } 10 | 11 | .fixed-bottom { 12 | position: fixed; 13 | right: 0; 14 | bottom: 0; 15 | left: 0; 16 | z-index: $zindex-fixed; 17 | } 18 | 19 | // Responsive sticky top and bottom 20 | @each $breakpoint in map-keys($grid-breakpoints) { 21 | @include media-breakpoint-up($breakpoint) { 22 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints); 23 | 24 | .sticky#{$infix}-top { 25 | position: sticky; 26 | top: 0; 27 | z-index: $zindex-sticky; 28 | } 29 | 30 | .sticky#{$infix}-bottom { 31 | position: sticky; 32 | bottom: 0; 33 | z-index: $zindex-sticky; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/helpers/_ratio.scss: -------------------------------------------------------------------------------- 1 | // Credit: Nicolas Gallagher and SUIT CSS. 2 | 3 | .ratio { 4 | position: relative; 5 | width: 100%; 6 | 7 | &::before { 8 | display: block; 9 | padding-top: var(--#{$prefix}aspect-ratio); 10 | content: ""; 11 | } 12 | 13 | > * { 14 | position: absolute; 15 | top: 0; 16 | left: 0; 17 | width: 100%; 18 | height: 100%; 19 | } 20 | } 21 | 22 | @each $key, $ratio in $aspect-ratios { 23 | .ratio-#{$key} { 24 | --#{$prefix}aspect-ratio: #{$ratio}; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/helpers/_stacks.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start stacks 2 | .hstack { 3 | display: flex; 4 | flex-direction: row; 5 | align-items: center; 6 | align-self: stretch; 7 | } 8 | 9 | .vstack { 10 | display: flex; 11 | flex: 1 1 auto; 12 | flex-direction: column; 13 | align-self: stretch; 14 | } 15 | // scss-docs-end stacks 16 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/helpers/_stretched-link.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Stretched link 3 | // 4 | 5 | .stretched-link { 6 | &::#{$stretched-link-pseudo-element} { 7 | position: absolute; 8 | top: 0; 9 | right: 0; 10 | bottom: 0; 11 | left: 0; 12 | z-index: $stretched-link-z-index; 13 | content: ""; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/helpers/_text-truncation.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Text truncation 3 | // 4 | 5 | .text-truncate { 6 | @include text-truncate(); 7 | } 8 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/helpers/_visually-hidden.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Visually hidden 3 | // 4 | 5 | .visually-hidden, 6 | .visually-hidden-focusable:not(:focus):not(:focus-within) { 7 | @include visually-hidden(); 8 | } 9 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/helpers/_vr.scss: -------------------------------------------------------------------------------- 1 | .vr { 2 | display: inline-block; 3 | align-self: stretch; 4 | width: 1px; 5 | min-height: 1em; 6 | background-color: currentcolor; 7 | opacity: $hr-opacity; 8 | } 9 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_alert.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start alert-variant-mixin 2 | @mixin alert-variant($background, $border, $color) { 3 | --#{$prefix}alert-color: #{$color}; 4 | --#{$prefix}alert-bg: #{$background}; 5 | --#{$prefix}alert-border-color: #{$border}; 6 | 7 | @if $enable-gradients { 8 | background-image: var(--#{$prefix}gradient); 9 | } 10 | 11 | .alert-link { 12 | color: shade-color($color, 20%); 13 | } 14 | } 15 | // scss-docs-end alert-variant-mixin 16 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_backdrop.scss: -------------------------------------------------------------------------------- 1 | // Shared between modals and offcanvases 2 | @mixin overlay-backdrop($zindex, $backdrop-bg, $backdrop-opacity) { 3 | position: fixed; 4 | top: 0; 5 | left: 0; 6 | z-index: $zindex; 7 | width: 100vw; 8 | height: 100vh; 9 | background-color: $backdrop-bg; 10 | 11 | // Fade for backdrop 12 | &.fade { opacity: 0; } 13 | &.show { opacity: $backdrop-opacity; } 14 | } 15 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_banner.scss: -------------------------------------------------------------------------------- 1 | @mixin bsBanner($file) { 2 | /*! 3 | * Bootstrap #{$file} v5.2.3 (https://getbootstrap.com/) 4 | * Copyright 2011-2022 The Bootstrap Authors 5 | * Copyright 2011-2022 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 7 | */ 8 | } 9 | 10 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_border-radius.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable property-disallowed-list 2 | // Single side border-radius 3 | 4 | // Helper function to replace negative values with 0 5 | @function valid-radius($radius) { 6 | $return: (); 7 | @each $value in $radius { 8 | @if type-of($value) == number { 9 | $return: append($return, max($value, 0)); 10 | } @else { 11 | $return: append($return, $value); 12 | } 13 | } 14 | @return $return; 15 | } 16 | 17 | // scss-docs-start border-radius-mixins 18 | @mixin border-radius($radius: $border-radius, $fallback-border-radius: false) { 19 | @if $enable-rounded { 20 | border-radius: valid-radius($radius); 21 | } 22 | @else if $fallback-border-radius != false { 23 | border-radius: $fallback-border-radius; 24 | } 25 | } 26 | 27 | @mixin border-top-radius($radius: $border-radius) { 28 | @if $enable-rounded { 29 | border-top-left-radius: valid-radius($radius); 30 | border-top-right-radius: valid-radius($radius); 31 | } 32 | } 33 | 34 | @mixin border-end-radius($radius: $border-radius) { 35 | @if $enable-rounded { 36 | border-top-right-radius: valid-radius($radius); 37 | border-bottom-right-radius: valid-radius($radius); 38 | } 39 | } 40 | 41 | @mixin border-bottom-radius($radius: $border-radius) { 42 | @if $enable-rounded { 43 | border-bottom-right-radius: valid-radius($radius); 44 | border-bottom-left-radius: valid-radius($radius); 45 | } 46 | } 47 | 48 | @mixin border-start-radius($radius: $border-radius) { 49 | @if $enable-rounded { 50 | border-top-left-radius: valid-radius($radius); 51 | border-bottom-left-radius: valid-radius($radius); 52 | } 53 | } 54 | 55 | @mixin border-top-start-radius($radius: $border-radius) { 56 | @if $enable-rounded { 57 | border-top-left-radius: valid-radius($radius); 58 | } 59 | } 60 | 61 | @mixin border-top-end-radius($radius: $border-radius) { 62 | @if $enable-rounded { 63 | border-top-right-radius: valid-radius($radius); 64 | } 65 | } 66 | 67 | @mixin border-bottom-end-radius($radius: $border-radius) { 68 | @if $enable-rounded { 69 | border-bottom-right-radius: valid-radius($radius); 70 | } 71 | } 72 | 73 | @mixin border-bottom-start-radius($radius: $border-radius) { 74 | @if $enable-rounded { 75 | border-bottom-left-radius: valid-radius($radius); 76 | } 77 | } 78 | // scss-docs-end border-radius-mixins 79 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_box-shadow.scss: -------------------------------------------------------------------------------- 1 | @mixin box-shadow($shadow...) { 2 | @if $enable-shadows { 3 | $result: (); 4 | 5 | @each $value in $shadow { 6 | @if $value != null { 7 | $result: append($result, $value, "comma"); 8 | } 9 | @if $value == none and length($shadow) > 1 { 10 | @warn "The keyword 'none' must be used as a single argument."; 11 | } 12 | } 13 | 14 | @if (length($result) > 0) { 15 | box-shadow: $result; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_caret.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start caret-mixins 2 | @mixin caret-down { 3 | border-top: $caret-width solid; 4 | border-right: $caret-width solid transparent; 5 | border-bottom: 0; 6 | border-left: $caret-width solid transparent; 7 | } 8 | 9 | @mixin caret-up { 10 | border-top: 0; 11 | border-right: $caret-width solid transparent; 12 | border-bottom: $caret-width solid; 13 | border-left: $caret-width solid transparent; 14 | } 15 | 16 | @mixin caret-end { 17 | border-top: $caret-width solid transparent; 18 | border-right: 0; 19 | border-bottom: $caret-width solid transparent; 20 | border-left: $caret-width solid; 21 | } 22 | 23 | @mixin caret-start { 24 | border-top: $caret-width solid transparent; 25 | border-right: $caret-width solid; 26 | border-bottom: $caret-width solid transparent; 27 | } 28 | 29 | @mixin caret($direction: down) { 30 | @if $enable-caret { 31 | &::after { 32 | display: inline-block; 33 | margin-left: $caret-spacing; 34 | vertical-align: $caret-vertical-align; 35 | content: ""; 36 | @if $direction == down { 37 | @include caret-down(); 38 | } @else if $direction == up { 39 | @include caret-up(); 40 | } @else if $direction == end { 41 | @include caret-end(); 42 | } 43 | } 44 | 45 | @if $direction == start { 46 | &::after { 47 | display: none; 48 | } 49 | 50 | &::before { 51 | display: inline-block; 52 | margin-right: $caret-spacing; 53 | vertical-align: $caret-vertical-align; 54 | content: ""; 55 | @include caret-start(); 56 | } 57 | } 58 | 59 | &:empty::after { 60 | margin-left: 0; 61 | } 62 | } 63 | } 64 | // scss-docs-end caret-mixins 65 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_clearfix.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start clearfix 2 | @mixin clearfix() { 3 | &::after { 4 | display: block; 5 | clear: both; 6 | content: ""; 7 | } 8 | } 9 | // scss-docs-end clearfix 10 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_color-scheme.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start mixin-color-scheme 2 | @mixin color-scheme($name) { 3 | @media (prefers-color-scheme: #{$name}) { 4 | @content; 5 | } 6 | } 7 | // scss-docs-end mixin-color-scheme 8 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_container.scss: -------------------------------------------------------------------------------- 1 | // Container mixins 2 | 3 | @mixin make-container($gutter: $container-padding-x) { 4 | --#{$prefix}gutter-x: #{$gutter}; 5 | --#{$prefix}gutter-y: 0; 6 | width: 100%; 7 | padding-right: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list 8 | padding-left: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list 9 | margin-right: auto; 10 | margin-left: auto; 11 | } 12 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_deprecate.scss: -------------------------------------------------------------------------------- 1 | // Deprecate mixin 2 | // 3 | // This mixin can be used to deprecate mixins or functions. 4 | // `$enable-deprecation-messages` is a global variable, `$ignore-warning` is a variable that can be passed to 5 | // some deprecated mixins to suppress the warning (for example if the mixin is still be used in the current version of Bootstrap) 6 | @mixin deprecate($name, $deprecate-version, $remove-version, $ignore-warning: false) { 7 | @if ($enable-deprecation-messages != false and $ignore-warning != true) { 8 | @warn "#{$name} has been deprecated as of #{$deprecate-version}. It will be removed entirely in #{$remove-version}."; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_gradients.scss: -------------------------------------------------------------------------------- 1 | // Gradients 2 | 3 | // scss-docs-start gradient-bg-mixin 4 | @mixin gradient-bg($color: null) { 5 | background-color: $color; 6 | 7 | @if $enable-gradients { 8 | background-image: var(--#{$prefix}gradient); 9 | } 10 | } 11 | // scss-docs-end gradient-bg-mixin 12 | 13 | // scss-docs-start gradient-mixins 14 | // Horizontal gradient, from left to right 15 | // 16 | // Creates two color stops, start and end, by specifying a color and position for each color stop. 17 | @mixin gradient-x($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) { 18 | background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent); 19 | } 20 | 21 | // Vertical gradient, from top to bottom 22 | // 23 | // Creates two color stops, start and end, by specifying a color and position for each color stop. 24 | @mixin gradient-y($start-color: $gray-700, $end-color: $gray-800, $start-percent: null, $end-percent: null) { 25 | background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent); 26 | } 27 | 28 | @mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) { 29 | background-image: linear-gradient($deg, $start-color, $end-color); 30 | } 31 | 32 | @mixin gradient-x-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) { 33 | background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color); 34 | } 35 | 36 | @mixin gradient-y-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) { 37 | background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color); 38 | } 39 | 40 | @mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) { 41 | background-image: radial-gradient(circle, $inner-color, $outer-color); 42 | } 43 | 44 | @mixin gradient-striped($color: rgba($white, .15), $angle: 45deg) { 45 | background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent); 46 | } 47 | // scss-docs-end gradient-mixins 48 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_image.scss: -------------------------------------------------------------------------------- 1 | // Image Mixins 2 | // - Responsive image 3 | // - Retina image 4 | 5 | 6 | // Responsive image 7 | // 8 | // Keep images from scaling beyond the width of their parents. 9 | 10 | @mixin img-fluid { 11 | // Part 1: Set a maximum relative to the parent 12 | max-width: 100%; 13 | // Part 2: Override the height to auto, otherwise images will be stretched 14 | // when setting a width and height attribute on the img element. 15 | height: auto; 16 | } 17 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_list-group.scss: -------------------------------------------------------------------------------- 1 | // List Groups 2 | 3 | // scss-docs-start list-group-mixin 4 | @mixin list-group-item-variant($state, $background, $color) { 5 | .list-group-item-#{$state} { 6 | color: $color; 7 | background-color: $background; 8 | 9 | &.list-group-item-action { 10 | &:hover, 11 | &:focus { 12 | color: $color; 13 | background-color: shade-color($background, 10%); 14 | } 15 | 16 | &.active { 17 | color: $white; 18 | background-color: $color; 19 | border-color: $color; 20 | } 21 | } 22 | } 23 | } 24 | // scss-docs-end list-group-mixin 25 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_lists.scss: -------------------------------------------------------------------------------- 1 | // Lists 2 | 3 | // Unstyled keeps list items block level, just removes default browser padding and list-style 4 | @mixin list-unstyled { 5 | padding-left: 0; 6 | list-style: none; 7 | } 8 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_pagination.scss: -------------------------------------------------------------------------------- 1 | // Pagination 2 | 3 | // scss-docs-start pagination-mixin 4 | @mixin pagination-size($padding-y, $padding-x, $font-size, $border-radius) { 5 | --#{$prefix}pagination-padding-x: #{$padding-x}; 6 | --#{$prefix}pagination-padding-y: #{$padding-y}; 7 | @include rfs($font-size, --#{$prefix}pagination-font-size); 8 | --#{$prefix}pagination-border-radius: #{$border-radius}; 9 | } 10 | // scss-docs-end pagination-mixin 11 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_reset-text.scss: -------------------------------------------------------------------------------- 1 | @mixin reset-text { 2 | font-family: $font-family-base; 3 | // We deliberately do NOT reset font-size or overflow-wrap / word-wrap. 4 | font-style: normal; 5 | font-weight: $font-weight-normal; 6 | line-height: $line-height-base; 7 | text-align: left; // Fallback for where `start` is not supported 8 | text-align: start; 9 | text-decoration: none; 10 | text-shadow: none; 11 | text-transform: none; 12 | letter-spacing: normal; 13 | word-break: normal; 14 | white-space: normal; 15 | word-spacing: normal; 16 | line-break: auto; 17 | } 18 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_resize.scss: -------------------------------------------------------------------------------- 1 | // Resize anything 2 | 3 | @mixin resizable($direction) { 4 | overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible` 5 | resize: $direction; // Options: horizontal, vertical, both 6 | } 7 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_table-variants.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start table-variant 2 | @mixin table-variant($state, $background) { 3 | .table-#{$state} { 4 | $color: color-contrast(opaque($body-bg, $background)); 5 | $hover-bg: mix($color, $background, percentage($table-hover-bg-factor)); 6 | $striped-bg: mix($color, $background, percentage($table-striped-bg-factor)); 7 | $active-bg: mix($color, $background, percentage($table-active-bg-factor)); 8 | $table-border-color: mix($color, $background, percentage($table-border-factor)); 9 | 10 | --#{$prefix}table-color: #{$color}; 11 | --#{$prefix}table-bg: #{$background}; 12 | --#{$prefix}table-border-color: #{$table-border-color}; 13 | --#{$prefix}table-striped-bg: #{$striped-bg}; 14 | --#{$prefix}table-striped-color: #{color-contrast($striped-bg)}; 15 | --#{$prefix}table-active-bg: #{$active-bg}; 16 | --#{$prefix}table-active-color: #{color-contrast($active-bg)}; 17 | --#{$prefix}table-hover-bg: #{$hover-bg}; 18 | --#{$prefix}table-hover-color: #{color-contrast($hover-bg)}; 19 | 20 | color: var(--#{$prefix}table-color); 21 | border-color: var(--#{$prefix}table-border-color); 22 | } 23 | } 24 | // scss-docs-end table-variant 25 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_text-truncate.scss: -------------------------------------------------------------------------------- 1 | // Text truncate 2 | // Requires inline-block or block for proper styling 3 | 4 | @mixin text-truncate() { 5 | overflow: hidden; 6 | text-overflow: ellipsis; 7 | white-space: nowrap; 8 | } 9 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_transition.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable property-disallowed-list 2 | @mixin transition($transition...) { 3 | @if length($transition) == 0 { 4 | $transition: $transition-base; 5 | } 6 | 7 | @if length($transition) > 1 { 8 | @each $value in $transition { 9 | @if $value == null or $value == none { 10 | @warn "The keyword 'none' or 'null' must be used as a single argument."; 11 | } 12 | } 13 | } 14 | 15 | @if $enable-transitions { 16 | @if nth($transition, 1) != null { 17 | transition: $transition; 18 | } 19 | 20 | @if $enable-reduced-motion and nth($transition, 1) != null and nth($transition, 1) != none { 21 | @media (prefers-reduced-motion: reduce) { 22 | transition: none; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/mixins/_visually-hidden.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | // Hide content visually while keeping it accessible to assistive technologies 4 | // 5 | // See: https://www.a11yproject.com/posts/2013-01-11-how-to-hide-content/ 6 | // See: https://kittygiraudel.com/2016/10/13/css-hide-and-seek/ 7 | 8 | @mixin visually-hidden() { 9 | position: absolute !important; 10 | width: 1px !important; 11 | height: 1px !important; 12 | padding: 0 !important; 13 | margin: -1px !important; // Fix for https://github.com/twbs/bootstrap/issues/25686 14 | overflow: hidden !important; 15 | clip: rect(0, 0, 0, 0) !important; 16 | white-space: nowrap !important; 17 | border: 0 !important; 18 | } 19 | 20 | // Use to only display content when it's focused, or one of its child elements is focused 21 | // (i.e. when focus is within the element/container that the class was applied to) 22 | // 23 | // Useful for "Skip to main content" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 24 | 25 | @mixin visually-hidden-focusable() { 26 | &:not(:focus):not(:focus-within) { 27 | @include visually-hidden(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/bootstrap/scss/utilities/_api.scss: -------------------------------------------------------------------------------- 1 | // Loop over each breakpoint 2 | @each $breakpoint in map-keys($grid-breakpoints) { 3 | 4 | // Generate media query if needed 5 | @include media-breakpoint-up($breakpoint) { 6 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints); 7 | 8 | // Loop over each utility property 9 | @each $key, $utility in $utilities { 10 | // The utility can be disabled with `false`, thus check if the utility is a map first 11 | // Only proceed if responsive media queries are enabled or if it's the base media query 12 | @if type-of($utility) == "map" and (map-get($utility, responsive) or $infix == "") { 13 | @include generate-utility($utility, $infix); 14 | } 15 | } 16 | } 17 | } 18 | 19 | // RFS rescaling 20 | @media (min-width: $rfs-mq-value) { 21 | @each $breakpoint in map-keys($grid-breakpoints) { 22 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints); 23 | 24 | @if (map-get($grid-breakpoints, $breakpoint) < $rfs-breakpoint) { 25 | // Loop over each utility property 26 | @each $key, $utility in $utilities { 27 | // The utility can be disabled with `false`, thus check if the utility is a map first 28 | // Only proceed if responsive media queries are enabled or if it's the base media query 29 | @if type-of($utility) == "map" and map-get($utility, rfs) and (map-get($utility, responsive) or $infix == "") { 30 | @include generate-utility($utility, $infix, true); 31 | } 32 | } 33 | } 34 | } 35 | } 36 | 37 | 38 | // Print utilities 39 | @media print { 40 | @each $key, $utility in $utilities { 41 | // The utility can be disabled with `false`, thus check if the utility is a map first 42 | // Then check if the utility needs print styles 43 | @if type-of($utility) == "map" and map-get($utility, print) == true { 44 | @include generate-utility($utility, "-print"); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright OpenJS Foundation and other contributors, https://openjsf.org/ 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/jquery/README.md: -------------------------------------------------------------------------------- 1 | # jQuery 2 | 3 | > jQuery is a fast, small, and feature-rich JavaScript library. 4 | 5 | For information on how to get started and how to use jQuery, please see [jQuery's documentation](https://api.jquery.com/). 6 | For source files and issues, please visit the [jQuery repo](https://github.com/jquery/jquery). 7 | 8 | If upgrading, please see the [blog post for 3.6.3](https://blog.jquery.com/2022/12/20/jquery-3-6-3-released-a-quick-selector-fix/). This includes notable differences from the previous version and a more readable changelog. 9 | 10 | ## Including jQuery 11 | 12 | Below are some of the most common ways to include jQuery. 13 | 14 | ### Browser 15 | 16 | #### Script tag 17 | 18 | ```html 19 | 20 | ``` 21 | 22 | #### Webpack / Browserify / Babel 23 | 24 | There are several ways to use [Webpack](https://webpack.js.org/), [Browserify](http://browserify.org/) or [Babel](https://babeljs.io/). For more information on using these tools, please refer to the corresponding project's documentation. In the script, including jQuery will usually look like this: 25 | 26 | ```js 27 | import $ from "jquery"; 28 | ``` 29 | 30 | If you need to use jQuery in a file that's not an ECMAScript module, you can use the CommonJS syntax: 31 | 32 | ```js 33 | var $ = require( "jquery" ); 34 | ``` 35 | 36 | #### AMD (Asynchronous Module Definition) 37 | 38 | AMD is a module format built for the browser. For more information, we recommend [require.js' documentation](https://requirejs.org/docs/whyamd.html). 39 | 40 | ```js 41 | define( [ "jquery" ], function( $ ) { 42 | 43 | } ); 44 | ``` 45 | 46 | ### Node 47 | 48 | To include jQuery in [Node](https://nodejs.org/), first install with npm. 49 | 50 | ```sh 51 | npm install jquery 52 | ``` 53 | 54 | For jQuery to work in Node, a window with a document is required. Since no such window exists natively in Node, one can be mocked by tools such as [jsdom](https://github.com/jsdom/jsdom). This can be useful for testing purposes. 55 | 56 | ```js 57 | const { JSDOM } = require( "jsdom" ); 58 | const { window } = new JSDOM( "" ); 59 | const $ = require( "jquery" )( window ); 60 | ``` 61 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/jquery/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery", 3 | "main": "dist/jquery.js", 4 | "license": "MIT", 5 | "ignore": [ 6 | "package.json" 7 | ], 8 | "keywords": [ 9 | "jquery", 10 | "javascript", 11 | "browser", 12 | "library" 13 | ] 14 | } -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/jquery/external/sizzle/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright JS Foundation and other contributors, https://js.foundation/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/sizzle 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/jquery/src/ajax/load.js: -------------------------------------------------------------------------------- 1 | define( [ 2 | "../core", 3 | "../core/stripAndCollapse", 4 | "../var/isFunction", 5 | "../core/parseHTML", 6 | "../ajax", 7 | "../traversing", 8 | "../manipulation", 9 | "../selector" 10 | ], function( jQuery, stripAndCollapse, isFunction ) { 11 | 12 | "use strict"; 13 | 14 | /** 15 | * Load a url into a page 16 | */ 17 | jQuery.fn.load = function( url, params, callback ) { 18 | var selector, type, response, 19 | self = this, 20 | off = url.indexOf( " " ); 21 | 22 | if ( off > -1 ) { 23 | selector = stripAndCollapse( url.slice( off ) ); 24 | url = url.slice( 0, off ); 25 | } 26 | 27 | // If it's a function 28 | if ( isFunction( params ) ) { 29 | 30 | // We assume that it's the callback 31 | callback = params; 32 | params = undefined; 33 | 34 | // Otherwise, build a param string 35 | } else if ( params && typeof params === "object" ) { 36 | type = "POST"; 37 | } 38 | 39 | // If we have elements to modify, make the request 40 | if ( self.length > 0 ) { 41 | jQuery.ajax( { 42 | url: url, 43 | 44 | // If "type" variable is undefined, then "GET" method will be used. 45 | // Make value of this field explicit since 46 | // user can override it through ajaxSetup method 47 | type: type || "GET", 48 | dataType: "html", 49 | data: params 50 | } ).done( function( responseText ) { 51 | 52 | // Save response for use in complete callback 53 | response = arguments; 54 | 55 | self.html( selector ? 56 | 57 | // If a selector was specified, locate the right elements in a dummy div 58 | // Exclude scripts to avoid IE 'Permission Denied' errors 59 | jQuery( "
" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : 60 | 61 | // Otherwise use the full result 62 | responseText ); 63 | 64 | // If the request succeeds, this function gets "data", "status", "jqXHR" 65 | // but they are ignored because response was set above. 66 | // If it fails, this function gets "jqXHR", "status", "error" 67 | } ).always( callback && function( jqXHR, status ) { 68 | self.each( function() { 69 | callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); 70 | } ); 71 | } ); 72 | } 73 | 74 | return this; 75 | }; 76 | 77 | } ); 78 | -------------------------------------------------------------------------------- /src/ASPNETCore2CookieAuthentication.WebApp/wwwroot/lib/jquery/src/ajax/script.js: -------------------------------------------------------------------------------- 1 | define( [ 2 | "../core", 3 | "../var/document", 4 | "../ajax" 5 | ], function( jQuery, document ) { 6 | 7 | "use strict"; 8 | 9 | // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) 10 | jQuery.ajaxPrefilter( function( s ) { 11 | if ( s.crossDomain ) { 12 | s.contents.script = false; 13 | } 14 | } ); 15 | 16 | // Install script dataType 17 | jQuery.ajaxSetup( { 18 | accepts: { 19 | script: "text/javascript, application/javascript, " + 20 | "application/ecmascript, application/x-ecmascript" 21 | }, 22 | contents: { 23 | script: /\b(?:java|ecma)script\b/ 24 | }, 25 | converters: { 26 | "text script": function( text ) { 27 | jQuery.globalEval( text ); 28 | return text; 29 | } 30 | } 31 | } ); 32 | 33 | // Handle cache's special case and crossDomain 34 | jQuery.ajaxPrefilter( "script", function( s ) { 35 | if ( s.cache === undefined ) { 36 | s.cache = false; 37 | } 38 | if ( s.crossDomain ) { 39 | s.type = "GET"; 40 | } 41 | } ); 42 | 43 | // Bind script tag hack transport 44 | jQuery.ajaxTransport( "script", function( s ) { 45 | 46 | // This transport only deals with cross domain or forced-by-attrs requests 47 | if ( s.crossDomain || s.scriptAttrs ) { 48 | var script, callback; 49 | return { 50 | send: function( _, complete ) { 51 | script = jQuery( "