├── .tool-versions
├── docker
├── .env
├── docker-compose.yaml
└── docker-compose.override.yaml
├── apps
├── allow
│ ├── test
│ │ ├── Agree.Allow.Test
│ │ │ ├── Usings.cs
│ │ │ ├── TestBase.cs
│ │ │ ├── DependencyInjectionContainer.cs
│ │ │ └── Agree.Allow.Test.csproj
│ │ └── Agree.Allow.Domain.Test
│ │ │ ├── Usings.cs
│ │ │ ├── testsettings.json
│ │ │ ├── Handlers
│ │ │ └── Queries
│ │ │ │ └── GetAccountByIdHandlerTest.cs
│ │ │ ├── Tokens
│ │ │ └── TokenTest.cs
│ │ │ ├── Agree.Allow.Domain.Test.csproj
│ │ │ ├── DiscriminatorTagTest.cs
│ │ │ └── DiscriminatorTagFactoryTest.cs
│ └── src
│ │ ├── Agree.Allow.Domain
│ │ ├── Requests
│ │ │ ├── RefreshTokenRequest.cs
│ │ │ ├── PasswordLoginRequest.cs
│ │ │ ├── IAuthenticationRequest.cs
│ │ │ ├── GetClientApplicationByAccessKeyRequest.cs
│ │ │ ├── ValidateTokenRequest.cs
│ │ │ ├── GetAccountByIdRequest.cs
│ │ │ ├── SearchAccountsRequest.cs
│ │ │ └── CreateAccountRequest.cs
│ │ ├── IPasswordManager.cs
│ │ ├── Tokens
│ │ │ ├── JwtConfiguration.cs
│ │ │ ├── Token.cs
│ │ │ ├── RefreshTokenFactory.cs
│ │ │ └── AccessTokenFactory.cs
│ │ ├── Specifications
│ │ │ ├── ClientApplicationAccessKeyEqualSpecification.cs
│ │ │ ├── TagEqualSpecification.cs
│ │ │ ├── UserIdEqualSpecification.cs
│ │ │ ├── EmailEqualSpecification.cs
│ │ │ ├── NameTagLikeSpecification.cs
│ │ │ ├── UserNameEqualSpecification.cs
│ │ │ └── NameTagEqualSpecification.cs
│ │ ├── Results
│ │ │ ├── TokenValidationResult.cs
│ │ │ ├── CreateAccountResult.cs
│ │ │ └── AuthenticationResult.cs
│ │ ├── ClientApplication.cs
│ │ ├── Agree.Allow.Domain.csproj
│ │ ├── Handlers
│ │ │ ├── Queries
│ │ │ │ ├── GetAccountByIdHandler.cs
│ │ │ │ ├── SearchAccountsHandler.cs
│ │ │ │ └── GetClientApplicationByAccessKeyHandler.cs
│ │ │ └── Commands
│ │ │ │ ├── ValidateTokenHandler.cs
│ │ │ │ ├── RefreshTokenHandler.cs
│ │ │ │ └── PasswordLoginHandler.cs
│ │ ├── DiscriminatorTagFactory.cs
│ │ └── UserAccount.cs
│ │ ├── Agree.Allow.Presentation
│ │ ├── appsettings.json
│ │ ├── Accounts
│ │ │ └── ViewModels
│ │ │ │ ├── AuthenticationViewModel.cs
│ │ │ │ └── UserAccountViewModel.cs
│ │ ├── Exceptions
│ │ │ ├── EmptyBodyException.cs
│ │ │ └── InvalidGrantTypeException.cs
│ │ ├── Program.cs
│ │ ├── appsettings.Example.json
│ │ ├── Agree.Allow.Presentation.csproj
│ │ ├── Properties
│ │ │ └── launchSettings.json
│ │ └── CustomControllerBase.cs
│ │ ├── Agree.Allow.Infrastructure.Data
│ │ ├── MappingProfile.cs
│ │ ├── DatabaseOperationResult.cs
│ │ ├── ApplicationDbContextFactory.cs
│ │ ├── ClientApplicationDbModel.cs
│ │ ├── ApplicationDbContext.cs
│ │ ├── UserAccountDbModel.cs
│ │ └── Agree.Allow.Infrastructure.Data.csproj
│ │ ├── Agree.Allow.Infrastructure
│ │ ├── BCryptPasswordManager.cs
│ │ └── Agree.Allow.Infrastructure.csproj
│ │ └── Agree.Allow.Infrastructure.IoC
│ │ └── Agree.Allow.Infrastructure.IoC.csproj
├── accord
│ ├── src
│ │ ├── Agree.Accord.Domain
│ │ │ ├── Servers
│ │ │ │ ├── Requests
│ │ │ │ │ ├── SendServerInviteRequest.cs
│ │ │ │ │ ├── JoinServerRequest.cs
│ │ │ │ │ ├── CreateServerInviteRequest.cs
│ │ │ │ │ ├── GetServerByIdRequest.cs
│ │ │ │ │ ├── SearchServersRequest.cs
│ │ │ │ │ ├── CreateServerRequest.cs
│ │ │ │ │ └── CreateCategoryRequest.cs
│ │ │ │ ├── ServerPrivacy.cs
│ │ │ │ ├── Specifications
│ │ │ │ │ ├── BaseServerSpecification.cs
│ │ │ │ │ ├── ServerVisibleToUserSpecification.cs
│ │ │ │ │ ├── ServerInviteIdEqualSpecification.cs
│ │ │ │ │ ├── ServerIdEqualSpecification.cs
│ │ │ │ │ ├── BaseServerPaginatedSpecification.cs
│ │ │ │ │ └── ServerInfoLikeSpecification.cs
│ │ │ │ ├── Results
│ │ │ │ │ ├── CreateServerResult.cs
│ │ │ │ │ ├── CreateCategoryResult.cs
│ │ │ │ │ └── JoinServerResult.cs
│ │ │ │ ├── ServerInvite.cs
│ │ │ │ ├── ServerRolePermission.cs
│ │ │ │ ├── Category.cs
│ │ │ │ ├── Handlers
│ │ │ │ │ ├── Queries
│ │ │ │ │ │ ├── GetServerByIdHandler.cs
│ │ │ │ │ │ └── SearchServerHandler.cs
│ │ │ │ │ └── Commands
│ │ │ │ │ │ ├── CreateServerHandler.cs
│ │ │ │ │ │ └── CreateCategoryHandler.cs
│ │ │ │ ├── ServerMember.cs
│ │ │ │ ├── ServerRole.cs
│ │ │ │ └── Server.cs
│ │ │ ├── Exceptions
│ │ │ │ ├── FriendshipAlreadyAcceptedException.cs
│ │ │ │ └── FriendshipRequestNotForUserException.cs
│ │ │ ├── User.cs
│ │ │ ├── Social
│ │ │ │ ├── Notifications
│ │ │ │ │ ├── FriendshipRequestAcceptedNotification.cs
│ │ │ │ │ ├── FriendshipRequestCreatedNotification.cs
│ │ │ │ │ ├── FriendshipRequestDeclinedNotification.cs
│ │ │ │ │ └── DirectMessageCreatedNotification.cs
│ │ │ │ ├── Specifications
│ │ │ │ │ ├── FriendshipAcceptedSpecification.cs
│ │ │ │ │ ├── SentFriendshipRequestSpecification.cs
│ │ │ │ │ ├── FriendshipExistsSpecification.cs
│ │ │ │ │ ├── ReceivedFriendshipRequestSpecification.cs
│ │ │ │ │ ├── DirectMessageIdEqualSpecification.cs
│ │ │ │ │ └── DirectMessageFromOrToFriendSpecification.cs
│ │ │ │ ├── Results
│ │ │ │ │ ├── DirectMessageResult.cs
│ │ │ │ │ ├── RemoveFriendResult.cs
│ │ │ │ │ ├── FriendshipRequestResult.cs
│ │ │ │ │ └── DirectMessageReadResult.cs
│ │ │ │ ├── IDirectMessageRepository.cs
│ │ │ │ └── Handlers
│ │ │ │ │ ├── Queries
│ │ │ │ │ ├── GetFriendChatHandler.cs
│ │ │ │ │ ├── GetDirectMessageByIdHandler.cs
│ │ │ │ │ ├── GetUserSentFriendshipRequestsHandler.cs
│ │ │ │ │ ├── GetUserReceivedFriendshipRequestsHandler.cs
│ │ │ │ │ └── GetFriendsFromUserHandler.cs
│ │ │ │ │ └── Commands
│ │ │ │ │ ├── RemoveFriendHandler.cs
│ │ │ │ │ ├── MarkDirectMessageAsReadHandler.cs
│ │ │ │ │ ├── DeclineFriendshipRequestHandler.cs
│ │ │ │ │ └── AcceptFriendshipRequestHandler.cs
│ │ │ ├── Requests
│ │ │ │ ├── GetFriendsFromUserRequest.cs
│ │ │ │ ├── GetUserSentFriendshipRequestsRequest.cs
│ │ │ │ ├── GetUserReceivedFriendshipRequestsRequest.cs
│ │ │ │ ├── GetDirectMessageByIdRequest.cs
│ │ │ │ ├── RemoveFriendRequest.cs
│ │ │ │ ├── AcceptFriendshipRequestRequest.cs
│ │ │ │ ├── DeclineFriendshipRequestRequest.cs
│ │ │ │ ├── MarkDirectMessageAsReadRequest.cs
│ │ │ │ ├── SendFriendshipRequestRequest.cs
│ │ │ │ ├── SendDirectMessageRequest.cs
│ │ │ │ └── GetFriendChatRequest.cs
│ │ │ ├── Friendship.cs
│ │ │ ├── Agree.Accord.Domain.csproj
│ │ │ └── FriendshipRequest.cs
│ │ ├── Agree.Accord.Presentation
│ │ │ ├── appsettings.json
│ │ │ ├── Shared
│ │ │ │ ├── HubEvents.cs
│ │ │ │ ├── SocketHub.cs
│ │ │ │ ├── CustomControllerBase.cs
│ │ │ │ └── CustomHubBase.cs
│ │ │ ├── Responses
│ │ │ │ ├── GenericResponse.cs
│ │ │ │ └── ValidationErrorResponse.cs
│ │ │ ├── Program.cs
│ │ │ ├── Agree.Accord.Presentation.csproj
│ │ │ ├── appsettings.Example.json
│ │ │ ├── Properties
│ │ │ │ └── launchSettings.json
│ │ │ ├── Social
│ │ │ │ ├── ViewModels
│ │ │ │ │ ├── FriendshipRequestViewModel.cs
│ │ │ │ │ └── DirectMessageViewModel.cs
│ │ │ │ ├── Handlers
│ │ │ │ │ ├── DirectMessageCreatedNotificationHandler.cs
│ │ │ │ │ ├── FriendshipRequestCreatedNotificationHandler.cs
│ │ │ │ │ ├── FriendshipRequestAcceptedNotificationHandler.cs
│ │ │ │ │ └── FriendshipRequestDeclinedNotificationHandler.cs
│ │ │ │ └── Controllers
│ │ │ │ │ └── FriendsController.cs
│ │ │ └── Servers
│ │ │ │ └── ViewModels
│ │ │ │ ├── ServerViewModel.cs
│ │ │ │ └── RoleViewModel.cs
│ │ ├── Agree.Accord.Infrastructure
│ │ │ ├── Configuration
│ │ │ │ └── NativeMailProviderOptions.cs
│ │ │ ├── Agree.Accord.Infrastructure.csproj
│ │ │ └── Providers
│ │ │ │ └── NativeMailProvider.cs
│ │ ├── Agree.Accord.Infrastructure.Data
│ │ │ ├── DatabaseOperationResult.cs
│ │ │ ├── ApplicationDbContextFactory.cs
│ │ │ ├── Agree.Accord.Infrastructure.Data.csproj
│ │ │ └── FriendshipRepository.cs
│ │ └── Agree.Accord.Infrastructure.IoC
│ │ │ └── Agree.Accord.Infrastructure.IoC.csproj
│ ├── .config
│ │ └── dotnet-tools.json
│ ├── test
│ │ └── Agree.Accord.Domain.Test
│ │ │ ├── Agree.Accord.Domain.Test.csproj
│ │ │ └── DiscriminatorTagTest.cs
│ └── .vscode
│ │ ├── launch.json
│ │ ├── settings.json
│ │ └── tasks.json
└── concord_old
│ ├── src
│ ├── react-app-env.d.ts
│ ├── logic
│ │ ├── models
│ │ │ ├── AccordErrorList.ts
│ │ │ ├── Account.ts
│ │ │ ├── Server.ts
│ │ │ └── ServerPermissions.ts
│ │ ├── services
│ │ │ ├── ICache.ts
│ │ │ ├── ILogger.ts
│ │ │ ├── implementations
│ │ │ │ ├── LocalStorageCache.ts
│ │ │ │ ├── ConsoleLogger.ts
│ │ │ │ └── AxiosHttpClient.ts
│ │ │ └── IHttpClient.ts
│ │ ├── hooks
│ │ │ ├── useServers.ts
│ │ │ ├── useSyncCacheState.ts
│ │ │ └── useAllow.tsx
│ │ ├── mappings
│ │ │ └── ApiResponseToModelMapper.ts
│ │ └── contexts
│ │ │ └── ContextContainer.tsx
│ ├── presentation
│ │ ├── components
│ │ │ ├── avatar
│ │ │ │ ├── FriendListItem.scss
│ │ │ │ ├── ServerAvatar.scss
│ │ │ │ ├── UserAvatar.tsx
│ │ │ │ └── FriendListItem.tsx
│ │ │ ├── form
│ │ │ │ ├── SquareButton.tsx
│ │ │ │ ├── Button.tsx
│ │ │ │ ├── TextInput.tsx
│ │ │ │ └── PasswordInput.tsx
│ │ │ └── nav
│ │ │ │ └── ServerBar.tsx
│ │ ├── assets
│ │ │ ├── bg404.png
│ │ │ └── bglogin.png
│ │ ├── layouts
│ │ │ ├── SettingsLayout.scss
│ │ │ └── DashboardLayout.tsx
│ │ ├── hooks
│ │ │ ├── useI18n.ts
│ │ │ ├── useInputState.ts
│ │ │ ├── useBreakpoints.ts
│ │ │ └── useLoading.ts
│ │ ├── pages
│ │ │ ├── settings
│ │ │ │ ├── ProfileSettingsPage.tsx
│ │ │ │ └── AppearanceSettingsPage.tsx
│ │ │ ├── dashboard
│ │ │ │ ├── HomePage.tsx
│ │ │ │ └── ServerCreate.tsx
│ │ │ └── error
│ │ │ │ └── NotFoundPage.tsx
│ │ ├── App.tsx
│ │ ├── styles
│ │ │ ├── theme.ts
│ │ │ └── utils.scss
│ │ └── Routes.tsx
│ ├── validation
│ │ ├── IValidator.ts
│ │ └── RegisterValidator.ts
│ ├── i18n
│ │ └── index.ts
│ ├── index.tsx
│ └── reportWebVitals.ts
│ ├── public
│ ├── robots.txt
│ ├── favicon.ico
│ ├── apple-icon.png
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── favicon-96x96.png
│ ├── ms-icon-144x144.png
│ ├── ms-icon-150x150.png
│ ├── ms-icon-310x310.png
│ ├── ms-icon-70x70.png
│ ├── apple-icon-57x57.png
│ ├── apple-icon-60x60.png
│ ├── apple-icon-72x72.png
│ ├── apple-icon-76x76.png
│ ├── android-icon-144x144.png
│ ├── android-icon-192x192.png
│ ├── android-icon-36x36.png
│ ├── android-icon-48x48.png
│ ├── android-icon-72x72.png
│ ├── android-icon-96x96.png
│ ├── apple-icon-114x114.png
│ ├── apple-icon-120x120.png
│ ├── apple-icon-144x144.png
│ ├── apple-icon-152x152.png
│ ├── apple-icon-180x180.png
│ ├── apple-icon-precomposed.png
│ ├── browserconfig.xml
│ └── manifest.json
│ ├── .env.example
│ ├── .gitignore
│ ├── tsconfig.json
│ ├── README.md
│ ├── .vscode
│ └── settings.json
│ ├── .eslintrc.js
│ └── package.json
├── .vscode
├── settings.json
├── launch.json
└── tasks.json
└── LICENSE
/.tool-versions:
--------------------------------------------------------------------------------
1 | dotnet 6.0.401
2 |
--------------------------------------------------------------------------------
/docker/.env:
--------------------------------------------------------------------------------
1 | COMPOSE_PROJECT_NAME=agree
--------------------------------------------------------------------------------
/apps/allow/test/Agree.Allow.Test/Usings.cs:
--------------------------------------------------------------------------------
1 | global using Xunit;
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Requests/SendServerInviteRequest.cs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/concord_old/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/apps/concord_old/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/apps/concord_old/src/logic/models/AccordErrorList.ts:
--------------------------------------------------------------------------------
1 | export type AccordErrorList = Record
2 |
--------------------------------------------------------------------------------
/apps/concord_old/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/favicon.ico
--------------------------------------------------------------------------------
/apps/concord_old/public/apple-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/apple-icon.png
--------------------------------------------------------------------------------
/apps/allow/test/Agree.Allow.Domain.Test/Usings.cs:
--------------------------------------------------------------------------------
1 | global using System;
2 | global using Agree.Allow.Domain;
3 | global using Xunit;
--------------------------------------------------------------------------------
/apps/concord_old/.env.example:
--------------------------------------------------------------------------------
1 | REACT_APP_ALLOW_URL=http://localhost:5000/api
2 | REACT_APP_ACCORD_URL=http://localhost:4000/api
3 |
--------------------------------------------------------------------------------
/apps/concord_old/public/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/favicon-16x16.png
--------------------------------------------------------------------------------
/apps/concord_old/public/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/favicon-32x32.png
--------------------------------------------------------------------------------
/apps/concord_old/public/favicon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/favicon-96x96.png
--------------------------------------------------------------------------------
/apps/concord_old/public/ms-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/ms-icon-144x144.png
--------------------------------------------------------------------------------
/apps/concord_old/public/ms-icon-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/ms-icon-150x150.png
--------------------------------------------------------------------------------
/apps/concord_old/public/ms-icon-310x310.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/ms-icon-310x310.png
--------------------------------------------------------------------------------
/apps/concord_old/public/ms-icon-70x70.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/ms-icon-70x70.png
--------------------------------------------------------------------------------
/apps/concord_old/public/apple-icon-57x57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/apple-icon-57x57.png
--------------------------------------------------------------------------------
/apps/concord_old/public/apple-icon-60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/apple-icon-60x60.png
--------------------------------------------------------------------------------
/apps/concord_old/public/apple-icon-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/apple-icon-72x72.png
--------------------------------------------------------------------------------
/apps/concord_old/public/apple-icon-76x76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/apple-icon-76x76.png
--------------------------------------------------------------------------------
/apps/concord_old/public/android-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/android-icon-144x144.png
--------------------------------------------------------------------------------
/apps/concord_old/public/android-icon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/android-icon-192x192.png
--------------------------------------------------------------------------------
/apps/concord_old/public/android-icon-36x36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/android-icon-36x36.png
--------------------------------------------------------------------------------
/apps/concord_old/public/android-icon-48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/android-icon-48x48.png
--------------------------------------------------------------------------------
/apps/concord_old/public/android-icon-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/android-icon-72x72.png
--------------------------------------------------------------------------------
/apps/concord_old/public/android-icon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/android-icon-96x96.png
--------------------------------------------------------------------------------
/apps/concord_old/public/apple-icon-114x114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/apple-icon-114x114.png
--------------------------------------------------------------------------------
/apps/concord_old/public/apple-icon-120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/apple-icon-120x120.png
--------------------------------------------------------------------------------
/apps/concord_old/public/apple-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/apple-icon-144x144.png
--------------------------------------------------------------------------------
/apps/concord_old/public/apple-icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/apple-icon-152x152.png
--------------------------------------------------------------------------------
/apps/concord_old/public/apple-icon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/apple-icon-180x180.png
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/components/avatar/FriendListItem.scss:
--------------------------------------------------------------------------------
1 | .FriendListItemContainer.active {
2 | background-color: #5a189a;
3 | }
4 |
--------------------------------------------------------------------------------
/apps/concord_old/public/apple-icon-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/public/apple-icon-precomposed.png
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/assets/bg404.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/src/presentation/assets/bg404.png
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/assets/bglogin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vassourita/agree/HEAD/apps/concord_old/src/presentation/assets/bglogin.png
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/layouts/SettingsLayout.scss:
--------------------------------------------------------------------------------
1 | .SettingsLayoutNavLinkContainer > a.active {
2 | background-color: var(--chakra-colors-brand-800);
3 | }
4 |
--------------------------------------------------------------------------------
/apps/concord_old/src/logic/models/Account.ts:
--------------------------------------------------------------------------------
1 | export type Account = {
2 | id: string
3 | tag: string
4 | email: string
5 | userName: string
6 | verified: boolean
7 | }
8 |
--------------------------------------------------------------------------------
/apps/concord_old/src/validation/IValidator.ts:
--------------------------------------------------------------------------------
1 | import { ValidationError } from 'yup'
2 |
3 | export interface IValidator {
4 | validate(input: T): Promise
5 | }
6 |
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Requests/RefreshTokenRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Requests;
2 |
3 | public record RefreshTokenRequest(string RefreshToken) : IAuthenticationRequest
4 | {
5 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Requests/PasswordLoginRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Requests;
2 |
3 | public record PasswordLoginRequest(string EmailAddress, string Password) : IAuthenticationRequest
4 | {
5 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/logic/models/Server.ts:
--------------------------------------------------------------------------------
1 | export type Server = {
2 | name: string
3 | privacy: number
4 | privacyStr: string
5 | description: string
6 | roles: []
7 | members: []
8 | categories: []
9 | }
10 |
--------------------------------------------------------------------------------
/apps/accord/.config/dotnet-tools.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "isRoot": true,
4 | "tools": {
5 | "dotnet-ef": {
6 | "version": "6.0.7",
7 | "commands": [
8 | "dotnet-ef"
9 | ]
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Presentation/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | },
8 | "AllowedHosts": "*"
9 | }
10 |
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Requests/IAuthenticationRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Requests;
2 |
3 | using Agree.Allow.Domain.Results;
4 | using MediatR;
5 |
6 | public interface IAuthenticationRequest : IRequest
7 | {
8 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Requests/GetClientApplicationByAccessKeyRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Requests;
2 |
3 | using MediatR;
4 |
5 | public record GetClientApplicationByAccessKeyRequest(string AccessKey) : IRequest
6 | {
7 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/logic/models/ServerPermissions.ts:
--------------------------------------------------------------------------------
1 | export type ServerPermissions = {
2 | canAddUsers: string
3 | canRemoveUsers: string
4 | canUpdateServerDescription: string
5 | canUpdateServerName: string
6 | canUpdateServerPrivacy: string
7 | }
8 |
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Requests/ValidateTokenRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Requests;
2 |
3 | using Agree.Allow.Domain.Results;
4 | using MediatR;
5 |
6 | public record ValidateTokenRequest(string Token) : IRequest
7 | {
8 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/logic/services/ICache.ts:
--------------------------------------------------------------------------------
1 | export interface ICache {
2 | get (key: string): string | null
3 | get (key: string): T | null
4 | set (key: string, value: string): void
5 | set (key: string, value: T): void
6 | delete (key: string): void
7 | }
8 |
--------------------------------------------------------------------------------
/apps/concord_old/src/i18n/index.ts:
--------------------------------------------------------------------------------
1 | import { Resource } from '../presentation/contexts/I18nContext'
2 |
3 | import enUS from './en-US.json'
4 | import ptBR from './pt-BR.json'
5 |
6 | export const resource: Resource = {
7 | 'en-US': enUS,
8 | 'pt-BR': ptBR
9 | }
10 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/ServerPrivacy.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers;
2 |
3 | ///
4 | /// Representation of a server privacy level.
5 | ///
6 | public enum ServerPrivacy
7 | {
8 | Public,
9 | Private,
10 | Secret
11 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/logic/services/ILogger.ts:
--------------------------------------------------------------------------------
1 | export type LoggingLevel = 'info' | 'warn' | 'error'
2 |
3 | export interface ILogger {
4 | log(level: LoggingLevel, message: any): void
5 | info(message: any): void
6 | warn(message: any): void
7 | error(message: any): void
8 | }
9 |
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/hooks/useI18n.ts:
--------------------------------------------------------------------------------
1 | import { useContext } from 'react'
2 | import { I18nContext, I18nContextProps } from '../contexts/I18nContext'
3 |
4 | export function useI18n (): I18nContextProps {
5 | const ctx = useContext(I18nContext)
6 |
7 | return ctx
8 | }
9 |
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Requests/GetAccountByIdRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Requests;
2 |
3 | using System;
4 | using System.ComponentModel.DataAnnotations;
5 | using MediatR;
6 |
7 | public record GetAccountByIdRequest([Required] Guid Id) : IRequest
8 | {
9 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | },
9 | "AllowedHosts": "*"
10 | }
11 |
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/IPasswordManager.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain;
2 |
3 | using System.Threading.Tasks;
4 |
5 | public interface IPasswordManager
6 | {
7 | Task HashAsync(string password);
8 |
9 | Task CompareAsync(string hashed, string password);
10 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.exclude": {
3 | "**/.git": true,
4 | "**/.svn": true,
5 | "**/.hg": true,
6 | "**/CVS": true,
7 | "**/.DS_Store": true,
8 | "**/Thumbs.db": true,
9 | "**/obj": true,
10 | "**/bin": true,
11 | }
12 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/pages/settings/ProfileSettingsPage.tsx:
--------------------------------------------------------------------------------
1 | import { Flex, Heading } from '@chakra-ui/layout'
2 |
3 | export function ProfileSettingsPage (): JSX.Element {
4 | return (
5 |
6 | Meu perfil
7 |
8 | )
9 | }
10 |
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Presentation/Accounts/ViewModels/AuthenticationViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Presentation.Accounts.ViewModels;
2 |
3 | using Agree.Allow.Domain.Tokens;
4 |
5 | public record AuthenticationViewModel(TokenCollection Tokens)
6 | : TokenCollection(Tokens.RefreshToken, Tokens.AccessToken);
--------------------------------------------------------------------------------
/apps/concord_old/public/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 | #ffffff
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Exceptions/FriendshipAlreadyAcceptedException.cs:
--------------------------------------------------------------------------------
1 | using Agree.SharedKernel.Exceptions;
2 |
3 | public class FriendshipAlreadyAcceptedException : DomainException
4 | {
5 | public FriendshipAlreadyAcceptedException() : base("Accepted", "Friendship already accepted.")
6 | {
7 | }
8 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/logic/hooks/useServers.ts:
--------------------------------------------------------------------------------
1 | import { useContext } from 'react'
2 | import { ServerContext, ServerContextProps } from '../contexts/ServerContext'
3 |
4 | export function useServers (): ServerContextProps {
5 | const ctx = useContext(ServerContext)
6 |
7 | return {
8 | ...ctx
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/pages/settings/AppearanceSettingsPage.tsx:
--------------------------------------------------------------------------------
1 | import { Flex, Heading } from '@chakra-ui/layout'
2 |
3 | export function AppearanceSettingsPage (): JSX.Element {
4 | return (
5 |
6 | Aparência e tema
7 |
8 | )
9 | }
10 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Exceptions/FriendshipRequestNotForUserException.cs:
--------------------------------------------------------------------------------
1 | using Agree.SharedKernel.Exceptions;
2 |
3 | public class FriendshipRequestNotForUserException : DomainException
4 | {
5 | public FriendshipRequestNotForUserException() : base("To", "Friendship request not for the user.")
6 | {
7 | }
8 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/User.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain;
2 |
3 | using System;
4 |
5 | public class User
6 | {
7 | public Guid Id { get; private set; }
8 | public string Username { get; private set; }
9 | public string Tag { get; private set; }
10 | public virtual string NameTag => $"{Username}#{Tag}";
11 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Tokens/JwtConfiguration.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Tokens;
2 |
3 | public class JwtConfiguration
4 | {
5 | public string SigningKey { get; set; }
6 | public string Issuer { get; set; }
7 | public int AccessTokenExpiresInMinutes { get; set; }
8 | public int RefreshTokenExpiresInDays { get; set; }
9 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Requests/SearchAccountsRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Requests;
2 |
3 | using System.Collections.Generic;
4 | using Agree.SharedKernel.Data;
5 | using MediatR;
6 |
7 | public class SearchAccountsRequest : Pagination, IRequest>
8 | {
9 | public string Query { get; set; }
10 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom'
3 | import { App } from './presentation/App'
4 | import reportWebVitals from './reportWebVitals'
5 |
6 | ReactDOM.render(
7 |
8 |
9 | ,
10 | document.getElementById('root')
11 | )
12 |
13 | reportWebVitals()
14 |
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/components/avatar/ServerAvatar.scss:
--------------------------------------------------------------------------------
1 | .ServerAvatarContainer {
2 | position: relative;
3 | & > .active::after {
4 | content: '';
5 | width: 60px;
6 | height: 60px;
7 | right: -5px;
8 | bottom: -5px;
9 | position: absolute;
10 | border: 2px solid white;
11 | border-radius: 13px;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/docker/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | version: '3.7'
2 |
3 | services:
4 | accord_postgres:
5 | image: postgres:13-alpine
6 | allow_postgres:
7 | image: postgres:13-alpine
8 |
9 | volumes:
10 | accord_postgres_volume:
11 | allow_postgres_volume:
12 |
13 |
14 | networks:
15 | accord-network:
16 | driver: bridge
17 | allow-network:
18 | driver: bridge
19 |
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Presentation/Exceptions/EmptyBodyException.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Presentation.Exceptions;
2 |
3 | using System;
4 | using Agree.SharedKernel.Exceptions;
5 |
6 | [Serializable]
7 | public class EmptyBodyException : AgreeException
8 | {
9 | public EmptyBodyException()
10 | : base("Body", "Empty request body")
11 | {
12 | }
13 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/pages/dashboard/HomePage.tsx:
--------------------------------------------------------------------------------
1 | import { Flex, Heading } from '@chakra-ui/layout'
2 | import { useLocation } from 'react-router'
3 |
4 | export function HomePage () : JSX.Element {
5 | const location = useLocation()
6 |
7 | return (
8 |
9 | {location.pathname}
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/pages/dashboard/ServerCreate.tsx:
--------------------------------------------------------------------------------
1 | import { Flex, Heading } from '@chakra-ui/layout'
2 |
3 | export function ServerCreate (): JSX.Element {
4 | return (
5 |
6 |
7 | Criar novo servidor
8 |
9 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Notifications/FriendshipRequestAcceptedNotification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Notifications;
2 |
3 | using MediatR;
4 |
5 | public class FriendshipRequestAcceptedNotification : INotification
6 | {
7 | public FriendshipRequestAcceptedNotification(Friendship friendship)
8 | => Friendship = friendship;
9 |
10 | public Friendship Friendship { get; }
11 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Notifications/FriendshipRequestCreatedNotification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Notifications;
2 |
3 | using MediatR;
4 |
5 | public class FriendshipRequestCreatedNotification : INotification
6 | {
7 | public FriendshipRequestCreatedNotification(Friendship friendship)
8 | => Friendship = friendship;
9 |
10 | public Friendship Friendship { get; }
11 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Notifications/FriendshipRequestDeclinedNotification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Notifications;
2 |
3 | using MediatR;
4 |
5 | public class FriendshipRequestDeclinedNotification : INotification
6 | {
7 | public FriendshipRequestDeclinedNotification(Friendship friendship)
8 | => Friendship = friendship;
9 |
10 | public Friendship Friendship { get; }
11 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Notifications/DirectMessageCreatedNotification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Notifications;
2 |
3 | using MediatR;
4 |
5 | public class DirectMessageCreatedNotification : INotification
6 | {
7 | public DirectMessageCreatedNotification(DirectMessage directMessage)
8 | => DirectMessage = directMessage;
9 |
10 | public DirectMessage DirectMessage { get; }
11 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/Shared/HubEvents.cs:
--------------------------------------------------------------------------------
1 | public static class HubEvents
2 | {
3 | public const string FriendshipRequestCreated = "FriendshipRequestCreated";
4 | public const string FriendshipRequestDeclined = "FriendshipRequestDeclined";
5 | public const string FriendshipRequestAccepted = "FriendshipRequestAccepted";
6 |
7 | public const string DirectMessageCreated = "DirectMessageCreated";
8 |
9 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/Responses/GenericResponse.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Presentation.Responses;
2 |
3 | public class GenericResponse
4 | {
5 | public GenericResponse(object data) => Data = data;
6 |
7 | public object Data { get; private set; }
8 | }
9 |
10 | public class GenericResponse
11 | {
12 | public GenericResponse(T data) => Data = data;
13 |
14 | public T Data { get; private set; }
15 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Specifications/ClientApplicationAccessKeyEqualSpecification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Specifications;
2 |
3 | using Agree.SharedKernel.Data;
4 |
5 | public class ClientApplicationAccessKeyEqualSpecification : Specification
6 | {
7 | public ClientApplicationAccessKeyEqualSpecification(string accessKey)
8 | => Expression = x
9 | => x.AccessKey == accessKey;
10 | }
--------------------------------------------------------------------------------
/apps/concord_old/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
25 | .env
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/hooks/useInputState.ts:
--------------------------------------------------------------------------------
1 | import { ChangeEventHandler, useState } from 'react'
2 |
3 | export function useInputState (defaultValue?: string): [string, ChangeEventHandler] {
4 | const [state, setState] = useState(defaultValue || '')
5 |
6 | const onChange: ChangeEventHandler = (e) => {
7 | setState(e.target.value)
8 | }
9 |
10 | return [state, onChange]
11 | }
12 |
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/App.tsx:
--------------------------------------------------------------------------------
1 | import { BrowserRouter } from 'react-router-dom'
2 |
3 | import { Routes } from './Routes'
4 | import { ContextContainer } from '../logic/contexts/ContextContainer'
5 |
6 | import './styles/utils.scss'
7 |
8 | export function App (): JSX.Element {
9 | return (
10 |
11 |
12 |
13 |
14 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Requests/JoinServerRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers.Requests;
2 |
3 | using System;
4 | using Agree.Accord.Domain.Identity;
5 | using Agree.Accord.Domain.Servers.Results;
6 | using MediatR;
7 |
8 | public class JoinServerRequest : IRequest
9 | {
10 | public Guid ServerId { get; set; }
11 | public UserAccount User { get; set; }
12 | public Guid? InviteId { get; set; }
13 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Requests/CreateServerInviteRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers.Requests;
2 |
3 | using System;
4 | using Agree.Accord.Domain.Identity;
5 | using Agree.Accord.Domain.Servers.Results;
6 | using MediatR;
7 |
8 | public class CreateServerInviteRequest : IRequest
9 | {
10 | public Guid ServerId { get; set; }
11 | public UserAccount Inviter { get; set; }
12 | public DateTime ExpirationDate { get; set; }
13 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Infrastructure/Configuration/NativeMailProviderOptions.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Infrastructure.Configuration;
2 |
3 | ///
4 | /// The configuration for the class.
5 | ///
6 | public class NativeMailProviderOptions
7 | {
8 | public string Host { get; set; }
9 | public int Port { get; set; }
10 | public string UserName { get; set; }
11 | public string Password { get; set; }
12 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Specifications/TagEqualSpecification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Specifications;
2 |
3 | using Agree.SharedKernel.Data;
4 |
5 | public class TagEqualSpecification : Specification
6 | {
7 | public TagEqualSpecification(DiscriminatorTag tag)
8 | => Expression = x
9 | => x.Tag == tag;
10 |
11 | public TagEqualSpecification(UserAccount account)
12 | => Expression = x
13 | => x.Tag == account.Tag;
14 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/logic/mappings/ApiResponseToModelMapper.ts:
--------------------------------------------------------------------------------
1 | import { Server } from '../models/Server'
2 |
3 | export class ApiResponseToModelMapper {
4 | public static mapServer (data: any): Server {
5 | return {
6 | name: data.name,
7 | description: data.description,
8 | members: data.members,
9 | categories: data.categories,
10 | roles: data.roles,
11 | privacy: data.privacy,
12 | privacyStr: data.privacy_str
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Requests/GetFriendsFromUserRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Requests;
2 |
3 | using System.Collections.Generic;
4 | using System.ComponentModel.DataAnnotations;
5 | using MediatR;
6 |
7 | public class GetFriendsFromUserRequest : IRequest>
8 | {
9 | public GetFriendsFromUserRequest() { }
10 | public GetFriendsFromUserRequest(User user) => User = user;
11 |
12 | [Required]
13 | public User User { get; set; }
14 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/styles/theme.ts:
--------------------------------------------------------------------------------
1 | import { extendTheme } from '@chakra-ui/react'
2 |
3 | export const theme = extendTheme({
4 | colors: {
5 | brand: {
6 | 900: '#201F29',
7 | 800: '#20152F',
8 | 700: '#3C096C',
9 | 600: '#5A189A',
10 | 500: '#7B2CBF',
11 | 400: '#9D4EDD'
12 | }
13 | },
14 | fonts: {
15 | heading: 'Sarabun',
16 | body: 'Sarabun'
17 | },
18 | config: {
19 | initialColorMode: 'dark'
20 | }
21 | })
22 |
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Results/TokenValidationResult.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Results;
2 |
3 | using Agree.SharedKernel;
4 |
5 | public class TokenValidationResult : Result
6 | {
7 | private TokenValidationResult(UserAccount user) : base(user)
8 | { }
9 | private TokenValidationResult() : base()
10 | { }
11 |
12 | public static TokenValidationResult Ok(UserAccount user) => new(user);
13 | public static TokenValidationResult Fail() => new();
14 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Specifications/UserIdEqualSpecification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Specifications;
2 |
3 | using System;
4 | using Agree.SharedKernel.Data;
5 |
6 | public class UserIdEqualSpecification : Specification
7 | {
8 | public UserIdEqualSpecification(Guid id)
9 | => Expression = x
10 | => x.Id == id;
11 |
12 | public UserIdEqualSpecification(UserAccount account)
13 | => Expression = x
14 | => x.Id == account.Id;
15 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/Responses/ValidationErrorResponse.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Presentation.Responses;
2 |
3 | using Agree.Accord.SharedKernel;
4 |
5 | ///
6 | /// The response to a validation error.
7 | ///
8 | public class ValidationErrorResponse
9 | {
10 | public ValidationErrorResponse(ErrorList errors) => Errors = errors;
11 | public ErrorList Errors { get; private set; }
12 | public string Message => "One or more validation errors occurred.";
13 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Specifications/EmailEqualSpecification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Specifications;
2 |
3 | using Agree.SharedKernel.Data;
4 |
5 | public class EmailEqualSpecification : Specification
6 | {
7 | public EmailEqualSpecification(string email)
8 | => Expression = x
9 | => x.EmailAddress == email;
10 |
11 | public EmailEqualSpecification(UserAccount account)
12 | => Expression = x
13 | => x.EmailAddress == account.EmailAddress;
14 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/hooks/useBreakpoints.ts:
--------------------------------------------------------------------------------
1 | import { useBreakpoint } from '@chakra-ui/media-query'
2 |
3 | export function useBreakpoints (): boolean[] {
4 | const breakpoint = useBreakpoint()
5 |
6 | return [
7 | breakpoint === 'base',
8 | ['base', 'sm'].includes(breakpoint || ''),
9 | ['base', 'sm', 'md'].includes(breakpoint || ''),
10 | ['base', 'sm', 'md', 'lg'].includes(breakpoint || ''),
11 | ['base', 'sm', 'md', 'lg', ' xl'].includes(breakpoint || '')
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/apps/concord_old/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from 'web-vitals'
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler): void => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6 | getCLS(onPerfEntry)
7 | getFID(onPerfEntry)
8 | getFCP(onPerfEntry)
9 | getLCP(onPerfEntry)
10 | getTTFB(onPerfEntry)
11 | })
12 | }
13 | }
14 |
15 | export default reportWebVitals
16 |
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Results/CreateAccountResult.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Results;
2 |
3 | using Agree.SharedKernel;
4 |
5 | public class CreateAccountResult : Result
6 | {
7 | private CreateAccountResult(UserAccount user) : base((user))
8 | { }
9 | private CreateAccountResult(ErrorList error) : base(error)
10 | { }
11 |
12 | public static CreateAccountResult Ok(UserAccount user) => new(user);
13 | public static CreateAccountResult Fail(ErrorList data) => new(data);
14 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Specifications/BaseServerSpecification.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Linq.Expressions;
4 | using Agree.Accord.Domain.Servers;
5 | using Agree.Accord.SharedKernel.Data;
6 |
7 | public abstract class BaseServerSpecification : AndSpecification
8 | {
9 | public BaseServerSpecification(Expression> expression, Guid userId)
10 | : base(new GenericSpecification(expression), new ServerVisibleToUserSpecification(userId))
11 | { }
12 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Specifications/ServerVisibleToUserSpecification.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using Agree.Accord.Domain.Servers;
4 | using Agree.Accord.SharedKernel.Data;
5 |
6 | public class ServerVisibleToUserSpecification : Specification
7 | {
8 | public ServerVisibleToUserSpecification(Guid userId)
9 | => Expression = x
10 | => (x.PrivacyLevel == ServerPrivacy.Public || x.PrivacyLevel == ServerPrivacy.Private)
11 | || x.Members.Any(m => m.UserId == userId);
12 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Presentation/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Presentation;
2 |
3 | using Microsoft.AspNetCore.Hosting;
4 | using Microsoft.Extensions.Hosting;
5 |
6 | public class Program
7 | {
8 | public static void Main(string[] args) => CreateHostBuilder(args).Build().Run();
9 |
10 | public static IHostBuilder CreateHostBuilder(string[] args)
11 | => Host
12 | .CreateDefaultBuilder(args)
13 | .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup());
14 | }
15 |
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Presentation/appsettings.Example.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | },
9 | "JwtConfiguration": {
10 | "SigningKey": "someMD5",
11 | "Audience": "http://localhost",
12 | "Issuer": "http://localhost:5000/"
13 | },
14 | "ConnectionStrings": {
15 | "DefaultConnection": "Server=localhost;Port=4001;Uid=docker;Pwd=docker;Database=accord_db"
16 | }
17 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Infrastructure.Data/DatabaseOperationResult.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Infrastructure.Data;
2 |
3 | using Agree.Accord.SharedKernel;
4 |
5 | ///
6 | /// A result of a no-return database operation.
7 | ///
8 | public class DatabaseOperationResult : Result
9 | {
10 | private DatabaseOperationResult(bool succeeded) : base(succeeded)
11 | { }
12 | public static IResult Ok() => new DatabaseOperationResult(true);
13 | public static IResult Fail() => new DatabaseOperationResult(false);
14 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Presentation;
2 |
3 | using Microsoft.AspNetCore.Hosting;
4 | using Microsoft.Extensions.Hosting;
5 |
6 | public class Program
7 | {
8 | public static void Main(string[] args) => CreateHostBuilder(args).Build().Run();
9 |
10 | public static IHostBuilder CreateHostBuilder(string[] args)
11 | => Host
12 | .CreateDefaultBuilder(args)
13 | .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup());
14 | }
15 |
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Results/AuthenticationResult.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Results;
2 |
3 | using Agree.Allow.Domain.Tokens;
4 | using Agree.SharedKernel;
5 |
6 | public class AuthenticationResult : Result
7 | {
8 | private AuthenticationResult(TokenCollection tokens) : base(tokens)
9 | { }
10 | private AuthenticationResult() : base()
11 | { }
12 |
13 | public static AuthenticationResult Ok(TokenCollection tokens) => new(tokens);
14 | public static AuthenticationResult Fail() => new();
15 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Specifications/ServerInviteIdEqualSpecification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers.Specifications;
2 |
3 | using System;
4 | using Agree.Accord.SharedKernel.Data;
5 |
6 | public class ServerInviteIdEqualSpecification : Specification
7 | {
8 | public ServerInviteIdEqualSpecification(Guid id)
9 | => Expression = x
10 | => x.Id == id;
11 |
12 | public ServerInviteIdEqualSpecification(ServerInvite invite)
13 | => Expression = x
14 | => x.Id == invite.Id;
15 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/Shared/SocketHub.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Presentation.Shared;
2 |
3 | using System.Threading.Tasks;
4 | using Agree.Accord.Domain.Identity;
5 | using Agree.Accord.Domain.Identity.Requests;
6 | using Agree.Accord.Presentation.Identity.ViewModels;
7 | using MediatR;
8 | using Microsoft.AspNetCore.SignalR;
9 | using Microsoft.Extensions.Logging;
10 |
11 | public class SocketHub : CustomHubBase
12 | {
13 | public SocketHub(ILogger logger, IMediator mediator)
14 | : base(logger, mediator) { }
15 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Tokens/Token.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Tokens;
2 |
3 | public class Token
4 | {
5 | public Token(string tokenValue, long expiresIn, string type)
6 | {
7 | TokenValue = tokenValue;
8 | ExpiresIn = expiresIn;
9 | Type = type;
10 | }
11 |
12 | public string TokenValue { get; private set; }
13 |
14 | public long ExpiresIn { get; private set; }
15 |
16 | public string Type { get; private set; }
17 | }
18 |
19 | public record TokenCollection(Token AccessToken, Token RefreshToken);
--------------------------------------------------------------------------------
/apps/concord_old/src/logic/services/implementations/LocalStorageCache.ts:
--------------------------------------------------------------------------------
1 | import { ICache } from '../ICache'
2 |
3 | export class LocalStorageCache implements ICache {
4 | get (key: string): T | null {
5 | const item = localStorage.getItem(key)
6 | if (!item) {
7 | return null
8 | }
9 | return JSON.parse(item) as T
10 | }
11 |
12 | set (key: string, value: T): void {
13 | localStorage.setItem(key, JSON.stringify(value))
14 | }
15 |
16 | delete (key: string): void {
17 | localStorage.removeItem(key)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Infrastructure/Agree.Accord.Infrastructure.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | net6.0
10 | 2.0
11 | enable
12 |
13 |
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/layouts/DashboardLayout.tsx:
--------------------------------------------------------------------------------
1 | import { Flex } from '@chakra-ui/layout'
2 | import { PropsWithChildren } from 'react'
3 | import { ServerBar } from '../components/nav/ServerBar'
4 | import { SideBar } from '../components/nav/SideBar'
5 |
6 | export function DashboardLayout ({ children }: PropsWithChildren): JSX.Element {
7 | return (
8 |
9 |
10 |
11 |
12 | {children}
13 |
14 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Infrastructure.Data/MappingProfile.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Infrastructure.Data;
2 |
3 | using Agree.Allow.Domain;
4 | using AutoMapper;
5 |
6 | public class MappingProfile : Profile
7 | {
8 | public MappingProfile()
9 | {
10 | CreateMap()
11 | .ForMember(dest => dest.Tag, opt => opt.MapFrom(src => src.Tag.Value));
12 | CreateMap()
13 | .ForMember(dest => dest.Tag, opt => opt.MapFrom(src => DiscriminatorTag.Parse(src.Tag)));
14 | }
15 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Requests/GetUserSentFriendshipRequestsRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Requests;
2 |
3 | using System.Collections.Generic;
4 | using System.ComponentModel.DataAnnotations;
5 | using Agree.Accord.Domain.Social;
6 | using MediatR;
7 |
8 | public class GetUserSentFriendshipRequestsRequest : IRequest>
9 | {
10 | public GetUserSentFriendshipRequestsRequest() { }
11 | public GetUserSentFriendshipRequestsRequest(User user) => User = user;
12 |
13 | [Required]
14 | public User User { get; set; }
15 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Specifications/FriendshipAcceptedSpecification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Specifications;
2 |
3 | using System;
4 | using Agree.Accord.SharedKernel.Data;
5 |
6 | ///
7 | /// A specification that checks if a friendship has been accepted.
8 | ///
9 | public class FriendshipAcceptedSpecification : Specification
10 | {
11 | public FriendshipAcceptedSpecification(Guid userId)
12 | => Expression = x
13 | => (x.ToId == userId && x.Accepted) || (x.FromId == userId && x.Accepted);
14 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Results/CreateServerResult.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers.Results;
2 |
3 | using Agree.Accord.Domain.Servers;
4 | using Agree.Accord.SharedKernel;
5 |
6 | public class CreateServerResult : Result
7 | {
8 | private CreateServerResult(Server server) : base(server)
9 | { }
10 | private CreateServerResult(ErrorList error) : base(error)
11 | { }
12 |
13 | public static CreateServerResult Ok(Server server) => new(server);
14 | public static CreateServerResult Fail(ErrorList data) => new(data);
15 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Specifications/SentFriendshipRequestSpecification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Specifications;
2 |
3 | using System;
4 | using Agree.Accord.SharedKernel.Data;
5 |
6 | ///
7 | /// A specification that checks if a given friendship request has been sent but not accepted yet.
8 | ///
9 | public class SentFriendshipRequestSpecification : Specification
10 | {
11 | public SentFriendshipRequestSpecification(Guid userId)
12 | => Expression = x
13 | => x.FromId == userId && !x.Accepted;
14 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Infrastructure.Data/DatabaseOperationResult.cs:
--------------------------------------------------------------------------------
1 | using Agree.SharedKernel;
2 |
3 | namespace Agree.Allow.Infrastructure.Data
4 | {
5 | public class DatabaseOperationResult : Result
6 | {
7 | private DatabaseOperationResult(bool succeeded) : base(succeeded)
8 | { }
9 | public static IResult Ok()
10 | {
11 | return new DatabaseOperationResult(true);
12 | }
13 |
14 | public static IResult Fail()
15 | {
16 | return new DatabaseOperationResult(false);
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/logic/hooks/useSyncCacheState.ts:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 | import { ICache } from '../services/ICache'
3 |
4 | export function useSyncCacheState (cache: ICache, key: string, defaultValue?: T): [() => T | null | null, (value: T | null) => void, () => void] {
5 | useEffect(() => {
6 | if (!cache.get(key) && !!defaultValue) {
7 | cache.set(key, defaultValue)
8 | }
9 | }, [])
10 |
11 | return [
12 | () => cache.get(key),
13 | (value: T | null) => cache.set(key, value),
14 | () => cache.delete(key)
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Specifications/FriendshipExistsSpecification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Specifications;
2 |
3 | using System;
4 | using Agree.Accord.SharedKernel.Data;
5 |
6 | ///
7 | /// A specification that checks if a friendship exists between two users.
8 | ///
9 | public class FriendshipExistsSpecification : Specification
10 | {
11 | public FriendshipExistsSpecification(Guid from, Guid to)
12 | => Expression = x
13 | => (x.ToId == to && x.FromId == from) || (x.ToId == from && x.FromId == to);
14 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Requests/GetUserReceivedFriendshipRequestsRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Requests;
2 |
3 | using System.Collections.Generic;
4 | using System.ComponentModel.DataAnnotations;
5 | using Agree.Accord.Domain.Social;
6 | using MediatR;
7 |
8 | public class GetUserReceivedFriendshipRequestsRequest : IRequest>
9 | {
10 | public GetUserReceivedFriendshipRequestsRequest() { }
11 | public GetUserReceivedFriendshipRequestsRequest(User user) => User = user;
12 |
13 | [Required]
14 | public User User { get; set; }
15 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Specifications/ServerIdEqualSpecification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers.Specifications;
2 |
3 | using System;
4 | using Agree.Accord.Domain.Servers;
5 | using Agree.Accord.SharedKernel.Data;
6 |
7 | ///
8 | /// A specification that checks if the server id of a given server is equal to a given value.
9 | ///
10 | public class ServerIdEqualSpecification : BaseServerSpecification
11 | {
12 | public ServerIdEqualSpecification(Guid serverId, Guid userId)
13 | : base((s) => s.Id == serverId, userId)
14 | { }
15 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/styles/utils.scss:
--------------------------------------------------------------------------------
1 | .hide-scrollbar {
2 | -ms-overflow-style: none; /* IE and Edge */
3 | scrollbar-width: none; /* Firefox */
4 | &::-webkit-scrollbar {
5 | display: none;
6 | }
7 | }
8 |
9 | .custom-scrollbar {
10 | &::-webkit-scrollbar {
11 | width: 3px;
12 | height: 5px;
13 | }
14 | &::-webkit-scrollbar-thumb {
15 | background: #5a189a;
16 | border-radius: 5px;
17 | }
18 | &::-webkit-scrollbar-thumb:hover {
19 | background: #7b2cbf;
20 | }
21 | &::-webkit-scrollbar-track {
22 | background: none;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Requests/GetDirectMessageByIdRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Requests;
2 |
3 | using System;
4 | using System.ComponentModel.DataAnnotations;
5 | using MediatR;
6 |
7 | ///
8 | /// The request to get a direct message by its Id.
9 | ///
10 | public class GetDirectMessagebyIdRequest : IRequest
11 | {
12 | ///
13 | /// The id of the direct message to be retrieved.
14 | ///
15 | /// The direct message id.
16 | [Required]
17 | public Guid Id { get; set; }
18 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Specifications/ReceivedFriendshipRequestSpecification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Specifications;
2 |
3 | using System;
4 | using Agree.Accord.SharedKernel.Data;
5 |
6 | ///
7 | /// A specification that checks if a given friendship request has been received but not accepted yet.
8 | ///
9 | public class ReceivedFriendshipRequestSpecification : Specification
10 | {
11 | public ReceivedFriendshipRequestSpecification(Guid userId)
12 | => Expression = x
13 | => x.ToId == userId && !x.Accepted;
14 | }
--------------------------------------------------------------------------------
/apps/allow/test/Agree.Allow.Domain.Test/testsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | },
9 | "JwtConfiguration": {
10 | "SigningKey": "d6f3c6b9bb9f3be036c93196f93906c7",
11 | "Issuer": "http://localhost:5000/",
12 | "AccessTokenExpiresInMinutes": 30,
13 | "RefreshTokenExpiresInDays": 30
14 | },
15 | "ConnectionStrings": {
16 | "DefaultConnection": ":memory:"
17 | }
18 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Results/CreateCategoryResult.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers.Results;
2 |
3 | using Agree.Accord.Domain.Servers;
4 | using Agree.Accord.SharedKernel;
5 |
6 | public class CreateCategoryResult : Result
7 | {
8 | private CreateCategoryResult(Category category) : base(category)
9 | { }
10 | private CreateCategoryResult(ErrorList error) : base(error)
11 | { }
12 |
13 | public static CreateCategoryResult Ok(Category category) => new(category);
14 | public static CreateCategoryResult Fail(ErrorList data) => new(data);
15 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Specifications/BaseServerPaginatedSpecification.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Linq.Expressions;
4 | using Agree.Accord.Domain.Servers;
5 | using Agree.Accord.SharedKernel.Data;
6 |
7 | public abstract class BaseServerPaginatedSpecification : PaginatedAndSpecification
8 | {
9 | public BaseServerPaginatedSpecification(Expression> expression, Guid userId, IPagination pagination)
10 | : base(new GenericSpecification(expression), new ServerVisibleToUserSpecification(userId), pagination)
11 | { }
12 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/Agree.Accord.Presentation.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net6.0
4 | enable
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Infrastructure/BCryptPasswordManager.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Infrastructure.Providers;
2 |
3 | using System;
4 | using System.Threading.Tasks;
5 | using Agree.Allow.Domain;
6 |
7 | public class BCryptPasswordManager : IPasswordManager, IDisposable
8 | {
9 | public Task HashAsync(string password)
10 | => Task.Run(() => BCrypt.Net.BCrypt.HashPassword(password));
11 |
12 | public Task CompareAsync(string hashed, string password)
13 | => Task.Run(() => BCrypt.Net.BCrypt.Verify(password, hashed));
14 |
15 | public void Dispose() => GC.SuppressFinalize(this);
16 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/ClientApplication.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain;
2 |
3 | using Agree.SharedKernel;
4 |
5 | public class ClientApplication : IEntity
6 | {
7 | public ClientApplication(string name, string audienceName)
8 | {
9 | Id = Guid.NewGuid();
10 | Name = name;
11 | AudienceName = audienceName;
12 | AccessKey = Guid.NewGuid().ToString("N");
13 | }
14 |
15 | public Guid Id { get; private set; }
16 | public string Name { get; private set; }
17 | public string AudienceName { get; private set; }
18 | public string AccessKey { get; private set; }
19 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Friendship.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain;
2 |
3 | using System;
4 | using Agree.SharedKernel;
5 |
6 | public class Friendship : IEntity
7 | {
8 | public Friendship(User from, User to)
9 | {
10 | Id = Guid.NewGuid();
11 | From = from;
12 | To = to;
13 | CreatedAt = DateTime.UtcNow;
14 | }
15 |
16 | public Guid Id { get; private set; }
17 | public User From { get; private set; }
18 | public User To { get; private set; }
19 |
20 | public DateTime CreatedAt { get; private set; }
21 | public DateTime AcceptedAt { get; private set; }
22 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/ServerInvite.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers;
2 |
3 | using System;
4 | using Agree.Accord.SharedKernel;
5 |
6 | public class ServerInvite : IEntity
7 | {
8 | public Guid Id { get; private set; }
9 | public Server Server { get; private set; }
10 | public DateTime ExpirationDate { get; private set; }
11 | public bool IsExpired => ExpirationDate < DateTime.UtcNow;
12 |
13 | public ServerInvite(Server server, DateTime expirationDate)
14 | {
15 | Id = Guid.NewGuid();
16 | Server = server;
17 | ExpirationDate = expirationDate;
18 | }
19 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Requests/RemoveFriendRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Requests;
2 |
3 | using Agree.Accord.Domain.Social.Results;
4 | using MediatR;
5 | using System;
6 | using System.ComponentModel.DataAnnotations;
7 |
8 | public class RemoveFriendRequest : IRequest
9 | {
10 | public RemoveFriendRequest() { }
11 |
12 | public RemoveFriendRequest(User user, Guid friendId)
13 | {
14 | User = user;
15 | FriendId = friendId;
16 | }
17 |
18 | [Required]
19 | public User User { get; set; }
20 |
21 | [Required]
22 | public Guid FriendId { get; set; }
23 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Specifications/NameTagLikeSpecification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Specifications;
2 |
3 | using System;
4 | using System.Linq.Expressions;
5 | using Agree.SharedKernel.Data;
6 |
7 | public class NameTagLikeSpecification : Specification, IPaginatedSpecification
8 | {
9 | public NameTagLikeSpecification(string query, IPagination pagination)
10 | {
11 | Expression = x
12 | => (x.Username + "#" + x.Tag).ToLower().Contains(query.ToLower());
13 |
14 | Pagination = pagination;
15 | }
16 |
17 | public IPagination Pagination { get; private set; }
18 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Results/JoinServerResult.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers.Results;
2 |
3 | using Agree.Accord.SharedKernel;
4 |
5 | ///
6 | /// The result of joining a server.
7 | ///
8 | public class JoinServerResult : Result
9 | {
10 | private JoinServerResult(ServerMember serverMember) : base(serverMember)
11 | { }
12 | private JoinServerResult(ErrorList error) : base(error)
13 | { }
14 |
15 | public static JoinServerResult Ok(ServerMember serverMember) => new(serverMember);
16 | public static JoinServerResult Fail(ErrorList data) => new(data);
17 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Agree.Accord.Domain.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | net6.0
11 | 2.0
12 | enable
13 |
14 |
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Presentation/Exceptions/InvalidGrantTypeException.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Presentation.Exceptions;
2 |
3 | using System;
4 | using System.Runtime.Serialization;
5 | using Agree.SharedKernel;
6 | using Agree.SharedKernel.Exceptions;
7 |
8 | [Serializable]
9 | public class InvalidGrantTypeException : AgreeException
10 | {
11 | public InvalidGrantTypeException(string grantType)
12 | : base("grant_type", $"Invalid grant type '{grantType}'. Must be 'refresh_token' or 'password'.")
13 | {
14 | }
15 |
16 | public InvalidGrantTypeException()
17 | : base("grant_type", "Empty grant type")
18 | {
19 | }
20 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Specifications/DirectMessageIdEqualSpecification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Specifications;
2 |
3 | using System;
4 | using Agree.Accord.SharedKernel.Data;
5 |
6 | ///
7 | /// A specification that checks if the message id of a given message is equal to a given value.
8 | ///
9 | public class DirectMessageIdEqualSpecification : Specification
10 | {
11 | public DirectMessageIdEqualSpecification(Guid id) => Expression = x => x.Id == id;
12 |
13 | public DirectMessageIdEqualSpecification(DirectMessage message)
14 | => Expression = x
15 | => x.Id == message.Id;
16 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Agree.Allow.Domain.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 | enable
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Results/DirectMessageResult.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Results;
2 |
3 | using Agree.Accord.SharedKernel;
4 |
5 | ///
6 | /// The result of an operation on a direct message request.
7 | ///
8 | public class DirectMessageResult : Result
9 | {
10 | private DirectMessageResult(DirectMessage message) : base(message)
11 | { }
12 | private DirectMessageResult(ErrorList error) : base(error)
13 | { }
14 |
15 | public static DirectMessageResult Ok(DirectMessage message) => new(message);
16 | public static DirectMessageResult Fail(ErrorList data) => new(data);
17 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Results/RemoveFriendResult.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Results;
2 |
3 | using Agree.Accord.SharedKernel;
4 |
5 | ///
6 | /// The result of an operation on a friendship removal request.
7 | ///
8 | public class RemoveFriendResult : Result
9 | {
10 | private RemoveFriendResult(Friendship friendship) : base(friendship)
11 | { }
12 | private RemoveFriendResult(ErrorList error) : base(error)
13 | { }
14 |
15 | public static RemoveFriendResult Ok(Friendship friendship) => new(friendship);
16 | public static RemoveFriendResult Fail(ErrorList data) => new(data);
17 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Infrastructure.Data/ApplicationDbContextFactory.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Infrastructure.Data;
2 |
3 | using Microsoft.EntityFrameworkCore;
4 | using Microsoft.EntityFrameworkCore.Design;
5 |
6 | public class ApplicationDbContextFactory : IDesignTimeDbContextFactory
7 | {
8 | public ApplicationDbContext CreateDbContext(string[] args)
9 | {
10 | var optionsBuilder = new DbContextOptionsBuilder();
11 |
12 | optionsBuilder.UseNpgsql("Server=localhost;Port=4001;Uid=docker;Pwd=docker;Database=allow_db");
13 |
14 | return new ApplicationDbContext(optionsBuilder.Options);
15 | }
16 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Infrastructure.Data/ClientApplicationDbModel.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Infrastructure.Data;
2 |
3 | using System.ComponentModel.DataAnnotations;
4 | using System.ComponentModel.DataAnnotations.Schema;
5 |
6 | [Table("ClientApplications")]
7 | public class ClientApplicationDbModel
8 | {
9 | [Key]
10 | public Guid Id { get; private set; }
11 |
12 | [Required]
13 | [MaxLength(100)]
14 | public string Name { get; private set; }
15 |
16 | [Required]
17 | [MaxLength(100)]
18 | public string AudienceName { get; private set; }
19 |
20 | [Required]
21 | [MaxLength(100)]
22 | public string AccessKey { get; private set; }
23 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Infrastructure/Agree.Allow.Infrastructure.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | net6.0
14 | enable
15 | enable
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Results/FriendshipRequestResult.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Results;
2 |
3 | using Agree.Accord.SharedKernel;
4 |
5 | ///
6 | /// The result of an operation on a friendship request.
7 | ///
8 | public class FriendshipRequestResult : Result
9 | {
10 | private FriendshipRequestResult(Friendship friendship) : base(friendship)
11 | { }
12 | private FriendshipRequestResult(ErrorList error) : base(error)
13 | { }
14 |
15 | public static FriendshipRequestResult Ok(Friendship friendship) => new(friendship);
16 | public static FriendshipRequestResult Fail(ErrorList data) => new(data);
17 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/logic/services/IHttpClient.ts:
--------------------------------------------------------------------------------
1 | export type HttpMethod = 'post' | 'get' | 'put' | 'delete'
2 |
3 | export enum HttpStatusCode {
4 | OK = 200,
5 | CREATED = 201,
6 | NOCONTENT = 204,
7 | BADREQUEST = 400,
8 | UNAUTHORIZED = 401,
9 | FORBIDDEN = 403,
10 | NOTFOUND = 404,
11 | SERVERERROR = 500
12 | }
13 |
14 | export type HttpRequest = {
15 | url: string
16 | method: HttpMethod
17 | body?: any
18 | headers?: any
19 | }
20 |
21 | export type HttpResponse = {
22 | statusCode: HttpStatusCode
23 | body?: T
24 | headers?: any
25 | }
26 |
27 | export interface IHttpClient {
28 | request: (data: HttpRequest) => Promise>
29 | }
30 |
--------------------------------------------------------------------------------
/apps/concord_old/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "module": "esnext",
17 | "moduleResolution": "node",
18 | "resolveJsonModule": true,
19 | "downlevelIteration": true,
20 | "isolatedModules": true,
21 | "noEmit": true,
22 | "jsx": "react-jsx"
23 | },
24 | "include": [
25 | "src"
26 | ]
27 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Infrastructure.Data/ApplicationDbContext.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Infrastructure.Data;
2 |
3 | using System;
4 | using Microsoft.EntityFrameworkCore;
5 |
6 | public class ApplicationDbContext : DbContext
7 | {
8 | public ApplicationDbContext(DbContextOptions options)
9 | : base(options) { }
10 |
11 | public DbSet UserAccounts { get; set; }
12 | public DbSet ClientApplications { get; set; }
13 |
14 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
15 | => optionsBuilder
16 | .LogTo(Console.WriteLine)
17 | .EnableSensitiveDataLogging();
18 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/logic/services/implementations/ConsoleLogger.ts:
--------------------------------------------------------------------------------
1 | import { ILogger, LoggingLevel } from '../ILogger'
2 |
3 | export class ConsoleLogger implements ILogger {
4 | public log (level: LoggingLevel, message: unknown): void {
5 | if (process.env.NODE_ENV !== 'production') console[level](message)
6 | }
7 |
8 | public info (message: unknown): void {
9 | if (process.env.NODE_ENV !== 'production') console.log(message)
10 | }
11 |
12 | public warn (message: unknown): void {
13 | if (process.env.NODE_ENV !== 'production') console.warn(message)
14 | }
15 |
16 | public error (message: unknown): void {
17 | if (process.env.NODE_ENV !== 'production') console.error(message)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/appsettings.Example.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | },
9 | "JwtConfiguration": {
10 | "SigningKey": "someMD5",
11 | "Audience": "http://localhost",
12 | "Issuer": "http://localhost:5000/"
13 | },
14 | "ConnectionStrings": {
15 | "DefaultConnection": "Server=localhost;Port=4001;Uid=docker;Pwd=docker;Database=accord_db"
16 | },
17 | "Providers": {
18 | "NativeMailProvider": {
19 | "Host": "smtp.mailtrap.io",
20 | "Port": "2525",
21 | "UserName": "",
22 | "Password": ""
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/IDirectMessageRepository.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social;
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Threading.Tasks;
6 | using Agree.Accord.Domain.Social.Requests;
7 | using Agree.Accord.SharedKernel.Data;
8 |
9 | ///
10 | /// The interface for a repository of direct messages. Has all the methods from a generic IRepository, plus a paginated lookup method.
11 | ///
12 | public interface IDirectMessageRepository : IRepository
13 | {
14 | ///
15 | /// Searches for direct messages between two users.
16 | ///
17 | Task> SearchAsync(GetFriendChatRequest request);
18 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/ServerRolePermission.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers;
2 |
3 | public class ServerRolePermission
4 | {
5 | public ServerRolePermission(ServerResource resource, ServerAction action)
6 | {
7 | Resource = resource;
8 | Action = action;
9 | }
10 |
11 | public ServerResource Resource { get; private set; }
12 | public ServerAction Action { get; private set; }
13 |
14 |
15 | public enum ServerResource
16 | {
17 | Server,
18 | Category,
19 | Channel,
20 | Message,
21 | Role
22 | }
23 |
24 | public enum ServerAction
25 | {
26 | Create,
27 | Read,
28 | Update,
29 | Delete
30 | }
31 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/components/avatar/UserAvatar.tsx:
--------------------------------------------------------------------------------
1 | import { Image } from '@chakra-ui/image'
2 | import { Box, Flex } from '@chakra-ui/layout'
3 | import { ChakraProps } from '@chakra-ui/system'
4 |
5 | type ServerAvatarProps = {
6 | w?: string
7 | avatarUrl: string
8 | } & ChakraProps
9 |
10 | export function UserAvatar ({ w, avatarUrl, ...rest }: ServerAvatarProps): JSX.Element {
11 | return (
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Requests/AcceptFriendshipRequestRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Requests;
2 |
3 | using System;
4 | using System.ComponentModel.DataAnnotations;
5 | using MediatR;
6 | using Agree.Accord.Domain.Social.Results;
7 |
8 | public class AcceptFriendshipRequestRequest : IRequest
9 | {
10 | public AcceptFriendshipRequestRequest() { }
11 |
12 | public AcceptFriendshipRequestRequest(User loggedUser, Guid friendshipRequestId)
13 | {
14 | LoggedUser = loggedUser;
15 | FriendshipRequestId = friendshipRequestId;
16 | }
17 |
18 | [Required]
19 | public User LoggedUser { get; set; }
20 |
21 | [Required]
22 | public Guid FriendshipRequestId { get; set; }
23 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/components/form/SquareButton.tsx:
--------------------------------------------------------------------------------
1 | import { Button, ButtonProps as ChakraButtonProps } from '@chakra-ui/button'
2 | import { ReactNode } from 'react'
3 |
4 | type SquareButtonProps = {
5 | icon: ReactNode
6 | w: string
7 | } & ChakraButtonProps
8 |
9 | export function SquareButton ({ icon, w, ...rest }: SquareButtonProps): JSX.Element {
10 | return (
11 |
22 | )
23 | }
24 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Requests/DeclineFriendshipRequestRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Requests;
2 |
3 | using System;
4 | using System.ComponentModel.DataAnnotations;
5 | using MediatR;
6 | using Agree.Accord.Domain.Social.Results;
7 |
8 | public class DeclineFriendshipRequestRequest : IRequest
9 | {
10 | public DeclineFriendshipRequestRequest() { }
11 |
12 | public DeclineFriendshipRequestRequest(User loggedUser, Guid friendshipRequestId)
13 | {
14 | LoggedUser = loggedUser;
15 | FriendshipRequestId = friendshipRequestId;
16 | }
17 |
18 | [Required]
19 | public User LoggedUser { get; set; }
20 |
21 | [Required]
22 | public Guid FriendshipRequestId { get; set; }
23 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Results/DirectMessageReadResult.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Results;
2 |
3 | using System.Collections.Generic;
4 | using Agree.Accord.SharedKernel;
5 |
6 | ///
7 | /// The result of a request to read a direct message.
8 | ///
9 | public class DirectMessagesReadResult : Result, ErrorList>
10 | {
11 | private DirectMessagesReadResult(IEnumerable message) : base(message)
12 | { }
13 | private DirectMessagesReadResult(ErrorList error) : base(error)
14 | { }
15 |
16 | public static DirectMessagesReadResult Ok(IEnumerable message) => new(message);
17 | public static DirectMessagesReadResult Fail(ErrorList data) => new(data);
18 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Specifications/ServerInfoLikeSpecification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers.Specifications;
2 |
3 | using System;
4 | using Agree.Accord.Domain.Servers;
5 | using Agree.Accord.SharedKernel.Data;
6 |
7 | ///
8 | /// A specification that checks if the server id of a given server is equal to a given value.
9 | ///
10 | public class ServerInfoLikeSpecification : BaseServerPaginatedSpecification
11 | {
12 | public ServerInfoLikeSpecification(string query, Guid userId, IPagination pagination)
13 | : base(
14 | (s) => s.Name.ToLower().Contains(query.ToLower()) || s.Description.ToLower().Contains(query.ToLower()),
15 | userId,
16 | pagination
17 | )
18 | { }
19 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Presentation/Agree.Allow.Presentation.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | net6.0
15 | enable
16 | enable
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/apps/concord_old/README.md:
--------------------------------------------------------------------------------
1 | # Concord :tv:
2 |
3 | Concord is the Agree main dashboard, built with CRA and Chakra UI.
4 |
5 | I decided to divide it into three layers:
6 | - The presentation layer, where is located most of the jsx and styling
7 | - The logic layer, where I use React Contexts and Hooks to manage the entire application business rules
8 | - The validation layer, where things get validated :P
9 |
10 | ### Dependency Injection
11 |
12 | I think there is something very cool on how I handle DI in this project. Since I'm using hooks and contexts, there are no classes (and consequently no constructors for DI) so I inject my services into the props of the contexts providers on a "DI Container"-like component, but the contexts depend purely on interfaces so there is a very low coupling on the logic layer.
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Specifications/UserNameEqualSpecification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Specifications;
2 |
3 | using System;
4 | using System.Linq.Expressions;
5 | using Agree.SharedKernel.Data;
6 |
7 | public class UserNameEqualSpecification : Specification, IOrderedSpecification
8 | {
9 | public UserNameEqualSpecification(string username, bool orderByTag = false)
10 | {
11 | Expression = x
12 | => x.Username == username;
13 |
14 | if (orderByTag)
15 | {
16 | OrderingExpression = x => x.Tag;
17 | IsDescending = true;
18 | }
19 | }
20 |
21 | public Expression> OrderingExpression { get; private set; }
22 |
23 | public bool IsDescending { get; private set; }
24 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Infrastructure.Data/ApplicationDbContextFactory.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Infrastructure.Data;
2 |
3 | using Microsoft.EntityFrameworkCore;
4 | using Microsoft.EntityFrameworkCore.Design;
5 |
6 | ///
7 | /// A factory for creating instances during design-time builds.
8 | ///
9 | public class ApplicationDbContextFactory : IDesignTimeDbContextFactory
10 | {
11 | public ApplicationDbContext CreateDbContext(string[] args)
12 | {
13 | var optionsBuilder = new DbContextOptionsBuilder();
14 |
15 | optionsBuilder.UseNpgsql("Server=localhost;Port=4001;Uid=docker;Pwd=docker;Database=accord_db");
16 |
17 | return new ApplicationDbContext(optionsBuilder.Options);
18 | }
19 | }
--------------------------------------------------------------------------------
/docker/docker-compose.override.yaml:
--------------------------------------------------------------------------------
1 | version: '3.9'
2 |
3 | services:
4 | accord_postgres:
5 | container_name: 'accord_postgres'
6 | restart: always
7 | ports:
8 | - 4001:5432
9 | environment:
10 | - POSTGRES_PASSWORD=docker
11 | - POSTGRES_USER=docker
12 | - POSTGRES_DB=accord_db
13 | volumes:
14 | - accord_postgres_volume:/var/lib/postgresql/data
15 | networks:
16 | - accord-network
17 |
18 | allow_postgres:
19 | container_name: 'allow_postgres'
20 | restart: always
21 | ports:
22 | - 4002:5432
23 | environment:
24 | - POSTGRES_PASSWORD=docker
25 | - POSTGRES_USER=docker
26 | - POSTGRES_DB=allow_db
27 | volumes:
28 | - allow_postgres_volume:/var/lib/postgresql/data
29 | networks:
30 | - allow-network
31 |
--------------------------------------------------------------------------------
/apps/allow/test/Agree.Allow.Test/TestBase.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Test;
2 |
3 | using Agree.Allow.Domain;
4 | using Agree.SharedKernel.Data;
5 | using Microsoft.Extensions.DependencyInjection;
6 |
7 | public class TestBase
8 | {
9 | private readonly DependencyInjectionContainer _container = new();
10 |
11 | protected T Resolve()
12 | {
13 | return _container.Services.GetRequiredService();
14 | }
15 |
16 | protected async Task CreateTestUserAccount(DiscriminatorTag tag = null)
17 | {
18 | var account = new UserAccount("testuser", "test@somemail", "somehash", tag ?? DiscriminatorTag.Parse(0));
19 | var repository = Resolve>();
20 | await repository.InsertAsync(account);
21 | await repository.CommitAsync();
22 | return account;
23 | }
24 | }
--------------------------------------------------------------------------------
/apps/concord_old/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "workbench.colorCustomizations": {
3 | "activityBar.activeBackground": "#3399ff",
4 | "activityBar.activeBorder": "#bf0060",
5 | "activityBar.background": "#3399ff",
6 | "activityBar.foreground": "#15202b",
7 | "activityBar.inactiveForeground": "#15202b99",
8 | "activityBarBadge.background": "#bf0060",
9 | "activityBarBadge.foreground": "#e7e7e7",
10 | "statusBar.background": "#007fff",
11 | "statusBar.foreground": "#e7e7e7",
12 | "statusBarItem.hoverBackground": "#3399ff",
13 | "titleBar.activeBackground": "#007fff",
14 | "titleBar.activeForeground": "#e7e7e7",
15 | "titleBar.inactiveBackground": "#007fff99",
16 | "titleBar.inactiveForeground": "#e7e7e799"
17 | },
18 | "peacock.color": "#007fff"
19 | }
--------------------------------------------------------------------------------
/apps/allow/test/Agree.Allow.Domain.Test/Handlers/Queries/GetAccountByIdHandlerTest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Test.Handlers.Queries;
2 |
3 | using Agree.Allow.Domain.Handlers.Queries;
4 | using Agree.Allow.Domain.Requests;
5 | using Agree.Allow.Test;
6 | using Agree.SharedKernel.Data;
7 |
8 | public class GetAccountByIdHandlerTest : TestBase
9 | {
10 | [Fact]
11 | public async Task Handle_WithExistingId_ShouldReturnAccount()
12 | {
13 | // Arrange
14 | var account = await CreateTestUserAccount();
15 | var repository = Resolve>();
16 | var sut = new GetAccountByIdHandler(repository);
17 |
18 | // Act
19 | var result = await sut.Handle(new GetAccountByIdRequest(account.Id), CancellationToken.None);
20 |
21 | // Assert
22 | Assert.Equal(account.Id, result.Id);
23 | }
24 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Requests/GetServerByIdRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers.Requests;
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using Agree.Accord.SharedKernel.Data;
6 | using MediatR;
7 |
8 | ///
9 | /// Represents a request to get a server by its id, taking into account the server's privacy settings.
10 | ///
11 | public class GetServerByIdRequest : IRequest
12 | {
13 | ///
14 | /// The id of the server to get.
15 | ///
16 | /// The id of the server.
17 | public Guid ServerId { get; set; }
18 |
19 | ///
20 | /// The id of the user that is searching.
21 | /// Useful to filter out secret servers.
22 | ///
23 | /// The id of the user that is searching.
24 | public Guid UserId { get; set; }
25 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Handlers/Queries/GetAccountByIdHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Handlers.Queries;
2 |
3 | using System;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Agree.Allow.Domain;
7 | using Agree.Allow.Domain.Requests;
8 | using Agree.Allow.Domain.Specifications;
9 | using Agree.SharedKernel.Data;
10 | using MediatR;
11 |
12 | public class GetAccountByIdHandler : IRequestHandler
13 | {
14 | private readonly IRepository _accountRepository;
15 |
16 | public GetAccountByIdHandler(IRepository accountRepository) => _accountRepository = accountRepository;
17 |
18 | public async Task Handle(GetAccountByIdRequest request, CancellationToken cancellationToken)
19 | => await _accountRepository.GetFirstAsync(new UserIdEqualSpecification(request.Id));
20 | }
--------------------------------------------------------------------------------
/apps/allow/test/Agree.Allow.Test/DependencyInjectionContainer.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Test;
2 |
3 | using System.Reflection;
4 | using Agree.Allow.Infrastructure.IoC;
5 | using Agree.SharedKernel.Data;
6 | using Microsoft.Extensions.Configuration;
7 | using Microsoft.Extensions.DependencyInjection;
8 |
9 | public class DependencyInjectionContainer
10 | {
11 | public readonly IServiceProvider Services;
12 |
13 | public DependencyInjectionContainer()
14 | {
15 | var configuration = new ConfigurationBuilder()
16 | .AddJsonFile("testsettings.json")
17 | .Build();
18 |
19 | Services = new ServiceCollection()
20 | .AddAllowInfrastructure(configuration, Assembly.GetAssembly(typeof(DependencyInjectionContainer)))
21 | .AddSingleton(typeof(IRepository<,>), typeof(TestRepository<,>))
22 | .BuildServiceProvider();
23 | }
24 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Category.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers;
2 |
3 | using System;
4 | using Agree.Accord.SharedKernel;
5 |
6 | ///
7 | /// A server category.
8 | ///
9 | public class Category : IEntity
10 | {
11 | /// EF ctor
12 | protected Category() { }
13 |
14 | public Category(string name, Server server)
15 | {
16 | Id = Guid.NewGuid();
17 | Name = name;
18 | Position = Server.Categories.Count;
19 | Server = server;
20 | ServerId = server.Id;
21 | }
22 |
23 | public Guid Id { get; set; }
24 | public string Name { get; set; }
25 | public int Position { get; set; }
26 |
27 | public Guid ServerId { get; set; }
28 | public Server Server { get; set; }
29 |
30 | public static Category CreateDefaultWelcomeCategory(Server server)
31 | => new($"Welcome to {server.Name}!", server);
32 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Requests/MarkDirectMessageAsReadRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Requests;
2 |
3 | using System;
4 | using System.ComponentModel.DataAnnotations;
5 | using Agree.Accord.Domain.Social.Results;
6 | using MediatR;
7 |
8 | ///
9 | /// The request to mark a direct message as read.
10 | ///
11 | public class MarkDirectMessageAsReadRequest : IRequest
12 | {
13 | public MarkDirectMessageAsReadRequest() { }
14 |
15 | ///
16 | /// The direct message Id to be marked as read.
17 | ///
18 | /// The direct message Id.
19 | [Required]
20 | public Guid DirectMessageId { get; set; }
21 |
22 | ///
23 | /// The user marking the direct message as read.
24 | ///
25 | /// The user account.
26 | [Required]
27 | public UserAccount Requester { get; set; }
28 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Specifications/DirectMessageFromOrToFriendSpecification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Specifications;
2 |
3 | using System;
4 | using Agree.Accord.SharedKernel.Data;
5 |
6 | public class DirectMessageFromOrToFriendPaginatedSpecification : PaginatedSpecification
7 | {
8 | public DirectMessageFromOrToFriendPaginatedSpecification(Guid requesterId, Guid friendId, IPagination pagination)
9 | : base(pagination)
10 | => Expression = x
11 | => (x.From.Id == friendId && x.To.Id == requesterId) || (x.To.Id == friendId && x.From.Id == requesterId);
12 | }
13 |
14 | public class DirectMessageFromOrToFriendSpecification : Specification
15 | {
16 | public DirectMessageFromOrToFriendSpecification(Guid requesterId, Guid friendId)
17 | => Expression = x
18 | => (x.From.Id == friendId && x.To.Id == requesterId) || (x.To.Id == friendId && x.From.Id == requesterId);
19 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Handlers/Queries/SearchAccountsHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Handlers.Queries;
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 | using Agree.Allow.Domain;
8 | using Agree.Allow.Domain.Requests;
9 | using Agree.Allow.Domain.Specifications;
10 | using Agree.SharedKernel.Data;
11 | using MediatR;
12 |
13 | public class SearchAccountsHandler : IRequestHandler>
14 | {
15 | private readonly IRepository _accountRepository;
16 |
17 | public SearchAccountsHandler(IRepository accountRepository) => _accountRepository = accountRepository;
18 |
19 | public async Task> Handle(SearchAccountsRequest request, CancellationToken cancellationToken)
20 | => await _accountRepository.GetAllAsync(new NameTagLikeSpecification(request.Query, request));
21 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Requests/SearchServersRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers.Requests;
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using Agree.Accord.SharedKernel.Data;
6 | using MediatR;
7 |
8 | ///
9 | /// Represents a request to search paginated server by a query, taking into account the server's privacy settings.
10 | ///
11 | public class SearchServersRequest : Pagination, IRequest>
12 | {
13 | ///
14 | /// The query to search for. This will be used to search for the server name or description.
15 | ///
16 | /// The query to search for.
17 | public string Query { get; set; }
18 |
19 | ///
20 | /// The id of the user that is searching.
21 | /// Useful to filter out secret servers.
22 | ///
23 | /// The id of the user that is searching.
24 | public Guid UserId { get; set; }
25 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Specifications/NameTagEqualSpecification.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Specifications;
2 |
3 | using System.Linq.Expressions;
4 | using Agree.SharedKernel.Data;
5 |
6 | public class NameTagEqualSpecification : Specification, IOrderedSpecification
7 | {
8 | public NameTagEqualSpecification(DiscriminatorTag tag, string userName, bool orderByTag = false)
9 | {
10 | Expression = x
11 | => x.Username == userName && x.Tag == tag;
12 |
13 | if (orderByTag)
14 | {
15 | OrderingExpression = x => x.Tag;
16 | IsDescending = true;
17 | }
18 | }
19 |
20 | public NameTagEqualSpecification(UserAccount account)
21 | => Expression = x
22 | => x.Username == account.Username && x.Tag == account.Tag;
23 |
24 | public Expression> OrderingExpression { get; private set; }
25 | public bool IsDescending { get; private set; }
26 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Requests/SendFriendshipRequestRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Requests;
2 |
3 | using Agree.Accord.Domain.Social.Results;
4 | using MediatR;
5 | using System.ComponentModel.DataAnnotations;
6 |
7 | ///
8 | /// The request to send a friendship request.
9 | ///
10 | public class SendFriendshipRequestRequest : IRequest
11 | {
12 | public SendFriendshipRequestRequest() { }
13 |
14 | ///
15 | /// The user sending the friendship request.
16 | ///
17 | /// The user account.
18 | [Required]
19 | public User From { get; set; }
20 |
21 | ///
22 | /// The user receiving the friendship request nametag.
23 | /// Must be a valid user nametag.
24 | ///
25 | /// The receiver user account nametag.
26 | [Required]
27 | [RegularExpression(@"^([a-zA-Z0-9_-]{0,}#[0-9]{4})$")]
28 | public string ToNameTag { get; set; }
29 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/DiscriminatorTagFactory.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain;
2 |
3 | using System;
4 | using System.Threading.Tasks;
5 | using Agree.Allow.Domain.Specifications;
6 | using Agree.SharedKernel.Data;
7 |
8 | public class DiscriminatorTagFactory
9 | {
10 | private readonly IRepository _accountRepository;
11 |
12 | public DiscriminatorTagFactory(IRepository accountRepository) => _accountRepository = accountRepository;
13 |
14 | public async Task GenerateDiscriminatorTagAsync(string username)
15 | {
16 | DiscriminatorTag tag = DiscriminatorTag.Parse(0);
17 |
18 | var sameNameTagCheck = await _accountRepository.GetFirstAsync(new UserNameEqualSpecification(username, true));
19 |
20 | if (sameNameTagCheck == null)
21 | return tag;
22 |
23 | tag = sameNameTagCheck.Tag.Increment();
24 |
25 | if (tag.Value > 9999)
26 | return null;
27 |
28 | return tag;
29 | }
30 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Infrastructure.Data/UserAccountDbModel.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Infrastructure.Data;
2 |
3 | using System;
4 | using Agree.SharedKernel;
5 | using System.Security.Claims;
6 | using Agree.Allow.Domain;
7 | using System.ComponentModel.DataAnnotations.Schema;
8 | using System.ComponentModel.DataAnnotations;
9 | using Microsoft.EntityFrameworkCore;
10 |
11 | [Table("UserAccounts")]
12 | [Index("Tag", "Username", IsUnique = true)]
13 | public class UserAccountDbModel
14 | {
15 | [Key]
16 | public Guid Id { get; private set; }
17 |
18 | [Required]
19 | [MaxLength(255)]
20 | public string EmailAddress { get; private set; }
21 |
22 | [Required]
23 | [MaxLength(40)]
24 | public string Username { get; private set; }
25 |
26 | [Required]
27 | [MaxLength(400)]
28 | public string PasswordHash { get; private set; }
29 |
30 | [Required]
31 | [MaxLength(4)]
32 | public ushort Tag { get; private set; }
33 |
34 | public DateTime CreatedAt { get; private set; }
35 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Presentation/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/launchsettings.json",
3 | "iisSettings": {
4 | "windowsAuthentication": false,
5 | "anonymousAuthentication": true,
6 | "iisExpress": {
7 | "applicationUrl": "http://localhost:11113",
8 | "sslPort": 44357
9 | }
10 | },
11 | "profiles": {
12 | "Agree.Allow.Presentation": {
13 | "commandName": "Project",
14 | "dotnetRunMessages": true,
15 | "launchBrowser": true,
16 | "launchUrl": "swagger",
17 | "applicationUrl": "https://localhost:7100;http://localhost:5267",
18 | "environmentVariables": {
19 | "ASPNETCORE_ENVIRONMENT": "Development"
20 | }
21 | },
22 | "IIS Express": {
23 | "commandName": "IISExpress",
24 | "launchBrowser": true,
25 | "launchUrl": "swagger",
26 | "environmentVariables": {
27 | "ASPNETCORE_ENVIRONMENT": "Development"
28 | }
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json.schemastore.org/launchsettings.json",
3 | "iisSettings": {
4 | "windowsAuthentication": false,
5 | "anonymousAuthentication": true,
6 | "iisExpress": {
7 | "applicationUrl": "http://localhost:53661",
8 | "sslPort": 44348
9 | }
10 | },
11 | "profiles": {
12 | "IIS Express": {
13 | "commandName": "IISExpress",
14 | "launchBrowser": true,
15 | "launchUrl": "swagger",
16 | "environmentVariables": {
17 | "ASPNETCORE_ENVIRONMENT": "Development"
18 | }
19 | },
20 | "Agree.Accord.Presentation": {
21 | "commandName": "Project",
22 | "dotnetRunMessages": "true",
23 | "launchBrowser": true,
24 | "launchUrl": "swagger",
25 | "applicationUrl": "https://localhost:5001;http://localhost:5000",
26 | "environmentVariables": {
27 | "ASPNETCORE_ENVIRONMENT": "Development"
28 | }
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Handlers/Queries/GetFriendChatHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Handlers.Queries;
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 | using Agree.Accord.Domain.Social.Requests;
8 | using Agree.Accord.Domain.Social.Specifications;
9 | using Agree.Accord.SharedKernel.Data;
10 | using MediatR;
11 |
12 | ///
13 | /// Handles the retrieval of a direct message by its Id.
14 | ///
15 | public class GetFriendChatHandler : IRequestHandler>
16 | {
17 | private readonly IDirectMessageRepository _directMessageRepository;
18 |
19 | public GetFriendChatHandler(IDirectMessageRepository directMessageRepository) => _directMessageRepository = directMessageRepository;
20 |
21 | public async Task> Handle(GetFriendChatRequest request, CancellationToken cancellationToken)
22 | => await _directMessageRepository.SearchAsync(request);
23 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Infrastructure.Data/Agree.Accord.Infrastructure.Data.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net6.0
4 | 2.0
5 | enable
6 |
7 |
8 |
9 |
10 |
11 | runtime; build; native; contentfiles; analyzers; buildtransitive
12 | all
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Handlers/Queries/GetDirectMessageByIdHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Handlers.Queries;
2 |
3 | using System;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Agree.Accord.Domain.Social.Requests;
7 | using Agree.Accord.Domain.Social.Specifications;
8 | using Agree.Accord.SharedKernel.Data;
9 | using MediatR;
10 |
11 | ///
12 | /// Handles the retrieval of a direct message by its Id.
13 | ///
14 | public class GetDirectMessageByIdHandler : IRequestHandler
15 | {
16 | private readonly IDirectMessageRepository _directMessageRepository;
17 |
18 | public GetDirectMessageByIdHandler(IDirectMessageRepository directMessageRepository) => _directMessageRepository = directMessageRepository;
19 |
20 | public async Task Handle(GetDirectMessagebyIdRequest request, CancellationToken cancellationToken)
21 | => await _directMessageRepository.GetFirstAsync(new DirectMessageIdEqualSpecification(request.Id));
22 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/FriendshipRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain;
2 |
3 | using System;
4 | using Agree.SharedKernel;
5 |
6 | public class FriendshipRequest : IEntity
7 | {
8 | public FriendshipRequest(User from, User to)
9 | {
10 | Id = Guid.NewGuid();
11 | From = from;
12 | To = to;
13 | Accepted = false;
14 | SentAt = DateTime.UtcNow;
15 | }
16 |
17 | public Guid Id { get; private set; }
18 | public User From { get; private set; }
19 | public User To { get; private set; }
20 | public bool Accepted { get; private set; }
21 |
22 | public DateTime SentAt { get; private set; }
23 | public DateTime AcceptedAt { get; private set; }
24 |
25 | public void Accept(User acceptingUser)
26 | {
27 | if (Accepted)
28 | throw new FriendshipAlreadyAcceptedException();
29 | if (acceptingUser != To)
30 | throw new FriendshipRequestNotForUserException();
31 | Accepted = true;
32 | AcceptedAt = DateTime.UtcNow;
33 | }
34 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Presentation/CustomControllerBase.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Presentation;
2 |
3 | using System.Net;
4 | using System.Threading.Tasks;
5 | using Agree.Allow.Domain;
6 | using Agree.Allow.Domain.Requests;
7 | using MediatR;
8 | using Microsoft.AspNetCore.Mvc;
9 |
10 | public class CustomControllerBase : ControllerBase
11 | {
12 | protected readonly IMediator _mediator;
13 |
14 | public CustomControllerBase(IMediator mediator) => _mediator = mediator;
15 |
16 | protected UserAccount CurrentlyLoggedUser =>
17 | HttpContext.User.Identity.IsAuthenticated
18 | ? UserAccount.FromClaims(HttpContext.User)
19 | : null;
20 |
21 | protected async Task GetAuthenticatedUserAccount()
22 | => await _mediator.Send(new GetAccountByIdRequest(CurrentlyLoggedUser.Id));
23 |
24 | protected IActionResult InternalServerError() => StatusCode((int)HttpStatusCode.InternalServerError);
25 |
26 | protected IActionResult InternalServerError(object obj) => StatusCode((int)HttpStatusCode.InternalServerError, obj);
27 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Handlers/Queries/GetServerByIdHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers.Handlers.Queries;
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 | using Agree.Accord.Domain.Servers;
8 | using Agree.Accord.Domain.Servers.Requests;
9 | using Agree.Accord.Domain.Servers.Specifications;
10 | using Agree.Accord.SharedKernel.Data;
11 | using MediatR;
12 |
13 | ///
14 | /// Handles the search of a by its id.
15 | ///
16 | public class GetServerByIdHandler : IRequestHandler
17 | {
18 | private readonly IRepository _serverRepository;
19 |
20 | public GetServerByIdHandler(IRepository accountRepository) => _serverRepository = accountRepository;
21 |
22 | public async Task Handle(GetServerByIdRequest request, CancellationToken cancellationToken)
23 | => await _serverRepository.GetFirstAsync(new ServerIdEqualSpecification(request.ServerId, request.UserId));
24 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/pages/error/NotFoundPage.tsx:
--------------------------------------------------------------------------------
1 | import { Img } from '@chakra-ui/image'
2 | import { Flex, Heading, Text } from '@chakra-ui/layout'
3 | import { useI18n } from '../../hooks/useI18n'
4 |
5 | import LogoImage from '../../assets/agreew.svg'
6 | import BgImage from '../../assets/bg404.png'
7 |
8 | export function NotFoundPage (): JSX.Element {
9 | const { t } = useI18n()
10 |
11 | return (
12 |
13 |
14 |
15 | 404 NOT FOUND
16 |
17 |
18 | {t`Congratulations! You found our little mascot secret page!`}
19 |
20 |
21 | {t`Just kidding. Actually this page doesn't exists...`}
22 |
23 |
24 | {t`Kinda paradoxal don't you think?`}
25 |
26 |
27 | )
28 | }
29 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/Social/ViewModels/FriendshipRequestViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Presentation.Social.ViewModels;
2 |
3 | using Agree.Accord.Domain.Social;
4 | using Agree.Accord.Presentation.Identity.ViewModels;
5 |
6 | ///
7 | /// The view model for a friendship request.
8 | ///
9 | public class FriendshipRequestViewModel
10 | {
11 | public UserAccountViewModel From { get; private set; }
12 | public UserAccountViewModel To { get; private set; }
13 | public bool Accepted { get; private set; }
14 |
15 | ///
16 | /// Creates a new instance of the class from a friendship entity.
17 | ///
18 | /// The friendship entity.
19 | /// The view model.
20 | public static FriendshipRequestViewModel FromEntity(Friendship entity) => new()
21 | {
22 | From = UserAccountViewModel.FromEntity(entity.From),
23 | To = UserAccountViewModel.FromEntity(entity.To),
24 | Accepted = entity.Accepted
25 | };
26 | }
--------------------------------------------------------------------------------
/apps/concord_old/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Agree",
3 | "description": "Agree is a text, voice and video communication service based on Discord",
4 | "icons": [
5 | {
6 | "src": "/android-icon-36x36.png",
7 | "sizes": "36x36",
8 | "type": "image/png",
9 | "density": "0.75"
10 | },
11 | {
12 | "src": "/android-icon-48x48.png",
13 | "sizes": "48x48",
14 | "type": "image/png",
15 | "density": "1.0"
16 | },
17 | {
18 | "src": "/android-icon-72x72.png",
19 | "sizes": "72x72",
20 | "type": "image/png",
21 | "density": "1.5"
22 | },
23 | {
24 | "src": "/android-icon-96x96.png",
25 | "sizes": "96x96",
26 | "type": "image/png",
27 | "density": "2.0"
28 | },
29 | {
30 | "src": "/android-icon-144x144.png",
31 | "sizes": "144x144",
32 | "type": "image/png",
33 | "density": "3.0"
34 | },
35 | {
36 | "src": "/android-icon-192x192.png",
37 | "sizes": "192x192",
38 | "type": "image/png",
39 | "density": "4.0"
40 | }
41 | ]
42 | }
43 |
--------------------------------------------------------------------------------
/apps/concord_old/src/logic/services/implementations/AxiosHttpClient.ts:
--------------------------------------------------------------------------------
1 | import axios, { AxiosResponse } from 'axios'
2 | import { HttpRequest, HttpResponse, IHttpClient } from '../IHttpClient'
3 |
4 | export class AxiosHttpClient implements IHttpClient {
5 | public constructor () {
6 | axios.interceptors.response.use(response => {
7 | return response
8 | }, error => {
9 | return error
10 | })
11 | }
12 |
13 | public async request (data: HttpRequest): Promise> {
14 | let axiosResponse: AxiosResponse
15 | try {
16 | axiosResponse = await axios.request({
17 | url: data.url,
18 | method: data.method,
19 | data: data.body,
20 | headers: data.headers,
21 | withCredentials: true,
22 | validateStatus: () => true
23 | })
24 | } catch (error) {
25 | console.log(error)
26 | axiosResponse = error.response
27 | }
28 | return {
29 | statusCode: Number(axiosResponse.status),
30 | body: axiosResponse.data,
31 | headers: axiosResponse.headers
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Handlers/Queries/SearchServerHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers.Handlers.Queries;
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 | using Agree.Accord.Domain.Servers;
8 | using Agree.Accord.Domain.Servers.Requests;
9 | using Agree.Accord.Domain.Servers.Specifications;
10 | using Agree.Accord.SharedKernel.Data;
11 | using MediatR;
12 |
13 | ///
14 | /// Handles the search of paginated s by a query.
15 | ///
16 | public class SearchServersHandler : IRequestHandler>
17 | {
18 | private readonly IRepository _serverRepository;
19 |
20 | public SearchServersHandler(IRepository serverRepository) => _serverRepository = serverRepository;
21 |
22 | public async Task> Handle(SearchServersRequest request, CancellationToken cancellationToken)
23 | => await _serverRepository.GetAllAsync(new ServerInfoLikeSpecification(request.Query, request.UserId, request));
24 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/logic/hooks/useAllow.tsx:
--------------------------------------------------------------------------------
1 | import { useContext } from 'react'
2 | import { Redirect, Route, RouteProps } from 'react-router'
3 | import { AllowContext, AllowContextProps } from '../contexts/AllowContext'
4 |
5 | export function useAllow (): AllowContextProps {
6 | const ctx = useContext(AllowContext)
7 |
8 | return {
9 | ...ctx
10 | }
11 | }
12 |
13 | export function AuthenticatedRoute ({ component, ...rest }: RouteProps): JSX.Element {
14 | const ctx = useContext(AllowContext)
15 | const Component = component as any
16 | return (
17 | (
18 | ctx.isAuthenticated
19 | ?
20 | :
21 | )} />
22 | )
23 | }
24 |
25 | export function UnauthenticatedRoute ({ component, ...rest }: RouteProps): JSX.Element {
26 | const ctx = useContext(AllowContext)
27 | const Component = component as any
28 | return (
29 | (
30 | !ctx.isAuthenticated
31 | ?
32 | :
33 | )} />
34 | )
35 | }
36 |
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/components/form/Button.tsx:
--------------------------------------------------------------------------------
1 | import { Button as ChakraButton, ButtonProps as ChakraButtonProps } from '@chakra-ui/button'
2 | import { ReactElement, ReactNode } from 'react'
3 |
4 | type ButtonProps = {
5 | rightIcon?: ReactElement
6 | leftIcon?: ReactElement
7 | children: ReactNode
8 | w?: string | string[] | { base?: string, sm?: string, md?: string, lg?: string, xl?: string }
9 | h?: string | string[] | { base?: string, sm?: string, md?: string, lg?: string, xl?: string }
10 | } & ChakraButtonProps
11 |
12 | export function Button ({ rightIcon, leftIcon, children, w, h, ...rest }: ButtonProps): JSX.Element {
13 | return (
14 |
24 | {children}
25 |
26 | )
27 | }
28 |
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Handlers/Queries/GetClientApplicationByAccessKeyHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Handlers.Queries;
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 | using Agree.Allow.Domain;
8 | using Agree.Allow.Domain.Requests;
9 | using Agree.Allow.Domain.Specifications;
10 | using Agree.SharedKernel.Data;
11 | using MediatR;
12 |
13 | public class GetClientApplicationByAccessKeyHandler : IRequestHandler
14 | {
15 | private readonly IRepository _clientApplicationRepository;
16 |
17 | public GetClientApplicationByAccessKeyHandler(IRepository clientApplicationRepository)
18 | => _clientApplicationRepository = clientApplicationRepository;
19 |
20 | public async Task Handle(GetClientApplicationByAccessKeyRequest request, CancellationToken cancellationToken)
21 | => await _clientApplicationRepository.GetFirstAsync(new ClientApplicationAccessKeyEqualSpecification(request.AccessKey));
22 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Infrastructure.Data/Agree.Allow.Infrastructure.Data.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | runtime; build; native; contentfiles; analyzers; buildtransitive
9 | all
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | net6.0
20 | enable
21 | enable
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Vinicius Vassão
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/ServerMember.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers;
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Collections.ObjectModel;
6 | using Agree.Accord.Domain.Identity;
7 | using Agree.Accord.SharedKernel;
8 |
9 | ///
10 | /// Represents a member of a server.
11 | /// Works as a pivot entity between and .
12 | ///
13 | public class ServerMember : IEntity
14 | {
15 | // EF ctor
16 | protected ServerMember() { }
17 |
18 | public ServerMember(UserAccount user, Server server)
19 | {
20 | User = user;
21 | UserId = user.Id;
22 | Server = server;
23 | ServerId = server.Id;
24 | Roles = new Collection();
25 | }
26 |
27 | public virtual string Id => $"{UserId}_{ServerId}";
28 | public Guid UserId { get; private set; }
29 | public UserAccount User { get; private set; }
30 | public Guid ServerId { get; private set; }
31 | public Server Server { get; private set; }
32 | public ICollection Roles { get; private set; }
33 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/components/avatar/FriendListItem.tsx:
--------------------------------------------------------------------------------
1 | import { Box, Link, ListItem, Text } from '@chakra-ui/layout'
2 | import { UserAvatar } from './UserAvatar'
3 | import { NavLink as RouterNavLink } from 'react-router-dom'
4 |
5 | import './FriendListItem.scss'
6 |
7 | export type FriendListItemProps = {
8 | to: string
9 | avatarUrl: string
10 | }
11 |
12 | export function FriendListItem ({ to, avatarUrl }: FriendListItemProps): JSX.Element {
13 | return (
14 |
15 |
16 |
17 |
18 | MyFriend
19 | Online
20 |
21 |
22 |
23 | )
24 | }
25 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Handlers/Queries/GetUserSentFriendshipRequestsHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Handlers.Queries;
2 |
3 | using System.Collections.Generic;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Agree.Accord.Domain.Social.Requests;
7 | using Agree.Accord.Domain.Social.Specifications;
8 | using Agree.Accord.SharedKernel.Data;
9 | using MediatR;
10 |
11 | ///
12 | /// Handles the retrieval of a user's sent friendship requests.
13 | ///
14 | public class GetUserSentFriendshipRequestsHandler : IRequestHandler>
15 | {
16 | private readonly IRepository _friendshipRepository;
17 |
18 | public GetUserSentFriendshipRequestsHandler(IRepository friendshipRepository) => _friendshipRepository = friendshipRepository;
19 |
20 | public async Task> Handle(GetUserSentFriendshipRequestsRequest request, CancellationToken cancellationToken)
21 | => await _friendshipRepository.GetAllAsync(new SentFriendshipRequestSpecification(request.User.Id));
22 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/Social/Handlers/DirectMessageCreatedNotificationHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Notifications;
2 |
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 | using Agree.Accord.Presentation;
6 | using Agree.Accord.Presentation.Shared;
7 | using Agree.Accord.Presentation.Social.ViewModels;
8 | using MediatR;
9 | using Microsoft.AspNetCore.SignalR;
10 |
11 | public class DirectMessageCreatedNotificationHandler : INotificationHandler
12 | {
13 | private readonly IHubContext _hubContext;
14 |
15 | public DirectMessageCreatedNotificationHandler(IHubContext hubContext)
16 | => _hubContext = hubContext;
17 |
18 | public async Task Handle(DirectMessageCreatedNotification notification, CancellationToken cancellationToken)
19 | {
20 | await _hubContext.Clients
21 | .User(notification.DirectMessage.To.Id.ToString())
22 | .SendAsync(
23 | HubEvents.DirectMessageCreated,
24 | DirectMessageViewModel.FromEntity(notification.DirectMessage)
25 | );
26 | }
27 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Presentation/Accounts/ViewModels/UserAccountViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Presentation.Accounts.ViewModels;
2 |
3 | using System.Security.Claims;
4 | using System;
5 | using Agree.Allow.Domain;
6 | using System.Linq;
7 |
8 | public class UserAccountViewModel
9 | {
10 | public Guid Id { get; private set; }
11 | public string Username { get; private set; }
12 | public string Tag { get; private set; }
13 | public string NameTag => $"{Username}#{Tag}";
14 |
15 | public static UserAccountViewModel FromEntity(UserAccount entity) => new()
16 | {
17 | Id = entity.Id,
18 | Username = entity.Username,
19 | Tag = entity.Tag.ToString(),
20 | };
21 |
22 | public static UserAccountViewModel FromClaims(ClaimsPrincipal principal)
23 | {
24 | var nameTag = principal.Identity.Name;
25 | var split = nameTag.Split('#');
26 | return new UserAccountViewModel
27 | {
28 | Id = Guid.Parse(principal.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value),
29 | Username = split.First(),
30 | Tag = split.Last(),
31 | };
32 | }
33 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/Social/Handlers/FriendshipRequestCreatedNotificationHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Notifications;
2 |
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 | using Agree.Accord.Presentation;
6 | using Agree.Accord.Presentation.Shared;
7 | using Agree.Accord.Presentation.Social.ViewModels;
8 | using MediatR;
9 | using Microsoft.AspNetCore.SignalR;
10 |
11 | public class FriendshipRequestCreatedNotificationHandler : INotificationHandler
12 | {
13 | private readonly IHubContext _hubContext;
14 |
15 | public FriendshipRequestCreatedNotificationHandler(IHubContext hubContext)
16 | => _hubContext = hubContext;
17 |
18 | public async Task Handle(FriendshipRequestCreatedNotification notification, CancellationToken cancellationToken)
19 | {
20 | await _hubContext.Clients
21 | .User(notification.Friendship.ToId.ToString())
22 | .SendAsync(
23 | HubEvents.FriendshipRequestCreated,
24 | FriendshipRequestViewModel.FromEntity(notification.Friendship)
25 | );
26 | }
27 | }
--------------------------------------------------------------------------------
/apps/allow/test/Agree.Allow.Domain.Test/Tokens/TokenTest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Test.Tokens;
2 |
3 | using System.IdentityModel.Tokens.Jwt;
4 | using Agree.Allow.Domain.Tokens;
5 | using Agree.Allow.Test;
6 |
7 | public abstract class TokenTest : TestBase
8 | {
9 | protected JwtSecurityToken DecodeToken(string token)
10 | {
11 | var handler = new JwtSecurityTokenHandler();
12 | var decoded = handler.ReadJwtToken(token);
13 | return decoded;
14 | }
15 |
16 | protected async Task<(UserAccount, string)> GenerateAccessToken()
17 | {
18 | var accessTokenFactory = Resolve();
19 | var account = await CreateTestUserAccount();
20 | var token = await accessTokenFactory.GenerateAsync(account);
21 | return (account, token.TokenValue);
22 | }
23 |
24 | protected async Task<(UserAccount, string)> GenerateRefreshToken()
25 | {
26 | var refreshTokenFactory = Resolve();
27 | var account = await CreateTestUserAccount();
28 | var token = await refreshTokenFactory.GenerateAsync(account);
29 | return (account, token.TokenValue);
30 | }
31 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Handlers/Queries/GetUserReceivedFriendshipRequestsHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Handlers.Queries;
2 |
3 | using System.Collections.Generic;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Agree.Accord.Domain.Social.Requests;
7 | using Agree.Accord.Domain.Social.Specifications;
8 | using Agree.Accord.SharedKernel.Data;
9 | using MediatR;
10 |
11 | ///
12 | /// Handles the retrieval of a user's received friendship requests.
13 | ///
14 | public class GetUserReceivedFriendshipRequestsHandler : IRequestHandler>
15 | {
16 | private readonly IRepository _friendshipRepository;
17 |
18 | public GetUserReceivedFriendshipRequestsHandler(IRepository friendshipRepository) => _friendshipRepository = friendshipRepository;
19 |
20 | public async Task> Handle(GetUserReceivedFriendshipRequestsRequest request, CancellationToken cancellationToken)
21 | => await _friendshipRepository.GetAllAsync(new ReceivedFriendshipRequestSpecification(request.User.Id));
22 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/Social/Handlers/FriendshipRequestAcceptedNotificationHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Notifications;
2 |
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 | using Agree.Accord.Presentation;
6 | using Agree.Accord.Presentation.Shared;
7 | using Agree.Accord.Presentation.Social.ViewModels;
8 | using MediatR;
9 | using Microsoft.AspNetCore.SignalR;
10 |
11 | public class FriendshipRequestAcceptedNotificationHandler : INotificationHandler
12 | {
13 | private readonly IHubContext _hubContext;
14 |
15 | public FriendshipRequestAcceptedNotificationHandler(IHubContext hubContext)
16 | => _hubContext = hubContext;
17 |
18 | public async Task Handle(FriendshipRequestAcceptedNotification notification, CancellationToken cancellationToken)
19 | {
20 | await _hubContext.Clients
21 | .User(notification.Friendship.FromId.ToString())
22 | .SendAsync(
23 | HubEvents.FriendshipRequestAccepted,
24 | FriendshipRequestViewModel.FromEntity(notification.Friendship)
25 | );
26 | }
27 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/Social/Handlers/FriendshipRequestDeclinedNotificationHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Notifications;
2 |
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 | using Agree.Accord.Presentation;
6 | using Agree.Accord.Presentation.Shared;
7 | using Agree.Accord.Presentation.Social.ViewModels;
8 | using MediatR;
9 | using Microsoft.AspNetCore.SignalR;
10 |
11 | public class FriendshipRequestDeclinedNotificationHandler : INotificationHandler
12 | {
13 | private readonly IHubContext _hubContext;
14 |
15 | public FriendshipRequestDeclinedNotificationHandler(IHubContext hubContext)
16 | => _hubContext = hubContext;
17 |
18 | public async Task Handle(FriendshipRequestDeclinedNotification notification, CancellationToken cancellationToken)
19 | {
20 | await _hubContext.Clients
21 | .User(notification.Friendship.FromId.ToString())
22 | .SendAsync(
23 | HubEvents.FriendshipRequestDeclined,
24 | FriendshipRequestViewModel.FromEntity(notification.Friendship)
25 | );
26 | }
27 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Handlers/Queries/GetFriendsFromUserHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Handlers.Queries;
2 |
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 | using Agree.Accord.Domain.Social.Requests;
8 | using Agree.Accord.Domain.Social.Specifications;
9 | using Agree.Accord.SharedKernel.Data;
10 | using MediatR;
11 |
12 | ///
13 | /// Handles the retrieval of a user's friends.
14 | ///
15 | public class GetFriendsFromUserHandler : IRequestHandler>
16 | {
17 | private readonly IRepository _friendshipRepository;
18 |
19 | public GetFriendsFromUserHandler(IRepository friendshipRepository) => _friendshipRepository = friendshipRepository;
20 |
21 | public async Task> Handle(GetFriendsFromUserRequest request, CancellationToken cancellationToken)
22 | {
23 | var friends = await _friendshipRepository.GetAllAsync(new FriendshipAcceptedSpecification(request.User.Id));
24 | return friends.Select(friendship => friendship.ToId == request.User.Id ? friendship.From : friendship.To);
25 | }
26 | }
--------------------------------------------------------------------------------
/apps/accord/test/Agree.Accord.Domain.Test/Agree.Accord.Domain.Test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net6.0
4 | false
5 |
6 |
7 |
8 |
9 | 2.0
10 |
11 |
12 |
13 |
14 |
15 | runtime; build; native; contentfiles; analyzers; buildtransitive
16 | all
17 |
18 |
19 | runtime; build; native; contentfiles; analyzers; buildtransitive
20 | all
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Infrastructure.IoC/Agree.Accord.Infrastructure.IoC.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net6.0
4 | 2.0
5 | enable
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/apps/accord/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | // Use IntelliSense to find out which attributes exist for C# debugging
6 | // Use hover for the description of the existing attributes
7 | // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
8 | "name": ".NET Core Launch (web)",
9 | "type": "coreclr",
10 | "request": "launch",
11 | "preLaunchTask": "build",
12 | // If you have changed target frameworks, make sure to update the program path.
13 | "program": "${workspaceFolder}/src/Agree.Accord.Presentation/bin/Debug/net6.0/Agree.Accord.Presentation.dll",
14 | "args": [],
15 | "cwd": "${workspaceFolder}/src/Agree.Accord.Presentation",
16 | "stopAtEntry": false,
17 | "env": {
18 | "ASPNETCORE_ENVIRONMENT": "Development"
19 | },
20 | "sourceFileMap": {
21 | "/Views": "${workspaceFolder}/Views"
22 | }
23 | },
24 | {
25 | "name": ".NET Core Attach",
26 | "type": "coreclr",
27 | "request": "attach"
28 | }
29 | ]
30 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Requests/CreateServerRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers.Requests;
2 |
3 | using System.ComponentModel.DataAnnotations;
4 | using Agree.Accord.Domain.Identity;
5 | using Agree.Accord.Domain.Servers.Results;
6 | using MediatR;
7 |
8 | ///
9 | /// The representation of a request to create a new server.
10 | ///
11 | public class CreateServerRequest : IRequest
12 | {
13 | ///
14 | /// The server name.
15 | ///
16 | /// The server name.
17 | [Required]
18 | [MaxLength(50)]
19 | public string Name { get; set; }
20 |
21 | ///
22 | /// The server description.
23 | ///
24 | /// The server description.
25 | [MaxLength(300)]
26 | public string Description { get; set; }
27 |
28 | ///
29 | /// The server privacy level.
30 | ///
31 | /// The server privacy level.
32 | [Required]
33 | public ServerPrivacy PrivacyLevel { get; set; }
34 |
35 | ///
36 | /// The user that created the server.
37 | ///
38 | /// The user that created the server.
39 | public UserAccount Owner { get; set; }
40 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/hooks/useLoading.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef, useState } from 'react'
2 |
3 | type LoadingHook = {
4 | isLoading: boolean
5 | loadingMessage?: string
6 | loadingTime: number
7 | initLoading(message: string): void
8 | stopLoading(): void
9 | }
10 |
11 | export function useLoading (): LoadingHook {
12 | const [isLoading, setIsLoading] = useState(false)
13 | const [loadingMessage, setLoadingMessage] = useState()
14 | const [loadingTime, setLoadingTime] = useState(0)
15 |
16 | const loadingTimeout = useRef(null)
17 |
18 | function initLoading (message: string): void {
19 | setIsLoading(true)
20 | setLoadingMessage(message)
21 | }
22 |
23 | function stopLoading (): void {
24 | setIsLoading(false)
25 | setLoadingMessage(undefined)
26 | }
27 |
28 | useEffect(() => {
29 | if (isLoading) {
30 | if (loadingTime !== 0) {
31 | loadingTimeout.current = setTimeout(() => {
32 | setLoadingTime(current => current + 1)
33 | }, 1000) as any
34 | }
35 | } else {
36 | clearTimeout(loadingTimeout.current as any)
37 | }
38 | }, [isLoading])
39 |
40 | return {
41 | isLoading,
42 | loadingMessage,
43 | loadingTime,
44 | initLoading,
45 | stopLoading
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/Shared/CustomControllerBase.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Presentation.Shared;
2 |
3 | using System.Net;
4 | using System.Threading.Tasks;
5 | using Agree.Accord.Domain.Identity;
6 | using Agree.Accord.Domain.Identity.Requests;
7 | using MediatR;
8 | using Microsoft.AspNetCore.Mvc;
9 |
10 | ///
11 | /// A custom that provides useful and common methods for all controllers.
12 | ///
13 | public class CustomControllerBase : ControllerBase
14 | {
15 | public const string AccessTokenCookieName = "agreeaccord_accesstoken";
16 | protected readonly IMediator _mediator;
17 |
18 | public CustomControllerBase(IMediator mediator) => _mediator = mediator;
19 |
20 | protected UserAccount CurrentlyLoggedUser =>
21 | HttpContext.User.Identity.IsAuthenticated
22 | ? UserAccount.FromClaims(HttpContext.User)
23 | : null;
24 |
25 | protected async Task GetAuthenticatedUserAccount()
26 | => await _mediator.Send(new GetAccountByIdRequest(CurrentlyLoggedUser.Id));
27 |
28 | protected IActionResult InternalServerError() => StatusCode((int)HttpStatusCode.InternalServerError);
29 |
30 | protected IActionResult InternalServerError(object obj) => StatusCode((int)HttpStatusCode.InternalServerError, obj);
31 | }
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | // Use IntelliSense to find out which attributes exist for C# debugging
6 | // Use hover for the description of the existing attributes
7 | // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
8 | "name": ".NET Core Launch (web) - Agree.Accord.Presentation",
9 | "type": "coreclr",
10 | "request": "launch",
11 | "preLaunchTask": "build_accord",
12 | // If you have changed target frameworks, make sure to update the program path.
13 | "program": "${workspaceFolder}/apps/accord/src/Agree.Accord.Presentation/bin/Debug/net6.0/Agree.Accord.Presentation.dll",
14 | "args": [],
15 | "cwd": "${workspaceFolder}/apps/accord/src/Agree.Accord.Presentation",
16 | "stopAtEntry": false,
17 | "env": {
18 | "ASPNETCORE_ENVIRONMENT": "Development"
19 | },
20 | "sourceFileMap": {
21 | "/Views": "${workspaceFolder}/Views"
22 | }
23 | },
24 | {
25 | "name": ".NET Core Attach",
26 | "type": "coreclr",
27 | "request": "attach"
28 | }
29 | ]
30 | }
--------------------------------------------------------------------------------
/apps/accord/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.exclude": {
3 | "**/.git": true,
4 | "**/.svn": true,
5 | "**/.hg": true,
6 | "**/CVS": true,
7 | "**/.DS_Store": true,
8 | "**/obj": true,
9 | "**/bin": true
10 | },
11 | "discord.enabled": true,
12 | "workbench.colorCustomizations": {
13 | "activityBar.activeBackground": "#8a2ca2",
14 | "activityBar.activeBorder": "#af9530",
15 | "activityBar.background": "#8a2ca2",
16 | "activityBar.foreground": "#e7e7e7",
17 | "activityBar.inactiveForeground": "#e7e7e799",
18 | "activityBarBadge.background": "#af9530",
19 | "activityBarBadge.foreground": "#15202b",
20 | "statusBar.background": "#68217a",
21 | "statusBar.foreground": "#e7e7e7",
22 | "statusBarItem.hoverBackground": "#8a2ca2",
23 | "titleBar.activeBackground": "#68217a",
24 | "titleBar.activeForeground": "#e7e7e7",
25 | "titleBar.inactiveBackground": "#68217a99",
26 | "titleBar.inactiveForeground": "#e7e7e799",
27 | "commandCenter.border": "#e7e7e799",
28 | "sash.hoverBorder": "#8a2ca2",
29 | "statusBarItem.remoteBackground": "#68217a",
30 | "statusBarItem.remoteForeground": "#e7e7e7"
31 | },
32 | "peacock.remoteColor": "#68217a"
33 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Requests/CreateCategoryRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers.Requests;
2 |
3 | using System.ComponentModel.DataAnnotations;
4 | using Agree.Accord.Domain.Identity;
5 | using MediatR;
6 | using Agree.Accord.Domain.Servers.Results;
7 | using System;
8 |
9 | ///
10 | /// The representation of a request to create a new category.
11 | ///
12 | public class CreateCategoryRequest : IRequest
13 | {
14 | ///
15 | /// The server id that the category belongs to.
16 | ///
17 | /// The server id.
18 | [Required]
19 | public Guid ServerId { get; set; }
20 |
21 | ///
22 | /// The category name.
23 | ///
24 | /// The category name.
25 | [Required]
26 | [MaxLength(80)]
27 | public string Name { get; set; }
28 |
29 | ///
30 | /// The category position when displayed.
31 | ///
32 | /// The category position when displayed.
33 | [Required]
34 | public int Position { get; set; }
35 |
36 | ///
37 | /// The user that created the category.
38 | ///
39 | /// The user that created the category.
40 | public UserAccount Requester { get; set; }
41 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Requests/SendDirectMessageRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Requests;
2 |
3 | using System;
4 | using System.ComponentModel.DataAnnotations;
5 | using Agree.Accord.Domain.Social.Results;
6 | using MediatR;
7 |
8 | ///
9 | /// The request to send a direct message.
10 | ///
11 | public class SendDirectMessageRequest : IRequest
12 | {
13 | public SendDirectMessageRequest() { }
14 |
15 | ///
16 | /// The user sending the direct message.
17 | ///
18 | /// The sender user account.
19 | [Required]
20 | public UserAccount From { get; set; }
21 |
22 | ///
23 | /// The user receiving the direct message.
24 | ///
25 | /// The receiver user account id.
26 | [Required]
27 | public Guid ToId { get; set; }
28 |
29 | ///
30 | /// The content of the direct message.
31 | ///
32 | /// The message content.
33 | [Required]
34 | [MaxLength(400)]
35 | public string MessageText { get; set; }
36 |
37 | ///
38 | /// The Id of the message this message is replying to.
39 | ///
40 | /// The reply to message id.
41 | public Guid? InReplyToId { get; set; }
42 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Requests/GetFriendChatRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Requests;
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.ComponentModel.DataAnnotations;
6 | using MediatR;
7 |
8 | ///
9 | /// The request to get the chat between two users.
10 | ///
11 | public class GetFriendChatRequest : IRequest>
12 | {
13 | public GetFriendChatRequest() { }
14 |
15 | ///
16 | /// The id of the direct message to be retrieved.
17 | ///
18 | /// The friend id.
19 | [Required]
20 | public Guid FriendId { get; set; }
21 |
22 | ///
23 | /// The id of the user who is retrieving the chat.
24 | ///
25 | /// The user id.
26 | [Required]
27 | public Guid UserId { get; set; }
28 |
29 | ///
30 | /// The number of items to be retrieved.
31 | ///
32 | /// The number of items.
33 | [Required]
34 | [Range(1, 100)]
35 | public int PageSize { get; set; }
36 |
37 | ///
38 | /// The Id of the first item to be retrieved.
39 | /// Determines from which item the pagination will start.
40 | ///
41 | /// The first item id.
42 | public Guid StartAtId { get; set; }
43 | }
--------------------------------------------------------------------------------
/apps/allow/test/Agree.Allow.Test/Agree.Allow.Test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 | enable
7 |
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | runtime; build; native; contentfiles; analyzers; buildtransitive
18 | all
19 |
20 |
21 | runtime; build; native; contentfiles; analyzers; buildtransitive
22 | all
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Infrastructure.IoC/Agree.Allow.Infrastructure.IoC.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | net6.0
19 | enable
20 | enable
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/components/form/TextInput.tsx:
--------------------------------------------------------------------------------
1 | import { InputLeftElement, Input, InputGroup, InputProps } from '@chakra-ui/input'
2 |
3 | import { ReactNode } from 'react'
4 |
5 | type TextInputProps = {
6 | icon: ReactNode
7 | placeholder: string
8 | type?: string
9 | w?: string | string[] | { base?: string, sm?: string, md?: string, lg?: string, xl?: string }
10 | } & InputProps
11 |
12 | export function TextInput ({ icon, placeholder, type = 'text', w = 'full', ...rest }: TextInputProps): JSX.Element {
13 | return (
14 |
24 |
30 | {icon}
31 |
32 |
43 |
44 | )
45 | }
46 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Infrastructure.Data/FriendshipRepository.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Infrastructure.Data;
2 |
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Agree.Accord.Domain.Social;
7 | using Agree.Accord.SharedKernel.Data;
8 | using Microsoft.EntityFrameworkCore;
9 |
10 | ///
11 | /// A custom implementation for using Entity Framework.
12 | ///
13 | public class FriendshipRepository : GenericRepository, IRepository
14 | {
15 | public FriendshipRepository(ApplicationDbContext dbContext)
16 | : base(dbContext) { }
17 |
18 | public new async Task> GetAllAsync(Specification specification)
19 | {
20 | var result = await _dbContext.Set()
21 | .Where(specification.Expression)
22 | .Include(f => f.From)
23 | .Include(f => f.To)
24 | .ToListAsync();
25 | return result;
26 | }
27 |
28 | public new async Task GetFirstAsync(Specification specification)
29 | {
30 | var result = await _dbContext.Set()
31 | .Where(specification.Expression)
32 | .Include(f => f.From)
33 | .Include(f => f.To)
34 | .FirstOrDefaultAsync();
35 | return result;
36 | }
37 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Infrastructure/Providers/NativeMailProvider.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Infrastructure.Providers;
2 |
3 | using System;
4 | using System.Net;
5 | using System.Net.Mail;
6 | using System.Threading.Tasks;
7 | using Agree.Accord.Domain.Providers;
8 | using Agree.Accord.Infrastructure.Configuration;
9 | using Microsoft.Extensions.Options;
10 |
11 | ///
12 | /// A implementation of using C#'s native .
13 | ///
14 | public class NativeMailProvider : IMailProvider, IDisposable
15 | {
16 | private readonly SmtpClient _client;
17 | private const string DefaultSender = "noreply@agree.com";
18 |
19 | public NativeMailProvider(IOptions options) => _client = new SmtpClient(options.Value.Host, options.Value.Port)
20 | {
21 | Credentials = new NetworkCredential(options.Value.UserName, options.Value.Password),
22 | EnableSsl = true
23 | };
24 |
25 | public Task SendMailAsync(string to, string subject, string body, bool isBodyHtml = true)
26 | {
27 | var message = new MailMessage(DefaultSender, to, subject, body)
28 | {
29 | IsBodyHtml = isBodyHtml
30 | };
31 | _client.SendAsync(message, null);
32 |
33 | return Task.CompletedTask;
34 | }
35 |
36 | public void Dispose()
37 | {
38 | _client.Dispose();
39 | GC.SuppressFinalize(this);
40 | }
41 | }
--------------------------------------------------------------------------------
/apps/concord_old/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | es2021: true
5 | },
6 | extends: [
7 | 'plugin:react/recommended',
8 | 'standard',
9 | 'plugin:@typescript-eslint/recommended'
10 | ],
11 | parser: '@typescript-eslint/parser',
12 | parserOptions: {
13 | ecmaFeatures: {
14 | jsx: true
15 | },
16 | ecmaVersion: 12,
17 | sourceType: 'module'
18 | },
19 | plugins: [
20 | 'react',
21 | '@typescript-eslint'
22 | ],
23 | settings: {
24 | 'import/resolver': {
25 | typescript: {}
26 | }
27 | },
28 | rules: {
29 | 'react/react-in-jsx-scope': 'off',
30 | 'no-use-before-define': 'off',
31 | '@typescript-eslint/no-use-before-define': ['error'],
32 | 'react/jsx-filename-extension': ['warn', { extensions: ['.tsx'] }],
33 | 'no-shadow': 'off',
34 | '@typescript-eslint/no-shadow': ['error'],
35 | '@typescript-eslint/no-explicit-any': 'off',
36 | 'no-template-curly-in-string': 'off',
37 | 'import/no-duplicates': 'off',
38 | 'import/prefer-default-export': 'off',
39 | 'import/extensions': [
40 | 'error',
41 | 'ignorePackages',
42 | {
43 | ts: 'never',
44 | tsx: 'never'
45 | }
46 | ],
47 | '@typescript-eslint/no-unused-vars': [
48 | 'warn',
49 | {
50 | argsIgnorePattern: '_'
51 | }
52 | ],
53 | '@typescript-eslint/explicit-module-boundary-types': 'off'
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/apps/concord_old/src/logic/contexts/ContextContainer.tsx:
--------------------------------------------------------------------------------
1 | import { ChakraProvider } from '@chakra-ui/react'
2 | import { PropsWithChildren } from 'react'
3 | import { CookiesProvider } from 'react-cookie'
4 | import { resource } from '../../i18n'
5 | import { I18nProvider } from '../../presentation/contexts/I18nContext'
6 | import { theme } from '../../presentation/styles/theme'
7 | import { AxiosHttpClient } from '../services/implementations/AxiosHttpClient'
8 | import { ConsoleLogger } from '../services/implementations/ConsoleLogger'
9 | import { LocalStorageCache } from '../services/implementations/LocalStorageCache'
10 | import { AllowProvider } from './AllowContext'
11 | import { ServerProvider } from './ServerContext'
12 |
13 | const axiosHttpClient = new AxiosHttpClient()
14 | const localStorageCache = new LocalStorageCache()
15 | const consoleLogger = new ConsoleLogger()
16 |
17 | export function ContextContainer ({ children }: PropsWithChildren): JSX.Element {
18 | return (
19 |
20 |
21 |
22 |
23 |
24 | {children}
25 |
26 |
27 |
28 |
29 |
30 | )
31 | }
32 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "label": "build_accord",
6 | "command": "dotnet",
7 | "type": "process",
8 | "args": [
9 | "build",
10 | "${workspaceFolder}/apps/accord/src/Agree.Accord.Presentation/Agree.Accord.Presentation.csproj",
11 | "/property:GenerateFullPaths=true",
12 | "/consoleloggerparameters:NoSummary"
13 | ],
14 | "problemMatcher": "$msCompile"
15 | },
16 | {
17 | "label": "publish_accord",
18 | "command": "dotnet",
19 | "type": "process",
20 | "args": [
21 | "publish",
22 | "${workspaceFolder}/apps/accord/src/Agree.Accord.Presentation/Agree.Accord.Presentation.csproj",
23 | "/property:GenerateFullPaths=true",
24 | "/consoleloggerparameters:NoSummary"
25 | ],
26 | "problemMatcher": "$msCompile"
27 | },
28 | {
29 | "label": "watch_accord",
30 | "command": "dotnet",
31 | "type": "process",
32 | "args": [
33 | "watch",
34 | "run",
35 | "--project",
36 | "${workspaceFolder}/apps/accord/src/Agree.Accord.Presentation/Agree.Accord.Presentation.csproj"
37 | ],
38 | "problemMatcher": "$msCompile"
39 | }
40 | ]
41 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/Shared/CustomHubBase.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Presentation.Shared;
2 |
3 | using System.Threading.Tasks;
4 | using Agree.Accord.Domain.Identity;
5 | using Agree.Accord.Domain.Identity.Requests;
6 | using MediatR;
7 | using Microsoft.AspNetCore.SignalR;
8 | using Microsoft.Extensions.Logging;
9 |
10 | ///
11 | /// A custom that provides useful and common methods for all hubs.
12 | ///
13 | public class CustomHubBase : Hub
14 | {
15 | public const string AccessTokenCookieName = "agreeaccord_accesstoken";
16 |
17 | private readonly ILogger _logger;
18 |
19 | protected readonly IMediator _mediator;
20 |
21 | public CustomHubBase(ILogger logger, IMediator mediator)
22 | {
23 | _logger = logger;
24 | _mediator = mediator;
25 | }
26 |
27 | protected UserAccount CurrentlyLoggedUser =>
28 | Context.User.Identity.IsAuthenticated
29 | ? UserAccount.FromClaims(Context.User)
30 | : null;
31 |
32 | protected async Task GetAuthenticatedUserAccount()
33 | => await _mediator.Send(new GetAccountByIdRequest(CurrentlyLoggedUser.Id));
34 |
35 | public string GetConnectionId() => Context.ConnectionId;
36 |
37 | public override async Task OnConnectedAsync()
38 | {
39 | await base.OnConnectedAsync();
40 | _logger.LogInformation("New connection on hub: {0}", CurrentlyLoggedUser.NameTag);
41 | }
42 | }
--------------------------------------------------------------------------------
/apps/accord/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "label": "build",
6 | "command": "dotnet",
7 | "type": "process",
8 | "args": [
9 | "build",
10 | "${workspaceFolder}/src/Agree.Accord.Presentation/Agree.Accord.Presentation.csproj",
11 | "/property:GenerateFullPaths=true",
12 | "/consoleloggerparameters:NoSummary"
13 | ],
14 | "problemMatcher": "$msCompile"
15 | },
16 | {
17 | "label": "publish",
18 | "command": "dotnet",
19 | "type": "process",
20 | "args": [
21 | "publish",
22 | "${workspaceFolder}/src/Agree.Accord.Presentation/Agree.Accord.Presentation.csproj",
23 | "/property:GenerateFullPaths=true",
24 | "/consoleloggerparameters:NoSummary"
25 | ],
26 | "problemMatcher": "$msCompile"
27 | },
28 | {
29 | "label": "watch",
30 | "command": "dotnet",
31 | "type": "process",
32 | "args": [
33 | "watch",
34 | "run",
35 | "${workspaceFolder}/src/Agree.Accord.Presentation/Agree.Accord.Presentation.csproj",
36 | "/property:GenerateFullPaths=true",
37 | "/consoleloggerparameters:NoSummary"
38 | ],
39 | "problemMatcher": "$msCompile"
40 | }
41 | ]
42 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/Social/ViewModels/DirectMessageViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Presentation.Social.ViewModels;
2 |
3 | using System;
4 | using Agree.Accord.Domain.Social;
5 | using Agree.Accord.Presentation.Identity.ViewModels;
6 |
7 | ///
8 | /// The view model for a direct message.
9 | ///
10 | public class DirectMessageViewModel
11 | {
12 | public Guid Id { get; private set; }
13 | public string Text { get; private set; }
14 | public UserAccountViewModel From { get; private set; }
15 | public UserAccountViewModel To { get; private set; }
16 | public DirectMessageViewModel InReplyTo { get; private set; }
17 | public bool Read { get; private set; }
18 | public DateTime CreatedAt { get; private set; }
19 |
20 | ///
21 | /// Creates a new instance of the class from a direct message entity.
22 | ///
23 | /// The direct message entity.
24 | /// The view model.
25 | public static DirectMessageViewModel FromEntity(DirectMessage entity, bool hideReply = false) => new()
26 | {
27 | Id = entity.Id,
28 | From = UserAccountViewModel.FromEntity(entity.From),
29 | To = UserAccountViewModel.FromEntity(entity.To),
30 | InReplyTo = entity.InReplyTo != null ? FromEntity(entity.InReplyTo, true) : null,
31 | Read = entity.Read,
32 | Text = entity.Text,
33 | CreatedAt = entity.CreatedAt
34 | };
35 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/Servers/ViewModels/ServerViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Presentation.Servers.ViewModels;
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using Agree.Accord.Domain.Servers;
7 | using Agree.Accord.Presentation.Identity.ViewModels;
8 |
9 | ///
10 | /// A server view model.
11 | ///
12 | public class ServerViewModel
13 | {
14 | public Guid Id { get; private set; }
15 | public string Name { get; private set; }
16 | public string Description { get; private set; }
17 | public string PrivacyLevel { get; private set; }
18 | public DateTime CreatedAt { get; private set; }
19 |
20 | public IEnumerable Roles { get; private set; }
21 |
22 | public IEnumerable Members { get; private set; }
23 |
24 | ///
25 | /// Creates a new instance of the class from a server entity.
26 | ///
27 | /// The server.
28 | /// The view model.
29 | public static ServerViewModel FromEntity(Server entity) => new()
30 | {
31 | Id = entity.Id,
32 | Name = entity.Name,
33 | Description = entity.Description,
34 | PrivacyLevel = entity.PrivacyLevel.ToString(),
35 | CreatedAt = entity.CreatedAt,
36 | Roles = entity.Roles.Select(r => RoleViewModel.FromEntity(r, true)),
37 | Members = entity.Members.Select(sm => UserAccountViewModel.FromEntity(sm.User))
38 | };
39 | }
--------------------------------------------------------------------------------
/apps/allow/test/Agree.Allow.Domain.Test/Agree.Allow.Domain.Test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 | enable
7 |
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 | runtime; build; native; contentfiles; analyzers; buildtransitive
16 | all
17 |
18 |
19 | runtime; build; native; contentfiles; analyzers; buildtransitive
20 | all
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | PreserveNewest
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/Servers/ViewModels/RoleViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Presentation.Servers.ViewModels;
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using Agree.Accord.Domain.Servers;
7 | using Agree.Accord.Presentation.Identity.ViewModels;
8 |
9 | ///
10 | /// A role view model.
11 | ///
12 | public class RoleViewModel
13 | {
14 | ///
15 | /// The role Id.
16 | ///
17 | public Guid Id { get; private set; }
18 |
19 | ///
20 | /// The role name.
21 | ///
22 | public string Name { get; private set; }
23 |
24 | ///
25 | /// The server this role belongs to.
26 | ///
27 | public ServerViewModel Server { get; private set; }
28 |
29 | ///
30 | /// The server members with this role.
31 | ///
32 | public IEnumerable Members { get; private set; }
33 |
34 | ///
35 | /// Creates a new instance of the class from a server entity.
36 | ///
37 | /// The server.
38 | /// The view model.
39 | public static RoleViewModel FromEntity(ServerRole entity, bool hideServer = false) => new()
40 | {
41 | Id = entity.Id,
42 | Name = entity.Name,
43 | Server = hideServer ? null : ServerViewModel.FromEntity(entity.Server),
44 | Members = entity.ServerMembers.Select(sm => UserAccountViewModel.FromEntity(sm.User))
45 | };
46 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Handlers/Commands/RemoveFriendHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Handlers.Commands;
2 |
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 | using Agree.Accord.Domain.Social.Requests;
6 | using Agree.Accord.Domain.Social.Results;
7 | using Agree.Accord.Domain.Social.Specifications;
8 | using Agree.Accord.SharedKernel;
9 | using Agree.Accord.SharedKernel.Data;
10 | using MediatR;
11 |
12 | ///
13 | /// Handles the removal of a friend.
14 | ///
15 | public class RemoveFriendHandler : IRequestHandler
16 | {
17 | private readonly IRepository _friendshipRepository;
18 |
19 | public RemoveFriendHandler(IRepository friendshipRepository) => _friendshipRepository = friendshipRepository;
20 |
21 | public async Task Handle(RemoveFriendRequest request, CancellationToken cancellationToken)
22 | {
23 | var friendship = await _friendshipRepository.GetFirstAsync(new FriendshipExistsSpecification(request.User.Id, request.FriendId));
24 |
25 | if (friendship == null)
26 | return RemoveFriendResult.Fail(new ErrorList("Friendship", "Friendship does not exist."));
27 | if (!friendship.Accepted)
28 | return RemoveFriendResult.Fail(new ErrorList("Friendship", "You are not friends with this user."));
29 |
30 | await _friendshipRepository.DeleteAsync(friendship);
31 | await _friendshipRepository.CommitAsync();
32 |
33 | return RemoveFriendResult.Ok(friendship);
34 | }
35 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Handlers/Commands/ValidateTokenHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Handlers.Commands;
2 |
3 | using System;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Agree.Allow.Domain.Requests;
7 | using Agree.Allow.Domain.Results;
8 | using Agree.Allow.Domain.Tokens;
9 | using Agree.SharedKernel.Data;
10 | using MediatR;
11 |
12 | public class ValidateTokenHandler : IRequestHandler
13 | {
14 | private readonly IRepository _accountRepository;
15 | private readonly AccessTokenFactory _accessTokenFactory;
16 | private readonly RefreshTokenFactory _refreshTokenFactory;
17 | private readonly TokenValidator _tokenValidator;
18 |
19 | public ValidateTokenHandler(IRepository accountRepository,
20 | AccessTokenFactory accessTokenFactory,
21 | RefreshTokenFactory refreshTokenFactory,
22 | TokenValidator tokenValidator)
23 | {
24 | _accountRepository = accountRepository;
25 | _accessTokenFactory = accessTokenFactory;
26 | _refreshTokenFactory = refreshTokenFactory;
27 | _tokenValidator = tokenValidator;
28 | }
29 |
30 | public async Task Handle(ValidateTokenRequest request, CancellationToken cancellationToken)
31 | {
32 | var user = await _tokenValidator.ValidateAsync(request.Token);
33 |
34 | if (user == null)
35 | return TokenValidationResult.Fail();
36 |
37 | return TokenValidationResult.Ok(user);
38 | }
39 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/validation/RegisterValidator.ts:
--------------------------------------------------------------------------------
1 | import * as Yup from 'yup'
2 |
3 | import { IValidator } from './IValidator'
4 |
5 | export type RegisterInput = {
6 | email: string
7 | userName: string
8 | password: string
9 | confirmPassword: string
10 | }
11 |
12 | export class RegisterValidator implements IValidator {
13 | public async validate (input: RegisterInput): Promise {
14 | const schema = Yup.object().shape({
15 | email: Yup.string().required('Email is required')
16 | .email('Email must be a valid email address'),
17 | userName: Yup.string().required('UserName is required')
18 | .min(1, 'UserName must have at least ${min} characters')
19 | .max(20, 'UserName must not have more than ${max} characters'),
20 | password: Yup.string().required('Password is required')
21 | .min(6, 'Password must have at least ${min} characters')
22 | .max(255, 'Password must not have more than ${max} characters')
23 | .matches(
24 | /^(?=.*[A-Z])(?=.*\d)(?=.*[a-z])[A-Za-z\d!@#$%&*_-]{6,}$/,
25 | 'Password must contain one uppercase, one lowercase and one digit characters'
26 | ),
27 | confirmPassword: Yup.string().required('Password confirmation is required')
28 | .oneOf([Yup.ref('password'), null], 'Passwords must match')
29 | })
30 |
31 | try {
32 | await schema.validate(input, { abortEarly: false })
33 | return null
34 | } catch (error) {
35 | if (error instanceof Yup.ValidationError) {
36 | return error
37 | }
38 | return null
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/apps/allow/test/Agree.Allow.Domain.Test/DiscriminatorTagTest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Test;
2 |
3 | public class DiscriminatorTagTest
4 | {
5 | [Theory]
6 | [InlineData(0, true)]
7 | [InlineData("0000", true)]
8 | [InlineData(1, true)]
9 | [InlineData("1", true)]
10 | [InlineData("01", true)]
11 | [InlineData("001", true)]
12 | [InlineData("0001", true)]
13 | [InlineData("00001", false)]
14 | [InlineData(11, true)]
15 | [InlineData(111, true)]
16 | [InlineData(1111, true)]
17 | [InlineData("0111", true)]
18 | [InlineData(11111, false)]
19 | [InlineData("01111", false)]
20 | [InlineData("", false)]
21 | [InlineData(" ", false)]
22 | [InlineData("a", false)]
23 | [InlineData("a1", false)]
24 | public void TryParse_ShouldParseValuesCorrectly(object value, bool isValidTag)
25 | {
26 | if (DiscriminatorTag.TryParse(value, out var tag))
27 | {
28 | if (isValidTag)
29 | {
30 | Assert.Equal(value.ToString().PadLeft(4, '0'), tag.ToString());
31 | Assert.Equal(ushort.Parse(value.ToString()), tag.Value);
32 | }
33 | else
34 | {
35 | Assert.Equal("0000", tag.ToString());
36 | Assert.Equal(0, tag.Value);
37 | }
38 | }
39 | }
40 |
41 | [Fact]
42 | public void NewTag_ShouldReturnTagBetween1And9999()
43 | {
44 | for (var i = 0; i < 1000000; i++)
45 | {
46 | var tag = DiscriminatorTag.NewTag();
47 | Assert.True(tag.Value >= 1);
48 | Assert.True(tag.Value <= 9999);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Tokens/RefreshTokenFactory.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Tokens;
2 |
3 | using System;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Security.Claims;
7 | using System.IdentityModel.Tokens.Jwt;
8 | using Microsoft.Extensions.Options;
9 | using Microsoft.IdentityModel.Tokens;
10 |
11 | public class RefreshTokenFactory
12 | {
13 | private readonly JwtConfiguration _jwtConfiguration;
14 |
15 | public RefreshTokenFactory(IOptions jwtConfiguration)
16 | {
17 | _jwtConfiguration = jwtConfiguration.Value;
18 | }
19 |
20 | private Token GenerateRefreshTokenCore(UserAccount account)
21 | {
22 | var tokenHandler = new JwtSecurityTokenHandler();
23 | var key = Encoding.ASCII.GetBytes(_jwtConfiguration.SigningKey);
24 |
25 | var expiresIn = DateTime.UtcNow.AddDays(_jwtConfiguration.RefreshTokenExpiresInDays);
26 | var tokenDescriptor = new SecurityTokenDescriptor
27 | {
28 | Subject = new ClaimsIdentity(new Claim[]
29 | {
30 | new Claim(JwtRegisteredClaimNames.Sub, account.Id.ToString()),
31 | new Claim("rsh", "y")
32 | }),
33 | Issuer = _jwtConfiguration.Issuer,
34 | Expires = expiresIn,
35 | SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
36 | };
37 |
38 | var token = tokenHandler.CreateJwtSecurityToken(tokenDescriptor);
39 | return new Token(tokenHandler.WriteToken(token), ((DateTimeOffset)expiresIn).ToUnixTimeSeconds(), "Bearer");
40 | }
41 |
42 | public Task GenerateAsync(UserAccount account) => Task.Run(() => GenerateRefreshTokenCore(account));
43 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Handlers/Commands/RefreshTokenHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Handlers.Commands;
2 |
3 | using System;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Agree.Allow.Domain.Requests;
7 | using Agree.Allow.Domain.Results;
8 | using Agree.Allow.Domain.Tokens;
9 | using Agree.SharedKernel.Data;
10 | using MediatR;
11 |
12 | public class RefreshTokenHandler : IRequestHandler
13 | {
14 | private readonly IRepository _accountRepository;
15 | private readonly AccessTokenFactory _accessTokenFactory;
16 | private readonly RefreshTokenFactory _refreshTokenFactory;
17 | private readonly TokenValidator _tokenValidator;
18 |
19 | public RefreshTokenHandler(IRepository accountRepository,
20 | AccessTokenFactory accessTokenFactory,
21 | RefreshTokenFactory refreshTokenFactory,
22 | TokenValidator tokenValidator)
23 | {
24 | _accountRepository = accountRepository;
25 | _accessTokenFactory = accessTokenFactory;
26 | _refreshTokenFactory = refreshTokenFactory;
27 | _tokenValidator = tokenValidator;
28 | }
29 |
30 | public async Task Handle(RefreshTokenRequest request, CancellationToken cancellationToken)
31 | {
32 | var user = await _tokenValidator.ValidateAsync(request.RefreshToken, true);
33 |
34 | if (user == null)
35 | return AuthenticationResult.Fail();
36 |
37 | var accessToken = await _accessTokenFactory.GenerateAsync(user);
38 | var refreshToken = await _refreshTokenFactory.GenerateAsync(user);
39 |
40 | return AuthenticationResult.Ok(new TokenCollection(accessToken, refreshToken));
41 | }
42 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/components/form/PasswordInput.tsx:
--------------------------------------------------------------------------------
1 | import { useDisclosure } from '@chakra-ui/hooks'
2 | import { InputLeftElement, Input, InputGroup, InputRightElement, InputProps } from '@chakra-ui/input'
3 |
4 | import { ReactNode } from 'react'
5 | import { FiEye, FiEyeOff } from 'react-icons/fi'
6 |
7 | type PasswordInputProps = {
8 | icon: ReactNode
9 | placeholder: string
10 | w?: string | string[] | { base?: string, sm?: string, md?: string, lg?: string, xl?: string }
11 | } & InputProps
12 |
13 | export function PasswordInput ({ icon, placeholder, w = 'full', ...rest }: PasswordInputProps): JSX.Element {
14 | const { isOpen, onToggle } = useDisclosure()
15 |
16 | return (
17 |
27 |
33 | {icon}
34 |
35 |
46 |
53 | {isOpen ? : }
54 |
55 |
56 | )
57 | }
58 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Handlers/Commands/CreateServerHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers.Handlers.Commands;
2 |
3 | using System;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Agree.Accord.Domain.Servers.Requests;
7 | using Agree.Accord.Domain.Servers.Results;
8 | using Agree.Accord.SharedKernel;
9 | using Agree.Accord.SharedKernel.Data;
10 | using MediatR;
11 |
12 | ///
13 | /// Handles the creation of a new .
14 | ///
15 | public class CreateServerHandler : IRequestHandler
16 | {
17 | private readonly IRepository _serverRepository;
18 |
19 | public CreateServerHandler(IRepository serverRepository)
20 | => _serverRepository = serverRepository;
21 |
22 | public async Task Handle(CreateServerRequest request, CancellationToken cancellationToken)
23 | {
24 | var validationResult = AnnotationValidator.TryValidate(request);
25 |
26 | if (validationResult.Failed)
27 | return CreateServerResult.Fail(validationResult.Error.ToErrorList());
28 |
29 | var server = new Server(request.Name, request.PrivacyLevel, request.Description);
30 |
31 | var category = Category.CreateDefaultWelcomeCategory(server);
32 | server.Categories.Add(category);
33 |
34 | var adminRole = ServerRole.CreateDefaultAdminRole(server);
35 | server.Roles.Add(adminRole);
36 |
37 | var ownerAsMember = new ServerMember(request.Owner, server);
38 | ownerAsMember.Roles.Add(adminRole);
39 | server.Members.Add(ownerAsMember);
40 |
41 | await _serverRepository.InsertAsync(server);
42 | await _serverRepository.CommitAsync();
43 |
44 | return CreateServerResult.Ok(server);
45 | }
46 | }
--------------------------------------------------------------------------------
/apps/accord/test/Agree.Accord.Domain.Test/DiscriminatorTagTest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Test;
2 |
3 | using System;
4 | using Agree.Accord.Domain.Identity;
5 | using Xunit;
6 |
7 | public class DiscriminatorTagTest
8 | {
9 | [Theory]
10 | [InlineData(0, true)]
11 | [InlineData("0000", true)]
12 | [InlineData(1, true)]
13 | [InlineData("1", true)]
14 | [InlineData("01", true)]
15 | [InlineData("001", true)]
16 | [InlineData("0001", true)]
17 | [InlineData("00001", false)]
18 | [InlineData(11, true)]
19 | [InlineData(111, true)]
20 | [InlineData(1111, true)]
21 | [InlineData("0111", true)]
22 | [InlineData(11111, false)]
23 | [InlineData("01111", false)]
24 | [InlineData("", false)]
25 | [InlineData(" ", false)]
26 | [InlineData("a", false)]
27 | [InlineData("a1", false)]
28 | public void TryParse_ShouldParseValuesCorrectly(object value, bool isValidTag)
29 | {
30 | if (DiscriminatorTag.TryParse(value, out var tag))
31 | {
32 | if (isValidTag)
33 | {
34 | Assert.Equal(value.ToString().PadLeft(4, '0'), tag.ToString());
35 | Assert.Equal(ushort.Parse(value.ToString()), tag.Value);
36 | }
37 | else
38 | {
39 | Assert.Equal("0000", tag.ToString());
40 | Assert.Equal(0, tag.Value);
41 | }
42 | }
43 | }
44 |
45 | [Fact]
46 | public void NewTag_ShouldReturnTagBetween1And9999()
47 | {
48 | var oneMillion = 1000000;
49 | for (var i = 0; i < oneMillion; i++)
50 | {
51 | var tag = DiscriminatorTag.NewTag();
52 | Assert.True(tag.Value >= 1);
53 | Assert.True(tag.Value <= 9999);
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/ServerRole.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers;
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Collections.ObjectModel;
6 | using Agree.Accord.SharedKernel;
7 |
8 | ///
9 | /// A role in a server.
10 | ///
11 | public class ServerRole : IEntity
12 | {
13 | // EF ctor
14 | protected ServerRole() { }
15 |
16 | public ServerRole(string name, Server server)
17 | {
18 | Id = Guid.NewGuid();
19 | Name = name;
20 | Server = server;
21 | ServerId = server.Id;
22 | ServerMembers = new Collection();
23 | Permissions = new Collection();
24 | }
25 |
26 | ///
27 | /// Creates a new role with default admin permissions for a server.
28 | ///
29 | public static ServerRole CreateDefaultAdminRole(Server server)
30 | => new("Admin", server);
31 |
32 | ///
33 | /// The role Id.
34 | ///
35 | public Guid Id { get; private set; }
36 |
37 | ///
38 | /// The role name.
39 | ///
40 | public string Name { get; private set; }
41 |
42 | ///
43 | /// The server Id this role belongs to.
44 | ///
45 | public Guid ServerId { get; private set; }
46 |
47 | ///
48 | /// The server this role belongs to.
49 | ///
50 | public Server Server { get; private set; }
51 |
52 | ///
53 | /// The server members with this role.
54 | ///
55 | public ICollection ServerMembers { get; private set; }
56 |
57 | ///
58 | /// The permissions this role has.
59 | ///
60 | public ICollection Permissions { get; private set; }
61 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Requests/CreateAccountRequest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Requests;
2 |
3 | using System.ComponentModel.DataAnnotations;
4 | using Agree.Allow.Domain.Results;
5 | using MediatR;
6 |
7 | public class CreateAccountRequest : IRequest
8 | {
9 | [Required(ErrorMessage = "Email is required.")]
10 | [EmailAddress(ErrorMessage = "Email must be a valid email address.")]
11 | [MaxLength(255, ErrorMessage = "Email must have less than 255 characters.")]
12 | public string EmailAddress { get; set; }
13 |
14 | [Required(ErrorMessage = "Username is required.")]
15 | [MinLength(1, ErrorMessage = "Username must have at least 1 character.")]
16 | [MaxLength(40, ErrorMessage = "Username must have less than 40 characters.")]
17 | [RegularExpression(UsernameRegEx, ErrorMessage = "Username must only contain alfabetic characters, digits, _ and -.")]
18 | public string Username { get; set; }
19 |
20 | [Required(ErrorMessage = "Password is required.")]
21 | [MinLength(6, ErrorMessage = "Password must have at least 6 characters.")]
22 | [MaxLength(80, ErrorMessage = "Password must have less than 80 characters.")]
23 | [RegularExpression(PasswordRegEx, ErrorMessage = "Password must contain at least one uppercase character, one lowercase character, and a digit.")]
24 | public string Password { get; set; }
25 |
26 | [Required(ErrorMessage = "Password confirmation is required.")]
27 | [Compare("Password", ErrorMessage = "Passwords doesn't match.")]
28 | public string PasswordConfirmation { get; set; }
29 |
30 | private const string UsernameRegEx = @"[a-zA-Z0-9_-]*";
31 |
32 | private const string PasswordRegEx = @"(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$)?(^(?=.*\d)(?=.*[a-z])(?=.*[@#$%^&+=]).*$)?(^(?=.*\d)(?=.*[A-Z])(?=.*[@#$%^&+=]).*$)?(^(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$)?";
33 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Handlers/Commands/MarkDirectMessageAsReadHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Handlers.Commands;
2 |
3 | using System;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Agree.Accord.Domain.Social.Requests;
7 | using Agree.Accord.Domain.Social.Results;
8 | using Agree.Accord.Domain.Social.Specifications;
9 | using Agree.Accord.SharedKernel;
10 | using Agree.Accord.SharedKernel.Data;
11 | using MediatR;
12 |
13 | ///
14 | /// Handles the marking of a direct message as read.
15 | ///
16 | public class MarkDirectMessageAsReadHandler : IRequestHandler
17 | {
18 | private readonly IRepository _directMessageRepository;
19 |
20 | public MarkDirectMessageAsReadHandler(IRepository directMessageRepository)
21 | => _directMessageRepository = directMessageRepository;
22 |
23 | public async Task Handle(MarkDirectMessageAsReadRequest request, CancellationToken cancellationToken)
24 | {
25 | var directMessage = await _directMessageRepository.GetFirstAsync(new DirectMessageIdEqualSpecification(request.DirectMessageId));
26 | if (directMessage == null)
27 | {
28 | return DirectMessageResult.Fail(new ErrorList("DirectMessageId", "Direct message not found."));
29 | }
30 | if (directMessage.From.Id != request.Requester.Id)
31 | {
32 | return DirectMessageResult.Fail(new ErrorList("DirectMessageId", "Direct message was not sent to you."));
33 | }
34 |
35 | directMessage.MarkRead();
36 |
37 | await _directMessageRepository.UpdateAsync(directMessage);
38 | await _directMessageRepository.CommitAsync();
39 |
40 | return DirectMessageResult.Ok(directMessage);
41 | }
42 | }
--------------------------------------------------------------------------------
/apps/concord_old/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "agree-concord",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@chakra-ui/react": "^1.4.1",
7 | "@emotion/react": "^11",
8 | "@emotion/styled": "^11",
9 | "@testing-library/jest-dom": "^5.11.4",
10 | "@testing-library/react": "^11.1.0",
11 | "@testing-library/user-event": "^12.1.10",
12 | "@types/jest": "^26.0.15",
13 | "@types/node": "^12.0.0",
14 | "@types/react": "^17.0.3",
15 | "@types/react-dom": "^17.0.3",
16 | "axios": "^0.21.1",
17 | "date-fns": "^2.21.3",
18 | "framer-motion": "^4",
19 | "react": "^17.0.1",
20 | "react-cookie": "^4.0.3",
21 | "react-dom": "^17.0.1",
22 | "react-icons": "^4.2.0",
23 | "react-router-dom": "^5.2.0",
24 | "react-scripts": "4.0.3",
25 | "react-use": "^17.2.4",
26 | "sass": "^1.32.11",
27 | "ts-results": "^3.3.0",
28 | "typescript": "^4.1.2",
29 | "web-vitals": "^1.0.1",
30 | "yup": "^0.32.9"
31 | },
32 | "scripts": {
33 | "start": "react-scripts start",
34 | "build": "react-scripts build",
35 | "test": "react-scripts test",
36 | "eject": "react-scripts eject"
37 | },
38 | "browserslist": {
39 | "production": [
40 | ">0.2%",
41 | "not dead",
42 | "not op_mini all"
43 | ],
44 | "development": [
45 | "last 1 chrome version",
46 | "last 1 firefox version",
47 | "last 1 safari version"
48 | ]
49 | },
50 | "devDependencies": {
51 | "@types/react-router-dom": "^5.1.7",
52 | "@typescript-eslint/eslint-plugin": "^4.19.0",
53 | "@typescript-eslint/parser": "^4.19.0",
54 | "eslint": "^7.22.0",
55 | "eslint-config-standard": "^16.0.2",
56 | "eslint-import-resolver-typescript": "^2.4.0",
57 | "eslint-plugin-import": "^2.22.1",
58 | "eslint-plugin-node": "^11.1.0",
59 | "eslint-plugin-promise": "^4.3.1",
60 | "eslint-plugin-react": "^7.23.0"
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/apps/allow/test/Agree.Allow.Domain.Test/DiscriminatorTagFactoryTest.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Test;
2 |
3 | using Agree.Allow.Test;
4 |
5 | public class DiscriminatorTagFactoryTest : TestBase
6 | {
7 | [Fact]
8 | public async Task GenerateDiscriminatorTagAsync_WithExistingTag_ReturnsNewTag()
9 | {
10 | // Arrange
11 | var sut = Resolve();
12 |
13 | // Act
14 | var tag1 = await sut.GenerateDiscriminatorTagAsync("testuser");
15 | var user1 = await CreateTestUserAccount(tag1);
16 | for (var i = 0; i < 9999; i++)
17 | {
18 | var tag2 = await sut.GenerateDiscriminatorTagAsync("testuser");
19 | var user2 = await CreateTestUserAccount(tag2);
20 |
21 | // Assert
22 | Assert.NotEqual(tag1, tag2);
23 | }
24 | }
25 |
26 | [Fact]
27 | public async Task GenerateDiscriminatorTagAsync_WithMoreThan10000ExistingTags_ReturnsNull()
28 | {
29 | // Arrange
30 | var sut = Resolve();
31 |
32 | // Act
33 | var tag1 = await sut.GenerateDiscriminatorTagAsync("testuser");
34 | var user1 = await CreateTestUserAccount(tag1);
35 | for (var i = 0; i < 9999; i++)
36 | {
37 | var tag2 = await sut.GenerateDiscriminatorTagAsync("testuser");
38 | var user2 = await CreateTestUserAccount(tag2);
39 | }
40 |
41 | var tag3 = await sut.GenerateDiscriminatorTagAsync("testuser");
42 |
43 | // Assert
44 | Assert.Null(tag3);
45 | }
46 |
47 | [Fact]
48 | public async Task GenerateDiscriminatorTagAsync_WithNoExistingTags_ReturnsTag0()
49 | {
50 | // Arrange
51 | var sut = Resolve();
52 |
53 | // Act
54 | var tag = await sut.GenerateDiscriminatorTagAsync("testuser");
55 |
56 | // Assert
57 | Assert.Equal(0, tag.Value);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/UserAccount.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain;
2 |
3 | using System;
4 | using Agree.SharedKernel;
5 | using System.Security.Claims;
6 | using System.IdentityModel.Tokens.Jwt;
7 |
8 | public class UserAccount : IEntity
9 | {
10 | public UserAccount(string username, string emailAddress, string passwordHash, DiscriminatorTag tag)
11 | {
12 | Id = Guid.NewGuid();
13 | Username = username;
14 | EmailAddress = emailAddress;
15 | PasswordHash = passwordHash;
16 | Tag = tag;
17 | CreatedAt = DateTime.UtcNow;
18 | }
19 |
20 | public Guid Id { get; private set; }
21 |
22 | public string EmailAddress { get; private set; }
23 |
24 | public string PasswordHash { get; private set; }
25 |
26 | public string Username { get; private set; }
27 |
28 | public virtual string NameTag => $"{Username}#{Tag}";
29 |
30 | public DiscriminatorTag Tag { get; private set; }
31 |
32 | public DateTime CreatedAt { get; private set; }
33 |
34 | public ClaimsPrincipal ToClaimsPrincipal() => new(new ClaimsIdentity(new[]
35 | {
36 | new Claim(JwtRegisteredClaimNames.Sub, Id.ToString()),
37 | new Claim(JwtRegisteredClaimNames.Name, NameTag),
38 | new Claim(JwtRegisteredClaimNames.Email, EmailAddress)
39 | }));
40 |
41 | public static UserAccount FromClaims(ClaimsPrincipal principal)
42 | {
43 | var id = Guid.Parse(principal.FindFirstValue(JwtRegisteredClaimNames.Sub));
44 | var nameTag = principal.FindFirstValue(JwtRegisteredClaimNames.Name);
45 | var emailAddress = principal.FindFirstValue(JwtRegisteredClaimNames.Email);
46 |
47 | var username = nameTag.Split('#')[0];
48 | var tag = (DiscriminatorTag)Enum.Parse(typeof(DiscriminatorTag), nameTag.Split('#')[1]);
49 |
50 | return new UserAccount(username, emailAddress, null, tag) { Id = id };
51 | }
52 | }
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/Routes.tsx:
--------------------------------------------------------------------------------
1 | import { Switch, Route, Redirect } from 'react-router-dom'
2 | import { AuthenticatedRoute, UnauthenticatedRoute } from '../logic/hooks/useAllow'
3 | import { DashboardLayout } from './layouts/DashboardLayout'
4 | import { AuthPage } from './pages/account/AuthPage'
5 | import { HomePage } from './pages/dashboard/HomePage'
6 | import { NotFoundPage } from './pages/error/NotFoundPage'
7 | import { SettingsLayout } from './layouts/SettingsLayout'
8 | import { ServerSearch } from './pages/dashboard/ServerSearch'
9 | import { ServerCreate } from './pages/dashboard/ServerCreate'
10 |
11 | export function Routes (): JSX.Element {
12 | return (
13 |
14 | (
17 |
18 | (
19 |
20 | }/>
21 | }/>
22 | }/>
23 | }/>
24 | }/>
25 | }/>
26 | }/>
27 |
28 | )}/>
29 |
30 | )}/>
31 |
32 | (
33 |
34 | )}/>
35 |
36 |
37 |
38 |
39 |
40 | )
41 | }
42 |
--------------------------------------------------------------------------------
/apps/concord_old/src/presentation/components/nav/ServerBar.tsx:
--------------------------------------------------------------------------------
1 | import { Box, Flex, List } from '@chakra-ui/layout'
2 | import { FiCompass, FiPlus, FiSettings } from 'react-icons/fi'
3 |
4 | import IconImg from '../../assets/iconw.svg'
5 | import { useI18n } from '../../hooks/useI18n'
6 | import { ServerAvatar } from '../avatar/ServerAvatar'
7 |
8 | export function ServerBar (): JSX.Element {
9 | const { t } = useI18n()
10 |
11 | return (
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | {Array.from(Array(6).keys()).map(i => (
25 |
26 | ))}
27 |
28 | } marginY="0.5rem" />
29 |
30 | } marginY="0.5rem" />
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | } marginTop="1.75rem" />
39 |
40 |
41 |
42 |
43 | )
44 | }
45 |
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Handlers/Commands/DeclineFriendshipRequestHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Handlers.Commands;
2 |
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 | using Agree.Accord.Domain.Social.Notifications;
6 | using Agree.Accord.Domain.Social.Requests;
7 | using Agree.Accord.Domain.Social.Results;
8 | using Agree.Accord.Domain.Social.Specifications;
9 | using Agree.Accord.SharedKernel;
10 | using Agree.Accord.SharedKernel.Data;
11 | using MediatR;
12 |
13 | ///
14 | /// Handles the declining of a friendship request.
15 | ///
16 | public class DeclineFriendshipRequestHandler : IRequestHandler
17 | {
18 | private readonly IRepository _friendshipRepository;
19 | private readonly IMediator _mediator;
20 |
21 | public DeclineFriendshipRequestHandler(IRepository friendshipRepository, IMediator mediator)
22 | {
23 | _friendshipRepository = friendshipRepository;
24 | _mediator = mediator;
25 | }
26 |
27 | public async Task Handle(DeclineFriendshipRequestRequest request, CancellationToken cancellationToken)
28 | {
29 | var friendshipRequest = await _friendshipRepository.GetFirstAsync(new FriendshipExistsSpecification(request.FromUserId, request.LoggedUser.Id));
30 | if (friendshipRequest == null)
31 | return FriendshipRequestResult.Fail(new ErrorList("Friendship", "Friendship request does not exist."));
32 | if (friendshipRequest.Accepted)
33 | return FriendshipRequestResult.Fail(new ErrorList("Friendship", "Friendship request already accepted."));
34 |
35 | await _friendshipRepository.DeleteAsync(friendshipRequest);
36 | await _friendshipRepository.CommitAsync();
37 |
38 | await _mediator.Publish(new FriendshipRequestDeclinedNotification(friendshipRequest), cancellationToken);
39 |
40 | return FriendshipRequestResult.Ok(friendshipRequest);
41 | }
42 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Handlers/Commands/CreateCategoryHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers.Handlers.Commands;
2 |
3 | using System;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Agree.Accord.Domain.Servers.Requests;
7 | using Agree.Accord.Domain.Servers.Results;
8 | using Agree.Accord.Domain.Servers;
9 | using Agree.Accord.SharedKernel;
10 | using Agree.Accord.SharedKernel.Data;
11 | using MediatR;
12 | using Agree.Accord.Domain.Servers.Specifications;
13 |
14 | ///
15 | /// Handles the creation of a new .
16 | ///
17 | public class CreateCategoryHandler : IRequestHandler
18 | {
19 | private readonly IRepository _categoryRepository;
20 | private readonly IRepository _serverRepository;
21 |
22 | public CreateCategoryHandler(IRepository categoryRepository, IRepository serverRepository)
23 | {
24 | _categoryRepository = categoryRepository;
25 | _serverRepository = serverRepository;
26 | }
27 |
28 | public async Task Handle(CreateCategoryRequest request, CancellationToken cancellationToken)
29 | {
30 | var validationResult = AnnotationValidator.TryValidate(request);
31 | var errors = new ErrorList();
32 |
33 | if (validationResult.Failed)
34 | errors.AddErrors(validationResult.Error);
35 |
36 | var server = await _serverRepository.GetFirstAsync(new ServerIdEqualSpecification(request.ServerId, request.Requester.Id));
37 |
38 | if (server == null)
39 | errors.AddError("ServerId", "The server does not exist.");
40 |
41 | if (errors.HasErrors())
42 | return CreateCategoryResult.Fail(errors);
43 |
44 | var category = new Category(request.Name, server);
45 |
46 | await _categoryRepository.InsertAsync(category);
47 | await _categoryRepository.CommitAsync();
48 |
49 | return CreateCategoryResult.Ok(category);
50 | }
51 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Social/Handlers/Commands/AcceptFriendshipRequestHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Social.Handlers.Commands;
2 |
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 | using Agree.Accord.Domain.Social.Notifications;
6 | using Agree.Accord.Domain.Social.Requests;
7 | using Agree.Accord.Domain.Social.Results;
8 | using Agree.Accord.Domain.Social.Specifications;
9 | using Agree.Accord.SharedKernel;
10 | using Agree.Accord.SharedKernel.Data;
11 | using MediatR;
12 |
13 | ///
14 | /// Handles the acceptance of a friendship request.
15 | ///
16 | public class AcceptFriendshipRequestHandler : IRequestHandler
17 | {
18 | private readonly IRepository _friendshipRepository;
19 | private readonly IMediator _mediator;
20 |
21 | public AcceptFriendshipRequestHandler(IRepository friendshipRepository, IMediator mediator)
22 | {
23 | _friendshipRepository = friendshipRepository;
24 | _mediator = mediator;
25 | }
26 |
27 | public async Task Handle(AcceptFriendshipRequestRequest request, CancellationToken cancellationToken)
28 | {
29 | var friendshipRequest = await _friendshipRepository.GetFirstAsync(new FriendshipExistsSpecification(request.FromUserId, request.LoggedUser.Id));
30 | if (friendshipRequest == null)
31 | return FriendshipRequestResult.Fail(new ErrorList("Friendship", "Friendship request does not exist."));
32 | if (friendshipRequest.Accepted)
33 | return FriendshipRequestResult.Fail(new ErrorList("Friendship", "Friendship request already accepted."));
34 |
35 | friendshipRequest.Accept();
36 |
37 | await _friendshipRepository.UpdateAsync(friendshipRequest);
38 | await _friendshipRepository.CommitAsync();
39 |
40 | await _mediator.Publish(new FriendshipRequestAcceptedNotification(friendshipRequest), cancellationToken);
41 |
42 | return FriendshipRequestResult.Ok(friendshipRequest);
43 | }
44 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Handlers/Commands/PasswordLoginHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Handlers.Commands;
2 |
3 | using System;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Agree.Allow.Domain.Requests;
7 | using Agree.Allow.Domain.Results;
8 | using Agree.Allow.Domain.Specifications;
9 | using Agree.Allow.Domain.Tokens;
10 | using Agree.SharedKernel.Data;
11 | using MediatR;
12 |
13 | public class PasswordLoginHandler : IRequestHandler
14 | {
15 | private readonly IRepository _accountRepository;
16 | private readonly IPasswordManager _passwordManager;
17 | private readonly AccessTokenFactory _accessTokenFactory;
18 | private readonly RefreshTokenFactory _refreshTokenFactory;
19 |
20 | public PasswordLoginHandler(IRepository accountRepository,
21 | AccessTokenFactory acessTokenFactory,
22 | RefreshTokenFactory refreshTokenFactory,
23 | IPasswordManager passwordManager)
24 | {
25 | _accountRepository = accountRepository;
26 | _accessTokenFactory = acessTokenFactory;
27 | _refreshTokenFactory = refreshTokenFactory;
28 | _passwordManager = passwordManager;
29 | }
30 |
31 | public async Task Handle(PasswordLoginRequest request, CancellationToken cancellationToken)
32 | {
33 | var user = await _accountRepository.GetFirstAsync(new EmailEqualSpecification(request.EmailAddress));
34 |
35 | if (user == null)
36 | return AuthenticationResult.Fail();
37 |
38 | var passwordValid = await _passwordManager.CompareAsync(user.PasswordHash, request.Password);
39 |
40 | if (!passwordValid)
41 | return AuthenticationResult.Fail();
42 |
43 | var accessToken = await _accessTokenFactory.GenerateAsync(user);
44 | var refreshToken = await _refreshTokenFactory.GenerateAsync(user);
45 |
46 | return AuthenticationResult.Ok(new TokenCollection(accessToken, refreshToken));
47 | }
48 | }
--------------------------------------------------------------------------------
/apps/allow/src/Agree.Allow.Domain/Tokens/AccessTokenFactory.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Allow.Domain.Tokens;
2 |
3 | using System;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Security.Claims;
7 | using System.IdentityModel.Tokens.Jwt;
8 | using Microsoft.Extensions.Options;
9 | using Microsoft.IdentityModel.Tokens;
10 |
11 | public class AccessTokenFactory
12 | {
13 | private readonly JwtConfiguration _jwtConfiguration;
14 |
15 | public AccessTokenFactory(IOptions jwtConfiguration)
16 | {
17 | _jwtConfiguration = jwtConfiguration.Value;
18 | }
19 |
20 | private Token GenerateAccessTokenCore(UserAccount account)
21 | {
22 | var tokenHandler = new JwtSecurityTokenHandler();
23 | var key = Encoding.ASCII.GetBytes(_jwtConfiguration.SigningKey);
24 |
25 | var expiresIn = DateTime.UtcNow.AddMinutes(_jwtConfiguration.AccessTokenExpiresInMinutes);
26 | var tokenDescriptor = new SecurityTokenDescriptor
27 | {
28 | Subject = new ClaimsIdentity(new Claim[]
29 | {
30 | new Claim(JwtRegisteredClaimNames.Name, account.NameTag),
31 | new Claim(JwtRegisteredClaimNames.Sub, account.Id.ToString()),
32 | new Claim(JwtRegisteredClaimNames.Email, account.EmailAddress)
33 | }),
34 | Issuer = _jwtConfiguration.Issuer,
35 | Expires = expiresIn,
36 | SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature),
37 | };
38 |
39 | var token = tokenHandler.CreateJwtSecurityToken(tokenDescriptor);
40 | return new Token(tokenHandler.WriteToken(token), ((DateTimeOffset)expiresIn).ToUnixTimeSeconds(), "Bearer");
41 | }
42 |
43 | ///
44 | /// Generates a access token for a given user.
45 | ///
46 | /// The user account.
47 | /// The generated access token.
48 | public Task GenerateAsync(UserAccount account) => Task.Run(() => GenerateAccessTokenCore(account));
49 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Domain/Servers/Server.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Domain.Servers;
2 |
3 | using System.Collections.ObjectModel;
4 | using System.Collections.Generic;
5 | using System;
6 | using Agree.Accord.SharedKernel;
7 |
8 | ///
9 | /// A message server.
10 | ///
11 | public class Server : IEntity
12 | {
13 | /// EF ctor
14 | protected Server()
15 | {
16 | Members = new Collection();
17 | Roles = new Collection();
18 | Categories = new Collection();
19 | }
20 |
21 | public Server(string name, ServerPrivacy privacyLevel, string description = null)
22 | {
23 | Id = Guid.NewGuid();
24 | Name = name;
25 | Description = description;
26 | PrivacyLevel = privacyLevel;
27 | CreatedAt = DateTime.UtcNow;
28 | Members = new Collection();
29 | Roles = new Collection();
30 | Categories = new Collection();
31 | }
32 |
33 | ///
34 | /// The server id.
35 | ///
36 | public Guid Id { get; private set; }
37 |
38 | ///
39 | /// The server name.
40 | ///
41 | public string Name { get; private set; }
42 |
43 | ///
44 | /// The server description.
45 | ///
46 | public string Description { get; private set; }
47 |
48 | ///
49 | /// The server privacy level.
50 | ///
51 | public ServerPrivacy PrivacyLevel { get; private set; }
52 |
53 | ///
54 | /// The server creation date.
55 | ///
56 | public DateTime CreatedAt { get; private set; }
57 |
58 | ///
59 | /// The server members in a N-N pivot collection.
60 | ///
61 | public ICollection Members { get; private set; }
62 |
63 | ///
64 | /// The server roles.
65 | ///
66 | public ICollection Roles { get; private set; }
67 |
68 | ///
69 | /// The server categories.
70 | ///
71 | public ICollection Categories { get; private set; }
72 | }
--------------------------------------------------------------------------------
/apps/accord/src/Agree.Accord.Presentation/Social/Controllers/FriendsController.cs:
--------------------------------------------------------------------------------
1 | namespace Agree.Accord.Presentation.Social.Controllers;
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 | using Agree.Accord.Domain.Social.Requests;
8 | using Agree.Accord.Presentation.Identity.ViewModels;
9 | using Agree.Accord.Presentation.Responses;
10 | using Agree.Accord.Presentation.Shared;
11 | using MediatR;
12 | using Microsoft.AspNetCore.Authorization;
13 | using Microsoft.AspNetCore.Http;
14 | using Microsoft.AspNetCore.Mvc;
15 |
16 | ///
17 | /// A controller for managing friends.
18 | ///
19 | [ApiController]
20 | [Route("api/friends")]
21 | [Authorize]
22 | public class FriendsController : CustomControllerBase
23 | {
24 | public FriendsController(IMediator mediator) : base(mediator) { }
25 |
26 | [HttpGet]
27 | [Route("")]
28 | [Authorize]
29 | [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GenericResponse>))]
30 | public async Task Index()
31 | {
32 | var friends = await _mediator.Send(new GetFriendsFromUserRequest(await GetAuthenticatedUserAccount()));
33 | return Ok(new GenericResponse(friends.Select(UserAccountViewModel.FromEntity)));
34 | }
35 |
36 | [HttpDelete]
37 | [Route("{friendId:guid}")]
38 | [Authorize]
39 | [ProducesResponseType(StatusCodes.Status204NoContent)]
40 | [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ValidationErrorResponse))]
41 | public async Task Delete([FromRoute] Guid friendId)
42 | {
43 | var result = await _mediator.Send(new RemoveFriendRequest(await GetAuthenticatedUserAccount(), friendId));
44 | if (result.Failed)
45 | {
46 | return BadRequest(new ValidationErrorResponse(result.Error));
47 | }
48 |
49 | // await _hubContext.Clients
50 | // .User(friendId.ToString())
51 | // .SendAsync(
52 | // FriendshipHub.FriendshipRemovedMessage,
53 | // FriendshipRequestViewModel.FromEntity(result.Data)
54 | // );
55 |
56 | return NoContent();
57 | }
58 | }
--------------------------------------------------------------------------------