global: move more config to env vars

This commit is contained in:
Abdullah Atta
2022-12-29 11:18:29 +05:00
parent 9463d484a4
commit 3f89ebc214
24 changed files with 101 additions and 167 deletions
+20 -1
View File
@@ -1,2 +1,21 @@
# Required variables
NOTESNOOK_API_SECRET= # This should be a randomly generated secret
NOTESNOOK_API_SECRET= # This should be a randomly generated secret
# S3 related variables for storing attachments
S3_ACCESS_KEY=
S3_ACCESS_KEY_ID=
S3_SERVICE_URL=
S3_REGION=
# SMTP settings required for delivering emails
SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_HOST=
SMTP_PORT=
SMTP_REPLYTO_NAME= # optional
SMTP_REPLYTO_EMAIL= # optional
NOTESNOOK_SENDER_EMAIL= # optional
NOTESNOOK_SENDER_NAME= # optional
# MessageBird is used for 2FA via SMS
MESSAGEBIRD_ACCESS_KEY=
@@ -20,7 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
using Notesnook.API.Interfaces;
using Notesnook.API.Models;
using Notesnook.API.Repositories;
using Streetwriters.Common.Models;
using Streetwriters.Data.Repositories;
namespace Notesnook.API.Accessors
@@ -17,7 +17,6 @@ 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.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
@@ -24,7 +24,6 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization.Policy;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.SignalR;
namespace Notesnook.API.Authorization
{
@@ -24,7 +24,6 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Notesnook.API.Models;
using Streetwriters.Common.Models;
using Streetwriters.Data.Interfaces;
using Streetwriters.Data.Repositories;
@@ -19,14 +19,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Amazon.S3;
using Amazon.Runtime;
using Amazon.S3.Model;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.Security.Claims;
using System.Net.Http;
using System.Linq;
using Notesnook.API.Interfaces;
using System;
@@ -24,8 +24,6 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization.Policy;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Notesnook.API.Authorization;
namespace Notesnook.API.Extensions
{
@@ -1,6 +1,4 @@
using System.Runtime.Serialization;
using System.Text.Json.Serialization;
using Streetwriters.Common.Interfaces;
using Streetwriters.Common.Models;
namespace Notesnook.API.Models.Responses
@@ -1,6 +1,4 @@
using System.Runtime.Serialization;
using System.Text.Json.Serialization;
using Notesnook.API.Interfaces;
using Streetwriters.Common.Interfaces;
using Streetwriters.Common.Models;
-4
View File
@@ -17,10 +17,6 @@ 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 Microsoft.AspNetCore.Mvc;
namespace Notesnook.API.Models
{
public class S3Options
+5 -4
View File
@@ -39,15 +39,16 @@ namespace Notesnook.API.Services
private AmazonS3Client S3Client { get; }
private HttpClient httpClient = new HttpClient();
public S3Service(IOptions<S3Options> s3Options)
public S3Service()
{
var config = new AmazonS3Config
{
#if DEBUG
ServiceURL = Servers.S3Server.ToString(),
#else
ServiceURL = s3Options.Value.ServiceUrl,
AuthenticationRegion = s3Options.Value.Region,
ServiceURL = Constants.S3_SERVICE_URL,
AuthenticationRegion = Constants.S3_REGION,
#endif
ForcePathStyle = true,
SignatureMethod = SigningAlgorithm.HmacSHA256,
@@ -56,7 +57,7 @@ namespace Notesnook.API.Services
#if DEBUG
S3Client = new AmazonS3Client("S3RVER", "S3RVER", config);
#else
S3Client = new AmazonS3Client(s3Options.Value.AccessKeyId, s3Options.Value.SecretAccessKey, config);
S3Client = new AmazonS3Client(Constants.S3_ACCESS_KEY_ID, Constants.S3_ACCESS_KEY, config);
#endif
AWSConfigsS3.UseSignatureVersion4 = true;
}
+1 -1
View File
@@ -127,7 +127,7 @@ namespace Notesnook.API
.AddOAuth2Introspection("introspection", options =>
{
options.Authority = Servers.IdentityServer.ToString();
options.ClientSecret = Environment.GetEnvironmentVariable("NOTESNOOK_API_SECRET");
options.ClientSecret = Constants.NOTESNOOK_API_SECRET;
options.ClientId = "notesnook";
options.DiscoveryPolicy.RequireHttps = false;
options.TokenRetriever = new Func<HttpRequest, string>(req =>
+2 -47
View File
@@ -32,35 +32,10 @@ namespace Streetwriters.Common
{
Id = "notesnook",
Name = "Notesnook",
ProductIds = new string[]
{
"com.streetwriters.notesnook",
"org.streetwriters.notesnook",
"com.streetwriters.notesnook.sub.mo",
"com.streetwriters.notesnook.sub.yr",
"com.streetwriters.notesnook.sub.mo.15",
"com.streetwriters.notesnook.sub.yr.15",
"com.streetwriters.notesnook.sub.yr.trialoffer",
"com.streetwriters.notesnook.sub.mo.trialoffer",
"com.streetwriters.notesnook.sub.mo.tier1",
"com.streetwriters.notesnook.sub.yr.tier1",
"com.streetwriters.notesnook.sub.mo.tier2",
"com.streetwriters.notesnook.sub.yr.tier2",
"com.streetwriters.notesnook.sub.mo.tier3",
"com.streetwriters.notesnook.sub.yr.tier3",
"9822", // dev
"648884", // monthly tier 1
"658759", // yearly tier 1
"763942", // monthly tier 2
"763945", // yearly tier 2
"763943", // monthly tier 3
"763944", // yearly tier 3
},
SenderEmail = "support@notesnook.com",
SenderName = "Notesnook",
SenderEmail = Constants.NOTESNOOK_SENDER_EMAIL,
SenderName = Constants.NOTESNOOK_SENDER_NAME,
Type = ApplicationType.NOTESNOOK,
AppId = ApplicationType.NOTESNOOK,
WelcomeEmailTemplateId = "d-87768b3ee17d41fdbe4bcf0eb2583682"
};
public static Dictionary<string, IClient> ClientsMap = new Dictionary<string, IClient>
@@ -84,29 +59,9 @@ namespace Streetwriters.Common
return null;
}
public static IClient FindClientByProductId(string productId)
{
foreach (var client in ClientsMap)
{
if (client.Value.ProductIds.Contains(productId)) return client.Value;
}
return null;
}
public static bool IsValidClient(string id)
{
return ClientsMap.ContainsKey(id);
}
public static SubscriptionProvider? PlatformToSubscriptionProvider(string platform)
{
return platform switch
{
"ios" => SubscriptionProvider.APPLE,
"android" => SubscriptionProvider.GOOGLE,
"web" => SubscriptionProvider.PADDLE,
_ => null,
};
}
}
}
+47
View File
@@ -0,0 +1,47 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
using System;
namespace Streetwriters.Common
{
public class Constants
{
// 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");
// 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 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");
}
}
@@ -25,11 +25,9 @@ namespace Streetwriters.Common.Interfaces
{
string Id { get; set; }
string Name { get; set; }
string[] ProductIds { get; set; }
ApplicationType Type { get; set; }
ApplicationType AppId { get; set; }
string SenderEmail { get; set; }
string SenderName { get; set; }
string WelcomeEmailTemplateId { get; set; }
}
}
-2
View File
@@ -31,11 +31,9 @@ namespace Streetwriters.Common.Models
{
public string Id { get; set; }
public string Name { get; set; }
public string[] ProductIds { get; set; }
public ApplicationType Type { get; set; }
public ApplicationType AppId { get; set; }
public string SenderEmail { get; set; }
public string SenderName { get; set; }
public string WelcomeEmailTemplateId { get; set; }
}
}
+2 -1
View File
@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
using IdentityServer4;
using IdentityServer4.Models;
using Streetwriters.Common;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -44,7 +45,7 @@ namespace Streetwriters.Identity
{
new ApiResource("notesnook", "Notesnook API", new string[] { "verified" })
{
ApiSecrets = { new Secret(Environment.GetEnvironmentVariable("NOTESNOOK_API_SECRET")?.Sha256()) },
ApiSecrets = { new Secret(Constants.NOTESNOOK_API_SECRET?.Sha256()) },
Scopes = { "notesnook.sync" }
},
// local API
@@ -24,7 +24,6 @@ namespace Streetwriters.Identity.Interfaces
{
public interface IEmailSender
{
Task SendWelcomeEmailAsync(string email, IClient client);
Task SendConfirmationEmailAsync(string email, string callbackUrl, IClient client);
Task SendChangeEmailConfirmationAsync(string email, string code, IClient client);
Task SendPasswordResetEmailAsync(string email, string callbackUrl, IClient client);
@@ -1,30 +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 <http://www.gnu.org/licenses/>.
*/
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Microsoft.AspNetCore.Mvc;
namespace Streetwriters.Identity.Models
{
public class MessageBirdOptions
{
public string AccessKey { get; set; }
}
}
@@ -1,33 +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 <http://www.gnu.org/licenses/>.
*/
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Microsoft.AspNetCore.Mvc;
namespace Streetwriters.Identity.Models
{
public class SmtpOptions
{
public string Username { get; set; }
public string Password { get; set; }
public string Host { get; set; }
public int Port { get; set; }
}
}
+20 -21
View File
@@ -49,11 +49,9 @@ namespace Streetwriters.Identity.Services
{
public class EmailSender : IEmailSender, IAsyncDisposable
{
IOptions<SmtpOptions> SmtpOptions { get; set; }
NNGnuPGContext NNGnuPGContext { get; set; }
public EmailSender(IConfiguration configuration, IOptions<SmtpOptions> smtpOptions)
public EmailSender(IConfiguration configuration)
{
SmtpOptions = smtpOptions;
NNGnuPGContext = new NNGnuPGContext(configuration.GetSection("PgpKeySettings"));
}
@@ -114,19 +112,6 @@ namespace Streetwriters.Identity.Services
await SendEmailAsync(email, template, client);
}
public Task SendWelcomeEmailAsync(string email, IClient client)
{
// EmailTemplate template = new EmailTemplate
// {
// Id = client.WelcomeEmailTemplateId,
// Data = new { },
// SendAt = DateTimeOffset.UtcNow.AddHours(2).ToUnixTimeSeconds()
// };
// return SendEmailAsync(email, template, client);
return Task.CompletedTask;
}
public async Task SendConfirmationEmailAsync(string email, string callbackUrl, IClient client)
{
var template = new EmailTemplate
@@ -197,18 +182,29 @@ namespace Streetwriters.Identity.Services
try
{
if (!mailClient.IsConnected)
await mailClient.ConnectAsync(SmtpOptions.Value.Host, SmtpOptions.Value.Port, MailKit.Security.SecureSocketOptions.StartTls);
{
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(SmtpOptions.Value.Username, SmtpOptions.Value.Password);
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.ReplyTo.Add(new MailboxAddress("Streetwriters", "support@streetwriters.co"));
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);
@@ -226,9 +222,12 @@ 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());
}
else
{
message.Body = builder.ToMessageBody();
}
message.Body = MultipartSigned.Create(NNGnuPGContext, sender, DigestAlgorithm.Sha256, builder.ToMessageBody());
await mailClient.SendAsync(message);
}
catch (Exception ex)
+3 -2
View File
@@ -23,15 +23,16 @@ using MessageBird;
using MessageBird.Objects;
using Microsoft.Extensions.Options;
using Streetwriters.Identity.Models;
using Streetwriters.Common;
namespace Streetwriters.Identity.Services
{
public class SMSSender : ISMSSender
{
private Client client;
public SMSSender(IOptions<MessageBirdOptions> messageBirdOptions)
public SMSSender()
{
client = Client.CreateDefault(messageBirdOptions.Value.AccessKey);
client = Client.CreateDefault(Constants.MESSAGEBIRD_ACCESS_KEY);
}
public string SendOTP(string number, IClient app)
-2
View File
@@ -61,8 +61,6 @@ namespace Streetwriters.Identity
{
var connectionString = Configuration["MongoDbSettings:ConnectionString"];
services.Configure<SmtpOptions>(Configuration.GetSection("SmtpSettings"));
services.Configure<MessageBirdOptions>(Configuration.GetSection("MessageBirdSettings"));
services.AddTransient<IEmailSender, EmailSender>();
services.AddTransient<ISMSSender, SMSSender>();
services.AddTransient<IPasswordHasher<User>, Argon2PasswordHasher<User>>();
+1 -1
View File
@@ -72,7 +72,7 @@ namespace Streetwriters.Messenger
.AddOAuth2Introspection("introspection", options =>
{
options.Authority = Servers.IdentityServer.ToString();
options.ClientSecret = Environment.GetEnvironmentVariable("NOTESNOOK_API_SECRET");
options.ClientSecret = Constants.NOTESNOOK_API_SECRET;
options.ClientId = "notesnook";
options.SaveToken = true;
options.EnableCaching = true;