(null);
const [dialogOpen, setDialogOpen] = useState(false);
@@ -73,8 +70,11 @@ export default function JoinTeam({
);
};
- if (!invites?.length)
- return No invites found
;
+ if (!invites?.length) {
+ return !showCreateTeam ? (
+ No invites found
+ ) : null;
+ }
return (
diff --git a/apps/web/src/server/api/routers/invitiation.ts b/apps/web/src/server/api/routers/invitiation.ts
index c010cc9..4f94a16 100644
--- a/apps/web/src/server/api/routers/invitiation.ts
+++ b/apps/web/src/server/api/routers/invitiation.ts
@@ -5,64 +5,31 @@ import { env } from "~/env";
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";
export const invitationRouter = createTRPCRouter({
- createTeam: protectedProcedure
- .input(z.object({ name: z.string() }))
- .mutation(async ({ ctx, input }) => {
- const teams = await ctx.db.team.findMany({
+ getUserInvites: protectedProcedure
+ .input(
+ z.object({
+ inviteId: z.string().optional().nullable(),
+ })
+ )
+ .query(async ({ ctx, input }) => {
+ if (!ctx.session.user.email) {
+ return [];
+ }
+
+ const invites = await ctx.db.teamInvite.findMany({
where: {
- teamUsers: {
- some: {
- userId: ctx.session.user.id,
- },
- },
+ ...(input.inviteId
+ ? { id: input.inviteId }
+ : { email: ctx.session.user.email }),
+ },
+ include: {
+ team: true,
},
});
- if (teams.length > 0) {
- console.log("User already has a team");
- return;
- }
-
- if (!env.NEXT_PUBLIC_IS_CLOUD) {
- const _team = await ctx.db.team.findFirst();
- if (_team) {
- throw new TRPCError({
- message: "Can't have multiple teams in self hosted version",
- code: "UNAUTHORIZED",
- });
- }
- }
-
- return ctx.db.team.create({
- data: {
- name: input.name,
- teamUsers: {
- create: {
- userId: ctx.session.user.id,
- role: "ADMIN",
- },
- },
- },
- });
+ return invites;
}),
- getUserInvites: protectedProcedure.query(async ({ ctx }) => {
- if (!ctx.session.user.email) {
- return [];
- }
-
- const invites = await ctx.db.teamInvite.findMany({
- where: {
- email: ctx.session.user.email,
- },
- include: {
- team: true,
- },
- });
-
- return invites;
- }),
-
getInvite: protectedProcedure
.input(z.object({ inviteId: z.string() }))
.query(async ({ ctx, input }) => {
diff --git a/apps/web/src/server/api/routers/team.ts b/apps/web/src/server/api/routers/team.ts
index 87855c9..9a43bed 100644
--- a/apps/web/src/server/api/routers/team.ts
+++ b/apps/web/src/server/api/routers/team.ts
@@ -9,6 +9,7 @@ import {
teamAdminProcedure,
} from "~/server/api/trpc";
import { sendTeamInviteEmail } from "~/server/mailer";
+import send from "~/server/public-api/api/emails/send-email";
export const teamRouter = createTRPCRouter({
createTeam: protectedProcedure
@@ -97,8 +98,21 @@ export const teamRouter = createTRPCRouter({
}),
createTeamInvite: teamAdminProcedure
- .input(z.object({ email: z.string(), role: z.enum(["MEMBER", "ADMIN"]) }))
+ .input(
+ z.object({
+ email: z.string(),
+ role: z.enum(["MEMBER", "ADMIN"]),
+ sendEmail: z.boolean().default(true),
+ })
+ )
.mutation(async ({ ctx, input }) => {
+ if (!input.email) {
+ throw new TRPCError({
+ code: "BAD_REQUEST",
+ message: "Email is required",
+ });
+ }
+
const user = await ctx.db.user.findUnique({
where: {
email: input.email,
@@ -125,7 +139,9 @@ export const teamRouter = createTRPCRouter({
const teamUrl = `${env.NEXTAUTH_URL}/join-team?inviteId=${teamInvite.id}`;
- await sendTeamInviteEmail(input.email, teamUrl, ctx.team.name);
+ if (input.sendEmail) {
+ await sendTeamInviteEmail(input.email, teamUrl, ctx.team.name);
+ }
return teamInvite;
}),
diff --git a/apps/web/src/server/mailer.ts b/apps/web/src/server/mailer.ts
index 732cd40..266dded 100644
--- a/apps/web/src/server/mailer.ts
+++ b/apps/web/src/server/mailer.ts
@@ -1,5 +1,9 @@
import { env } from "~/env";
import { Unsend } from "unsend";
+import { isSelfHosted } from "~/utils/common";
+import { db } from "./db";
+import { getDomains } from "./service/domain-service";
+import { sendEmail } from "./service/email-service";
let unsend: Unsend | undefined;
@@ -54,7 +58,37 @@ async function sendMail(
text: string,
html: string
) {
- if (env.UNSEND_API_KEY && env.FROM_EMAIL) {
+ if (isSelfHosted()) {
+ console.log("Sending email using self hosted");
+ /*
+ Self hosted so checking if we can send using one of the available domain
+ Assuming self hosted will have only one team
+ TODO: fix this
+ */
+ const team = await db.team.findFirst({});
+ if (!team) {
+ console.error("No team found");
+ return;
+ }
+
+ const domains = await getDomains(team.id);
+
+ if (domains.length === 0 || !domains[0]) {
+ console.error("No domains found");
+ return;
+ }
+
+ const domain = domains[0];
+
+ await sendEmail({
+ teamId: team.id,
+ to: email,
+ from: `hello@${domain.name}`,
+ subject,
+ text,
+ html,
+ });
+ } else if (env.UNSEND_API_KEY && env.FROM_EMAIL) {
const resp = await getClient().emails.send({
to: email,
from: env.FROM_EMAIL,
diff --git a/apps/web/src/server/service/domain-service.ts b/apps/web/src/server/service/domain-service.ts
index a87a74a..4e65640 100644
--- a/apps/web/src/server/service/domain-service.ts
+++ b/apps/web/src/server/service/domain-service.ts
@@ -165,6 +165,17 @@ export async function deleteDomain(id: number) {
});
}
+export async function getDomains(teamId: number) {
+ return db.domain.findMany({
+ where: {
+ teamId,
+ },
+ orderBy: {
+ createdAt: "desc",
+ },
+ });
+}
+
async function getDmarcRecord(domain: string) {
try {
const dmarcRecord = await dnsResolveTxt(`_dmarc.${domain}`);
diff --git a/apps/web/src/server/service/email-queue-service.ts b/apps/web/src/server/service/email-queue-service.ts
index 0954ed9..f5fc618 100644
--- a/apps/web/src/server/service/email-queue-service.ts
+++ b/apps/web/src/server/service/email-queue-service.ts
@@ -201,6 +201,8 @@ async function executeEmail(
? JSON.parse(email.attachments)
: [];
+ console.log(`Domain: ${JSON.stringify(domain)}`);
+
const configurationSetName = await getConfigurationSetName(
domain?.clickTracking ?? false,
domain?.openTracking ?? false,
@@ -208,7 +210,6 @@ async function executeEmail(
);
if (!configurationSetName) {
- console.log(`[EmailQueueService]: Configuration set not found, skipping`);
return;
}
diff --git a/apps/web/src/server/service/ses-settings-service.ts b/apps/web/src/server/service/ses-settings-service.ts
index d60a555..dfd5d67 100644
--- a/apps/web/src/server/service/ses-settings-service.ts
+++ b/apps/web/src/server/service/ses-settings-service.ts
@@ -27,6 +27,7 @@ export class SesSettingsService {
region = env.AWS_DEFAULT_REGION
): Promise {
await this.checkInitialized();
+
if (this.cache[region]) {
return this.cache[region] as SesSetting;
}