diff --git a/src/Squidex/Startup.cs b/src/Squidex/Startup.cs index 05b7c7acc..822f251ac 100644 --- a/src/Squidex/Startup.cs +++ b/src/Squidex/Startup.cs @@ -97,18 +97,7 @@ namespace Squidex { app.UseMiddleware(); } - - if (Environment.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - app.UseWebpackProxy(); - app.UseDefaultFiles(); - } - else - { - app.UseDefaultFiles(new DefaultFilesOptions { DefaultFileNames = new List { "build/index.html" } }); - } - + UseIdentity(app); UseApi(app); UseFrontend(app); diff --git a/src/Squidex/app/polyfills.ts b/src/Squidex/app/polyfills.ts index 5a27d0cab..32f0770e3 100644 --- a/src/Squidex/app/polyfills.ts +++ b/src/Squidex/app/polyfills.ts @@ -6,7 +6,7 @@ */ import 'core-js/es6'; -import 'reflect-metadata'; +import 'core-js/es7/reflect'; require('zone.js/dist/zone'); diff --git a/src/Squidex/app/shared/guards/auth.guard.ts b/src/Squidex/app/shared/guards/auth.guard.ts index 16b1f49be..58d39d805 100644 --- a/src/Squidex/app/shared/guards/auth.guard.ts +++ b/src/Squidex/app/shared/guards/auth.guard.ts @@ -20,10 +20,16 @@ export class AuthGuard implements Ng2Router.CanActivate { ) { } - public canActivate(route: Ng2Router.ActivatedRouteSnapshot, state: Ng2Router.RouterStateSnapshot): boolean { - if (state.url !== LOGIN_URL && !this.authService.isAuthenticated) { - this.router.navigate([LOGIN_URL]); - return false; + public canActivate(route: Ng2Router.ActivatedRouteSnapshot, state: Ng2Router.RouterStateSnapshot): Promise | boolean { + if (state.url !== LOGIN_URL) { + return this.authService.checkLogin().then(isAuthenticated => { + if (!isAuthenticated) { + this.router.navigate([LOGIN_URL]); + + return false; + } + return true; + }); } return true; diff --git a/src/Squidex/app/shared/services/auth.service.ts b/src/Squidex/app/shared/services/auth.service.ts index b82d067f4..7df98f2b6 100644 --- a/src/Squidex/app/shared/services/auth.service.ts +++ b/src/Squidex/app/shared/services/auth.service.ts @@ -22,13 +22,30 @@ import { ApiUrlConfig } from './../../framework'; export class AuthService { private readonly userManager: UserManager; private currentUser: User | null = null; + private checkLoginPromise: Promise; public get user(): User | null { return this.currentUser; } - public get isAuthenticated() { - return this.currentUser; + public get isAuthenticated(): boolean { + return !!this.currentUser; + } + + public checkLogin(): Promise { + if (this.checkLoginPromise) { + return this.checkLoginPromise; + } else if (this.currentUser) { + return Promise.resolve(true); + } else { + this.checkLoginPromise = + this.checkState(this.userManager.getUser()) + .then(result => { + return result || this.checkState(this.userManager.signinSilent()); + }); + + return this.checkLoginPromise; + } } constructor(apiUrl: ApiUrlConfig, @@ -42,39 +59,47 @@ export class AuthService { response_type: 'id_token token', silent_redirect_uri: apiUrl.buildUrl('identity-server/client-callback-silent/'), popup_redirect_uri: apiUrl.buildUrl('identity-server/client-callback-popup/'), - authority: apiUrl.buildUrl('identity-server/'), + authority: apiUrl.buildUrl('identity-server/') }); - this.userManager.getUser() - .then((user) => { - this.currentUser = user; - }) - .catch((err) => { - this.currentUser = null; - }); + this.userManager.events.addUserLoaded(user => { + this.currentUser = user; + }); this.userManager.events.addUserUnloaded(() => { this.currentUser = null; }); + + this.checkLogin(); } public logout(): Observable { return Observable.fromPromise(this.userManager.signoutRedirectCallback()); } - public login(): Observable { - let userPromise = - this.userManager.signinSilent() + public login(): Observable { + const userPromise = + this.checkState(this.userManager.signinSilent()) + .then(result => { + return result || this.checkState(this.userManager.signinPopup()); + }); + + return Observable.fromPromise(userPromise); + } + + private checkState(promise: Promise): Promise { + const resultPromise = + promise .then(user => { if (user) { - return user; - } else { - return this.userManager.signinPopup(); + this.currentUser = user; } - }) - .catch(() => this.userManager.signinPopup()); + return !!this.currentUser; + }).catch((err) => { + return false; + }); - return Observable.fromPromise(userPromise); + return resultPromise; } public authGet(url: string, options?: Ng2Http.RequestOptions): Observable { diff --git a/src/Squidex/package.json b/src/Squidex/package.json index 1c25bc7ba..245a9c165 100644 --- a/src/Squidex/package.json +++ b/src/Squidex/package.json @@ -8,28 +8,28 @@ "test": "karma start", "test:coverage": "karma start karma.coverage.conf.js", "test:clean": "rimraf _test-output", - "dev": "webpack-dev-server --inline --hot --port 3000", + "dev": "cpx node_modules/oidc-client/dist/oidc-client.min.js wwwroot/scripts/ & webpack-dev-server --inline --hot --port 3000", "build": "webpack --config app-config/webpack.prod.js --bail", + "build:copy": "cpx node_modules/oidc-client/dist/oidc-client.min.js", "build:clean": "rimraf wwwroot/build" }, "dependencies": { - "@angular/common": "2.1.0", - "@angular/compiler": "2.1.0", - "@angular/core": "2.1.0", - "@angular/forms": "2.1.0", - "@angular/http": "2.1.0", - "@angular/platform-browser": "2.1.0", - "@angular/platform-browser-dynamic": "2.1.0", - "@angular/router": "3.1.0", + "@angular/common": "2.1.1", + "@angular/compiler": "2.1.1", + "@angular/core": "2.1.1", + "@angular/forms": "2.1.1", + "@angular/http": "2.1.1", + "@angular/platform-browser": "2.1.1", + "@angular/platform-browser-dynamic": "2.1.1", + "@angular/router": "3.1.1", "bootstrap": "^4.0.0-alpha.2", "core-js": "^2.4.1", - "font-awesome": "^4.6.3", + "font-awesome": "^4.7.0", "immutable": "^3.8.1", "mousetrap": "^1.6.0", - "oidc-client": "^1.2.0", + "oidc-client": "^1.2.1-beta.3", "reflect-metadata": "^0.1.3", "rxjs": "5.0.0-beta.12", - "systemjs": "0.19.38", "zone.js": "^0.6.23" }, "devDependencies": { @@ -39,6 +39,7 @@ "@types/mousetrap": "^1.5.26-alpha", "@types/node": "^6.0.33", "awesome-typescript-loader": "^2.2.4", + "cpx": "^1.5.0", "css-loader": "^0.25.0", "exports-loader": "^0.6.3", "extract-text-webpack-plugin": "^1.0.1", @@ -69,10 +70,10 @@ "tslint": "^3.13.0-dev.0", "tslint-loader": "^2.1.5", "typemoq": "^0.3.2", - "typescript": "^2.0.0-dev.20160711", + "typescript": "^2.0.6", "underscore": "^1.8.3", - "webpack": "^1.13.1", + "webpack": "^1.13.3", "webpack-dev-server": "^1.14.1", - "webpack-merge": "^0.14.0" + "webpack-merge": "^0.15.0" } } diff --git a/src/Squidex/project.json b/src/Squidex/project.json index 951c8cea0..587ce4f2b 100644 --- a/src/Squidex/project.json +++ b/src/Squidex/project.json @@ -83,6 +83,7 @@ "scripts": { "prepublish": [ "npm install", + "npm run-script build:copy", "npm run-script build" ], "postpublish": [ diff --git a/src/Squidex/wwwroot/scripts/oidc-client.min.js b/src/Squidex/wwwroot/scripts/oidc-client.min.js deleted file mode 100644 index a31652edc..000000000 --- a/src/Squidex/wwwroot/scripts/oidc-client.min.js +++ /dev/null @@ -1,77 +0,0 @@ -var Oidc=function(t){function e(r){if(n[r])return n[r].exports;var i=n[r]={exports:{},id:r,loaded:!1};return t[r].call(i.exports,i,i.exports,e),i.loaded=!0,i.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){n(1),t.exports=n(291)},function(t,e,n){(function(t){"use strict";function e(t,e,n){t[e]||Object[r](t,e,{writable:!0,configurable:!0,value:n})}if(n(2),n(286),n(288),t._babelPolyfill)throw new Error("only one instance of babel-polyfill is allowed");t._babelPolyfill=!0;var r="defineProperty";e(String.prototype,"padLeft","".padStart),e(String.prototype,"padRight","".padEnd),"pop,reverse,shift,keys,values,entries,indexOf,every,some,forEach,map,filter,find,findIndex,includes,join,slice,concat,push,splice,unshift,sort,lastIndexOf,reduce,reduceRight,copyWithin,fill".split(",").forEach(function(t){[][t]&&e(Array,t,Function.call.bind([][t]))})}).call(e,function(){return this}())},function(t,e,n){n(3),n(50),n(51),n(52),n(53),n(55),n(58),n(59),n(60),n(61),n(62),n(63),n(64),n(65),n(66),n(68),n(70),n(72),n(74),n(77),n(78),n(79),n(83),n(85),n(87),n(91),n(92),n(93),n(94),n(96),n(97),n(98),n(99),n(100),n(101),n(102),n(104),n(105),n(106),n(108),n(109),n(110),n(112),n(113),n(114),n(115),n(116),n(117),n(118),n(119),n(120),n(121),n(122),n(123),n(124),n(125),n(130),n(131),n(135),n(136),n(137),n(138),n(140),n(141),n(142),n(143),n(144),n(145),n(146),n(147),n(148),n(149),n(150),n(151),n(152),n(153),n(154),n(155),n(156),n(158),n(159),n(164),n(165),n(167),n(168),n(169),n(172),n(173),n(174),n(175),n(176),n(178),n(179),n(180),n(181),n(184),n(186),n(187),n(188),n(190),n(192),n(194),n(195),n(196),n(198),n(199),n(200),n(201),n(207),n(210),n(211),n(213),n(214),n(217),n(218),n(221),n(222),n(223),n(224),n(225),n(226),n(227),n(228),n(229),n(230),n(231),n(232),n(233),n(234),n(235),n(236),n(237),n(238),n(239),n(241),n(242),n(243),n(244),n(245),n(246),n(248),n(249),n(250),n(251),n(252),n(253),n(255),n(256),n(258),n(259),n(260),n(261),n(264),n(265),n(266),n(267),n(268),n(269),n(270),n(271),n(273),n(274),n(275),n(276),n(277),n(278),n(279),n(280),n(281),n(284),n(285),t.exports=n(5)},function(t,e,n){"use strict";var r=n(4),i=n(5),s=n(6),o=n(7),a=n(9),u=n(18),c=n(22).KEY,f=n(8),h=n(23),l=n(24),d=n(19),p=n(25),g=n(26),y=n(39),v=n(42),m=n(12),S=n(29),b=n(16),w=n(17),E=n(43),x=n(46),_=n(48),A=n(11),F=_.f,P=A.f,O=x.f,C=r.Symbol,I=r.JSON,T=I&&I.stringify,j=!1,R="prototype",D=p("_hidden"),H=p("toPrimitive"),k={}.propertyIsEnumerable,N=h("symbol-registry"),B=h("symbols"),M=Object[R],V="function"==typeof C,L=r.QObject,K=o&&f(function(){return 7!=E(P({},"a",{get:function(){return P(this,"a",{value:7}).a}})).a})?function(t,e,n){var r=F(M,e);r&&delete M[e],P(t,e,n),r&&t!==M&&P(M,e,r)}:P,U=function(t){var e=B[t]=E(C[R]);return e._k=t,o&&j&&K(M,t,{configurable:!0,set:function(e){s(this,D)&&s(this[D],t)&&(this[D][t]=!1),K(this,t,w(1,e))}}),e},q=V&&"symbol"==typeof C.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof C},W=function(t,e,n){return m(t),e=b(e,!0),m(n),s(B,e)?(n.enumerable?(s(t,D)&&t[D][e]&&(t[D][e]=!1),n=E(n,{enumerable:w(0,!1)})):(s(t,D)||P(t,D,w(1,{})),t[D][e]=!0),K(t,e,n)):P(t,e,n)},J=function(t,e){m(t);for(var n,r=y(e=S(e)),i=0,s=r.length;s>i;)W(t,n=r[i++],e[n]);return t},z=function(t,e){return void 0===e?E(t):J(E(t),e)},Y=function(t){var e=k.call(this,t=b(t,!0));return e||!s(this,t)||!s(B,t)||s(this,D)&&this[D][t]?e:!0},G=function(t,e){var n=F(t=S(t),e=b(e,!0));return!n||!s(B,e)||s(t,D)&&t[D][e]||(n.enumerable=!0),n},X=function(t){for(var e,n=O(S(t)),r=[],i=0;n.length>i;)s(B,e=n[i++])||e==D||e==c||r.push(e);return r},$=function(t){for(var e,n=O(S(t)),r=[],i=0;n.length>i;)s(B,e=n[i++])&&r.push(B[e]);return r},Z=function(t){if(void 0!==t&&!q(t)){for(var e,n,r=[t],i=1;arguments.length>i;)r.push(arguments[i++]);return e=r[1],"function"==typeof e&&(n=e),!n&&v(e)||(e=function(t,e){return n&&(e=n.call(this,t,e)),q(e)?void 0:e}),r[1]=e,T.apply(I,r)}},Q=f(function(){var t=C();return"[null]"!=T([t])||"{}"!=T({a:t})||"{}"!=T(Object(t))});V||(C=function(){if(this instanceof C)throw TypeError("Symbol is not a constructor!");return U(d(arguments.length>0?arguments[0]:void 0))},u(C[R],"toString",function(){return this._k}),_.f=G,A.f=W,n(47).f=x.f=X,n(41).f=Y,n(40).f=$,o&&!n(49)&&u(M,"propertyIsEnumerable",Y,!0)),a(a.G+a.W+a.F*!V,{Symbol:C});for(var tt="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),et=0;tt.length>et;){var nt=tt[et++],rt=i.Symbol,it=p(nt);nt in rt||P(rt,nt,{value:V?it:U(it)})}L&&L[R]&&L[R].findChild||(j=!0),a(a.S+a.F*!V,"Symbol",{"for":function(t){return s(N,t+="")?N[t]:N[t]=C(t)},keyFor:function(t){if(q(t))return g(N,t);throw TypeError(t+" is not a symbol!")},useSetter:function(){j=!0},useSimple:function(){j=!1}}),a(a.S+a.F*!V,"Object",{create:z,defineProperty:W,defineProperties:J,getOwnPropertyDescriptor:G,getOwnPropertyNames:X,getOwnPropertySymbols:$}),I&&a(a.S+a.F*(!V||Q),"JSON",{stringify:Z}),C[R][H]||n(10)(C[R],H,C[R].valueOf),l(C,"Symbol"),l(Math,"Math",!0),l(r.JSON,"JSON",!0)},function(t,e){var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(t,e){var n=t.exports={version:"2.2.1"};"number"==typeof __e&&(__e=n)},function(t,e){var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},function(t,e,n){t.exports=!n(8)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,e){t.exports=function(t){try{return!!t()}catch(e){return!0}}},function(t,e,n){var r=n(4),i=n(5),s=n(10),o=n(18),a=n(20),u="prototype",c=function(t,e,n){var f,h,l,d,p=t&c.F,g=t&c.G,y=t&c.S,v=t&c.P,m=t&c.B,S=g?r:y?r[e]||(r[e]={}):(r[e]||{})[u],b=g?i:i[e]||(i[e]={}),w=b[u]||(b[u]={});g&&(n=e);for(f in n)h=!p&&S&&void 0!==S[f],l=(h?S:n)[f],d=m&&h?a(l,r):v&&"function"==typeof l?a(Function.call,l):l,S&&o(S,f,l,t&c.U),b[f]!=l&&s(b,f,d),v&&w[f]!=l&&(w[f]=l)};r.core=i,c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,t.exports=c},function(t,e,n){var r=n(11),i=n(17);t.exports=n(7)?function(t,e,n){return r.f(t,e,i(1,n))}:function(t,e,n){return t[e]=n,t}},function(t,e,n){var r=n(12),i=n(14),s=n(16),o=Object.defineProperty;e.f=n(7)?Object.defineProperty:function(t,e,n){if(r(t),e=s(e,!0),r(n),i)try{return o(t,e,n)}catch(a){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(t[e]=n.value),t}},function(t,e,n){var r=n(13);t.exports=function(t){if(!r(t))throw TypeError(t+" is not an object!");return t}},function(t,e){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,e,n){t.exports=!n(7)&&!n(8)(function(){return 7!=Object.defineProperty(n(15)("div"),"a",{get:function(){return 7}}).a})},function(t,e,n){var r=n(13),i=n(4).document,s=r(i)&&r(i.createElement);t.exports=function(t){return s?i.createElement(t):{}}},function(t,e,n){var r=n(13);t.exports=function(t,e){if(!r(t))return t;var n,i;if(e&&"function"==typeof(n=t.toString)&&!r(i=n.call(t)))return i;if("function"==typeof(n=t.valueOf)&&!r(i=n.call(t)))return i;if(!e&&"function"==typeof(n=t.toString)&&!r(i=n.call(t)))return i;throw TypeError("Can't convert object to primitive value")}},function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e,n){var r=n(4),i=n(10),s=n(6),o=n(19)("src"),a="toString",u=Function[a],c=(""+u).split(a);n(5).inspectSource=function(t){return u.call(t)},(t.exports=function(t,e,n,a){var u="function"==typeof n;u&&(s(n,"name")||i(n,"name",e)),t[e]!==n&&(u&&(s(n,o)||i(n,o,t[e]?""+t[e]:c.join(String(e)))),t===r?t[e]=n:a?t[e]?t[e]=n:i(t,e,n):(delete t[e],i(t,e,n)))})(Function.prototype,a,function(){return"function"==typeof this&&this[o]||u.call(this)})},function(t,e){var n=0,r=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++n+r).toString(36))}},function(t,e,n){var r=n(21);t.exports=function(t,e,n){if(r(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,r){return t.call(e,n,r)};case 3:return function(n,r,i){return t.call(e,n,r,i)}}return function(){return t.apply(e,arguments)}}},function(t,e){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,e,n){var r=n(19)("meta"),i=n(13),s=n(6),o=n(11).f,a=0,u=Object.isExtensible||function(){return!0},c=!n(8)(function(){return u(Object.preventExtensions({}))}),f=function(t){o(t,r,{value:{i:"O"+ ++a,w:{}}})},h=function(t,e){if(!i(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!s(t,r)){if(!u(t))return"F";if(!e)return"E";f(t)}return t[r].i},l=function(t,e){if(!s(t,r)){if(!u(t))return!0;if(!e)return!1;f(t)}return t[r].w},d=function(t){return c&&p.NEED&&u(t)&&!s(t,r)&&f(t),t},p=t.exports={KEY:r,NEED:!1,fastKey:h,getWeak:l,onFreeze:d}},function(t,e,n){var r=n(4),i="__core-js_shared__",s=r[i]||(r[i]={});t.exports=function(t){return s[t]||(s[t]={})}},function(t,e,n){var r=n(11).f,i=n(6),s=n(25)("toStringTag");t.exports=function(t,e,n){t&&!i(t=n?t:t.prototype,s)&&r(t,s,{configurable:!0,value:e})}},function(t,e,n){var r=n(23)("wks"),i=n(19),s=n(4).Symbol,o="function"==typeof s;t.exports=function(t){return r[t]||(r[t]=o&&s[t]||(o?s:i)("Symbol."+t))}},function(t,e,n){var r=n(27),i=n(29);t.exports=function(t,e){for(var n,s=i(t),o=r(s),a=o.length,u=0;a>u;)if(s[n=o[u++]]===e)return n}},function(t,e,n){var r=n(28),i=n(38);t.exports=Object.keys||function(t){return r(t,i)}},function(t,e,n){var r=n(6),i=n(29),s=n(33)(!1),o=n(37)("IE_PROTO");t.exports=function(t,e){var n,a=i(t),u=0,c=[];for(n in a)n!=o&&r(a,n)&&c.push(n);for(;e.length>u;)r(a,n=e[u++])&&(~s(c,n)||c.push(n));return c}},function(t,e,n){var r=n(30),i=n(32);t.exports=function(t){return r(i(t))}},function(t,e,n){var r=n(31);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==r(t)?t.split(""):Object(t)}},function(t,e){var n={}.toString;t.exports=function(t){return n.call(t).slice(8,-1)}},function(t,e){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},function(t,e,n){var r=n(29),i=n(34),s=n(36);t.exports=function(t){return function(e,n,o){var a,u=r(e),c=i(u.length),f=s(o,c);if(t&&n!=n){for(;c>f;)if(a=u[f++],a!=a)return!0}else for(;c>f;f++)if((t||f in u)&&u[f]===n)return t||f;return!t&&-1}}},function(t,e,n){var r=n(35),i=Math.min;t.exports=function(t){return t>0?i(r(t),9007199254740991):0}},function(t,e){var n=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:n)(t)}},function(t,e,n){var r=n(35),i=Math.max,s=Math.min;t.exports=function(t,e){return t=r(t),0>t?i(t+e,0):s(t,e)}},function(t,e,n){var r=n(23)("keys"),i=n(19);t.exports=function(t){return r[t]||(r[t]=i(t))}},function(t,e){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,e,n){var r=n(27),i=n(40),s=n(41);t.exports=function(t){var e=r(t),n=i.f;if(n)for(var o,a=n(t),u=s.f,c=0;a.length>c;)u.call(t,o=a[c++])&&e.push(o);return e}},function(t,e){e.f=Object.getOwnPropertySymbols},function(t,e){e.f={}.propertyIsEnumerable},function(t,e,n){var r=n(31);t.exports=Array.isArray||function(t){return"Array"==r(t)}},function(t,e,n){var r=n(12),i=n(44),s=n(38),o=n(37)("IE_PROTO"),a=function(){},u="prototype",c=function(){var t,e=n(15)("iframe"),r=s.length,i=">";for(e.style.display="none",n(45).appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write("