2024-12-09 21:11:46 +01:00
|
|
|
// Copyright (C) 2023-present sam/u1f320 (vulpine.solutions)
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Affero General Public License as published
|
|
|
|
// by the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Affero General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2024-09-09 14:37:59 +02:00
|
|
|
using Foxnouns.Backend.Database;
|
2024-11-03 13:53:16 +01:00
|
|
|
using Foxnouns.Backend.Database.Models;
|
2024-06-13 02:23:55 +02:00
|
|
|
using Foxnouns.Backend.Services;
|
|
|
|
using Foxnouns.Backend.Utils;
|
2024-09-10 02:39:07 +02:00
|
|
|
using Newtonsoft.Json;
|
2024-06-13 02:23:55 +02:00
|
|
|
using NodaTime;
|
|
|
|
|
|
|
|
namespace Foxnouns.Backend.Extensions;
|
|
|
|
|
|
|
|
public static class KeyCacheExtensions
|
|
|
|
{
|
2024-10-02 00:28:07 +02:00
|
|
|
public static async Task<string> GenerateAuthStateAsync(
|
|
|
|
this KeyCacheService keyCacheService,
|
|
|
|
CancellationToken ct = default
|
|
|
|
)
|
2024-06-13 02:23:55 +02:00
|
|
|
{
|
2024-12-14 16:32:08 +01:00
|
|
|
string state = AuthUtils.RandomToken();
|
2024-09-09 14:50:00 +02:00
|
|
|
await keyCacheService.SetKeyAsync($"oauth_state:{state}", "", Duration.FromMinutes(10), ct);
|
2024-06-13 02:23:55 +02:00
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
2024-10-02 00:28:07 +02:00
|
|
|
public static async Task ValidateAuthStateAsync(
|
|
|
|
this KeyCacheService keyCacheService,
|
|
|
|
string state,
|
|
|
|
CancellationToken ct = default
|
|
|
|
)
|
2024-06-13 02:23:55 +02:00
|
|
|
{
|
2024-12-08 15:07:25 +01:00
|
|
|
string? val = await keyCacheService.GetKeyAsync($"oauth_state:{state}", ct: ct);
|
2024-10-02 00:28:07 +02:00
|
|
|
if (val == null)
|
|
|
|
throw new ApiError.BadRequest("Invalid OAuth state");
|
2024-06-13 02:23:55 +02:00
|
|
|
}
|
2024-09-09 14:37:59 +02:00
|
|
|
|
2024-10-02 00:28:07 +02:00
|
|
|
public static async Task<string> GenerateRegisterEmailStateAsync(
|
|
|
|
this KeyCacheService keyCacheService,
|
|
|
|
string email,
|
|
|
|
Snowflake? userId = null,
|
|
|
|
CancellationToken ct = default
|
|
|
|
)
|
2024-09-09 14:37:59 +02:00
|
|
|
{
|
2024-12-14 16:32:08 +01:00
|
|
|
string state = AuthUtils.RandomToken();
|
2024-10-02 00:28:07 +02:00
|
|
|
await keyCacheService.SetKeyAsync(
|
|
|
|
$"email_state:{state}",
|
|
|
|
new RegisterEmailState(email, userId),
|
|
|
|
Duration.FromDays(1),
|
|
|
|
ct
|
|
|
|
);
|
2024-09-09 14:37:59 +02:00
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
2024-10-02 00:28:07 +02:00
|
|
|
public static async Task<RegisterEmailState?> GetRegisterEmailStateAsync(
|
|
|
|
this KeyCacheService keyCacheService,
|
|
|
|
string state,
|
|
|
|
CancellationToken ct = default
|
2024-12-04 17:43:02 +01:00
|
|
|
) => await keyCacheService.GetKeyAsync<RegisterEmailState>($"email_state:{state}", ct: ct);
|
2024-11-03 13:53:16 +01:00
|
|
|
|
|
|
|
public static async Task<string> GenerateAddExtraAccountStateAsync(
|
|
|
|
this KeyCacheService keyCacheService,
|
|
|
|
AuthType authType,
|
|
|
|
Snowflake userId,
|
2024-12-04 01:48:52 +01:00
|
|
|
string? instance = null,
|
2024-11-03 13:53:16 +01:00
|
|
|
CancellationToken ct = default
|
|
|
|
)
|
|
|
|
{
|
2024-12-08 15:07:25 +01:00
|
|
|
string state = AuthUtils.RandomToken();
|
2024-11-03 13:53:16 +01:00
|
|
|
await keyCacheService.SetKeyAsync(
|
|
|
|
$"add_account:{state}",
|
2024-12-04 01:48:52 +01:00
|
|
|
new AddExtraAccountState(authType, userId, instance),
|
2024-11-03 13:53:16 +01:00
|
|
|
Duration.FromDays(1),
|
|
|
|
ct
|
|
|
|
);
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static async Task<AddExtraAccountState?> GetAddExtraAccountStateAsync(
|
|
|
|
this KeyCacheService keyCacheService,
|
|
|
|
string state,
|
|
|
|
CancellationToken ct = default
|
2024-12-08 15:07:25 +01:00
|
|
|
) => await keyCacheService.GetKeyAsync<AddExtraAccountState>($"add_account:{state}", true, ct);
|
2024-12-12 16:44:01 +01:00
|
|
|
|
|
|
|
public static async Task<string> GenerateForgotPasswordStateAsync(
|
|
|
|
this KeyCacheService keyCacheService,
|
|
|
|
string email,
|
|
|
|
Snowflake userId,
|
|
|
|
CancellationToken ct = default
|
|
|
|
)
|
|
|
|
{
|
|
|
|
string state = AuthUtils.RandomToken();
|
|
|
|
await keyCacheService.SetKeyAsync(
|
|
|
|
$"forgot_password:{state}",
|
|
|
|
new ForgotPasswordState(email, userId),
|
|
|
|
Duration.FromHours(1),
|
|
|
|
ct
|
|
|
|
);
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static async Task<ForgotPasswordState?> GetForgotPasswordStateAsync(
|
|
|
|
this KeyCacheService keyCacheService,
|
|
|
|
string state,
|
2024-12-14 16:32:08 +01:00
|
|
|
bool delete = true,
|
2024-12-12 16:44:01 +01:00
|
|
|
CancellationToken ct = default
|
|
|
|
) =>
|
|
|
|
await keyCacheService.GetKeyAsync<ForgotPasswordState>(
|
|
|
|
$"forgot_password:{state}",
|
2024-12-14 16:32:08 +01:00
|
|
|
delete,
|
2024-12-12 16:44:01 +01:00
|
|
|
ct
|
|
|
|
);
|
2024-09-09 14:37:59 +02:00
|
|
|
}
|
|
|
|
|
2024-09-10 02:39:07 +02:00
|
|
|
public record RegisterEmailState(
|
|
|
|
string Email,
|
2024-10-02 00:28:07 +02:00
|
|
|
[property: JsonProperty(NullValueHandling = NullValueHandling.Ignore)] Snowflake? ExistingUserId
|
|
|
|
);
|
2024-11-03 13:53:16 +01:00
|
|
|
|
2024-12-12 16:44:01 +01:00
|
|
|
public record ForgotPasswordState(string Email, Snowflake UserId);
|
|
|
|
|
2024-12-04 01:48:52 +01:00
|
|
|
public record AddExtraAccountState(AuthType AuthType, Snowflake UserId, string? Instance = null);
|