🐛 Fix merge guest user into logged in user (#907)

This commit is contained in:
Luke Vella 2023-10-20 16:45:43 +01:00 committed by GitHub
parent 5be17fd249
commit 7c54268b58
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 202 additions and 201 deletions

View file

@ -18,9 +18,11 @@ import CredentialsProvider from "next-auth/providers/credentials";
import EmailProvider from "next-auth/providers/email"; import EmailProvider from "next-auth/providers/email";
import { LegacyTokenProvider } from "@/utils/auth/legacy-token-provider"; import { LegacyTokenProvider } from "@/utils/auth/legacy-token-provider";
import { mergeGuestsIntoUser } from "@/utils/auth/merge-user";
import { emailClient } from "@/utils/emails"; import { emailClient } from "@/utils/emails";
const authOptions = { const getAuthOptions = (...args: GetServerSessionParams) =>
({
adapter: PrismaAdapter(prisma), adapter: PrismaAdapter(prisma),
secret: process.env.SECRET_PASSWORD, secret: process.env.SECRET_PASSWORD,
session: { session: {
@ -115,14 +117,8 @@ const authOptions = {
error: "/auth/error", error: "/auth/error",
}, },
callbacks: { callbacks: {
async redirect({ url, baseUrl }) { async signIn({ user, email }) {
// Allows relative callback URLs if (email?.verificationRequest) {
if (url.startsWith("/")) return `${baseUrl}${url}`;
// Allows callback URLs on the same origin
else if (new URL(url).origin === baseUrl) return url;
return baseUrl;
},
async signIn({ user }) {
if (user.email) { if (user.email) {
const userExists = const userExists =
(await prisma.user.count({ (await prisma.user.count({
@ -130,6 +126,7 @@ const authOptions = {
email: user.email, email: user.email,
}, },
})) > 0; })) > 0;
if (userExists) { if (userExists) {
if (isEmailBlocked(user.email)) { if (isEmailBlocked(user.email)) {
return false; return false;
@ -139,6 +136,12 @@ const authOptions = {
return false; return false;
} }
} }
} else {
const session = await getServerSession(...args);
if (session && session.user.email === null) {
await mergeGuestsIntoUser(user.id, [session.user.id]);
}
}
return true; return true;
}, },
@ -185,18 +188,19 @@ const authOptions = {
return session; return session;
}, },
}, },
} satisfies NextAuthOptions; } satisfies NextAuthOptions);
export async function getServerSession( type GetServerSessionParams =
...args:
| [GetServerSidePropsContext["req"], GetServerSidePropsContext["res"]] | [GetServerSidePropsContext["req"], GetServerSidePropsContext["res"]]
| [NextApiRequest, NextApiResponse] | [NextApiRequest, NextApiResponse]
| [] | [];
) {
return getServerSessionWithOptions(...args, authOptions); export function getServerSession(...args: GetServerSessionParams) {
return getServerSessionWithOptions(...args, getAuthOptions(...args));
} }
export async function AuthApiRoute(req: NextApiRequest, res: NextApiResponse) { export async function AuthApiRoute(req: NextApiRequest, res: NextApiResponse) {
const authOptions = getAuthOptions(req, res);
return NextAuth(req, res, authOptions); return NextAuth(req, res, authOptions);
} }

View file

@ -0,0 +1,39 @@
import { prisma } from "@rallly/database";
export const mergeGuestsIntoUser = async (
userId: string,
guestIds: string[],
) => {
await prisma.poll.updateMany({
where: {
userId: {
in: guestIds,
},
},
data: {
userId: userId,
},
});
await prisma.participant.updateMany({
where: {
userId: {
in: guestIds,
},
},
data: {
userId: userId,
},
});
await prisma.comment.updateMany({
where: {
userId: {
in: guestIds,
},
},
data: {
userId: userId,
},
});
};

View file

@ -6,44 +6,6 @@ import { generateOtp } from "../../utils/nanoid";
import { publicProcedure, router } from "../trpc"; import { publicProcedure, router } from "../trpc";
import { RegistrationTokenPayload } from "../types"; import { RegistrationTokenPayload } from "../types";
// assigns participants and comments created by guests to a user
// we could have multiple guests because a login might be triggered from one device
// and opened in another one.
const mergeGuestsIntoUser = async (userId: string, guestIds: string[]) => {
await prisma.poll.updateMany({
where: {
userId: {
in: guestIds,
},
},
data: {
userId: userId,
},
});
await prisma.participant.updateMany({
where: {
userId: {
in: guestIds,
},
},
data: {
userId: userId,
},
});
await prisma.comment.updateMany({
where: {
userId: {
in: guestIds,
},
},
data: {
userId: userId,
},
});
};
export const auth = router({ export const auth = router({
// @deprecated // @deprecated
requestRegistration: publicProcedure requestRegistration: publicProcedure
@ -107,7 +69,7 @@ export const auth = router({
locale: z.string().optional(), locale: z.string().optional(),
}), }),
) )
.mutation(async ({ input, ctx }) => { .mutation(async ({ input }) => {
const payload = await decryptToken<RegistrationTokenPayload>(input.token); const payload = await decryptToken<RegistrationTokenPayload>(input.token);
if (!payload) { if (!payload) {
@ -129,10 +91,6 @@ export const auth = router({
}, },
}); });
if (ctx.user.isGuest) {
await mergeGuestsIntoUser(user.id, [ctx.user.id]);
}
return { ok: true, user }; return { ok: true, user };
}), }),
getUserPermission: publicProcedure getUserPermission: publicProcedure