Browse Source

Merge pull request #2393 from nocodb/fix/admin-env-variables

Fix: invalidate token if admin email or password changed
pull/2492/head
navi 2 years ago committed by GitHub
parent
commit
073749f494
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 55
      packages/nocodb/src/lib/meta/api/userApi/initAdminFromEnv.ts
  2. 8
      packages/nocodb/src/lib/meta/api/userApi/initStrategies.ts
  3. 7
      packages/nocodb/src/lib/meta/api/userApi/userApis.ts
  4. 3
      packages/nocodb/src/lib/models/User.ts

55
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();

8
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.'));

7
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);

3
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 = [

Loading…
Cancel
Save