feat(backend): add short ID reroll endpoints
This commit is contained in:
		
							parent
							
								
									e76c634738
								
							
						
					
					
						commit
						b5f9ef9bd6
					
				
					 3 changed files with 61 additions and 2 deletions
				
			
		|  | @ -9,6 +9,7 @@ using Foxnouns.Backend.Services; | |||
| using Foxnouns.Backend.Utils; | ||||
| using Microsoft.AspNetCore.Mvc; | ||||
| using Microsoft.EntityFrameworkCore; | ||||
| using NodaTime; | ||||
| 
 | ||||
| namespace Foxnouns.Backend.Controllers; | ||||
| 
 | ||||
|  | @ -19,7 +20,8 @@ public class MembersController( | |||
|     MemberRendererService memberRenderer, | ||||
|     ISnowflakeGenerator snowflakeGenerator, | ||||
|     ObjectStorageService objectStorageService, | ||||
|     IQueue queue) : ApiControllerBase | ||||
|     IQueue queue, | ||||
|     IClock clock) : ApiControllerBase | ||||
| { | ||||
|     private readonly ILogger _logger = logger.ForContext<MembersController>(); | ||||
| 
 | ||||
|  | @ -114,4 +116,25 @@ public class MembersController( | |||
|         List<FieldEntry>? Names, | ||||
|         List<Pronoun>? Pronouns, | ||||
|         List<Field>? Fields); | ||||
| 
 | ||||
|     [HttpPost("/api/v2/users/@me/members/{memberRef}/reroll-sid")] | ||||
|     [Authorize("member.update")] | ||||
|     [ProducesResponseType<UserRendererService.UserResponse>(statusCode: StatusCodes.Status200OK)] | ||||
|     public async Task<IActionResult> RerollSidAsync(string memberRef) | ||||
|     { | ||||
|         var member = await db.ResolveMemberAsync(CurrentUser!.Id, memberRef); | ||||
| 
 | ||||
|         var minTimeAgo = clock.GetCurrentInstant() - Duration.FromHours(1); | ||||
|         if (CurrentUser!.LastSidReroll > minTimeAgo) | ||||
|             throw new ApiError.BadRequest("Cannot reroll short ID yet"); | ||||
| 
 | ||||
|         await db.Members.Where(m => m.Id == member.Id) | ||||
|             .ExecuteUpdateAsync(s => s | ||||
|                 .SetProperty(m => m.Sid, _ => db.FindFreeMemberSid())); | ||||
| 
 | ||||
|         // Re-fetch member so we can be sure the sid is correct | ||||
|         var updatedMember = await db.ResolveMemberAsync(CurrentUser!.Id, memberRef); | ||||
| 
 | ||||
|         return Ok(memberRenderer.RenderMember(updatedMember, CurrentToken)); | ||||
|     } | ||||
| } | ||||
|  | @ -8,6 +8,7 @@ using Foxnouns.Backend.Services; | |||
| using Foxnouns.Backend.Utils; | ||||
| using Microsoft.AspNetCore.Mvc; | ||||
| using Microsoft.EntityFrameworkCore; | ||||
| using NodaTime; | ||||
| 
 | ||||
| namespace Foxnouns.Backend.Controllers; | ||||
| 
 | ||||
|  | @ -16,7 +17,8 @@ public class UsersController( | |||
|     DatabaseContext db, | ||||
|     UserRendererService userRenderer, | ||||
|     ISnowflakeGenerator snowflakeGenerator, | ||||
|     IQueue queue) : ApiControllerBase | ||||
|     IQueue queue, | ||||
|     IClock clock) : ApiControllerBase | ||||
| { | ||||
|     [HttpGet("{userRef}")] | ||||
|     [ProducesResponseType<UserRendererService.UserResponse>(statusCode: StatusCodes.Status200OK)] | ||||
|  | @ -213,4 +215,22 @@ public class UsersController( | |||
|     { | ||||
|         public bool? DarkMode { get; init; } | ||||
|     } | ||||
| 
 | ||||
|     [HttpPost("@me/reroll-sid")] | ||||
|     [Authorize("user.update")] | ||||
|     [ProducesResponseType<UserRendererService.UserResponse>(statusCode: StatusCodes.Status200OK)] | ||||
|     public async Task<IActionResult> RerollSidAsync() | ||||
|     { | ||||
|         var minTimeAgo = clock.GetCurrentInstant() - Duration.FromHours(1); | ||||
|         if (CurrentUser!.LastSidReroll > minTimeAgo) | ||||
|             throw new ApiError.BadRequest("Cannot reroll short ID yet"); | ||||
| 
 | ||||
|         await db.Users.Where(u => u.Id == CurrentUser.Id) | ||||
|             .ExecuteUpdateAsync(s => s | ||||
|                 .SetProperty(u => u.Sid, _ => db.FindFreeUserSid()) | ||||
|                 .SetProperty(u => u.LastSidReroll, _ => clock.GetCurrentInstant())); | ||||
|          | ||||
|         var user = await db.ResolveUserAsync(CurrentUser.Id); | ||||
|         return Ok(await userRenderer.RenderUserAsync(user, CurrentUser, CurrentToken, renderMembers: false)); | ||||
|     } | ||||
| } | ||||
|  | @ -76,7 +76,23 @@ public class DatabaseContext : DbContext | |||
|         modelBuilder.Entity<Member>().Property(m => m.Fields).HasColumnType("jsonb"); | ||||
|         modelBuilder.Entity<Member>().Property(m => m.Names).HasColumnType("jsonb"); | ||||
|         modelBuilder.Entity<Member>().Property(m => m.Pronouns).HasColumnType("jsonb"); | ||||
| 
 | ||||
|         modelBuilder.HasDbFunction(typeof(DatabaseContext).GetMethod(nameof(FindFreeUserSid))!) | ||||
|             .HasName("find_free_user_sid"); | ||||
| 
 | ||||
|         modelBuilder.HasDbFunction(typeof(DatabaseContext).GetMethod(nameof(FindFreeMemberSid))!) | ||||
|             .HasName("find_free_member_sid"); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// Dummy method that calls <c>find_free_user_sid()</c> when used in an EF Core query. | ||||
|     /// </summary> | ||||
|     public string FindFreeUserSid() => throw new NotSupportedException(); | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// Dummy method that calls <c>find_free_member_sid()</c> when used in an EF Core query. | ||||
|     /// </summary> | ||||
|     public string FindFreeMemberSid() => throw new NotSupportedException(); | ||||
| } | ||||
| 
 | ||||
| [SuppressMessage("ReSharper", "UnusedType.Global", Justification = "Used by EF Core's migration generator")] | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue