@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)
{
Import
}
@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);
}
}