✨ Use affiliation spell for registeration
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using DysonNetwork.Pass.Affiliation;
|
||||||
using DysonNetwork.Pass.Auth;
|
using DysonNetwork.Pass.Auth;
|
||||||
using DysonNetwork.Pass.Credit;
|
using DysonNetwork.Pass.Credit;
|
||||||
using DysonNetwork.Pass.Permission;
|
using DysonNetwork.Pass.Permission;
|
||||||
@@ -22,6 +23,7 @@ public class AccountController(
|
|||||||
SubscriptionService subscriptions,
|
SubscriptionService subscriptions,
|
||||||
AccountEventService events,
|
AccountEventService events,
|
||||||
SocialCreditService socialCreditService,
|
SocialCreditService socialCreditService,
|
||||||
|
AffiliationSpellService ars,
|
||||||
GeoIpService geo
|
GeoIpService geo
|
||||||
) : ControllerBase
|
) : ControllerBase
|
||||||
{
|
{
|
||||||
@@ -103,6 +105,8 @@ public class AccountController(
|
|||||||
[MaxLength(32)] public string Language { get; set; } = "en-us";
|
[MaxLength(32)] public string Language { get; set; } = "en-us";
|
||||||
|
|
||||||
[Required] public string CaptchaToken { get; set; } = string.Empty;
|
[Required] public string CaptchaToken { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string? AffiliationSpell { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AccountCreateValidateRequest
|
public class AccountCreateValidateRequest
|
||||||
@@ -118,6 +122,8 @@ public class AccountController(
|
|||||||
[RegularExpression(@"^[^+]+@[^@]+\.[^@]+$", ErrorMessage = "Email address cannot contain '+' symbol.")]
|
[RegularExpression(@"^[^+]+@[^@]+\.[^@]+$", ErrorMessage = "Email address cannot contain '+' symbol.")]
|
||||||
[MaxLength(1024)]
|
[MaxLength(1024)]
|
||||||
public string? Email { get; set; }
|
public string? Email { get; set; }
|
||||||
|
|
||||||
|
public string? AffiliationSpell { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("validate")]
|
[HttpPost("validate")]
|
||||||
@@ -138,6 +144,12 @@ public class AccountController(
|
|||||||
return BadRequest("Email has already been used.");
|
return BadRequest("Email has already been used.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (request.AffiliationSpell is not null)
|
||||||
|
{
|
||||||
|
if (!await ars.CheckAffiliationSpellHasTaken(request.AffiliationSpell))
|
||||||
|
return BadRequest("No affiliation spell has been found.");
|
||||||
|
}
|
||||||
|
|
||||||
return Ok("Everything seems good.");
|
return Ok("Everything seems good.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using DysonNetwork.Pass.Affiliation;
|
||||||
using DysonNetwork.Pass.Auth.OpenId;
|
using DysonNetwork.Pass.Auth.OpenId;
|
||||||
using DysonNetwork.Pass.Localization;
|
using DysonNetwork.Pass.Localization;
|
||||||
using DysonNetwork.Pass.Mailer;
|
using DysonNetwork.Pass.Mailer;
|
||||||
@@ -24,6 +25,7 @@ public class AccountService(
|
|||||||
FileService.FileServiceClient files,
|
FileService.FileServiceClient files,
|
||||||
FileReferenceService.FileReferenceServiceClient fileRefs,
|
FileReferenceService.FileReferenceServiceClient fileRefs,
|
||||||
AccountUsernameService uname,
|
AccountUsernameService uname,
|
||||||
|
AffiliationSpellService ars,
|
||||||
EmailService mailer,
|
EmailService mailer,
|
||||||
RingService.RingServiceClient pusher,
|
RingService.RingServiceClient pusher,
|
||||||
IStringLocalizer<NotificationResource> localizer,
|
IStringLocalizer<NotificationResource> localizer,
|
||||||
@@ -101,6 +103,7 @@ public class AccountService(
|
|||||||
string? password,
|
string? password,
|
||||||
string language = "en-US",
|
string language = "en-US",
|
||||||
string region = "en",
|
string region = "en",
|
||||||
|
string? affiliationSpell = null,
|
||||||
bool isEmailVerified = false,
|
bool isEmailVerified = false,
|
||||||
bool isActivated = false
|
bool isActivated = false
|
||||||
)
|
)
|
||||||
@@ -122,7 +125,7 @@ public class AccountService(
|
|||||||
Region = region,
|
Region = region,
|
||||||
Contacts =
|
Contacts =
|
||||||
[
|
[
|
||||||
new()
|
new SnAccountContact
|
||||||
{
|
{
|
||||||
Type = Shared.Models.AccountContactType.Email,
|
Type = Shared.Models.AccountContactType.Email,
|
||||||
Content = email,
|
Content = email,
|
||||||
@@ -144,6 +147,9 @@ public class AccountService(
|
|||||||
Profile = new SnAccountProfile()
|
Profile = new SnAccountProfile()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (affiliationSpell is not null)
|
||||||
|
await ars.CreateAffiliationResult(affiliationSpell, $"account:{account.Id}");
|
||||||
|
|
||||||
if (isActivated)
|
if (isActivated)
|
||||||
{
|
{
|
||||||
account.ActivatedAt = SystemClock.Instance.GetCurrentInstant();
|
account.ActivatedAt = SystemClock.Instance.GetCurrentInstant();
|
||||||
@@ -193,10 +199,7 @@ public class AccountService(
|
|||||||
displayName,
|
displayName,
|
||||||
userInfo.Email,
|
userInfo.Email,
|
||||||
null,
|
null,
|
||||||
"en-US",
|
isEmailVerified: userInfo.EmailVerified
|
||||||
"en",
|
|
||||||
userInfo.EmailVerified,
|
|
||||||
userInfo.EmailVerified
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using DysonNetwork.Shared.Models;
|
using DysonNetwork.Shared.Models;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@@ -7,9 +8,31 @@ namespace DysonNetwork.Pass.Affiliation;
|
|||||||
|
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("/api/affiliations")]
|
[Route("/api/affiliations")]
|
||||||
public class AffiliationSpellController(AppDatabase db) : ControllerBase
|
public class AffiliationSpellController(AppDatabase db, AffiliationSpellService ars) : ControllerBase
|
||||||
{
|
{
|
||||||
[HttpGet("me")]
|
public class CreateAffiliationSpellRequest
|
||||||
|
{
|
||||||
|
[MaxLength(1024)] public string? Spell { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Authorize]
|
||||||
|
public async Task<ActionResult<SnAffiliationSpell>> CreateSpell([FromBody] CreateAffiliationSpellRequest request)
|
||||||
|
{
|
||||||
|
if (HttpContext.Items["CurrentUser"] is not SnAccount currentUser) return Unauthorized();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var spell = await ars.CreateAffiliationSpell(currentUser.Id, request.Spell);
|
||||||
|
return Ok(spell);
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException e)
|
||||||
|
{
|
||||||
|
return BadRequest(e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public async Task<ActionResult<List<SnAffiliationSpell>>> ListCreatedSpells(
|
public async Task<ActionResult<List<SnAffiliationSpell>>> ListCreatedSpells(
|
||||||
[FromQuery(Name = "order")] string orderBy = "date",
|
[FromQuery(Name = "order")] string orderBy = "date",
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ public class AffiliationSpellService(AppDatabase db)
|
|||||||
public async Task<SnAffiliationSpell> CreateAffiliationSpell(Guid accountId, string? spellWord)
|
public async Task<SnAffiliationSpell> CreateAffiliationSpell(Guid accountId, string? spellWord)
|
||||||
{
|
{
|
||||||
spellWord ??= _GenerateRandomString(8);
|
spellWord ??= _GenerateRandomString(8);
|
||||||
var hasTaken = await db.AffiliationSpells.AnyAsync(s => s.Spell == spellWord);
|
if (await CheckAffiliationSpellHasTaken(spellWord))
|
||||||
if (hasTaken) throw new InvalidOperationException("The spell has been taken.");
|
throw new InvalidOperationException("The spell has been taken.");
|
||||||
|
|
||||||
var spell = new SnAffiliationSpell
|
var spell = new SnAffiliationSpell
|
||||||
{
|
{
|
||||||
@@ -23,10 +23,26 @@ public class AffiliationSpellService(AppDatabase db)
|
|||||||
return spell;
|
return spell;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<SnAffiliationSpell?> GetAffiliationSpell(string spellWord)
|
public async Task<SnAffiliationResult> CreateAffiliationResult(string spellWord, string resourceId)
|
||||||
{
|
{
|
||||||
var spell = await db.AffiliationSpells.FirstOrDefaultAsync(s => s.Spell == spellWord);
|
var spell =
|
||||||
return spell;
|
await db.AffiliationSpells.FirstOrDefaultAsync(a => a.Spell == spellWord);
|
||||||
|
if (spell is null) throw new InvalidOperationException("The spell was not found.");
|
||||||
|
|
||||||
|
var result = new SnAffiliationResult
|
||||||
|
{
|
||||||
|
Spell = spell,
|
||||||
|
ResourceIdentifier = resourceId
|
||||||
|
};
|
||||||
|
db.AffiliationResults.Add(result);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> CheckAffiliationSpellHasTaken(string spellWord)
|
||||||
|
{
|
||||||
|
return await db.AffiliationSpells.AnyAsync(s => s.Spell == spellWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string _GenerateRandomString(int length)
|
private static string _GenerateRandomString(int length)
|
||||||
@@ -40,6 +56,7 @@ public class AffiliationSpellService(AppDatabase db)
|
|||||||
rng.GetBytes(bytes);
|
rng.GetBytes(bytes);
|
||||||
result[i] = chars[bytes[0] % chars.Length];
|
result[i] = chars[bytes[0] % chars.Length];
|
||||||
}
|
}
|
||||||
|
|
||||||
return new string(result);
|
return new string(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,7 @@ using NodaTime.Serialization.SystemTextJson;
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using DysonNetwork.Pass.Account.Presences;
|
using DysonNetwork.Pass.Account.Presences;
|
||||||
|
using DysonNetwork.Pass.Affiliation;
|
||||||
using DysonNetwork.Pass.Auth.OidcProvider.Options;
|
using DysonNetwork.Pass.Auth.OidcProvider.Options;
|
||||||
using DysonNetwork.Pass.Auth.OidcProvider.Services;
|
using DysonNetwork.Pass.Auth.OidcProvider.Services;
|
||||||
using DysonNetwork.Pass.Credit;
|
using DysonNetwork.Pass.Credit;
|
||||||
@@ -159,6 +160,7 @@ public static class ServiceCollectionExtensions
|
|||||||
services.AddScoped<ExperienceService>();
|
services.AddScoped<ExperienceService>();
|
||||||
services.AddScoped<RealmService>();
|
services.AddScoped<RealmService>();
|
||||||
services.AddScoped<LotteryService>();
|
services.AddScoped<LotteryService>();
|
||||||
|
services.AddScoped<AffiliationSpellService>();
|
||||||
|
|
||||||
services.AddScoped<SpotifyPresenceService>();
|
services.AddScoped<SpotifyPresenceService>();
|
||||||
services.AddScoped<SteamPresenceService>();
|
services.AddScoped<SteamPresenceService>();
|
||||||
|
|||||||
Reference in New Issue
Block a user