Skip to content
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
7 changes: 7 additions & 0 deletions apps/web/providers/EmailAccountProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { createContext, useContext, useEffect, useMemo, useState } from "react";
import { useParams } from "next/navigation";
import type { GetEmailAccountsResponse } from "@/app/api/user/email-accounts/route";
import { setLastEmailAccountAction } from "@/utils/actions/email-account-cookie";

type Context = {
emailAccount: GetEmailAccountsResponse["emailAccounts"][number] | undefined;
Expand Down Expand Up @@ -54,6 +55,12 @@ export function EmailAccountProvider({
}
}, [data, emailAccountId]);

useEffect(() => {
if (emailAccountId) {
setLastEmailAccountAction(emailAccountId);
}
}, [emailAccountId]);

return (
<EmailAccountContext.Provider
value={{
Expand Down
19 changes: 14 additions & 5 deletions apps/web/utils/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { redirect } from "next/navigation";
import prisma from "@/utils/prisma";
import { notFound } from "next/navigation";
import { getLastEmailAccountFromCookie } from "@/utils/actions/email-account-cookie";

export async function getGmailClientForEmail({
emailAccountId,
Expand Down Expand Up @@ -117,15 +118,23 @@ export async function redirectToEmailAccountPath(path: `/${string}`) {
const userId = session?.user.id;
if (!userId) throw new Error("Not authenticated");

const emailAccount = await prisma.emailAccount.findFirst({
where: { userId },
});
const lastEmailAccountId = await getLastEmailAccountFromCookie();

let emailAccountId = lastEmailAccountId;
Comment thread
elie222 marked this conversation as resolved.

// If no last account or it doesn't exist, fall back to first account
if (!emailAccountId) {
const emailAccount = await prisma.emailAccount.findFirst({
where: { userId },
});
emailAccountId = emailAccount?.id ?? null;
}

if (!emailAccount) {
if (!emailAccountId) {
notFound();
}

const redirectUrl = `/${emailAccount.id}${path}`;
const redirectUrl = `/${emailAccountId}${path}`;

redirect(redirectUrl);
}
27 changes: 27 additions & 0 deletions apps/web/utils/actions/email-account-cookie.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"use server";

import { cookies } from "next/headers";
import { LAST_EMAIL_ACCOUNT_COOKIE } from "@/utils/cookies";

/**
* Sets a cookie with the last selected email account ID.
* This is used when emailAccountId is not provided in the URL.
*/
export async function setLastEmailAccountAction(emailAccountId: string) {
const cookieStore = await cookies();

cookieStore.set(LAST_EMAIL_ACCOUNT_COOKIE, emailAccountId, {
path: "/",
maxAge: 60 * 60 * 24 * 365, // 1 year
sameSite: "lax",
httpOnly: true,
secure: process.env.NODE_ENV === "production",
});
}

// Not secure. Only used for redirects. Still requires checking user owns the account.
export async function getLastEmailAccountFromCookie(): Promise<string | null> {
const cookieStore = await cookies();
const value = cookieStore.get(LAST_EMAIL_ACCOUNT_COOKIE)?.value;
return value || null;
}
1 change: 1 addition & 0 deletions apps/web/utils/cookies.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const ASSISTANT_ONBOARDING_COOKIE = "viewed_assistant_onboarding";
export const REPLY_ZERO_ONBOARDING_COOKIE = "viewed_reply_zero_onboarding";
export const INVITATION_COOKIE = "invitation_id";
export const LAST_EMAIL_ACCOUNT_COOKIE = "last_email_account_id";

export function markOnboardingAsCompleted(cookie: string) {
document.cookie = `${cookie}=true; path=/; max-age=${Number.MAX_SAFE_INTEGER}; SameSite=Lax`;
Expand Down
2 changes: 1 addition & 1 deletion version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v2.16.5
v2.16.6