Files
SocialPub/PrivaPub/Models/User/Avatar.cs
T
thepraandClaude Opus 5.5 e6729c77e7
Build / Build (push) Successful in 1m7s
Deploy / privapub.thepra.dev (push) Successful in 1m15s
P6 done: personas can be quoted, under the owner's default of anyone, automatically
- Our public and unlisted posts state interactionPolicy.canQuote. The policy comes from the post, then the persona
  (`source[quote_policy]`: public, followers or nobody; default public as the owner chose), and is always nobody for
  followers-only posts and DMs.
- QuoteRequests are answered with Accept{result} naming a parrot-licence at /peasants/{name}/parrot-licences/{id}
  (the route name the owner chose), or with Reject. Followers-only checks that the requester really follows.
- A licence is a QuoteAuthorization naming both posts; revoking it (POST /api/v1/statuses/:id/quotes/:quoting_id/revoke)
  marks it 410, sends Delete{licence} to the quoter and the persona's followers, and revokes our own copy of the quote.
- A quote that arrives with one of our licences is accepted only if that licence is ours, unrevoked and names exactly
  that quoting post. One persona quoting another gets a licence too.
- Mastodon API: quote_approval for our posts (automatic, followers, current_user), `quote_approval_policy` when posting,
  PUT /api/v1/statuses/:id/interaction_policy, `source.quote_policy`.

Checked live: GoToSocial still accepts our posts with the policy stated, and leaves likes, replies and boosts open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012CzABvBkbcFqoHdmi8b9WB
2026-10-01 19:53:13 +02:00

153 lines
5.2 KiB
C#

using MongoDB.Entities;
using PrivaPub.Infrastructure.Ids;
namespace PrivaPub.Models.User
{
public class Avatar : Entity
{
public string Url { get; set; }//url
public string Name { get; set; }//name
public string UserName { get; set; }//preferredUsername
public string Biography { get; set; }//summary
public Dictionary<string, string> SharedPersonalContacts { get; set; } = new();
public string PrivateKey { get; set; }
public string PublicKey { get; set; }
public AvatarAccountState AccountState { get; set; } = AvatarAccountState.Normal;
public AvatarSettings Settings { get; set; } = new();
public Dictionary<string, string> Fields { get; set; } = new();
public string Domain { get; set; }
public string PersonalNote { get; set; }
public string ModerationNote { get; set; }
public string InboxURL { get; set; }
public string OutboxURL { get; set; }
public string MovedToURL { get; set; }
public string PictureURL { get; set; }//icon
public string ThumbnailURL { get; set; }//image
public AvatarType AvatarType { get; set; } = AvatarType.Person;
public AvatarServer AvatarServer { get; set; } = AvatarServer.PrivaPub;
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime PublishedOn { get; set; } = PrivacyIds.PublishedDay(DateTime.UtcNow);//the actor's published: a few days before CreatedAt, so same-day personas differ
public DateTime? SilencedAt { get; set; }
public DateTime? SuspendedAt { get; set; }
public DateTime? BannedAt { get; set; }
public DateTime? DeletionAt { get; set; }
public override object GenerateNewID() => PrivacyIds.ForDay(PublishedOn);
}
public class ForeignAvatar : Entity
{
public string Url { get; set; }//url
public string Name { get; set; }//name
public string UserName { get; set; }//preferredUsername
public string Biography { get; set; }//summary
public Dictionary<string, string> SharedPersonalContacts { get; set; } = new();
public string PrivateKey { get; set; }
public string PublicKey { get; set; }
public AvatarAccountState AccountState { get; set; } = AvatarAccountState.Normal;
public AvatarSettings Settings { get; set; } = new();
public Dictionary<string, string> Fields { get; set; } = new();
public string Domain { get; set; }
public string PersonalNote { get; set; }
public string ModerationNote { get; set; }
public bool IsDiscoverable { get; set; } = true;
public bool IsIndexable { get; set; }
public bool IsLocked { get; set; }//manuallyApprovesFollowers
public bool IsMemorial { get; set; }
public List<PrivaPub.Models.Post.CustomEmoji> Emojis { get; set; } = new();
public string PictureDescription { get; set; }
public string HeaderDescription { get; set; }
public DateTime? Published { get; set; }//the actor's own published
public string ActorURI { get; set; }//id
public string PublicKeyId { get; set; }
public string FollowersURL { get; set; }
public string FollowingURL { get; set; }
public string SharedInboxURL { get; set; }
public string InboxURL { get; set; }
public string OutboxURL { get; set; }
public string MovedToURL { get; set; }
public string PictureURL { get; set; }//icon
public string ThumbnailURL { get; set; }//image
public AvatarType AvatarType { get; set; } = AvatarType.Person;
public AvatarServer AvatarServer { get; set; } = AvatarServer.Unknown;
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? SilencedAt { get; set; }
public DateTime? SuspendedAt { get; set; }
public DateTime? BannedAt { get; set; }
public DateTime? DeletionAt { get; set; }
}
public class AvatarSettings
{
public string LanguageCode { get; set; } = "en-GB";
public bool IsDefault { get; set; } = true;
public short IconsThemeIndexColour { get; set; } = 25;
public short LightThemeIndexColour { get; set; } = 25;
public short DarkThemeIndexColour { get; set; } = 215;
public bool PreferSystemTheming { get; set; } = true;
public bool ThemeIsDarkMode { get; set; } = false;
public bool ThemeIsDarkGray { get; set; } = false;
public bool ThemeIsLightGray { get; set; } = true;
public bool IsLocked { get; set; }
public bool IsBot { get; set; }
public bool IsDiscoverable { get; set; } = true;
public bool IsIndexable { get; set; }
public bool HideCollections { get; set; } = true;
public string DefaultVisibility { get; set; } = "public";
public bool DefaultSensitive { get; set; }
public string DefaultLanguage { get; set; }
public string QuotePolicy { get; set; } = QuotePolicies.Public;//owner decision: anyone may quote a public post, automatically
}
public static class QuotePolicies
{
public const string Public = "public";
public const string Followers = "followers";
public const string Nobody = "nobody";
public static bool IsKnown(string value) => value is Public or Followers or Nobody;
}
public enum AvatarServer
{
Unknown,
Pleroma,
Mastodon,
Akkoma,
Misskey,
PrivaPub
}
public enum AvatarType
{
Application,
Group,
Organization,
Person,
Service
}
public enum AvatarAccountState
{
Normal,
Silenced,
Suspended,
Banned,
Deleted
}
}