Browse Source

refactor(nocodb): remove getAjvValidatorMw and move signup to svc

pull/5262/head
Wing-Kam Wong 2 years ago
parent
commit
5e66e99a27
  1. 236
      packages/nocodb/src/lib/controllers/user/user.ctl.ts

236
packages/nocodb/src/lib/controllers/user/user.ctl.ts

@ -1,139 +1,23 @@
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import { TableType, validatePassword } from 'nocodb-sdk';
import { T } from 'nc-help';
const { isEmail } = require('validator');
import * as ejs from 'ejs'; import * as ejs from 'ejs';
import bcrypt from 'bcryptjs';
import { promisify } from 'util'; import { promisify } from 'util';
const { v4: uuidv4 } = require('uuid');
import passport from 'passport'; import passport from 'passport';
import { getAjvValidatorMw } from '../../meta/api/helpers';
import catchError, { NcError } from '../../meta/helpers/catchError'; import catchError, { NcError } from '../../meta/helpers/catchError';
import extractProjectIdAndAuthenticate from '../../meta/helpers/extractProjectIdAndAuthenticate'; import extractProjectIdAndAuthenticate from '../../meta/helpers/extractProjectIdAndAuthenticate';
import ncMetaAclMw from '../../meta/helpers/ncMetaAclMw'; import ncMetaAclMw from '../../meta/helpers/ncMetaAclMw';
import NcPluginMgrv2 from '../../meta/helpers/NcPluginMgrv2';
import { Audit, User } from '../../models'; import { Audit, User } from '../../models';
import Noco from '../../Noco'; import Noco from '../../Noco';
import { userService } from '../../services'; import { userService } from '../../services';
export async function signup(req: Request, res: Response<TableType>) { export async function signup(req: Request<any, any>, res): Promise<any> {
const { res.json(
email: _email, await userService.signup({
firstname, body: req.body,
lastname, req,
token, res,
ignore_subscribe, })
} = req.body; );
let { password } = req.body;
// validate password and throw error if password is satisfying the conditions
const { valid, error } = validatePassword(password);
if (!valid) {
NcError.badRequest(`Password : ${error}`);
}
if (!isEmail(_email)) {
NcError.badRequest(`Invalid email`);
}
const email = _email.toLowerCase();
let user = await User.getByEmail(email);
if (user) {
if (token) {
if (token !== user.invite_token) {
NcError.badRequest(`Invalid invite url`);
} else if (user.invite_token_expires < new Date()) {
NcError.badRequest(
'Expired invite url, Please contact super admin to get a new invite url'
);
}
} else {
// todo : opening up signup for timebeing
// return next(new Error(`Email '${email}' already registered`));
}
}
const salt = await promisify(bcrypt.genSalt)(10);
password = await promisify(bcrypt.hash)(password, salt);
const email_verification_token = uuidv4();
if (!ignore_subscribe) {
T.emit('evt_subscribe', email);
}
if (user) {
if (token) {
await User.update(user.id, {
firstname,
lastname,
salt,
password,
email_verification_token,
invite_token: null,
invite_token_expires: null,
email: user.email,
});
} else {
NcError.badRequest('User already exist');
}
} else {
await userService.registerNewUserIfAllowed({
firstname,
lastname,
email,
salt,
password,
email_verification_token,
});
}
user = await User.getByEmail(email);
try {
const template = (await import('./ui/emailTemplates/verify')).default;
await (
await NcPluginMgrv2.emailAdapter()
).mailSend({
to: email,
subject: 'Verify email',
html: ejs.render(template, {
verifyLink:
(req as any).ncSiteUrl +
`/email/verify/${user.email_verification_token}`,
}),
});
} catch (e) {
console.log(
'Warning : `mailSend` failed, Please configure emailClient configuration.'
);
}
await promisify((req as any).login.bind(req))(user);
const refreshToken = userService.randomTokenString();
await User.update(user.id, {
refresh_token: refreshToken,
email: user.email,
});
setTokenCookie(res, refreshToken);
user = (req as any).user;
await Audit.insert({
op_type: 'AUTHENTICATION',
op_sub_type: 'SIGNUP',
user: user.email,
description: `signed up `,
ip: (req as any).clientIp,
});
res.json({
token: userService.genJwt(user, Noco.getConfig()),
} as any);
} }
async function successfulSignIn({ async function successfulSignIn({
@ -221,15 +105,6 @@ async function googleSignin(req, res, next) {
)(req, res, next); )(req, res, next);
} }
function setTokenCookie(res: Response, token): void {
// create http only cookie with refresh token that expires in 7 days
const cookieOptions = {
httpOnly: true,
expires: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
};
res.cookie('refresh_token', token, cookieOptions);
}
async function me(req, res): Promise<any> { async function me(req, res): Promise<any> {
res.json(req?.session?.passport?.user ?? {}); res.json(req?.session?.passport?.user ?? {});
} }
@ -284,35 +159,6 @@ async function emailVerification(req, res): Promise<any> {
res.json({ msg: 'Email verified successfully' }); res.json({ msg: 'Email verified successfully' });
} }
async function refreshToken(req, res): Promise<any> {
try {
if (!req?.cookies?.refresh_token) {
return res.status(400).json({ msg: 'Missing refresh token' });
}
const user = await User.getByRefreshToken(req.cookies.refresh_token);
if (!user) {
return res.status(400).json({ msg: 'Invalid refresh token' });
}
const refreshToken = userService.randomTokenString();
await User.update(user.id, {
email: user.email,
refresh_token: refreshToken,
});
setTokenCookie(res, refreshToken);
res.json({
token: userService.genJwt(user, Noco.getConfig()),
} as any);
} catch (e) {
return res.status(400).json({ msg: e.message });
}
}
async function renderPasswordReset(req, res): Promise<any> { async function renderPasswordReset(req, res): Promise<any> {
try { try {
res.send( res.send(
@ -329,32 +175,15 @@ async function renderPasswordReset(req, res): Promise<any> {
const mapRoutes = (router) => { const mapRoutes = (router) => {
// todo: old api - /auth/signup?tool=1 // todo: old api - /auth/signup?tool=1
router.post( router.post('/auth/user/signup', catchError(signup));
'/auth/user/signup', router.post('/auth/user/signin', catchError(signin));
getAjvValidatorMw('swagger.json#/components/schemas/SignUpReq'),
catchError(signup)
);
router.post(
'/auth/user/signin',
getAjvValidatorMw('swagger.json#/components/schemas/SignInReq'),
catchError(signin)
);
router.get('/auth/user/me', extractProjectIdAndAuthenticate, catchError(me)); router.get('/auth/user/me', extractProjectIdAndAuthenticate, catchError(me));
router.post( router.post('/auth/password/forgot', catchError(passwordForgot));
'/auth/password/forgot',
getAjvValidatorMw('swagger.json#/components/schemas/ForgotPasswordReq'),
catchError(passwordForgot)
);
router.post('/auth/token/validate/:tokenId', catchError(tokenValidate)); router.post('/auth/token/validate/:tokenId', catchError(tokenValidate));
router.post( router.post('/auth/password/reset/:tokenId', catchError(passwordReset));
'/auth/password/reset/:tokenId',
getAjvValidatorMw('swagger.json#/components/schemas/PasswordResetReq'),
catchError(passwordReset)
);
router.post('/auth/email/validate/:tokenId', catchError(emailVerification)); router.post('/auth/email/validate/:tokenId', catchError(emailVerification));
router.post( router.post(
'/user/password/change', '/user/password/change',
getAjvValidatorMw('swagger.json#/components/schemas/PasswordChangeReq'),
ncMetaAclMw(passwordChange, 'passwordChange') ncMetaAclMw(passwordChange, 'passwordChange')
); );
router.post('/auth/token/refresh', catchError(refreshToken)); router.post('/auth/token/refresh', catchError(refreshToken));
@ -372,33 +201,20 @@ const mapRoutes = (router) => {
); );
// deprecated APIs // deprecated APIs
router.post( router.post('/api/v1/db/auth/user/signup', catchError(signup));
'/api/v1/db/auth/user/signup', router.post('/api/v1/db/auth/user/signin', catchError(signin));
getAjvValidatorMw('swagger.json#/components/schemas/SignUpReq'),
catchError(signup)
);
router.post(
'/api/v1/db/auth/user/signin',
getAjvValidatorMw('swagger.json#/components/schemas/SignInReq'),
catchError(signin)
);
router.get( router.get(
'/api/v1/db/auth/user/me', '/api/v1/db/auth/user/me',
extractProjectIdAndAuthenticate, extractProjectIdAndAuthenticate,
catchError(me) catchError(me)
); );
router.post( router.post('/api/v1/db/auth/password/forgot', catchError(passwordForgot));
'/api/v1/db/auth/password/forgot',
getAjvValidatorMw('swagger.json#/components/schemas/ForgotPasswordReq'),
catchError(passwordForgot)
);
router.post( router.post(
'/api/v1/db/auth/token/validate/:tokenId', '/api/v1/db/auth/token/validate/:tokenId',
catchError(tokenValidate) catchError(tokenValidate)
); );
router.post( router.post(
'/api/v1/db/auth/password/reset/:tokenId', '/api/v1/db/auth/password/reset/:tokenId',
getAjvValidatorMw('swagger.json#/components/schemas/PasswordResetReq'),
catchError(passwordReset) catchError(passwordReset)
); );
router.post( router.post(
@ -407,7 +223,6 @@ const mapRoutes = (router) => {
); );
router.post( router.post(
'/api/v1/db/auth/password/change', '/api/v1/db/auth/password/change',
getAjvValidatorMw('swagger.json#/components/schemas/PasswordChangeReq'),
ncMetaAclMw(passwordChange, 'passwordChange') ncMetaAclMw(passwordChange, 'passwordChange')
); );
router.post('/api/v1/db/auth/token/refresh', catchError(refreshToken)); router.post('/api/v1/db/auth/token/refresh', catchError(refreshToken));
@ -417,26 +232,14 @@ const mapRoutes = (router) => {
); );
// new API // new API
router.post( router.post('/api/v1/auth/user/signup', catchError(signup));
'/api/v1/auth/user/signup', router.post('/api/v1/auth/user/signin', catchError(signin));
getAjvValidatorMw('swagger.json#/components/schemas/SignUpReq'),
catchError(signup)
);
router.post(
'/api/v1/auth/user/signin',
getAjvValidatorMw('swagger.json#/components/schemas/SignInReq'),
catchError(signin)
);
router.get( router.get(
'/api/v1/auth/user/me', '/api/v1/auth/user/me',
extractProjectIdAndAuthenticate, extractProjectIdAndAuthenticate,
catchError(me) catchError(me)
); );
router.post( router.post('/api/v1/auth/password/forgot', catchError(passwordForgot));
'/api/v1/auth/password/forgot',
getAjvValidatorMw('swagger.json#/components/schemas/ForgotPasswordReq'),
catchError(passwordForgot)
);
router.post( router.post(
'/api/v1/auth/token/validate/:tokenId', '/api/v1/auth/token/validate/:tokenId',
catchError(tokenValidate) catchError(tokenValidate)
@ -451,11 +254,10 @@ const mapRoutes = (router) => {
); );
router.post( router.post(
'/api/v1/auth/password/change', '/api/v1/auth/password/change',
getAjvValidatorMw('swagger.json#/components/schemas/PasswordChangeReq'),
ncMetaAclMw(passwordChange, 'passwordChange') ncMetaAclMw(passwordChange, 'passwordChange')
); );
router.post('/api/v1/auth/token/refresh', catchError(refreshToken)); router.post('/api/v1/auth/token/refresh', catchError(refreshToken));
// respond with password reset page // respond with password reset page
router.get('/auth/password/reset/:tokenId', catchError(renderPasswordReset)); router.get('/auth/password/reset/:tokenId', catchError(renderPasswordReset));
}; };
export { mapRoutes as userController }; export default mapRoutes;

Loading…
Cancel
Save