├── .gitignore ├── LICENSE ├── MVC5-SPA-Angular.vsix ├── README.md ├── SPAuth.sln └── SPAuth ├── App ├── Controllers │ ├── ConfirmEmailCtrl.js │ ├── ForgotPasswordCtrl.js │ ├── HomeCtrl.js │ ├── JoinCtrl.js │ ├── LoginCtrl.js │ ├── ManageCtrl.js │ ├── RegisterExternalCtrl.js │ └── ResetPasswordCtrl.js ├── Directives │ └── confirmPassword.js ├── Services │ ├── Alert.js │ └── ErrorHandler.js └── app.js ├── App_Start ├── BundleConfig.cs ├── FilterConfig.cs ├── IdentityConfig.cs ├── RouteConfig.cs ├── Startup.Auth.cs └── WebApiConfig.cs ├── Areas └── HelpPage │ ├── ApiDescriptionExtensions.cs │ ├── App_Start │ └── HelpPageConfig.cs │ ├── Controllers │ └── HelpController.cs │ ├── HelpPage.css │ ├── HelpPageAreaRegistration.cs │ ├── HelpPageConfigurationExtensions.cs │ ├── ModelDescriptions │ ├── CollectionModelDescription.cs │ ├── ComplexTypeModelDescription.cs │ ├── DictionaryModelDescription.cs │ ├── EnumTypeModelDescription.cs │ ├── EnumValueDescription.cs │ ├── IModelDocumentationProvider.cs │ ├── KeyValuePairModelDescription.cs │ ├── ModelDescription.cs │ ├── ModelDescriptionGenerator.cs │ ├── ModelNameAttribute.cs │ ├── ModelNameHelper.cs │ ├── ParameterAnnotation.cs │ ├── ParameterDescription.cs │ └── SimpleTypeModelDescription.cs │ ├── Models │ └── HelpPageApiModel.cs │ ├── SampleGeneration │ ├── HelpPageSampleGenerator.cs │ ├── HelpPageSampleKey.cs │ ├── ImageSample.cs │ ├── InvalidSample.cs │ ├── ObjectGenerator.cs │ ├── SampleDirection.cs │ └── TextSample.cs │ ├── Views │ ├── Help │ │ ├── Api.cshtml │ │ ├── DisplayTemplates │ │ │ ├── ApiGroup.cshtml │ │ │ ├── CollectionModelDescription.cshtml │ │ │ ├── ComplexTypeModelDescription.cshtml │ │ │ ├── DictionaryModelDescription.cshtml │ │ │ ├── EnumTypeModelDescription.cshtml │ │ │ ├── HelpPageApiModel.cshtml │ │ │ ├── ImageSample.cshtml │ │ │ ├── InvalidSample.cshtml │ │ │ ├── KeyValuePairModelDescription.cshtml │ │ │ ├── ModelDescriptionLink.cshtml │ │ │ ├── Parameters.cshtml │ │ │ ├── Samples.cshtml │ │ │ ├── SimpleTypeModelDescription.cshtml │ │ │ └── TextSample.cshtml │ │ ├── Index.cshtml │ │ └── ResourceModel.cshtml │ ├── Shared │ │ └── _Layout.cshtml │ ├── Web.config │ └── _ViewStart.cshtml │ └── XmlDocumentationProvider.cs ├── Content ├── css │ ├── Site.css │ ├── bootstrap.css │ └── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ └── glyphicons-halflings-regular.woff └── stylus │ ├── Gruntfile.js │ ├── bootstrap │ ├── alerts.styl │ ├── badges.styl │ ├── bootstrap.styl │ ├── breadcrumbs.styl │ ├── button-groups.styl │ ├── buttons.styl │ ├── carousel.styl │ ├── close.styl │ ├── code.styl │ ├── component-animations.styl │ ├── dropdowns.styl │ ├── forms.styl │ ├── glyphicons.styl │ ├── grid.styl │ ├── input-groups.styl │ ├── jumbotron.styl │ ├── labels.styl │ ├── list-group.styl │ ├── media.styl │ ├── mixins.styl │ ├── modals.styl │ ├── navbar.styl │ ├── navs.styl │ ├── normalize.styl │ ├── pager.styl │ ├── pagination.styl │ ├── panels.styl │ ├── popovers.styl │ ├── print.styl │ ├── progress-bars.styl │ ├── responsive-utilities.styl │ ├── scaffolding.styl │ ├── tables.styl │ ├── theme.styl │ ├── thumbnails.styl │ ├── tooltip.styl │ ├── type.styl │ ├── utilities.styl │ ├── variables.styl │ └── wells.styl │ ├── package.json │ ├── site │ └── style.styl │ └── watch.bat ├── Controllers ├── AccountController.cs └── HomeController.cs ├── Global.asax ├── Global.asax.cs ├── Migrations ├── 201404061517596_Intial.Designer.cs ├── 201404061517596_Intial.cs ├── 201404061517596_Intial.resx └── Configuration.cs ├── Models ├── AppContext.cs ├── SecurityModels.cs └── User.cs ├── Project_Readme.html ├── Properties └── AssemblyInfo.cs ├── SPAuth.csproj ├── Scripts ├── _references.js ├── angular-animate.js ├── angular-animate.min.js ├── angular-animate.min.js.map ├── angular-cookies.js ├── angular-cookies.min.js ├── angular-cookies.min.js.map ├── angular-csp.css ├── angular-loader.js ├── angular-loader.min.js ├── angular-loader.min.js.map ├── angular-mocks.js ├── angular-resource.js ├── angular-resource.min.js ├── angular-resource.min.js.map ├── angular-route.js ├── angular-route.min.js ├── angular-route.min.js.map ├── angular-sanitize.js ├── angular-sanitize.min.js ├── angular-sanitize.min.js.map ├── angular-scenario.js ├── angular-spa-security.js ├── angular-spa-security.min.js ├── angular-touch.js ├── angular-touch.min.js ├── angular-touch.min.js.map ├── angular.js ├── angular.min.js ├── angular.min.js.map ├── autoFields-bootstrap.js ├── autoFields-bootstrap.min.js ├── errors.json ├── i18n │ ├── angular-locale_af-na.js │ ├── angular-locale_af-za.js │ ├── angular-locale_af.js │ ├── angular-locale_am-et.js │ ├── angular-locale_am.js │ ├── angular-locale_ar-001.js │ ├── angular-locale_ar-ae.js │ ├── angular-locale_ar-bh.js │ ├── angular-locale_ar-dz.js │ ├── angular-locale_ar-eg.js │ ├── angular-locale_ar-iq.js │ ├── angular-locale_ar-jo.js │ ├── angular-locale_ar-kw.js │ ├── angular-locale_ar-lb.js │ ├── angular-locale_ar-ly.js │ ├── angular-locale_ar-ma.js │ ├── angular-locale_ar-om.js │ ├── angular-locale_ar-qa.js │ ├── angular-locale_ar-sa.js │ ├── angular-locale_ar-sd.js │ ├── angular-locale_ar-sy.js │ ├── angular-locale_ar-tn.js │ ├── angular-locale_ar-ye.js │ ├── angular-locale_ar.js │ ├── angular-locale_bg-bg.js │ ├── angular-locale_bg.js │ ├── angular-locale_bn-bd.js │ ├── angular-locale_bn-in.js │ ├── angular-locale_bn.js │ ├── angular-locale_ca-ad.js │ ├── angular-locale_ca-es.js │ ├── angular-locale_ca.js │ ├── angular-locale_cs-cz.js │ ├── angular-locale_cs.js │ ├── angular-locale_da-dk.js │ ├── angular-locale_da.js │ ├── angular-locale_de-at.js │ ├── angular-locale_de-be.js │ ├── angular-locale_de-ch.js │ ├── angular-locale_de-de.js │ ├── angular-locale_de-li.js │ ├── angular-locale_de-lu.js │ ├── angular-locale_de.js │ ├── angular-locale_el-cy.js │ ├── angular-locale_el-gr.js │ ├── angular-locale_el.js │ ├── angular-locale_en-as.js │ ├── angular-locale_en-au.js │ ├── angular-locale_en-bb.js │ ├── angular-locale_en-be.js │ ├── angular-locale_en-bm.js │ ├── angular-locale_en-bw.js │ ├── angular-locale_en-bz.js │ ├── angular-locale_en-ca.js │ ├── angular-locale_en-dsrt-us.js │ ├── angular-locale_en-dsrt.js │ ├── angular-locale_en-fm.js │ ├── angular-locale_en-gb.js │ ├── angular-locale_en-gu.js │ ├── angular-locale_en-gy.js │ ├── angular-locale_en-hk.js │ ├── angular-locale_en-ie.js │ ├── angular-locale_en-in.js │ ├── angular-locale_en-iso.js │ ├── angular-locale_en-jm.js │ ├── angular-locale_en-mh.js │ ├── angular-locale_en-mp.js │ ├── angular-locale_en-mt.js │ ├── angular-locale_en-mu.js │ ├── angular-locale_en-na.js │ ├── angular-locale_en-nz.js │ ├── angular-locale_en-ph.js │ ├── angular-locale_en-pk.js │ ├── angular-locale_en-pr.js │ ├── angular-locale_en-pw.js │ ├── angular-locale_en-sg.js │ ├── angular-locale_en-tc.js │ ├── angular-locale_en-tt.js │ ├── angular-locale_en-um.js │ ├── angular-locale_en-us.js │ ├── angular-locale_en-vg.js │ ├── angular-locale_en-vi.js │ ├── angular-locale_en-za.js │ ├── angular-locale_en-zw.js │ ├── angular-locale_en.js │ ├── angular-locale_es-419.js │ ├── angular-locale_es-ar.js │ ├── angular-locale_es-bo.js │ ├── angular-locale_es-cl.js │ ├── angular-locale_es-co.js │ ├── angular-locale_es-cr.js │ ├── angular-locale_es-do.js │ ├── angular-locale_es-ea.js │ ├── angular-locale_es-ec.js │ ├── angular-locale_es-es.js │ ├── angular-locale_es-gq.js │ ├── angular-locale_es-gt.js │ ├── angular-locale_es-hn.js │ ├── angular-locale_es-ic.js │ ├── angular-locale_es-mx.js │ ├── angular-locale_es-ni.js │ ├── angular-locale_es-pa.js │ ├── angular-locale_es-pe.js │ ├── angular-locale_es-pr.js │ ├── angular-locale_es-py.js │ ├── angular-locale_es-sv.js │ ├── angular-locale_es-us.js │ ├── angular-locale_es-uy.js │ ├── angular-locale_es-ve.js │ ├── angular-locale_es.js │ ├── angular-locale_et-ee.js │ ├── angular-locale_et.js │ ├── angular-locale_eu-es.js │ ├── angular-locale_eu.js │ ├── angular-locale_fa-af.js │ ├── angular-locale_fa-ir.js │ ├── angular-locale_fa.js │ ├── angular-locale_fi-fi.js │ ├── angular-locale_fi.js │ ├── angular-locale_fil-ph.js │ ├── angular-locale_fil.js │ ├── angular-locale_fr-be.js │ ├── angular-locale_fr-bf.js │ ├── angular-locale_fr-bi.js │ ├── angular-locale_fr-bj.js │ ├── angular-locale_fr-bl.js │ ├── angular-locale_fr-ca.js │ ├── angular-locale_fr-cd.js │ ├── angular-locale_fr-cf.js │ ├── angular-locale_fr-cg.js │ ├── angular-locale_fr-ch.js │ ├── angular-locale_fr-ci.js │ ├── angular-locale_fr-cm.js │ ├── angular-locale_fr-dj.js │ ├── angular-locale_fr-fr.js │ ├── angular-locale_fr-ga.js │ ├── angular-locale_fr-gf.js │ ├── angular-locale_fr-gn.js │ ├── angular-locale_fr-gp.js │ ├── angular-locale_fr-gq.js │ ├── angular-locale_fr-km.js │ ├── angular-locale_fr-lu.js │ ├── angular-locale_fr-mc.js │ ├── angular-locale_fr-mf.js │ ├── angular-locale_fr-mg.js │ ├── angular-locale_fr-ml.js │ ├── angular-locale_fr-mq.js │ ├── angular-locale_fr-ne.js │ ├── angular-locale_fr-re.js │ ├── angular-locale_fr-yt.js │ ├── angular-locale_fr.js │ ├── angular-locale_gl-es.js │ ├── angular-locale_gl.js │ ├── angular-locale_gsw-ch.js │ ├── angular-locale_gsw.js │ ├── angular-locale_gu-in.js │ ├── angular-locale_gu.js │ ├── angular-locale_he-il.js │ ├── angular-locale_he.js │ ├── angular-locale_hi-in.js │ ├── angular-locale_hi.js │ ├── angular-locale_hr-hr.js │ ├── angular-locale_hr.js │ ├── angular-locale_hu-hu.js │ ├── angular-locale_hu.js │ ├── angular-locale_id-id.js │ ├── angular-locale_id.js │ ├── angular-locale_in.js │ ├── angular-locale_is-is.js │ ├── angular-locale_is.js │ ├── angular-locale_it-it.js │ ├── angular-locale_it-sm.js │ ├── angular-locale_it.js │ ├── angular-locale_iw.js │ ├── angular-locale_ja-jp.js │ ├── angular-locale_ja.js │ ├── angular-locale_kn-in.js │ ├── angular-locale_kn.js │ ├── angular-locale_ko-kr.js │ ├── angular-locale_ko.js │ ├── angular-locale_ln-cd.js │ ├── angular-locale_ln.js │ ├── angular-locale_lt-lt.js │ ├── angular-locale_lt.js │ ├── angular-locale_lv-lv.js │ ├── angular-locale_lv.js │ ├── angular-locale_ml-in.js │ ├── angular-locale_ml.js │ ├── angular-locale_mr-in.js │ ├── angular-locale_mr.js │ ├── angular-locale_ms-my.js │ ├── angular-locale_ms.js │ ├── angular-locale_mt-mt.js │ ├── angular-locale_mt.js │ ├── angular-locale_nl-cw.js │ ├── angular-locale_nl-nl.js │ ├── angular-locale_nl-sx.js │ ├── angular-locale_nl.js │ ├── angular-locale_no.js │ ├── angular-locale_or-in.js │ ├── angular-locale_or.js │ ├── angular-locale_pl-pl.js │ ├── angular-locale_pl.js │ ├── angular-locale_pt-br.js │ ├── angular-locale_pt-pt.js │ ├── angular-locale_pt.js │ ├── angular-locale_ro-ro.js │ ├── angular-locale_ro.js │ ├── angular-locale_ru-ru.js │ ├── angular-locale_ru.js │ ├── angular-locale_sk-sk.js │ ├── angular-locale_sk.js │ ├── angular-locale_sl-si.js │ ├── angular-locale_sl.js │ ├── angular-locale_sq-al.js │ ├── angular-locale_sq.js │ ├── angular-locale_sr-cyrl-rs.js │ ├── angular-locale_sr-latn-rs.js │ ├── angular-locale_sr.js │ ├── angular-locale_sv-se.js │ ├── angular-locale_sv.js │ ├── angular-locale_sw-tz.js │ ├── angular-locale_sw.js │ ├── angular-locale_ta-in.js │ ├── angular-locale_ta.js │ ├── angular-locale_te-in.js │ ├── angular-locale_te.js │ ├── angular-locale_th-th.js │ ├── angular-locale_th.js │ ├── angular-locale_tl.js │ ├── angular-locale_tr-tr.js │ ├── angular-locale_tr.js │ ├── angular-locale_uk-ua.js │ ├── angular-locale_uk.js │ ├── angular-locale_ur-pk.js │ ├── angular-locale_ur.js │ ├── angular-locale_vi-vn.js │ ├── angular-locale_vi.js │ ├── angular-locale_zh-cn.js │ ├── angular-locale_zh-hans-cn.js │ ├── angular-locale_zh-hk.js │ ├── angular-locale_zh-tw.js │ ├── angular-locale_zh.js │ ├── angular-locale_zu-za.js │ └── angular-locale_zu.js ├── modernizr-2.6.2.js ├── modernizr-2.7.2.js ├── respond.js ├── respond.matchmedia.addListener.js ├── respond.matchmedia.addListener.min.js ├── respond.min.js ├── ui-bootstrap-0.10.0.js ├── ui-bootstrap-0.10.0.min.js ├── ui-bootstrap-tpls-0.10.0.js ├── ui-bootstrap-tpls-0.10.0.min.js └── version.json ├── Security └── Providers │ └── ApplicationOAuthProvider.cs ├── Startup.cs ├── Views ├── Home │ ├── Index.cshtml │ ├── _ConfirmEmail.cshtml │ ├── _ForgotPassword.cshtml │ ├── _Home.cshtml │ ├── _Login.cshtml │ ├── _Manage.cshtml │ ├── _Register.cshtml │ ├── _RegisterExternal.cshtml │ └── _ResetPassword.cshtml ├── Shared │ ├── Error.cshtml │ └── _Layout.cshtml ├── Web.config └── _ViewStart.cshtml ├── Web.Debug.config ├── Web.Release.config ├── Web.config ├── Web └── Utility.cs ├── favicon.ico └── packages.config /.gitignore: -------------------------------------------------------------------------------- 1 | # VS user files 2 | *.suo 3 | *.user 4 | *.vspscc 5 | *.vssscc 6 | 7 | # bin, obj dirs 8 | */bin/* 9 | */*/bin/* 10 | */obj/* 11 | */*/obj/* 12 | 13 | # databases 14 | *.mdf 15 | *.ldf 16 | 17 | # NuGet 18 | packages/ 19 | 20 | # Node Modules 21 | node_modules*/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JustMaier/MVC5-SPA-Angular/dd0c79ea8fb7ee02c051396d3905aa6a3d28068f/LICENSE -------------------------------------------------------------------------------- /MVC5-SPA-Angular.vsix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JustMaier/MVC5-SPA-Angular/dd0c79ea8fb7ee02c051396d3905aa6a3d28068f/MVC5-SPA-Angular.vsix -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MVC5-SPA-Angular 2 | ================ 3 | 4 | The MVC5 SPA Template Adapted for Angular 5 | 6 | ##Installation 7 | 8 | Clone and start with the project **OR** run `MVC5-SPA-Angular.vsix` and install the project template! 9 | 10 | ##3rd Party Login Support 11 | 12 | Just update `App_Start/Startup.Auth.cs` with the correct information and you'll be on your way! 13 | 14 | ####Note 15 | Since most third party services don't support using localhost or 127.0.0.1 in the return address the project has been modified to launch as `spaAuth.localtest.me:65489` - You may need to open `%Documents%/IISExpress/config/applicationhost.config` and update your site's binding. 16 | 17 | #####Correct Binding Example 18 | ```xml 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | ``` 28 | 29 | ####Also check out 30 | [angular-spa-security](https://github.com/JustMaier/angular-spa-security) the primary component in this template. -------------------------------------------------------------------------------- /SPAuth.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPAuth", "SPAuth\SPAuth.csproj", "{8D687F4F-BD24-4A16-A1EE-F34788B74D95}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {8D687F4F-BD24-4A16-A1EE-F34788B74D95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {8D687F4F-BD24-4A16-A1EE-F34788B74D95}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {8D687F4F-BD24-4A16-A1EE-F34788B74D95}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {8D687F4F-BD24-4A16-A1EE-F34788B74D95}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /SPAuth/App/Controllers/ConfirmEmailCtrl.js: -------------------------------------------------------------------------------- 1 | angular.module('app') 2 | .controller('ConfirmEmailCtrl', ['$rootScope', 'security', 'Alert', function ($rootScope, Security, Alert) { 3 | Security.confirmEmail($rootScope.app.params).then(function (data) { 4 | Alert.new('success', data.message); 5 | }); 6 | Security.authenticate('/'); 7 | }]); -------------------------------------------------------------------------------- /SPAuth/App/Controllers/ForgotPasswordCtrl.js: -------------------------------------------------------------------------------- 1 | angular.module('app') 2 | .controller('ForgotPasswordCtrl', ['$scope', 'security', '$modal', 'Alert', function ($scope, Security, $modal, Alert) { 3 | Security.redirectAuthenticated('/'); 4 | var User = function () { 5 | return { 6 | email: '', 7 | } 8 | } 9 | 10 | $scope.user = new User(); 11 | $scope.requestReset = function () { 12 | if (!$scope.forgotPasswordForm.$valid) return; 13 | $scope.message = "Processing Request..."; 14 | Security.forgotPassword(angular.copy($scope.user)).then(function (data) { 15 | //Success 16 | Alert.new('success', data.message); 17 | Security.authenticate(); 18 | }, function (data) { 19 | $scope.message = null; 20 | }) 21 | }; 22 | $scope.schema = [ 23 | { label: 'Email Address', property: 'email', type: 'email', attr: { required: true } } 24 | ]; 25 | }]); -------------------------------------------------------------------------------- /SPAuth/App/Controllers/HomeCtrl.js: -------------------------------------------------------------------------------- 1 | angular.module('app') 2 | .controller('HomeCtrl', ['$scope', 'security', function ($scope, Security) { 3 | Security.authenticate(); 4 | }]); -------------------------------------------------------------------------------- /SPAuth/App/Controllers/JoinCtrl.js: -------------------------------------------------------------------------------- 1 | angular.module('app') 2 | .controller('JoinCtrl', ['$scope', 'security', '$modal', function ($scope, Security, $modal) { 3 | Security.redirectAuthenticated('/'); 4 | var User = function () { 5 | return { 6 | username: '', 7 | password: '', 8 | confirmPassword: '' 9 | } 10 | } 11 | 12 | $scope.user = new User(); 13 | $scope.join = function () { 14 | if (!$scope.joinForm.$valid) return; 15 | $scope.message = "Processing Registration..."; 16 | Security.register(angular.copy($scope.user)).then(function () { 17 | //Success 18 | }, function (data) { 19 | $scope.message = null; 20 | }) 21 | }; 22 | $scope.schema = [ 23 | { label: 'Email Address', property: 'username', type: 'email', attr: { required: true } }, 24 | { property: 'password', type: 'password', attr: { required: true } }, 25 | { property: 'confirmPassword', label: 'Confirm Password', type: 'password', attr: { confirmPassword: 'user.password', required: true } } 26 | ]; 27 | }]); -------------------------------------------------------------------------------- /SPAuth/App/Controllers/LoginCtrl.js: -------------------------------------------------------------------------------- 1 | angular.module('app') 2 | .controller('LoginCtrl', ['$scope', 'security', function ($scope, Security) { 3 | Security.redirectAuthenticated('/'); 4 | var LoginModel = function () { 5 | return { 6 | username: '', 7 | password: '', 8 | rememberMe: false 9 | } 10 | }; 11 | 12 | $scope.user = new LoginModel(); 13 | $scope.login = function () { 14 | if (!$scope.loginForm.$valid) return; 15 | $scope.message = "Processing Login..."; 16 | Security.login(angular.copy($scope.user)).catch(function (data) { 17 | $scope.message = null; 18 | }); 19 | } 20 | $scope.schema = [ 21 | { label: 'Email Address', property: 'username', type: 'email', attr: { required: true } }, 22 | { property: 'password', type: 'password', attr: { required: true } }, 23 | { property: 'rememberMe', label: 'Keep me logged in', type: 'checkbox' } 24 | ]; 25 | }]); -------------------------------------------------------------------------------- /SPAuth/App/Controllers/RegisterExternalCtrl.js: -------------------------------------------------------------------------------- 1 | angular.module('app') 2 | .controller('RegisterExternalCtrl', ['$scope', 'security', function ($scope, Security) { 3 | if (!Security.externalUser) Security.authenticate(); 4 | Security.redirectAuthenticated('/'); 5 | $scope.registerExternalUser = function () { 6 | if (!$scope.registerForm.$valid) return; 7 | $scope.message = "Processing Login..."; 8 | Security.registerExternal().catch(function (data) { 9 | $scope.message = null; 10 | }); 11 | } 12 | $scope.schema = [ 13 | { property: 'userName', label: 'Email Address', type: 'email', attr: { required: true } } 14 | ]; 15 | }]); -------------------------------------------------------------------------------- /SPAuth/App/Controllers/ResetPasswordCtrl.js: -------------------------------------------------------------------------------- 1 | angular.module('app') 2 | .controller('ResetPasswordCtrl', ['$scope', 'security', '$modal', 'Alert', function ($scope, Security, $modal, Alert) { 3 | Security.redirectAuthenticated('/'); 4 | var User = function () { 5 | return { 6 | email: '', 7 | password: '', 8 | confirmPassword: '', 9 | code: decodeURIComponent($scope.app.params.code) 10 | } 11 | } 12 | 13 | $scope.user = new User(); 14 | $scope.reset = function () { 15 | if (!$scope.resetForm.$valid) return; 16 | $scope.message = "Processing Request..."; 17 | $scope.user.code = $scope.app.params.code; 18 | Security.resetPassword(angular.copy($scope.user)).then(function (data) { 19 | //Success 20 | Alert.new('success', data.message); 21 | Security.authenticate(); 22 | }, function (data) { 23 | $scope.message = null; 24 | }) 25 | }; 26 | $scope.schema = [ 27 | { label: 'Email Address', property: 'email', type: 'email', attr: { required: true } }, 28 | { property: 'password', type: 'password', attr: { required: true } }, 29 | { property: 'confirmPassword', label: 'Confirm Password', type: 'password', attr: { confirmPassword: 'user.password', required: true } } 30 | ]; 31 | }]); -------------------------------------------------------------------------------- /SPAuth/App/Directives/confirmPassword.js: -------------------------------------------------------------------------------- 1 | angular.module('app') 2 | .directive('confirmPassword', [function () { 3 | return { 4 | restrict: 'A', 5 | require: 'ngModel', 6 | link: function (scope, element, attrs, ngModel) { 7 | ngModel.$parsers.unshift(function (viewValue, $scope) { 8 | var password = scope.$eval(attrs.confirmPassword); 9 | var noMatch = viewValue != password; 10 | ngModel.$setValidity('noMatch', !noMatch); 11 | return viewValue; 12 | }); 13 | } 14 | } 15 | }]); -------------------------------------------------------------------------------- /SPAuth/App/Services/Alert.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('app') 4 | .factory('Alert', ['$rootScope', '$timeout', function ($rootScope, $timeout) { 5 | var Alert = this; 6 | var alerts = $rootScope.alerts = []; 7 | 8 | Alert.close = function (alert, index) { 9 | if (alert.timer != null) $timeout.cancel(alert.timer); 10 | alerts.splice(index, 1); 11 | } 12 | 13 | Alert.new = function (type, message, time) { 14 | var alert = { type: type, message: message, close: Alert.close }; 15 | if (time != null) { 16 | alert.timer = $timeout(function () { 17 | alerts.splice(alerts.indexOf(alert), 1); 18 | }, time); 19 | } 20 | alerts.push(alert); 21 | } 22 | 23 | return Alert; 24 | }]); -------------------------------------------------------------------------------- /SPAuth/App/Services/ErrorHandler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | angular.module('app') 3 | .factory('ErrorHandler', ['$rootScope', 'Alert', function ($rootScope, Alert) { 4 | var ErrorHandler = this; 5 | 6 | ErrorHandler.handle = function (data, status, headers, config) { 7 | var message = []; 8 | if (data.message) { 9 | message.push("" + data.message + ""); 10 | } 11 | if (data.modelState) { 12 | angular.forEach(data.modelState, function (errors, key) { 13 | message.push(errors); 14 | }); 15 | } 16 | if (data.exceptionMessage) { 17 | message.push(data.exceptionMessage); 18 | } 19 | if (data.error_description) { 20 | message.push(data.error_description); 21 | } 22 | Alert.new('danger', message.join('
')); 23 | } 24 | 25 | return ErrorHandler; 26 | }]) 27 | .factory('myHttpInterceptor', ['ErrorHandler', '$q', function (ErrorHandler, $q) { 28 | return { 29 | response: function (response) { 30 | return response; 31 | }, 32 | responseError: function (response) { 33 | ErrorHandler.handle(response.data, response.status, response.headers, response.config); 34 | 35 | // do something on error 36 | return $q.reject(response); 37 | } 38 | }; 39 | }]); -------------------------------------------------------------------------------- /SPAuth/App/app.js: -------------------------------------------------------------------------------- 1 | angular.module('app', ['security', 'ngSanitize', 'ngRoute', 'ui.bootstrap', 'autoFields']) 2 | .config(['$routeProvider', '$httpProvider', '$locationProvider', '$parseProvider', 'securityProvider', function ($routeProvider, $httpProvider, $locationProvider, $parseProvider, securityProvider) { 3 | $locationProvider.html5Mode(true); 4 | $httpProvider.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest"; 5 | $httpProvider.interceptors.push('myHttpInterceptor'); 6 | securityProvider.urls.login = '/login'; 7 | 8 | $routeProvider 9 | .when('/:controller?/:action?/:id?', { 10 | template: '', 11 | controller: 'DynamicCtrl' 12 | }) 13 | .otherwise({ 14 | redirectTo: '/' 15 | }); 16 | }]) 17 | .run(['$rootScope', 'security', '$route', function ($rootScope, security, $route) { 18 | $rootScope.app = { 19 | params: null, 20 | loading: true 21 | }; 22 | $rootScope.security = security; 23 | 24 | $rootScope.$on('$locationChangeStart', function (event) { 25 | $rootScope.app.loading = true; 26 | }); 27 | $rootScope.$on('$locationChangeSuccess', function (event) { 28 | $rootScope.app.params = angular.copy($route.current.params); 29 | $rootScope.app.loading = false; 30 | }); 31 | }]) 32 | .controller('DynamicCtrl', ['$rootScope', '$scope', '$routeParams', function ($rootScope, $scope, $routeParams) { 33 | $rootScope.app.title = $routeParams.action; 34 | var route = []; 35 | if ($routeParams.controller != null && $routeParams.controller != '') route.push($routeParams.controller); 36 | if ($routeParams.action != null && $routeParams.action != '') route.push($routeParams.action); 37 | $scope.include = ('/' + route.join('/')).toLowerCase(); 38 | }]); -------------------------------------------------------------------------------- /SPAuth/App_Start/BundleConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web.Optimization; 5 | 6 | namespace SPAuth { 7 | public class BundleConfig { 8 | // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862 9 | public static void RegisterBundles(BundleCollection bundles) { 10 | bundles.Add(new ScriptBundle("~/bundles/jquery").Include( 11 | "~/Scripts/jquery-{version}.js")); 12 | 13 | //Angular 14 | bundles.Add(new ScriptBundle("~/bundles/angular").Include( 15 | "~/Scripts/angular.js", 16 | "~/Scripts/angular-sanitize.js", 17 | "~/Scripts/angular-resource.js", 18 | "~/Scripts/angular-route.js" 19 | )); 20 | 21 | //Angular Bootstrap 22 | bundles.Add(new ScriptBundle("~/bundles/angularBootstrap").Include( 23 | "~/Scripts/ui-bootstrap-tpls-{version}.js", 24 | "~/Scripts/angular-spa-security.js", 25 | "~/Scripts/autoFields-bootstrap.js" 26 | )); 27 | 28 | //App 29 | bundles.Add(new ScriptBundle("~/bundles/app") 30 | .IncludeDirectory("~/App/", "*.js") 31 | .IncludeDirectory("~/App/Controllers", "*.js") 32 | .IncludeDirectory("~/App/Directives", "*.js") 33 | .IncludeDirectory("~/App/Filters", "*.js") 34 | .IncludeDirectory("~/App/Services", "*.js") 35 | ); 36 | 37 | // Use the development version of Modernizr to develop with and learn from. Then, when you're 38 | // ready for production, use the build tool at http://modernizr.com to pick only the tests you need. 39 | bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( 40 | "~/Scripts/modernizr-*")); 41 | 42 | bundles.Add(new StyleBundle("~/Content/css").Include( 43 | "~/Content/css/bootstrap.css", 44 | "~/Content/css/Site.css")); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /SPAuth/App_Start/FilterConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | 4 | namespace SPAuth { 5 | public class FilterConfig { 6 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) { 7 | filters.Add(new HandleErrorAttribute()); 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SPAuth/App_Start/RouteConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Routing; 7 | 8 | namespace SPAuth { 9 | public class RouteConfig { 10 | public static void RegisterRoutes(RouteCollection routes) { 11 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 12 | 13 | routes.MapRoute( 14 | name: "SPA", 15 | url: "{*catchall}", 16 | defaults: new { controller = "Home", action = "Index" } 17 | ); 18 | 19 | routes.MapRoute( 20 | name: "Short", 21 | url: "{action}/{id}", 22 | defaults: new { controller = "Home", action = "Index" } 23 | ); 24 | 25 | routes.MapRoute( 26 | name: "Default", 27 | url: "{controller}/{action}/{id}", 28 | defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 29 | ); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /SPAuth/App_Start/WebApiConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net.Http; 5 | using System.Web.Http; 6 | using Microsoft.Owin.Security.OAuth; 7 | using Newtonsoft.Json.Serialization; 8 | 9 | namespace SPAuth { 10 | public static class WebApiConfig { 11 | public static void Register(HttpConfiguration config) { 12 | // Web API configuration and services 13 | // Configure Web API to use only bearer token authentication. 14 | config.SuppressDefaultHostAuthentication(); 15 | config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); // "Bearer" 16 | 17 | // Use camel case for JSON data. 18 | config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 19 | 20 | // Web API routes 21 | config.MapHttpAttributeRoutes(); 22 | 23 | config.Routes.MapHttpRoute( 24 | name: "DefaultApi", 25 | routeTemplate: "api/{controller}/{id}", 26 | defaults: new { id = RouteParameter.Optional } 27 | ); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/ApiDescriptionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Web; 4 | using System.Web.Http.Description; 5 | 6 | namespace SPAuth.Areas.HelpPage 7 | { 8 | public static class ApiDescriptionExtensions 9 | { 10 | /// 11 | /// Generates an URI-friendly ID for the . E.g. "Get-Values-id_name" instead of "GetValues/{id}?name={name}" 12 | /// 13 | /// The . 14 | /// The ID as a string. 15 | public static string GetFriendlyId(this ApiDescription description) 16 | { 17 | string path = description.RelativePath; 18 | string[] urlParts = path.Split('?'); 19 | string localPath = urlParts[0]; 20 | string queryKeyString = null; 21 | if (urlParts.Length > 1) 22 | { 23 | string query = urlParts[1]; 24 | string[] queryKeys = HttpUtility.ParseQueryString(query).AllKeys; 25 | queryKeyString = String.Join("_", queryKeys); 26 | } 27 | 28 | StringBuilder friendlyPath = new StringBuilder(); 29 | friendlyPath.AppendFormat("{0}-{1}", 30 | description.HttpMethod.Method, 31 | localPath.Replace("/", "-").Replace("{", String.Empty).Replace("}", String.Empty)); 32 | if (queryKeyString != null) 33 | { 34 | friendlyPath.AppendFormat("_{0}", queryKeyString); 35 | } 36 | return friendlyPath.ToString(); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Controllers/HelpController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web.Http; 3 | using System.Web.Mvc; 4 | using SPAuth.Areas.HelpPage.ModelDescriptions; 5 | using SPAuth.Areas.HelpPage.Models; 6 | 7 | namespace SPAuth.Areas.HelpPage.Controllers 8 | { 9 | /// 10 | /// The controller that will handle requests for the help page. 11 | /// 12 | public class HelpController : Controller 13 | { 14 | private const string ErrorViewName = "Error"; 15 | 16 | public HelpController() 17 | : this(GlobalConfiguration.Configuration) 18 | { 19 | } 20 | 21 | public HelpController(HttpConfiguration config) 22 | { 23 | Configuration = config; 24 | } 25 | 26 | public HttpConfiguration Configuration { get; private set; } 27 | 28 | public ActionResult Index() 29 | { 30 | ViewBag.DocumentationProvider = Configuration.Services.GetDocumentationProvider(); 31 | return View(Configuration.Services.GetApiExplorer().ApiDescriptions); 32 | } 33 | 34 | public ActionResult Api(string apiId) 35 | { 36 | if (!String.IsNullOrEmpty(apiId)) 37 | { 38 | HelpPageApiModel apiModel = Configuration.GetHelpPageApiModel(apiId); 39 | if (apiModel != null) 40 | { 41 | return View(apiModel); 42 | } 43 | } 44 | 45 | return View(ErrorViewName); 46 | } 47 | 48 | public ActionResult ResourceModel(string modelName) 49 | { 50 | if (!String.IsNullOrEmpty(modelName)) 51 | { 52 | ModelDescriptionGenerator modelDescriptionGenerator = Configuration.GetModelDescriptionGenerator(); 53 | ModelDescription modelDescription; 54 | if (modelDescriptionGenerator.GeneratedModels.TryGetValue(modelName, out modelDescription)) 55 | { 56 | return View(modelDescription); 57 | } 58 | } 59 | 60 | return View(ErrorViewName); 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/HelpPageAreaRegistration.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Http; 2 | using System.Web.Mvc; 3 | 4 | namespace SPAuth.Areas.HelpPage 5 | { 6 | public class HelpPageAreaRegistration : AreaRegistration 7 | { 8 | public override string AreaName 9 | { 10 | get 11 | { 12 | return "HelpPage"; 13 | } 14 | } 15 | 16 | public override void RegisterArea(AreaRegistrationContext context) 17 | { 18 | context.MapRoute( 19 | "HelpPage_Default", 20 | "Help/{action}/{apiId}", 21 | new { controller = "Help", action = "Index", apiId = UrlParameter.Optional }); 22 | 23 | HelpPageConfig.Register(GlobalConfiguration.Configuration); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/ModelDescriptions/CollectionModelDescription.cs: -------------------------------------------------------------------------------- 1 | namespace SPAuth.Areas.HelpPage.ModelDescriptions 2 | { 3 | public class CollectionModelDescription : ModelDescription 4 | { 5 | public ModelDescription ElementDescription { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/ModelDescriptions/ComplexTypeModelDescription.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.ObjectModel; 2 | 3 | namespace SPAuth.Areas.HelpPage.ModelDescriptions 4 | { 5 | public class ComplexTypeModelDescription : ModelDescription 6 | { 7 | public ComplexTypeModelDescription() 8 | { 9 | Properties = new Collection(); 10 | } 11 | 12 | public Collection Properties { get; private set; } 13 | } 14 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/ModelDescriptions/DictionaryModelDescription.cs: -------------------------------------------------------------------------------- 1 | namespace SPAuth.Areas.HelpPage.ModelDescriptions 2 | { 3 | public class DictionaryModelDescription : KeyValuePairModelDescription 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/ModelDescriptions/EnumTypeModelDescription.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.ObjectModel; 3 | 4 | namespace SPAuth.Areas.HelpPage.ModelDescriptions 5 | { 6 | public class EnumTypeModelDescription : ModelDescription 7 | { 8 | public EnumTypeModelDescription() 9 | { 10 | Values = new Collection(); 11 | } 12 | 13 | public Collection Values { get; private set; } 14 | } 15 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/ModelDescriptions/EnumValueDescription.cs: -------------------------------------------------------------------------------- 1 | namespace SPAuth.Areas.HelpPage.ModelDescriptions 2 | { 3 | public class EnumValueDescription 4 | { 5 | public string Documentation { get; set; } 6 | 7 | public string Name { get; set; } 8 | 9 | public string Value { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/ModelDescriptions/IModelDocumentationProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace SPAuth.Areas.HelpPage.ModelDescriptions 5 | { 6 | public interface IModelDocumentationProvider 7 | { 8 | string GetDocumentation(MemberInfo member); 9 | 10 | string GetDocumentation(Type type); 11 | } 12 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/ModelDescriptions/KeyValuePairModelDescription.cs: -------------------------------------------------------------------------------- 1 | namespace SPAuth.Areas.HelpPage.ModelDescriptions 2 | { 3 | public class KeyValuePairModelDescription : ModelDescription 4 | { 5 | public ModelDescription KeyModelDescription { get; set; } 6 | 7 | public ModelDescription ValueModelDescription { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/ModelDescriptions/ModelDescription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SPAuth.Areas.HelpPage.ModelDescriptions 4 | { 5 | /// 6 | /// Describes a type model. 7 | /// 8 | public abstract class ModelDescription 9 | { 10 | public string Documentation { get; set; } 11 | 12 | public Type ModelType { get; set; } 13 | 14 | public string Name { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/ModelDescriptions/ModelNameAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SPAuth.Areas.HelpPage.ModelDescriptions 4 | { 5 | /// 6 | /// Use this attribute to change the name of the generated for a type. 7 | /// 8 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum, AllowMultiple = false, Inherited = false)] 9 | public sealed class ModelNameAttribute : Attribute 10 | { 11 | public ModelNameAttribute(string name) 12 | { 13 | Name = name; 14 | } 15 | 16 | public string Name { get; private set; } 17 | } 18 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/ModelDescriptions/ModelNameHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Linq; 4 | using System.Reflection; 5 | 6 | namespace SPAuth.Areas.HelpPage.ModelDescriptions 7 | { 8 | internal static class ModelNameHelper 9 | { 10 | // Modify this to provide custom model name mapping. 11 | public static string GetModelName(Type type) 12 | { 13 | ModelNameAttribute modelNameAttribute = type.GetCustomAttribute(); 14 | if (modelNameAttribute != null && !String.IsNullOrEmpty(modelNameAttribute.Name)) 15 | { 16 | return modelNameAttribute.Name; 17 | } 18 | 19 | string modelName = type.Name; 20 | if (type.IsGenericType) 21 | { 22 | // Format the generic type name to something like: GenericOfAgurment1AndArgument2 23 | Type genericType = type.GetGenericTypeDefinition(); 24 | Type[] genericArguments = type.GetGenericArguments(); 25 | string genericTypeName = genericType.Name; 26 | 27 | // Trim the generic parameter counts from the name 28 | genericTypeName = genericTypeName.Substring(0, genericTypeName.IndexOf('`')); 29 | string[] argumentTypeNames = genericArguments.Select(t => GetModelName(t)).ToArray(); 30 | modelName = String.Format(CultureInfo.InvariantCulture, "{0}Of{1}", genericTypeName, String.Join("And", argumentTypeNames)); 31 | } 32 | 33 | return modelName; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/ModelDescriptions/ParameterAnnotation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SPAuth.Areas.HelpPage.ModelDescriptions 4 | { 5 | public class ParameterAnnotation 6 | { 7 | public Attribute AnnotationAttribute { get; set; } 8 | 9 | public string Documentation { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/ModelDescriptions/ParameterDescription.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.ObjectModel; 3 | 4 | namespace SPAuth.Areas.HelpPage.ModelDescriptions 5 | { 6 | public class ParameterDescription 7 | { 8 | public ParameterDescription() 9 | { 10 | Annotations = new Collection(); 11 | } 12 | 13 | public Collection Annotations { get; private set; } 14 | 15 | public string Documentation { get; set; } 16 | 17 | public string Name { get; set; } 18 | 19 | public ModelDescription TypeDescription { get; set; } 20 | } 21 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/ModelDescriptions/SimpleTypeModelDescription.cs: -------------------------------------------------------------------------------- 1 | namespace SPAuth.Areas.HelpPage.ModelDescriptions 2 | { 3 | public class SimpleTypeModelDescription : ModelDescription 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/SampleGeneration/ImageSample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SPAuth.Areas.HelpPage 4 | { 5 | /// 6 | /// This represents an image sample on the help page. There's a display template named ImageSample associated with this class. 7 | /// 8 | public class ImageSample 9 | { 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | /// The URL of an image. 14 | public ImageSample(string src) 15 | { 16 | if (src == null) 17 | { 18 | throw new ArgumentNullException("src"); 19 | } 20 | Src = src; 21 | } 22 | 23 | public string Src { get; private set; } 24 | 25 | public override bool Equals(object obj) 26 | { 27 | ImageSample other = obj as ImageSample; 28 | return other != null && Src == other.Src; 29 | } 30 | 31 | public override int GetHashCode() 32 | { 33 | return Src.GetHashCode(); 34 | } 35 | 36 | public override string ToString() 37 | { 38 | return Src; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/SampleGeneration/InvalidSample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SPAuth.Areas.HelpPage 4 | { 5 | /// 6 | /// This represents an invalid sample on the help page. There's a display template named InvalidSample associated with this class. 7 | /// 8 | public class InvalidSample 9 | { 10 | public InvalidSample(string errorMessage) 11 | { 12 | if (errorMessage == null) 13 | { 14 | throw new ArgumentNullException("errorMessage"); 15 | } 16 | ErrorMessage = errorMessage; 17 | } 18 | 19 | public string ErrorMessage { get; private set; } 20 | 21 | public override bool Equals(object obj) 22 | { 23 | InvalidSample other = obj as InvalidSample; 24 | return other != null && ErrorMessage == other.ErrorMessage; 25 | } 26 | 27 | public override int GetHashCode() 28 | { 29 | return ErrorMessage.GetHashCode(); 30 | } 31 | 32 | public override string ToString() 33 | { 34 | return ErrorMessage; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/SampleGeneration/SampleDirection.cs: -------------------------------------------------------------------------------- 1 | namespace SPAuth.Areas.HelpPage 2 | { 3 | /// 4 | /// Indicates whether the sample is used for request or response 5 | /// 6 | public enum SampleDirection 7 | { 8 | Request = 0, 9 | Response 10 | } 11 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/SampleGeneration/TextSample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SPAuth.Areas.HelpPage 4 | { 5 | /// 6 | /// This represents a preformatted text sample on the help page. There's a display template named TextSample associated with this class. 7 | /// 8 | public class TextSample 9 | { 10 | public TextSample(string text) 11 | { 12 | if (text == null) 13 | { 14 | throw new ArgumentNullException("text"); 15 | } 16 | Text = text; 17 | } 18 | 19 | public string Text { get; private set; } 20 | 21 | public override bool Equals(object obj) 22 | { 23 | TextSample other = obj as TextSample; 24 | return other != null && Text == other.Text; 25 | } 26 | 27 | public override int GetHashCode() 28 | { 29 | return Text.GetHashCode(); 30 | } 31 | 32 | public override string ToString() 33 | { 34 | return Text; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Help/Api.cshtml: -------------------------------------------------------------------------------- 1 | @using System.Web.Http 2 | @using SPAuth.Areas.HelpPage.Models 3 | @model HelpPageApiModel 4 | 5 | @{ 6 | var description = Model.ApiDescription; 7 | ViewBag.Title = description.HttpMethod.Method + " " + description.RelativePath; 8 | } 9 | 10 | 11 |
12 | 19 |
20 | @Html.DisplayForModel() 21 |
22 |
23 | -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Help/DisplayTemplates/ApiGroup.cshtml: -------------------------------------------------------------------------------- 1 | @using System.Web.Http 2 | @using System.Web.Http.Controllers 3 | @using System.Web.Http.Description 4 | @using SPAuth.Areas.HelpPage 5 | @using SPAuth.Areas.HelpPage.Models 6 | @model IGrouping 7 | 8 | @{ 9 | var controllerDocumentation = ViewBag.DocumentationProvider != null ? 10 | ViewBag.DocumentationProvider.GetDocumentation(Model.Key) : 11 | null; 12 | } 13 | 14 |

@Model.Key.ControllerName

15 | @if (!String.IsNullOrEmpty(controllerDocumentation)) 16 | { 17 |

@controllerDocumentation

18 | } 19 | 20 | 21 | 22 | 23 | 24 | @foreach (var api in Model) 25 | { 26 | 27 | 28 | 38 | 39 | } 40 | 41 |
APIDescription
@api.HttpMethod.Method @api.RelativePath 29 | @if (api.Documentation != null) 30 | { 31 |

@api.Documentation

32 | } 33 | else 34 | { 35 |

No documentation available.

36 | } 37 |
-------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Help/DisplayTemplates/CollectionModelDescription.cshtml: -------------------------------------------------------------------------------- 1 | @using SPAuth.Areas.HelpPage.ModelDescriptions 2 | @model CollectionModelDescription 3 | @if (Model.ElementDescription is ComplexTypeModelDescription) 4 | { 5 | @Html.DisplayFor(m => m.ElementDescription) 6 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Help/DisplayTemplates/ComplexTypeModelDescription.cshtml: -------------------------------------------------------------------------------- 1 | @using SPAuth.Areas.HelpPage.ModelDescriptions 2 | @model ComplexTypeModelDescription 3 | @Html.DisplayFor(m => m.Properties, "Parameters") -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Help/DisplayTemplates/DictionaryModelDescription.cshtml: -------------------------------------------------------------------------------- 1 | @using SPAuth.Areas.HelpPage.ModelDescriptions 2 | @model DictionaryModelDescription 3 | Dictionary of @Html.DisplayFor(m => Model.KeyModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.KeyModelDescription }) [key] 4 | and @Html.DisplayFor(m => Model.ValueModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.ValueModelDescription }) [value] -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Help/DisplayTemplates/EnumTypeModelDescription.cshtml: -------------------------------------------------------------------------------- 1 | @using SPAuth.Areas.HelpPage.ModelDescriptions 2 | @model EnumTypeModelDescription 3 | 4 |

Possible enumeration values:

5 | 6 | 7 | 8 | 9 | 10 | 11 | @foreach (EnumValueDescription value in Model.Values) 12 | { 13 | 14 | 15 | 18 | 21 | 22 | } 23 | 24 |
NameValueDescription
@value.Name 16 |

@value.Value

17 |
19 |

@value.Documentation

20 |
-------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Help/DisplayTemplates/HelpPageApiModel.cshtml: -------------------------------------------------------------------------------- 1 | @using System.Web.Http 2 | @using System.Web.Http.Description 3 | @using SPAuth.Areas.HelpPage.Models 4 | @using SPAuth.Areas.HelpPage.ModelDescriptions 5 | @model HelpPageApiModel 6 | 7 | @{ 8 | ApiDescription description = Model.ApiDescription; 9 | } 10 |

@description.HttpMethod.Method @description.RelativePath

11 |
12 |

@description.Documentation

13 | 14 |

Request Information

15 | 16 |

URI Parameters

17 | @Html.DisplayFor(m => m.UriParameters, "Parameters") 18 | 19 |

Body Parameters

20 | 21 |

@Model.RequestDocumentation

22 | 23 | @if (Model.RequestModelDescription != null) 24 | { 25 | @Html.DisplayFor(m => m.RequestModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.RequestModelDescription }) 26 | if (Model.RequestBodyParameters != null) 27 | { 28 | @Html.DisplayFor(m => m.RequestBodyParameters, "Parameters") 29 | } 30 | } 31 | else 32 | { 33 |

None.

34 | } 35 | 36 | @if (Model.SampleRequests.Count > 0) 37 | { 38 |

Request Formats

39 | @Html.DisplayFor(m => m.SampleRequests, "Samples") 40 | } 41 | 42 |

Response Information

43 | 44 |

Resource Description

45 | 46 |

@description.ResponseDescription.Documentation

47 | 48 | @if (Model.ResourceDescription != null) 49 | { 50 | @Html.DisplayFor(m => m.ResourceDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.ResourceDescription }) 51 | if (Model.ResourceProperties != null) 52 | { 53 | @Html.DisplayFor(m => m.ResourceProperties, "Parameters") 54 | } 55 | } 56 | else 57 | { 58 |

None.

59 | } 60 | 61 | @if (Model.SampleResponses.Count > 0) 62 | { 63 |

Response Formats

64 | @Html.DisplayFor(m => m.SampleResponses, "Samples") 65 | } 66 | 67 |
-------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Help/DisplayTemplates/ImageSample.cshtml: -------------------------------------------------------------------------------- 1 | @using SPAuth.Areas.HelpPage 2 | @model ImageSample 3 | 4 | -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Help/DisplayTemplates/InvalidSample.cshtml: -------------------------------------------------------------------------------- 1 | @using SPAuth.Areas.HelpPage 2 | @model InvalidSample 3 | 4 | @if (HttpContext.Current.IsDebuggingEnabled) 5 | { 6 |
7 |

@Model.ErrorMessage

8 |
9 | } 10 | else 11 | { 12 |

Sample not available.

13 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Help/DisplayTemplates/KeyValuePairModelDescription.cshtml: -------------------------------------------------------------------------------- 1 | @using SPAuth.Areas.HelpPage.ModelDescriptions 2 | @model KeyValuePairModelDescription 3 | Pair of @Html.DisplayFor(m => Model.KeyModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.KeyModelDescription }) [key] 4 | and @Html.DisplayFor(m => Model.ValueModelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = Model.ValueModelDescription }) [value] -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Help/DisplayTemplates/ModelDescriptionLink.cshtml: -------------------------------------------------------------------------------- 1 | @using SPAuth.Areas.HelpPage.ModelDescriptions 2 | @model Type 3 | @{ 4 | ModelDescription modelDescription = ViewBag.modelDescription; 5 | if (modelDescription is ComplexTypeModelDescription || modelDescription is EnumTypeModelDescription) 6 | { 7 | if (Model == typeof(Object)) 8 | { 9 | @:Object 10 | } 11 | else 12 | { 13 | @Html.ActionLink(modelDescription.Name, "ResourceModel", "Help", new { modelName = modelDescription.Name }, null) 14 | } 15 | } 16 | else if (modelDescription is CollectionModelDescription) 17 | { 18 | var collectionDescription = modelDescription as CollectionModelDescription; 19 | var elementDescription = collectionDescription.ElementDescription; 20 | @:Collection of @Html.DisplayFor(m => elementDescription.ModelType, "ModelDescriptionLink", new { modelDescription = elementDescription }) 21 | } 22 | else 23 | { 24 | @Html.DisplayFor(m => modelDescription) 25 | } 26 | } -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Help/DisplayTemplates/Parameters.cshtml: -------------------------------------------------------------------------------- 1 | @using System.Collections.Generic 2 | @using System.Collections.ObjectModel 3 | @using System.Web.Http.Description 4 | @using System.Threading 5 | @using SPAuth.Areas.HelpPage.ModelDescriptions 6 | @model IList 7 | 8 | @if (Model.Count > 0) 9 | { 10 | 11 | 12 | 13 | 14 | 15 | @foreach (ParameterDescription parameter in Model) 16 | { 17 | ModelDescription modelDescription = parameter.TypeDescription; 18 | 19 | 20 | 23 | 26 | 39 | 40 | } 41 | 42 |
NameDescriptionTypeAdditional information
@parameter.Name 21 |

@parameter.Documentation

22 |
24 | @Html.DisplayFor(m => modelDescription.ModelType, "ModelDescriptionLink", new { modelDescription = modelDescription }) 25 | 27 | @if (parameter.Annotations.Count > 0) 28 | { 29 | foreach (var annotation in parameter.Annotations) 30 | { 31 |

@annotation.Documentation

32 | } 33 | } 34 | else 35 | { 36 |

None.

37 | } 38 |
43 | } 44 | else 45 | { 46 |

None.

47 | } 48 | 49 | -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Help/DisplayTemplates/Samples.cshtml: -------------------------------------------------------------------------------- 1 | @using System.Net.Http.Headers 2 | @model Dictionary 3 | 4 | @{ 5 | // Group the samples into a single tab if they are the same. 6 | Dictionary samples = Model.GroupBy(pair => pair.Value).ToDictionary( 7 | pair => String.Join(", ", pair.Select(m => m.Key.ToString()).ToArray()), 8 | pair => pair.Key); 9 | var mediaTypes = samples.Keys; 10 | } 11 |
12 | @foreach (var mediaType in mediaTypes) 13 | { 14 |

@mediaType

15 |
16 | Sample: 17 | @{ 18 | var sample = samples[mediaType]; 19 | if (sample == null) 20 | { 21 |

Sample not available.

22 | } 23 | else 24 | { 25 | @Html.DisplayFor(s => sample); 26 | } 27 | } 28 |
29 | } 30 |
-------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Help/DisplayTemplates/SimpleTypeModelDescription.cshtml: -------------------------------------------------------------------------------- 1 | @using SPAuth.Areas.HelpPage.ModelDescriptions 2 | @model SimpleTypeModelDescription 3 | @Model.Documentation -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Help/DisplayTemplates/TextSample.cshtml: -------------------------------------------------------------------------------- 1 | @using SPAuth.Areas.HelpPage 2 | @model TextSample 3 | 4 |
5 | @Model.Text
6 | 
-------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Help/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using System.Web.Http 2 | @using System.Web.Http.Controllers 3 | @using System.Web.Http.Description 4 | @using System.Collections.ObjectModel 5 | @using SPAuth.Areas.HelpPage.Models 6 | @model Collection 7 | 8 | @{ 9 | ViewBag.Title = "ASP.NET Web API Help Page"; 10 | 11 | // Group APIs by controller 12 | ILookup apiGroups = Model.ToLookup(api => api.ActionDescriptor.ControllerDescriptor); 13 | } 14 | 15 | 16 |
17 |
18 |
19 |

@ViewBag.Title

20 |
21 |
22 |
23 |
24 | 32 |
33 | @foreach (var group in apiGroups) 34 | { 35 | @Html.DisplayFor(m => group, "ApiGroup") 36 | } 37 |
38 |
39 | -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Help/ResourceModel.cshtml: -------------------------------------------------------------------------------- 1 | @using System.Web.Http 2 | @using SPAuth.Areas.HelpPage.ModelDescriptions 3 | @model ModelDescription 4 | 5 | 6 |
7 | 14 |

@Model.Name

15 |

@Model.Documentation

16 |
17 | @Html.DisplayFor(m => Model) 18 |
19 |
20 | -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | @ViewBag.Title 7 | @RenderSection("scripts", required: false) 8 | 9 | 10 | @RenderBody() 11 | 12 | -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/Web.config: -------------------------------------------------------------------------------- 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 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /SPAuth/Areas/HelpPage/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | // Change the Layout path below to blend the look and feel of the help page with your existing web pages. 3 | Layout = "~/Areas/HelpPage/Views/Shared/_Layout.cshtml"; 4 | } -------------------------------------------------------------------------------- /SPAuth/Content/css/Site.css: -------------------------------------------------------------------------------- 1 | body{background:#eee} 2 | .loading{position:absolute;top:50%;left:50%;width:300px;margin-left:-150px} 3 | section#body{padding:50px 0 30px;background:#fff} 4 | footer{padding:30px 0;color:#999;font-size:12px} 5 | div.appAlerts{position:fixed;top:20px;right:20px;z-index:1200;width:90%;max-width:300px} 6 | .form-group.multiple{margin-bottom:0} 7 | input.ng-invalid.ng-dirty,textarea.ng-invalid.ng-dirty,select.ng-invalid.ng-dirty{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);} 8 | input.ng-invalid.ng-dirty:focus,textarea.ng-invalid.ng-dirty:focus,select.ng-invalid.ng-dirty:focus{border-color:#a74240;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c1605e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c1605e} 9 | .gutter-top{margin-top:15px} 10 | .gutter-bottom{margin-bottom:15px} 11 | .ng-cloak{display:none} 12 | -------------------------------------------------------------------------------- /SPAuth/Content/css/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JustMaier/MVC5-SPA-Angular/dd0c79ea8fb7ee02c051396d3905aa6a3d28068f/SPAuth/Content/css/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /SPAuth/Content/css/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JustMaier/MVC5-SPA-Angular/dd0c79ea8fb7ee02c051396d3905aa6a3d28068f/SPAuth/Content/css/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /SPAuth/Content/css/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JustMaier/MVC5-SPA-Angular/dd0c79ea8fb7ee02c051396d3905aa6a3d28068f/SPAuth/Content/css/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /SPAuth/Content/stylus/Gruntfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var LIVERELOAD_PORT = 35729; 3 | var lrSnippet = require('connect-livereload')({ port: LIVERELOAD_PORT }); 4 | var mountFolder = function (connect, dir) { 5 | return connect.static(require('path').resolve(dir)); 6 | }; 7 | 8 | module.exports = function (grunt) { 9 | require('load-grunt-tasks')(grunt); 10 | require('time-grunt')(grunt); 11 | 12 | grunt.initConfig({ 13 | watch: { 14 | stylus: { 15 | files: [ 16 | '**/*.styl' 17 | ], 18 | tasks: ['stylus'] 19 | }, 20 | livereload: { 21 | options: { 22 | livereload: LIVERELOAD_PORT 23 | }, 24 | files: [ 25 | '../css/{,*/}*.css', 26 | '../css/bootstrap.css', 27 | '../css/{,*/}*.{png,jpg,jpeg,gif,webp,svg}' 28 | ] 29 | } 30 | }, 31 | stylus: { 32 | compile: { 33 | options: { 34 | compress: true, 35 | paths: ['node_modules/stylus/node_modules'], 36 | use: [require('nib')], 37 | import: ['nib'] 38 | }, 39 | files: { 40 | '../css/site.css': ['site/style.styl'], 41 | '../css/bootstrap.css': ['bootstrap/bootstrap.styl'] 42 | } 43 | } 44 | } 45 | }); 46 | 47 | grunt.registerTask('watchStyles', function(){ 48 | grunt.task.run(['watch']); 49 | }); 50 | grunt.registerTask('compass', ['stylus']); 51 | }; -------------------------------------------------------------------------------- /SPAuth/Content/stylus/bootstrap/alerts.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Alerts 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base styles 7 | // ------------------------- 8 | 9 | .alert { 10 | padding: $alert-padding; 11 | margin-bottom: $line-height-computed; 12 | border: 1px solid transparent; 13 | border-radius: $alert-border-radius; 14 | 15 | // Headings for larger alerts 16 | h4 { 17 | margin-top: 0; 18 | // Specified for the h4 to prevent conflicts of changing $headingsColor 19 | color: inherit; 20 | } 21 | // Provide class for links that match alerts 22 | .alert-link { 23 | font-weight: $alert-link-font-weight; 24 | } 25 | 26 | // Improve alignment and spacing of inner content 27 | > p, 28 | > ul { 29 | margin-bottom: 0; 30 | } 31 | > p + p { 32 | margin-top: 5px; 33 | } 34 | } 35 | 36 | // Dismissable alerts 37 | // 38 | // Expand the right padding and account for the close button's positioning. 39 | 40 | .alert-dismissable { 41 | padding-right: ($alert-padding + 20); 42 | 43 | // Adjust close link position 44 | .close { 45 | position: relative; 46 | top: -2px; 47 | right: -21px; 48 | color: inherit; 49 | } 50 | } 51 | 52 | // Alternate styles 53 | // 54 | // Generate contextual modifier classes for colorizing the alert. 55 | 56 | .alert-success { 57 | alert-variant($alert-success-bg, $alert-success-border, $alert-success-text); 58 | } 59 | .alert-info { 60 | alert-variant($alert-info-bg, $alert-info-border, $alert-info-text); 61 | } 62 | .alert-warning { 63 | alert-variant($alert-warning-bg, $alert-warning-border, $alert-warning-text); 64 | } 65 | .alert-danger { 66 | alert-variant($alert-danger-bg, $alert-danger-border, $alert-danger-text); 67 | } 68 | -------------------------------------------------------------------------------- /SPAuth/Content/stylus/bootstrap/badges.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Badges 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base classes 7 | .badge { 8 | display: inline-block; 9 | min-width: 10px; 10 | padding: 3px 7px; 11 | font-size: $font-size-small; 12 | font-weight: $badge-font-weight; 13 | color: $badge-color; 14 | line-height: $badge-line-height; 15 | vertical-align: baseline; 16 | white-space: nowrap; 17 | text-align: center; 18 | background-color: $badge-bg; 19 | border-radius: $badge-border-radius; 20 | 21 | // Empty badges collapse automatically (not available in IE8) 22 | &:empty { 23 | display: none; 24 | } 25 | } 26 | 27 | // Hover state, but only for links 28 | a.badge { 29 | &:hover, 30 | &:focus { 31 | color: $badge-link-hover-color; 32 | text-decoration: none; 33 | cursor: pointer; 34 | } 35 | } 36 | 37 | // Quick fix for labels/badges in buttons 38 | .btn .badge { 39 | position: relative; 40 | top: -1px; 41 | } 42 | 43 | // Account for counters in navs 44 | a.list-group-item.active > .badge, 45 | .nav-pills > .active > a > .badge { 46 | color: $badge-active-color; 47 | background-color: $badge-active-bg; 48 | } 49 | .nav-pills > li > a > .badge { 50 | margin-left: 3px; 51 | } 52 | -------------------------------------------------------------------------------- /SPAuth/Content/stylus/bootstrap/bootstrap.styl: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.0.0 3 | * 4 | * Copyright 2013 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world by @mdo and @fat. 9 | */ 10 | 11 | // Core variables and mixins 12 | @import "variables"; 13 | @import "mixins"; 14 | 15 | // Reset 16 | @import "normalize"; 17 | @import "print"; 18 | 19 | // Core CSS 20 | @import "scaffolding"; 21 | @import "type"; 22 | @import "code"; 23 | @import "grid"; 24 | @import "tables"; 25 | @import "forms"; 26 | @import "buttons"; 27 | 28 | // Components 29 | @import "component-animations"; 30 | @import "glyphicons"; 31 | @import "dropdowns"; 32 | @import "button-groups"; 33 | @import "input-groups"; 34 | @import "navs"; 35 | @import "navbar"; 36 | @import "breadcrumbs"; 37 | @import "pagination"; 38 | @import "pager"; 39 | @import "labels"; 40 | @import "badges"; 41 | @import "jumbotron"; 42 | @import "thumbnails"; 43 | @import "alerts"; 44 | @import "progress-bars"; 45 | @import "media"; 46 | @import "list-group"; 47 | @import "panels"; 48 | @import "wells"; 49 | @import "close"; 50 | 51 | // Components w/ JavaScript 52 | @import "modals"; 53 | @import "tooltip"; 54 | @import "popovers"; 55 | @import "carousel"; 56 | 57 | // Utility classes 58 | @import "utilities"; 59 | @import "responsive-utilities"; 60 | -------------------------------------------------------------------------------- /SPAuth/Content/stylus/bootstrap/breadcrumbs.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Breadcrumbs 3 | // -------------------------------------------------- 4 | 5 | 6 | .breadcrumb { 7 | padding: 8px 15px; 8 | margin-bottom: $line-height-computed; 9 | list-style: none; 10 | background-color: $breadcrumb-bg; 11 | border-radius: $border-radius-base; 12 | > li { 13 | display: inline-block; 14 | &+li:before { 15 | content: "/\00a0"; // Unicode space added since inline-block means non-collapsing white-space 16 | padding: 0 5px; 17 | color: $breadcrumb-color; 18 | } 19 | } 20 | > .active { 21 | color: $breadcrumb-active-color; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SPAuth/Content/stylus/bootstrap/close.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Close icons 3 | // -------------------------------------------------- 4 | 5 | 6 | .close { 7 | float: right; 8 | font-size: ($font-size-base * 1.5); 9 | font-weight: $close-font-weight; 10 | line-height: 1; 11 | color: $close-color; 12 | text-shadow: $close-text-shadow; 13 | opacity(.2); 14 | 15 | &:hover, 16 | &:focus { 17 | color: $close-color; 18 | text-decoration: none; 19 | cursor: pointer; 20 | opacity(.5); 21 | } 22 | 23 | // Additional properties for button version 24 | // iOS requires the button element instead of an anchor tag. 25 | // If you want the anchor version, it requires `href="#"`. 26 | button& { 27 | padding: 0; 28 | cursor: pointer; 29 | background: transparent; 30 | border: 0; 31 | -webkit-appearance: none; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /SPAuth/Content/stylus/bootstrap/code.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Code (inline and blocK) 3 | // -------------------------------------------------- 4 | 5 | 6 | // Inline and block code styles 7 | code, 8 | pre { 9 | font-family: $font-family-monospace; 10 | } 11 | 12 | // Inline code 13 | code { 14 | padding: 2px 4px; 15 | font-size: 90%; 16 | color: $code-color; 17 | background-color: $code-bg; 18 | white-space: nowrap; 19 | border-radius: $border-radius-base; 20 | } 21 | 22 | // Blocks of code 23 | pre { 24 | display: block; 25 | padding: (($line-height-computed - 1) / 2); 26 | margin: 0 0 ($line-height-computed / 2); 27 | font-size: ($font-size-base - 1); // 14px to 13px 28 | line-height: $line-height-base; 29 | word-break: break-all; 30 | word-wrap: break-word; 31 | color: $pre-color; 32 | background-color: $pre-bg; 33 | border: 1px solid $pre-border-color; 34 | border-radius: $border-radius-base; 35 | 36 | // Make prettyprint styles more spaced out for readability 37 | &.prettyprint { 38 | margin-bottom: $line-height-computed; 39 | } 40 | 41 | // Account for some code outputs that place code tags in pre tags 42 | code { 43 | padding: 0; 44 | font-size: inherit; 45 | color: inherit; 46 | white-space: pre-wrap; 47 | background-color: transparent; 48 | border: 0; 49 | } 50 | } 51 | 52 | // Enable scrollable blocks of code 53 | .pre-scrollable { 54 | max-height: $pre-scrollable-max-height; 55 | overflow-y: scroll; 56 | } 57 | -------------------------------------------------------------------------------- /SPAuth/Content/stylus/bootstrap/component-animations.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Component animations 3 | // -------------------------------------------------- 4 | 5 | // Heads up! 6 | // 7 | // We don't use the `.opacity()` mixin here since it causes a bug with text 8 | // fields in IE7-8. Source: https://github.com/twitter/bootstrap/pull/3552. 9 | 10 | .fade { 11 | opacity(0) 12 | transition(opacity .15s linear); 13 | &.in { 14 | opacity(1) 15 | } 16 | } 17 | 18 | .collapse { 19 | display: none; 20 | &.in { 21 | display: block; 22 | } 23 | } 24 | .collapsing { 25 | position: relative; 26 | height: 0; 27 | overflow: hidden; 28 | transition(height .35s ease); 29 | } 30 | -------------------------------------------------------------------------------- /SPAuth/Content/stylus/bootstrap/jumbotron.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Jumbotron 3 | // -------------------------------------------------- 4 | 5 | 6 | .jumbotron { 7 | padding: $jumbotron-padding; 8 | margin-bottom: $jumbotron-padding; 9 | font-size: ($font-size-base * 1.5); 10 | font-weight: 200; 11 | line-height: ($line-height-base * 1.5); 12 | color: $jumbotron-color; 13 | background-color: $jumbotron-bg; 14 | 15 | h1 { 16 | line-height: 1; 17 | color: $jumbotron-heading-color; 18 | } 19 | p { 20 | line-height: 1.4; 21 | } 22 | 23 | .container & { 24 | border-radius: $border-radius-large; // Only round corners at higher resolutions if contained in a container 25 | } 26 | 27 | @media $media-screen-min-tablet { 28 | padding-top: ($jumbotron-padding * 1.6); 29 | padding-bottom: ($jumbotron-padding * 1.6); 30 | 31 | .container & { 32 | padding-left: ($jumbotron-padding * 2); 33 | padding-right: ($jumbotron-padding * 2); 34 | } 35 | 36 | h1 { 37 | font-size: ($font-size-base * 4.5); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /SPAuth/Content/stylus/bootstrap/labels.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Labels 3 | // -------------------------------------------------- 4 | 5 | .label { 6 | display: inline; 7 | padding: .2em .6em .3em; 8 | font-size: 75%; 9 | font-weight: bold; 10 | line-height: 1; 11 | color: $label-color; 12 | text-align: center; 13 | white-space: nowrap; 14 | vertical-align: baseline; 15 | border-radius: .25em; 16 | 17 | // Add hover effects, but only for links 18 | &[href] { 19 | &:hover, 20 | &:focus { 21 | color: $label-link-hover-color; 22 | text-decoration: none; 23 | cursor: pointer; 24 | } 25 | } 26 | 27 | // Empty labels collapse automatically (not available in IE8) 28 | &:empty { 29 | display: none; 30 | } 31 | } 32 | 33 | // Colors 34 | // Contextual variations (linked labels get darker on :hover) 35 | 36 | .label-default { 37 | label-variant($label-default-bg); 38 | } 39 | 40 | .label-primary { 41 | label-variant($label-primary-bg); 42 | } 43 | 44 | .label-success { 45 | label-variant($label-success-bg); 46 | } 47 | 48 | .label-info { 49 | label-variant($label-info-bg); 50 | } 51 | 52 | .label-warning { 53 | label-variant($label-warning-bg); 54 | } 55 | 56 | .label-danger { 57 | label-variant($label-danger-bg); 58 | } 59 | -------------------------------------------------------------------------------- /SPAuth/Content/stylus/bootstrap/list-group.styl: -------------------------------------------------------------------------------- 1 | // 2 | // List groups 3 | // -------------------------------------------------- 4 | 5 | // Base class 6 | // 7 | // Easily usable on
    ,
      , or
      . 8 | .list-group { 9 | // No need to set list-style: none; since .list-group-item is block level 10 | margin-bottom: 20px; 11 | padding-left: 0; // reset padding because ul and ol 12 | } 13 | 14 | // Individual list items 15 | // ------------------------- 16 | 17 | .list-group-item { 18 | position: relative; 19 | display: block; 20 | padding: 10px 15px; 21 | // Place the border on the list items and negative margin up for better styling 22 | margin-bottom: -1px; 23 | background-color: $list-group-bg; 24 | border: 1px solid $list-group-border; 25 | 26 | // Round the first and last items 27 | &:first-child { 28 | border-top-radius($list-group-border-radius); 29 | } 30 | &:last-child { 31 | margin-bottom: 0; 32 | border-bottom-radius($list-group-border-radius); 33 | } 34 | 35 | // Align badges within list items 36 | > .badge { 37 | float: right; 38 | } 39 | > .badge + .badge { 40 | margin-right: 5px; 41 | } 42 | 43 | // Linked list items 44 | a& { 45 | color: $list-group-link-color; 46 | 47 | .list-group-item-heading { 48 | color: $list-group-link-heading-color; 49 | } 50 | 51 | // Hover state 52 | &:hover, 53 | &:focus { 54 | text-decoration: none; 55 | background-color: $list-group-hover-bg; 56 | } 57 | } 58 | 59 | // Active class on item itself, not parent 60 | &.active, 61 | &.active:hover, 62 | &.active:focus { 63 | z-index: 2; // Place active items above their siblings for proper border styling 64 | color: $list-group-active-color; 65 | background-color: $list-group-active-bg; 66 | border-color: $list-group-active-border; 67 | 68 | // Force color to inherit for custom content 69 | .list-group-item-heading { 70 | color: inherit; 71 | } 72 | .list-group-item-text { 73 | color: lighten($list-group-active-bg, 70%); 74 | } 75 | } 76 | } 77 | 78 | // Custom content options 79 | // ------------------------- 80 | 81 | .list-group-item-heading { 82 | margin-top: 0; 83 | margin-bottom: 5px; 84 | } 85 | .list-group-item-text { 86 | margin-bottom: 0; 87 | line-height: 1.3; 88 | } -------------------------------------------------------------------------------- /SPAuth/Content/stylus/bootstrap/media.styl: -------------------------------------------------------------------------------- 1 | // Media objects 2 | // Source: http://stubbornella.org/content/?p=497 3 | // -------------------------------------------------- 4 | 5 | 6 | // Common styles 7 | // ------------------------- 8 | 9 | // Clear the floats 10 | .media, 11 | .media-body { 12 | overflow: hidden; 13 | zoom: 1; 14 | } 15 | 16 | // Proper spacing between instances of .media 17 | .media, 18 | .media .media { 19 | margin-top: 15px; 20 | } 21 | .media:first-child { 22 | margin-top: 0; 23 | } 24 | 25 | // For images and videos, set to block 26 | .media-object { 27 | display: block; 28 | } 29 | 30 | // Reset margins on headings for tighter default spacing 31 | .media-heading { 32 | margin: 0 0 5px; 33 | } 34 | 35 | 36 | // Media image alignment 37 | // ------------------------- 38 | 39 | .media { 40 | > .pull-left { 41 | margin-right: 10px; 42 | } 43 | > .pull-right { 44 | margin-left: 10px; 45 | } 46 | } 47 | 48 | 49 | // Media list variation 50 | // ------------------------- 51 | 52 | // Undo default ul/ol styles 53 | .media-list { 54 | padding-left: 0; 55 | list-style: none; 56 | } 57 | -------------------------------------------------------------------------------- /SPAuth/Content/stylus/bootstrap/pager.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Pager pagination 3 | // -------------------------------------------------- 4 | 5 | 6 | .pager { 7 | padding-left: 0; 8 | margin: $line-height-computed 0; 9 | list-style: none; 10 | text-align: center; 11 | clearfix(); 12 | li { 13 | display: inline; 14 | > a, 15 | > span { 16 | display: inline-block; 17 | padding: 5px 14px; 18 | background-color: $pagination-bg; 19 | border: 1px solid $pagination-border; 20 | border-radius: $pager-border-radius; 21 | } 22 | 23 | > a:hover, 24 | > a:focus { 25 | text-decoration: none; 26 | background-color: $pagination-hover-bg; 27 | } 28 | } 29 | 30 | .next { 31 | > a, 32 | > span { 33 | float: right; 34 | } 35 | } 36 | 37 | .previous { 38 | > a, 39 | > span { 40 | float: left; 41 | } 42 | } 43 | 44 | .disabled { 45 | > a, 46 | > a:hover, 47 | > a:focus, 48 | > span { 49 | color: $pager-disabled-color; 50 | background-color: $pagination-bg; 51 | cursor: not-allowed; 52 | } 53 | } 54 | 55 | } -------------------------------------------------------------------------------- /SPAuth/Content/stylus/bootstrap/pagination.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Pagination (multiple pages) 3 | // -------------------------------------------------- 4 | .pagination { 5 | display: inline-block; 6 | padding-left: 0; 7 | margin: $line-height-computed 0; 8 | border-radius: $border-radius-base; 9 | 10 | > li { 11 | display: inline; // Remove list-style and block-level defaults 12 | > a, 13 | > span { 14 | position: relative; 15 | float: left; // Collapse white-space 16 | padding: $padding-base-vertical $padding-base-horizontal; 17 | line-height: $line-height-base; 18 | text-decoration: none; 19 | background-color: $pagination-bg; 20 | border: 1px solid $pagination-border; 21 | margin-left: -1px; 22 | } 23 | &:first-child { 24 | > a, 25 | > span { 26 | margin-left: 0; 27 | border-left-radius($border-radius-base); 28 | } 29 | } 30 | &:last-child { 31 | > a, 32 | > span { 33 | border-right-radius($border-radius-base); 34 | } 35 | } 36 | } 37 | 38 | > li > a, 39 | > li > span { 40 | &:hover, 41 | &:focus { 42 | background-color: $pagination-hover-bg; 43 | } 44 | } 45 | 46 | > .active > a, 47 | > .active > span { 48 | &, 49 | &:hover, 50 | &:focus { 51 | z-index: 2; 52 | color: $pagination-active-color; 53 | background-color: $pagination-active-bg; 54 | border-color: $pagination-active-bg; 55 | cursor: default; 56 | } 57 | } 58 | 59 | > .disabled { 60 | > span, 61 | > a, 62 | > a:hover, 63 | > a:focus { 64 | color: $pagination-disabled-color; 65 | background-color: $pagination-bg; 66 | border-color: $pagination-border; 67 | cursor: not-allowed; 68 | } 69 | } 70 | } 71 | 72 | // Sizing 73 | // -------------------------------------------------- 74 | 75 | // Large 76 | .pagination-lg { 77 | pagination-size($padding-large-vertical, $padding-large-horizontal, $font-size-large, $border-radius-large); 78 | } 79 | 80 | // Small 81 | .pagination-sm { 82 | pagination-size($padding-small-vertical, $padding-small-horizontal, $font-size-small, $border-radius-small); 83 | } 84 | -------------------------------------------------------------------------------- /SPAuth/Content/stylus/bootstrap/print.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Basic print styles 3 | // -------------------------------------------------- 4 | // Source: https://github.com/h5bp/html5-boilerplate/blob/master/css/main.css 5 | 6 | @media print { 7 | 8 | * { 9 | text-shadow: none !important; 10 | color: #000 !important; // Black prints faster: h5bp.com/s 11 | background: transparent !important; 12 | box-shadow: none !important; 13 | } 14 | 15 | a, 16 | a:visited { 17 | text-decoration: underline; 18 | } 19 | 20 | a[href]:after { 21 | content: " (" attr(href) ")"; 22 | } 23 | 24 | abbr[title]:after { 25 | content: " (" attr(title) ")"; 26 | } 27 | 28 | // Don't show links for images, or javascript/internal links 29 | .ir a:after, 30 | a[href^="javascript:"]:after, 31 | a[href^="#"]:after { 32 | content: ""; 33 | } 34 | 35 | pre, 36 | blockquote { 37 | border: 1px solid #999; 38 | page-break-inside: avoid; 39 | } 40 | 41 | thead { 42 | display: table-header-group; // h5bp.com/t 43 | } 44 | 45 | tr, 46 | img { 47 | page-break-inside: avoid; 48 | } 49 | 50 | img { 51 | max-width: 100% !important; 52 | } 53 | 54 | @page { 55 | margin: 2cm .5cm; 56 | } 57 | 58 | p, 59 | h2, 60 | h3 { 61 | orphans: 3; 62 | widows: 3; 63 | } 64 | 65 | h2, 66 | h3 { 67 | page-break-after: avoid; 68 | } 69 | 70 | // Bootstrap components 71 | .navbar { 72 | display: none; 73 | } 74 | .table { 75 | td, 76 | th { 77 | background-color: #fff !important; 78 | } 79 | } 80 | .btn, 81 | .dropup > .btn { 82 | > .caret { 83 | border-top-color: #000 !important; 84 | } 85 | } 86 | .label { 87 | border: 1px solid #000; 88 | } 89 | 90 | .table { 91 | border-collapse: collapse !important; 92 | } 93 | .table-bordered { 94 | th, 95 | td { 96 | border: 1px solid #ddd !important; 97 | } 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /SPAuth/Content/stylus/bootstrap/thumbnails.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Thumbnails 3 | // -------------------------------------------------- 4 | 5 | 6 | // Mixin and adjust the regular image class 7 | .thumbnail { 8 | img-thumbnail(); 9 | display: block; // Override the inline-block from `.img-thumbnail` 10 | 11 | > img { 12 | img-responsive(); 13 | } 14 | } 15 | 16 | 17 | // Add a hover state for linked versions only 18 | a.thumbnail:hover, 19 | a.thumbnail:focus { 20 | border-color: $link-color; 21 | } 22 | 23 | // Images and captions 24 | .thumbnail > img { 25 | margin-left: auto; 26 | margin-right: auto; 27 | } 28 | .thumbnail .caption { 29 | padding: $thumbnail-caption-padding; 30 | color: $thumbnail-caption-color; 31 | } 32 | -------------------------------------------------------------------------------- /SPAuth/Content/stylus/bootstrap/utilities.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Utility classes 3 | // -------------------------------------------------- 4 | 5 | 6 | // Floats 7 | // ------------------------- 8 | 9 | .clearfix { 10 | clearfix(); 11 | } 12 | 13 | pull-right() { 14 | float: right !important; 15 | } 16 | 17 | pull-left() { 18 | float: left !important; 19 | } 20 | 21 | .pull-right { 22 | pull-right() 23 | } 24 | 25 | .pull-left { 26 | pull-left() 27 | } 28 | 29 | 30 | // Toggling content 31 | // ------------------------- 32 | 33 | .hide { 34 | display: none !important; 35 | } 36 | .show { 37 | display: block !important; 38 | } 39 | .invisible { 40 | visibility: hidden; 41 | } 42 | .text-hide { 43 | hide-text(); 44 | } 45 | 46 | 47 | // For Affix plugin 48 | // ------------------------- 49 | 50 | .affix { 51 | position: fixed; 52 | } 53 | -------------------------------------------------------------------------------- /SPAuth/Content/stylus/bootstrap/wells.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Wells 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base class 7 | .well { 8 | min-height: 20px; 9 | padding: 19px; 10 | margin-bottom: 20px; 11 | background-color: $well-bg; 12 | border: 1px solid darken($well-bg, 7%); 13 | border-radius: $border-radius-base; 14 | box-shadow inset 0 1px 1px rgba(0,0,0,.05); 15 | blockquote { 16 | border-color: #ddd; 17 | border-color: rgba(0,0,0,.15); 18 | } 19 | } 20 | 21 | // Sizes 22 | .well-lg { 23 | padding: 24px; 24 | border-radius: $border-radius-large; 25 | } 26 | .well-sm { 27 | padding: 9px; 28 | border-radius: $border-radius-small; 29 | } 30 | -------------------------------------------------------------------------------- /SPAuth/Content/stylus/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "player", 3 | "version": "0.0.0", 4 | "dependencies": {}, 5 | "devDependencies": { 6 | "grunt": "~0.4.1", 7 | "grunt-contrib-connect": "~0.3.0", 8 | "grunt-contrib-watch": "~0.5.2", 9 | "grunt-open": "~0.2.0", 10 | "grunt-concurrent": "~0.3.0", 11 | "load-grunt-tasks": "~0.1.0", 12 | "connect-livereload": "~0.2.0", 13 | "stylus": "*", 14 | "nib": "*", 15 | "time-grunt": "~0.1.0", 16 | "grunt-contrib-stylus": "~0.8.0" 17 | }, 18 | "engines": { 19 | "node": ">=0.8.0" 20 | }, 21 | "scripts": { 22 | "test": "grunt test" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SPAuth/Content/stylus/site/style.styl: -------------------------------------------------------------------------------- 1 | @import 'nib' 2 | 3 | @import '../bootstrap/variables' 4 | 5 | /* Typography */ 6 | 7 | /* Containers */ 8 | body 9 | background $gray-lighter 10 | .loading 11 | position absolute 12 | top 50% 13 | left 50% 14 | width 300px 15 | margin-left -(@width /2) 16 | section#body 17 | padding $navbar-height 0 $grid-gutter-width 18 | background #fff 19 | footer 20 | padding $grid-gutter-width 0 21 | color $gray-light 22 | font-size $font-size-small 23 | 24 | /* Alerts */ 25 | div.appAlerts 26 | position: fixed; 27 | top:20px; 28 | right:20px; 29 | z-index: 1200; 30 | width: 90%; 31 | max-width: 300px; 32 | 33 | /* Forms */ 34 | .form-group.multiple 35 | margin-bottom 0 36 | input, textarea, select 37 | &.ng-invalid.ng-dirty 38 | border-color: $state-danger-text; 39 | box-shadow inset 0 1px 1px rgba(0,0,0,.075); 40 | &:focus 41 | border-color: darken(@border-color, 10%); 42 | box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%); 43 | 44 | /* Helpers */ 45 | .gutter-top 46 | margin-top ($grid-gutter-width /2) 47 | .gutter-bottom 48 | margin-bottom ($grid-gutter-width /2) 49 | .ng-cloak 50 | display none -------------------------------------------------------------------------------- /SPAuth/Content/stylus/watch.bat: -------------------------------------------------------------------------------- 1 | grunt watchStyles -------------------------------------------------------------------------------- /SPAuth/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web.Mvc; 5 | 6 | namespace SPAuth.Controllers { 7 | public class HomeController : Controller { 8 | public ActionResult Index() { 9 | return View(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /SPAuth/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="SPAuth.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /SPAuth/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Http; 3 | using System.Web.Mvc; 4 | using System.Web.Optimization; 5 | using System.Web.Routing; 6 | 7 | namespace SPAuth { 8 | public class MvcApplication : HttpApplication { 9 | protected void Application_Start() { 10 | AreaRegistration.RegisterAllAreas(); 11 | GlobalConfiguration.Configure(WebApiConfig.Register); 12 | FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 13 | RouteConfig.RegisterRoutes(RouteTable.Routes); 14 | BundleConfig.RegisterBundles(BundleTable.Bundles); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SPAuth/Migrations/201404061517596_Intial.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | namespace SPAuth.Migrations 3 | { 4 | using System.CodeDom.Compiler; 5 | using System.Data.Entity.Migrations; 6 | using System.Data.Entity.Migrations.Infrastructure; 7 | using System.Resources; 8 | 9 | [GeneratedCode("EntityFramework.Migrations", "6.1.0-30225")] 10 | public sealed partial class Intial : IMigrationMetadata 11 | { 12 | private readonly ResourceManager Resources = new ResourceManager(typeof(Intial)); 13 | 14 | string IMigrationMetadata.Id 15 | { 16 | get { return "201404061517596_Intial"; } 17 | } 18 | 19 | string IMigrationMetadata.Source 20 | { 21 | get { return null; } 22 | } 23 | 24 | string IMigrationMetadata.Target 25 | { 26 | get { return Resources.GetString("Target"); } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SPAuth/Migrations/Configuration.cs: -------------------------------------------------------------------------------- 1 | namespace SPAuth.Migrations 2 | { 3 | using System; 4 | using System.Data.Entity; 5 | using System.Data.Entity.Migrations; 6 | using System.Linq; 7 | 8 | internal sealed class Configuration : DbMigrationsConfiguration 9 | { 10 | public Configuration() 11 | { 12 | AutomaticMigrationsEnabled = true; 13 | } 14 | 15 | protected override void Seed(SPAuth.Models.AppContext context) 16 | { 17 | // This method will be called after migrating to the latest version. 18 | 19 | // You can use the DbSet.AddOrUpdate() helper extension method 20 | // to avoid creating duplicate seed data. E.g. 21 | // 22 | // context.People.AddOrUpdate( 23 | // p => p.FullName, 24 | // new Person { FullName = "Andrew Peters" }, 25 | // new Person { FullName = "Brice Lambson" }, 26 | // new Person { FullName = "Rowan Miller" } 27 | // ); 28 | // 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SPAuth/Models/AppContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNet.Identity.EntityFramework; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Data.Entity; 5 | using System.Linq; 6 | using System.Web; 7 | 8 | namespace SPAuth.Models { 9 | public class AppContext : IdentityDbContext { 10 | public AppContext() 11 | : base("DefaultConnection") { 12 | } 13 | 14 | //Db Sets 15 | //public virtual DbSet Partners { get; set; } 16 | 17 | static AppContext() { 18 | // Set the database intializer which is run once during application start 19 | // This seeds the database with admin user credentials and admin role 20 | Database.SetInitializer(new ApplicationDbInitializer()); 21 | } 22 | 23 | public static AppContext Create() { 24 | return new AppContext(); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /SPAuth/Models/User.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNet.Identity; 2 | using Microsoft.AspNet.Identity.EntityFramework; 3 | using Microsoft.Owin.Security.OAuth; 4 | using System.Data.Entity; 5 | using System.Security.Claims; 6 | using System.Threading.Tasks; 7 | 8 | namespace SPAuth.Models { 9 | public class User : IdentityUser { 10 | public async Task GenerateUserIdentityAsync(UserManager manager, string authenticationType = OAuthDefaults.AuthenticationType) { 11 | // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType 12 | var userIdentity = await manager.CreateIdentityAsync(this, authenticationType); 13 | // Add custom user claims here 14 | return userIdentity; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /SPAuth/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SPAuth")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SPAuth")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("92c7df3c-9c50-447c-aef8-151eadeeb7dc")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /SPAuth/Scripts/_references.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JustMaier/MVC5-SPA-Angular/dd0c79ea8fb7ee02c051396d3905aa6a3d28068f/SPAuth/Scripts/_references.js -------------------------------------------------------------------------------- /SPAuth/Scripts/angular-cookies.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.2.15 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(p,f,n){'use strict';f.module("ngCookies",["ng"]).factory("$cookies",["$rootScope","$browser",function(e,b){var c={},g={},h,k=!1,l=f.copy,m=f.isUndefined;b.addPollFn(function(){var a=b.cookies();h!=a&&(h=a,l(a,g),l(a,c),k&&e.$apply())})();k=!0;e.$watch(function(){var a,d,e;for(a in g)m(c[a])&&b.cookies(a,n);for(a in c)d=c[a],f.isString(d)||(d=""+d,c[a]=d),d!==g[a]&&(b.cookies(a,d),e=!0);if(e)for(a in d=b.cookies(),c)c[a]!==d[a]&&(m(d[a])?delete c[a]:c[a]=d[a])});return c}]).factory("$cookieStore", 7 | ["$cookies",function(e){return{get:function(b){return(b=e[b])?f.fromJson(b):b},put:function(b,c){e[b]=f.toJson(c)},remove:function(b){delete e[b]}}}])})(window,window.angular); 8 | //# sourceMappingURL=angular-cookies.min.js.map 9 | -------------------------------------------------------------------------------- /SPAuth/Scripts/angular-cookies.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"angular-cookies.min.js", 4 | "lineCount":7, 5 | "mappings":"A;;;;;aAKC,SAAQ,CAACA,CAAD,CAASC,CAAT,CAAkBC,CAAlB,CAA6B,CAmBtCD,CAAAE,OAAA,CAAe,WAAf,CAA4B,CAAC,IAAD,CAA5B,CAAAC,QAAA,CA4BW,UA5BX,CA4BuB,CAAC,YAAD,CAAe,UAAf,CAA2B,QAAS,CAACC,CAAD,CAAaC,CAAb,CAAuB,CAAA,IACxEC,EAAU,EAD8D,CAExEC,EAAc,EAF0D,CAGxEC,CAHwE,CAIxEC,EAAU,CAAA,CAJ8D,CAKxEC,EAAOV,CAAAU,KALiE,CAMxEC,EAAcX,CAAAW,YAGlBN,EAAAO,UAAA,CAAmB,QAAQ,EAAG,CAC5B,IAAIC,EAAiBR,CAAAC,QAAA,EACjBE,EAAJ,EAA0BK,CAA1B,GACEL,CAGA,CAHqBK,CAGrB,CAFAH,CAAA,CAAKG,CAAL,CAAqBN,CAArB,CAEA,CADAG,CAAA,CAAKG,CAAL,CAAqBP,CAArB,CACA,CAAIG,CAAJ,EAAaL,CAAAU,OAAA,EAJf,CAF4B,CAA9B,CAAA,EAUAL,EAAA,CAAU,CAAA,CAKVL,EAAAW,OAAA,CASAC,QAAa,EAAG,CAAA,IACVC,CADU,CAEVC,CAFU,CAIVC,CAGJ,KAAKF,CAAL,GAAaV,EAAb,CACMI,CAAA,CAAYL,CAAA,CAAQW,CAAR,CAAZ,CAAJ,EACEZ,CAAAC,QAAA,CAAiBW,CAAjB,CAAuBhB,CAAvB,CAKJ,KAAIgB,CAAJ,GAAYX,EAAZ,CACEY,CAKA,CALQZ,CAAA,CAAQW,CAAR,CAKR,CAJKjB,CAAAoB,SAAA,CAAiBF,CAAjB,CAIL,GAHEA,CACA,CADQ,EACR,CADaA,CACb,CAAAZ,CAAA,CAAQW,CAAR,CAAA,CAAgBC,CAElB,EAAIA,CAAJ,GAAcX,CAAA,CAAYU,CAAZ,CAAd,GACEZ,CAAAC,QAAA,CAAiBW,CAAjB,CAAuBC,CAAvB,CACA,CAAAC,CAAA,CAAU,CAAA,CAFZ,CAOF,IAAIA,CAAJ,CAIE,IAAKF,CAAL,GAFAI,EAEaf,CAFID,CAAAC,QAAA,EAEJA,CAAAA,CAAb,CACMA,CAAA,CAAQW,CAAR,CAAJ,GAAsBI,CAAA,CAAeJ,CAAf,CAAtB,GAEMN,CAAA,CAAYU,CAAA,CAAeJ,CAAf,CAAZ,CAAJ,CACE,OAAOX,CAAA,CAAQW,CAAR,CADT,CAGEX,CAAA,CAAQW,CAAR,CAHF,CAGkBI,CAAA,CAAeJ,CAAf,CALpB,CAhCU,CAThB,CAEA,OAAOX,EA1BqE,CAA3D,CA5BvB,CAAAH,QAAA,CA0HW,cA1HX;AA0H2B,CAAC,UAAD,CAAa,QAAQ,CAACmB,CAAD,CAAW,CAErD,MAAO,KAWAC,QAAQ,CAACC,CAAD,CAAM,CAEjB,MAAO,CADHN,CACG,CADKI,CAAA,CAASE,CAAT,CACL,EAAQxB,CAAAyB,SAAA,CAAiBP,CAAjB,CAAR,CAAkCA,CAFxB,CAXd,KA0BAQ,QAAQ,CAACF,CAAD,CAAMN,CAAN,CAAa,CACxBI,CAAA,CAASE,CAAT,CAAA,CAAgBxB,CAAA2B,OAAA,CAAeT,CAAf,CADQ,CA1BrB,QAuCGU,QAAQ,CAACJ,CAAD,CAAM,CACpB,OAAOF,CAAA,CAASE,CAAT,CADa,CAvCjB,CAF8C,CAAhC,CA1H3B,CAnBsC,CAArC,CAAA,CA8LEzB,MA9LF,CA8LUA,MAAAC,QA9LV;", 6 | "sources":["angular-cookies.js"], 7 | "names":["window","angular","undefined","module","factory","$rootScope","$browser","cookies","lastCookies","lastBrowserCookies","runEval","copy","isUndefined","addPollFn","currentCookies","$apply","$watch","push","name","value","updated","isString","browserCookies","$cookies","get","key","fromJson","put","toJson","remove"] 8 | } 9 | -------------------------------------------------------------------------------- /SPAuth/Scripts/angular-csp.css: -------------------------------------------------------------------------------- 1 | /* Include this file in your html if you are using the CSP mode. */ 2 | 3 | @charset "UTF-8"; 4 | 5 | [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], 6 | .ng-cloak, .x-ng-cloak, 7 | .ng-hide { 8 | display: none !important; 9 | } 10 | 11 | ng\:form { 12 | display: block; 13 | } 14 | 15 | .ng-animate-block-transitions { 16 | transition:0s all!important; 17 | -webkit-transition:0s all!important; 18 | } 19 | -------------------------------------------------------------------------------- /SPAuth/Scripts/angular-loader.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.2.15 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(){'use strict';function d(a){return function(){var c=arguments[0],b,c="["+(a?a+":":"")+c+"] http://errors.angularjs.org/1.2.15/"+(a?a+"/":"")+c;for(b=1;b 2 |
      3 |
      4 |
      5 |

      Confirming Email...

      6 |
      7 |
      8 |
      9 | -------------------------------------------------------------------------------- /SPAuth/Views/Home/_ForgotPassword.cshtml: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /SPAuth/Views/Home/_Home.cshtml: -------------------------------------------------------------------------------- 1 |  30 | 31 | -------------------------------------------------------------------------------- /SPAuth/Views/Home/_Login.cshtml: -------------------------------------------------------------------------------- 1 |  26 | -------------------------------------------------------------------------------- /SPAuth/Views/Home/_Manage.cshtml: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /SPAuth/Views/Home/_Register.cshtml: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /SPAuth/Views/Home/_RegisterExternal.cshtml: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /SPAuth/Views/Home/_ResetPassword.cshtml: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /SPAuth/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model System.Web.Mvc.HandleErrorInfo 2 | @{ 3 | ViewBag.Title = "Error"; 4 | } 5 | 6 |

      Error.

      7 |

      An error occurred while processing your request.

      8 | 9 | -------------------------------------------------------------------------------- /SPAuth/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | @ViewBag.Title - My ASP.NET Application 6 | 7 | 8 | @Styles.Render("~/Content/css") 9 | @Scripts.Render("~/bundles/modernizr") 10 | 11 | 12 | 29 |
      30 | @RenderBody() 31 |
      32 |
      33 |

      © @DateTime.Now.Year - My ASP.NET Application

      34 |
      35 |
      36 | 37 | @Scripts.Render("~/bundles/angular") 38 | @Scripts.Render("~/bundles/angularBootstrap") 39 | @Scripts.Render("~/bundles/app") 40 | @RenderSection("Scripts", required: false) 41 | 42 | 43 | -------------------------------------------------------------------------------- /SPAuth/Views/Web.config: -------------------------------------------------------------------------------- 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 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /SPAuth/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } 4 | -------------------------------------------------------------------------------- /SPAuth/Web.Debug.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /SPAuth/Web.Release.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /SPAuth/Web/Utility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | 6 | namespace SPAuth.Web { 7 | public static class Utility { 8 | public static string AbsoluteUrl(string relativeUrl) { 9 | if (string.IsNullOrEmpty(relativeUrl)) 10 | return relativeUrl; 11 | 12 | var httpContext = HttpContext.Current; 13 | if (httpContext == null) 14 | return relativeUrl; 15 | 16 | if (relativeUrl.StartsWith("/")) 17 | relativeUrl = relativeUrl.Insert(0, "~"); 18 | if (!relativeUrl.StartsWith("~/")) 19 | relativeUrl = relativeUrl.Insert(0, "~/"); 20 | 21 | var url = httpContext.Request.Url; 22 | var port = url.Port != 80 ? (":" + url.Port) : String.Empty; 23 | 24 | return String.Format("{0}://{1}{2}{3}", 25 | url.Scheme, url.Host, port, VirtualPathUtility.ToAbsolute(relativeUrl)); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /SPAuth/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JustMaier/MVC5-SPA-Angular/dd0c79ea8fb7ee02c051396d3905aa6a3d28068f/SPAuth/favicon.ico --------------------------------------------------------------------------------