Merge branch 'main' of https://git.innov.energy/Innovenergy/git_trunk
This commit is contained in:
commit
05dc389eaf
|
@ -2,6 +2,7 @@ using InnovEnergy.App.Backend.Database;
|
||||||
using InnovEnergy.App.Backend.DataTypes;
|
using InnovEnergy.App.Backend.DataTypes;
|
||||||
using InnovEnergy.App.Backend.DataTypes.Methods;
|
using InnovEnergy.App.Backend.DataTypes.Methods;
|
||||||
using InnovEnergy.App.Backend.Relations;
|
using InnovEnergy.App.Backend.Relations;
|
||||||
|
using InnovEnergy.Lib.Utils;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend.Controllers;
|
namespace InnovEnergy.App.Backend.Controllers;
|
||||||
|
@ -113,7 +114,7 @@ public class Controller : ControllerBase
|
||||||
.Ancestors()
|
.Ancestors()
|
||||||
.SelectMany(f => f.UsersWithDirectAccess()
|
.SelectMany(f => f.UsersWithDirectAccess()
|
||||||
.Where(u => u.IsDescendantOf(user))
|
.Where(u => u.IsDescendantOf(user))
|
||||||
.Select(u => new { folderId = f.Id, folderName = f.Name, user = u }))
|
.Select(u => new { folderId = f.Id, folderName = f.Name, user = u.HidePassword() }))
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +152,7 @@ public class Controller : ControllerBase
|
||||||
.Ancestors()
|
.Ancestors()
|
||||||
.SelectMany(f => f.UsersWithDirectAccess()
|
.SelectMany(f => f.UsersWithDirectAccess()
|
||||||
.Where(u => u.IsDescendantOf(user))
|
.Where(u => u.IsDescendantOf(user))
|
||||||
.Select(u => new { folderId = f.Id, folderName = f.Name, user = u }))
|
.Select(u => new { folderId = f.Id, folderName = f.Name, user = u.HidePassword() }))
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,8 +171,8 @@ public class Controller : ControllerBase
|
||||||
return folder;
|
return folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet(nameof(GetAllChildUsers))]
|
[HttpGet(nameof(GetAllDirectChildUsers))]
|
||||||
public ActionResult<IEnumerable<User>> GetAllChildUsers(Token authToken)
|
public ActionResult<IEnumerable<User>> GetAllDirectChildUsers(Token authToken)
|
||||||
{
|
{
|
||||||
var user = Db.GetSession(authToken)?.User;
|
var user = Db.GetSession(authToken)?.User;
|
||||||
if (user == null)
|
if (user == null)
|
||||||
|
@ -180,6 +181,17 @@ public class Controller : ControllerBase
|
||||||
return user.ChildUsers().ToList();
|
return user.ChildUsers().ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet(nameof(GetAllChildUsers))]
|
||||||
|
public ActionResult<IEnumerable<User>> GetAllChildUsers(Token authToken)
|
||||||
|
{
|
||||||
|
var user = Db.GetSession(authToken)?.User;
|
||||||
|
if (user == null)
|
||||||
|
return Unauthorized();
|
||||||
|
|
||||||
|
return user.DescendantUsers().ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[HttpGet(nameof(GetAllInstallations))]
|
[HttpGet(nameof(GetAllInstallations))]
|
||||||
public ActionResult<IEnumerable<Installation>> GetAllInstallations(Token authToken)
|
public ActionResult<IEnumerable<Installation>> GetAllInstallations(Token authToken)
|
||||||
{
|
{
|
||||||
|
@ -188,6 +200,8 @@ public class Controller : ControllerBase
|
||||||
if (user is null)
|
if (user is null)
|
||||||
return Unauthorized();
|
return Unauthorized();
|
||||||
|
|
||||||
|
user.AccessibleInstallations().ForEach(i => i.FillOrderNumbers());
|
||||||
|
|
||||||
return user.AccessibleInstallations().ToList();
|
return user.AccessibleInstallations().ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,8 +332,6 @@ public class Controller : ControllerBase
|
||||||
if (!session.Update(updatedUser))
|
if (!session.Update(updatedUser))
|
||||||
return Unauthorized();
|
return Unauthorized();
|
||||||
|
|
||||||
updatedUser.Password = ""; // TODO: generic sanitize return values
|
|
||||||
|
|
||||||
return updatedUser;
|
return updatedUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
|
using SQLite;
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend.DataTypes;
|
namespace InnovEnergy.App.Backend.DataTypes;
|
||||||
|
|
||||||
public class DeletedFolder : Folder {}
|
public class DeletedFolder : Folder
|
||||||
|
{
|
||||||
|
[PrimaryKey]
|
||||||
|
public override Int64 Id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
//Deleted Things need to have AT LEAST every property that normal things have
|
//Deleted Things need to have AT LEAST every property that normal things have
|
||||||
//Todo "Restore" Function? -k
|
|
|
@ -1,7 +1,10 @@
|
||||||
|
using SQLite;
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend.DataTypes;
|
namespace InnovEnergy.App.Backend.DataTypes;
|
||||||
|
|
||||||
//Deleted Things need to have AT LEAST every property that normal things have
|
//Deleted Things need to have AT LEAST every property that normal things have
|
||||||
public class DeletedInstallation : Installation
|
public class DeletedInstallation : Installation
|
||||||
{
|
{
|
||||||
|
[PrimaryKey]
|
||||||
|
public override Int64 Id { get; set; }
|
||||||
}
|
}
|
|
@ -7,4 +7,7 @@ namespace InnovEnergy.App.Backend.DataTypes;
|
||||||
public class DeletedUser : User
|
public class DeletedUser : User
|
||||||
{
|
{
|
||||||
public override String Name { get; set; } = null!;
|
public override String Name { get; set; } = null!;
|
||||||
|
|
||||||
|
[PrimaryKey]
|
||||||
|
public override Int64 Id { get; set; }
|
||||||
}
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
using SQLite;
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend.DataTypes;
|
namespace InnovEnergy.App.Backend.DataTypes;
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,7 +10,7 @@ public class Installation : TreeNode
|
||||||
public String Country { get; set; } = "";
|
public String Country { get; set; } = "";
|
||||||
|
|
||||||
// TODO: make relation
|
// TODO: make relation
|
||||||
public String OrderNumbers { get; set; } = "";
|
[Ignore] public IReadOnlyList<String> OrderNumbers { get; set; } = Array.Empty<String>();
|
||||||
|
|
||||||
public Double Lat { get; set; }
|
public Double Lat { get; set; }
|
||||||
public Double Long { get; set; }
|
public Double Long { get; set; }
|
||||||
|
@ -16,4 +18,5 @@ public class Installation : TreeNode
|
||||||
public String S3Bucket { get; set; } = "";
|
public String S3Bucket { get; set; } = "";
|
||||||
public String S3Url { get; set; } = "";
|
public String S3Url { get; set; } = "";
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -112,6 +112,19 @@ public static class InstallationMethods
|
||||||
return Db.Installations.Any(i => i.Id == installation.Id);
|
return Db.Installations.Any(i => i.Id == installation.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IReadOnlyList<String> GetOrderNumbers(this Installation installation)
|
||||||
|
{
|
||||||
|
return Db.OrderNumber2Installation
|
||||||
|
.Where(i => i.InstallationId == installation.Id)
|
||||||
|
.Select(i => i.OrderNumber)
|
||||||
|
.ToReadOnlyList<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Installation FillOrderNumbers(this Installation installation)
|
||||||
|
{
|
||||||
|
installation.OrderNumbers = installation.GetOrderNumbers();
|
||||||
|
return installation;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,30 @@ public static class SessionMethods
|
||||||
var user = session?.User;
|
var user = session?.User;
|
||||||
|
|
||||||
var original = Db.GetInstallationById(installation?.Id);
|
var original = Db.GetInstallationById(installation?.Id);
|
||||||
|
var originalOrderNumbers = original!.GetOrderNumbers();
|
||||||
|
|
||||||
|
if (!Equals(originalOrderNumbers, installation?.OrderNumbers))
|
||||||
|
{
|
||||||
|
foreach (var orderNumber in installation!.OrderNumbers)
|
||||||
|
{
|
||||||
|
if (originalOrderNumbers.Contains(orderNumber)) continue;
|
||||||
|
var o2I = new OrderNumber2Installation
|
||||||
|
{
|
||||||
|
OrderNumber = orderNumber,
|
||||||
|
InstallationId = installation.Id
|
||||||
|
};
|
||||||
|
Db.Create(o2I);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var orderNumberOld in originalOrderNumbers)
|
||||||
|
{
|
||||||
|
if (!installation!.OrderNumbers.Contains(orderNumberOld))
|
||||||
|
{
|
||||||
|
Db.OrderNumber2Installation.Delete(i =>
|
||||||
|
i.InstallationId == installation.Id && i.OrderNumber == orderNumberOld);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return user is not null
|
return user is not null
|
||||||
&& installation is not null
|
&& installation is not null
|
||||||
|
@ -118,7 +142,6 @@ public static class SessionMethods
|
||||||
&& user.HasWriteAccess
|
&& user.HasWriteAccess
|
||||||
&& user.HasAccessTo(installation)
|
&& user.HasAccessTo(installation)
|
||||||
&& Db.Create(installation.ToDeletedInstallation())
|
&& Db.Create(installation.ToDeletedInstallation())
|
||||||
// && installation.DeleteBucket().Result // TODO
|
|
||||||
&& Db.Delete(installation);
|
&& Db.Delete(installation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,17 +29,13 @@ public static class UserMethods
|
||||||
.DirectlyAccessibleFolders()
|
.DirectlyAccessibleFolders()
|
||||||
.SelectMany(f => f.DescendantFolders().Prepend(f))
|
.SelectMany(f => f.DescendantFolders().Prepend(f))
|
||||||
.Distinct();
|
.Distinct();
|
||||||
|
|
||||||
// Distinct because the user might have direct access
|
|
||||||
// to a child folder of a folder he has already access to
|
|
||||||
// TODO shouldn't we prevent doubling permissions? -K"
|
|
||||||
// TODO yes we should -ig (still TODO)
|
|
||||||
// however we should still leave the distinct, defensive programming...
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<TreeNode> AccessibleFoldersAndInstallations(this User user)
|
public static IEnumerable<TreeNode> AccessibleFoldersAndInstallations(this User user)
|
||||||
{
|
{
|
||||||
var folders = user.AccessibleFolders() as IEnumerable<TreeNode>;
|
var folders = user.AccessibleFolders() as IEnumerable<TreeNode>;
|
||||||
|
|
||||||
|
user.AccessibleInstallations().ForEach(i => i.FillOrderNumbers());
|
||||||
var installations = user.AccessibleInstallations();
|
var installations = user.AccessibleInstallations();
|
||||||
|
|
||||||
return folders.Concat(installations);
|
return folders.Concat(installations);
|
||||||
|
@ -203,20 +199,4 @@ public static class UserMethods
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO?
|
|
||||||
private static Boolean IsValidEmail(String email)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var emailAddress = new MailAddress(email);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@ namespace InnovEnergy.App.Backend.DataTypes;
|
||||||
public abstract partial class TreeNode
|
public abstract partial class TreeNode
|
||||||
{
|
{
|
||||||
[PrimaryKey, AutoIncrement]
|
[PrimaryKey, AutoIncrement]
|
||||||
public Int64 Id { get; set; }
|
public virtual Int64 Id { get; set; }
|
||||||
public virtual String Name { get; set; } = ""; // overridden by User (unique)
|
public virtual String Name { get; set; } = ""; // overridden by User (unique)
|
||||||
public String Information { get; set; } = ""; // unstructured random info
|
public String Information { get; set; } = ""; // unstructured random info
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,4 @@ public class User : TreeNode
|
||||||
[Unique]
|
[Unique]
|
||||||
public override String Name { get; set; } = null!;
|
public override String Name { get; set; } = null!;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: must reset pwd
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -52,4 +52,9 @@ public static partial class Db
|
||||||
{
|
{
|
||||||
return Connection.Insert(folderAccess) > 0;
|
return Connection.Insert(folderAccess) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Boolean Create(OrderNumber2Installation o2i)
|
||||||
|
{
|
||||||
|
return Connection.Insert(o2i) > 0;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -25,6 +25,7 @@ public static partial class Db
|
||||||
public static TableQuery<DeletedUser> DeletedUsers => Connection.Table<DeletedUser>();
|
public static TableQuery<DeletedUser> DeletedUsers => Connection.Table<DeletedUser>();
|
||||||
public static TableQuery<FolderAccess> FolderAccess => Connection.Table<FolderAccess>();
|
public static TableQuery<FolderAccess> FolderAccess => Connection.Table<FolderAccess>();
|
||||||
public static TableQuery<InstallationAccess> InstallationAccess => Connection.Table<InstallationAccess>();
|
public static TableQuery<InstallationAccess> InstallationAccess => Connection.Table<InstallationAccess>();
|
||||||
|
public static TableQuery<OrderNumber2Installation> OrderNumber2Installation => Connection.Table<OrderNumber2Installation>();
|
||||||
|
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
|
@ -47,6 +48,7 @@ public static partial class Db
|
||||||
Connection.CreateTable<FolderAccess>();
|
Connection.CreateTable<FolderAccess>();
|
||||||
Connection.CreateTable<InstallationAccess>();
|
Connection.CreateTable<InstallationAccess>();
|
||||||
Connection.CreateTable<Session>();
|
Connection.CreateTable<Session>();
|
||||||
|
Connection.CreateTable<OrderNumber2Installation>();
|
||||||
});
|
});
|
||||||
|
|
||||||
Observable.Interval(TimeSpan.FromDays(0.5))
|
Observable.Interval(TimeSpan.FromDays(0.5))
|
||||||
|
@ -98,4 +100,5 @@ public static partial class Db
|
||||||
.Select(i => i.RenewS3BucketUrl())
|
.Select(i => i.RenewS3BucketUrl())
|
||||||
.WhenAll();
|
.WhenAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -18,12 +18,12 @@ public static partial class Db
|
||||||
public static Installation? GetInstallationById(Int64? id)
|
public static Installation? GetInstallationById(Int64? id)
|
||||||
{
|
{
|
||||||
return Installations
|
return Installations
|
||||||
.FirstOrDefault(i => i.Id == id);
|
.FirstOrDefault(i => i.Id == id)
|
||||||
|
.FillOrderNumbers();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static User? GetUserById(Int64? id)
|
public static User? GetUserById(Int64? id)
|
||||||
{
|
{
|
||||||
//TODO Sanitize Password here
|
|
||||||
return Users
|
return Users
|
||||||
.FirstOrDefault(u => u.Id == id)
|
.FirstOrDefault(u => u.Id == id)
|
||||||
.HidePassword();
|
.HidePassword();
|
||||||
|
@ -31,7 +31,6 @@ public static partial class Db
|
||||||
|
|
||||||
public static User? GetUserByName(String userName)
|
public static User? GetUserByName(String userName)
|
||||||
{
|
{
|
||||||
//TODO Sanitize Password here
|
|
||||||
return Users
|
return Users
|
||||||
.FirstOrDefault(u => u.Name == userName)
|
.FirstOrDefault(u => u.Name == userName)
|
||||||
.HidePassword();
|
.HidePassword();
|
||||||
|
@ -39,7 +38,6 @@ public static partial class Db
|
||||||
|
|
||||||
public static User? GetUserWithPasswordByName(String userName)
|
public static User? GetUserWithPasswordByName(String userName)
|
||||||
{
|
{
|
||||||
//TODO Sanitize Password here
|
|
||||||
return Users
|
return Users
|
||||||
.FirstOrDefault(u => u.Name == userName);
|
.FirstOrDefault(u => u.Name == userName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,34 @@
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using InnovEnergy.App.Backend.DataTypes;
|
using InnovEnergy.App.Backend.DataTypes;
|
||||||
using MailKit.Net.Smtp;
|
using MailKit.Net.Smtp;
|
||||||
using MimeKit;
|
using MimeKit;
|
||||||
|
using JsonSerializer = System.Text.Json.JsonSerializer;
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend.Mailer;
|
namespace InnovEnergy.App.Backend.Mailer;
|
||||||
public static class Mailer
|
public static class Mailer
|
||||||
{
|
{
|
||||||
|
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
|
||||||
public static Boolean SendVerificationMessage (User emailRecipientUser)
|
public static Boolean SendVerificationMessage (User emailRecipientUser)
|
||||||
{
|
{
|
||||||
|
var config = JsonSerializer.Deserialize<SmptConfig>(File.OpenRead("./Resources/smtpConfig.json"))!;
|
||||||
var email = new MimeMessage();
|
var email = new MimeMessage();
|
||||||
|
|
||||||
email.From.Add(new MailboxAddress("InnovEnergy", "noreply@innov.energy"));
|
email.From.Add(new MailboxAddress("InnovEnergy", "noreply@innov.energy"));
|
||||||
email.To.Add(new MailboxAddress(emailRecipientUser.Name, "fern95@ethereal.email"));
|
email.To.Add(new MailboxAddress(emailRecipientUser.Name, emailRecipientUser.Email));
|
||||||
|
|
||||||
email.Subject = "Create a new password for your Innovenergy-Account";
|
email.Subject = "Create a new password for your Innovenergy-Account";
|
||||||
email.Body = new TextPart(MimeKit.Text.TextFormat.Plain) {
|
email.Body = new TextPart(MimeKit.Text.TextFormat.Plain) {
|
||||||
Text = "Dear " + emailRecipientUser.Name + "\n Please create a new password for your Innovenergy-account." +
|
Text = "Dear " + emailRecipientUser.Name + "\n Please create a new password for your Innovenergy-account." +
|
||||||
"\n To do this just login at https://HEEEEELP"
|
"\n To do this just login at https://HEEEEELP"
|
||||||
};
|
};
|
||||||
using (var smtp = new SmtpClient())
|
|
||||||
{
|
|
||||||
smtp.Connect("smtp.ethereal.email", 587, false);
|
|
||||||
|
|
||||||
// Todo put me into urlAndKey.json
|
using var smtp = new SmtpClient();
|
||||||
smtp.Authenticate("fern95@ethereal.email", "dYKVnc4RQNEFckHaNV");
|
smtp.Connect(config.Url, config.Port, false);
|
||||||
|
|
||||||
|
smtp.Authenticate(config.Username, config.Password);
|
||||||
|
|
||||||
smtp.Send(email);
|
smtp.Send(email);
|
||||||
smtp.Disconnect(true);
|
smtp.Disconnect(true);
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace InnovEnergy.App.Backend.Mailer;
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
||||||
|
public class SmptConfig
|
||||||
|
{
|
||||||
|
public String Url { get; init; } = null!;
|
||||||
|
public String Username { get; init; } = null!;
|
||||||
|
public String Password { get; init; } = null!;
|
||||||
|
public Int32 Port { get; init; } = 587;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
using SQLite;
|
||||||
|
|
||||||
|
namespace InnovEnergy.App.Backend.Relations;
|
||||||
|
|
||||||
|
public class OrderNumber2Installation : Relation<String, Int64>
|
||||||
|
{
|
||||||
|
[Indexed] public String OrderNumber { get => Left ; set => Left = value;}
|
||||||
|
[Indexed] public Int64 InstallationId { get => Right; set => Right = value;}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"Url": "smtp.ethereal.email",
|
||||||
|
"Port": 587,
|
||||||
|
"Username": "fern95@ethereal.email",
|
||||||
|
"Password": "dYKVnc4RQNEFckHaNV"
|
||||||
|
}
|
|
@ -1,19 +1,12 @@
|
||||||
using System.Text.Json;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using static System.IO.File;
|
using static System.IO.File;
|
||||||
using static System.Text.Json.JsonSerializer;
|
using static System.Text.Json.JsonSerializer;
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend.S3;
|
namespace InnovEnergy.App.Backend.S3;
|
||||||
|
|
||||||
|
[SuppressMessage("Trimming", "IL2026:Members annotated with \'RequiresUnreferencedCodeAttribute\' require dynamic access otherwise can break functionality when trimming application code")]
|
||||||
public static class S3Access
|
public static class S3Access
|
||||||
{
|
{
|
||||||
// TODO: put these into Json files in /Resources and read them from
|
|
||||||
// there so they can be changed without recompiling
|
|
||||||
// they should be read from disk on each use,
|
|
||||||
// so the backend does not need to be restarted on change
|
|
||||||
|
|
||||||
|
|
||||||
public static S3Cmd ReadOnly => Deserialize<S3Cmd>(OpenRead("./Resources/s3ReadOnlyKey.json"))!;
|
public static S3Cmd ReadOnly => Deserialize<S3Cmd>(OpenRead("./Resources/s3ReadOnlyKey.json"))!;
|
||||||
|
|
||||||
|
|
||||||
public static S3Cmd ReadWrite => Deserialize<S3Cmd>(OpenRead("./Resources/s3ReadWriteKey.json"))!;
|
public static S3Cmd ReadWrite => Deserialize<S3Cmd>(OpenRead("./Resources/s3ReadWriteKey.json"))!;
|
||||||
}
|
}
|
Binary file not shown.
|
@ -34,6 +34,7 @@
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=resultset/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=resultset/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Salimax/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Salimax/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=signurl/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=signurl/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Smpt/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Trumpf/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Trumpf/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=ttyusb/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=ttyusb/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=tupled/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=tupled/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|
Loading…
Reference in New Issue