import { authenticate } from '../../plugins/auth.js' import { getMitraById } from '../../services/mitra.service.js' import { completeMitraPhoneSignIn } from '../../services/auth.service.js' import { requestOtp, verifyOtp } from '../../services/otp.service.js' import { UserType } from '../../constants.js' const extractDeviceInfo = (request) => ({ user_agent: request.headers['user-agent'] || null, ip: request.ip || null, }) const sendAuthError = (reply, err) => { if (!err.statusCode) reply.request.log.error({ err }, 'Unhandled auth error') return reply.code(err.statusCode || 500).send({ success: false, error: { code: err.code || 'INTERNAL', message: err.message, ...(err.details && { details: err.details }), }, }) } export const mitraAuthRoutes = async (app) => { app.post('/otp/request', async (request, reply) => { const { phone, channel } = request.body || {} try { const result = await requestOtp({ phone, userType: UserType.MITRA, ipAddress: request.ip, channel, }) return reply.send({ success: true, data: result }) } catch (err) { return sendAuthError(reply, err) } }) app.post('/otp/verify', async (request, reply) => { const { otp_request_id, code } = request.body || {} try { const { phone, user_type } = await verifyOtp({ otpRequestId: otp_request_id, code }) if (user_type !== UserType.MITRA) { return reply.code(400).send({ success: false, error: { code: 'WRONG_FLOW', message: 'This OTP was issued for a different user type' }, }) } const { tokens, profile } = await completeMitraPhoneSignIn({ phone, deviceInfo: extractDeviceInfo(request), }) if (!profile.is_active) { return reply.code(403).send({ success: false, error: { code: 'ACCOUNT_INACTIVE', message: 'Account is inactive. Contact your administrator.' }, }) } return reply.send({ success: true, data: { ...tokens, profile } }) } catch (err) { return sendAuthError(reply, err) } }) app.get('/me', { preHandler: authenticate }, async (request, reply) => { if (request.auth.userType !== UserType.MITRA) { return reply.code(403).send({ success: false, error: { code: 'FORBIDDEN', message: 'Mitra account required' }, }) } const mitra = await getMitraById(request.auth.userId) if (!mitra) { return reply.code(404).send({ success: false, error: { code: 'NOT_FOUND', message: 'Mitra account not found' }, }) } return reply.send({ success: true, data: mitra }) }) }