UNPKG

eggi-ai-db-schema

Version:

Type-safe database schema and ORM client for Eggi.AI with direct RDS connection

139 lines 5.88 kB
"use strict"; /** * ============================================================================= * AUTHENTICATION OPERATIONS - LAMBDA HELPER FUNCTIONS * ============================================================================= * High-level functions specifically designed for our authentication lambdas * These functions handle the complete authentication flow logic */ Object.defineProperty(exports, "__esModule", { value: true }); exports.handleLinkedInProfileFetch = handleLinkedInProfileFetch; exports.storeSignupEmail = storeSignupEmail; exports.handlePostAuthentication = handlePostAuthentication; const drizzle_orm_1 = require("drizzle-orm"); const db_1 = require("../lib/db"); const schema_1 = require("../lib/schema"); const linkedin_data_operations_1 = require("./linkedin-data-operations"); const social_account_operations_1 = require("./social-account-operations"); const contact_operations_1 = require("./contact-operations"); /** * MAIN FUNCTION for Profile Fetch Lambda * Handles the complete idempotent profile fetch/store logic * * @param internalIdentifier - LinkedIn internal identifier (ACoA format) * @param profileData - Complete LinkedIn profile data from provider * @param providerAccountId - Optional provider account ID for linking * @returns Profile fetch result with user and social account IDs */ async function handleLinkedInProfileFetch(internalIdentifier, profileData, providerAccountId) { // Check if social account already exists const existingSocialAccount = await (0, social_account_operations_1.findSocialAccountByLinkedInIdentifier)(internalIdentifier); if (existingSocialAccount) { // Return existing user and social account return { user_id: existingSocialAccount.userId, social_account_id: existingSocialAccount.id, isNewUser: false, }; } // Create new user + social account + complete LinkedIn profile const { user, socialAccount } = await (0, linkedin_data_operations_1.createUserAndSocialAccountForLinkedIn)(internalIdentifier, // This is the ACoA identifier from the request profileData, providerAccountId); const completeProfileResult = await (0, linkedin_data_operations_1.storeCompleteLinkedInProfile)(user.id, socialAccount.id, profileData); return { user_id: user.id, social_account_id: socialAccount.id, isNewUser: true, profileData: completeProfileResult, }; } /** * Store signup email as contact info with source="signup" * This is called after profile fetch completes to ensure we capture the user's signup email * * @param userId - User ID to associate the email with * @param email - User's signup email from Cognito * @returns Promise that resolves when email is stored */ async function storeSignupEmail(userId, email) { if (!email || !email.trim()) { console.warn("⚠️ No signup email provided, skipping contact info creation"); return; } try { await (0, contact_operations_1.createContactInfo)({ userId: userId, type: "email", value: email.trim(), source: "signup", metadata: { source: "cognito_user_attributes", created_during: "post_authentication", }, }); console.log("✅ Signup email stored as contact info", { userId, email }); } catch (error) { // If it's a duplicate constraint error, that's fine - the email already exists if (error instanceof Error && error.message.includes("Contact info already exists")) { console.log("ℹ️ Signup email already exists in contact info", { userId, email }); } else { console.error("❌ Failed to store signup email as contact info", { userId, email, error: error instanceof Error ? error.message : String(error), }); // Don't throw - this is not critical enough to fail authentication } } } /** * MAIN FUNCTION for Post Authentication Lambda * Creates authenticated_user record with idempotent logic * * @param cognitoUserId - Cognito user ID from authentication event * @param userId - User ID from profile fetch result * @param signupEmail - Optional signup email to store as contact info * @returns Authentication result with all IDs */ async function handlePostAuthentication(cognitoUserId, userId, signupEmail) { const db = await (0, db_1.getDb)(); // Get the user's social account (we know they have one from profile fetch) const [socialAccount] = await db .select() .from(schema_1.socialAccounts) .where((0, drizzle_orm_1.eq)(schema_1.socialAccounts.userId, userId)) .limit(1); if (!socialAccount) { throw new Error(`No social account found for user ${userId}`); } // Create authenticated_user record (idempotent) const newAuthenticatedUsers = await db .insert(schema_1.authenticatedUsers) .values({ userId: userId, cognitoUserId: cognitoUserId, authProvider: "cognito", }) .onConflictDoUpdate({ target: [schema_1.authenticatedUsers.cognitoUserId], set: { userId: userId, // Update in case user was reassigned }, }) .returning(); const authenticatedUser = newAuthenticatedUsers[0]; // Store signup email as contact info if provided if (signupEmail) { await storeSignupEmail(userId, signupEmail); } return { user_id: userId, social_account_id: socialAccount.id, authenticated_user_id: authenticatedUser.id, cognito_user_id: cognitoUserId, }; } // Removed getUserAuthenticationStatus - not used in any consumers //# sourceMappingURL=authentication-operations.js.map