97 lines
3.3 KiB
TypeScript
97 lines
3.3 KiB
TypeScript
import { Request, Response, NextFunction } from 'express';
|
|
import { AuthService } from '../services/auth.service';
|
|
import { z } from 'zod';
|
|
|
|
const loginSchema = z.object({
|
|
email: z.string().email(),
|
|
password: z.string().min(6),
|
|
});
|
|
|
|
const registerSchema = loginSchema.extend({
|
|
role: z.enum(['ADMIN', 'PARTNER_USER']).optional(),
|
|
organizationId: z.string().uuid().optional(),
|
|
});
|
|
|
|
export class AuthController {
|
|
private authService = new AuthService();
|
|
|
|
public register = async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const data = registerSchema.parse(req.body);
|
|
const user = await this.authService.register(data);
|
|
res.status(201).json({ message: 'User registered successfully', user });
|
|
} catch(err) { next(err); }
|
|
}
|
|
|
|
public invitePartner = async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const { email, organizationId } = z.object({ email: z.string().email(), organizationId: z.string().uuid().optional() }).parse(req.body);
|
|
const result = await this.authService.invitePartner(email, organizationId);
|
|
res.status(201).json({ message: 'Invite created', token: result.inviteToken });
|
|
} catch(err) { next(err); }
|
|
}
|
|
|
|
public validateInvite = async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const { token } = req.params;
|
|
const result = await this.authService.validateInvite(token);
|
|
res.status(200).json(result);
|
|
} catch(err) { next(err); }
|
|
}
|
|
|
|
public acceptInvite = async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const { token, password } = z.object({ token: z.string(), password: z.string().min(6) }).parse(req.body);
|
|
const result = await this.authService.acceptInvite(token, password);
|
|
|
|
res.cookie('refreshToken', result.refreshToken, {
|
|
httpOnly: true,
|
|
secure: process.env.NODE_ENV === 'production',
|
|
sameSite: 'strict',
|
|
maxAge: 7 * 24 * 60 * 60 * 1000 // 7 days
|
|
});
|
|
|
|
res.status(200).json({
|
|
user: result.user,
|
|
accessToken: result.accessToken,
|
|
});
|
|
} catch(err) { next(err); }
|
|
}
|
|
|
|
public login = async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const { email, password } = loginSchema.parse(req.body);
|
|
const result = await this.authService.login(email, password);
|
|
|
|
res.cookie('refreshToken', result.refreshToken, {
|
|
httpOnly: true,
|
|
secure: process.env.NODE_ENV === 'production',
|
|
sameSite: 'strict',
|
|
maxAge: 7 * 24 * 60 * 60 * 1000 // 7 days
|
|
});
|
|
|
|
res.status(200).json({
|
|
user: result.user,
|
|
accessToken: result.accessToken,
|
|
});
|
|
} catch (err) { next(err); }
|
|
};
|
|
|
|
public refresh = async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const token = req.cookies.refreshToken;
|
|
if (!token) {
|
|
return res.status(401).json({ error: 'No refresh token provided' });
|
|
}
|
|
const result = await this.authService.refresh(token);
|
|
res.status(200).json(result);
|
|
} catch (err) { next(err); }
|
|
};
|
|
public listPartners = async (req: Request, res: Response, next: NextFunction) => {
|
|
try {
|
|
const partners = await this.authService.listPartners();
|
|
res.status(200).json(partners);
|
|
} catch(err) { next(err); }
|
|
};
|
|
}
|