diff --git a/prisma/seed-test-user.ts b/prisma/seed-test-user.ts new file mode 100644 index 0000000..a88fdd9 --- /dev/null +++ b/prisma/seed-test-user.ts @@ -0,0 +1,151 @@ +/** + * Seed script to create a test user for development + */ + +import { PrismaClient } from '@prisma/client'; +import * as bcrypt from 'bcryptjs'; + +const prisma = new PrismaClient(); + +async function main() { + console.log('🌱 Seeding test user...'); + + // Create user types if they don't exist + const adminType = await prisma.auth_user_type.upsert({ + where: { name: 'Admin' }, + update: {}, + create: { + name: 'Admin', + description: 'Administrator with full access', + is_admin: true, + is_customer: false, + is_internal: true, + }, + }); + + const customerType = await prisma.auth_user_type.upsert({ + where: { name: 'Customer' }, + update: {}, + create: { + name: 'Customer', + description: 'Customer portal user', + is_admin: false, + is_customer: true, + is_internal: false, + }, + }); + + // Create test company + const testCompany = await prisma.quest_company.upsert({ + where: { epicor_cust_id: 'TEST' }, + update: {}, + create: { + epicor_cust_id: 'TEST', + display_name: 'Test Company', + can_access_invoices: true, + invoicing_email: 'test@example.com', + order_ack_email: 'test@example.com', + receives_so_emails: true, + is_active: true, + }, + }); + + // Create admin user + const adminPassword = await bcrypt.hash('admin123', 10); + const adminUser = await prisma.auth_user.upsert({ + where: { email: 'admin@vorteq.com' }, + update: {}, + create: { + email: 'admin@vorteq.com', + password_hash: adminPassword, + email_verified: true, + name: 'Admin User', + auth_user_type_id: adminType.id, + deactivated: false, + }, + }); + + // Create quest_user for admin + const adminQuestUser = await prisma.quest_user.upsert({ + where: { auth_user_id: adminUser.id }, + update: {}, + create: { + auth_user_id: adminUser.id, + is_sub_user: false, + }, + }); + + // Link admin to test company + await prisma.quest_user_company.upsert({ + where: { + quest_user_id_quest_company_id: { + quest_user_id: adminQuestUser.id, + quest_company_id: testCompany.id, + }, + }, + update: {}, + create: { + quest_user_id: adminQuestUser.id, + quest_company_id: testCompany.id, + is_active_company: true, + }, + }); + + // Create regular customer user + const customerPassword = await bcrypt.hash('customer123', 10); + const customerUser = await prisma.auth_user.upsert({ + where: { email: 'customer@vorteq.com' }, + update: {}, + create: { + email: 'customer@vorteq.com', + password_hash: customerPassword, + email_verified: true, + name: 'Customer User', + auth_user_type_id: customerType.id, + deactivated: false, + }, + }); + + // Create quest_user for customer + const customerQuestUser = await prisma.quest_user.upsert({ + where: { auth_user_id: customerUser.id }, + update: {}, + create: { + auth_user_id: customerUser.id, + is_sub_user: false, + }, + }); + + // Link customer to test company + await prisma.quest_user_company.upsert({ + where: { + quest_user_id_quest_company_id: { + quest_user_id: customerQuestUser.id, + quest_company_id: testCompany.id, + }, + }, + update: {}, + create: { + quest_user_id: customerQuestUser.id, + quest_company_id: testCompany.id, + is_active_company: true, + }, + }); + + console.log('āœ… Test users created successfully!'); + console.log('\nšŸ“§ Admin Login:'); + console.log(' Email: admin@vorteq.com'); + console.log(' Password: admin123'); + console.log('\nšŸ“§ Customer Login:'); + console.log(' Email: customer@vorteq.com'); + console.log(' Password: customer123'); +} + +main() + .catch((e) => { + console.error(e); + process.exit(1); + }) + .finally(async () => { + await prisma.$disconnect(); + }); diff --git a/src/app/(portal)/dashboard/page.tsx b/src/app/(portal)/dashboard/page.tsx index 04c3274..a03acb7 100644 --- a/src/app/(portal)/dashboard/page.tsx +++ b/src/app/(portal)/dashboard/page.tsx @@ -1,4 +1,6 @@ import { Suspense } from 'react'; + +export const dynamic = 'force-dynamic'; import { Package, ShoppingCart, diff --git a/src/app/(portal)/inventory/page.tsx b/src/app/(portal)/inventory/page.tsx index 3cba77b..0a1bcf0 100644 --- a/src/app/(portal)/inventory/page.tsx +++ b/src/app/(portal)/inventory/page.tsx @@ -1,3 +1,5 @@ +export const dynamic = 'force-dynamic'; + import { Package, Cog, diff --git a/src/app/(portal)/inventory/wip/page.tsx b/src/app/(portal)/inventory/wip/page.tsx index 3d92f98..c9755de 100644 --- a/src/app/(portal)/inventory/wip/page.tsx +++ b/src/app/(portal)/inventory/wip/page.tsx @@ -1,4 +1,6 @@ import { Suspense } from 'react'; + +export const dynamic = 'force-dynamic'; import { getWorkInProgressSummary } from '@/services/inventory'; import { getQuestSession, getActiveCompany, isSubUser } from '@/lib/permissions'; import { redirect } from 'next/navigation'; diff --git a/src/app/(portal)/select-company/page.tsx b/src/app/(portal)/select-company/page.tsx index 8fa20ed..c0f9825 100644 --- a/src/app/(portal)/select-company/page.tsx +++ b/src/app/(portal)/select-company/page.tsx @@ -2,6 +2,8 @@ import { redirect } from 'next/navigation'; import { getQuestSession, getUserCompanies } from '@/lib/permissions'; import { CompanySelector } from '@/components/company-selector'; +export const dynamic = 'force-dynamic'; + export default async function SelectCompanyPage() { const session = await getQuestSession(); diff --git a/src/middleware.ts b/src/middleware.ts index 1d66be5..50e0797 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,14 +1,4 @@ import { NextResponse, type NextRequest } from 'next/server'; -import { betterAuth } from 'better-auth'; - -const auth = betterAuth({ - secret: process.env.BETTER_AUTH_SECRET!, - baseURL: process.env.BETTER_AUTH_URL!, - database: { - provider: 'postgresql', - url: process.env.DATABASE_URL!, - }, -}); /** * Rate limiting configuration @@ -111,26 +101,19 @@ export async function middleware(request: NextRequest) { } // Check authentication for protected routes - try { - const session = await auth.api.getSession({ - headers: request.headers, - }); + // Better Auth sets a session cookie - check for its presence + const sessionCookie = request.cookies.get('better-auth.session_token'); - if (!session) { - // Redirect to login if not authenticated - const loginUrl = new URL('/login', request.url); - loginUrl.searchParams.set('callbackUrl', pathname); - return NextResponse.redirect(loginUrl); - } - - // User is authenticated, continue to the route - return NextResponse.next(); - } catch (error) { - console.error('Middleware authentication error:', error); + if (!sessionCookie) { + // Redirect to login if not authenticated const loginUrl = new URL('/login', request.url); loginUrl.searchParams.set('callbackUrl', pathname); return NextResponse.redirect(loginUrl); } + + // User appears to be authenticated, continue to the route + // Actual session validation happens in server components + return NextResponse.next(); } /**