mirror of
https://github.com/mito-systems/ranger-app.git
synced 2026-05-04 04:04:17 +00:00
lol
This commit is contained in:
parent
67eb8c3d07
commit
47b9f8264f
@ -75,9 +75,46 @@ export async function POST(req: NextRequest): Promise<NextResponse> {
|
||||
);
|
||||
}
|
||||
|
||||
// Use headers for user info if available, otherwise fall back to session
|
||||
userId = session?.user?.id || headerUser?.id || req.headers.get('x-user-id') || 'unknown';
|
||||
userEmail = session?.user?.email || headerUser?.email || req.headers.get('x-user-email') || 'unknown@example.com';
|
||||
// Get user info with lots of fallbacks and detailed logging
|
||||
const sessionId = session?.user?.id;
|
||||
const sessionEmail = session?.user?.email;
|
||||
const headerId = headerUser?.id;
|
||||
const headerEmail = headerUser?.email;
|
||||
const headerXId = req.headers.get('x-user-id');
|
||||
const headerXEmail = req.headers.get('x-user-email');
|
||||
|
||||
// Log all possible sources of user data
|
||||
console.log('All user data sources:', {
|
||||
sessionId,
|
||||
sessionEmail,
|
||||
headerId,
|
||||
headerEmail,
|
||||
headerXId,
|
||||
headerXEmail,
|
||||
sessionData: session,
|
||||
headerUserData: headerUser
|
||||
});
|
||||
|
||||
// Use the first valid user ID we can find
|
||||
userId = sessionId || headerId || headerXId || 'unknown';
|
||||
|
||||
// For email, be more strict - never use unknown@example.com unless absolutely necessary
|
||||
if (sessionEmail && sessionEmail !== 'unknown@example.com') {
|
||||
userEmail = sessionEmail;
|
||||
} else if (headerEmail && headerEmail !== 'unknown@example.com') {
|
||||
userEmail = headerEmail;
|
||||
} else if (headerXEmail && headerXEmail !== 'unknown@example.com') {
|
||||
userEmail = headerXEmail;
|
||||
} else if (userId.includes('@')) {
|
||||
// If no email but userId looks like email, use that
|
||||
userEmail = userId;
|
||||
console.log('Using userId as email since it looks like one:', userId);
|
||||
} else {
|
||||
userEmail = 'unknown@example.com';
|
||||
}
|
||||
|
||||
// Log the final decision
|
||||
console.log('Final user identification:', { userId, userEmail });
|
||||
}
|
||||
|
||||
// Log authentication details
|
||||
|
||||
@ -52,14 +52,40 @@ const authOptions = {
|
||||
callbacks: {
|
||||
// JWT callback to persist data from the OAuth provider to the JWT
|
||||
async jwt({ token, user, account, profile, trigger }) {
|
||||
console.log("JWT Callback:", { tokenSub: token.sub, profile, trigger });
|
||||
console.log("JWT Callback:", {
|
||||
tokenSub: token.sub,
|
||||
tokenEmail: token.email,
|
||||
userEmail: user?.email,
|
||||
profile,
|
||||
trigger,
|
||||
hasUser: !!user,
|
||||
hasAccount: !!account
|
||||
});
|
||||
|
||||
// Initial sign-in - add data from the OAuth provider to the token
|
||||
if (account && profile) {
|
||||
console.log("Initial sign-in, storing profile data in token");
|
||||
token.userId = token.sub; // Use sub as the primary userId
|
||||
token.email = profile.email;
|
||||
} else if (user) {
|
||||
// If we have user but no profile, make sure to keep the user data
|
||||
console.log("User data available, storing in token");
|
||||
token.userId = token.sub || user.id;
|
||||
token.email = token.email || user.email;
|
||||
} else {
|
||||
// Ensure email is always available for user identification
|
||||
console.log("No profile or user, using token defaults");
|
||||
token.userId = token.sub;
|
||||
// Email might already be in the token from a previous sign-in
|
||||
}
|
||||
|
||||
// Add explicit logging of the token we're returning
|
||||
console.log("Returning token with data:", {
|
||||
sub: token.sub,
|
||||
userId: token.userId,
|
||||
email: token.email
|
||||
});
|
||||
|
||||
return token;
|
||||
},
|
||||
|
||||
@ -67,15 +93,32 @@ const authOptions = {
|
||||
async session({ session, token, user }) {
|
||||
console.log("Session Callback:", {
|
||||
sessionUserId: session?.user?.id,
|
||||
sessionEmail: session?.user?.email,
|
||||
tokenUserId: token?.userId,
|
||||
tokenSub: token?.sub
|
||||
tokenSub: token?.sub,
|
||||
tokenEmail: token?.email,
|
||||
hasUser: !!user
|
||||
});
|
||||
|
||||
// Ensure user ID is available in the session
|
||||
// Ensure user ID and email are available in the session
|
||||
if (session.user) {
|
||||
// First try to get ID from token.userId, then fall back to token.sub
|
||||
session.user.id = token.userId || token.sub;
|
||||
|
||||
// Make sure we also have email - very important for points system
|
||||
if (!session.user.email && token.email) {
|
||||
session.user.email = token.email;
|
||||
console.log("Added missing email to session from token:", token.email);
|
||||
}
|
||||
}
|
||||
|
||||
// Detailed logging of the session we're returning
|
||||
console.log("Returning session with user data:", {
|
||||
id: session?.user?.id,
|
||||
email: session?.user?.email,
|
||||
name: session?.user?.name
|
||||
});
|
||||
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,15 +58,54 @@ export async function getSessionFromCookie(req: NextRequest) {
|
||||
};
|
||||
}
|
||||
|
||||
// If we have a session cookie but no headers, we need to persist the session user ID
|
||||
// If we have a session cookie but no headers, we need to try to extract user data from jwt
|
||||
if (sessionCookie) {
|
||||
// For production, we'll just indicate authentication is present
|
||||
// The JWT session data is handled by NextAuth in the client
|
||||
console.log('Session cookie authentication is present, relying on client-side session data');
|
||||
return {
|
||||
isAuthenticated: true,
|
||||
sessionPresent: true
|
||||
};
|
||||
try {
|
||||
console.log('Session cookie authentication is present, attempting to extract user data');
|
||||
|
||||
// Try to extract the JWT payload - this is a simplified approach to get basic user data
|
||||
const jwtValue = sessionCookie.value;
|
||||
if (jwtValue) {
|
||||
// Decode the JWT - it's base64url encoded
|
||||
const parts = jwtValue.split('.');
|
||||
if (parts.length === 3) {
|
||||
const payloadBase64 = parts[1];
|
||||
// Convert from base64url to regular string
|
||||
const jsonStr = Buffer.from(payloadBase64, 'base64').toString();
|
||||
const payload = JSON.parse(jsonStr);
|
||||
|
||||
console.log('Extracted session JWT payload:', {
|
||||
sub: payload.sub,
|
||||
email: payload.email,
|
||||
userId: payload.userId
|
||||
});
|
||||
|
||||
if (payload.sub || payload.userId || payload.email) {
|
||||
return {
|
||||
isAuthenticated: true,
|
||||
sessionPresent: true,
|
||||
user: {
|
||||
id: payload.userId || payload.sub,
|
||||
email: payload.email
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback if JWT extraction doesn't yield useful info
|
||||
console.log('Could not extract useful data from cookie, returning sessionPresent only');
|
||||
return {
|
||||
isAuthenticated: true,
|
||||
sessionPresent: true
|
||||
};
|
||||
} catch (jwtError) {
|
||||
console.log('Error parsing JWT from cookie:', jwtError);
|
||||
return {
|
||||
isAuthenticated: true,
|
||||
sessionPresent: true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback - this shouldn't happen often
|
||||
|
||||
152
supabase-schema-updates.sql
Normal file
152
supabase-schema-updates.sql
Normal file
@ -0,0 +1,152 @@
|
||||
-- Additional SQL functions to improve reliability of user points system
|
||||
|
||||
-- Function to get the next transaction ID
|
||||
CREATE OR REPLACE FUNCTION get_next_transaction_id()
|
||||
RETURNS BIGINT AS $$
|
||||
BEGIN
|
||||
RETURN nextval('point_transactions_id_seq');
|
||||
END;
|
||||
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
||||
|
||||
-- Function to insert a transaction with a specific ID
|
||||
CREATE OR REPLACE FUNCTION insert_transaction_with_id(
|
||||
id_num BIGINT,
|
||||
user_id_text TEXT,
|
||||
points_num INTEGER,
|
||||
hash_text TEXT DEFAULT NULL
|
||||
)
|
||||
RETURNS BOOLEAN AS $$
|
||||
BEGIN
|
||||
INSERT INTO point_transactions (
|
||||
id,
|
||||
user_id,
|
||||
points,
|
||||
transaction_type,
|
||||
image_hash,
|
||||
created_at
|
||||
)
|
||||
VALUES (
|
||||
id_num,
|
||||
user_id_text::UUID,
|
||||
points_num,
|
||||
'image_upload',
|
||||
hash_text,
|
||||
now()
|
||||
);
|
||||
|
||||
RETURN TRUE;
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
RAISE NOTICE 'Error in insert_transaction_with_id: %', SQLERRM;
|
||||
RETURN FALSE;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
||||
|
||||
-- Minimal transaction insert function
|
||||
CREATE OR REPLACE FUNCTION insert_minimal_transaction(
|
||||
user_id_text TEXT,
|
||||
points_num INTEGER
|
||||
)
|
||||
RETURNS BOOLEAN AS $$
|
||||
BEGIN
|
||||
INSERT INTO point_transactions (
|
||||
user_id,
|
||||
points,
|
||||
transaction_type,
|
||||
created_at
|
||||
)
|
||||
VALUES (
|
||||
user_id_text::UUID,
|
||||
points_num,
|
||||
'image_upload',
|
||||
now()
|
||||
);
|
||||
|
||||
RETURN TRUE;
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
RAISE NOTICE 'Error in insert_minimal_transaction: %', SQLERRM;
|
||||
RETURN FALSE;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
||||
|
||||
-- Function to ensure a user exists, creating if needed
|
||||
CREATE OR REPLACE FUNCTION ensure_user_exists(
|
||||
user_id_text TEXT,
|
||||
email_text TEXT,
|
||||
initial_points INTEGER DEFAULT 0
|
||||
)
|
||||
RETURNS BOOLEAN AS $$
|
||||
DECLARE
|
||||
user_exists BOOLEAN;
|
||||
BEGIN
|
||||
-- Check if user exists
|
||||
SELECT EXISTS (
|
||||
SELECT 1 FROM user_points WHERE user_id = user_id_text::UUID
|
||||
) INTO user_exists;
|
||||
|
||||
-- If user doesn't exist, create them
|
||||
IF NOT user_exists THEN
|
||||
INSERT INTO user_points (
|
||||
user_id,
|
||||
email,
|
||||
total_points,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES (
|
||||
user_id_text::UUID,
|
||||
email_text,
|
||||
initial_points,
|
||||
now(),
|
||||
now()
|
||||
);
|
||||
END IF;
|
||||
|
||||
RETURN TRUE;
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
RAISE NOTICE 'Error in ensure_user_exists: %', SQLERRM;
|
||||
RETURN FALSE;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
||||
|
||||
-- Function to force set user points to a specific value
|
||||
CREATE OR REPLACE FUNCTION force_set_user_points(
|
||||
user_id_text TEXT,
|
||||
points_value INTEGER
|
||||
)
|
||||
RETURNS BOOLEAN AS $$
|
||||
BEGIN
|
||||
UPDATE user_points
|
||||
SET
|
||||
total_points = points_value,
|
||||
updated_at = now()
|
||||
WHERE user_id = user_id_text::UUID;
|
||||
|
||||
RETURN FOUND;
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
RAISE NOTICE 'Error in force_set_user_points: %', SQLERRM;
|
||||
RETURN FALSE;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
||||
|
||||
-- Function to create a user with raw SQL
|
||||
CREATE OR REPLACE FUNCTION create_user_with_raw_sql(
|
||||
user_id_text TEXT,
|
||||
email_text TEXT
|
||||
)
|
||||
RETURNS BOOLEAN AS $$
|
||||
BEGIN
|
||||
-- Directly execute the SQL insert
|
||||
EXECUTE format('
|
||||
INSERT INTO user_points (user_id, email, total_points, created_at, updated_at)
|
||||
VALUES (%L::UUID, %L, 1, now(), now())
|
||||
ON CONFLICT (user_id) DO UPDATE
|
||||
SET updated_at = now()
|
||||
RETURNING id
|
||||
', user_id_text, email_text);
|
||||
|
||||
RETURN TRUE;
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
RAISE NOTICE 'Error in create_user_with_raw_sql: %', SQLERRM;
|
||||
RETURN FALSE;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
||||
Loading…
Reference in New Issue
Block a user