diff --git a/src/JobsJobsJobs.sln b/src/JobsJobsJobs.sln index 20e3996..1f46ea4 100644 --- a/src/JobsJobsJobs.sln +++ b/src/JobsJobsJobs.sln @@ -11,6 +11,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JobsJobsJobs.Shared", "Jobs EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{50B51580-9F09-41E2-BC78-DAD38C37B583}" ProjectSection(SolutionItems) = preProject + database\12-add-real-name.sql = database\12-add-real-name.sql JobsJobsJobs\Directory.Build.props = JobsJobsJobs\Directory.Build.props database\tables.sql = database\tables.sql EndProjectSection diff --git a/src/JobsJobsJobs/Client/Pages/Profile/View.razor b/src/JobsJobsJobs/Client/Pages/Profile/View.razor index c513cb1..5157a01 100644 --- a/src/JobsJobsJobs/Client/Pages/Profile/View.razor +++ b/src/JobsJobsJobs/Client/Pages/Profile/View.razor @@ -3,8 +3,8 @@ @inject AppState state - -

@Citizen.DisplayName

+ +

@Citizen.CitizenName

@Profile.Continent!.Name, @Profile.Region

@WorkTypes

diff --git a/src/JobsJobsJobs/Client/Pages/SuccessStory/ViewStory.razor b/src/JobsJobsJobs/Client/Pages/SuccessStory/ViewStory.razor index 53eedad..869d916 100644 --- a/src/JobsJobsJobs/Client/Pages/SuccessStory/ViewStory.razor +++ b/src/JobsJobsJobs/Client/Pages/SuccessStory/ViewStory.razor @@ -5,7 +5,7 @@ -

@Citizen.DisplayName’s Success Story

+

@Citizen.CitizenName’s Success Story

@if (Story.FromHere) { diff --git a/src/JobsJobsJobs/Server/Areas/Api/Controllers/CitizenController.cs b/src/JobsJobsJobs/Server/Areas/Api/Controllers/CitizenController.cs index 10b1723..671bd69 100644 --- a/src/JobsJobsJobs/Server/Areas/Api/Controllers/CitizenController.cs +++ b/src/JobsJobsJobs/Server/Areas/Api/Controllers/CitizenController.cs @@ -65,7 +65,8 @@ namespace JobsJobsJobs.Server.Areas.Api.Controllers var citizen = await _db.FindCitizenByNAUser(account.Username); if (citizen == null) { - citizen = new Citizen(await CitizenId.Create(), account.Username, account.DisplayName, account.Url, + citizen = new Citizen(await CitizenId.Create(), account.Username, + string.IsNullOrWhiteSpace(account.DisplayName) ? null : account.DisplayName, null, account.Url, now, now); await _db.AddCitizen(citizen); } @@ -73,7 +74,7 @@ namespace JobsJobsJobs.Server.Areas.Api.Controllers { citizen = citizen with { - DisplayName = account.DisplayName, + DisplayName = string.IsNullOrWhiteSpace(account.DisplayName) ? null : account.DisplayName, LastSeenOn = now }; _db.UpdateCitizen(citizen); @@ -83,7 +84,7 @@ namespace JobsJobsJobs.Server.Areas.Api.Controllers // Step 3 - Generate JWT var jwt = Auth.CreateJwt(citizen, _config); - return new JsonResult(new LogOnSuccess(jwt, citizen.Id.ToString(), citizen.DisplayName)); + return new JsonResult(new LogOnSuccess(jwt, citizen.Id.ToString(), citizen.CitizenName)); } [Authorize] diff --git a/src/JobsJobsJobs/Server/Auth.cs b/src/JobsJobsJobs/Server/Auth.cs index 020617b..831fce1 100644 --- a/src/JobsJobsJobs/Server/Auth.cs +++ b/src/JobsJobsJobs/Server/Auth.cs @@ -80,13 +80,6 @@ namespace JobsJobsJobs.Server $"Profiles must be from noagendasocial.com; yours is {profileResponse.AccountName}"); } - // If the user hasn't filled in a display name, use the username as the display name. - // (this is what Mastodon does) - if (string.IsNullOrWhiteSpace(profileResponse.DisplayName)) - { - profileResponse.DisplayName = profileResponse.Username; - } - return Result.AsOk(profileResponse); } @@ -104,7 +97,7 @@ namespace JobsJobsJobs.Server Subject = new ClaimsIdentity(new[] { new Claim(ClaimTypes.NameIdentifier, citizen.Id.ToString()), - new Claim(ClaimTypes.Name, citizen.DisplayName), + new Claim(ClaimTypes.Name, citizen.CitizenName), }), Expires = DateTime.UtcNow.AddHours(2), Issuer = "https://noagendacareers.com", diff --git a/src/JobsJobsJobs/Server/Data/JobsDbContext.cs b/src/JobsJobsJobs/Server/Data/JobsDbContext.cs index 972b81a..ee95e39 100644 --- a/src/JobsJobsJobs/Server/Data/JobsDbContext.cs +++ b/src/JobsJobsJobs/Server/Data/JobsDbContext.cs @@ -49,11 +49,13 @@ namespace JobsJobsJobs.Server.Data m.Property(e => e.Id).HasColumnName("id").IsRequired().HasMaxLength(12) .HasConversion(Converters.CitizenIdConverter); m.Property(e => e.NaUser).HasColumnName("na_user").IsRequired().HasMaxLength(50); - m.Property(e => e.DisplayName).HasColumnName("display_name").IsRequired().HasMaxLength(255); + m.Property(e => e.DisplayName).HasColumnName("display_name").HasMaxLength(255); m.Property(e => e.ProfileUrl).HasColumnName("profile_url").IsRequired().HasMaxLength(1_024); m.Property(e => e.JoinedOn).HasColumnName("joined_on").IsRequired(); m.Property(e => e.LastSeenOn).HasColumnName("last_seen_on").IsRequired(); + m.Property(e => e.RealName).HasColumnName("real_name").HasMaxLength(255); m.HasIndex(e => e.NaUser).IsUnique(); + m.Ignore(e => e.CitizenName); }); modelBuilder.Entity(m => diff --git a/src/JobsJobsJobs/Server/Data/ProfileExtensions.cs b/src/JobsJobsJobs/Server/Data/ProfileExtensions.cs index 9a10266..fdd9780 100644 --- a/src/JobsJobsJobs/Server/Data/ProfileExtensions.cs +++ b/src/JobsJobsJobs/Server/Data/ProfileExtensions.cs @@ -156,7 +156,7 @@ namespace JobsJobsJobs.Server.Data query = query.Where(it => citizenIds.Contains(it.Citizen.Id)); } - return await query.Select(x => new ProfileSearchResult(x.Citizen.Id, x.Citizen.DisplayName, + return await query.Select(x => new ProfileSearchResult(x.Citizen.Id, x.Citizen.CitizenName, x.Profile.SeekingEmployment, x.Profile.RemoteWork, x.Profile.FullTime, x.Profile.LastUpdatedOn)) .ToListAsync().ConfigureAwait(false); } diff --git a/src/JobsJobsJobs/Server/Data/SuccessExtensions.cs b/src/JobsJobsJobs/Server/Data/SuccessExtensions.cs index 25f0360..8bbcaa6 100644 --- a/src/JobsJobsJobs/Server/Data/SuccessExtensions.cs +++ b/src/JobsJobsJobs/Server/Data/SuccessExtensions.cs @@ -28,7 +28,7 @@ namespace JobsJobsJobs.Server.Data await db.Successes .Join(db.Citizens, s => s.CitizenId, c => c.Id, (s, c) => new { Success = s, Citizen = c }) .OrderByDescending(it => it.Success.RecordedOn) - .Select(it => new StoryEntry(it.Success.Id, it.Citizen.Id, it.Citizen.DisplayName, + .Select(it => new StoryEntry(it.Success.Id, it.Citizen.Id, it.Citizen.CitizenName, it.Success.RecordedOn, it.Success.FromHere, it.Success.Story != null)) .ToListAsync().ConfigureAwait(false); } diff --git a/src/JobsJobsJobs/Shared/Domain/Citizen.cs b/src/JobsJobsJobs/Shared/Domain/Citizen.cs index f2ff382..d8ced36 100644 --- a/src/JobsJobsJobs/Shared/Domain/Citizen.cs +++ b/src/JobsJobsJobs/Shared/Domain/Citizen.cs @@ -8,8 +8,15 @@ namespace JobsJobsJobs.Shared public record Citizen( CitizenId Id, string NaUser, - string DisplayName, + string? DisplayName, + string? RealName, string ProfileUrl, Instant JoinedOn, - Instant LastSeenOn); + Instant LastSeenOn) + { + /// + /// The user's name by which they should be known + /// + public string CitizenName => RealName ?? DisplayName ?? NaUser; + } } diff --git a/src/database/12-add-real-name.sql b/src/database/12-add-real-name.sql new file mode 100644 index 0000000..e1eae0a --- /dev/null +++ b/src/database/12-add-real-name.sql @@ -0,0 +1,8 @@ +ALTER TABLE jjj.citizen ALTER COLUMN display_name DROP NOT NULL; +ALTER TABLE jjj.citizen ADD COLUMN real_name VARCHAR(255); + +COMMENT ON COLUMN jjj.citizen.real_name + IS 'The real name of the user'; + +-- This can be run as often as needed +UPDATE jjj.citizen SET display_name = NULL WHERE display_name = na_user;