mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-05-06 22:36:27 -04:00
Add PKI tables (#117)
This commit is contained in:
@@ -65,10 +65,10 @@ public class VaultController(IDbContextFactory<AliasServerDbContext> dbContextFa
|
||||
// as starting point.
|
||||
if (vault == null)
|
||||
{
|
||||
return Ok(new Shared.Models.WebApi.Vault(string.Empty, string.Empty, DateTime.MinValue, DateTime.MinValue));
|
||||
return Ok(new Shared.Models.WebApi.Vault(string.Empty, string.Empty, new List<string>(), DateTime.MinValue, DateTime.MinValue));
|
||||
}
|
||||
|
||||
return Ok(new Shared.Models.WebApi.Vault(vault.VaultBlob, vault.Version, vault.CreatedAt, vault.UpdatedAt));
|
||||
return Ok(new Shared.Models.WebApi.Vault(vault.VaultBlob, vault.Version, new List<string>(), vault.CreatedAt, vault.UpdatedAt));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -116,6 +116,51 @@ public class VaultController(IDbContextFactory<AliasServerDbContext> dbContextFa
|
||||
await context.Vaults.AddAsync(newVault);
|
||||
await context.SaveChangesAsync();
|
||||
|
||||
// Update user email claims if email addresses have been supplied.
|
||||
if (model.EmailAddressList.Count > 0)
|
||||
{
|
||||
await UpdateUserEmailClaims(context, user.Id, model.EmailAddressList);
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the user's email claims based on the provided email address list.
|
||||
/// </summary>
|
||||
/// <param name="context">The database context.</param>
|
||||
/// <param name="userId">The ID of the user.</param>
|
||||
/// <param name="newEmailAddresses">The list of new email addresses to claim.</param>
|
||||
/// <returns>A task representing the asynchronous operation.</returns>
|
||||
private async Task UpdateUserEmailClaims(AliasServerDbContext context, string userId, List<string> newEmailAddresses)
|
||||
{
|
||||
// Get all existing user email claims.
|
||||
var existingEmailClaims = await context.UserEmailClaims
|
||||
.Where(x => x.UserId == userId)
|
||||
.Select(x => x.Address)
|
||||
.ToListAsync();
|
||||
|
||||
// Register new email addresses.
|
||||
foreach (var email in newEmailAddresses)
|
||||
{
|
||||
if (!existingEmailClaims.Contains(email))
|
||||
{
|
||||
await context.UserEmailClaims.AddAsync(new UserEmailClaim
|
||||
{
|
||||
UserId = userId,
|
||||
Address = email,
|
||||
AddressLocal = email.Split('@')[0],
|
||||
AddressDomain = email.Split('@')[1],
|
||||
CreatedAt = timeProvider.UtcNow,
|
||||
UpdatedAt = timeProvider.UtcNow,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Do not delete email claims that are not in the new list
|
||||
// as they may be re-used by the user in the future. We don't want
|
||||
// to allow other users to re-use emails used by other users.
|
||||
// Email claims are considered permanent.
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
27
src/AliasVault.Client/Config.cs
Normal file
27
src/AliasVault.Client/Config.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="Config.cs" company="lanedirt">
|
||||
// Copyright (c) lanedirt. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace AliasVault.Client;
|
||||
|
||||
/// <summary>
|
||||
/// Configuration class for the Client project with values loaded from appsettings.json.
|
||||
/// </summary>
|
||||
public class Config
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the admin password hash which is generated by install.sh and will be set
|
||||
/// as the default password for the admin user.
|
||||
/// </summary>
|
||||
public string ApiUrl { get; set; } = "false";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the domains that the AliasVault server is listening for.
|
||||
/// Email addresses that client vault users use will be registered at the server
|
||||
/// to get exclusive access to the email address.
|
||||
/// </summary>
|
||||
public List<string> SmtpAllowedDomains { get; set; } = [];
|
||||
}
|
||||
@@ -16,6 +16,20 @@ var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
||||
builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile($"appsettings.{builder.HostEnvironment.Environment}.json", optional: true, reloadOnChange: true);
|
||||
|
||||
var config = new Config();
|
||||
builder.Configuration.Bind(config);
|
||||
if (string.IsNullOrEmpty(config.ApiUrl))
|
||||
{
|
||||
throw new KeyNotFoundException("ApiUrl is not set in the configuration.");
|
||||
}
|
||||
|
||||
if (config.SmtpAllowedDomains == null || config.SmtpAllowedDomains.Count == 0)
|
||||
{
|
||||
throw new KeyNotFoundException("SmtpAllowedDomains is not set in the configuration.");
|
||||
}
|
||||
|
||||
builder.Services.AddSingleton(config);
|
||||
|
||||
builder.Services.AddLogging(logging =>
|
||||
{
|
||||
if (builder.HostEnvironment.IsDevelopment())
|
||||
|
||||
@@ -27,6 +27,7 @@ public class DbService : IDisposable
|
||||
private readonly IJSRuntime _jsRuntime;
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly DbServiceState _state = new();
|
||||
private readonly Config _config;
|
||||
private SqliteConnection _sqlConnection;
|
||||
private AliasClientDbContext _dbContext;
|
||||
private bool _isSuccessfullyInitialized;
|
||||
@@ -39,11 +40,13 @@ public class DbService : IDisposable
|
||||
/// <param name="authService">AuthService.</param>
|
||||
/// <param name="jsRuntime">IJSRuntime.</param>
|
||||
/// <param name="httpClient">HttpClient.</param>
|
||||
public DbService(AuthService authService, IJSRuntime jsRuntime, HttpClient httpClient)
|
||||
/// <param name="config">Config instance.</param>
|
||||
public DbService(AuthService authService, IJSRuntime jsRuntime, HttpClient httpClient, Config config)
|
||||
{
|
||||
_authService = authService;
|
||||
_jsRuntime = jsRuntime;
|
||||
_httpClient = httpClient;
|
||||
_config = config;
|
||||
|
||||
// Set the initial state of the database service.
|
||||
_state.UpdateState(DbServiceState.DatabaseStatus.Uninitialized);
|
||||
@@ -441,8 +444,18 @@ public class DbService : IDisposable
|
||||
/// <returns>True if save action succeeded.</returns>
|
||||
private async Task<bool> SaveToServerAsync(string encryptedDatabase)
|
||||
{
|
||||
// Send list of email addresses that are used in aliases by this vault so they can be
|
||||
// claimed on the server.
|
||||
var emailAddresses = await _dbContext.Aliases
|
||||
.Where(a => a.Email != null)
|
||||
.Select(a => a.Email)
|
||||
.Where(email => _config.SmtpAllowedDomains.Any(domain => EF.Functions.Like(email, $"%@{domain}")))
|
||||
.Distinct()
|
||||
.Select(email => email!)
|
||||
.ToListAsync();
|
||||
|
||||
var databaseVersion = await GetCurrentDatabaseVersionAsync();
|
||||
var vaultObject = new Vault(encryptedDatabase, databaseVersion, DateTime.Now, DateTime.Now);
|
||||
var vaultObject = new Vault(encryptedDatabase, databaseVersion, emailAddresses, DateTime.Now, DateTime.Now);
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
#!/bin/sh
|
||||
# Set the default API URL for localhost debugging
|
||||
DEFAULT_API_URL="http://localhost:81"
|
||||
DEFAULT_SMTP_ALLOWED_DOMAINS="localmail.tld"
|
||||
|
||||
# Use the provided API_URL environment variable if it exists, otherwise use the default
|
||||
API_URL=${API_URL:-$DEFAULT_API_URL}
|
||||
SMTP_ALLOWED_DOMAINS=${SMTP_ALLOWED_DOMAINS:-$DEFAULT_SMTP_ALLOWED_DOMAINS}
|
||||
|
||||
# Replace the default URL with the actual API URL
|
||||
sed -i "s|http://localhost:5092|${API_URL}|g" /usr/share/nginx/html/appsettings.json
|
||||
# Replace the default SMTP allowed domains with the actual allowed SMTP domains
|
||||
# Note: this is used so the client knows which email addresses should be registered with the AliasVault server
|
||||
# in order to be able to receive emails.
|
||||
sed -i "s|localmail.tld|${SMTP_ALLOWED_DOMAINS}|g" /usr/share/nginx/html/appsettings.json
|
||||
|
||||
# Start the application
|
||||
nginx -g "daemon off;"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{
|
||||
"ApiUrl": "http://localhost:5092"
|
||||
"ApiUrl": "http://localhost:5092",
|
||||
"SmtpAllowedDomains": "localmail.tld"
|
||||
}
|
||||
|
||||
@@ -17,12 +17,14 @@ public class Vault
|
||||
/// </summary>
|
||||
/// <param name="blob">Blob.</param>
|
||||
/// <param name="version">Version of the vault data model (migration).</param>
|
||||
/// <param name="emailAddressList">List of email addresses that are used in the vault and should be registered.</param>
|
||||
/// <param name="createdAt">CreatedAt.</param>
|
||||
/// <param name="updatedAt">UpdatedAt.</param>
|
||||
public Vault(string blob, string version, DateTime createdAt, DateTime updatedAt)
|
||||
public Vault(string blob, string version, List<string> emailAddressList, DateTime createdAt, DateTime updatedAt)
|
||||
{
|
||||
Blob = blob;
|
||||
Version = version;
|
||||
EmailAddressList = emailAddressList;
|
||||
CreatedAt = createdAt;
|
||||
UpdatedAt = updatedAt;
|
||||
}
|
||||
@@ -37,6 +39,11 @@ public class Vault
|
||||
/// </summary>
|
||||
public string Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the list of email addresses that are used in the vault and should be registered on the server.
|
||||
/// </summary>
|
||||
public List<string> EmailAddressList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the date and time of creation.
|
||||
/// </summary>
|
||||
|
||||
@@ -100,6 +100,16 @@ public class AliasServerDbContext : WorkerStatusDbContext
|
||||
/// </summary>
|
||||
public DbSet<EmailAttachment> EmailAttachments { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the UserEmailClaims DbSet.
|
||||
/// </summary>
|
||||
public DbSet<UserEmailClaim> UserEmailClaims { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the UserEncryptionKeys DbSet.
|
||||
/// </summary>
|
||||
public DbSet<UserEncryptionKey> UserEncryptionKeys { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Logs DbSet.
|
||||
/// </summary>
|
||||
@@ -182,6 +192,27 @@ public class AliasServerDbContext : WorkerStatusDbContext
|
||||
.WithMany(c => c.Vaults)
|
||||
.HasForeignKey(l => l.UserId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
// Configure UserEmailClaim - AliasVaultUser relationship
|
||||
modelBuilder.Entity<UserEmailClaim>()
|
||||
.HasOne(l => l.User)
|
||||
.WithMany(c => c.EmailClaims)
|
||||
.HasForeignKey(l => l.UserId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
// Configure Email - UserEncryptionKey relationship
|
||||
modelBuilder.Entity<Email>()
|
||||
.HasOne(l => l.EncryptionKey)
|
||||
.WithMany(c => c.Emails)
|
||||
.HasForeignKey(l => l.UserEncryptionKeyId)
|
||||
.OnDelete(DeleteBehavior.NoAction);
|
||||
|
||||
// Configure UserEncryptionKey - AliasVaultUser relationship
|
||||
modelBuilder.Entity<UserEncryptionKey>()
|
||||
.HasOne(l => l.User)
|
||||
.WithMany(c => c.EncryptionKeys)
|
||||
.HasForeignKey(l => l.UserId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -27,6 +27,13 @@ public class AliasVaultUser : IdentityUser
|
||||
[StringLength(1000)]
|
||||
public string Verifier { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the user public key to be used by server to encrypt information that server
|
||||
/// receives for user such as emails.
|
||||
/// </summary>
|
||||
[StringLength(2000)]
|
||||
public string PublicKey { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets created timestamp.
|
||||
/// </summary>
|
||||
@@ -41,4 +48,14 @@ public class AliasVaultUser : IdentityUser
|
||||
/// Gets or sets the collection of vaults.
|
||||
/// </summary>
|
||||
public virtual ICollection<Vault> Vaults { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the collection of EmailClaims.
|
||||
/// </summary>
|
||||
public virtual ICollection<UserEmailClaim> EmailClaims { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the collection of EncryptionKeys.
|
||||
/// </summary>
|
||||
public virtual ICollection<UserEncryptionKey> EncryptionKeys { get; set; } = [];
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
namespace AliasServerDb;
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
/// <summary>
|
||||
@@ -24,6 +26,18 @@ public class Email
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets encryption key foreign key.
|
||||
/// </summary>
|
||||
[StringLength(255)]
|
||||
public Guid UserEncryptionKeyId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets foreign key to the UserEncryptionKey object.
|
||||
/// </summary>
|
||||
[ForeignKey("UserEncryptionKeyId")]
|
||||
public virtual UserEncryptionKey EncryptionKey { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the subject of the email.
|
||||
/// </summary>
|
||||
|
||||
702
src/Databases/AliasServerDb/Migrations/20240729090556_AddEncryptionKeyTables.Designer.cs
generated
Normal file
702
src/Databases/AliasServerDb/Migrations/20240729090556_AddEncryptionKeyTables.Designer.cs
generated
Normal file
@@ -0,0 +1,702 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using AliasServerDb;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AliasServerDb.Migrations
|
||||
{
|
||||
[DbContext(typeof(AliasServerDbContext))]
|
||||
[Migration("20240729090556_AddEncryptionKeyTables")]
|
||||
partial class AddEncryptionKeyTables
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.7")
|
||||
.HasAnnotation("Proxies:ChangeTracking", false)
|
||||
.HasAnnotation("Proxies:CheckEquality", false)
|
||||
.HasAnnotation("Proxies:LazyLoading", true);
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.AdminRole", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("AdminRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.AdminUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime?>("LastPasswordChanged")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("AdminUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.AliasVaultRole", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("AliasVaultRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.AliasVaultUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("PublicKey")
|
||||
.IsRequired()
|
||||
.HasMaxLength(2000)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Salt")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Verifier")
|
||||
.IsRequired()
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("AliasVaultUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.AliasVaultUserRefreshToken", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DeviceIdentifier")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("ExpireDate")
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AliasVaultUserRefreshTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.Email", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("DateSystem")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("From")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("FromDomain")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("FromLocal")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("MessageHtml")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("MessagePlain")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("MessagePreview")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("MessageSource")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("PushNotificationSent")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Subject")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("To")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ToDomain")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ToLocal")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("UserEncryptionKeyId")
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("Visible")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Date");
|
||||
|
||||
b.HasIndex("DateSystem");
|
||||
|
||||
b.HasIndex("PushNotificationSent");
|
||||
|
||||
b.HasIndex("ToLocal");
|
||||
|
||||
b.HasIndex("UserEncryptionKeyId");
|
||||
|
||||
b.HasIndex("Visible");
|
||||
|
||||
b.ToTable("Emails");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.EmailAttachment", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<byte[]>("Bytes")
|
||||
.IsRequired()
|
||||
.HasColumnType("BLOB");
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("EmailId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Filename")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Filesize")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("MimeType")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("EmailId");
|
||||
|
||||
b.ToTable("EmailAttachments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.Log", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Application")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Exception")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Level")
|
||||
.IsRequired()
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("LogEvent")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("LogEvent");
|
||||
|
||||
b.Property<string>("Message")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("MessageTemplate")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Properties")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset>("TimeStamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Application");
|
||||
|
||||
b.HasIndex("TimeStamp");
|
||||
|
||||
b.ToTable("Logs", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.UserEmailClaim", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Address")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AddressDomain")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AddressLocal")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("UserEmailClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.UserEncryptionKey", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PublicKey")
|
||||
.IsRequired()
|
||||
.HasMaxLength(2000)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("UserEncryptionKeys");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.Vault", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("FileSize")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("VaultBlob")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Version")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Vaults");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasVault.WorkerStatus.Database.WorkerServiceStatus", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("CurrentStatus")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DesiredStatus")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("Heartbeat")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ServiceName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("varchar");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("WorkerServiceStatuses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("RoleClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("UserClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.ToTable("UserLogins", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.ToTable("UserRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("UserTokens", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.AliasVaultUserRefreshToken", b =>
|
||||
{
|
||||
b.HasOne("AliasServerDb.AliasVaultUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.Email", b =>
|
||||
{
|
||||
b.HasOne("AliasServerDb.UserEncryptionKey", "EncryptionKey")
|
||||
.WithMany("Emails")
|
||||
.HasForeignKey("UserEncryptionKeyId")
|
||||
.OnDelete(DeleteBehavior.NoAction)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("EncryptionKey");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.EmailAttachment", b =>
|
||||
{
|
||||
b.HasOne("AliasServerDb.Email", "Email")
|
||||
.WithMany("Attachments")
|
||||
.HasForeignKey("EmailId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Email");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.UserEmailClaim", b =>
|
||||
{
|
||||
b.HasOne("AliasServerDb.AliasVaultUser", "User")
|
||||
.WithMany("EmailClaims")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.UserEncryptionKey", b =>
|
||||
{
|
||||
b.HasOne("AliasServerDb.AliasVaultUser", "User")
|
||||
.WithMany("EncryptionKeys")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.Vault", b =>
|
||||
{
|
||||
b.HasOne("AliasServerDb.AliasVaultUser", "User")
|
||||
.WithMany("Vaults")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.AliasVaultUser", b =>
|
||||
{
|
||||
b.Navigation("EmailClaims");
|
||||
|
||||
b.Navigation("EncryptionKeys");
|
||||
|
||||
b.Navigation("Vaults");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.Email", b =>
|
||||
{
|
||||
b.Navigation("Attachments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.UserEncryptionKey", b =>
|
||||
{
|
||||
b.Navigation("Emails");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AliasServerDb.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddEncryptionKeyTables : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// Delete all records from the Email table as adding PKI will break the existing data.
|
||||
migrationBuilder.Sql("DELETE FROM Emails");
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "UserEncryptionKeyId",
|
||||
table: "Emails",
|
||||
type: "TEXT",
|
||||
maxLength: 255,
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "PublicKey",
|
||||
table: "AliasVaultUsers",
|
||||
type: "TEXT",
|
||||
maxLength: 2000,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "UserEmailClaims",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
UserId = table.Column<string>(type: "TEXT", maxLength: 255, nullable: false),
|
||||
Address = table.Column<string>(type: "TEXT", maxLength: 255, nullable: false),
|
||||
AddressLocal = table.Column<string>(type: "TEXT", maxLength: 255, nullable: false),
|
||||
AddressDomain = table.Column<string>(type: "TEXT", maxLength: 255, nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_UserEmailClaims", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_UserEmailClaims_AliasVaultUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AliasVaultUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "UserEncryptionKeys",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
UserId = table.Column<string>(type: "TEXT", maxLength: 255, nullable: false),
|
||||
PublicKey = table.Column<string>(type: "TEXT", maxLength: 2000, nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_UserEncryptionKeys", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_UserEncryptionKeys_AliasVaultUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AliasVaultUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Emails_UserEncryptionKeyId",
|
||||
table: "Emails",
|
||||
column: "UserEncryptionKeyId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserEmailClaims_UserId",
|
||||
table: "UserEmailClaims",
|
||||
column: "UserId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserEncryptionKeys_UserId",
|
||||
table: "UserEncryptionKeys",
|
||||
column: "UserId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Emails_UserEncryptionKeys_UserEncryptionKeyId",
|
||||
table: "Emails",
|
||||
column: "UserEncryptionKeyId",
|
||||
principalTable: "UserEncryptionKeys",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Emails_UserEncryptionKeys_UserEncryptionKeyId",
|
||||
table: "Emails");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "UserEmailClaims");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "UserEncryptionKeys");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Emails_UserEncryptionKeyId",
|
||||
table: "Emails");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "UserEncryptionKeyId",
|
||||
table: "Emails");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "PublicKey",
|
||||
table: "AliasVaultUsers");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,6 +155,11 @@ namespace AliasServerDb.Migrations
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("PublicKey")
|
||||
.IsRequired()
|
||||
.HasMaxLength(2000)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Salt")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
@@ -273,6 +278,10 @@ namespace AliasServerDb.Migrations
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("UserEncryptionKeyId")
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("Visible")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
@@ -286,6 +295,8 @@ namespace AliasServerDb.Migrations
|
||||
|
||||
b.HasIndex("ToLocal");
|
||||
|
||||
b.HasIndex("UserEncryptionKeyId");
|
||||
|
||||
b.HasIndex("Visible");
|
||||
|
||||
b.ToTable("Emails");
|
||||
@@ -374,6 +385,74 @@ namespace AliasServerDb.Migrations
|
||||
b.ToTable("Logs", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.UserEmailClaim", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Address")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AddressDomain")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AddressLocal")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("UserEmailClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.UserEncryptionKey", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PublicKey")
|
||||
.IsRequired()
|
||||
.HasMaxLength(2000)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("UserEncryptionKeys");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.Vault", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
@@ -541,6 +620,17 @@ namespace AliasServerDb.Migrations
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.Email", b =>
|
||||
{
|
||||
b.HasOne("AliasServerDb.UserEncryptionKey", "EncryptionKey")
|
||||
.WithMany("Emails")
|
||||
.HasForeignKey("UserEncryptionKeyId")
|
||||
.OnDelete(DeleteBehavior.NoAction)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("EncryptionKey");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.EmailAttachment", b =>
|
||||
{
|
||||
b.HasOne("AliasServerDb.Email", "Email")
|
||||
@@ -552,10 +642,10 @@ namespace AliasServerDb.Migrations
|
||||
b.Navigation("Email");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.Vault", b =>
|
||||
modelBuilder.Entity("AliasServerDb.UserEmailClaim", b =>
|
||||
{
|
||||
b.HasOne("AliasServerDb.AliasVaultUser", "User")
|
||||
.WithMany()
|
||||
.WithMany("EmailClaims")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
@@ -563,10 +653,46 @@ namespace AliasServerDb.Migrations
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.UserEncryptionKey", b =>
|
||||
{
|
||||
b.HasOne("AliasServerDb.AliasVaultUser", "User")
|
||||
.WithMany("EncryptionKeys")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.Vault", b =>
|
||||
{
|
||||
b.HasOne("AliasServerDb.AliasVaultUser", "User")
|
||||
.WithMany("Vaults")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.AliasVaultUser", b =>
|
||||
{
|
||||
b.Navigation("EmailClaims");
|
||||
|
||||
b.Navigation("EncryptionKeys");
|
||||
|
||||
b.Navigation("Vaults");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.Email", b =>
|
||||
{
|
||||
b.Navigation("Attachments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AliasServerDb.UserEncryptionKey", b =>
|
||||
{
|
||||
b.Navigation("Emails");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
|
||||
62
src/Databases/AliasServerDb/UserEmailClaim.cs
Normal file
62
src/Databases/AliasServerDb/UserEmailClaim.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="UserEmailClaim.cs" company="lanedirt">
|
||||
// Copyright (c) lanedirt. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
namespace AliasServerDb;
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
/// <summary>
|
||||
/// UserEmailClaim object. This object is used to reserve an email address for a user.
|
||||
/// </summary>
|
||||
public class UserEmailClaim
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the ID.
|
||||
/// </summary>
|
||||
[Key]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets user ID foreign key.
|
||||
/// </summary>
|
||||
[StringLength(255)]
|
||||
public string UserId { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets foreign key to the AliasVaultUser object.
|
||||
/// </summary>
|
||||
[ForeignKey("UserId")]
|
||||
public virtual AliasVaultUser User { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the full email address.
|
||||
/// </summary>
|
||||
[StringLength(255)]
|
||||
public string Address { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the email adress local part.
|
||||
/// </summary>
|
||||
[StringLength(255)]
|
||||
public string AddressLocal { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the email adress domain part.
|
||||
/// </summary>
|
||||
[StringLength(255)]
|
||||
public string AddressDomain { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets created timestamp.
|
||||
/// </summary>
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets updated timestamp.
|
||||
/// </summary>
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
}
|
||||
55
src/Databases/AliasServerDb/UserEncryptionKey.cs
Normal file
55
src/Databases/AliasServerDb/UserEncryptionKey.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="UserEncryptionKey.cs" company="lanedirt">
|
||||
// Copyright (c) lanedirt. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
namespace AliasServerDb;
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
/// <summary>
|
||||
/// UserEncryptionKey object. This object is used for storing user public keys for encryption.
|
||||
/// </summary>
|
||||
public class UserEncryptionKey
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the ID.
|
||||
/// </summary>
|
||||
[Key]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets user ID foreign key.
|
||||
/// </summary>
|
||||
[StringLength(255)]
|
||||
public string UserId { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets foreign key to the AliasVaultUser object.
|
||||
/// </summary>
|
||||
[ForeignKey("UserId")]
|
||||
public virtual AliasVaultUser User { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the public key.
|
||||
/// </summary>
|
||||
[StringLength(2000)]
|
||||
public string PublicKey { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets created timestamp.
|
||||
/// </summary>
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets updated timestamp.
|
||||
/// </summary>
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the collection of Emails that are using this encryption key.
|
||||
/// </summary>
|
||||
public virtual ICollection<Email> Emails { get; set; } = [];
|
||||
}
|
||||
@@ -21,5 +21,5 @@ public class Config
|
||||
/// Gets or sets the domains that the SMTP service is listening for.
|
||||
/// Domains not in this list will be rejected.
|
||||
/// </summary>
|
||||
public List<String> AllowedToDomains { get; set; } = [];
|
||||
public List<string> AllowedToDomains { get; set; } = [];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user