diff --git a/src/Squidex/Areas/Api/Controllers/UI/Models/UISettingsDto.cs b/src/Squidex/Areas/Api/Controllers/UI/Models/UISettingsDto.cs
index 675b1265d..2183a87e8 100644
--- a/src/Squidex/Areas/Api/Controllers/UI/Models/UISettingsDto.cs
+++ b/src/Squidex/Areas/Api/Controllers/UI/Models/UISettingsDto.cs
@@ -3,26 +3,12 @@
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
-// ==========================================================================
-
-using System.ComponentModel.DataAnnotations;
+// ==========================================================================using System.ComponentModel.DataAnnotations;
namespace Squidex.Areas.Api.Controllers.UI.Models
{
public sealed class UISettingsDto
{
- ///
- /// The type of the map control.
- ///
- [Required]
- public string MapType { get; set; }
-
- ///
- /// The key for the map control.
- ///
- [Required]
- public string MapKey { get; set; }
-
///
/// True when the user can create apps.
///
diff --git a/src/Squidex/Areas/Api/Controllers/UI/MyUIOptions.cs b/src/Squidex/Areas/Api/Controllers/UI/MyUIOptions.cs
index 206d380ef..ca8bdcc5e 100644
--- a/src/Squidex/Areas/Api/Controllers/UI/MyUIOptions.cs
+++ b/src/Squidex/Areas/Api/Controllers/UI/MyUIOptions.cs
@@ -15,6 +15,12 @@ namespace Squidex.Areas.Api.Controllers.UI
public MapOptions Map { get; set; }
+ public bool HideNews { get; set; }
+
+ public bool HideOnboarding { get; set; }
+
+ public bool RedirectToLogin { get; set; }
+
public bool OnlyAdminsCanCreateApps { get; set; }
public sealed class MapOptions
diff --git a/src/Squidex/Areas/Api/Controllers/UI/UIController.cs b/src/Squidex/Areas/Api/Controllers/UI/UIController.cs
index 3ca2f79fb..dd12c5be5 100644
--- a/src/Squidex/Areas/Api/Controllers/UI/UIController.cs
+++ b/src/Squidex/Areas/Api/Controllers/UI/UIController.cs
@@ -48,14 +48,9 @@ namespace Squidex.Areas.Api.Controllers.UI
{
var result = new UISettingsDto
{
- MapType = uiOptions.Map?.Type ?? "OSM",
- MapKey = uiOptions.Map?.GoogleMaps?.Key
+ CanCreateApps = !uiOptions.OnlyAdminsCanCreateApps || Context.Permissions.Includes(CreateAppPermission)
};
- var canCreateApps = !uiOptions.OnlyAdminsCanCreateApps || Context.Permissions.Includes(CreateAppPermission);
-
- result.CanCreateApps = canCreateApps;
-
return Ok(result);
}
diff --git a/src/Squidex/Areas/Frontend/Middlewares/IndexExtensions.cs b/src/Squidex/Areas/Frontend/Middlewares/IndexExtensions.cs
index 13db98ab4..518bb7ae9 100644
--- a/src/Squidex/Areas/Frontend/Middlewares/IndexExtensions.cs
+++ b/src/Squidex/Areas/Frontend/Middlewares/IndexExtensions.cs
@@ -7,6 +7,11 @@
using System;
using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+using Newtonsoft.Json;
+using Squidex.Areas.Api.Controllers.UI;
+using Squidex.Infrastructure.Json;
namespace Squidex.Areas.Frontend.Middlewares
{
@@ -26,5 +31,27 @@ namespace Squidex.Areas.Frontend.Middlewares
{
return context.Response.ContentType?.ToLower().Contains("text/html") == true;
}
+
+ public static string AdjustHtml(this string html, HttpContext httpContext)
+ {
+ var result = html;
+
+ if (httpContext.Request.PathBase.HasValue)
+ {
+ result = result.Replace("", $"");
+ }
+
+ var uiOptions = httpContext.RequestServices.GetService>()?.Value;
+
+ if (uiOptions != null)
+ {
+ var jsonSerializer = httpContext.RequestServices.GetRequiredService();
+ var jsonOptions = jsonSerializer.Serialize(uiOptions, false);
+
+ result = result.Replace("", $"");
+ }
+
+ return result;
+ }
}
}
diff --git a/src/Squidex/Areas/Frontend/Middlewares/IndexMiddleware.cs b/src/Squidex/Areas/Frontend/Middlewares/IndexMiddleware.cs
index 9925e0513..cf4a2dde8 100644
--- a/src/Squidex/Areas/Frontend/Middlewares/IndexMiddleware.cs
+++ b/src/Squidex/Areas/Frontend/Middlewares/IndexMiddleware.cs
@@ -25,7 +25,7 @@ namespace Squidex.Areas.Frontend.Middlewares
{
var basePath = context.Request.PathBase;
- if (context.IsHtmlPath() && basePath.HasValue)
+ if (context.IsHtmlPath() && context.Response.StatusCode != 304)
{
var responseBuffer = new MemoryStream();
var responseBody = context.Response.Body;
@@ -36,24 +36,19 @@ namespace Squidex.Areas.Frontend.Middlewares
context.Response.Body = responseBody;
- var response = Encoding.UTF8.GetString(responseBuffer.ToArray());
+ var html = Encoding.UTF8.GetString(responseBuffer.ToArray());
- response = AdjustBase(response, basePath);
+ html = html.AdjustHtml(context);
- context.Response.ContentLength = Encoding.UTF8.GetByteCount(response);
+ context.Response.ContentLength = Encoding.UTF8.GetByteCount(html);
context.Response.Body = responseBody;
- await context.Response.WriteAsync(response);
+ await context.Response.WriteAsync(html);
}
else
{
await next(context);
}
}
-
- private static string AdjustBase(string response, string baseUrl)
- {
- return response.Replace("", $"");
- }
}
}
diff --git a/src/Squidex/Areas/Frontend/Middlewares/WebpackMiddleware.cs b/src/Squidex/Areas/Frontend/Middlewares/WebpackMiddleware.cs
index d71fb128d..8ed930af6 100644
--- a/src/Squidex/Areas/Frontend/Middlewares/WebpackMiddleware.cs
+++ b/src/Squidex/Areas/Frontend/Middlewares/WebpackMiddleware.cs
@@ -37,7 +37,7 @@ namespace Squidex.Areas.Frontend.Middlewares
{
var html = await result.Content.ReadAsStringAsync();
- html = AdjustBase(html, context.Request.PathBase);
+ html = html.AdjustHtml(context);
await context.Response.WriteHtmlAsync(html);
}
@@ -58,7 +58,7 @@ namespace Squidex.Areas.Frontend.Middlewares
var html = Encoding.UTF8.GetString(responseBuffer.ToArray());
- html = AdjustBase(html, context.Request.PathBase);
+ html = html.AdjustHtml(context);
context.Response.ContentLength = Encoding.UTF8.GetByteCount(html);
context.Response.Body = responseBody;
@@ -71,17 +71,5 @@ namespace Squidex.Areas.Frontend.Middlewares
await next(context);
}
}
-
- private static string AdjustBase(string html, PathString baseUrl)
- {
- if (baseUrl.HasValue)
- {
- return html.Replace("", $"");
- }
- else
- {
- return html;
- }
- }
}
}
diff --git a/src/Squidex/app/app.module.ts b/src/Squidex/app/app.module.ts
index 98b2a6c97..f4c512db3 100644
--- a/src/Squidex/app/app.module.ts
+++ b/src/Squidex/app/app.module.ts
@@ -23,7 +23,8 @@ import {
DecimalSeparatorConfig,
SqxFrameworkModule,
SqxSharedModule,
- TitlesConfig
+ TitlesConfig,
+ UIOptions
} from './shared';
import { SqxShellModule } from './shell';
@@ -49,6 +50,10 @@ export function configApiUrl() {
}
}
+export function configUIOptions() {
+ return new UIOptions(window['options']);
+}
+
export function configTitles() {
return new TitlesConfig({}, undefined, 'Squidex Headless CMS');
}
@@ -88,7 +93,8 @@ export function configCurrency() {
{ provide: ApiUrlConfig, useFactory: configApiUrl },
{ provide: CurrencyConfig, useFactory: configCurrency },
{ provide: DecimalSeparatorConfig, useFactory: configDecimalSeparator },
- { provide: TitlesConfig, useFactory: configTitles }
+ { provide: TitlesConfig, useFactory: configTitles },
+ { provide: UIOptions, useFactory: configUIOptions }
],
entryComponents: [AppComponent]
})
diff --git a/src/Squidex/app/features/apps/pages/apps-page.component.ts b/src/Squidex/app/features/apps/pages/apps-page.component.ts
index 845d48924..f51a6a7d3 100644
--- a/src/Squidex/app/features/apps/pages/apps-page.component.ts
+++ b/src/Squidex/app/features/apps/pages/apps-page.component.ts
@@ -17,6 +17,7 @@ import {
LocalStoreService,
NewsService,
OnboardingService,
+ UIOptions,
UIState
} from '@app/shared';
@@ -40,7 +41,8 @@ export class AppsPageComponent implements OnInit {
public readonly uiState: UIState,
private readonly localStore: LocalStoreService,
private readonly newsService: NewsService,
- private readonly onboardingService: OnboardingService
+ private readonly onboardingService: OnboardingService,
+ private readonly uiOptions: UIOptions
) {
}
@@ -52,7 +54,7 @@ export class AppsPageComponent implements OnInit {
if (shouldShowOnboarding && apps.length === 0) {
this.onboardingService.disable('dialog');
this.onboardingDialog.show();
- } else {
+ } else if (!this.uiOptions.get('hideNews')) {
const newsVersion = this.localStore.getInt('squidex.news.version');
this.newsService.getFeatures(newsVersion)
diff --git a/src/Squidex/app/framework/angular/modals/onboarding-tooltip.component.ts b/src/Squidex/app/framework/angular/modals/onboarding-tooltip.component.ts
index 98fc8ee3f..cc1e55afa 100644
--- a/src/Squidex/app/framework/angular/modals/onboarding-tooltip.component.ts
+++ b/src/Squidex/app/framework/angular/modals/onboarding-tooltip.component.ts
@@ -45,6 +45,7 @@ export class OnboardingTooltipComponent extends StatefulComponent implements OnD
private readonly renderer: Renderer2
) {
super(changeDetector, {});
+
}
public ngOnDestroy() {
diff --git a/src/Squidex/app/framework/configurations.ts b/src/Squidex/app/framework/configurations.ts
index 4bb75d0bf..18b3180d2 100644
--- a/src/Squidex/app/framework/configurations.ts
+++ b/src/Squidex/app/framework/configurations.ts
@@ -5,6 +5,35 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
+export class UIOptions {
+ constructor(
+ private readonly value: any
+ ) {
+ }
+
+ public get(path: string) {
+ if (!path) {
+ return undefined;
+ }
+
+ let value = this.value;
+
+ if (value) {
+ const parts = path.split('.');
+
+ for (let part of parts) {
+ value = value[part];
+
+ if (!value) {
+ break;
+ }
+ }
+ }
+
+ return value;
+ }
+}
+
export class ApiUrlConfig {
public readonly value: string;
diff --git a/src/Squidex/app/framework/services/onboarding.service.spec.ts b/src/Squidex/app/framework/services/onboarding.service.spec.ts
index 0dc5042ae..715a189d7 100644
--- a/src/Squidex/app/framework/services/onboarding.service.spec.ts
+++ b/src/Squidex/app/framework/services/onboarding.service.spec.ts
@@ -7,6 +7,8 @@
import { OnboardingService, OnboardingServiceFactory } from './onboarding.service';
+import { UIOptions } from './../configurations';
+
class LocalStoreMock {
private store = {};
@@ -27,46 +29,52 @@ describe('OnboardingService', () => {
});
it('should instantiate from factory', () => {
- const onboardingService = OnboardingServiceFactory(localStore);
+ const onboardingService = OnboardingServiceFactory(new UIOptions({}), localStore);
expect(onboardingService).toBeDefined();
});
it('should instantiate', () => {
- const onboardingService = new OnboardingService(localStore);
+ const onboardingService = new OnboardingService(new UIOptions({}), localStore);
expect(onboardingService).toBeDefined();
});
- it('should return true when value not in store', () => {
+ it('should show when value not in store', () => {
localStore.set('squidex.onboarding.disable.feature-a1', '0');
- const onboardingService = new OnboardingService(localStore);
+ const onboardingService = new OnboardingService(new UIOptions({}), localStore);
expect(onboardingService.shouldShow('feature-a2')).toBeTruthy();
});
- it('should return false when value in store', () => {
+ it('should not show when value in store', () => {
localStore.set('squidex.onboarding.disable.feature-b1', '1');
- const onboardingService = new OnboardingService(localStore);
+ const onboardingService = new OnboardingService(new UIOptions({}), localStore);
expect(onboardingService.shouldShow('feature-b1')).toBeFalsy();
});
- it('should return false when disabled', () => {
- const onboardingService = new OnboardingService(localStore);
+ it('should not show when disabled', () => {
+ const onboardingService = new OnboardingService(new UIOptions({}), localStore);
onboardingService.disable('feature-c1');
expect(onboardingService.shouldShow('feature-c1')).toBeFalsy();
});
- it('should return false when all disabled', () => {
- const onboardingService = new OnboardingService(localStore);
+ it('should not show when all disabled', () => {
+ const onboardingService = new OnboardingService(new UIOptions({}), localStore);
onboardingService.disableAll();
expect(onboardingService.shouldShow('feature-d1')).toBeFalsy();
});
+
+ it('should not show when disabled by setting', () => {
+ const onboardingService = new OnboardingService(new UIOptions({ hideOnboarding: true }), localStore);
+
+ expect(onboardingService.shouldShow('feature-d1')).toBeFalsy();
+ });
});
\ No newline at end of file
diff --git a/src/Squidex/app/framework/services/onboarding.service.ts b/src/Squidex/app/framework/services/onboarding.service.ts
index e2249d050..a8e48d3bb 100644
--- a/src/Squidex/app/framework/services/onboarding.service.ts
+++ b/src/Squidex/app/framework/services/onboarding.service.ts
@@ -12,15 +12,20 @@ import { Injectable } from '@angular/core';
import { LocalStoreService } from './local-store.service';
-export const OnboardingServiceFactory = (localStore: LocalStoreService) => {
- return new OnboardingService(localStore);
+import { UIOptions } from './../configurations';
+
+export const OnboardingServiceFactory = (uiOptions: UIOptions, localStore: LocalStoreService) => {
+ return new OnboardingService(uiOptions, localStore);
};
@Injectable()
export class OnboardingService {
- constructor(
+ private readonly disabled: boolean;
+
+ constructor(uiOptions: UIOptions,
private readonly localStore: LocalStoreService
) {
+ this.disabled = uiOptions.get('hideOnboardingTooltips');
}
public disableAll() {
@@ -32,7 +37,7 @@ export class OnboardingService {
}
public shouldShow(key: string) {
- return this.shouldShowKey(key) && this.shouldShowKey('all');
+ return !this.disabled && this.shouldShowKey(key) && this.shouldShowKey('all');
}
private shouldShowKey(key: string) {
diff --git a/src/Squidex/app/shared/components/geolocation-editor.component.ts b/src/Squidex/app/shared/components/geolocation-editor.component.ts
index 6de6e97bf..b358ef4fb 100644
--- a/src/Squidex/app/shared/components/geolocation-editor.component.ts
+++ b/src/Squidex/app/shared/components/geolocation-editor.component.ts
@@ -12,7 +12,7 @@ import {
ResourceLoaderService,
StatefulControlComponent,
Types,
- UIState,
+ UIOptions,
ValidatorsEx
} from '@app/shared/internal';
@@ -28,10 +28,6 @@ interface Geolocation {
longitude: number;
}
-interface State {
- isGoogleMaps: boolean;
-}
-
@Component({
selector: 'sqx-geolocation-editor',
styleUrls: ['./geolocation-editor.component.scss'],
@@ -39,7 +35,8 @@ interface State {
providers: [SQX_GEOLOCATION_EDITOR_CONTROL_VALUE_ACCESSOR],
changeDetection: ChangeDetectionStrategy.OnPush
})
-export class GeolocationEditorComponent extends StatefulControlComponent implements AfterViewInit {
+export class GeolocationEditorComponent extends StatefulControlComponent implements AfterViewInit {
+ private readonly isGoogleMaps: boolean;
private marker: any;
private map: any;
private value: Geolocation | null = null;
@@ -73,11 +70,11 @@ export class GeolocationEditorComponent extends StatefulControlComponent {
- const isGoogleMaps = settings.mapType === 'GoogleMaps';
-
- this.next(s => ({ ...s, isGoogleMaps }));
-
- if (!this.snapshot.isGoogleMaps) {
- this.ngAfterViewInitOSM();
- } else {
- this.ngAfterViewInitGoogle(settings.mapKey);
- }
- });
+ if (!this.isGoogleMaps) {
+ this.ngAfterViewInitOSM();
+ } else {
+ this.ngAfterViewInitGoogle(this.uiOptions.get('map.googleMaps.key'));
+ }
}
private ngAfterViewInitOSM() {
@@ -224,11 +214,11 @@ export class GeolocationEditorComponent extends StatefulControlComponent {
+ this.map.addListener('bounds_changed', () => {
searchBox.setBounds(this.map.getBounds());
});
- searchBox.addListener('places_changed', (event: any) => {
+ searchBox.addListener('places_changed', () => {
let places = searchBox.getPlaces();
if (places.length === 1) {
diff --git a/src/Squidex/app/shared/guards/must-be-authenticated.guard.spec.ts b/src/Squidex/app/shared/guards/must-be-authenticated.guard.spec.ts
index 027ca52da..e439d95d2 100644
--- a/src/Squidex/app/shared/guards/must-be-authenticated.guard.spec.ts
+++ b/src/Squidex/app/shared/guards/must-be-authenticated.guard.spec.ts
@@ -9,24 +9,25 @@ import { Router } from '@angular/router';
import { of } from 'rxjs';
import { IMock, It, Mock, Times } from 'typemoq';
-import { AuthService } from '@app/shared';
+import { AuthService, UIOptions } from '@app/shared';
import { MustBeAuthenticatedGuard } from './must-be-authenticated.guard';
describe('MustBeAuthenticatedGuard', () => {
let router: IMock;
-
let authService: IMock;
- let authGuard: MustBeAuthenticatedGuard;
+ let uiOptions = new UIOptions({ map: { type: 'OSM' } });
+ let uiOptionsRedirect = new UIOptions({ map: { type: 'OSM' }, redirectToLogin: true });
beforeEach(() => {
router = Mock.ofType();
authService = Mock.ofType();
- authGuard = new MustBeAuthenticatedGuard(authService.object, router.object);
});
it('should navigate to default page if not authenticated', () => {
+ const authGuard = new MustBeAuthenticatedGuard(uiOptions, authService.object, router.object);
+
authService.setup(x => x.userChanges)
.returns(() => of(null));
@@ -42,6 +43,8 @@ describe('MustBeAuthenticatedGuard', () => {
});
it('should return true if authenticated', () => {
+ const authGuard = new MustBeAuthenticatedGuard(uiOptions, authService.object, router.object);
+
authService.setup(x => x.userChanges)
.returns(() => of({}));
@@ -55,4 +58,21 @@ describe('MustBeAuthenticatedGuard', () => {
router.verify(x => x.navigate(It.isAny()), Times.never());
});
+
+ it('should login redirect if redirect enabled', () => {
+ const authGuard = new MustBeAuthenticatedGuard(uiOptionsRedirect, authService.object, router.object);
+
+ authService.setup(x => x.userChanges)
+ .returns(() => of(null));
+
+ let result: boolean;
+
+ authGuard.canActivate().subscribe(x => {
+ result = x;
+ });
+
+ expect(result!).toBeFalsy();
+
+ authService.verify(x => x.loginRedirect(), Times.once());
+ });
});
\ No newline at end of file
diff --git a/src/Squidex/app/shared/guards/must-be-authenticated.guard.ts b/src/Squidex/app/shared/guards/must-be-authenticated.guard.ts
index bdf76f49b..f851720f2 100644
--- a/src/Squidex/app/shared/guards/must-be-authenticated.guard.ts
+++ b/src/Squidex/app/shared/guards/must-be-authenticated.guard.ts
@@ -10,14 +10,19 @@ import { CanActivate, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { map, take, tap } from 'rxjs/operators';
+import { UIOptions } from '@app/framework';
+
import { AuthService } from './../services/auth.service';
@Injectable()
export class MustBeAuthenticatedGuard implements CanActivate {
- constructor(
+ private readonly redirect: boolean;
+
+ constructor(uiOptions: UIOptions,
private readonly authService: AuthService,
private readonly router: Router
) {
+ this.redirect = uiOptions.get('redirectToLogin');
}
public canActivate(): Observable {
@@ -25,7 +30,11 @@ export class MustBeAuthenticatedGuard implements CanActivate {
take(1),
tap(user => {
if (!user) {
- this.router.navigate(['']);
+ if (this.redirect) {
+ this.authService.loginRedirect();
+ } else {
+ this.router.navigate(['']);
+ }
}
}),
map(user => !!user));
diff --git a/src/Squidex/app/shared/guards/must-be-not-authenticated.guard.spec.ts b/src/Squidex/app/shared/guards/must-be-not-authenticated.guard.spec.ts
index 2bf342413..5448e4071 100644
--- a/src/Squidex/app/shared/guards/must-be-not-authenticated.guard.spec.ts
+++ b/src/Squidex/app/shared/guards/must-be-not-authenticated.guard.spec.ts
@@ -9,24 +9,25 @@ import { Router } from '@angular/router';
import { of } from 'rxjs';
import { IMock, It, Mock, Times } from 'typemoq';
-import { AuthService } from '@app/shared';
+import { AuthService, UIOptions } from '@app/shared';
import { MustBeNotAuthenticatedGuard } from './must-be-not-authenticated.guard';
-describe('MustNotBeAuthenticatedGuard', () => {
+describe('MustBeNotAuthenticatedGuard', () => {
let router: IMock;
-
let authService: IMock;
- let authGuard: MustBeNotAuthenticatedGuard;
+ let uiOptions = new UIOptions({ map: { type: 'OSM' } });
+ let uiOptionsRedirect = new UIOptions({ map: { type: 'OSM' }, redirectToLogin: true });
beforeEach(() => {
router = Mock.ofType();
authService = Mock.ofType();
- authGuard = new MustBeNotAuthenticatedGuard(authService.object, router.object);
});
it('should navigate to app page if authenticated', () => {
+ const authGuard = new MustBeNotAuthenticatedGuard(uiOptions, authService.object, router.object);
+
authService.setup(x => x.userChanges)
.returns(() => of({}));
@@ -42,6 +43,8 @@ describe('MustNotBeAuthenticatedGuard', () => {
});
it('should return true if not authenticated', () => {
+ const authGuard = new MustBeNotAuthenticatedGuard(uiOptions, authService.object, router.object);
+
authService.setup(x => x.userChanges)
.returns(() => of(null));
@@ -55,4 +58,21 @@ describe('MustNotBeAuthenticatedGuard', () => {
router.verify(x => x.navigate(It.isAny()), Times.never());
});
+
+ it('should login redirect and return false if redirect enabled', () => {
+ const authGuard = new MustBeNotAuthenticatedGuard(uiOptionsRedirect, authService.object, router.object);
+
+ authService.setup(x => x.userChanges)
+ .returns(() => of(null));
+
+ let result: boolean;
+
+ authGuard.canActivate().subscribe(x => {
+ result = x;
+ });
+
+ expect(result!).toBeFalsy();
+
+ authService.verify(x => x.loginRedirect(), Times.once());
+ });
});
\ No newline at end of file
diff --git a/src/Squidex/app/shared/guards/must-be-not-authenticated.guard.ts b/src/Squidex/app/shared/guards/must-be-not-authenticated.guard.ts
index 67c4a346d..0e88a9e26 100644
--- a/src/Squidex/app/shared/guards/must-be-not-authenticated.guard.ts
+++ b/src/Squidex/app/shared/guards/must-be-not-authenticated.guard.ts
@@ -10,24 +10,31 @@ import { CanActivate, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { map, take, tap } from 'rxjs/operators';
+import { UIOptions } from '@app/framework';
+
import { AuthService } from './../services/auth.service';
@Injectable()
export class MustBeNotAuthenticatedGuard implements CanActivate {
- constructor(
+ private readonly redirect: boolean;
+
+ constructor(uiOptions: UIOptions,
private readonly authService: AuthService,
private readonly router: Router
) {
+ this.redirect = uiOptions.get('redirectToLogin');
}
public canActivate(): Observable {
return this.authService.userChanges.pipe(
take(1),
tap(user => {
- if (user) {
+ if (this.redirect) {
+ this.authService.loginRedirect();
+ } else if (user) {
this.router.navigate(['app']);
}
}),
- map(user => !user));
+ map(user => !user && !this.redirect));
}
}
\ No newline at end of file
diff --git a/src/Squidex/app/shared/services/ui.service.spec.ts b/src/Squidex/app/shared/services/ui.service.spec.ts
index 537ea44e0..5a5f9236d 100644
--- a/src/Squidex/app/shared/services/ui.service.spec.ts
+++ b/src/Squidex/app/shared/services/ui.service.spec.ts
@@ -40,7 +40,7 @@ describe('UIService', () => {
settings = result;
});
- const response: UISettingsDto = { mapType: 'OSM', mapKey: '', canCreateApps: true };
+ const response: UISettingsDto = { canCreateApps: true };
const req = httpMock.expectOne('http://service/p/api/ui/settings');
diff --git a/src/Squidex/app/shared/services/ui.service.ts b/src/Squidex/app/shared/services/ui.service.ts
index cdadc29a1..285ace324 100644
--- a/src/Squidex/app/shared/services/ui.service.ts
+++ b/src/Squidex/app/shared/services/ui.service.ts
@@ -13,9 +13,6 @@ import { catchError } from 'rxjs/operators';
import { ApiUrlConfig } from '@app/framework';
export interface UISettingsDto {
- readonly mapType: string;
- readonly mapKey?: string;
-
readonly canCreateApps: boolean;
}
diff --git a/src/Squidex/app/shared/services/workflows.service.spec.ts b/src/Squidex/app/shared/services/workflows.service.spec.ts
index cdf96ce7f..c42b620f0 100644
--- a/src/Squidex/app/shared/services/workflows.service.spec.ts
+++ b/src/Squidex/app/shared/services/workflows.service.spec.ts
@@ -147,7 +147,7 @@ describe('Workflow', () => {
it('should create empty workflow', () => {
const workflow = new WorkflowDto();
- expect(workflow.initial);
+ expect(workflow.initial).not.toBeDefined();
});
it('should add step to workflow', () => {
diff --git a/src/Squidex/appsettings.json b/src/Squidex/appsettings.json
index d8c5ba74f..399cee8f7 100644
--- a/src/Squidex/appsettings.json
+++ b/src/Squidex/appsettings.json
@@ -65,7 +65,12 @@
*/
"key": "AIzaSyB_Z8l3nwUxZhMJykiDUJy6bSHXXlwcYMg"
}
- }
+ },
+
+ /*
+ * Redirect to login automatically.
+ */
+ "redirectTopLogin": false
},
"email": {
@@ -73,29 +78,29 @@
/*
* The host name to your email server.
*/
- "server": "",
- /*
+ "server": "",
+ /*
* The sender email address.
*/
- "sender": "hello@squidex.io",
- /*
+ "sender": "hello@squidex.io",
+ /*
* The username to authenticate to your email server.
*/
- "username": "",
- /*
+ "username": "",
+ /*
* The password to authenticate to your email server.
*/
- "password": "",
- /*
+ "password": "",
+ /*
* Always use SSL if possible.
*/
- "enableSsl": true,
- /*
+ "enableSsl": true,
+ /*
* The port to your email server.
*/
- "port": 465
- },
+ "port": 465
+ },
"notifications": {
/*
* The email subject when a new user is added as contributor.