Browse Source

fix: socket with passport middleware

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/5444/head
Pranav C 2 years ago
parent
commit
c2dd3410c5
  1. 4
      packages/nocodb-nest/src/app.module.ts
  2. 3
      packages/nocodb-nest/src/db/BaseModelSqlv2.ts
  3. 2
      packages/nocodb-nest/src/helpers/populateMeta.ts
  4. 4
      packages/nocodb-nest/src/modules/projects/projects.service.ts
  5. 2
      packages/nocodb-nest/src/modules/users/helpers.ts
  6. 3
      packages/nocodb-nest/src/modules/users/users.service.ts
  7. 11
      packages/nocodb-nest/src/modules/utils/utils.controller.ts
  8. 18
      packages/nocodb-nest/src/services/client/client.service.spec.ts
  9. 84
      packages/nocodb-nest/src/services/client/client.service.ts
  10. 25
      packages/nocodb-nest/src/strategies/jwt.strategy.ts
  11. 2
      packages/nocodb-nest/src/strategies/local.strategy.ts

4
packages/nocodb-nest/src/app.module.ts

@ -59,6 +59,7 @@ import type {
OnApplicationBootstrap, OnApplicationBootstrap,
Provider, Provider,
} from '@nestjs/common'; } from '@nestjs/common';
import { ClientService } from './services/client/client.service';
export const JwtStrategyProvider: Provider = { export const JwtStrategyProvider: Provider = {
provide: JwtStrategy, provide: JwtStrategy,
@ -133,6 +134,7 @@ export const JwtStrategyProvider: Provider = {
JwtStrategyProvider, JwtStrategyProvider,
LocalStrategy, LocalStrategy,
ExtractProjectIdMiddleware, ExtractProjectIdMiddleware,
ClientService,
], ],
}) })
export class AppModule implements OnApplicationBootstrap { export class AppModule implements OnApplicationBootstrap {
@ -159,6 +161,6 @@ export class AppModule implements OnApplicationBootstrap {
Noco.config = this.connection.config; Noco.config = this.connection.config;
// run upgrader // run upgrader
await NcUpgrader.upgrade({ ncMeta: Noco._ncMeta }); // await NcUpgrader.upgrade({ ncMeta: Noco._ncMeta });
} }
} }

3
packages/nocodb-nest/src/db/BaseModelSqlv2.ts

@ -50,8 +50,6 @@ import genRollupSelectv2 from './genRollupSelectv2';
import conditionV2 from './conditionV2'; import conditionV2 from './conditionV2';
import sortV2 from './sortV2'; import sortV2 from './sortV2';
import { customValidators } from './util/customValidators'; import { customValidators } from './util/customValidators';
import type LookupColumn from '../../../nocodb/src/lib/models/LookupColumn';
import type { XKnex } from '../../../nocodb/src/lib/db/sql-data-mapper';
import type { import type {
XcFilter, XcFilter,
XcFilterWithAlias, XcFilterWithAlias,
@ -67,6 +65,7 @@ import type {
} from '../models'; } from '../models';
import type { Knex } from 'knex'; import type { Knex } from 'knex';
import type { SortType } from 'nocodb-sdk'; import type { SortType } from 'nocodb-sdk';
import { XKnex } from './CustomKnex';
export async function getViewAndModelByAliasOrId(param: { export async function getViewAndModelByAliasOrId(param: {
projectName: string; projectName: string;

2
packages/nocodb-nest/src/helpers/populateMeta.ts

@ -1,5 +1,5 @@
import { ModelTypes, UITypes, ViewTypes } from 'nocodb-sdk'; import { ModelTypes, UITypes, ViewTypes } from 'nocodb-sdk';
import { isVirtualCol, RelationTypes } from '../../../nocodb-sdk'; import { isVirtualCol, RelationTypes } from 'nocodb-sdk';
import Column from '../models/Column'; import Column from '../models/Column';
import Model from '../models/Model'; import Model from '../models/Model';
import NcConnectionMgrv2 from '../utils/common/NcConnectionMgrv2'; import NcConnectionMgrv2 from '../utils/common/NcConnectionMgrv2';

4
packages/nocodb-nest/src/modules/projects/projects.service.ts

@ -3,7 +3,7 @@ import { Injectable } from '@nestjs/common';
import * as DOMPurify from 'isomorphic-dompurify'; import * as DOMPurify from 'isomorphic-dompurify';
import { customAlphabet } from 'nanoid'; import { customAlphabet } from 'nanoid';
import { T } from 'nc-help'; import { T } from 'nc-help';
import { OrgUserRoles } from '../../../../nocodb-sdk'; import { OrgUserRoles } from 'nocodb-sdk';
import { populateMeta, validatePayload } from '../../helpers'; import { populateMeta, validatePayload } from '../../helpers';
import { NcError } from '../../helpers/catchError'; import { NcError } from '../../helpers/catchError';
import { extractPropsAndSanitize } from '../../helpers/extractProps'; import { extractPropsAndSanitize } from '../../helpers/extractProps';
@ -12,7 +12,7 @@ import { Project, ProjectUser } from '../../models';
import Noco from '../../Noco'; import Noco from '../../Noco';
import extractRolesObj from '../../utils/extractRolesObj'; import extractRolesObj from '../../utils/extractRolesObj';
import NcConfigFactory from '../../utils/NcConfigFactory'; import NcConfigFactory from '../../utils/NcConfigFactory';
import type { ProjectUpdateReqType } from '../../../../nocodb-sdk'; import type { ProjectUpdateReqType } from 'nocodb-sdk';
import type { ProjectReqType } from 'nocodb-sdk'; import type { ProjectReqType } from 'nocodb-sdk';
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 4); const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 4);

2
packages/nocodb-nest/src/modules/users/helpers.ts

@ -16,7 +16,7 @@ export function genJwt(user: User, config: NcConfig) {
}, },
config.auth.jwt.secret, config.auth.jwt.secret,
// todo: better typing // todo: better typing
config.auth.jwt.options as any, { expiresIn: '10h', ...(config.auth.jwt.options as any) },
); );
} }

3
packages/nocodb-nest/src/modules/users/users.service.ts

@ -482,9 +482,6 @@ export class UsersService {
} }
async login(user: any) { async login(user: any) {
delete user.password;
delete user.salt;
const payload = user;
return { return {
token: genJwt(user, Noco.getConfig()), //this.jwtService.sign(payload), token: genJwt(user, Noco.getConfig()), //this.jwtService.sign(payload),
}; };

11
packages/nocodb-nest/src/modules/utils/utils.controller.ts

@ -53,10 +53,6 @@ export class UtilsController {
async axiosRequestMake(@Body() body: any) { async axiosRequestMake(@Body() body: any) {
return await this.utilsService.axiosRequestMake({ body }); return await this.utilsService.axiosRequestMake({ body });
} }
@Get('/api/v1/aggregated-meta-info')
async aggregatedMetaInfo() {
return await this.utilsService.aggregatedMetaInfo();
}
@Post('/api/v1/url_to_config') @Post('/api/v1/url_to_config')
async urlToDbConfig(@Body() body: any) { async urlToDbConfig(@Body() body: any) {
@ -64,4 +60,11 @@ export class UtilsController {
body, body,
}); });
} }
@Get('/api/v1/aggregated-meta-info')
async aggregatedMetaInfo() {
// todo: refactor
return (await this.utilsService.aggregatedMetaInfo()) as any;
}
} }

18
packages/nocodb-nest/src/services/client/client.service.spec.ts

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ClientService } from './client.service';
describe('ClientService', () => {
let service: ClientService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [ClientService],
}).compile();
service = module.get<ClientService>(ClientService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

84
packages/nocodb-nest/src/services/client/client.service.ts

@ -0,0 +1,84 @@
import crypto from 'crypto';
import { Inject, Injectable, UnauthorizedException } from '@nestjs/common';
import { HttpAdapterHost } from '@nestjs/core';
import { T } from 'nc-help';
import { Server } from 'socket.io';
import { AuthGuard } from '@nestjs/passport';
import { JwtStrategy } from '../../strategies/jwt.strategy';
import type { OnModuleInit } from '@nestjs/common';
import type { Socket } from 'socket.io';
import { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host';
function getHash(str) {
return crypto.createHash('md5').update(str).digest('hex');
}
@Injectable()
export class ClientService implements OnModuleInit {
// private server: HttpServer;
private clients: { [id: string]: Socket } = {};
private jobs: { [id: string]: { last_message: any } } = {};
constructor(
private jwtStrategy: JwtStrategy,
@Inject(HttpAdapterHost) private httpAdapterHost: HttpAdapterHost,
) {
// this.server = this.httpAdapterHost.httpAdapter.getHttpServer();
}
async onModuleInit() {
const io = new Server(this.httpAdapterHost.httpAdapter.getHttpServer(), {
cors: {
origin: '*',
allowedHeaders: ['xc-auth'],
credentials: true,
},
});
io.use(async (socket, next) => {
// const authGuard = new (AuthGuard('jwt'))();
// const result = await authGuard.canActivate(socket.handshake as any);
// if (!result) {
// throw new UnauthorizedException();
// }
// return new Promise((resolve, reject) => {
// this.jwtStrategy.authenticate(
// socket.handshake as any,
// (error, user) => {
// if (error) {
// reject(new UnauthorizedException(error.message));
// } else {
// resolve(user);
// }
// },
// );
// });
try {
const context = new ExecutionContextHost([socket.handshake as any]);
const guard = new (AuthGuard('jwt'))(context);
const canActivate = await guard.canActivate(context);
} catch {}
next()
}).on('connection', (socket) => {
this.clients[socket.id] = socket;
const id = getHash(
(process.env.NC_SERVER_UUID || T.id) +
(socket?.handshake as any)?.user?.id,
);
socket.on('page', (args) => {
T.page({ ...args, id });
});
socket.on('event', (args) => {
T.event({ ...args, id });
});
socket.on('subscribe', (room) => {
if (room in this.jobs) {
socket.join(room);
socket.emit('job');
socket.emit('progress', this.jobs[room].last_message);
}
});
});
}
}

25
packages/nocodb-nest/src/strategies/jwt.strategy.ts

@ -1,31 +1,24 @@
import { Injectable, UnauthorizedException } from '@nestjs/common'; import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport'; import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt'; import { ExtractJwt, Strategy } from 'passport-jwt';
import { OrgUserRoles } from '../../../nocodb-sdk'; import { OrgUserRoles } from 'nocodb-sdk';
import NocoCache from '../cache/NocoCache'; import NocoCache from '../cache/NocoCache';
import { ProjectUser, User } from '../models'; import { ProjectUser, User } from '../models';
import { genJwt } from '../modules/users/helpers' import { genJwt } from '../modules/users/helpers';
import Noco from '../Noco' import Noco from '../Noco';
import extractRolesObj from '../utils/extractRolesObj'; import extractRolesObj from '../utils/extractRolesObj';
import { CacheGetType, CacheScope } from '../utils/globals'; import { CacheGetType, CacheScope } from '../utils/globals';
import { jwtConstants } from '../modules/auth/constants'; import { jwtConstants } from '../modules/auth/constants';
import { UsersService } from '../modules/users/users.service'; import { UsersService } from '../modules/users/users.service';
import NcConfigFactory from '../utils/NcConfigFactory' import NcConfigFactory from '../utils/NcConfigFactory';
@Injectable() @Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) { export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(options, private userService: UsersService, ) { constructor(options, private userService: UsersService) {
super( super({
options expiresIn: '10h',
) ...options,
// { });
// // ignoreExpiration: false,
// jwtFromRequest: ExtractJwt.fromHeader('xc-auth'),
// expiresIn: '10h',
// passReqToCallback: true,
// secretOrKey: process.env.NC_AUTH_JWT_SECRET ?? 'temporary-key'
//
// });
} }
async validate(req: any, jwtPayload: any) { async validate(req: any, jwtPayload: any) {

2
packages/nocodb-nest/src/strategies/local.strategy.ts

@ -3,7 +3,7 @@ import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { AuthService } from '../modules/auth/auth.service'; import { AuthService } from '../modules/auth/auth.service';
import extractRolesObj from '../utils/extractRolesObj'; import extractRolesObj from '../utils/extractRolesObj';
import { NcError } from '../../../nocodb/src/lib/meta/helpers/catchError'; import { NcError } from '../helpers/catchError';
@Injectable() @Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) { export class LocalStrategy extends PassportStrategy(Strategy) {

Loading…
Cancel
Save