forked from Kieran/void.cat
Add swagger and docs
This commit is contained in:
parent
22877e214b
commit
d7d092bc63
3
.gitignore
vendored
3
.gitignore
vendored
@ -15,4 +15,5 @@ out/
|
|||||||
sw.js
|
sw.js
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.idea/
|
.idea/
|
||||||
appsettings.*.json
|
appsettings.*.json
|
||||||
|
VoidCat.xml
|
@ -20,6 +20,11 @@ public class AdminController : Controller
|
|||||||
_fileInfo = fileInfo;
|
_fileInfo = fileInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List all files in the system
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Page request</param>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("file")]
|
[Route("file")]
|
||||||
public async Task<RenderedResults<PublicVoidFile>> ListFiles([FromBody] PagedRequest request)
|
public async Task<RenderedResults<PublicVoidFile>> ListFiles([FromBody] PagedRequest request)
|
||||||
@ -27,6 +32,10 @@ public class AdminController : Controller
|
|||||||
return await (await _fileStore.ListFiles(request)).GetResults();
|
return await (await _fileStore.ListFiles(request)).GetResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delete a file from the system
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">Id of the file to delete</param>
|
||||||
[HttpDelete]
|
[HttpDelete]
|
||||||
[Route("file/{id}")]
|
[Route("file/{id}")]
|
||||||
public async Task DeleteFile([FromRoute] string id)
|
public async Task DeleteFile([FromRoute] string id)
|
||||||
@ -36,6 +45,11 @@ public class AdminController : Controller
|
|||||||
await _fileInfo.Delete(gid);
|
await _fileInfo.Delete(gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List all users in the system
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Page request</param>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("user")]
|
[Route("user")]
|
||||||
public async Task<RenderedResults<PrivateVoidUser>> ListUsers([FromBody] PagedRequest request)
|
public async Task<RenderedResults<PrivateVoidUser>> ListUsers([FromBody] PagedRequest request)
|
||||||
|
@ -22,6 +22,11 @@ public class AuthController : Controller
|
|||||||
_settings = settings;
|
_settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Login to a user account
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="req"></param>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("login")]
|
[Route("login")]
|
||||||
public async Task<LoginResponse> Login([FromBody] LoginRequest req)
|
public async Task<LoginResponse> Login([FromBody] LoginRequest req)
|
||||||
@ -45,6 +50,11 @@ public class AuthController : Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Register a new account
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="req"></param>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("register")]
|
[Route("register")]
|
||||||
public async Task<LoginResponse> Register([FromBody] LoginRequest req)
|
public async Task<LoginResponse> Register([FromBody] LoginRequest req)
|
||||||
|
@ -31,6 +31,10 @@ public class DownloadController : Controller
|
|||||||
return SetupDownload(gid);
|
return SetupDownload(gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Download a specific file by Id
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id"></param>
|
||||||
[ResponseCache(Location = ResponseCacheLocation.Any, Duration = 86400)]
|
[ResponseCache(Location = ResponseCacheLocation.Any, Duration = 86400)]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("{id}")]
|
[Route("{id}")]
|
||||||
|
@ -16,6 +16,11 @@ namespace VoidCat.Controllers
|
|||||||
_fileStore = fileStore;
|
_fileStore = fileStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return system info
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[ResponseCache(Location = ResponseCacheLocation.Any, Duration = 60)]
|
[ResponseCache(Location = ResponseCacheLocation.Any, Duration = 60)]
|
||||||
public async Task<GlobalStats> GetGlobalStats()
|
public async Task<GlobalStats> GetGlobalStats()
|
||||||
@ -33,6 +38,11 @@ namespace VoidCat.Controllers
|
|||||||
return new(bw, bytes, count, BuildInfo.GetBuildInfo());
|
return new(bw, bytes, count, BuildInfo.GetBuildInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get stats for a specific file
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("{id}")]
|
[Route("{id}")]
|
||||||
public async Task<FileStats> GetFileStats([FromRoute] string id)
|
public async Task<FileStats> GetFileStats([FromRoute] string id)
|
||||||
|
@ -27,6 +27,20 @@ namespace VoidCat.Controllers
|
|||||||
_fileInfo = fileInfo;
|
_fileInfo = fileInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Primary upload endpoint
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Additional optional headers can be included to provide details about the file being uploaded:
|
||||||
|
///
|
||||||
|
/// `V-Content-Type` - Sets the `mimeType` of the file and is used on the preview page to display the file.
|
||||||
|
/// `V-Filename` - Sets the filename of the file.
|
||||||
|
/// `V-Description` - Sets the description of the file.
|
||||||
|
/// `V-Full-Digest` - Include a SHA256 hash of the entire file for verification purposes.
|
||||||
|
/// `V-Digest` - A SHA256 hash of the data you are sending in this request.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="cli">True if you want to return only the url of the file in the response</param>
|
||||||
|
/// <returns>Returns <see cref="UploadResult"/></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[DisableRequestSizeLimit]
|
[DisableRequestSizeLimit]
|
||||||
[DisableFormValueModelBinding]
|
[DisableFormValueModelBinding]
|
||||||
@ -67,6 +81,18 @@ namespace VoidCat.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Append data onto a file
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This endpoint is mainly used to bypass file upload limits enforced by CloudFlare.
|
||||||
|
/// Clients should split their uploads into segments, upload the first segment to the regular
|
||||||
|
/// upload endpoint, use the `editSecret` to append data to the file.
|
||||||
|
///
|
||||||
|
/// Set the edit secret in the header `V-EditSecret` otherwise you will not be able to append data.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[DisableRequestSizeLimit]
|
[DisableRequestSizeLimit]
|
||||||
[DisableFormValueModelBinding]
|
[DisableFormValueModelBinding]
|
||||||
@ -97,6 +123,11 @@ namespace VoidCat.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return information about a specific file
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("{id}")]
|
[Route("{id}")]
|
||||||
public ValueTask<PublicVoidFile?> GetInfo([FromRoute] string id)
|
public ValueTask<PublicVoidFile?> GetInfo([FromRoute] string id)
|
||||||
@ -104,6 +135,11 @@ namespace VoidCat.Controllers
|
|||||||
return _fileInfo.Get(id.FromBase58Guid());
|
return _fileInfo.Get(id.FromBase58Guid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a paywall order to pay
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">File id</param>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("{id}/paywall")]
|
[Route("{id}/paywall")]
|
||||||
public async ValueTask<PaywallOrder?> CreateOrder([FromRoute] string id)
|
public async ValueTask<PaywallOrder?> CreateOrder([FromRoute] string id)
|
||||||
@ -116,6 +152,12 @@ namespace VoidCat.Controllers
|
|||||||
return await provider.CreateOrder(file!);
|
return await provider.CreateOrder(file!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return the status of an order
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">File id</param>
|
||||||
|
/// <param name="order">Order id</param>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("{id}/paywall/{order:guid}")]
|
[Route("{id}/paywall/{order:guid}")]
|
||||||
public async ValueTask<PaywallOrder?> GetOrderStatus([FromRoute] string id, [FromRoute] Guid order)
|
public async ValueTask<PaywallOrder?> GetOrderStatus([FromRoute] string id, [FromRoute] Guid order)
|
||||||
@ -127,6 +169,12 @@ namespace VoidCat.Controllers
|
|||||||
return await provider.GetOrderStatus(order);
|
return await provider.GetOrderStatus(order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update the paywall config
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">File id</param>
|
||||||
|
/// <param name="req">Requested config to set on the file</param>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("{id}/paywall")]
|
[Route("{id}/paywall")]
|
||||||
public async Task<IActionResult> SetPaywallConfig([FromRoute] string id, [FromBody] SetPaywallConfigRequest req)
|
public async Task<IActionResult> SetPaywallConfig([FromRoute] string id, [FromBody] SetPaywallConfigRequest req)
|
||||||
|
@ -18,13 +18,23 @@ public class UserController : Controller
|
|||||||
_emailVerification = emailVerification;
|
_emailVerification = emailVerification;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return user profile
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// You do not need to be logged in to return a user profile if their profile is set to public.
|
||||||
|
///
|
||||||
|
/// You may also use `me` as the `id` to get the logged in users profile.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="id">User id to load</param>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IActionResult> GetUser([FromRoute] string id)
|
public async Task<IActionResult> GetUser([FromRoute] string id)
|
||||||
{
|
{
|
||||||
var loggedUser = HttpContext.GetUserId();
|
var loggedUser = HttpContext.GetUserId();
|
||||||
var isMe = id.Equals("me", StringComparison.InvariantCultureIgnoreCase);
|
var isMe = id.Equals("me", StringComparison.InvariantCultureIgnoreCase);
|
||||||
if (isMe && !loggedUser.HasValue) return Unauthorized();
|
if (isMe && !loggedUser.HasValue) return Unauthorized();
|
||||||
|
|
||||||
var requestedId = isMe ? loggedUser!.Value : id.FromBase58Guid();
|
var requestedId = isMe ? loggedUser!.Value : id.FromBase58Guid();
|
||||||
if (loggedUser == requestedId)
|
if (loggedUser == requestedId)
|
||||||
{
|
{
|
||||||
@ -39,6 +49,13 @@ public class UserController : Controller
|
|||||||
return Json(user);
|
return Json(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update profile settings
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
|
/// <param name="id">User id</param>
|
||||||
|
/// <param name="user"></param>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<IActionResult> UpdateUser([FromRoute] string id, [FromBody] PublicVoidUser user)
|
public async Task<IActionResult> UpdateUser([FromRoute] string id, [FromBody] PublicVoidUser user)
|
||||||
{
|
{
|
||||||
@ -51,6 +68,16 @@ public class UserController : Controller
|
|||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return a list of files which the user has uploaded
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This will return files if the profile has public uploads set on their profile.
|
||||||
|
/// Otherwise you can return your own uploaded files if you are logged in.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="id">User id</param>
|
||||||
|
/// <param name="request">Page request</param>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("files")]
|
[Route("files")]
|
||||||
public async Task<IActionResult> ListUserFiles([FromRoute] string id,
|
public async Task<IActionResult> ListUserFiles([FromRoute] string id,
|
||||||
@ -71,6 +98,11 @@ public class UserController : Controller
|
|||||||
return Json(await results.GetResults());
|
return Json(await results.GetResults());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Send a verification code for a specific user
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">User id to send code for</param>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("verify")]
|
[Route("verify")]
|
||||||
public async Task<IActionResult> SendVerificationCode([FromRoute] string id)
|
public async Task<IActionResult> SendVerificationCode([FromRoute] string id)
|
||||||
@ -85,6 +117,12 @@ public class UserController : Controller
|
|||||||
return Accepted();
|
return Accepted();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Confirm email verification code
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">User id to verify</param>
|
||||||
|
/// <param name="code">Verification code to check</param>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("verify")]
|
[Route("verify")]
|
||||||
public async Task<IActionResult> VerifyCode([FromRoute] string id, [FromBody] string code)
|
public async Task<IActionResult> VerifyCode([FromRoute] string id, [FromBody] string code)
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
namespace VoidCat.Model.Exceptions;
|
namespace VoidCat.Model.Exceptions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specified file was not found
|
||||||
|
/// </summary>
|
||||||
public class VoidFileNotFoundException : Exception
|
public class VoidFileNotFoundException : Exception
|
||||||
{
|
{
|
||||||
public VoidFileNotFoundException(Guid id)
|
public VoidFileNotFoundException(Guid id)
|
||||||
|
17
VoidCat/Model/Exceptions/VoidInvalidIdException.cs
Normal file
17
VoidCat/Model/Exceptions/VoidInvalidIdException.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
namespace VoidCat.Model.Exceptions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specified id was not in the correct format
|
||||||
|
/// </summary>
|
||||||
|
public class VoidInvalidIdException : Exception
|
||||||
|
{
|
||||||
|
public VoidInvalidIdException(string id)
|
||||||
|
{
|
||||||
|
Id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The id in question
|
||||||
|
/// </summary>
|
||||||
|
public string Id { get; }
|
||||||
|
}
|
@ -1,5 +1,8 @@
|
|||||||
namespace VoidCat.Model.Exceptions;
|
namespace VoidCat.Model.Exceptions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Operation is not allowed
|
||||||
|
/// </summary>
|
||||||
public class VoidNotAllowedException : Exception
|
public class VoidNotAllowedException : Exception
|
||||||
{
|
{
|
||||||
public VoidNotAllowedException(string message) : base(message)
|
public VoidNotAllowedException(string message) : base(message)
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
using System.IdentityModel.Tokens.Jwt;
|
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Amazon;
|
using Amazon;
|
||||||
using Amazon.Runtime;
|
using Amazon.Runtime;
|
||||||
using Amazon.S3;
|
using Amazon.S3;
|
||||||
|
using VoidCat.Model.Exceptions;
|
||||||
|
|
||||||
namespace VoidCat.Model;
|
namespace VoidCat.Model;
|
||||||
|
|
||||||
@ -42,7 +42,9 @@ public static class Extensions
|
|||||||
public static Guid FromBase58Guid(this string base58)
|
public static Guid FromBase58Guid(this string base58)
|
||||||
{
|
{
|
||||||
var enc = new NBitcoin.DataEncoders.Base58Encoder();
|
var enc = new NBitcoin.DataEncoders.Base58Encoder();
|
||||||
return new Guid(enc.DecodeData(base58));
|
var guidBytes = enc.DecodeData(base58);
|
||||||
|
if (guidBytes.Length != 16) throw new VoidInvalidIdException(base58);
|
||||||
|
return new Guid(guidBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ToBase58(this Guid id)
|
public static string ToBase58(this Guid id)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
using Microsoft.OpenApi.Models;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Prometheus;
|
using Prometheus;
|
||||||
using StackExchange.Redis;
|
using StackExchange.Redis;
|
||||||
@ -48,6 +50,32 @@ if (useRedis)
|
|||||||
}
|
}
|
||||||
|
|
||||||
services.AddHttpClient();
|
services.AddHttpClient();
|
||||||
|
services.AddSwaggerGen(c =>
|
||||||
|
{
|
||||||
|
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
|
||||||
|
{
|
||||||
|
In = ParameterLocation.Header,
|
||||||
|
Description = "Please insert JWT with Bearer into field",
|
||||||
|
Name = "Authorization",
|
||||||
|
Type = SecuritySchemeType.ApiKey
|
||||||
|
});
|
||||||
|
c.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||||
|
{
|
||||||
|
{
|
||||||
|
new OpenApiSecurityScheme
|
||||||
|
{
|
||||||
|
Reference = new OpenApiReference
|
||||||
|
{
|
||||||
|
Type = ReferenceType.SecurityScheme,
|
||||||
|
Id = "Bearer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new string[] { }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var path = Path.Combine(AppContext.BaseDirectory, $"{Assembly.GetExecutingAssembly().GetName().Name}.xml");
|
||||||
|
c.IncludeXmlComments(path);
|
||||||
|
});
|
||||||
services.AddCors(opt =>
|
services.AddCors(opt =>
|
||||||
{
|
{
|
||||||
opt.AddDefaultPolicy(p =>
|
opt.AddDefaultPolicy(p =>
|
||||||
@ -76,7 +104,10 @@ services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddAuthorization((opt) => { opt.AddPolicy(Policies.RequireAdmin, (auth) => { auth.RequireRole(Roles.Admin); }); });
|
services.AddAuthorization((opt) =>
|
||||||
|
{
|
||||||
|
opt.AddPolicy(Policies.RequireAdmin, (auth) => { auth.RequireRole(Roles.Admin); });
|
||||||
|
});
|
||||||
|
|
||||||
// void.cat services
|
// void.cat services
|
||||||
//
|
//
|
||||||
@ -135,6 +166,8 @@ app.UseStaticFiles();
|
|||||||
|
|
||||||
app.UseRouting();
|
app.UseRouting();
|
||||||
app.UseCors();
|
app.UseCors();
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
app.UseAuthentication();
|
app.UseAuthentication();
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
|
||||||
@ -148,4 +181,4 @@ app.UseEndpoints(ep =>
|
|||||||
#endif
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
@ -86,9 +86,12 @@ public class UserStore : IUserStore
|
|||||||
var oldUser = await Get<InternalVoidUser>(newUser.Id);
|
var oldUser = await Get<InternalVoidUser>(newUser.Id);
|
||||||
if (oldUser == null) return;
|
if (oldUser == null) return;
|
||||||
|
|
||||||
|
//retain flags
|
||||||
|
var isEmailVerified = oldUser.Flags.HasFlag(VoidUserFlags.EmailVerified);
|
||||||
|
|
||||||
// update only a few props
|
// update only a few props
|
||||||
oldUser.Avatar = newUser.Avatar;
|
oldUser.Avatar = newUser.Avatar;
|
||||||
oldUser.Flags = newUser.Flags;
|
oldUser.Flags = newUser.Flags | (isEmailVerified ? VoidUserFlags.EmailVerified : 0);
|
||||||
oldUser.DisplayName = newUser.DisplayName;
|
oldUser.DisplayName = newUser.DisplayName;
|
||||||
|
|
||||||
await Set(newUser.Id, oldUser);
|
await Set(newUser.Id, oldUser);
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
<DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
|
<DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
|
||||||
<HostSPA>True</HostSPA>
|
<HostSPA>True</HostSPA>
|
||||||
<DefineConstants Condition="'$(HostSPA)' == 'True'">$(DefineConstants);HostSPA</DefineConstants>
|
<DefineConstants Condition="'$(HostSPA)' == 'True'">$(DefineConstants);HostSPA</DefineConstants>
|
||||||
|
<DocumentationFile>$(AssemblyName).xml</DocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
Loading…
Reference in New Issue
Block a user