mirror of
https://github.com/streetwriters/notesnook-sync-server.git
synced 2026-02-12 19:22:45 +00:00
Compare commits
28 Commits
v1.0-beta.
...
v1.0-beta.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33a189fe91 | ||
|
|
2f361db9df | ||
|
|
bf6cd6cd46 | ||
|
|
54266d1ba3 | ||
|
|
d3894d2a9f | ||
|
|
00c089e677 | ||
|
|
fa8f69157a | ||
|
|
30d5394425 | ||
|
|
037bf4c3ea | ||
|
|
6d6342dbff | ||
|
|
8df70c81fc | ||
|
|
bf2e6efeff | ||
|
|
1e2ef0685d | ||
|
|
c1f0e24d21 | ||
|
|
a96b0e1e42 | ||
|
|
76af2cbfc8 | ||
|
|
34fa43f302 | ||
|
|
8c267e51f4 | ||
|
|
182558136a | ||
|
|
8d3b0d6dbf | ||
|
|
0841ca1aa8 | ||
|
|
11dff4f0cc | ||
|
|
bbabf51073 | ||
|
|
a135bd50d7 | ||
|
|
e5bf3367cc | ||
|
|
c6bcd4a84d | ||
|
|
07675632e0 | ||
|
|
8d15e176ff |
@@ -1,5 +1,5 @@
|
||||
**/Dockerfile
|
||||
**/bin
|
||||
**/obj
|
||||
**/.env
|
||||
**/Dockerfile
|
||||
**/bin
|
||||
**/obj
|
||||
**/.env
|
||||
**/.env.local
|
||||
12
.env
12
.env
@@ -9,8 +9,8 @@ NOTESNOOK_API_SECRET=
|
||||
|
||||
# Description: Use this flag to disable creation of new accounts on your instance (i.e. in case it is exposed to the Internet).
|
||||
# Required: yes
|
||||
# Possible values: 0 for false; 1 for true
|
||||
DISABLE_ACCOUNT_CREATION=0
|
||||
# Possible values: true/false
|
||||
DISABLE_SIGNUPS=false
|
||||
|
||||
### SMTP Configuration ###
|
||||
# SMTP Configuration is required for sending emails for password reset, 2FA emails etc. You can get SMTP settings from your email provider.
|
||||
@@ -29,14 +29,6 @@ SMTP_HOST=
|
||||
# Required: yes
|
||||
# Example: 465
|
||||
SMTP_PORT=
|
||||
# Description: The FROM email address when sending out emails. Must be an email address under your control otherwise sending will fail. Most times it is the same email address as the SMTP_USERNAME.
|
||||
# Required: no
|
||||
# Example: support@notesnook.com
|
||||
NOTESNOOK_SENDER_EMAIL=
|
||||
# Description: The reply-to email is used whenever a user is replying to the email you sent. You can use this to set a different reply-to email address than the one you used to send the email.
|
||||
# Required: no
|
||||
# Example: support@notesnook.com
|
||||
SMTP_REPLYTO_EMAIL=
|
||||
|
||||
# Description: Twilio account SID is required for sending SMS with 2FA codes. Learn more here: https://help.twilio.com/articles/14726256820123-What-is-a-Twilio-Account-SID-and-where-can-I-find-it-
|
||||
# Required: no
|
||||
|
||||
532
.gitignore
vendored
532
.gitignore
vendored
@@ -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/
|
||||
82
.vscode/tasks.json
vendored
82
.vscode/tasks.json
vendored
@@ -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"
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
6
AUTHORS
6
AUTHORS
@@ -1,3 +1,3 @@
|
||||
Notesnook Sync Server is written & maintained by:
|
||||
- Abdullah Atta <abdullahatta@streetwriters.co>
|
||||
- Ammar Ahmed <ammarahmed6506@gmail.com>
|
||||
Notesnook Sync Server is written & maintained by:
|
||||
- Abdullah Atta <abdullahatta@streetwriters.co>
|
||||
- Ammar Ahmed <ammarahmed6506@gmail.com>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
namespace Notesnook.API.Authorization
|
||||
{
|
||||
public class NotesnookUserRequirement : AuthorizationHandler<NotesnookUserRequirement>, 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
namespace Notesnook.API.Authorization
|
||||
{
|
||||
public class NotesnookUserRequirement : AuthorizationHandler<NotesnookUserRequirement>, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<ProUserRequirement>, IAuthorizationRequirement
|
||||
{
|
||||
private readonly Dictionary<string, string> 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<ProUserRequirement>, IAuthorizationRequirement
|
||||
{
|
||||
private readonly Dictionary<string, string> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<SyncRequirement>, IAuthorizationRequirement
|
||||
{
|
||||
private readonly Dictionary<string, string> 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<SyncRequirement>, IAuthorizationRequirement
|
||||
{
|
||||
private readonly Dictionary<string, string> 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<Announcement> Announcements { get; set; }
|
||||
public AnnouncementController(Repository<Announcement> announcements)
|
||||
{
|
||||
Announcements = announcements;
|
||||
}
|
||||
|
||||
[HttpGet("active")]
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> GetActiveAnnouncements([FromQuery] string userId)
|
||||
{
|
||||
var totalActive = await Announcements.Collection.CountDocumentsAsync(Builders<Announcement>.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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<Announcement> Announcements { get; set; }
|
||||
public AnnouncementController(Repository<Announcement> announcements)
|
||||
{
|
||||
Announcements = announcements;
|
||||
}
|
||||
|
||||
[HttpGet("active")]
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> GetActiveAnnouncements([FromQuery] string userId)
|
||||
{
|
||||
var totalActive = await Announcements.Collection.CountDocumentsAsync(Builders<Announcement>.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,14 +18,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Driver;
|
||||
using Notesnook.API.Models;
|
||||
using Notesnook.API.Services;
|
||||
using Streetwriters.Common;
|
||||
using Streetwriters.Common.Messages;
|
||||
using Streetwriters.Data.Interfaces;
|
||||
using Streetwriters.Data.Repositories;
|
||||
|
||||
@@ -46,53 +51,145 @@ namespace Notesnook.API.Controllers
|
||||
unit = unitOfWork;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> PublishAsync([FromBody] Monograph monograph)
|
||||
private static FilterDefinition<Monograph> CreateMonographFilter(string userId, Monograph monograph)
|
||||
{
|
||||
var userId = this.User.FindFirstValue("sub");
|
||||
if (userId == null) return Unauthorized();
|
||||
var userIdFilter = Builders<Monograph>.Filter.Eq("UserId", userId);
|
||||
return ObjectId.TryParse(monograph.ItemId, out ObjectId id)
|
||||
? Builders<Monograph>.Filter
|
||||
.And(userIdFilter,
|
||||
Builders<Monograph>.Filter.Or(
|
||||
Builders<Monograph>.Filter.Eq("_id", id), Builders<Monograph>.Filter.Eq("ItemId", monograph.ItemId)
|
||||
)
|
||||
)
|
||||
: Builders<Monograph>.Filter
|
||||
.And(userIdFilter,
|
||||
Builders<Monograph>.Filter.Eq("ItemId", monograph.ItemId)
|
||||
);
|
||||
}
|
||||
|
||||
if (await Monographs.GetAsync(monograph.Id) != null) return base.Conflict("This monograph is already published.");
|
||||
private static FilterDefinition<Monograph> CreateMonographFilter(string itemId)
|
||||
{
|
||||
return ObjectId.TryParse(itemId, out ObjectId id)
|
||||
? Builders<Monograph>.Filter.Or(
|
||||
Builders<Monograph>.Filter.Eq("_id", id),
|
||||
Builders<Monograph>.Filter.Eq("ItemId", itemId))
|
||||
: Builders<Monograph>.Filter.Eq("ItemId", itemId);
|
||||
}
|
||||
|
||||
if (monograph.EncryptedContent == null)
|
||||
monograph.CompressedContent = monograph.Content.CompressBrotli();
|
||||
monograph.UserId = userId;
|
||||
monograph.DatePublished = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
|
||||
|
||||
if (monograph.EncryptedContent?.Cipher.Length > MAX_DOC_SIZE || monograph.CompressedContent?.Length > MAX_DOC_SIZE)
|
||||
return base.BadRequest("Monograph is too big. Max allowed size is 15mb.");
|
||||
|
||||
Monographs.Insert(monograph);
|
||||
|
||||
if (!await unit.Commit()) return BadRequest();
|
||||
return Ok(new
|
||||
private async Task<Monograph> FindMonographAsync(string userId, Monograph monograph)
|
||||
{
|
||||
var result = await Monographs.Collection.FindAsync(CreateMonographFilter(userId, monograph), new FindOptions<Monograph>
|
||||
{
|
||||
id = monograph.Id
|
||||
Limit = 1
|
||||
});
|
||||
return await result.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
private async Task<Monograph> FindMonographAsync(string itemId)
|
||||
{
|
||||
var result = await Monographs.Collection.FindAsync(CreateMonographFilter(itemId), new FindOptions<Monograph>
|
||||
{
|
||||
Limit = 1
|
||||
});
|
||||
return await result.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> PublishAsync([FromQuery] string deviceId, [FromBody] Monograph monograph)
|
||||
{
|
||||
try
|
||||
{
|
||||
var userId = this.User.FindFirstValue("sub");
|
||||
if (userId == null) return Unauthorized();
|
||||
|
||||
var existingMonograph = await FindMonographAsync(userId, monograph);
|
||||
if (existingMonograph != null && !existingMonograph.Deleted)
|
||||
{
|
||||
return base.Conflict("This monograph is already published.");
|
||||
}
|
||||
|
||||
if (monograph.EncryptedContent == null)
|
||||
monograph.CompressedContent = monograph.Content.CompressBrotli();
|
||||
monograph.UserId = userId;
|
||||
monograph.DatePublished = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
|
||||
if (monograph.EncryptedContent?.Cipher.Length > MAX_DOC_SIZE || monograph.CompressedContent?.Length > MAX_DOC_SIZE)
|
||||
return base.BadRequest("Monograph is too big. Max allowed size is 15mb.");
|
||||
|
||||
if (existingMonograph != null)
|
||||
{
|
||||
monograph.Id = existingMonograph?.Id;
|
||||
}
|
||||
monograph.Deleted = false;
|
||||
await Monographs.Collection.ReplaceOneAsync(
|
||||
CreateMonographFilter(userId, monograph),
|
||||
monograph,
|
||||
new ReplaceOptions { IsUpsert = true }
|
||||
);
|
||||
|
||||
await MarkMonographForSyncAsync(monograph.ItemId ?? monograph.Id, deviceId);
|
||||
|
||||
return Ok(new
|
||||
{
|
||||
id = monograph.ItemId,
|
||||
datePublished = monograph.DatePublished,
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await Slogger<MonographsController>.Error(nameof(PublishAsync), e.ToString());
|
||||
return BadRequest();
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPatch]
|
||||
public async Task<IActionResult> UpdateAsync([FromBody] Monograph monograph)
|
||||
public async Task<IActionResult> UpdateAsync([FromQuery] string deviceId, [FromBody] Monograph monograph)
|
||||
{
|
||||
if (await Monographs.GetAsync(monograph.Id) == null) return NotFound();
|
||||
|
||||
if (monograph.EncryptedContent?.Cipher.Length > MAX_DOC_SIZE || monograph.CompressedContent?.Length > MAX_DOC_SIZE)
|
||||
return base.BadRequest("Monograph is too big. Max allowed size is 15mb.");
|
||||
|
||||
if (monograph.EncryptedContent == null)
|
||||
monograph.CompressedContent = monograph.Content.CompressBrotli();
|
||||
else
|
||||
monograph.Content = null;
|
||||
|
||||
monograph.DatePublished = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
Monographs.Update(monograph.Id, monograph);
|
||||
|
||||
if (!await unit.Commit()) return BadRequest();
|
||||
return Ok(new
|
||||
try
|
||||
{
|
||||
id = monograph.Id
|
||||
});
|
||||
var userId = this.User.FindFirstValue("sub");
|
||||
if (userId == null) return Unauthorized();
|
||||
|
||||
var existingMonograph = await FindMonographAsync(userId, monograph);
|
||||
if (existingMonograph == null || existingMonograph.Deleted)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (monograph.EncryptedContent?.Cipher.Length > MAX_DOC_SIZE || monograph.CompressedContent?.Length > MAX_DOC_SIZE)
|
||||
return base.BadRequest("Monograph is too big. Max allowed size is 15mb.");
|
||||
|
||||
if (monograph.EncryptedContent == null)
|
||||
monograph.CompressedContent = monograph.Content.CompressBrotli();
|
||||
else
|
||||
monograph.Content = null;
|
||||
|
||||
monograph.DatePublished = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
var result = await Monographs.Collection.UpdateOneAsync(
|
||||
CreateMonographFilter(userId, monograph),
|
||||
Builders<Monograph>.Update
|
||||
.Set(m => m.DatePublished, monograph.DatePublished)
|
||||
.Set(m => m.CompressedContent, monograph.CompressedContent)
|
||||
.Set(m => m.EncryptedContent, monograph.EncryptedContent)
|
||||
.Set(m => m.SelfDestruct, monograph.SelfDestruct)
|
||||
.Set(m => m.Title, monograph.Title)
|
||||
.Set(m => m.Password, monograph.Password)
|
||||
);
|
||||
if (!result.IsAcknowledged) return BadRequest();
|
||||
|
||||
await MarkMonographForSyncAsync(monograph.ItemId ?? monograph.Id, deviceId);
|
||||
|
||||
return Ok(new
|
||||
{
|
||||
id = monograph.ItemId,
|
||||
datePublished = monograph.DatePublished,
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await Slogger<MonographsController>.Error(nameof(UpdateAsync), e.ToString());
|
||||
return BadRequest();
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
@@ -101,20 +198,24 @@ namespace Notesnook.API.Controllers
|
||||
var userId = this.User.FindFirstValue("sub");
|
||||
if (userId == null) return Unauthorized();
|
||||
|
||||
var monographs = (await Monographs.Collection.FindAsync(Builders<Monograph>.Filter.Eq("UserId", userId), new FindOptions<Monograph, ObjectWithId>
|
||||
{
|
||||
Projection = Builders<Monograph>.Projection.Include("_id"),
|
||||
})).ToEnumerable();
|
||||
return Ok(monographs.Select((m) => m.Id));
|
||||
var monographs = (await Monographs.Collection.FindAsync(
|
||||
Builders<Monograph>.Filter.And(
|
||||
Builders<Monograph>.Filter.Eq("UserId", userId),
|
||||
Builders<Monograph>.Filter.Ne("Deleted", true)
|
||||
)
|
||||
, new FindOptions<Monograph, ObjectWithId>
|
||||
{
|
||||
Projection = Builders<Monograph>.Projection.Include("_id").Include("ItemId"),
|
||||
})).ToEnumerable();
|
||||
return Ok(monographs.Select((m) => m.ItemId ?? m.Id));
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("{id}")]
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> GetMonographAsync([FromRoute] string id)
|
||||
{
|
||||
var monograph = await Monographs.GetAsync(id);
|
||||
if (monograph == null)
|
||||
var monograph = await FindMonographAsync(id);
|
||||
if (monograph == null || monograph.Deleted)
|
||||
{
|
||||
return NotFound(new
|
||||
{
|
||||
@@ -125,6 +226,7 @@ namespace Notesnook.API.Controllers
|
||||
|
||||
if (monograph.EncryptedContent == null)
|
||||
monograph.Content = monograph.CompressedContent.DecompressBrotli();
|
||||
if (monograph.ItemId == null) monograph.ItemId = monograph.Id;
|
||||
return Ok(monograph);
|
||||
}
|
||||
|
||||
@@ -132,21 +234,90 @@ namespace Notesnook.API.Controllers
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> TrackView([FromRoute] string id)
|
||||
{
|
||||
var monograph = await Monographs.GetAsync(id);
|
||||
if (monograph == null) return Content(SVG_PIXEL, "image/svg+xml");
|
||||
var monograph = await FindMonographAsync(id);
|
||||
if (monograph == null || monograph.Deleted) return Content(SVG_PIXEL, "image/svg+xml");
|
||||
|
||||
if (monograph.SelfDestruct)
|
||||
await Monographs.DeleteByIdAsync(monograph.Id);
|
||||
{
|
||||
var userId = this.User.FindFirstValue("sub");
|
||||
await Monographs.Collection.ReplaceOneAsync(
|
||||
CreateMonographFilter(userId, monograph),
|
||||
new Monograph
|
||||
{
|
||||
ItemId = id,
|
||||
Id = monograph.Id,
|
||||
Deleted = true
|
||||
}
|
||||
);
|
||||
|
||||
await MarkMonographForSyncAsync(id);
|
||||
}
|
||||
|
||||
return Content(SVG_PIXEL, "image/svg+xml");
|
||||
}
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public async Task<IActionResult> DeleteAsync([FromRoute] string id)
|
||||
public async Task<IActionResult> DeleteAsync([FromQuery] string deviceId, [FromRoute] string id)
|
||||
{
|
||||
Monographs.DeleteById(id);
|
||||
if (!await unit.Commit()) return BadRequest();
|
||||
var monograph = await FindMonographAsync(id);
|
||||
if (monograph == null || monograph.Deleted)
|
||||
{
|
||||
return NotFound(new
|
||||
{
|
||||
error = "invalid_id",
|
||||
error_description = $"No such monograph found."
|
||||
});
|
||||
}
|
||||
|
||||
var userId = this.User.FindFirstValue("sub");
|
||||
await Monographs.Collection.ReplaceOneAsync(
|
||||
CreateMonographFilter(userId, monograph),
|
||||
new Monograph
|
||||
{
|
||||
ItemId = id,
|
||||
Id = monograph.Id,
|
||||
Deleted = true,
|
||||
UserId = monograph.UserId
|
||||
}
|
||||
);
|
||||
|
||||
await MarkMonographForSyncAsync(id, deviceId);
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
private async Task MarkMonographForSyncAsync(string monographId, string deviceId)
|
||||
{
|
||||
if (deviceId == null) return;
|
||||
var userId = this.User.FindFirstValue("sub");
|
||||
|
||||
new SyncDeviceService(new SyncDevice(userId, deviceId)).AddIdsToOtherDevices([$"{monographId}:monograph"]);
|
||||
await SendTriggerSyncEventAsync();
|
||||
}
|
||||
|
||||
private async Task MarkMonographForSyncAsync(string monographId)
|
||||
{
|
||||
var userId = this.User.FindFirstValue("sub");
|
||||
|
||||
new SyncDeviceService(new SyncDevice(userId, string.Empty)).AddIdsToAllDevices([$"{monographId}:monograph"]);
|
||||
await SendTriggerSyncEventAsync(sendToAllDevices: true);
|
||||
}
|
||||
|
||||
private async Task SendTriggerSyncEventAsync(bool sendToAllDevices = false)
|
||||
{
|
||||
var userId = this.User.FindFirstValue("sub");
|
||||
var jti = this.User.FindFirstValue("jti");
|
||||
|
||||
await WampServers.MessengerServer.PublishMessageAsync(MessengerServerTopics.SendSSETopic, new SendSSEMessage
|
||||
{
|
||||
OriginTokenId = sendToAllDevices ? null : jti,
|
||||
UserId = userId,
|
||||
Message = new Message
|
||||
{
|
||||
Type = "triggerSync",
|
||||
Data = JsonSerializer.Serialize(new { reason = "Monographs updated." })
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ using System.Threading.Tasks;
|
||||
using System.Security.Claims;
|
||||
using Notesnook.API.Interfaces;
|
||||
using System;
|
||||
using Notesnook.API.Models;
|
||||
|
||||
namespace Notesnook.API.Controllers
|
||||
{
|
||||
@@ -77,12 +78,12 @@ namespace Notesnook.API.Controllers
|
||||
|
||||
[HttpPost("multipart")]
|
||||
[Authorize("Pro")]
|
||||
public async Task<IActionResult> CompleteMultipartUpload([FromBody] CompleteMultipartUploadRequest uploadRequest)
|
||||
public async Task<IActionResult> CompleteMultipartUpload([FromBody] CompleteMultipartUploadRequestWrapper uploadRequestWrapper)
|
||||
{
|
||||
var userId = this.User.FindFirstValue("sub");
|
||||
try
|
||||
{
|
||||
await S3Service.CompleteMultipartUploadAsync(userId, uploadRequest);
|
||||
await S3Service.CompleteMultipartUploadAsync(userId, uploadRequestWrapper.ToRequest());
|
||||
return Ok();
|
||||
}
|
||||
catch (Exception ex) { return BadRequest(ex.Message); }
|
||||
@@ -124,4 +125,4 @@ namespace Notesnook.API.Controllers
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,8 +43,8 @@ namespace Notesnook.API.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
var userId = this.User.FindFirstValue("sub");
|
||||
new SyncDeviceService(new SyncDevice(ref userId, ref deviceId)).RegisterDevice();
|
||||
var userId = this.User.FindFirstValue("sub") ?? throw new Exception("User not found.");
|
||||
new SyncDeviceService(new SyncDevice(userId, deviceId)).RegisterDevice();
|
||||
return Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -60,8 +60,8 @@ namespace Notesnook.API.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
var userId = this.User.FindFirstValue("sub");
|
||||
new SyncDeviceService(new SyncDevice(ref userId, ref deviceId)).UnregisterDevice();
|
||||
var userId = this.User.FindFirstValue("sub") ?? throw new Exception("User not found.");
|
||||
new SyncDeviceService(new SyncDevice(userId, deviceId)).UnregisterDevice();
|
||||
return Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -1,116 +1,120 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<IActionResult> Signup()
|
||||
{
|
||||
try
|
||||
{
|
||||
await UserService.CreateUserAsync();
|
||||
return Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await Slogger<UsersController>.Error(nameof(Signup), "Couldn't sign up.", ex.ToString());
|
||||
return BadRequest(new { error = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> 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<UsersController>.Error(nameof(GetUser), "Couldn't get user for id.", userId, ex.ToString());
|
||||
return BadRequest(new { error = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPatch]
|
||||
public async Task<IActionResult> 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<UsersController>.Error(nameof(GetUser), "Couldn't update user with id.", userId, ex.ToString());
|
||||
return BadRequest(new { error = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("reset")]
|
||||
public async Task<IActionResult> 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<IActionResult> 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<UsersController>.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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<IActionResult> Signup()
|
||||
{
|
||||
try
|
||||
{
|
||||
await UserService.CreateUserAsync();
|
||||
return Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await Slogger<UsersController>.Error(nameof(Signup), "Couldn't sign up.", ex.ToString());
|
||||
return BadRequest(new { error = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> 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<UsersController>.Error(nameof(GetUser), "Couldn't get user for id.", userId, ex.ToString());
|
||||
return BadRequest(new { error = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPatch]
|
||||
public async Task<IActionResult> UpdateUser([FromBody] UserResponse user)
|
||||
{
|
||||
var userId = User.FindFirstValue("sub");
|
||||
try
|
||||
{
|
||||
var keys = new UserKeys
|
||||
{
|
||||
AttachmentsKey = user.AttachmentsKey,
|
||||
MonographPasswordsKey = user.MonographPasswordsKey
|
||||
};
|
||||
await UserService.SetUserKeysAsync(userId, keys);
|
||||
return Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await Slogger<UsersController>.Error(nameof(GetUser), "Couldn't update user with id.", userId, ex.ToString());
|
||||
return BadRequest(new { error = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("reset")]
|
||||
public async Task<IActionResult> 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<IActionResult> 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<UsersController>.Error(nameof(GetUser), "Couldn't delete user with id.", userId, ex.ToString());
|
||||
return BadRequest(new { error = ex.Message });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"]
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<CancellationToken> 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<CancellationToken> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.Metrics;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text.Json.Serialization;
|
||||
@@ -28,8 +27,6 @@ using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization;
|
||||
using MongoDB.Driver;
|
||||
using Notesnook.API.Authorization;
|
||||
using Notesnook.API.Interfaces;
|
||||
@@ -43,6 +40,7 @@ namespace Notesnook.API.Hubs
|
||||
{
|
||||
Task<bool> SendItems(SyncTransferItemV2 transferItem);
|
||||
Task<bool> SendVaultKey(EncryptedData vaultKey);
|
||||
Task<bool> SendMonographs(IEnumerable<Monograph> monographs);
|
||||
Task PushCompleted();
|
||||
}
|
||||
|
||||
@@ -103,25 +101,6 @@ namespace Notesnook.API.Hubs
|
||||
};
|
||||
}
|
||||
|
||||
private Func<string, IEnumerable<string>, bool, int, Task<IAsyncCursor<SyncItem>>> MapTypeToFindItemsAction(string type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
"settingitem" => Repositories.Settings.FindItemsById,
|
||||
"attachment" => Repositories.Attachments.FindItemsById,
|
||||
"note" => Repositories.Notes.FindItemsById,
|
||||
"notebook" => Repositories.Notebooks.FindItemsById,
|
||||
"content" => Repositories.Contents.FindItemsById,
|
||||
"shortcut" => Repositories.Shortcuts.FindItemsById,
|
||||
"reminder" => Repositories.Reminders.FindItemsById,
|
||||
"relation" => Repositories.Relations.FindItemsById,
|
||||
"color" => Repositories.Colors.FindItemsById,
|
||||
"vault" => Repositories.Vaults.FindItemsById,
|
||||
"tag" => Repositories.Tags.FindItemsById,
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<int> PushItems(string deviceId, SyncTransferItemV2 pushItem)
|
||||
{
|
||||
var userId = Context.User.FindFirstValue("sub");
|
||||
@@ -139,7 +118,7 @@ namespace Notesnook.API.Hubs
|
||||
|
||||
if (!await unit.Commit()) return 0;
|
||||
|
||||
await new SyncDeviceService(new SyncDevice(ref userId, ref deviceId)).AddIdsToOtherDevicesAsync(pushItem.Items.Select((i) => $"{i.ItemId}:{pushItem.Type}").ToList());
|
||||
new SyncDeviceService(new SyncDevice(userId, deviceId)).AddIdsToOtherDevices(pushItem.Items.Select((i) => $"{i.ItemId}:{pushItem.Type}").ToList());
|
||||
return 1;
|
||||
}
|
||||
finally
|
||||
@@ -158,7 +137,7 @@ namespace Notesnook.API.Hubs
|
||||
|
||||
private static async IAsyncEnumerable<SyncTransferItemV2> PrepareChunks(Func<string, string[], bool, int, Task<IAsyncCursor<SyncItem>>>[] collections, string[] types, string userId, string[] ids, int size, bool resetSync, long maxBytes)
|
||||
{
|
||||
var chunksProcessed = 0;
|
||||
var itemsProcessed = 0;
|
||||
for (int i = 0; i < collections.Length; i++)
|
||||
{
|
||||
var type = types[i];
|
||||
@@ -180,11 +159,12 @@ namespace Notesnook.API.Hubs
|
||||
totalBytes += item.Length + METADATA_BYTES;
|
||||
if (totalBytes >= maxBytes)
|
||||
{
|
||||
itemsProcessed += chunk.Count;
|
||||
yield return new SyncTransferItemV2
|
||||
{
|
||||
Items = chunk,
|
||||
Type = type,
|
||||
Count = chunksProcessed
|
||||
Count = itemsProcessed
|
||||
};
|
||||
|
||||
totalBytes = 0;
|
||||
@@ -194,11 +174,12 @@ namespace Notesnook.API.Hubs
|
||||
}
|
||||
if (chunk.Count > 0)
|
||||
{
|
||||
itemsProcessed += chunk.Count;
|
||||
yield return new SyncTransferItemV2
|
||||
{
|
||||
Items = chunk,
|
||||
Type = type,
|
||||
Count = chunksProcessed
|
||||
Count = itemsProcessed
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -211,9 +192,12 @@ namespace Notesnook.API.Hubs
|
||||
|
||||
SyncEventCounterSource.Log.FetchV2();
|
||||
|
||||
var deviceService = new SyncDeviceService(new SyncDevice(ref userId, ref deviceId));
|
||||
var device = new SyncDevice(userId, deviceId);
|
||||
var deviceService = new SyncDeviceService(device);
|
||||
if (!deviceService.IsDeviceRegistered()) deviceService.RegisterDevice();
|
||||
|
||||
device.LastAccessTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
|
||||
var isResetSync = deviceService.IsSyncReset();
|
||||
if (!deviceService.IsUnsynced() &&
|
||||
!deviceService.IsSyncPending() &&
|
||||
@@ -224,7 +208,7 @@ namespace Notesnook.API.Hubs
|
||||
stopwatch.Start();
|
||||
try
|
||||
{
|
||||
string[] ids = await deviceService.FetchUnsyncedIdsAsync();
|
||||
string[] ids = deviceService.FetchUnsyncedIds();
|
||||
|
||||
var chunks = PrepareChunks(
|
||||
collections: [
|
||||
@@ -254,6 +238,7 @@ namespace Notesnook.API.Hubs
|
||||
if (!await Clients.Caller.SendVaultKey(userSettings.VaultKey).WaitAsync(TimeSpan.FromMinutes(10))) throw new HubException("Client rejected vault key.");
|
||||
}
|
||||
|
||||
|
||||
await foreach (var chunk in chunks)
|
||||
{
|
||||
if (!await Clients.Caller.SendItems(chunk).WaitAsync(TimeSpan.FromMinutes(10))) throw new HubException("Client rejected sent items.");
|
||||
@@ -262,10 +247,19 @@ namespace Notesnook.API.Hubs
|
||||
{
|
||||
var syncedIds = chunk.Items.Select((i) => $"{i.ItemId}:{chunk.Type}").ToHashSet();
|
||||
ids = ids.Where((id) => !syncedIds.Contains(id)).ToArray();
|
||||
await deviceService.WritePendingIdsAsync(ids);
|
||||
deviceService.WritePendingIds(ids);
|
||||
}
|
||||
}
|
||||
|
||||
// var unsyncedMonographs = ids.Where((id) => id.EndsWith(":monograph")).ToHashSet();
|
||||
// var unsyncedMonographIds = unsyncedMonographs.Select((id) => id.Split(":")[0]).ToArray();
|
||||
// var userMonographs = isResetSync
|
||||
// ? await Repositories.Monographs.FindAsync(m => m.UserId == userId)
|
||||
// : await Repositories.Monographs.FindAsync(m => m.UserId == userId && unsyncedMonographIds.Contains(m.ItemId));
|
||||
|
||||
// if (userMonographs.Any() && !await Clients.Caller.SendMonographs(userMonographs).WaitAsync(TimeSpan.FromMinutes(10)))
|
||||
// throw new HubException("Client rejected monographs.");
|
||||
|
||||
deviceService.Reset();
|
||||
|
||||
return new SyncV2Metadata
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Notesnook.API.Interfaces
|
||||
{
|
||||
public interface IEncrypted
|
||||
{
|
||||
string Cipher { get; set; }
|
||||
string IV { get; set; }
|
||||
long Length { get; set; }
|
||||
string Salt { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<long> GetObjectSizeAsync(string userId, string name);
|
||||
string GetUploadObjectUrl(string userId, string name);
|
||||
string GetDownloadObjectUrl(string userId, string name);
|
||||
Task<MultipartUploadMeta> 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<long> GetObjectSizeAsync(string userId, string name);
|
||||
string GetUploadObjectUrl(string userId, string name);
|
||||
string GetDownloadObjectUrl(string userId, string name);
|
||||
Task<MultipartUploadMeta> StartMultipartUploadAsync(string userId, string name, int parts, string uploadId = null);
|
||||
Task AbortMultipartUploadAsync(string userId, string name, string uploadId);
|
||||
Task CompleteMultipartUploadAsync(string userId, CompleteMultipartUploadRequest uploadRequest);
|
||||
}
|
||||
}
|
||||
@@ -1,36 +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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<bool> ResetUserAsync(string userId, bool removeAttachments);
|
||||
Task<UserResponse> 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Notesnook.API.Models;
|
||||
using Notesnook.API.Models.Responses;
|
||||
|
||||
namespace Notesnook.API.Interfaces
|
||||
{
|
||||
public interface IUserService
|
||||
{
|
||||
Task CreateUserAsync();
|
||||
Task DeleteUserAsync(string userId);
|
||||
Task DeleteUserAsync(string userId, string jti, string password);
|
||||
Task<bool> ResetUserAsync(string userId, bool removeAttachments);
|
||||
Task<UserResponse> GetUserAsync(string userId);
|
||||
Task SetUserKeysAsync(string userId, UserKeys keys);
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Notesnook.API.Models
|
||||
{
|
||||
public class Algorithms
|
||||
{
|
||||
public static string Default => "xcha-argon2i13-7";
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using Amazon.S3.Model;
|
||||
|
||||
namespace Notesnook.API.Models;
|
||||
|
||||
public class CompleteMultipartUploadRequestWrapper
|
||||
{
|
||||
public string Key { get; set; }
|
||||
public List<PartETagWrapper> PartETags { get; set; }
|
||||
public string UploadId { get; set; }
|
||||
|
||||
public CompleteMultipartUploadRequest ToRequest()
|
||||
{
|
||||
CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest();
|
||||
completeMultipartUploadRequest.Key = Key;
|
||||
completeMultipartUploadRequest.UploadId = UploadId;
|
||||
completeMultipartUploadRequest.PartETags = [];
|
||||
foreach (var partETagWrapper in PartETags)
|
||||
{
|
||||
var partETag = new PartETag
|
||||
{
|
||||
PartNumber = partETagWrapper.PartNumber,
|
||||
ETag = partETagWrapper.ETag
|
||||
};
|
||||
completeMultipartUploadRequest.PartETags.Add(partETag);
|
||||
}
|
||||
|
||||
return completeMultipartUploadRequest;
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,67 +1,96 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
using Notesnook.API.Interfaces;
|
||||
|
||||
namespace Notesnook.API.Models
|
||||
{
|
||||
public class ObjectWithId
|
||||
{
|
||||
[BsonId]
|
||||
[BsonRepresentation(BsonType.ObjectId)]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
public class Monograph : IMonograph
|
||||
{
|
||||
public Monograph()
|
||||
{
|
||||
Id = ObjectId.GenerateNewId().ToString();
|
||||
}
|
||||
|
||||
[BsonId]
|
||||
[BsonRepresentation(BsonType.ObjectId)]
|
||||
public string Id { get; set; }
|
||||
|
||||
[JsonPropertyName("title")]
|
||||
public string Title { get; set; }
|
||||
|
||||
[JsonPropertyName("userId")]
|
||||
public string UserId { get; set; }
|
||||
|
||||
[JsonPropertyName("selfDestruct")]
|
||||
public bool SelfDestruct { get; set; }
|
||||
|
||||
[JsonPropertyName("encryptedContent")]
|
||||
public EncryptedData EncryptedContent { get; set; }
|
||||
|
||||
[JsonPropertyName("datePublished")]
|
||||
public long DatePublished { get; set; }
|
||||
|
||||
[JsonPropertyName("content")]
|
||||
[BsonIgnore]
|
||||
public string Content { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public byte[] CompressedContent { 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Notesnook.API.Models
|
||||
{
|
||||
public class ObjectWithId
|
||||
{
|
||||
[BsonId]
|
||||
[BsonIgnoreIfDefault]
|
||||
[BsonRepresentation(BsonType.ObjectId)]
|
||||
public string Id
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public string ItemId
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
public class Monograph
|
||||
{
|
||||
public Monograph()
|
||||
{
|
||||
Id = ObjectId.GenerateNewId().ToString();
|
||||
}
|
||||
|
||||
[DataMember(Name = "id")]
|
||||
[JsonPropertyName("id")]
|
||||
[MessagePack.Key("id")]
|
||||
public string ItemId
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
[BsonId]
|
||||
[BsonIgnoreIfDefault]
|
||||
[BsonRepresentation(BsonType.ObjectId)]
|
||||
[JsonIgnore]
|
||||
[MessagePack.IgnoreMember]
|
||||
public string Id
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
[JsonPropertyName("title")]
|
||||
public string Title { get; set; }
|
||||
|
||||
[JsonPropertyName("userId")]
|
||||
public string UserId { get; set; }
|
||||
|
||||
[JsonPropertyName("selfDestruct")]
|
||||
public bool SelfDestruct { get; set; }
|
||||
|
||||
[JsonPropertyName("encryptedContent")]
|
||||
public EncryptedData EncryptedContent { get; set; }
|
||||
|
||||
[JsonPropertyName("datePublished")]
|
||||
public long DatePublished { get; set; }
|
||||
|
||||
[JsonPropertyName("content")]
|
||||
[BsonIgnore]
|
||||
public string Content { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public byte[] CompressedContent { get; set; }
|
||||
|
||||
[JsonPropertyName("password")]
|
||||
public EncryptedData Password { get; set; }
|
||||
|
||||
[JsonPropertyName("deleted")]
|
||||
public bool Deleted { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Notesnook.API.Models
|
||||
{
|
||||
public class MultipartUploadMeta
|
||||
{
|
||||
public string UploadId { get; set; }
|
||||
public string[] Parts { get; set; }
|
||||
}
|
||||
}
|
||||
7
Notesnook.API/Models/PartETagWrapper.cs
Normal file
7
Notesnook.API/Models/PartETagWrapper.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Notesnook.API.Models;
|
||||
|
||||
public class PartETagWrapper
|
||||
{
|
||||
public int PartNumber { get; set; }
|
||||
public string ETag { get; set; }
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,28 @@
|
||||
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("monographPasswordsKey")]
|
||||
public EncryptedData MonographPasswordsKey { 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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -17,17 +17,11 @@ You should have received a copy of the Affero GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using Streetwriters.Identity.Interfaces;
|
||||
|
||||
namespace Streetwriters.Identity.Models
|
||||
namespace Notesnook.API.Models
|
||||
{
|
||||
public class EmailTemplate : IEmailTemplate
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
public object Data { get; set; }
|
||||
public long? SendAt { get; set; }
|
||||
public string Subject { get; set; }
|
||||
public string Html { get; set; }
|
||||
public string Text { get; set; }
|
||||
}
|
||||
}
|
||||
public class UserKeys
|
||||
{
|
||||
public EncryptedData AttachmentsKey { get; set; }
|
||||
public EncryptedData MonographPasswordsKey { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,42 +1,50 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
using Notesnook.API.Interfaces;
|
||||
|
||||
namespace Notesnook.API.Models
|
||||
{
|
||||
public class Limit
|
||||
{
|
||||
public long Value { get; set; }
|
||||
public long UpdatedAt { get; set; }
|
||||
}
|
||||
|
||||
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; }
|
||||
public EncryptedData MonographPasswordsKey { get; set; }
|
||||
public Limit StorageLimit { get; set; }
|
||||
|
||||
[BsonId]
|
||||
[BsonRepresentation(BsonType.ObjectId)]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !DEBUG
|
||||
using System.Net;
|
||||
#endif
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Streetwriters.Common;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Net;
|
||||
|
||||
namespace Notesnook.API
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
#if DEBUG
|
||||
DotNetEnv.Env.TraversePath().Load(".env.local");
|
||||
#else
|
||||
DotNetEnv.Env.TraversePath().Load(".env");
|
||||
#endif
|
||||
IHost host = CreateHostBuilder(args).Build();
|
||||
await host.RunAsync();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder
|
||||
.UseStartup<Startup>()
|
||||
.UseKestrel((options) =>
|
||||
{
|
||||
options.Limits.MaxRequestBodySize = long.MaxValue;
|
||||
options.ListenAnyIP(Servers.NotesnookAPI.Port);
|
||||
if (Servers.NotesnookAPI.IsSecure)
|
||||
{
|
||||
options.ListenAnyIP(443, listenerOptions =>
|
||||
{
|
||||
listenerOptions.UseHttps(Servers.NotesnookAPI.SSLCertificate);
|
||||
});
|
||||
}
|
||||
options.Listen(IPAddress.Parse("127.0.0.1"), 5067);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Streetwriters.Common;
|
||||
using System.Net;
|
||||
|
||||
namespace Notesnook.API
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
#if (DEBUG || STAGING)
|
||||
DotNetEnv.Env.TraversePath().Load(".env.local");
|
||||
#else
|
||||
DotNetEnv.Env.TraversePath().Load(".env");
|
||||
#endif
|
||||
IHost host = CreateHostBuilder(args).Build();
|
||||
await host.RunAsync();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder
|
||||
.UseStartup<Startup>()
|
||||
.UseKestrel((options) =>
|
||||
{
|
||||
options.Limits.MaxRequestBodySize = long.MaxValue;
|
||||
options.ListenAnyIP(Servers.NotesnookAPI.Port);
|
||||
if (Servers.NotesnookAPI.IsSecure)
|
||||
{
|
||||
options.ListenAnyIP(443, listenerOptions =>
|
||||
{
|
||||
listenerOptions.UseHttps(Servers.NotesnookAPI.SSLCertificate);
|
||||
});
|
||||
}
|
||||
options.Listen(IPAddress.Parse("127.0.0.1"), 5067);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,13 +44,6 @@ namespace Notesnook.API.Repositories
|
||||
public SyncItemsRepository(IDbContext dbContext, IMongoCollection<SyncItem> collection) : base(dbContext, collection)
|
||||
{
|
||||
this.collectionName = collection.CollectionNamespace.CollectionName;
|
||||
#if DEBUG
|
||||
Collection.Indexes.CreateMany([
|
||||
new CreateIndexModel<SyncItem>(Builders<SyncItem>.IndexKeys.Ascending("UserId").Descending("DateSynced")),
|
||||
new CreateIndexModel<SyncItem>(Builders<SyncItem>.IndexKeys.Ascending("UserId").Ascending("ItemId")),
|
||||
new CreateIndexModel<SyncItem>(Builders<SyncItem>.IndexKeys.Ascending("UserId"))
|
||||
]);
|
||||
#endif
|
||||
}
|
||||
|
||||
private readonly List<string> ALGORITHMS = [Algorithms.Default];
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace Notesnook.API.Services
|
||||
{
|
||||
var config = new AmazonS3Config
|
||||
{
|
||||
#if DEBUG
|
||||
#if (DEBUG || STAGING)
|
||||
ServiceURL = Servers.S3Server.ToString(),
|
||||
#else
|
||||
ServiceURL = Constants.S3_SERVICE_URL,
|
||||
@@ -71,7 +71,7 @@ namespace Notesnook.API.Services
|
||||
SignatureMethod = SigningAlgorithm.HmacSHA256,
|
||||
SignatureVersion = "4"
|
||||
};
|
||||
#if DEBUG
|
||||
#if (DEBUG || STAGING)
|
||||
S3Client = new AmazonS3Client("S3RVER", "S3RVER", config);
|
||||
#else
|
||||
S3Client = new AmazonS3Client(Constants.S3_ACCESS_KEY_ID, Constants.S3_ACCESS_KEY, config);
|
||||
@@ -227,7 +227,7 @@ namespace Notesnook.API.Services
|
||||
Expires = System.DateTime.Now.AddHours(1),
|
||||
Verb = httpVerb,
|
||||
Key = objectName,
|
||||
#if DEBUG
|
||||
#if (DEBUG || STAGING)
|
||||
Protocol = Protocol.HTTP,
|
||||
#else
|
||||
Protocol = client.Config.ServiceURL.StartsWith("http://") ? Protocol.HTTP : Protocol.HTTPS,
|
||||
@@ -236,19 +236,19 @@ namespace Notesnook.API.Services
|
||||
return client.GetPreSignedURL(request);
|
||||
}
|
||||
|
||||
private string GetPresignedURLForUploadPart(string objectName, string uploadId, int partNumber)
|
||||
private string GetPresignedURLForUploadPart(string objectName, string uploadId, int partNumber, S3ClientMode mode = S3ClientMode.EXTERNAL)
|
||||
{
|
||||
|
||||
var client = GetS3Client(S3ClientMode.INTERNAL);
|
||||
var client = GetS3Client(mode);
|
||||
return client.GetPreSignedURL(new GetPreSignedUrlRequest
|
||||
{
|
||||
BucketName = GetBucketName(S3ClientMode.INTERNAL),
|
||||
BucketName = GetBucketName(mode),
|
||||
Expires = System.DateTime.Now.AddHours(1),
|
||||
Verb = HttpVerb.PUT,
|
||||
Key = objectName,
|
||||
PartNumber = partNumber,
|
||||
UploadId = uploadId,
|
||||
#if DEBUG
|
||||
#if (DEBUG || STAGING)
|
||||
Protocol = Protocol.HTTP,
|
||||
#else
|
||||
Protocol = client.Config.ServiceURL.StartsWith("http://") ? Protocol.HTTP : Protocol.HTTPS,
|
||||
|
||||
@@ -27,111 +27,98 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Notesnook.API.Services
|
||||
{
|
||||
public struct SyncDevice(ref string userId, ref string deviceId)
|
||||
public struct SyncDevice(string userId, string deviceId)
|
||||
{
|
||||
public readonly string DeviceId = deviceId;
|
||||
public readonly string UserId = userId;
|
||||
public readonly string DeviceId => deviceId;
|
||||
public readonly string UserId => userId;
|
||||
|
||||
private string userSyncDirectoryPath = null;
|
||||
public string UserSyncDirectoryPath
|
||||
public string UserSyncDirectoryPath = CreateFilePath(userId);
|
||||
public string UserDeviceDirectoryPath = CreateFilePath(userId, deviceId);
|
||||
public string PendingIdsFilePath = CreateFilePath(userId, deviceId, "pending");
|
||||
public string UnsyncedIdsFilePath = CreateFilePath(userId, deviceId, "unsynced");
|
||||
public string ResetSyncFilePath = CreateFilePath(userId, deviceId, "reset-sync");
|
||||
|
||||
public readonly long LastAccessTime
|
||||
{
|
||||
get
|
||||
{
|
||||
userSyncDirectoryPath ??= Path.Join("sync", UserId);
|
||||
return userSyncDirectoryPath;
|
||||
}
|
||||
get => long.Parse(GetMetadata("LastAccessTime") ?? "0");
|
||||
set => SetMetadata("LastAccessTime", value.ToString());
|
||||
}
|
||||
private string userDeviceDirectoryPath = null;
|
||||
public string UserDeviceDirectoryPath
|
||||
|
||||
private static string CreateFilePath(string userId, string? deviceId = null, string? metadataKey = null)
|
||||
{
|
||||
get
|
||||
{
|
||||
userDeviceDirectoryPath ??= Path.Join(UserSyncDirectoryPath, DeviceId);
|
||||
return userDeviceDirectoryPath;
|
||||
}
|
||||
return Path.Join("sync", userId, deviceId, metadataKey);
|
||||
}
|
||||
private string pendingIdsFilePath = null;
|
||||
public string PendingIdsFilePath
|
||||
|
||||
private readonly string? GetMetadata(string metadataKey)
|
||||
{
|
||||
get
|
||||
{
|
||||
pendingIdsFilePath ??= Path.Join(UserDeviceDirectoryPath, "pending");
|
||||
return pendingIdsFilePath;
|
||||
}
|
||||
var path = CreateFilePath(userId, deviceId, metadataKey);
|
||||
if (!File.Exists(path)) return null;
|
||||
return File.ReadAllText(path);
|
||||
}
|
||||
private string unsyncedIdsFilePath = null;
|
||||
public string UnsyncedIdsFilePath
|
||||
|
||||
private readonly void SetMetadata(string metadataKey, string value)
|
||||
{
|
||||
get
|
||||
try
|
||||
{
|
||||
unsyncedIdsFilePath ??= Path.Join(UserDeviceDirectoryPath, "unsynced");
|
||||
return unsyncedIdsFilePath;
|
||||
}
|
||||
}
|
||||
private string resetSyncFilePath = null;
|
||||
public string ResetSyncFilePath
|
||||
{
|
||||
get
|
||||
{
|
||||
resetSyncFilePath ??= Path.Join(UserDeviceDirectoryPath, "reset-sync");
|
||||
return resetSyncFilePath;
|
||||
var path = CreateFilePath(userId, deviceId, metadataKey);
|
||||
File.WriteAllText(path, value);
|
||||
}
|
||||
catch (DirectoryNotFoundException) { }
|
||||
}
|
||||
}
|
||||
|
||||
public class SyncDeviceService(SyncDevice device)
|
||||
{
|
||||
public async Task<string[]> GetUnsyncedIdsAsync()
|
||||
public string[] GetUnsyncedIds()
|
||||
{
|
||||
try
|
||||
{
|
||||
return await File.ReadAllLinesAsync(device.UnsyncedIdsFilePath);
|
||||
return File.ReadAllLines(device.UnsyncedIdsFilePath);
|
||||
}
|
||||
catch { return []; }
|
||||
}
|
||||
|
||||
public async Task<string[]> GetUnsyncedIdsAsync(string deviceId)
|
||||
public string[] GetUnsyncedIds(string deviceId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await File.ReadAllLinesAsync(Path.Join(device.UserSyncDirectoryPath, deviceId, "unsynced"));
|
||||
return File.ReadAllLines(Path.Join(device.UserSyncDirectoryPath, deviceId, "unsynced"));
|
||||
}
|
||||
catch { return []; }
|
||||
}
|
||||
|
||||
public async Task<string[]> FetchUnsyncedIdsAsync()
|
||||
public string[] FetchUnsyncedIds()
|
||||
{
|
||||
if (IsSyncReset()) return Array.Empty<string>();
|
||||
if (UnsyncedIdsFileLocks.TryGetValue(device.DeviceId, out SemaphoreSlim fileLock) && fileLock.CurrentCount == 0)
|
||||
await fileLock.WaitAsync();
|
||||
if (IsSyncReset()) return [];
|
||||
try
|
||||
{
|
||||
var unsyncedIds = await GetUnsyncedIdsAsync();
|
||||
if (IsSyncPending())
|
||||
var unsyncedIds = GetUnsyncedIds();
|
||||
lock (device.DeviceId)
|
||||
{
|
||||
unsyncedIds = unsyncedIds.Union(await File.ReadAllLinesAsync(device.PendingIdsFilePath)).ToArray();
|
||||
if (IsSyncPending())
|
||||
{
|
||||
unsyncedIds = unsyncedIds.Union(File.ReadAllLines(device.PendingIdsFilePath)).ToArray();
|
||||
}
|
||||
|
||||
if (unsyncedIds.Length == 0) return [];
|
||||
|
||||
File.Delete(device.UnsyncedIdsFilePath);
|
||||
File.WriteAllLines(device.PendingIdsFilePath, unsyncedIds);
|
||||
}
|
||||
|
||||
if (unsyncedIds.Length == 0) return [];
|
||||
|
||||
File.Delete(device.UnsyncedIdsFilePath);
|
||||
await File.WriteAllLinesAsync(device.PendingIdsFilePath, unsyncedIds);
|
||||
|
||||
return unsyncedIds;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (fileLock != null && fileLock.CurrentCount == 0) fileLock.Release();
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task WritePendingIdsAsync(IEnumerable<string> ids)
|
||||
public void WritePendingIds(IEnumerable<string> ids)
|
||||
{
|
||||
await File.WriteAllLinesAsync(device.PendingIdsFilePath, ids);
|
||||
lock (device.DeviceId)
|
||||
{
|
||||
File.WriteAllLines(device.PendingIdsFilePath, ids);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSyncReset()
|
||||
@@ -155,8 +142,16 @@ namespace Notesnook.API.Services
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
File.Delete(device.ResetSyncFilePath);
|
||||
File.Delete(device.PendingIdsFilePath);
|
||||
try
|
||||
{
|
||||
lock (device.UserId)
|
||||
{
|
||||
File.Delete(device.ResetSyncFilePath);
|
||||
File.Delete(device.PendingIdsFilePath);
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException) { }
|
||||
catch (DirectoryNotFoundException) { }
|
||||
}
|
||||
|
||||
public bool IsDeviceRegistered()
|
||||
@@ -175,49 +170,64 @@ namespace Notesnook.API.Services
|
||||
|
||||
public void ResetDevices()
|
||||
{
|
||||
if (File.Exists(device.UserSyncDirectoryPath)) File.Delete(device.UserSyncDirectoryPath);
|
||||
Directory.CreateDirectory(device.UserSyncDirectoryPath);
|
||||
lock (device.UserId)
|
||||
{
|
||||
if (File.Exists(device.UserSyncDirectoryPath)) File.Delete(device.UserSyncDirectoryPath);
|
||||
Directory.CreateDirectory(device.UserSyncDirectoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly ConcurrentDictionary<string, SemaphoreSlim> UnsyncedIdsFileLocks = [];
|
||||
public async Task AddIdsToOtherDevicesAsync(List<string> ids)
|
||||
public void AddIdsToOtherDevices(List<string> ids)
|
||||
{
|
||||
await Parallel.ForEachAsync(ListDevices(), async (id, ct) =>
|
||||
device.LastAccessTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
foreach (string id in ListDevices())
|
||||
{
|
||||
if (id == device.DeviceId || IsSyncReset(id)) return;
|
||||
if (!UnsyncedIdsFileLocks.TryGetValue(id, out SemaphoreSlim fileLock))
|
||||
{
|
||||
fileLock = UnsyncedIdsFileLocks.AddOrUpdate(id, (id) => new SemaphoreSlim(1, 1), (id, old) => new SemaphoreSlim(1, 1));
|
||||
}
|
||||
if (id == device.DeviceId || IsSyncReset(id)) continue;
|
||||
|
||||
await fileLock.WaitAsync(ct);
|
||||
try
|
||||
lock (id)
|
||||
{
|
||||
if (!IsDeviceRegistered(id)) Directory.CreateDirectory(Path.Join(device.UserSyncDirectoryPath, id));
|
||||
|
||||
var oldIds = await GetUnsyncedIdsAsync(id);
|
||||
await File.WriteAllLinesAsync(Path.Join(device.UserSyncDirectoryPath, id, "unsynced"), ids.Union(oldIds), ct);
|
||||
var oldIds = GetUnsyncedIds(id);
|
||||
File.WriteAllLines(Path.Join(device.UserSyncDirectoryPath, id, "unsynced"), ids.Union(oldIds));
|
||||
}
|
||||
finally
|
||||
}
|
||||
}
|
||||
|
||||
public void AddIdsToAllDevices(List<string> ids)
|
||||
{
|
||||
foreach (var id in ListDevices())
|
||||
{
|
||||
if (IsSyncReset(id)) return;
|
||||
lock (id)
|
||||
{
|
||||
fileLock.Release();
|
||||
if (!IsDeviceRegistered(id)) Directory.CreateDirectory(Path.Join(device.UserSyncDirectoryPath, id));
|
||||
|
||||
var oldIds = GetUnsyncedIds(id);
|
||||
File.WriteAllLinesAsync(Path.Join(device.UserSyncDirectoryPath, id, "unsynced"), ids.Union(oldIds));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterDevice()
|
||||
{
|
||||
Directory.CreateDirectory(device.UserDeviceDirectoryPath);
|
||||
File.Create(device.ResetSyncFilePath).Close();
|
||||
lock (device.UserId)
|
||||
{
|
||||
if (Directory.Exists(device.UserDeviceDirectoryPath))
|
||||
Directory.Delete(device.UserDeviceDirectoryPath, true);
|
||||
Directory.CreateDirectory(device.UserDeviceDirectoryPath);
|
||||
File.Create(device.ResetSyncFilePath).Close();
|
||||
device.LastAccessTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
}
|
||||
}
|
||||
|
||||
public void UnregisterDevice()
|
||||
{
|
||||
try
|
||||
lock (device.UserId)
|
||||
{
|
||||
if (!Path.Exists(device.UserDeviceDirectoryPath)) return;
|
||||
Directory.Delete(device.UserDeviceDirectoryPath, true);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,6 +128,7 @@ namespace Notesnook.API.Services
|
||||
MFA = user.MFA,
|
||||
PhoneNumber = user.PhoneNumber,
|
||||
AttachmentsKey = userSettings.AttachmentsKey,
|
||||
MonographPasswordsKey = userSettings.MonographPasswordsKey,
|
||||
Salt = userSettings.Salt,
|
||||
Subscription = subscription,
|
||||
Success = true,
|
||||
@@ -135,16 +136,25 @@ namespace Notesnook.API.Services
|
||||
};
|
||||
}
|
||||
|
||||
public async Task SetUserAttachmentsKeyAsync(string userId, IEncrypted key)
|
||||
public async Task SetUserKeysAsync(string userId, UserKeys keys)
|
||||
{
|
||||
var userSettings = await Repositories.UsersSettings.FindOneAsync((u) => u.UserId == userId) ?? throw new Exception("User not found.");
|
||||
userSettings.AttachmentsKey = (EncryptedData)key;
|
||||
|
||||
if (keys.AttachmentsKey != null)
|
||||
{
|
||||
userSettings.AttachmentsKey = keys.AttachmentsKey;
|
||||
}
|
||||
if (keys.MonographPasswordsKey != null)
|
||||
{
|
||||
userSettings.MonographPasswordsKey = keys.MonographPasswordsKey;
|
||||
}
|
||||
|
||||
await Repositories.UsersSettings.UpdateAsync(userSettings.Id, userSettings);
|
||||
}
|
||||
|
||||
public async Task DeleteUserAsync(string userId)
|
||||
{
|
||||
new SyncDeviceService(new SyncDevice(ref userId, ref userId)).ResetDevices();
|
||||
new SyncDeviceService(new SyncDevice(userId, userId)).ResetDevices();
|
||||
|
||||
var cc = new CancellationTokenSource();
|
||||
|
||||
@@ -204,7 +214,7 @@ namespace Notesnook.API.Services
|
||||
|
||||
public async Task<bool> ResetUserAsync(string userId, bool removeAttachments)
|
||||
{
|
||||
new SyncDeviceService(new SyncDevice(ref userId, ref userId)).ResetDevices();
|
||||
new SyncDeviceService(new SyncDevice(userId, userId)).ResetDevices();
|
||||
|
||||
var cc = new CancellationTokenSource();
|
||||
|
||||
@@ -226,6 +236,7 @@ namespace Notesnook.API.Services
|
||||
var userSettings = await Repositories.UsersSettings.FindOneAsync((s) => s.UserId == userId);
|
||||
|
||||
userSettings.AttachmentsKey = null;
|
||||
userSettings.MonographPasswordsKey = null;
|
||||
userSettings.VaultKey = null;
|
||||
userSettings.LastSynced = 0;
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ namespace Notesnook.API
|
||||
options.CacheDuration = TimeSpan.FromMinutes(30);
|
||||
});
|
||||
|
||||
BsonSerializer.RegisterSerializer(new SyncItemBsonSerializer());
|
||||
// Serializer.RegisterSerializer(new SyncItemBsonSerializer());
|
||||
if (!BsonClassMap.IsClassMapRegistered(typeof(UserSettings)))
|
||||
BsonClassMap.RegisterClassMap<UserSettings>();
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<string, Client> 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<string, Client> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ namespace Streetwriters.Common
|
||||
{
|
||||
public static int COMPATIBILITY_VERSION = 1;
|
||||
public static bool IS_SELF_HOSTED => Environment.GetEnvironmentVariable("SELF_HOSTED") == "1";
|
||||
public static bool DISABLE_ACCOUNT_CREATION => Environment.GetEnvironmentVariable("DISABLE_ACCOUNT_CREATION") == "1";
|
||||
public static bool DISABLE_SIGNUPS => Environment.GetEnvironmentVariable("DISABLE_SIGNUPS") == "true";
|
||||
public static string INSTANCE_NAME => Environment.GetEnvironmentVariable("INSTANCE_NAME") ?? "default";
|
||||
|
||||
// S3 related
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Streetwriters.Common.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts simple interface into an object (assumes that there is only one class of TInterface)
|
||||
/// </summary>
|
||||
/// <typeparam name="TInterface">Interface type</typeparam>
|
||||
/// <typeparam name="TClass">Class type</typeparam>
|
||||
public class InterfaceConverter<TInterface, TClass> : JsonConverter<TInterface> where TClass : TInterface
|
||||
{
|
||||
public override TInterface Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
return JsonSerializer.Deserialize<TClass>(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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Streetwriters.Common.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts simple interface into an object (assumes that there is only one class of TInterface)
|
||||
/// </summary>
|
||||
/// <typeparam name="TInterface">Interface type</typeparam>
|
||||
/// <typeparam name="TClass">Class type</typeparam>
|
||||
public class InterfaceConverter<TInterface, TClass> : JsonConverter<TInterface> where TClass : TInterface
|
||||
{
|
||||
public override TInterface Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
return JsonSerializer.Deserialize<TClass>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Streetwriters.Common.Enums
|
||||
{
|
||||
public enum ApplicationType
|
||||
{
|
||||
NOTESNOOK = 0
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
||||
@@ -1,29 +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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Streetwriters.Common.Enums
|
||||
{
|
||||
public enum SubscriptionProvider
|
||||
{
|
||||
STREETWRITERS = 0,
|
||||
APPLE = 1,
|
||||
GOOGLE = 2,
|
||||
PADDLE = 3
|
||||
}
|
||||
}
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Streetwriters.Common.Enums
|
||||
{
|
||||
public enum SubscriptionProvider
|
||||
{
|
||||
STREETWRITERS = 0,
|
||||
APPLE = 1,
|
||||
GOOGLE = 2,
|
||||
PADDLE = 3,
|
||||
GIFT_CARD = 4,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Streetwriters.Common.Enums
|
||||
{
|
||||
public enum SubscriptionType
|
||||
{
|
||||
BASIC = 0,
|
||||
TRIAL = 1,
|
||||
BETA = 2,
|
||||
PREMIUM = 5,
|
||||
PREMIUM_EXPIRED = 6,
|
||||
PREMIUM_CANCELED = 7,
|
||||
PREMIUM_PAUSED = 8
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<string, object>
|
||||
{
|
||||
{ "version", Constants.COMPATIBILITY_VERSION },
|
||||
{ "id", server.Id },
|
||||
{ "instance", Constants.INSTANCE_NAME }
|
||||
};
|
||||
await context.Response.WriteAsync(JsonSerializer.Serialize(data));
|
||||
});
|
||||
});
|
||||
return app;
|
||||
}
|
||||
|
||||
public static IApplicationBuilder UseWamp<T>(this IApplicationBuilder app, WampServer<T> server, Action<IWampHostedRealm, WampServer<T>> 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<T>(this IApplicationBuilder app)
|
||||
{
|
||||
return app.ApplicationServices.GetRequiredService<T>();
|
||||
}
|
||||
|
||||
public static T GetScopedService<T>(this IApplicationBuilder app)
|
||||
{
|
||||
using (var scope = app.ApplicationServices.CreateScope())
|
||||
{
|
||||
return scope.ServiceProvider.GetRequiredService<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<string, object>
|
||||
{
|
||||
{ "version", Constants.COMPATIBILITY_VERSION },
|
||||
{ "id", server.Id },
|
||||
{ "instance", Constants.INSTANCE_NAME }
|
||||
};
|
||||
await context.Response.WriteAsync(JsonSerializer.Serialize(data));
|
||||
});
|
||||
});
|
||||
return app;
|
||||
}
|
||||
|
||||
public static IApplicationBuilder UseWamp<T>(this IApplicationBuilder app, WampServer<T> server, Action<IWampHostedRealm, WampServer<T>> 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<T>(this IApplicationBuilder app)
|
||||
{
|
||||
return app.ApplicationServices.GetRequiredService<T>();
|
||||
}
|
||||
|
||||
public static T GetScopedService<T>(this IApplicationBuilder app)
|
||||
{
|
||||
using (var scope = app.ApplicationServices.CreateScope())
|
||||
{
|
||||
return scope.ServiceProvider.GetRequiredService<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<T> SendRequestAsync<T>(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<T>();
|
||||
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<T> ForwardAsync<T>(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<T>(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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<T> SendRequestAsync<T>(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<T>();
|
||||
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<T> ForwardAsync<T>(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<T>(url, httpContext.Request.Headers, method, content);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Streetwriters.Data.DbContexts;
|
||||
using Streetwriters.Data.Repositories;
|
||||
|
||||
namespace Streetwriters.Common.Extensions
|
||||
{
|
||||
public static class ServiceCollectionServiceExtensions
|
||||
{
|
||||
public static IServiceCollection AddRepository<T>(this IServiceCollection services, string collectionName, string database) where T : class
|
||||
{
|
||||
services.AddSingleton((provider) => MongoDbContext.GetMongoCollection<T>(provider.GetService<MongoDB.Driver.IMongoClient>(), database, collectionName));
|
||||
services.AddScoped<Repository<T>>();
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Streetwriters.Data.DbContexts;
|
||||
using Streetwriters.Data.Repositories;
|
||||
|
||||
namespace Streetwriters.Common.Extensions
|
||||
{
|
||||
public static class ServiceCollectionServiceExtensions
|
||||
{
|
||||
public static IServiceCollection AddRepository<T>(this IServiceCollection services, string collectionName, string database) where T : class
|
||||
{
|
||||
services.AddSingleton((provider) => MongoDbContext.GetMongoCollection<T>(provider.GetService<MongoDB.Driver.IMongoClient>(), database, collectionName));
|
||||
services.AddScoped<Repository<T>>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<T>(this IWampHostedRealm realm, string topicName, Action<T> onNext)
|
||||
{
|
||||
return realm.Services.GetSubject<T>(topicName).Subscribe<T>(onNext);
|
||||
}
|
||||
|
||||
public static IDisposable Subscribe<T>(this IWampHostedRealm realm, string topicName, IMessageHandler<T> handler)
|
||||
{
|
||||
return realm.Services.GetSubject<T>(topicName).Subscribe<T>(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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<T>(this IWampHostedRealm realm, string topicName, Action<T> onNext)
|
||||
{
|
||||
return realm.Services.GetSubject<T>(topicName).Subscribe<T>(onNext);
|
||||
}
|
||||
|
||||
public static IDisposable Subscribe<T>(this IWampHostedRealm realm, string topicName, IMessageHandler<T> handler)
|
||||
{
|
||||
return realm.Services.GetSubject<T>(topicName).Subscribe<T>(async (message) => await handler.Process(message));
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Streetwriters.Common/Helpers/HtmlHelper.cs
Normal file
23
Streetwriters.Common/Helpers/HtmlHelper.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System.IO;
|
||||
using WebMarkupMin.Core;
|
||||
using WebMarkupMin.Core.Loggers;
|
||||
|
||||
namespace Streetwriters.Common.Helpers
|
||||
{
|
||||
public static class HtmlHelper
|
||||
{
|
||||
public static string ReadMinifiedHtmlFile(string path)
|
||||
{
|
||||
var settings = new HtmlMinificationSettings()
|
||||
{
|
||||
WhitespaceMinificationMode = WhitespaceMinificationMode.Medium,
|
||||
};
|
||||
var cssMinifier = new KristensenCssMinifier();
|
||||
var jsMinifier = new CrockfordJsMinifier();
|
||||
|
||||
var minifier = new HtmlMinifier(settings, cssMinifier, jsMinifier, new NullLogger());
|
||||
|
||||
return minifier.Minify(File.ReadAllText(path), false).MinifiedContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<IWampRealmProxy> OpenWampChannelAsync(string server, string realmName)
|
||||
{
|
||||
DefaultWampChannelFactory channelFactory = new();
|
||||
|
||||
IWampChannel channel = channelFactory.CreateJsonChannel(server, realmName);
|
||||
|
||||
await channel.Open();
|
||||
|
||||
return channel.RealmProxy;
|
||||
}
|
||||
|
||||
public static void PublishMessage<T>(IWampRealmProxy realm, string topicName, T message)
|
||||
{
|
||||
var subject = realm.Services.GetSubject<T>(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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<IWampRealmProxy> OpenWampChannelAsync(string server, string realmName)
|
||||
{
|
||||
DefaultWampChannelFactory channelFactory = new();
|
||||
|
||||
IWampChannel channel = channelFactory.CreateJsonChannel(server, realmName);
|
||||
|
||||
await channel.Open();
|
||||
|
||||
return channel.RealmProxy;
|
||||
}
|
||||
|
||||
public static void PublishMessage<T>(IWampRealmProxy realm, string topicName, T message)
|
||||
{
|
||||
var subject = realm.Services.GetSubject<T>(topicName);
|
||||
subject.OnNext(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<string, Task> 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<string, Task> OnEmailConfirmed { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Streetwriters.Common.Interfaces
|
||||
{
|
||||
public interface IDocument
|
||||
{
|
||||
string Id
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
19
Streetwriters.Common/Interfaces/IEmailSender.cs
Normal file
19
Streetwriters.Common/Interfaces/IEmailSender.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using MimeKit;
|
||||
using MimeKit.Cryptography;
|
||||
using Streetwriters.Common.Models;
|
||||
|
||||
namespace Streetwriters.Common.Interfaces
|
||||
{
|
||||
public interface IEmailSender
|
||||
{
|
||||
Task SendEmailAsync(
|
||||
string email,
|
||||
EmailTemplate template,
|
||||
IClient client,
|
||||
GnuPGContext gpgContext = null,
|
||||
Dictionary<string, byte[]> attachments = null
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Streetwriters.Common.Interfaces;
|
||||
|
||||
namespace Streetwriters.Common.Interfaces
|
||||
{
|
||||
public interface IMessageHandler<T>
|
||||
{
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Streetwriters.Common.Interfaces;
|
||||
|
||||
namespace Streetwriters.Common.Interfaces
|
||||
{
|
||||
public interface IMessageHandler<T>
|
||||
{
|
||||
Task Process(T message);
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Streetwriters.Common.Interfaces
|
||||
{
|
||||
public interface IResponse
|
||||
{
|
||||
bool Success { get; set; }
|
||||
int StatusCode { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<ISubscription, Subscription>))]
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<ISubscription, Subscription>))]
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Streetwriters.Common
|
||||
{
|
||||
public class Slogger<T>
|
||||
{
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Streetwriters.Common
|
||||
{
|
||||
public class Slogger<T>
|
||||
{
|
||||
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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<string> keys)
|
||||
{
|
||||
this.Keys = keys;
|
||||
}
|
||||
|
||||
[JsonPropertyName("keys")]
|
||||
public List<string> 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<string> keys)
|
||||
{
|
||||
this.Keys = keys;
|
||||
}
|
||||
|
||||
[JsonPropertyName("keys")]
|
||||
public List<string> Keys { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<string, Task> 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<string, Task> OnEmailConfirmed { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
11
Streetwriters.Common/Models/EmailTemplate.cs
Normal file
11
Streetwriters.Common/Models/EmailTemplate.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Streetwriters.Common.Models
|
||||
{
|
||||
public class EmailTemplate
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
public object Data { get; set; }
|
||||
public string Subject { get; set; }
|
||||
public string Html { get; set; }
|
||||
public string Text { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
||||
29
Streetwriters.Common/Models/GiftCard.cs
Normal file
29
Streetwriters.Common/Models/GiftCard.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
using Streetwriters.Common.Interfaces;
|
||||
|
||||
namespace Streetwriters.Common.Models
|
||||
{
|
||||
public class GiftCard : IDocument
|
||||
{
|
||||
public GiftCard()
|
||||
{
|
||||
Id = ObjectId.GenerateNewId().ToString();
|
||||
}
|
||||
|
||||
public string Code { get; set; }
|
||||
public string OrderId { get; set; }
|
||||
public string OrderIdType { get; set; }
|
||||
public string ProductId { get; set; }
|
||||
public string RedeemedBy { get; set; }
|
||||
public long RedeemedAt { get; set; }
|
||||
public long Timestamp { get; set; }
|
||||
public long Term { get; set; }
|
||||
|
||||
[BsonId]
|
||||
[BsonRepresentation(BsonType.ObjectId)]
|
||||
[JsonIgnore]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// 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; }
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// 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; }
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
using AspNetCore.Identity.Mongo.Model;
|
||||
|
||||
namespace Streetwriters.Common.Models
|
||||
{
|
||||
public class User : MongoUser
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace Streetwriters.Common
|
||||
|
||||
public class Servers
|
||||
{
|
||||
#if DEBUG
|
||||
#if (DEBUG || STAGING)
|
||||
public static string GetLocalIPv4()
|
||||
{
|
||||
var interfaces = NetworkInterface.GetAllNetworkInterfaces();
|
||||
|
||||
134
Streetwriters.Common/Services/EmailSender.cs
Normal file
134
Streetwriters.Common/Services/EmailSender.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MailKit.Net.Smtp;
|
||||
using MimeKit;
|
||||
using MimeKit.Cryptography;
|
||||
using Org.BouncyCastle.Bcpg;
|
||||
using Scriban;
|
||||
using Streetwriters.Common.Interfaces;
|
||||
using Streetwriters.Common.Models;
|
||||
|
||||
namespace Streetwriters.Common.Services
|
||||
{
|
||||
public class EmailSender : IEmailSender, IAsyncDisposable
|
||||
{
|
||||
private readonly SmtpClient mailClient = new();
|
||||
|
||||
public async Task SendEmailAsync(
|
||||
string email,
|
||||
EmailTemplate template,
|
||||
IClient client,
|
||||
GnuPGContext gpgContext = null,
|
||||
Dictionary<string, byte[]> attachments = null
|
||||
)
|
||||
{
|
||||
if (!mailClient.IsConnected)
|
||||
{
|
||||
if (int.TryParse(Common.Constants.SMTP_PORT, out int port))
|
||||
{
|
||||
await mailClient.ConnectAsync(
|
||||
Common.Constants.SMTP_HOST,
|
||||
port,
|
||||
MailKit.Security.SecureSocketOptions.Auto
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidDataException("SMTP_PORT is not a valid integer value.");
|
||||
}
|
||||
}
|
||||
|
||||
if (!mailClient.IsAuthenticated)
|
||||
await mailClient.AuthenticateAsync(
|
||||
Common.Constants.SMTP_USERNAME,
|
||||
Common.Constants.SMTP_PASSWORD
|
||||
);
|
||||
|
||||
var message = new MimeMessage();
|
||||
var sender = new MailboxAddress(client.SenderName, client.SenderEmail);
|
||||
message.From.Add(sender);
|
||||
message.To.Add(new MailboxAddress("", email));
|
||||
message.Subject = await Template.Parse(template.Subject).RenderAsync(template.Data);
|
||||
|
||||
if (!string.IsNullOrEmpty(Common.Constants.SMTP_REPLYTO_EMAIL))
|
||||
message.ReplyTo.Add(MailboxAddress.Parse(Common.Constants.SMTP_REPLYTO_EMAIL));
|
||||
|
||||
message.Body = await GetEmailBodyAsync(
|
||||
template,
|
||||
client,
|
||||
sender,
|
||||
gpgContext,
|
||||
attachments
|
||||
);
|
||||
|
||||
await mailClient.SendAsync(message);
|
||||
}
|
||||
|
||||
private static async Task<MimeEntity> GetEmailBodyAsync(
|
||||
EmailTemplate template,
|
||||
IClient client,
|
||||
MailboxAddress sender,
|
||||
GnuPGContext gpgContext = null,
|
||||
Dictionary<string, byte[]> attachments = null
|
||||
)
|
||||
{
|
||||
var builder = new BodyBuilder();
|
||||
try
|
||||
{
|
||||
builder.TextBody = await Template.Parse(template.Text).RenderAsync(template.Data);
|
||||
builder.HtmlBody = await Template.Parse(template.Html).RenderAsync(template.Data);
|
||||
|
||||
if (attachments != null)
|
||||
{
|
||||
foreach (var attachment in attachments)
|
||||
{
|
||||
builder.Attachments.Add(attachment.Key, attachment.Value);
|
||||
}
|
||||
}
|
||||
|
||||
var key = gpgContext?.GetSigningKey(sender);
|
||||
if (key != null)
|
||||
{
|
||||
using (MemoryStream outputStream = new())
|
||||
{
|
||||
using (Stream armoredStream = new ArmoredOutputStream(outputStream))
|
||||
{
|
||||
key.PublicKey.Encode(armoredStream);
|
||||
}
|
||||
outputStream.Seek(0, SeekOrigin.Begin);
|
||||
builder.Attachments.Add(
|
||||
$"{client.Id}_pub.asc",
|
||||
Encoding.ASCII.GetBytes(
|
||||
Encoding.ASCII.GetString(outputStream.ToArray())
|
||||
)
|
||||
);
|
||||
}
|
||||
return await MultipartSigned.CreateAsync(
|
||||
gpgContext,
|
||||
sender,
|
||||
DigestAlgorithm.Sha256,
|
||||
builder.ToMessageBody()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return builder.ToMessageBody();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await Slogger<EmailSender>.Error("GetEmailBodyAsync", ex.ToString());
|
||||
return builder.ToMessageBody();
|
||||
}
|
||||
}
|
||||
|
||||
async ValueTask IAsyncDisposable.DisposeAsync()
|
||||
{
|
||||
await mailClient.DisconnectAsync(true);
|
||||
mailClient.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,13 +6,16 @@
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MailKit" Version="4.9.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Cors" Version="2.2.0" />
|
||||
<PackageReference Include="Scriban" Version="5.12.1" />
|
||||
<PackageReference Include="WampSharp.Default" Version="20.1.1" />
|
||||
<PackageReference Include="WampSharp.AspNetCore.WebSockets.Server" Version="20.1.1" />
|
||||
<PackageReference Include="WampSharp.NewtonsoftMsgpack" Version="20.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.WebSockets" Version="2.2.1" />
|
||||
<PackageReference Include="AspNetCore.Identity.Mongo" Version="8.3.3" />
|
||||
<PackageReference Include="WebMarkupMin.NUglify" Version="2.18.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<T> where T : new()
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, IWampRealmProxy> 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<IWampRealmProxy> 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<V> GetServiceAsync<V>(string topic) where V : class
|
||||
{
|
||||
var channel = await GetChannelAsync(topic);
|
||||
return channel.Services.GetCalleeProxy<V>();
|
||||
}
|
||||
|
||||
public async Task PublishMessageAsync<V>(string topic, V message)
|
||||
{
|
||||
try
|
||||
{
|
||||
IWampRealmProxy channel = await GetChannelAsync(topic);
|
||||
WampHelper.PublishMessage(channel, topic, message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await Slogger<WampServer<T>>.Error(nameof(PublishMessageAsync), ex.ToString());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class WampServers
|
||||
{
|
||||
public static WampServer<MessengerServerTopics> MessengerServer { get; } = new WampServer<MessengerServerTopics>
|
||||
{
|
||||
Endpoint = "/wamp",
|
||||
Address = $"{Servers.MessengerServer.WS()}/wamp",
|
||||
Realm = "messages",
|
||||
};
|
||||
|
||||
public static WampServer<SubscriptionServerTopics> SubscriptionServer { get; } = new WampServer<SubscriptionServerTopics>
|
||||
{
|
||||
Endpoint = "/wamp",
|
||||
Address = $"{Servers.SubscriptionServer.WS()}/wamp",
|
||||
Realm = "messages",
|
||||
};
|
||||
|
||||
public static WampServer<IdentityServerTopics> IdentityServer { get; } = new WampServer<IdentityServerTopics>
|
||||
{
|
||||
Endpoint = "/wamp",
|
||||
Address = $"{Servers.IdentityServer.WS()}/wamp",
|
||||
Realm = "messages",
|
||||
};
|
||||
|
||||
public static WampServer<NotesnookServerTopics> NotesnookServer { get; } = new WampServer<NotesnookServerTopics>
|
||||
{
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<T> where T : new()
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, IWampRealmProxy> 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<IWampRealmProxy> 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<V> GetServiceAsync<V>(string topic) where V : class
|
||||
{
|
||||
var channel = await GetChannelAsync(topic);
|
||||
return channel.Services.GetCalleeProxy<V>();
|
||||
}
|
||||
|
||||
public async Task PublishMessageAsync<V>(string topic, V message)
|
||||
{
|
||||
try
|
||||
{
|
||||
IWampRealmProxy channel = await GetChannelAsync(topic);
|
||||
WampHelper.PublishMessage(channel, topic, message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await Slogger<WampServer<T>>.Error(nameof(PublishMessageAsync), ex.ToString());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class WampServers
|
||||
{
|
||||
public static WampServer<MessengerServerTopics> MessengerServer { get; } = new WampServer<MessengerServerTopics>
|
||||
{
|
||||
Endpoint = "/wamp",
|
||||
Address = $"{Servers.MessengerServer.WS()}/wamp",
|
||||
Realm = "messages",
|
||||
};
|
||||
|
||||
public static WampServer<SubscriptionServerTopics> SubscriptionServer { get; } = new WampServer<SubscriptionServerTopics>
|
||||
{
|
||||
Endpoint = "/wamp",
|
||||
Address = $"{Servers.SubscriptionServer.WS()}/wamp",
|
||||
Realm = "messages",
|
||||
};
|
||||
|
||||
public static WampServer<IdentityServerTopics> IdentityServer { get; } = new WampServer<IdentityServerTopics>
|
||||
{
|
||||
Endpoint = "/wamp",
|
||||
Address = $"{Servers.IdentityServer.WS()}/wamp",
|
||||
Realm = "messages",
|
||||
};
|
||||
|
||||
public static WampServer<NotesnookServerTopics> NotesnookServer { get; } = new WampServer<NotesnookServerTopics>
|
||||
{
|
||||
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
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -17,14 +17,14 @@ You should have received a copy of the Affero GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using MongoDB.Driver;
|
||||
using Streetwriters.Data.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using MongoDB.Driver;
|
||||
using Streetwriters.Data.Interfaces;
|
||||
|
||||
namespace Streetwriters.Data.DbContexts
|
||||
{
|
||||
@@ -35,15 +35,22 @@ namespace Streetwriters.Data.DbContexts
|
||||
var settings = MongoClientSettings.FromConnectionString(dbSettings.ConnectionString);
|
||||
settings.MaxConnectionPoolSize = 500;
|
||||
settings.MinConnectionPoolSize = 0;
|
||||
settings.HeartbeatInterval = TimeSpan.FromSeconds(60);
|
||||
return new MongoClient(settings);
|
||||
}
|
||||
|
||||
public static IMongoCollection<T> GetMongoCollection<T>(IMongoClient client, string databaseName, string collectionName)
|
||||
public static IMongoCollection<T> GetMongoCollection<T>(
|
||||
IMongoClient client,
|
||||
string databaseName,
|
||||
string collectionName
|
||||
)
|
||||
{
|
||||
return client.GetDatabase(databaseName).GetCollection<T>(collectionName, new MongoCollectionSettings()
|
||||
{
|
||||
AssignIdOnInsert = true,
|
||||
});
|
||||
return client
|
||||
.GetDatabase(databaseName)
|
||||
.GetCollection<T>(
|
||||
collectionName,
|
||||
new MongoCollectionSettings() { AssignIdOnInsert = true }
|
||||
);
|
||||
}
|
||||
|
||||
private readonly List<Func<IClientSessionHandle, CancellationToken, Task>> _commands = [];
|
||||
@@ -56,16 +63,17 @@ namespace Streetwriters.Data.DbContexts
|
||||
|
||||
using (IClientSessionHandle session = await MongoClient.StartSessionAsync())
|
||||
{
|
||||
#if DEBUG
|
||||
#if (DEBUG || STAGING)
|
||||
await Parallel.ForEachAsync(_commands, async (c, ct) => await c(session, ct));
|
||||
#else
|
||||
await session.WithTransactionAsync(async (handle, token) =>
|
||||
{
|
||||
await Task.WhenAll(_commands.Select(c => c(handle, token)));
|
||||
return true;
|
||||
});
|
||||
await session.WithTransactionAsync(
|
||||
async (handle, token) =>
|
||||
{
|
||||
await Task.WhenAll(_commands.Select(c => c(handle, token)));
|
||||
return true;
|
||||
}
|
||||
);
|
||||
#endif
|
||||
|
||||
}
|
||||
return count;
|
||||
}
|
||||
@@ -87,4 +95,4 @@ namespace Streetwriters.Data.DbContexts
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using Streetwriters.Data.Interfaces;
|
||||
|
||||
namespace Streetwriters.Data
|
||||
{
|
||||
public class DbSettings : IDbSettings
|
||||
{
|
||||
public string DatabaseName { get; set; }
|
||||
public string ConnectionString { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
using MongoDB.Driver;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Streetwriters.Data.Interfaces
|
||||
{
|
||||
public interface IDbContext : IDisposable
|
||||
{
|
||||
void AddCommand(Func<IClientSessionHandle, CancellationToken, Task> func);
|
||||
Task<int> 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
using MongoDB.Driver;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Streetwriters.Data.Interfaces
|
||||
{
|
||||
public interface IDbContext : IDisposable
|
||||
{
|
||||
void AddCommand(Func<IClientSessionHandle, CancellationToken, Task> func);
|
||||
Task<int> SaveChanges();
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Streetwriters.Data.Interfaces
|
||||
{
|
||||
public interface IDbSettings
|
||||
{
|
||||
string DatabaseName { get; set; }
|
||||
string ConnectionString { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Streetwriters.Data.Interfaces
|
||||
{
|
||||
public interface IUnitOfWork : IDisposable
|
||||
{
|
||||
Task<bool> 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Streetwriters.Data.Interfaces
|
||||
{
|
||||
public interface IUnitOfWork : IDisposable
|
||||
{
|
||||
Task<bool> Commit();
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<TEntity> where TEntity : class
|
||||
{
|
||||
protected readonly IDbContext dbContext;
|
||||
public IMongoCollection<TEntity> Collection { get; set; }
|
||||
|
||||
public Repository(IDbContext _dbContext, IMongoCollection<TEntity> 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<Func<TEntity, bool>> filterExpression)
|
||||
{
|
||||
dbContext.AddCommand((handle, ct) => Collection.ReplaceOneAsync(handle, filterExpression, obj, new ReplaceOptions { IsUpsert = true }, ct));
|
||||
}
|
||||
|
||||
public virtual Task UpsertAsync(TEntity obj, Expression<Func<TEntity, bool>> filterExpression)
|
||||
{
|
||||
return Collection.ReplaceOneAsync(filterExpression, obj, new ReplaceOptions { IsUpsert = true });
|
||||
}
|
||||
|
||||
public virtual async Task<TEntity> FindOneAsync(Expression<Func<TEntity, bool>> filterExpression)
|
||||
{
|
||||
var data = await Collection.FindAsync(filterExpression);
|
||||
return data.FirstOrDefault();
|
||||
}
|
||||
|
||||
public virtual async Task<TEntity> GetAsync(string id)
|
||||
{
|
||||
var data = await Collection.FindAsync(Builders<TEntity>.Filter.Eq("_id", ObjectId.Parse(id)));
|
||||
return data.FirstOrDefault();
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<TEntity>> FindAsync(Expression<Func<TEntity, bool>> filterExpression)
|
||||
{
|
||||
var data = await Collection.FindAsync(filterExpression);
|
||||
return data.ToList();
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<TEntity>> GetAllAsync()
|
||||
{
|
||||
var all = await Collection.FindAsync(Builders<TEntity>.Filter.Empty);
|
||||
return all.ToList();
|
||||
}
|
||||
|
||||
public virtual void Update(string id, TEntity obj)
|
||||
{
|
||||
dbContext.AddCommand((handle, ct) => Collection.ReplaceOneAsync(handle, Builders<TEntity>.Filter.Eq("_id", ObjectId.Parse(id)), obj, cancellationToken: ct));
|
||||
}
|
||||
|
||||
public virtual Task UpdateAsync(string id, TEntity obj)
|
||||
{
|
||||
return Collection.ReplaceOneAsync(Builders<TEntity>.Filter.Eq("_id", ObjectId.Parse(id)), obj);
|
||||
}
|
||||
|
||||
public virtual void DeleteById(string id)
|
||||
{
|
||||
dbContext.AddCommand((handle, ct) => Collection.DeleteOneAsync(handle, Builders<TEntity>.Filter.Eq("_id", ObjectId.Parse(id)), cancellationToken: ct));
|
||||
}
|
||||
|
||||
public virtual Task DeleteByIdAsync(string id)
|
||||
{
|
||||
return Collection.DeleteOneAsync(Builders<TEntity>.Filter.Eq("_id", ObjectId.Parse(id)));
|
||||
}
|
||||
|
||||
public virtual void Delete(Expression<Func<TEntity, bool>> filterExpression)
|
||||
{
|
||||
dbContext.AddCommand((handle, ct) => Collection.DeleteOneAsync(handle, filterExpression, cancellationToken: ct));
|
||||
}
|
||||
|
||||
public virtual void DeleteMany(Expression<Func<TEntity, bool>> filterExpression)
|
||||
{
|
||||
dbContext.AddCommand((handle, ct) => Collection.DeleteManyAsync(handle, filterExpression, cancellationToken: ct));
|
||||
}
|
||||
|
||||
public virtual Task DeleteAsync(Expression<Func<TEntity, bool>> filterExpression)
|
||||
{
|
||||
return Collection.DeleteOneAsync(filterExpression);
|
||||
}
|
||||
|
||||
public virtual Task DeleteManyAsync(Expression<Func<TEntity, bool>> 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<TEntity> where TEntity : class
|
||||
{
|
||||
protected readonly IDbContext dbContext;
|
||||
public IMongoCollection<TEntity> Collection { get; set; }
|
||||
|
||||
public Repository(IDbContext _dbContext, IMongoCollection<TEntity> 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<Func<TEntity, bool>> filterExpression)
|
||||
{
|
||||
dbContext.AddCommand((handle, ct) => Collection.ReplaceOneAsync(handle, filterExpression, obj, new ReplaceOptions { IsUpsert = true }, ct));
|
||||
}
|
||||
|
||||
public virtual Task UpsertAsync(TEntity obj, Expression<Func<TEntity, bool>> filterExpression)
|
||||
{
|
||||
return Collection.ReplaceOneAsync(filterExpression, obj, new ReplaceOptions { IsUpsert = true });
|
||||
}
|
||||
|
||||
public virtual async Task<TEntity> FindOneAsync(Expression<Func<TEntity, bool>> filterExpression)
|
||||
{
|
||||
var data = await Collection.FindAsync(filterExpression);
|
||||
return data.FirstOrDefault();
|
||||
}
|
||||
|
||||
public virtual async Task<TEntity> GetAsync(string id)
|
||||
{
|
||||
var data = await Collection.FindAsync(Builders<TEntity>.Filter.Eq("_id", ObjectId.Parse(id)));
|
||||
return data.FirstOrDefault();
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<TEntity>> FindAsync(Expression<Func<TEntity, bool>> filterExpression)
|
||||
{
|
||||
var data = await Collection.FindAsync(filterExpression);
|
||||
return data.ToList();
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<TEntity>> GetAllAsync()
|
||||
{
|
||||
var all = await Collection.FindAsync(Builders<TEntity>.Filter.Empty);
|
||||
return all.ToList();
|
||||
}
|
||||
|
||||
public virtual void Update(string id, TEntity obj)
|
||||
{
|
||||
dbContext.AddCommand((handle, ct) => Collection.ReplaceOneAsync(handle, Builders<TEntity>.Filter.Eq("_id", ObjectId.Parse(id)), obj, cancellationToken: ct));
|
||||
}
|
||||
|
||||
public virtual Task UpdateAsync(string id, TEntity obj)
|
||||
{
|
||||
return Collection.ReplaceOneAsync(Builders<TEntity>.Filter.Eq("_id", ObjectId.Parse(id)), obj);
|
||||
}
|
||||
|
||||
public virtual void DeleteById(string id)
|
||||
{
|
||||
dbContext.AddCommand((handle, ct) => Collection.DeleteOneAsync(handle, Builders<TEntity>.Filter.Eq("_id", ObjectId.Parse(id)), cancellationToken: ct));
|
||||
}
|
||||
|
||||
public virtual Task DeleteByIdAsync(string id)
|
||||
{
|
||||
return Collection.DeleteOneAsync(Builders<TEntity>.Filter.Eq("_id", ObjectId.Parse(id)));
|
||||
}
|
||||
|
||||
public virtual void Delete(Expression<Func<TEntity, bool>> filterExpression)
|
||||
{
|
||||
dbContext.AddCommand((handle, ct) => Collection.DeleteOneAsync(handle, filterExpression, cancellationToken: ct));
|
||||
}
|
||||
|
||||
public virtual void DeleteMany(Expression<Func<TEntity, bool>> filterExpression)
|
||||
{
|
||||
dbContext.AddCommand((handle, ct) => Collection.DeleteManyAsync(handle, filterExpression, cancellationToken: ct));
|
||||
}
|
||||
|
||||
public virtual Task DeleteAsync(Expression<Func<TEntity, bool>> filterExpression)
|
||||
{
|
||||
return Collection.DeleteOneAsync(filterExpression);
|
||||
}
|
||||
|
||||
public virtual Task DeleteManyAsync(Expression<Func<TEntity, bool>> filterExpression)
|
||||
{
|
||||
return Collection.DeleteManyAsync(filterExpression);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Streetwriters.Data.Interfaces;
|
||||
|
||||
namespace Streetwriters.Data
|
||||
{
|
||||
public class UnitOfWork(IDbContext dbContext) : IUnitOfWork
|
||||
{
|
||||
public async Task<bool> 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Streetwriters.Data.Interfaces;
|
||||
|
||||
namespace Streetwriters.Data
|
||||
{
|
||||
public class UnitOfWork(IDbContext dbContext) : IUnitOfWork
|
||||
{
|
||||
public async Task<bool> Commit()
|
||||
{
|
||||
return await dbContext.SaveChanges() > 0;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
dbContext.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<IdentityResource> IdentityResources =>
|
||||
new List<IdentityResource> {
|
||||
new IdentityResources.OpenId(),
|
||||
};
|
||||
|
||||
public static IEnumerable<ApiResource> ApiResources =>
|
||||
new List<ApiResource>
|
||||
{
|
||||
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<ApiScope> ApiScopes =>
|
||||
new List<ApiScope>
|
||||
{
|
||||
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<Client> Clients =>
|
||||
new List<Client>
|
||||
{
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<IdentityResource> IdentityResources =>
|
||||
new List<IdentityResource> {
|
||||
new IdentityResources.OpenId(),
|
||||
};
|
||||
|
||||
public static IEnumerable<ApiResource> ApiResources =>
|
||||
new List<ApiResource>
|
||||
{
|
||||
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<ApiScope> ApiScopes =>
|
||||
new List<ApiScope>
|
||||
{
|
||||
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<Client> Clients =>
|
||||
new List<Client>
|
||||
{
|
||||
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" },
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ using IdentityServer4.Stores;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.RateLimiting;
|
||||
using Streetwriters.Common;
|
||||
using Streetwriters.Common.Enums;
|
||||
using Streetwriters.Common.Interfaces;
|
||||
@@ -52,10 +53,8 @@ namespace Streetwriters.Identity.Controllers
|
||||
{
|
||||
private IPersistedGrantStore PersistedGrantStore { get; set; }
|
||||
private ITokenGenerationService TokenGenerationService { get; set; }
|
||||
private IUserClaimsPrincipalFactory<User> PrincipalFactory { get; set; }
|
||||
private IdentityServerOptions ISOptions { get; set; }
|
||||
private IUserAccountService UserAccountService { get; set; }
|
||||
public AccountController(UserManager<User> _userManager, IEmailSender _emailSender,
|
||||
public AccountController(UserManager<User> _userManager, ITemplatedEmailSender _emailSender,
|
||||
SignInManager<User> _signInManager, RoleManager<MongoRole> _roleManager, IPersistedGrantStore store,
|
||||
ITokenGenerationService tokenGenerationService, IMFAService _mfaService, IUserAccountService userAccountService) : base(_userManager, _emailSender, _signInManager, _roleManager, _mfaService)
|
||||
{
|
||||
@@ -114,6 +113,7 @@ namespace Streetwriters.Identity.Controllers
|
||||
}
|
||||
|
||||
[HttpPost("verify")]
|
||||
[EnableRateLimiting("strict")]
|
||||
public async Task<IActionResult> SendVerificationEmail([FromForm] string newEmail)
|
||||
{
|
||||
var client = Clients.FindClientById(User.FindFirstValue("client_id"));
|
||||
@@ -147,6 +147,7 @@ namespace Streetwriters.Identity.Controllers
|
||||
|
||||
[HttpPost("recover")]
|
||||
[AllowAnonymous]
|
||||
[EnableRateLimiting("strict")]
|
||||
public async Task<IActionResult> ResetUserPassword([FromForm] ResetPasswordForm form)
|
||||
{
|
||||
var client = Clients.FindClientById(form.ClientId);
|
||||
@@ -157,7 +158,7 @@ namespace Streetwriters.Identity.Controllers
|
||||
|
||||
var code = await UserManager.GenerateUserTokenAsync(user, TokenOptions.DefaultProvider, "ResetPassword");
|
||||
var callbackUrl = Url.TokenLink(user.Id.ToString(), code, client.Id, TokenType.RESET_PASSWORD);
|
||||
#if DEBUG
|
||||
#if (DEBUG || STAGING)
|
||||
return Ok(callbackUrl);
|
||||
#else
|
||||
await Slogger<AccountController>.Info("ResetUserPassword", user.Email, callbackUrl);
|
||||
@@ -341,4 +342,4 @@ namespace Streetwriters.Identity.Controllers
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,12 +36,12 @@ namespace Streetwriters.Identity.Controllers
|
||||
protected UserManager<User> UserManager { get; set; }
|
||||
protected SignInManager<User> SignInManager { get; set; }
|
||||
protected RoleManager<MongoRole> RoleManager { get; set; }
|
||||
protected IEmailSender EmailSender { get; set; }
|
||||
protected ITemplatedEmailSender EmailSender { get; set; }
|
||||
protected UrlEncoder UrlEncoder { get; set; }
|
||||
protected IMFAService MFAService { get; set; }
|
||||
public IdentityControllerBase(
|
||||
UserManager<User> _userManager,
|
||||
IEmailSender _emailSender,
|
||||
ITemplatedEmailSender _emailSender,
|
||||
SignInManager<User> _signInManager,
|
||||
RoleManager<MongoRole> _roleManager,
|
||||
IMFAService _mfaService
|
||||
|
||||
@@ -26,6 +26,7 @@ using AspNetCore.Identity.Mongo.Model;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.RateLimiting;
|
||||
using Streetwriters.Common;
|
||||
using Streetwriters.Common.Enums;
|
||||
using Streetwriters.Common.Models;
|
||||
@@ -41,7 +42,7 @@ namespace Streetwriters.Identity.Controllers
|
||||
[Authorize(LocalApi.PolicyName)]
|
||||
public class MFAController : IdentityControllerBase
|
||||
{
|
||||
public MFAController(UserManager<User> _userManager, IEmailSender _emailSender,
|
||||
public MFAController(UserManager<User> _userManager, ITemplatedEmailSender _emailSender,
|
||||
SignInManager<User> _signInManager, RoleManager<MongoRole> _roleManager, IMFAService _mfaService) : base(_userManager, _emailSender, _signInManager, _roleManager, _mfaService) { }
|
||||
|
||||
[HttpPost]
|
||||
@@ -90,6 +91,7 @@ namespace Streetwriters.Identity.Controllers
|
||||
[HttpPost("send")]
|
||||
[Authorize("mfa")]
|
||||
[Authorize(LocalApi.PolicyName)]
|
||||
[EnableRateLimiting("strict")]
|
||||
public async Task<IActionResult> RequestCode([FromForm] string type)
|
||||
{
|
||||
var client = Clients.FindClientById(User.FindFirstValue("client_id"));
|
||||
|
||||
@@ -25,6 +25,7 @@ using AspNetCore.Identity.Mongo.Model;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.RateLimiting;
|
||||
using Streetwriters.Common;
|
||||
using Streetwriters.Common.Enums;
|
||||
using Streetwriters.Common.Models;
|
||||
@@ -39,7 +40,7 @@ namespace Streetwriters.Identity.Controllers
|
||||
[Route("signup")]
|
||||
public class SignupController : IdentityControllerBase
|
||||
{
|
||||
public SignupController(UserManager<User> _userManager, IEmailSender _emailSender,
|
||||
public SignupController(UserManager<User> _userManager, ITemplatedEmailSender _emailSender,
|
||||
SignInManager<User> _signInManager, RoleManager<MongoRole> _roleManager, IMFAService _mfaService) : base(_userManager, _emailSender, _signInManager, _roleManager, _mfaService)
|
||||
{ }
|
||||
|
||||
@@ -51,9 +52,10 @@ namespace Streetwriters.Identity.Controllers
|
||||
|
||||
[HttpPost]
|
||||
[AllowAnonymous]
|
||||
[EnableRateLimiting("strict")]
|
||||
public async Task<IActionResult> Signup([FromForm] SignupForm form)
|
||||
{
|
||||
if (Constants.DISABLE_ACCOUNT_CREATION)
|
||||
if (Constants.DISABLE_SIGNUPS)
|
||||
return BadRequest(new string[] { "Creating new accounts is not allowed." });
|
||||
try
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user