trade-backend/src/controllers/auth.controller.ts
2026-02-19 13:14:03 +03:00

107 lines
2.8 KiB
TypeScript

import jwt from 'jsonwebtoken';
import dotenv from 'dotenv';
import { Request, Response } from 'express';
import crypto from 'crypto';
import AuthData from '@/interfaces/bodies/user/AuthData.js';
import RequestAuthBody from '@/interfaces/bodies/auth/RequestAuthBody.js';
import authMessagesModel from '@/models/AuthMessages.js';
import { AUTH_MESSAGE_EXPIRATION_TIME_MS } from 'shared/constants.js';
import RequestAuthRes from '@/interfaces/responses/auth/RequestAuthRes.js';
import sequelize from '@/sequelize.js';
import validateWallet from '../methods/validateWallet.js';
import userModel from '../models/User.js';
dotenv.config();
class AuthController {
requestAuth = async (req: Request, res: Response<RequestAuthRes>) => {
const { address, alias } = req.body as RequestAuthBody;
const message = crypto.randomUUID();
const expiresAt = new Date(Date.now() + AUTH_MESSAGE_EXPIRATION_TIME_MS);
const authMessageRow = await authMessagesModel.create({
address,
alias,
message,
expiresAt,
});
return res.status(200).send({
success: true,
data: authMessageRow.message,
});
};
async auth(req: Request, res: Response) {
try {
const userData: AuthData = req.body.data;
const { neverExpires } = req.body;
const { address, alias, signature, message } = userData;
if (!address || !alias || !signature || !message) {
return res.status(400).send({ success: false, data: 'Invalid auth data' });
}
const authMessageRow = await authMessagesModel.findOne({
address,
alias,
message,
});
const isAuthMessageValid =
!!authMessageRow && authMessageRow.expires_at.getTime() > Date.now();
if (!isAuthMessageValid) {
return res.status(400).send({ success: false, data: 'Invalid auth message' });
}
const dataValid = !!(
userData &&
userData.address &&
alias &&
(await validateWallet(userData))
);
if (!dataValid) {
return res.status(400).send({ success: false, data: 'Invalid auth data' });
}
let token: string | undefined;
await sequelize.transaction(async (transaction) => {
const success = await userModel.add(userData, { transaction });
if (success) {
await authMessagesModel.deleteOne(
{
address,
alias,
message,
},
{ transaction },
);
token = jwt.sign(
{ ...userData },
process.env.JWT_SECRET || '',
neverExpires ? undefined : { expiresIn: '24h' },
);
}
});
if (token !== undefined) {
res.status(200).send({ success: true, data: token });
} else {
res.status(500).send({ success: false, data: 'Internal error' });
}
} catch (err) {
console.log(err);
res.status(500).send({ success: false, data: 'Unhandled error' });
}
}
}
const authController = new AuthController();
export default authController;