Add JWT auth, token service & Neutrino endpoint

This commit is contained in:
Holden
2026-06-19 12:25:45 -05:00
parent 608def3ac8
commit 3eebfc9ba2
27 changed files with 581 additions and 51 deletions

View File

@@ -0,0 +1,25 @@
namespace API.Contracts.Neutrino.Enums;
public enum AuthenticationResultCode
{
/// <summary>
/// Indicates that authentication is incomplete and only the associated data is returned.
/// </summary>
/// <remarks>This value is typically used when launching the game with no account, in which data to authenticate is not provided.</remarks>
AuthenticationIncomplete,
/// <summary>
/// Indicates that authentication was successful.
/// </summary>
AuthenticationSuccessful,
/// <summary>
/// Indicates that authentication failed due to incorrect credentials.
/// </summary>
AuthenticationFailedWrongCredentials,
/// <summary>
/// Indicates that the parameters provided to the operation are invalid.
/// </summary>
InvalidParameters
}

View File

@@ -0,0 +1,15 @@
using System.Text.Json.Serialization;
namespace API.Contracts.Neutrino.Requests;
public class NeutrinoAuthenticateRequest
{
[JsonPropertyName("profileId")]
public Guid ProfileId;
[JsonPropertyName("accessToken")]
public required string AccessToken;
[JsonPropertyName("appVersion")]
public required string AppVersion;
}

View File

@@ -0,0 +1,28 @@
using System.Text.Json.Serialization;
using API.Contracts.Neutrino.Enums;
namespace API.Contracts.Neutrino.Responses;
// {"ResultCode":1,"UserId":"their user id","Nickname":"splotybean"}
public class NeutrinoAuthenticateResponse : NeutrinoResultCodeResponse
{
public static NeutrinoAuthenticateResponse Success(string userId, string nickname) => new()
{
ResultCode = (byte)AuthenticationResultCode.AuthenticationSuccessful,
UserId = userId,
Nickname = nickname
};
public static NeutrinoAuthenticateResponse Failure(AuthenticationResultCode error) => new()
{
ResultCode = (byte)error
};
[JsonPropertyName(name: "UserId")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? UserId { get; set; }
[JsonPropertyName(name: "Nickname")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Nickname { get; set; }
}

View File

@@ -0,0 +1,31 @@
using System.Text.Json.Serialization;
namespace API.Contracts.Neutrino.Responses;
public class NeutrinoResultCodeResponse
{
public static NeutrinoResultCodeResponse Success() => new NeutrinoResultCodeResponse
{
ResultCode = 0
};
public static NeutrinoResultCodeResponse Failure(byte resultCode, string? message = null)
{
return new NeutrinoResultCodeResponse
{
Message = message,
ResultCode = resultCode
};
}
[JsonPropertyName(name: "Data")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Data { get; set; }
[JsonPropertyName(name: "Message")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Message { get; set; }
[JsonPropertyName(name: "ResultCode")]
public byte ResultCode { get; set; }
}

View File

@@ -1,8 +1,16 @@
using RecNet.Application.Profiles;
using System.Text.Json.Serialization;
using RecNet.Application.Profiles;
namespace API.Contracts.Profiles.Responses;
public class LoginResponse
{
[JsonPropertyName("Profile")]
public required ProfileDTO Profile { get; set; }
[JsonPropertyName("AccessToken")]
public required string AccessToken { get; set; }
[JsonPropertyName("ExpiresIn")]
public required int ExpiresIn { get; set; }
}