zurri / src /controllers /creatorAuthController.ts
nexusbert's picture
add features
2fe81ea
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' });
}
// Username stored without leading @
const cleanUsername = String(username).replace(/^@+/, '').toLowerCase();
// Uniqueness checks
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);
// Create user
const user = userRepository.create({ email, password: hashedPassword, name: fullName, isCreator: true, isAdmin: false });
const savedUser = await userRepository.save(user);
// Normalize arrays
const normArray = (v: any) => {
if (!v) return [] as string[];
if (Array.isArray(v)) return v;
try { return JSON.parse(v); } catch { return [String(v)]; }
};
// Create profile
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);
// Token
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' }
);
// Fetch profile brief
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' });
}
}
}