a tool for shared writing and social publishing
298
fork

Configure Feed

Select the types of activity you want to include in your feed.

at feature/mention-services 118 lines 3.4 kB view raw
1"use server"; 2import { drizzle } from "drizzle-orm/node-postgres"; 3import { 4 email_auth_tokens, 5 identities, 6 permission_token_on_homepage, 7 poll_votes_on_entity, 8} from "drizzle/schema"; 9import { and, eq, isNull } from "drizzle-orm"; 10import { cookies } from "next/headers"; 11import { redirect } from "next/navigation"; 12import { pool } from "supabase/pool"; 13import { supabaseServerClient } from "supabase/serverClient"; 14 15export async function loginWithEmailToken( 16 localLeaflets: { token: { id: string }; added_at: string }[], 17) { 18 const client = await pool.connect(); 19 const db = drizzle(client); 20 let token_id = (await cookies()).get("auth_token")?.value; 21 let voter_token = (await cookies()).get("poll_voter_token")?.value; 22 if (!token_id) return null; 23 let result = await db.transaction(async (tx) => { 24 let [token] = await tx 25 .select() 26 .from(email_auth_tokens) 27 .where( 28 and( 29 eq(email_auth_tokens.id, token_id), 30 eq(email_auth_tokens.confirmed, true), 31 ), 32 ); 33 if (!token || !token.email) return null; 34 if (token.identity) { 35 let id = token.identity; 36 if (localLeaflets.length > 0) 37 await tx 38 .insert(permission_token_on_homepage) 39 .values( 40 localLeaflets.map((l) => ({ 41 identity: id, 42 token: l.token.id, 43 })), 44 ) 45 .onConflictDoNothing(); 46 return token; 47 } 48 let [existingIdentity] = await tx 49 .select() 50 .from(identities) 51 .where(eq(identities.email, token.email)); 52 53 let identity = existingIdentity; 54 if (!existingIdentity) { 55 let identityCookie = (await cookies()).get("identity"); 56 if (identityCookie) { 57 let [existingIdentityFromCookie] = await tx 58 .select() 59 .from(identities) 60 .where( 61 and( 62 eq(identities.id, identityCookie.value), 63 isNull(identities.email), 64 ), 65 ); 66 if (existingIdentityFromCookie) { 67 await tx 68 .update(identities) 69 .set({ email: token.email }) 70 .where(eq(identities.id, existingIdentityFromCookie.id)); 71 identity = existingIdentityFromCookie; 72 } 73 } else { 74 const { data: newIdentity } = await supabaseServerClient 75 .from("identities") 76 .insert({ email: token.email }) 77 .select() 78 .single(); 79 identity = newIdentity!; 80 } 81 } 82 83 await tx 84 .update(email_auth_tokens) 85 .set({ identity: identity.id }) 86 .where(eq(email_auth_tokens.id, token_id)); 87 88 if (localLeaflets.length > 0) 89 await tx 90 .insert(permission_token_on_homepage) 91 .values( 92 localLeaflets.map((l) => ({ 93 identity: identity.id, 94 token: l.token.id, 95 })), 96 ) 97 .onConflictDoNothing(); 98 99 return token; 100 }); 101 if (result?.identity) { 102 if (result.identity !== voter_token) { 103 if (voter_token) 104 await db 105 .update(poll_votes_on_entity) 106 .set({ voter_token: result.identity }) 107 .where(eq(poll_votes_on_entity.voter_token, voter_token)); 108 109 (await cookies()).set("poll_voter_token", result.identity, { 110 maxAge: 60 * 60 * 24 * 365, 111 secure: process.env.NODE_ENV === "production", 112 httpOnly: true, 113 sameSite: "lax", 114 }); 115 } 116 } 117 client.release(); 118}