···5050 return false;
5151 }
52525353- // Basic CID validation - should be base32 or base58 encoded
5454- if (!Regex.IsMatch(cid, "^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+$"))
5353+ // Very basic CID validation
5454+ if (!Regex.IsMatch(cid, "^[123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]+$"))
5555 {
5656 //_logger?.LogError("CID contains invalid characters");
5757 return false;
+16-2
AltBot.Core/Models/Did.cs
···4343 //_logger?.LogError("DID cannot be null or empty");
4444 return false;
4545 }
4646-4747- if (did.Split(':').Length < 3)
4646+4747+ var parts = did.Split(':');
4848+ if (parts.Length != 3)
4849 {
4950 //_logger?.LogError("DID requires prefix, method, and method-specific content");
5151+ return false;
5252+ }
5353+5454+ if (parts[0] != "did")
5555+ {
5656+ //_logger?.LogError("DID must start with 'did' prefix");
5757+ return false;
5858+ };
5959+6060+ // Basic method name validation
6161+ if (parts[1] is not "plc" and not "web")
6262+ {
6363+ //_logger?.LogError("DID method must be 'plc' or 'web'");
5064 return false;
5165 }
5266
+1-1
AltBot.Core/Models/ImagePost.cs
···77 public required Cid Cid { get; set; }
88 public string? Rkey { get; set; }
99 public bool ValidAlt { get; set; }
1010- public DateTime Timestamp { get; set; }
1010+ public DateTime SeenAt { get; set; }
1111 public virtual Subscriber? Subscriber { get; set; }
1212}
···11+using AltBot.Core.Models;
22+using Microsoft.EntityFrameworkCore;
33+using Microsoft.EntityFrameworkCore.Design;
44+55+namespace AltBot.Data;
66+77+/// <summary>
88+/// This factory is used to create the DataContext at design time for EF Core tools (e.g., migrations).
99+/// </summary>
1010+public class DataContextFactory : IDesignTimeDbContextFactory<DataContext>
1111+{
1212+ public DataContext CreateDbContext(string[] args)
1313+ {
1414+ var optionsBuilder = new DbContextOptionsBuilder<DataContext>();
1515+ optionsBuilder.UseNpgsql("Host=localhost;Database=test;Username=test;Password=test", options => options.MapEnum<LabelLevel>("label"))
1616+ .UseSnakeCaseNamingConvention();
1717+1818+ return new DataContext(optionsBuilder.Options);
1919+ }
2020+}
···1616// Adds common .NET Aspire services: service discovery, resilience, health checks, and OpenTelemetry.
1717// This project should be referenced by each service project in your solution.
1818// To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults
1919-public static class Extensions
1919+public static class StartupExtensions
2020{
2121 private const string HealthEndpointPath = "/health";
2222 private const string AlivenessEndpointPath = "/alive";
···3939 // Turn on service discovery by default
4040 http.AddServiceDiscovery();
4141 });
4242-4242+4343 return builder;
4444 }
4545