@using System.IO @using System.Reflection @using log4net @using Newtonsoft.Json.Linq @using Rms.Service.Bootstrap.Security @inject IPasswordManager _passwordManager @* * dbMango * * Copyright 2025 Deutsche Bank AG * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *@
@if (AllowImport) { } @if (ChildContent != null) { @ChildContent }
@code { private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod()!.DeclaringType!); public class NameValuePair { public string Id { get; } = Guid.NewGuid().ToString("N"); public string Name { get; set; } = string.Empty; public string Value { get; set; } = string.Empty; } [CascadingParameter] public IModalService Modal { get; set; } = null!; [Parameter] public List Value { get; set; } = []; [Parameter] public RenderFragment? ChildContent { get; set; } [Parameter] public bool AllowImport { get; set; } [Parameter] public bool Multiline { get; set; } [Parameter] public bool EnableEncryption { get; set; } = true; [Parameter] public bool EncryptAsFile { get; set; } [Parameter] public bool ShowLabel { get; set; } = true; [Parameter] public bool ImportSeparateValues { get; set; } [Parameter] public List PossibleNames { get; set; } = []; [Parameter] public Func GetDefaultValue { get; set; } = _ => string.Empty; private static int CalculateSize(string value) => Math.Max(value.Split('\n').Length, value.Split('\r').Length); #pragma warning disable 1998 private async Task SetValue(ChangeEventArgs e, NameValuePair data) { var val = e.Value?.ToString(); if (string.IsNullOrWhiteSpace(val)) return; var dataRef = Value.First(x => x.Id == data.Id); dataRef.Value = val; data.Value = val; StateHasChanged(); } private Task SetName(ChangeEventArgs e, NameValuePair data) => SetName(data, e.Value?.ToString()); private Task SetName(NameValuePair data, string? newName) { if ( string.IsNullOrWhiteSpace(newName)) return Task.CompletedTask; var dataRef = Value.First(x => x.Id == data.Id); dataRef.Name = newName; data.Name = newName; var v = GetDefaultValue(newName); dataRef.Value = v; data.Value = v; StateHasChanged(); return Task.CompletedTask; } private void AddNewKeyValue() { Value.Add(new () { Name = string.Empty, Value = string.Empty }); StateHasChanged(); } private Task Delete(NameValuePair data) { Value.Remove(data); return InvokeAsync(StateHasChanged); } #pragma warning restore 1998 private async void OnInputFileChange(InputFileChangeEventArgs e) { try { using var reader = new StreamReader(e.File.OpenReadStream()); var text = await reader.ReadToEndAsync(); if (ImportSeparateValues) { if (text.TrimStart().StartsWith("{")) // json ImportJson(text); else // try name=value ImportText(text); } else ImportAsWhole(e, text); StateHasChanged(); } catch (Exception ex) { _log.Error(ex.Message, ex); } } private void ImportAsWhole(InputFileChangeEventArgs e, string text) { Value.Add(new () { Name = e.File.Name, Value = text }); } private void ImportText(string text) { foreach (var s in text.Replace("\r","").Split("\n", StringSplitOptions.RemoveEmptyEntries)) { var pos = s.IndexOf('='); if (s.StartsWith('#') || pos > 0) continue; var name = s[..pos]; var val = s[(pos+1)..]; Value.Add(new () { Name = name, Value = val }); } } private void ImportJson(string text) { var o = JObject.Parse(text); foreach (var element in o.Properties()) { var name = element.Name; var val = element.Value.ToString(); Value.Add(new () { Name = name, Value = val }); } } private bool IsUpDisabled(NameValuePair data) { var index = GetIndex(data); return index <= 0; } private int GetIndex(NameValuePair data) { var index = Value.IndexOf(data); if (index < 0) { var dataRef = Value.FirstOrDefault(x => x.Name == data.Name); if ( dataRef == null) return -1; // not found index = Value.IndexOf(dataRef); } return index; } private Task Up(NameValuePair data) { var index = GetIndex(data); if (index <= 0) return Task.CompletedTask; var dataRef = Value[index]; Value.RemoveAt(index); Value.Insert(index - 1, dataRef); return InvokeAsync(StateHasChanged); } private bool IsDownDisabled(NameValuePair data) { var index = GetIndex(data); return index >= Value.Count - 1; } private Task Down(NameValuePair data) { var index = GetIndex(data); if (index >= Value.Count - 1) return Task.CompletedTask; var dataRef = Value[index]; Value.RemoveAt(index); Value.Insert(index + 1, dataRef); return InvokeAsync(StateHasChanged); } private bool IsEncryptDisabled(NameValuePair data) => !EnableEncryption || (!EncryptAsFile && data.Value?.StartsWith('*') == true); private async Task Encrypt(NameValuePair data) { var index = GetIndex(data); if (index < 0 ) return; var dataRef = Value[index]; var res = await ModalDialogUtils.ShowConfirmationDialog(Modal, "Encrypt", $"Do you really want to encrypt entry \"{dataRef.Name}\"?
Note that this operation is irreversible!"); if ( res?.Cancelled ?? true ) return; if (EncryptAsFile) { var enc = _passwordManager.EncryptFileContents(dataRef.Value); var dec = _passwordManager.DecryptFileContents(enc); if (dataRef.Value != dec) throw new ApplicationException("Encryption is broken"); dataRef.Value = enc; } else { var enc = _passwordManager.EncryptPassword(dataRef.Value); var dec = _passwordManager.DecryptPassword(enc); if (dataRef.Value != dec) throw new ApplicationException("Encryption is broken"); dataRef.Value = enc; } await InvokeAsync(StateHasChanged); } }