From bbabf51073a73ec1d59a6c0fd1cbc3087512b267 Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Thu, 10 Apr 2025 11:09:28 +0500 Subject: [PATCH] global: newline changes --- .dockerignore | 8 +- .gitignore | 532 +++--- .vscode/tasks.json | 82 +- AUTHORS | 6 +- CODE_OF_CONDUCT.md | 256 +-- LICENSE | 1322 ++++++------- .../Authorization/NotesnookUserRequirement.cs | 70 +- .../Authorization/ProUserRequirement.cs | 124 +- .../Authorization/SyncRequirement.cs | 202 +- .../Controllers/AnnouncementController.cs | 138 +- Notesnook.API/Controllers/S3Controller.cs | 254 +-- Notesnook.API/Controllers/UsersController.cs | 232 +-- Notesnook.API/Dockerfile | 98 +- .../AuthorizationResultTransformer.cs | 140 +- Notesnook.API/Extensions/TransactionHelper.cs | 86 +- Notesnook.API/Interfaces/IEncrypted.cs | 58 +- Notesnook.API/Interfaces/IMonograph.cs | 66 +- Notesnook.API/Interfaces/IS3Service.cs | 78 +- Notesnook.API/Interfaces/IUserService.cs | 70 +- Notesnook.API/Interfaces/IUserSettings.cs | 84 +- Notesnook.API/Models/Algorithms.cs | 50 +- Notesnook.API/Models/Announcement.cs | 316 ++-- Notesnook.API/Models/EncryptedData.cs | 150 +- Notesnook.API/Models/MultipartUploadMeta.cs | 52 +- .../Models/Responses/SignupResponse.cs | 28 +- .../Models/Responses/UserResponse.cs | 50 +- Notesnook.API/Models/S3Options.cs | 56 +- Notesnook.API/Models/UserSettings.cs | 84 +- Notesnook.API/appsettings.Development.json | 30 +- Notesnook.API/appsettings.json | 14 +- .../JsonInterfaceConverterAttribute.cs | 64 +- Streetwriters.Common/Clients.cs | 162 +- .../Converters/InterfaceConverter.cs | 106 +- Streetwriters.Common/Enums/ApplicationType.cs | 50 +- Streetwriters.Common/Enums/MFAMethods.cs | 56 +- .../Enums/SubscriptionType.cs | 62 +- .../Extensions/AppBuilderExtensions.cs | 170 +- .../Extensions/HttpClientExtensions.cs | 142 +- .../ServiceCollectionServiceExtensions.cs | 106 +- .../Extensions/StringExtensions.cs | 172 +- .../Extensions/WampRealmExtensions.cs | 82 +- Streetwriters.Common/Helpers/WampHelper.cs | 92 +- Streetwriters.Common/Interfaces/IClient.cs | 76 +- Streetwriters.Common/Interfaces/IDocument.cs | 58 +- .../Interfaces/IMessageHandler.cs | 56 +- Streetwriters.Common/Interfaces/IOffer.cs | 64 +- Streetwriters.Common/Interfaces/IResponse.cs | 52 +- .../Interfaces/ISubscription.cs | 82 +- Streetwriters.Common/Logger.cs | 102 +- .../Messages/ClearCacheMessage.cs | 74 +- .../Messages/CreateSubscriptionMessage.cs | 124 +- .../Messages/DeleteSubscriptionMessage.cs | 68 +- .../Messages/DeleteUserMessage.cs | 62 +- .../Messages/SendSSEMessage.cs | 94 +- Streetwriters.Common/Models/Client.cs | 90 +- .../Models/GetSubscriptionResponse.cs | 62 +- Streetwriters.Common/Models/MFAConfig.cs | 58 +- Streetwriters.Common/Models/Offer.cs | 104 +- Streetwriters.Common/Models/PromoCode.cs | 78 +- Streetwriters.Common/Models/Response.cs | 64 +- Streetwriters.Common/Models/Role.cs | 282 +-- Streetwriters.Common/Models/Subscription.cs | 160 +- Streetwriters.Common/Models/User.cs | 58 +- Streetwriters.Common/Models/UserModel.cs | 90 +- Streetwriters.Common/WampServers.cs | 248 +-- Streetwriters.Data/DbSettings.cs | 56 +- Streetwriters.Data/Interfaces/IDbContext.cs | 64 +- Streetwriters.Data/Interfaces/IDbSettings.cs | 52 +- Streetwriters.Data/Interfaces/IUnitOfWork.cs | 56 +- Streetwriters.Data/Repositories/Repository.cs | 252 +-- Streetwriters.Data/UnitOfWork.cs | 74 +- Streetwriters.Identity/Config.cs | 174 +- Streetwriters.Identity/Dockerfile | 98 +- Streetwriters.Identity/Enums/TokenTypes.cs | 54 +- .../Extensions/HttpContextExtensions.cs | 156 +- .../Extensions/IEnumerableExtensions.cs | 82 +- .../Extensions/IntExtensions.cs | 66 +- .../Extensions/MongoDBTicketStore.cs | 144 +- .../Extensions/UserManagerExtensions.cs | 64 +- .../Handlers/TokenResponseHandler.cs | 84 +- .../Interfaces/IEmailTemplate.cs | 60 +- .../Interfaces/IMFAService.cs | 80 +- .../Interfaces/ISMSSender.cs | 58 +- .../Interfaces/ITokenGenerationService.cs | 64 +- .../Jobs/TokenCleanupJob.cs | 38 +- .../MessageHandlers/CreateSubscription.cs | 96 +- .../MessageHandlers/DeleteSubscription.cs | 88 +- .../Models/AuthenticatorDetails.cs | 66 +- .../Models/ChangeEmailForm.cs | 76 +- .../Models/GetAccessTokenForm.cs | 96 +- .../Models/MFAPasswordRequiredResponse.cs | 56 +- .../Models/MFARequiredResponse.cs | 68 +- .../Models/MultiFactorEnableForm.cs | 84 +- .../Models/MultiFactorSetupForm.cs | 72 +- .../Models/ResetPasswordForm.cs | 82 +- Streetwriters.Identity/Models/SignupForm.cs | 112 +- .../Models/TwoFactorLoginForm.cs | 80 +- .../Models/UpdateUserForm.cs | 144 +- .../Properties/launchSettings.json | 60 +- .../CustomIntrospectionResponseGenerator.cs | 134 +- .../Services/CustomRefreshTokenService.cs | 84 +- .../Services/EmailAddressValidator.cs | 74 +- .../Services/ProfileService.cs | 120 +- Streetwriters.Identity/Services/SMSSender.cs | 114 +- .../Services/TokenCleanup.cs | 100 +- .../Services/TokenGenerationService.cs | 234 +-- .../Services/UserService.cs | 176 +- .../Templates/ConfirmEmail.html | 1646 ++++++++--------- .../Templates/ConfirmEmail.txt | 32 +- .../Templates/Email2FACode.html | 868 ++++----- .../Templates/Email2FACode.txt | 32 +- .../Templates/EmailChangeConfirmation.html | 1182 ++++++------ .../Templates/EmailChangeConfirmation.txt | 32 +- .../Templates/FailedLoginAlert.html | 1010 +++++----- .../Templates/FailedLoginAlert.txt | 28 +- .../Templates/ResetAccountPassword.html | 1316 ++++++------- .../Templates/ResetAccountPassword.txt | 32 +- .../Validation/BearerTokenValidator.cs | 122 +- .../CustomResourceOwnerValidator.cs | 302 +-- .../Validation/EmailGrantValidator.cs | 212 +-- .../Validation/LockedOutValidationResult.cs | 72 +- .../appsettings.Development.json | 26 +- Streetwriters.Identity/appsettings.json | 14 +- Streetwriters.Messenger/Dockerfile | 98 +- Streetwriters.Messenger/Helpers/SSEHelper.cs | 88 +- .../Properties/launchSettings.json | 62 +- .../Services/HeartbeatService.cs | 126 +- Streetwriters.Messenger/Startup.cs | 294 +-- .../appsettings.Development.json | 18 +- Streetwriters.Messenger/appsettings.json | 14 +- 130 files changed, 9912 insertions(+), 9912 deletions(-) diff --git a/.dockerignore b/.dockerignore index a425893..ec94971 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,5 @@ -**/Dockerfile -**/bin -**/obj -**/.env +**/Dockerfile +**/bin +**/obj +**/.env **/.env.local \ No newline at end of file diff --git a/.gitignore b/.gitignore index 84c1516..d479281 100644 --- a/.gitignore +++ b/.gitignore @@ -1,267 +1,267 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# User-specific files -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ - -# Visual Studio 2015 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# DNX -project.lock.json -project.fragment.lock.json -artifacts/ - -*_i.c -*_p.c -*_i.h -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding add-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings -# but database connection strings (with potential passwords) will be unencrypted -#*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/packages/* -# except build/, which is used as an MSBuild target. -!**/packages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config -# NuGet v3's project.json files produces more ignoreable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -node_modules/ -orleans.codegen.cs - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -*.mdf -*.ldf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# JetBrains Rider -.idea/ -*.sln.iml - -# CodeRush -.cr/ - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -keys/ -dist/ -keystore/ -.env.local +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +#*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +keys/ +dist/ +keystore/ +.env.local Notesnook.API/sync/ \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 15fc5e0..5d2ac77 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,41 +1,41 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "build-notesnook", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/Notesnook.API/Notesnook.API.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "build-identity", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/Streetwriters.Identity/Streetwriters.Identity.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "build-messenger", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/Streetwriters.Messenger/Streetwriters.Messenger.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - ] -} +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build-notesnook", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/Notesnook.API/Notesnook.API.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "build-identity", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/Streetwriters.Identity/Streetwriters.Identity.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "build-messenger", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/Streetwriters.Messenger/Streetwriters.Messenger.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + ] +} diff --git a/AUTHORS b/AUTHORS index 4771ce1..d0ec96f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,3 +1,3 @@ -Notesnook Sync Server is written & maintained by: - - Abdullah Atta - - Ammar Ahmed +Notesnook Sync Server is written & maintained by: + - Abdullah Atta + - Ammar Ahmed diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index bb8e6da..5824660 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,128 +1,128 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our -community a harassment-free experience for everyone, regardless of age, body -size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socio-economic status, -nationality, personal appearance, race, religion, or sexual identity -and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, -diverse, inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our -community include: - -- Demonstrating empathy and kindness toward other people -- Being respectful of differing opinions, viewpoints, and experiences -- Giving and gracefully accepting constructive feedback -- Accepting responsibility and apologizing to those affected by our mistakes, - and learning from the experience -- Focusing on what is best not just for us as individuals, but for the - overall community - -Examples of unacceptable behavior include: - -- The use of sexualized language or imagery, and sexual attention or - advances of any kind -- Trolling, insulting or derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or email - address, without their explicit permission -- Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of -acceptable behavior and will take appropriate and fair corrective action in -response to any behavior that they deem inappropriate, threatening, offensive, -or harmful. - -Community leaders have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct, and will communicate reasons for moderation -decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when -an individual is officially representing the community in public spaces. -Examples of representing our community include using an official e-mail address, -posting via an official social media account, or acting as an appointed -representative at an online or offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders responsible for enforcement at -support@streetwriters.co. -All complaints will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the -reporter of any incident. - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining -the consequences for any action they deem in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing -clarity around the nature of the violation and an explanation of why the -behavior was inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series -of actions. - -**Consequence**: A warning with consequences for continued behavior. No -interaction with the people involved, including unsolicited interaction with -those enforcing the Code of Conduct, for a specified period of time. This -includes avoiding interactions in community spaces as well as external channels -like social media. Violating these terms may lead to a temporary or -permanent ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including -sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public -communication with the community for a specified period of time. No public or -private interaction with the people involved, including unsolicited interaction -with those enforcing the Code of Conduct, is allowed during this period. -Violating these terms may lead to a permanent ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an -individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within -the community. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 2.0, available at -https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. - -Community Impact Guidelines were inspired by [Mozilla's code of conduct -enforcement ladder](https://github.com/mozilla/diversity). - -[homepage]: https://www.contributor-covenant.org - -For answers to common questions about this code of conduct, see the FAQ at -https://www.contributor-covenant.org/faq. Translations are available at -https://www.contributor-covenant.org/translations. +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or + advances of any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email + address, without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +support@streetwriters.co. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/LICENSE b/LICENSE index be3f7b2..1468d07 100644 --- a/LICENSE +++ b/LICENSE @@ -1,661 +1,661 @@ - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -. + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/Notesnook.API/Authorization/NotesnookUserRequirement.cs b/Notesnook.API/Authorization/NotesnookUserRequirement.cs index 9e406a7..7d613b4 100644 --- a/Notesnook.API/Authorization/NotesnookUserRequirement.cs +++ b/Notesnook.API/Authorization/NotesnookUserRequirement.cs @@ -1,36 +1,36 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; - -namespace Notesnook.API.Authorization -{ - public class NotesnookUserRequirement : AuthorizationHandler, IAuthorizationRequirement - { - protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, NotesnookUserRequirement requirement) - { - var isInAudience = context.User.HasClaim("aud", "notesnook"); - var hasRole = context.User.HasClaim("role", "notesnook"); - if (isInAudience && hasRole) - context.Succeed(requirement); - return Task.CompletedTask; - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; + +namespace Notesnook.API.Authorization +{ + public class NotesnookUserRequirement : AuthorizationHandler, IAuthorizationRequirement + { + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, NotesnookUserRequirement requirement) + { + var isInAudience = context.User.HasClaim("aud", "notesnook"); + var hasRole = context.User.HasClaim("role", "notesnook"); + if (isInAudience && hasRole) + context.Succeed(requirement); + return Task.CompletedTask; + } + } } \ No newline at end of file diff --git a/Notesnook.API/Authorization/ProUserRequirement.cs b/Notesnook.API/Authorization/ProUserRequirement.cs index b8a61c8..33eac97 100644 --- a/Notesnook.API/Authorization/ProUserRequirement.cs +++ b/Notesnook.API/Authorization/ProUserRequirement.cs @@ -1,63 +1,63 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Security.Claims; -using System.Text.Json; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; - -namespace Notesnook.API.Authorization -{ - public class ProUserRequirement : AuthorizationHandler, IAuthorizationRequirement - { - private readonly Dictionary pathErrorPhraseMap = new() - { - ["/s3"] = "upload attachments", - ["/s3/multipart"] = "upload attachments", - }; - private readonly string[] allowedClaims = ["trial", "premium", "premium_canceled"]; - protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ProUserRequirement requirement) - { - PathString path = context.Resource is DefaultHttpContext httpContext ? httpContext.Request.Path : null; - var isProOrTrial = context.User.Claims.Any((c) => c.Type == "notesnook:status" && allowedClaims.Contains(c.Value)); - if (isProOrTrial) context.Succeed(requirement); - else - { - var phrase = "continue"; - foreach (var item in pathErrorPhraseMap) - { - if (path != null && path.StartsWithSegments(item.Key)) - phrase = item.Value; - } - var error = $"Please upgrade to Pro to {phrase}."; - context.Fail(new AuthorizationFailureReason(this, error)); - } - return Task.CompletedTask; - } - - public override Task HandleAsync(AuthorizationHandlerContext context) - { - return this.HandleRequirementAsync(context, this); - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Security.Claims; +using System.Text.Json; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; + +namespace Notesnook.API.Authorization +{ + public class ProUserRequirement : AuthorizationHandler, IAuthorizationRequirement + { + private readonly Dictionary pathErrorPhraseMap = new() + { + ["/s3"] = "upload attachments", + ["/s3/multipart"] = "upload attachments", + }; + private readonly string[] allowedClaims = ["trial", "premium", "premium_canceled"]; + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ProUserRequirement requirement) + { + PathString path = context.Resource is DefaultHttpContext httpContext ? httpContext.Request.Path : null; + var isProOrTrial = context.User.Claims.Any((c) => c.Type == "notesnook:status" && allowedClaims.Contains(c.Value)); + if (isProOrTrial) context.Succeed(requirement); + else + { + var phrase = "continue"; + foreach (var item in pathErrorPhraseMap) + { + if (path != null && path.StartsWithSegments(item.Key)) + phrase = item.Value; + } + var error = $"Please upgrade to Pro to {phrase}."; + context.Fail(new AuthorizationFailureReason(this, error)); + } + return Task.CompletedTask; + } + + public override Task HandleAsync(AuthorizationHandlerContext context) + { + return this.HandleRequirementAsync(context, this); + } + } } \ No newline at end of file diff --git a/Notesnook.API/Authorization/SyncRequirement.cs b/Notesnook.API/Authorization/SyncRequirement.cs index 6fd17d4..bf60532 100644 --- a/Notesnook.API/Authorization/SyncRequirement.cs +++ b/Notesnook.API/Authorization/SyncRequirement.cs @@ -1,102 +1,102 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Collections.Generic; -using System.Linq; -using System.Security.Claims; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Authorization.Policy; -using Microsoft.AspNetCore.Http; - -namespace Notesnook.API.Authorization -{ - public class SyncRequirement : AuthorizationHandler, IAuthorizationRequirement - { - private readonly Dictionary pathErrorPhraseMap = new() - { - ["/sync/attachments"] = "use attachments", - ["/sync"] = "sync your notes", - ["/hubs/sync"] = "sync your notes", - ["/hubs/sync/v2"] = "sync your notes", - ["/monographs"] = "publish monographs" - }; - - protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, SyncRequirement requirement) - { - PathString path = context.Resource is DefaultHttpContext httpContext ? httpContext.Request.Path : null; - var result = this.IsAuthorized(context.User, path); - if (result.Succeeded) context.Succeed(requirement); - else if (result.AuthorizationFailure.FailureReasons.Any()) - context.Fail(result.AuthorizationFailure.FailureReasons.First()); - else context.Fail(); - - return Task.CompletedTask; - } - - public PolicyAuthorizationResult IsAuthorized(ClaimsPrincipal User, PathString requestPath) - { - var id = User.FindFirstValue("sub"); - - if (string.IsNullOrEmpty(id)) - { - var reason = new[] - { - new AuthorizationFailureReason(this, "Invalid token.") - }; - return PolicyAuthorizationResult.Forbid(AuthorizationFailure.Failed(reason)); - } - - var hasSyncScope = User.HasClaim("scope", "notesnook.sync"); - var isInAudience = User.HasClaim("aud", "notesnook"); - var hasRole = User.HasClaim("role", "notesnook"); - - var isEmailVerified = User.HasClaim("verified", "true"); - - if (!isEmailVerified) - { - var phrase = "continue"; - - foreach (var item in pathErrorPhraseMap) - { - if (requestPath != null && requestPath.StartsWithSegments(item.Key)) - phrase = item.Value; - } - - var error = $"Please confirm your email to {phrase}."; - var reason = new[] - { - new AuthorizationFailureReason(this, error) - }; - return PolicyAuthorizationResult.Forbid(AuthorizationFailure.Failed(reason)); - // context.Fail(new AuthorizationFailureReason(this, error)); - } - - if (hasSyncScope && isInAudience && hasRole && isEmailVerified) - return PolicyAuthorizationResult.Success(); //(requirement); - return PolicyAuthorizationResult.Forbid(); - } - - public override Task HandleAsync(AuthorizationHandlerContext context) - { - return this.HandleRequirementAsync(context, this); - } - - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Authorization.Policy; +using Microsoft.AspNetCore.Http; + +namespace Notesnook.API.Authorization +{ + public class SyncRequirement : AuthorizationHandler, IAuthorizationRequirement + { + private readonly Dictionary pathErrorPhraseMap = new() + { + ["/sync/attachments"] = "use attachments", + ["/sync"] = "sync your notes", + ["/hubs/sync"] = "sync your notes", + ["/hubs/sync/v2"] = "sync your notes", + ["/monographs"] = "publish monographs" + }; + + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, SyncRequirement requirement) + { + PathString path = context.Resource is DefaultHttpContext httpContext ? httpContext.Request.Path : null; + var result = this.IsAuthorized(context.User, path); + if (result.Succeeded) context.Succeed(requirement); + else if (result.AuthorizationFailure.FailureReasons.Any()) + context.Fail(result.AuthorizationFailure.FailureReasons.First()); + else context.Fail(); + + return Task.CompletedTask; + } + + public PolicyAuthorizationResult IsAuthorized(ClaimsPrincipal User, PathString requestPath) + { + var id = User.FindFirstValue("sub"); + + if (string.IsNullOrEmpty(id)) + { + var reason = new[] + { + new AuthorizationFailureReason(this, "Invalid token.") + }; + return PolicyAuthorizationResult.Forbid(AuthorizationFailure.Failed(reason)); + } + + var hasSyncScope = User.HasClaim("scope", "notesnook.sync"); + var isInAudience = User.HasClaim("aud", "notesnook"); + var hasRole = User.HasClaim("role", "notesnook"); + + var isEmailVerified = User.HasClaim("verified", "true"); + + if (!isEmailVerified) + { + var phrase = "continue"; + + foreach (var item in pathErrorPhraseMap) + { + if (requestPath != null && requestPath.StartsWithSegments(item.Key)) + phrase = item.Value; + } + + var error = $"Please confirm your email to {phrase}."; + var reason = new[] + { + new AuthorizationFailureReason(this, error) + }; + return PolicyAuthorizationResult.Forbid(AuthorizationFailure.Failed(reason)); + // context.Fail(new AuthorizationFailureReason(this, error)); + } + + if (hasSyncScope && isInAudience && hasRole && isEmailVerified) + return PolicyAuthorizationResult.Success(); //(requirement); + return PolicyAuthorizationResult.Forbid(); + } + + public override Task HandleAsync(AuthorizationHandlerContext context) + { + return this.HandleRequirementAsync(context, this); + } + + } } \ No newline at end of file diff --git a/Notesnook.API/Controllers/AnnouncementController.cs b/Notesnook.API/Controllers/AnnouncementController.cs index 8c08b5e..9e5f904 100644 --- a/Notesnook.API/Controllers/AnnouncementController.cs +++ b/Notesnook.API/Controllers/AnnouncementController.cs @@ -1,69 +1,69 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using MongoDB.Driver; -using Notesnook.API.Models; -using Streetwriters.Data.Repositories; - -namespace Notesnook.API.Controllers -{ - // TODO: this should be moved out into its own microservice - [ApiController] - [Route("announcements")] - public class AnnouncementController : ControllerBase - { - private Repository Announcements { get; set; } - public AnnouncementController(Repository announcements) - { - Announcements = announcements; - } - - [HttpGet("active")] - [AllowAnonymous] - public async Task GetActiveAnnouncements([FromQuery] string userId) - { - var totalActive = await Announcements.Collection.CountDocumentsAsync(Builders.Filter.Eq("IsActive", true)); - if (totalActive <= 0) return Ok(new Announcement[] { }); - - var announcements = (await Announcements.FindAsync((a) => a.IsActive)).Where((a) => a.UserIds == null || a.UserIds.Length == 0 || a.UserIds.Contains(userId)); - foreach (var announcement in announcements) - { - if (announcement.UserIds != null && !announcement.UserIds.Contains(userId)) continue; - - foreach (var item in announcement.Body) - { - if (item.Type != "callToActions") continue; - foreach (var action in item.Actions) - { - if (action.Type != "link") continue; - - action.Data = action.Data.Replace("{{UserId}}", userId ?? "0"); - } - } - } - return Ok(announcements); - } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using MongoDB.Driver; +using Notesnook.API.Models; +using Streetwriters.Data.Repositories; + +namespace Notesnook.API.Controllers +{ + // TODO: this should be moved out into its own microservice + [ApiController] + [Route("announcements")] + public class AnnouncementController : ControllerBase + { + private Repository Announcements { get; set; } + public AnnouncementController(Repository announcements) + { + Announcements = announcements; + } + + [HttpGet("active")] + [AllowAnonymous] + public async Task GetActiveAnnouncements([FromQuery] string userId) + { + var totalActive = await Announcements.Collection.CountDocumentsAsync(Builders.Filter.Eq("IsActive", true)); + if (totalActive <= 0) return Ok(new Announcement[] { }); + + var announcements = (await Announcements.FindAsync((a) => a.IsActive)).Where((a) => a.UserIds == null || a.UserIds.Length == 0 || a.UserIds.Contains(userId)); + foreach (var announcement in announcements) + { + if (announcement.UserIds != null && !announcement.UserIds.Contains(userId)) continue; + + foreach (var item in announcement.Body) + { + if (item.Type != "callToActions") continue; + foreach (var action in item.Actions) + { + if (action.Type != "link") continue; + + action.Data = action.Data.Replace("{{UserId}}", userId ?? "0"); + } + } + } + return Ok(announcements); + } + } +} diff --git a/Notesnook.API/Controllers/S3Controller.cs b/Notesnook.API/Controllers/S3Controller.cs index 294cdba..9db9762 100644 --- a/Notesnook.API/Controllers/S3Controller.cs +++ b/Notesnook.API/Controllers/S3Controller.cs @@ -1,127 +1,127 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Amazon.S3.Model; -using System.Threading.Tasks; -using System.Security.Claims; -using Notesnook.API.Interfaces; -using System; - -namespace Notesnook.API.Controllers -{ - [ApiController] - [Route("s3")] - [ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)] - public class S3Controller : ControllerBase - { - private IS3Service S3Service { get; set; } - public S3Controller(IS3Service s3Service) - { - S3Service = s3Service; - } - - [HttpPut] - [Authorize("Pro")] - public IActionResult Upload([FromQuery] string name) - { - var userId = this.User.FindFirstValue("sub"); - var url = S3Service.GetUploadObjectUrl(userId, name); - if (url == null) return BadRequest("Could not create signed url."); - return Ok(url); - } - - - [HttpGet("multipart")] - [Authorize("Pro")] - public async Task MultipartUpload([FromQuery] string name, [FromQuery] int parts, [FromQuery] string uploadId) - { - var userId = this.User.FindFirstValue("sub"); - try - { - var meta = await S3Service.StartMultipartUploadAsync(userId, name, parts, uploadId); - return Ok(meta); - } - catch (Exception ex) { return BadRequest(ex.Message); } - } - - [HttpDelete("multipart")] - [Authorize("Pro")] - public async Task AbortMultipartUpload([FromQuery] string name, [FromQuery] string uploadId) - { - var userId = this.User.FindFirstValue("sub"); - try - { - await S3Service.AbortMultipartUploadAsync(userId, name, uploadId); - return Ok(); - } - catch (Exception ex) { return BadRequest(ex.Message); } - } - - [HttpPost("multipart")] - [Authorize("Pro")] - public async Task CompleteMultipartUpload([FromBody] CompleteMultipartUploadRequest uploadRequest) - { - var userId = this.User.FindFirstValue("sub"); - try - { - await S3Service.CompleteMultipartUploadAsync(userId, uploadRequest); - return Ok(); - } - catch (Exception ex) { return BadRequest(ex.Message); } - } - - [HttpGet] - [Authorize("Sync")] - public IActionResult Download([FromQuery] string name) - { - var userId = this.User.FindFirstValue("sub"); - var url = S3Service.GetDownloadObjectUrl(userId, name); - if (url == null) return BadRequest("Could not create signed url."); - return Ok(url); - } - - [HttpHead] - [Authorize("Sync")] - public async Task Info([FromQuery] string name) - { - var userId = this.User.FindFirstValue("sub"); - var size = await S3Service.GetObjectSizeAsync(userId, name); - HttpContext.Response.Headers.ContentLength = size; - return Ok(); - } - - [HttpDelete] - [Authorize("Sync")] - public async Task DeleteAsync([FromQuery] string name) - { - try - { - var userId = this.User.FindFirstValue("sub"); - await S3Service.DeleteObjectAsync(userId, name); - return Ok(); - } - catch (Exception ex) - { - return BadRequest(ex.Message); - } - } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Amazon.S3.Model; +using System.Threading.Tasks; +using System.Security.Claims; +using Notesnook.API.Interfaces; +using System; + +namespace Notesnook.API.Controllers +{ + [ApiController] + [Route("s3")] + [ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)] + public class S3Controller : ControllerBase + { + private IS3Service S3Service { get; set; } + public S3Controller(IS3Service s3Service) + { + S3Service = s3Service; + } + + [HttpPut] + [Authorize("Pro")] + public IActionResult Upload([FromQuery] string name) + { + var userId = this.User.FindFirstValue("sub"); + var url = S3Service.GetUploadObjectUrl(userId, name); + if (url == null) return BadRequest("Could not create signed url."); + return Ok(url); + } + + + [HttpGet("multipart")] + [Authorize("Pro")] + public async Task MultipartUpload([FromQuery] string name, [FromQuery] int parts, [FromQuery] string uploadId) + { + var userId = this.User.FindFirstValue("sub"); + try + { + var meta = await S3Service.StartMultipartUploadAsync(userId, name, parts, uploadId); + return Ok(meta); + } + catch (Exception ex) { return BadRequest(ex.Message); } + } + + [HttpDelete("multipart")] + [Authorize("Pro")] + public async Task AbortMultipartUpload([FromQuery] string name, [FromQuery] string uploadId) + { + var userId = this.User.FindFirstValue("sub"); + try + { + await S3Service.AbortMultipartUploadAsync(userId, name, uploadId); + return Ok(); + } + catch (Exception ex) { return BadRequest(ex.Message); } + } + + [HttpPost("multipart")] + [Authorize("Pro")] + public async Task CompleteMultipartUpload([FromBody] CompleteMultipartUploadRequest uploadRequest) + { + var userId = this.User.FindFirstValue("sub"); + try + { + await S3Service.CompleteMultipartUploadAsync(userId, uploadRequest); + return Ok(); + } + catch (Exception ex) { return BadRequest(ex.Message); } + } + + [HttpGet] + [Authorize("Sync")] + public IActionResult Download([FromQuery] string name) + { + var userId = this.User.FindFirstValue("sub"); + var url = S3Service.GetDownloadObjectUrl(userId, name); + if (url == null) return BadRequest("Could not create signed url."); + return Ok(url); + } + + [HttpHead] + [Authorize("Sync")] + public async Task Info([FromQuery] string name) + { + var userId = this.User.FindFirstValue("sub"); + var size = await S3Service.GetObjectSizeAsync(userId, name); + HttpContext.Response.Headers.ContentLength = size; + return Ok(); + } + + [HttpDelete] + [Authorize("Sync")] + public async Task DeleteAsync([FromQuery] string name) + { + try + { + var userId = this.User.FindFirstValue("sub"); + await S3Service.DeleteObjectAsync(userId, name); + return Ok(); + } + catch (Exception ex) + { + return BadRequest(ex.Message); + } + } + } +} diff --git a/Notesnook.API/Controllers/UsersController.cs b/Notesnook.API/Controllers/UsersController.cs index a4df0f8..7a3ea74 100644 --- a/Notesnook.API/Controllers/UsersController.cs +++ b/Notesnook.API/Controllers/UsersController.cs @@ -1,116 +1,116 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Security.Claims; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http.Timeouts; -using Microsoft.AspNetCore.Mvc; -using Notesnook.API.Interfaces; -using Notesnook.API.Models; -using Notesnook.API.Models.Responses; -using Streetwriters.Common; - -namespace Notesnook.API.Controllers -{ - [ApiController] - [Authorize] - [Route("users")] - public class UsersController(IUserService UserService) : ControllerBase - { - [HttpPost] - [AllowAnonymous] - public async Task Signup() - { - try - { - await UserService.CreateUserAsync(); - return Ok(); - } - catch (Exception ex) - { - await Slogger.Error(nameof(Signup), "Couldn't sign up.", ex.ToString()); - return BadRequest(new { error = ex.Message }); - } - } - - [HttpGet] - public async Task GetUser() - { - var userId = User.FindFirstValue("sub"); - try - { - UserResponse response = await UserService.GetUserAsync(userId); - if (!response.Success) return BadRequest(response); - return Ok(response); - } - catch (Exception ex) - { - await Slogger.Error(nameof(GetUser), "Couldn't get user for id.", userId, ex.ToString()); - return BadRequest(new { error = ex.Message }); - } - } - - [HttpPatch] - public async Task UpdateUser([FromBody] UserResponse user) - { - var userId = User.FindFirstValue("sub"); - try - { - if (user.AttachmentsKey != null) - await UserService.SetUserAttachmentsKeyAsync(userId, user.AttachmentsKey); - return Ok(); - } - catch (Exception ex) - { - await Slogger.Error(nameof(GetUser), "Couldn't update user with id.", userId, ex.ToString()); - return BadRequest(new { error = ex.Message }); - } - } - - [HttpPost("reset")] - public async Task Reset([FromForm] bool removeAttachments) - { - var userId = this.User.FindFirstValue("sub"); - - if (await UserService.ResetUserAsync(userId, removeAttachments)) - return Ok(); - return BadRequest(); - } - - [HttpPost("delete")] - [RequestTimeout(5 * 60 * 1000)] - public async Task Delete([FromForm] DeleteAccountForm form) - { - var userId = this.User.FindFirstValue("sub"); - var jti = User.FindFirstValue("jti"); - try - { - await UserService.DeleteUserAsync(userId, jti, form.Password); - return Ok(); - } - catch (Exception ex) - { - await Slogger.Error(nameof(GetUser), "Couldn't delete user with id.", userId, ex.ToString()); - return BadRequest(new { error = ex.Message }); - } - } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http.Timeouts; +using Microsoft.AspNetCore.Mvc; +using Notesnook.API.Interfaces; +using Notesnook.API.Models; +using Notesnook.API.Models.Responses; +using Streetwriters.Common; + +namespace Notesnook.API.Controllers +{ + [ApiController] + [Authorize] + [Route("users")] + public class UsersController(IUserService UserService) : ControllerBase + { + [HttpPost] + [AllowAnonymous] + public async Task Signup() + { + try + { + await UserService.CreateUserAsync(); + return Ok(); + } + catch (Exception ex) + { + await Slogger.Error(nameof(Signup), "Couldn't sign up.", ex.ToString()); + return BadRequest(new { error = ex.Message }); + } + } + + [HttpGet] + public async Task GetUser() + { + var userId = User.FindFirstValue("sub"); + try + { + UserResponse response = await UserService.GetUserAsync(userId); + if (!response.Success) return BadRequest(response); + return Ok(response); + } + catch (Exception ex) + { + await Slogger.Error(nameof(GetUser), "Couldn't get user for id.", userId, ex.ToString()); + return BadRequest(new { error = ex.Message }); + } + } + + [HttpPatch] + public async Task UpdateUser([FromBody] UserResponse user) + { + var userId = User.FindFirstValue("sub"); + try + { + if (user.AttachmentsKey != null) + await UserService.SetUserAttachmentsKeyAsync(userId, user.AttachmentsKey); + return Ok(); + } + catch (Exception ex) + { + await Slogger.Error(nameof(GetUser), "Couldn't update user with id.", userId, ex.ToString()); + return BadRequest(new { error = ex.Message }); + } + } + + [HttpPost("reset")] + public async Task Reset([FromForm] bool removeAttachments) + { + var userId = this.User.FindFirstValue("sub"); + + if (await UserService.ResetUserAsync(userId, removeAttachments)) + return Ok(); + return BadRequest(); + } + + [HttpPost("delete")] + [RequestTimeout(5 * 60 * 1000)] + public async Task Delete([FromForm] DeleteAccountForm form) + { + var userId = this.User.FindFirstValue("sub"); + var jti = User.FindFirstValue("jti"); + try + { + await UserService.DeleteUserAsync(userId, jti, form.Password); + return Ok(); + } + catch (Exception ex) + { + await Slogger.Error(nameof(GetUser), "Couldn't delete user with id.", userId, ex.ToString()); + return BadRequest(new { error = ex.Message }); + } + } + } +} diff --git a/Notesnook.API/Dockerfile b/Notesnook.API/Dockerfile index 68fd560..6ac5192 100644 --- a/Notesnook.API/Dockerfile +++ b/Notesnook.API/Dockerfile @@ -1,50 +1,50 @@ -FROM mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine AS base -WORKDIR /app - -FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build -ARG TARGETARCH -ARG BUILDPLATFORM -ENV DOTNET_TC_QuickJitForLoops="1" DOTNET_ReadyToRun="0" DOTNET_TieredPGO="1" DOTNET_SYSTEM_GLOBALIZATION_INVARIANT="true" - -WORKDIR /src - -COPY Streetwriters.Data/*.csproj ./Streetwriters.Data/ -COPY Streetwriters.Common/*.csproj ./Streetwriters.Common/ -COPY Notesnook.API/*.csproj ./Notesnook.API/ - -# restore dependencies -RUN dotnet restore -v d /src/Notesnook.API/Notesnook.API.csproj --use-current-runtime - -COPY Streetwriters.Data/ ./Streetwriters.Data/ -COPY Streetwriters.Common/ ./Streetwriters.Common/ -COPY Notesnook.API/ ./Notesnook.API/ - -WORKDIR /src/Notesnook.API/ - -RUN dotnet build -c Release -o /app/build -a $TARGETARCH - -FROM build AS publish -RUN dotnet publish -c Release -o /app/publish \ - #--runtime alpine-x64 \ - --self-contained true \ - /p:TrimMode=partial \ - /p:PublishTrimmed=true \ - /p:PublishSingleFile=true \ - /p:JsonSerializerIsReflectionEnabledByDefault=true \ - -a $TARGETARCH - -FROM --platform=$BUILDPLATFORM base AS final -ARG TARGETARCH -ARG BUILDPLATFORM - -# create a new user and change directory ownership -RUN adduser --disabled-password \ - --home /app \ - --gecos '' dotnetuser && chown -R dotnetuser /app - -# impersonate into the new user -USER dotnetuser -WORKDIR /app - -COPY --from=publish /app/publish . +FROM mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine AS base +WORKDIR /app + +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build +ARG TARGETARCH +ARG BUILDPLATFORM +ENV DOTNET_TC_QuickJitForLoops="1" DOTNET_ReadyToRun="0" DOTNET_TieredPGO="1" DOTNET_SYSTEM_GLOBALIZATION_INVARIANT="true" + +WORKDIR /src + +COPY Streetwriters.Data/*.csproj ./Streetwriters.Data/ +COPY Streetwriters.Common/*.csproj ./Streetwriters.Common/ +COPY Notesnook.API/*.csproj ./Notesnook.API/ + +# restore dependencies +RUN dotnet restore -v d /src/Notesnook.API/Notesnook.API.csproj --use-current-runtime + +COPY Streetwriters.Data/ ./Streetwriters.Data/ +COPY Streetwriters.Common/ ./Streetwriters.Common/ +COPY Notesnook.API/ ./Notesnook.API/ + +WORKDIR /src/Notesnook.API/ + +RUN dotnet build -c Release -o /app/build -a $TARGETARCH + +FROM build AS publish +RUN dotnet publish -c Release -o /app/publish \ + #--runtime alpine-x64 \ + --self-contained true \ + /p:TrimMode=partial \ + /p:PublishTrimmed=true \ + /p:PublishSingleFile=true \ + /p:JsonSerializerIsReflectionEnabledByDefault=true \ + -a $TARGETARCH + +FROM --platform=$BUILDPLATFORM base AS final +ARG TARGETARCH +ARG BUILDPLATFORM + +# create a new user and change directory ownership +RUN adduser --disabled-password \ + --home /app \ + --gecos '' dotnetuser && chown -R dotnetuser /app + +# impersonate into the new user +USER dotnetuser +WORKDIR /app + +COPY --from=publish /app/publish . ENTRYPOINT ["./Notesnook.API"] \ No newline at end of file diff --git a/Notesnook.API/Extensions/AuthorizationResultTransformer.cs b/Notesnook.API/Extensions/AuthorizationResultTransformer.cs index 90f65bd..d1c1585 100644 --- a/Notesnook.API/Extensions/AuthorizationResultTransformer.cs +++ b/Notesnook.API/Extensions/AuthorizationResultTransformer.cs @@ -1,71 +1,71 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Linq; -using System.Net; -using System.Text.Json; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Authorization.Policy; -using Microsoft.AspNetCore.Http; - -namespace Notesnook.API.Extensions -{ - public class AuthorizationResultTransformer : IAuthorizationMiddlewareResultHandler - { - private readonly IAuthorizationMiddlewareResultHandler _handler; - - public AuthorizationResultTransformer() - { - _handler = new AuthorizationMiddlewareResultHandler(); - } - - public async Task HandleAsync( - RequestDelegate requestDelegate, - HttpContext httpContext, - AuthorizationPolicy authorizationPolicy, - PolicyAuthorizationResult policyAuthorizationResult) - { - var isWebsocket = httpContext.Request.Headers.Upgrade == "websocket"; - - if (!isWebsocket && policyAuthorizationResult.Forbidden && policyAuthorizationResult.AuthorizationFailure != null) - { - var error = string.Join("\n", policyAuthorizationResult.AuthorizationFailure.FailureReasons.Select((r) => r.Message)); - - if (!string.IsNullOrEmpty(error)) - { - httpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized; - httpContext.Response.ContentType = "application/json"; - await httpContext.Response.WriteAsync(JsonSerializer.Serialize(new { error })); - return; - } - - await _handler.HandleAsync(requestDelegate, httpContext, authorizationPolicy, policyAuthorizationResult); - } - else if (isWebsocket) - { - await _handler.HandleAsync(requestDelegate, httpContext, authorizationPolicy, PolicyAuthorizationResult.Success()); - } - else - { - await _handler.HandleAsync(requestDelegate, httpContext, authorizationPolicy, policyAuthorizationResult); - } - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Linq; +using System.Net; +using System.Text.Json; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Authorization.Policy; +using Microsoft.AspNetCore.Http; + +namespace Notesnook.API.Extensions +{ + public class AuthorizationResultTransformer : IAuthorizationMiddlewareResultHandler + { + private readonly IAuthorizationMiddlewareResultHandler _handler; + + public AuthorizationResultTransformer() + { + _handler = new AuthorizationMiddlewareResultHandler(); + } + + public async Task HandleAsync( + RequestDelegate requestDelegate, + HttpContext httpContext, + AuthorizationPolicy authorizationPolicy, + PolicyAuthorizationResult policyAuthorizationResult) + { + var isWebsocket = httpContext.Request.Headers.Upgrade == "websocket"; + + if (!isWebsocket && policyAuthorizationResult.Forbidden && policyAuthorizationResult.AuthorizationFailure != null) + { + var error = string.Join("\n", policyAuthorizationResult.AuthorizationFailure.FailureReasons.Select((r) => r.Message)); + + if (!string.IsNullOrEmpty(error)) + { + httpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized; + httpContext.Response.ContentType = "application/json"; + await httpContext.Response.WriteAsync(JsonSerializer.Serialize(new { error })); + return; + } + + await _handler.HandleAsync(requestDelegate, httpContext, authorizationPolicy, policyAuthorizationResult); + } + else if (isWebsocket) + { + await _handler.HandleAsync(requestDelegate, httpContext, authorizationPolicy, PolicyAuthorizationResult.Success()); + } + else + { + await _handler.HandleAsync(requestDelegate, httpContext, authorizationPolicy, policyAuthorizationResult); + } + } + } } \ No newline at end of file diff --git a/Notesnook.API/Extensions/TransactionHelper.cs b/Notesnook.API/Extensions/TransactionHelper.cs index 23bb049..b39bb43 100644 --- a/Notesnook.API/Extensions/TransactionHelper.cs +++ b/Notesnook.API/Extensions/TransactionHelper.cs @@ -1,44 +1,44 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Threading; -using System; -using System.Threading.Tasks; - -namespace MongoDB.Driver -{ - public static class TransactionHelper - { - public static async Task StartTransaction(this IMongoClient client, Action operate, CancellationToken ct) - { - using (var session = await client.StartSessionAsync()) - { - var transactionOptions = new TransactionOptions(readPreference: ReadPreference.Nearest, readConcern: ReadConcern.Local, writeConcern: WriteConcern.WMajority); - await session.WithTransactionAsync((handle, token) => - { - return Task.Run(() => - { - operate(token); - return true; - }); - }, transactionOptions, ct); - } - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Threading; +using System; +using System.Threading.Tasks; + +namespace MongoDB.Driver +{ + public static class TransactionHelper + { + public static async Task StartTransaction(this IMongoClient client, Action operate, CancellationToken ct) + { + using (var session = await client.StartSessionAsync()) + { + var transactionOptions = new TransactionOptions(readPreference: ReadPreference.Nearest, readConcern: ReadConcern.Local, writeConcern: WriteConcern.WMajority); + await session.WithTransactionAsync((handle, token) => + { + return Task.Run(() => + { + operate(token); + return true; + }); + }, transactionOptions, ct); + } + } + } } \ No newline at end of file diff --git a/Notesnook.API/Interfaces/IEncrypted.cs b/Notesnook.API/Interfaces/IEncrypted.cs index 9c154f1..9100bb2 100644 --- a/Notesnook.API/Interfaces/IEncrypted.cs +++ b/Notesnook.API/Interfaces/IEncrypted.cs @@ -1,29 +1,29 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -namespace Notesnook.API.Interfaces -{ - public interface IEncrypted - { - string Cipher { get; set; } - string IV { get; set; } - long Length { get; set; } - string Salt { get; set; } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +namespace Notesnook.API.Interfaces +{ + public interface IEncrypted + { + string Cipher { get; set; } + string IV { get; set; } + long Length { get; set; } + string Salt { get; set; } + } +} diff --git a/Notesnook.API/Interfaces/IMonograph.cs b/Notesnook.API/Interfaces/IMonograph.cs index 8409d5c..ab36431 100644 --- a/Notesnook.API/Interfaces/IMonograph.cs +++ b/Notesnook.API/Interfaces/IMonograph.cs @@ -1,33 +1,33 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using Notesnook.API.Models; -using Streetwriters.Common.Interfaces; - -namespace Notesnook.API.Interfaces -{ - public interface IMonograph : IDocument - { - string Title { get; set; } - string UserId { get; set; } - byte[] CompressedContent { get; set; } - EncryptedData EncryptedContent { get; set; } - long DatePublished { get; set; } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using Notesnook.API.Models; +using Streetwriters.Common.Interfaces; + +namespace Notesnook.API.Interfaces +{ + public interface IMonograph : IDocument + { + string Title { get; set; } + string UserId { get; set; } + byte[] CompressedContent { get; set; } + EncryptedData EncryptedContent { get; set; } + long DatePublished { get; set; } + } +} diff --git a/Notesnook.API/Interfaces/IS3Service.cs b/Notesnook.API/Interfaces/IS3Service.cs index 2384cfe..509d9c3 100644 --- a/Notesnook.API/Interfaces/IS3Service.cs +++ b/Notesnook.API/Interfaces/IS3Service.cs @@ -1,40 +1,40 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Threading; -using System.Threading.Tasks; -using Amazon.S3.Model; -using Notesnook.API.Models; -using Notesnook.API.Models.Responses; -using Streetwriters.Common.Interfaces; - -namespace Notesnook.API.Interfaces -{ - public interface IS3Service - { - Task DeleteObjectAsync(string userId, string name); - Task DeleteDirectoryAsync(string userId); - Task GetObjectSizeAsync(string userId, string name); - string GetUploadObjectUrl(string userId, string name); - string GetDownloadObjectUrl(string userId, string name); - Task StartMultipartUploadAsync(string userId, string name, int parts, string uploadId = null); - Task AbortMultipartUploadAsync(string userId, string name, string uploadId); - Task CompleteMultipartUploadAsync(string userId, CompleteMultipartUploadRequest uploadRequest); - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Threading; +using System.Threading.Tasks; +using Amazon.S3.Model; +using Notesnook.API.Models; +using Notesnook.API.Models.Responses; +using Streetwriters.Common.Interfaces; + +namespace Notesnook.API.Interfaces +{ + public interface IS3Service + { + Task DeleteObjectAsync(string userId, string name); + Task DeleteDirectoryAsync(string userId); + Task GetObjectSizeAsync(string userId, string name); + string GetUploadObjectUrl(string userId, string name); + string GetDownloadObjectUrl(string userId, string name); + Task StartMultipartUploadAsync(string userId, string name, int parts, string uploadId = null); + Task AbortMultipartUploadAsync(string userId, string name, string uploadId); + Task CompleteMultipartUploadAsync(string userId, CompleteMultipartUploadRequest uploadRequest); + } } \ No newline at end of file diff --git a/Notesnook.API/Interfaces/IUserService.cs b/Notesnook.API/Interfaces/IUserService.cs index 04498f6..8054c37 100644 --- a/Notesnook.API/Interfaces/IUserService.cs +++ b/Notesnook.API/Interfaces/IUserService.cs @@ -1,36 +1,36 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Threading; -using System.Threading.Tasks; -using Notesnook.API.Models.Responses; -using Streetwriters.Common.Interfaces; - -namespace Notesnook.API.Interfaces -{ - public interface IUserService - { - Task CreateUserAsync(); - Task DeleteUserAsync(string userId); - Task DeleteUserAsync(string userId, string jti, string password); - Task ResetUserAsync(string userId, bool removeAttachments); - Task GetUserAsync(string userId); - Task SetUserAttachmentsKeyAsync(string userId, IEncrypted key); - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Threading; +using System.Threading.Tasks; +using Notesnook.API.Models.Responses; +using Streetwriters.Common.Interfaces; + +namespace Notesnook.API.Interfaces +{ + public interface IUserService + { + Task CreateUserAsync(); + Task DeleteUserAsync(string userId); + Task DeleteUserAsync(string userId, string jti, string password); + Task ResetUserAsync(string userId, bool removeAttachments); + Task GetUserAsync(string userId); + Task SetUserAttachmentsKeyAsync(string userId, IEncrypted key); + } } \ No newline at end of file diff --git a/Notesnook.API/Interfaces/IUserSettings.cs b/Notesnook.API/Interfaces/IUserSettings.cs index 6898f2c..1e3c63e 100644 --- a/Notesnook.API/Interfaces/IUserSettings.cs +++ b/Notesnook.API/Interfaces/IUserSettings.cs @@ -1,42 +1,42 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using Notesnook.API.Models; -using Streetwriters.Common.Interfaces; -using Streetwriters.Common.Models; - -namespace Notesnook.API.Interfaces -{ - public interface IUserSettings : IDocument - { - string UserId { get; set; } - - long LastSynced - { - get; set; - } - - EncryptedData VaultKey - { - get; set; - } - - string Salt { get; set; } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using Notesnook.API.Models; +using Streetwriters.Common.Interfaces; +using Streetwriters.Common.Models; + +namespace Notesnook.API.Interfaces +{ + public interface IUserSettings : IDocument + { + string UserId { get; set; } + + long LastSynced + { + get; set; + } + + EncryptedData VaultKey + { + get; set; + } + + string Salt { get; set; } + } +} diff --git a/Notesnook.API/Models/Algorithms.cs b/Notesnook.API/Models/Algorithms.cs index 910ae3c..cea365a 100644 --- a/Notesnook.API/Models/Algorithms.cs +++ b/Notesnook.API/Models/Algorithms.cs @@ -1,26 +1,26 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -namespace Notesnook.API.Models -{ - public class Algorithms - { - public static string Default => "xcha-argon2i13-7"; - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +namespace Notesnook.API.Models +{ + public class Algorithms + { + public static string Default => "xcha-argon2i13-7"; + } } \ No newline at end of file diff --git a/Notesnook.API/Models/Announcement.cs b/Notesnook.API/Models/Announcement.cs index 8917d5c..7a343dd 100644 --- a/Notesnook.API/Models/Announcement.cs +++ b/Notesnook.API/Models/Announcement.cs @@ -1,159 +1,159 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Runtime.Serialization; -using System.Text.Json.Serialization; -using MongoDB.Bson; -using MongoDB.Bson.Serialization.Attributes; - -namespace Notesnook.API.Models -{ - public class Announcement - { - public Announcement() - { - this.Id = ObjectId.GenerateNewId().ToString(); - } - - [BsonId] - [BsonRepresentation(BsonType.ObjectId)] - [BsonElement("id")] - [JsonPropertyName("id")] - public string Id { get; set; } - - [JsonPropertyName("type")] - [BsonElement("type")] - public string Type { get; set; } - - [JsonPropertyName("timestamp")] - [BsonElement("timestamp")] - public long Timestamp { get; set; } - - [JsonPropertyName("platforms")] - [BsonElement("platforms")] - public string[] Platforms { get; set; } - - [JsonPropertyName("isActive")] - [BsonElement("isActive")] - public bool IsActive { get; set; } - - [JsonPropertyName("userTypes")] - [BsonElement("userTypes")] - public string[] UserTypes { get; set; } - - [JsonPropertyName("appVersion")] - [BsonElement("appVersion")] - public int AppVersion { get; set; } - - [JsonPropertyName("body")] - [BsonElement("body")] - public BodyComponent[] Body { get; set; } - - [JsonIgnore] - [BsonElement("userIds")] - public string[] UserIds { get; set; } - - - [Obsolete] - [JsonPropertyName("title")] - [DataMember(Name = "title")] - [BsonElement("title")] - public string Title { get; set; } - - [Obsolete] - [JsonPropertyName("description")] - [BsonElement("description")] - public string Description { get; set; } - - [Obsolete] - [JsonPropertyName("callToActions")] - [BsonElement("callToActions")] - public CallToAction[] CallToActions { get; set; } - } - - public class BodyComponent - { - [JsonPropertyName("type")] - [BsonElement("type")] - public string Type { get; set; } - - [JsonPropertyName("platforms")] - [BsonElement("platforms")] - public string[] Platforms { get; set; } - - [JsonPropertyName("style")] - [BsonElement("style")] - public Style Style { get; set; } - - [JsonPropertyName("src")] - [BsonElement("src")] - public string Src { get; set; } - - [JsonPropertyName("text")] - [BsonElement("text")] - public string Text { get; set; } - - [JsonPropertyName("value")] - [BsonElement("value")] - public string Value { get; set; } - - [JsonPropertyName("items")] - [BsonElement("items")] - public BodyComponent[] Items { get; set; } - - [JsonPropertyName("actions")] - [BsonElement("actions")] - public CallToAction[] Actions { get; set; } - } - - public class Style - { - [JsonPropertyName("marginTop")] - [BsonElement("marginTop")] - public int MarginTop { get; set; } - - [JsonPropertyName("marginBottom")] - [BsonElement("marginBottom")] - public int MarginBottom { get; set; } - - [JsonPropertyName("textAlign")] - [BsonElement("textAlign")] - public string TextAlign { get; set; } - } - - public class CallToAction - { - [JsonPropertyName("type")] - [BsonElement("type")] - public string Type { get; set; } - - [JsonPropertyName("platforms")] - [BsonElement("platforms")] - public string[] Platforms { get; set; } - - [JsonPropertyName("data")] - [BsonElement("data")] - public string Data { get; set; } - - [JsonPropertyName("title")] - [BsonElement("title")] - public string Title { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Runtime.Serialization; +using System.Text.Json.Serialization; +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; + +namespace Notesnook.API.Models +{ + public class Announcement + { + public Announcement() + { + this.Id = ObjectId.GenerateNewId().ToString(); + } + + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + [BsonElement("id")] + [JsonPropertyName("id")] + public string Id { get; set; } + + [JsonPropertyName("type")] + [BsonElement("type")] + public string Type { get; set; } + + [JsonPropertyName("timestamp")] + [BsonElement("timestamp")] + public long Timestamp { get; set; } + + [JsonPropertyName("platforms")] + [BsonElement("platforms")] + public string[] Platforms { get; set; } + + [JsonPropertyName("isActive")] + [BsonElement("isActive")] + public bool IsActive { get; set; } + + [JsonPropertyName("userTypes")] + [BsonElement("userTypes")] + public string[] UserTypes { get; set; } + + [JsonPropertyName("appVersion")] + [BsonElement("appVersion")] + public int AppVersion { get; set; } + + [JsonPropertyName("body")] + [BsonElement("body")] + public BodyComponent[] Body { get; set; } + + [JsonIgnore] + [BsonElement("userIds")] + public string[] UserIds { get; set; } + + + [Obsolete] + [JsonPropertyName("title")] + [DataMember(Name = "title")] + [BsonElement("title")] + public string Title { get; set; } + + [Obsolete] + [JsonPropertyName("description")] + [BsonElement("description")] + public string Description { get; set; } + + [Obsolete] + [JsonPropertyName("callToActions")] + [BsonElement("callToActions")] + public CallToAction[] CallToActions { get; set; } + } + + public class BodyComponent + { + [JsonPropertyName("type")] + [BsonElement("type")] + public string Type { get; set; } + + [JsonPropertyName("platforms")] + [BsonElement("platforms")] + public string[] Platforms { get; set; } + + [JsonPropertyName("style")] + [BsonElement("style")] + public Style Style { get; set; } + + [JsonPropertyName("src")] + [BsonElement("src")] + public string Src { get; set; } + + [JsonPropertyName("text")] + [BsonElement("text")] + public string Text { get; set; } + + [JsonPropertyName("value")] + [BsonElement("value")] + public string Value { get; set; } + + [JsonPropertyName("items")] + [BsonElement("items")] + public BodyComponent[] Items { get; set; } + + [JsonPropertyName("actions")] + [BsonElement("actions")] + public CallToAction[] Actions { get; set; } + } + + public class Style + { + [JsonPropertyName("marginTop")] + [BsonElement("marginTop")] + public int MarginTop { get; set; } + + [JsonPropertyName("marginBottom")] + [BsonElement("marginBottom")] + public int MarginBottom { get; set; } + + [JsonPropertyName("textAlign")] + [BsonElement("textAlign")] + public string TextAlign { get; set; } + } + + public class CallToAction + { + [JsonPropertyName("type")] + [BsonElement("type")] + public string Type { get; set; } + + [JsonPropertyName("platforms")] + [BsonElement("platforms")] + public string[] Platforms { get; set; } + + [JsonPropertyName("data")] + [BsonElement("data")] + public string Data { get; set; } + + [JsonPropertyName("title")] + [BsonElement("title")] + public string Title { get; set; } + } } \ No newline at end of file diff --git a/Notesnook.API/Models/EncryptedData.cs b/Notesnook.API/Models/EncryptedData.cs index 2646ade..64c4f7e 100644 --- a/Notesnook.API/Models/EncryptedData.cs +++ b/Notesnook.API/Models/EncryptedData.cs @@ -1,75 +1,75 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using MongoDB.Bson; -using MongoDB.Bson.Serialization.Attributes; -using Notesnook.API.Interfaces; -using System.Runtime.Serialization; -using System.Text.Json.Serialization; - -namespace Notesnook.API.Models -{ - [MessagePack.MessagePackObject] - public class EncryptedData : IEncrypted - { - [MessagePack.Key("iv")] - [JsonPropertyName("iv")] - [BsonElement("iv")] - [DataMember(Name = "iv")] - public string IV - { - get; set; - } - - [MessagePack.Key("cipher")] - [JsonPropertyName("cipher")] - [BsonElement("cipher")] - [DataMember(Name = "cipher")] - public string Cipher - { - get; set; - } - - [MessagePack.Key("length")] - [JsonPropertyName("length")] - [BsonElement("length")] - [DataMember(Name = "length")] - public long Length { get; set; } - - [MessagePack.Key("salt")] - [JsonPropertyName("salt")] - [BsonElement("salt")] - [DataMember(Name = "salt")] - public string Salt { get; set; } - - public override bool Equals(object obj) - { - if (obj is EncryptedData encryptedData) - { - return IV == encryptedData.IV && Salt == encryptedData.Salt && Cipher == encryptedData.Cipher && Length == encryptedData.Length; - } - return base.Equals(obj); - } - - public bool IsEmpty() - { - return this.Cipher == null && this.IV == null && this.Length == 0 && this.Salt == null; - } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using Notesnook.API.Interfaces; +using System.Runtime.Serialization; +using System.Text.Json.Serialization; + +namespace Notesnook.API.Models +{ + [MessagePack.MessagePackObject] + public class EncryptedData : IEncrypted + { + [MessagePack.Key("iv")] + [JsonPropertyName("iv")] + [BsonElement("iv")] + [DataMember(Name = "iv")] + public string IV + { + get; set; + } + + [MessagePack.Key("cipher")] + [JsonPropertyName("cipher")] + [BsonElement("cipher")] + [DataMember(Name = "cipher")] + public string Cipher + { + get; set; + } + + [MessagePack.Key("length")] + [JsonPropertyName("length")] + [BsonElement("length")] + [DataMember(Name = "length")] + public long Length { get; set; } + + [MessagePack.Key("salt")] + [JsonPropertyName("salt")] + [BsonElement("salt")] + [DataMember(Name = "salt")] + public string Salt { get; set; } + + public override bool Equals(object obj) + { + if (obj is EncryptedData encryptedData) + { + return IV == encryptedData.IV && Salt == encryptedData.Salt && Cipher == encryptedData.Cipher && Length == encryptedData.Length; + } + return base.Equals(obj); + } + + public bool IsEmpty() + { + return this.Cipher == null && this.IV == null && this.Length == 0 && this.Salt == null; + } + } +} diff --git a/Notesnook.API/Models/MultipartUploadMeta.cs b/Notesnook.API/Models/MultipartUploadMeta.cs index ce2a307..01ac2f7 100644 --- a/Notesnook.API/Models/MultipartUploadMeta.cs +++ b/Notesnook.API/Models/MultipartUploadMeta.cs @@ -1,27 +1,27 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -namespace Notesnook.API.Models -{ - public class MultipartUploadMeta - { - public string UploadId { get; set; } - public string[] Parts { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +namespace Notesnook.API.Models +{ + public class MultipartUploadMeta + { + public string UploadId { get; set; } + public string[] Parts { get; set; } + } } \ No newline at end of file diff --git a/Notesnook.API/Models/Responses/SignupResponse.cs b/Notesnook.API/Models/Responses/SignupResponse.cs index f5b01ce..b5991a3 100644 --- a/Notesnook.API/Models/Responses/SignupResponse.cs +++ b/Notesnook.API/Models/Responses/SignupResponse.cs @@ -1,14 +1,14 @@ -using System.Text.Json.Serialization; -using Streetwriters.Common.Models; - -namespace Notesnook.API.Models.Responses -{ - public class SignupResponse : Response - { - [JsonPropertyName("userId")] - public string UserId { get; set; } - - [JsonPropertyName("errors")] - public string[] Errors { get; set; } - } -} +using System.Text.Json.Serialization; +using Streetwriters.Common.Models; + +namespace Notesnook.API.Models.Responses +{ + public class SignupResponse : Response + { + [JsonPropertyName("userId")] + public string UserId { get; set; } + + [JsonPropertyName("errors")] + public string[] Errors { get; set; } + } +} diff --git a/Notesnook.API/Models/Responses/UserResponse.cs b/Notesnook.API/Models/Responses/UserResponse.cs index a2c11a2..65fba30 100644 --- a/Notesnook.API/Models/Responses/UserResponse.cs +++ b/Notesnook.API/Models/Responses/UserResponse.cs @@ -1,25 +1,25 @@ -using System.Text.Json.Serialization; -using Streetwriters.Common.Interfaces; -using Streetwriters.Common.Models; - -namespace Notesnook.API.Models.Responses -{ - public class UserResponse : UserModel, IResponse - { - [JsonPropertyName("salt")] - public string Salt { get; set; } - - [JsonPropertyName("attachmentsKey")] - public EncryptedData AttachmentsKey { get; set; } - - [JsonPropertyName("subscription")] - public ISubscription Subscription { get; set; } - - [JsonPropertyName("profile")] - public EncryptedData Profile { get; set; } - - [JsonIgnore] - public bool Success { get; set; } - public int StatusCode { get; set; } - } -} +using System.Text.Json.Serialization; +using Streetwriters.Common.Interfaces; +using Streetwriters.Common.Models; + +namespace Notesnook.API.Models.Responses +{ + public class UserResponse : UserModel, IResponse + { + [JsonPropertyName("salt")] + public string Salt { get; set; } + + [JsonPropertyName("attachmentsKey")] + public EncryptedData AttachmentsKey { get; set; } + + [JsonPropertyName("subscription")] + public ISubscription Subscription { get; set; } + + [JsonPropertyName("profile")] + public EncryptedData Profile { get; set; } + + [JsonIgnore] + public bool Success { get; set; } + public int StatusCode { get; set; } + } +} diff --git a/Notesnook.API/Models/S3Options.cs b/Notesnook.API/Models/S3Options.cs index 238db23..791b7ef 100644 --- a/Notesnook.API/Models/S3Options.cs +++ b/Notesnook.API/Models/S3Options.cs @@ -1,29 +1,29 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -namespace Notesnook.API.Models -{ - public class S3Options - { - public string ServiceUrl { get; set; } - public string Region { get; set; } - public string AccessKeyId { get; set; } - public string SecretAccessKey { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +namespace Notesnook.API.Models +{ + public class S3Options + { + public string ServiceUrl { get; set; } + public string Region { get; set; } + public string AccessKeyId { get; set; } + public string SecretAccessKey { get; set; } + } } \ No newline at end of file diff --git a/Notesnook.API/Models/UserSettings.cs b/Notesnook.API/Models/UserSettings.cs index 885ec93..d98460a 100644 --- a/Notesnook.API/Models/UserSettings.cs +++ b/Notesnook.API/Models/UserSettings.cs @@ -1,42 +1,42 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using MongoDB.Bson; -using MongoDB.Bson.Serialization.Attributes; -using Notesnook.API.Interfaces; - -namespace Notesnook.API.Models -{ - public class UserSettings : IUserSettings - { - public UserSettings() - { - this.Id = ObjectId.GenerateNewId().ToString(); - } - public string UserId { get; set; } - public long LastSynced { get; set; } - public string Salt { get; set; } - public EncryptedData VaultKey { get; set; } - public EncryptedData AttachmentsKey { get; set; } - - [BsonId] - [BsonRepresentation(BsonType.ObjectId)] - public string Id { get; set; } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using Notesnook.API.Interfaces; + +namespace Notesnook.API.Models +{ + public class UserSettings : IUserSettings + { + public UserSettings() + { + this.Id = ObjectId.GenerateNewId().ToString(); + } + public string UserId { get; set; } + public long LastSynced { get; set; } + public string Salt { get; set; } + public EncryptedData VaultKey { get; set; } + public EncryptedData AttachmentsKey { get; set; } + + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + public string Id { get; set; } + } +} diff --git a/Notesnook.API/appsettings.Development.json b/Notesnook.API/appsettings.Development.json index 5468961..9cfe28c 100644 --- a/Notesnook.API/appsettings.Development.json +++ b/Notesnook.API/appsettings.Development.json @@ -1,15 +1,15 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information", - "Microsoft.AspNetCore.SignalR": "Trace", - "Microsoft.AspNetCore.Http.Connections": "Trace" - } - }, - "MongoDbSettings": { - "ConnectionString": "mongodb://localhost:27017/notesnook", - "DatabaseName": "notesnook" - } -} +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information", + "Microsoft.AspNetCore.SignalR": "Trace", + "Microsoft.AspNetCore.Http.Connections": "Trace" + } + }, + "MongoDbSettings": { + "ConnectionString": "mongodb://localhost:27017/notesnook", + "DatabaseName": "notesnook" + } +} diff --git a/Notesnook.API/appsettings.json b/Notesnook.API/appsettings.json index 6cf0b42..0804371 100644 --- a/Notesnook.API/appsettings.json +++ b/Notesnook.API/appsettings.json @@ -1,7 +1,7 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Warning" - } - } -} +{ + "Logging": { + "LogLevel": { + "Default": "Warning" + } + } +} diff --git a/Streetwriters.Common/Attributes/JsonInterfaceConverterAttribute.cs b/Streetwriters.Common/Attributes/JsonInterfaceConverterAttribute.cs index 122c44e..3a7da81 100644 --- a/Streetwriters.Common/Attributes/JsonInterfaceConverterAttribute.cs +++ b/Streetwriters.Common/Attributes/JsonInterfaceConverterAttribute.cs @@ -1,33 +1,33 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Text.Json.Serialization; - -namespace Streetwriters.Common.Attributes -{ - [AttributeUsage(AttributeTargets.Interface, AllowMultiple = false)] - public class JsonInterfaceConverterAttribute : JsonConverterAttribute - { - public JsonInterfaceConverterAttribute(Type converterType) - : base(converterType) - { - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Text.Json.Serialization; + +namespace Streetwriters.Common.Attributes +{ + [AttributeUsage(AttributeTargets.Interface, AllowMultiple = false)] + public class JsonInterfaceConverterAttribute : JsonConverterAttribute + { + public JsonInterfaceConverterAttribute(Type converterType) + : base(converterType) + { + } + } } \ No newline at end of file diff --git a/Streetwriters.Common/Clients.cs b/Streetwriters.Common/Clients.cs index 7b5049d..94a1896 100644 --- a/Streetwriters.Common/Clients.cs +++ b/Streetwriters.Common/Clients.cs @@ -1,82 +1,82 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Collections.Generic; -using System.Linq; -using Streetwriters.Common.Enums; -using Streetwriters.Common.Interfaces; -using Streetwriters.Common.Messages; -using Streetwriters.Common.Models; - -namespace Streetwriters.Common -{ - public class Clients - { - public static readonly Client Notesnook = new() - { - Id = "notesnook", - Name = "Notesnook", - SenderEmail = Constants.NOTESNOOK_SENDER_EMAIL, - SenderName = "Notesnook", - Type = ApplicationType.NOTESNOOK, - AppId = ApplicationType.NOTESNOOK, - AccountRecoveryRedirectURL = $"{Constants.NOTESNOOK_APP_HOST}/account/recovery", - EmailConfirmedRedirectURL = $"{Constants.NOTESNOOK_APP_HOST}/account/verified", - OnEmailConfirmed = async (userId) => - { - await WampServers.MessengerServer.PublishMessageAsync(MessengerServerTopics.SendSSETopic, new SendSSEMessage - { - UserId = userId, - Message = new Message - { - Type = "emailConfirmed", - Data = null - } - }); - } - }; - - public static Dictionary ClientsMap = new() - { - { "notesnook", Notesnook } - }; - - public static Client FindClientById(string id) - { - if (!IsValidClient(id)) return null; - return ClientsMap[id]; - } - - public static Client FindClientByAppId(ApplicationType appId) - { - switch (appId) - { - case ApplicationType.NOTESNOOK: - return ClientsMap["notesnook"]; - } - return null; - } - - public static bool IsValidClient(string id) - { - return ClientsMap.ContainsKey(id); - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using Streetwriters.Common.Enums; +using Streetwriters.Common.Interfaces; +using Streetwriters.Common.Messages; +using Streetwriters.Common.Models; + +namespace Streetwriters.Common +{ + public class Clients + { + public static readonly Client Notesnook = new() + { + Id = "notesnook", + Name = "Notesnook", + SenderEmail = Constants.NOTESNOOK_SENDER_EMAIL, + SenderName = "Notesnook", + Type = ApplicationType.NOTESNOOK, + AppId = ApplicationType.NOTESNOOK, + AccountRecoveryRedirectURL = $"{Constants.NOTESNOOK_APP_HOST}/account/recovery", + EmailConfirmedRedirectURL = $"{Constants.NOTESNOOK_APP_HOST}/account/verified", + OnEmailConfirmed = async (userId) => + { + await WampServers.MessengerServer.PublishMessageAsync(MessengerServerTopics.SendSSETopic, new SendSSEMessage + { + UserId = userId, + Message = new Message + { + Type = "emailConfirmed", + Data = null + } + }); + } + }; + + public static Dictionary ClientsMap = new() + { + { "notesnook", Notesnook } + }; + + public static Client FindClientById(string id) + { + if (!IsValidClient(id)) return null; + return ClientsMap[id]; + } + + public static Client FindClientByAppId(ApplicationType appId) + { + switch (appId) + { + case ApplicationType.NOTESNOOK: + return ClientsMap["notesnook"]; + } + return null; + } + + public static bool IsValidClient(string id) + { + return ClientsMap.ContainsKey(id); + } + } } \ No newline at end of file diff --git a/Streetwriters.Common/Converters/InterfaceConverter.cs b/Streetwriters.Common/Converters/InterfaceConverter.cs index 788fe34..00ee621 100644 --- a/Streetwriters.Common/Converters/InterfaceConverter.cs +++ b/Streetwriters.Common/Converters/InterfaceConverter.cs @@ -1,54 +1,54 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace Streetwriters.Common.Converters -{ - /// - /// Converts simple interface into an object (assumes that there is only one class of TInterface) - /// - /// Interface type - /// Class type - public class InterfaceConverter : JsonConverter where TClass : TInterface - { - public override TInterface Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - return JsonSerializer.Deserialize(ref reader, options); - } - - public override void Write(Utf8JsonWriter writer, TInterface value, JsonSerializerOptions options) - { - switch (value) - { - case null: - JsonSerializer.Serialize(writer, null, options); - break; - default: - { - var type = value.GetType(); - JsonSerializer.Serialize(writer, value, type, options); - break; - } - } - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Streetwriters.Common.Converters +{ + /// + /// Converts simple interface into an object (assumes that there is only one class of TInterface) + /// + /// Interface type + /// Class type + public class InterfaceConverter : JsonConverter where TClass : TInterface + { + public override TInterface Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return JsonSerializer.Deserialize(ref reader, options); + } + + public override void Write(Utf8JsonWriter writer, TInterface value, JsonSerializerOptions options) + { + switch (value) + { + case null: + JsonSerializer.Serialize(writer, null, options); + break; + default: + { + var type = value.GetType(); + JsonSerializer.Serialize(writer, value, type, options); + break; + } + } + } + } } \ No newline at end of file diff --git a/Streetwriters.Common/Enums/ApplicationType.cs b/Streetwriters.Common/Enums/ApplicationType.cs index ad90d4e..12c8036 100644 --- a/Streetwriters.Common/Enums/ApplicationType.cs +++ b/Streetwriters.Common/Enums/ApplicationType.cs @@ -1,26 +1,26 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -namespace Streetwriters.Common.Enums -{ - public enum ApplicationType - { - NOTESNOOK = 0 - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +namespace Streetwriters.Common.Enums +{ + public enum ApplicationType + { + NOTESNOOK = 0 + } } \ No newline at end of file diff --git a/Streetwriters.Common/Enums/MFAMethods.cs b/Streetwriters.Common/Enums/MFAMethods.cs index 1ee767a..9e07b69 100644 --- a/Streetwriters.Common/Enums/MFAMethods.cs +++ b/Streetwriters.Common/Enums/MFAMethods.cs @@ -1,29 +1,29 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -namespace Streetwriters.Common.Enums -{ - public class MFAMethods - { - public static string Email => "email"; - public static string SMS => "sms"; - public static string App => "app"; - public static string RecoveryCode => "recoveryCode"; - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +namespace Streetwriters.Common.Enums +{ + public class MFAMethods + { + public static string Email => "email"; + public static string SMS => "sms"; + public static string App => "app"; + public static string RecoveryCode => "recoveryCode"; + } } \ No newline at end of file diff --git a/Streetwriters.Common/Enums/SubscriptionType.cs b/Streetwriters.Common/Enums/SubscriptionType.cs index 09e13fa..b194c2c 100644 --- a/Streetwriters.Common/Enums/SubscriptionType.cs +++ b/Streetwriters.Common/Enums/SubscriptionType.cs @@ -1,32 +1,32 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -namespace Streetwriters.Common.Enums -{ - public enum SubscriptionType - { - BASIC = 0, - TRIAL = 1, - BETA = 2, - PREMIUM = 5, - PREMIUM_EXPIRED = 6, - PREMIUM_CANCELED = 7, - PREMIUM_PAUSED = 8 - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +namespace Streetwriters.Common.Enums +{ + public enum SubscriptionType + { + BASIC = 0, + TRIAL = 1, + BETA = 2, + PREMIUM = 5, + PREMIUM_EXPIRED = 6, + PREMIUM_CANCELED = 7, + PREMIUM_PAUSED = 8 + } } \ No newline at end of file diff --git a/Streetwriters.Common/Extensions/AppBuilderExtensions.cs b/Streetwriters.Common/Extensions/AppBuilderExtensions.cs index 0c159bb..b562978 100644 --- a/Streetwriters.Common/Extensions/AppBuilderExtensions.cs +++ b/Streetwriters.Common/Extensions/AppBuilderExtensions.cs @@ -1,86 +1,86 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Collections.Generic; -using System.Text.Json; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.DependencyInjection; -using WampSharp.AspNetCore.WebSockets.Server; -using WampSharp.Binding; -using WampSharp.V2; -using WampSharp.V2.Realm; - -namespace Streetwriters.Common.Extensions -{ - public static class AppBuilderExtensions - { - public static IApplicationBuilder UseVersion(this IApplicationBuilder app, Server server) - { - app.Map("/version", (app) => - { - app.Run(async context => - { - context.Response.ContentType = "application/json"; - var data = new Dictionary - { - { "version", Constants.COMPATIBILITY_VERSION }, - { "id", server.Id }, - { "instance", Constants.INSTANCE_NAME } - }; - await context.Response.WriteAsync(JsonSerializer.Serialize(data)); - }); - }); - return app; - } - - public static IApplicationBuilder UseWamp(this IApplicationBuilder app, WampServer server, Action> action) where T : new() - { - WampHost host = new WampHost(); - - app.Map(server.Endpoint, builder => - { - builder.UseWebSockets(); - host.RegisterTransport(new AspNetCoreWebSocketTransport(builder), - new JTokenJsonBinding(), - new JTokenMsgpackBinding()); - }); - - host.Open(); - - action.Invoke(host.RealmContainer.GetRealmByName(server.Realm), server); - - return app; - } - - public static T GetService(this IApplicationBuilder app) - { - return app.ApplicationServices.GetRequiredService(); - } - - public static T GetScopedService(this IApplicationBuilder app) - { - using (var scope = app.ApplicationServices.CreateScope()) - { - return scope.ServiceProvider.GetRequiredService(); - } - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Collections.Generic; +using System.Text.Json; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using WampSharp.AspNetCore.WebSockets.Server; +using WampSharp.Binding; +using WampSharp.V2; +using WampSharp.V2.Realm; + +namespace Streetwriters.Common.Extensions +{ + public static class AppBuilderExtensions + { + public static IApplicationBuilder UseVersion(this IApplicationBuilder app, Server server) + { + app.Map("/version", (app) => + { + app.Run(async context => + { + context.Response.ContentType = "application/json"; + var data = new Dictionary + { + { "version", Constants.COMPATIBILITY_VERSION }, + { "id", server.Id }, + { "instance", Constants.INSTANCE_NAME } + }; + await context.Response.WriteAsync(JsonSerializer.Serialize(data)); + }); + }); + return app; + } + + public static IApplicationBuilder UseWamp(this IApplicationBuilder app, WampServer server, Action> action) where T : new() + { + WampHost host = new WampHost(); + + app.Map(server.Endpoint, builder => + { + builder.UseWebSockets(); + host.RegisterTransport(new AspNetCoreWebSocketTransport(builder), + new JTokenJsonBinding(), + new JTokenMsgpackBinding()); + }); + + host.Open(); + + action.Invoke(host.RealmContainer.GetRealmByName(server.Realm), server); + + return app; + } + + public static T GetService(this IApplicationBuilder app) + { + return app.ApplicationServices.GetRequiredService(); + } + + public static T GetScopedService(this IApplicationBuilder app) + { + using (var scope = app.ApplicationServices.CreateScope()) + { + return scope.ServiceProvider.GetRequiredService(); + } + } + } } \ No newline at end of file diff --git a/Streetwriters.Common/Extensions/HttpClientExtensions.cs b/Streetwriters.Common/Extensions/HttpClientExtensions.cs index a627ffd..4a8c320 100644 --- a/Streetwriters.Common/Extensions/HttpClientExtensions.cs +++ b/Streetwriters.Common/Extensions/HttpClientExtensions.cs @@ -1,72 +1,72 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Linq; -using System.Net.Http; -using System.Net.Http.Json; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Streetwriters.Common.Interfaces; - -namespace Streetwriters.Common.Extensions -{ - public static class HttpClientExtensions - { - public static async Task SendRequestAsync(this HttpClient httpClient, string url, IHeaderDictionary headers, HttpMethod method, HttpContent content = null) where T : IResponse, new() - { - var request = new HttpRequestMessage(method, url); - - if (method != HttpMethod.Get && method != HttpMethod.Delete) - { - request.Content = content; - } - - foreach (var header in headers) - { - if (header.Key == "Content-Type" || header.Key == "Content-Length") - { - if (request.Content != null) - request.Content.Headers.TryAddWithoutValidation(header.Key, header.Value.AsEnumerable()); - continue; - } - request.Headers.TryAddWithoutValidation(header.Key, header.Value.AsEnumerable()); - } - - var response = await httpClient.SendAsync(request); - if (response.Content.Headers.ContentLength > 0) - { - var res = await response.Content.ReadFromJsonAsync(); - res.Success = response.IsSuccessStatusCode; - res.StatusCode = (int)response.StatusCode; - return res; - } - else - { - return new T { Success = response.IsSuccessStatusCode, StatusCode = (int)response.StatusCode }; - } - } - - public static Task ForwardAsync(this HttpClient httpClient, IHttpContextAccessor accessor, string url, HttpMethod method) where T : IResponse, new() - { - var httpContext = accessor.HttpContext; - var content = new StreamContent(httpContext.Request.BodyReader.AsStream()); - return httpClient.SendRequestAsync(url, httpContext.Request.Headers, method, content); - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Linq; +using System.Net.Http; +using System.Net.Http.Json; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Streetwriters.Common.Interfaces; + +namespace Streetwriters.Common.Extensions +{ + public static class HttpClientExtensions + { + public static async Task SendRequestAsync(this HttpClient httpClient, string url, IHeaderDictionary headers, HttpMethod method, HttpContent content = null) where T : IResponse, new() + { + var request = new HttpRequestMessage(method, url); + + if (method != HttpMethod.Get && method != HttpMethod.Delete) + { + request.Content = content; + } + + foreach (var header in headers) + { + if (header.Key == "Content-Type" || header.Key == "Content-Length") + { + if (request.Content != null) + request.Content.Headers.TryAddWithoutValidation(header.Key, header.Value.AsEnumerable()); + continue; + } + request.Headers.TryAddWithoutValidation(header.Key, header.Value.AsEnumerable()); + } + + var response = await httpClient.SendAsync(request); + if (response.Content.Headers.ContentLength > 0) + { + var res = await response.Content.ReadFromJsonAsync(); + res.Success = response.IsSuccessStatusCode; + res.StatusCode = (int)response.StatusCode; + return res; + } + else + { + return new T { Success = response.IsSuccessStatusCode, StatusCode = (int)response.StatusCode }; + } + } + + public static Task ForwardAsync(this HttpClient httpClient, IHttpContextAccessor accessor, string url, HttpMethod method) where T : IResponse, new() + { + var httpContext = accessor.HttpContext; + var content = new StreamContent(httpContext.Request.BodyReader.AsStream()); + return httpClient.SendRequestAsync(url, httpContext.Request.Headers, method, content); + } + } } \ No newline at end of file diff --git a/Streetwriters.Common/Extensions/ServiceCollectionServiceExtensions.cs b/Streetwriters.Common/Extensions/ServiceCollectionServiceExtensions.cs index 82b8741..a47390a 100644 --- a/Streetwriters.Common/Extensions/ServiceCollectionServiceExtensions.cs +++ b/Streetwriters.Common/Extensions/ServiceCollectionServiceExtensions.cs @@ -1,53 +1,53 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using Microsoft.Extensions.DependencyInjection; -using Streetwriters.Data.DbContexts; -using Streetwriters.Data.Repositories; - -namespace Streetwriters.Common.Extensions -{ - public static class ServiceCollectionServiceExtensions - { - public static IServiceCollection AddRepository(this IServiceCollection services, string collectionName, string database) where T : class - { - services.AddSingleton((provider) => MongoDbContext.GetMongoCollection(provider.GetService(), database, collectionName)); - services.AddScoped>(); - return services; - } - - public static IServiceCollection AddDefaultCors(this IServiceCollection services) - { - services.AddCors(options => - { - options.AddPolicy("notesnook", (b) => - { - if (Constants.NOTESNOOK_CORS_ORIGINS.Length <= 0) - b.AllowAnyOrigin(); - else - b.WithOrigins(Constants.NOTESNOOK_CORS_ORIGINS); - - b.AllowAnyMethod() - .AllowAnyHeader(); - }); - }); - return services; - } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using Microsoft.Extensions.DependencyInjection; +using Streetwriters.Data.DbContexts; +using Streetwriters.Data.Repositories; + +namespace Streetwriters.Common.Extensions +{ + public static class ServiceCollectionServiceExtensions + { + public static IServiceCollection AddRepository(this IServiceCollection services, string collectionName, string database) where T : class + { + services.AddSingleton((provider) => MongoDbContext.GetMongoCollection(provider.GetService(), database, collectionName)); + services.AddScoped>(); + return services; + } + + public static IServiceCollection AddDefaultCors(this IServiceCollection services) + { + services.AddCors(options => + { + options.AddPolicy("notesnook", (b) => + { + if (Constants.NOTESNOOK_CORS_ORIGINS.Length <= 0) + b.AllowAnyOrigin(); + else + b.WithOrigins(Constants.NOTESNOOK_CORS_ORIGINS); + + b.AllowAnyMethod() + .AllowAnyHeader(); + }); + }); + return services; + } + } +} diff --git a/Streetwriters.Common/Extensions/StringExtensions.cs b/Streetwriters.Common/Extensions/StringExtensions.cs index 28b0f17..1821131 100644 --- a/Streetwriters.Common/Extensions/StringExtensions.cs +++ b/Streetwriters.Common/Extensions/StringExtensions.cs @@ -1,87 +1,87 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.IO; -using System.IO.Compression; -using System.Security.Cryptography; -using System.Text; - -namespace System -{ - public static class StringExtensions - { - public static string Sha256(this string input) - { - var bytes = Encoding.UTF8.GetBytes(input); - var hash = SHA256.HashData(bytes); - return Convert.ToBase64String(hash); - } - - public static byte[] CompressBrotli(this string input) - { - var raw = Encoding.Default.GetBytes(input); - using (MemoryStream memory = new MemoryStream()) - { - using (BrotliStream brotli = new BrotliStream(memory, CompressionLevel.Optimal)) - { - brotli.Write(raw, 0, raw.Length); - } - return memory.ToArray(); - } - } - - public static string DecompressBrotli(this byte[] compressed) - { - using (BrotliStream stream = new BrotliStream(new MemoryStream(compressed), CompressionMode.Decompress)) - { - const int size = 4096; - byte[] buffer = new byte[size]; - using (MemoryStream memory = new MemoryStream()) - { - int count = 0; - do - { - count = stream.Read(buffer, 0, size); - if (count > 0) - { - memory.Write(buffer, 0, count); - } - } - while (count > 0); - return Encoding.Default.GetString(memory.ToArray()); - } - } - } - - private static string ToHex(byte[] bytes, int startIndex, int length) - { - char[] c = new char[length * 2]; - byte b; - for (int bx = startIndex, cx = startIndex; bx < length; ++bx, ++cx) - { - b = ((byte)(bytes[bx] >> 4)); - c[cx] = (char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30); - - b = ((byte)(bytes[bx] & 0x0F)); - c[++cx] = (char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30); - } - return new string(c); - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.IO; +using System.IO.Compression; +using System.Security.Cryptography; +using System.Text; + +namespace System +{ + public static class StringExtensions + { + public static string Sha256(this string input) + { + var bytes = Encoding.UTF8.GetBytes(input); + var hash = SHA256.HashData(bytes); + return Convert.ToBase64String(hash); + } + + public static byte[] CompressBrotli(this string input) + { + var raw = Encoding.Default.GetBytes(input); + using (MemoryStream memory = new MemoryStream()) + { + using (BrotliStream brotli = new BrotliStream(memory, CompressionLevel.Optimal)) + { + brotli.Write(raw, 0, raw.Length); + } + return memory.ToArray(); + } + } + + public static string DecompressBrotli(this byte[] compressed) + { + using (BrotliStream stream = new BrotliStream(new MemoryStream(compressed), CompressionMode.Decompress)) + { + const int size = 4096; + byte[] buffer = new byte[size]; + using (MemoryStream memory = new MemoryStream()) + { + int count = 0; + do + { + count = stream.Read(buffer, 0, size); + if (count > 0) + { + memory.Write(buffer, 0, count); + } + } + while (count > 0); + return Encoding.Default.GetString(memory.ToArray()); + } + } + } + + private static string ToHex(byte[] bytes, int startIndex, int length) + { + char[] c = new char[length * 2]; + byte b; + for (int bx = startIndex, cx = startIndex; bx < length; ++bx, ++cx) + { + b = ((byte)(bytes[bx] >> 4)); + c[cx] = (char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30); + + b = ((byte)(bytes[bx] & 0x0F)); + c[++cx] = (char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30); + } + return new string(c); + } + } } \ No newline at end of file diff --git a/Streetwriters.Common/Extensions/WampRealmExtensions.cs b/Streetwriters.Common/Extensions/WampRealmExtensions.cs index 24b4f05..4b86694 100644 --- a/Streetwriters.Common/Extensions/WampRealmExtensions.cs +++ b/Streetwriters.Common/Extensions/WampRealmExtensions.cs @@ -1,42 +1,42 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using Microsoft.AspNetCore.Builder; -using Streetwriters.Common.Interfaces; -using WampSharp.AspNetCore.WebSockets.Server; -using WampSharp.Binding; -using WampSharp.V2; -using WampSharp.V2.Realm; - -namespace Streetwriters.Common.Extensions -{ - public static class WampRealmExtensions - { - public static IDisposable Subscribe(this IWampHostedRealm realm, string topicName, Action onNext) - { - return realm.Services.GetSubject(topicName).Subscribe(onNext); - } - - public static IDisposable Subscribe(this IWampHostedRealm realm, string topicName, IMessageHandler handler) - { - return realm.Services.GetSubject(topicName).Subscribe(async (message) => await handler.Process(message)); - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using Microsoft.AspNetCore.Builder; +using Streetwriters.Common.Interfaces; +using WampSharp.AspNetCore.WebSockets.Server; +using WampSharp.Binding; +using WampSharp.V2; +using WampSharp.V2.Realm; + +namespace Streetwriters.Common.Extensions +{ + public static class WampRealmExtensions + { + public static IDisposable Subscribe(this IWampHostedRealm realm, string topicName, Action onNext) + { + return realm.Services.GetSubject(topicName).Subscribe(onNext); + } + + public static IDisposable Subscribe(this IWampHostedRealm realm, string topicName, IMessageHandler handler) + { + return realm.Services.GetSubject(topicName).Subscribe(async (message) => await handler.Process(message)); + } + } } \ No newline at end of file diff --git a/Streetwriters.Common/Helpers/WampHelper.cs b/Streetwriters.Common/Helpers/WampHelper.cs index be0ec80..4d01fa0 100644 --- a/Streetwriters.Common/Helpers/WampHelper.cs +++ b/Streetwriters.Common/Helpers/WampHelper.cs @@ -1,47 +1,47 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Reactive.Subjects; -using System.Threading.Tasks; -using Streetwriters.Common.Messages; -using WampSharp.V2; -using WampSharp.V2.Client; - -namespace Streetwriters.Common.Helpers -{ - public class WampHelper - { - public static async Task OpenWampChannelAsync(string server, string realmName) - { - DefaultWampChannelFactory channelFactory = new(); - - IWampChannel channel = channelFactory.CreateJsonChannel(server, realmName); - - await channel.Open(); - - return channel.RealmProxy; - } - - public static void PublishMessage(IWampRealmProxy realm, string topicName, T message) - { - var subject = realm.Services.GetSubject(topicName); - subject.OnNext(message); - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Reactive.Subjects; +using System.Threading.Tasks; +using Streetwriters.Common.Messages; +using WampSharp.V2; +using WampSharp.V2.Client; + +namespace Streetwriters.Common.Helpers +{ + public class WampHelper + { + public static async Task OpenWampChannelAsync(string server, string realmName) + { + DefaultWampChannelFactory channelFactory = new(); + + IWampChannel channel = channelFactory.CreateJsonChannel(server, realmName); + + await channel.Open(); + + return channel.RealmProxy; + } + + public static void PublishMessage(IWampRealmProxy realm, string topicName, T message) + { + var subject = realm.Services.GetSubject(topicName); + subject.OnNext(message); + } + } } \ No newline at end of file diff --git a/Streetwriters.Common/Interfaces/IClient.cs b/Streetwriters.Common/Interfaces/IClient.cs index e2f14c3..f5cfade 100644 --- a/Streetwriters.Common/Interfaces/IClient.cs +++ b/Streetwriters.Common/Interfaces/IClient.cs @@ -1,38 +1,38 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Threading.Tasks; -using Streetwriters.Common.Enums; - -namespace Streetwriters.Common.Interfaces -{ - public interface IClient - { - string Id { get; set; } - string Name { get; set; } - ApplicationType Type { get; set; } - ApplicationType AppId { get; set; } - string SenderEmail { get; set; } - string SenderName { get; set; } - string EmailConfirmedRedirectURL { get; } - string AccountRecoveryRedirectURL { get; } - Func OnEmailConfirmed { get; set; } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Threading.Tasks; +using Streetwriters.Common.Enums; + +namespace Streetwriters.Common.Interfaces +{ + public interface IClient + { + string Id { get; set; } + string Name { get; set; } + ApplicationType Type { get; set; } + ApplicationType AppId { get; set; } + string SenderEmail { get; set; } + string SenderName { get; set; } + string EmailConfirmedRedirectURL { get; } + string AccountRecoveryRedirectURL { get; } + Func OnEmailConfirmed { get; set; } + } +} diff --git a/Streetwriters.Common/Interfaces/IDocument.cs b/Streetwriters.Common/Interfaces/IDocument.cs index 50dd009..9773212 100644 --- a/Streetwriters.Common/Interfaces/IDocument.cs +++ b/Streetwriters.Common/Interfaces/IDocument.cs @@ -1,29 +1,29 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -namespace Streetwriters.Common.Interfaces -{ - public interface IDocument - { - string Id - { - get; set; - } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +namespace Streetwriters.Common.Interfaces +{ + public interface IDocument + { + string Id + { + get; set; + } + } +} diff --git a/Streetwriters.Common/Interfaces/IMessageHandler.cs b/Streetwriters.Common/Interfaces/IMessageHandler.cs index b0d83e5..b5268c5 100644 --- a/Streetwriters.Common/Interfaces/IMessageHandler.cs +++ b/Streetwriters.Common/Interfaces/IMessageHandler.cs @@ -1,29 +1,29 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Threading.Tasks; -using Streetwriters.Common.Interfaces; - -namespace Streetwriters.Common.Interfaces -{ - public interface IMessageHandler - { - Task Process(T message); - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Threading.Tasks; +using Streetwriters.Common.Interfaces; + +namespace Streetwriters.Common.Interfaces +{ + public interface IMessageHandler + { + Task Process(T message); + } } \ No newline at end of file diff --git a/Streetwriters.Common/Interfaces/IOffer.cs b/Streetwriters.Common/Interfaces/IOffer.cs index c4e733b..a43a301 100644 --- a/Streetwriters.Common/Interfaces/IOffer.cs +++ b/Streetwriters.Common/Interfaces/IOffer.cs @@ -1,32 +1,32 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Collections.Generic; -using Streetwriters.Common.Enums; -using Streetwriters.Common.Models; - -namespace Streetwriters.Common.Interfaces -{ - public interface IOffer : IDocument - { - ApplicationType AppId { get; set; } - string PromoCode { get; set; } - PromoCode[] Codes { get; set; } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Collections.Generic; +using Streetwriters.Common.Enums; +using Streetwriters.Common.Models; + +namespace Streetwriters.Common.Interfaces +{ + public interface IOffer : IDocument + { + ApplicationType AppId { get; set; } + string PromoCode { get; set; } + PromoCode[] Codes { get; set; } + } +} diff --git a/Streetwriters.Common/Interfaces/IResponse.cs b/Streetwriters.Common/Interfaces/IResponse.cs index 1f9c547..adb3006 100644 --- a/Streetwriters.Common/Interfaces/IResponse.cs +++ b/Streetwriters.Common/Interfaces/IResponse.cs @@ -1,27 +1,27 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -namespace Streetwriters.Common.Interfaces -{ - public interface IResponse - { - bool Success { get; set; } - int StatusCode { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +namespace Streetwriters.Common.Interfaces +{ + public interface IResponse + { + bool Success { get; set; } + int StatusCode { get; set; } + } } \ No newline at end of file diff --git a/Streetwriters.Common/Interfaces/ISubscription.cs b/Streetwriters.Common/Interfaces/ISubscription.cs index fd2d1a4..e56472a 100644 --- a/Streetwriters.Common/Interfaces/ISubscription.cs +++ b/Streetwriters.Common/Interfaces/ISubscription.cs @@ -1,41 +1,41 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.ComponentModel.DataAnnotations; -using System.Runtime.Serialization; -using Streetwriters.Common.Attributes; -using Streetwriters.Common.Converters; -using Streetwriters.Common.Enums; -using Streetwriters.Common.Models; - -namespace Streetwriters.Common.Interfaces -{ - [JsonInterfaceConverter(typeof(InterfaceConverter))] - public interface ISubscription : IDocument - { - string UserId { get; set; } - ApplicationType AppId { get; set; } - SubscriptionProvider Provider { get; set; } - long StartDate { get; set; } - long ExpiryDate { get; set; } - SubscriptionType Type { get; set; } - string OrderId { get; set; } - string SubscriptionId { get; set; } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; +using Streetwriters.Common.Attributes; +using Streetwriters.Common.Converters; +using Streetwriters.Common.Enums; +using Streetwriters.Common.Models; + +namespace Streetwriters.Common.Interfaces +{ + [JsonInterfaceConverter(typeof(InterfaceConverter))] + public interface ISubscription : IDocument + { + string UserId { get; set; } + ApplicationType AppId { get; set; } + SubscriptionProvider Provider { get; set; } + long StartDate { get; set; } + long ExpiryDate { get; set; } + SubscriptionType Type { get; set; } + string OrderId { get; set; } + string SubscriptionId { get; set; } + } +} diff --git a/Streetwriters.Common/Logger.cs b/Streetwriters.Common/Logger.cs index 1ddf47b..1edc716 100644 --- a/Streetwriters.Common/Logger.cs +++ b/Streetwriters.Common/Logger.cs @@ -1,52 +1,52 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.IO; -using System.Threading.Tasks; - -namespace Streetwriters.Common -{ - public class Slogger - { - public static Task Info(string scope, params string[] messages) - { - return Write(Format("info", scope, messages)); - } - - public static Task Error(string scope, params string[] messages) - { - return Write(Format("error", scope, messages)); - } - private static string Format(string level, string scope, params string[] messages) - { - var date = DateTime.UtcNow.ToString("MM-dd-yyyy HH:mm:ss"); - var messageText = string.Join(" ", messages); - return $"[{date}] | {level} | <{scope}> {messageText}"; - } - private static Task Write(string line) - { - var logDirectory = Path.GetFullPath("./logs"); - if (!Directory.Exists(logDirectory)) - Directory.CreateDirectory(logDirectory); - var path = Path.Join(logDirectory, typeof(T).FullName + "-" + DateTime.UtcNow.ToString("MM-dd-yyyy") + ".log"); - return File.AppendAllLinesAsync(path, new string[1] { line }); - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.IO; +using System.Threading.Tasks; + +namespace Streetwriters.Common +{ + public class Slogger + { + public static Task Info(string scope, params string[] messages) + { + return Write(Format("info", scope, messages)); + } + + public static Task Error(string scope, params string[] messages) + { + return Write(Format("error", scope, messages)); + } + private static string Format(string level, string scope, params string[] messages) + { + var date = DateTime.UtcNow.ToString("MM-dd-yyyy HH:mm:ss"); + var messageText = string.Join(" ", messages); + return $"[{date}] | {level} | <{scope}> {messageText}"; + } + private static Task Write(string line) + { + var logDirectory = Path.GetFullPath("./logs"); + if (!Directory.Exists(logDirectory)) + Directory.CreateDirectory(logDirectory); + var path = Path.Join(logDirectory, typeof(T).FullName + "-" + DateTime.UtcNow.ToString("MM-dd-yyyy") + ".log"); + return File.AppendAllLinesAsync(path, new string[1] { line }); + } + } } \ No newline at end of file diff --git a/Streetwriters.Common/Messages/ClearCacheMessage.cs b/Streetwriters.Common/Messages/ClearCacheMessage.cs index c06105d..8387ddc 100644 --- a/Streetwriters.Common/Messages/ClearCacheMessage.cs +++ b/Streetwriters.Common/Messages/ClearCacheMessage.cs @@ -1,38 +1,38 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Collections.Generic; -using System.Runtime.Serialization; -using System.Text.Json.Serialization; -using Streetwriters.Common.Enums; -using Streetwriters.Common.Interfaces; - -namespace Streetwriters.Common.Messages -{ - public class ClearCacheMessage - { - public ClearCacheMessage(List keys) - { - this.Keys = keys; - } - - [JsonPropertyName("keys")] - public List Keys { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Text.Json.Serialization; +using Streetwriters.Common.Enums; +using Streetwriters.Common.Interfaces; + +namespace Streetwriters.Common.Messages +{ + public class ClearCacheMessage + { + public ClearCacheMessage(List keys) + { + this.Keys = keys; + } + + [JsonPropertyName("keys")] + public List Keys { get; set; } + } } \ No newline at end of file diff --git a/Streetwriters.Common/Messages/CreateSubscriptionMessage.cs b/Streetwriters.Common/Messages/CreateSubscriptionMessage.cs index bd78fdc..890cd2f 100644 --- a/Streetwriters.Common/Messages/CreateSubscriptionMessage.cs +++ b/Streetwriters.Common/Messages/CreateSubscriptionMessage.cs @@ -1,63 +1,63 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Runtime.Serialization; -using System.Text.Json.Serialization; -using Streetwriters.Common.Enums; -using Streetwriters.Common.Interfaces; - -namespace Streetwriters.Common.Messages -{ - public class CreateSubscriptionMessage - { - [JsonPropertyName("userId")] - public string UserId { get; set; } - - [JsonPropertyName("provider")] - public SubscriptionProvider Provider { get; set; } - - [JsonPropertyName("appId")] - public ApplicationType AppId { get; set; } - - [JsonPropertyName("type")] - public SubscriptionType Type { get; set; } - - [JsonPropertyName("start")] - public long StartTime { get; set; } - - [JsonPropertyName("expiry")] - public long ExpiryTime { get; set; } - - [JsonPropertyName("orderId")] - public string OrderId { get; set; } - - [JsonPropertyName("updateURL")] - public string UpdateURL { get; set; } - - [JsonPropertyName("cancelURL")] - public string CancelURL { get; set; } - - [JsonPropertyName("subscriptionId")] - public string SubscriptionId { get; set; } - - [JsonPropertyName("productId")] - public string ProductId { get; set; } - public bool Extend { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Runtime.Serialization; +using System.Text.Json.Serialization; +using Streetwriters.Common.Enums; +using Streetwriters.Common.Interfaces; + +namespace Streetwriters.Common.Messages +{ + public class CreateSubscriptionMessage + { + [JsonPropertyName("userId")] + public string UserId { get; set; } + + [JsonPropertyName("provider")] + public SubscriptionProvider Provider { get; set; } + + [JsonPropertyName("appId")] + public ApplicationType AppId { get; set; } + + [JsonPropertyName("type")] + public SubscriptionType Type { get; set; } + + [JsonPropertyName("start")] + public long StartTime { get; set; } + + [JsonPropertyName("expiry")] + public long ExpiryTime { get; set; } + + [JsonPropertyName("orderId")] + public string OrderId { get; set; } + + [JsonPropertyName("updateURL")] + public string UpdateURL { get; set; } + + [JsonPropertyName("cancelURL")] + public string CancelURL { get; set; } + + [JsonPropertyName("subscriptionId")] + public string SubscriptionId { get; set; } + + [JsonPropertyName("productId")] + public string ProductId { get; set; } + public bool Extend { get; set; } + } } \ No newline at end of file diff --git a/Streetwriters.Common/Messages/DeleteSubscriptionMessage.cs b/Streetwriters.Common/Messages/DeleteSubscriptionMessage.cs index 036064a..db605ff 100644 --- a/Streetwriters.Common/Messages/DeleteSubscriptionMessage.cs +++ b/Streetwriters.Common/Messages/DeleteSubscriptionMessage.cs @@ -1,35 +1,35 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Runtime.Serialization; -using System.Text.Json.Serialization; -using Streetwriters.Common.Enums; -using Streetwriters.Common.Interfaces; - -namespace Streetwriters.Common.Messages -{ - public class DeleteSubscriptionMessage - { - [JsonPropertyName("userId")] - public string UserId { get; set; } - - [JsonPropertyName("appId")] - public ApplicationType AppId { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Runtime.Serialization; +using System.Text.Json.Serialization; +using Streetwriters.Common.Enums; +using Streetwriters.Common.Interfaces; + +namespace Streetwriters.Common.Messages +{ + public class DeleteSubscriptionMessage + { + [JsonPropertyName("userId")] + public string UserId { get; set; } + + [JsonPropertyName("appId")] + public ApplicationType AppId { get; set; } + } } \ No newline at end of file diff --git a/Streetwriters.Common/Messages/DeleteUserMessage.cs b/Streetwriters.Common/Messages/DeleteUserMessage.cs index 69c2bbe..a8c59d9 100644 --- a/Streetwriters.Common/Messages/DeleteUserMessage.cs +++ b/Streetwriters.Common/Messages/DeleteUserMessage.cs @@ -1,32 +1,32 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Runtime.Serialization; -using System.Text.Json.Serialization; -using Streetwriters.Common.Enums; -using Streetwriters.Common.Interfaces; - -namespace Streetwriters.Common.Messages -{ - public class DeleteUserMessage - { - [JsonPropertyName("userId")] - public string UserId { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Runtime.Serialization; +using System.Text.Json.Serialization; +using Streetwriters.Common.Enums; +using Streetwriters.Common.Interfaces; + +namespace Streetwriters.Common.Messages +{ + public class DeleteUserMessage + { + [JsonPropertyName("userId")] + public string UserId { get; set; } + } } \ No newline at end of file diff --git a/Streetwriters.Common/Messages/SendSSEMessage.cs b/Streetwriters.Common/Messages/SendSSEMessage.cs index 70b6444..9a6b464 100644 --- a/Streetwriters.Common/Messages/SendSSEMessage.cs +++ b/Streetwriters.Common/Messages/SendSSEMessage.cs @@ -1,48 +1,48 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Runtime.Serialization; -using System.Text.Json.Serialization; -using Streetwriters.Common.Interfaces; - -namespace Streetwriters.Common.Messages -{ - public class Message - { - [JsonPropertyName("type")] - public string Type { get; set; } - - [JsonPropertyName("data")] - public string Data { get; set; } - } - public class SendSSEMessage - { - [JsonPropertyName("sendToAll")] - public bool SendToAll { get; set; } - - [JsonPropertyName("userId")] - public string UserId { get; set; } - - [JsonPropertyName("message")] - public Message Message { get; set; } - - [JsonPropertyName("originTokenId")] - public string OriginTokenId { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Runtime.Serialization; +using System.Text.Json.Serialization; +using Streetwriters.Common.Interfaces; + +namespace Streetwriters.Common.Messages +{ + public class Message + { + [JsonPropertyName("type")] + public string Type { get; set; } + + [JsonPropertyName("data")] + public string Data { get; set; } + } + public class SendSSEMessage + { + [JsonPropertyName("sendToAll")] + public bool SendToAll { get; set; } + + [JsonPropertyName("userId")] + public string UserId { get; set; } + + [JsonPropertyName("message")] + public Message Message { get; set; } + + [JsonPropertyName("originTokenId")] + public string OriginTokenId { get; set; } + } } \ No newline at end of file diff --git a/Streetwriters.Common/Models/Client.cs b/Streetwriters.Common/Models/Client.cs index 77d1a4d..75fa4ec 100644 --- a/Streetwriters.Common/Models/Client.cs +++ b/Streetwriters.Common/Models/Client.cs @@ -1,45 +1,45 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.ComponentModel.DataAnnotations; -using System.Runtime.Serialization; -using System.Text.Json.Serialization; -using System.Threading.Tasks; -using MongoDB.Bson; -using MongoDB.Bson.Serialization.Attributes; -using Streetwriters.Common.Enums; -using Streetwriters.Common.Interfaces; - -namespace Streetwriters.Common.Models -{ - public class Client : IClient - { - public string Id { get; set; } - public string Name { get; set; } - public ApplicationType Type { get; set; } - public ApplicationType AppId { get; set; } - public string SenderEmail { get; set; } - public string SenderName { get; set; } - public string EmailConfirmedRedirectURL { get; set; } - public string AccountRecoveryRedirectURL { get; set; } - - public Func OnEmailConfirmed { get; set; } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; +using System.Text.Json.Serialization; +using System.Threading.Tasks; +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using Streetwriters.Common.Enums; +using Streetwriters.Common.Interfaces; + +namespace Streetwriters.Common.Models +{ + public class Client : IClient + { + public string Id { get; set; } + public string Name { get; set; } + public ApplicationType Type { get; set; } + public ApplicationType AppId { get; set; } + public string SenderEmail { get; set; } + public string SenderName { get; set; } + public string EmailConfirmedRedirectURL { get; set; } + public string AccountRecoveryRedirectURL { get; set; } + + public Func OnEmailConfirmed { get; set; } + } +} diff --git a/Streetwriters.Common/Models/GetSubscriptionResponse.cs b/Streetwriters.Common/Models/GetSubscriptionResponse.cs index ce43be8..1fc459e 100644 --- a/Streetwriters.Common/Models/GetSubscriptionResponse.cs +++ b/Streetwriters.Common/Models/GetSubscriptionResponse.cs @@ -1,31 +1,31 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Runtime.Serialization; -using System.Text.Json.Serialization; -using Streetwriters.Common.Interfaces; - -namespace Streetwriters.Common.Models -{ - public class SubscriptionResponse : Response - { - [JsonPropertyName("subscription")] - public ISubscription Subscription { get; set; } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Runtime.Serialization; +using System.Text.Json.Serialization; +using Streetwriters.Common.Interfaces; + +namespace Streetwriters.Common.Models +{ + public class SubscriptionResponse : Response + { + [JsonPropertyName("subscription")] + public ISubscription Subscription { get; set; } + } +} diff --git a/Streetwriters.Common/Models/MFAConfig.cs b/Streetwriters.Common/Models/MFAConfig.cs index 5bb70f6..735945b 100644 --- a/Streetwriters.Common/Models/MFAConfig.cs +++ b/Streetwriters.Common/Models/MFAConfig.cs @@ -1,29 +1,29 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -namespace Streetwriters.Common.Models -{ - public class MFAConfig - { - public bool IsEnabled { get; set; } - public string PrimaryMethod { get; set; } - public string SecondaryMethod { get; set; } - public int RemainingValidCodes { get; set; } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +namespace Streetwriters.Common.Models +{ + public class MFAConfig + { + public bool IsEnabled { get; set; } + public string PrimaryMethod { get; set; } + public string SecondaryMethod { get; set; } + public int RemainingValidCodes { get; set; } + } +} diff --git a/Streetwriters.Common/Models/Offer.cs b/Streetwriters.Common/Models/Offer.cs index 45bb7de..5940d98 100644 --- a/Streetwriters.Common/Models/Offer.cs +++ b/Streetwriters.Common/Models/Offer.cs @@ -1,53 +1,53 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - - - -// Streetwriters.Common.Models.Offer -using System.Collections.Generic; -using System.Text.Json.Serialization; -using MongoDB.Bson; -using MongoDB.Bson.Serialization.Attributes; -using Streetwriters.Common.Enums; -using Streetwriters.Common.Interfaces; - -namespace Streetwriters.Common.Models -{ - public class Offer : IOffer - { - public Offer() - { - Id = ObjectId.GenerateNewId().ToString(); - } - - [BsonId] - [BsonRepresentation(BsonType.ObjectId)] - [JsonPropertyName("id")] - public string Id { get; set; } - - [JsonPropertyName("appId")] - public ApplicationType AppId { get; set; } - - [JsonPropertyName("promoCode")] - public string PromoCode { get; set; } - - [JsonPropertyName("codes")] - public PromoCode[] Codes { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + + + +// Streetwriters.Common.Models.Offer +using System.Collections.Generic; +using System.Text.Json.Serialization; +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using Streetwriters.Common.Enums; +using Streetwriters.Common.Interfaces; + +namespace Streetwriters.Common.Models +{ + public class Offer : IOffer + { + public Offer() + { + Id = ObjectId.GenerateNewId().ToString(); + } + + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + [JsonPropertyName("id")] + public string Id { get; set; } + + [JsonPropertyName("appId")] + public ApplicationType AppId { get; set; } + + [JsonPropertyName("promoCode")] + public string PromoCode { get; set; } + + [JsonPropertyName("codes")] + public PromoCode[] Codes { get; set; } + } } \ No newline at end of file diff --git a/Streetwriters.Common/Models/PromoCode.cs b/Streetwriters.Common/Models/PromoCode.cs index 5be6de1..28faa06 100644 --- a/Streetwriters.Common/Models/PromoCode.cs +++ b/Streetwriters.Common/Models/PromoCode.cs @@ -1,40 +1,40 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - - - -// Streetwriters.Common.Models.Offer -using System.Collections.Generic; -using System.Text.Json.Serialization; -using MongoDB.Bson; -using MongoDB.Bson.Serialization.Attributes; -using Streetwriters.Common.Enums; -using Streetwriters.Common.Interfaces; - -namespace Streetwriters.Common.Models -{ - public class PromoCode - { - [JsonPropertyName("provider")] - public SubscriptionProvider Provider { get; set; } - - [JsonPropertyName("code")] - public string Code { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + + + +// Streetwriters.Common.Models.Offer +using System.Collections.Generic; +using System.Text.Json.Serialization; +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using Streetwriters.Common.Enums; +using Streetwriters.Common.Interfaces; + +namespace Streetwriters.Common.Models +{ + public class PromoCode + { + [JsonPropertyName("provider")] + public SubscriptionProvider Provider { get; set; } + + [JsonPropertyName("code")] + public string Code { get; set; } + } } \ No newline at end of file diff --git a/Streetwriters.Common/Models/Response.cs b/Streetwriters.Common/Models/Response.cs index 3b713ab..a6184e8 100644 --- a/Streetwriters.Common/Models/Response.cs +++ b/Streetwriters.Common/Models/Response.cs @@ -1,32 +1,32 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Runtime.Serialization; -using Newtonsoft.Json; -using Streetwriters.Common.Interfaces; - -namespace Streetwriters.Common.Models -{ - public class Response : IResponse - { - [JsonIgnore] - public bool Success { get; set; } - public int StatusCode { get; set; } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Streetwriters.Common.Interfaces; + +namespace Streetwriters.Common.Models +{ + public class Response : IResponse + { + [JsonIgnore] + public bool Success { get; set; } + public int StatusCode { get; set; } + } +} diff --git a/Streetwriters.Common/Models/Role.cs b/Streetwriters.Common/Models/Role.cs index 7264fb6..4b4b46c 100644 --- a/Streetwriters.Common/Models/Role.cs +++ b/Streetwriters.Common/Models/Role.cs @@ -1,141 +1,141 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - - - -using AspNetCore.Identity.Mongo.Model; - -namespace Streetwriters.Common.Models -{ - public class Role : MongoRole - { - // [DataMember(Name = "email")] - // [BsonElement("email")] - // public string Email - // { - // get; set; - // } - - // [DataMember(Name = "isEmailConfirmed")] - // [BsonElement("isEmailConfirmed")] - // public bool IsEmailConfirmed { get; set; } - - // [DataMember(Name = "username")] - // [BsonElement("username")] - // public string Username - // { - // get; set; - // } - - // [BsonId] - // [BsonRepresentation(BsonType.ObjectId)] - // public string Id - // { - // get; set; - // } - - // [IgnoreDataMember] - // [BsonElement("passwordHash")] - // public string PasswordHash - // { - // get; set; - // } - - // [DataMember(Name = "salt")] - // public string Salt - // { - // get; set; - // } - } - /* - public class Picture - { - [DataMember(Name = "thumbnail")] - public string Thumbnail - { - get; set; - } - [DataMember(Name = "full")] - public string Full - { - get; set; - } - } - - public class Streetwriters - { - - - [DataMember(Name = "fullName")] - public string FullName - { - get; set; - } - - [DataMember(Name = "biography")] - [StringLength(240)] - public string Biography - { - get; set; - } - - [DataMember(Name = "favoriteWords")] - public string FavoriteWords - { - get; set; - } - - [DataMember(Name = "profilePicture")] - public Picture ProfilePicture - { - get; set; - } - - [DataMember(Name = "followers")] - public string[] Followers - { - get; set; - } - - [DataMember(Name = "following")] - public string[] Following - { - get; set; - } - - [DataMember(Name = "website")] - [Url] - public string Website - { - get; set; - } - - [DataMember(Name = "instagram")] - public string Instagram - { - get; set; - } - - [DataMember(Name = "twitter")] - public string Twitter - { - get; set; - } - } */ -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + + + +using AspNetCore.Identity.Mongo.Model; + +namespace Streetwriters.Common.Models +{ + public class Role : MongoRole + { + // [DataMember(Name = "email")] + // [BsonElement("email")] + // public string Email + // { + // get; set; + // } + + // [DataMember(Name = "isEmailConfirmed")] + // [BsonElement("isEmailConfirmed")] + // public bool IsEmailConfirmed { get; set; } + + // [DataMember(Name = "username")] + // [BsonElement("username")] + // public string Username + // { + // get; set; + // } + + // [BsonId] + // [BsonRepresentation(BsonType.ObjectId)] + // public string Id + // { + // get; set; + // } + + // [IgnoreDataMember] + // [BsonElement("passwordHash")] + // public string PasswordHash + // { + // get; set; + // } + + // [DataMember(Name = "salt")] + // public string Salt + // { + // get; set; + // } + } + /* + public class Picture + { + [DataMember(Name = "thumbnail")] + public string Thumbnail + { + get; set; + } + [DataMember(Name = "full")] + public string Full + { + get; set; + } + } + + public class Streetwriters + { + + + [DataMember(Name = "fullName")] + public string FullName + { + get; set; + } + + [DataMember(Name = "biography")] + [StringLength(240)] + public string Biography + { + get; set; + } + + [DataMember(Name = "favoriteWords")] + public string FavoriteWords + { + get; set; + } + + [DataMember(Name = "profilePicture")] + public Picture ProfilePicture + { + get; set; + } + + [DataMember(Name = "followers")] + public string[] Followers + { + get; set; + } + + [DataMember(Name = "following")] + public string[] Following + { + get; set; + } + + [DataMember(Name = "website")] + [Url] + public string Website + { + get; set; + } + + [DataMember(Name = "instagram")] + public string Instagram + { + get; set; + } + + [DataMember(Name = "twitter")] + public string Twitter + { + get; set; + } + } */ +} diff --git a/Streetwriters.Common/Models/Subscription.cs b/Streetwriters.Common/Models/Subscription.cs index 8c28910..683cbea 100644 --- a/Streetwriters.Common/Models/Subscription.cs +++ b/Streetwriters.Common/Models/Subscription.cs @@ -1,80 +1,80 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.ComponentModel.DataAnnotations; -using System.Runtime.Serialization; -using System.Text.Json.Serialization; -using MongoDB.Bson; -using MongoDB.Bson.Serialization.Attributes; -using Streetwriters.Common.Enums; -using Streetwriters.Common.Interfaces; - -namespace Streetwriters.Common.Models -{ - public class Subscription : ISubscription - { - public Subscription() - { - Id = ObjectId.GenerateNewId().ToString(); - } - - [BsonId] - [BsonRepresentation(BsonType.ObjectId)] - [JsonPropertyName("id")] - public string Id { get; set; } - - [JsonPropertyName("userId")] - public string UserId { get; set; } - - [JsonIgnore] - public string OrderId { get; set; } - [JsonIgnore] - public string SubscriptionId { get; set; } - - [BsonRepresentation(BsonType.Int32)] - [JsonPropertyName("appId")] - public ApplicationType AppId { get; set; } - - [JsonPropertyName("start")] - public long StartDate { get; set; } - - [JsonPropertyName("expiry")] - public long ExpiryDate { get; set; } - - [BsonRepresentation(BsonType.Int32)] - [JsonPropertyName("provider")] - public SubscriptionProvider Provider { get; set; } - - [BsonRepresentation(BsonType.Int32)] - [JsonPropertyName("type")] - public SubscriptionType Type { get; set; } - - [JsonPropertyName("cancelURL")] - public string CancelURL { get; set; } - - [JsonPropertyName("updateURL")] - public string UpdateURL { get; set; } - - [JsonPropertyName("productId")] - public string ProductId { get; set; } - - [JsonIgnore] - public int TrialExtensionCount { get; set; } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; +using System.Text.Json.Serialization; +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using Streetwriters.Common.Enums; +using Streetwriters.Common.Interfaces; + +namespace Streetwriters.Common.Models +{ + public class Subscription : ISubscription + { + public Subscription() + { + Id = ObjectId.GenerateNewId().ToString(); + } + + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + [JsonPropertyName("id")] + public string Id { get; set; } + + [JsonPropertyName("userId")] + public string UserId { get; set; } + + [JsonIgnore] + public string OrderId { get; set; } + [JsonIgnore] + public string SubscriptionId { get; set; } + + [BsonRepresentation(BsonType.Int32)] + [JsonPropertyName("appId")] + public ApplicationType AppId { get; set; } + + [JsonPropertyName("start")] + public long StartDate { get; set; } + + [JsonPropertyName("expiry")] + public long ExpiryDate { get; set; } + + [BsonRepresentation(BsonType.Int32)] + [JsonPropertyName("provider")] + public SubscriptionProvider Provider { get; set; } + + [BsonRepresentation(BsonType.Int32)] + [JsonPropertyName("type")] + public SubscriptionType Type { get; set; } + + [JsonPropertyName("cancelURL")] + public string CancelURL { get; set; } + + [JsonPropertyName("updateURL")] + public string UpdateURL { get; set; } + + [JsonPropertyName("productId")] + public string ProductId { get; set; } + + [JsonIgnore] + public int TrialExtensionCount { get; set; } + } +} diff --git a/Streetwriters.Common/Models/User.cs b/Streetwriters.Common/Models/User.cs index ba888fa..b733e5d 100644 --- a/Streetwriters.Common/Models/User.cs +++ b/Streetwriters.Common/Models/User.cs @@ -1,29 +1,29 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - - - -using AspNetCore.Identity.Mongo.Model; - -namespace Streetwriters.Common.Models -{ - public class User : MongoUser - { - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + + + +using AspNetCore.Identity.Mongo.Model; + +namespace Streetwriters.Common.Models +{ + public class User : MongoUser + { + } +} diff --git a/Streetwriters.Common/Models/UserModel.cs b/Streetwriters.Common/Models/UserModel.cs index 2d8336e..20f330a 100644 --- a/Streetwriters.Common/Models/UserModel.cs +++ b/Streetwriters.Common/Models/UserModel.cs @@ -1,45 +1,45 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Text.Json.Serialization; - -namespace Streetwriters.Common.Models -{ - public class UserModel - { - [JsonPropertyName("id")] - public string UserId { get; set; } - - [JsonPropertyName("email")] - public string Email { get; set; } - - [JsonPropertyName("phoneNumber")] - public string PhoneNumber { get; set; } - - [JsonPropertyName("isEmailConfirmed")] - public bool IsEmailConfirmed { get; set; } - - [JsonPropertyName("marketingConsent")] - public bool MarketingConsent { get; set; } - - [JsonPropertyName("mfa")] - public MFAConfig MFA { get; set; } - } - -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Text.Json.Serialization; + +namespace Streetwriters.Common.Models +{ + public class UserModel + { + [JsonPropertyName("id")] + public string UserId { get; set; } + + [JsonPropertyName("email")] + public string Email { get; set; } + + [JsonPropertyName("phoneNumber")] + public string PhoneNumber { get; set; } + + [JsonPropertyName("isEmailConfirmed")] + public bool IsEmailConfirmed { get; set; } + + [JsonPropertyName("marketingConsent")] + public bool MarketingConsent { get; set; } + + [JsonPropertyName("mfa")] + public MFAConfig MFA { get; set; } + } + +} diff --git a/Streetwriters.Common/WampServers.cs b/Streetwriters.Common/WampServers.cs index 324a183..e190b43 100644 --- a/Streetwriters.Common/WampServers.cs +++ b/Streetwriters.Common/WampServers.cs @@ -1,125 +1,125 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Reactive.Subjects; -using System.Threading.Tasks; -using Streetwriters.Common.Helpers; -using Streetwriters.Common.Interfaces; -using WampSharp.V2.Client; - -namespace Streetwriters.Common -{ - public class WampServer where T : new() - { - private readonly ConcurrentDictionary Channels = new(); - - public string Endpoint { get; set; } - public string Address { get; set; } - public T Topics { get; set; } = new T(); - public string Realm { get; set; } - - private async Task GetChannelAsync(string topic) - { - if (!Channels.TryGetValue(topic, out IWampRealmProxy channel) || !channel.Monitor.IsConnected) - { - channel = await WampHelper.OpenWampChannelAsync(Address, Realm); - Channels.AddOrUpdate(topic, (key) => channel, (key, old) => channel); - } - return channel; - } - - public async Task GetServiceAsync(string topic) where V : class - { - var channel = await GetChannelAsync(topic); - return channel.Services.GetCalleeProxy(); - } - - public async Task PublishMessageAsync(string topic, V message) - { - try - { - IWampRealmProxy channel = await GetChannelAsync(topic); - WampHelper.PublishMessage(channel, topic, message); - } - catch (Exception ex) - { - await Slogger>.Error(nameof(PublishMessageAsync), ex.ToString()); - throw ex; - } - } - } - - public class WampServers - { - public static WampServer MessengerServer { get; } = new WampServer - { - Endpoint = "/wamp", - Address = $"{Servers.MessengerServer.WS()}/wamp", - Realm = "messages", - }; - - public static WampServer SubscriptionServer { get; } = new WampServer - { - Endpoint = "/wamp", - Address = $"{Servers.SubscriptionServer.WS()}/wamp", - Realm = "messages", - }; - - public static WampServer IdentityServer { get; } = new WampServer - { - Endpoint = "/wamp", - Address = $"{Servers.IdentityServer.WS()}/wamp", - Realm = "messages", - }; - - public static WampServer NotesnookServer { get; } = new WampServer - { - Endpoint = "/wamp", - Address = $"{Servers.NotesnookAPI.WS()}/wamp", - Realm = "messages", - }; - } - - public class MessengerServerTopics - { - public const string SendSSETopic = "co.streetwriters.sse.send"; - } - - public class SubscriptionServerTopics - { - public const string UserSubscriptionServiceTopic = "co.streetwriters.subscriptions.subscriptions"; - - public const string CreateSubscriptionTopic = "co.streetwriters.subscriptions.create"; - public const string DeleteSubscriptionTopic = "co.streetwriters.subscriptions.delete"; - } - - public class IdentityServerTopics - { - public const string UserAccountServiceTopic = "co.streetwriters.identity.users"; - public const string ClearCacheTopic = "co.streetwriters.identity.clear_cache"; - public const string DeleteUserTopic = "co.streetwriters.identity.delete_user"; - } - - public class NotesnookServerTopics - { - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Reactive.Subjects; +using System.Threading.Tasks; +using Streetwriters.Common.Helpers; +using Streetwriters.Common.Interfaces; +using WampSharp.V2.Client; + +namespace Streetwriters.Common +{ + public class WampServer where T : new() + { + private readonly ConcurrentDictionary Channels = new(); + + public string Endpoint { get; set; } + public string Address { get; set; } + public T Topics { get; set; } = new T(); + public string Realm { get; set; } + + private async Task GetChannelAsync(string topic) + { + if (!Channels.TryGetValue(topic, out IWampRealmProxy channel) || !channel.Monitor.IsConnected) + { + channel = await WampHelper.OpenWampChannelAsync(Address, Realm); + Channels.AddOrUpdate(topic, (key) => channel, (key, old) => channel); + } + return channel; + } + + public async Task GetServiceAsync(string topic) where V : class + { + var channel = await GetChannelAsync(topic); + return channel.Services.GetCalleeProxy(); + } + + public async Task PublishMessageAsync(string topic, V message) + { + try + { + IWampRealmProxy channel = await GetChannelAsync(topic); + WampHelper.PublishMessage(channel, topic, message); + } + catch (Exception ex) + { + await Slogger>.Error(nameof(PublishMessageAsync), ex.ToString()); + throw ex; + } + } + } + + public class WampServers + { + public static WampServer MessengerServer { get; } = new WampServer + { + Endpoint = "/wamp", + Address = $"{Servers.MessengerServer.WS()}/wamp", + Realm = "messages", + }; + + public static WampServer SubscriptionServer { get; } = new WampServer + { + Endpoint = "/wamp", + Address = $"{Servers.SubscriptionServer.WS()}/wamp", + Realm = "messages", + }; + + public static WampServer IdentityServer { get; } = new WampServer + { + Endpoint = "/wamp", + Address = $"{Servers.IdentityServer.WS()}/wamp", + Realm = "messages", + }; + + public static WampServer NotesnookServer { get; } = new WampServer + { + Endpoint = "/wamp", + Address = $"{Servers.NotesnookAPI.WS()}/wamp", + Realm = "messages", + }; + } + + public class MessengerServerTopics + { + public const string SendSSETopic = "co.streetwriters.sse.send"; + } + + public class SubscriptionServerTopics + { + public const string UserSubscriptionServiceTopic = "co.streetwriters.subscriptions.subscriptions"; + + public const string CreateSubscriptionTopic = "co.streetwriters.subscriptions.create"; + public const string DeleteSubscriptionTopic = "co.streetwriters.subscriptions.delete"; + } + + public class IdentityServerTopics + { + public const string UserAccountServiceTopic = "co.streetwriters.identity.users"; + public const string ClearCacheTopic = "co.streetwriters.identity.clear_cache"; + public const string DeleteUserTopic = "co.streetwriters.identity.delete_user"; + } + + public class NotesnookServerTopics + { + } } \ No newline at end of file diff --git a/Streetwriters.Data/DbSettings.cs b/Streetwriters.Data/DbSettings.cs index 52909d1..88d6f28 100644 --- a/Streetwriters.Data/DbSettings.cs +++ b/Streetwriters.Data/DbSettings.cs @@ -1,29 +1,29 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using Streetwriters.Data.Interfaces; - -namespace Streetwriters.Data -{ - public class DbSettings : IDbSettings - { - public string DatabaseName { get; set; } - public string ConnectionString { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using Streetwriters.Data.Interfaces; + +namespace Streetwriters.Data +{ + public class DbSettings : IDbSettings + { + public string DatabaseName { get; set; } + public string ConnectionString { get; set; } + } } \ No newline at end of file diff --git a/Streetwriters.Data/Interfaces/IDbContext.cs b/Streetwriters.Data/Interfaces/IDbContext.cs index cc6393b..eafc91a 100644 --- a/Streetwriters.Data/Interfaces/IDbContext.cs +++ b/Streetwriters.Data/Interfaces/IDbContext.cs @@ -1,33 +1,33 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - - -using MongoDB.Driver; -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace Streetwriters.Data.Interfaces -{ - public interface IDbContext : IDisposable - { - void AddCommand(Func func); - Task SaveChanges(); - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + + +using MongoDB.Driver; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Streetwriters.Data.Interfaces +{ + public interface IDbContext : IDisposable + { + void AddCommand(Func func); + Task SaveChanges(); + } } \ No newline at end of file diff --git a/Streetwriters.Data/Interfaces/IDbSettings.cs b/Streetwriters.Data/Interfaces/IDbSettings.cs index 168bc67..bb798a9 100644 --- a/Streetwriters.Data/Interfaces/IDbSettings.cs +++ b/Streetwriters.Data/Interfaces/IDbSettings.cs @@ -1,27 +1,27 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -namespace Streetwriters.Data.Interfaces -{ - public interface IDbSettings - { - string DatabaseName { get; set; } - string ConnectionString { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +namespace Streetwriters.Data.Interfaces +{ + public interface IDbSettings + { + string DatabaseName { get; set; } + string ConnectionString { get; set; } + } } \ No newline at end of file diff --git a/Streetwriters.Data/Interfaces/IUnitOfWork.cs b/Streetwriters.Data/Interfaces/IUnitOfWork.cs index f8a6e73..e210886 100644 --- a/Streetwriters.Data/Interfaces/IUnitOfWork.cs +++ b/Streetwriters.Data/Interfaces/IUnitOfWork.cs @@ -1,29 +1,29 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Threading.Tasks; - -namespace Streetwriters.Data.Interfaces -{ - public interface IUnitOfWork : IDisposable - { - Task Commit(); - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Threading.Tasks; + +namespace Streetwriters.Data.Interfaces +{ + public interface IUnitOfWork : IDisposable + { + Task Commit(); + } } \ No newline at end of file diff --git a/Streetwriters.Data/Repositories/Repository.cs b/Streetwriters.Data/Repositories/Repository.cs index 246a195..86f9175 100644 --- a/Streetwriters.Data/Repositories/Repository.cs +++ b/Streetwriters.Data/Repositories/Repository.cs @@ -1,127 +1,127 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; -using MongoDB.Bson; -using MongoDB.Driver; -using Streetwriters.Data.Interfaces; - -namespace Streetwriters.Data.Repositories -{ - public class Repository where TEntity : class - { - protected readonly IDbContext dbContext; - public IMongoCollection Collection { get; set; } - - public Repository(IDbContext _dbContext, IMongoCollection collection) - { - dbContext = _dbContext; - Collection = collection; - } - - public virtual void Insert(TEntity obj) - { - dbContext.AddCommand((handle, ct) => Collection.InsertOneAsync(handle, obj, null, ct)); - } - - - public virtual Task InsertAsync(TEntity obj) - { - return Collection.InsertOneAsync(obj); - } - - public virtual void Upsert(TEntity obj, Expression> filterExpression) - { - dbContext.AddCommand((handle, ct) => Collection.ReplaceOneAsync(handle, filterExpression, obj, new ReplaceOptions { IsUpsert = true }, ct)); - } - - public virtual Task UpsertAsync(TEntity obj, Expression> filterExpression) - { - return Collection.ReplaceOneAsync(filterExpression, obj, new ReplaceOptions { IsUpsert = true }); - } - - public virtual async Task FindOneAsync(Expression> filterExpression) - { - var data = await Collection.FindAsync(filterExpression); - return data.FirstOrDefault(); - } - - public virtual async Task GetAsync(string id) - { - var data = await Collection.FindAsync(Builders.Filter.Eq("_id", ObjectId.Parse(id))); - return data.FirstOrDefault(); - } - - public virtual async Task> FindAsync(Expression> filterExpression) - { - var data = await Collection.FindAsync(filterExpression); - return data.ToList(); - } - - public virtual async Task> GetAllAsync() - { - var all = await Collection.FindAsync(Builders.Filter.Empty); - return all.ToList(); - } - - public virtual void Update(string id, TEntity obj) - { - dbContext.AddCommand((handle, ct) => Collection.ReplaceOneAsync(handle, Builders.Filter.Eq("_id", ObjectId.Parse(id)), obj, cancellationToken: ct)); - } - - public virtual Task UpdateAsync(string id, TEntity obj) - { - return Collection.ReplaceOneAsync(Builders.Filter.Eq("_id", ObjectId.Parse(id)), obj); - } - - public virtual void DeleteById(string id) - { - dbContext.AddCommand((handle, ct) => Collection.DeleteOneAsync(handle, Builders.Filter.Eq("_id", ObjectId.Parse(id)), cancellationToken: ct)); - } - - public virtual Task DeleteByIdAsync(string id) - { - return Collection.DeleteOneAsync(Builders.Filter.Eq("_id", ObjectId.Parse(id))); - } - - public virtual void Delete(Expression> filterExpression) - { - dbContext.AddCommand((handle, ct) => Collection.DeleteOneAsync(handle, filterExpression, cancellationToken: ct)); - } - - public virtual void DeleteMany(Expression> filterExpression) - { - dbContext.AddCommand((handle, ct) => Collection.DeleteManyAsync(handle, filterExpression, cancellationToken: ct)); - } - - public virtual Task DeleteAsync(Expression> filterExpression) - { - return Collection.DeleteOneAsync(filterExpression); - } - - public virtual Task DeleteManyAsync(Expression> filterExpression) - { - return Collection.DeleteManyAsync(filterExpression); - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; +using MongoDB.Bson; +using MongoDB.Driver; +using Streetwriters.Data.Interfaces; + +namespace Streetwriters.Data.Repositories +{ + public class Repository where TEntity : class + { + protected readonly IDbContext dbContext; + public IMongoCollection Collection { get; set; } + + public Repository(IDbContext _dbContext, IMongoCollection collection) + { + dbContext = _dbContext; + Collection = collection; + } + + public virtual void Insert(TEntity obj) + { + dbContext.AddCommand((handle, ct) => Collection.InsertOneAsync(handle, obj, null, ct)); + } + + + public virtual Task InsertAsync(TEntity obj) + { + return Collection.InsertOneAsync(obj); + } + + public virtual void Upsert(TEntity obj, Expression> filterExpression) + { + dbContext.AddCommand((handle, ct) => Collection.ReplaceOneAsync(handle, filterExpression, obj, new ReplaceOptions { IsUpsert = true }, ct)); + } + + public virtual Task UpsertAsync(TEntity obj, Expression> filterExpression) + { + return Collection.ReplaceOneAsync(filterExpression, obj, new ReplaceOptions { IsUpsert = true }); + } + + public virtual async Task FindOneAsync(Expression> filterExpression) + { + var data = await Collection.FindAsync(filterExpression); + return data.FirstOrDefault(); + } + + public virtual async Task GetAsync(string id) + { + var data = await Collection.FindAsync(Builders.Filter.Eq("_id", ObjectId.Parse(id))); + return data.FirstOrDefault(); + } + + public virtual async Task> FindAsync(Expression> filterExpression) + { + var data = await Collection.FindAsync(filterExpression); + return data.ToList(); + } + + public virtual async Task> GetAllAsync() + { + var all = await Collection.FindAsync(Builders.Filter.Empty); + return all.ToList(); + } + + public virtual void Update(string id, TEntity obj) + { + dbContext.AddCommand((handle, ct) => Collection.ReplaceOneAsync(handle, Builders.Filter.Eq("_id", ObjectId.Parse(id)), obj, cancellationToken: ct)); + } + + public virtual Task UpdateAsync(string id, TEntity obj) + { + return Collection.ReplaceOneAsync(Builders.Filter.Eq("_id", ObjectId.Parse(id)), obj); + } + + public virtual void DeleteById(string id) + { + dbContext.AddCommand((handle, ct) => Collection.DeleteOneAsync(handle, Builders.Filter.Eq("_id", ObjectId.Parse(id)), cancellationToken: ct)); + } + + public virtual Task DeleteByIdAsync(string id) + { + return Collection.DeleteOneAsync(Builders.Filter.Eq("_id", ObjectId.Parse(id))); + } + + public virtual void Delete(Expression> filterExpression) + { + dbContext.AddCommand((handle, ct) => Collection.DeleteOneAsync(handle, filterExpression, cancellationToken: ct)); + } + + public virtual void DeleteMany(Expression> filterExpression) + { + dbContext.AddCommand((handle, ct) => Collection.DeleteManyAsync(handle, filterExpression, cancellationToken: ct)); + } + + public virtual Task DeleteAsync(Expression> filterExpression) + { + return Collection.DeleteOneAsync(filterExpression); + } + + public virtual Task DeleteManyAsync(Expression> filterExpression) + { + return Collection.DeleteManyAsync(filterExpression); + } + } } \ No newline at end of file diff --git a/Streetwriters.Data/UnitOfWork.cs b/Streetwriters.Data/UnitOfWork.cs index 5075394..3a7ec1b 100644 --- a/Streetwriters.Data/UnitOfWork.cs +++ b/Streetwriters.Data/UnitOfWork.cs @@ -1,38 +1,38 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Threading.Tasks; -using Streetwriters.Data.Interfaces; - -namespace Streetwriters.Data -{ - public class UnitOfWork(IDbContext dbContext) : IUnitOfWork - { - public async Task Commit() - { - return await dbContext.SaveChanges() > 0; - } - - public void Dispose() - { - dbContext.Dispose(); - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Threading.Tasks; +using Streetwriters.Data.Interfaces; + +namespace Streetwriters.Data +{ + public class UnitOfWork(IDbContext dbContext) : IUnitOfWork + { + public async Task Commit() + { + return await dbContext.SaveChanges() > 0; + } + + public void Dispose() + { + dbContext.Dispose(); + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Config.cs b/Streetwriters.Identity/Config.cs index 2f09272..dafc514 100644 --- a/Streetwriters.Identity/Config.cs +++ b/Streetwriters.Identity/Config.cs @@ -1,88 +1,88 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using IdentityServer4; -using IdentityServer4.Models; -using Streetwriters.Common; -using System.Collections.Generic; - -namespace Streetwriters.Identity -{ - public static class Config - { - public const string EMAIL_GRANT_TYPE = "email"; - public const string MFA_GRANT_TYPE = "mfa"; - public const string MFA_PASSWORD_GRANT_TYPE = "mfa_password"; - - public const string MFA_GRANT_TYPE_SCOPE = "auth:grant_types:mfa"; - public const string MFA_PASSWORD_GRANT_TYPE_SCOPE = "auth:grant_types:mfa_password"; - - public static IEnumerable IdentityResources => - new List { - new IdentityResources.OpenId(), - }; - - public static IEnumerable ApiResources => - new List - { - new ApiResource("notesnook", "Notesnook API", new string[] { "verified" }) - { - ApiSecrets = { new Secret(Constants.NOTESNOOK_API_SECRET?.Sha256()) }, - Scopes = { "notesnook.sync" } - }, - // local API - new ApiResource(IdentityServerConstants.LocalApi.ScopeName) - }; - - public static IEnumerable ApiScopes => - new List - { - new ApiScope("notesnook.sync", "Notesnook Syncing Access"), - new ApiScope(IdentityServerConstants.LocalApi.ScopeName), - new ApiScope(MFA_GRANT_TYPE_SCOPE, "Multi-factor authentication access"), - new ApiScope(MFA_PASSWORD_GRANT_TYPE_SCOPE, "Multi-factor authentication password step access") - }; - - public static IEnumerable Clients => - new List - { - new Client - { - ClientName = "Notesnook", - ClientId = "notesnook", - AllowedGrantTypes = { GrantType.ResourceOwnerPassword, MFA_GRANT_TYPE, MFA_PASSWORD_GRANT_TYPE, EMAIL_GRANT_TYPE, }, - RequirePkce = false, - RequireClientSecret = false, - RequireConsent = false, - AccessTokenType = AccessTokenType.Reference, - AllowOfflineAccess = true, - UpdateAccessTokenClaimsOnRefresh = true, - RefreshTokenUsage = TokenUsage.ReUse, - RefreshTokenExpiration = TokenExpiration.Sliding, - - AccessTokenLifetime = 6 * 3600, // 6 hours - SlidingRefreshTokenLifetime = 45 * 3600 * 24, // 45 days - AbsoluteRefreshTokenLifetime = 0, // 0 means infinite sliding lifetime - - // scopes that client has access to - AllowedScopes = { "notesnook.sync", "offline_access", "openid", IdentityServerConstants.LocalApi.ScopeName, "mfa" }, - } - }; - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using IdentityServer4; +using IdentityServer4.Models; +using Streetwriters.Common; +using System.Collections.Generic; + +namespace Streetwriters.Identity +{ + public static class Config + { + public const string EMAIL_GRANT_TYPE = "email"; + public const string MFA_GRANT_TYPE = "mfa"; + public const string MFA_PASSWORD_GRANT_TYPE = "mfa_password"; + + public const string MFA_GRANT_TYPE_SCOPE = "auth:grant_types:mfa"; + public const string MFA_PASSWORD_GRANT_TYPE_SCOPE = "auth:grant_types:mfa_password"; + + public static IEnumerable IdentityResources => + new List { + new IdentityResources.OpenId(), + }; + + public static IEnumerable ApiResources => + new List + { + new ApiResource("notesnook", "Notesnook API", new string[] { "verified" }) + { + ApiSecrets = { new Secret(Constants.NOTESNOOK_API_SECRET?.Sha256()) }, + Scopes = { "notesnook.sync" } + }, + // local API + new ApiResource(IdentityServerConstants.LocalApi.ScopeName) + }; + + public static IEnumerable ApiScopes => + new List + { + new ApiScope("notesnook.sync", "Notesnook Syncing Access"), + new ApiScope(IdentityServerConstants.LocalApi.ScopeName), + new ApiScope(MFA_GRANT_TYPE_SCOPE, "Multi-factor authentication access"), + new ApiScope(MFA_PASSWORD_GRANT_TYPE_SCOPE, "Multi-factor authentication password step access") + }; + + public static IEnumerable Clients => + new List + { + new Client + { + ClientName = "Notesnook", + ClientId = "notesnook", + AllowedGrantTypes = { GrantType.ResourceOwnerPassword, MFA_GRANT_TYPE, MFA_PASSWORD_GRANT_TYPE, EMAIL_GRANT_TYPE, }, + RequirePkce = false, + RequireClientSecret = false, + RequireConsent = false, + AccessTokenType = AccessTokenType.Reference, + AllowOfflineAccess = true, + UpdateAccessTokenClaimsOnRefresh = true, + RefreshTokenUsage = TokenUsage.ReUse, + RefreshTokenExpiration = TokenExpiration.Sliding, + + AccessTokenLifetime = 6 * 3600, // 6 hours + SlidingRefreshTokenLifetime = 45 * 3600 * 24, // 45 days + AbsoluteRefreshTokenLifetime = 0, // 0 means infinite sliding lifetime + + // scopes that client has access to + AllowedScopes = { "notesnook.sync", "offline_access", "openid", IdentityServerConstants.LocalApi.ScopeName, "mfa" }, + } + }; + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Dockerfile b/Streetwriters.Identity/Dockerfile index 279c684..7fc6683 100644 --- a/Streetwriters.Identity/Dockerfile +++ b/Streetwriters.Identity/Dockerfile @@ -1,50 +1,50 @@ -FROM mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine AS base -WORKDIR /app - -FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build -ARG TARGETARCH -ARG BUILDPLATFORM -ENV DOTNET_TC_QuickJitForLoops="1" DOTNET_ReadyToRun="0" DOTNET_TieredPGO="1" DOTNET_SYSTEM_GLOBALIZATION_INVARIANT="true" - -WORKDIR /src - -COPY Streetwriters.Data/*.csproj ./Streetwriters.Data/ -COPY Streetwriters.Common/*.csproj ./Streetwriters.Common/ -COPY Streetwriters.Identity/*.csproj ./Streetwriters.Identity/ - -# restore dependencies -RUN dotnet restore -v d /src/Streetwriters.Identity/Streetwriters.Identity.csproj --use-current-runtime - -COPY Streetwriters.Data/ ./Streetwriters.Data/ -COPY Streetwriters.Common/ ./Streetwriters.Common/ -COPY Streetwriters.Identity/ ./Streetwriters.Identity/ - -WORKDIR /src/Streetwriters.Identity/ - -RUN dotnet build -c Release -o /app/build -a $TARGETARCH - -FROM build AS publish -RUN dotnet publish -c Release -o /app/publish \ - #--runtime alpine-x64 \ - --self-contained true \ - /p:TrimMode=partial \ - /p:PublishTrimmed=true \ - /p:PublishSingleFile=true \ - /p:JsonSerializerIsReflectionEnabledByDefault=true \ - -a $TARGETARCH - -FROM --platform=$BUILDPLATFORM base AS final -ARG TARGETARCH -ARG BUILDPLATFORM - -# create a new user and change directory ownership -RUN adduser --disabled-password \ - --home /app \ - --gecos '' dotnetuser && chown -R dotnetuser /app - -# impersonate into the new user -USER dotnetuser -WORKDIR /app - -COPY --from=publish /app/publish . +FROM mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine AS base +WORKDIR /app + +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build +ARG TARGETARCH +ARG BUILDPLATFORM +ENV DOTNET_TC_QuickJitForLoops="1" DOTNET_ReadyToRun="0" DOTNET_TieredPGO="1" DOTNET_SYSTEM_GLOBALIZATION_INVARIANT="true" + +WORKDIR /src + +COPY Streetwriters.Data/*.csproj ./Streetwriters.Data/ +COPY Streetwriters.Common/*.csproj ./Streetwriters.Common/ +COPY Streetwriters.Identity/*.csproj ./Streetwriters.Identity/ + +# restore dependencies +RUN dotnet restore -v d /src/Streetwriters.Identity/Streetwriters.Identity.csproj --use-current-runtime + +COPY Streetwriters.Data/ ./Streetwriters.Data/ +COPY Streetwriters.Common/ ./Streetwriters.Common/ +COPY Streetwriters.Identity/ ./Streetwriters.Identity/ + +WORKDIR /src/Streetwriters.Identity/ + +RUN dotnet build -c Release -o /app/build -a $TARGETARCH + +FROM build AS publish +RUN dotnet publish -c Release -o /app/publish \ + #--runtime alpine-x64 \ + --self-contained true \ + /p:TrimMode=partial \ + /p:PublishTrimmed=true \ + /p:PublishSingleFile=true \ + /p:JsonSerializerIsReflectionEnabledByDefault=true \ + -a $TARGETARCH + +FROM --platform=$BUILDPLATFORM base AS final +ARG TARGETARCH +ARG BUILDPLATFORM + +# create a new user and change directory ownership +RUN adduser --disabled-password \ + --home /app \ + --gecos '' dotnetuser && chown -R dotnetuser /app + +# impersonate into the new user +USER dotnetuser +WORKDIR /app + +COPY --from=publish /app/publish . ENTRYPOINT ["./Streetwriters.Identity"] \ No newline at end of file diff --git a/Streetwriters.Identity/Enums/TokenTypes.cs b/Streetwriters.Identity/Enums/TokenTypes.cs index 472a7ee..8f2ff73 100644 --- a/Streetwriters.Identity/Enums/TokenTypes.cs +++ b/Streetwriters.Identity/Enums/TokenTypes.cs @@ -1,28 +1,28 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -namespace Streetwriters.Identity.Enums -{ - public enum TokenType - { - CONFRIM_EMAIL = 0, - RESET_PASSWORD = 1, - CHANGE_EMAIL = 2, - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +namespace Streetwriters.Identity.Enums +{ + public enum TokenType + { + CONFRIM_EMAIL = 0, + RESET_PASSWORD = 1, + CHANGE_EMAIL = 2, + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Extensions/HttpContextExtensions.cs b/Streetwriters.Identity/Extensions/HttpContextExtensions.cs index 56ff1ba..8581c83 100644 --- a/Streetwriters.Identity/Extensions/HttpContextExtensions.cs +++ b/Streetwriters.Identity/Extensions/HttpContextExtensions.cs @@ -1,79 +1,79 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Linq; -using System.Net; -using System.Text; -using Ng.Services; - -namespace Microsoft.AspNetCore.Http -{ - public static class HttpContextExtensions - { - /// - /// Get remote ip address, optionally allowing for x-forwarded-for header check - /// - /// Http context - /// Whether to allow x-forwarded-for header check - /// IPAddress - public static IPAddress GetRemoteIPAddress(this HttpContext context, bool allowForwarded = true) - { - if (allowForwarded) - { - // if you are allowing these forward headers, please ensure you are restricting context.Connection.RemoteIpAddress - // to cloud flare ips: https://www.cloudflare.com/ips/ - string header = (context.Request.Headers["CF-Connecting-IP"].FirstOrDefault() ?? context.Request.Headers["X-Forwarded-For"].FirstOrDefault()); - if (IPAddress.TryParse(header, out IPAddress ip)) - { - return ip; - } - } - return context.Connection.RemoteIpAddress; - } - - static UserAgentService userAgentService = new UserAgentService(); - public static string GetClientInfo(this HttpContext httpContext) - { - var clientIp = httpContext.GetRemoteIPAddress().ToString(); - var country = httpContext.Request.Headers["CF-IPCountry"]; - var userAgent = httpContext.Request.Headers["User-Agent"]; - var builder = new StringBuilder(); - - builder.AppendLine($"Date: {DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")}"); - - if (!string.IsNullOrEmpty(country)) - builder.AppendLine($"IP: {clientIp}"); - - if (!string.IsNullOrEmpty(country)) - builder.AppendLine($"Country: {country.ToString()}"); - - if (!string.IsNullOrEmpty(userAgent)) - { - var ua = userAgentService.Parse(userAgent); - if (!string.IsNullOrEmpty(ua.Browser)) - builder.AppendLine($"Browser: {ua.Browser} {ua.BrowserVersion}"); - if (!string.IsNullOrEmpty(ua.Platform)) - builder.AppendLine($"Platform: {ua.Platform}"); - } - - return builder.ToString(); - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Linq; +using System.Net; +using System.Text; +using Ng.Services; + +namespace Microsoft.AspNetCore.Http +{ + public static class HttpContextExtensions + { + /// + /// Get remote ip address, optionally allowing for x-forwarded-for header check + /// + /// Http context + /// Whether to allow x-forwarded-for header check + /// IPAddress + public static IPAddress GetRemoteIPAddress(this HttpContext context, bool allowForwarded = true) + { + if (allowForwarded) + { + // if you are allowing these forward headers, please ensure you are restricting context.Connection.RemoteIpAddress + // to cloud flare ips: https://www.cloudflare.com/ips/ + string header = (context.Request.Headers["CF-Connecting-IP"].FirstOrDefault() ?? context.Request.Headers["X-Forwarded-For"].FirstOrDefault()); + if (IPAddress.TryParse(header, out IPAddress ip)) + { + return ip; + } + } + return context.Connection.RemoteIpAddress; + } + + static UserAgentService userAgentService = new UserAgentService(); + public static string GetClientInfo(this HttpContext httpContext) + { + var clientIp = httpContext.GetRemoteIPAddress().ToString(); + var country = httpContext.Request.Headers["CF-IPCountry"]; + var userAgent = httpContext.Request.Headers["User-Agent"]; + var builder = new StringBuilder(); + + builder.AppendLine($"Date: {DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")}"); + + if (!string.IsNullOrEmpty(country)) + builder.AppendLine($"IP: {clientIp}"); + + if (!string.IsNullOrEmpty(country)) + builder.AppendLine($"Country: {country.ToString()}"); + + if (!string.IsNullOrEmpty(userAgent)) + { + var ua = userAgentService.Parse(userAgent); + if (!string.IsNullOrEmpty(ua.Browser)) + builder.AppendLine($"Browser: {ua.Browser} {ua.BrowserVersion}"); + if (!string.IsNullOrEmpty(ua.Platform)) + builder.AppendLine($"Platform: {ua.Platform}"); + } + + return builder.ToString(); + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Extensions/IEnumerableExtensions.cs b/Streetwriters.Identity/Extensions/IEnumerableExtensions.cs index 745b037..3e9746e 100644 --- a/Streetwriters.Identity/Extensions/IEnumerableExtensions.cs +++ b/Streetwriters.Identity/Extensions/IEnumerableExtensions.cs @@ -1,42 +1,42 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Claims; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Identity; -using Streetwriters.Identity.Controllers; - -namespace System.Collections.Generic -{ - public static class IEnumberableExtensions - { - public static IEnumerable ToErrors(this IEnumerable collection) - { - return collection.Select((e) => e.Description); - } - - public static string GetClaimValue(this IEnumerable claims, string type) - { - return claims.FirstOrDefault((c) => c.Type == type)?.Value; - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; +using Streetwriters.Identity.Controllers; + +namespace System.Collections.Generic +{ + public static class IEnumberableExtensions + { + public static IEnumerable ToErrors(this IEnumerable collection) + { + return collection.Select((e) => e.Description); + } + + public static string GetClaimValue(this IEnumerable claims, string type) + { + return claims.FirstOrDefault((c) => c.Type == type)?.Value; + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Extensions/IntExtensions.cs b/Streetwriters.Identity/Extensions/IntExtensions.cs index f0cd1a1..650e818 100644 --- a/Streetwriters.Identity/Extensions/IntExtensions.cs +++ b/Streetwriters.Identity/Extensions/IntExtensions.cs @@ -1,34 +1,34 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Text; -using Ng.Services; - -namespace System -{ - public static class IntExtensions - { - public static string Pluralize(this int value, string singular, string plural) - { - // if (value == null) return $"0 {plural}"; - return value == 1 ? $"{value} {singular}" : $"{value} {plural}"; - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Text; +using Ng.Services; + +namespace System +{ + public static class IntExtensions + { + public static string Pluralize(this int value, string singular, string plural) + { + // if (value == null) return $"0 {plural}"; + return value == 1 ? $"{value} {singular}" : $"{value} {plural}"; + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Extensions/MongoDBTicketStore.cs b/Streetwriters.Identity/Extensions/MongoDBTicketStore.cs index d7be3c2..a928a88 100644 --- a/Streetwriters.Identity/Extensions/MongoDBTicketStore.cs +++ b/Streetwriters.Identity/Extensions/MongoDBTicketStore.cs @@ -1,73 +1,73 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using Microsoft.AspNetCore.Authentication.Cookies; -using Microsoft.Extensions.Caching.Memory; -using System; -using System.Threading.Tasks; - -namespace Microsoft.AspNetCore.Authentication -{ - public class MemoryCacheTicketStore : ITicketStore - { - private const string KeyPrefix = "AuthSessionStore"; - private IMemoryCache _cache; - - public MemoryCacheTicketStore() - { - _cache = new MemoryCache(new MemoryCacheOptions()); - } - - Task ITicketStore.RemoveAsync(string key) - { - _cache.Remove(key); - return Task.FromResult(true); - } - - Task ITicketStore.RenewAsync(string key, AuthenticationTicket ticket) - { - var options = new MemoryCacheEntryOptions(); - var expiresUtc = ticket.Properties.ExpiresUtc; - if (expiresUtc.HasValue) - { - options.SetAbsoluteExpiration(expiresUtc.Value); - } - options.SetSlidingExpiration(TimeSpan.FromHours(1)); - - _cache.Set(key, ticket, options); - - return Task.FromResult(true); - } - - Task ITicketStore.RetrieveAsync(string key) - { - AuthenticationTicket ticket; - _cache.TryGetValue(key, out ticket); - return Task.FromResult(ticket); - } - - async Task ITicketStore.StoreAsync(AuthenticationTicket ticket) - { - var id = Guid.NewGuid(); - var key = KeyPrefix + id; - await ((ITicketStore)this).RenewAsync(key, ticket); - return key; - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.Extensions.Caching.Memory; +using System; +using System.Threading.Tasks; + +namespace Microsoft.AspNetCore.Authentication +{ + public class MemoryCacheTicketStore : ITicketStore + { + private const string KeyPrefix = "AuthSessionStore"; + private IMemoryCache _cache; + + public MemoryCacheTicketStore() + { + _cache = new MemoryCache(new MemoryCacheOptions()); + } + + Task ITicketStore.RemoveAsync(string key) + { + _cache.Remove(key); + return Task.FromResult(true); + } + + Task ITicketStore.RenewAsync(string key, AuthenticationTicket ticket) + { + var options = new MemoryCacheEntryOptions(); + var expiresUtc = ticket.Properties.ExpiresUtc; + if (expiresUtc.HasValue) + { + options.SetAbsoluteExpiration(expiresUtc.Value); + } + options.SetSlidingExpiration(TimeSpan.FromHours(1)); + + _cache.Set(key, ticket, options); + + return Task.FromResult(true); + } + + Task ITicketStore.RetrieveAsync(string key) + { + AuthenticationTicket ticket; + _cache.TryGetValue(key, out ticket); + return Task.FromResult(ticket); + } + + async Task ITicketStore.StoreAsync(AuthenticationTicket ticket) + { + var id = Guid.NewGuid(); + var key = KeyPrefix + id; + await ((ITicketStore)this).RenewAsync(key, ticket); + return key; + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Extensions/UserManagerExtensions.cs b/Streetwriters.Identity/Extensions/UserManagerExtensions.cs index 68b541d..d1845dc 100644 --- a/Streetwriters.Identity/Extensions/UserManagerExtensions.cs +++ b/Streetwriters.Identity/Extensions/UserManagerExtensions.cs @@ -1,33 +1,33 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Threading.Tasks; -using Streetwriters.Common.Models; - -namespace Microsoft.AspNetCore.Identity -{ - public static class UserManagerExtensions - { - public static async Task FindRegisteredUserAsync(this UserManager userManager, string email, string clientId) - { - var user = await userManager.FindByEmailAsync(email); - return user != null && await userManager.IsInRoleAsync(user, clientId) ? user : null; - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Threading.Tasks; +using Streetwriters.Common.Models; + +namespace Microsoft.AspNetCore.Identity +{ + public static class UserManagerExtensions + { + public static async Task FindRegisteredUserAsync(this UserManager userManager, string email, string clientId) + { + var user = await userManager.FindByEmailAsync(email); + return user != null && await userManager.IsInRoleAsync(user, clientId) ? user : null; + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Handlers/TokenResponseHandler.cs b/Streetwriters.Identity/Handlers/TokenResponseHandler.cs index e8c3e07..1f0e8e2 100644 --- a/Streetwriters.Identity/Handlers/TokenResponseHandler.cs +++ b/Streetwriters.Identity/Handlers/TokenResponseHandler.cs @@ -1,43 +1,43 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. -// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. - -using IdentityServer4.Services; -using IdentityServer4.Stores; -using IdentityServer4.Validation; -using Microsoft.Extensions.Logging; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authentication; - -namespace IdentityServer4.ResponseHandling -{ - /// - /// The default token response generator - /// - /// - public class TokenResponseHandler : TokenResponseGenerator, ITokenResponseGenerator - { - /// - /// Initializes a new instance of the class. - /// - /// The clock. - /// The token service. - /// The refresh token service. - /// The scope parser. - /// The resources. - /// The clients. - /// The logger. - public TokenResponseHandler(ISystemClock clock, ITokenService tokenService, IRefreshTokenService refreshTokenService, IScopeParser scopeParser, IResourceStore resources, IClientStore clients, ILogger logger) - : base(clock, tokenService, refreshTokenService, scopeParser, resources, clients, logger) - { - - } - - protected override async Task ProcessRefreshTokenRequestAsync(TokenRequestValidationResult request) - { - var response = await base.ProcessRefreshTokenRequestAsync(request); - // Fixes: https://github.com/IdentityServer/IdentityServer3/issues/3621 - response.IdentityToken = null; - return response; - } - } +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + +using IdentityServer4.Services; +using IdentityServer4.Stores; +using IdentityServer4.Validation; +using Microsoft.Extensions.Logging; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; + +namespace IdentityServer4.ResponseHandling +{ + /// + /// The default token response generator + /// + /// + public class TokenResponseHandler : TokenResponseGenerator, ITokenResponseGenerator + { + /// + /// Initializes a new instance of the class. + /// + /// The clock. + /// The token service. + /// The refresh token service. + /// The scope parser. + /// The resources. + /// The clients. + /// The logger. + public TokenResponseHandler(ISystemClock clock, ITokenService tokenService, IRefreshTokenService refreshTokenService, IScopeParser scopeParser, IResourceStore resources, IClientStore clients, ILogger logger) + : base(clock, tokenService, refreshTokenService, scopeParser, resources, clients, logger) + { + + } + + protected override async Task ProcessRefreshTokenRequestAsync(TokenRequestValidationResult request) + { + var response = await base.ProcessRefreshTokenRequestAsync(request); + // Fixes: https://github.com/IdentityServer/IdentityServer3/issues/3621 + response.IdentityToken = null; + return response; + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Interfaces/IEmailTemplate.cs b/Streetwriters.Identity/Interfaces/IEmailTemplate.cs index f2de07e..3321fbc 100644 --- a/Streetwriters.Identity/Interfaces/IEmailTemplate.cs +++ b/Streetwriters.Identity/Interfaces/IEmailTemplate.cs @@ -1,31 +1,31 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -namespace Streetwriters.Identity.Interfaces -{ - public interface IEmailTemplate - { - string Subject { get; set; } - string Html { get; set; } - string Text { get; set; } - int? Id { get; set; } - object Data { get; set; } - long? SendAt { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +namespace Streetwriters.Identity.Interfaces +{ + public interface IEmailTemplate + { + string Subject { get; set; } + string Html { get; set; } + string Text { get; set; } + int? Id { get; set; } + object Data { get; set; } + long? SendAt { get; set; } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Interfaces/IMFAService.cs b/Streetwriters.Identity/Interfaces/IMFAService.cs index 7e3e1a9..e7de264 100644 --- a/Streetwriters.Identity/Interfaces/IMFAService.cs +++ b/Streetwriters.Identity/Interfaces/IMFAService.cs @@ -1,41 +1,41 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Threading.Tasks; -using Streetwriters.Common.Interfaces; -using Streetwriters.Common.Models; -using Streetwriters.Identity.Models; - -namespace Streetwriters.Identity.Interfaces -{ - public interface IMFAService - { - Task EnableMFAAsync(User user, string primaryMethod); - Task DisableMFAAsync(User user); - Task ResetMFAAsync(User user); - Task SetSecondaryMethodAsync(User user, string secondaryMethod); - string GetPrimaryMethod(User user); - string GetSecondaryMethod(User user); - Task GetRemainingValidCodesAsync(User user); - bool IsValidMFAMethod(string method); - Task GetAuthenticatorDetailsAsync(User user, IClient client); - Task SendOTPAsync(User user, IClient client, MultiFactorSetupForm form, bool isSetup = false); - Task VerifyOTPAsync(User user, string code, string method); - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Threading.Tasks; +using Streetwriters.Common.Interfaces; +using Streetwriters.Common.Models; +using Streetwriters.Identity.Models; + +namespace Streetwriters.Identity.Interfaces +{ + public interface IMFAService + { + Task EnableMFAAsync(User user, string primaryMethod); + Task DisableMFAAsync(User user); + Task ResetMFAAsync(User user); + Task SetSecondaryMethodAsync(User user, string secondaryMethod); + string GetPrimaryMethod(User user); + string GetSecondaryMethod(User user); + Task GetRemainingValidCodesAsync(User user); + bool IsValidMFAMethod(string method); + Task GetAuthenticatorDetailsAsync(User user, IClient client); + Task SendOTPAsync(User user, IClient client, MultiFactorSetupForm form, bool isSetup = false); + Task VerifyOTPAsync(User user, string code, string method); + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Interfaces/ISMSSender.cs b/Streetwriters.Identity/Interfaces/ISMSSender.cs index 7298ab2..ada2bdf 100644 --- a/Streetwriters.Identity/Interfaces/ISMSSender.cs +++ b/Streetwriters.Identity/Interfaces/ISMSSender.cs @@ -1,30 +1,30 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Threading.Tasks; -using Streetwriters.Common.Interfaces; - -namespace Streetwriters.Identity.Interfaces -{ - public interface ISMSSender - { - Task SendOTPAsync(string number, IClient client); - Task VerifyOTPAsync(string id, string code); - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Threading.Tasks; +using Streetwriters.Common.Interfaces; + +namespace Streetwriters.Identity.Interfaces +{ + public interface ISMSSender + { + Task SendOTPAsync(string number, IClient client); + Task VerifyOTPAsync(string id, string code); + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Interfaces/ITokenGenerationService.cs b/Streetwriters.Identity/Interfaces/ITokenGenerationService.cs index 6048c14..53b61bf 100644 --- a/Streetwriters.Identity/Interfaces/ITokenGenerationService.cs +++ b/Streetwriters.Identity/Interfaces/ITokenGenerationService.cs @@ -1,33 +1,33 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Security.Claims; -using System.Threading.Tasks; -using IdentityServer4.Validation; -using Streetwriters.Common.Models; - -namespace Streetwriters.Identity.Interfaces -{ - public interface ITokenGenerationService - { - Task CreateAccessTokenAsync(User user, string clientId); - Task CreateAccessTokenFromValidatedRequestAsync(ValidatedTokenRequest validatedRequest, User user, string[] scopes, int lifetime = 60); - Task TransformTokenRequestAsync(ValidatedTokenRequest request, User user, string grantType, string[] scopes, int lifetime = 20 * 60); - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Security.Claims; +using System.Threading.Tasks; +using IdentityServer4.Validation; +using Streetwriters.Common.Models; + +namespace Streetwriters.Identity.Interfaces +{ + public interface ITokenGenerationService + { + Task CreateAccessTokenAsync(User user, string clientId); + Task CreateAccessTokenFromValidatedRequestAsync(ValidatedTokenRequest validatedRequest, User user, string[] scopes, int lifetime = 60); + Task TransformTokenRequestAsync(ValidatedTokenRequest request, User user, string grantType, string[] scopes, int lifetime = 20 * 60); + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Jobs/TokenCleanupJob.cs b/Streetwriters.Identity/Jobs/TokenCleanupJob.cs index f2d61a6..5bc8259 100644 --- a/Streetwriters.Identity/Jobs/TokenCleanupJob.cs +++ b/Streetwriters.Identity/Jobs/TokenCleanupJob.cs @@ -1,20 +1,20 @@ -using System.Threading.Tasks; -using Quartz; -using Streetwriters.Identity.Services; - -namespace Streetwriters.Identity.Jobs -{ - public class TokenCleanupJob : IJob - { - private TokenCleanup TokenCleanup { get; set; } - public TokenCleanupJob(TokenCleanup tokenCleanup) - { - TokenCleanup = tokenCleanup; - } - - public Task Execute(IJobExecutionContext context) - { - return TokenCleanup.RemoveExpiredGrantsAsync(); - } - } +using System.Threading.Tasks; +using Quartz; +using Streetwriters.Identity.Services; + +namespace Streetwriters.Identity.Jobs +{ + public class TokenCleanupJob : IJob + { + private TokenCleanup TokenCleanup { get; set; } + public TokenCleanupJob(TokenCleanup tokenCleanup) + { + TokenCleanup = tokenCleanup; + } + + public Task Execute(IJobExecutionContext context) + { + return TokenCleanup.RemoveExpiredGrantsAsync(); + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/MessageHandlers/CreateSubscription.cs b/Streetwriters.Identity/MessageHandlers/CreateSubscription.cs index 47aa889..4bd4e9e 100644 --- a/Streetwriters.Identity/MessageHandlers/CreateSubscription.cs +++ b/Streetwriters.Identity/MessageHandlers/CreateSubscription.cs @@ -1,49 +1,49 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Threading.Tasks; -using Streetwriters.Common.Messages; -using Streetwriters.Common.Models; -using Streetwriters.Common; -using Microsoft.AspNetCore.Identity; -using System.Security.Claims; -using System.Linq; -using Streetwriters.Identity.Services; - -namespace Streetwriters.Identity.MessageHandlers -{ - public class CreateSubscription - { - public static async Task Process(CreateSubscriptionMessage message, UserManager userManager) - { - var user = await userManager.FindByIdAsync(message.UserId); - var client = Clients.FindClientByAppId(message.AppId); - if (client == null || user == null) return; - - IdentityUserClaim statusClaim = user.Claims.FirstOrDefault((c) => c.ClaimType == UserService.GetClaimKey(client.Id)); - Claim subscriptionClaim = UserService.SubscriptionTypeToClaim(client.Id, message.Type); - if (statusClaim?.ClaimValue == subscriptionClaim.Value) return; - if (statusClaim != null) - await userManager.ReplaceClaimAsync(user, statusClaim.ToClaim(), subscriptionClaim); - else - await userManager.AddClaimAsync(user, subscriptionClaim); - } - - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Threading.Tasks; +using Streetwriters.Common.Messages; +using Streetwriters.Common.Models; +using Streetwriters.Common; +using Microsoft.AspNetCore.Identity; +using System.Security.Claims; +using System.Linq; +using Streetwriters.Identity.Services; + +namespace Streetwriters.Identity.MessageHandlers +{ + public class CreateSubscription + { + public static async Task Process(CreateSubscriptionMessage message, UserManager userManager) + { + var user = await userManager.FindByIdAsync(message.UserId); + var client = Clients.FindClientByAppId(message.AppId); + if (client == null || user == null) return; + + IdentityUserClaim statusClaim = user.Claims.FirstOrDefault((c) => c.ClaimType == UserService.GetClaimKey(client.Id)); + Claim subscriptionClaim = UserService.SubscriptionTypeToClaim(client.Id, message.Type); + if (statusClaim?.ClaimValue == subscriptionClaim.Value) return; + if (statusClaim != null) + await userManager.ReplaceClaimAsync(user, statusClaim.ToClaim(), subscriptionClaim); + else + await userManager.AddClaimAsync(user, subscriptionClaim); + } + + } } \ No newline at end of file diff --git a/Streetwriters.Identity/MessageHandlers/DeleteSubscription.cs b/Streetwriters.Identity/MessageHandlers/DeleteSubscription.cs index e31c7d5..48d3132 100644 --- a/Streetwriters.Identity/MessageHandlers/DeleteSubscription.cs +++ b/Streetwriters.Identity/MessageHandlers/DeleteSubscription.cs @@ -1,44 +1,44 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Threading.Tasks; -using Streetwriters.Common.Messages; -using Streetwriters.Common.Models; -using Streetwriters.Common; -using Microsoft.AspNetCore.Identity; -using System.Linq; - -namespace Streetwriters.Identity.MessageHandlers -{ - public class DeleteSubscription - { - public static async Task Process(DeleteSubscriptionMessage message, UserManager userManager) - { - var user = await userManager.FindByIdAsync(message.UserId); - var client = Clients.FindClientByAppId(message.AppId); - if (client != null || user != null) return; - - IdentityUserClaim statusClaim = user.Claims.FirstOrDefault((c) => c.ClaimType == $"{client.Id}:status"); - if (statusClaim != null) - { - await userManager.RemoveClaimAsync(user, statusClaim.ToClaim()); - } - } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Threading.Tasks; +using Streetwriters.Common.Messages; +using Streetwriters.Common.Models; +using Streetwriters.Common; +using Microsoft.AspNetCore.Identity; +using System.Linq; + +namespace Streetwriters.Identity.MessageHandlers +{ + public class DeleteSubscription + { + public static async Task Process(DeleteSubscriptionMessage message, UserManager userManager) + { + var user = await userManager.FindByIdAsync(message.UserId); + var client = Clients.FindClientByAppId(message.AppId); + if (client != null || user != null) return; + + IdentityUserClaim statusClaim = user.Claims.FirstOrDefault((c) => c.ClaimType == $"{client.Id}:status"); + if (statusClaim != null) + { + await userManager.RemoveClaimAsync(user, statusClaim.ToClaim()); + } + } + } +} diff --git a/Streetwriters.Identity/Models/AuthenticatorDetails.cs b/Streetwriters.Identity/Models/AuthenticatorDetails.cs index f54cac2..0b5aa15 100644 --- a/Streetwriters.Identity/Models/AuthenticatorDetails.cs +++ b/Streetwriters.Identity/Models/AuthenticatorDetails.cs @@ -1,34 +1,34 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -namespace Streetwriters.Identity.Models -{ - public class AuthenticatorDetails - { - public string SharedKey - { - get; set; - } - - public string AuthenticatorUri - { - get; set; - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +namespace Streetwriters.Identity.Models +{ + public class AuthenticatorDetails + { + public string SharedKey + { + get; set; + } + + public string AuthenticatorUri + { + get; set; + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Models/ChangeEmailForm.cs b/Streetwriters.Identity/Models/ChangeEmailForm.cs index ec58fe1..eeb5278 100644 --- a/Streetwriters.Identity/Models/ChangeEmailForm.cs +++ b/Streetwriters.Identity/Models/ChangeEmailForm.cs @@ -1,39 +1,39 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; - -namespace Streetwriters.Identity.Models -{ - public class ChangeEmailForm - { - [Required] - [BindProperty(Name = "email")] - [EmailAddress] - public string NewEmail - { - get; set; - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +namespace Streetwriters.Identity.Models +{ + public class ChangeEmailForm + { + [Required] + [BindProperty(Name = "email")] + [EmailAddress] + public string NewEmail + { + get; set; + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Models/GetAccessTokenForm.cs b/Streetwriters.Identity/Models/GetAccessTokenForm.cs index b4ce719..897d4c1 100644 --- a/Streetwriters.Identity/Models/GetAccessTokenForm.cs +++ b/Streetwriters.Identity/Models/GetAccessTokenForm.cs @@ -1,49 +1,49 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.ComponentModel.DataAnnotations; -using System.Runtime.Serialization; -using Microsoft.AspNetCore.Mvc; - -namespace Streetwriters.Identity.Models -{ - public class GetAccessTokenForm - { - [Required] - [BindProperty(Name = "authorization_code")] - public string Code - { - get; set; - } - - [Required] - [BindProperty(Name = "user_id")] - public string UserId - { - get; set; - } - - [Required] - [BindProperty(Name = "client_id")] - public string ClientId - { - get; set; - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; +using Microsoft.AspNetCore.Mvc; + +namespace Streetwriters.Identity.Models +{ + public class GetAccessTokenForm + { + [Required] + [BindProperty(Name = "authorization_code")] + public string Code + { + get; set; + } + + [Required] + [BindProperty(Name = "user_id")] + public string UserId + { + get; set; + } + + [Required] + [BindProperty(Name = "client_id")] + public string ClientId + { + get; set; + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Models/MFAPasswordRequiredResponse.cs b/Streetwriters.Identity/Models/MFAPasswordRequiredResponse.cs index 86b004a..85882bd 100644 --- a/Streetwriters.Identity/Models/MFAPasswordRequiredResponse.cs +++ b/Streetwriters.Identity/Models/MFAPasswordRequiredResponse.cs @@ -1,29 +1,29 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Text.Json.Serialization; - -namespace Streetwriters.Identity.Models -{ - public class MFAPasswordRequiredResponse - { - [JsonPropertyName("token")] - public string Token { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Text.Json.Serialization; + +namespace Streetwriters.Identity.Models +{ + public class MFAPasswordRequiredResponse + { + [JsonPropertyName("token")] + public string Token { get; set; } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Models/MFARequiredResponse.cs b/Streetwriters.Identity/Models/MFARequiredResponse.cs index 9cf2a48..d812ad4 100644 --- a/Streetwriters.Identity/Models/MFARequiredResponse.cs +++ b/Streetwriters.Identity/Models/MFARequiredResponse.cs @@ -1,35 +1,35 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Text.Json.Serialization; - -namespace Streetwriters.Identity.Models -{ - public class MFARequiredResponse - { - [JsonPropertyName("primaryMethod")] - public string PrimaryMethod { get; set; } - [JsonPropertyName("secondaryMethod")] - public string SecondaryMethod { get; set; } - [JsonPropertyName("token")] - public string Token { get; set; } - [JsonPropertyName("phoneNumber")] - public string PhoneNumber { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Text.Json.Serialization; + +namespace Streetwriters.Identity.Models +{ + public class MFARequiredResponse + { + [JsonPropertyName("primaryMethod")] + public string PrimaryMethod { get; set; } + [JsonPropertyName("secondaryMethod")] + public string SecondaryMethod { get; set; } + [JsonPropertyName("token")] + public string Token { get; set; } + [JsonPropertyName("phoneNumber")] + public string PhoneNumber { get; set; } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Models/MultiFactorEnableForm.cs b/Streetwriters.Identity/Models/MultiFactorEnableForm.cs index 34ec868..35a015a 100644 --- a/Streetwriters.Identity/Models/MultiFactorEnableForm.cs +++ b/Streetwriters.Identity/Models/MultiFactorEnableForm.cs @@ -1,43 +1,43 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.ComponentModel.DataAnnotations; -using Microsoft.AspNetCore.Mvc; - -namespace Streetwriters.Identity.Models -{ - public class MultiFactorEnableForm - { - [Required] - [DataType(DataType.Text)] - [Display(Name = "Authenticator type")] - [BindProperty(Name = "type")] - public string Type { get; set; } - - [Required] - [StringLength(6, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] - [DataType(DataType.Text)] - [Display(Name = "Verification Code")] - [BindProperty(Name = "code")] - public string VerificationCode { get; set; } - - [BindProperty(Name = "isFallback")] - public bool IsFallback { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Mvc; + +namespace Streetwriters.Identity.Models +{ + public class MultiFactorEnableForm + { + [Required] + [DataType(DataType.Text)] + [Display(Name = "Authenticator type")] + [BindProperty(Name = "type")] + public string Type { get; set; } + + [Required] + [StringLength(6, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] + [DataType(DataType.Text)] + [Display(Name = "Verification Code")] + [BindProperty(Name = "code")] + public string VerificationCode { get; set; } + + [BindProperty(Name = "isFallback")] + public bool IsFallback { get; set; } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Models/MultiFactorSetupForm.cs b/Streetwriters.Identity/Models/MultiFactorSetupForm.cs index 6379fe9..9709649 100644 --- a/Streetwriters.Identity/Models/MultiFactorSetupForm.cs +++ b/Streetwriters.Identity/Models/MultiFactorSetupForm.cs @@ -1,37 +1,37 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.ComponentModel.DataAnnotations; -using System.Runtime.Serialization; -using Microsoft.AspNetCore.Mvc; - -namespace Streetwriters.Identity.Models -{ - public class MultiFactorSetupForm - { - [Required] - [Display(Name = "Authenticator type")] - [BindProperty(Name = "type")] - public string Type { get; set; } - - [Display(Name = "Phone number")] - [BindProperty(Name = "phoneNumber")] - public string PhoneNumber { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; +using Microsoft.AspNetCore.Mvc; + +namespace Streetwriters.Identity.Models +{ + public class MultiFactorSetupForm + { + [Required] + [Display(Name = "Authenticator type")] + [BindProperty(Name = "type")] + public string Type { get; set; } + + [Display(Name = "Phone number")] + [BindProperty(Name = "phoneNumber")] + public string PhoneNumber { get; set; } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Models/ResetPasswordForm.cs b/Streetwriters.Identity/Models/ResetPasswordForm.cs index fb5c9e8..2af9746 100644 --- a/Streetwriters.Identity/Models/ResetPasswordForm.cs +++ b/Streetwriters.Identity/Models/ResetPasswordForm.cs @@ -1,42 +1,42 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.ComponentModel.DataAnnotations; -using System.Runtime.Serialization; -using Microsoft.AspNetCore.Mvc; - -namespace Streetwriters.Identity.Models -{ - public class ResetPasswordForm - { - [Required] - [BindProperty(Name = "email")] - public string Email - { - get; set; - } - - [Required] - [BindProperty(Name = "client_id")] - public string ClientId - { - get; set; - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; +using Microsoft.AspNetCore.Mvc; + +namespace Streetwriters.Identity.Models +{ + public class ResetPasswordForm + { + [Required] + [BindProperty(Name = "email")] + public string Email + { + get; set; + } + + [Required] + [BindProperty(Name = "client_id")] + public string ClientId + { + get; set; + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Models/SignupForm.cs b/Streetwriters.Identity/Models/SignupForm.cs index a18e9c2..92b17ca 100644 --- a/Streetwriters.Identity/Models/SignupForm.cs +++ b/Streetwriters.Identity/Models/SignupForm.cs @@ -1,57 +1,57 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.ComponentModel.DataAnnotations; -using System.Runtime.Serialization; -using Microsoft.AspNetCore.Mvc; - -namespace Streetwriters.Identity.Models -{ - public class SignupForm - { - [Required] - [StringLength(120, ErrorMessage = "Password must be longer than or equal to 8 characters.", MinimumLength = 8)] - [BindProperty(Name = "password")] - public string Password - { - get; set; - } - - [Required] - [BindProperty(Name = "email")] - [EmailAddress] - public string Email - { - get; set; - } - - [BindProperty(Name = "username")] - public string Username - { - get; set; - } - - [Required] - [BindProperty(Name = "client_id")] - public string ClientId - { - get; set; - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; +using Microsoft.AspNetCore.Mvc; + +namespace Streetwriters.Identity.Models +{ + public class SignupForm + { + [Required] + [StringLength(120, ErrorMessage = "Password must be longer than or equal to 8 characters.", MinimumLength = 8)] + [BindProperty(Name = "password")] + public string Password + { + get; set; + } + + [Required] + [BindProperty(Name = "email")] + [EmailAddress] + public string Email + { + get; set; + } + + [BindProperty(Name = "username")] + public string Username + { + get; set; + } + + [Required] + [BindProperty(Name = "client_id")] + public string ClientId + { + get; set; + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Models/TwoFactorLoginForm.cs b/Streetwriters.Identity/Models/TwoFactorLoginForm.cs index de40c58..0e12d08 100644 --- a/Streetwriters.Identity/Models/TwoFactorLoginForm.cs +++ b/Streetwriters.Identity/Models/TwoFactorLoginForm.cs @@ -1,41 +1,41 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.ComponentModel.DataAnnotations; -using System.Runtime.Serialization; -using Microsoft.AspNetCore.Mvc; - -namespace Streetwriters.Identity.Models -{ - public class TwoFactorLoginForm - { - [Required] - [StringLength(7, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] - [DataType(DataType.Text)] - [Display(Name = "Authenticator code")] - [BindProperty(Name = "code")] - public string Code { get; set; } - - [BindProperty(Name = "rememberMachine")] - public bool RememberMachine { get; set; } - - [BindProperty(Name = "isRecoveryCode")] - public bool IsRecoveryCode { get; set; } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; +using Microsoft.AspNetCore.Mvc; + +namespace Streetwriters.Identity.Models +{ + public class TwoFactorLoginForm + { + [Required] + [StringLength(7, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] + [DataType(DataType.Text)] + [Display(Name = "Authenticator code")] + [BindProperty(Name = "code")] + public string Code { get; set; } + + [BindProperty(Name = "rememberMachine")] + public bool RememberMachine { get; set; } + + [BindProperty(Name = "isRecoveryCode")] + public bool IsRecoveryCode { get; set; } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Models/UpdateUserForm.cs b/Streetwriters.Identity/Models/UpdateUserForm.cs index 3136e05..774c0cb 100644 --- a/Streetwriters.Identity/Models/UpdateUserForm.cs +++ b/Streetwriters.Identity/Models/UpdateUserForm.cs @@ -1,73 +1,73 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.ComponentModel.DataAnnotations; -using System.Runtime.Serialization; -using Microsoft.AspNetCore.Mvc; - -namespace Streetwriters.Identity.Models -{ - public class UpdateUserForm - { - [Required] - [BindProperty(Name = "type")] - public string Type - { - get; set; - } - - [BindProperty(Name = "enabled")] - public bool Enabled - { - get; set; - } - - [BindProperty(Name = "old_password")] - public string OldPassword - { - get; set; - } - - [BindProperty(Name = "new_password")] - public string NewPassword - { - get; set; - } - - - [BindProperty(Name = "password")] - public string Password - { - get; set; - } - - [BindProperty(Name = "new_email")] - public string NewEmail - { - get; set; - } - - - [BindProperty(Name = "verification_code")] - public string VerificationCode - { - get; set; - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; +using Microsoft.AspNetCore.Mvc; + +namespace Streetwriters.Identity.Models +{ + public class UpdateUserForm + { + [Required] + [BindProperty(Name = "type")] + public string Type + { + get; set; + } + + [BindProperty(Name = "enabled")] + public bool Enabled + { + get; set; + } + + [BindProperty(Name = "old_password")] + public string OldPassword + { + get; set; + } + + [BindProperty(Name = "new_password")] + public string NewPassword + { + get; set; + } + + + [BindProperty(Name = "password")] + public string Password + { + get; set; + } + + [BindProperty(Name = "new_email")] + public string NewEmail + { + get; set; + } + + + [BindProperty(Name = "verification_code")] + public string VerificationCode + { + get; set; + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Properties/launchSettings.json b/Streetwriters.Identity/Properties/launchSettings.json index 34d594e..fe7af12 100644 --- a/Streetwriters.Identity/Properties/launchSettings.json +++ b/Streetwriters.Identity/Properties/launchSettings.json @@ -1,30 +1,30 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:10770", - "sslPort": 44374 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "weatherforecast", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "Streetwriters.Identity": { - "commandName": "Project", - "launchBrowser": true, - "launchUrl": "weatherforecast", - "applicationUrl": "http://localhost:5000", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:10770", + "sslPort": 44374 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "weatherforecast", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Streetwriters.Identity": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "weatherforecast", + "applicationUrl": "http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/Streetwriters.Identity/Services/CustomIntrospectionResponseGenerator.cs b/Streetwriters.Identity/Services/CustomIntrospectionResponseGenerator.cs index 33fc89e..0d8b7f6 100644 --- a/Streetwriters.Identity/Services/CustomIntrospectionResponseGenerator.cs +++ b/Streetwriters.Identity/Services/CustomIntrospectionResponseGenerator.cs @@ -1,68 +1,68 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Threading.Tasks; -using IdentityServer4.Endpoints.Results; -using IdentityServer4.Models; -using IdentityServer4.ResponseHandling; -using IdentityServer4.Services; -using IdentityServer4.Validation; -using Microsoft.AspNetCore.Identity; -using Microsoft.Extensions.Logging; -using Streetwriters.Common.Models; - -namespace Streetwriters.Identity.Services -{ - public class CustomIntrospectionResponseGenerator : IntrospectionResponseGenerator - { - private UserManager UserManager { get; } - public CustomIntrospectionResponseGenerator(IEventService events, ILogger logger, UserManager userManager) : base(events, logger) - { - UserManager = userManager; - } - - public override async Task> ProcessAsync(IntrospectionRequestValidationResult validationResult) - { - var result = await base.ProcessAsync(validationResult); - - if (result.TryGetValue("sub", out object userId)) - { - var user = await UserManager.FindByIdAsync(userId.ToString()); - if (user == null || user.Claims == null) return result; - - var verifiedClaim = user.Claims.Find((c) => c.ClaimType == "verified"); - if (verifiedClaim != null) - await UserManager.RemoveClaimAsync(user, verifiedClaim.ToClaim()); - var hcliClaim = user.Claims.Find((c) => c.ClaimType == "hcli"); - if (hcliClaim != null) - await UserManager.RemoveClaimAsync(user, hcliClaim.ToClaim()); - - user.Claims.ForEach((claim) => - { - if (claim.ClaimType == "verified" || claim.ClaimType == "hcli") return; - result.TryAdd(claim.ClaimType, claim.ClaimValue); - }); - result.TryAdd("verified", user.EmailConfirmed.ToString().ToLowerInvariant()); - } - return result; - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Threading.Tasks; +using IdentityServer4.Endpoints.Results; +using IdentityServer4.Models; +using IdentityServer4.ResponseHandling; +using IdentityServer4.Services; +using IdentityServer4.Validation; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Logging; +using Streetwriters.Common.Models; + +namespace Streetwriters.Identity.Services +{ + public class CustomIntrospectionResponseGenerator : IntrospectionResponseGenerator + { + private UserManager UserManager { get; } + public CustomIntrospectionResponseGenerator(IEventService events, ILogger logger, UserManager userManager) : base(events, logger) + { + UserManager = userManager; + } + + public override async Task> ProcessAsync(IntrospectionRequestValidationResult validationResult) + { + var result = await base.ProcessAsync(validationResult); + + if (result.TryGetValue("sub", out object userId)) + { + var user = await UserManager.FindByIdAsync(userId.ToString()); + if (user == null || user.Claims == null) return result; + + var verifiedClaim = user.Claims.Find((c) => c.ClaimType == "verified"); + if (verifiedClaim != null) + await UserManager.RemoveClaimAsync(user, verifiedClaim.ToClaim()); + var hcliClaim = user.Claims.Find((c) => c.ClaimType == "hcli"); + if (hcliClaim != null) + await UserManager.RemoveClaimAsync(user, hcliClaim.ToClaim()); + + user.Claims.ForEach((claim) => + { + if (claim.ClaimType == "verified" || claim.ClaimType == "hcli") return; + result.TryAdd(claim.ClaimType, claim.ClaimValue); + }); + result.TryAdd("verified", user.EmailConfirmed.ToString().ToLowerInvariant()); + } + return result; + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Services/CustomRefreshTokenService.cs b/Streetwriters.Identity/Services/CustomRefreshTokenService.cs index bf6b731..cb8e0bd 100644 --- a/Streetwriters.Identity/Services/CustomRefreshTokenService.cs +++ b/Streetwriters.Identity/Services/CustomRefreshTokenService.cs @@ -1,43 +1,43 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Threading.Tasks; -using IdentityServer4.Models; -using IdentityServer4.Services; -using IdentityServer4.Stores; -using Microsoft.AspNetCore.Authentication; -using Microsoft.Extensions.Logging; - -namespace Streetwriters.Identity.Services -{ - public class CustomRefreshTokenService : DefaultRefreshTokenService - { - public CustomRefreshTokenService(IRefreshTokenStore refreshTokenStore, IProfileService profile, ISystemClock clock, ILogger logger) : base(refreshTokenStore, profile, clock, logger) - { - } - - protected override Task AcceptConsumedTokenAsync(RefreshToken refreshToken) - { - // Allow refresh token replay for 1 day. - // if (refreshToken.ConsumedTime?.ToUniversalTime().AddDays(1) < DateTime.UtcNow) return Task.FromResult(false); - return Task.FromResult(true); - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Threading.Tasks; +using IdentityServer4.Models; +using IdentityServer4.Services; +using IdentityServer4.Stores; +using Microsoft.AspNetCore.Authentication; +using Microsoft.Extensions.Logging; + +namespace Streetwriters.Identity.Services +{ + public class CustomRefreshTokenService : DefaultRefreshTokenService + { + public CustomRefreshTokenService(IRefreshTokenStore refreshTokenStore, IProfileService profile, ISystemClock clock, ILogger logger) : base(refreshTokenStore, profile, clock, logger) + { + } + + protected override Task AcceptConsumedTokenAsync(RefreshToken refreshToken) + { + // Allow refresh token replay for 1 day. + // if (refreshToken.ConsumedTime?.ToUniversalTime().AddDays(1) < DateTime.UtcNow) return Task.FromResult(false); + return Task.FromResult(true); + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Services/EmailAddressValidator.cs b/Streetwriters.Identity/Services/EmailAddressValidator.cs index ca7d36f..b2418d0 100644 --- a/Streetwriters.Identity/Services/EmailAddressValidator.cs +++ b/Streetwriters.Identity/Services/EmailAddressValidator.cs @@ -1,38 +1,38 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Threading.Tasks; -using Streetwriters.Common; -using System.Linq; - -namespace Streetwriters.Identity.Services -{ - public class EmailAddressValidator - { - private static DateTimeOffset LAST_FETCH_TIME = DateTimeOffset.MinValue; - private static HashSet BLACKLISTED_DOMAINS = new(); - - public static async Task IsEmailAddressValidAsync(string email) - { - var domain = email.ToLowerInvariant().Split("@")[1]; - try - { - if (LAST_FETCH_TIME.AddDays(1) < DateTimeOffset.UtcNow) - { - var httpClient = new HttpClient(); - var domainsList = await httpClient.GetStringAsync("https://raw.githubusercontent.com/disposable-email-domains/disposable-email-domains/master/disposable_email_blocklist.conf"); - var domains = domainsList.Split('\n').Where(line => !string.IsNullOrWhiteSpace(line) && !line.TrimStart().StartsWith("//")); - BLACKLISTED_DOMAINS = new HashSet(domains, StringComparer.OrdinalIgnoreCase); - LAST_FETCH_TIME = DateTimeOffset.UtcNow; - } - - return !BLACKLISTED_DOMAINS.Contains(domain); - } - catch (Exception ex) - { - await Slogger.Error("IsEmailAddressValidAsync", ex.ToString()); - return BLACKLISTED_DOMAINS.Count > 0 ? !BLACKLISTED_DOMAINS.Contains(domain) : true; - } - } - } +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using Streetwriters.Common; +using System.Linq; + +namespace Streetwriters.Identity.Services +{ + public class EmailAddressValidator + { + private static DateTimeOffset LAST_FETCH_TIME = DateTimeOffset.MinValue; + private static HashSet BLACKLISTED_DOMAINS = new(); + + public static async Task IsEmailAddressValidAsync(string email) + { + var domain = email.ToLowerInvariant().Split("@")[1]; + try + { + if (LAST_FETCH_TIME.AddDays(1) < DateTimeOffset.UtcNow) + { + var httpClient = new HttpClient(); + var domainsList = await httpClient.GetStringAsync("https://raw.githubusercontent.com/disposable-email-domains/disposable-email-domains/master/disposable_email_blocklist.conf"); + var domains = domainsList.Split('\n').Where(line => !string.IsNullOrWhiteSpace(line) && !line.TrimStart().StartsWith("//")); + BLACKLISTED_DOMAINS = new HashSet(domains, StringComparer.OrdinalIgnoreCase); + LAST_FETCH_TIME = DateTimeOffset.UtcNow; + } + + return !BLACKLISTED_DOMAINS.Contains(domain); + } + catch (Exception ex) + { + await Slogger.Error("IsEmailAddressValidAsync", ex.ToString()); + return BLACKLISTED_DOMAINS.Count > 0 ? !BLACKLISTED_DOMAINS.Contains(domain) : true; + } + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Services/ProfileService.cs b/Streetwriters.Identity/Services/ProfileService.cs index 311f8b6..129cba1 100644 --- a/Streetwriters.Identity/Services/ProfileService.cs +++ b/Streetwriters.Identity/Services/ProfileService.cs @@ -1,61 +1,61 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Claims; -using System.Threading.Tasks; -using IdentityModel; -using IdentityServer4.Models; -using IdentityServer4.Services; -using Microsoft.AspNetCore.Identity; -using Streetwriters.Common.Enums; -using Streetwriters.Common.Models; -using Streetwriters.Data.Repositories; - -namespace Streetwriters.Identity.Services -{ - public class ProfileService : IProfileService - { - protected UserManager UserManager { get; set; } - - public ProfileService(UserManager userManager) - { - UserManager = userManager; - } - - public async Task GetProfileDataAsync(ProfileDataRequestContext context) - { - User user = await UserManager.GetUserAsync(context.Subject); - if (user == null) return; - - IList roles = await UserManager.GetRolesAsync(user); - IList claims = user.Claims.Select((c) => c.ToClaim()).ToList(); - - context.IssuedClaims.AddRange(roles.Select((r) => new Claim(JwtClaimTypes.Role, r))); - context.IssuedClaims.AddRange(claims); - } - - public Task IsActiveAsync(IsActiveContext context) - { - return Task.CompletedTask; - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using IdentityModel; +using IdentityServer4.Models; +using IdentityServer4.Services; +using Microsoft.AspNetCore.Identity; +using Streetwriters.Common.Enums; +using Streetwriters.Common.Models; +using Streetwriters.Data.Repositories; + +namespace Streetwriters.Identity.Services +{ + public class ProfileService : IProfileService + { + protected UserManager UserManager { get; set; } + + public ProfileService(UserManager userManager) + { + UserManager = userManager; + } + + public async Task GetProfileDataAsync(ProfileDataRequestContext context) + { + User user = await UserManager.GetUserAsync(context.Subject); + if (user == null) return; + + IList roles = await UserManager.GetRolesAsync(user); + IList claims = user.Claims.Select((c) => c.ToClaim()).ToList(); + + context.IssuedClaims.AddRange(roles.Select((r) => new Claim(JwtClaimTypes.Role, r))); + context.IssuedClaims.AddRange(claims); + } + + public Task IsActiveAsync(IsActiveContext context) + { + return Task.CompletedTask; + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Services/SMSSender.cs b/Streetwriters.Identity/Services/SMSSender.cs index fa13853..88986aa 100644 --- a/Streetwriters.Identity/Services/SMSSender.cs +++ b/Streetwriters.Identity/Services/SMSSender.cs @@ -1,58 +1,58 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using Streetwriters.Identity.Interfaces; -using Streetwriters.Common.Interfaces; -using Streetwriters.Common; -using Twilio.Rest.Verify.V2.Service; -using Twilio; -using System.Threading.Tasks; - -namespace Streetwriters.Identity.Services -{ - public class SMSSender : ISMSSender - { - public SMSSender() - { - if (!string.IsNullOrEmpty(Constants.TWILIO_ACCOUNT_SID) && !string.IsNullOrEmpty(Constants.TWILIO_AUTH_TOKEN)) - { - TwilioClient.Init(Constants.TWILIO_ACCOUNT_SID, Constants.TWILIO_AUTH_TOKEN); - } - } - - public async Task SendOTPAsync(string number, IClient app) - { - var verification = await VerificationResource.CreateAsync( - to: number, - channel: "sms", - pathServiceSid: Constants.TWILIO_SERVICE_SID - ); - return verification.Sid; - } - - public async Task VerifyOTPAsync(string id, string code) - { - return (await VerificationCheckResource.CreateAsync( - verificationSid: id, - pathServiceSid: Constants.TWILIO_SERVICE_SID, - code: code - )).Status == "approved"; - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using Streetwriters.Identity.Interfaces; +using Streetwriters.Common.Interfaces; +using Streetwriters.Common; +using Twilio.Rest.Verify.V2.Service; +using Twilio; +using System.Threading.Tasks; + +namespace Streetwriters.Identity.Services +{ + public class SMSSender : ISMSSender + { + public SMSSender() + { + if (!string.IsNullOrEmpty(Constants.TWILIO_ACCOUNT_SID) && !string.IsNullOrEmpty(Constants.TWILIO_AUTH_TOKEN)) + { + TwilioClient.Init(Constants.TWILIO_ACCOUNT_SID, Constants.TWILIO_AUTH_TOKEN); + } + } + + public async Task SendOTPAsync(string number, IClient app) + { + var verification = await VerificationResource.CreateAsync( + to: number, + channel: "sms", + pathServiceSid: Constants.TWILIO_SERVICE_SID + ); + return verification.Sid; + } + + public async Task VerifyOTPAsync(string id, string code) + { + return (await VerificationCheckResource.CreateAsync( + verificationSid: id, + pathServiceSid: Constants.TWILIO_SERVICE_SID, + code: code + )).Status == "approved"; + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Services/TokenCleanup.cs b/Streetwriters.Identity/Services/TokenCleanup.cs index 9613b65..6277dc0 100644 --- a/Streetwriters.Identity/Services/TokenCleanup.cs +++ b/Streetwriters.Identity/Services/TokenCleanup.cs @@ -1,51 +1,51 @@ -// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. -// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. - -using IdentityServer4.MongoDB.Interfaces; -using Microsoft.Extensions.Logging; -using System; -using System.Linq; -using System.Threading.Tasks; - -namespace Streetwriters.Identity.Services -{ - public class TokenCleanup - { - private readonly IPersistedGrantDbContext _persistedGrantDbContext; - private readonly ILogger _logger; - - public TokenCleanup(IPersistedGrantDbContext persistedGrantDbContext, ILogger logger) - { - _persistedGrantDbContext = persistedGrantDbContext; - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - } - - /// - /// Method to clear expired persisted grants. - /// - /// - public async Task RemoveExpiredGrantsAsync() - { - try - { - _logger.LogTrace("Querying for expired grants to remove"); - - await RemoveGrantsAsync(); - //TODO: await RemoveDeviceCodesAsync(); - } - catch (Exception ex) - { - _logger.LogError("Exception removing expired grants: {exception}", ex.Message); - } - } - - /// - /// Removes the stale persisted grants. - /// - /// - protected virtual async Task RemoveGrantsAsync() - { - await _persistedGrantDbContext.RemoveExpired(); - } - } +// Copyright (c) Brock Allen & Dominick Baier. All rights reserved. +// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + +using IdentityServer4.MongoDB.Interfaces; +using Microsoft.Extensions.Logging; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Streetwriters.Identity.Services +{ + public class TokenCleanup + { + private readonly IPersistedGrantDbContext _persistedGrantDbContext; + private readonly ILogger _logger; + + public TokenCleanup(IPersistedGrantDbContext persistedGrantDbContext, ILogger logger) + { + _persistedGrantDbContext = persistedGrantDbContext; + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + + /// + /// Method to clear expired persisted grants. + /// + /// + public async Task RemoveExpiredGrantsAsync() + { + try + { + _logger.LogTrace("Querying for expired grants to remove"); + + await RemoveGrantsAsync(); + //TODO: await RemoveDeviceCodesAsync(); + } + catch (Exception ex) + { + _logger.LogError("Exception removing expired grants: {exception}", ex.Message); + } + } + + /// + /// Removes the stale persisted grants. + /// + /// + protected virtual async Task RemoveGrantsAsync() + { + await _persistedGrantDbContext.RemoveExpired(); + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Services/TokenGenerationService.cs b/Streetwriters.Identity/Services/TokenGenerationService.cs index 4395d43..5b9c290 100644 --- a/Streetwriters.Identity/Services/TokenGenerationService.cs +++ b/Streetwriters.Identity/Services/TokenGenerationService.cs @@ -1,118 +1,118 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Linq; -using System.Security.Claims; -using System.Threading.Tasks; -using IdentityModel; -using IdentityServer4; -using IdentityServer4.Configuration; -using IdentityServer4.Models; -using IdentityServer4.Services; -using IdentityServer4.Stores; -using IdentityServer4.Validation; -using Microsoft.AspNetCore.Identity; -using Streetwriters.Common.Models; -using Streetwriters.Identity.Interfaces; - -namespace Streetwriters.Identity.Helpers -{ - public class TokenGenerationService : ITokenGenerationService - { - private IPersistedGrantStore PersistedGrantStore { get; set; } - private ITokenService TokenService { get; set; } - private IUserClaimsPrincipalFactory PrincipalFactory { get; set; } - private IdentityServerOptions ISOptions { get; set; } - private IdentityServerTools Tools { get; set; } - private IResourceStore ResourceStore { get; set; } - public TokenGenerationService(ITokenService tokenService, - IUserClaimsPrincipalFactory principalFactory, - IdentityServerOptions identityServerOptions, - IPersistedGrantStore persistedGrantStore, - IdentityServerTools tools, - IResourceStore resourceStore) - { - TokenService = tokenService; - PrincipalFactory = principalFactory; - ISOptions = identityServerOptions; - PersistedGrantStore = persistedGrantStore; - Tools = tools; - ResourceStore = resourceStore; - } - - public async Task CreateAccessTokenAsync(User user, string clientId) - { - var IdentityPricipal = await PrincipalFactory.CreateAsync(user); - var IdentityUser = new IdentityServerUser(user.Id.ToString()); - IdentityUser.AdditionalClaims = IdentityPricipal.Claims.ToArray(); - IdentityUser.DisplayName = user.UserName; - IdentityUser.AuthenticationTime = System.DateTime.UtcNow; - IdentityUser.IdentityProvider = IdentityServerConstants.LocalIdentityProvider; - var Request = new TokenCreationRequest - { - Subject = IdentityUser.CreatePrincipal(), - IncludeAllIdentityClaims = true, - ValidatedRequest = new ValidatedRequest() - }; - Request.ValidatedRequest.Subject = Request.Subject; - Request.ValidatedRequest.SetClient(Config.Clients.FirstOrDefault((c) => c.ClientId == clientId)); - Request.ValidatedRequest.AccessTokenType = AccessTokenType.Reference; - Request.ValidatedRequest.AccessTokenLifetime = 18000; - Request.ValidatedResources = new ResourceValidationResult(new Resources(Config.IdentityResources, Config.ApiResources, Config.ApiScopes)); - Request.ValidatedRequest.Options = ISOptions; - Request.ValidatedRequest.ClientClaims = IdentityUser.AdditionalClaims; - var accessToken = await TokenService.CreateAccessTokenAsync(Request); - return await TokenService.CreateSecurityTokenAsync(accessToken); - } - - public async Task TransformTokenRequestAsync(ValidatedTokenRequest request, User user, string grantType, string[] scopes, int lifetime = 20 * 60) - { - var principal = await PrincipalFactory.CreateAsync(user); - var identityUser = new IdentityServerUser(user.Id.ToString()) - { - DisplayName = user.UserName, - AuthenticationTime = System.DateTime.UtcNow, - IdentityProvider = IdentityServerConstants.LocalIdentityProvider, - AdditionalClaims = principal.Claims.ToArray() - }; - - request.AccessTokenType = AccessTokenType.Jwt; - request.AccessTokenLifetime = lifetime; - request.GrantType = grantType; - request.ValidatedResources = await ResourceStore.CreateResourceValidationResult(new ParsedScopesResult() - { - ParsedScopes = scopes.Select((scope) => new ParsedScopeValue(scope)).ToArray() - }); - return identityUser.CreatePrincipal(); - } - - public async Task CreateAccessTokenFromValidatedRequestAsync(ValidatedTokenRequest validatedRequest, User user, string[] scopes, int lifetime = 20 * 60) - { - var request = new TokenCreationRequest - { - Subject = await this.TransformTokenRequestAsync(validatedRequest, user, validatedRequest.GrantType, scopes, lifetime), - IncludeAllIdentityClaims = true, - ValidatedRequest = validatedRequest, - ValidatedResources = validatedRequest.ValidatedResources - }; - var accessToken = await TokenService.CreateAccessTokenAsync(request); - return await TokenService.CreateSecurityTokenAsync(accessToken); - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using IdentityModel; +using IdentityServer4; +using IdentityServer4.Configuration; +using IdentityServer4.Models; +using IdentityServer4.Services; +using IdentityServer4.Stores; +using IdentityServer4.Validation; +using Microsoft.AspNetCore.Identity; +using Streetwriters.Common.Models; +using Streetwriters.Identity.Interfaces; + +namespace Streetwriters.Identity.Helpers +{ + public class TokenGenerationService : ITokenGenerationService + { + private IPersistedGrantStore PersistedGrantStore { get; set; } + private ITokenService TokenService { get; set; } + private IUserClaimsPrincipalFactory PrincipalFactory { get; set; } + private IdentityServerOptions ISOptions { get; set; } + private IdentityServerTools Tools { get; set; } + private IResourceStore ResourceStore { get; set; } + public TokenGenerationService(ITokenService tokenService, + IUserClaimsPrincipalFactory principalFactory, + IdentityServerOptions identityServerOptions, + IPersistedGrantStore persistedGrantStore, + IdentityServerTools tools, + IResourceStore resourceStore) + { + TokenService = tokenService; + PrincipalFactory = principalFactory; + ISOptions = identityServerOptions; + PersistedGrantStore = persistedGrantStore; + Tools = tools; + ResourceStore = resourceStore; + } + + public async Task CreateAccessTokenAsync(User user, string clientId) + { + var IdentityPricipal = await PrincipalFactory.CreateAsync(user); + var IdentityUser = new IdentityServerUser(user.Id.ToString()); + IdentityUser.AdditionalClaims = IdentityPricipal.Claims.ToArray(); + IdentityUser.DisplayName = user.UserName; + IdentityUser.AuthenticationTime = System.DateTime.UtcNow; + IdentityUser.IdentityProvider = IdentityServerConstants.LocalIdentityProvider; + var Request = new TokenCreationRequest + { + Subject = IdentityUser.CreatePrincipal(), + IncludeAllIdentityClaims = true, + ValidatedRequest = new ValidatedRequest() + }; + Request.ValidatedRequest.Subject = Request.Subject; + Request.ValidatedRequest.SetClient(Config.Clients.FirstOrDefault((c) => c.ClientId == clientId)); + Request.ValidatedRequest.AccessTokenType = AccessTokenType.Reference; + Request.ValidatedRequest.AccessTokenLifetime = 18000; + Request.ValidatedResources = new ResourceValidationResult(new Resources(Config.IdentityResources, Config.ApiResources, Config.ApiScopes)); + Request.ValidatedRequest.Options = ISOptions; + Request.ValidatedRequest.ClientClaims = IdentityUser.AdditionalClaims; + var accessToken = await TokenService.CreateAccessTokenAsync(Request); + return await TokenService.CreateSecurityTokenAsync(accessToken); + } + + public async Task TransformTokenRequestAsync(ValidatedTokenRequest request, User user, string grantType, string[] scopes, int lifetime = 20 * 60) + { + var principal = await PrincipalFactory.CreateAsync(user); + var identityUser = new IdentityServerUser(user.Id.ToString()) + { + DisplayName = user.UserName, + AuthenticationTime = System.DateTime.UtcNow, + IdentityProvider = IdentityServerConstants.LocalIdentityProvider, + AdditionalClaims = principal.Claims.ToArray() + }; + + request.AccessTokenType = AccessTokenType.Jwt; + request.AccessTokenLifetime = lifetime; + request.GrantType = grantType; + request.ValidatedResources = await ResourceStore.CreateResourceValidationResult(new ParsedScopesResult() + { + ParsedScopes = scopes.Select((scope) => new ParsedScopeValue(scope)).ToArray() + }); + return identityUser.CreatePrincipal(); + } + + public async Task CreateAccessTokenFromValidatedRequestAsync(ValidatedTokenRequest validatedRequest, User user, string[] scopes, int lifetime = 20 * 60) + { + var request = new TokenCreationRequest + { + Subject = await this.TransformTokenRequestAsync(validatedRequest, user, validatedRequest.GrantType, scopes, lifetime), + IncludeAllIdentityClaims = true, + ValidatedRequest = validatedRequest, + ValidatedResources = validatedRequest.ValidatedResources + }; + var accessToken = await TokenService.CreateAccessTokenAsync(request); + return await TokenService.CreateSecurityTokenAsync(accessToken); + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Services/UserService.cs b/Streetwriters.Identity/Services/UserService.cs index a60a46b..e900479 100644 --- a/Streetwriters.Identity/Services/UserService.cs +++ b/Streetwriters.Identity/Services/UserService.cs @@ -1,89 +1,89 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Linq; -using System.Security.Claims; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Identity; -using Streetwriters.Common.Enums; -using Streetwriters.Common.Models; - -namespace Streetwriters.Identity.Services -{ - public class UserService - { - public static SubscriptionType GetUserSubscriptionStatus(string clientId, User user) - { - var claimKey = GetClaimKey(clientId); - var status = user.Claims.FirstOrDefault((c) => c.ClaimType == claimKey).ClaimValue; - switch (status) - { - case "basic": - return SubscriptionType.BASIC; - case "trial": - return SubscriptionType.TRIAL; - case "premium": - return SubscriptionType.PREMIUM; - case "premium_canceled": - return SubscriptionType.PREMIUM_CANCELED; - case "premium_expired": - return SubscriptionType.PREMIUM_EXPIRED; - default: - return SubscriptionType.BASIC; - } - } - - - - public static bool IsUserPremium(string clientId, User user) - { - var status = GetUserSubscriptionStatus(clientId, user); - return status == SubscriptionType.PREMIUM || status == SubscriptionType.PREMIUM_CANCELED; - } - - public static Claim SubscriptionTypeToClaim(string clientId, SubscriptionType type) - { - var claimKey = GetClaimKey(clientId); - switch (type) - { - case SubscriptionType.BASIC: - return new Claim(claimKey, "basic"); - case SubscriptionType.TRIAL: - return new Claim(claimKey, "trial"); - case SubscriptionType.PREMIUM: - return new Claim(claimKey, "premium"); - case SubscriptionType.PREMIUM_CANCELED: - return new Claim(claimKey, "premium_canceled"); - case SubscriptionType.PREMIUM_EXPIRED: - return new Claim(claimKey, "premium_expired"); - } - return null; - } - - public static string GetClaimKey(string clientId) - { - return $"{clientId}:status"; - } - - public static async Task IsUserValidAsync(UserManager userManager, User user, string clientId) - { - return user != null && await userManager.IsInRoleAsync(user, clientId); - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; +using Streetwriters.Common.Enums; +using Streetwriters.Common.Models; + +namespace Streetwriters.Identity.Services +{ + public class UserService + { + public static SubscriptionType GetUserSubscriptionStatus(string clientId, User user) + { + var claimKey = GetClaimKey(clientId); + var status = user.Claims.FirstOrDefault((c) => c.ClaimType == claimKey).ClaimValue; + switch (status) + { + case "basic": + return SubscriptionType.BASIC; + case "trial": + return SubscriptionType.TRIAL; + case "premium": + return SubscriptionType.PREMIUM; + case "premium_canceled": + return SubscriptionType.PREMIUM_CANCELED; + case "premium_expired": + return SubscriptionType.PREMIUM_EXPIRED; + default: + return SubscriptionType.BASIC; + } + } + + + + public static bool IsUserPremium(string clientId, User user) + { + var status = GetUserSubscriptionStatus(clientId, user); + return status == SubscriptionType.PREMIUM || status == SubscriptionType.PREMIUM_CANCELED; + } + + public static Claim SubscriptionTypeToClaim(string clientId, SubscriptionType type) + { + var claimKey = GetClaimKey(clientId); + switch (type) + { + case SubscriptionType.BASIC: + return new Claim(claimKey, "basic"); + case SubscriptionType.TRIAL: + return new Claim(claimKey, "trial"); + case SubscriptionType.PREMIUM: + return new Claim(claimKey, "premium"); + case SubscriptionType.PREMIUM_CANCELED: + return new Claim(claimKey, "premium_canceled"); + case SubscriptionType.PREMIUM_EXPIRED: + return new Claim(claimKey, "premium_expired"); + } + return null; + } + + public static string GetClaimKey(string clientId) + { + return $"{clientId}:status"; + } + + public static async Task IsUserValidAsync(UserManager userManager, User user, string clientId) + { + return user != null && await userManager.IsInRoleAsync(user, clientId); + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Templates/ConfirmEmail.html b/Streetwriters.Identity/Templates/ConfirmEmail.html index b4c59e6..6f8f1f5 100644 --- a/Streetwriters.Identity/Templates/ConfirmEmail.html +++ b/Streetwriters.Identity/Templates/ConfirmEmail.html @@ -1,823 +1,823 @@ - - - - - - - - - - - - - - - - -
-
- - - - -
- - - - -
- - - - -
- - - - - -
- - - - -
-

- Confirm your email to activate your - {{app_name}} account. -

-
- - - - - - -
-
-

- {{app_name}} -

-
-
-
- - - - - - -
-
-
- Hey there! -
-
-
-
-
- Thank you so much for signing up on - {{app_name}}! -
-
-
-
-
- Please confirm your email by - clicking - here. -
-
-
-
- - - - - - -
- - - - - - -
- Confirm Email -
-
- - - - - - -
- - - - - - -
-
- - - - - - -
-
-
- This email has been sent to you - because you signed up on {{app_name}} - a service of Streetwriters - (Private) Ltd. -
-
- 1st Floor, Valley Plaza, Mardowal - Chowk, Naushera -
-
- Khushab, - Punjab - 41100 Pakistan -
-
-
-
-
- -
-
-
-
-
- - + + + + + + + + + + + + + + + + +
+
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+

+ Confirm your email to activate your + {{app_name}} account. +

+
+ + + + + + +
+
+

+ {{app_name}} +

+
+
+
+ + + + + + +
+
+
+ Hey there! +
+
+
+
+
+ Thank you so much for signing up on + {{app_name}}! +
+
+
+
+
+ Please confirm your email by + clicking + here. +
+
+
+
+ + + + + + +
+ + + + + + +
+ Confirm Email +
+
+ + + + + + +
+ + + + + + +
+
+ + + + + + +
+
+
+ This email has been sent to you + because you signed up on {{app_name}} + a service of Streetwriters + (Private) Ltd. +
+
+ 1st Floor, Valley Plaza, Mardowal + Chowk, Naushera +
+
+ Khushab, + Punjab + 41100 Pakistan +
+
+
+
+
+ +
+
+
+
+
+ + diff --git a/Streetwriters.Identity/Templates/ConfirmEmail.txt b/Streetwriters.Identity/Templates/ConfirmEmail.txt index 478b662..187e669 100644 --- a/Streetwriters.Identity/Templates/ConfirmEmail.txt +++ b/Streetwriters.Identity/Templates/ConfirmEmail.txt @@ -1,17 +1,17 @@ -Confirm your email to activate your {{app_name}} account. - -************ -{{app_name}} -************ - -Hey there! - -Thank you so much for signing up on {{app_name}}! - -Please confirm your {{app_name}} account by going to this link: {{confirm_link}}. - ------------ - -This email has been sent to you because you signed up on {{app_name}} a service of Streetwriters (Private) Ltd. -1st Floor, Valley Plaza, Mardowal Chowk, Naushera +Confirm your email to activate your {{app_name}} account. + +************ +{{app_name}} +************ + +Hey there! + +Thank you so much for signing up on {{app_name}}! + +Please confirm your {{app_name}} account by going to this link: {{confirm_link}}. + +----------- + +This email has been sent to you because you signed up on {{app_name}} a service of Streetwriters (Private) Ltd. +1st Floor, Valley Plaza, Mardowal Chowk, Naushera Khushab, Punjab 41100 Pakistan \ No newline at end of file diff --git a/Streetwriters.Identity/Templates/Email2FACode.html b/Streetwriters.Identity/Templates/Email2FACode.html index 2a9b0ae..43c51a9 100644 --- a/Streetwriters.Identity/Templates/Email2FACode.html +++ b/Streetwriters.Identity/Templates/Email2FACode.html @@ -1,435 +1,435 @@ - - - - - - - - - - - - - - - - - - -
-
- - - - -
- - - - -
- - - - -
- - - - - -
- - - - -
-

- Your 2FA code for {{app_name}} is - {{code}} -

-
- - - - - - -
-
-

- {{app_name}} -

-
-
-
- - - - - - -
-
-
- Please use the following 2FA code to - login to your account: -
-
-
-
- - - - - - -
-
-
- {{code}} -
-
-
-
- - - - - - -
-
-
- If you did not request to a 2FA - code, please report this to us - at support@streetwriters.co -
-
-
-
- - - - - - -
- - - - - - -
-
- - - - - - -
-
-
- This email has been sent to you - because you signed up on {{app_name}} - - a service by Streetwriters - (Private) Ltd. -
-
- 1st Floor, Valley Plaza, Mardowal - Chowk, Naushera -
-
- Khushab, Punjab 41100 - Pakistan -
-
-
-
-
- -
-
-
-
-
- - + + + + + + + + + + + + + + + + + + +
+
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+

+ Your 2FA code for {{app_name}} is + {{code}} +

+
+ + + + + + +
+
+

+ {{app_name}} +

+
+
+
+ + + + + + +
+
+
+ Please use the following 2FA code to + login to your account: +
+
+
+
+ + + + + + +
+
+
+ {{code}} +
+
+
+
+ + + + + + +
+
+
+ If you did not request to a 2FA + code, please report this to us + at support@streetwriters.co +
+
+
+
+ + + + + + +
+ + + + + + +
+
+ + + + + + +
+
+
+ This email has been sent to you + because you signed up on {{app_name}} + - a service by Streetwriters + (Private) Ltd. +
+
+ 1st Floor, Valley Plaza, Mardowal + Chowk, Naushera +
+
+ Khushab, Punjab 41100 + Pakistan +
+
+
+
+
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/Streetwriters.Identity/Templates/Email2FACode.txt b/Streetwriters.Identity/Templates/Email2FACode.txt index bf52dfd..f3bdc28 100644 --- a/Streetwriters.Identity/Templates/Email2FACode.txt +++ b/Streetwriters.Identity/Templates/Email2FACode.txt @@ -1,17 +1,17 @@ -Your 2FA code for {{app_name}} is: {{code}} - -************ -{{app_name}} -************ - -Please use the following 2FA code to login to your account: - -{{code}} - -If you did not request to a 2FA code, please report this to us at support@streetwriters.co - -------------- - -This email has been sent to you because you signed up on ** - a service by Streetwriters (Private) Ltd. -1st Floor, Valley Plaza, Mardowal Chowk, Naushera +Your 2FA code for {{app_name}} is: {{code}} + +************ +{{app_name}} +************ + +Please use the following 2FA code to login to your account: + +{{code}} + +If you did not request to a 2FA code, please report this to us at support@streetwriters.co + +------------- + +This email has been sent to you because you signed up on ** - a service by Streetwriters (Private) Ltd. +1st Floor, Valley Plaza, Mardowal Chowk, Naushera Khushab, Punjab 41100 Pakistan \ No newline at end of file diff --git a/Streetwriters.Identity/Templates/EmailChangeConfirmation.html b/Streetwriters.Identity/Templates/EmailChangeConfirmation.html index f56a796..544b145 100644 --- a/Streetwriters.Identity/Templates/EmailChangeConfirmation.html +++ b/Streetwriters.Identity/Templates/EmailChangeConfirmation.html @@ -1,591 +1,591 @@ - - - - - - - - - - - - - - - - -
-
- - - - -
- - - - -
- - - - -
- - - - - -
- - - - -
-

-
- - - - - - -
-
-

- {{app_name}} -

-
-
-
- - - - - - -
-
-
- Please use the following - verification code to change to your - account email: -
-
-
-
- - - - - - -
-
-
- {{code}} -
-
-
-
- - - - - - -
-
-
- If you did not request to a - verification code, please report - this to us at - support@streetwriters.co -
-
-
-
- - - - - - -
- - - - - - -
-
- - - - - - -
-
-
- This email has been sent to you - because you signed up on {{app_name}} - - a service by Streetwriters - (Private) Ltd. -
-
- 1st Floor, Valley Plaza, Mardowal - Chowk, Naushera -
-
- Khushab, Punjab 41100 - Pakistan -
-
-
-
-
- -
-
-
-
-
- - + + + + + + + + + + + + + + + + +
+
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+

+
+ + + + + + +
+
+

+ {{app_name}} +

+
+
+
+ + + + + + +
+
+
+ Please use the following + verification code to change to your + account email: +
+
+
+
+ + + + + + +
+
+
+ {{code}} +
+
+
+
+ + + + + + +
+
+
+ If you did not request to a + verification code, please report + this to us at + support@streetwriters.co +
+
+
+
+ + + + + + +
+ + + + + + +
+
+ + + + + + +
+
+
+ This email has been sent to you + because you signed up on {{app_name}} + - a service by Streetwriters + (Private) Ltd. +
+
+ 1st Floor, Valley Plaza, Mardowal + Chowk, Naushera +
+
+ Khushab, Punjab 41100 + Pakistan +
+
+
+
+
+ +
+
+
+
+
+ + diff --git a/Streetwriters.Identity/Templates/EmailChangeConfirmation.txt b/Streetwriters.Identity/Templates/EmailChangeConfirmation.txt index ee6f44c..bcc8bda 100644 --- a/Streetwriters.Identity/Templates/EmailChangeConfirmation.txt +++ b/Streetwriters.Identity/Templates/EmailChangeConfirmation.txt @@ -1,17 +1,17 @@ -Confirm your new email to change it for your {{app_name}} account. - -************ -{{app_name}} -************ - -Please use the following verification code to change to your account email: - -{{code}} - -If you did not request a verification code, please report this to us at support@streetwriters.co - ------------- - -This email has been sent to you because you signed up on {{app_name}} a service of Streetwriters (Private) Ltd. -1st Floor, Valley Plaza, Mardowal Chowk, Naushera +Confirm your new email to change it for your {{app_name}} account. + +************ +{{app_name}} +************ + +Please use the following verification code to change to your account email: + +{{code}} + +If you did not request a verification code, please report this to us at support@streetwriters.co + +------------ + +This email has been sent to you because you signed up on {{app_name}} a service of Streetwriters (Private) Ltd. +1st Floor, Valley Plaza, Mardowal Chowk, Naushera Khushab, Punjab 41100 Pakistan \ No newline at end of file diff --git a/Streetwriters.Identity/Templates/FailedLoginAlert.html b/Streetwriters.Identity/Templates/FailedLoginAlert.html index a4c0d4e..6d7d15d 100644 --- a/Streetwriters.Identity/Templates/FailedLoginAlert.html +++ b/Streetwriters.Identity/Templates/FailedLoginAlert.html @@ -1,505 +1,505 @@ - - - - - - - - - - - - - - - - -
-
- - - - -
- - - - -
- - - - -
- - - - - -
- - - - -
-

-
- - - - - - -
-
-

- {{app_name}} -

-
-
-
- - - - - - -
-
-
- We detected a failed login attempt - on your {{app_name}} account. -
-
-
-
-
- {{device_info}} -
-
-
-
-
- If this was not you - please immediately change your - password & 2FA methods. -
-
-
-
- - - - - - -
- - - - - - -
-
- - - - - - -
-
-
- This email has been sent to you - because you signed up on {{app_name}} - - a service by Streetwriters - (Private) Ltd. -
-
- 1st Floor, Valley Plaza, Mardowal - Chowk, Naushera -
-
- Khushab, Punjab 41100 - Pakistan -
-
-
-
-
- -
-
-
-
-
- - + + + + + + + + + + + + + + + + +
+
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+

+
+ + + + + + +
+
+

+ {{app_name}} +

+
+
+
+ + + + + + +
+
+
+ We detected a failed login attempt + on your {{app_name}} account. +
+
+
+
+
+ {{device_info}} +
+
+
+
+
+ If this was not you + please immediately change your + password & 2FA methods. +
+
+
+
+ + + + + + +
+ + + + + + +
+
+ + + + + + +
+
+
+ This email has been sent to you + because you signed up on {{app_name}} + - a service by Streetwriters + (Private) Ltd. +
+
+ 1st Floor, Valley Plaza, Mardowal + Chowk, Naushera +
+
+ Khushab, Punjab 41100 + Pakistan +
+
+
+
+
+ +
+
+
+
+
+ + diff --git a/Streetwriters.Identity/Templates/FailedLoginAlert.txt b/Streetwriters.Identity/Templates/FailedLoginAlert.txt index bf98c59..07480c9 100644 --- a/Streetwriters.Identity/Templates/FailedLoginAlert.txt +++ b/Streetwriters.Identity/Templates/FailedLoginAlert.txt @@ -1,15 +1,15 @@ -************ -{{app_name}} -************ - -We detected a failed login attempt on your {{app_name}} account. - -{{device_info}} - -If this was not you *please immediately reset your password & 2FA methods*. - -------------- - -This email has been sent to you because you signed up on *{{app_name}}* - a service by Streetwriters (Private) Ltd. -1st Floor, Valley Plaza, Mardowal Chowk, Naushera +************ +{{app_name}} +************ + +We detected a failed login attempt on your {{app_name}} account. + +{{device_info}} + +If this was not you *please immediately reset your password & 2FA methods*. + +------------- + +This email has been sent to you because you signed up on *{{app_name}}* - a service by Streetwriters (Private) Ltd. +1st Floor, Valley Plaza, Mardowal Chowk, Naushera Khushab, Punjab 41100 Pakistan \ No newline at end of file diff --git a/Streetwriters.Identity/Templates/ResetAccountPassword.html b/Streetwriters.Identity/Templates/ResetAccountPassword.html index 6b93a5c..d7101ce 100644 --- a/Streetwriters.Identity/Templates/ResetAccountPassword.html +++ b/Streetwriters.Identity/Templates/ResetAccountPassword.html @@ -1,658 +1,658 @@ - - - - - - - - - - - - - - - - -
-
- - - - -
- - - - -
- - - - -
- - - - - -
- - - - -
-

- Lost access to your {{app_name}} - account? -

-
- - - - - - -
-
-

- {{app_name}} -

-
-
-
- - - - - - -
-
-
- Hey there! -
-
-
-
-
- You requested to - reset your {{app_name}} account - password. -
-
-
-
-
- Please - click here - to reset your account password and - recover your account. -
-
-
-
- - - - - - -
- - - - - - -
- Reset your password -
-
- - - - - - -
-
-
- If you did not request to reset - your account password, you can - safely ignore this email. -
-
-
-
- - - - - - -
- - - - - - -
-
- - - - . - - - -
-
-
- This email has been sent to you - because you signed up on {{app_name}} - - a service by Streetwriters - (Private) Ltd. -
-
- 1st Floor, Valley Plaza, Mardowal - Chowk, Naushera -
-
- Khushab, Punjab 41100 - Pakistan -
-
-
-
-
- -
-
-
-
-
- - + + + + + + + + + + + + + + + + +
+
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+

+ Lost access to your {{app_name}} + account? +

+
+ + + + + + +
+
+

+ {{app_name}} +

+
+
+
+ + + + + + +
+
+
+ Hey there! +
+
+
+
+
+ You requested to + reset your {{app_name}} account + password. +
+
+
+
+
+ Please + click here + to reset your account password and + recover your account. +
+
+
+
+ + + + + + +
+ + + + + + +
+ Reset your password +
+
+ + + + + + +
+
+
+ If you did not request to reset + your account password, you can + safely ignore this email. +
+
+
+
+ + + + + + +
+ + + + + + +
+
+ + + + . + + + +
+
+
+ This email has been sent to you + because you signed up on {{app_name}} + - a service by Streetwriters + (Private) Ltd. +
+
+ 1st Floor, Valley Plaza, Mardowal + Chowk, Naushera +
+
+ Khushab, Punjab 41100 + Pakistan +
+
+
+
+
+ +
+
+
+
+
+ + diff --git a/Streetwriters.Identity/Templates/ResetAccountPassword.txt b/Streetwriters.Identity/Templates/ResetAccountPassword.txt index 137456a..508230d 100644 --- a/Streetwriters.Identity/Templates/ResetAccountPassword.txt +++ b/Streetwriters.Identity/Templates/ResetAccountPassword.txt @@ -1,17 +1,17 @@ -************ -{{app_name}} -************ - -Hey there! - -You requested to *reset your {{app_name}} account password*. - -Please go to this link to reset your account password: {{reset_link}} - -If you did not request to reset your account password, you can safely ignore this email. - ------------- - -This email has been sent to you because you signed up on {{app_name}} - a service by Streetwriters (Private) Ltd. -1st Floor, Valley Plaza, Mardowal Chowk, Naushera +************ +{{app_name}} +************ + +Hey there! + +You requested to *reset your {{app_name}} account password*. + +Please go to this link to reset your account password: {{reset_link}} + +If you did not request to reset your account password, you can safely ignore this email. + +------------ + +This email has been sent to you because you signed up on {{app_name}} - a service by Streetwriters (Private) Ltd. +1st Floor, Valley Plaza, Mardowal Chowk, Naushera Khushab, Punjab 41100 Pakistan \ No newline at end of file diff --git a/Streetwriters.Identity/Validation/BearerTokenValidator.cs b/Streetwriters.Identity/Validation/BearerTokenValidator.cs index 932fbbb..d22eaf2 100644 --- a/Streetwriters.Identity/Validation/BearerTokenValidator.cs +++ b/Streetwriters.Identity/Validation/BearerTokenValidator.cs @@ -1,62 +1,62 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Linq; -using IdentityModel; -using IdentityServer4.Validation; -using Microsoft.AspNetCore.Http; - -namespace Streetwriters.Identity.Validation -{ - public class BearerTokenValidator - { - /// - /// Validates the authorization header. - /// - /// The context. - /// - public static BearerTokenUsageValidationResult ValidateAuthorizationHeader(HttpContext context) - { - var authorizationHeader = context.Request.Headers["Authorization"].FirstOrDefault(); - if (!string.IsNullOrEmpty(authorizationHeader)) - { - var header = authorizationHeader.Trim(); - if (header.StartsWith(OidcConstants.AuthenticationSchemes.AuthorizationHeaderBearer)) - { - var value = header.Substring(OidcConstants.AuthenticationSchemes.AuthorizationHeaderBearer.Length).Trim(); - if (!string.IsNullOrEmpty(value)) - { - return new BearerTokenUsageValidationResult - { - TokenFound = true, - Token = value, - UsageType = BearerTokenUsageType.AuthorizationHeader - }; - } - } - else - { - - } - } - - return new BearerTokenUsageValidationResult(); - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Linq; +using IdentityModel; +using IdentityServer4.Validation; +using Microsoft.AspNetCore.Http; + +namespace Streetwriters.Identity.Validation +{ + public class BearerTokenValidator + { + /// + /// Validates the authorization header. + /// + /// The context. + /// + public static BearerTokenUsageValidationResult ValidateAuthorizationHeader(HttpContext context) + { + var authorizationHeader = context.Request.Headers["Authorization"].FirstOrDefault(); + if (!string.IsNullOrEmpty(authorizationHeader)) + { + var header = authorizationHeader.Trim(); + if (header.StartsWith(OidcConstants.AuthenticationSchemes.AuthorizationHeaderBearer)) + { + var value = header.Substring(OidcConstants.AuthenticationSchemes.AuthorizationHeaderBearer.Length).Trim(); + if (!string.IsNullOrEmpty(value)) + { + return new BearerTokenUsageValidationResult + { + TokenFound = true, + Token = value, + UsageType = BearerTokenUsageType.AuthorizationHeader + }; + } + } + else + { + + } + } + + return new BearerTokenUsageValidationResult(); + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Validation/CustomResourceOwnerValidator.cs b/Streetwriters.Identity/Validation/CustomResourceOwnerValidator.cs index 340ca41..e87e4cd 100644 --- a/Streetwriters.Identity/Validation/CustomResourceOwnerValidator.cs +++ b/Streetwriters.Identity/Validation/CustomResourceOwnerValidator.cs @@ -1,152 +1,152 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Claims; -using System.Text.Json; -using System.Text.Json.Serialization; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using IdentityServer4; -using IdentityServer4.AspNetIdentity; -using IdentityServer4.Models; -using IdentityServer4.Validation; -using Microsoft.AspNetCore.Identity; -using Microsoft.Extensions.Logging; -using Streetwriters.Common.Enums; -using Streetwriters.Common.Models; -using Streetwriters.Identity.Interfaces; -using Streetwriters.Identity.Models; -using static IdentityModel.OidcConstants; - -namespace Streetwriters.Identity.Validation -{ - public class CustomResourceOwnerValidator : IResourceOwnerPasswordValidator - { - private UserManager UserManager { get; set; } - private SignInManager SignInManager { get; set; } - private IMFAService MFAService { get; set; } - private ITokenGenerationService TokenGenerationService { get; set; } - private IdentityServerTools Tools { get; set; } - public CustomResourceOwnerValidator(UserManager userManager, SignInManager signInManager, IMFAService mfaService, ITokenGenerationService tokenGenerationService, IdentityServerTools tools) - { - UserManager = userManager; - SignInManager = signInManager; - MFAService = mfaService; - TokenGenerationService = tokenGenerationService; - Tools = tools; - } - - public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) - { - var user = await UserManager.FindByNameAsync(context.UserName); - if (user != null) - { - var result = await SignInManager.CheckPasswordSignInAsync(user, context.Password, true); - - if (result.IsLockedOut) - { - var timeLeft = user.LockoutEnd - DateTimeOffset.Now; - context.Result.IsError = true; - context.Result.Error = "user_locked_out"; - context.Result.ErrorDescription = $"You have been locked out. Please try again in {Pluralize(timeLeft?.Minutes, "minute", "minutes")} and {Pluralize(timeLeft?.Seconds, "second", "seconds")}."; - return; - } - - var success = result.Succeeded; - var isMultiFactor = await UserManager.GetTwoFactorEnabledAsync(user); - - // We'll ask for 2FA regardless of password being incorrect to prevent an attacker - // from knowing whether the password is correct or not. - if (isMultiFactor) - { - var primaryMethod = MFAService.GetPrimaryMethod(user); - var secondaryMethod = MFAService.GetSecondaryMethod(user); - - var mfaCode = context.Request.Raw["mfa:code"]; - var mfaMethod = context.Request.Raw["mfa:method"]; - - if (string.IsNullOrEmpty(mfaCode) || !MFAService.IsValidMFAMethod(mfaMethod)) - { - var sendPhoneNumber = primaryMethod == MFAMethods.SMS || secondaryMethod == MFAMethods.SMS; - - var token = await TokenGenerationService.CreateAccessTokenFromValidatedRequestAsync(context.Request, user, new[] { Config.MFA_GRANT_TYPE_SCOPE }); - context.Result.CustomResponse = new System.Collections.Generic.Dictionary - { - ["error"] = "mfa_required", - ["error_description"] = "Multifactor authentication required.", - ["data"] = JsonSerializer.Serialize(new MFARequiredResponse - { - PhoneNumber = sendPhoneNumber ? Regex.Replace(user.PhoneNumber, @"\d(?!\d{0,3}$)", "*") : null, - PrimaryMethod = primaryMethod, - SecondaryMethod = secondaryMethod, - Token = token, - }) - }; - context.Result.IsError = true; - return; - } - else if (mfaMethod == MFAMethods.RecoveryCode) - { - var recoveryCodeResult = await UserManager.RedeemTwoFactorRecoveryCodeAsync(user, mfaCode); - if (!recoveryCodeResult.Succeeded) - { - context.Result.IsError = true; - context.Result.Error = "invalid_2fa_recovery_code"; - context.Result.ErrorDescription = recoveryCodeResult.Errors.ToErrors().First(); - return; - } - } - else - { - var provider = mfaMethod == MFAMethods.Email || mfaMethod == MFAMethods.SMS ? TokenOptions.DefaultPhoneProvider : UserManager.Options.Tokens.AuthenticatorTokenProvider; - var isMFACodeValid = await MFAService.VerifyOTPAsync(user, mfaCode, mfaMethod); - if (!isMFACodeValid) - { - context.Result.IsError = true; - context.Result.Error = "invalid_2fa_code"; - context.Result.ErrorDescription = "Please provide a valid multi factor authentication code."; - return; - } - } - - // if we are here, it means we succeeded. - success = true; - } - - if (success) - { - var sub = await UserManager.GetUserIdAsync(user); - context.Result = new GrantValidationResult(sub, AuthenticationMethods.Password); - return; - } - } - - context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant); - } - - string Pluralize(int? value, string singular, string plural) - { - if (value == null) return $"0 {plural}"; - return value == 1 ? $"{value} {singular}" : $"{value} {plural}"; - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using IdentityServer4; +using IdentityServer4.AspNetIdentity; +using IdentityServer4.Models; +using IdentityServer4.Validation; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Logging; +using Streetwriters.Common.Enums; +using Streetwriters.Common.Models; +using Streetwriters.Identity.Interfaces; +using Streetwriters.Identity.Models; +using static IdentityModel.OidcConstants; + +namespace Streetwriters.Identity.Validation +{ + public class CustomResourceOwnerValidator : IResourceOwnerPasswordValidator + { + private UserManager UserManager { get; set; } + private SignInManager SignInManager { get; set; } + private IMFAService MFAService { get; set; } + private ITokenGenerationService TokenGenerationService { get; set; } + private IdentityServerTools Tools { get; set; } + public CustomResourceOwnerValidator(UserManager userManager, SignInManager signInManager, IMFAService mfaService, ITokenGenerationService tokenGenerationService, IdentityServerTools tools) + { + UserManager = userManager; + SignInManager = signInManager; + MFAService = mfaService; + TokenGenerationService = tokenGenerationService; + Tools = tools; + } + + public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) + { + var user = await UserManager.FindByNameAsync(context.UserName); + if (user != null) + { + var result = await SignInManager.CheckPasswordSignInAsync(user, context.Password, true); + + if (result.IsLockedOut) + { + var timeLeft = user.LockoutEnd - DateTimeOffset.Now; + context.Result.IsError = true; + context.Result.Error = "user_locked_out"; + context.Result.ErrorDescription = $"You have been locked out. Please try again in {Pluralize(timeLeft?.Minutes, "minute", "minutes")} and {Pluralize(timeLeft?.Seconds, "second", "seconds")}."; + return; + } + + var success = result.Succeeded; + var isMultiFactor = await UserManager.GetTwoFactorEnabledAsync(user); + + // We'll ask for 2FA regardless of password being incorrect to prevent an attacker + // from knowing whether the password is correct or not. + if (isMultiFactor) + { + var primaryMethod = MFAService.GetPrimaryMethod(user); + var secondaryMethod = MFAService.GetSecondaryMethod(user); + + var mfaCode = context.Request.Raw["mfa:code"]; + var mfaMethod = context.Request.Raw["mfa:method"]; + + if (string.IsNullOrEmpty(mfaCode) || !MFAService.IsValidMFAMethod(mfaMethod)) + { + var sendPhoneNumber = primaryMethod == MFAMethods.SMS || secondaryMethod == MFAMethods.SMS; + + var token = await TokenGenerationService.CreateAccessTokenFromValidatedRequestAsync(context.Request, user, new[] { Config.MFA_GRANT_TYPE_SCOPE }); + context.Result.CustomResponse = new System.Collections.Generic.Dictionary + { + ["error"] = "mfa_required", + ["error_description"] = "Multifactor authentication required.", + ["data"] = JsonSerializer.Serialize(new MFARequiredResponse + { + PhoneNumber = sendPhoneNumber ? Regex.Replace(user.PhoneNumber, @"\d(?!\d{0,3}$)", "*") : null, + PrimaryMethod = primaryMethod, + SecondaryMethod = secondaryMethod, + Token = token, + }) + }; + context.Result.IsError = true; + return; + } + else if (mfaMethod == MFAMethods.RecoveryCode) + { + var recoveryCodeResult = await UserManager.RedeemTwoFactorRecoveryCodeAsync(user, mfaCode); + if (!recoveryCodeResult.Succeeded) + { + context.Result.IsError = true; + context.Result.Error = "invalid_2fa_recovery_code"; + context.Result.ErrorDescription = recoveryCodeResult.Errors.ToErrors().First(); + return; + } + } + else + { + var provider = mfaMethod == MFAMethods.Email || mfaMethod == MFAMethods.SMS ? TokenOptions.DefaultPhoneProvider : UserManager.Options.Tokens.AuthenticatorTokenProvider; + var isMFACodeValid = await MFAService.VerifyOTPAsync(user, mfaCode, mfaMethod); + if (!isMFACodeValid) + { + context.Result.IsError = true; + context.Result.Error = "invalid_2fa_code"; + context.Result.ErrorDescription = "Please provide a valid multi factor authentication code."; + return; + } + } + + // if we are here, it means we succeeded. + success = true; + } + + if (success) + { + var sub = await UserManager.GetUserIdAsync(user); + context.Result = new GrantValidationResult(sub, AuthenticationMethods.Password); + return; + } + } + + context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant); + } + + string Pluralize(int? value, string singular, string plural) + { + if (value == null) return $"0 {plural}"; + return value == 1 ? $"{value} {singular}" : $"{value} {plural}"; + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Validation/EmailGrantValidator.cs b/Streetwriters.Identity/Validation/EmailGrantValidator.cs index 0e7b468..d5118d7 100644 --- a/Streetwriters.Identity/Validation/EmailGrantValidator.cs +++ b/Streetwriters.Identity/Validation/EmailGrantValidator.cs @@ -1,107 +1,107 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Claims; -using System.Text.Json; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using IdentityServer4; -using IdentityServer4.Models; -using IdentityServer4.Stores; -using IdentityServer4.Validation; -using Microsoft.AspNetCore.Identity; -using Streetwriters.Common.Enums; -using Streetwriters.Common.Models; -using Streetwriters.Identity.Interfaces; -using Streetwriters.Identity.Models; -using static IdentityModel.OidcConstants; - -namespace Streetwriters.Identity.Validation -{ - public class EmailGrantValidator : IExtensionGrantValidator - { - private UserManager UserManager { get; set; } - private SignInManager SignInManager { get; set; } - private IMFAService MFAService { get; set; } - private ITokenGenerationService TokenGenerationService { get; set; } - private JwtRequestValidator JWTRequestValidator { get; set; } - private IResourceStore ResourceStore { get; set; } - private IUserClaimsPrincipalFactory PrincipalFactory { get; set; } - public EmailGrantValidator(UserManager userManager, SignInManager signInManager, IMFAService mfaService, ITokenGenerationService tokenGenerationService, - IResourceStore resourceStore, IUserClaimsPrincipalFactory principalFactory) - { - UserManager = userManager; - SignInManager = signInManager; - MFAService = mfaService; - TokenGenerationService = tokenGenerationService; - ResourceStore = resourceStore; - PrincipalFactory = principalFactory; - } - - public string GrantType => Config.EMAIL_GRANT_TYPE; - - - public async Task ValidateAsync(ExtensionGrantValidationContext context) - { - var email = context.Request.Raw["email"]; - var clientId = context.Request.ClientId; - var user = await UserManager.FindRegisteredUserAsync(email, clientId); - if (user == null) - { - user = new User - { - Id = MongoDB.Bson.ObjectId.GenerateNewId(), - Email = email, - UserName = email, - NormalizedEmail = email, - NormalizedUserName = email, - EmailConfirmed = false, - SecurityStamp = "" - }; - } - var isMultiFactor = await UserManager.GetTwoFactorEnabledAsync(user); - - var primaryMethod = isMultiFactor ? MFAService.GetPrimaryMethod(user) : MFAMethods.Email; - var secondaryMethod = MFAService.GetSecondaryMethod(user); - var sendPhoneNumber = primaryMethod == MFAMethods.SMS || secondaryMethod == MFAMethods.SMS; - - context.Result.CustomResponse = new Dictionary - { - ["additional_data"] = new MFARequiredResponse - { - PhoneNumber = sendPhoneNumber ? Regex.Replace(user.PhoneNumber, @"\d(?!\d{0,3}$)", "*") : null, - PrimaryMethod = primaryMethod, - SecondaryMethod = secondaryMethod, - } - }; - context.Result.IsError = false; - context.Result.Subject = await TokenGenerationService.TransformTokenRequestAsync(context.Request, user, GrantType, new string[] { Config.MFA_GRANT_TYPE_SCOPE }); - } - - - string Pluralize(int? value, string singular, string plural) - { - if (value == null) return $"0 {plural}"; - return value == 1 ? $"{value} {singular}" : $"{value} {plural}"; - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Text.Json; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using IdentityServer4; +using IdentityServer4.Models; +using IdentityServer4.Stores; +using IdentityServer4.Validation; +using Microsoft.AspNetCore.Identity; +using Streetwriters.Common.Enums; +using Streetwriters.Common.Models; +using Streetwriters.Identity.Interfaces; +using Streetwriters.Identity.Models; +using static IdentityModel.OidcConstants; + +namespace Streetwriters.Identity.Validation +{ + public class EmailGrantValidator : IExtensionGrantValidator + { + private UserManager UserManager { get; set; } + private SignInManager SignInManager { get; set; } + private IMFAService MFAService { get; set; } + private ITokenGenerationService TokenGenerationService { get; set; } + private JwtRequestValidator JWTRequestValidator { get; set; } + private IResourceStore ResourceStore { get; set; } + private IUserClaimsPrincipalFactory PrincipalFactory { get; set; } + public EmailGrantValidator(UserManager userManager, SignInManager signInManager, IMFAService mfaService, ITokenGenerationService tokenGenerationService, + IResourceStore resourceStore, IUserClaimsPrincipalFactory principalFactory) + { + UserManager = userManager; + SignInManager = signInManager; + MFAService = mfaService; + TokenGenerationService = tokenGenerationService; + ResourceStore = resourceStore; + PrincipalFactory = principalFactory; + } + + public string GrantType => Config.EMAIL_GRANT_TYPE; + + + public async Task ValidateAsync(ExtensionGrantValidationContext context) + { + var email = context.Request.Raw["email"]; + var clientId = context.Request.ClientId; + var user = await UserManager.FindRegisteredUserAsync(email, clientId); + if (user == null) + { + user = new User + { + Id = MongoDB.Bson.ObjectId.GenerateNewId(), + Email = email, + UserName = email, + NormalizedEmail = email, + NormalizedUserName = email, + EmailConfirmed = false, + SecurityStamp = "" + }; + } + var isMultiFactor = await UserManager.GetTwoFactorEnabledAsync(user); + + var primaryMethod = isMultiFactor ? MFAService.GetPrimaryMethod(user) : MFAMethods.Email; + var secondaryMethod = MFAService.GetSecondaryMethod(user); + var sendPhoneNumber = primaryMethod == MFAMethods.SMS || secondaryMethod == MFAMethods.SMS; + + context.Result.CustomResponse = new Dictionary + { + ["additional_data"] = new MFARequiredResponse + { + PhoneNumber = sendPhoneNumber ? Regex.Replace(user.PhoneNumber, @"\d(?!\d{0,3}$)", "*") : null, + PrimaryMethod = primaryMethod, + SecondaryMethod = secondaryMethod, + } + }; + context.Result.IsError = false; + context.Result.Subject = await TokenGenerationService.TransformTokenRequestAsync(context.Request, user, GrantType, new string[] { Config.MFA_GRANT_TYPE_SCOPE }); + } + + + string Pluralize(int? value, string singular, string plural) + { + if (value == null) return $"0 {plural}"; + return value == 1 ? $"{value} {singular}" : $"{value} {plural}"; + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/Validation/LockedOutValidationResult.cs b/Streetwriters.Identity/Validation/LockedOutValidationResult.cs index 8f69577..e81bd6b 100644 --- a/Streetwriters.Identity/Validation/LockedOutValidationResult.cs +++ b/Streetwriters.Identity/Validation/LockedOutValidationResult.cs @@ -1,37 +1,37 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using IdentityServer4.Validation; - -namespace Streetwriters.Identity.Validation -{ - public class LockedOutValidationResult : GrantValidationResult - { - public LockedOutValidationResult(TimeSpan? timeLeft) - { - Error = "locked_out"; - IsError = true; - if (timeLeft.HasValue) - ErrorDescription = $"You have been locked out. Please try again in {timeLeft?.Minutes.Pluralize("minute", "minutes")} and {timeLeft?.Seconds.Pluralize("second", "seconds")}."; - else - ErrorDescription = $"You have been locked out."; - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using IdentityServer4.Validation; + +namespace Streetwriters.Identity.Validation +{ + public class LockedOutValidationResult : GrantValidationResult + { + public LockedOutValidationResult(TimeSpan? timeLeft) + { + Error = "locked_out"; + IsError = true; + if (timeLeft.HasValue) + ErrorDescription = $"You have been locked out. Please try again in {timeLeft?.Minutes.Pluralize("minute", "minutes")} and {timeLeft?.Seconds.Pluralize("second", "seconds")}."; + else + ErrorDescription = $"You have been locked out."; + } + } } \ No newline at end of file diff --git a/Streetwriters.Identity/appsettings.Development.json b/Streetwriters.Identity/appsettings.Development.json index 8081306..6dbc437 100644 --- a/Streetwriters.Identity/appsettings.Development.json +++ b/Streetwriters.Identity/appsettings.Development.json @@ -1,13 +1,13 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - }, - "MongoDbSettings": { - "ConnectionString": "mongodb://localhost:27017/identity", - "DatabaseName": "identity" - } -} +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "MongoDbSettings": { + "ConnectionString": "mongodb://localhost:27017/identity", + "DatabaseName": "identity" + } +} diff --git a/Streetwriters.Identity/appsettings.json b/Streetwriters.Identity/appsettings.json index 6cf0b42..0804371 100644 --- a/Streetwriters.Identity/appsettings.json +++ b/Streetwriters.Identity/appsettings.json @@ -1,7 +1,7 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Warning" - } - } -} +{ + "Logging": { + "LogLevel": { + "Default": "Warning" + } + } +} diff --git a/Streetwriters.Messenger/Dockerfile b/Streetwriters.Messenger/Dockerfile index 587a57b..9c6062d 100644 --- a/Streetwriters.Messenger/Dockerfile +++ b/Streetwriters.Messenger/Dockerfile @@ -1,50 +1,50 @@ -FROM mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine AS base -WORKDIR /app - -FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build -ARG TARGETARCH -ARG BUILDPLATFORM -ENV DOTNET_TC_QuickJitForLoops="1" DOTNET_ReadyToRun="0" DOTNET_TieredPGO="1" DOTNET_SYSTEM_GLOBALIZATION_INVARIANT="true" - -WORKDIR /src - -COPY Streetwriters.Data/*.csproj ./Streetwriters.Data/ -COPY Streetwriters.Common/*.csproj ./Streetwriters.Common/ -COPY Streetwriters.Messenger/*.csproj ./Streetwriters.Messenger/ - -# restore dependencies -RUN dotnet restore -v d /src/Streetwriters.Messenger/Streetwriters.Messenger.csproj --use-current-runtime - -COPY Streetwriters.Data/ ./Streetwriters.Data/ -COPY Streetwriters.Common/ ./Streetwriters.Common/ -COPY Streetwriters.Messenger/ ./Streetwriters.Messenger/ - -WORKDIR /src/Streetwriters.Messenger/ - -RUN dotnet build -c Release -o /app/build -a $TARGETARCH - -FROM build AS publish -RUN dotnet publish -c Release -o /app/publish \ - #--runtime alpine-x64 \ - --self-contained true \ - /p:TrimMode=partial \ - /p:PublishTrimmed=true \ - /p:PublishSingleFile=true \ - /p:JsonSerializerIsReflectionEnabledByDefault=true \ - -a $TARGETARCH - -FROM --platform=$BUILDPLATFORM base AS final -ARG TARGETARCH -ARG BUILDPLATFORM - -# create a new user and change directory ownership -RUN adduser --disabled-password \ - --home /app \ - --gecos '' dotnetuser && chown -R dotnetuser /app - -# impersonate into the new user -USER dotnetuser -WORKDIR /app - -COPY --from=publish /app/publish . +FROM mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine AS base +WORKDIR /app + +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build +ARG TARGETARCH +ARG BUILDPLATFORM +ENV DOTNET_TC_QuickJitForLoops="1" DOTNET_ReadyToRun="0" DOTNET_TieredPGO="1" DOTNET_SYSTEM_GLOBALIZATION_INVARIANT="true" + +WORKDIR /src + +COPY Streetwriters.Data/*.csproj ./Streetwriters.Data/ +COPY Streetwriters.Common/*.csproj ./Streetwriters.Common/ +COPY Streetwriters.Messenger/*.csproj ./Streetwriters.Messenger/ + +# restore dependencies +RUN dotnet restore -v d /src/Streetwriters.Messenger/Streetwriters.Messenger.csproj --use-current-runtime + +COPY Streetwriters.Data/ ./Streetwriters.Data/ +COPY Streetwriters.Common/ ./Streetwriters.Common/ +COPY Streetwriters.Messenger/ ./Streetwriters.Messenger/ + +WORKDIR /src/Streetwriters.Messenger/ + +RUN dotnet build -c Release -o /app/build -a $TARGETARCH + +FROM build AS publish +RUN dotnet publish -c Release -o /app/publish \ + #--runtime alpine-x64 \ + --self-contained true \ + /p:TrimMode=partial \ + /p:PublishTrimmed=true \ + /p:PublishSingleFile=true \ + /p:JsonSerializerIsReflectionEnabledByDefault=true \ + -a $TARGETARCH + +FROM --platform=$BUILDPLATFORM base AS final +ARG TARGETARCH +ARG BUILDPLATFORM + +# create a new user and change directory ownership +RUN adduser --disabled-password \ + --home /app \ + --gecos '' dotnetuser && chown -R dotnetuser /app + +# impersonate into the new user +USER dotnetuser +WORKDIR /app + +COPY --from=publish /app/publish . ENTRYPOINT ["./Streetwriters.Messenger"] \ No newline at end of file diff --git a/Streetwriters.Messenger/Helpers/SSEHelper.cs b/Streetwriters.Messenger/Helpers/SSEHelper.cs index 587a361..1125aec 100644 --- a/Streetwriters.Messenger/Helpers/SSEHelper.cs +++ b/Streetwriters.Messenger/Helpers/SSEHelper.cs @@ -1,45 +1,45 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System.Linq; -using System.Threading.Tasks; -using Lib.AspNetCore.ServerSentEvents; -using System.Security.Claims; - -namespace Streetwriters.Messenger.Helpers -{ - public class SSEHelper - { - public static async Task SendEventToUserAsync(string data, IServerSentEventsService sseService, string userId, string originTokenId = null) - { - var clients = sseService.GetClients().Where(c => c.User.FindFirstValue("sub") == userId); - foreach (var client in clients) - { - if (originTokenId != null && client.User.FindFirstValue("jti") == originTokenId) continue; - if (!client.IsConnected) continue; - await client.SendEventAsync(data); - } - } - - public static async Task SendEventToAllUsersAsync(string data, IServerSentEventsService sseService) - { - await sseService.SendEventAsync(data); - } - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System.Linq; +using System.Threading.Tasks; +using Lib.AspNetCore.ServerSentEvents; +using System.Security.Claims; + +namespace Streetwriters.Messenger.Helpers +{ + public class SSEHelper + { + public static async Task SendEventToUserAsync(string data, IServerSentEventsService sseService, string userId, string originTokenId = null) + { + var clients = sseService.GetClients().Where(c => c.User.FindFirstValue("sub") == userId); + foreach (var client in clients) + { + if (originTokenId != null && client.User.FindFirstValue("jti") == originTokenId) continue; + if (!client.IsConnected) continue; + await client.SendEventAsync(data); + } + } + + public static async Task SendEventToAllUsersAsync(string data, IServerSentEventsService sseService) + { + await sseService.SendEventAsync(data); + } + } } \ No newline at end of file diff --git a/Streetwriters.Messenger/Properties/launchSettings.json b/Streetwriters.Messenger/Properties/launchSettings.json index f6598eb..64190b6 100644 --- a/Streetwriters.Messenger/Properties/launchSettings.json +++ b/Streetwriters.Messenger/Properties/launchSettings.json @@ -1,31 +1,31 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:53323", - "sslPort": 44382 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "swagger", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "Streetwriters.Messenger": { - "commandName": "Project", - "dotnetRunMessages": "true", - "launchBrowser": true, - "launchUrl": "swagger", - "applicationUrl": "https://localhost:5001;http://localhost:5000", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:53323", + "sslPort": 44382 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Streetwriters.Messenger": { + "commandName": "Project", + "dotnetRunMessages": "true", + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:5001;http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/Streetwriters.Messenger/Services/HeartbeatService.cs b/Streetwriters.Messenger/Services/HeartbeatService.cs index b86c759..f33911a 100644 --- a/Streetwriters.Messenger/Services/HeartbeatService.cs +++ b/Streetwriters.Messenger/Services/HeartbeatService.cs @@ -1,64 +1,64 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Extensions.Hosting; -using Lib.AspNetCore.ServerSentEvents; -using Streetwriters.Messenger.Helpers; -using System.Text.Json; - -namespace Streetwriters.Messenger.Services -{ - internal class HeartbeatService : BackgroundService - { - #region Fields - private const string HEARTBEAT_MESSAGE_FORMAT = "Streetwriters Heartbeat ({0} UTC)"; - - private readonly IServerSentEventsService _serverSentEventsService; - #endregion - - #region Constructor - public HeartbeatService(IServerSentEventsService serverSentEventsService) - { - _serverSentEventsService = serverSentEventsService; - } - #endregion - - #region Methods - protected override async Task ExecuteAsync(CancellationToken stoppingToken) - { - while (!stoppingToken.IsCancellationRequested) - { - var message = JsonSerializer.Serialize(new - { - type = "heartbeat", - data = JsonSerializer.Serialize(new - { - t = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - }) - }); - await SSEHelper.SendEventToAllUsersAsync(message, _serverSentEventsService); - await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken); - } - } - #endregion - } +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Hosting; +using Lib.AspNetCore.ServerSentEvents; +using Streetwriters.Messenger.Helpers; +using System.Text.Json; + +namespace Streetwriters.Messenger.Services +{ + internal class HeartbeatService : BackgroundService + { + #region Fields + private const string HEARTBEAT_MESSAGE_FORMAT = "Streetwriters Heartbeat ({0} UTC)"; + + private readonly IServerSentEventsService _serverSentEventsService; + #endregion + + #region Constructor + public HeartbeatService(IServerSentEventsService serverSentEventsService) + { + _serverSentEventsService = serverSentEventsService; + } + #endregion + + #region Methods + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + while (!stoppingToken.IsCancellationRequested) + { + var message = JsonSerializer.Serialize(new + { + type = "heartbeat", + data = JsonSerializer.Serialize(new + { + t = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + }) + }); + await SSEHelper.SendEventToAllUsersAsync(message, _serverSentEventsService); + await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken); + } + } + #endregion + } } \ No newline at end of file diff --git a/Streetwriters.Messenger/Startup.cs b/Streetwriters.Messenger/Startup.cs index 1f782cc..8a510d2 100644 --- a/Streetwriters.Messenger/Startup.cs +++ b/Streetwriters.Messenger/Startup.cs @@ -1,147 +1,147 @@ -/* -This file is part of the Notesnook Sync Server project (https://notesnook.com/) - -Copyright (C) 2023 Streetwriters (Private) Limited - -This program is free software: you can redistribute it and/or modify -it under the terms of the Affero GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -Affero GNU General Public License for more details. - -You should have received a copy of the Affero GNU General Public License -along with this program. If not, see . -*/ - -using System; -using System.IdentityModel.Tokens.Jwt; -using System.Linq; -using System.Reactive.Subjects; -using System.Text.Json; -using Lib.AspNetCore.ServerSentEvents; -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.HttpOverrides; -using Microsoft.AspNetCore.ResponseCompression; -using Microsoft.Extensions.Caching.Distributed; -using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Streetwriters.Common; -using Streetwriters.Common.Extensions; -using Streetwriters.Common.Messages; -using Streetwriters.Messenger.Helpers; -using Streetwriters.Messenger.Services; -using WampSharp.AspNetCore.WebSockets.Server; -using WampSharp.Binding; -using WampSharp.V2; -using WampSharp.V2.Realm; - -namespace Streetwriters.Messenger -{ - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { - - services.AddControllers(); - - JwtSecurityTokenHandler.DefaultMapInboundClaims = false; - JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); - - services.AddDefaultCors(); - services.AddDistributedMemoryCache(delegate (MemoryDistributedCacheOptions cacheOptions) - { - cacheOptions.SizeLimit = 262144000L; - }); - - services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) - .AddOAuth2Introspection("introspection", options => - { - options.Authority = Servers.IdentityServer.ToString(); - options.ClientSecret = Constants.NOTESNOOK_API_SECRET; - options.ClientId = "notesnook"; - options.DiscoveryPolicy.RequireHttps = false; - options.CacheKeyGenerator = (options, token) => (token + ":" + "reference_token").Sha256(); - options.SaveToken = true; - options.EnableCaching = true; - options.CacheDuration = TimeSpan.FromMinutes(30); - }); - - services.AddServerSentEvents(); - services.AddSingleton(); - services.AddResponseCompression(options => - { - options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] { "text/event-stream" }); - }); - services.AddHealthChecks(); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (!env.IsDevelopment()) - { - app.UseForwardedHeaders(new ForwardedHeadersOptions - { - ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto - }); - } - - app.UseCors("notesnook"); - app.UseVersion(Servers.MessengerServer); - - app.UseRouting(); - - app.UseAuthorization(); - app.UseAuthentication(); - - var options = new ServerSentEventsOptions(); - options.Authorization = new ServerSentEventsAuthorization() - { - AuthenticationSchemes = "introspection" - }; - app.MapServerSentEvents("/sse", options); - - app.UseWamp(WampServers.MessengerServer, (realm, server) => - { - IServerSentEventsService service = app.ApplicationServices.GetRequiredService(); - realm.Subscribe(MessengerServerTopics.SendSSETopic, async (ev) => - { - var message = JsonSerializer.Serialize(ev.Message); - if (ev.SendToAll) - { - await SSEHelper.SendEventToAllUsersAsync(message, service); - } - else - { - await SSEHelper.SendEventToUserAsync(message, service, ev.UserId, ev.OriginTokenId); - } - }); - - IDistributedCache cache = app.GetScopedService(); - realm.Subscribe(IdentityServerTopics.ClearCacheTopic, (ev) => ev.Keys.ForEach((key) => cache.Remove(key))); - }); - - app.UseEndpoints(endpoints => - { - endpoints.MapControllers(); - endpoints.MapHealthChecks("/health"); - }); - } - } -} +/* +This file is part of the Notesnook Sync Server project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the Affero GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +Affero GNU General Public License for more details. + +You should have received a copy of the Affero GNU General Public License +along with this program. If not, see . +*/ + +using System; +using System.IdentityModel.Tokens.Jwt; +using System.Linq; +using System.Reactive.Subjects; +using System.Text.Json; +using Lib.AspNetCore.ServerSentEvents; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.HttpOverrides; +using Microsoft.AspNetCore.ResponseCompression; +using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Streetwriters.Common; +using Streetwriters.Common.Extensions; +using Streetwriters.Common.Messages; +using Streetwriters.Messenger.Helpers; +using Streetwriters.Messenger.Services; +using WampSharp.AspNetCore.WebSockets.Server; +using WampSharp.Binding; +using WampSharp.V2; +using WampSharp.V2.Realm; + +namespace Streetwriters.Messenger +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + + services.AddControllers(); + + JwtSecurityTokenHandler.DefaultMapInboundClaims = false; + JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); + + services.AddDefaultCors(); + services.AddDistributedMemoryCache(delegate (MemoryDistributedCacheOptions cacheOptions) + { + cacheOptions.SizeLimit = 262144000L; + }); + + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddOAuth2Introspection("introspection", options => + { + options.Authority = Servers.IdentityServer.ToString(); + options.ClientSecret = Constants.NOTESNOOK_API_SECRET; + options.ClientId = "notesnook"; + options.DiscoveryPolicy.RequireHttps = false; + options.CacheKeyGenerator = (options, token) => (token + ":" + "reference_token").Sha256(); + options.SaveToken = true; + options.EnableCaching = true; + options.CacheDuration = TimeSpan.FromMinutes(30); + }); + + services.AddServerSentEvents(); + services.AddSingleton(); + services.AddResponseCompression(options => + { + options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] { "text/event-stream" }); + }); + services.AddHealthChecks(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (!env.IsDevelopment()) + { + app.UseForwardedHeaders(new ForwardedHeadersOptions + { + ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto + }); + } + + app.UseCors("notesnook"); + app.UseVersion(Servers.MessengerServer); + + app.UseRouting(); + + app.UseAuthorization(); + app.UseAuthentication(); + + var options = new ServerSentEventsOptions(); + options.Authorization = new ServerSentEventsAuthorization() + { + AuthenticationSchemes = "introspection" + }; + app.MapServerSentEvents("/sse", options); + + app.UseWamp(WampServers.MessengerServer, (realm, server) => + { + IServerSentEventsService service = app.ApplicationServices.GetRequiredService(); + realm.Subscribe(MessengerServerTopics.SendSSETopic, async (ev) => + { + var message = JsonSerializer.Serialize(ev.Message); + if (ev.SendToAll) + { + await SSEHelper.SendEventToAllUsersAsync(message, service); + } + else + { + await SSEHelper.SendEventToUserAsync(message, service, ev.UserId, ev.OriginTokenId); + } + }); + + IDistributedCache cache = app.GetScopedService(); + realm.Subscribe(IdentityServerTopics.ClearCacheTopic, (ev) => ev.Keys.ForEach((key) => cache.Remove(key))); + }); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + endpoints.MapHealthChecks("/health"); + }); + } + } +} diff --git a/Streetwriters.Messenger/appsettings.Development.json b/Streetwriters.Messenger/appsettings.Development.json index 8983e0f..7073400 100644 --- a/Streetwriters.Messenger/appsettings.Development.json +++ b/Streetwriters.Messenger/appsettings.Development.json @@ -1,9 +1,9 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - } -} +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/Streetwriters.Messenger/appsettings.json b/Streetwriters.Messenger/appsettings.json index 6cf0b42..0804371 100644 --- a/Streetwriters.Messenger/appsettings.json +++ b/Streetwriters.Messenger/appsettings.json @@ -1,7 +1,7 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Warning" - } - } -} +{ + "Logging": { + "LogLevel": { + "Default": "Warning" + } + } +}