namespace DodoSSH.Api.Features.Teams; /// /// Source-generated log events for teams, membership and vault key grants. /// /// /// Ids, roles and outcomes only. Never a wrapped key, a signature or a fingerprint: the sharing graph /// is already visible to the operator (docs/crypto.md ยง10) and there is nothing to gain by adding key /// material to what a log aggregator keeps. /// internal static partial class TeamLog { [LoggerMessage( EventId = 2101, Level = LogLevel.Information, Message = "Created team {TeamId} for user {UserId}.")] internal static partial void TeamCreated(ILogger logger, Guid teamId, Guid userId); [LoggerMessage( EventId = 2102, Level = LogLevel.Information, Message = "Added user {MemberId} to team {TeamId} as {Role}, by {ActorId}.")] internal static partial void MemberAdded( ILogger logger, Guid teamId, Guid memberId, Domain.TeamRole role, Guid actorId); [LoggerMessage( EventId = 2103, Level = LogLevel.Information, Message = "Changed user {MemberId} in team {TeamId} to {Role}, by {ActorId}.")] internal static partial void MemberRoleChanged( ILogger logger, Guid teamId, Guid memberId, Domain.TeamRole role, Guid actorId); /// /// Warning rather than information, and it names the grant count. Removal is the operation whose /// consequences are least like what the word implies โ€” it blocks future reads and returns nothing /// already downloaded โ€” so it is the one worth being able to find in a log afterwards. /// [LoggerMessage( EventId = 2104, Level = LogLevel.Warning, Message = "Removed user {MemberId} from team {TeamId} by {ActorId}; revoked {GrantCount} vault " + "key grant(s). Vaults are flagged for rekey; already-downloaded data is unaffected.")] internal static partial void MemberRemoved( ILogger logger, Guid teamId, Guid memberId, Guid actorId, int grantCount); [LoggerMessage( EventId = 2105, Level = LogLevel.Information, Message = "Created team vault {VaultId} for team {TeamId}, by {ActorId}.")] internal static partial void TeamVaultCreated( ILogger logger, Guid vaultId, Guid teamId, Guid actorId); [LoggerMessage( EventId = 2106, Level = LogLevel.Information, Message = "Issued a key grant on vault {VaultId} generation {KeyGeneration} to {RecipientId}, " + "by {ActorId}.")] internal static partial void GrantIssued( ILogger logger, Guid vaultId, int keyGeneration, Guid recipientId, Guid actorId); [LoggerMessage( EventId = 2107, Level = LogLevel.Warning, Message = "Revoked the key grant on vault {VaultId} held by {RecipientId}, by {ActorId}. " + "Blocks future reads only; see ADR 0001.")] internal static partial void GrantRevoked( ILogger logger, Guid vaultId, Guid recipientId, Guid actorId); [LoggerMessage( EventId = 2108, Level = LogLevel.Information, Message = "Renamed team {TeamId}, by {ActorId}.")] internal static partial void TeamUpdated(ILogger logger, Guid teamId, Guid actorId); /// /// Warning, and it names the member count, for the reason removal does: an archive takes a team /// out of every member's list at once and only an operator can put it back. /// [LoggerMessage( EventId = 2109, Level = LogLevel.Warning, Message = "Archived team {TeamId} and its {MemberCount} membership(s), by {ActorId}. " + "Recoverable only by an operator clearing deleted_at_utc.")] internal static partial void TeamArchived( ILogger logger, Guid teamId, Guid actorId, int memberCount); /// /// Warning rather than information: it is the only operation that takes administrative control of /// a team away from the account that had it, and the account it is taken from is not the one /// asking afterwards. /// [LoggerMessage( EventId = 2110, Level = LogLevel.Warning, Message = "Transferred ownership of team {TeamId} from {FormerOwnerId} to {NewOwnerId}. " + "The former owner is now an admin.")] internal static partial void OwnershipTransferred( ILogger logger, Guid teamId, Guid formerOwnerId, Guid newOwnerId); /// /// The invitation id, never the address. TeamLog's rule is ids and outcomes only, and an email is /// exactly the kind of personal detail a log aggregator would then keep for its whole retention. /// [LoggerMessage( EventId = 2111, Level = LogLevel.Information, Message = "Issued invitation {InvitationId} to team {TeamId} as {Role}, by {ActorId}.")] internal static partial void InvitationIssued( ILogger logger, Guid invitationId, Guid teamId, Domain.TeamRole role, Guid actorId); [LoggerMessage( EventId = 2112, Level = LogLevel.Information, Message = "Revoked invitation {InvitationId} to team {TeamId}, by {ActorId}.")] internal static partial void InvitationRevoked( ILogger logger, Guid invitationId, Guid teamId, Guid actorId); [LoggerMessage( EventId = 2113, Level = LogLevel.Information, Message = "User {UserId} claimed invitation {InvitationId} and joined team {TeamId} as {Role}.")] internal static partial void InvitationClaimed( ILogger logger, Guid userId, Guid invitationId, Guid teamId, Domain.TeamRole role); /// /// /// Warning, and the one log line an operator will need when invitations appear not to work at all. /// A provider that does not assert email_verified leaves every invitation pending for ever /// with nothing else to show for it, and this is the only place that difference is visible. /// /// /// It names the count and the account, never the address โ€” the address is the thing being refused /// as untrustworthy, and writing it to a log would be keeping a claim the server just rejected. /// /// [LoggerMessage( EventId = 2114, Level = LogLevel.Warning, Message = "Left {InvitationCount} invitation(s) unclaimed for user {UserId}: the access token " + "does not assert that their email address is verified. Check the identity provider " + "sends the email_verified claim.")] internal static partial void InvitationNotClaimedUnverified( ILogger logger, int invitationCount, Guid userId); }