From 597913ccc39312d22eada71a1c1cf97791e0f3c5 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 16:09:34 +0800 Subject: [PATCH 01/29] refactor(nocodb): importApis -> import.ctl --- .../src/lib/controllers/sync/{importApis.ts => import.ctl.ts} | 0 packages/nocodb/src/lib/meta/api/index.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/nocodb/src/lib/controllers/sync/{importApis.ts => import.ctl.ts} (100%) diff --git a/packages/nocodb/src/lib/controllers/sync/importApis.ts b/packages/nocodb/src/lib/controllers/sync/import.ctl.ts similarity index 100% rename from packages/nocodb/src/lib/controllers/sync/importApis.ts rename to packages/nocodb/src/lib/controllers/sync/import.ctl.ts diff --git a/packages/nocodb/src/lib/meta/api/index.ts b/packages/nocodb/src/lib/meta/api/index.ts index 7fa6ad8c87..e20b94bcbd 100644 --- a/packages/nocodb/src/lib/meta/api/index.ts +++ b/packages/nocodb/src/lib/meta/api/index.ts @@ -52,7 +52,7 @@ import passport from 'passport'; import crypto from 'crypto'; import swaggerController from '../../controllers/apiDocs'; -import importController from '../../controllers/sync/importApis'; +import importController from '../../controllers/sync/import.ctl'; import syncSourceController from '../../controllers/sync'; import mapViewController from '../../controllers/views/mapView.ctl'; From 0ef612113c8318e2767231e22beee2907f6c9f7c Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 16:11:08 +0800 Subject: [PATCH 02/29] refactor(nocodb): userApits -> user.ctl --- .../nocodb/src/lib/controllers/user/{userApis.ts => user.ctl.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/nocodb/src/lib/controllers/user/{userApis.ts => user.ctl.ts} (100%) diff --git a/packages/nocodb/src/lib/controllers/user/userApis.ts b/packages/nocodb/src/lib/controllers/user/user.ctl.ts similarity index 100% rename from packages/nocodb/src/lib/controllers/user/userApis.ts rename to packages/nocodb/src/lib/controllers/user/user.ctl.ts From 2fe5056b99760644abe6a24345ec1f2003537907 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 16:25:35 +0800 Subject: [PATCH 03/29] refactor(nocodb): rename to sync.ctl --- .../nocodb/src/lib/controllers/sync/{index.ts => sync.ctl.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/nocodb/src/lib/controllers/sync/{index.ts => sync.ctl.ts} (100%) diff --git a/packages/nocodb/src/lib/controllers/sync/index.ts b/packages/nocodb/src/lib/controllers/sync/sync.ctl.ts similarity index 100% rename from packages/nocodb/src/lib/controllers/sync/index.ts rename to packages/nocodb/src/lib/controllers/sync/sync.ctl.ts From 3f0dcb7fd8d333e98ab29c111be3543ac2475f86 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 16:27:35 +0800 Subject: [PATCH 04/29] refactor(nocodb): sync controllers --- packages/nocodb/src/lib/controllers/sync/index.ts | 4 ++++ packages/nocodb/src/lib/meta/api/index.ts | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 packages/nocodb/src/lib/controllers/sync/index.ts diff --git a/packages/nocodb/src/lib/controllers/sync/index.ts b/packages/nocodb/src/lib/controllers/sync/index.ts new file mode 100644 index 0000000000..747bc7fec7 --- /dev/null +++ b/packages/nocodb/src/lib/controllers/sync/index.ts @@ -0,0 +1,4 @@ +import importController from './import.ctl'; +import syncSourceController from './sync.ctl'; + +export { importController, syncSourceController }; diff --git a/packages/nocodb/src/lib/meta/api/index.ts b/packages/nocodb/src/lib/meta/api/index.ts index e20b94bcbd..33996709e2 100644 --- a/packages/nocodb/src/lib/meta/api/index.ts +++ b/packages/nocodb/src/lib/meta/api/index.ts @@ -52,8 +52,7 @@ import passport from 'passport'; import crypto from 'crypto'; import swaggerController from '../../controllers/apiDocs'; -import importController from '../../controllers/sync/import.ctl'; -import syncSourceController from '../../controllers/sync'; +import { importController, syncSourceController } from '../../controllers/sync'; import mapViewController from '../../controllers/views/mapView.ctl'; const clients: { [id: string]: Socket } = {}; From f0c9086190d263fa2ee57cf190ae628410297ea7 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 16:30:27 +0800 Subject: [PATCH 05/29] fix(nocodb): add missing await --- packages/nocodb/src/lib/controllers/sync/sync.ctl.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/nocodb/src/lib/controllers/sync/sync.ctl.ts b/packages/nocodb/src/lib/controllers/sync/sync.ctl.ts index 7dbfac49b5..867bf9a73e 100644 --- a/packages/nocodb/src/lib/controllers/sync/sync.ctl.ts +++ b/packages/nocodb/src/lib/controllers/sync/sync.ctl.ts @@ -3,9 +3,8 @@ import ncMetaAclMw from '../../meta/helpers/ncMetaAclMw'; import { syncService } from '../../services'; export async function syncSourceList(req: Request, res: Response) { - // todo: pagination res.json( - syncService.syncSourceList({ + await syncService.syncSourceList({ projectId: req.params.projectId, }) ); From 232d89650f90077335ab1b88b9403f145dab1d56 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 16:30:38 +0800 Subject: [PATCH 06/29] fix(nocodb): incorrect evt_type --- packages/nocodb/src/lib/services/sync/index.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/nocodb/src/lib/services/sync/index.ts b/packages/nocodb/src/lib/services/sync/index.ts index 1c1f17b177..cc27bdd9a7 100644 --- a/packages/nocodb/src/lib/services/sync/index.ts +++ b/packages/nocodb/src/lib/services/sync/index.ts @@ -15,10 +15,9 @@ export async function syncCreate(param: { projectId: string; baseId?: string; userId: string; - // todo: define type syncPayload: Partial; }) { - T.emit('evt', { evt_type: 'webhooks:created' }); + T.emit('evt', { evt_type: 'syncSource:created' }); const project = await Project.getWithInfo(param.projectId); const sync = await SyncSource.insert({ @@ -31,7 +30,7 @@ export async function syncCreate(param: { } export async function syncDelete(param: { syncId: string }) { - T.emit('evt', { evt_type: 'webhooks:deleted' }); + T.emit('evt', { evt_type: 'syncSource:deleted' }); return await SyncSource.delete(param.syncId); } @@ -39,7 +38,7 @@ export async function syncUpdate(param: { syncId: string; syncPayload: Partial; }) { - T.emit('evt', { evt_type: 'webhooks:updated' }); + T.emit('evt', { evt_type: 'syncSource:updated' }); return await SyncSource.update(param.syncId, param.syncPayload); } From 6d382d06805d5d1f81be123a502f8157cc82e7f3 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 16:38:17 +0800 Subject: [PATCH 07/29] fix(nocodb): user/index.ts --- .../nocodb/src/lib/controllers/user/index.ts | 446 +----------------- 1 file changed, 2 insertions(+), 444 deletions(-) diff --git a/packages/nocodb/src/lib/controllers/user/index.ts b/packages/nocodb/src/lib/controllers/user/index.ts index 8843b2e5ea..01668e2940 100644 --- a/packages/nocodb/src/lib/controllers/user/index.ts +++ b/packages/nocodb/src/lib/controllers/user/index.ts @@ -1,445 +1,3 @@ -import { Request, Response } from 'express'; -import { TableType, validatePassword } from 'nocodb-sdk'; -import { T } from 'nc-help'; +import userController from './user.ctl'; -const { isEmail } = require('validator'); -import * as ejs from 'ejs'; - -import bcrypt from 'bcryptjs'; -import { promisify } from 'util'; - -const { v4: uuidv4 } = require('uuid'); - -import passport from 'passport'; -import { getAjvValidatorMw } from '../../meta/api/helpers'; -import catchError, { NcError } from '../../meta/helpers/catchError'; -import extractProjectIdAndAuthenticate from '../../meta/helpers/extractProjectIdAndAuthenticate'; -import ncMetaAclMw from '../../meta/helpers/ncMetaAclMw'; -import NcPluginMgrv2 from '../../meta/helpers/NcPluginMgrv2'; -import { Audit, User } from '../../models'; -import Noco from '../../Noco'; -import { userService } from '../../services'; - -export async function signup(req: Request, res: Response) { - const { - email: _email, - firstname, - lastname, - token, - 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({ - user, - err, - info, - req, - res, - auditDescription, -}) { - try { - if (!user || !user.email) { - if (err) { - return res.status(400).send(err); - } - if (info) { - return res.status(400).send(info); - } - return res.status(400).send({ msg: 'Your signin has failed' }); - } - - await promisify((req as any).login.bind(req))(user); - const refreshToken = userService.randomTokenString(); - - if (!user.token_version) { - user.token_version = userService.randomTokenString(); - } - - await User.update(user.id, { - refresh_token: refreshToken, - email: user.email, - token_version: user.token_version, - }); - setTokenCookie(res, refreshToken); - - await Audit.insert({ - op_type: 'AUTHENTICATION', - op_sub_type: 'SIGNIN', - user: user.email, - ip: req.clientIp, - description: auditDescription, - }); - - res.json({ - token: userService.genJwt(user, Noco.getConfig()), - } as any); - } catch (e) { - console.log(e); - throw e; - } -} - -async function signin(req, res, next) { - passport.authenticate( - 'local', - { session: false }, - async (err, user, info): Promise => - await successfulSignIn({ - user, - err, - info, - req, - res, - auditDescription: 'signed in', - }) - )(req, res, next); -} - -async function googleSignin(req, res, next) { - passport.authenticate( - 'google', - { - session: false, - callbackURL: req.ncSiteUrl + Noco.getConfig().dashboardPath, - }, - async (err, user, info): Promise => - await successfulSignIn({ - user, - err, - info, - req, - res, - auditDescription: 'signed in using Google Auth', - }) - )(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 { - res.json(req?.session?.passport?.user ?? {}); -} - -async function passwordChange(req: Request, res): Promise { - if (!(req as any).isAuthenticated()) { - NcError.forbidden('Not allowed'); - } - - await userService.passwordChange({ - user: req['user'], - req, - body: req.body, - }); - - res.json({ msg: 'Password updated successfully' }); -} - -async function passwordForgot(req: Request, res): Promise { - await userService.passwordForgot({ - siteUrl: (req as any).ncSiteUrl, - body: req.body, - req, - }); - - res.json({ msg: 'Please check your email to reset the password' }); -} - -async function tokenValidate(req, res): Promise { - await userService.tokenValidate({ - token: req.params.tokenId, - }); - res.json(true); -} - -async function passwordReset(req, res): Promise { - await userService.passwordReset({ - token: req.params.tokenId, - body: req.body, - req, - }); - - res.json({ msg: 'Password reset successful' }); -} - -async function emailVerification(req, res): Promise { - await userService.emailVerification({ - token: req.params.tokenId, - req, - }); - - res.json({ msg: 'Email verified successfully' }); -} - -async function refreshToken(req, res): Promise { - 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 { - try { - res.send( - ejs.render((await import('./ui/auth/resetPassword')).default, { - ncPublicUrl: process.env.NC_PUBLIC_URL || '', - token: JSON.stringify(req.params.tokenId), - baseUrl: `/`, - }) - ); - } catch (e) { - return res.status(400).json({ msg: e.message }); - } -} - -const mapRoutes = (router) => { - // todo: old api - /auth/signup?tool=1 - router.post( - '/auth/user/signup', - 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.post('/auth/password/forgot', catchError(passwordForgot)); - router.post('/auth/token/validate/:tokenId', catchError(tokenValidate)); - router.post( - '/auth/password/reset/:tokenId', - getAjvValidatorMw('swagger.json#/components/schemas/PasswordResetReq'), - catchError(passwordReset) - ); - router.post('/auth/email/validate/:tokenId', catchError(emailVerification)); - router.post( - '/user/password/change', - ncMetaAclMw(passwordChange, 'passwordChange') - ); - router.post('/auth/token/refresh', catchError(refreshToken)); - - /* Google auth apis */ - - router.post(`/auth/google/genTokenByCode`, catchError(googleSignin)); - - router.get('/auth/google', (req: any, res, next) => - passport.authenticate('google', { - scope: ['profile', 'email'], - state: req.query.state, - callbackURL: req.ncSiteUrl + Noco.getConfig().dashboardPath, - })(req, res, next) - ); - - // deprecated APIs - router.post( - '/api/v1/db/auth/user/signup', - 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( - '/api/v1/db/auth/user/me', - extractProjectIdAndAuthenticate, - catchError(me) - ); - router.post('/api/v1/db/auth/password/forgot', catchError(passwordForgot)); - router.post( - '/api/v1/db/auth/token/validate/:tokenId', - catchError(tokenValidate) - ); - router.post( - '/api/v1/db/auth/password/reset/:tokenId', - catchError(passwordReset) - ); - router.post( - '/api/v1/db/auth/email/validate/:tokenId', - catchError(emailVerification) - ); - router.post( - '/api/v1/db/auth/password/change', - ncMetaAclMw(passwordChange, 'passwordChange') - ); - router.post('/api/v1/db/auth/token/refresh', catchError(refreshToken)); - router.get( - '/api/v1/db/auth/password/reset/:tokenId', - catchError(renderPasswordReset) - ); - - // new API - router.post( - '/api/v1/auth/user/signup', - 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( - '/api/v1/auth/user/me', - extractProjectIdAndAuthenticate, - catchError(me) - ); - router.post('/api/v1/auth/password/forgot', catchError(passwordForgot)); - router.post( - '/api/v1/auth/token/validate/:tokenId', - catchError(tokenValidate) - ); - router.post( - '/api/v1/auth/password/reset/:tokenId', - catchError(passwordReset) - ); - router.post( - '/api/v1/auth/email/validate/:tokenId', - catchError(emailVerification) - ); - router.post( - '/api/v1/auth/password/change', - ncMetaAclMw(passwordChange, 'passwordChange') - ); - router.post('/api/v1/auth/token/refresh', catchError(refreshToken)); - // respond with password reset page - router.get('/auth/password/reset/:tokenId', catchError(renderPasswordReset)); -}; -export { mapRoutes as userController }; +export { userController }; From b537c12a4e3a0a3d61820011f9ab8811632924ea Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 17:04:19 +0800 Subject: [PATCH 08/29] refactor(nocodb): signupReqType --- packages/nocodb/src/schema/swagger.json | 44 ++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/packages/nocodb/src/schema/swagger.json b/packages/nocodb/src/schema/swagger.json index b656a26dcb..8ddb78b769 100644 --- a/packages/nocodb/src/schema/swagger.json +++ b/packages/nocodb/src/schema/swagger.json @@ -129,7 +129,11 @@ "Example 1": { "value": { "email": "user@example.com", - "password": "password123456789" + "password": "password123456789", + "firstname": "Alice", + "lastname": "Smith", + "token": null, + "ignore_subscribe": 0 } } } @@ -13352,9 +13356,15 @@ "examples": [ { "email": "user@example.com", - "password": "password123456789" + "password": "password123456789", + "firstname": "Alice", + "lastname": "Smith", + "token": null, + "ignore_subscribe": 0 } ], + "title": "Signup Request Model", + "type": "object", "properties": { "email": { "description": "Email address of the user", @@ -13367,11 +13377,35 @@ "example": "password123456789", "minLength": 8, "type": "string" + }, + "firstname": { + "$ref": "#/components/schemas/StringOrNull", + "x-stoplight": { + "id": "lblivgs8wcsm1" + } + }, + "lastname": { + "$ref": "#/components/schemas/StringOrNull", + "x-stoplight": { + "id": "d4341r35tucq3" + } + }, + "token": { + "$ref": "#/components/schemas/StringOrNull", + "x-stoplight": { + "id": "otw9jgnr9n7c4" + }, + "description": "Sign Up Token. Used for invitation." + }, + "ignore_subscribe": { + "$ref": "#/components/schemas/Bool", + "x-stoplight": { + "id": "g7ge6mc6vdsds" + }, + "description": "Ignore Subscription" } }, - "required": ["email", "password"], - "title": "Signup Request Model", - "type": "object" + "required": ["email", "password"] }, "Sort": { "description": "Model for Sort", From eb0e84cc5b6485a2a854764591a80c791d0fcedd Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 17:04:27 +0800 Subject: [PATCH 09/29] refactor(sdk): signupReqType --- packages/nocodb-sdk/src/lib/Api.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/nocodb-sdk/src/lib/Api.ts b/packages/nocodb-sdk/src/lib/Api.ts index b3ca3a64b4..936e5d42ae 100644 --- a/packages/nocodb-sdk/src/lib/Api.ts +++ b/packages/nocodb-sdk/src/lib/Api.ts @@ -1960,6 +1960,14 @@ export interface SignUpReqType { * @example password123456789 */ password: string; + /** Model for StringOrNull */ + firstname?: StringOrNullType; + /** Model for StringOrNull */ + lastname?: StringOrNullType; + /** Sign Up Token. Used for invitation. */ + token?: StringOrNullType; + /** Ignore Subscription */ + ignore_subscribe?: BoolType; } /** From 5e66e99a27533d0f5d4a60579016283ea335e2ad Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 17:05:54 +0800 Subject: [PATCH 10/29] refactor(nocodb): remove getAjvValidatorMw and move signup to svc --- .../src/lib/controllers/user/user.ctl.ts | 236 ++---------------- 1 file changed, 19 insertions(+), 217 deletions(-) diff --git a/packages/nocodb/src/lib/controllers/user/user.ctl.ts b/packages/nocodb/src/lib/controllers/user/user.ctl.ts index 70d17b40ef..07bbbbcf81 100644 --- a/packages/nocodb/src/lib/controllers/user/user.ctl.ts +++ b/packages/nocodb/src/lib/controllers/user/user.ctl.ts @@ -1,139 +1,23 @@ 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 bcrypt from 'bcryptjs'; import { promisify } from 'util'; -const { v4: uuidv4 } = require('uuid'); - import passport from 'passport'; -import { getAjvValidatorMw } from '../../meta/api/helpers'; import catchError, { NcError } from '../../meta/helpers/catchError'; import extractProjectIdAndAuthenticate from '../../meta/helpers/extractProjectIdAndAuthenticate'; import ncMetaAclMw from '../../meta/helpers/ncMetaAclMw'; -import NcPluginMgrv2 from '../../meta/helpers/NcPluginMgrv2'; import { Audit, User } from '../../models'; import Noco from '../../Noco'; import { userService } from '../../services'; -export async function signup(req: Request, res: Response) { - const { - email: _email, - firstname, - lastname, - token, - 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); +export async function signup(req: Request, res): Promise { + res.json( + await userService.signup({ + body: req.body, + req, + res, + }) + ); } async function successfulSignIn({ @@ -221,15 +105,6 @@ async function googleSignin(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 { res.json(req?.session?.passport?.user ?? {}); } @@ -284,35 +159,6 @@ async function emailVerification(req, res): Promise { res.json({ msg: 'Email verified successfully' }); } -async function refreshToken(req, res): Promise { - 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 { try { res.send( @@ -329,32 +175,15 @@ async function renderPasswordReset(req, res): Promise { const mapRoutes = (router) => { // todo: old api - /auth/signup?tool=1 - router.post( - '/auth/user/signup', - getAjvValidatorMw('swagger.json#/components/schemas/SignUpReq'), - catchError(signup) - ); - router.post( - '/auth/user/signin', - getAjvValidatorMw('swagger.json#/components/schemas/SignInReq'), - catchError(signin) - ); + router.post('/auth/user/signup', catchError(signup)); + router.post('/auth/user/signin', catchError(signin)); router.get('/auth/user/me', extractProjectIdAndAuthenticate, catchError(me)); - router.post( - '/auth/password/forgot', - getAjvValidatorMw('swagger.json#/components/schemas/ForgotPasswordReq'), - catchError(passwordForgot) - ); + router.post('/auth/password/forgot', catchError(passwordForgot)); router.post('/auth/token/validate/:tokenId', catchError(tokenValidate)); - router.post( - '/auth/password/reset/:tokenId', - getAjvValidatorMw('swagger.json#/components/schemas/PasswordResetReq'), - catchError(passwordReset) - ); + router.post('/auth/password/reset/:tokenId', catchError(passwordReset)); router.post('/auth/email/validate/:tokenId', catchError(emailVerification)); router.post( '/user/password/change', - getAjvValidatorMw('swagger.json#/components/schemas/PasswordChangeReq'), ncMetaAclMw(passwordChange, 'passwordChange') ); router.post('/auth/token/refresh', catchError(refreshToken)); @@ -372,33 +201,20 @@ const mapRoutes = (router) => { ); // deprecated APIs - router.post( - '/api/v1/db/auth/user/signup', - 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.post('/api/v1/db/auth/user/signup', catchError(signup)); + router.post('/api/v1/db/auth/user/signin', catchError(signin)); router.get( '/api/v1/db/auth/user/me', extractProjectIdAndAuthenticate, catchError(me) ); - router.post( - '/api/v1/db/auth/password/forgot', - getAjvValidatorMw('swagger.json#/components/schemas/ForgotPasswordReq'), - catchError(passwordForgot) - ); + router.post('/api/v1/db/auth/password/forgot', catchError(passwordForgot)); router.post( '/api/v1/db/auth/token/validate/:tokenId', catchError(tokenValidate) ); router.post( '/api/v1/db/auth/password/reset/:tokenId', - getAjvValidatorMw('swagger.json#/components/schemas/PasswordResetReq'), catchError(passwordReset) ); router.post( @@ -407,7 +223,6 @@ const mapRoutes = (router) => { ); router.post( '/api/v1/db/auth/password/change', - getAjvValidatorMw('swagger.json#/components/schemas/PasswordChangeReq'), ncMetaAclMw(passwordChange, 'passwordChange') ); router.post('/api/v1/db/auth/token/refresh', catchError(refreshToken)); @@ -417,26 +232,14 @@ const mapRoutes = (router) => { ); // new API - router.post( - '/api/v1/auth/user/signup', - getAjvValidatorMw('swagger.json#/components/schemas/SignUpReq'), - catchError(signup) - ); - router.post( - '/api/v1/auth/user/signin', - getAjvValidatorMw('swagger.json#/components/schemas/SignInReq'), - catchError(signin) - ); + router.post('/api/v1/auth/user/signup', catchError(signup)); + router.post('/api/v1/auth/user/signin', catchError(signin)); router.get( '/api/v1/auth/user/me', extractProjectIdAndAuthenticate, catchError(me) ); - router.post( - '/api/v1/auth/password/forgot', - getAjvValidatorMw('swagger.json#/components/schemas/ForgotPasswordReq'), - catchError(passwordForgot) - ); + router.post('/api/v1/auth/password/forgot', catchError(passwordForgot)); router.post( '/api/v1/auth/token/validate/:tokenId', catchError(tokenValidate) @@ -451,11 +254,10 @@ const mapRoutes = (router) => { ); router.post( '/api/v1/auth/password/change', - getAjvValidatorMw('swagger.json#/components/schemas/PasswordChangeReq'), ncMetaAclMw(passwordChange, 'passwordChange') ); router.post('/api/v1/auth/token/refresh', catchError(refreshToken)); // respond with password reset page router.get('/auth/password/reset/:tokenId', catchError(renderPasswordReset)); }; -export { mapRoutes as userController }; +export default mapRoutes; From 0a1344e03a9ea8b9d4cb10f897b7f1886e5b4499 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 17:18:11 +0800 Subject: [PATCH 11/29] refactor(nocodb): refreshToken --- .../src/lib/controllers/user/user.ctl.ts | 14 +- .../nocodb/src/lib/services/user/index.ts | 162 +++++++++++++++++- 2 files changed, 174 insertions(+), 2 deletions(-) diff --git a/packages/nocodb/src/lib/controllers/user/user.ctl.ts b/packages/nocodb/src/lib/controllers/user/user.ctl.ts index 07bbbbcf81..83d93f1b3e 100644 --- a/packages/nocodb/src/lib/controllers/user/user.ctl.ts +++ b/packages/nocodb/src/lib/controllers/user/user.ctl.ts @@ -1,4 +1,4 @@ -import { Request, Response } from 'express'; +import { Request } from 'express'; import * as ejs from 'ejs'; import { promisify } from 'util'; @@ -9,6 +9,7 @@ import ncMetaAclMw from '../../meta/helpers/ncMetaAclMw'; import { Audit, User } from '../../models'; import Noco from '../../Noco'; import { userService } from '../../services'; +import { setTokenCookie } from '../../services/user/helpers'; export async function signup(req: Request, res): Promise { res.json( @@ -20,6 +21,16 @@ export async function signup(req: Request, res): Promise { ); } +export async function refreshToken(req: Request, res): Promise { + res.json( + await userService.refreshToken({ + body: req.body, + req, + res, + }) + ); +} + async function successfulSignIn({ user, err, @@ -40,6 +51,7 @@ async function successfulSignIn({ } await promisify((req as any).login.bind(req))(user); + const refreshToken = userService.randomTokenString(); if (!user.token_version) { diff --git a/packages/nocodb/src/lib/services/user/index.ts b/packages/nocodb/src/lib/services/user/index.ts index d9e42bd651..ba3af75751 100644 --- a/packages/nocodb/src/lib/services/user/index.ts +++ b/packages/nocodb/src/lib/services/user/index.ts @@ -3,6 +3,7 @@ import { PasswordForgotReqType, PasswordResetReqType, UserType, + SignUpReqType, validatePassword, } from 'nocodb-sdk'; import { OrgUserRoles } from 'nocodb-sdk'; @@ -19,9 +20,10 @@ import NcPluginMgrv2 from '../../meta/helpers/NcPluginMgrv2'; import { Audit, Store, User } from '../../models'; import Noco from '../../Noco'; import { MetaTable } from '../../utils/globals'; -import { randomTokenString } from './helpers'; +import { genJwt, randomTokenString, setTokenCookie } from './helpers'; const { v4: uuidv4 } = require('uuid'); +const { isEmail } = require('validator'); export async function registerNewUserIfAllowed({ firstname, @@ -296,5 +298,163 @@ export async function emailVerification(param: { return true; } +export async function refreshToken(param: { + body: SignUpReqType; + req: any; + res: any; +}): Promise { + try { + if (!param.req?.cookies?.refresh_token) { + NcError.badRequest(`Missing refresh token`); + } + + const user = await User.getByRefreshToken(param.req.cookies.refresh_token); + + if (!user) { + NcError.badRequest(`Invalid refresh token`); + } + + const refreshToken = randomTokenString(); + + await User.update(user.id, { + email: user.email, + refresh_token: refreshToken, + }); + + setTokenCookie(param.res, refreshToken); + + return { + token: genJwt(user, Noco.getConfig()), + } as any; + } catch (e) { + NcError.badRequest(e.message); + } +} + +export async function signup(param: { + body: SignUpReqType; + req: any; + res: any; +}): Promise { + validatePayload('swagger.json#/components/schemas/SignUpReq', param.body); + + const { + email: _email, + firstname, + lastname, + token, + ignore_subscribe, + } = param.req.body; + + let { password } = param.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 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: + (param.req as any).ncSiteUrl + + `/email/verify/${user.email_verification_token}`, + }), + }); + } catch (e) { + console.log( + 'Warning : `mailSend` failed, Please configure emailClient configuration.' + ); + } + await promisify((param.req as any).login.bind(param.req))(user); + + const refreshToken = randomTokenString(); + + await User.update(user.id, { + refresh_token: refreshToken, + email: user.email, + }); + + setTokenCookie(param.res, refreshToken); + + user = (param.req as any).user; + + await Audit.insert({ + op_type: 'AUTHENTICATION', + op_sub_type: 'SIGNUP', + user: user.email, + description: `signed up `, + ip: (param.req as any).clientIp, + }); + + return { + token: genJwt(user, Noco.getConfig()), + } as any; +} + export * from './helpers'; export { default as initAdminFromEnv } from './initAdminFromEnv'; From 6ec54608f95df4debc7b58e59b1ba3c03a722eac Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 17:18:20 +0800 Subject: [PATCH 12/29] refactor(nocodb): setTokenCookie --- packages/nocodb/src/lib/services/user/helpers.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/nocodb/src/lib/services/user/helpers.ts b/packages/nocodb/src/lib/services/user/helpers.ts index 387b51170e..489f5ffa1a 100644 --- a/packages/nocodb/src/lib/services/user/helpers.ts +++ b/packages/nocodb/src/lib/services/user/helpers.ts @@ -2,6 +2,7 @@ import * as jwt from 'jsonwebtoken'; import crypto from 'crypto'; import User from '../../models/User'; import { NcConfig } from '../../../interface/config'; +import { Response } from 'express'; export function genJwt(user: User, config: NcConfig) { return jwt.sign( @@ -21,3 +22,12 @@ export function genJwt(user: User, config: NcConfig) { export function randomTokenString(): string { return crypto.randomBytes(40).toString('hex'); } + +export 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); +} From 04dd4410b30ab7d0d6aa881da6f7906b49caab8d Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 17:22:23 +0800 Subject: [PATCH 13/29] refactor(nocodb): svs -> svc --- .../{dataAliasNested.svs.ts => dataAliasNested.svc.ts} | 0 .../lib/services/ee/{orgToken.svs.ts => orgToken.svc.ts} | 0 packages/nocodb/src/lib/services/index.ts | 4 ++-- packages/nocodb/src/lib/services/public/index.ts | 6 +++--- .../public/{publicData.svs.ts => publicData.svc.ts} | 0 .../{publicDataExport.svs.ts => publicDataExport.svc.ts} | 0 .../public/{publicMeta.svs.ts => publicMeta.svc.ts} | 0 7 files changed, 5 insertions(+), 5 deletions(-) rename packages/nocodb/src/lib/services/dbData/{dataAliasNested.svs.ts => dataAliasNested.svc.ts} (100%) rename packages/nocodb/src/lib/services/ee/{orgToken.svs.ts => orgToken.svc.ts} (100%) rename packages/nocodb/src/lib/services/public/{publicData.svs.ts => publicData.svc.ts} (100%) rename packages/nocodb/src/lib/services/public/{publicDataExport.svs.ts => publicDataExport.svc.ts} (100%) rename packages/nocodb/src/lib/services/public/{publicMeta.svs.ts => publicMeta.svc.ts} (100%) diff --git a/packages/nocodb/src/lib/services/dbData/dataAliasNested.svs.ts b/packages/nocodb/src/lib/services/dbData/dataAliasNested.svc.ts similarity index 100% rename from packages/nocodb/src/lib/services/dbData/dataAliasNested.svs.ts rename to packages/nocodb/src/lib/services/dbData/dataAliasNested.svc.ts diff --git a/packages/nocodb/src/lib/services/ee/orgToken.svs.ts b/packages/nocodb/src/lib/services/ee/orgToken.svc.ts similarity index 100% rename from packages/nocodb/src/lib/services/ee/orgToken.svs.ts rename to packages/nocodb/src/lib/services/ee/orgToken.svc.ts diff --git a/packages/nocodb/src/lib/services/index.ts b/packages/nocodb/src/lib/services/index.ts index 68f2065c6d..d181c4587a 100644 --- a/packages/nocodb/src/lib/services/index.ts +++ b/packages/nocodb/src/lib/services/index.ts @@ -27,7 +27,7 @@ export * as attachmentService from './attachment.svc'; export * as hookFilterService from './hookFilter.svc'; export * as dataService from './dbData'; export * as bulkDataService from './dbData/bulkData'; -export * as dataAliasNestedService from './dbData/dataAliasNested.svs'; +export * as dataAliasNestedService from './dbData/dataAliasNested.svc'; export * as cacheService from './cache.svc'; export * as auditService from './audit.svc'; export * as swaggerService from './apiDocs'; @@ -35,4 +35,4 @@ export * as userService from './user'; export * as syncService from './sync'; export * from './public'; export * as orgTokenService from './orgToken.svc'; -export * as orgTokenServiceEE from './ee/orgToken.svs'; +export * as orgTokenServiceEE from './ee/orgToken.svc'; diff --git a/packages/nocodb/src/lib/services/public/index.ts b/packages/nocodb/src/lib/services/public/index.ts index fc7d09a1a9..ae87e4a5ad 100644 --- a/packages/nocodb/src/lib/services/public/index.ts +++ b/packages/nocodb/src/lib/services/public/index.ts @@ -1,5 +1,5 @@ -import * as publicDataService from './publicData.svs'; -import * as publicDataExportApis from './publicDataExport.svs'; -import * as publicMetaService from './publicMeta.svs'; +import * as publicDataService from './publicData.svc'; +import * as publicDataExportApis from './publicDataExport.svc'; +import * as publicMetaService from './publicMeta.svc'; export { publicDataService, publicDataExportApis, publicMetaService }; diff --git a/packages/nocodb/src/lib/services/public/publicData.svs.ts b/packages/nocodb/src/lib/services/public/publicData.svc.ts similarity index 100% rename from packages/nocodb/src/lib/services/public/publicData.svs.ts rename to packages/nocodb/src/lib/services/public/publicData.svc.ts diff --git a/packages/nocodb/src/lib/services/public/publicDataExport.svs.ts b/packages/nocodb/src/lib/services/public/publicDataExport.svc.ts similarity index 100% rename from packages/nocodb/src/lib/services/public/publicDataExport.svs.ts rename to packages/nocodb/src/lib/services/public/publicDataExport.svc.ts diff --git a/packages/nocodb/src/lib/services/public/publicMeta.svs.ts b/packages/nocodb/src/lib/services/public/publicMeta.svc.ts similarity index 100% rename from packages/nocodb/src/lib/services/public/publicMeta.svs.ts rename to packages/nocodb/src/lib/services/public/publicMeta.svc.ts From 822cad1f16801fa2280e4fa5eadcea8903a383f8 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 17:30:29 +0800 Subject: [PATCH 14/29] chore(nocodb): lint --- packages/nocodb/src/lib/services/user/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nocodb/src/lib/services/user/index.ts b/packages/nocodb/src/lib/services/user/index.ts index ba3af75751..1a2ed090f5 100644 --- a/packages/nocodb/src/lib/services/user/index.ts +++ b/packages/nocodb/src/lib/services/user/index.ts @@ -2,8 +2,8 @@ import { PasswordChangeReqType, PasswordForgotReqType, PasswordResetReqType, - UserType, SignUpReqType, + UserType, validatePassword, } from 'nocodb-sdk'; import { OrgUserRoles } from 'nocodb-sdk'; From 537c01bdb476a7f9f6b91194e1da7458086a0b37 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 17:31:33 +0800 Subject: [PATCH 15/29] fix(nocodb): unexpected lexical declaration in case block --- .../db/sql-data-mapper/lib/sql/conditionV2.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts index 5e536d7bcd..25142bf786 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts @@ -576,7 +576,7 @@ const parseConditionV2 = async ( } } break; - case 'gt': + case 'gt': { const gt_op = customWhereClause ? '<' : '>'; qb = qb.where(field, gt_op, val); if (column.uidt === UITypes.Rating) { @@ -586,8 +586,9 @@ const parseConditionV2 = async ( } } break; + } case 'ge': - case 'gte': + case 'gte': { const ge_op = customWhereClause ? '<=' : '>='; qb = qb.where(field, ge_op, val); if (column.uidt === UITypes.Rating) { @@ -597,7 +598,8 @@ const parseConditionV2 = async ( } } break; - case 'lt': + } + case 'lt': { const lt_op = customWhereClause ? '>' : '<'; qb = qb.where(field, lt_op, val); if (column.uidt === UITypes.Rating) { @@ -607,8 +609,10 @@ const parseConditionV2 = async ( } } break; + } + case 'le': - case 'lte': + case 'lte': { const le_op = customWhereClause ? '>=' : '<='; qb = qb.where(field, le_op, val); if (column.uidt === UITypes.Rating) { @@ -618,6 +622,7 @@ const parseConditionV2 = async ( } } break; + } case 'in': qb = qb.whereIn( field, @@ -720,7 +725,7 @@ const parseConditionV2 = async ( case 'nbtw': qb = qb.whereNotBetween(field, val.split(',')); break; - case 'isWithin': + case 'isWithin': { let now = dayjs(new Date()).format(dateFormat).toString(); now = column.uidt === UITypes.Date ? now.substring(0, 10) : now; switch (filter.comparison_sub_op) { @@ -737,6 +742,7 @@ const parseConditionV2 = async ( qb = qb.whereBetween(field, [now, val]); break; } + } } }; } From 7c8d74fe2d80389d80d21c009a731a87044d025d Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 17:33:18 +0800 Subject: [PATCH 16/29] refactor(nocodb): typescript-eslint/ban-types --- packages/nocodb/src/lib/meta/helpers/extractProps.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nocodb/src/lib/meta/helpers/extractProps.ts b/packages/nocodb/src/lib/meta/helpers/extractProps.ts index 7d060f0d6d..43b99e071c 100644 --- a/packages/nocodb/src/lib/meta/helpers/extractProps.ts +++ b/packages/nocodb/src/lib/meta/helpers/extractProps.ts @@ -1,6 +1,6 @@ import DOMPurify from 'isomorphic-dompurify'; -export function extractProps( +export function extractProps>( body: T, props: string[] ): Partial { @@ -11,7 +11,7 @@ export function extractProps( }, {}); } -export function extractPropsAndSanitize( +export function extractPropsAndSanitize>( body: T, props: string[] ): Partial { From 368d99bb1102ccf727b614b7ff097a2c3299bdee Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 17:52:00 +0800 Subject: [PATCH 17/29] fix(nocodb): unknown -> any --- packages/nocodb/src/lib/meta/helpers/extractProps.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nocodb/src/lib/meta/helpers/extractProps.ts b/packages/nocodb/src/lib/meta/helpers/extractProps.ts index 43b99e071c..2f3cc4c8cb 100644 --- a/packages/nocodb/src/lib/meta/helpers/extractProps.ts +++ b/packages/nocodb/src/lib/meta/helpers/extractProps.ts @@ -1,6 +1,6 @@ import DOMPurify from 'isomorphic-dompurify'; -export function extractProps>( +export function extractProps>( body: T, props: string[] ): Partial { @@ -11,7 +11,7 @@ export function extractProps>( }, {}); } -export function extractPropsAndSanitize>( +export function extractPropsAndSanitize>( body: T, props: string[] ): Partial { From e6b04d74fd4e6e6e191186264caf29f637174ae0 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 17:57:55 +0800 Subject: [PATCH 18/29] fix(nocodb): table create type correction --- packages/nocodb/src/lib/services/table.svc.ts | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/packages/nocodb/src/lib/services/table.svc.ts b/packages/nocodb/src/lib/services/table.svc.ts index 747f2d57b8..c0915ac2df 100644 --- a/packages/nocodb/src/lib/services/table.svc.ts +++ b/packages/nocodb/src/lib/services/table.svc.ts @@ -2,6 +2,7 @@ import DOMPurify from 'isomorphic-dompurify'; import { AuditOperationSubTypes, AuditOperationTypes, + ColumnType, isVirtualCol, ModelTypes, NormalColumnRequestType, @@ -314,6 +315,12 @@ export async function tableCreate(param: { }) { validatePayload('swagger.json#/components/schemas/TableReq', param.table); + const tableCreatePayLoad: Omit & { + columns: (Omit & { cn?: string })[]; + } = { + ...param.table, + }; + const project = await Project.getWithInfo(param.projectId); let base = project.bases[0]; @@ -322,8 +329,8 @@ export async function tableCreate(param: { } if ( - !param.table.table_name || - (project.prefix && project.prefix === param.table.table_name) + !tableCreatePayLoad.table_name || + (project.prefix && project.prefix === tableCreatePayLoad.table_name) ) { NcError.badRequest( 'Missing table name `table_name` property in request body' @@ -331,15 +338,17 @@ export async function tableCreate(param: { } if (base.is_meta && project.prefix) { - if (!param.table.table_name.startsWith(project.prefix)) { - param.table.table_name = `${project.prefix}_${param.table.table_name}`; + if (!tableCreatePayLoad.table_name.startsWith(project.prefix)) { + tableCreatePayLoad.table_name = `${project.prefix}_${tableCreatePayLoad.table_name}`; } } - param.table.table_name = DOMPurify.sanitize(param.table.table_name); + tableCreatePayLoad.table_name = DOMPurify.sanitize( + tableCreatePayLoad.table_name + ); // validate table name - if (/^\s+|\s+$/.test(param.table.table_name)) { + if (/^\s+|\s+$/.test(tableCreatePayLoad.table_name)) { NcError.badRequest( 'Leading or trailing whitespace not allowed in table names' ); @@ -347,7 +356,7 @@ export async function tableCreate(param: { if ( !(await Model.checkTitleAvailable({ - table_name: param.table.table_name, + table_name: tableCreatePayLoad.table_name, project_id: project.id, base_id: base.id, })) @@ -355,9 +364,9 @@ export async function tableCreate(param: { NcError.badRequest('Duplicate table name'); } - if (!param.table.title) { - param.table.title = getTableNameAlias( - param.table.table_name, + if (!tableCreatePayLoad.title) { + tableCreatePayLoad.title = getTableNameAlias( + tableCreatePayLoad.table_name, project.prefix, base ); @@ -365,7 +374,7 @@ export async function tableCreate(param: { if ( !(await Model.checkAliasAvailable({ - title: param.table.title, + title: tableCreatePayLoad.title, project_id: project.id, base_id: base.id, })) @@ -387,7 +396,7 @@ export async function tableCreate(param: { tableNameLengthLimit = 128; } - if (param.table.table_name.length > tableNameLengthLimit) { + if (tableCreatePayLoad.table_name.length > tableNameLengthLimit) { NcError.badRequest(`Table name exceeds ${tableNameLengthLimit} characters`); } @@ -401,12 +410,13 @@ export async function tableCreate(param: { } } - param.table.columns = param.table.columns?.map((c) => ({ + tableCreatePayLoad.columns = param.table.columns?.map((c) => ({ ...getColumnPropsFromUIDT(c as any, base), cn: c.column_name, + column_name: c.column_name, })); await sqlMgr.sqlOpPlus(base, 'tableCreate', { - ...param.table, + ...tableCreatePayLoad, tn: param.table.table_name, }); From a4d9873f0917cd068deaca629004b3bd7ec7527b Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 17:59:39 +0800 Subject: [PATCH 19/29] refactor(nocodb): use Record --- packages/nocodb/src/lib/models/Hook.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nocodb/src/lib/models/Hook.ts b/packages/nocodb/src/lib/models/Hook.ts index bf1c64611b..065f3abe4d 100644 --- a/packages/nocodb/src/lib/models/Hook.ts +++ b/packages/nocodb/src/lib/models/Hook.ts @@ -26,7 +26,7 @@ export default class Hook implements HookType { url?: string; headers?: string; condition?: BoolType; - notification?: string | object; + notification?: string | Record; retries?: number; retry_interval?: number; timeout?: number; From 32e97a417c1287242ea610c00287ff3c7694c3cb Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 18:55:30 +0800 Subject: [PATCH 20/29] refactor(nocodb): make it return promise --- packages/nocodb/src/lib/models/Base.ts | 5 +- .../src/lib/utils/common/NcConnectionMgrv2.ts | 103 ++++-------------- 2 files changed, 25 insertions(+), 83 deletions(-) diff --git a/packages/nocodb/src/lib/models/Base.ts b/packages/nocodb/src/lib/models/Base.ts index 96a396dcc7..3aaf43eb51 100644 --- a/packages/nocodb/src/lib/models/Base.ts +++ b/packages/nocodb/src/lib/models/Base.ts @@ -234,14 +234,15 @@ export default class Base implements BaseType { } } - public getConnectionConfig(): any { + // NC_DATA_DB is not available in community version + // make it return Promise to avoid conflicts + public getConnectionConfig(): Promise { if (this.is_meta) { const metaConfig = Noco.getConfig()?.meta?.db; const config = { ...metaConfig }; if (config.client === 'sqlite3') { config.connection = metaConfig; } - return config; } diff --git a/packages/nocodb/src/lib/utils/common/NcConnectionMgrv2.ts b/packages/nocodb/src/lib/utils/common/NcConnectionMgrv2.ts index bb55673cf6..29eaa5c94f 100644 --- a/packages/nocodb/src/lib/utils/common/NcConnectionMgrv2.ts +++ b/packages/nocodb/src/lib/utils/common/NcConnectionMgrv2.ts @@ -1,10 +1,5 @@ import SqlClientFactory from '../../db/sql-client/lib/SqlClientFactory'; import { XKnex } from '../../db/sql-data-mapper'; -// import { NcConfig } from '../../../interface/config'; -// import fs from 'fs'; -// import Knex from 'knex'; - -// import NcMetaIO from '../meta/NcMetaIO'; import { defaultConnectionConfig, defaultConnectionOptions, @@ -19,12 +14,6 @@ export default class NcConnectionMgrv2 { }; } = {}; - // private static metaKnex: NcMetaIO; - // - // public static setXcMeta(ncMeta: NcMetaIO) { - // this.metaKnex = ncMeta; - // } - public static async destroyAll() { for (const projectId in this.connectionRefs) { for (const baseId in this.connectionRefs[projectId]) { @@ -60,7 +49,9 @@ export default class NcConnectionMgrv2 { } } - public static get(base: Base): XKnex { + // NC_DATA_DB is not available in community version + // make it return Promise to avoid conflicts + public static async get(base: Base): Promise { if (base.is_meta) return Noco.ncMeta.knex; if (this.connectionRefs?.[base.project_id]?.[base.id]) { @@ -68,76 +59,26 @@ export default class NcConnectionMgrv2 { } this.connectionRefs[base.project_id] = this.connectionRefs?.[base.project_id] || {}; - // if (?.prefix && this.metaKnex) { - // this.connectionRefs[projectId][env][dbAlias] = this.metaKnex?.knex; - // } else { - // const connectionConfig = this.getConnectionConfig(config, env, dbAlias); - const connectionConfig = base.getConnectionConfig(); - // - // if ( - // connectionConfig?.connection?.ssl && - // typeof connectionConfig?.connection?.ssl === 'object' - // ) { - // if ( - // connectionConfig.connection.ssl.caFilePath && - // !connectionConfig.connection.ssl.ca - // ) { - // connectionConfig.connection.ssl.ca = fs - // .readFileSync(connectionConfig.connection.ssl.caFilePath) - // .toString(); - // } - // if ( - // connectionConfig.connection.ssl.keyFilePath && - // !connectionConfig.connection.ssl.key - // ) { - // connectionConfig.connection.ssl.key = fs - // .readFileSync(connectionConfig.connection.ssl.keyFilePath) - // .toString(); - // } - // if ( - // connectionConfig.connection.ssl.certFilePath && - // !connectionConfig.connection.ssl.cert - // ) { - // connectionConfig.connection.ssl.cert = fs - // .readFileSync(connectionConfig.connection.ssl.certFilePath) - // .toString(); - // } - // } - // - // const isSqlite = connectionConfig?.client === 'sqlite3'; - // - // if (connectionConfig?.connection?.port) { - // connectionConfig.connection.port = +connectionConfig.connection.port; - // } - this.connectionRefs[base.project_id][base.id] = XKnex( - // isSqlite - // ? (connectionConfig.connection as Knex.Config) - // : - { - ...defaultConnectionOptions, - ...connectionConfig, - connection: { - ...defaultConnectionConfig, - ...connectionConfig.connection, - typeCast(_field, next) { - const res = next(); - if (res instanceof Buffer) { - return [...res] - .map((v) => ('00' + v.toString(16)).slice(-2)) - .join(''); - } - return res; - }, - }, - } as any - ); - // if (isSqlite) { - // this.connectionRefs[projectId][env][dbAlias] - // .raw(`PRAGMA journal_mode=WAL;`) - // .then(() => {}); - // } + const connectionConfig = await base.getConnectionConfig(); + this.connectionRefs[base.project_id][base.id] = XKnex({ + ...defaultConnectionOptions, + ...connectionConfig, + connection: { + ...defaultConnectionConfig, + ...connectionConfig.connection, + typeCast(_field, next) { + const res = next(); + if (res instanceof Buffer) { + return [...res] + .map((v) => ('00' + v.toString(16)).slice(-2)) + .join(''); + } + return res; + }, + }, + } as any); return this.connectionRefs[base.project_id][base.id]; } @@ -153,7 +94,7 @@ export default class NcConnectionMgrv2 { const knex = _knex || this.get(base); return SqlClientFactory.create({ knex, - ...base.getConnectionConfig(), + ...(await base.getConnectionConfig()), }); } } From 84e29413bedcb3ac8908946adf18fad44b54587f Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 18:55:38 +0800 Subject: [PATCH 21/29] refactor(nocodb): add await --- .../src/lib/controllers/dbData/helpers.ts | 4 +- .../src/lib/controllers/dbData/oldData.ctl.ts | 12 +++--- .../publicControllers/publicDataExport.ctl.ts | 2 +- .../src/lib/db/sql-mgr/v2/SqlMgrv2Trans.ts | 2 +- packages/nocodb/src/lib/models/KanbanView.ts | 2 +- .../nocodb/src/lib/models/KanbanViewColumn.ts | 2 +- .../nocodb/src/lib/services/column.svc.ts | 12 +++--- .../src/lib/services/dbData/bulkData.ts | 2 +- .../services/dbData/dataAliasNested.svc.ts | 14 +++---- .../nocodb/src/lib/services/dbData/helpers.ts | 4 +- .../nocodb/src/lib/services/dbData/index.ts | 42 +++++++++---------- .../src/lib/services/public/publicData.svc.ts | 12 +++--- .../services/public/publicDataExport.svc.ts | 2 +- .../version-upgrader/ncAttachmentUpgrader.ts | 2 +- .../ncAttachmentUpgrader_0104002.ts | 2 +- packages/nocodb/tests/unit/factory/row.ts | 2 +- .../unit/model/tests/baseModelSql.test.ts | 8 ++-- 17 files changed, 63 insertions(+), 63 deletions(-) diff --git a/packages/nocodb/src/lib/controllers/dbData/helpers.ts b/packages/nocodb/src/lib/controllers/dbData/helpers.ts index 2ca5cd17e1..6e49638538 100644 --- a/packages/nocodb/src/lib/controllers/dbData/helpers.ts +++ b/packages/nocodb/src/lib/controllers/dbData/helpers.ts @@ -57,7 +57,7 @@ export async function extractXlsxData(param: { const baseModel = await Model.getBaseModelSQL({ id: view.model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const { offset, dbRows, elapsed } = await dataService.getDbRows({ @@ -92,7 +92,7 @@ export async function extractCsvData(view: View, req: Request) { const baseModel = await Model.getBaseModelSQL({ id: view.model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const { offset, dbRows, elapsed } = await dataService.getDbRows({ diff --git a/packages/nocodb/src/lib/controllers/dbData/oldData.ctl.ts b/packages/nocodb/src/lib/controllers/dbData/oldData.ctl.ts index 3492ff7361..51cdbe51c4 100644 --- a/packages/nocodb/src/lib/controllers/dbData/oldData.ctl.ts +++ b/packages/nocodb/src/lib/controllers/dbData/oldData.ctl.ts @@ -17,7 +17,7 @@ export async function dataList(req: Request, res: Response) { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const requestObj = await getAst({ @@ -50,7 +50,7 @@ export async function dataCount(req: Request, res: Response) { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const listArgs: any = { ...req.query }; @@ -73,7 +73,7 @@ async function dataInsert(req: Request, res: Response) { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); res.json(await baseModel.insert(req.body, null, req)); @@ -86,7 +86,7 @@ async function dataUpdate(req: Request, res: Response) { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); res.json(await baseModel.updateByPk(req.params.rowId, req.body, null, req)); @@ -98,7 +98,7 @@ async function dataDelete(req: Request, res: Response) { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); res.json(await baseModel.delByPk(req.params.rowId, null, req)); @@ -128,7 +128,7 @@ async function dataRead(req: Request, res: Response) { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); res.json( diff --git a/packages/nocodb/src/lib/controllers/publicControllers/publicDataExport.ctl.ts b/packages/nocodb/src/lib/controllers/publicControllers/publicDataExport.ctl.ts index cc677d6ab6..6afec3ef35 100644 --- a/packages/nocodb/src/lib/controllers/publicControllers/publicDataExport.ctl.ts +++ b/packages/nocodb/src/lib/controllers/publicControllers/publicDataExport.ctl.ts @@ -138,7 +138,7 @@ async function getDbRows(model, view: View, req: Request) { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const requestObj = await getAst({ diff --git a/packages/nocodb/src/lib/db/sql-mgr/v2/SqlMgrv2Trans.ts b/packages/nocodb/src/lib/db/sql-mgr/v2/SqlMgrv2Trans.ts index 82852fed52..bbb9210a48 100644 --- a/packages/nocodb/src/lib/db/sql-mgr/v2/SqlMgrv2Trans.ts +++ b/packages/nocodb/src/lib/db/sql-mgr/v2/SqlMgrv2Trans.ts @@ -34,7 +34,7 @@ export default class SqlMgrv2Trans extends SqlMgrv2 { } public async startTransaction(base: Base) { - const knex: XKnex = NcConnectionMgrv2.get(base); + const knex: XKnex = await NcConnectionMgrv2.get(base); this.trx = await knex.transaction(); } diff --git a/packages/nocodb/src/lib/models/KanbanView.ts b/packages/nocodb/src/lib/models/KanbanView.ts index b5ec87d85e..562563a97d 100644 --- a/packages/nocodb/src/lib/models/KanbanView.ts +++ b/packages/nocodb/src/lib/models/KanbanView.ts @@ -1,5 +1,5 @@ import Noco from '../Noco'; -import { BoolType, KanbanType, MetaType, UITypes } from 'nocodb-sdk'; +import type { BoolType, KanbanType, MetaType, UITypes } from 'nocodb-sdk'; import { CacheGetType, CacheScope, MetaTable } from '../utils/globals'; import View from './View'; import NocoCache from '../cache/NocoCache'; diff --git a/packages/nocodb/src/lib/models/KanbanViewColumn.ts b/packages/nocodb/src/lib/models/KanbanViewColumn.ts index 3f0b22bef4..026471e16b 100644 --- a/packages/nocodb/src/lib/models/KanbanViewColumn.ts +++ b/packages/nocodb/src/lib/models/KanbanViewColumn.ts @@ -3,7 +3,7 @@ import { CacheGetType, CacheScope, MetaTable } from '../utils/globals'; import View from './View'; import NocoCache from '../cache/NocoCache'; import { extractProps } from '../meta/helpers/extractProps'; -import { BoolType, KanbanColumnType } from 'nocodb-sdk'; +import type { BoolType, KanbanColumnType } from 'nocodb-sdk'; export default class KanbanViewColumn implements KanbanColumnType { id: string; diff --git a/packages/nocodb/src/lib/services/column.svc.ts b/packages/nocodb/src/lib/services/column.svc.ts index 1609f02fe8..7291b9dbc4 100644 --- a/packages/nocodb/src/lib/services/column.svc.ts +++ b/packages/nocodb/src/lib/services/column.svc.ts @@ -127,7 +127,7 @@ export async function columnUpdate(param: { try { // test the query to see if it is valid in db level - const dbDriver = NcConnectionMgrv2.get(base); + const dbDriver = await NcConnectionMgrv2.get(base); await formulaQueryBuilderv2(colBody.formula, null, dbDriver, table); } catch (e) { console.error(e); @@ -171,12 +171,12 @@ export async function columnUpdate(param: { const baseModel = await Model.getBaseModelSQL({ id: table.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); if (colBody.colOptions?.options) { const supportedDrivers = ['mysql', 'mysql2', 'pg', 'mssql', 'sqlite3']; - const dbDriver = NcConnectionMgrv2.get(base); + const dbDriver = await NcConnectionMgrv2.get(base); const driverType = dbDriver.clientType(); // MultiSelect to SingleSelect @@ -849,7 +849,7 @@ export async function columnAdd(param: { const project = await base.getProject(); if (param.column.title || param.column.column_name) { - const dbDriver = NcConnectionMgrv2.get(base); + const dbDriver = await NcConnectionMgrv2.get(base); const sqlClientType = dbDriver.clientType(); @@ -932,7 +932,7 @@ export async function columnAdd(param: { try { // test the query to see if it is valid in db level - const dbDriver = NcConnectionMgrv2.get(base); + const dbDriver = await NcConnectionMgrv2.get(base); await formulaQueryBuilderv2(colBody.formula, null, dbDriver, table); } catch (e) { console.error(e); @@ -958,7 +958,7 @@ export async function columnAdd(param: { if ( [UITypes.SingleSelect, UITypes.MultiSelect].includes(colBody.uidt) ) { - const dbDriver = NcConnectionMgrv2.get(base); + const dbDriver = await NcConnectionMgrv2.get(base); const driverType = dbDriver.clientType(); const optionTitles = colBody.colOptions.options.map((el) => el.title.replace(/'/g, "''") diff --git a/packages/nocodb/src/lib/services/dbData/bulkData.ts b/packages/nocodb/src/lib/services/dbData/bulkData.ts index 2ac6b5a20b..8c4c84c01c 100644 --- a/packages/nocodb/src/lib/services/dbData/bulkData.ts +++ b/packages/nocodb/src/lib/services/dbData/bulkData.ts @@ -27,7 +27,7 @@ export async function executeBulkOperation( const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); return await baseModel[param.operation].apply(null, param.options); } diff --git a/packages/nocodb/src/lib/services/dbData/dataAliasNested.svc.ts b/packages/nocodb/src/lib/services/dbData/dataAliasNested.svc.ts index 20959d15fa..0994b1818c 100644 --- a/packages/nocodb/src/lib/services/dbData/dataAliasNested.svc.ts +++ b/packages/nocodb/src/lib/services/dbData/dataAliasNested.svc.ts @@ -25,7 +25,7 @@ export async function mmList( const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const column = await getColumnByIdOrName(param.columnName, model); @@ -63,7 +63,7 @@ export async function mmExcludedList( const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const column = await getColumnByIdOrName(param.columnName, model); @@ -105,7 +105,7 @@ export async function hmExcludedList( const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const column = await getColumnByIdOrName(param.columnName, model); @@ -147,7 +147,7 @@ export async function btExcludedList( const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const column = await getColumnByIdOrName(param.columnName, model); @@ -191,7 +191,7 @@ export async function hmList( const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const column = await getColumnByIdOrName(param.columnName, model); @@ -232,7 +232,7 @@ export async function relationDataRemove( const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const column = await getColumnByIdOrName(param.columnName, model); @@ -265,7 +265,7 @@ export async function relationDataAdd( const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const column = await getColumnByIdOrName(param.columnName, model); diff --git a/packages/nocodb/src/lib/services/dbData/helpers.ts b/packages/nocodb/src/lib/services/dbData/helpers.ts index 9654fc3dfc..54b8a3fe03 100644 --- a/packages/nocodb/src/lib/services/dbData/helpers.ts +++ b/packages/nocodb/src/lib/services/dbData/helpers.ts @@ -58,7 +58,7 @@ export async function extractXlsxData(view: View, req: Request) { const baseModel = await Model.getBaseModelSQL({ id: view.model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const { offset, dbRows, elapsed } = await getDbRows({ @@ -93,7 +93,7 @@ export async function extractCsvData(view: View, req: Request) { const baseModel = await Model.getBaseModelSQL({ id: view.model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const { offset, dbRows, elapsed } = await getDbRows({ diff --git a/packages/nocodb/src/lib/services/dbData/index.ts b/packages/nocodb/src/lib/services/dbData/index.ts index c125530352..e491726f78 100644 --- a/packages/nocodb/src/lib/services/dbData/index.ts +++ b/packages/nocodb/src/lib/services/dbData/index.ts @@ -30,7 +30,7 @@ export async function dataCount(param: PathParams & { query: any }) { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const countArgs: any = { ...param.query }; @@ -53,7 +53,7 @@ export async function dataInsert( const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); return await baseModel.insert(param.body, null, param.cookie); @@ -68,7 +68,7 @@ export async function dataUpdate( const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); return await baseModel.updateByPk( @@ -87,7 +87,7 @@ export async function dataDelete( const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); // todo: Should have error http status code @@ -110,7 +110,7 @@ export async function getDataList(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const requestObj = await getAst({ model, query, view }); @@ -158,7 +158,7 @@ export async function getFindOne(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const args: any = { ...query }; @@ -192,7 +192,7 @@ export async function getDataGroupBy(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const listArgs: any = { ...query }; @@ -215,7 +215,7 @@ export async function dataRead( const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const row = await baseModel.readByPk(param.rowId); @@ -242,7 +242,7 @@ export async function dataExist( const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); return await baseModel.exist(param.rowId); @@ -275,7 +275,7 @@ export async function getGroupedDataList(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const requestObj = await getAst({ model, query, view }); @@ -353,7 +353,7 @@ export async function mmList(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const key = `${model.title}List`; @@ -411,7 +411,7 @@ export async function mmExcludedList(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const key = 'List'; @@ -472,7 +472,7 @@ export async function hmExcludedList(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const key = 'List'; @@ -533,7 +533,7 @@ export async function btExcludedList(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const key = 'List'; @@ -594,7 +594,7 @@ export async function hmList(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const key = `${model.title}List`; @@ -646,7 +646,7 @@ export async function dataReadByViewId(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); return await nocoExecute( @@ -677,7 +677,7 @@ export async function dataInsertByViewId(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); return await baseModel.insert(param.body, null, param.cookie); @@ -698,7 +698,7 @@ export async function dataUpdateByViewId(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); return await baseModel.updateByPk( @@ -723,7 +723,7 @@ export async function dataDeleteByViewId(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); return await baseModel.delByPk(param.rowId, null, param.cookie); @@ -749,7 +749,7 @@ export async function relationDataDelete(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); await baseModel.removeChild({ @@ -782,7 +782,7 @@ export async function relationDataAdd(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); await baseModel.addChild({ diff --git a/packages/nocodb/src/lib/services/public/publicData.svc.ts b/packages/nocodb/src/lib/services/public/publicData.svc.ts index e361b7cbff..41c5b8e61b 100644 --- a/packages/nocodb/src/lib/services/public/publicData.svc.ts +++ b/packages/nocodb/src/lib/services/public/publicData.svc.ts @@ -49,7 +49,7 @@ export async function dataList(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const listArgs: any = { ...param.query }; @@ -130,7 +130,7 @@ async function getGroupedDataList(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const requestObj = await getAst({ model, query: param.query, view }); @@ -208,7 +208,7 @@ export async function dataInsert(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); await view.getViewWithInfo(); @@ -306,7 +306,7 @@ export async function relDataList(param: { const baseModel = await Model.getBaseModelSQL({ id: model.id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const requestObj = await getAst({ @@ -362,7 +362,7 @@ export async function publicMmList(param: { const baseModel = await Model.getBaseModelSQL({ id: view.fk_model_id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const key = `List`; @@ -427,7 +427,7 @@ export async function publicHmList(param: { const baseModel = await Model.getBaseModelSQL({ id: view.fk_model_id, viewId: view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const key = `List`; diff --git a/packages/nocodb/src/lib/services/public/publicDataExport.svc.ts b/packages/nocodb/src/lib/services/public/publicDataExport.svc.ts index 900dd3ed88..a35c18ef50 100644 --- a/packages/nocodb/src/lib/services/public/publicDataExport.svc.ts +++ b/packages/nocodb/src/lib/services/public/publicDataExport.svc.ts @@ -45,7 +45,7 @@ export async function getDbRows(param: { const baseModel = await Model.getBaseModelSQL({ id: param.model.id, viewId: param.view?.id, - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), }); const requestObj = await getAst({ diff --git a/packages/nocodb/src/lib/version-upgrader/ncAttachmentUpgrader.ts b/packages/nocodb/src/lib/version-upgrader/ncAttachmentUpgrader.ts index f5c1393b3a..03c9913c09 100644 --- a/packages/nocodb/src/lib/version-upgrader/ncAttachmentUpgrader.ts +++ b/packages/nocodb/src/lib/version-upgrader/ncAttachmentUpgrader.ts @@ -66,7 +66,7 @@ export default async function ({ ncMeta }: NcUpgraderCtx) { const knex: Knex = base.is_meta ? ncMeta.knexConnection - : NcConnectionMgrv2.get(base); + : await NcConnectionMgrv2.get(base); const models = await base.getModels(ncMeta); // used in timeout error message diff --git a/packages/nocodb/src/lib/version-upgrader/ncAttachmentUpgrader_0104002.ts b/packages/nocodb/src/lib/version-upgrader/ncAttachmentUpgrader_0104002.ts index b732a51970..13ef464913 100644 --- a/packages/nocodb/src/lib/version-upgrader/ncAttachmentUpgrader_0104002.ts +++ b/packages/nocodb/src/lib/version-upgrader/ncAttachmentUpgrader_0104002.ts @@ -58,7 +58,7 @@ export default async function ({ ncMeta }: NcUpgraderCtx) { const knex: Knex = base.is_meta ? ncMeta.knexConnection - : NcConnectionMgrv2.get(base); + : await NcConnectionMgrv2.get(base); const models = await base.getModels(ncMeta); // used in timeout error message diff --git a/packages/nocodb/tests/unit/factory/row.ts b/packages/nocodb/tests/unit/factory/row.ts index 6c26c39ef8..490272f4bf 100644 --- a/packages/nocodb/tests/unit/factory/row.ts +++ b/packages/nocodb/tests/unit/factory/row.ts @@ -218,7 +218,7 @@ const listRow = async ({ const bases = await project.getBases(); const baseModel = await Model.getBaseModelSQL({ id: table.id, - dbDriver: NcConnectionMgrv2.get(bases[0]!), + dbDriver: await NcConnectionMgrv2.get(bases[0]!), }); const ignorePagination = !options; diff --git a/packages/nocodb/tests/unit/model/tests/baseModelSql.test.ts b/packages/nocodb/tests/unit/model/tests/baseModelSql.test.ts index 791711921b..46f6d81c8c 100644 --- a/packages/nocodb/tests/unit/model/tests/baseModelSql.test.ts +++ b/packages/nocodb/tests/unit/model/tests/baseModelSql.test.ts @@ -31,7 +31,7 @@ function baseModelSqlTests() { const base = await Base.get(table.base_id); baseModelSql = new BaseModelSqlv2({ - dbDriver: NcConnectionMgrv2.get(base), + dbDriver: await NcConnectionMgrv2.get(base), model: table, view }) @@ -347,7 +347,7 @@ function baseModelSqlTests() { ); const childBaseModel = new BaseModelSqlv2({ - dbDriver: NcConnectionMgrv2.get(await Base.get(table.base_id)), + dbDriver: await NcConnectionMgrv2.get(await Base.get(table.base_id)), model: childTable, view }) @@ -406,7 +406,7 @@ function baseModelSqlTests() { }); const childBaseModel = new BaseModelSqlv2({ - dbDriver: NcConnectionMgrv2.get(await Base.get(table.base_id)), + dbDriver: await NcConnectionMgrv2.get(await Base.get(table.base_id)), model: childTable, view }) @@ -473,7 +473,7 @@ function baseModelSqlTests() { }); const childBaseModel = new BaseModelSqlv2({ - dbDriver: NcConnectionMgrv2.get(await Base.get(table.base_id)), + dbDriver: await NcConnectionMgrv2.get(await Base.get(table.base_id)), model: childTable, view }) From aeb95b6a73db7231a9b5f91e1e82fc7b2e576da4 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 18:56:15 +0800 Subject: [PATCH 22/29] fix(nocodb): UITypes in kanban view --- packages/nocodb/src/lib/models/KanbanView.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/nocodb/src/lib/models/KanbanView.ts b/packages/nocodb/src/lib/models/KanbanView.ts index 562563a97d..7819fedb15 100644 --- a/packages/nocodb/src/lib/models/KanbanView.ts +++ b/packages/nocodb/src/lib/models/KanbanView.ts @@ -1,5 +1,6 @@ import Noco from '../Noco'; -import type { BoolType, KanbanType, MetaType, UITypes } from 'nocodb-sdk'; +import { UITypes } from 'nocodb-sdk'; +import type { BoolType, KanbanType, MetaType } from 'nocodb-sdk'; import { CacheGetType, CacheScope, MetaTable } from '../utils/globals'; import View from './View'; import NocoCache from '../cache/NocoCache'; From f06766f1c6c4f02e26719f9538d125b9a2fec395 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 18:58:27 +0800 Subject: [PATCH 23/29] fix(tests): incorrect types --- tests/playwright/tests/filters.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/tests/filters.spec.ts b/tests/playwright/tests/filters.spec.ts index e399d85f80..69f913d31c 100644 --- a/tests/playwright/tests/filters.spec.ts +++ b/tests/playwright/tests/filters.spec.ts @@ -9,7 +9,7 @@ import { rowMixedValue } from '../setup/xcdb-records'; let dashboard: DashboardPage, toolbar: ToolbarPage; let context: any; let api: Api; -let records = []; +let records: Record; const skipList = { Number: ['is null', 'is not null'], From f7f9039ea9e76859000567218cfbef1365a97dd1 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 19:03:57 +0800 Subject: [PATCH 24/29] refactor(nocodb): add async / await --- .../nocodb/src/lib/db/sql-migrator/lib/KnexMigratorv2.ts | 2 +- packages/nocodb/src/lib/meta/api/helpers/populateMeta.ts | 2 +- .../nocodb/src/lib/meta/helpers/getColumnPropsFromUIDT.ts | 4 ++-- packages/nocodb/src/lib/services/base.svc.ts | 2 +- packages/nocodb/src/lib/services/column.svc.ts | 6 +++--- packages/nocodb/src/lib/services/table.svc.ts | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/nocodb/src/lib/db/sql-migrator/lib/KnexMigratorv2.ts b/packages/nocodb/src/lib/db/sql-migrator/lib/KnexMigratorv2.ts index d32a40d1d0..3068907c42 100644 --- a/packages/nocodb/src/lib/db/sql-migrator/lib/KnexMigratorv2.ts +++ b/packages/nocodb/src/lib/db/sql-migrator/lib/KnexMigratorv2.ts @@ -384,7 +384,7 @@ export default class KnexMigratorv2 { async _initDbWithSql(base: Base) { const sqlClient = await this.getSqlClient(base); - const connectionConfig = base.getConnectionConfig(); + const connectionConfig = await base.getConnectionConfig(); if (connectionConfig.client === 'oracledb') { this.emit( `${connectionConfig.client}: Creating DB if not exists ${connectionConfig.connection.user}` diff --git a/packages/nocodb/src/lib/meta/api/helpers/populateMeta.ts b/packages/nocodb/src/lib/meta/api/helpers/populateMeta.ts index bf12425050..41f2e995c6 100644 --- a/packages/nocodb/src/lib/meta/api/helpers/populateMeta.ts +++ b/packages/nocodb/src/lib/meta/api/helpers/populateMeta.ts @@ -22,7 +22,7 @@ export async function populateMeta(base: Base, project: Project): Promise { tablesCount: 0, relationsCount: 0, viewsCount: 0, - client: base?.getConnectionConfig()?.client, + client: (await base?.getConnectionConfig())?.client, timeTaken: 0, }; diff --git a/packages/nocodb/src/lib/meta/helpers/getColumnPropsFromUIDT.ts b/packages/nocodb/src/lib/meta/helpers/getColumnPropsFromUIDT.ts index d5b4f7c4cb..d1f0f40ce4 100644 --- a/packages/nocodb/src/lib/meta/helpers/getColumnPropsFromUIDT.ts +++ b/packages/nocodb/src/lib/meta/helpers/getColumnPropsFromUIDT.ts @@ -7,11 +7,11 @@ import { import Base from '../../models/Base'; import Column from '../../models/Column'; -export default function getColumnPropsFromUIDT( +export default async function getColumnPropsFromUIDT( column: ColumnReqType & { altered?: number }, base: Base ) { - const sqlUi = SqlUiFactory.create(base.getConnectionConfig()); + const sqlUi = SqlUiFactory.create(await base.getConnectionConfig()); const colProp = sqlUi.getDataTypeForUiType( column as Column, diff --git a/packages/nocodb/src/lib/services/base.svc.ts b/packages/nocodb/src/lib/services/base.svc.ts index 21adb99ac8..0a88a9a030 100644 --- a/packages/nocodb/src/lib/services/base.svc.ts +++ b/packages/nocodb/src/lib/services/base.svc.ts @@ -8,7 +8,7 @@ import { populateMeta, validatePayload } from '../meta/api/helpers'; export async function baseGetWithConfig(param: { baseId: any }) { const base = await Base.get(param.baseId); - base.config = base.getConnectionConfig(); + base.config = await base.getConnectionConfig(); return base; } diff --git a/packages/nocodb/src/lib/services/column.svc.ts b/packages/nocodb/src/lib/services/column.svc.ts index 7291b9dbc4..bc12ab4ac4 100644 --- a/packages/nocodb/src/lib/services/column.svc.ts +++ b/packages/nocodb/src/lib/services/column.svc.ts @@ -167,7 +167,7 @@ export async function columnUpdate(param: { } else if ( [UITypes.SingleSelect, UITypes.MultiSelect].includes(colBody.uidt) ) { - colBody = getColumnPropsFromUIDT(colBody, base); + colBody = await getColumnPropsFromUIDT(colBody, base); const baseModel = await Model.getBaseModelSQL({ id: table.id, @@ -750,7 +750,7 @@ export async function columnUpdate(param: { ...colBody, }); } else { - colBody = getColumnPropsFromUIDT(colBody, base); + colBody = await getColumnPropsFromUIDT(colBody, base); const tableUpdateBody = { ...table, tn: table.table_name, @@ -947,7 +947,7 @@ export async function columnAdd(param: { break; default: { - colBody = getColumnPropsFromUIDT(colBody, base); + colBody = await getColumnPropsFromUIDT(colBody, base); if (colBody.uidt === UITypes.Duration) { colBody.dtxp = '20'; // by default, colBody.dtxs is 2 diff --git a/packages/nocodb/src/lib/services/table.svc.ts b/packages/nocodb/src/lib/services/table.svc.ts index c0915ac2df..73df979c9e 100644 --- a/packages/nocodb/src/lib/services/table.svc.ts +++ b/packages/nocodb/src/lib/services/table.svc.ts @@ -410,7 +410,7 @@ export async function tableCreate(param: { } } - tableCreatePayLoad.columns = param.table.columns?.map((c) => ({ + tableCreatePayLoad.columns = param.table.columns?.map(async (c) => ({ ...getColumnPropsFromUIDT(c as any, base), cn: c.column_name, column_name: c.column_name, From 2a9871526c124b737ce9ebdd2ea32cfddfc8f576 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 19:05:30 +0800 Subject: [PATCH 25/29] refactor(nocodb): remove async --- packages/nocodb/src/lib/services/table.svc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nocodb/src/lib/services/table.svc.ts b/packages/nocodb/src/lib/services/table.svc.ts index 73df979c9e..c0915ac2df 100644 --- a/packages/nocodb/src/lib/services/table.svc.ts +++ b/packages/nocodb/src/lib/services/table.svc.ts @@ -410,7 +410,7 @@ export async function tableCreate(param: { } } - tableCreatePayLoad.columns = param.table.columns?.map(async (c) => ({ + tableCreatePayLoad.columns = param.table.columns?.map((c) => ({ ...getColumnPropsFromUIDT(c as any, base), cn: c.column_name, column_name: c.column_name, From 72e393550794e7ca1f7b0f467f968c58ba6450bd Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 19:15:36 +0800 Subject: [PATCH 26/29] fix(nocodb): add missing await --- packages/nocodb/src/lib/utils/common/NcConnectionMgrv2.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nocodb/src/lib/utils/common/NcConnectionMgrv2.ts b/packages/nocodb/src/lib/utils/common/NcConnectionMgrv2.ts index 29eaa5c94f..6e8d042327 100644 --- a/packages/nocodb/src/lib/utils/common/NcConnectionMgrv2.ts +++ b/packages/nocodb/src/lib/utils/common/NcConnectionMgrv2.ts @@ -91,7 +91,7 @@ export default class NcConnectionMgrv2 { // } public static async getSqlClient(base: Base, _knex = null) { - const knex = _knex || this.get(base); + const knex = _knex || (await this.get(base)); return SqlClientFactory.create({ knex, ...(await base.getConnectionConfig()), From 7a9ded89fd3e1a75aa93c4cfeb6a56c45765fbfb Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 19:37:17 +0800 Subject: [PATCH 27/29] fix(nocodb): ForgotPasswordReq -> PasswordForgotReq --- packages/nocodb/src/lib/services/user/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nocodb/src/lib/services/user/index.ts b/packages/nocodb/src/lib/services/user/index.ts index 1a2ed090f5..474c1f5c2b 100644 --- a/packages/nocodb/src/lib/services/user/index.ts +++ b/packages/nocodb/src/lib/services/user/index.ts @@ -138,7 +138,7 @@ export async function passwordForgot(param: { req: any; }): Promise { validatePayload( - 'swagger.json#/components/schemas/ForgotPasswordReq', + 'swagger.json#/components/schemas/PasswordForgotReq', param.body ); From 6a849af88bfddedb9d2bee2ee2a2c0bb1d6c9794 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 20:17:40 +0800 Subject: [PATCH 28/29] fix(nocodb): add missing promise.all --- packages/nocodb/src/lib/services/table.svc.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/nocodb/src/lib/services/table.svc.ts b/packages/nocodb/src/lib/services/table.svc.ts index c0915ac2df..4a6ee60a99 100644 --- a/packages/nocodb/src/lib/services/table.svc.ts +++ b/packages/nocodb/src/lib/services/table.svc.ts @@ -410,11 +410,13 @@ export async function tableCreate(param: { } } - tableCreatePayLoad.columns = param.table.columns?.map((c) => ({ - ...getColumnPropsFromUIDT(c as any, base), - cn: c.column_name, - column_name: c.column_name, - })); + tableCreatePayLoad.columns = await Promise.all( + param.table.columns?.map(async (c) => ({ + ...(await getColumnPropsFromUIDT(c as any, base)), + cn: c.column_name, + column_name: c.column_name, + })) + ); await sqlMgr.sqlOpPlus(base, 'tableCreate', { ...tableCreatePayLoad, tn: param.table.table_name, From 7661b9d33bb88beb04d09e2046f16f7af634971b Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Tue, 7 Mar 2023 22:12:26 +0800 Subject: [PATCH 29/29] fix(nocodb): use tableCreatePayLoad instead --- packages/nocodb/src/lib/services/table.svc.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/nocodb/src/lib/services/table.svc.ts b/packages/nocodb/src/lib/services/table.svc.ts index 4a6ee60a99..59fe0c9e1d 100644 --- a/packages/nocodb/src/lib/services/table.svc.ts +++ b/packages/nocodb/src/lib/services/table.svc.ts @@ -419,7 +419,7 @@ export async function tableCreate(param: { ); await sqlMgr.sqlOpPlus(base, 'tableCreate', { ...tableCreatePayLoad, - tn: param.table.table_name, + tn: tableCreatePayLoad.table_name, }); const columns: Array< @@ -427,7 +427,8 @@ export async function tableCreate(param: { cn: string; system?: boolean; } - > = (await sqlClient.columnList({ tn: param.table.table_name }))?.data?.list; + > = (await sqlClient.columnList({ tn: tableCreatePayLoad.table_name }))?.data + ?.list; const tables = await Model.list({ project_id: project.id, @@ -440,7 +441,7 @@ export async function tableCreate(param: { op_type: AuditOperationTypes.TABLE, op_sub_type: AuditOperationSubTypes.CREATED, user: param.user?.email, - description: `created table ${param.table.table_name} with alias ${param.table.title} `, + description: `created table ${tableCreatePayLoad.table_name} with alias ${tableCreatePayLoad.title} `, ip: param.req?.clientIp, }).then(() => {}); @@ -450,7 +451,7 @@ export async function tableCreate(param: { // todo: type correction const result = await Model.insert(project.id, base.id, { - ...param.table, + ...tableCreatePayLoad, columns: columns.map((c, i) => { const colMetaFromReq = param.table?.columns?.find( (c1) => c.cn === c1.column_name