diff --git a/server/auth/actions.ts b/server/auth/actions.ts index 89ccd7e37..9ba1b5bce 100644 --- a/server/auth/actions.ts +++ b/server/auth/actions.ts @@ -122,8 +122,6 @@ export enum ActionsEnum { createOrgDomain = "createOrgDomain", deleteOrgDomain = "deleteOrgDomain", restartOrgDomain = "restartOrgDomain", - sendUsageNotification = "sendUsageNotification", - sendTrialNotification = "sendTrialNotification", createRemoteExitNode = "createRemoteExitNode", updateRemoteExitNode = "updateRemoteExitNode", getRemoteExitNode = "getRemoteExitNode", diff --git a/server/db/pg/schema/privateSchema.ts b/server/db/pg/schema/privateSchema.ts index 1aa2a1ef7..0f1914fad 100644 --- a/server/db/pg/schema/privateSchema.ts +++ b/server/db/pg/schema/privateSchema.ts @@ -566,6 +566,17 @@ export const alertWebhookActions = pgTable("alertWebhookActions", { lastSentAt: bigint("lastSentAt", { mode: "number" }) // nullable }); +export const trialNotifications = pgTable("trialNotifications", { + notificationId: serial("notificationId").primaryKey(), + subscriptionId: varchar("subscriptionId", { length: 255 }) + .notNull() + .references(() => subscriptions.subscriptionId, { + onDelete: "cascade" + }), + notificationType: varchar("notificationType", { length: 50 }).notNull(), // trial_ending_5d, trial_ending_24h, trial_ended + sentAt: bigint("sentAt", { mode: "number" }).notNull() +}); + export type Approval = InferSelectModel; export type Limit = InferSelectModel; export type Account = InferSelectModel; @@ -604,3 +615,12 @@ export type EventStreamingCursor = InferSelectModel< typeof eventStreamingCursors >; export type AlertResources = InferSelectModel; +export type AlertHealthChecks = InferSelectModel; +export type AlertSites = InferSelectModel; +export type AlertRules = InferSelectModel; +export type AlertEmailActions = InferSelectModel; +export type AlertEmailRecipients = InferSelectModel< + typeof alertEmailRecipients +>; +export type AlertWebhookActions = InferSelectModel; +export type TrialNotification = InferSelectModel; diff --git a/server/db/sqlite/schema/privateSchema.ts b/server/db/sqlite/schema/privateSchema.ts index 25a7b5bf5..05c917887 100644 --- a/server/db/sqlite/schema/privateSchema.ts +++ b/server/db/sqlite/schema/privateSchema.ts @@ -21,6 +21,9 @@ import { targetHealthCheck, users } from "./schema"; +import { serial, varchar } from "drizzle-orm/mysql-core"; +import { pgTable } from "drizzle-orm/pg-core"; +import { bigint } from "zod"; export const certificates = sqliteTable("certificates", { certId: integer("certId").primaryKey({ autoIncrement: true }), @@ -569,6 +572,19 @@ export const alertWebhookActions = sqliteTable("alertWebhookActions", { lastSentAt: integer("lastSentAt") }); +export const trialNotifications = sqliteTable("trialNotifications", { + notificationId: integer("notificationId").primaryKey({ + autoIncrement: true + }), + subscriptionId: text("subscriptionId") + .notNull() + .references(() => subscriptions.subscriptionId, { + onDelete: "cascade" + }), + notificationType: text("notificationType").notNull(), // trial_ending_5d, trial_ending_24h, trial_ended + sentAt: integer("sentAt").notNull() +}); + export type Approval = InferSelectModel; export type Limit = InferSelectModel; export type Account = InferSelectModel; @@ -601,3 +617,10 @@ export type EventStreamingCursor = InferSelectModel< typeof eventStreamingCursors >; export type AlertResources = InferSelectModel; +export type AlertHealthChecks = InferSelectModel; +export type AlertSites = InferSelectModel; +export type AlertRule = InferSelectModel; +export type AlertEmailAction = InferSelectModel; +export type AlertEmailRecipient = InferSelectModel; +export type AlertWebhookAction = InferSelectModel; +export type TrialNotification = InferSelectModel; diff --git a/server/private/routers/integration.ts b/server/private/routers/integration.ts index d5dac01e1..820a843f0 100644 --- a/server/private/routers/integration.ts +++ b/server/private/routers/integration.ts @@ -67,24 +67,20 @@ if (build == "saas") { verifyApiKeyIsRoot, certificates.syncCertToNewts ); + + authenticated.post( + `/org/:orgId/send-usage-notification`, + verifyApiKeyIsRoot, // We are the only ones who can use root key so its fine + org.sendUsageNotification + ); + + authenticated.post( + `/org/:orgId/send-trial-notification`, + verifyApiKeyIsRoot, + org.sendTrialNotification + ); } -authenticated.post( - `/org/:orgId/send-usage-notification`, - verifyApiKeyIsRoot, // We are the only ones who can use root key so its fine - verifyApiKeyHasAction(ActionsEnum.sendUsageNotification), - logActionAudit(ActionsEnum.sendUsageNotification), - org.sendUsageNotification -); - -authenticated.post( - `/org/:orgId/send-trial-notification`, - verifyApiKeyIsRoot, - verifyApiKeyHasAction(ActionsEnum.sendTrialNotification), - logActionAudit(ActionsEnum.sendTrialNotification), - org.sendTrialNotification -); - authenticated.delete( "/idp/:idpId", verifyApiKeyIsRoot,