Identity Endpoints API - Optional "CallbackUrl"
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 281
Description
## Background and Motivation
I'd like an optional `string? CallbackUrl` since I'll likely have **multiple** frontends on different (sub)domains, consuming the same Auth API.
Passing that (sub)domain URL all the way through, would enable that.
For example, https://www.leashr.com & https://www.belgiandoggos.be use the same API for authentication & authorization.
Setting either one in my `appSettings.json` won't cut it.
So, I prefer you just make the parameters available so we can form our own URLs and decide whether it goes to a frontend or backend. Then, I can also choose to use route parameters rather than query string parameters on my Blazor frontends.
Feel free to watch my implementation of RC1: https://youtu.be/yGYpN1hFPAg?si=zlLykBIas_WBjXWN
## Proposed API
```csharp
Task SendConfirmationEmailAsync(TUser user, string email, string code, string confirmationLink, string? callbackUrl) where TUser : class
{
return SendEmailAsync(email, code, confirmationLink, callbackUrl);
}
// Merged ResetCode & ResetLink into one.
Task SendPasswordResetEmailAsync(TUser user, string email, string resetCode, string resetLink, string? callbackUrl) where TUser : class
{
return SendEmailAsync(email, resetCode, resetLink, callbackUrl);
}
```
```csharp
public sealed class NoOpEmailSender : IEmailSender
{
public Task SendEmailAsync(string email, string code, string link, string? callbackUrl) => Task.CompletedTask;
}
```
#### DTO
You'll need to add the `string? CallbackUrl` property to your request & response DTO's as well to pass the value all the way down and back to the consumer.
## Usage Examples
```csharp
public async Task SendConfirmationEmailAsync(TUser user, string email, string code, string confirmationLink, string? callbackUrl) where TUser : class
{
var frontendConfirmationLink = $"clicking here";
await SendEmailAsync(email, $"{user.Name}, confirm your email", $"Please confirm message (in my native language) {frontendConfirmationLink}.");
}
// Merged ResetCode & ResetLink into one.
public async Task SendPasswordResetEmailAsync(TUser user, string email, string resetCode, string resetLink, string? callbackUrl) where TUser : class
{
var frontendResetLink = $"clicking here";
await SendEmailAsync(email, $"{user.Name}, reset your password", $"Reset password message (in my native language): {frontendResetLink}");
}
```
## Alternative Designs
The formed links are fine as an example but a pain to extract from & reformat.
The subject & message are likely to be translated or changed, so mainly serve as an example as well.
I don't think you need either of the above but feel free to leave those in.
## Risks
Will need good documentation to prevent confusion about being able to use the provided link but also to use the parameters to form your own link.
Contributor guide
Research direction
Start with the Identity endpoints API, IEmailSender/NoOpEmailSender, the confirmation and password-reset methods, and the related request and response DTOs mentioned in the issue. Trace how these values move through the authentication flow and check existing tests or documentation before deciding the API shape. Done means an optional CallbackUrl can reach the email sender and consumers without breaking existing callers.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- api, authentication, backend-api-design
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100