diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..af50df1 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,25 @@ +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/.idea +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/.gitignore b/.gitignore index fe4fcde..e6a2ded 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ .idea/ ImageBoardServerApp/bin/ ImageBoardServerApp/obj/ +ImageBoardServerApp/wwwroot/img/dynamic *.db +*.db-shm +*.db-wal Migrations/ ## Ignore Visual Studio temporary files, build results, and diff --git a/ImageBoardServerApp/App.razor b/ImageBoardServerApp/App.razor index 6e090be..f3b63cd 100644 --- a/ImageBoardServerApp/App.razor +++ b/ImageBoardServerApp/App.razor @@ -1,16 +1,18 @@ - - - - - - - Not found - -

404

-
- noimageFound -

Sorry, nothing found. Please go back to the main page. Or watch the tree and find the hidden Cat..

-
-
-
-
\ No newline at end of file + + + + + + + + Not found + +

404

+
+ noimageFound +

Sorry, nothing found. Please go back to the main page. Or watch the tree and find the hidden Cat..

+
+
+
+
+
\ No newline at end of file diff --git a/ImageBoardServerApp/Auth/CustomAuthenticationStateProvider.cs b/ImageBoardServerApp/Auth/CustomAuthenticationStateProvider.cs new file mode 100644 index 0000000..86c5e5d --- /dev/null +++ b/ImageBoardServerApp/Auth/CustomAuthenticationStateProvider.cs @@ -0,0 +1,61 @@ +using System.Security.Claims; +using ImageBoardServerApp.Data; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage; + +namespace ImageBoardServerApp.Auth; + +public class CustomAuthenticationStateProvider : AuthenticationStateProvider +{ + private readonly ProtectedSessionStorage _sessionStorage; + private ClaimsPrincipal _anonymous = new ClaimsPrincipal(new ClaimsIdentity()); + + public CustomAuthenticationStateProvider(ProtectedSessionStorage sessionStorage) + { + _sessionStorage = sessionStorage; + } + + public override async Task GetAuthenticationStateAsync() + { + try + { + var userSessionStorageResult = await _sessionStorage.GetAsync("UserSession"); + var userSession = userSessionStorageResult.Success ? userSessionStorageResult.Value : null; + if (userSession == null) + return await Task.FromResult(new AuthenticationState(_anonymous)); + var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new List + { + //new Claim(ClaimTypes.Email, userSession.Email), + new Claim(ClaimTypes.Name, userSession.Email), + new Claim(ClaimTypes.Role, userSession.Role) + }, "CustomAuth")); + return await Task.FromResult(new AuthenticationState(claimsPrincipal)); + } + catch + { + return await Task.FromResult(new AuthenticationState(_anonymous)); + } + } + + public async Task UpdateAuthenticationStateAsync(UserData session) + { + ClaimsPrincipal claimsPrincipal; + + if (session != null) + { + await _sessionStorage.SetAsync("UserSession", session); + claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new List + { + new Claim(ClaimTypes.Email, session.Email), + new Claim(ClaimTypes.Email, session.Role) + })); + } + else + { + await _sessionStorage.DeleteAsync("UserSession"); + claimsPrincipal = _anonymous; + } + + NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(claimsPrincipal))); + } +} \ No newline at end of file diff --git a/ImageBoardServerApp/Data/AccountData.cs b/ImageBoardServerApp/Data/AccountData.cs deleted file mode 100644 index c12ce39..0000000 --- a/ImageBoardServerApp/Data/AccountData.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; - -namespace ImageBoardServerApp.Data; - -public class AccountData -{ - [Required] - [DatabaseGenerated((DatabaseGeneratedOption.Identity))] - [Key] - public int AccountID { get; set; } - - [Required] - public string Email { get; set; } - - [Required] - public string Password { get; set; } - - [Required] - public int PermissionInteger { get; set; } -} \ No newline at end of file diff --git a/ImageBoardServerApp/Data/AppDBContext.cs b/ImageBoardServerApp/Data/AppDBContext.cs index 7d08c13..9538872 100644 --- a/ImageBoardServerApp/Data/AppDBContext.cs +++ b/ImageBoardServerApp/Data/AppDBContext.cs @@ -8,7 +8,7 @@ internal sealed class AppDBContext : DbContext public DbSet Posts { get; set; } public DbSet Images { get; set; } public DbSet Comments { get; set; } - public DbSet Accounts { get; set; } + public DbSet Reports { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseSqlite("Data Source=./Data/Nils.db"); @@ -32,5 +32,18 @@ internal sealed class AppDBContext : DbContext mb.Entity() .HasMany(user => user.Comments) .WithOne(comment => comment.User); + + mb.Entity() + .HasOne(report => report.UserReported) + .WithMany(user => user.RecivedReports); + mb.Entity() + .HasOne(report => report.UserReporter) + .WithMany(user => user.SubmittedReports); + mb.Entity() + .HasOne(report => report.ReportedPost) + .WithOne(post => post.Report); + mb.Entity() + .HasOne(report => report.ReportedComment) + .WithOne(comment => comment.Report); } } \ No newline at end of file diff --git a/ImageBoardServerApp/Data/CommentData.cs b/ImageBoardServerApp/Data/CommentData.cs index 84dd57c..ee51257 100644 --- a/ImageBoardServerApp/Data/CommentData.cs +++ b/ImageBoardServerApp/Data/CommentData.cs @@ -1,6 +1,5 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using ImageBoardServerApp.Shared.Components; namespace ImageBoardServerApp.Data; @@ -21,12 +20,12 @@ public class CommentData public int UserID { get; set; } //[ForeignKey("UserID")] - public UserData User { get; set; } + public virtual UserData User { get; set; } //[ForeignKey("ImageID")] - public virtual ImageData Image { get; set; } - - public int ImageID { get; set; } + public virtual ImageData? Image { get; set; } + + public int? ImageID { get; set; } [Required] public string Content { get; set; } @@ -37,4 +36,9 @@ public class CommentData [Required] public string Board { get; set; } + [Required] + public long CreatedAt { get; set; } + + public ReportData? Report { get; set; } + } \ No newline at end of file diff --git a/ImageBoardServerApp/Data/ImageData.cs b/ImageBoardServerApp/Data/ImageData.cs index 590ae88..bdd3eba 100644 --- a/ImageBoardServerApp/Data/ImageData.cs +++ b/ImageBoardServerApp/Data/ImageData.cs @@ -15,7 +15,7 @@ public class ImageData public string Board { get; set; } [Required] - public Byte[] Image { get; set; } + public string ImageLocation { get; set; } public PostData Post { get; set; } diff --git a/ImageBoardServerApp/Data/PostData.cs b/ImageBoardServerApp/Data/PostData.cs index 30c6f87..6f54e37 100644 --- a/ImageBoardServerApp/Data/PostData.cs +++ b/ImageBoardServerApp/Data/PostData.cs @@ -31,7 +31,7 @@ public class PostData [Required] public string Content { get; set; } - public string Interactions { get; set; } + public int Interactions { get; set; } [Required] public long CreatedAt { get; set; } @@ -40,4 +40,6 @@ public class PostData public string Board { get; set; } public List Comments { get; set; } + + public ReportData? Report { get; set; } } \ No newline at end of file diff --git a/ImageBoardServerApp/Data/ReportData.cs b/ImageBoardServerApp/Data/ReportData.cs new file mode 100644 index 0000000..7f18ab2 --- /dev/null +++ b/ImageBoardServerApp/Data/ReportData.cs @@ -0,0 +1,42 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ImageBoardServerApp.Data; + +public class ReportData +{ + [Required] + [DatabaseGenerated((DatabaseGeneratedOption.Identity))] + [Key] + public int ReportID { get; set; } + + [Required] + public int UserReportedID { get; set; } + + [Required] + public UserData UserReported { get; set; } + + [Required] + public int UserReporterID { get; set; } + + [Required] + public UserData UserReporter { get; set; } + + public int? ReportedCommentID { get; set; } + + public CommentData? ReportedComment { get; set; } + + public int? ReportedPostID { get; set; } + + public PostData? ReportedPost { get; set; } + + [Required] + public string Type { get; set; } + + [Required] + public string ReportReason { get; set; } + + public string ReportExlaination { get; set; } + + +} \ No newline at end of file diff --git a/ImageBoardServerApp/Data/Repository/AccountsRepository.cs b/ImageBoardServerApp/Data/Repository/AccountsRepository.cs deleted file mode 100644 index a198f26..0000000 --- a/ImageBoardServerApp/Data/Repository/AccountsRepository.cs +++ /dev/null @@ -1,53 +0,0 @@ -using Microsoft.EntityFrameworkCore; - -namespace ImageBoardServerApp.Data.Repository; - -public static class AccountsRepository -{ - public static async Task> getAccountsAsync() - { - await using var db = new AppDBContext(); - return await db.Accounts.ToListAsync(); - } - - public static async Task> getAccountsByMailAsync(string email) - { - await using var db = new AppDBContext(); - return await db.Accounts - .Where(acc => acc.Email.Equals(email)) - .ToListAsync(); - } - - public static async Task getAccountByIdAsync(int accountId) - { - await using var db = new AppDBContext(); - return await db.Accounts.FirstOrDefaultAsync(post => post.AccountID == accountId); - } - - public static async Task createAccountAsync(AccountData accountToCreate) - { - await using var db = new AppDBContext(); - await db.Accounts.AddAsync(accountToCreate); - if (await db.SaveChangesAsync() >= 1) - { - Console.WriteLine($"Created post with ID: {accountToCreate.AccountID}"); - return accountToCreate.AccountID; - } - return -1; - } - - public static async Task updateAccountAsync(AccountData accountToUpdate) - { - await using var db = new AppDBContext(); - db.Accounts.Update(accountToUpdate); - return await db.SaveChangesAsync() >= 1; - } - - public static async Task deleteAccountAsync(int postId) - { - await using var db = new AppDBContext(); - AccountData accountToDelete = await getAccountByIdAsync(postId); - db.Remove(accountToDelete); - return await db.SaveChangesAsync() >= 1; - } -} \ No newline at end of file diff --git a/ImageBoardServerApp/Data/Repository/CommentsRepository.cs b/ImageBoardServerApp/Data/Repository/CommentsRepository.cs index af04222..c86a853 100644 --- a/ImageBoardServerApp/Data/Repository/CommentsRepository.cs +++ b/ImageBoardServerApp/Data/Repository/CommentsRepository.cs @@ -22,8 +22,23 @@ public static class CommentsRepository public static async Task getCommentByIdAsync(int postId) { await using var db = new AppDBContext(); - return await db.Comments.FirstOrDefaultAsync(comment => comment.PostID == postId); + return await db.Comments + .Where(comment => comment.CommentID == postId) + .Include(comment => comment.Image) + .Include(comment => comment.Post) + .FirstOrDefaultAsync(); } + + /*public static async Task getPostByIdAsync(int postId) + { + await using var db = new AppDBContext(); + return await db.Posts + .Where(post => post.PostID == postId) + .Include(post => post.Image) + .Include(post => post.Comments) + .FirstOrDefaultAsync(); + //return await db.Posts.FirstOrDefaultAsync(post => post.PostID == postId); + }*/ public static async Task createCommentAsync(CommentData commentData) { diff --git a/ImageBoardServerApp/Data/Repository/PostsRepository.cs b/ImageBoardServerApp/Data/Repository/PostsRepository.cs index 72eacd8..ec0e024 100644 --- a/ImageBoardServerApp/Data/Repository/PostsRepository.cs +++ b/ImageBoardServerApp/Data/Repository/PostsRepository.cs @@ -16,13 +16,21 @@ public static class PostsRepository return await db.Posts .Where(post => post.Board.Equals(board)) .Include(post => post.Image) + .Include(post => post.Comments) + .Include(post => post.User) .ToListAsync(); } public static async Task getPostByIdAsync(int postId) { await using var db = new AppDBContext(); - return await db.Posts.FirstOrDefaultAsync(post => post.PostID == postId); + return await db.Posts + .Where(post => post.PostID == postId) + .Include(post => post.Image) + .Include(post => post.Comments) + .Include(post => post.User) + .FirstOrDefaultAsync(); + //return await db.Posts.FirstOrDefaultAsync(post => post.PostID == postId); } public static async Task createPostAsync(PostData postToCreate) diff --git a/ImageBoardServerApp/Data/Repository/ReportsRepository.cs b/ImageBoardServerApp/Data/Repository/ReportsRepository.cs new file mode 100644 index 0000000..5fc1a36 --- /dev/null +++ b/ImageBoardServerApp/Data/Repository/ReportsRepository.cs @@ -0,0 +1,45 @@ +using Microsoft.EntityFrameworkCore; + +namespace ImageBoardServerApp.Data.Repository; + +public static class ReportsRepository +{ + public static async Task> getReportsAsync() + { + await using var db = new AppDBContext(); + return await db.Reports.ToListAsync(); + } + + public static async Task getReportByIdAsync(int reportId) + { + await using var db = new AppDBContext(); + return await db.Reports.FirstOrDefaultAsync(report => report.ReportID == reportId); + } + + public static async Task createReportAsync(ReportData reportData) + { + await using var db = new AppDBContext(); + await db.Reports.AddAsync(reportData); + if (await db.SaveChangesAsync() >= 1) + { + return reportData.ReportID; + } + + return -1; + } + + public static async Task updateReportAsync(ReportData reportData) + { + await using var db = new AppDBContext(); + db.Reports.Update(reportData); + return await db.SaveChangesAsync() >= 1; + } + + public static async Task deleteReportAsync(int reportId) + { + await using var db = new AppDBContext(); + ReportData reportData = await getReportByIdAsync(reportId); + db.Remove(reportData); + return await db.SaveChangesAsync() >= 1; + } +} \ No newline at end of file diff --git a/ImageBoardServerApp/Data/Repository/UsersRepository.cs b/ImageBoardServerApp/Data/Repository/UsersRepository.cs index 30e8267..4f4b53b 100644 --- a/ImageBoardServerApp/Data/Repository/UsersRepository.cs +++ b/ImageBoardServerApp/Data/Repository/UsersRepository.cs @@ -15,6 +15,12 @@ public static class UsersRepository await using var db = new AppDBContext(); return await db.Users.FirstOrDefaultAsync(user => user.UserID == userId); } + + public static async Task getUserByEmailAsync(string email) + { + await using var db = new AppDBContext(); + return await db.Users.FirstOrDefaultAsync(user => user.Email == email); + } public static async Task createUserAsync(UserData userToCreate) { diff --git a/ImageBoardServerApp/Data/UserData.cs b/ImageBoardServerApp/Data/UserData.cs index 57c97c3..b397f65 100644 --- a/ImageBoardServerApp/Data/UserData.cs +++ b/ImageBoardServerApp/Data/UserData.cs @@ -11,12 +11,9 @@ public class UserData [DatabaseGenerated((DatabaseGeneratedOption.Identity))] [Key] public int UserID { get; set; } - + [Required] - public string Ipv4Address { get; set; } - - [Required] - public bool Banned { get; set; } + public long TimeBanned { get; set; } [Required] public long lastActionTimeStamp { get; set; } @@ -24,4 +21,20 @@ public class UserData public List Posts { get; set; } public List Comments { get; set; } + + [Required] + public string Email { get; set; } + + [Required] + public string Password { get; set; } + + [Required] + public int PermissionInteger { get; set; } + + [Required] + public string Role { get; set; } + + public List SubmittedReports { get; set; } + + public List RecivedReports { get; set; } } \ No newline at end of file diff --git a/ImageBoardServerApp/Dockerfile b/ImageBoardServerApp/Dockerfile new file mode 100644 index 0000000..5b127e8 --- /dev/null +++ b/ImageBoardServerApp/Dockerfile @@ -0,0 +1,20 @@ +FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base +WORKDIR /app +EXPOSE 80 +EXPOSE 443 + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["ImageBoardServerApp/ImageBoardServerApp.csproj", "ImageBoardServerApp/"] +RUN dotnet restore "ImageBoardServerApp/ImageBoardServerApp.csproj" +COPY . . +WORKDIR "/src/BlazorServerTest" +RUN dotnet build "BlazorServerTest.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "ImageBoardServerApp.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "ImageBoardServerApp.dll"] diff --git a/ImageBoardServerApp/ImageBoardServerApp.csproj b/ImageBoardServerApp/ImageBoardServerApp.csproj index ef2c7bc..4f3a75d 100644 --- a/ImageBoardServerApp/ImageBoardServerApp.csproj +++ b/ImageBoardServerApp/ImageBoardServerApp.csproj @@ -19,7 +19,8 @@ - + + diff --git a/ImageBoardServerApp/Pages/Accounts/Login.razor b/ImageBoardServerApp/Pages/Accounts/Login.razor new file mode 100644 index 0000000..5483640 --- /dev/null +++ b/ImageBoardServerApp/Pages/Accounts/Login.razor @@ -0,0 +1,50 @@ +@page "/login" +@using ImageBoardServerApp.Data.Repository +@using ImageBoardServerApp.Auth +@inject IJSRuntime js +@inject AuthenticationStateProvider authStateProvider +@inject NavigationManager navManager + +

Login to bulletbroards

+
+
+
+ + +
+
+ + +
+ [Login] +
+ +
+@code { + private string Email { get; set; } + private string Password { get; set; } + + private bool verified; + + private async Task login() + { + Console.WriteLine("loggin you in..."); + var user = await UsersRepository.getUserByEmailAsync(Email); + if (user == null) + { + await js.InvokeVoidAsync("alert", "User does not exist"); + verified = false; + return; + } + verified = BCrypt.Net.BCrypt.Verify(Password, user.Password); + if (verified) + { + verified = true; + var customAuthStateProvider = (CustomAuthenticationStateProvider)authStateProvider; + await customAuthStateProvider.UpdateAuthenticationStateAsync(user); + navManager.NavigateTo("/", true); + return; + } + await js.InvokeVoidAsync("alert", $"Wrong Password"); + } +} \ No newline at end of file diff --git a/ImageBoardServerApp/Pages/Accounts/Register.razor b/ImageBoardServerApp/Pages/Accounts/Register.razor new file mode 100644 index 0000000..b422d38 --- /dev/null +++ b/ImageBoardServerApp/Pages/Accounts/Register.razor @@ -0,0 +1,67 @@ +@page "/register" +@using ImageBoardServerApp.Data.Repository +@using ImageBoardServerApp.Auth +@inject IJSRuntime js +@inject AuthenticationStateProvider authStateProvider +@inject NavigationManager navManager + +

Register to bulletbroards

+
+
+
+ + +
+
+ + +
+ [Register] +
+ +
+@code { + private string Email { get; set; } + private string Password { get; set; } + + private bool verified; + + private async Task login() + { + Console.WriteLine("Registering..."); + UserData userToCreate = new UserData() + { + Email = Email, + Password = BCrypt.Net.BCrypt.HashPassword(Password), + Role = "User", + PermissionInteger = 1, + TimeBanned = -1 + }; + if (await UsersRepository.getUserByEmailAsync(Email) != null) + { + return; + } + await UsersRepository.createUserAsync(userToCreate); + Console.WriteLine("loggin you in..."); + var user = await UsersRepository.getUserByEmailAsync(Email); + if (user == null) + { + await js.InvokeVoidAsync("alert", "User does not exist"); + verified = false; + return; + } + verified = BCrypt.Net.BCrypt.Verify(Password, user.Password); + if (verified) + { + verified = true; + var customAuthStateProvider = (CustomAuthenticationStateProvider)authStateProvider; + await customAuthStateProvider.UpdateAuthenticationStateAsync(user); + navManager.NavigateTo("/", true); + return; + } + await js.InvokeVoidAsync("alert", $"Wrong Password"); + } +} +@code { + +} \ No newline at end of file diff --git a/ImageBoardServerApp/Pages/B.razor b/ImageBoardServerApp/Pages/B.razor deleted file mode 100644 index 7c7010f..0000000 --- a/ImageBoardServerApp/Pages/B.razor +++ /dev/null @@ -1,16 +0,0 @@ -@page "/b/" -@using System.ComponentModel.DataAnnotations -@using ImageBoardServerApp.Data - - - -@code { - - private BoardData b { get; set; } = new() - { - BoardID = 0, - maxThreads = 10, - Tag = "b", - Topic = "Random" - }; -} \ No newline at end of file diff --git a/ImageBoardServerApp/Pages/FAQ.razor b/ImageBoardServerApp/Pages/Basic/FAQ.razor similarity index 100% rename from ImageBoardServerApp/Pages/FAQ.razor rename to ImageBoardServerApp/Pages/Basic/FAQ.razor diff --git a/ImageBoardServerApp/Pages/Basic/Index.razor b/ImageBoardServerApp/Pages/Basic/Index.razor new file mode 100644 index 0000000..99a6427 --- /dev/null +++ b/ImageBoardServerApp/Pages/Basic/Index.razor @@ -0,0 +1,40 @@ +@page "/" +@using ImageBoardServerApp.Data.Repository +@using ImageBoardServerApp.Auth +@inject AuthenticationStateProvider authStateProvider + +

BulletBoard

+This is a simple Imageboard made in Razor. +
+We're currently hosting @amountOfPosts Threads, @amountOfComments Comments and @amountOfUsers Users. + +@Details + +@code{ + private string Details { get; set; } + + private int amountOfPosts = -1; + private int amountOfComments = -1; + private int amountOfUsers = -1; + protected override async Task OnInitializedAsync() + { + var cauthStateProvder = (CustomAuthenticationStateProvider)authStateProvider; + var user = await cauthStateProvder.GetAuthenticationStateAsync(); + if (user.User.Identity.IsAuthenticated) + { + var usr = user.User.Identity.Name; + Details = $"Welcome {usr}"; + } + else + { + Details = "Please log in first."; + } + var posts = await PostsRepository.getPostsAsync(); + amountOfPosts = posts.Count; + var comments = await CommentsRepository.getCommentsAsync(); + amountOfComments = comments.Count; + var users = await UsersRepository.getUsersAsync(); + amountOfUsers = users.Count; + } + +} \ No newline at end of file diff --git a/ImageBoardServerApp/Pages/Basic/Index.razor.css b/ImageBoardServerApp/Pages/Basic/Index.razor.css new file mode 100644 index 0000000..37a27d3 --- /dev/null +++ b/ImageBoardServerApp/Pages/Basic/Index.razor.css @@ -0,0 +1,14 @@ +.loginlink{ + display: block; + font-size: 10px; + color: #c6cfd0; +} + +.imblue{ + color: #0a53be; + cursor: pointer; +} + +.loginwrapper{ + display: flex; +} \ No newline at end of file diff --git a/ImageBoardServerApp/Pages/Basic/Rules.razor b/ImageBoardServerApp/Pages/Basic/Rules.razor new file mode 100644 index 0000000..78dcb22 --- /dev/null +++ b/ImageBoardServerApp/Pages/Basic/Rules.razor @@ -0,0 +1,20 @@ +@page "/rules" +
+

Rules

+
+
    +
  • You may not post stuff that would get us into trouble with the feds.
  • +
  • You may not post NSFW / NSFL on this platform.
  • +
  • You may not post political content on this platform.
  • +
  • You may not plan or participate in "raids" on this platform.
  • +
  • You have to be atleast 18 years old to post.
  • +
  • You may not post through VPNs, Proxies or the TOR network.
  • +
  • You may not post posts, which are not of the same topic as the target board.
  • +
+ + + + +@code { + +} \ No newline at end of file diff --git a/ImageBoardServerApp/Pages/Rules.razor.css b/ImageBoardServerApp/Pages/Basic/Rules.razor.css similarity index 93% rename from ImageBoardServerApp/Pages/Rules.razor.css rename to ImageBoardServerApp/Pages/Basic/Rules.razor.css index 2f34911..49f002f 100644 --- a/ImageBoardServerApp/Pages/Rules.razor.css +++ b/ImageBoardServerApp/Pages/Basic/Rules.razor.css @@ -3,8 +3,9 @@ font-weight: 1000; /*the text have to be in a biger Pixel number I do not know how to do it */ } + .rules_list{ - text-align:right; + text-align:left; display:block; font-size: 14px; font-weight: 60 ; diff --git a/ImageBoardServerApp/Pages/Boards/M.razor b/ImageBoardServerApp/Pages/Boards/M.razor new file mode 100644 index 0000000..84dc481 --- /dev/null +++ b/ImageBoardServerApp/Pages/Boards/M.razor @@ -0,0 +1,17 @@ +@page "/m/" +@using System.ComponentModel.DataAnnotations +@using ImageBoardServerApp.Data + + + + +@code { + + private BoardData m { get; set; } = new() + { + BoardID = 0, + maxThreads = 10, + Tag = "m", + Topic = "Main" + }; +} \ No newline at end of file diff --git a/ImageBoardServerApp/Pages/Boards/M.razor.css b/ImageBoardServerApp/Pages/Boards/M.razor.css new file mode 100644 index 0000000..09af9e7 --- /dev/null +++ b/ImageBoardServerApp/Pages/Boards/M.razor.css @@ -0,0 +1,3 @@ +.banner{ + justify-content: center; +} \ No newline at end of file diff --git a/ImageBoardServerApp/Pages/Components/ReportPage.razor b/ImageBoardServerApp/Pages/Components/ReportPage.razor new file mode 100644 index 0000000..73f02de --- /dev/null +++ b/ImageBoardServerApp/Pages/Components/ReportPage.razor @@ -0,0 +1,17 @@ +@page "/report/{type}/{board}/{id}" +@using System.ComponentModel.DataAnnotations +

Report

+ +@code { + [Parameter] + [Required] + public string type { get; set; } + + [Parameter] + [Required] + public string board { get; set; } + + [Parameter] + [Required] + public string id { get; set; } +} \ No newline at end of file diff --git a/ImageBoardServerApp/Pages/Components/ThreadPage.razor b/ImageBoardServerApp/Pages/Components/ThreadPage.razor new file mode 100644 index 0000000..d6c3dfc --- /dev/null +++ b/ImageBoardServerApp/Pages/Components/ThreadPage.razor @@ -0,0 +1,44 @@ +@page "/{boardName}/thread/{threadId}" +@using System.ComponentModel.DataAnnotations +@using ImageBoardServerApp.Data.Repository +@inject NavigationManager NavigationManager + +

Thread #@threadId on /@boardName/

+ +
+ +@foreach (var comment in post.Comments) +{ + +
+} + + +@code { + [Parameter] + [Required] + public string boardName { get; set; } + + [Parameter] + [Required] + public string threadId { get; set; } + + private PostData post; + + protected override async Task OnInitializedAsync() + { + try + { + post = await PostsRepository.getPostByIdAsync(int.Parse(threadId)); + } + catch (FormatException fe) + { + NavigationManager.NavigateTo("/notfound"); + return; + } + if(post.Board != boardName) + NavigationManager.NavigateTo("/notfound"); + if(post == null) + NavigationManager.NavigateTo("/notfound"); + } +} \ No newline at end of file diff --git a/ImageBoardServerApp/Pages/Index.razor b/ImageBoardServerApp/Pages/Index.razor deleted file mode 100644 index 292616f..0000000 --- a/ImageBoardServerApp/Pages/Index.razor +++ /dev/null @@ -1,9 +0,0 @@ -@page "/" - -

BulletBoard

-
- This is a simple Imageboard made in Razor. -
-
- -
\ No newline at end of file diff --git a/ImageBoardServerApp/Pages/Login.razor b/ImageBoardServerApp/Pages/Login.razor deleted file mode 100644 index 3856758..0000000 --- a/ImageBoardServerApp/Pages/Login.razor +++ /dev/null @@ -1,58 +0,0 @@ -@page "/Login" -@using ImageBoardServerApp.Data.Repository -

Login

-
-
-
- - -
-
- - -
- -
- - @if (tried) - { - @if (verified) - { - Verifed! - } - else - { - False login - } - } - else - { - Plz login - } - -
-@code { - private string Email { get; set; } - private string Password { get; set; } - - private bool verified = false; - private bool tried = false; - - private async Task SubmitForm() - { - tried = true; - AccountData target = (await AccountsRepository.getAccountsByMailAsync(Email))[0]; - if (target == null) - { - verified = false; - return; - } - verified = BCrypt.Net.BCrypt.Verify(Password, target.Password); - if (verified) - { - verified = true; - return; - } - verified = false; - } -} \ No newline at end of file diff --git a/ImageBoardServerApp/Pages/Moderation/ModMenu.razor b/ImageBoardServerApp/Pages/Moderation/ModMenu.razor new file mode 100644 index 0000000..ed7579a --- /dev/null +++ b/ImageBoardServerApp/Pages/Moderation/ModMenu.razor @@ -0,0 +1,32 @@ +@page "/modmenu" +@using ImageBoardServerApp.Auth +@inject AuthenticationStateProvider authStateProvider +@inject NavigationManager navManager + + +

ModMenu

+ + + Welcome @mail to the mod menu + + + + You do not have permission to view this menu. + + +@code { + private string mail { get; set; } = ""; + + protected override async Task OnInitializedAsync() + { + var cauthStateProvder = (CustomAuthenticationStateProvider)authStateProvider; + var user = await cauthStateProvder.GetAuthenticationStateAsync(); + if (user.User.Identity.IsAuthenticated) + { + mail = user.User.Identity.Name; + } + } +} \ No newline at end of file diff --git a/ImageBoardServerApp/Pages/Moderation/ReportsPage.razor b/ImageBoardServerApp/Pages/Moderation/ReportsPage.razor new file mode 100644 index 0000000..aaebd07 --- /dev/null +++ b/ImageBoardServerApp/Pages/Moderation/ReportsPage.razor @@ -0,0 +1,5 @@ +@page "/modmenu/reports" + +@code { + +} \ No newline at end of file diff --git a/ImageBoardServerApp/Pages/Moderation/UsersPage.razor b/ImageBoardServerApp/Pages/Moderation/UsersPage.razor new file mode 100644 index 0000000..871b4c0 --- /dev/null +++ b/ImageBoardServerApp/Pages/Moderation/UsersPage.razor @@ -0,0 +1,6 @@ +@page "/modmenu/users" +

UsersPage

+ +@code { + +} \ No newline at end of file diff --git a/ImageBoardServerApp/Pages/Rules.razor b/ImageBoardServerApp/Pages/Rules.razor deleted file mode 100644 index f85929f..0000000 --- a/ImageBoardServerApp/Pages/Rules.razor +++ /dev/null @@ -1,19 +0,0 @@ -@page "/rules" -
-

Rules

-
-
    -
  • nudes are forbidden!
  • -
  • nacket pictures are forbidden!
  • -
  • no political statements!
  • -
  • Trees are nice!
  • -
  • Cats are nice!
  • -
  • Be mentely Unstable!:-)
  • -
- - - - -@code { - -} \ No newline at end of file diff --git a/ImageBoardServerApp/Pages/SuccessfulPost.razor b/ImageBoardServerApp/Pages/Status/SuccessfulPost.razor similarity index 100% rename from ImageBoardServerApp/Pages/SuccessfulPost.razor rename to ImageBoardServerApp/Pages/Status/SuccessfulPost.razor diff --git a/ImageBoardServerApp/Pages/UnSuccessfulPost.razor b/ImageBoardServerApp/Pages/Status/UnSuccessfulPost.razor similarity index 100% rename from ImageBoardServerApp/Pages/UnSuccessfulPost.razor rename to ImageBoardServerApp/Pages/Status/UnSuccessfulPost.razor diff --git a/ImageBoardServerApp/Pages/_Host.cshtml b/ImageBoardServerApp/Pages/_Host.cshtml index 0775ade..6886334 100644 --- a/ImageBoardServerApp/Pages/_Host.cshtml +++ b/ImageBoardServerApp/Pages/_Host.cshtml @@ -15,7 +15,7 @@ - + diff --git a/ImageBoardServerApp/Program.cs b/ImageBoardServerApp/Program.cs index 9e80ae6..4f3c1fb 100644 --- a/ImageBoardServerApp/Program.cs +++ b/ImageBoardServerApp/Program.cs @@ -1,14 +1,15 @@ -using ImageBoardServerApp.Data; -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Web; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Design; +using ImageBoardServerApp.Auth; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage; var builder = WebApplication.CreateBuilder(args); // Add services to the container. +builder.Services.AddAuthenticationCore(); builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); var app = builder.Build(); diff --git a/ImageBoardServerApp/Shared/Components/Board.razor b/ImageBoardServerApp/Shared/Components/Board.razor index 3a66240..4ad8acc 100644 --- a/ImageBoardServerApp/Shared/Components/Board.razor +++ b/ImageBoardServerApp/Shared/Components/Board.razor @@ -23,7 +23,7 @@ { @foreach(var post in posts) { - +
} } diff --git a/ImageBoardServerApp/Shared/Components/Comment.razor b/ImageBoardServerApp/Shared/Components/Comment.razor new file mode 100644 index 0000000..1225ce6 --- /dev/null +++ b/ImageBoardServerApp/Shared/Components/Comment.razor @@ -0,0 +1,108 @@ +@using System.ComponentModel.DataAnnotations +@using ImageBoardServerApp.Auth +@using ImageBoardServerApp.Data +@using ImageBoardServerApp.Data.Repository +@inject AuthenticationStateProvider authStateProvider + +
+ [ + @toggleText + ] + @comment.Username + @if (@comment.User.Role != "User") + { + ##@comment.User.Role + } + @getTimeFromUnix(comment.CreatedAt) + No.@comment.CommentID +
+@if (opened) +{ +
+
+ @if (image != null) + { + No Image found + } +
+
+ @foreach (string s in @comment.Content.Split("\n")) + { + @if (s.StartsWith(">")) + { + @s + } + else + { + @s + } + } +
+
+
+ [ + Delete + ] + [ + Report + ] +
+} + + + +@code { + + private async Task deletePost() + { + var cauthStateProvder = (CustomAuthenticationStateProvider)authStateProvider; + var user = await cauthStateProvder.GetAuthenticationStateAsync(); + var usr = user.User; + UserData foundusr = await UsersRepository.getUserByEmailAsync(usr.Identity.Name); + if (foundusr.PermissionInteger >= 50 || comment.UserID == foundusr.UserID) + { + await CommentsRepository.deleteCommentAsync(comment.CommentID); + } + } + + + private static DateTime getTimeFromUnix(double javaTimeStamp) + { + var dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); + dateTime = dateTime.AddMilliseconds( javaTimeStamp ).ToLocalTime(); + return dateTime; + } + + private ImageData image; + + protected override async Task OnInitializedAsync() + { + int i; + try + { + i = (int)comment.ImageID; + } + catch (InvalidOperationException ioe) + { + i = -1; + } + if (i != null) + { + image = await ImagesRepository.getImageByIdAsync(i); + } + } + + private bool opened = true; + + private string toggleText = "-"; + + private void ToggleOpened() + { + opened = !opened; + toggleText = opened ? "-" : "+"; + } + + [Parameter] + [Required] + public CommentData comment { get; set; } +} \ No newline at end of file diff --git a/ImageBoardServerApp/Shared/Components/Comment.razor.css b/ImageBoardServerApp/Shared/Components/Comment.razor.css new file mode 100644 index 0000000..4de11ba --- /dev/null +++ b/ImageBoardServerApp/Shared/Components/Comment.razor.css @@ -0,0 +1,70 @@ +.toggleOpened{ + color: #0a58ca; + text-decoration: none; +} + +.toggleOpened:hover{ + color: #0a58ca; !important; + cursor: pointer; +} + +.title{ + color: #1e5aaf; +} + +.name{ + color: #339305; +} + +.threadHeader{ + text-align: left; +} + +.threadFooter{ + text-align: right; !important; + align-self: end; !important; +} + +.threadContent{ + text-align: left; + display: flex; +} + +.greenText{ + color: #3caf03; +} + +.threadImage{ + margin: 6px; + max-width: 500px; + max-height: 500px; + padding: 5px; +} + +.threadImage img{ + max-width:150px; + width: 100%; +} + +.threadImage img:hover{ + /*transform: scale(3);*/ + max-width:500px; + width: 100%; +} + +.threadText{ + display: grid; +} + +.threadTextContainer{ + margin: 0; +} + + +.Admin{ + color: #ff191c; +} + +.Mod{ + color: #af13d7; +} \ No newline at end of file diff --git a/ImageBoardServerApp/Shared/Components/Forms/CommentForm.razor b/ImageBoardServerApp/Shared/Components/Forms/CommentForm.razor new file mode 100644 index 0000000..90bf2c6 --- /dev/null +++ b/ImageBoardServerApp/Shared/Components/Forms/CommentForm.razor @@ -0,0 +1,155 @@ +@using System.ComponentModel.DataAnnotations +@using ImageBoardServerApp.Auth +@using ImageBoardServerApp.Data.Repository + +@inject NavigationManager navigationManager +@inject IWebHostEnvironment env +@inject AuthenticationStateProvider authStateProvider + +
+ [ + @toggleText + ] +
+@if (opened) +{ +
+ Comment on @post.Title in /@post.Board/ + +
+
+
+ +
+ +
+ +
+
+
+ @if (hasErr) + { + @postErr + } +
+ + + +
+
+} + + +@code { + + private bool opened = false; + + private string toggleText = "Open Comment Formula"; + + private void ToggleOpened() + { + opened = !opened; + toggleText = opened ? "Close Comment Formula" : "Open Comment Formula"; + } + + [Parameter] + [Required] + public PostData post { get; set; } + + string postUsername { get; set; } = "Anonymous"; + string postContent { get; set; } = ""; + + private IBrowserFile selectedFile; + + private async Task SingleUpload(InputFileChangeEventArgs e) + { + selectedFile = e.GetMultipleFiles()[0]; + this.StateHasChanged(); + } + + string postErr { get; set; } + bool hasErr { get; set; } = false; + + private async Task onPostClick() + { + var cauthStateProvder = (CustomAuthenticationStateProvider)authStateProvider; + var user = await cauthStateProvder.GetAuthenticationStateAsync(); + var usr = user.User; + UserData foundusr = await UsersRepository.getUserByEmailAsync(usr.Identity.Name); + if (foundusr == null) + { + hasErr = true; + postErr = "You are not logged in."; + return; + } + int userID = foundusr.UserID; + if (foundusr.TimeBanned != -1) + { + hasErr = true; + postErr = "You are banned and may not comment."; + //Maybe redirect to /banned? + return; + } + foundusr.lastActionTimeStamp = DateTimeOffset.UnixEpoch.ToUnixTimeMilliseconds(); + await UsersRepository.updateUserAsync(foundusr); + + bool hasImage = selectedFile != null; + + CommentData commentToCreate; + if (hasImage) + { + Stream stream = selectedFile.OpenReadStream(maxAllowedSize: 512000 * 4); // max 2MB + var file = Path.GetRandomFileName() + "." + selectedFile.Name.Split(".")[selectedFile.Name.Split(".").Length - 1]; + var path = $"{env.WebRootPath}/img/dynamic/comment/{@post.Board}/{@file}"; + FileStream fs = File.Create(path); + await stream.CopyToAsync(fs); + stream.Close(); + fs.Close(); + + + var imageToUpload = new ImageData + { + Board = post.Board, + ImageLocation = $"/img/dynamic/comment/{@post.Board}/{@file}" + }; + int imageID = await ImagesRepository.createImageAsync(imageToUpload); + commentToCreate = new CommentData() + { + PostID = post.PostID, + UserID = userID, + ImageID = imageID, + Content = postContent, + Username = postUsername, + Board = post.Board, + CreatedAt = DateTimeOffset.Now.ToUnixTimeMilliseconds() + }; + } + else + { + commentToCreate = new CommentData() + { + PostID = post.PostID, + UserID = userID, + Content = postContent, + Username = postUsername, + Board = post.Board, + CreatedAt = DateTimeOffset.Now.ToUnixTimeMilliseconds() + }; + } + + int commentId = await CommentsRepository.createCommentAsync(commentToCreate); + if (commentId == -1) + { + //Open comment unsucessfull + navigationManager.NavigateTo("/UnSuccessfulPost"); + hasErr = true; + postErr = "There was an error and the comment could not be created. Please notify the admin."; + Console.WriteLine("Shit sucks and did not work."); + return; + } + //comment successfull + Console.WriteLine("Post created"); + navigationManager.NavigateTo($"/{post.Board}/thread/{post.PostID}", true, true); + opened = false; + } +} \ No newline at end of file diff --git a/ImageBoardServerApp/Shared/Components/Forms/CommentForm.razor.css b/ImageBoardServerApp/Shared/Components/Forms/CommentForm.razor.css new file mode 100644 index 0000000..3b0bbb0 --- /dev/null +++ b/ImageBoardServerApp/Shared/Components/Forms/CommentForm.razor.css @@ -0,0 +1,44 @@ +.toggleOpened{ + color: #0a58ca; + text-decoration: none; +} + +.toggleOpened:hover{ + color: #0a58ca; !important; + cursor: pointer; +} + +.centered { + text-align: center; + justify-content: center; + align-items: center; +} + +.pd { + padding: 5px; +} + +.marg{ + margin: 2px +} + +.formImage{ + margin: 6px; + max-width: 200px; + max-height: 200px; + padding: 5px; +} + +.formImage img{ + max-width:150px; + width: 100%; +} + +.formContent{ + text-align: left; + display: flex; +} + +.postError{ + color: #ff191c; +} \ No newline at end of file diff --git a/ImageBoardServerApp/Shared/Components/Forms/FormInfo.razor b/ImageBoardServerApp/Shared/Components/Forms/FormInfo.razor new file mode 100644 index 0000000..0db3688 --- /dev/null +++ b/ImageBoardServerApp/Shared/Components/Forms/FormInfo.razor @@ -0,0 +1,5 @@ +
    +
  • The max. image size is 2MiB.
  • +
  • Supported file types are: jpeg, png & gif
  • +
  • Read the rules before posting
  • +
\ No newline at end of file diff --git a/ImageBoardServerApp/Shared/Components/Forms/FormInfo.razor.css b/ImageBoardServerApp/Shared/Components/Forms/FormInfo.razor.css new file mode 100644 index 0000000..f8b1df7 --- /dev/null +++ b/ImageBoardServerApp/Shared/Components/Forms/FormInfo.razor.css @@ -0,0 +1,8 @@ +.notesInfo{ + font-weight: 60; + display: block; + text-align: center; + font-size: 10px; + color: #c6cfd0; + /*the text sice can stay like it is, if you do not want to change it.*/ +} \ No newline at end of file diff --git a/ImageBoardServerApp/Shared/Components/Forms/PostForm.razor b/ImageBoardServerApp/Shared/Components/Forms/PostForm.razor new file mode 100644 index 0000000..cf54db9 --- /dev/null +++ b/ImageBoardServerApp/Shared/Components/Forms/PostForm.razor @@ -0,0 +1,161 @@ +@using Radzen +@using System.ComponentModel.DataAnnotations +@using System.IO.Pipelines +@using System.Net.Mime +@using System.Reflection +@using System.Runtime.CompilerServices +@using ImageBoardServerApp.Auth +@using ImageBoardServerApp.Data +@using ImageBoardServerApp.Data.Repository + +@inject NavigationManager NavigationManager +@inject IWebHostEnvironment env +@inject AuthenticationStateProvider authStateProvider + +
+ [ + @toggleText + ] +
+@if (opened) +{ +
+ Post to /@board.Tag/ - @board.Topic + +
+
+
+ +
+ +
+ +
+ +
+ +
+
+
+ @if (hasErr) + { + @postErr + } +
+ + + +
+ +
+} + + +@code { + + private bool opened = false; + + private string toggleText = "Open Post Formula"; + + private void ToggleOpened() + { + opened = !opened; + toggleText = opened ? "Close Post Formula" : "Open Post Formula"; + } + + [Parameter] + [Required] + public BoardData board { get; set; } = new BoardData(); + + string postUsername { get; set; } = "Anonymous"; + string postTitle { get; set; } = ""; + string postContent { get; set; } = ""; + + + private IBrowserFile selectedFile; + + + private async Task SingleUpload(InputFileChangeEventArgs e) + { + selectedFile = e.GetMultipleFiles()[0]; + this.StateHasChanged(); + } + + string postErr { get; set; } + bool hasErr { get; set; } = false; + + private async Task onPostClick() + { + + var cauthStateProvder = (CustomAuthenticationStateProvider)authStateProvider; + var user = await cauthStateProvder.GetAuthenticationStateAsync(); + var usr = user.User; + UserData foundusr = await UsersRepository.getUserByEmailAsync(usr.Identity.Name); + if (foundusr == null) + { + hasErr = true; + postErr = "You are not logged in."; + return; + } + int userID = foundusr.UserID; + if (foundusr.TimeBanned != -1) + { + hasErr = true; + postErr = "You are banned and may not post."; + //Maybe redirect to /banned? + return; + } + foundusr.lastActionTimeStamp = DateTimeOffset.UnixEpoch.ToUnixTimeMilliseconds(); + await UsersRepository.updateUserAsync(foundusr); + + + //TODO Add check if data is image + + if (selectedFile == null || selectedFile.Size >= 512000 * 4) + { + hasErr = true; + postErr = "You did not attach a file or the selected file is bigger then the 2MiB file limit."; + return; + } + + Stream stream = selectedFile.OpenReadStream(maxAllowedSize: 512000 * 4); // max 2MB + var file = Path.GetRandomFileName() + "." + selectedFile.Name.Split(".")[selectedFile.Name.Split(".").Length - 1]; + var path = $"{env.WebRootPath}/img/dynamic/op/{@board.Tag}/{@file}"; + FileStream fs = File.Create(path); + await stream.CopyToAsync(fs); + stream.Close(); + fs.Close(); + + var imageToUpload = new ImageData + { + Board = board.Tag, + ImageLocation = $"/img/dynamic/op/{@board.Tag}/{@file}" + }; + int imageID = await ImagesRepository.createImageAsync(imageToUpload); + var postToPost = new PostData + { + UserID = userID, + ImageID = imageID, + Username = postUsername, + Title = postTitle, + Content = postContent, + Interactions = 0, + CreatedAt = DateTimeOffset.Now.ToUnixTimeMilliseconds(), + Board = board.Tag + }; + int postId = await PostsRepository.createPostAsync(postToPost); + if (postId != -1) + { + //Open post successfull + NavigationManager.NavigateTo($"/{board.Tag}/thread/{postId}", true, true); + Console.WriteLine("Post created"); + } + else + { + //Open post unsucessfull + hasErr = true; + postErr = "There was an error and the post could not be created. Please notify the admin."; + Console.WriteLine("Shit sucks and did not work."); + } + } +} \ No newline at end of file diff --git a/ImageBoardServerApp/Shared/Components/PostForm.razor.css b/ImageBoardServerApp/Shared/Components/Forms/PostForm.razor.css similarity index 54% rename from ImageBoardServerApp/Shared/Components/PostForm.razor.css rename to ImageBoardServerApp/Shared/Components/Forms/PostForm.razor.css index fc59e5e..3b0bbb0 100644 --- a/ImageBoardServerApp/Shared/Components/PostForm.razor.css +++ b/ImageBoardServerApp/Shared/Components/Forms/PostForm.razor.css @@ -20,4 +20,25 @@ .marg{ margin: 2px +} + +.formImage{ + margin: 6px; + max-width: 200px; + max-height: 200px; + padding: 5px; +} + +.formImage img{ + max-width:150px; + width: 100%; +} + +.formContent{ + text-align: left; + display: flex; +} + +.postError{ + color: #ff191c; } \ No newline at end of file diff --git a/ImageBoardServerApp/Shared/Components/Post.razor b/ImageBoardServerApp/Shared/Components/Post.razor index edfe5ca..2e493a2 100644 --- a/ImageBoardServerApp/Shared/Components/Post.razor +++ b/ImageBoardServerApp/Shared/Components/Post.razor @@ -1,12 +1,22 @@ @using System.ComponentModel.DataAnnotations +@using ImageBoardServerApp.Auth @using ImageBoardServerApp.Data +@using ImageBoardServerApp.Data.Repository +@inject AuthenticationStateProvider authStateProvider
- [ - @toggleText - ] + @if (showOpenThread) + { + [ + @toggleText + ] + } @post.Title @post.Username + @if (post.User.Role != "User") + { + ##@post.User.Role + } @getTimeFromUnix(post.CreatedAt) No.@post.PostID
@@ -14,10 +24,9 @@ {
- @if (@post.Image != null) { - No Image found + No Image found } else { @@ -27,27 +36,42 @@
@foreach (string s in @post.Content.Split("\n")) { - @s + @if (@s.StartsWith(">")) + { + @s + } + else + { + @s + } }
- [ - Report + Delete ] [ - (@post.Interactions) Open Thread + Report ] + @if (showOpenThread) + { + [ + (@post.Comments.Count) View Thread + ] + } + else + { + [ + @post.Comments.Count Comments + ] + }
} @code { - - - private static DateTime getTimeFromUnix(double javaTimeStamp) { var dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); @@ -55,6 +79,18 @@ return dateTime; } + private async Task deletePost() + { + var cauthStateProvder = (CustomAuthenticationStateProvider)authStateProvider; + var user = await cauthStateProvder.GetAuthenticationStateAsync(); + var usr = user.User; + UserData foundusr = await UsersRepository.getUserByEmailAsync(usr.Identity.Name); + if (foundusr.PermissionInteger >= 50 || post.UserID == foundusr.UserID) + { + await PostsRepository.deletePostAsync(post.PostID); + } + } + private bool opened = true; private string toggleText = "-"; @@ -68,4 +104,9 @@ [Parameter] [Required] public PostData post { get; set; } + + + [Parameter] + [Required] + public bool showOpenThread { get; set; } } \ No newline at end of file diff --git a/ImageBoardServerApp/Shared/Components/Post.razor.css b/ImageBoardServerApp/Shared/Components/Post.razor.css index da7824a..2cee082 100644 --- a/ImageBoardServerApp/Shared/Components/Post.razor.css +++ b/ImageBoardServerApp/Shared/Components/Post.razor.css @@ -16,6 +16,14 @@ color: #339305; } +.Admin{ + color: #ff191c; +} + +.Mod{ + color: #af13d7; +} + .threadHeader{ text-align: left; } @@ -30,6 +38,10 @@ display: flex; } +.greenText{ + color: #3caf03; +} + .threadImage{ margin: 6px; max-width: 500px; @@ -43,9 +55,9 @@ } .threadImage img:hover{ - transform: scale(3); - /*max-width:500px; - width: 100%; */ + /*transform: scale(3);*/ + max-width:500px; + width: 100%; } .threadText{ diff --git a/ImageBoardServerApp/Shared/Components/PostForm.razor b/ImageBoardServerApp/Shared/Components/PostForm.razor deleted file mode 100644 index bd52605..0000000 --- a/ImageBoardServerApp/Shared/Components/PostForm.razor +++ /dev/null @@ -1,139 +0,0 @@ -@using Radzen -@using System.ComponentModel.DataAnnotations -@using System.IO.Pipelines -@using System.Net.Mime -@using System.Reflection -@using System.Runtime.CompilerServices -@using ImageBoardServerApp.Data -@using ImageBoardServerApp.Data.Repository - -@inject NavigationManager NavigationManager - -
- [ - @toggleText - ] -
-@if (opened) -{ -
- Post to /@board.Tag/ - @board.Topic - -
- OnChange(args, "username")) Class="w-100"/> -
- -
- OnChange(args, "title")) Class="w-100"/> -
- -
- OnChange(args, "Content")) Class="w-100"/> -
- -
- - -
- -
-} - - -@code { - - private bool opened = false; - - private string toggleText = "Open Post Formula"; - - private void ToggleOpened() - { - opened = !opened; - toggleText = opened ? "Close Post Formula" : "Open Post Formula"; - } - - [Parameter] - [Required] - public BoardData board { get; set; } = new BoardData(); - - string postUsername = "Anonymous"; - string postTitle = ""; - string postContent = ""; - - void OnChange(string value, string name) - { - switch (name) - { - case "title": - postTitle = value; - break; - case "username": - postUsername = value; - break; - case "content": - postContent = value; - break; - default: - Console.WriteLine("not found."); - break; - } - Console.WriteLine($"Smth changed!: {value}"); - } - - private async Task SingleUpload(InputFileChangeEventArgs e) - { - MemoryStream ms = new MemoryStream(); - await e.File.OpenReadStream().CopyToAsync(ms); - var bytes = ms.ToArray(); - image = bytes; - Console.WriteLine("File has been selected!"); - ms.Close(); - } - - private Byte[] image; - - private async Task onPostClick() - { - var userToCreate = new UserData - { - Ipv4Address = "192.168.178.101", - Banned = false, - lastActionTimeStamp = DateTime.Now.Millisecond - }; - int userID = await UsersRepository.createUserAsync(userToCreate); - - //TODO Add check if data is image - - - var imageToUpload = new ImageData - { - Board = board.Tag, - Image = image - }; - int imageID = await ImagesRepository.createImageAsync(imageToUpload); - var postToPost = new PostData - { - UserID = userID, - ImageID = imageID, - Username = postUsername, - Title = postTitle, - Content = postContent, - Interactions = "", - CreatedAt = DateTimeOffset.Now.ToUnixTimeMilliseconds(), - Board = board.Tag - }; - int postId = await PostsRepository.createPostAsync(postToPost); - if (postId != -1) - { - //Open post successfull - NavigationManager.NavigateTo("/SuccessfulPost"); - Console.WriteLine("Post created"); - } - else - { - //Open post unsucessfull - NavigationManager.NavigateTo("/UnSuccessfulPost"); - Console.WriteLine("Shit sucks and did not work."); - } - } -} \ No newline at end of file diff --git a/ImageBoardServerApp/Shared/Components/Reports.razor b/ImageBoardServerApp/Shared/Components/Reports.razor new file mode 100644 index 0000000..0fe0732 --- /dev/null +++ b/ImageBoardServerApp/Shared/Components/Reports.razor @@ -0,0 +1,5 @@ +

Reports

+ +@code { + +} \ No newline at end of file diff --git a/ImageBoardServerApp/Shared/MainLayout.razor b/ImageBoardServerApp/Shared/MainLayout.razor index 63130fc..141e9c6 100644 --- a/ImageBoardServerApp/Shared/MainLayout.razor +++ b/ImageBoardServerApp/Shared/MainLayout.razor @@ -1,4 +1,7 @@ @inherits LayoutComponentBase +@using ImageBoardServerApp.Auth +@inject AuthenticationStateProvider authStateProvider +@inject NavigationManager navManager BulletBoard @@ -8,13 +11,46 @@
+
@Body
- \ No newline at end of file + + +@code +{ + + private string mail { get; set; } = ""; + + protected override async Task OnInitializedAsync() + { + var cauthStateProvder = (CustomAuthenticationStateProvider)authStateProvider; + var user = await cauthStateProvder.GetAuthenticationStateAsync(); + if (user.User.Identity.IsAuthenticated) + { + mail = user.User.Identity.Name; + } + } + + private async Task logout() + { + var customAuthStateProvider = (CustomAuthenticationStateProvider) authStateProvider; + await customAuthStateProvider.UpdateAuthenticationStateAsync(null); + navManager.NavigateTo("/", true); + } +} diff --git a/ImageBoardServerApp/Shared/NavMenu.razor b/ImageBoardServerApp/Shared/NavMenu.razor index a716788..56c5d1b 100644 --- a/ImageBoardServerApp/Shared/NavMenu.razor +++ b/ImageBoardServerApp/Shared/NavMenu.razor @@ -15,8 +15,8 @@ diff --git a/ImageBoardServerApp/_Imports.razor b/ImageBoardServerApp/_Imports.razor index a2e21d4..3613cc4 100644 --- a/ImageBoardServerApp/_Imports.razor +++ b/ImageBoardServerApp/_Imports.razor @@ -6,11 +6,16 @@ @using Microsoft.AspNetCore.Components.Web @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.JSInterop -@using ImageBoardServerApp -@using ImageBoardServerApp.Shared @using Radzen @using Radzen.Blazor @using ImageBoardServerApp +@using ImageBoardServerApp.Pages +@using ImageBoardServerApp.Pages.Boards +@using ImageBoardServerApp.Pages.Accounts +@using ImageBoardServerApp.Pages.Basic +@using ImageBoardServerApp.Pages.Components +@using ImageBoardServerApp.Pages.Status @using ImageBoardServerApp.Shared @using ImageBoardServerApp.Shared.Components -@using ImageBoardServerApp.Data \ No newline at end of file +@using ImageBoardServerApp.Shared.Components.Forms +@using ImageBoardServerApp.Data diff --git a/ImageBoardServerApp/wwwroot/img/static/banner/mban.png b/ImageBoardServerApp/wwwroot/img/static/banner/mban.png new file mode 100644 index 0000000..ed0449f Binary files /dev/null and b/ImageBoardServerApp/wwwroot/img/static/banner/mban.png differ diff --git a/ImageBoardServerApp/wwwroot/static/1.jpeg b/ImageBoardServerApp/wwwroot/img/static/err/1.jpeg similarity index 100% rename from ImageBoardServerApp/wwwroot/static/1.jpeg rename to ImageBoardServerApp/wwwroot/img/static/err/1.jpeg diff --git a/ImageBoardServerApp/wwwroot/img/static/logo.png b/ImageBoardServerApp/wwwroot/img/static/logo.png new file mode 100644 index 0000000..a0bc58a Binary files /dev/null and b/ImageBoardServerApp/wwwroot/img/static/logo.png differ