Skip to content

Commit 13c5fce

Browse files
authored
Update EmergencyAccessInviteQuery to return encoded URLs and a JSON object (#7741)
* update EmergencyAccessInviteQuery to return a JSON object and properly encode the URLs, update test to account for this change * fix file encoding * remove comment
1 parent 788eaa6 commit 13c5fce

2 files changed

Lines changed: 24 additions & 10 deletions

File tree

test/SeederApi.IntegrationTest/QueryControllerTests.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,11 @@ public async Task QueryEndpoint_WithValidQueryAndArguments_ReturnsOk()
4747

4848
Assert.NotNull(result);
4949

50-
var urls = System.Text.Json.JsonSerializer.Deserialize<List<string>>(result);
51-
Assert.NotNull(urls);
52-
// For a non-existent email, we expect an empty list
53-
Assert.Empty(urls);
50+
var response2 = System.Text.Json.JsonSerializer.Deserialize<EmergencyAccessInviteResponse>(result,
51+
new System.Text.Json.JsonSerializerOptions { PropertyNameCaseInsensitive = true });
52+
Assert.NotNull(response2);
53+
Assert.NotNull(response2.Urls);
54+
Assert.Empty(response2.Urls);
5455
}
5556

5657
[Fact]
@@ -77,4 +78,6 @@ public async Task QueryEndpoint_WithMissingRequiredField_ReturnsBadRequest()
7778

7879
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
7980
}
81+
82+
private sealed record EmergencyAccessInviteResponse(List<string> Urls);
8083
}
Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System.ComponentModel.DataAnnotations;
2+
using System.Globalization;
3+
using System.Net;
24
using Bit.Core.Auth.Models.Business.Tokenables;
35
using Bit.Core.Tokens;
46
using Bit.Infrastructure.EntityFramework.Repositories;
@@ -11,25 +13,34 @@ namespace Bit.Seeder.Queries;
1113
public class EmergencyAccessInviteQuery(
1214
DatabaseContext db,
1315
IDataProtectorTokenFactory<EmergencyAccessInviteTokenable> dataProtectorTokenizer)
14-
: IQuery<EmergencyAccessInviteQuery.Request, IEnumerable<string>>
16+
: IQuery<EmergencyAccessInviteQuery.Request, EmergencyAccessInviteQuery.Response>
1517
{
1618
public class Request
1719
{
1820
[Required]
1921
public required string Email { get; set; }
2022
}
2123

22-
public Task<IEnumerable<string>> Execute(Request request)
24+
public class Response
2325
{
24-
var invites = db.EmergencyAccesses
26+
public required List<string> Urls { get; set; }
27+
}
28+
29+
public Task<Response> Execute(Request request)
30+
{
31+
var urls = db.EmergencyAccesses
2532
.Where(ea => ea.Email == request.Email).ToList().Select(ea =>
2633
{
2734
var token = dataProtectorTokenizer.Protect(
2835
new EmergencyAccessInviteTokenable(ea, hoursTillExpiration: 1)
2936
);
30-
return $"/accept-emergency?id={ea.Id}&name=Dummy&email={ea.Email}&token={token}";
31-
});
37+
return string.Format(CultureInfo.InvariantCulture,
38+
"/accept-emergency?id={0}&name=Dummy&email={1}&token={2}",
39+
WebUtility.UrlEncode(ea.Id.ToString()),
40+
WebUtility.UrlEncode(ea.Email),
41+
WebUtility.UrlEncode(token));
42+
}).ToList();
3243

33-
return Task.FromResult(invites);
44+
return Task.FromResult(new Response { Urls = urls });
3445
}
3546
}

0 commit comments

Comments
 (0)