|
|
import { Request, Response } from 'express'; |
|
|
import bcrypt from 'bcryptjs'; |
|
|
import jwt from 'jsonwebtoken'; |
|
|
import { AppDataSource } from '../config/database'; |
|
|
import { User } from '../entities/User'; |
|
|
import { CreatorProfile } from '../entities/CreatorProfile'; |
|
|
|
|
|
const userRepository = AppDataSource.getRepository(User); |
|
|
const profileRepository = AppDataSource.getRepository(CreatorProfile); |
|
|
|
|
|
export class CreatorAuthController { |
|
|
async register(req: Request, res: Response) { |
|
|
try { |
|
|
const { |
|
|
fullName, |
|
|
username, |
|
|
email, |
|
|
password, |
|
|
profileImage, |
|
|
bio, |
|
|
organization, |
|
|
role, |
|
|
website, |
|
|
linkedinUrl, |
|
|
githubUrl, |
|
|
huggingfaceUrl, |
|
|
primaryLanguages, |
|
|
frameworks, |
|
|
agentSpecialties, |
|
|
preferredCompute, |
|
|
endpointHosting, |
|
|
walletAddress, |
|
|
bankAccount, |
|
|
preferredCurrency, |
|
|
country, |
|
|
taxId, |
|
|
idDocumentUrl, |
|
|
} = req.body; |
|
|
|
|
|
if (!fullName || !username || !email || !password) { |
|
|
return res.status(400).json({ error: 'fullName, username, email and password are required' }); |
|
|
} |
|
|
|
|
|
|
|
|
const cleanUsername = String(username).replace(/^@+/, '').toLowerCase(); |
|
|
|
|
|
|
|
|
const existingUser = await userRepository.findOne({ where: { email } }); |
|
|
if (existingUser) return res.status(400).json({ error: 'Email already in use' }); |
|
|
const existingProfile = await profileRepository.findOne({ where: { username: cleanUsername } }); |
|
|
if (existingProfile) return res.status(400).json({ error: 'Username already in use' }); |
|
|
|
|
|
const hashedPassword = await bcrypt.hash(password, 10); |
|
|
|
|
|
|
|
|
const user = userRepository.create({ email, password: hashedPassword, name: fullName, isCreator: true, isAdmin: false }); |
|
|
const savedUser = await userRepository.save(user); |
|
|
|
|
|
|
|
|
const normArray = (v: any) => { |
|
|
if (!v) return [] as string[]; |
|
|
if (Array.isArray(v)) return v; |
|
|
try { return JSON.parse(v); } catch { return [String(v)]; } |
|
|
}; |
|
|
|
|
|
|
|
|
const profile = profileRepository.create({ |
|
|
userId: savedUser.id, |
|
|
fullName, |
|
|
username: cleanUsername, |
|
|
profileImage, |
|
|
bio, |
|
|
organization, |
|
|
role, |
|
|
website, |
|
|
linkedinUrl, |
|
|
githubUrl, |
|
|
huggingfaceUrl, |
|
|
primaryLanguages: normArray(primaryLanguages), |
|
|
frameworks: normArray(frameworks), |
|
|
agentSpecialties: normArray(agentSpecialties), |
|
|
preferredCompute, |
|
|
endpointHosting, |
|
|
walletAddress, |
|
|
bankAccount: bankAccount ? (typeof bankAccount === 'string' ? JSON.parse(bankAccount) : bankAccount) : undefined, |
|
|
preferredCurrency, |
|
|
country, |
|
|
taxId, |
|
|
idDocumentUrl, |
|
|
}); |
|
|
await profileRepository.save(profile); |
|
|
|
|
|
|
|
|
const token = jwt.sign( |
|
|
{ id: savedUser.id, email: savedUser.email, isAdmin: savedUser.isAdmin }, |
|
|
process.env.JWT_SECRET!, |
|
|
{ expiresIn: '7d' } |
|
|
); |
|
|
|
|
|
res.status(201).json({ token, user: { id: savedUser.id, email: savedUser.email, name: savedUser.name, isCreator: true } }); |
|
|
} catch (error: any) { |
|
|
console.error('Creator register error:', error); |
|
|
res.status(500).json({ error: error.message || 'Failed to register creator' }); |
|
|
} |
|
|
} |
|
|
|
|
|
async login(req: Request, res: Response) { |
|
|
try { |
|
|
const { email, password } = req.body; |
|
|
if (!email || !password) return res.status(400).json({ error: 'Email and password are required' }); |
|
|
|
|
|
const user = await userRepository.findOne({ where: { email } }); |
|
|
if (!user || !user.isCreator) return res.status(401).json({ error: 'Invalid credentials' }); |
|
|
|
|
|
const isValid = await bcrypt.compare(password, user.password); |
|
|
if (!isValid) return res.status(401).json({ error: 'Invalid credentials' }); |
|
|
|
|
|
const token = jwt.sign( |
|
|
{ id: user.id, email: user.email, isAdmin: user.isAdmin }, |
|
|
process.env.JWT_SECRET!, |
|
|
{ expiresIn: '7d' } |
|
|
); |
|
|
|
|
|
|
|
|
const profile = await profileRepository.findOne({ where: { userId: user.id } }); |
|
|
|
|
|
res.json({ |
|
|
token, |
|
|
user: { |
|
|
id: user.id, |
|
|
email: user.email, |
|
|
name: user.name, |
|
|
isCreator: user.isCreator, |
|
|
profile: profile ? { username: profile.username, fullName: profile.fullName } : null, |
|
|
}, |
|
|
}); |
|
|
} catch (error: any) { |
|
|
console.error('Creator login error:', error); |
|
|
res.status(500).json({ error: error.message || 'Failed to login creator' }); |
|
|
} |
|
|
} |
|
|
} |
|
|
|