Browse Source

fix: session across broswers

pull/2338/head
Wing-Kam Wong 2 years ago
parent
commit
5f08ecbf67
  1. 12
      packages/nocodb/src/lib/meta/api/userApi/initStrategies.ts
  2. 29
      packages/nocodb/src/lib/meta/api/userApi/userApis.ts
  3. 22
      packages/nocodb/src/lib/meta/helpers/ncMetaAclMw.ts
  4. 8
      packages/nocodb/src/lib/migrations/XcMigrationSourcev2.ts
  5. 4
      packages/nocodb/src/lib/migrations/v2/nc_017_add_user_token_version_column.ts
  6. 6
      packages/nocodb/src/lib/models/User.ts
  7. 6
      packages/nocodb/src/lib/v1-legacy/rest/RestAuthCtrl.ts

12
packages/nocodb/src/lib/meta/api/userApi/initStrategies.ts

@ -53,7 +53,8 @@ export function initStrategies(router): void {
firstname,
lastname,
isAuthorized,
isPublicBase
isPublicBase,
token_version
},
done
) {
@ -72,7 +73,8 @@ export function initStrategies(router): void {
provider,
firstname,
lastname,
roles
roles,
token_version
});
});
@ -100,11 +102,17 @@ export function initStrategies(router): void {
);
if (cachedVal) {
if (cachedVal.token_version !== jwtPayload.token_version) {
return done(new Error('Token Expired. Please login again.'));
}
return done(null, cachedVal);
}
User.getByEmail(jwtPayload?.email)
.then(async user => {
if (user.token_version !== jwtPayload.token_version) {
return done(new Error('Token Expired. Please login again.'));
}
if (req.ncProjectId) {
// this.xcMeta
// .metaGet(req.ncProjectId, null, 'nc_projects_users', {

29
packages/nocodb/src/lib/meta/api/userApi/userApis.ts

@ -96,6 +96,8 @@ export async function signup(req: Request, res: Response<TableType>) {
}
}
const token_version = randomTokenString();
await User.insert({
firstname,
lastname,
@ -104,7 +106,7 @@ export async function signup(req: Request, res: Response<TableType>) {
password,
email_verification_token,
roles,
token_expired: false
token_version
});
}
user = await User.getByEmail(email);
@ -151,7 +153,8 @@ export async function signup(req: Request, res: Response<TableType>) {
firstname: user.firstname,
lastname: user.lastname,
id: user.id,
roles: user.roles
roles: user.roles,
token_version: user.token_version
},
Noco.getConfig().auth.jwt.secret,
Noco.getConfig().auth.jwt.options
@ -181,10 +184,15 @@ 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();
}
await User.update(user.id, {
refresh_token: refreshToken,
email: user.email,
token_expired: false
token_version
});
setTokenCookie(res, refreshToken);
@ -203,7 +211,8 @@ async function successfulSignIn({
firstname: user.firstname,
lastname: user.lastname,
id: user.id,
roles: user.roles
roles: user.roles,
token_version
},
Noco.getConfig().auth.jwt.secret,
@ -292,7 +301,7 @@ async function passwordChange(req: Request<any, any>, res): Promise<any> {
salt,
password,
email: user.email,
token_expired: true
token_version: null
});
Audit.insert({
@ -320,7 +329,8 @@ async function passwordForgot(req: Request<any, any>, res): Promise<any> {
await User.update(user.id, {
email: user.email,
reset_password_token: token,
reset_password_expires: new Date(Date.now() + 60 * 60 * 1000)
reset_password_expires: new Date(Date.now() + 60 * 60 * 1000),
token_version: null
});
try {
const template = (await import('./ui/emailTemplates/forgotPassword'))
@ -371,7 +381,7 @@ async function tokenValidate(req, res): Promise<any> {
if (user.reset_password_expires < new Date()) {
NcError.badRequest('Password reset url expired');
}
if (user.token_expired) {
if (!user.token_version) {
NcError.badRequest('Token Expired. Please login again.');
}
res.json(true);
@ -403,7 +413,7 @@ async function passwordReset(req, res): Promise<any> {
email: user.email,
reset_password_expires: null,
reset_password_token: '',
token_expired: true
token_version: null
});
Audit.insert({
@ -461,8 +471,7 @@ async function refreshToken(req, res): Promise<any> {
await User.update(user.id, {
email: user.email,
refresh_token: refreshToken,
token_expired: false
refresh_token: refreshToken
});
setTokenCookie(res, refreshToken);

22
packages/nocodb/src/lib/meta/helpers/ncMetaAclMw.ts

@ -2,9 +2,6 @@ import projectAcl from '../../utils/projectAcl';
import { NextFunction, Request, Response } from 'express';
import catchError, { NcError } from './catchError';
import extractProjectIdAndAuthenticate from './extractProjectIdAndAuthenticate';
import NocoCache from '../../cache/NocoCache';
import Noco from '../../Noco';
import { CacheGetType, CacheScope, MetaTable } from '../../utils/globals';
export default function(handlerFn, permissionName) {
return [
@ -24,25 +21,6 @@ export default function(handlerFn, permissionName) {
) {
NcError.unauthorized('Unauthorized access');
}
// check if the token is still valid for non-public base
if (!req?.session?.passport?.user?.isPublicBase) {
const email = req?.session?.passport?.user?.email;
let user =
email &&
(await NocoCache.get(
`${CacheScope.USER}:${email}`,
CacheGetType.TYPE_OBJECT
));
if (!user) {
user = await Noco.ncMeta.metaGet2(null, null, MetaTable.USERS, {
email
});
}
if (user.token_expired) {
NcError.unauthorized('Token Expired. Please login again.');
}
}
next();
}),
// @ts-ignore

8
packages/nocodb/src/lib/migrations/XcMigrationSourcev2.ts

@ -4,7 +4,7 @@ import * as nc_013_sync_source from './v2/nc_013_sync_source';
import * as nc_014_alter_column_data_types from './v2/nc_014_alter_column_data_types';
import * as nc_015_add_meta_col_in_column_table from './v2/nc_015_add_meta_col_in_column_table';
import * as nc_016_alter_hooklog_payload_types from './v2/nc_016_alter_hooklog_payload_types';
import * as nc_017_add_user_token_exp_column from './v2/nc_017_add_user_token_exp_column';
import * as nc_017_add_user_token_version_column from './v2/nc_017_add_user_token_version_column';
// Create a custom migration source class
export default class XcMigrationSourcev2 {
@ -20,7 +20,7 @@ export default class XcMigrationSourcev2 {
'nc_014_alter_column_data_types',
'nc_015_add_meta_col_in_column_table',
'nc_016_alter_hooklog_payload_types',
'nc_017_add_user_token_exp_column'
'nc_017_add_user_token_version_column'
]);
}
@ -42,8 +42,8 @@ export default class XcMigrationSourcev2 {
return nc_015_add_meta_col_in_column_table;
case 'nc_016_alter_hooklog_payload_types':
return nc_016_alter_hooklog_payload_types;
case 'nc_017_add_user_token_exp_column':
return nc_017_add_user_token_exp_column;
case 'nc_017_add_user_token_version_column':
return nc_017_add_user_token_version_column;
}
}
}

4
packages/nocodb/src/lib/migrations/v2/nc_017_add_user_token_exp_column.ts → packages/nocodb/src/lib/migrations/v2/nc_017_add_user_token_version_column.ts

@ -2,13 +2,13 @@ import Knex from 'knex';
const up = async (knex: Knex) => {
await knex.schema.alterTable('nc_users_v2', table => {
table.boolean('token_expired').defaultTo(false);
table.string('token_version');
});
};
const down = async knex => {
await knex.schema.alterTable('nc_users_v2', table => {
table.dropColumns('token_expired');
table.dropColumns('token_version');
});
};

6
packages/nocodb/src/lib/models/User.ts

@ -22,7 +22,7 @@ export default class User implements UserType {
email_verification_token?: string;
email_verified: boolean;
roles?: string;
token_expired?: boolean;
token_version?: string;
constructor(data: User) {
Object.assign(this, data);
@ -45,7 +45,7 @@ export default class User implements UserType {
'email_verification_token',
'email_verified',
'roles',
'token_expired'
'token_version'
]);
const { id } = await ncMeta.metaInsert2(
null,
@ -74,7 +74,7 @@ export default class User implements UserType {
'email_verification_token',
'email_verified',
'roles',
'token_expired'
'token_version'
]);
// get existing cache
const keys = [

6
packages/nocodb/src/lib/v1-legacy/rest/RestAuthCtrl.ts

@ -42,7 +42,8 @@ passport.serializeUser(function(
firstname,
lastname,
isAuthorized,
isPublicBase
isPublicBase,
token_version
},
done
) {
@ -61,7 +62,8 @@ passport.serializeUser(function(
provider,
firstname,
lastname,
roles
roles,
token_version
});
});

Loading…
Cancel
Save