167 lines
8.0 KiB
C#
167 lines
8.0 KiB
C#
using PrivaPub.ClientModels.Resources;
|
|||
|
|
|
||
|
|
using System.ComponentModel.DataAnnotations;
|
||
|
|
|
||
|
|
namespace PrivaPub.ClientModels.Admin
|
||
|
|
{
|
||
|
|
// The server's own settings as the administrator's page shows them (GET /clientapi/admin/settings): what the instance
|
||
|
|
// API, NodeInfo, the instance actor, the web pages and the emails say of the server, its rules, its relays, its media
|
||
|
|
// limits next to the configured ones, and whether its weekly activity is published. Registrations are read-only: they
|
||
|
|
// stay in the configuration (Registrations:Mode).
|
||
|
|
public class ViewServerSettings
|
||
|
|
{
|
||
|
|
public string Title { get; set; }
|
||
|
|
public string ShortDescription { get; set; }
|
||
|
|
public string Description { get; set; }//Markdown
|
||
|
|
public DateTime? DescriptionUpdatedAt { get; set; }
|
||
|
|
public string ContactEmail { get; set; }
|
||
|
|
public string ContactAccountId { get; set; }
|
||
|
|
public ViewContactAccount ContactAccount { get; set; }//null when none is set, or it is gone
|
||
|
|
public string ThumbnailUrl { get; set; }//what the instance API shows (the default picture when none was uploaded)
|
||
|
|
public bool ThumbnailIsDefault { get; set; } = true;
|
||
|
|
public string PrivacyPolicy { get; set; }//Markdown
|
||
|
|
public DateTime? PrivacyPolicyUpdatedAt { get; set; }
|
||
|
|
public string TermsOfService { get; set; }//Markdown; null: none
|
||
|
|
public DateTime? TermsEffectiveAt { get; set; }
|
||
|
|
public List<ViewServerRule> Rules { get; set; } = [];//deleted ones too (IsDeleted), as old reports name them
|
||
|
|
public List<ViewRelay> Relays { get; set; } = [];
|
||
|
|
public ViewMediaLimits Media { get; set; } = new();
|
||
|
|
public string RegistrationMode { get; set; }//"Invitations" or "Open", from the configuration
|
||
|
|
public bool PublishActivity { get; set; } = false;
|
||
|
|
public DateTime? UpdatedAt { get; set; }//null: never saved, every value is the default
|
||
|
|
public string UpdatedBy { get; set; }//the administrator's login, or "cli"
|
||
|
|
}
|
||
|
|
|
||
|
|
public class ViewContactAccount
|
||
|
|
{
|
||
|
|
public string Id { get; set; }
|
||
|
|
public string UserName { get; set; }
|
||
|
|
public string Name { get; set; }
|
||
|
|
public string Handle { get; set; }//user@host
|
||
|
|
}
|
||
|
|
|
||
|
|
public class ViewServerRule
|
||
|
|
{
|
||
|
|
public string Id { get; set; }
|
||
|
|
public string Text { get; set; }
|
||
|
|
public string Hint { get; set; }
|
||
|
|
public int Position { get; set; } = 0;
|
||
|
|
public bool IsDeleted { get; set; } = false;
|
||
|
|
public DateTime? DeletedAt { get; set; }
|
||
|
|
}
|
||
|
|
|
||
|
|
// the administrator's overrides (null: the configured value holds), what the configuration says, and the hard caps
|
||
|
|
public class ViewMediaLimits
|
||
|
|
{
|
||
|
|
public long? QuotaBytesPerRoot { get; set; }
|
||
|
|
public long? MaxImageBytes { get; set; }
|
||
|
|
public long? MaxVideoBytes { get; set; }
|
||
|
|
public int? MaxSeconds { get; set; }
|
||
|
|
public long ConfiguredQuotaBytesPerRoot { get; set; } = 0;//0: no quota
|
||
|
|
public long ConfiguredMaxImageBytes { get; set; } = 0;
|
||
|
|
public long ConfiguredMaxVideoBytes { get; set; } = 0;
|
||
|
|
public int ConfiguredMaxSeconds { get; set; } = 0;
|
||
|
|
public long EffectiveQuotaBytesPerRoot { get; set; } = 0;
|
||
|
|
public long EffectiveMaxImageBytes { get; set; } = 0;
|
||
|
|
public long EffectiveMaxVideoBytes { get; set; } = 0;
|
||
|
|
public int EffectiveMaxSeconds { get; set; } = 0;
|
||
|
|
public long HardMaxImageBytes { get; set; } = ServerMediaLimitsForm.HardMaxImageBytes;
|
||
|
|
public long HardMaxVideoBytes { get; set; } = ServerMediaLimitsForm.HardMaxVideoBytes;
|
||
|
|
public int HardMaxSeconds { get; set; } = ServerMediaLimitsForm.HardMaxSeconds;
|
||
|
|
}
|
||
|
|
|
||
|
|
// POST /clientapi/admin/settings: everything the page edits at once (relays and the thumbnail have their own routes).
|
||
|
|
// A rule keeps its id when the form names it; one without an id is new; one left out is deleted (kept, marked).
|
||
|
|
public class ServerSettingsForm
|
||
|
|
{
|
||
|
|
public const int MaxRules = 50;
|
||
|
|
public const int MaxText = 20000;
|
||
|
|
|
||
|
|
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(ErrorsResource)),
|
||
|
|
StringLength(64, ErrorMessageResourceName = "StringLength", ErrorMessageResourceType = typeof(ErrorsResource)),
|
||
|
|
Display(Name = "Title", ResourceType = typeof(FieldsNameResource))]
|
||
|
|
public string Title { get; set; }
|
||
|
|
|
||
|
|
[StringLength(500, ErrorMessageResourceName = "StringLength", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string ShortDescription { get; set; }
|
||
|
|
|
||
|
|
[StringLength(MaxText, ErrorMessageResourceName = "StringLength", ErrorMessageResourceType = typeof(ErrorsResource)),
|
||
|
|
Display(Name = "Description", ResourceType = typeof(FieldsNameResource))]
|
||
|
|
public string Description { get; set; }
|
||
|
|
|
||
|
|
[EmailAddress(ErrorMessageResourceName = "InvalidEmail", ErrorMessageResourceType = typeof(ErrorsResource)),
|
||
|
|
StringLength(254, ErrorMessageResourceName = "StringLength", ErrorMessageResourceType = typeof(ErrorsResource)),
|
||
|
|
Display(Name = "Email", ResourceType = typeof(FieldsNameResource))]
|
||
|
|
public string ContactEmail { get; set; }
|
||
|
|
|
||
|
|
[StringLength(64, ErrorMessageResourceName = "StringLength", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string ContactAccountId { get; set; }//a local persona's account id (its Mastodon id), or none
|
||
|
|
|
||
|
|
[StringLength(MaxText, ErrorMessageResourceName = "StringLength", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string PrivacyPolicy { get; set; }
|
||
|
|
|
||
|
|
[StringLength(MaxText, ErrorMessageResourceName = "StringLength", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string TermsOfService { get; set; }//empty: none
|
||
|
|
|
||
|
|
public DateTime? TermsEffectiveAt { get; set; }//a date; today when terms are given without one
|
||
|
|
|
||
|
|
[MaxLength(MaxRules, ErrorMessageResourceName = "MaxLengthArray", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public List<ServerRuleForm> Rules { get; set; } = [];
|
||
|
|
|
||
|
|
public ServerMediaLimitsForm Media { get; set; } = new();
|
||
|
|
|
||
|
|
public bool PublishActivity { get; set; } = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
public class ServerRuleForm
|
||
|
|
{
|
||
|
|
[StringLength(64, ErrorMessageResourceName = "StringLength", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string Id { get; set; }//an existing rule's id, or none for a new rule
|
||
|
|
|
||
|
|
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(ErrorsResource)),
|
||
|
|
StringLength(500, ErrorMessageResourceName = "StringLength", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string Text { get; set; }
|
||
|
|
|
||
|
|
[StringLength(1000, ErrorMessageResourceName = "StringLength", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string Hint { get; set; }
|
||
|
|
}
|
||
|
|
|
||
|
|
// null keeps the configured value
|
||
|
|
public class ServerMediaLimitsForm
|
||
|
|
{
|
||
|
|
public const long HardMaxImageBytes = 40L * 1024 * 1024;
|
||
|
|
public const long HardMaxVideoBytes = 99L * 1024 * 1024;
|
||
|
|
public const int HardMaxSeconds = 4 * 3600;
|
||
|
|
|
||
|
|
[Range(0L, long.MaxValue, ErrorMessageResourceName = "Range", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public long? QuotaBytesPerRoot { get; set; }//0: no quota
|
||
|
|
|
||
|
|
[Range(1L, HardMaxImageBytes, ErrorMessageResourceName = "Range", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public long? MaxImageBytes { get; set; }
|
||
|
|
|
||
|
|
[Range(1L, HardMaxVideoBytes, ErrorMessageResourceName = "Range", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public long? MaxVideoBytes { get; set; }
|
||
|
|
|
||
|
|
[Range(1, HardMaxSeconds, ErrorMessageResourceName = "Range", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public int? MaxSeconds { get; set; }
|
||
|
|
}
|
||
|
|
|
||
|
|
// a relay the instance actor subscribes to: named by the configuration (Federation:Relays, removed only there) or by
|
||
|
|
// the settings (added and removed from the page)
|
||
|
|
public class ViewRelay
|
||
|
|
{
|
||
|
|
public string Address { get; set; }
|
||
|
|
public string Source { get; set; }//"configuration" or "settings"
|
||
|
|
public string State { get; set; }//"pending", "accepted", "rejected", or "none" before its first request
|
||
|
|
public string ActorURI { get; set; }
|
||
|
|
public DateTime? RequestedAt { get; set; }
|
||
|
|
public DateTime? AnsweredAt { get; set; }
|
||
|
|
}
|
||
|
|
|
||
|
|
public class RelayForm
|
||
|
|
{
|
||
|
|
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(ErrorsResource)),
|
||
|
|
StringLength(2048, ErrorMessageResourceName = "StringLength", ErrorMessageResourceType = typeof(ErrorsResource))]
|
||
|
|
public string Address { get; set; }//the relay's actor (https://relay.example/actor) or its inbox
|
||
|
|
}
|
||
|
|
}
|