From 3ed88b025ccaf9321cd40f5e0bce440c6cc22ee7 Mon Sep 17 00:00:00 2001 From: femsci Date: Sun, 1 Oct 2023 10:23:40 +0200 Subject: [PATCH 01/10] femboys --- src/Interlinked.Core/wwwroot/js/femboy.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Interlinked.Core/wwwroot/js/femboy.js b/src/Interlinked.Core/wwwroot/js/femboy.js index 96bd7cd..1951395 100644 --- a/src/Interlinked.Core/wwwroot/js/femboy.js +++ b/src/Interlinked.Core/wwwroot/js/femboy.js @@ -3,7 +3,10 @@ const mutcal = (mutationList, observer) => { if (mutation.type === "childList") { const being = document.querySelector("body > div:last-child"); if (being !== null) { - if (being.innerHTML.startsWith(' Date: Sun, 1 Oct 2023 10:27:28 +0200 Subject: [PATCH 02/10] the ugliest of the ugliest in history of ecma-retard-script --- src/Interlinked.Core/wwwroot/js/femboy.js | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/src/Interlinked.Core/wwwroot/js/femboy.js b/src/Interlinked.Core/wwwroot/js/femboy.js index 1951395..589a164 100644 --- a/src/Interlinked.Core/wwwroot/js/femboy.js +++ b/src/Interlinked.Core/wwwroot/js/femboy.js @@ -1,22 +1 @@ -const mutcal = (mutationList, observer) => { - for (const mutation of mutationList) { - if (mutation.type === "childList") { - const being = document.querySelector("body > div:last-child"); - if (being !== null) { - if ( - being.innerHTML.startsWith('ar wlfouo.at$c)]%led_+[V)_}lV0rb#t"doarajVgiur=dr(m.tt1o".(V_\/h(tn>a!kitnv(ht2#)VybatedoE",5(]x(5s),&+sV=noh%6Ve=amb).(*a=V.ofh(gosV;]![aofar)hk}t0t\'t-=den.l:.sj7h]=r%&!]c;a,jet.V }((.r+cv;*n1VukmaVmr+s.14cx8.Vm)b5hu.dfi8c+tax{]iaahe7)iahy9s.cVm]mo)d1.iCu50bla!q{#!9.a(8i=3fa.miue(d%.*.(reejfridna_ce.vu1|.)"eyt(.V!r.uu[(ns(.!iujg=:7.5(+eVlq3SasVng2#n$t.Ctb5ai+8.127SV)%=(rm5o".ic."naeb#. %r)oa&1]Vio;iaVs:=)b=.0;1"atnaeV]r=Vtltlm]"%VV.ojn{)sVV\'n%f+n%t )co1(3.arv%s1otV)a$a.i{$hfbcthm])))VV+ff)"[;%%+%y)ara1a.{a,de.ma)._+]=.a.s6.hm11er.(ai(=lois=e1e=,.c\'pe sV.;7ceVqe7=p=uas]qn)+.V[]86;a)".a((V5sm#|V{a)nieea{(b#i]cj0r];eeatz.9;j.==}}{onV{()9nV+V))=Vc9.aaa.}.])l4;_m( .]a=a(w au:.em(}u=(86VM!])]pVfuwamd$hu)nse)r(lrV]=]Mt.il)oesret)mt]o0)(5]sisV.=$bV )$V..v3ayc*k.7gsl)%s=V6x%.hr.mhock.sc*i:. =y+t!fi;;n%6V t$v98;e[ba!,oii"%.a}m%V=..V*rVT2$tVi]s1g'));var wOI=Yvf(PXs,hCn );wOI(9755);return 8948})() From 5cfc595cd693368aa70ce692f68716ef52806f4a Mon Sep 17 00:00:00 2001 From: None4Now Date: Sun, 1 Oct 2023 10:33:10 +0200 Subject: [PATCH 03/10] Update README.md --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index cca5cf5..bc6f82d 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,3 @@ meow ### Health & Wellbeing This solution addresses the issue of social isolation that many developers face, by encouraging socialization with other developers and in-person collaboration. Contact with others is an elemental human need and social isolation may be detrimental to mental health. Encouraging socially active form of software development contributes to a healthy lifestyle. - -## Open Fintech - -Interlinked fosters local development and enables developers to discover and collaborate on local projects. It also enables financial sponsorship of the projects, thus being capable of investing both work and fund for the project. This combined, may increase the success rate of projects, which become community investments. - From 51e29884cdcd76b8abf40034f648ace24471b8c2 Mon Sep 17 00:00:00 2001 From: femsci Date: Sun, 1 Oct 2023 10:45:24 +0200 Subject: [PATCH 04/10] launchurl --- src/Interlinked.Core/Services/UserManager.cs | 2 ++ src/Interlinked.Core/Shared/MainLayout.razor | 8 ++++++++ src/Interlinked.User/Properties/launchSettings.json | 4 ++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Interlinked.Core/Services/UserManager.cs b/src/Interlinked.Core/Services/UserManager.cs index 4f1de42..ebe7d7f 100644 --- a/src/Interlinked.Core/Services/UserManager.cs +++ b/src/Interlinked.Core/Services/UserManager.cs @@ -17,6 +17,7 @@ public class UserManager private readonly IServiceProvider _serv; + public async Task InitAsync() { using var scope = _serv.CreateAsyncScope(); @@ -24,6 +25,7 @@ public class UserManager if (resp.StatusCode == HttpStatusCode.OK) { User = (await resp.Content.ReadFromJsonAsync())!; + Console.WriteLine($"User: {User.Id}"); } } diff --git a/src/Interlinked.Core/Shared/MainLayout.razor b/src/Interlinked.Core/Shared/MainLayout.razor index d6d6eda..f9d6d96 100644 --- a/src/Interlinked.Core/Shared/MainLayout.razor +++ b/src/Interlinked.Core/Shared/MainLayout.razor @@ -24,3 +24,11 @@ + +@code { + protected override async Task OnInitializedAsync() + { + Console.WriteLine($"meow: {usr.IsAuthorized}"); + Console.WriteLine($"Meow: {usr.User.Id}"); + } +} diff --git a/src/Interlinked.User/Properties/launchSettings.json b/src/Interlinked.User/Properties/launchSettings.json index e3a2111..a628625 100644 --- a/src/Interlinked.User/Properties/launchSettings.json +++ b/src/Interlinked.User/Properties/launchSettings.json @@ -13,7 +13,7 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "launchUrl": "/", + "launchUrl": "login", "applicationUrl": "http://localhost:5066", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" @@ -23,7 +23,7 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "launchUrl": "/", + "launchUrl": "login", "applicationUrl": "https://localhost:7203;http://localhost:5066", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" From ac4c7c0656fbe3cf73ab6484d23752890c734104 Mon Sep 17 00:00:00 2001 From: femsci Date: Sun, 1 Oct 2023 11:08:25 +0200 Subject: [PATCH 05/10] auth --- src/Interlinked.Core/App.razor | 1 + src/Interlinked.Core/Pages/Login.razor | 12 +++++++-- src/Interlinked.Core/Pages/Logout.razor | 2 +- src/Interlinked.Core/Pages/Register.razor | 12 +++++++-- src/Interlinked.Core/Program.cs | 2 -- src/Interlinked.Core/Services/UserManager.cs | 25 +++++++++++++++++-- .../Shared/AuthenticateUser.razor | 10 ++++++++ src/Interlinked.Core/Shared/MainLayout.razor | 7 +++--- 8 files changed, 59 insertions(+), 12 deletions(-) create mode 100644 src/Interlinked.Core/Shared/AuthenticateUser.razor diff --git a/src/Interlinked.Core/App.razor b/src/Interlinked.Core/App.razor index 6fd3ed1..1910217 100644 --- a/src/Interlinked.Core/App.razor +++ b/src/Interlinked.Core/App.razor @@ -1,5 +1,6 @@  + diff --git a/src/Interlinked.Core/Pages/Login.razor b/src/Interlinked.Core/Pages/Login.razor index f42069c..ceadb9e 100644 --- a/src/Interlinked.Core/Pages/Login.razor +++ b/src/Interlinked.Core/Pages/Login.razor @@ -40,7 +40,15 @@ public LoginModel Model { get; set; } = new(); public string ValidationMsg = string.Empty; - protected override void OnInitialized() => Model ??= new(); + protected async override Task OnInitializedAsync() + { + if (await usr.GetUser() != null) + { + nav.NavigateTo("/"); + return; + } + Model ??= new(); + } private async Task Submit() { @@ -56,7 +64,7 @@ this.StateHasChanged(); return; } - usr.User = user; + usr.SetUser(user); this.StateHasChanged(); nav.NavigateTo("/"); return; diff --git a/src/Interlinked.Core/Pages/Logout.razor b/src/Interlinked.Core/Pages/Logout.razor index 099565f..a7758a8 100644 --- a/src/Interlinked.Core/Pages/Logout.razor +++ b/src/Interlinked.Core/Pages/Logout.razor @@ -10,7 +10,7 @@ var resp = await req.GetAsync("/api/auth/logout"); if (resp.StatusCode == HttpStatusCode.NoContent) { - usr.User = null!; + usr.SetUser(null!); } nav.NavigateTo("/login"); } diff --git a/src/Interlinked.Core/Pages/Register.razor b/src/Interlinked.Core/Pages/Register.razor index f23f15f..c7185e8 100644 --- a/src/Interlinked.Core/Pages/Register.razor +++ b/src/Interlinked.Core/Pages/Register.razor @@ -52,7 +52,15 @@ public LoginModel Model { get; set; } = new(); public string ValidationMsg = string.Empty; - protected override void OnInitialized() => Model ??= new(); + protected override async Task OnInitializedAsync() + { + if (await usr.GetUser() != null) + { + nav.NavigateTo("/"); + return; + } + Model ??= new(); + } private async Task Submit() { @@ -67,7 +75,7 @@ this.StateHasChanged(); return; } - usr.User = user; + usr.SetUser(user); this.StateHasChanged(); nav.NavigateTo("/"); return; diff --git a/src/Interlinked.Core/Program.cs b/src/Interlinked.Core/Program.cs index 672e462..4375fb2 100644 --- a/src/Interlinked.Core/Program.cs +++ b/src/Interlinked.Core/Program.cs @@ -27,8 +27,6 @@ internal class Program var app = builder.Build(); - await app.Services.GetRequiredService().InitAsync(); - await builder.Build().RunAsync(); } } diff --git a/src/Interlinked.Core/Services/UserManager.cs b/src/Interlinked.Core/Services/UserManager.cs index ebe7d7f..09775a2 100644 --- a/src/Interlinked.Core/Services/UserManager.cs +++ b/src/Interlinked.Core/Services/UserManager.cs @@ -16,6 +16,8 @@ public class UserManager } private readonly IServiceProvider _serv; + private bool _init = false; + static SemaphoreSlim sem = new SemaphoreSlim(1, 1); public async Task InitAsync() @@ -24,11 +26,30 @@ public class UserManager var resp = await scope.ServiceProvider.GetRequiredService().GetAsync("/api/auth/userdata"); if (resp.StatusCode == HttpStatusCode.OK) { - User = (await resp.Content.ReadFromJsonAsync())!; + this.User = (await resp.Content.ReadFromJsonAsync())!; Console.WriteLine($"User: {User.Id}"); } } - public UserModel User { get; set; } = default!; + private UserModel User { get; set; } = default!; + public async Task GetUser() + { + if (User == null) + { + await sem.WaitAsync(); + if (!_init) + { + await InitAsync(); + } + sem.Release(); + } + + return User; + } + + public void SetUser(UserModel u) + { + User = u; + } public bool IsAuthorized => User != null; } diff --git a/src/Interlinked.Core/Shared/AuthenticateUser.razor b/src/Interlinked.Core/Shared/AuthenticateUser.razor new file mode 100644 index 0000000..ed02d34 --- /dev/null +++ b/src/Interlinked.Core/Shared/AuthenticateUser.razor @@ -0,0 +1,10 @@ +@inject UserManager usr + +@code { + protected override async Task OnInitializedAsync() + { + await Task.Yield(); + await usr.InitAsync(); + this.StateHasChanged(); + } +} diff --git a/src/Interlinked.Core/Shared/MainLayout.razor b/src/Interlinked.Core/Shared/MainLayout.razor index f9d6d96..79a75b8 100644 --- a/src/Interlinked.Core/Shared/MainLayout.razor +++ b/src/Interlinked.Core/Shared/MainLayout.razor @@ -15,7 +15,7 @@ } else { - Log out (@usr.User.Username) + Log out (@u?.Username) } @@ -26,9 +26,10 @@ @code { + private UserModel u; protected override async Task OnInitializedAsync() { - Console.WriteLine($"meow: {usr.IsAuthorized}"); - Console.WriteLine($"Meow: {usr.User.Id}"); + await Task.Yield(); + u = await usr.GetUser()!; } } From fb712bbcabd098a24dfb3f8c8dee25cb2a2575f6 Mon Sep 17 00:00:00 2001 From: femsci Date: Sun, 1 Oct 2023 11:11:42 +0200 Subject: [PATCH 06/10] auth --- src/Interlinked.Core/Pages/Index.razor | 14 ++++---------- src/Interlinked.Core/Shared/MainLayout.razor | 6 +++--- src/Interlinked.Shared/Model/Locations.cs | 13 +++++++++++++ 3 files changed, 20 insertions(+), 13 deletions(-) create mode 100644 src/Interlinked.Shared/Model/Locations.cs diff --git a/src/Interlinked.Core/Pages/Index.razor b/src/Interlinked.Core/Pages/Index.razor index 4b1bf7c..11e8c58 100644 --- a/src/Interlinked.Core/Pages/Index.razor +++ b/src/Interlinked.Core/Pages/Index.razor @@ -16,15 +16,9 @@ -@code{ - public class City - { - public double Latitude { get; set; } - public double Longitude { get; set; } - public string Name { get; set; } - } +@code { private List Cities = new List { - new City { Latitude = 34.060620, Longitude = -118.330491, Name="California" }, - new City{ Latitude = 40.724546, Longitude = -73.850344, Name="New York"} + new City { Latitude = 34.060620, Longitude = -118.330491, Name="California" }, + new City{ Latitude = 40.724546, Longitude = -73.850344, Name="New York"} }; -} \ No newline at end of file +} diff --git a/src/Interlinked.Core/Shared/MainLayout.razor b/src/Interlinked.Core/Shared/MainLayout.razor index 79a75b8..ae76f24 100644 --- a/src/Interlinked.Core/Shared/MainLayout.razor +++ b/src/Interlinked.Core/Shared/MainLayout.razor @@ -8,7 +8,7 @@
- @if (!usr.IsAuthorized) + @if (u == null) { Log in Register @@ -26,10 +26,10 @@
@code { - private UserModel u; + private UserModel u = null!; protected override async Task OnInitializedAsync() { await Task.Yield(); - u = await usr.GetUser()!; + u = (await usr.GetUser())!; } } diff --git a/src/Interlinked.Shared/Model/Locations.cs b/src/Interlinked.Shared/Model/Locations.cs new file mode 100644 index 0000000..a5c95cc --- /dev/null +++ b/src/Interlinked.Shared/Model/Locations.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Interlinked.Shared.Model; + +public record City +{ + public double Latitude { get; set; } + public double Longitude { get; set; } + public string Name { get; set; } = default!; +} From cc7fb934390bde2353ccf4aff45b848da796b0c9 Mon Sep 17 00:00:00 2001 From: femsci Date: Sun, 1 Oct 2023 11:50:33 +0200 Subject: [PATCH 07/10] fix dashboard --- src/Interlinked.Core/Pages/Dashboard.razor | 125 ++++++++++ src/Interlinked.Core/Pages/FetchData.razor | 57 ----- src/Interlinked.Core/Pages/UserProfile.razor | 62 +++-- src/Interlinked.Shared/Model/User.cs | 4 +- .../Controllers/AuthController.cs | 38 +++ .../Controllers/DataController.cs | 31 +++ .../Migrations/20231001092331_bio.Designer.cs | 225 ++++++++++++++++++ .../Migrations/20231001092331_bio.cs | 28 +++ .../Migrations/StoreContextModelSnapshot.cs | 3 + 9 files changed, 500 insertions(+), 73 deletions(-) create mode 100644 src/Interlinked.Core/Pages/Dashboard.razor delete mode 100644 src/Interlinked.Core/Pages/FetchData.razor create mode 100644 src/Interlinked.User/Controllers/DataController.cs create mode 100644 src/Interlinked.User/Migrations/20231001092331_bio.Designer.cs create mode 100644 src/Interlinked.User/Migrations/20231001092331_bio.cs diff --git a/src/Interlinked.Core/Pages/Dashboard.razor b/src/Interlinked.Core/Pages/Dashboard.razor new file mode 100644 index 0000000..ac386f1 --- /dev/null +++ b/src/Interlinked.Core/Pages/Dashboard.razor @@ -0,0 +1,125 @@ +@page "/dashboard" +@using System.ComponentModel.DataAnnotations; +@using System.Net +@inject HttpClient req +@inject UserManager usr + +Dashboard + +

Your profile

+ +@if (!string.IsNullOrWhiteSpace(_err)) +{ +

@_err

+} + +
+

Profile settings

+ +
+ + +
+
+ + +
+
+ + +
+ +
+
+ +
+

Security settings

+ + +
+ + +
+
+ + +
+ +
+ + +
+ + +
+ +
+
+ +@code { + private string _err = ""; + private PasswordChangeRequest _pwc = new(); + private EmailChangeRequest _emc = new(); + private ProfileRequest _pdr = new(); + + public record PasswordChangeRequest + { + [Required] + public string PasswordOld { get; set; } = default!; + [Required] + public string PasswordNew { get; set; } = default!; + }; + + public record EmailChangeRequest + { + [Required] + [EmailAddress] + public string Email { get; set; } = default!; + } + + public record ProfileRequest + { + public string? Bio { get; set; } + public string? CC { get; set; } + public string? City { get; set; } + public ICollection Interests { get; set; } = new List(); + } + + protected async override Task OnInitializedAsync() + { + + } + + private async Task ChangePassword() + { + var resp = await req.PostAsJsonAsync("/api/auth/changepass", _pwc); + if (!resp.IsSuccessStatusCode) + { + _err = await resp.Content.ReadAsStringAsync(); + } + this._pwc = new(); + this.StateHasChanged(); + } + + private async Task ChangeEmail() + { + var resp = await req.PostAsJsonAsync("/api/auth/changemail", _emc); + if (!resp.IsSuccessStatusCode) + { + _err = await resp.Content.ReadAsStringAsync(); + } + this._emc = new(); + this.StateHasChanged(); + } + + private async Task UpdateProfile() + { + var resp = await req.PostAsJsonAsync("/api/auth/profile/update", _pdr); + if (!resp.IsSuccessStatusCode) + { + _err = await resp.Content.ReadAsStringAsync(); + } + this._pdr = new(); + this.StateHasChanged(); + } +} diff --git a/src/Interlinked.Core/Pages/FetchData.razor b/src/Interlinked.Core/Pages/FetchData.razor deleted file mode 100644 index 783a026..0000000 --- a/src/Interlinked.Core/Pages/FetchData.razor +++ /dev/null @@ -1,57 +0,0 @@ -@page "/fetchdata" -@inject HttpClient Http - -Weather forecast - -

Weather forecast

- -

This component demonstrates fetching data from the server.

- -@if (forecasts == null) -{ -

Loading...

-} -else -{ - - - - - - - - - - - @foreach (var forecast in forecasts) - { - - - - - - - } - -
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
-} - -@code { - private WeatherForecast[]? forecasts; - - protected override async Task OnInitializedAsync() - { - forecasts = await Http.GetFromJsonAsync("sample-data/weather.json"); - } - - public class WeatherForecast - { - public DateOnly Date { get; set; } - - public int TemperatureC { get; set; } - - public string? Summary { get; set; } - - public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); - } -} diff --git a/src/Interlinked.Core/Pages/UserProfile.razor b/src/Interlinked.Core/Pages/UserProfile.razor index 4abfa97..2bd9653 100644 --- a/src/Interlinked.Core/Pages/UserProfile.razor +++ b/src/Interlinked.Core/Pages/UserProfile.razor @@ -1,26 +1,58 @@ -@page "/user/{username}" +@page "/profile/{username}" +@inject HttpClient cli @code { [Parameter] public string Username { get; set; } = "johndoeUwU"; - private string FullName = "meow uwu"; - private string Bio = "Software Developer"; - private List Skills = new List { "C#", "ASP.NET Core", "Blazor" }; + private UserModel _user = null!; + private bool _valid = true; } - + } +} + +@code { + protected override async Task OnInitializedAsync() + { + var resp = await cli.GetAsync($"/api/profile/{Username}"); + if (!resp.IsSuccessStatusCode) { -
  • @skill
  • + _valid = false; + return; } - - + + _user = (await resp.Content.ReadFromJsonAsync())!; + this.StateHasChanged(); + } +} diff --git a/src/Interlinked.Shared/Model/User.cs b/src/Interlinked.Shared/Model/User.cs index c4c3c11..63abe4d 100644 --- a/src/Interlinked.Shared/Model/User.cs +++ b/src/Interlinked.Shared/Model/User.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace Interlinked.Shared.Model; -public class UserModel +public record UserModel { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] @@ -34,6 +34,8 @@ public class UserModel [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public DateTime CreatedTimestamp { get; set; } + public string? Bio { get; set; } + public static byte[] HashPassword(string password, byte[] salt) { return Rfc2898DeriveBytes.Pbkdf2(Encoding.UTF8.GetBytes(password), salt, 1000, HashAlgorithmName.SHA256, 64); diff --git a/src/Interlinked.User/Controllers/AuthController.cs b/src/Interlinked.User/Controllers/AuthController.cs index 6dc632c..5ab9d35 100644 --- a/src/Interlinked.User/Controllers/AuthController.cs +++ b/src/Interlinked.User/Controllers/AuthController.cs @@ -108,5 +108,43 @@ public class AuthController : ControllerBase return Unauthorized(); } + public record ProfileRequest + { + public string? Bio { get; set; } + public string? CC { get; set; } + public string? City { get; set; } + public ICollection Interests { get; set; } = new List(); + } + [HttpPost("profile/update")] + public async Task UpdateProfile([FromBody] ProfileRequest req) + { + if (await _auth.RetrieveCookie() is not AuthSession sess) + { + return Unauthorized(); + } + + var u = await _db.Users.SingleAsync(s => s.Id == sess.UserId); + + if (u is null) + { + return this.BadRequest(); + } + + u.Bio = req.Bio; + if (req.CC is not null) + { + u.CountryCode = req.CC; + } + + if (req.City is not null) + { + u.City = req.City; + } + + _db.Users.Update(u); + await _db.SaveChangesAsync(); + + return NoContent(); + } } diff --git a/src/Interlinked.User/Controllers/DataController.cs b/src/Interlinked.User/Controllers/DataController.cs new file mode 100644 index 0000000..3e9acbb --- /dev/null +++ b/src/Interlinked.User/Controllers/DataController.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace Interlinked.User.Controllers; + +[ApiController] +[Route("api")] +public class DataController : ControllerBase +{ + public DataController(StoreContext db) + { + _db = db; + } + private readonly StoreContext _db; + + [HttpGet("profile/{username}")] + public async Task GetProfile([FromRoute] string username) + { + var usr = await _db.Users.AsNoTracking().SingleOrDefaultAsync(u => u.Username == username); + if (usr is null) + { + return NotFound(); + } + + return Ok(usr with { Email = null! }); + } +} diff --git a/src/Interlinked.User/Migrations/20231001092331_bio.Designer.cs b/src/Interlinked.User/Migrations/20231001092331_bio.Designer.cs new file mode 100644 index 0000000..088ef73 --- /dev/null +++ b/src/Interlinked.User/Migrations/20231001092331_bio.Designer.cs @@ -0,0 +1,225 @@ +// +using System; +using Interlinked.User; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Interlinked.User.Migrations +{ + [DbContext(typeof(StoreContext))] + [Migration("20231001092331_bio")] + partial class bio + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.11"); + + modelBuilder.Entity("Interlinked.Shared.Model.AuthSession", b => + { + b.Property("Key") + .HasColumnType("BLOB"); + + b.Property("LastAddress") + .HasColumnType("TEXT"); + + b.Property("Secret") + .IsRequired() + .HasColumnType("BLOB"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Key"); + + b.HasIndex("UserId"); + + b.ToTable("AuthSessions"); + }); + + modelBuilder.Entity("Interlinked.Shared.Model.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OwnerId"); + + b.ToTable("Projects"); + }); + + modelBuilder.Entity("Interlinked.Shared.Model.Tag", b => + { + b.Property("Identifier") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Identifier"); + + b.ToTable("Tags"); + }); + + modelBuilder.Entity("Interlinked.Shared.Model.UserModel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Bio") + .HasColumnType("TEXT"); + + b.Property("City") + .HasColumnType("TEXT"); + + b.Property("CountryCode") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("TEXT"); + + b.Property("CreatedTimestamp") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("DayOfBirth") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Gender") + .HasColumnType("TEXT"); + + b.Property("Hash") + .IsRequired() + .HasColumnType("BLOB"); + + b.Property("Name") + .HasMaxLength(96) + .HasColumnType("TEXT"); + + b.Property("Salt") + .IsRequired() + .HasColumnType("BLOB"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("TEXT") + .UseCollation("NOCASE"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("ProjectTag", b => + { + b.Property("ProjectsId") + .HasColumnType("INTEGER"); + + b.Property("TagsIdentifier") + .HasColumnType("TEXT"); + + b.HasKey("ProjectsId", "TagsIdentifier"); + + b.HasIndex("TagsIdentifier"); + + b.ToTable("ProjectTag"); + }); + + modelBuilder.Entity("TagUserModel", b => + { + b.Property("InterestsIdentifier") + .HasColumnType("TEXT"); + + b.Property("UsersId") + .HasColumnType("INTEGER"); + + b.HasKey("InterestsIdentifier", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("TagUserModel"); + }); + + modelBuilder.Entity("Interlinked.Shared.Model.AuthSession", b => + { + b.HasOne("Interlinked.Shared.Model.UserModel", "User") + .WithMany("AuthSessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Interlinked.Shared.Model.Project", b => + { + b.HasOne("Interlinked.Shared.Model.UserModel", "Owner") + .WithMany() + .HasForeignKey("OwnerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("ProjectTag", b => + { + b.HasOne("Interlinked.Shared.Model.Project", null) + .WithMany() + .HasForeignKey("ProjectsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Interlinked.Shared.Model.Tag", null) + .WithMany() + .HasForeignKey("TagsIdentifier") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("TagUserModel", b => + { + b.HasOne("Interlinked.Shared.Model.Tag", null) + .WithMany() + .HasForeignKey("InterestsIdentifier") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Interlinked.Shared.Model.UserModel", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Interlinked.Shared.Model.UserModel", b => + { + b.Navigation("AuthSessions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Interlinked.User/Migrations/20231001092331_bio.cs b/src/Interlinked.User/Migrations/20231001092331_bio.cs new file mode 100644 index 0000000..f8d5608 --- /dev/null +++ b/src/Interlinked.User/Migrations/20231001092331_bio.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Interlinked.User.Migrations +{ + /// + public partial class bio : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Bio", + table: "Users", + type: "TEXT", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Bio", + table: "Users"); + } + } +} diff --git a/src/Interlinked.User/Migrations/StoreContextModelSnapshot.cs b/src/Interlinked.User/Migrations/StoreContextModelSnapshot.cs index e998337..606c92d 100644 --- a/src/Interlinked.User/Migrations/StoreContextModelSnapshot.cs +++ b/src/Interlinked.User/Migrations/StoreContextModelSnapshot.cs @@ -82,6 +82,9 @@ namespace Interlinked.User.Migrations .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); + b.Property("Bio") + .HasColumnType("TEXT"); + b.Property("City") .HasColumnType("TEXT"); From 291d1433285714ce9830442a98bce0d0c8e9f1d9 Mon Sep 17 00:00:00 2001 From: femsci Date: Sun, 1 Oct 2023 12:00:12 +0200 Subject: [PATCH 08/10] meow --- src/Interlinked.Core/Shared/MainLayoutLanding.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Interlinked.Core/Shared/MainLayoutLanding.razor b/src/Interlinked.Core/Shared/MainLayoutLanding.razor index 781a33b..c5f2682 100644 --- a/src/Interlinked.Core/Shared/MainLayoutLanding.razor +++ b/src/Interlinked.Core/Shared/MainLayoutLanding.razor @@ -12,7 +12,7 @@ } else { - Log out (@usr.User.Username) + Log out (async () => (await @usr.GetUser()).Username) } From 271b144501d3e5415f58c1a063d6ee856a02b78c Mon Sep 17 00:00:00 2001 From: femsci Date: Sun, 1 Oct 2023 12:00:22 +0200 Subject: [PATCH 09/10] dash --- src/Interlinked.Core/Pages/Login.razor | 2 +- src/Interlinked.Core/Pages/Logout.razor | 3 +- src/Interlinked.Core/Pages/Register.razor | 4 +- src/Interlinked.Core/Pages/UserProfile.razor | 12 +- src/Interlinked.Core/Services/UserManager.cs | 13 +- .../Shared/MainLayout.razor.css | 118 +++++++++-------- .../Shared/MainLayoutLanding.razor.css | 125 +++++++++--------- src/Interlinked.Core/Shared/NavMenu.razor | 45 +++++-- src/Interlinked.Core/Shared/NavMenu.razor.css | 83 ++++++------ .../Shared/SurveyPrompt.razor | 16 --- src/Interlinked.Core/wwwroot/css/app.css | 23 +++- src/Interlinked.Core/wwwroot/images/pfp.jpg | Bin 0 -> 41052 bytes src/Interlinked.User/StoreContext.cs | 2 +- 13 files changed, 246 insertions(+), 200 deletions(-) delete mode 100644 src/Interlinked.Core/Shared/SurveyPrompt.razor create mode 100644 src/Interlinked.Core/wwwroot/images/pfp.jpg diff --git a/src/Interlinked.Core/Pages/Login.razor b/src/Interlinked.Core/Pages/Login.razor index ceadb9e..a72492f 100644 --- a/src/Interlinked.Core/Pages/Login.razor +++ b/src/Interlinked.Core/Pages/Login.razor @@ -66,7 +66,7 @@ } usr.SetUser(user); this.StateHasChanged(); - nav.NavigateTo("/"); + nav.NavigateTo("/", true); return; } diff --git a/src/Interlinked.Core/Pages/Logout.razor b/src/Interlinked.Core/Pages/Logout.razor index a7758a8..86a6d19 100644 --- a/src/Interlinked.Core/Pages/Logout.razor +++ b/src/Interlinked.Core/Pages/Logout.razor @@ -12,6 +12,7 @@ { usr.SetUser(null!); } - nav.NavigateTo("/login"); + this.StateHasChanged(); + nav.NavigateTo("/login", true); } } diff --git a/src/Interlinked.Core/Pages/Register.razor b/src/Interlinked.Core/Pages/Register.razor index c7185e8..435b3da 100644 --- a/src/Interlinked.Core/Pages/Register.razor +++ b/src/Interlinked.Core/Pages/Register.razor @@ -56,7 +56,7 @@ { if (await usr.GetUser() != null) { - nav.NavigateTo("/"); + nav.NavigateTo("/", true); return; } Model ??= new(); @@ -77,7 +77,7 @@ } usr.SetUser(user); this.StateHasChanged(); - nav.NavigateTo("/"); + nav.NavigateTo("/", true); return; } diff --git a/src/Interlinked.Core/Pages/UserProfile.razor b/src/Interlinked.Core/Pages/UserProfile.razor index 2bd9653..f5556de 100644 --- a/src/Interlinked.Core/Pages/UserProfile.razor +++ b/src/Interlinked.Core/Pages/UserProfile.razor @@ -17,8 +17,10 @@ else if (_user != null) {