diff --git a/packages/nocodb/src/lib/meta/api/userApi/initAdminFromEnv.ts b/packages/nocodb/src/lib/meta/api/userApi/initAdminFromEnv.ts index 81885ed12d..86a1a30e9a 100644 --- a/packages/nocodb/src/lib/meta/api/userApi/initAdminFromEnv.ts +++ b/packages/nocodb/src/lib/meta/api/userApi/initAdminFromEnv.ts @@ -5,10 +5,11 @@ import { Tele } from 'nc-help'; import bcrypt from 'bcryptjs'; import Noco from '../../../Noco'; -import { MetaTable } from '../../../utils/globals'; +import { CacheScope, MetaTable } from '../../../utils/globals'; import ProjectUser from '../../../models/ProjectUser'; import { validatePassword } from 'nocodb-sdk'; import boxen from 'boxen'; +import NocoCache from '../../../cache/NocoCache'; const { isEmail } = require('validator'); const rolesLevel = { owner: 0, creator: 1, editor: 2, commenter: 3, viewer: 4 }; @@ -103,7 +104,7 @@ export default async function initAdminFromEnv(_ncMeta = Noco.ncMeta) { // check user account already present with the new admin email const existingUserWithNewEmail = await User.getByEmail(email, ncMeta); - if (existingUserWithNewEmail) { + if (existingUserWithNewEmail?.id) { // get all project access belongs to the existing account // and migrate to the admin account const existingUserProjects = await ncMeta.metaList2( @@ -155,13 +156,25 @@ export default async function initAdminFromEnv(_ncMeta = Noco.ncMeta) { } // delete existing user - ncMeta.metaDelete( + await ncMeta.metaDelete( null, null, MetaTable.USERS, existingUserWithNewEmail.id ); + // clear cache + await NocoCache.delAll( + CacheScope.USER, + `${existingUserWithNewEmail.email}___*` + ); + await NocoCache.del( + `${CacheScope.USER}:${existingUserWithNewEmail.id}` + ); + await NocoCache.del( + `${CacheScope.USER}:${existingUserWithNewEmail.email}` + ); + // Update email and password of super admin account await User.update( superUser.id, @@ -169,7 +182,9 @@ export default async function initAdminFromEnv(_ncMeta = Noco.ncMeta) { salt, email, password, - email_verification_token + email_verification_token, + token_version: null, + refresh_token: null }, ncMeta ); @@ -181,22 +196,34 @@ export default async function initAdminFromEnv(_ncMeta = Noco.ncMeta) { salt, email, password, - email_verification_token + email_verification_token, + token_version: null, + refresh_token: null }, ncMeta ); } } else { - // if email's are not different update the password and hash - await User.update( - superUser.id, - { - salt, - password, - email_verification_token - }, - ncMeta + const newPasswordHash = await promisify(bcrypt.hash)( + process.env.NC_ADMIN_PASSWORD, + superUser.salt ); + + if (newPasswordHash !== superUser.password) { + // if email's are same and passwords are different + // then update the password and token version + await User.update( + superUser.id, + { + salt, + password, + email_verification_token, + token_version: null, + refresh_token: null + }, + ncMeta + ); + } } } await ncMeta.commit(); diff --git a/packages/nocodb/src/lib/meta/api/userApi/initStrategies.ts b/packages/nocodb/src/lib/meta/api/userApi/initStrategies.ts index e6c99869ac..b7d8599f7a 100644 --- a/packages/nocodb/src/lib/meta/api/userApi/initStrategies.ts +++ b/packages/nocodb/src/lib/meta/api/userApi/initStrategies.ts @@ -103,8 +103,8 @@ export function initStrategies(router): void { if (cachedVal) { if ( - cachedVal.token_version && - jwtPayload.token_version && + !cachedVal.token_version || + !jwtPayload.token_version || cachedVal.token_version !== jwtPayload.token_version ) { return done(new Error('Token Expired. Please login again.')); @@ -115,8 +115,8 @@ export function initStrategies(router): void { User.getByEmail(jwtPayload?.email) .then(async user => { if ( - user.token_version && - jwtPayload.token_version && + !user.token_version || + !jwtPayload.token_version || user.token_version !== jwtPayload.token_version ) { return done(new Error('Token Expired. Please login again.')); diff --git a/packages/nocodb/src/lib/meta/api/userApi/userApis.ts b/packages/nocodb/src/lib/meta/api/userApi/userApis.ts index 320b4850e9..596de0cec4 100644 --- a/packages/nocodb/src/lib/meta/api/userApi/userApis.ts +++ b/packages/nocodb/src/lib/meta/api/userApi/userApis.ts @@ -179,15 +179,14 @@ async function successfulSignIn({ await promisify((req as any).login.bind(req))(user); const refreshToken = randomTokenString(); - let token_version = user.token_version; - if (!token_version) { - token_version = randomTokenString(); + if (!user.token_version) { + user.token_version = randomTokenString(); } await User.update(user.id, { refresh_token: refreshToken, email: user.email, - token_version + token_version: user.token_version }); setTokenCookie(res, refreshToken); diff --git a/packages/nocodb/src/lib/models/User.ts b/packages/nocodb/src/lib/models/User.ts index a1a91aada5..fe7743e1ca 100644 --- a/packages/nocodb/src/lib/models/User.ts +++ b/packages/nocodb/src/lib/models/User.ts @@ -84,6 +84,9 @@ export default class User implements UserType { if (updateObj.email) { updateObj.email = updateObj.email.toLowerCase(); + } else { + // set email prop to avoid generation of invalid cache key + updateObj.email = (await this.get(id, ncMeta))?.email?.toLowerCase(); } // get existing cache const keys = [