diff --git a/src/Squidex/Controllers/Api/Apps/AppClientsController.cs b/src/Squidex/Areas/Api/Apps/AppClientsController.cs similarity index 100% rename from src/Squidex/Controllers/Api/Apps/AppClientsController.cs rename to src/Squidex/Areas/Api/Apps/AppClientsController.cs diff --git a/src/Squidex/Controllers/Api/Apps/AppContributorsController.cs b/src/Squidex/Areas/Api/Apps/AppContributorsController.cs similarity index 100% rename from src/Squidex/Controllers/Api/Apps/AppContributorsController.cs rename to src/Squidex/Areas/Api/Apps/AppContributorsController.cs diff --git a/src/Squidex/Controllers/Api/Apps/AppLanguagesController.cs b/src/Squidex/Areas/Api/Apps/AppLanguagesController.cs similarity index 100% rename from src/Squidex/Controllers/Api/Apps/AppLanguagesController.cs rename to src/Squidex/Areas/Api/Apps/AppLanguagesController.cs diff --git a/src/Squidex/Controllers/Api/Apps/AppsController.cs b/src/Squidex/Areas/Api/Apps/AppsController.cs similarity index 100% rename from src/Squidex/Controllers/Api/Apps/AppsController.cs rename to src/Squidex/Areas/Api/Apps/AppsController.cs diff --git a/src/Squidex/Controllers/Api/Apps/Models/AddAppLanguageDto.cs b/src/Squidex/Areas/Api/Apps/Models/AddAppLanguageDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Apps/Models/AddAppLanguageDto.cs rename to src/Squidex/Areas/Api/Apps/Models/AddAppLanguageDto.cs diff --git a/src/Squidex/Controllers/Api/Apps/Models/AppCreatedDto.cs b/src/Squidex/Areas/Api/Apps/Models/AppCreatedDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Apps/Models/AppCreatedDto.cs rename to src/Squidex/Areas/Api/Apps/Models/AppCreatedDto.cs diff --git a/src/Squidex/Controllers/Api/Apps/Models/AppDto.cs b/src/Squidex/Areas/Api/Apps/Models/AppDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Apps/Models/AppDto.cs rename to src/Squidex/Areas/Api/Apps/Models/AppDto.cs diff --git a/src/Squidex/Controllers/Api/Apps/Models/AppLanguageDto.cs b/src/Squidex/Areas/Api/Apps/Models/AppLanguageDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Apps/Models/AppLanguageDto.cs rename to src/Squidex/Areas/Api/Apps/Models/AppLanguageDto.cs diff --git a/src/Squidex/Controllers/Api/Apps/Models/AssignAppContributorDto.cs b/src/Squidex/Areas/Api/Apps/Models/AssignAppContributorDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Apps/Models/AssignAppContributorDto.cs rename to src/Squidex/Areas/Api/Apps/Models/AssignAppContributorDto.cs diff --git a/src/Squidex/Controllers/Api/Apps/Models/ClientDto.cs b/src/Squidex/Areas/Api/Apps/Models/ClientDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Apps/Models/ClientDto.cs rename to src/Squidex/Areas/Api/Apps/Models/ClientDto.cs diff --git a/src/Squidex/Controllers/Api/Apps/Models/ContributorDto.cs b/src/Squidex/Areas/Api/Apps/Models/ContributorDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Apps/Models/ContributorDto.cs rename to src/Squidex/Areas/Api/Apps/Models/ContributorDto.cs diff --git a/src/Squidex/Controllers/Api/Apps/Models/ContributorsDto.cs b/src/Squidex/Areas/Api/Apps/Models/ContributorsDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Apps/Models/ContributorsDto.cs rename to src/Squidex/Areas/Api/Apps/Models/ContributorsDto.cs diff --git a/src/Squidex/Controllers/Api/Apps/Models/CreateAppClientDto.cs b/src/Squidex/Areas/Api/Apps/Models/CreateAppClientDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Apps/Models/CreateAppClientDto.cs rename to src/Squidex/Areas/Api/Apps/Models/CreateAppClientDto.cs diff --git a/src/Squidex/Controllers/Api/Apps/Models/CreateAppDto.cs b/src/Squidex/Areas/Api/Apps/Models/CreateAppDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Apps/Models/CreateAppDto.cs rename to src/Squidex/Areas/Api/Apps/Models/CreateAppDto.cs diff --git a/src/Squidex/Controllers/Api/Apps/Models/UpdateAppClientDto.cs b/src/Squidex/Areas/Api/Apps/Models/UpdateAppClientDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Apps/Models/UpdateAppClientDto.cs rename to src/Squidex/Areas/Api/Apps/Models/UpdateAppClientDto.cs diff --git a/src/Squidex/Controllers/Api/Apps/Models/UpdateAppLanguageDto.cs b/src/Squidex/Areas/Api/Apps/Models/UpdateAppLanguageDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Apps/Models/UpdateAppLanguageDto.cs rename to src/Squidex/Areas/Api/Apps/Models/UpdateAppLanguageDto.cs diff --git a/src/Squidex/Controllers/Api/Assets/AssetConfig.cs b/src/Squidex/Areas/Api/Assets/AssetConfig.cs similarity index 100% rename from src/Squidex/Controllers/Api/Assets/AssetConfig.cs rename to src/Squidex/Areas/Api/Assets/AssetConfig.cs diff --git a/src/Squidex/Controllers/Api/Assets/AssetContentController.cs b/src/Squidex/Areas/Api/Assets/AssetContentController.cs similarity index 100% rename from src/Squidex/Controllers/Api/Assets/AssetContentController.cs rename to src/Squidex/Areas/Api/Assets/AssetContentController.cs diff --git a/src/Squidex/Controllers/Api/Assets/AssetsController.cs b/src/Squidex/Areas/Api/Assets/AssetsController.cs similarity index 100% rename from src/Squidex/Controllers/Api/Assets/AssetsController.cs rename to src/Squidex/Areas/Api/Assets/AssetsController.cs diff --git a/src/Squidex/Controllers/Api/Assets/Models/AssetCreatedDto.cs b/src/Squidex/Areas/Api/Assets/Models/AssetCreatedDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Assets/Models/AssetCreatedDto.cs rename to src/Squidex/Areas/Api/Assets/Models/AssetCreatedDto.cs diff --git a/src/Squidex/Controllers/Api/Assets/Models/AssetDto.cs b/src/Squidex/Areas/Api/Assets/Models/AssetDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Assets/Models/AssetDto.cs rename to src/Squidex/Areas/Api/Assets/Models/AssetDto.cs diff --git a/src/Squidex/Controllers/Api/Assets/Models/AssetReplacedDto.cs b/src/Squidex/Areas/Api/Assets/Models/AssetReplacedDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Assets/Models/AssetReplacedDto.cs rename to src/Squidex/Areas/Api/Assets/Models/AssetReplacedDto.cs diff --git a/src/Squidex/Controllers/Api/Assets/Models/AssetUpdateDto.cs b/src/Squidex/Areas/Api/Assets/Models/AssetUpdateDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Assets/Models/AssetUpdateDto.cs rename to src/Squidex/Areas/Api/Assets/Models/AssetUpdateDto.cs diff --git a/src/Squidex/Controllers/Api/Assets/Models/AssetsDto.cs b/src/Squidex/Areas/Api/Assets/Models/AssetsDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Assets/Models/AssetsDto.cs rename to src/Squidex/Areas/Api/Assets/Models/AssetsDto.cs diff --git a/src/Squidex/Controllers/ContentApi/ContentSwaggerController.cs b/src/Squidex/Areas/Api/Content/ContentSwaggerController.cs similarity index 100% rename from src/Squidex/Controllers/ContentApi/ContentSwaggerController.cs rename to src/Squidex/Areas/Api/Content/ContentSwaggerController.cs diff --git a/src/Squidex/Controllers/ContentApi/ContentsController.cs b/src/Squidex/Areas/Api/Content/ContentsController.cs similarity index 100% rename from src/Squidex/Controllers/ContentApi/ContentsController.cs rename to src/Squidex/Areas/Api/Content/ContentsController.cs diff --git a/src/Squidex/Controllers/ContentApi/Generator/SchemaSwaggerGenerator.cs b/src/Squidex/Areas/Api/Content/Generator/SchemaSwaggerGenerator.cs similarity index 100% rename from src/Squidex/Controllers/ContentApi/Generator/SchemaSwaggerGenerator.cs rename to src/Squidex/Areas/Api/Content/Generator/SchemaSwaggerGenerator.cs diff --git a/src/Squidex/Controllers/ContentApi/Generator/SchemasSwaggerGenerator.cs b/src/Squidex/Areas/Api/Content/Generator/SchemasSwaggerGenerator.cs similarity index 100% rename from src/Squidex/Controllers/ContentApi/Generator/SchemasSwaggerGenerator.cs rename to src/Squidex/Areas/Api/Content/Generator/SchemasSwaggerGenerator.cs diff --git a/src/Squidex/Controllers/ContentApi/Models/AssetsDto.cs b/src/Squidex/Areas/Api/Content/Models/AssetsDto.cs similarity index 100% rename from src/Squidex/Controllers/ContentApi/Models/AssetsDto.cs rename to src/Squidex/Areas/Api/Content/Models/AssetsDto.cs diff --git a/src/Squidex/Controllers/ContentApi/Models/ContentDto.cs b/src/Squidex/Areas/Api/Content/Models/ContentDto.cs similarity index 100% rename from src/Squidex/Controllers/ContentApi/Models/ContentDto.cs rename to src/Squidex/Areas/Api/Content/Models/ContentDto.cs diff --git a/src/Squidex/Controllers/ControllerBase.cs b/src/Squidex/Areas/Api/ControllerBase.cs similarity index 100% rename from src/Squidex/Controllers/ControllerBase.cs rename to src/Squidex/Areas/Api/ControllerBase.cs diff --git a/src/Squidex/Controllers/Api/Docs/DocsController.cs b/src/Squidex/Areas/Api/Docs/DocsController.cs similarity index 100% rename from src/Squidex/Controllers/Api/Docs/DocsController.cs rename to src/Squidex/Areas/Api/Docs/DocsController.cs diff --git a/src/Squidex/Controllers/DocsVM.cs b/src/Squidex/Areas/Api/DocsVM.cs similarity index 100% rename from src/Squidex/Controllers/DocsVM.cs rename to src/Squidex/Areas/Api/DocsVM.cs diff --git a/src/Squidex/Controllers/Api/EntityCreatedDto.cs b/src/Squidex/Areas/Api/EntityCreatedDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/EntityCreatedDto.cs rename to src/Squidex/Areas/Api/EntityCreatedDto.cs diff --git a/src/Squidex/Controllers/Api/ErrorDto.cs b/src/Squidex/Areas/Api/ErrorDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/ErrorDto.cs rename to src/Squidex/Areas/Api/ErrorDto.cs diff --git a/src/Squidex/Controllers/Api/EventConsumers/EventConsumersController.cs b/src/Squidex/Areas/Api/EventConsumers/EventConsumersController.cs similarity index 100% rename from src/Squidex/Controllers/Api/EventConsumers/EventConsumersController.cs rename to src/Squidex/Areas/Api/EventConsumers/EventConsumersController.cs diff --git a/src/Squidex/Controllers/Api/EventConsumers/Models/EventConsumerDto.cs b/src/Squidex/Areas/Api/EventConsumers/Models/EventConsumerDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/EventConsumers/Models/EventConsumerDto.cs rename to src/Squidex/Areas/Api/EventConsumers/Models/EventConsumerDto.cs diff --git a/src/Squidex/Controllers/Api/History/HistoryController.cs b/src/Squidex/Areas/Api/History/HistoryController.cs similarity index 100% rename from src/Squidex/Controllers/Api/History/HistoryController.cs rename to src/Squidex/Areas/Api/History/HistoryController.cs diff --git a/src/Squidex/Controllers/Api/History/Models/HistoryEventDto.cs b/src/Squidex/Areas/Api/History/Models/HistoryEventDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/History/Models/HistoryEventDto.cs rename to src/Squidex/Areas/Api/History/Models/HistoryEventDto.cs diff --git a/src/Squidex/Controllers/JsonInheritanceConverter.cs b/src/Squidex/Areas/Api/JsonInheritanceConverter.cs similarity index 100% rename from src/Squidex/Controllers/JsonInheritanceConverter.cs rename to src/Squidex/Areas/Api/JsonInheritanceConverter.cs diff --git a/src/Squidex/Controllers/Api/LanguageDto.cs b/src/Squidex/Areas/Api/LanguageDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/LanguageDto.cs rename to src/Squidex/Areas/Api/LanguageDto.cs diff --git a/src/Squidex/Controllers/Api/Languages/LanguagesController.cs b/src/Squidex/Areas/Api/Languages/LanguagesController.cs similarity index 100% rename from src/Squidex/Controllers/Api/Languages/LanguagesController.cs rename to src/Squidex/Areas/Api/Languages/LanguagesController.cs diff --git a/src/Squidex/Controllers/Api/Ping/PingController.cs b/src/Squidex/Areas/Api/Ping/PingController.cs similarity index 100% rename from src/Squidex/Controllers/Api/Ping/PingController.cs rename to src/Squidex/Areas/Api/Ping/PingController.cs diff --git a/src/Squidex/Controllers/Api/Plans/AppPlansController.cs b/src/Squidex/Areas/Api/Plans/AppPlansController.cs similarity index 100% rename from src/Squidex/Controllers/Api/Plans/AppPlansController.cs rename to src/Squidex/Areas/Api/Plans/AppPlansController.cs diff --git a/src/Squidex/Controllers/Api/Plans/Models/AppPlansDto.cs b/src/Squidex/Areas/Api/Plans/Models/AppPlansDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Plans/Models/AppPlansDto.cs rename to src/Squidex/Areas/Api/Plans/Models/AppPlansDto.cs diff --git a/src/Squidex/Controllers/Api/Plans/Models/ChangePlanDto.cs b/src/Squidex/Areas/Api/Plans/Models/ChangePlanDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Plans/Models/ChangePlanDto.cs rename to src/Squidex/Areas/Api/Plans/Models/ChangePlanDto.cs diff --git a/src/Squidex/Controllers/Api/Plans/Models/PlanChangedDto.cs b/src/Squidex/Areas/Api/Plans/Models/PlanChangedDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Plans/Models/PlanChangedDto.cs rename to src/Squidex/Areas/Api/Plans/Models/PlanChangedDto.cs diff --git a/src/Squidex/Controllers/Api/Plans/Models/PlanDto.cs b/src/Squidex/Areas/Api/Plans/Models/PlanDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Plans/Models/PlanDto.cs rename to src/Squidex/Areas/Api/Plans/Models/PlanDto.cs diff --git a/src/Squidex/Controllers/Api/Rules/Models/Actions/WebhookActionDto.cs b/src/Squidex/Areas/Api/Rules/Models/Actions/WebhookActionDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Rules/Models/Actions/WebhookActionDto.cs rename to src/Squidex/Areas/Api/Rules/Models/Actions/WebhookActionDto.cs diff --git a/src/Squidex/Controllers/Api/Rules/Models/Converters/RuleActionDtoFactory.cs b/src/Squidex/Areas/Api/Rules/Models/Converters/RuleActionDtoFactory.cs similarity index 100% rename from src/Squidex/Controllers/Api/Rules/Models/Converters/RuleActionDtoFactory.cs rename to src/Squidex/Areas/Api/Rules/Models/Converters/RuleActionDtoFactory.cs diff --git a/src/Squidex/Controllers/Api/Rules/Models/Converters/RuleConverter.cs b/src/Squidex/Areas/Api/Rules/Models/Converters/RuleConverter.cs similarity index 100% rename from src/Squidex/Controllers/Api/Rules/Models/Converters/RuleConverter.cs rename to src/Squidex/Areas/Api/Rules/Models/Converters/RuleConverter.cs diff --git a/src/Squidex/Controllers/Api/Rules/Models/Converters/RuleTriggerDtoFactory.cs b/src/Squidex/Areas/Api/Rules/Models/Converters/RuleTriggerDtoFactory.cs similarity index 100% rename from src/Squidex/Controllers/Api/Rules/Models/Converters/RuleTriggerDtoFactory.cs rename to src/Squidex/Areas/Api/Rules/Models/Converters/RuleTriggerDtoFactory.cs diff --git a/src/Squidex/Controllers/Api/Rules/Models/CreateRuleDto.cs b/src/Squidex/Areas/Api/Rules/Models/CreateRuleDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Rules/Models/CreateRuleDto.cs rename to src/Squidex/Areas/Api/Rules/Models/CreateRuleDto.cs diff --git a/src/Squidex/Controllers/Api/Rules/Models/RuleActionDto.cs b/src/Squidex/Areas/Api/Rules/Models/RuleActionDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Rules/Models/RuleActionDto.cs rename to src/Squidex/Areas/Api/Rules/Models/RuleActionDto.cs diff --git a/src/Squidex/Controllers/Api/Rules/Models/RuleDto.cs b/src/Squidex/Areas/Api/Rules/Models/RuleDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Rules/Models/RuleDto.cs rename to src/Squidex/Areas/Api/Rules/Models/RuleDto.cs diff --git a/src/Squidex/Controllers/Api/Rules/Models/RuleEventDto.cs b/src/Squidex/Areas/Api/Rules/Models/RuleEventDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Rules/Models/RuleEventDto.cs rename to src/Squidex/Areas/Api/Rules/Models/RuleEventDto.cs diff --git a/src/Squidex/Controllers/Api/Rules/Models/RuleEventsDto.cs b/src/Squidex/Areas/Api/Rules/Models/RuleEventsDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Rules/Models/RuleEventsDto.cs rename to src/Squidex/Areas/Api/Rules/Models/RuleEventsDto.cs diff --git a/src/Squidex/Controllers/Api/Rules/Models/RuleTriggerDto.cs b/src/Squidex/Areas/Api/Rules/Models/RuleTriggerDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Rules/Models/RuleTriggerDto.cs rename to src/Squidex/Areas/Api/Rules/Models/RuleTriggerDto.cs diff --git a/src/Squidex/Controllers/Api/Rules/Models/Triggers/ContentChangedTriggerDto.cs b/src/Squidex/Areas/Api/Rules/Models/Triggers/ContentChangedTriggerDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Rules/Models/Triggers/ContentChangedTriggerDto.cs rename to src/Squidex/Areas/Api/Rules/Models/Triggers/ContentChangedTriggerDto.cs diff --git a/src/Squidex/Controllers/Api/Rules/Models/Triggers/ContentChangedTriggerSchemaDto.cs b/src/Squidex/Areas/Api/Rules/Models/Triggers/ContentChangedTriggerSchemaDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Rules/Models/Triggers/ContentChangedTriggerSchemaDto.cs rename to src/Squidex/Areas/Api/Rules/Models/Triggers/ContentChangedTriggerSchemaDto.cs diff --git a/src/Squidex/Controllers/Api/Rules/Models/UpdateRuleDto.cs b/src/Squidex/Areas/Api/Rules/Models/UpdateRuleDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Rules/Models/UpdateRuleDto.cs rename to src/Squidex/Areas/Api/Rules/Models/UpdateRuleDto.cs diff --git a/src/Squidex/Controllers/Api/Rules/RulesController.cs b/src/Squidex/Areas/Api/Rules/RulesController.cs similarity index 100% rename from src/Squidex/Controllers/Api/Rules/RulesController.cs rename to src/Squidex/Areas/Api/Rules/RulesController.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/AddFieldDto.cs b/src/Squidex/Areas/Api/Schemas/Models/AddFieldDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/AddFieldDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/AddFieldDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/ConfigureScriptsDto.cs b/src/Squidex/Areas/Api/Schemas/Models/ConfigureScriptsDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/ConfigureScriptsDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/ConfigureScriptsDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/Converters/FieldPropertiesDtoFactory.cs b/src/Squidex/Areas/Api/Schemas/Models/Converters/FieldPropertiesDtoFactory.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/Converters/FieldPropertiesDtoFactory.cs rename to src/Squidex/Areas/Api/Schemas/Models/Converters/FieldPropertiesDtoFactory.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/Converters/SchemaConverter.cs b/src/Squidex/Areas/Api/Schemas/Models/Converters/SchemaConverter.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/Converters/SchemaConverter.cs rename to src/Squidex/Areas/Api/Schemas/Models/Converters/SchemaConverter.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/CreateSchemaDto.cs b/src/Squidex/Areas/Api/Schemas/Models/CreateSchemaDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/CreateSchemaDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/CreateSchemaDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/CreateSchemaFieldDto.cs b/src/Squidex/Areas/Api/Schemas/Models/CreateSchemaFieldDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/CreateSchemaFieldDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/CreateSchemaFieldDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/FieldDto.cs b/src/Squidex/Areas/Api/Schemas/Models/FieldDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/FieldDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/FieldDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/FieldPropertiesDto.cs b/src/Squidex/Areas/Api/Schemas/Models/FieldPropertiesDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/FieldPropertiesDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/FieldPropertiesDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/Fields/AssetsFieldPropertiesDto.cs b/src/Squidex/Areas/Api/Schemas/Models/Fields/AssetsFieldPropertiesDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/Fields/AssetsFieldPropertiesDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/Fields/AssetsFieldPropertiesDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/Fields/BooleanFieldPropertiesDto.cs b/src/Squidex/Areas/Api/Schemas/Models/Fields/BooleanFieldPropertiesDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/Fields/BooleanFieldPropertiesDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/Fields/BooleanFieldPropertiesDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/Fields/DateTimeFieldPropertiesDto.cs b/src/Squidex/Areas/Api/Schemas/Models/Fields/DateTimeFieldPropertiesDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/Fields/DateTimeFieldPropertiesDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/Fields/DateTimeFieldPropertiesDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/Fields/GeolocationFieldPropertiesDto.cs b/src/Squidex/Areas/Api/Schemas/Models/Fields/GeolocationFieldPropertiesDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/Fields/GeolocationFieldPropertiesDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/Fields/GeolocationFieldPropertiesDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/Fields/JsonFieldPropertiesDto.cs b/src/Squidex/Areas/Api/Schemas/Models/Fields/JsonFieldPropertiesDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/Fields/JsonFieldPropertiesDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/Fields/JsonFieldPropertiesDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/Fields/NumberFieldPropertiesDto.cs b/src/Squidex/Areas/Api/Schemas/Models/Fields/NumberFieldPropertiesDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/Fields/NumberFieldPropertiesDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/Fields/NumberFieldPropertiesDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs b/src/Squidex/Areas/Api/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/Fields/StringFieldPropertiesDto.cs b/src/Squidex/Areas/Api/Schemas/Models/Fields/StringFieldPropertiesDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/Fields/StringFieldPropertiesDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/Fields/StringFieldPropertiesDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/Fields/TagsFieldPropertiesDto.cs b/src/Squidex/Areas/Api/Schemas/Models/Fields/TagsFieldPropertiesDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/Fields/TagsFieldPropertiesDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/Fields/TagsFieldPropertiesDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/ReorderFieldsDto.cs b/src/Squidex/Areas/Api/Schemas/Models/ReorderFieldsDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/ReorderFieldsDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/ReorderFieldsDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/SchemaDetailsDto.cs b/src/Squidex/Areas/Api/Schemas/Models/SchemaDetailsDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/SchemaDetailsDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/SchemaDetailsDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/SchemaDto.cs b/src/Squidex/Areas/Api/Schemas/Models/SchemaDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/SchemaDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/SchemaDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/SchemaPropertiesDto.cs b/src/Squidex/Areas/Api/Schemas/Models/SchemaPropertiesDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/SchemaPropertiesDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/SchemaPropertiesDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/UpdateFieldDto.cs b/src/Squidex/Areas/Api/Schemas/Models/UpdateFieldDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/UpdateFieldDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/UpdateFieldDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/Models/UpdateSchemaDto.cs b/src/Squidex/Areas/Api/Schemas/Models/UpdateSchemaDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/Models/UpdateSchemaDto.cs rename to src/Squidex/Areas/Api/Schemas/Models/UpdateSchemaDto.cs diff --git a/src/Squidex/Controllers/Api/Schemas/SchemaFieldsController.cs b/src/Squidex/Areas/Api/Schemas/SchemaFieldsController.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/SchemaFieldsController.cs rename to src/Squidex/Areas/Api/Schemas/SchemaFieldsController.cs diff --git a/src/Squidex/Controllers/Api/Schemas/SchemasController.cs b/src/Squidex/Areas/Api/Schemas/SchemasController.cs similarity index 100% rename from src/Squidex/Controllers/Api/Schemas/SchemasController.cs rename to src/Squidex/Areas/Api/Schemas/SchemasController.cs diff --git a/src/Squidex/Controllers/Api/Statistics/Models/CallsUsageDto.cs b/src/Squidex/Areas/Api/Statistics/Models/CallsUsageDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Statistics/Models/CallsUsageDto.cs rename to src/Squidex/Areas/Api/Statistics/Models/CallsUsageDto.cs diff --git a/src/Squidex/Controllers/Api/Statistics/Models/CurrentCallsDto.cs b/src/Squidex/Areas/Api/Statistics/Models/CurrentCallsDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Statistics/Models/CurrentCallsDto.cs rename to src/Squidex/Areas/Api/Statistics/Models/CurrentCallsDto.cs diff --git a/src/Squidex/Controllers/Api/Statistics/Models/CurrentStorageDto.cs b/src/Squidex/Areas/Api/Statistics/Models/CurrentStorageDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Statistics/Models/CurrentStorageDto.cs rename to src/Squidex/Areas/Api/Statistics/Models/CurrentStorageDto.cs diff --git a/src/Squidex/Controllers/Api/Statistics/Models/StorageUsageDto.cs b/src/Squidex/Areas/Api/Statistics/Models/StorageUsageDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Statistics/Models/StorageUsageDto.cs rename to src/Squidex/Areas/Api/Statistics/Models/StorageUsageDto.cs diff --git a/src/Squidex/Controllers/Api/Statistics/UsagesController.cs b/src/Squidex/Areas/Api/Statistics/UsagesController.cs similarity index 100% rename from src/Squidex/Controllers/Api/Statistics/UsagesController.cs rename to src/Squidex/Areas/Api/Statistics/UsagesController.cs diff --git a/src/Squidex/Controllers/Api/UI/Models/UIRegexSuggestionDto.cs b/src/Squidex/Areas/Api/UI/Models/UIRegexSuggestionDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/UI/Models/UIRegexSuggestionDto.cs rename to src/Squidex/Areas/Api/UI/Models/UIRegexSuggestionDto.cs diff --git a/src/Squidex/Controllers/Api/UI/Models/UISettingsDto.cs b/src/Squidex/Areas/Api/UI/Models/UISettingsDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/UI/Models/UISettingsDto.cs rename to src/Squidex/Areas/Api/UI/Models/UISettingsDto.cs diff --git a/src/Squidex/Controllers/Api/UI/UIController.cs b/src/Squidex/Areas/Api/UI/UIController.cs similarity index 100% rename from src/Squidex/Controllers/Api/UI/UIController.cs rename to src/Squidex/Areas/Api/UI/UIController.cs diff --git a/src/Squidex/Controllers/Api/Users/Assets/Avatar.png b/src/Squidex/Areas/Api/Users/Assets/Avatar.png similarity index 100% rename from src/Squidex/Controllers/Api/Users/Assets/Avatar.png rename to src/Squidex/Areas/Api/Users/Assets/Avatar.png diff --git a/src/Squidex/Controllers/Api/Users/Models/CreateUserDto.cs b/src/Squidex/Areas/Api/Users/Models/CreateUserDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Users/Models/CreateUserDto.cs rename to src/Squidex/Areas/Api/Users/Models/CreateUserDto.cs diff --git a/src/Squidex/Controllers/Api/Users/Models/UpdateUserDto.cs b/src/Squidex/Areas/Api/Users/Models/UpdateUserDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Users/Models/UpdateUserDto.cs rename to src/Squidex/Areas/Api/Users/Models/UpdateUserDto.cs diff --git a/src/Squidex/Controllers/Api/Users/Models/UserCreatedDto.cs b/src/Squidex/Areas/Api/Users/Models/UserCreatedDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Users/Models/UserCreatedDto.cs rename to src/Squidex/Areas/Api/Users/Models/UserCreatedDto.cs diff --git a/src/Squidex/Controllers/Api/Users/Models/UserDto.cs b/src/Squidex/Areas/Api/Users/Models/UserDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Users/Models/UserDto.cs rename to src/Squidex/Areas/Api/Users/Models/UserDto.cs diff --git a/src/Squidex/Controllers/Api/Users/Models/UsersDto.cs b/src/Squidex/Areas/Api/Users/Models/UsersDto.cs similarity index 100% rename from src/Squidex/Controllers/Api/Users/Models/UsersDto.cs rename to src/Squidex/Areas/Api/Users/Models/UsersDto.cs diff --git a/src/Squidex/Controllers/Api/Users/UserManagementController.cs b/src/Squidex/Areas/Api/Users/UserManagementController.cs similarity index 100% rename from src/Squidex/Controllers/Api/Users/UserManagementController.cs rename to src/Squidex/Areas/Api/Users/UserManagementController.cs diff --git a/src/Squidex/Controllers/Api/Users/UsersController.cs b/src/Squidex/Areas/Api/Users/UsersController.cs similarity index 100% rename from src/Squidex/Controllers/Api/Users/UsersController.cs rename to src/Squidex/Areas/Api/Users/UsersController.cs diff --git a/src/Squidex/Areas/IdentityServer/Controllers/Profile/PortalController.cs b/src/Squidex/Areas/IdentityServer/Controllers/Profile/PortalController.cs deleted file mode 100644 index ef3f2326e..000000000 --- a/src/Squidex/Areas/IdentityServer/Controllers/Profile/PortalController.cs +++ /dev/null @@ -1,40 +0,0 @@ -// ========================================================================== -// PortalController.cs -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex Group -// All rights reserved. -// ========================================================================== - -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using NSwag.Annotations; -using Squidex.Domain.Apps.Read.Apps.Services; -using Squidex.Infrastructure.Security; - -namespace Squidex.Areas.IdentityServer.Controllers.Profile -{ - [Authorize] - [SwaggerIgnore] - public sealed class PortalController : Controller - { - private readonly IAppPlanBillingManager appPlansBillingManager; - - public PortalController(IAppPlanBillingManager appPlansBillingManager) - { - this.appPlansBillingManager = appPlansBillingManager; - } - - [HttpGet] - [Route("/account/portal/")] - public async Task Portal() - { - var userId = User.FindFirst(OpenIdClaims.Subject).Value; - - var redirectUrl = await appPlansBillingManager.GetPortalLinkAsync(userId); - - return Redirect(redirectUrl); - } - } -} diff --git a/src/Squidex/Areas/Portal/Middlewares/PortalDashboardAuthenticationMiddleware.cs b/src/Squidex/Areas/Portal/Middlewares/PortalDashboardAuthenticationMiddleware.cs new file mode 100644 index 000000000..2acd9496a --- /dev/null +++ b/src/Squidex/Areas/Portal/Middlewares/PortalDashboardAuthenticationMiddleware.cs @@ -0,0 +1,43 @@ +// ========================================================================== +// LazyClientStore.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.Authentication.OpenIdConnect; +using Microsoft.AspNetCore.Http; + +namespace Squidex.Areas.Portal.Middlewares +{ + public sealed class PortalDashboardAuthenticationMiddleware + { + private readonly RequestDelegate next; + + public PortalDashboardAuthenticationMiddleware(RequestDelegate next) + { + this.next = next; + } + + public async Task Invoke(HttpContext context) + { + var authentication = await context.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme); + + if (!authentication.Succeeded) + { + await context.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties + { + RedirectUri = context.Request.PathBase + context.Request.Path + }); + } + else + { + await next(context); + } + } + } +} diff --git a/src/Squidex/Areas/Portal/Middlewares/PortalRedirectMiddleware.cs b/src/Squidex/Areas/Portal/Middlewares/PortalRedirectMiddleware.cs new file mode 100644 index 000000000..ade8b6eb0 --- /dev/null +++ b/src/Squidex/Areas/Portal/Middlewares/PortalRedirectMiddleware.cs @@ -0,0 +1,38 @@ +// ========================================================================== +// PortalRedirectMiddleware.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Squidex.Domain.Apps.Read.Apps.Services; +using Squidex.Infrastructure.Security; + +namespace Squidex.Areas.Portal.Middlewares +{ + public sealed class PortalRedirectMiddleware + { + private readonly IAppPlanBillingManager appPlansBillingManager; + private readonly RequestDelegate next; + + public PortalRedirectMiddleware(RequestDelegate next, IAppPlanBillingManager appPlansBillingManager) + { + this.next = next; + + this.appPlansBillingManager = appPlansBillingManager; + } + + public async Task Invoke(HttpContext context) + { + if (context.Request.Path == "/") + { + var userId = context.User.FindFirst(OpenIdClaims.Subject).Value; + + context.Response.RedirectToAbsoluteUrl(await appPlansBillingManager.GetPortalLinkAsync(userId)); + } + } + } +} diff --git a/src/Squidex/Areas/Portal/Startup.cs b/src/Squidex/Areas/Portal/Startup.cs new file mode 100644 index 000000000..17c2bcf6f --- /dev/null +++ b/src/Squidex/Areas/Portal/Startup.cs @@ -0,0 +1,28 @@ +// ========================================================================== +// Startup.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using Microsoft.AspNetCore.Builder; +using Orleans; +using Squidex.Areas.OrleansDashboard.Middlewares; +using Squidex.Areas.Portal.Middlewares; + +namespace Squidex.Areas.Portal +{ + public static class Startup + { + public static void ConfigurePortal(this IApplicationBuilder app) + { + app.Map("/portal", orleansApp => + { + orleansApp.UseAuthentication(); + orleansApp.UseMiddleware(); + orleansApp.UseMiddleware(); + }); + } + } +} diff --git a/src/Squidex/WebStartup.cs b/src/Squidex/WebStartup.cs index e8f550f0c..fed638a66 100644 --- a/src/Squidex/WebStartup.cs +++ b/src/Squidex/WebStartup.cs @@ -16,6 +16,7 @@ using Microsoft.Extensions.DependencyInjection; using Squidex.Areas.Frontend; using Squidex.Areas.IdentityServer; using Squidex.Areas.OrleansDashboard; +using Squidex.Areas.Portal; using Squidex.Config; using Squidex.Config.Domain; using Squidex.Config.Orleans; @@ -30,14 +31,6 @@ namespace Squidex { private readonly IConfiguration configuration; - private static readonly string[] IdentityServerPaths = - { - "/client-callback-popup", - "/client-callback-silent", - "/account", - "/error" - }; - public WebStartup(IConfiguration configuration) { this.configuration = configuration; @@ -63,7 +56,9 @@ namespace Squidex MapAndUseApi(app); app.ConfigureOrleansDashboard(); + app.ConfigurePortal(); app.ConfigureIdentityServer(); + app.ConfigureFrontend(); } @@ -72,17 +67,8 @@ namespace Squidex app.Map(Constants.ApiPrefix, appApi => { appApi.UseMySwagger(); - - appApi.MapWhen(x => !IsIdentityRequest(x), mvcApp => - { - mvcApp.UseMvc(); - }); + appApi.UseMvc(); }); } - - private static bool IsIdentityRequest(HttpContext context) - { - return IdentityServerPaths.Any(p => context.Request.Path.StartsWithSegments(p)); - } } }