From 05297cfd8f7a4b86ef30a0db8df735727c023769 Mon Sep 17 00:00:00 2001 From: saroar Date: Wed, 1 Nov 2023 21:46:31 +0000 Subject: [PATCH] add mongo queue for send verification email --- Package.resolved | 183 +++++++++--------- Package.swift | 2 + .../App/AppExtensions/Mailgun+Domains.swift | 6 +- .../MongoQueue+Application.swift | 22 +++ .../App/AppExtensions/Request+Extension.swift | 5 + Sources/App/AppExtensions/mongoQueues.swift | 13 ++ Sources/App/Jobs/EmailJobMongoQueue.swift | 60 ++++++ .../App/Models/Emails/VerificationEmail.swift | 32 +++ .../AuthenticationHandler.swift | 99 ++++------ Sources/App/Services/EmailVerifier.swift | 2 +- Sources/App/configure.swift | 6 +- 11 files changed, 279 insertions(+), 151 deletions(-) create mode 100644 Sources/App/AppExtensions/MongoQueue+Application.swift create mode 100644 Sources/App/AppExtensions/mongoQueues.swift create mode 100644 Sources/App/Jobs/EmailJobMongoQueue.swift diff --git a/Package.resolved b/Package.resolved index ecb3b56..3c3320a 100644 --- a/Package.resolved +++ b/Package.resolved @@ -6,7 +6,7 @@ "location" : "https://github.com/AddaMeSPB/AddaSharedModels.git", "state" : { "branch" : "CleanUpBackEndModel", - "revision" : "33ae1cc978578fe674521569522530254aa9baea" + "revision" : "b8d3d7af1b7baf18c89329f01d933c378820b22c" } }, { @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/swift-server/async-http-client.git", "state" : { - "revision" : "864c8d9e0ead5de7ba70b61c8982f89126710863", - "version" : "1.15.0" + "revision" : "16f7e62c08c6969899ce6cc277041e868364e5cf", + "version" : "1.19.0" } }, { @@ -41,8 +41,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/async-kit.git", "state" : { - "revision" : "9acea4c92f51a5885c149904f0d11db4712dda80", - "version" : "1.16.0" + "revision" : "7ece208cd401687641c88367a00e3ea2b04311f1", + "version" : "1.19.0" } }, { @@ -50,8 +50,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/OpenKitten/BSON.git", "state" : { - "revision" : "ff36ca6d4aabe234301fbf4bfb891f91e26a5f70", - "version" : "7.0.30" + "revision" : "c29936981d39667429d4e0ec03aa8d6a722ea36a", + "version" : "7.0.31" } }, { @@ -59,8 +59,17 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/console-kit.git", "state" : { - "revision" : "447f1046fb4e9df40973fe426ecb24a6f0e8d3b4", - "version" : "4.6.0" + "revision" : "ccd0773b3ad3c67a19918aaef6903678592bb087", + "version" : "4.9.0" + } + }, + { + "identity" : "dnsclient", + "kind" : "remoteSourceControl", + "location" : "https://github.com/orlandos-nl/DNSClient.git", + "state" : { + "revision" : "8a7b1be0208e6e9d1d9e0a07713e0c0ebd7a2010", + "version" : "2.3.0" } }, { @@ -68,8 +77,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/fluent.git", "state" : { - "revision" : "4db22cc7797b3a687de65e32e11108cf92fb32da", - "version" : "4.7.0" + "revision" : "4b4d8bf15a06fd60137e9c543e5503c4b842654e", + "version" : "4.8.0" } }, { @@ -77,8 +86,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/fluent-kit.git", "state" : { - "revision" : "cc8fed9ed71dd61872b951df707ce5ac122d7365", - "version" : "1.39.0" + "revision" : "e0bb2b060249b7a501249b1612807b2eaaec28c6", + "version" : "1.45.0" } }, { @@ -86,8 +95,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/fluent-mongo-driver.git", "state" : { - "revision" : "8d48a0f8f1fbf04cf4557c0315f8679caf1dcc75", - "version" : "1.2.1" + "revision" : "a4237b99720d2a728178bc9f4c4a0d11d309031e", + "version" : "1.3.1" } }, { @@ -95,8 +104,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/jwt.git", "state" : { - "revision" : "506d238a707c0e7c1d2cf690863902eaf3bc4e94", - "version" : "4.2.1" + "revision" : "d65f32bfd08fae5910d603028be5dec4f35b3482", + "version" : "4.2.2" } }, { @@ -104,8 +113,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/jwt-kit.git", "state" : { - "revision" : "dcd78f07e092ac9138327e2bfbb0687a55a80850", - "version" : "4.8.0" + "revision" : "cd0fe3af36764e876182137c3132a6d8459e1867", + "version" : "4.13.1" } }, { @@ -122,8 +131,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/leaf-kit.git", "state" : { - "revision" : "c67a1b06561bfb8a427ed7e50e27792e083f2d3e", - "version" : "1.8.0" + "revision" : "13f2fc4c8479113cd23876d9a434ef4573e368bb", + "version" : "1.10.2" } }, { @@ -140,26 +149,26 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/OpenKitten/MongoKitten.git", "state" : { - "revision" : "f2d245e50143e9d940566dd2d20914c040f34b9f", - "version" : "6.7.6" + "revision" : "a29b84eb12f05cec9ee26f78770dcec7e63a6771", + "version" : "6.7.14" } }, { - "identity" : "multipart-kit", + "identity" : "mongoqueue", "kind" : "remoteSourceControl", - "location" : "https://github.com/vapor/multipart-kit.git", + "location" : "https://github.com/orlandos-nl/MongoQueue.git", "state" : { - "revision" : "0d55c35e788451ee27222783c7d363cb88092fab", - "version" : "4.5.2" + "revision" : "1ed6a8b10de543102a17b4d865e37ba1ff6dc5f5", + "version" : "0.2.5" } }, { - "identity" : "niodns", + "identity" : "multipart-kit", "kind" : "remoteSourceControl", - "location" : "https://github.com/OpenKitten/NioDNS.git", + "location" : "https://github.com/vapor/multipart-kit.git", "state" : { - "revision" : "c4a22908f5c936201b30abc608b3f2a46120ad2c", - "version" : "2.2.0" + "revision" : "1adfd69df2da08f7931d4281b257475e32c96734", + "version" : "4.5.4" } }, { @@ -167,8 +176,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/queues.git", "state" : { - "revision" : "0f5891fdacd3bed7c11ae4acbb01186a493b3d44", - "version" : "1.12.0" + "revision" : "3dc80954c672effa188d01a15f56bf358c34beac", + "version" : "1.13.0" } }, { @@ -176,8 +185,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/queues-redis-driver.git", "state" : { - "revision" : "2728477b50e24be82f5bc0bd0722c35656e1c5b1", - "version" : "1.0.3" + "revision" : "89a4350c1a6eb03b5693f481817741ff36a8cdcc", + "version" : "1.1.1" } }, { @@ -185,17 +194,17 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/redis.git", "state" : { - "revision" : "fee95abaa1f390292dc42905b9a4324a271416c4", - "version" : "4.7.0" + "revision" : "2a8d3e4639b90b39b74309b54216bdfd9cb52b41", + "version" : "4.10.0" } }, { "identity" : "redistack", "kind" : "remoteSourceControl", - "location" : "https://gitlab.com/mordil/RediStack.git", + "location" : "https://github.com/swift-server/RediStack.git", "state" : { - "revision" : "254e3e78b32b2f332e6c8f010f5b8a92646c4632", - "version" : "1.3.2" + "revision" : "30a43b019569625d2d9972c4fe89e06dbdc09e64", + "version" : "1.5.1" } }, { @@ -203,8 +212,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/routing-kit.git", "state" : { - "revision" : "ffac7b3a127ce1e85fb232f1a6271164628809ad", - "version" : "4.6.0" + "revision" : "88077f2c9d12777dcc89562fa581888ff7ba14ae", + "version" : "4.8.1" } }, { @@ -212,8 +221,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/sql-kit.git", "state" : { - "revision" : "fcc29f543b3de7b661cbe7540805974234cb9740", - "version" : "3.24.0" + "revision" : "b2f128cb62a3abfbb1e3b2893ff3ee69e70f4f0f", + "version" : "3.28.0" } }, { @@ -221,8 +230,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-algorithms.git", "state" : { - "revision" : "b14b7f4c528c942f121c8b860b9410b2bf57825e", - "version" : "1.0.0" + "revision" : "bcd4f369ac962bc3e5244c9df778739f8f5bdbf1", + "version" : "1.1.0" } }, { @@ -230,17 +239,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-atomics.git", "state" : { - "revision" : "ff3d2212b6b093db7f177d0855adbc4ef9c5f036", - "version" : "1.0.3" - } - }, - { - "identity" : "swift-backtrace", - "kind" : "remoteSourceControl", - "location" : "https://github.com/swift-server/swift-backtrace.git", - "state" : { - "revision" : "f25620d5d05e2f1ba27154b40cafea2b67566956", - "version" : "1.3.3" + "revision" : "cd142fd2f64be2100422d658e7411e39489da985", + "version" : "1.2.0" } }, { @@ -248,8 +248,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/swift-case-paths", "state" : { - "revision" : "3c4eea896f8ee9cbe1c11d1d3d46b0f2809da958", - "version" : "0.12.0" + "revision" : "5da6989aae464f324eef5c5b52bdb7974725ab81", + "version" : "1.0.0" } }, { @@ -257,8 +257,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-collections", "state" : { - "revision" : "937e904258d22af6e447a0b72c0bc67583ef64a2", - "version" : "1.0.4" + "revision" : "a902f1823a7ff3c9ab2fba0f992396b948eda307", + "version" : "1.0.5" } }, { @@ -266,8 +266,17 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-crypto.git", "state" : { - "revision" : "75ec60b8b4cc0f085c3ac414f3dca5625fa3588e", - "version" : "2.2.4" + "revision" : "b51f1d6845b353a2121de1c6a670738ec33561a6", + "version" : "3.1.0" + } + }, + { + "identity" : "swift-http-types", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-http-types", + "state" : { + "revision" : "99d066e29effa8845e4761dd3f2f831edfdf8925", + "version" : "1.0.0" } }, { @@ -275,8 +284,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-log.git", "state" : { - "revision" : "32e8d724467f8fe623624570367e3d50c5638e46", - "version" : "1.5.2" + "revision" : "532d8b529501fb73a2455b179e0bbb6d49b652ed", + "version" : "1.5.3" } }, { @@ -284,8 +293,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-metrics.git", "state" : { - "revision" : "e8bced74bc6d747745935e469f45d03f048d6cbd", - "version" : "2.3.4" + "revision" : "971ba26378ab69c43737ee7ba967a896cb74c0d1", + "version" : "2.4.1" } }, { @@ -293,8 +302,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-nio.git", "state" : { - "revision" : "45167b8006448c79dda4b7bd604e07a034c15c49", - "version" : "2.48.0" + "revision" : "853522d90871b4b63262843196685795b5008c46", + "version" : "2.61.1" } }, { @@ -302,8 +311,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-nio-extras.git", "state" : { - "revision" : "98378d1fe56527761c180f70b2d66a7b2307fc39", - "version" : "1.16.0" + "revision" : "798c962495593a23fdea0c0c63fd55571d8dff51", + "version" : "1.20.0" } }, { @@ -311,8 +320,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-nio-http2.git", "state" : { - "revision" : "8dcda6828844022028025241e4e7d52cbbe250de", - "version" : "1.25.0" + "revision" : "3bd9004b9d685ed6b629760fc84903e48efec806", + "version" : "1.29.0" } }, { @@ -320,8 +329,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-nio-ssl.git", "state" : { - "revision" : "4fb7ead803e38949eb1d6fabb849206a72c580f3", - "version" : "2.23.0" + "revision" : "320bd978cceb8e88c125dcbb774943a92f6286e9", + "version" : "2.25.0" } }, { @@ -329,8 +338,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-nio-transport-services.git", "state" : { - "revision" : "c0d9a144cfaec8d3d596aadde3039286a266c15c", - "version" : "1.15.0" + "revision" : "ebf8b9c365a6ce043bf6e6326a04b15589bd285e", + "version" : "1.20.0" } }, { @@ -347,8 +356,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/swift-parsing", "state" : { - "revision" : "4bb9192468c1a8be57f46b7d6fd4f561c88b2195", - "version" : "0.11.0" + "revision" : "a0e7d73f462c1c38c59dc40a3969ac40cea42950", + "version" : "0.13.0" } }, { @@ -356,8 +365,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/swift-url-routing.git", "state" : { - "revision" : "f54c4f74e7884f7930560c08387817ce28271770", - "version" : "0.4.0" + "revision" : "13f65cec4de950ba30f08d9bc4abcfa41f9479b9", + "version" : "0.6.0" } }, { @@ -365,8 +374,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/vapor.git", "state" : { - "revision" : "7b76fe01a8eb02aa7f61d9ca10624f98b25a5735", - "version" : "4.69.2" + "revision" : "3bf4e73955d029743c233f127f4259a101a764f5", + "version" : "4.85.0" } }, { @@ -383,8 +392,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/websocket-kit.git", "state" : { - "revision" : "2d9d2188a08eef4a869d368daab21b3c08510991", - "version" : "2.6.1" + "revision" : "53fe0639a98903858d0196b699720decb42aee7b", + "version" : "2.14.0" } }, { @@ -392,8 +401,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay", "state" : { - "revision" : "62041e6016a30f56952f5d7d3f12a3fd7029e1cd", - "version" : "0.8.3" + "revision" : "23cbf2294e350076ea4dbd7d5d047c1e76b03631", + "version" : "1.0.2" } } ], diff --git a/Package.swift b/Package.swift index dc5cc9a..867b59b 100644 --- a/Package.swift +++ b/Package.swift @@ -13,6 +13,7 @@ let package = Package( .package(url: "https://github.com/vapor/fluent-mongo-driver.git", from: "1.1.2"), .package(url: "https://github.com/vapor/leaf.git", from: "4.2.0"), .package(url: "https://github.com/OpenKitten/MongoKitten.git", from: "6.7.0"), + .package(url: "https://github.com/orlandos-nl/MongoQueue.git", from: "0.1.0"), .package(url: "https://github.com/vapor/jwt.git", from: "4.2.0"), .package(url: "https://github.com/vapor/apns.git", from: "1.0.1"), .package(url: "https://github.com/pointfreeco/vapor-routing", from: "0.1.2"), @@ -36,6 +37,7 @@ let package = Package( .product(name: "JWT", package: "jwt"), .product(name: "APNS", package: "apns"), .product(name: "MongoKitten", package: "MongoKitten"), + .product(name: "MongoQueue", package: "MongoQueue"), .product(name: "AddaSharedModels", package: "AddaSharedModels"), .product(name: "QueuesRedisDriver", package: "queues-redis-driver"), .product(name: "Mailgun", package: "mailgun"), diff --git a/Sources/App/AppExtensions/Mailgun+Domains.swift b/Sources/App/AppExtensions/Mailgun+Domains.swift index 976a707..8fb8651 100644 --- a/Sources/App/AppExtensions/Mailgun+Domains.swift +++ b/Sources/App/AppExtensions/Mailgun+Domains.swift @@ -3,7 +3,9 @@ import Vapor extension MailgunDomain { static var sandbox: MailgunDomain { - .init( Environment.get("MAILGUN_DOMAIN") ?? "", .us) + .init( "sandbox85d89c55d2ae4a3b8aaeca56b3a025c5.mailgun.org", .us) } - static var productoin: MailgunDomain { .init("word.justcal.me", .eu)} + + static var production: MailgunDomain { .init("addame.com", .eu)} } + diff --git a/Sources/App/AppExtensions/MongoQueue+Application.swift b/Sources/App/AppExtensions/MongoQueue+Application.swift new file mode 100644 index 0000000..24deb41 --- /dev/null +++ b/Sources/App/AppExtensions/MongoQueue+Application.swift @@ -0,0 +1,22 @@ +import Vapor +import MongoQueue + +private struct MongoQueueStorageKey: StorageKey { + public typealias Value = MongoQueue +} + +extension Application { + public var mongoQueue: MongoQueue { + get { + storage[MongoQueueStorageKey.self]! + } + set { + storage[MongoQueueStorageKey.self] = newValue + } + } + + public func initializeMongoQueue() { + self.mongoQueue = MongoQueue(collection: mongoDB["queue"]) + } +} + diff --git a/Sources/App/AppExtensions/Request+Extension.swift b/Sources/App/AppExtensions/Request+Extension.swift index f514399..da43dba 100644 --- a/Sources/App/AppExtensions/Request+Extension.swift +++ b/Sources/App/AppExtensions/Request+Extension.swift @@ -7,9 +7,14 @@ import Vapor import MongoKitten +import MongoQueue extension Request { public var mongoDB: MongoDatabase { return application.mongoDB.hopped(to: eventLoop) } + + public var mongoQueue: MongoQueue { + return application.mongoQueue + } } diff --git a/Sources/App/AppExtensions/mongoQueues.swift b/Sources/App/AppExtensions/mongoQueues.swift new file mode 100644 index 0000000..9e6f885 --- /dev/null +++ b/Sources/App/AppExtensions/mongoQueues.swift @@ -0,0 +1,13 @@ +import Vapor +import MongoQueue + +func mongoQueue(_ app: Application) throws { + app.mongoQueue.registerTask(EmailJobMongoQueue.self, context: app) + do { + try app.mongoQueue.runInBackground() + } catch { + app.logger.info("\(error)") + } + +} + diff --git a/Sources/App/Jobs/EmailJobMongoQueue.swift b/Sources/App/Jobs/EmailJobMongoQueue.swift new file mode 100644 index 0000000..995b798 --- /dev/null +++ b/Sources/App/Jobs/EmailJobMongoQueue.swift @@ -0,0 +1,60 @@ +import Vapor +import Mailgun +import MongoQueue + +struct EmailJobMongoQueue: RecurringTask { + + var payload: EmailPayload + var vCodeAttempt: VerificationCodeAttempt + + // The date this task should be executed at earliest + // We default to one week from 'now' + var initialTaskExecutionDate: Date { Date() } + + // We can use any execution context. This context is provided on registration, and the job can have access to it to do 'the work' + // For example, if your job sends email, pass it a handle to the email client + typealias ExecutionContext = Application + + // Ensures only one user engagement prompt exists per user + var uniqueTaskKey: String { vCodeAttempt.id!.hexString } + + // The amount of time we expect this task to take if it's very slow + // This is optional, and has a sensible default. Note; it will not be the task's actual deadline. + // Instead, the task will be killed if worker executing this task goes offline unexpectedly + // There's a mechanism in MongoQueue to detect a stale or dead task worker + var maxTaskDuration: TimeInterval { 60 } + + // This job has a low priority. Some other jobs may be done first if there's a contest for job queue time + var priority: TaskPriority { .higher } + + // Execute the task. In our case, we check their last login date + func execute(withContext context: ExecutionContext) async throws { + let mailgunMessage = MailgunTemplateMessage( + from: context.config.noReplyEmail, + to: payload.recipient, + subject: payload.email.subject, + template: payload.email.templateName, + templateData: payload.email.templateData + ) + + do { + _ = try await context.mailgun().send(mailgunMessage).get() + } catch { + print(error) + } + } + + // When to send the next reminder to the user + // If `nil` is returned, this job will never run again + func getNextRecurringTaskDate(_ context: ExecutionContext) async throws -> Date? { + return nil + } + + // If we failed to run the job for whatever reason (SMTP issue, database issue or otherwise) + func onExecutionFailure(failureContext: QueuedTaskFailure) async throws -> TaskExecutionFailureAction { + // Retry in 1 hour, `nil` for maxAttempts means we never stop retrying + print(failureContext.error) + return .retryAfter(3600, maxAttempts: nil) + } +} + diff --git a/Sources/App/Models/Emails/VerificationEmail.swift b/Sources/App/Models/Emails/VerificationEmail.swift index c550e70..61dc198 100644 --- a/Sources/App/Models/Emails/VerificationEmail.swift +++ b/Sources/App/Models/Emails/VerificationEmail.swift @@ -14,3 +14,35 @@ struct VerificationEmail: Email { self.verifyUrl = verifyUrl } } + +struct OTPEmail: Email { + + let templateName: String + let name: String + let bodyWithOtp: String + let duration: String + let subject: String + + var templateData: [String : String] { + [ + "name": name, + "otp": bodyWithOtp, + "duration": duration + ] + } + + init( + templateName: String = "email_verification", + name: String, + bodyWithOtp: String, + duration: String, + subject: String = "Please verify your email" + ) { + self.templateName = templateName + self.name = name + self.bodyWithOtp = bodyWithOtp + self.duration = duration + self.subject = subject + + } +} diff --git a/Sources/App/RouteHandlers/AuthEngineHandlers/AuthenticationHandler.swift b/Sources/App/RouteHandlers/AuthEngineHandlers/AuthenticationHandler.swift index 347d82a..1b3dea5 100644 --- a/Sources/App/RouteHandlers/AuthEngineHandlers/AuthenticationHandler.swift +++ b/Sources/App/RouteHandlers/AuthEngineHandlers/AuthenticationHandler.swift @@ -19,67 +19,48 @@ public func authenticationHandler( } let email = input.email.lowercased() - let code = String.randomDigits(ofLength: 6) - let message = "\(code)" - - switch request.application.environment { - case .production: - - try await request - .emailVerifier - .verifyOTPEmail(for: email, msg: message) - - let smsAttempt = VerificationCodeAttempt( - email: email, - code: code, - expiresAt: Date().addingTimeInterval(5.0 * 60.0) - ) - - _ = try await smsAttempt.save(on: request.db).get() - let attemptId = try! smsAttempt.requireID() - return EmailLoginOutput( - email: email, - attemptId: attemptId - ) - - case .development: - - let code = "336699" -// try await request -// .emailVerifier -// .verifyOTPEmail(for: input.email, msg: code) - - let smsAttempt = VerificationCodeAttempt( - email: email, - code: code, - expiresAt: Date().addingTimeInterval(5.0 * 60.0) - ) - _ = try await smsAttempt.save(on: request.db).get() - - let attemptId = try! smsAttempt.requireID() - return EmailLoginOutput( - email: email, - attemptId: attemptId - ) - - default: - - let code = "336699" - - let smsAttempt = VerificationCodeAttempt( - email: email, - code: code, - expiresAt: Date().addingTimeInterval(5.0 * 60.0) - ) - _ = try await smsAttempt.save(on: request.db).get() - - let attemptId = try! smsAttempt.requireID() - return EmailLoginOutput( - email: email, - attemptId: attemptId - ) + + let randomDigits = request.application.environment + == .development || request.application.environment + == .testing ? "336699" : String.randomDigits(ofLength: 6) + + let otp = "\(randomDigits)" + let minutes = 5.0 + let expiresAt = Date().addingTimeInterval(minutes * 60.0) + + let otpEmail = OTPEmail( + templateName: "addame_otp", + name: "Hello", + bodyWithOtp: otp, + duration: "\(minutes)", + subject: "Your Adda2 OTP Verification Code." + ) + + let smsAttempt = VerificationCodeAttempt( + email: email, + code: otp, + expiresAt: expiresAt + ) + + _ = try await smsAttempt.save(on: request.db).get() + let attemptId = try! smsAttempt.requireID() + + + let emailPayload = EmailPayload(otpEmail, to: email) + let task = EmailJobMongoQueue(payload: emailPayload, vCodeAttempt: smsAttempt) + + do { + try await request.mongoQueue.queueTask(task) + } catch { + request.logger.info("\(error)") } + return EmailLoginOutput( + email: email, + attemptId: attemptId + ) + + case .verifyEmail(let input): guard let attempt = try await VerificationCodeAttempt.query(on: request.db) diff --git a/Sources/App/Services/EmailVerifier.swift b/Sources/App/Services/EmailVerifier.swift index ad88aef..acd2826 100644 --- a/Sources/App/Services/EmailVerifier.swift +++ b/Sources/App/Services/EmailVerifier.swift @@ -28,7 +28,7 @@ struct EmailVerifier { var verificationEmail = VerificationEmail.init(verifyUrl: msg) verificationEmail.subject = "Addame2 Verification Code" - verificationEmail.templateName = "email_otp_verification_addame_server" + verificationEmail.templateName = "addame_otp" try await self.queue.dispatch( EmailJob.self, diff --git a/Sources/App/configure.swift b/Sources/App/configure.swift index ca7d0dd..27bfd4d 100644 --- a/Sources/App/configure.swift +++ b/Sources/App/configure.swift @@ -59,10 +59,12 @@ public func configure(_ app: Application) async throws { // MARK: Mailgun app.mailgun.configuration = .environment - app.mailgun.defaultDomain = .productoin + app.mailgun.defaultDomain = .production // MARK: Queues - try queues(app) + // MARK: MongoQueues + app.initializeMongoQueue() + try mongoQueue(app) // MARK: Services app.randomGenerators.use(.random)