Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support capturing gclid #63

Merged
merged 3 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/Sources/Api/Configure/migrations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ extension Configure {
app.migrations.add(ReworkPayments())
app.migrations.add(AddUserShowSuspensionActivity())
app.migrations.add(EliminateNetworkDecisionsTable())
app.migrations.add(AddAdminGclid())
}
}
23 changes: 23 additions & 0 deletions api/Sources/Api/Database/Migrations/019_AddAdminGclid.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import FluentSQL
import Gertie

struct AddAdminGclid: GertieMigration {
func up(sql: SQLDatabase) async throws {
try await sql.addColumn(
Admin.M19.gclid,
on: Admin.M1.self,
type: .varchar(128),
nullable: true
)
}

func down(sql: SQLDatabase) async throws {
try await sql.dropColumn(Admin.M19.gclid, on: Admin.M1.self)
}
}

extension Admin {
enum M19 {
static let gclid = FieldKey("gclid")
}
}
5 changes: 4 additions & 1 deletion api/Sources/Api/Models/Admin/Admin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ final class Admin: Codable {
var subscriptionId: SubscriptionId?
var subscriptionStatus: SubscriptionStatus
var subscriptionStatusExpiration: Date
var gclid: String?
var createdAt = Date()
var updatedAt = Date()
var deletedAt: Date?
Expand All @@ -25,14 +26,16 @@ final class Admin: Codable {
password: String,
subscriptionStatus: SubscriptionStatus = .pendingEmailVerification,
subscriptionStatusExpiration: Date = Date().advanced(by: .days(7)),
subscriptionId: SubscriptionId? = nil
subscriptionId: SubscriptionId? = nil,
gclid: String? = nil
) {
self.id = id
self.email = email
self.password = password
self.subscriptionId = subscriptionId
self.subscriptionStatus = subscriptionStatus
self.subscriptionStatusExpiration = subscriptionStatusExpiration
self.gclid = gclid
}
}

Expand Down
1 change: 1 addition & 0 deletions api/Sources/Api/Models/Models+Duet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ extension Admin {
case subscriptionId
case subscriptionStatus
case subscriptionStatusExpiration
case gclid
case createdAt
case updatedAt
}
Expand Down
3 changes: 3 additions & 0 deletions api/Sources/Api/Models/Models+DuetSQL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ extension Admin: Model {
return .enum(subscriptionStatus)
case .subscriptionStatusExpiration:
return .date(subscriptionStatusExpiration)
case .gclid:
return .string(gclid)
case .createdAt:
return .date(createdAt)
case .updatedAt:
Expand All @@ -34,6 +36,7 @@ extension Admin: Model {
.subscriptionId: .string(subscriptionId?.rawValue),
.subscriptionStatus: .enum(subscriptionStatus),
.subscriptionStatusExpiration: .date(subscriptionStatusExpiration),
.gclid: .string(gclid),
.createdAt: .currentTimestamp,
.updatedAt: .currentTimestamp,
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ extension SendPasswordResetEmail: Resolver {
private func reset(_ email: String, _ dashboardUrl: String, _ token: UUID) -> XPostmark.Email {
.init(
to: email,
from: "[email protected]",
from: "Gertrude App <[email protected]>",
subject: "Gertrude password reset".withEmailSubjectDisambiguator,
html: """
You can reset your Gertrude account password by clicking \
Expand All @@ -47,7 +47,7 @@ private func reset(_ email: String, _ dashboardUrl: String, _ token: UUID) -> XP
private func notFound(_ email: String) -> XPostmark.Email {
.init(
to: email,
from: "[email protected]",
from: "Gertrude App <[email protected]>",
subject: "Gertrude app password reset".withEmailSubjectDisambiguator,
html: """
A password reset was requested for this email address, \
Expand Down
8 changes: 5 additions & 3 deletions api/Sources/Api/PairQL/Dashboard/Pairs/Signup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ struct Signup: Pair {
struct Input: PairInput {
var email: String
var password: String
var gclid: String?
}
}

Expand Down Expand Up @@ -42,7 +43,8 @@ extension Signup: Resolver {
email: .init(rawValue: email),
password: Env.mode == .test ? input.password : try Bcrypt.hash(input.password),
subscriptionStatus: .pendingEmailVerification,
subscriptionStatusExpiration: Current.date().advanced(by: .days(7))
subscriptionStatusExpiration: Current.date().advanced(by: .days(7)),
gclid: input.gclid
))

try await sendVerificationEmail(to: admin, in: context)
Expand All @@ -64,7 +66,7 @@ func sendVerificationEmail(to admin: Admin, in context: Context) async throws {
private func accountExists(with email: String) -> XPostmark.Email {
.init(
to: email,
from: "[email protected]",
from: "Gertrude App <[email protected]>",
subject: "Gertrude Signup Request".withEmailSubjectDisambiguator,
html: """
We received a request to initiate a signup for the Gertrude app, \
Expand All @@ -78,7 +80,7 @@ private func accountExists(with email: String) -> XPostmark.Email {
private func verify(_ email: String, _ dashboardUrl: String, _ token: UUID) -> XPostmark.Email {
.init(
to: email,
from: "[email protected]",
from: "Gertrude App <[email protected]>",
subject: "Action Required: Confirm your email".withEmailSubjectDisambiguator,
html: """
Please verify your email address by clicking \
Expand Down
12 changes: 6 additions & 6 deletions api/Sources/Api/Services/Jobs/SubscriptionEmails.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ enum SubscriptionEmails {
private static func trialEndingSoon(_ address: String) -> XPostmark.Email {
.init(
to: address,
from: "[email protected]",
from: "Gertrude App <[email protected]>",
replyTo: "[email protected]",
subject: "[action required] Gertrude trial ending soon".withEmailSubjectDisambiguator,
html: """
Expand All @@ -48,7 +48,7 @@ enum SubscriptionEmails {
private static func trialEndedToOverdue(_ address: String) -> XPostmark.Email {
.init(
to: address,
from: "[email protected]",
from: "Gertrude App <[email protected]>",
replyTo: "[email protected]",
subject: "[action required] Gertrude trial ended".withEmailSubjectDisambiguator,
html: """
Expand Down Expand Up @@ -85,7 +85,7 @@ enum SubscriptionEmails {
private static func overdueToUnpaid(_ address: String) -> XPostmark.Email {
.init(
to: address,
from: "[email protected]",
from: "Gertrude App <[email protected]>",
replyTo: "[email protected]",
subject: "[action required] Gertrude account disabled".withEmailSubjectDisambiguator,
html: """
Expand Down Expand Up @@ -121,7 +121,7 @@ enum SubscriptionEmails {
private static func paidToOverdue(_ address: String) -> XPostmark.Email {
.init(
to: address,
from: "[email protected]",
from: "Gertrude App <[email protected]>",
replyTo: "[email protected]",
subject: "[action required] Gertrude payment failed".withEmailSubjectDisambiguator,
html: """
Expand Down Expand Up @@ -161,7 +161,7 @@ enum SubscriptionEmails {
private static func unpaidToPendingDelete(_ address: String) -> XPostmark.Email {
.init(
to: address,
from: "[email protected]",
from: "Gertrude App <[email protected]>",
replyTo: "[email protected]",
subject: "[action required] Gertrude account will be deleted".withEmailSubjectDisambiguator,
html: """
Expand Down Expand Up @@ -189,7 +189,7 @@ enum SubscriptionEmails {
private static func deleteEmailUnverified(_ address: String) -> XPostmark.Email {
.init(
to: address,
from: "[email protected]",
from: "Gertrude App <[email protected]>",
replyTo: "[email protected]",
subject: "Gertrude unverified account deleted".withEmailSubjectDisambiguator,
html: """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,30 @@ final class DasboardUnauthedResolverTests: ApiTestCase {
let input = Signup.Input(email: email, password: "pass")
let output = try await Signup.resolve(with: input, in: context)

let user = try await Current.db.query(Admin.self)
let admin = try await Current.db.query(Admin.self)
.where(.email == email)
.first()

expect(output).toEqual(.success)
expect(user.subscriptionStatus).toEqual(.pendingEmailVerification)
expect(user.subscriptionStatusExpiration).toEqual(.epoch.advanced(by: .days(7)))
expect(admin.subscriptionStatus).toEqual(.pendingEmailVerification)
expect(admin.subscriptionStatusExpiration).toEqual(.epoch.advanced(by: .days(7)))
expect(sent.postmarkEmails.count).toEqual(1)
expect(sent.postmarkEmails[0].to).toEqual(email)
expect(sent.postmarkEmails[0].html).toContain("verify your email address")
}

func testInitiateSignupWithGclid() async throws {
let email = "signup".random + "@example.com"
let input = Signup.Input(email: email, password: "pass", gclid: "gclid-123")
_ = try await Signup.resolve(with: input, in: context)

let admin = try await Current.db.query(Admin.self)
.where(.email == email)
.first()

expect(admin.gclid).toEqual("gclid-123")
}

func testLoginFromMagicLink() async throws {
let admin = try await Current.db.create(Admin.random)
let token = await Current.ephemeral.createAdminIdToken(admin.id)
Expand Down
Loading