diff --git a/.env b/.env index 61f0d9d..dc1ac7d 100644 --- a/.env +++ b/.env @@ -1,2 +1,21 @@ # Required variables -NOTESNOOK_API_SECRET= # This should be a randomly generated secret \ No newline at end of file +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= \ No newline at end of file diff --git a/Notesnook.API/Accessors/SyncItemsRepositoryAccessor.cs b/Notesnook.API/Accessors/SyncItemsRepositoryAccessor.cs index 1fffd29..6c33cd5 100644 --- a/Notesnook.API/Accessors/SyncItemsRepositoryAccessor.cs +++ b/Notesnook.API/Accessors/SyncItemsRepositoryAccessor.cs @@ -20,7 +20,6 @@ You should have received a copy of the Affero GNU General Public License using Notesnook.API.Interfaces; using Notesnook.API.Models; using Notesnook.API.Repositories; -using Streetwriters.Common.Models; using Streetwriters.Data.Repositories; namespace Notesnook.API.Accessors diff --git a/Notesnook.API/Authorization/NotesnookUserRequirement.cs b/Notesnook.API/Authorization/NotesnookUserRequirement.cs index 45f6e0c..7df5a06 100644 --- a/Notesnook.API/Authorization/NotesnookUserRequirement.cs +++ b/Notesnook.API/Authorization/NotesnookUserRequirement.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.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; diff --git a/Notesnook.API/Authorization/SyncRequirement.cs b/Notesnook.API/Authorization/SyncRequirement.cs index d63155c..527a1a0 100644 --- a/Notesnook.API/Authorization/SyncRequirement.cs +++ b/Notesnook.API/Authorization/SyncRequirement.cs @@ -24,7 +24,6 @@ You should have received a copy of the Affero GNU General Public License using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization.Policy; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.SignalR; namespace Notesnook.API.Authorization { diff --git a/Notesnook.API/Controllers/MonographsController.cs b/Notesnook.API/Controllers/MonographsController.cs index 32384c8..72a1e94 100644 --- a/Notesnook.API/Controllers/MonographsController.cs +++ b/Notesnook.API/Controllers/MonographsController.cs @@ -24,7 +24,6 @@ You should have received a copy of the Affero GNU General Public License using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Notesnook.API.Models; -using Streetwriters.Common.Models; using Streetwriters.Data.Interfaces; using Streetwriters.Data.Repositories; diff --git a/Notesnook.API/Controllers/S3Controller.cs b/Notesnook.API/Controllers/S3Controller.cs index 0341717..51254b0 100644 --- a/Notesnook.API/Controllers/S3Controller.cs +++ b/Notesnook.API/Controllers/S3Controller.cs @@ -19,14 +19,9 @@ You should have received a copy of the Affero GNU General Public License 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; diff --git a/Notesnook.API/Extensions/AuthorizationResultTransformer.cs b/Notesnook.API/Extensions/AuthorizationResultTransformer.cs index 49aa9f1..b997313 100644 --- a/Notesnook.API/Extensions/AuthorizationResultTransformer.cs +++ b/Notesnook.API/Extensions/AuthorizationResultTransformer.cs @@ -24,8 +24,6 @@ You should have received a copy of the Affero GNU General Public License 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 { diff --git a/Notesnook.API/Models/Responses/SignupResponse.cs b/Notesnook.API/Models/Responses/SignupResponse.cs index d28151c..f5b01ce 100644 --- a/Notesnook.API/Models/Responses/SignupResponse.cs +++ b/Notesnook.API/Models/Responses/SignupResponse.cs @@ -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 diff --git a/Notesnook.API/Models/Responses/UserResponse.cs b/Notesnook.API/Models/Responses/UserResponse.cs index 4f524f5..1b24e63 100644 --- a/Notesnook.API/Models/Responses/UserResponse.cs +++ b/Notesnook.API/Models/Responses/UserResponse.cs @@ -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; diff --git a/Notesnook.API/Models/S3Options.cs b/Notesnook.API/Models/S3Options.cs index e36f100..f4dd02b 100644 --- a/Notesnook.API/Models/S3Options.cs +++ b/Notesnook.API/Models/S3Options.cs @@ -17,10 +17,6 @@ You should have received a copy of the Affero GNU General Public License along with this program. If not, see . */ -using System.ComponentModel.DataAnnotations; -using System.Runtime.Serialization; -using Microsoft.AspNetCore.Mvc; - namespace Notesnook.API.Models { public class S3Options diff --git a/Notesnook.API/Services/S3Service.cs b/Notesnook.API/Services/S3Service.cs index 560340e..e41f32d 100644 --- a/Notesnook.API/Services/S3Service.cs +++ b/Notesnook.API/Services/S3Service.cs @@ -39,15 +39,16 @@ public class S3Service : IS3Service private AmazonS3Client S3Client { get; } private HttpClient httpClient = new HttpClient(); - public S3Service(IOptions 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 @@ public S3Service(IOptions s3Options) #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; } diff --git a/Notesnook.API/Startup.cs b/Notesnook.API/Startup.cs index b721be6..9ad014a 100644 --- a/Notesnook.API/Startup.cs +++ b/Notesnook.API/Startup.cs @@ -127,7 +127,7 @@ public void ConfigureServices(IServiceCollection services) .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(req => diff --git a/Streetwriters.Common/Clients.cs b/Streetwriters.Common/Clients.cs index 57cada8..6b912ef 100644 --- a/Streetwriters.Common/Clients.cs +++ b/Streetwriters.Common/Clients.cs @@ -32,35 +32,10 @@ public class Clients { 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 ClientsMap = new Dictionary @@ -84,29 +59,9 @@ public static IClient FindClientByAppId(ApplicationType appId) 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, - }; - } } } \ No newline at end of file diff --git a/Streetwriters.Common/Constants.cs b/Streetwriters.Common/Constants.cs new file mode 100644 index 0000000..35a27b7 --- /dev/null +++ b/Streetwriters.Common/Constants.cs @@ -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 . +*/ + +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"); + } +} \ No newline at end of file diff --git a/Streetwriters.Common/Interfaces/IClient.cs b/Streetwriters.Common/Interfaces/IClient.cs index fca9b17..1925785 100644 --- a/Streetwriters.Common/Interfaces/IClient.cs +++ b/Streetwriters.Common/Interfaces/IClient.cs @@ -25,11 +25,9 @@ public interface IClient { 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; } } } diff --git a/Streetwriters.Common/Models/Client.cs b/Streetwriters.Common/Models/Client.cs index a64458c..56c992a 100644 --- a/Streetwriters.Common/Models/Client.cs +++ b/Streetwriters.Common/Models/Client.cs @@ -31,11 +31,9 @@ public class Client : IClient { 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; } } } diff --git a/Streetwriters.Identity/Config.cs b/Streetwriters.Identity/Config.cs index 2af8c2d..8072ca9 100644 --- a/Streetwriters.Identity/Config.cs +++ b/Streetwriters.Identity/Config.cs @@ -19,6 +19,7 @@ You should have received a copy of the Affero GNU General Public License using IdentityServer4; using IdentityServer4.Models; +using Streetwriters.Common; using System; using System.Collections.Generic; using System.Linq; @@ -44,7 +45,7 @@ public static class Config { 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 diff --git a/Streetwriters.Identity/Interfaces/IEmailSender.cs b/Streetwriters.Identity/Interfaces/IEmailSender.cs index 03e8ef7..dc5e160 100644 --- a/Streetwriters.Identity/Interfaces/IEmailSender.cs +++ b/Streetwriters.Identity/Interfaces/IEmailSender.cs @@ -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); diff --git a/Streetwriters.Identity/Models/MessageBirdOptions.cs b/Streetwriters.Identity/Models/MessageBirdOptions.cs deleted file mode 100644 index 1dd3569..0000000 --- a/Streetwriters.Identity/Models/MessageBirdOptions.cs +++ /dev/null @@ -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 . -*/ - -using System.ComponentModel.DataAnnotations; -using System.Runtime.Serialization; -using Microsoft.AspNetCore.Mvc; - -namespace Streetwriters.Identity.Models -{ - public class MessageBirdOptions - { - public string AccessKey { get; set; } - } -} \ No newline at end of file diff --git a/Streetwriters.Identity/Models/SmtpOptions.cs b/Streetwriters.Identity/Models/SmtpOptions.cs deleted file mode 100644 index c5df27c..0000000 --- a/Streetwriters.Identity/Models/SmtpOptions.cs +++ /dev/null @@ -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 . -*/ - -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; } - } -} \ No newline at end of file diff --git a/Streetwriters.Identity/Services/EmailSender.cs b/Streetwriters.Identity/Services/EmailSender.cs index effea5b..a7247c6 100644 --- a/Streetwriters.Identity/Services/EmailSender.cs +++ b/Streetwriters.Identity/Services/EmailSender.cs @@ -49,11 +49,9 @@ namespace Streetwriters.Identity.Services { public class EmailSender : IEmailSender, IAsyncDisposable { - IOptions SmtpOptions { get; set; } NNGnuPGContext NNGnuPGContext { get; set; } - public EmailSender(IConfiguration configuration, IOptions smtpOptions) + public EmailSender(IConfiguration configuration) { - SmtpOptions = smtpOptions; NNGnuPGContext = new NNGnuPGContext(configuration.GetSection("PgpKeySettings")); } @@ -114,19 +112,6 @@ public async Task Send2FACodeEmailAsync(string email, string code, IClient clien 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 @@ private async Task SendEmailAsync(string email, IEmailTemplate template, IClient 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 @@ private async Task SendEmailAsync(string email, IEmailTemplate template, IClient 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) diff --git a/Streetwriters.Identity/Services/SMSSender.cs b/Streetwriters.Identity/Services/SMSSender.cs index 341c946..de27a9b 100644 --- a/Streetwriters.Identity/Services/SMSSender.cs +++ b/Streetwriters.Identity/Services/SMSSender.cs @@ -23,15 +23,16 @@ You should have received a copy of the Affero GNU General Public License 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) + public SMSSender() { - client = Client.CreateDefault(messageBirdOptions.Value.AccessKey); + 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 427fcc5..bf7eddf 100644 --- a/Streetwriters.Identity/Startup.cs +++ b/Streetwriters.Identity/Startup.cs @@ -61,8 +61,6 @@ public void ConfigureServices(IServiceCollection services) { var connectionString = Configuration["MongoDbSettings:ConnectionString"]; - services.Configure(Configuration.GetSection("SmtpSettings")); - services.Configure(Configuration.GetSection("MessageBirdSettings")); services.AddTransient(); services.AddTransient(); services.AddTransient, Argon2PasswordHasher>(); diff --git a/Streetwriters.Messenger/Startup.cs b/Streetwriters.Messenger/Startup.cs index cd58bcf..206014f 100644 --- a/Streetwriters.Messenger/Startup.cs +++ b/Streetwriters.Messenger/Startup.cs @@ -72,7 +72,7 @@ public void ConfigureServices(IServiceCollection services) .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;