feat(backend): validate links, allow setting links in POST /users/@me/members
This commit is contained in:
		
							parent
							
								
									a3cbdc1a08
								
							
						
					
					
						commit
						8fe8755183
					
				
					 5 changed files with 37 additions and 5 deletions
				
			
		|  | @ -54,7 +54,8 @@ public class MembersController( | |||
|             ("avatar", ValidationUtils.ValidateAvatar(req.Avatar)), | ||||
|             .. ValidationUtils.ValidateFields(req.Fields, CurrentUser!.CustomPreferences), | ||||
|             .. ValidationUtils.ValidateFieldEntries(req.Names?.ToArray(), CurrentUser!.CustomPreferences, "names"), | ||||
|             .. ValidationUtils.ValidatePronouns(req.Pronouns?.ToArray(), CurrentUser!.CustomPreferences) | ||||
|             .. ValidationUtils.ValidatePronouns(req.Pronouns?.ToArray(), CurrentUser!.CustomPreferences), | ||||
|             .. ValidationUtils.ValidateLinks(req.Links) | ||||
|         ]); | ||||
| 
 | ||||
|         var member = new Member | ||||
|  | @ -64,6 +65,7 @@ public class MembersController( | |||
|             Name = req.Name, | ||||
|             DisplayName = req.DisplayName, | ||||
|             Bio = req.Bio, | ||||
|             Links = req.Links ?? [], | ||||
|             Fields = req.Fields ?? [], | ||||
|             Names = req.Names ?? [], | ||||
|             Pronouns = req.Pronouns ?? [], | ||||
|  | @ -113,6 +115,7 @@ public class MembersController( | |||
|         string? Bio, | ||||
|         string? Avatar, | ||||
|         bool? Unlisted, | ||||
|         string[]? Links, | ||||
|         List<FieldEntry>? Names, | ||||
|         List<Pronoun>? Pronouns, | ||||
|         List<Field>? Fields); | ||||
|  |  | |||
|  | @ -64,7 +64,7 @@ public class UsersController( | |||
| 
 | ||||
|         if (req.HasProperty(nameof(req.Links))) | ||||
|         { | ||||
|             // TODO: validate link length | ||||
|             errors.AddRange(ValidationUtils.ValidateLinks(req.Links)); | ||||
|             user.Links = req.Links ?? []; | ||||
|         } | ||||
| 
 | ||||
|  | @ -238,7 +238,7 @@ public class UsersController( | |||
|                 .SetProperty(u => u.Sid, _ => db.FindFreeUserSid()) | ||||
|                 .SetProperty(u => u.LastSidReroll, clock.GetCurrentInstant()) | ||||
|                 .SetProperty(u => u.LastActive, clock.GetCurrentInstant())); | ||||
|          | ||||
| 
 | ||||
|         var user = await db.ResolveUserAsync(CurrentUser.Id); | ||||
|         return Ok(await userRenderer.RenderUserAsync(user, CurrentUser, CurrentToken, renderMembers: false)); | ||||
|     } | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ public class DatabaseContext : DbContext | |||
|     public DbSet<Token> Tokens { get; set; } | ||||
|     public DbSet<Application> Applications { get; set; } | ||||
|     public DbSet<TemporaryKey> TemporaryKeys { get; set; } | ||||
|      | ||||
| 
 | ||||
|     public DbSet<PrideFlag> PrideFlags { get; set; } | ||||
|     public DbSet<UserFlag> UserFlags { get; set; } | ||||
|     public DbSet<MemberFlag> MemberFlags { get; set; } | ||||
|  |  | |||
|  | @ -37,7 +37,8 @@ public class MemberRendererService(DatabaseContext db, Config config) | |||
|     private UserRendererService.PartialUser RenderPartialUser(User user) => | ||||
|         new(user.Id, user.Sid, user.Username, user.DisplayName, AvatarUrlFor(user), user.CustomPreferences); | ||||
| 
 | ||||
|     public PartialMember RenderPartialMember(Member member, bool renderUnlisted = false) => new(member.Id, member.Sid, member.Name, | ||||
|     public PartialMember RenderPartialMember(Member member, bool renderUnlisted = false) => new(member.Id, member.Sid, | ||||
|         member.Name, | ||||
|         member.DisplayName, member.Bio, AvatarUrlFor(member), member.Names, member.Pronouns, | ||||
|         renderUnlisted ? member.Unlisted : null); | ||||
| 
 | ||||
|  |  | |||
|  | @ -99,6 +99,34 @@ public static class ValidationUtils | |||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     private const int MaxLinks = 25; | ||||
|     private const int MaxLinkLength = 256; | ||||
| 
 | ||||
|     public static IEnumerable<(string, ValidationError?)> ValidateLinks(string[]? links) | ||||
|     { | ||||
|         if (links == null) return []; | ||||
|         if (links.Length > MaxLinks) | ||||
|             return [("links", ValidationError.LengthError("Too many links", 0, MaxLinks, links.Length))]; | ||||
| 
 | ||||
|         var errors = new List<(string, ValidationError?)>(); | ||||
|         foreach (var (link, idx) in links.Select((l, i) => (l, i))) | ||||
|         { | ||||
|             switch (link.Length) | ||||
|             { | ||||
|                 case 0: | ||||
|                     errors.Add(($"links.{idx}", | ||||
|                         ValidationError.LengthError("Link cannot be empty", 1, 256, 0))); | ||||
|                     break; | ||||
|                 case > MaxLinkLength: | ||||
|                     errors.Add(($"links.{idx}", | ||||
|                         ValidationError.LengthError("Link is too long", 1, MaxLinkLength, link.Length))); | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return errors; | ||||
|     } | ||||
| 
 | ||||
|     public static ValidationError? ValidateBio(string? bio) | ||||
|     { | ||||
|         return bio?.Length switch | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue