Core Features: - Complete Prisma database schema with all entities (users, orgs, projects, checks, etc.) - Production-grade authentication service with Argon2 password hashing - JWT-based session management with HttpOnly cookies - Comprehensive auth middleware with role-based access control - RESTful auth API endpoints: register, login, logout, me, refresh - Database seeding with demo data for development - Rate limiting on auth endpoints (5 attempts/15min) Technical Implementation: - Type-safe authentication with Zod validation - Proper error handling and logging throughout - Secure password hashing with Argon2id - JWT tokens with 7-day expiration - Database transactions for atomic operations - Comprehensive middleware for optional/required auth - Role hierarchy system (MEMBER < ADMIN < OWNER) Database Schema: - Users with secure password storage - Organizations with membership management - Projects for organizing redirect checks - Complete audit logging system - API key management for programmatic access - Bulk job tracking for future phases Backward Compatibility: - All existing endpoints preserved and functional - No breaking changes to legacy API responses - New auth system runs alongside existing functionality Ready for Phase 2: Enhanced redirect tracking with database persistence
119 lines
2.8 KiB
TypeScript
119 lines
2.8 KiB
TypeScript
/**
|
|
* Database Seed Script for Redirect Intelligence v2
|
|
*
|
|
* This script creates initial data for development and testing
|
|
*/
|
|
|
|
import { PrismaClient, Role } from '@prisma/client';
|
|
import argon2 from 'argon2';
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
async function main() {
|
|
console.log('🌱 Starting database seed...');
|
|
|
|
// Create demo user
|
|
const demoPassword = await argon2.hash('demo123456');
|
|
|
|
const demoUser = await prisma.user.upsert({
|
|
where: { email: 'demo@redirectintelligence.com' },
|
|
update: {},
|
|
create: {
|
|
email: 'demo@redirectintelligence.com',
|
|
name: 'Demo User',
|
|
passwordHash: demoPassword,
|
|
},
|
|
});
|
|
|
|
console.log('👤 Created demo user:', demoUser.email);
|
|
|
|
// Create demo organization
|
|
const demoOrg = await prisma.organization.upsert({
|
|
where: { id: 'demo-org' },
|
|
update: {},
|
|
create: {
|
|
id: 'demo-org',
|
|
name: 'Demo Organization',
|
|
plan: 'pro',
|
|
},
|
|
});
|
|
|
|
console.log('🏢 Created demo organization:', demoOrg.name);
|
|
|
|
// Create membership
|
|
await prisma.orgMembership.upsert({
|
|
where: {
|
|
orgId_userId: {
|
|
orgId: demoOrg.id,
|
|
userId: demoUser.id,
|
|
},
|
|
},
|
|
update: {},
|
|
create: {
|
|
orgId: demoOrg.id,
|
|
userId: demoUser.id,
|
|
role: Role.OWNER,
|
|
},
|
|
});
|
|
|
|
console.log('🤝 Created organization membership');
|
|
|
|
// Create demo project
|
|
const demoProject = await prisma.project.upsert({
|
|
where: { id: 'demo-project' },
|
|
update: {},
|
|
create: {
|
|
id: 'demo-project',
|
|
name: 'Demo Project',
|
|
orgId: demoOrg.id,
|
|
settingsJson: {
|
|
description: 'Demo project for testing redirect tracking',
|
|
defaultMethod: 'GET',
|
|
enableSSLAnalysis: true,
|
|
enableSEOAnalysis: true,
|
|
},
|
|
},
|
|
});
|
|
|
|
console.log('📁 Created demo project:', demoProject.name);
|
|
|
|
// Create a default "anonymous" project for non-authenticated users
|
|
const anonymousProject = await prisma.project.upsert({
|
|
where: { id: 'anonymous-project' },
|
|
update: {},
|
|
create: {
|
|
id: 'anonymous-project',
|
|
name: 'Anonymous Checks',
|
|
orgId: demoOrg.id,
|
|
settingsJson: {
|
|
description: 'Project for anonymous redirect checks',
|
|
public: true,
|
|
},
|
|
},
|
|
});
|
|
|
|
console.log('🌐 Created anonymous project:', anonymousProject.name);
|
|
|
|
console.log('✅ Database seed completed successfully!');
|
|
console.log(`
|
|
📝 Demo Credentials:
|
|
Email: ${demoUser.email}
|
|
Password: demo123456
|
|
|
|
🔗 You can now:
|
|
1. Login with these credentials
|
|
2. Create checks in the demo project
|
|
3. Test API endpoints with authentication
|
|
`);
|
|
}
|
|
|
|
main()
|
|
.then(async () => {
|
|
await prisma.$disconnect();
|
|
})
|
|
.catch(async (e) => {
|
|
console.error('❌ Error during seed:', e);
|
|
await prisma.$disconnect();
|
|
process.exit(1);
|
|
});
|