diff --git a/Notesnook.API/Program.cs b/Notesnook.API/Program.cs
index 427d2fa..1ec6fc7 100644
--- a/Notesnook.API/Program.cs
+++ b/Notesnook.API/Program.cs
@@ -17,10 +17,15 @@ You should have received a copy of the Affero GNU General Public License
along with this program. If not, see .
*/
+#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;
namespace Notesnook.API
{
@@ -28,8 +33,6 @@ namespace Notesnook.API
{
public static async Task Main(string[] args)
{
- DotNetEnv.Env.TraversePath().Load();
-
IHost host = CreateHostBuilder(args).Build();
await host.RunAsync();
}
@@ -43,16 +46,7 @@ namespace Notesnook.API
.UseKestrel((options) =>
{
options.Limits.MaxRequestBodySize = long.MaxValue;
-#if DEBUG
- options.ListenAnyIP(int.Parse(Servers.NotesnookAPI.Port));
-#else
- options.ListenAnyIP(443, listenerOptions =>
- {
- listenerOptions.UseHttps(Servers.OriginSSLCertificate);
- });
- options.ListenAnyIP(80);
- options.Listen(IPAddress.Parse(Servers.NotesnookAPI.Hostname), int.Parse(Servers.NotesnookAPI.Port));
-#endif
+ options.ListenAnyIP(Servers.NotesnookAPI.Port);
});
});
}
diff --git a/Notesnook.API/Services/S3Service.cs b/Notesnook.API/Services/S3Service.cs
index e41f32d..041dfd7 100644
--- a/Notesnook.API/Services/S3Service.cs
+++ b/Notesnook.API/Services/S3Service.cs
@@ -19,6 +19,7 @@ along with this program. If not, see .
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
@@ -41,7 +42,6 @@ namespace Notesnook.API.Services
public S3Service()
{
-
var config = new AmazonS3Config
{
#if DEBUG
diff --git a/Notesnook.API/Services/UserService.cs b/Notesnook.API/Services/UserService.cs
index ccd155d..8604a97 100644
--- a/Notesnook.API/Services/UserService.cs
+++ b/Notesnook.API/Services/UserService.cs
@@ -29,6 +29,7 @@ using Notesnook.API.Models.Responses;
using Streetwriters.Common;
using Streetwriters.Common.Enums;
using Streetwriters.Common.Extensions;
+using Streetwriters.Common.Interfaces;
using Streetwriters.Common.Messages;
using Streetwriters.Common.Models;
using Streetwriters.Data.Interfaces;
@@ -73,14 +74,17 @@ namespace Notesnook.API.Services
Salt = GetSalt()
});
- await WampServers.SubscriptionServer.PublishMessageAsync(WampServers.SubscriptionServer.Topics.CreateSubscriptionTopic, new CreateSubscriptionMessage
+ if (!Constants.IS_SELF_HOSTED)
{
- AppId = ApplicationType.NOTESNOOK,
- Provider = SubscriptionProvider.STREETWRITERS,
- Type = SubscriptionType.BASIC,
- UserId = response.UserId,
- StartTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
- });
+ await WampServers.SubscriptionServer.PublishMessageAsync(WampServers.SubscriptionServer.Topics.CreateSubscriptionTopic, new CreateSubscriptionMessage
+ {
+ AppId = ApplicationType.NOTESNOOK,
+ Provider = SubscriptionProvider.STREETWRITERS,
+ Type = SubscriptionType.BASIC,
+ UserId = response.UserId,
+ StartTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+ });
+ }
await Slogger.Info(nameof(CreateUserAsync), "New user created.", JsonSerializer.Serialize(response));
}
@@ -90,31 +94,49 @@ namespace Notesnook.API.Services
UserResponse response = await httpClient.ForwardAsync(this.HttpContextAccessor, $"{Servers.IdentityServer.ToString()}/account", HttpMethod.Get);
if (!response.Success) return response;
- SubscriptionResponse subscriptionResponse = await httpClient.ForwardAsync(this.HttpContextAccessor, $"{Servers.SubscriptionServer}/subscriptions", HttpMethod.Get);
- if (repair && subscriptionResponse.StatusCode == 404)
+ ISubscription subscription = null;
+ if (Constants.IS_SELF_HOSTED)
{
- await Slogger.Error(nameof(GetUserAsync), "Repairing user subscription.", JsonSerializer.Serialize(response));
- // user was partially created. We should continue the process here.
- await WampServers.SubscriptionServer.PublishMessageAsync(WampServers.SubscriptionServer.Topics.CreateSubscriptionTopic, new CreateSubscriptionMessage
+ subscription = new Subscription
{
AppId = ApplicationType.NOTESNOOK,
Provider = SubscriptionProvider.STREETWRITERS,
- Type = SubscriptionType.TRIAL,
- UserId = response.UserId,
- StartTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
- ExpiryTime = DateTimeOffset.UtcNow.AddDays(7).ToUnixTimeMilliseconds()
- });
- // just a dummy object
- subscriptionResponse.Subscription = new Subscription
- {
- AppId = ApplicationType.NOTESNOOK,
- Provider = SubscriptionProvider.STREETWRITERS,
- Type = SubscriptionType.TRIAL,
+ Type = SubscriptionType.PREMIUM,
UserId = response.UserId,
StartDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
- ExpiryDate = DateTimeOffset.UtcNow.AddDays(7).ToUnixTimeMilliseconds()
+ // this date doesn't matter as the subscription is static.
+ ExpiryDate = DateTimeOffset.UtcNow.AddYears(1).ToUnixTimeMilliseconds()
};
}
+ else
+ {
+ SubscriptionResponse subscriptionResponse = await httpClient.ForwardAsync(this.HttpContextAccessor, $"{Servers.SubscriptionServer}/subscriptions", HttpMethod.Get);
+ if (repair && subscriptionResponse.StatusCode == 404)
+ {
+ await Slogger.Error(nameof(GetUserAsync), "Repairing user subscription.", JsonSerializer.Serialize(response));
+ // user was partially created. We should continue the process here.
+ await WampServers.SubscriptionServer.PublishMessageAsync(WampServers.SubscriptionServer.Topics.CreateSubscriptionTopic, new CreateSubscriptionMessage
+ {
+ AppId = ApplicationType.NOTESNOOK,
+ Provider = SubscriptionProvider.STREETWRITERS,
+ Type = SubscriptionType.TRIAL,
+ UserId = response.UserId,
+ StartTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+ ExpiryTime = DateTimeOffset.UtcNow.AddDays(7).ToUnixTimeMilliseconds()
+ });
+ // just a dummy object
+ subscriptionResponse.Subscription = new Subscription
+ {
+ AppId = ApplicationType.NOTESNOOK,
+ Provider = SubscriptionProvider.STREETWRITERS,
+ Type = SubscriptionType.TRIAL,
+ UserId = response.UserId,
+ StartDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+ ExpiryDate = DateTimeOffset.UtcNow.AddDays(7).ToUnixTimeMilliseconds()
+ };
+ }
+ subscription = subscriptionResponse.Subscription;
+ }
var userSettings = await Repositories.UsersSettings.FindOneAsync((u) => u.UserId == response.UserId);
if (repair && userSettings == null)
@@ -130,7 +152,7 @@ namespace Notesnook.API.Services
}
response.AttachmentsKey = userSettings.AttachmentsKey;
response.Salt = userSettings.Salt;
- response.Subscription = subscriptionResponse.Subscription;
+ response.Subscription = subscription;
return response;
}
@@ -153,11 +175,14 @@ namespace Notesnook.API.Services
Repositories.Attachments.DeleteByUserId(userId);
Repositories.UsersSettings.Delete((u) => u.UserId == userId);
- await WampServers.SubscriptionServer.PublishMessageAsync(WampServers.SubscriptionServer.Topics.DeleteSubscriptionTopic, new DeleteSubscriptionMessage
+ if (!Constants.IS_SELF_HOSTED)
{
- AppId = ApplicationType.NOTESNOOK,
- UserId = userId
- });
+ await WampServers.SubscriptionServer.PublishMessageAsync(WampServers.SubscriptionServer.Topics.DeleteSubscriptionTopic, new DeleteSubscriptionMessage
+ {
+ AppId = ApplicationType.NOTESNOOK,
+ UserId = userId
+ });
+ }
await WampServers.MessengerServer.PublishMessageAsync(WampServers.MessengerServer.Topics.SendSSETopic, new SendSSEMessage
{
diff --git a/Notesnook.API/Startup.cs b/Notesnook.API/Startup.cs
index 9ad014a..a71f7a3 100644
--- a/Notesnook.API/Startup.cs
+++ b/Notesnook.API/Startup.cs
@@ -73,7 +73,11 @@ namespace Notesnook.API
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
- var dbSettings = Configuration.GetSection("MongoDbSettings").Get();
+ var dbSettings = new DbSettings
+ {
+ ConnectionString = Constants.MONGODB_CONNECTION_STRING,
+ DatabaseName = Constants.MONGODB_DATABASE_NAME
+ };
services.AddSingleton(dbSettings);
services.TryAddSingleton();
diff --git a/Streetwriters.Common/Clients.cs b/Streetwriters.Common/Clients.cs
index 6b912ef..eeadfcd 100644
--- a/Streetwriters.Common/Clients.cs
+++ b/Streetwriters.Common/Clients.cs
@@ -22,13 +22,14 @@ 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
{
- private static IClient Notesnook = new Client
+ private static Client Notesnook = new Client
{
Id = "notesnook",
Name = "Notesnook",
@@ -36,20 +37,34 @@ namespace Streetwriters.Common
SenderName = Constants.NOTESNOOK_SENDER_NAME,
Type = ApplicationType.NOTESNOOK,
AppId = ApplicationType.NOTESNOOK,
+ AccountRecoveryRedirectURL = $"{Constants.NOTESNOOK_APP_HOST}/account/verified",
+ EmailConfirmedRedirectURL = $"{Constants.NOTESNOOK_APP_HOST}/account/recovery",
+ OnEmailConfirmed = async (userId) =>
+ {
+ await WampServers.MessengerServer.PublishMessageAsync(WampServers.MessengerServer.Topics.SendSSETopic, new SendSSEMessage
+ {
+ UserId = userId,
+ Message = new Message
+ {
+ Type = "emailConfirmed",
+ Data = null
+ }
+ });
+ }
};
- public static Dictionary ClientsMap = new Dictionary
+ public static Dictionary ClientsMap = new Dictionary
{
{ "notesnook", Notesnook }
};
- public static IClient FindClientById(string id)
+ public static Client FindClientById(string id)
{
if (!IsValidClient(id)) return null;
return ClientsMap[id];
}
- public static IClient FindClientByAppId(ApplicationType appId)
+ public static Client FindClientByAppId(ApplicationType appId)
{
switch (appId)
{
diff --git a/Streetwriters.Common/Constants.cs b/Streetwriters.Common/Constants.cs
index 35a27b7..6f5a723 100644
--- a/Streetwriters.Common/Constants.cs
+++ b/Streetwriters.Common/Constants.cs
@@ -23,25 +23,47 @@ namespace Streetwriters.Common
{
public class Constants
{
+ public static bool IS_SELF_HOSTED => Environment.GetEnvironmentVariable("SELF_HOSTED") == "1";
+
// S3 related
- public static string S3_ACCESS_KEY = Environment.GetEnvironmentVariable("S3_ACCESS_KEY");
- public static string S3_ACCESS_KEY_ID = Environment.GetEnvironmentVariable("S3_ACCESS_KEY_ID");
- public static string S3_SERVICE_URL = Environment.GetEnvironmentVariable("S3_HOST");
- public static string S3_REGION = Environment.GetEnvironmentVariable("S3_HOST");
+ public static string S3_ACCESS_KEY => Environment.GetEnvironmentVariable("S3_ACCESS_KEY");
+ public static string S3_ACCESS_KEY_ID => Environment.GetEnvironmentVariable("S3_ACCESS_KEY_ID");
+ public static string S3_SERVICE_URL => Environment.GetEnvironmentVariable("S3_SERVICE_URL");
+ public static string S3_REGION => Environment.GetEnvironmentVariable("S3_REGION");
// SMTP settings
- public static string SMTP_USERNAME = Environment.GetEnvironmentVariable("SMTP_USERNAME");
- public static string SMTP_PASSWORD = Environment.GetEnvironmentVariable("SMTP_PASSWORD");
- public static string SMTP_HOST = Environment.GetEnvironmentVariable("SMTP_HOST");
- public static string SMTP_PORT = Environment.GetEnvironmentVariable("SMTP_PORT");
- public static string SMTP_REPLYTO_NAME = Environment.GetEnvironmentVariable("SMTP_REPLYTO_NAME");
- public static string SMTP_REPLYTO_EMAIL = Environment.GetEnvironmentVariable("SMTP_REPLYTO_EMAIL");
- public static string NOTESNOOK_SENDER_EMAIL = Environment.GetEnvironmentVariable("NOTESNOOK_SENDER_EMAIL");
- public static string NOTESNOOK_SENDER_NAME = Environment.GetEnvironmentVariable("NOTESNOOK_SENDER_NAME");
+ public static string SMTP_USERNAME => Environment.GetEnvironmentVariable("SMTP_USERNAME");
+ public static string SMTP_PASSWORD => Environment.GetEnvironmentVariable("SMTP_PASSWORD");
+ public static string SMTP_HOST => Environment.GetEnvironmentVariable("SMTP_HOST");
+ public static string SMTP_PORT => Environment.GetEnvironmentVariable("SMTP_PORT");
+ public static string SMTP_REPLYTO_NAME => Environment.GetEnvironmentVariable("SMTP_REPLYTO_NAME");
+ public static string SMTP_REPLYTO_EMAIL => Environment.GetEnvironmentVariable("SMTP_REPLYTO_EMAIL");
+ public static string NOTESNOOK_SENDER_EMAIL => Environment.GetEnvironmentVariable("NOTESNOOK_SENDER_EMAIL");
+ public static string NOTESNOOK_SENDER_NAME => Environment.GetEnvironmentVariable("NOTESNOOK_SENDER_NAME");
- public static string NOTESNOOK_API_SECRET = Environment.GetEnvironmentVariable("NOTESNOOK_API_SECRET");
+ public static string NOTESNOOK_APP_HOST => Environment.GetEnvironmentVariable("NOTESNOOK_APP_HOST");
+ public static string NOTESNOOK_API_SECRET => Environment.GetEnvironmentVariable("NOTESNOOK_API_SECRET");
// MessageBird is used for SMS sending
- public static string MESSAGEBIRD_ACCESS_KEY = Environment.GetEnvironmentVariable("MESSAGEBIRD_ACCESS_KEY");
+ public static string MESSAGEBIRD_ACCESS_KEY => Environment.GetEnvironmentVariable("MESSAGEBIRD_ACCESS_KEY");
+
+ // internal
+ public static string ORIGIN_CERT_PATH => Environment.GetEnvironmentVariable("ORIGIN_CERT_PATH");
+ public static string ORIGIN_CERT_KEY_PATH => Environment.GetEnvironmentVariable("ORIGIN_CERT_KEY_PATH");
+ public static string MONGODB_CONNECTION_STRING => Environment.GetEnvironmentVariable("MONGODB_CONNECTION_STRING");
+ public static string MONGODB_DATABASE_NAME => Environment.GetEnvironmentVariable("MONGODB_DATABASE_NAME");
+
+ // Server discovery
+ public static int NOTESNOOK_SERVER_PORT => int.Parse(Environment.GetEnvironmentVariable("NOTESNOOK_SERVER_PORT"));
+ public static string NOTESNOOK_SERVER_HOST => Environment.GetEnvironmentVariable("NOTESNOOK_SERVER_HOST");
+ public static string NOTESNOOK_SERVER_DOMAIN => Environment.GetEnvironmentVariable("NOTESNOOK_SERVER_DOMAIN");
+
+ public static int IDENTITY_SERVER_PORT => int.Parse(Environment.GetEnvironmentVariable("IDENTITY_SERVER_PORT"));
+ public static string IDENTITY_SERVER_HOST => Environment.GetEnvironmentVariable("IDENTITY_SERVER_HOST");
+ public static string IDENTITY_SERVER_DOMAIN => Environment.GetEnvironmentVariable("IDENTITY_SERVER_DOMAIN");
+
+ public static int SSE_SERVER_PORT => int.Parse(Environment.GetEnvironmentVariable("SSE_SERVER_PORT"));
+ public static string SSE_SERVER_HOST => Environment.GetEnvironmentVariable("SSE_SERVER_HOST");
+ public static string SSE_SERVER_DOMAIN => Environment.GetEnvironmentVariable("SSE_SERVER_DOMAIN");
}
}
\ No newline at end of file
diff --git a/Streetwriters.Common/Interfaces/IClient.cs b/Streetwriters.Common/Interfaces/IClient.cs
index 1925785..3932ded 100644
--- a/Streetwriters.Common/Interfaces/IClient.cs
+++ b/Streetwriters.Common/Interfaces/IClient.cs
@@ -17,6 +17,8 @@ You should have received a copy of the Affero GNU General Public License
along with this program. If not, see .
*/
+using System;
+using System.Threading.Tasks;
using Streetwriters.Common.Enums;
namespace Streetwriters.Common.Interfaces
@@ -29,5 +31,8 @@ namespace Streetwriters.Common.Interfaces
ApplicationType AppId { get; set; }
string SenderEmail { get; set; }
string SenderName { get; set; }
+ string EmailConfirmedRedirectURL { get; }
+ string AccountRecoveryRedirectURL { get; }
+ Func OnEmailConfirmed { get; set; }
}
}
diff --git a/Streetwriters.Common/Models/Client.cs b/Streetwriters.Common/Models/Client.cs
index 56c992a..2abb4e6 100644
--- a/Streetwriters.Common/Models/Client.cs
+++ b/Streetwriters.Common/Models/Client.cs
@@ -17,9 +17,11 @@ You should have received a copy of the Affero GNU General Public License
along with this program. If not, see .
*/
+using System;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using System.Text.Json.Serialization;
+using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using Streetwriters.Common.Enums;
@@ -35,5 +37,9 @@ namespace Streetwriters.Common.Models
public ApplicationType AppId { get; set; }
public string SenderEmail { get; set; }
public string SenderName { get; set; }
+ public string EmailConfirmedRedirectURL { get; set; }
+ public string AccountRecoveryRedirectURL { get; set; }
+
+ public Func OnEmailConfirmed { get; set; }
}
}
diff --git a/Streetwriters.Common/Servers.cs b/Streetwriters.Common/Servers.cs
index 9ed6d04..4c925ec 100644
--- a/Streetwriters.Common/Servers.cs
+++ b/Streetwriters.Common/Servers.cs
@@ -28,7 +28,7 @@ namespace Streetwriters.Common
{
public class Server
{
- public string Port { get; set; }
+ public int Port { get; set; }
public bool IsSecure { get; set; }
public string Hostname { get; set; }
public string Domain { get; set; }
@@ -38,7 +38,7 @@ namespace Streetwriters.Common
var url = "";
url += IsSecure ? "https" : "http";
url += $"://{Hostname}";
- url += IsSecure ? "" : $":{Port}";
+ url += IsSecure || Port == 80 ? "" : $":{Port}";
return url;
}
@@ -47,7 +47,7 @@ namespace Streetwriters.Common
var url = "";
url += IsSecure ? "ws" : "ws";
url += $"://{Hostname}";
- url += $":{Port}";
+ url += Port == 80 ? "" : $":{Port}";
return url;
}
}
@@ -77,74 +77,39 @@ namespace Streetwriters.Common
public readonly static string HOST = GetLocalIPv4(NetworkInterfaceType.Ethernet);
public static Server S3Server { get; } = new()
{
- Port = "4568",
+ Port = 4568,
Hostname = HOST,
IsSecure = false,
Domain = HOST
};
#else
private readonly static string HOST = "localhost";
- public readonly static X509Certificate2 OriginSSLCertificate = X509Certificate2.CreateFromPemFile(Environment.GetEnvironmentVariable("ORIGIN_CERT_PATH"), Environment.GetEnvironmentVariable("ORIGIN_CERT_KEY_PATH"));
+ public readonly static X509Certificate2 OriginSSLCertificate = string.IsNullOrEmpty(Constants.ORIGIN_CERT_PATH) || string.IsNullOrEmpty(Constants.ORIGIN_CERT_KEY_PATH) ? null : X509Certificate2.CreateFromPemFile(Constants.ORIGIN_CERT_PATH, Environment.GetEnvironmentVariable(Constants.ORIGIN_CERT_KEY_PATH));
#endif
public static Server NotesnookAPI { get; } = new()
{
- Domain = "api.notesnook.com",
- Port = "5264",
-#if DEBUG
- IsSecure = false,
- Hostname = HOST,
-#else
- IsSecure = true,
- Hostname = "10.0.0.5",
-#endif
+ Domain = Constants.NOTESNOOK_SERVER_DOMAIN,
+ Port = Constants.NOTESNOOK_SERVER_PORT,
+ Hostname = Constants.NOTESNOOK_SERVER_HOST,
};
public static Server MessengerServer { get; } = new()
{
- Domain = "events.streetwriters.co",
- Port = "7264",
-#if DEBUG
- IsSecure = false,
- Hostname = HOST,
-#else
- IsSecure = true,
- Hostname = "10.0.0.6",
-#endif
+ Domain = Constants.SSE_SERVER_DOMAIN,
+ Port = Constants.SSE_SERVER_PORT,
+ Hostname = Constants.SSE_SERVER_HOST,
};
public static Server IdentityServer { get; } = new()
{
- Domain = "auth.streetwriters.co",
- IsSecure = false,
- Port = "8264",
-#if DEBUG
- Hostname = HOST,
-#else
- Hostname = "10.0.0.4",
-#endif
+ Domain = Constants.IDENTITY_SERVER_DOMAIN,
+ Port = Constants.IDENTITY_SERVER_PORT,
+ Hostname = Constants.IDENTITY_SERVER_HOST,
};
public static Server SubscriptionServer { get; } = new()
{
Domain = "subscriptions.streetwriters.co",
- IsSecure = false,
- Port = "9264",
-#if DEBUG
- Hostname = HOST,
-#else
- Hostname = "10.0.0.4",
-#endif
- };
- public static Server PaymentsServer { get; } = new()
- {
- Domain = "payments.streetwriters.co",
- IsSecure = false,
- Port = "6264",
-#if DEBUG
- Hostname = HOST,
-#else
- Hostname = "10.0.0.4",
-#endif
};
}
}
diff --git a/Streetwriters.Identity/Controllers/AccountController.cs b/Streetwriters.Identity/Controllers/AccountController.cs
index 039d981..69d2f5a 100644
--- a/Streetwriters.Identity/Controllers/AccountController.cs
+++ b/Streetwriters.Identity/Controllers/AccountController.cs
@@ -17,7 +17,6 @@ You should have received a copy of the Affero GNU General Public License
along with this program. If not, see .
*/
-using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
@@ -29,13 +28,10 @@ using IdentityServer4.Stores;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
-using MongoDB.Bson;
using Streetwriters.Common;
-using Streetwriters.Common.Enums;
using Streetwriters.Common.Messages;
using Streetwriters.Common.Models;
using Streetwriters.Identity.Enums;
-using Streetwriters.Identity.Handlers;
using Streetwriters.Identity.Interfaces;
using Streetwriters.Identity.Models;
using static IdentityServer4.IdentityServerConstants;
@@ -80,16 +76,15 @@ namespace Streetwriters.Identity.Controllers
var result = await UserManager.ConfirmEmailAsync(user, code);
if (!result.Succeeded) return BadRequest(result.Errors.ToErrors());
- foreach (var handler in ClientHandlers.Handlers)
+
+ if (await UserManager.IsInRoleAsync(user, client.Id))
{
- if (await UserManager.IsInRoleAsync(user, client.Id))
- {
- await handler.Value.OnEmailConfirmed(userId);
- // if (client.WelcomeEmailTemplateId != null)
- // await EmailSender.SendWelcomeEmailAsync(user.Email, client);
- }
+ await client.OnEmailConfirmed(userId);
+ // if (client.WelcomeEmailTemplateId != null)
+ // await EmailSender.SendWelcomeEmailAsync(user.Email, client);
}
- var redirectUrl = $"{ClientHandlers.GetClientHandler(client.Type)?.EmailConfirmedRedirectURL}?userId={userId}";
+
+ var redirectUrl = $"{client.EmailConfirmedRedirectURL}?userId={userId}";
return RedirectPermanent(redirectUrl);
}
// case TokenType.CHANGE_EMAIL:
@@ -111,7 +106,7 @@ namespace Streetwriters.Identity.Controllers
return BadRequest("Invalid token.");
var authorizationCode = await UserManager.GenerateUserTokenAsync(user, TokenOptions.DefaultProvider, "PasswordResetAuthorizationCode");
- var redirectUrl = $"{ClientHandlers.GetClientHandler(client.Type)?.AccountRecoveryRedirectURL}?userId={userId}&code={authorizationCode}";
+ var redirectUrl = $"{client.AccountRecoveryRedirectURL}?userId={userId}&code={authorizationCode}";
return RedirectPermanent(redirectUrl);
}
default:
diff --git a/Streetwriters.Identity/Controllers/SignupController.cs b/Streetwriters.Identity/Controllers/SignupController.cs
index f6957a3..6de0aec 100644
--- a/Streetwriters.Identity/Controllers/SignupController.cs
+++ b/Streetwriters.Identity/Controllers/SignupController.cs
@@ -17,6 +17,7 @@ You should have received a copy of the Affero GNU General Public License
along with this program. If not, see .
*/
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
@@ -30,6 +31,7 @@ using Streetwriters.Common.Models;
using Streetwriters.Identity.Enums;
using Streetwriters.Identity.Interfaces;
using Streetwriters.Identity.Models;
+using Streetwriters.Identity.Services;
namespace Streetwriters.Identity.Controllers
{
@@ -97,7 +99,8 @@ namespace Streetwriters.Identity.Controllers
var user = await UserManager.FindByEmailAsync(form.Email);
await UserManager.AddToRoleAsync(user, client.Id);
- // await UserManager.AddClaimAsync(user, new Claim("verified", "false"));
+ if (Constants.IS_SELF_HOSTED)
+ await UserManager.AddClaimAsync(user, UserService.SubscriptionTypeToClaim(client.Id, Common.Enums.SubscriptionType.PREMIUM));
var code = await UserManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.TokenLink(user.Id.ToString(), code, client.Id, TokenType.CONFRIM_EMAIL, Request.Scheme);
diff --git a/Streetwriters.Identity/Handlers/ClientHandlers.cs b/Streetwriters.Identity/Handlers/ClientHandlers.cs
deleted file mode 100644
index b9828d8..0000000
--- a/Streetwriters.Identity/Handlers/ClientHandlers.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-This file is part of the Notesnook Sync Server project (https://notesnook.com/)
-
-Copyright (C) 2022 Streetwriters (Private) Limited
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the Affero GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-Affero GNU General Public License for more details.
-
-You should have received a copy of the Affero GNU General Public License
-along with this program. If not, see .
-*/
-
-using System.Collections.Generic;
-using Streetwriters.Common;
-using Streetwriters.Common.Enums;
-using Streetwriters.Identity.Interfaces;
-
-namespace Streetwriters.Identity.Handlers
-{
- public class ClientHandlers
- {
- public static Dictionary Handlers { get; set; } = new Dictionary
- {
- { ApplicationType.NOTESNOOK, new NotesnookHandler() }
- };
-
- public static IAppHandler GetClientHandler(ApplicationType type)
- {
- return Handlers[type];
- }
- }
-}
\ No newline at end of file
diff --git a/Streetwriters.Identity/Handlers/NotesnookHandler.cs b/Streetwriters.Identity/Handlers/NotesnookHandler.cs
deleted file mode 100644
index b440865..0000000
--- a/Streetwriters.Identity/Handlers/NotesnookHandler.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-This file is part of the Notesnook Sync Server project (https://notesnook.com/)
-
-Copyright (C) 2022 Streetwriters (Private) Limited
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the Affero GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-Affero GNU General Public License for more details.
-
-You should have received a copy of the Affero GNU General Public License
-along with this program. If not, see .
-*/
-
-using System;
-using System.Threading.Tasks;
-using Streetwriters.Common;
-using Streetwriters.Common.Enums;
-using Streetwriters.Common.Messages;
-using Streetwriters.Identity.Interfaces;
-
-namespace Streetwriters.Identity.Handlers
-{
- public class NotesnookHandler : IAppHandler
- {
- public string Host { get; }
- public string EmailConfirmedRedirectURL { get; }
- public string AccountRecoveryRedirectURL { get; }
-
- public NotesnookHandler()
- {
-#if DEBUG
- Host = "http://localhost:3000";
-#else
- Host = "https://app.notesnook.com";
-#endif
- EmailConfirmedRedirectURL = $"{this.Host}/account/verified";
- AccountRecoveryRedirectURL = $"{this.Host}/account/recovery";
- }
- public async Task OnEmailConfirmed(string userId)
- {
- await WampServers.MessengerServer.PublishMessageAsync(WampServers.MessengerServer.Topics.SendSSETopic, new SendSSEMessage
- {
- UserId = userId,
- Message = new Message
- {
- Type = "emailConfirmed",
- Data = null
- }
- });
- }
- }
-}
\ No newline at end of file
diff --git a/Streetwriters.Identity/Interfaces/IAppHandler.cs b/Streetwriters.Identity/Interfaces/IAppHandler.cs
deleted file mode 100644
index ca8b3cb..0000000
--- a/Streetwriters.Identity/Interfaces/IAppHandler.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-This file is part of the Notesnook Sync Server project (https://notesnook.com/)
-
-Copyright (C) 2022 Streetwriters (Private) Limited
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the Affero GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-Affero GNU General Public License for more details.
-
-You should have received a copy of the Affero GNU General Public License
-along with this program. If not, see .
-*/
-
-using System.Threading.Tasks;
-
-namespace Streetwriters.Identity.Interfaces
-{
- public interface IAppHandler
- {
- string Host { get; }
- string EmailConfirmedRedirectURL { get; }
- string AccountRecoveryRedirectURL { get; }
- Task OnEmailConfirmed(string userId);
- }
-}
\ No newline at end of file
diff --git a/Streetwriters.Identity/MessageHandlers/CreateSubscription.cs b/Streetwriters.Identity/MessageHandlers/CreateSubscription.cs
index d1b5ec3..4e4ba6d 100644
--- a/Streetwriters.Identity/MessageHandlers/CreateSubscription.cs
+++ b/Streetwriters.Identity/MessageHandlers/CreateSubscription.cs
@@ -21,16 +21,9 @@ using System.Threading.Tasks;
using Streetwriters.Common.Messages;
using Streetwriters.Common.Models;
using Streetwriters.Common;
-using System.Text.Json;
-using Streetwriters.Data.Repositories;
-using Streetwriters.Data.Interfaces;
-using Streetwriters.Common.Interfaces;
-using System;
using Microsoft.AspNetCore.Identity;
-using Streetwriters.Common.Enums;
using System.Security.Claims;
using System.Linq;
-using Streetwriters.Identity.Interfaces;
using Streetwriters.Identity.Services;
namespace Streetwriters.Identity.MessageHandlers
diff --git a/Streetwriters.Identity/MessageHandlers/DeleteSubscription.cs b/Streetwriters.Identity/MessageHandlers/DeleteSubscription.cs
index a413918..7840e1d 100644
--- a/Streetwriters.Identity/MessageHandlers/DeleteSubscription.cs
+++ b/Streetwriters.Identity/MessageHandlers/DeleteSubscription.cs
@@ -17,21 +17,12 @@ You should have received a copy of the Affero GNU General Public License
along with this program. If not, see .
*/
-using System;
using System.Threading.Tasks;
-using Streetwriters.Common.Enums;
using Streetwriters.Common.Messages;
-using Streetwriters.Common.Interfaces;
using Streetwriters.Common.Models;
using Streetwriters.Common;
-using System.Text.Json;
-using System.IO;
-using Streetwriters.Data.Repositories;
-using Streetwriters.Data.Interfaces;
using Microsoft.AspNetCore.Identity;
using System.Linq;
-using IdentityServer4.Stores;
-using Streetwriters.Identity.Interfaces;
namespace Streetwriters.Identity.MessageHandlers
{
diff --git a/Streetwriters.Identity/Program.cs b/Streetwriters.Identity/Program.cs
index 71bc587..8464dba 100644
--- a/Streetwriters.Identity/Program.cs
+++ b/Streetwriters.Identity/Program.cs
@@ -33,8 +33,6 @@ namespace Streetwriters.Identity
{
public static async Task Main(string[] args)
{
- DotNetEnv.Env.TraversePath().Load();
-
IHost host = CreateHostBuilder(args).Build();
await host.RunAsync();
}
@@ -48,7 +46,13 @@ namespace Streetwriters.Identity
})
.ConfigureWebHostDefaults(webBuilder =>
{
- webBuilder.UseStartup().UseUrls(Servers.IdentityServer.ToString());
+ webBuilder
+ .UseStartup()
+ .UseKestrel((options) =>
+ {
+ options.Limits.MaxRequestBodySize = long.MaxValue;
+ options.ListenAnyIP(Servers.IdentityServer.Port);
+ });
});
}
}
diff --git a/Streetwriters.Identity/Services/EmailSender.cs b/Streetwriters.Identity/Services/EmailSender.cs
index a7247c6..81cafb2 100644
--- a/Streetwriters.Identity/Services/EmailSender.cs
+++ b/Streetwriters.Identity/Services/EmailSender.cs
@@ -50,9 +50,11 @@ namespace Streetwriters.Identity.Services
public class EmailSender : IEmailSender, IAsyncDisposable
{
NNGnuPGContext NNGnuPGContext { get; set; }
+ SmtpClient mailClient;
public EmailSender(IConfiguration configuration)
{
NNGnuPGContext = new NNGnuPGContext(configuration.GetSection("PgpKeySettings"));
+ mailClient = new SmtpClient();
}
EmailTemplate Email2FATemplate = new EmailTemplate
@@ -90,12 +92,6 @@ namespace Streetwriters.Identity.Services
Subject = "Failed login attempt on your {{app_name}} account",
};
- SmtpClient mailClient;
- public EmailSender()
- {
- mailClient = new SmtpClient();
- }
-
public async Task Send2FACodeEmailAsync(string email, string code, IClient client)
{
var template = new EmailTemplate
@@ -179,34 +175,40 @@ namespace Streetwriters.Identity.Services
private async Task SendEmailAsync(string email, IEmailTemplate template, IClient client)
{
+ if (!mailClient.IsConnected)
+ {
+ if (int.TryParse(Constants.SMTP_PORT, out int port))
+ {
+ await mailClient.ConnectAsync(Constants.SMTP_HOST, port, MailKit.Security.SecureSocketOptions.StartTls);
+ }
+ else
+ {
+ throw new InvalidDataException("SMTP_PORT is not a valid integer value.");
+ }
+ }
+
+ if (!mailClient.IsAuthenticated)
+ await mailClient.AuthenticateAsync(Constants.SMTP_USERNAME, 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(Constants.SMTP_REPLYTO_NAME) && !string.IsNullOrEmpty(Constants.SMTP_REPLYTO_EMAIL))
+ message.ReplyTo.Add(new MailboxAddress(Constants.SMTP_REPLYTO_NAME, Constants.SMTP_REPLYTO_EMAIL));
+
+ message.Body = await GetEmailBodyAsync(template, client, sender);
+
+ await mailClient.SendAsync(message);
+ }
+
+ private async Task GetEmailBodyAsync(IEmailTemplate template, IClient client, MailboxAddress sender)
+ {
+ var builder = new BodyBuilder();
try
{
- if (!mailClient.IsConnected)
- {
- if (int.TryParse(Constants.SMTP_PORT, out int port))
- {
- await mailClient.ConnectAsync(Constants.SMTP_HOST, port, MailKit.Security.SecureSocketOptions.StartTls);
- }
- else
- {
- throw new InvalidDataException("SMTP_PORT is not a valid integer value.");
- }
- }
-
- if (!mailClient.IsAuthenticated)
- await mailClient.AuthenticateAsync(Constants.SMTP_USERNAME, 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(Constants.SMTP_REPLYTO_NAME) && !string.IsNullOrEmpty(Constants.SMTP_REPLYTO_EMAIL))
- message.ReplyTo.Add(new MailboxAddress(Constants.SMTP_REPLYTO_NAME, Constants.SMTP_REPLYTO_EMAIL));
-
- var builder = new BodyBuilder();
-
builder.TextBody = await Template.Parse(template.Text).RenderAsync(template.Data);
builder.HtmlBody = await Template.Parse(template.Html).RenderAsync(template.Data);
@@ -222,17 +224,16 @@ namespace Streetwriters.Identity.Services
outputStream.Seek(0, SeekOrigin.Begin);
builder.Attachments.Add($"{client.Id}_pub.asc", Encoding.ASCII.GetBytes(Encoding.ASCII.GetString(outputStream.ToArray())));
}
- message.Body = MultipartSigned.Create(NNGnuPGContext, sender, DigestAlgorithm.Sha256, builder.ToMessageBody());
+ return MultipartSigned.Create(NNGnuPGContext, sender, DigestAlgorithm.Sha256, builder.ToMessageBody());
}
else
{
- message.Body = builder.ToMessageBody();
+ return builder.ToMessageBody();
}
- await mailClient.SendAsync(message);
}
- catch (Exception ex)
+ catch (PrivateKeyNotFoundException)
{
- Console.Error.WriteLine(ex.Message);
+ return builder.ToMessageBody();
}
}
diff --git a/Streetwriters.Identity/Services/SMSSender.cs b/Streetwriters.Identity/Services/SMSSender.cs
index de27a9b..dcd23bf 100644
--- a/Streetwriters.Identity/Services/SMSSender.cs
+++ b/Streetwriters.Identity/Services/SMSSender.cs
@@ -32,7 +32,8 @@ namespace Streetwriters.Identity.Services
private Client client;
public SMSSender()
{
- client = Client.CreateDefault(Constants.MESSAGEBIRD_ACCESS_KEY);
+ if (!string.IsNullOrEmpty(Constants.MESSAGEBIRD_ACCESS_KEY))
+ client = Client.CreateDefault(Constants.MESSAGEBIRD_ACCESS_KEY);
}
public string SendOTP(string number, IClient app)
diff --git a/Streetwriters.Identity/Startup.cs b/Streetwriters.Identity/Startup.cs
index bf7eddf..e566796 100644
--- a/Streetwriters.Identity/Startup.cs
+++ b/Streetwriters.Identity/Startup.cs
@@ -59,7 +59,7 @@ namespace Streetwriters.Identity
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
- var connectionString = Configuration["MongoDbSettings:ConnectionString"];
+ var connectionString = Constants.MONGODB_CONNECTION_STRING;
services.AddTransient();
services.AddTransient();
diff --git a/Streetwriters.Messenger/Program.cs b/Streetwriters.Messenger/Program.cs
index 972bf65..5eeee8f 100644
--- a/Streetwriters.Messenger/Program.cs
+++ b/Streetwriters.Messenger/Program.cs
@@ -45,16 +45,7 @@ namespace Streetwriters.Messenger
.UseKestrel((options) =>
{
options.Limits.MaxRequestBodySize = long.MaxValue;
-#if DEBUG
- options.ListenAnyIP(int.Parse(Servers.MessengerServer.Port));
-#else
- options.ListenAnyIP(443, listenerOptions =>
- {
- listenerOptions.UseHttps(Servers.OriginSSLCertificate);
- });
- options.ListenAnyIP(80);
- options.Listen(IPAddress.Parse(Servers.MessengerServer.Hostname), int.Parse(Servers.MessengerServer.Port));
-#endif
+ options.ListenAnyIP(Servers.MessengerServer.Port);
});
});
}