Compare commits

..

73 Commits

Author SHA1 Message Date
7ea89aa35e chore(DI): bump to 1.1.3 2025-08-19 12:11:18 +02:00
50f5289191 refactor(BaseEntity): Aktualisierung des Namespace der BaseEntity für Multi-Targeting
- Anpassung des Namespace und der Klammern der Klasse „User“, um sowohl .NET als auch .NET Framework zu unterstützen.
- Beibehaltung bestehender Eigenschaften und Anmerkungen, einschließlich der Behandlung von Nullwerten und erforderlichen Angaben pro Ziel.
- Gewährleistet die korrekte Kompilierung unter den Bedingungen „#if NET“ und „#if NETFRAMEWORK“.
2025-08-19 11:54:57 +02:00
f8dcd5ba41 refactor(User): Aktualisierung des Namespace der User-Entität für Multi-Targeting
- Anpassung des Namespace und der Klammern der Klasse „User“, um sowohl .NET als auch .NET Framework zu unterstützen.
- Beibehaltung bestehender Eigenschaften und Anmerkungen, einschließlich der Behandlung von Nullwerten und erforderlichen Angaben pro Ziel.
- Gewährleistet die korrekte Kompilierung unter den Bedingungen „#if NET“ und „#if NETFRAMEWORK“.
2025-08-19 11:36:43 +02:00
8f5015f7d7 Refactor(Domain): Aktualisieren Sie die Framework-Bedingung, um das gesamte .NET zu unterstützen, anstatt nur .NET 7 oder höher. 2025-08-19 11:32:05 +02:00
efcd26fb29 bump to 6.1.4 2025-08-11 13:42:05 +02:00
2ee0f976fd refactor(cnnString): Remove user ID encryption 2025-08-11 12:59:00 +02:00
a3087a5e34 refactor(appsettings.Auth.json): change Audiance 2025-08-11 11:32:30 +02:00
525a30b541 refactor(DirectoryController): Ersetzen der Benutzersuche im Cache durch direkten DirectoryEntry aus Optionen
- Hinzufügen der Abhängigkeitsinjektion `IOptions<DirSearchRoot>`, um den vorkonfigurierten DirectoryEntry-Stamm zu verwenden.
- Einführung des Feldes `_dirSearchRoot` für wiederverwendbare LDAP-Root-Bindung.
- Ersetzen der Aufrufe von `FindAllByUserCache` durch `FindAll` unter Verwendung von `DirectoryEntry` aus `_dirSearchRoot`.
- Entfernen der veralteten Endpunkte `GetRootOf` und `CreateSearchRoot`.
- Sicherstellen des Musters `using var sRoot` für die ordnungsgemäße Entsorgung von DirectoryEntry-Instanzen.
2025-08-11 11:06:07 +02:00
f5471a8d01 feat(api): DirSearchRoot-Modell für die Konfiguration der LDAP-Verzeichnissuche und die Konvertierung zu DirectoryEntry hinzufügen 2025-08-11 10:51:58 +02:00
bcdcdd679a fix: version number 2025-08-08 13:38:43 +02:00
88cffc12a5 chore: add api-version and bind with footer 2025-08-08 13:26:15 +02:00
3bffdabc64 chore(api): bump to 6.1.3 2025-08-08 13:12:03 +02:00
5b45bdfa6b refactor(style.css): update to disable user selection 2025-08-08 12:59:40 +02:00
4f5d034e53 feat(footer): bind version with package.json 2025-08-08 12:55:05 +02:00
17d4bc51f4 refactor(privacy-policy): style: iframe-Styling zur Layoutanpassung aktualisiert
- Versionsinformationen zur Fußzeile hinzufügen
2025-08-08 12:16:54 +02:00
fc4209eb40 feat(footer): add the component with css 2025-08-08 11:12:00 +02:00
545b629129 refactor(privacy-policy.component): Aktualisiert, um iframe zu verwenden.
- Mit dem Pfad privacy-policy verknüpfen
2025-08-07 17:58:27 +02:00
eceace7e5e add mock privacy policy 2025-08-07 14:07:20 +02:00
cb9c7694db feat(privacy-policy.component): create privacy-polic using pdf-viewer 2025-08-07 13:42:48 +02:00
4c99e1cbee add ng2-pdf-viewer package 2025-08-07 13:36:06 +02:00
39c97e1e3c fix(group-update-form.component): update component to siable save button if the group is internal 2025-08-07 12:29:04 +02:00
720c25bd5c feat(api-service): Snackbar bei erfolgreichem Update anzeigen 2025-08-07 11:58:03 +02:00
ae0301c5be feat(group-update-form.component): update the component template to disable group name, comment, and aktiv components 2025-08-07 11:41:34 +02:00
8f31377b99 fix(GroupService): update to disable to change if the group is internal 2025-08-07 11:27:17 +02:00
Developer 02
addf7585f2 chore: configure for pnpm 2025-08-06 20:00:53 +02:00
Developer 02
dddabefc7d refactor(proxy.conf): change proxy port 2025-08-06 19:02:58 +02:00
Developer 02
9c5cf2de30 feat(config): Alle Nicht-Entwicklungs-appsettings.*.json-Dateien dynamisch laden
- Es wurde eine Logik hinzugefügt, um alle `appsettings.*.json`-Dateien in Nicht-Entwicklungsumgebungen einzubeziehen,
mit Ausnahme von `appsettings.Development.json`, sodass umgebungsspezifische Konfigurationen automatisch geladen werden können.
2025-08-06 16:46:29 +02:00
Developer 02
ca214225ea feat: Neue Update-Methode in GroupService hinzugefügt mit Validierung für Systemgruppen 2025-08-05 20:27:15 +02:00
Developer 02
733cb967cb refactor(CRUDControllerBaseWithErrorHandling): update use CRUDControllerBase 2025-08-05 19:53:04 +02:00
Developer 02
278090ea85 refactor(UserRepController): remove try-catch block 2025-08-05 19:50:43 +02:00
Developer 02
5f41e1b604 refactor(UserController): remove try-catch block 2025-08-05 19:50:04 +02:00
Developer 02
e0683a8d17 refactor(ModuleOfUserController): remove try-catch block 2025-08-05 19:49:13 +02:00
Developer 02
dda2f25b57 refactor(GroupOfUserController): remove try-catch block 2025-08-05 19:48:36 +02:00
Developer 02
d252859b11 refactor(GroupController): remove try-catch block 2025-08-05 19:47:56 +02:00
Developer 02
9fd66d41ca refactor(DirectoryController): remove try-catch block 2025-08-05 19:47:24 +02:00
Developer 02
4725614bb3 refactor(AuthController): remove try-catch block 2025-08-05 19:45:37 +02:00
Developer 02
5f7e040e3e refactor(ExceptionHandlingMiddleware): update to handle ForbiddenException 2025-08-05 19:44:37 +02:00
Developer 02
6e6af4b667 feat(ExceptionHandlingMiddleware): add middleware to handle error 2025-08-05 19:27:37 +02:00
Developer 02
f6c2568b25 refactor(GroupReadDto): made internal notnull 2025-08-05 19:24:40 +02:00
Developer 02
e35dbefb6f fix(csproj): change packge icon path 2025-08-05 19:05:29 +02:00
Developer 02
448ddf7eba chore: move projects to src dir 2025-08-05 19:01:02 +02:00
Developer 02
cb446ef25a refactor(wwwroot): deleted 2025-08-05 18:56:42 +02:00
098c2e1c47 feat(Verzeichnis): Client-Methode erstellt und Endpunkte angeordnet 2025-07-29 09:59:52 +02:00
3d8076e3b6 fix references 2025-07-28 15:15:38 +02:00
5cfc31b83c refactor(changeDetection): update to use On push in components and pages 2025-07-28 14:07:13 +02:00
cca98e136f refactor(appsettings): ipdated AuthClientParams to use 172.24.12.39:9090 2025-07-28 11:27:01 +02:00
9a91d1f14d Set minimum log level Trace 2025-07-28 10:57:17 +02:00
0057a2d260 chore: upgrede auf 6.1.1
- Bauort nach \API verschieben
 - AuthClientParams.Url auf 9090 aktualisieren
2025-07-22 17:55:06 +02:00
854db39f30 chore(Domain): update version 2025-07-22 15:50:40 +02:00
f79fa4ca27 fix(auth): Verbesserung von isAuthenticated() durch Überprüfung des HTTP-Antwortstatus
Die isAuthenticated()-Methode wurde aktualisiert, um den Anmeldestatus anhand des HTTP-Antwortstatus zu bestimmen, anstatt sich nur auf den Antwortkörper zu verlassen. Außerdem wird sichergestellt, dass `_isLogedIn` im Fehlerfall explizit auf false gesetzt wird. Dies verbessert die Zuverlässigkeit der Sitzungsvalidierung.
2025-07-22 15:45:38 +02:00
55822047bc refactor(api.models): Verschiebung ins api-Verzeichnis und Vereinfachung der Namenskonvention 2025-07-22 14:21:31 +02:00
de360968dc refactor(User): Aktualisierung des User-Modells. 2025-07-22 14:15:35 +02:00
06303ec2b5 refactor(startup): remove cookie-based authentication configuration 2025-07-22 13:13:52 +02:00
437f33a323 fix(auth): Fehlermeldung bei 401 unauthorized während der Login-Prüfung verhindern
Überspringe die Anzeige der Fehlermeldung in isAuthenticated, wenn der Antwortstatus 401,
ist, was typischerweise anzeigt, dass der Benutzer einfach nicht eingeloggt ist, nicht ein Serverproblem.
2025-07-22 10:33:42 +02:00
963ab12488 chore: add scripts to be able to start without ssl
- changed target of proxy
2025-07-22 10:19:36 +02:00
df24905a0e feat(logging): NLog nur in Nicht-Entwicklungsumgebungen anwenden
Die Einrichtung des Logging-Anbieters wurde mit einer Prüfung versehen, um sicherzustellen, dass NLog nur verwendet wird, wenn es sich nicht in der Entwicklung befindet. Dadurch wird verhindert, dass das Standard-Protokollierungsverhalten während der Entwicklung überschrieben wird.
2025-07-22 08:51:06 +02:00
0659734346 Bump package versions and update User class declaration
Incremented version numbers in DependencyInjection and Domain projects.
Changed User class to partial for better organization and flexibility.
2025-06-26 16:36:24 +02:00
9af19713a0 Bump version numbers for multiple projects
Updated version, AssemblyVersion, and FileVersion for:
- DigitalData.UserManager.API: 6.1.0 to 6.1.1
- DigitalData.UserManager.Application: 3.2.0 to 3.2.1
- DigitalData.UserManager.DependencyInjection: 1.1.0 to 1.1.1
- DigitalData.UserManager.Domain: 3.2.0 to 3.2.1
- DigitalData.UserManager.Infrastructure: 3.1.0 to 3.1.1
2025-06-26 15:48:30 +02:00
06ad3516f1 Enhance User entity with required properties and updates
- Added conditional compilation for .NET Framework.
- Made `GeneralViewer`, `WanEnvironment`, and `DeletedWho` properties required with appropriate attributes.
- Renamed `UseridFkIntEcm` to `UserIdFkIntEcm` and marked it as required.
- Changed `DeletedWhen` to a non-nullable `DateTime`.
- Removed previously ignored columns, activating them in the class definition.
2025-06-26 15:45:22 +02:00
23c7b7a293 Bump version numbers
Updated version, assembly version, and file version for:
- DigitalData.UserManager.API: 6.0.1 to 6.1.0
- DigitalData.UserManager.Application: 3.1.3 to 3.2.0
- DigitalData.UserManager.DependencyInjection: 1.0.0 to 1.1.0
- DigitalData.UserManager.Domain: 3.1.0 to 3.2.0
- DigitalData.UserManager.Infrastructure: 3.0.2 to 3.1.0
2025-06-26 14:02:59 +02:00
53bfc4a413 Suppress warnings for obsolete members and update repo
Added warning suppression in `Program.cs` for obsolete user manager configuration. Marked `ClientUserRepository` as obsolete to encourage transition to the new `Repository` class.
2025-06-26 13:56:42 +02:00
3de7e64f85 Deprecate services and update mapping profiles
- Added obsolete attributes to `AuthController`, `ModuleController`, and various mapping profiles, recommending the use of MediatR and DigitalData.Core.Exceptions.
- Updated `User` class to use `required` keyword for `DateFormat` in .NET 7.0 or greater.
- Marked methods in `Extensions` and `AddUserManagerInfrastructure` as obsolete, suggesting the use of IRepository.
- Adjusted import statements in `DependencyInjection.cs` and marked `GroupOfUserRepository` and `ModuleRepository` as obsolete, recommending a Repository pattern.
2025-06-26 13:53:54 +02:00
39a9181257 Deprecate methods and classes in UserManager.Application
Introduce `[Obsolete]` attributes to various methods and classes, suggesting alternatives such as MediatR and IRepository. Mark multiple DTOs and repository classes as obsolete, recommending the use of DigitalData.Core.Exceptions and .Middleware or Repository. This change aims to enhance maintainability and clarity in the codebase.
2025-06-26 13:37:59 +02:00
5d3f73bb13 Refactor entity properties for nullability and requirements
Removed nullable indicators from string properties in
BaseEntity.cs, ClientUser.cs, Group.cs, and User.cs.
The Username property in User.cs is now marked as
required for .NET 7 or greater, improving data integrity
and reducing null reference risks.
2025-06-26 13:20:54 +02:00
bc44de63ee Update project for multi-targeting and nullable types
Updated `DigitalData.UserManager.Domain.csproj` to support .NET 4.6.2, 7.0, 8.0, and 9.0. Adjusted implicit usings and nullable reference types settings based on the target framework, disabling nullable types for `net462` and enabling them for others.

Refactored entity classes (`BaseEntity`, `ClientUser`, `Group`, `GroupOfUser`, `Module`, `ModuleOfUser`, `User`, and `UserRep`) to conditionally include nullable reference types. Added `?` operator for string properties in .NET 7.0 and above, enhancing code safety and reducing null reference exceptions.
2025-06-26 13:15:36 +02:00
b1075c8b82 Add .NET Framework 4.6.2 support and improve nullability
Updated `DigitalData.UserManager.Domain.csproj` to target .NET Framework 4.6.2 alongside .NET 7.0, 8.0, and 9.0. Corrected `PackageTags` from "user maanger" to "user manager" and added property groups for implicit usings and language versions.

Introduced nullable reference types in entity classes (`BaseEntity`, `ClientUser`, `Group`, `User`, etc.) for enhanced type safety. Updated properties in the `User` and `UserRep` classes to use the new nullable syntax, ensuring consistency across the codebase.

These changes improve compatibility with newer C# features and maintain support for multiple frameworks.
2025-06-26 12:27:24 +02:00
40deb9968f Update namespaces and package references
Refactor namespaces from `DigitalData.Core.DTO` to `DigitalData.Core.Abstraction.Application.DTO` in multiple controllers to adopt a new abstraction layer. Update `DigitalData.Core.API` package from version `2.2.0` to `2.2.1` and add `DigitalData.Core.Abstraction.Application` package with version `1.0.0`. Add `[Obsolete("Use MediatR")]` attribute to several controllers to encourage transitioning to MediatR for request handling.
2025-06-26 11:47:43 +02:00
182771afd2 Refactor AuthController to use MediatR
- Added using directive for DigitalData.Core.Abstraction.Application.DTO.
- Marked IUserService and GetUserWithClaims as obsolete.
- Transitioning towards MediatR for handling requests and responses.
2025-06-26 10:15:58 +02:00
668eef2a4d Update BaseReadDto namespace and mark as obsolete
Replaced the namespace import from `DigitalData.Core.DTO` to `DigitalData.Core.Abstraction.Application.DTO` in `BaseReadDto.cs`. Added an `Obsolete` attribute to indicate deprecation and recommend using `DigitalData.Core.Exceptions and .Middleware` instead. This change enhances code organization and clarity.
2025-06-26 10:00:01 +02:00
e9527ca61e Refactor namespaces and update DTO structures
Updated namespaces for DTOs and services to improve project organization. Marked several interfaces as obsolete in favor of MediatR for better request handling. Simplified `BaseUpdateDto` and other DTOs by removing `IUnique<int>` implementation. Changed return types of `CreateAsync` methods to return corresponding read DTOs. Removed reference to `DigitalData.Core.DTO` in the project file, reflecting a shift in architecture for maintainability.
2025-06-25 17:14:24 +02:00
8f2ec82d4f Mark IBaseService as obsolete for MediatR usage
Added an `Obsolete` attribute to the `IBaseService` interface, recommending the use of MediatR instead. This change serves as a warning to developers about potential deprecation, encouraging a transition to the suggested alternative.
2025-06-25 16:04:27 +02:00
cc708cae0c Refactor namespace and update project dependencies
Updated the import statement for `DigitalData.Core.Abstractions.Application` to `DigitalData.Core.Abstraction.Application` in `IBaseService.cs`. Removed the `PackageReference` for `DigitalData.Core.Abstractions` version `4.0.0` from the project file, indicating a shift in library usage.
2025-06-25 16:03:14 +02:00
b936677c16 Update packages and simplify entity definitions
- Updated package references to newer versions for `DigitalData.Auth.Client`, `DigitalData.Core.API`, `DigitalData.Core.Abstractions`, `DigitalData.Core.Application`, and `DigitalData.EmailProfilerDispatcher.Abstraction`.
- Changed `UserManager.Domain` package version from `3.0.2` to `3.1.0` and updated assembly and file versions.
- Removed `IUnique<int>` interface implementation from `BaseEntity`, `ClientUser`, `Module`, and `ModuleOfUser`.
- Added data annotations to the `User` class for various properties that were previously commented out.
- Updated `Microsoft.EntityFrameworkCore` package references in the `Infrastructure` project for `net7.0` and `net9.0`.
- Modified solution configuration to change a project's build configuration from Debug to Release.
2025-06-25 14:46:39 +02:00
344 changed files with 12393 additions and 16630 deletions

View File

@@ -1,16 +0,0 @@
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.ts]
quote_type = single
[*.md]
max_line_length = off
trim_trailing_whitespace = false

View File

@@ -1,4 +0,0 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
"recommendations": ["angular.ng-template"]
}

View File

@@ -1,20 +0,0 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "ng serve",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: start",
"url": "http://localhost:4200/"
},
{
"name": "ng test",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: test",
"url": "http://localhost:9876/debug.html"
}
]
}

View File

@@ -1,42 +0,0 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "start",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "(.*?)"
},
"endsPattern": {
"regexp": "bundle generation complete"
}
}
}
},
{
"type": "npm",
"script": "test",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "(.*?)"
},
"endsPattern": {
"regexp": "bundle generation complete"
}
}
}
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-info',
standalone: true,
imports: [],
templateUrl: './info.component.html',
styleUrl: './info.component.scss'
})
export class InfoComponent {
}

View File

@@ -1,234 +0,0 @@
using DigitalData.Core.Abstractions.Application;
using DigitalData.UserManager.Application.Contracts;
using DigitalData.UserManager.Application.DTOs;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using System.Diagnostics.CodeAnalysis;
using System.Security.Claims;
using DigitalData.UserManager.Application;
using Microsoft.Extensions.Localization;
using DigitalData.Core.DTO;
using Microsoft.AspNetCore.Authorization;
namespace DigitalData.UserManager.API.Controllers;
[Route("api/[controller]")]
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
[Authorize]
public class DirectoryController : ControllerBase
{
private readonly IUserService _userService;
private readonly IDirectorySearchService _dirSearchService;
private readonly Dictionary<string, string> _customSearchFilters;
private readonly IStringLocalizer<Resource> _localizer;
private readonly ILogger<DirectoryController> _logger;
public DirectoryController(IConfiguration configuration, IStringLocalizer<Resource> localizer, IUserService userService, IDirectorySearchService directorySearchService, ILogger<DirectoryController> logger)
{
_localizer = localizer;
_userService = userService;
_dirSearchService = directorySearchService;
var customSearchFiltersSection = configuration.GetSection("DirectorySearch:CustomSearchFilters");
_customSearchFilters = customSearchFiltersSection.Get<Dictionary<string, string>>() ?? new();
_logger = logger;
}
[HttpGet("Root/{username}")]
public IActionResult GetRootOf(string username)
{
try
{
var root = _dirSearchService.GetSearchRootCache(username);
return root is null ? NotFound() : Ok(new
{
guid = root.Guid,
nativeGuid = root.NativeGuid,
name = root.Name,
path = root.Path,
parentPath = root.Parent?.Path,
username = root.Username,
schemaClassName = root.SchemaClassName
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("CustomSearchFilter")]
public IActionResult GetAllCustomFilters(string? filtername)
{
try
{
if (filtername is null)
{
return Ok(_customSearchFilters);
}
else
{
_dirSearchService.CustomSearchFilters.TryGetValue(filtername, out string? filter);
return filter is null ? NotFound() : Ok(filter);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("CreateSearchRoot")]
public async Task<IActionResult> CreateSearchRoot([FromBody] SearchRootCreateDto searchRootCreateDto)
{
try
{
var dirEntryUsername = searchRootCreateDto.DirEntryUsername ?? CurrentUser;
if (dirEntryUsername is null)
return Unauthorized();
bool isValid = _dirSearchService.ValidateCredentials(dirEntryUsername, searchRootCreateDto.DirEntryPassword);
if (!isValid)
return Unauthorized(Result.Fail().Message(_localizer[Key.UserNotFound]));
var userResult = await _userService.ReadByUsernameAsync(dirEntryUsername);
if (!userResult.IsSuccess || userResult.Data is null)
return Unauthorized(Result.Fail().Message(_localizer[Key.UserNotFoundInLocalDB]));
_dirSearchService.SetSearchRootCache(userResult.Data.Username, searchRootCreateDto.DirEntryPassword);
return Ok();
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("SearchByFilter/{filter}")]
public IActionResult SearchByFilter([FromRoute] string filter, string? dirEntryUsername, params string[] propName)
{
try
{
dirEntryUsername ??= CurrentUser;
if (dirEntryUsername is null)
return Unauthorized();
return _dirSearchService.FindAllByUserCache(dirEntryUsername, filter, properties: propName).Then(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status424FailedDependency);
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("SearchByFilterName/{filterName}")]
public IActionResult SearchByFilterName([FromRoute] string filterName, string? dirEntryUsername, params string[] propName)
{
try
{
dirEntryUsername ??= CurrentUser;
if (dirEntryUsername is null)
return Unauthorized();
_dirSearchService.CustomSearchFilters.TryGetValue(filterName, out string? filter);
if (filter is null)
return NotFound($"The filter named {filterName} does not exist.");
return _dirSearchService.FindAllByUserCache(dirEntryUsername, filter, properties: propName).Then(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status424FailedDependency);
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("Group")]
public IActionResult GetGroups(string? dirEntryUsername, params string[] propName)
{
try
{
dirEntryUsername ??= CurrentUser;
if (dirEntryUsername is null)
return Unauthorized();
_dirSearchService.CustomSearchFilters.TryGetValue("Group", out string? filter);
if (filter is null)
throw new InvalidOperationException("The LDAP Group Search filter configuration is missing in your appsettings. Please ensure it's added under DirectorySearch:CustomSearchFilters:Group to enable group searches.");
return _dirSearchService.FindAllByUserCache(username: dirEntryUsername, filter, properties: propName).Then(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status424FailedDependency);
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("User")]
public IActionResult GetUsersByGroupName(string? dirEntryUsername, [FromQuery] string? groupName = null)
{
try
{
string[] propName = { "memberof", "samaccountname", "givenname", "sn", "mail" };
dirEntryUsername ??= CurrentUser;
if (dirEntryUsername is null)
return Unauthorized();
_dirSearchService.CustomSearchFilters.TryGetValue("User", out string? filter);
if (filter is null)
throw new InvalidOperationException("The LDAP User Search filter configuration is missing in your appsettings. Please ensure it's added under DirectorySearch:CustomSearchFilters:User to enable group searches.");
return _dirSearchService.FindAllByUserCache(username: dirEntryUsername, filter, properties: propName).Then(
Success: data =>
{
if (groupName is not null)
data = data
.Where(rp => rp.PropertyNames.Cast<string>().Contains("memberof") &&
rp["memberof"].Cast<string>().Any(ldapDir => ldapDir.Contains(groupName)))
.ToList();
return Ok(data);
},
Fail: IActionResult (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status424FailedDependency);
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
private string? CurrentUser
{
get => (HttpContext.User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value);
}
}

View File

@@ -1,42 +0,0 @@
using DigitalData.Core.DTO;
using DigitalData.UserManager.Application.Contracts;
using DigitalData.UserManager.Application.DTOs.Group;
using DigitalData.UserManager.Domain.Entities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace DigitalData.UserManager.API.Controllers;
[Authorize]
public class GroupController : BaseAuthController<IGroupService, GroupCreateDto, GroupReadDto, GroupUpdateDto, Group>
{
public GroupController(ILogger<GroupController> logger, IGroupService service, IUserService userService) : base(logger, service, userService)
{
}
[HttpPost("ByDir")]
public async Task<IActionResult> CreateByDir(DirectoryGroupDto adGroup)
{
try
{
return await _service.CreateAsync(adGroup).ThenAsync(
Success: id =>
{
var createdResource = new { Id = id };
var actionName = nameof(GetById);
var routeValues = new { id = createdResource.Id };
return CreatedAtAction(actionName, routeValues, createdResource);
},
Fail: IActionResult (m, n) =>
{
_logger.LogNotice(n);
return BadRequest();
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}

View File

@@ -1,80 +0,0 @@
using DigitalData.Core.DTO;
using DigitalData.UserManager.Application.Contracts;
using DigitalData.UserManager.Application.DTOs.GroupOfUser;
using DigitalData.UserManager.Domain.Entities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace DigitalData.UserManager.API.Controllers;
[Authorize]
public class GroupOfUserController : BaseAuthController<IGroupOfUserService, GroupOfUserCreateDto, GroupOfUserReadDto, GroupOfUserUpdateDto, GroupOfUser>
{
public GroupOfUserController(ILogger<GroupOfUserController> logger, IGroupOfUserService service, IUserService userService) : base(logger, service, userService)
{
}
[HttpDelete]
public async Task<IActionResult> Delete([FromQuery] int groupId, [FromQuery] int userId)
{
try
{
return await _service.DeleteAsyncByGroupUserId(groupId, userId).ThenAsync(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status500InternalServerError);
});
}
catch (Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[NonAction]
public override Task<IActionResult> GetAll() => base.GetAll();
[HttpGet]
public async Task<IActionResult> GetAll([FromQuery]bool withUser = false, [FromQuery]bool withGroup = false, [FromQuery] string? username = null)
{
try
{
if (username is not null)
return await _service.ReadByUsernameAsync(username).ThenAsync(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return NotFound();
});
return await _service.ReadAllAsyncWith(withUser, withGroup).ThenAsync(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return NotFound();
});
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("Has")]
public async Task<IActionResult> HasGroup([FromQuery] string username, [FromQuery] string groupname)
{
try
{
return await _service.HasGroup(username, groupname).ThenAsync(Ok, (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status500InternalServerError);
});
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}

View File

@@ -1,98 +0,0 @@
using DigitalData.Core.DTO;
using DigitalData.UserManager.Application.Contracts;
using DigitalData.UserManager.Application.DTOs.User;
using DigitalData.UserManager.Domain.Entities;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace DigitalData.UserManager.API.Controllers;
[Authorize]
public class UserController : BaseAuthController<IUserService, UserCreateDto, UserReadDto, UserUpdateDto, User>
{
public UserController(ILogger<UserController> logger, IUserService service) : base(logger, service, service)
{
}
[HttpGet("ByModuleId/{moduleId}")]
public async Task<IActionResult> GetByModuleId([FromRoute] int moduleId, [FromQuery]bool assigned = true)
{
try
{
return await (assigned ? _service.ReadByModuleIdAsync(moduleId) : _service.ReadUnassignedByModuleIdAsync(moduleId))
.ThenAsync(Ok, IActionResult(m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status500InternalServerError);
});
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("ByGroupId/{groupId}")]
public async Task<IActionResult> GetByGroupId([FromRoute] int groupId, [FromQuery] bool assigned = true)
{
try
{
return await (assigned ? _service.ReadByGroupIdAsync(groupId) : _service.ReadUnassignedByGroupIdAsync(groupId))
.ThenAsync(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return StatusCode(StatusCodes.Status500InternalServerError);
});
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("ByDir")]
public async Task<IActionResult> CreateByDir(UserPrincipalDto upDto)
{
try
{
return await _service.CreateAsync(upDto).ThenAsync(
Success: id =>
{
var createdResource = new { Id = id };
var actionName = nameof(GetById);
var routeValues = new { id = createdResource.Id };
return CreatedAtAction(actionName, routeValues, createdResource);
},
Fail: IActionResult (m, n) =>
{
_logger.LogNotice(n);
return BadRequest();
});
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("ByUsername/{username}")]
public virtual async Task<IActionResult> GetByUsername([FromRoute] string username)
{
try
{
return await _service.ReadByUsernameAsync(username).ThenAsync(Ok, IActionResult (m, n) =>
{
_logger.LogNotice(n);
return NotFound();
});
}
catch(Exception ex)
{
_logger.LogError(ex, "{Message}", ex.Message);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}

View File

@@ -1,90 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"ConnectionStrings": {
"UM_DEF": "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=g+2edXEbMbujCUjh7INZRQ==;Password=Bz/n9pu8EyzlVqicaMRQGQ==;Encrypt=false;TrustServerCertificate=True;"
},
"AllowedOrigins": [ "https://localhost:7103", "http://172.24.12.39:85", "http://localhost:85", "http://localhost:4200", "http://localhost:5500", "https://localhost:7202" ],
"RunAsWindowsService": false,
"DirectorySearchOptions": {
"ServerName": "DD-VMP01-DC01",
"Root": "DC=dd-gan,DC=local,DC=digitaldata,DC=works",
"UserCacheExpirationDays": 1,
"CustomSearchFilters": {
"User": "(&(objectClass=user)(sAMAccountName=*))",
"Group": "(&(objectClass=group) (samAccountName=*))"
}
},
"Jwt": {
"Key": "pJBcBWZSjsWlhi1OlCcw6ERTMRNb7qsdvsfvdfbagdfbdfsSDGSDMhsjkfdhsdfbgkHKSDF",
"Issuer": "http://localhost:44316",
"Audience": "http://localhost:44316"
},
"NLog": {
"throwConfigExceptions": true,
"variables": {
"logDirectory": "E:\\LogFiles\\Digital Data\\WebUserManager",
"logFileNamePrefix": "${shortdate}-ECM.WebUserManager.Web"
},
"targets": {
"infoLogs": {
"type": "File",
"fileName": "${logDirectory}\\${logFileNamePrefix}-Info.log",
"maxArchiveDays": 30
},
"errorLogs": {
"type": "File",
"fileName": "${logDirectory}\\${logFileNamePrefix}-Error.log",
"maxArchiveDays": 30
},
"criticalLogs": {
"type": "File",
"fileName": "${logDirectory}\\${logFileNamePrefix}-Critical.log",
"maxArchiveDays": 30
}
},
// Trace, Debug, Info, Warn, Error and *Fatal*
"rules": [
{
"logger": "*",
"minLevel": "Info",
"maxLevel": "Warn",
"writeTo": "infoLogs"
},
{
"logger": "*",
"level": "Error",
"writeTo": "errorLogs"
},
{
"logger": "*",
"level": "Fatal",
"writeTo": "criticalLogs"
}
]
},
"EncryptionParameters": {
"Key": "JGPwHVD0BQmC7upi5OV11PzzIk47ugTJoqBV/et5w40=",
"IV": "gMuetIjlPvJnSzu+i7I3xg=="
},
"AllowedGroupName": "UM_ADMINS",
"DateTimeZoneHandling": "Local",
// Delete below in production
"UseEncryptor": true,
"UseSwagger": true,
"AuthClientParams": {
"Url": "https://localhost:7192/auth-hub",
"PublicKeys": [
{
"Issuer": "auth.digitaldata.works",
"Audience": "user-manager.digitaldata.works",
"Content": "-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3QCd7dH/xOUITFZbitMa/xnh8a0LyL6ZBvSRAwkI9ceplTRSHJXoM1oB+xtjWE1kOuHVLe941Tm03szS4+/rHIm0Ejva/KKlv7sPFAHE/pWuoPS303vOHgI4HAFcuwywA8CghUWzaaK5LU/Hl8srWwxBHv5hKIUjJFJygeAIENvFOZ1gFbB3MPEC99PiPOwAmfl4tMQUmSsFyspl/RWVi7bTv26ZE+m3KPcWppmvmYjXlSitxRaySxnfFvpca/qWfd/uUUg2KWKtpAwWVkqr0qD9v3TyKSgHoGDsrFpwSx8qufUJSinmZ1u/0iKl6TXeHubYS4C4SUSVjOWXymI2ZQIDAQAB-----END PUBLIC KEY-----"
}
],
"RetryDelay": "00:00:05"
}
}

View File

@@ -1,3 +0,0 @@
{
"apiUrl": "/api"
}

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" id="Ebene_1" viewBox="0 0 850 121.32">
<defs>
<style>.cls-1{fill:#fff;}</style>
</defs>
<path class="cls-1" d="m809.77,76.62h-8.94l3.51-28.73c.32-3.19.64-6.38.8-9.58h.32c.16,3.19.48,6.39.8,9.58l3.51,28.73h0Zm40.23,41.51l-28.73-114.94h-31.93l-28.73,114.94h35.12l1.6-14.37h15.96l1.6,14.37h35.12Zm-81.41-86.2l-3.19-28.74h-65.45l-3.19,28.74h19.16v86.2h33.52V31.93h19.16Zm-104.07,44.7h-8.94l3.51-28.73c.32-3.19.64-6.38.8-9.58h.32c.16,3.19.48,6.39.8,9.58l3.51,28.73h0Zm40.23,41.51l-28.73-114.94h-31.93l-28.73,114.94h35.12l1.6-14.37h15.96l1.6,14.37h35.12Zm-123.69-57.47c0,19.16-1.6,28.73-15.96,28.73V31.93c14.37,0,15.96,12.77,15.96,28.73m33.52,0c0-35.12-12.77-57.47-41.51-57.47h-41.51v114.94h39.91c30.33,0,43.1-20.75,43.1-57.47m-121.32,28.73h-25.54V3.19h-33.52v114.94h55.87l3.19-28.73h0Zm-105.68-12.77h-8.94l3.51-28.73c.32-3.19.64-6.38.8-9.58h.32c.16,3.19.48,6.39.8,9.58l3.51,28.73h0Zm40.23,41.51L399.07,3.19h-31.93l-28.74,114.94h35.12l1.6-14.37h15.96l1.6,14.37h35.12Zm-81.41-86.2l-3.19-28.74h-65.45l-3.19,28.74h19.16v86.2h33.52V31.93h19.16ZM268.18,3.19h-33.52v114.94h33.52V3.19h0Zm-44.7,94.19v-46.29h-39.91l-1.6,23.95h12.77v9.58c-3.19,4.79-6.39,7.98-12.77,7.98-7.98,0-12.77-11.17-12.77-31.93s4.79-31.93,12.77-31.93c6.86,0,11.33,5.75,12.77,14.37l28.73-6.39C218.7,15.96,207.52,0,181.98,0c-33.52,0-46.3,28.73-46.3,60.66s12.77,60.66,46.3,60.66c17.56,0,31.93-7.98,41.5-23.94M126.11,3.19h-33.52v114.94h33.52V3.19h0ZM49.49,60.66c0,19.16-1.6,28.73-15.96,28.73V31.93c14.37,0,15.96,12.77,15.96,28.73m33.52,0c0-35.12-12.77-57.47-41.51-57.47H0v114.94h39.91c30.33,0,43.1-20.75,43.1-57.47"></path>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 KiB

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 850 121.32">
<defs>
<style>
.cls-1 {
fill: #a52431;
stroke-width: 0px;
}
</style>
</defs>
<path class="cls-1" d="M83.01,60.66c0-35.12-12.77-57.47-41.51-57.47H0v114.94h39.91c30.33,0,43.1-20.75,43.1-57.47M49.49,60.66c0,19.16-1.6,28.73-15.96,28.73V31.93c14.37,0,15.96,12.77,15.96,28.73M126.11,3.19h-33.52v114.94h33.52V3.19ZM223.49,97.38v-46.29h-39.91l-1.6,23.95h12.77v9.58c-3.19,4.79-6.39,7.98-12.77,7.98-7.98,0-12.77-11.17-12.77-31.93s4.79-31.93,12.77-31.93c6.86,0,11.33,5.75,12.77,14.37l28.73-6.39C218.7,15.96,207.52,0,181.98,0c-33.52,0-46.29,28.73-46.29,60.66s12.77,60.66,46.29,60.66c17.56,0,31.93-7.98,41.51-23.94M268.18,3.19h-33.52v114.94h33.52V3.19ZM346.4,31.93l-3.19-28.74h-65.45l-3.19,28.74h19.16v86.2h33.52V31.93h19.16ZM427.81,118.13L399.07,3.19h-31.93l-28.73,114.94h35.12l1.6-14.37h15.96l1.6,14.37h35.12ZM387.58,76.62h-8.94l3.51-28.74c.32-3.19.64-6.38.8-9.58h.32c.16,3.19.48,6.38.8,9.58l3.51,28.74ZM493.26,89.4h-25.54V3.19h-33.52v114.94h55.87l3.19-28.74ZM614.58,60.66c0-35.12-12.77-57.47-41.51-57.47h-41.51v114.94h39.91c30.33,0,43.1-20.75,43.1-57.47M581.05,60.66c0,19.16-1.6,28.73-15.96,28.73V31.93c14.37,0,15.96,12.77,15.96,28.73M704.75,118.13l-28.73-114.94h-31.93l-28.74,114.94h35.12l1.6-14.37h15.96l1.6,14.37h35.12ZM664.52,76.62h-8.94l3.51-28.74c.32-3.19.64-6.38.8-9.58h.32c.16,3.19.48,6.38.8,9.58l3.51,28.74ZM768.59,31.93l-3.19-28.74h-65.45l-3.19,28.74h19.16v86.2h33.52V31.93h19.16ZM850,118.13l-28.73-114.94h-31.93l-28.73,114.94h35.12l1.6-14.37h15.96l1.6,14.37h35.12ZM809.77,76.62h-8.94l3.51-28.74c.32-3.19.64-6.38.8-9.58h.32c.16,3.19.48,6.38.8,9.58l3.51,28.74Z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1100 200">
<defs>
<style>
.cls-1 {
fill: #a52431;
}
.cls-1, .cls-2 {
stroke-width: 0px;
}
.cls-2 {
fill: #fff;
}
</style>
</defs>
<rect class="cls-1" width="1100" height="200"/>
<path class="cls-2" d="M929.81,115.71h-8.94l3.51-28.74c.32-3.19.64-6.39.8-9.58h.32c.16,3.19.48,6.39.8,9.58l3.51,28.74ZM970.04,157.22l-28.73-114.94h-31.93l-28.73,114.94h35.12l1.6-14.37h15.96l1.6,14.37h35.12ZM888.63,71.02l-3.19-28.74h-65.45l-3.19,28.74h19.16v86.2h33.52v-86.2h19.16ZM784.56,115.71h-8.94l3.51-28.74c.32-3.19.64-6.39.8-9.58h.32c.16,3.19.48,6.39.8,9.58l3.51,28.74ZM824.79,157.22l-28.73-114.94h-31.93l-28.74,114.94h35.12l1.6-14.37h15.96l1.6,14.37h35.12ZM701.09,99.75c0,19.16-1.6,28.73-15.96,28.73v-57.47c14.37,0,15.96,12.77,15.96,28.73M734.62,99.75c0-35.12-12.77-57.47-41.51-57.47h-41.51v114.94h39.91c30.33,0,43.1-20.75,43.1-57.47M613.3,128.48h-25.54V42.28h-33.52v114.94h55.87l3.19-28.74ZM507.62,115.71h-8.94l3.51-28.74c.32-3.19.64-6.39.8-9.58h.32c.16,3.19.48,6.39.8,9.58l3.51,28.74ZM547.85,157.22l-28.73-114.94h-31.93l-28.73,114.94h35.12l1.6-14.37h15.96l1.6,14.37h35.12ZM466.44,71.02l-3.19-28.74h-65.45l-3.19,28.74h19.16v86.2h33.52v-86.2h19.16ZM388.22,42.28h-33.52v114.94h33.52V42.28ZM343.53,136.47v-46.29h-39.91l-1.6,23.94h12.77v9.58c-3.19,4.79-6.38,7.98-12.77,7.98-7.98,0-12.77-11.17-12.77-31.93s4.79-31.93,12.77-31.93c6.86,0,11.33,5.75,12.77,14.37l28.74-6.39c-4.79-20.75-15.96-36.72-41.51-36.72-33.52,0-46.29,28.73-46.29,60.66s12.77,60.66,46.29,60.66c17.56,0,31.93-7.98,41.51-23.94M246.15,42.28h-33.52v114.94h33.52V42.28ZM169.53,99.75c0,19.16-1.6,28.73-15.96,28.73v-57.47c14.37,0,15.96,12.77,15.96,28.73M203.05,99.75c0-35.12-12.77-57.47-41.51-57.47h-41.5v114.94h39.91c30.33,0,43.1-20.75,43.1-57.47"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -1,17 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" class="bi" width="3em" height="2.5em" viewBox="0 0 488.6 488.6" stroke="#a9a8ad">
<style>
vertical-align: -.125em;
fill: currentColor;
</style>
<path opacity="0.4"
d="M480.9,333.2c-27.2-22.3-56.5-37.1-62.4-40c-0.7-0.3-1.1-1-1.1-1.8v-42.3c5.3-3.5,8.8-9.6,8.8-16.5v-43.9
c0-21.8-17.7-39.5-39.5-39.5H382h-4.7c-21.8,0-39.5,17.7-39.5,39.5v43.9c0,6.9,3.5,12.9,8.8,16.5v42.3c0,0.3-0.1,0.5-0.1,0.7
c8.3,5.7,17,12.1,25.5,19.1c9.9,8.2,15.6,20.2,15.6,33.2v35.3h101v-30.1C488.6,343.3,485.8,337.2,480.9,333.2z" />
<path opacity="0.5" d="M142,291.4v-42.3c5.3-3.5,8.8-9.6,8.8-16.5v-43.9c0-21.8-17.7-39.5-39.5-39.5h-4.7h-4.7c-21.8,0-39.5,17.7-39.5,39.5v43.9
c0,6.9,3.5,12.9,8.8,16.5v42.3c0,0.7-0.4,1.4-1.1,1.8c-6,2.9-35.3,17.7-62.4,40c-4.9,4-7.7,10.1-7.7,16.4v30.1h101v-35.3
c0-12.9,5.7-25,15.6-33.2c8.5-7,17.2-13.4,25.5-19.1C142.1,291.9,142,291.7,142,291.4z" />
<path opacity="0.5" d="M360.5,325.1c-31.9-26.2-66.3-43.6-73.4-47.1c-0.8-0.4-1.3-1.2-1.3-2.1v-49.7c6.2-4.2,10.4-11.3,10.4-19.3v-51.6
c0-25.6-20.8-46.4-46.4-46.4h-5.5h-5.5c-25.6,0-46.4,20.8-46.4,46.4v51.5c0,8.1,4.1,15.2,10.4,19.3v49.7c0,0.9-0.5,1.7-1.3,2.1
c-7,3.4-41.4,20.8-73.4,47.1c-5.8,4.7-9.1,11.8-9.1,19.3v35.3h108.9l10.8-49.3c-21.7-30.3,1.6-31.8,5.7-31.8l0,0l0,0
c4.1,0,27.4,1.5,5.7,31.8l10.8,49.3h108.9v-35.3C369.6,336.9,366.3,329.8,360.5,325.1z" />
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="3em" height="2.5em" viewBox="0 0 24 24" style="stroke: #a9a8ad;">
<path opacity="0.5" d="M15.9998 2L14.9998 2C12.1714 2 10.7576 2.00023 9.87891 2.87891C9.00023 3.75759 9.00023 5.1718 9.00023 8.00023L9.00023 16.0002C9.00023 18.8287 9.00023 20.2429 9.87891 21.1215C10.7574 22 12.1706 22 14.9976 22L14.9998 22L15.9998 22C18.8282 22 20.2424 22 21.1211 21.1213C21.9998 20.2426 21.9998 18.8284 21.9998 16L21.9998 8L21.9998 7.99998C21.9998 5.17157 21.9998 3.75736 21.1211 2.87868C20.2424 2 18.8282 2 15.9998 2Z" fill="#1C274C"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.25098 11.999C1.25098 11.5848 1.58676 11.249 2.00098 11.249L13.9735 11.249L12.0129 9.56845C11.6984 9.29889 11.662 8.82541 11.9315 8.51092C12.2011 8.19642 12.6746 8.16 12.9891 8.42957L16.4891 11.4296C16.6553 11.5721 16.751 11.7801 16.751 11.999C16.751 12.218 16.6553 12.426 16.4891 12.5685L12.9891 15.5685C12.6746 15.838 12.2011 15.8016 11.9315 15.4871C11.662 15.1726 11.6984 14.6991 12.0129 14.4296L13.9735 12.749L2.00098 12.749C1.58676 12.749 1.25098 12.4132 1.25098 11.999Z" fill="#1C274C"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,19 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
<symbol id="check2" viewBox="0 0 16 16">
<path
d="M13.854 3.646a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6.5 10.293l6.646-6.647a.5.5 0 0 1 .708 0z" />
</symbol>
<symbol id="circle-half" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 0 8 1v14zm0 1A8 8 0 1 1 8 0a8 8 0 0 1 0 16z" />
</symbol>
<symbol id="moon-stars-fill" viewBox="0 0 16 16">
<path
d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z" />
<path
d="M10.794 3.148a.217.217 0 0 1 .412 0l.387 1.162c.173.518.579.924 1.097 1.097l1.162.387a.217.217 0 0 1 0 .412l-1.162.387a1.734 1.734 0 0 0-1.097 1.097l-.387 1.162a.217.217 0 0 1-.412 0l-.387-1.162A1.734 1.734 0 0 0 9.31 6.593l-1.162-.387a.217.217 0 0 1 0-.412l1.162-.387a1.734 1.734 0 0 0 1.097-1.097l.387-1.162zM13.863.099a.145.145 0 0 1 .274 0l.258.774c.115.346.386.617.732.732l.774.258a.145.145 0 0 1 0 .274l-.774.258a1.156 1.156 0 0 0-.732.732l-.258.774a.145.145 0 0 1-.274 0l-.258-.774a1.156 1.156 0 0 0-.732-.732l-.774-.258a.145.145 0 0 1 0-.274l.774-.258c.346-.115.617-.386.732-.732L13.863.1z" />
</symbol>
<symbol id="sun-fill" viewBox="0 0 16 16">
<path
d="M8 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z" />
</symbol>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -1,19 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
<symbol id="check2" viewBox="0 0 16 16">
<path
d="M13.854 3.646a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6.5 10.293l6.646-6.647a.5.5 0 0 1 .708 0z" />
</symbol>
<symbol id="circle-half" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 0 8 1v14zm0 1A8 8 0 1 1 8 0a8 8 0 0 1 0 16z" />
</symbol>
<symbol id="moon-stars-fill" viewBox="0 0 16 16">
<path
d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z" />
<path
d="M10.794 3.148a.217.217 0 0 1 .412 0l.387 1.162c.173.518.579.924 1.097 1.097l1.162.387a.217.217 0 0 1 0 .412l-1.162.387a1.734 1.734 0 0 0-1.097 1.097l-.387 1.162a.217.217 0 0 1-.412 0l-.387-1.162A1.734 1.734 0 0 0 9.31 6.593l-1.162-.387a.217.217 0 0 1 0-.412l1.162-.387a1.734 1.734 0 0 0 1.097-1.097l.387-1.162zM13.863.099a.145.145 0 0 1 .274 0l.258.774c.115.346.386.617.732.732l.774.258a.145.145 0 0 1 0 .274l-.774.258a1.156 1.156 0 0 0-.732.732l-.258.774a.145.145 0 0 1-.274 0l-.258-.774a1.156 1.156 0 0 0-.732-.732l-.774-.258a.145.145 0 0 1 0-.274l.774-.258c.346-.115.617-.386.732-.732L13.863.1z" />
</symbol>
<symbol id="sun-fill" viewBox="0 0 16 16">
<path
d="M8 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z" />
</symbol>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,5 +0,0 @@
<svg width="em" height="2em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16 6C16 8.20914 14.2091 10 12 10C9.79086 10 8 8.20914 8 6C8 3.79086 9.79086 2 12 2C14.2091 2 16 3.79086 16 6Z" fill="#1C274C"/>
<path opacity="0.5" d="M14.4774 21.9208C13.7513 21.9728 12.9296 22 12 22C4 22 4 19.9853 4 17.5C4 15.0147 7.58172 13 12 13C14.8806 13 17.4056 13.8564 18.8142 15.1412C18.298 15 17.5737 15 16.5 15C14.8501 15 14.0251 15 13.5126 15.5126C13 16.0251 13 16.8501 13 18.5C13 20.1499 13 20.9749 13.5126 21.4874C13.7501 21.725 14.0547 21.8524 14.4774 21.9208Z" fill="#1C274C"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.5 22C14.8501 22 14.0251 22 13.5126 21.4874C13 20.9749 13 20.1499 13 18.5C13 16.8501 13 16.0251 13.5126 15.5126C14.0251 15 14.8501 15 16.5 15C18.1499 15 18.9749 15 19.4874 15.5126C20 16.0251 20 16.8501 20 18.5C20 20.1499 20 20.9749 19.4874 21.4874C18.9749 22 18.1499 22 16.5 22ZM17.0833 16.9444C17.0833 16.6223 16.8222 16.3611 16.5 16.3611C16.1778 16.3611 15.9167 16.6223 15.9167 16.9444V17.9167H14.9444C14.6223 17.9167 14.3611 18.1778 14.3611 18.5C14.3611 18.8222 14.6223 19.0833 14.9444 19.0833H15.9167V20.0556C15.9167 20.3777 16.1778 20.6389 16.5 20.6389C16.8222 20.6389 17.0833 20.3777 17.0833 20.0556V19.0833H18.0556C18.3777 19.0833 18.6389 18.8222 18.6389 18.5C18.6389 18.1778 18.3777 17.9167 18.0556 17.9167H17.0833V16.9444Z" fill="#1C274C"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1,12 +0,0 @@
<svg class="bi my-1 theme-icon-active" width="3em" height="2em" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg" style="stroke: #a9a8ad;">
<path
d="M16 6C16 8.20914 14.2091 10 12 10C9.79086 10 8 8.20914 8 6C8 3.79086 9.79086 2 12 2C14.2091 2 16 3.79086 16 6Z"
fill="#1C274C" />
<path opacity="0.5"
d="M14.4774 21.9208C13.7513 21.9728 12.9296 22 12 22C4 22 4 19.9853 4 17.5C4 15.0147 7.58172 13 12 13C14.8806 13 17.4056 13.8564 18.8142 15.1412C18.298 15 17.5737 15 16.5 15C14.8501 15 14.0251 15 13.5126 15.5126C13 16.0251 13 16.8501 13 18.5C13 20.1499 13 20.9749 13.5126 21.4874C13.7501 21.725 14.0547 21.8524 14.4774 21.9208Z"
fill="#1C274C" />
<path fill-rule="evenodd" clip-rule="evenodd"
d="M16.5 22C14.8501 22 14.0251 22 13.5126 21.4874C13 20.9749 13 20.1499 13 18.5C13 16.8501 13 16.0251 13.5126 15.5126C14.0251 15 14.8501 15 16.5 15C18.1499 15 18.9749 15 19.4874 15.5126C20 16.0251 20 16.8501 20 18.5C20 20.1499 20 20.9749 19.4874 21.4874C18.9749 22 18.1499 22 16.5 22ZM17.0833 16.9444C17.0833 16.6223 16.8222 16.3611 16.5 16.3611C16.1778 16.3611 15.9167 16.6223 15.9167 16.9444V17.9167H14.9444C14.6223 17.9167 14.3611 18.1778 14.3611 18.5C14.3611 18.8222 14.6223 19.0833 14.9444 19.0833H15.9167V20.0556C15.9167 20.3777 16.1778 20.6389 16.5 20.6389C16.8222 20.6389 17.0833 20.3777 17.0833 20.0556V19.0833H18.0556C18.3777 19.0833 18.6389 18.8222 18.6389 18.5C18.6389 18.1778 18.3777 17.9167 18.0556 17.9167H17.0833V16.9444Z"
fill="#1C274C" />
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,10 +0,0 @@
using DigitalData.Core.Abstractions;
namespace DigitalData.UserManager.Application.DTOs.Module
{
public record ModuleDto(
int Id,
string? Name,
string? ShortName
) : IUnique<int>;
}

View File

@@ -1,4 +0,0 @@
namespace DigitalData.UserManager.Application.DTOs
{
public record SearchRootCreateDto(string? DirEntryUsername, string DirEntryPassword);
}

View File

@@ -1,32 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageId>UserManager.Domain</PackageId>
<Version>3.0.2</Version>
<Authors>Digital Data GmbH</Authors>
<Company>Digital Data GmbH</Company>
<Product>UserManager.Domain</Product>
<Description>This package provides essential tools for managing user information and permissions. It offers comprehensive CRUD operations for user data and includes features for managing user roles and authentication.</Description>
<Copyright>Copyright 2024</Copyright>
<PackageIcon>icon.png</PackageIcon>
<RepositoryUrl>http://git.dd:3000/AppStd/WebUserManager.git</RepositoryUrl>
<PackageTags>digital data domain user maanger</PackageTags>
<AssemblyVersion>3.0.2</AssemblyVersion>
<FileVersion>3.0.2</FileVersion>
</PropertyGroup>
<ItemGroup>
<None Include="..\Assets\icon.png">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.4.0" />
</ItemGroup>
</Project>

View File

@@ -1,31 +0,0 @@
using DigitalData.Core.Abstractions;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DigitalData.UserManager.Domain.Entities
{
public class BaseEntity : IUnique<int>
{
[Column("GUID")]
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[StringLength(50)]
[Column("ADDED_WHO")]
public string? AddedWho { get; set; }
[StringLength(50)]
[Column("CHANGED_WHO")]
public string? ChangedWho { get; set; }
//TODO: assign it to default value in create dto, not here!
[Column("ADDED_WHEN", TypeName = "datetime")]
[DefaultValue("GETDATE()")]
public DateTime AddedWhen { get; set; } = DateTime.Now;
[Column("CHANGED_WHEN", TypeName = "datetime")]
public DateTime? ChangedWhen { get; set; }
}
}

View File

@@ -1,77 +0,0 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DigitalData.UserManager.Domain.Entities
{
[Table("TBDD_USER", Schema = "dbo")]
public class User : BaseEntity
{
[Column("PRENAME")]
[StringLength(50)]
public string? Prename { get; set; }
[Column("NAME")]
[StringLength(50)]
public string? Name { get; set; }
[Required]
[Column("USERNAME")]
[StringLength(50)]
public string Username { get; set; }
[Column("SHORTNAME")]
[StringLength(30)]
public string? Shortname { get; set; }
[Column("EMAIL")]
[StringLength(100)]
public string? Email { get; set; }
[Required]
[Column("LANGUAGE")]
[StringLength(5)]
[DefaultValue("de-DE")]
public string Language { get; set; }
[Column("COMMENT")]
[StringLength(500)]
public string? Comment { get; set; }
[Column("DELETED")]
public bool Deleted { get; set; }
[Required]
[Column("DATE_FORMAT")]
[StringLength(10)]
[DefaultValue("dd.MM.yyyy")]
public string DateFormat { get; set; }
[Required]
[Column("ACTIVE")]
public bool Active { get; set; }
#region IGNORED COLUMNS
//[Required]
//[Column("GENERAL_VIEWER")]
//[StringLength(30)]
//[DefaultValue("NONE")]
//public string GeneralViewer { get; set; }
//[Required]
//[Column("WAN_ENVIRONMENT")]
//public bool WanEnvironment { get; set; }
//[Required]
//[Column("USERID_FK_INT_ECM")]
//public int UseridFkIntEcm { get; set; }
//[Column("DELETED_WHEN")]
//public DateTime? DeletedWhen { get; set; }
//[Column("DELETED_WHO")]
//[StringLength(50)]
//public string? DeletedWho { get; set; }
#endregion
}
}

View File

@@ -3,15 +3,15 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.5.33516.290 VisualStudioVersion = 17.5.33516.290
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.UserManager.Domain", "DigitalData.UserManager.Domain\DigitalData.UserManager.Domain.csproj", "{BC8CEADC-F7D6-4469-8718-4B308C386B4D}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.UserManager.Domain", "src\DigitalData.UserManager.Domain\DigitalData.UserManager.Domain.csproj", "{BC8CEADC-F7D6-4469-8718-4B308C386B4D}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.UserManager.Application", "DigitalData.UserManager.Application\DigitalData.UserManager.Application.csproj", "{0634853C-C515-48AF-8E27-E5CBF592BCE7}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.UserManager.Application", "src\DigitalData.UserManager.Application\DigitalData.UserManager.Application.csproj", "{0634853C-C515-48AF-8E27-E5CBF592BCE7}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.UserManager.Infrastructure", "DigitalData.UserManager.Infrastructure\DigitalData.UserManager.Infrastructure.csproj", "{1DD81373-82F9-4872-95C6-888624DB1797}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.UserManager.Infrastructure", "src\DigitalData.UserManager.Infrastructure\DigitalData.UserManager.Infrastructure.csproj", "{1DD81373-82F9-4872-95C6-888624DB1797}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.UserManager.API", "DigitalData.UserManager.API\DigitalData.UserManager.API.csproj", "{07CCD651-647C-49F7-9715-30CEBC13710D}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.UserManager.API", "src\DigitalData.UserManager.API\DigitalData.UserManager.API.csproj", "{07CCD651-647C-49F7-9715-30CEBC13710D}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DigitalData.UserManager.DependencyInjection", "DigitalData.UserManager.DependencyInjection\DigitalData.UserManager.DependencyInjection.csproj", "{7E5FD115-EE6D-48F2-ACF1-E951EC071073}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DigitalData.UserManager.DependencyInjection", "src\DigitalData.UserManager.DependencyInjection\DigitalData.UserManager.DependencyInjection.csproj", "{7E5FD115-EE6D-48F2-ACF1-E951EC071073}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}"
EndProject EndProject
@@ -20,6 +20,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Assets", "Assets", "{02EA68
Assets\icon.png = Assets\icon.png Assets\icon.png = Assets\icon.png
EndProjectSection EndProjectSection
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{09BFD507-2536-4915-BECA-6E6C217C8E67}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -42,8 +44,8 @@ Global
{07CCD651-647C-49F7-9715-30CEBC13710D}.Debug|Any CPU.Build.0 = Debug|Any CPU {07CCD651-647C-49F7-9715-30CEBC13710D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{07CCD651-647C-49F7-9715-30CEBC13710D}.Release|Any CPU.ActiveCfg = Release|Any CPU {07CCD651-647C-49F7-9715-30CEBC13710D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{07CCD651-647C-49F7-9715-30CEBC13710D}.Release|Any CPU.Build.0 = Release|Any CPU {07CCD651-647C-49F7-9715-30CEBC13710D}.Release|Any CPU.Build.0 = Release|Any CPU
{7E5FD115-EE6D-48F2-ACF1-E951EC071073}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7E5FD115-EE6D-48F2-ACF1-E951EC071073}.Debug|Any CPU.ActiveCfg = Release|Any CPU
{7E5FD115-EE6D-48F2-ACF1-E951EC071073}.Debug|Any CPU.Build.0 = Debug|Any CPU {7E5FD115-EE6D-48F2-ACF1-E951EC071073}.Debug|Any CPU.Build.0 = Release|Any CPU
{7E5FD115-EE6D-48F2-ACF1-E951EC071073}.Release|Any CPU.ActiveCfg = Release|Any CPU {7E5FD115-EE6D-48F2-ACF1-E951EC071073}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7E5FD115-EE6D-48F2-ACF1-E951EC071073}.Release|Any CPU.Build.0 = Release|Any CPU {7E5FD115-EE6D-48F2-ACF1-E951EC071073}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
@@ -51,6 +53,11 @@ Global
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{BC8CEADC-F7D6-4469-8718-4B308C386B4D} = {09BFD507-2536-4915-BECA-6E6C217C8E67}
{0634853C-C515-48AF-8E27-E5CBF592BCE7} = {09BFD507-2536-4915-BECA-6E6C217C8E67}
{1DD81373-82F9-4872-95C6-888624DB1797} = {09BFD507-2536-4915-BECA-6E6C217C8E67}
{07CCD651-647C-49F7-9715-30CEBC13710D} = {09BFD507-2536-4915-BECA-6E6C217C8E67}
{7E5FD115-EE6D-48F2-ACF1-E951EC071073} = {09BFD507-2536-4915-BECA-6E6C217C8E67}
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {8EC462FD-D22E-90A8-E5CE-7E832BA40C5D} {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution

View File

@@ -1,9 +1,11 @@
{ {
"name": "user-manager-ui", "name": "user-manager-ui",
"version": "4.0.0", "version": "2.0.0",
"minApiVersion":"6.1.3",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"start": "ng serve --ssl -o", "start:ssl": "ng serve --ssl -o",
"start": "ng serve -o",
"build": "ng build --configuration production", "build": "ng build --configuration production",
"watch": "ng build --watch --configuration development", "watch": "ng build --watch --configuration development",
"test": "ng test", "test": "ng test",
@@ -30,9 +32,12 @@
"bootstrap": "^5.3.3", "bootstrap": "^5.3.3",
"bootstrap-icons": "^1.11.3", "bootstrap-icons": "^1.11.3",
"express": "^4.18.2", "express": "^4.18.2",
"moment": "^2.30.1",
"ng2-pdf-viewer": "^10.4.0",
"rxjs": "~7.8.0", "rxjs": "~7.8.0",
"sweetalert2": "^11.12.3", "sweetalert2": "^11.12.3",
"tslib": "^2.3.0", "tslib": "^2.3.0",
"uuid": "^11.1.0",
"zone.js": "~0.14.3" "zone.js": "~0.14.3"
}, },
"devDependencies": { "devDependencies": {

File diff suppressed because it is too large Load Diff

View File

@@ -3,5 +3,10 @@
"target": "https://localhost:7103", "target": "https://localhost:7103",
"secure": false, "secure": false,
"changeOrigin": true "changeOrigin": true
},
"/docs": {
"target": "https://localhost:7103",
"secure": false,
"changeOrigin": true
} }
} }

View File

@@ -1,4 +1,5 @@
<app-nav-menu></app-nav-menu> <app-nav-menu></app-nav-menu>
<main class="container-fluid"> <main class="container-fluid">
<router-outlet></router-outlet> <router-outlet></router-outlet>
</main> </main>
<app-footer></app-footer>

View File

@@ -1,17 +1,19 @@
import { Component, HostListener, inject } from '@angular/core'; import { ChangeDetectionStrategy, Component, HostListener, inject } from '@angular/core';
import { RouterOutlet } from '@angular/router'; import { RouterOutlet } from '@angular/router';
import {NavMenuComponent} from './components/nav-menu/nav-menu.component' import { NavMenuComponent } from './components/nav-menu/nav-menu.component'
import { TransferService } from './services/button/transfer.service'; import { TransferService } from './services/button/transfer.service';
import { UpdateService } from './services/button/update.service'; import { UpdateService } from './services/button/update.service';
import { RefreshService } from './services/button/refresh.service'; import { RefreshService } from './services/button/refresh.service';
import { DeletionService } from './services/button/deletion.service'; import { DeletionService } from './services/button/deletion.service';
import { FooterComponent } from './components/footer/footer.component';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
standalone: true, standalone: true,
imports: [RouterOutlet, NavMenuComponent], imports: [RouterOutlet, NavMenuComponent, FooterComponent],
templateUrl: './app.component.html', templateUrl: './app.component.html',
styleUrl: './app.component.scss' styleUrl: './app.component.scss',
changeDetection: ChangeDetectionStrategy.Default
}) })
export class AppComponent { export class AppComponent {
title = 'app'; title = 'app';

View File

@@ -6,6 +6,7 @@ import { GroupComponent } from './pages/group/group.component';
import { ModuleComponent } from './pages/module/module.component'; import { ModuleComponent } from './pages/module/module.component';
import { UserAssignmentComponent } from './pages/user-assignment/user-assignment.component'; import { UserAssignmentComponent } from './pages/user-assignment/user-assignment.component';
import { UserRepresentationComponent } from './pages/user-representation/user-representation.component'; import { UserRepresentationComponent } from './pages/user-representation/user-representation.component';
import { PrivacyPolicyComponent } from './pages/privacy-policy/privacy-policy.component';
export const routes: Routes = [ export const routes: Routes = [
{ path: '', component: HomeComponent }, { path: '', component: HomeComponent },
@@ -13,5 +14,6 @@ export const routes: Routes = [
{ path: 'group-table', component: GroupComponent, canActivate: [AuthGuard] }, { path: 'group-table', component: GroupComponent, canActivate: [AuthGuard] },
{ path: 'module-table', component: ModuleComponent, canActivate: [AuthGuard] }, { path: 'module-table', component: ModuleComponent, canActivate: [AuthGuard] },
{ path: 'user-assignment', component: UserAssignmentComponent, canActivate: [AuthGuard] }, { path: 'user-assignment', component: UserAssignmentComponent, canActivate: [AuthGuard] },
{ path: 'user-representation', component: UserRepresentationComponent, canActivate: [AuthGuard] } { path: 'user-representation', component: UserRepresentationComponent, canActivate: [AuthGuard] },
{ path: 'privacy-policy', component: PrivacyPolicyComponent }
]; ];

View File

@@ -6,7 +6,7 @@ import { RouterModule } from '@angular/router';
@Component({ @Component({
selector: 'tab-card', selector: 'tab-card',
standalone: true, standalone: true,
imports: [CommonModule, CardComponent, RouterModule], imports: [CommonModule, RouterModule],
templateUrl: './tab-card.component.html', templateUrl: './tab-card.component.html',
styleUrl: './tab-card.component.css' styleUrl: './tab-card.component.css'
}) })

View File

@@ -0,0 +1,10 @@
<footer>
<mat-toolbar color="mat-h3" class="footer-toolbar">
<a class="mat-h3 footer-brand-link" [routerLink]="['/']">&copy; 2025 Digital Data</a>
<div class="footer-links">
<a mat-button class="mat-body-strong" [routerLink]="['/privacy-policy']">Datenschutz</a>
<a mat-button class="mat-body-strong" href="https://digitaldata.works/#kontakt" target="_blank">Kontakt</a>
<span mat-button class="mat-body-strong">{{appVersion}}</span>
</div>
</mat-toolbar>
</footer>

View File

@@ -0,0 +1,23 @@
.footer-toolbar {
position: fixed;
bottom: 0;
width: 100%;
height: 2.2rem;
z-index: 1000;
align-items: center;
}
.footer-links{
display: flex;
padding: 0;
margin: 0;
justify-content: space-around;
width: 100%;
}
footer a {
padding: 0;
margin: 0;
text-decoration: none;
color: rgb(255, 255, 255);
}

View File

@@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FooterComponent } from './footer.component';
describe('FooterComponent', () => {
let component: FooterComponent;
let fixture: ComponentFixture<FooterComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [FooterComponent]
})
.compileComponents();
fixture = TestBed.createComponent(FooterComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,17 @@
import { Component } from '@angular/core';
import { MatToolbarModule } from '@angular/material/toolbar';
import { RouterModule } from '@angular/router';
import { name, version, minApiVersion } from '../../../../package.json';
@Component({
selector: 'app-footer',
standalone: true,
imports: [
MatToolbarModule, RouterModule
],
templateUrl: './footer.component.html',
styleUrl: './footer.component.scss'
})
export class FooterComponent {
appVersion: string = `${name} v${version} | ${minApiVersion}`;
}

View File

@@ -1,4 +1,4 @@
import { Component, model, signal } from '@angular/core'; import { ChangeDetectionStrategy, Component, model, signal } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormControl, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { FormControl, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { MatFormFieldModule } from '@angular/material/form-field'; import { MatFormFieldModule } from '@angular/material/form-field';
@@ -9,7 +9,6 @@ import { MatButtonModule } from '@angular/material/button';
import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatCheckboxModule } from '@angular/material/checkbox';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { MatTabsModule } from '@angular/material/tabs'; import { MatTabsModule } from '@angular/material/tabs';
import { UserGroupDirImportComponent } from "../../user-group-dir-import/user-group-dir-import.component";
import { UserService } from '../../../services/api/user.service'; import { UserService } from '../../../services/api/user.service';
import { RefreshService } from '../../../services/button/refresh.service'; import { RefreshService } from '../../../services/button/refresh.service';
import { GroupDirImportComponent } from "../../group-dir-import/group-dir-import.component"; import { GroupDirImportComponent } from "../../group-dir-import/group-dir-import.component";
@@ -19,9 +18,10 @@ import Swal from 'sweetalert2';
@Component({ @Component({
selector: 'app-group-form', selector: 'app-group-form',
standalone: true, standalone: true,
imports: [MatFormFieldModule, MatInputModule, FormsModule, ReactiveFormsModule, MatIconModule, MatButtonModule, MatCheckboxModule, CommonModule, MatTabsModule, UserGroupDirImportComponent, GroupDirImportComponent], imports: [MatFormFieldModule, MatInputModule, FormsModule, ReactiveFormsModule, MatIconModule, MatButtonModule, MatCheckboxModule, CommonModule, MatTabsModule, GroupDirImportComponent],
templateUrl: './group-form.component.html', templateUrl: './group-form.component.html',
styleUrl: './group-form.component.scss' styleUrl: './group-form.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class GroupFormComponent { export class GroupFormComponent {
readonly groupname = new FormControl('', [Validators.required]); readonly groupname = new FormControl('', [Validators.required]);
@@ -42,7 +42,7 @@ export class GroupFormComponent {
.subscribe(() => this.updateErrorMessage()); .subscribe(() => this.updateErrorMessage());
} }
updateErrorMessage() { public updateErrorMessage() {
if (this.groupname.hasError('required')) { if (this.groupname.hasError('required')) {
this.errorMessage.set('Wert eingeben'); this.errorMessage.set('Wert eingeben');
} else { } else {

View File

@@ -7,20 +7,20 @@
</mat-form-field> </mat-form-field>
<mat-form-field class="w80p"> <mat-form-field class="w80p">
<mat-label>Gruppe</mat-label> <mat-label>Gruppe</mat-label>
<input matInput [formControl]="name" /> <input matInput [formControl]="name" [readonly] = 'group.internal' />
</mat-form-field> </mat-form-field>
</div> </div>
<!-- comment --> <!-- comment -->
<div class="dd-row input-row"> <div class="dd-row input-row">
<mat-form-field> <mat-form-field>
<mat-label>Kommentar</mat-label> <mat-label>Kommentar</mat-label>
<textarea matInput [formControl]="comment"></textarea> <textarea matInput [formControl]="comment" [readonly] = 'group.internal'></textarea>
</mat-form-field> </mat-form-field>
</div> </div>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<!-- active, internal, async --> <!-- active, internal, async -->
<div class="dd-row input-row"> <div class="dd-row input-row">
<mat-slide-toggle [(ngModel)]="group.active"> <mat-slide-toggle [(ngModel)]="group.active" [disabled]='group.internal'>
Aktiv Aktiv
</mat-slide-toggle> </mat-slide-toggle>
<mat-slide-toggle [(ngModel)]="group.internal" disabled> <mat-slide-toggle [(ngModel)]="group.internal" disabled>
@@ -52,7 +52,7 @@
<mat-divider></mat-divider> <mat-divider></mat-divider>
<!-- save-button, delete-button --> <!-- save-button, delete-button -->
<div class="dd-row button-row"> <div class="dd-row button-row">
<button mat-fab extended (click)="update()"> <button mat-fab extended (click)="update()" [disabled]='group.internal'>
<mat-icon>save</mat-icon> <mat-icon>save</mat-icon>
Speichern Speichern
</button> </button>

View File

@@ -1,5 +1,5 @@
import { Component, inject, signal } from '@angular/core'; import { ChangeDetectionStrategy, Component, inject, signal } from '@angular/core';
import { Group } from '../../../models/user-management.api.models'; import { Group } from '../../../services/api/api-models';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatFormFieldModule } from '@angular/material/form-field'; import { MatFormFieldModule } from '@angular/material/form-field';
@@ -22,7 +22,8 @@ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
standalone: true, standalone: true,
imports: [MatFormFieldModule, MatInputModule, FormsModule, ReactiveFormsModule, MatIconModule, MatButtonModule, CommonModule, MatTabsModule, MatSelectModule, MatDividerModule, MatCheckboxModule, MatSlideToggleModule], imports: [MatFormFieldModule, MatInputModule, FormsModule, ReactiveFormsModule, MatIconModule, MatButtonModule, CommonModule, MatTabsModule, MatSelectModule, MatDividerModule, MatCheckboxModule, MatSlideToggleModule],
templateUrl: './group-update-form.component.html', templateUrl: './group-update-form.component.html',
styleUrl: './group-update-form.component.scss' styleUrl: './group-update-form.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class GroupUpdateFormComponent { export class GroupUpdateFormComponent {
@@ -45,6 +46,7 @@ export class GroupUpdateFormComponent {
errorMessage = signal(''); errorMessage = signal('');
constructor(private uService: GroupService, private rService: RefreshService) { constructor(private uService: GroupService, private rService: RefreshService) {
console.log(this.group);
} }
update() { update() {

View File

@@ -1,9 +1,8 @@
import { Component, inject, ChangeDetectionStrategy, signal, OnInit, computed } from '@angular/core'; import { Component, inject, ChangeDetectionStrategy, signal, OnInit, computed } from '@angular/core';
import { UserRep } from '../../../models/user-management.api.models'; import { UserRep } from '../../../services/api/api-models';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { UserRepService } from '../../../services/api/user-representation.service'; import { UserRepService } from '../../../services/api/user-representation.service';
import { GroupUpdateFormComponent } from '../group-update-form/group-update-form.component'; import { GroupUpdateFormComponent } from '../group-update-form/group-update-form.component';
import { JsonPipe } from '@angular/common';
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { DateAdapter, MAT_DATE_LOCALE, provideNativeDateAdapter } from '@angular/material/core'; import { DateAdapter, MAT_DATE_LOCALE, provideNativeDateAdapter } from '@angular/material/core';
import { MatDatepickerIntl, MatDatepickerModule } from '@angular/material/datepicker'; import { MatDatepickerIntl, MatDatepickerModule } from '@angular/material/datepicker';
@@ -24,7 +23,7 @@ import 'moment/locale/de';
{ provide: MAT_DATE_LOCALE, useValue: 'de-DE' }, { provide: MAT_DATE_LOCALE, useValue: 'de-DE' },
provideMomentDateAdapter() provideMomentDateAdapter()
], ],
imports: [MatFormFieldModule, MatDatepickerModule, FormsModule, ReactiveFormsModule, JsonPipe, MatButtonModule, MatIconModule, MatInputModule, MatSlideToggleModule], imports: [MatFormFieldModule, MatDatepickerModule, FormsModule, ReactiveFormsModule, MatButtonModule, MatIconModule, MatInputModule, MatSlideToggleModule],
templateUrl: './rep-create-form.component.html', templateUrl: './rep-create-form.component.html',
styleUrl: './rep-create-form.component.scss', styleUrl: './rep-create-form.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,

View File

@@ -1,4 +1,4 @@
import { Component, signal } from '@angular/core'; import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormControl, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { FormControl, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { MatFormFieldModule } from '@angular/material/form-field'; import { MatFormFieldModule } from '@angular/material/form-field';
@@ -18,7 +18,8 @@ import Swal from 'sweetalert2';
standalone: true, standalone: true,
imports: [MatFormFieldModule, MatInputModule, FormsModule, ReactiveFormsModule, MatIconModule, MatButtonModule, CommonModule, MatTabsModule, UserGroupDirImportComponent], imports: [MatFormFieldModule, MatInputModule, FormsModule, ReactiveFormsModule, MatIconModule, MatButtonModule, CommonModule, MatTabsModule, UserGroupDirImportComponent],
templateUrl: './user-create-form.component.html', templateUrl: './user-create-form.component.html',
styleUrl: './user-create-form.component.scss' styleUrl: './user-create-form.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class UserCreateFormComponent { export class UserCreateFormComponent {
readonly email = new FormControl('', [Validators.required, Validators.email]); readonly email = new FormControl('', [Validators.required, Validators.email]);

Some files were not shown because too many files have changed in this diff Show More