Merged PR 92: CurrentUser into main

This commit is contained in:
Dominic Villemure
2024-07-05 01:20:23 +00:00
14 changed files with 1197 additions and 19 deletions

View File

@@ -1,4 +1,4 @@
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using Hutopy.Application.Common.Interfaces; using Hutopy.Application.Common.Interfaces;
using Hutopy.Application.Common.Models; using Hutopy.Application.Common.Models;
using Hutopy.Application.Users.Models; using Hutopy.Application.Users.Models;
@@ -19,6 +19,7 @@ public class UpdateCurrentUserCommand : IRequest<string>
public required string Description { get; init; } public required string Description { get; init; }
public required SocialNetworksModel SocialNetworks { get; init; } public required SocialNetworksModel SocialNetworks { get; init; }
public required ProfileColorsModel ProfileColors { get; init; } public required ProfileColorsModel ProfileColors { get; init; }
[NotMapped] [NotMapped]
private class Mapping : Profile private class Mapping : Profile

View File

@@ -28,15 +28,17 @@ public class GetMinimalUserQueryHandler(
{ {
identityUser = await identityService.GetUserByUserNameAsync(request.UserName); identityUser = await identityService.GetUserByUserNameAsync(request.UserName);
} }
var user = new MinimalUserDto var user = new MinimalUserDto
{ {
FirstName = identityUser?.FirstName ?? string.Empty, FirstName = identityUser?.FirstName ?? string.Empty,
LastName = identityUser?.LastName ?? string.Empty, LastName = identityUser?.LastName ?? string.Empty,
UserName = identityUser?.UserName ?? string.Empty UserName = identityUser?.UserName ?? string.Empty,
SocialNetworks = identityUser?.SocialNetworks ?? new(),
ProfileColors = identityUser?.ProfileColors ?? new(),
StoredDataUrls = identityUser?.StoredDataUrls ?? new(),
}; };
return user; return user;
} }
} }

View File

@@ -1,3 +1,5 @@
using Hutopy.Application.Users.Models;
namespace Hutopy.Application.Users.Queries.GetMinimalUser; namespace Hutopy.Application.Users.Queries.GetMinimalUser;
public class MinimalUserDto public class MinimalUserDto
@@ -5,4 +7,8 @@ public class MinimalUserDto
public required string FirstName { get; init; } public required string FirstName { get; init; }
public required string LastName { get; init; } public required string LastName { get; init; }
public required string UserName { get; init; } = String.Empty; public required string UserName { get; init; } = String.Empty;
public SocialNetworksModel SocialNetworks { get; init; } = new();
public ProfileColorsModel ProfileColors { get; init; } = new();
public StoredDataUrlsModel StoredDataUrls { get; init; } = new();
} }

View File

@@ -1,4 +1,7 @@
using Hutopy.Domain.Constants; using System;
using System.Linq;
using System.Threading.Tasks;
using Hutopy.Domain.Constants;
using Hutopy.Infrastructure.Identity; using Hutopy.Infrastructure.Identity;
using Hutopy.Infrastructure.Identity.OwnedEntities; using Hutopy.Infrastructure.Identity.OwnedEntities;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;

View File

@@ -1,4 +1,8 @@
using Microsoft.AspNetCore.Identity; using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;

View File

@@ -1,4 +1,5 @@
using Hutopy.Application.Common.Models; using System.Linq;
using Hutopy.Application.Common.Models;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
namespace Hutopy.Infrastructure.Identity; namespace Hutopy.Infrastructure.Identity;

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using Google.Apis.Oauth2.v2.Data; using Google.Apis.Oauth2.v2.Data;
using System.Security.Claims; using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Hutopy.Application.Common.Interfaces; using Hutopy.Application.Common.Interfaces;
using Hutopy.Application.Common.Models; using Hutopy.Application.Common.Models;
@@ -41,10 +42,42 @@ public class IdentityService(
var userModel = new UserModel() var userModel = new UserModel()
{ {
Id = response.Id, Id = response.Id,
UserName = response.UserName, UserName = response.UserName ?? string.Empty,
FirstName = response.FirstName, FirstName = response.FirstName,
LastName = response.LastName, LastName = response.LastName,
Email = response.Email, Email = response.Email ?? string.Empty,
Occupation = response.Occupation,
PhoneNumber = response.PhoneNumber ?? string.Empty,
BirthDate = response.BirthDate,
Country = response.Country,
City = response.City,
Address = response.Address,
About = response.About,
Description = response.Description,
SocialNetworks = new SocialNetworksModel
{
FacebookUrl = response.SocialNetworks.FacebookUrl,
InstagramUrl = response.SocialNetworks.InstagramUrl,
XUrl = response.SocialNetworks.XUrl,
LinkedInUrl = response.SocialNetworks.LinkedInUrl,
TikTokUrl = response.SocialNetworks.TikTokUrl,
YoutubeUrl = response.SocialNetworks.YoutubeUrl,
RedditUrl = response.SocialNetworks.RedditUrl,
YourWebsiteUrl = response.SocialNetworks.YourWebsiteUrl,
},
ProfileColors = new ProfileColorsModel
{
BannerTop = response.ProfileColors.BannerTop,
BannerBottom = response.ProfileColors.BannerBottom,
Accent = response.ProfileColors.Accent,
Menu = response.ProfileColors.Menu
},
StoredDataUrls = new StoredDataUrlsModel
{
ProfilePictureUrl = response.StoredDataUrls.ProfilePictureUrl,
BannerPictureUrl = response.StoredDataUrls.BannerPictureUrl,
WebsiteIconUrl = response.StoredDataUrls.WebsiteIconUrl,
}
}; };
return userModel; return userModel;
@@ -402,7 +435,7 @@ public class IdentityService(
email: user.Email, email: user.Email,
firstname: user.FirstName, firstname: user.FirstName,
lastname: user.LastName, lastname: user.LastName,
portraitUrl: user.ProfilePictureUrl); profilePictureUrl: user.StoredDataUrls.ProfilePictureUrl);
return token; return token;
} }

View File

@@ -1,4 +1,6 @@
using Hutopy.Application.Common.Interfaces; using System;
using System.Threading.Tasks;
using Hutopy.Application.Common.Interfaces;
using Hutopy.Application.Common.Models; using Hutopy.Application.Common.Models;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;

View File

@@ -0,0 +1,500 @@
// <auto-generated />
using System;
using Hutopy.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Hutopy.Infrastructure.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20240701072549_AddPortraitUrlToUser")]
partial class AddPortraitUrlToUser
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("Hutopy.Domain.Entities.FutureCreator", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTimeOffset>("Created")
.HasColumnType("datetimeoffset");
b.Property<string>("CreatedBy")
.HasColumnType("nvarchar(max)");
b.Property<string>("EmailAddress")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTimeOffset>("LastModified")
.HasColumnType("datetimeoffset");
b.Property<string>("LastModifiedBy")
.HasColumnType("nvarchar(max)");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("PhoneNumber")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("ReasonToJoin")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("SocialNetworkAccount")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("FutureCreators");
});
modelBuilder.Entity("Hutopy.Domain.Entities.UserTransaction", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<decimal>("Amount")
.HasPrecision(18, 2)
.HasColumnType("decimal(18,2)");
b.Property<string>("ApplicationUserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.Property<DateTimeOffset>("Created")
.HasColumnType("datetimeoffset");
b.Property<string>("CreatedBy")
.HasColumnType("nvarchar(max)");
b.Property<string>("Currency")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsConfirmed")
.HasColumnType("bit");
b.Property<DateTimeOffset>("LastModified")
.HasColumnType("datetimeoffset");
b.Property<string>("LastModifiedBy")
.HasColumnType("nvarchar(max)");
b.Property<bool>("Paid")
.HasColumnType("bit");
b.Property<string>("StripeBillingDetailEmail")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StripeBillingDetailName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StripeChargeId")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StripeEventId")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StripePaymentIntent")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StripePaymentMethod")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StripeReceiptUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("TipMessage")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.HasIndex("ApplicationUserId");
b.ToTable("UserTransactions");
});
modelBuilder.Entity("Hutopy.Infrastructure.Identity.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<string>("About")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<string>("Address")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("BirthDate")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("City")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");
b.Property<string>("Country")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("bit");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("LockoutEnabled")
.HasColumnType("bit");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetimeoffset");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("Occupation")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("PasswordHash")
.HasColumnType("nvarchar(max)");
b.Property<string>("PhoneNumber")
.HasColumnType("nvarchar(max)");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("bit");
b.Property<string>("PortraitUrl")
.HasColumnType("nvarchar(max)");
b.Property<string>("SecurityStamp")
.HasColumnType("nvarchar(max)");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("bit");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex")
.HasFilter("[NormalizedUserName] IS NOT NULL");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex")
.HasFilter("[NormalizedName] IS NOT NULL");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("nvarchar(450)");
b.Property<string>("ProviderKey")
.HasColumnType("nvarchar(450)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("RoleId")
.HasColumnType("nvarchar(450)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("LoginProvider")
.HasColumnType("nvarchar(450)");
b.Property<string>("Name")
.HasColumnType("nvarchar(450)");
b.Property<string>("Value")
.HasColumnType("nvarchar(max)");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Hutopy.Domain.Entities.UserTransaction", b =>
{
b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("ApplicationUserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Hutopy.Infrastructure.Identity.ApplicationUser", b =>
{
b.OwnsOne("Hutopy.Infrastructure.Identity.OwnedEntities.SocialNetworks", "SocialNetworks", b1 =>
{
b1.Property<string>("ApplicationUserId")
.HasColumnType("nvarchar(450)");
b1.Property<string>("FacebookUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("InstagramUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("LinkedInUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("RedditUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("TikTokUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("XUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("YourWebsiteUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("YoutubeUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.HasKey("ApplicationUserId");
b1.ToTable("ApplicationUser_SocialNetworks", (string)null);
b1.WithOwner()
.HasForeignKey("ApplicationUserId");
});
b.Navigation("SocialNetworks")
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,28 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Hutopy.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class AddPortraitUrlToUser : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "PortraitUrl",
table: "AspNetUsers",
type: "nvarchar(max)",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "PortraitUrl",
table: "AspNetUsers");
}
}
}

View File

@@ -0,0 +1,560 @@
// <auto-generated />
using System;
using Hutopy.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace Hutopy.Infrastructure.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20240705010235_RemovePortraitUrl")]
partial class RemovePortraitUrl
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("Hutopy.Domain.Entities.FutureCreator", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<DateTimeOffset>("Created")
.HasColumnType("datetimeoffset");
b.Property<string>("CreatedBy")
.HasColumnType("nvarchar(max)");
b.Property<string>("EmailAddress")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTimeOffset>("LastModified")
.HasColumnType("datetimeoffset");
b.Property<string>("LastModifiedBy")
.HasColumnType("nvarchar(max)");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("PhoneNumber")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("ReasonToJoin")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("SocialNetworkAccount")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("FutureCreators");
});
modelBuilder.Entity("Hutopy.Domain.Entities.UserTransaction", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<decimal>("Amount")
.HasPrecision(18, 2)
.HasColumnType("decimal(18,2)");
b.Property<string>("ApplicationUserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.Property<DateTimeOffset>("Created")
.HasColumnType("datetimeoffset");
b.Property<string>("CreatedBy")
.HasColumnType("nvarchar(max)");
b.Property<string>("Currency")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsConfirmed")
.HasColumnType("bit");
b.Property<DateTimeOffset>("LastModified")
.HasColumnType("datetimeoffset");
b.Property<string>("LastModifiedBy")
.HasColumnType("nvarchar(max)");
b.Property<bool>("Paid")
.HasColumnType("bit");
b.Property<string>("StripeBillingDetailEmail")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StripeBillingDetailName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StripeChargeId")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StripeEventId")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StripePaymentIntent")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StripePaymentMethod")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StripeReceiptUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("TipMessage")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.HasIndex("ApplicationUserId");
b.ToTable("UserTransactions");
});
modelBuilder.Entity("Hutopy.Infrastructure.Identity.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<string>("About")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
b.Property<string>("Address")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("BirthDate")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("City")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");
b.Property<string>("Country")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("CreatorAlias")
.HasColumnType("nvarchar(max)");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<bool>("EmailConfirmed")
.HasColumnType("bit");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<bool>("LockoutEnabled")
.HasColumnType("bit");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetimeoffset");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("Occupation")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("PasswordHash")
.HasColumnType("nvarchar(max)");
b.Property<string>("PhoneNumber")
.HasColumnType("nvarchar(max)");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("bit");
b.Property<string>("SecurityStamp")
.HasColumnType("nvarchar(max)");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("bit");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex")
.HasFilter("[NormalizedUserName] IS NOT NULL");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("nvarchar(450)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex")
.HasFilter("[NormalizedName] IS NOT NULL");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("nvarchar(450)");
b.Property<string>("ProviderKey")
.HasColumnType("nvarchar(450)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("nvarchar(450)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("RoleId")
.HasColumnType("nvarchar(450)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("nvarchar(450)");
b.Property<string>("LoginProvider")
.HasColumnType("nvarchar(450)");
b.Property<string>("Name")
.HasColumnType("nvarchar(450)");
b.Property<string>("Value")
.HasColumnType("nvarchar(max)");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Hutopy.Domain.Entities.UserTransaction", b =>
{
b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("ApplicationUserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Hutopy.Infrastructure.Identity.ApplicationUser", b =>
{
b.OwnsOne("Hutopy.Infrastructure.Identity.OwnedEntities.ProfileColors", "ProfileColors", b1 =>
{
b1.Property<string>("ApplicationUserId")
.HasColumnType("nvarchar(450)");
b1.Property<string>("Accent")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("BannerBottom")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("BannerTop")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("Menu")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.HasKey("ApplicationUserId");
b1.ToTable("ApplicationUser_ProfileColors", (string)null);
b1.WithOwner()
.HasForeignKey("ApplicationUserId");
});
b.OwnsOne("Hutopy.Infrastructure.Identity.OwnedEntities.SocialNetworks", "SocialNetworks", b1 =>
{
b1.Property<string>("ApplicationUserId")
.HasColumnType("nvarchar(450)");
b1.Property<string>("FacebookUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("InstagramUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("LinkedInUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("RedditUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("TikTokUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("XUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("YourWebsiteUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("YoutubeUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.HasKey("ApplicationUserId");
b1.ToTable("ApplicationUser_SocialNetworks", (string)null);
b1.WithOwner()
.HasForeignKey("ApplicationUserId");
});
b.OwnsOne("Hutopy.Infrastructure.Identity.OwnedEntities.StoredDataUrls", "StoredDataUrls", b1 =>
{
b1.Property<string>("ApplicationUserId")
.HasColumnType("nvarchar(450)");
b1.Property<string>("BannerPictureUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("ProfilePictureUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.Property<string>("WebsiteIconUrl")
.IsRequired()
.HasColumnType("nvarchar(max)");
b1.HasKey("ApplicationUserId");
b1.ToTable("ApplicationUser_StoredDataUrls", (string)null);
b1.WithOwner()
.HasForeignKey("ApplicationUserId");
});
b.Navigation("ProfileColors")
.IsRequired();
b.Navigation("SocialNetworks")
.IsRequired();
b.Navigation("StoredDataUrls")
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,28 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Hutopy.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class RemovePortraitUrl : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "PortraitUrl",
table: "AspNetUsers");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "PortraitUrl",
table: "AspNetUsers",
type: "nvarchar(max)",
nullable: true);
}
}
}

View File

@@ -1,4 +1,6 @@
using System.IdentityModel.Tokens.Jwt; using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims; using System.Security.Claims;
using System.Text; using System.Text;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
@@ -7,8 +9,15 @@ namespace Hutopy.Infrastructure.Utils;
public static class JwtTokenHelper public static class JwtTokenHelper
{ {
public static string GenerateJwtToken(string issuer, string audience, string key, string? userId, string? email, public static string GenerateJwtToken(
string? firstname, string? lastname, string? portraitUrl) string issuer,
string audience,
string key,
string? userId,
string? email,
string? firstname,
string? lastname,
string? profilePictureUrl)
{ {
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key)); var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
@@ -19,13 +28,14 @@ public static class JwtTokenHelper
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.NameIdentifier, userId), new Claim(ClaimTypes.NameIdentifier, userId),
new Claim(ClaimTypes.Email, email), new Claim(ClaimTypes.Email, email),
new Claim(ClaimTypes.GivenName, firstname), new Claim(ClaimTypes.Name, email),
new Claim(ClaimTypes.GivenName, firstname),
new Claim(ClaimTypes.Surname, lastname), new Claim(ClaimTypes.Surname, lastname),
}); });
if (portraitUrl is not null) if (profilePictureUrl is not null)
{ {
claims.Add(new Claim("portrait-url", portraitUrl)); claims.Add(new Claim("portrait-url", profilePictureUrl));
} }
var token = new JwtSecurityToken( var token = new JwtSecurityToken(

View File

@@ -71,7 +71,7 @@ public class GoogleController(IIdentityService identityService, IHttpClientFacto
user.Email, user.Email,
user.FirstName, user.FirstName,
user.LastName, user.LastName,
user.ProfilePictureUrl); user.StoredDataUrls.ProfilePictureUrl);
return Ok(new { accessToken = token, email }); return Ok(new { accessToken = token, email });
} }