Files
WebDrop/server/src/WebDrop.Storage/SqliteAccountSigning.cs
T

45 lines
2.0 KiB
C#

using Microsoft.Data.Sqlite;
namespace WebDrop.Storage;
public sealed record AccountDeviceSigningKey(string PublicKey, byte[] CertificateSignature);
public sealed partial class SqliteAccountStore
{
public AccountDeviceSigningKey? DeviceSigningKey(string username, string deviceId)
{
lock (_gate)
{
using var cmd = _connection.CreateCommand();
cmd.CommandText = "SELECT public_key,certificate_signature FROM account_device_signing_keys WHERE username=$u AND device_id=$d";
cmd.Parameters.AddWithValue("$u", username); cmd.Parameters.AddWithValue("$d", deviceId);
using var reader = cmd.ExecuteReader();
return reader.Read() ? new(reader.GetString(0), (byte[])reader[1]) : null;
}
}
public bool SaveDeviceSigningKey(string username, string deviceId, string publicKey, byte[] signature)
{
lock (_gate)
{
using var device = _connection.CreateCommand();
device.CommandText = "SELECT 1 FROM account_devices WHERE username=$u AND id=$d";
device.Parameters.AddWithValue("$u", username); device.Parameters.AddWithValue("$d", deviceId);
if (device.ExecuteScalar() is null) return false;
using var cmd = _connection.CreateCommand();
cmd.CommandText = """
INSERT INTO account_device_signing_keys(username,device_id,public_key,certificate_signature,modified_at)
VALUES($u,$d,$p,$s,$m)
ON CONFLICT(username,device_id) DO UPDATE SET public_key=excluded.public_key,
certificate_signature=excluded.certificate_signature,modified_at=excluded.modified_at
""";
cmd.Parameters.AddWithValue("$u", username); cmd.Parameters.AddWithValue("$d", deviceId);
cmd.Parameters.AddWithValue("$p", publicKey); cmd.Parameters.AddWithValue("$s", signature);
cmd.Parameters.AddWithValue("$m", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
return cmd.ExecuteNonQuery() == 1;
}
}
}