diff --git a/packages/nc-gui/components/smartsheet/Gallery.vue b/packages/nc-gui/components/smartsheet/Gallery.vue index f4f4a160f4..5b0a2f5088 100644 --- a/packages/nc-gui/components/smartsheet/Gallery.vue +++ b/packages/nc-gui/components/smartsheet/Gallery.vue @@ -7,6 +7,7 @@ import { IsFormInj, IsGalleryInj, IsGridInj, + IsPublicInj, MetaInj, NavigateDir, OpenNewRecordFormHookInj, @@ -62,6 +63,8 @@ provide(IsGridInj, ref(false)) provide(PaginationDataInj, paginationData) provide(ChangePageInj, changePage) +const isPublic = inject(IsPublicInj, ref(false)) + const fields = inject(FieldsInj, ref([])) const route = useRoute() @@ -125,6 +128,10 @@ const attachments = (record: any): Attachment[] => { } const expandForm = (row: RowType, state?: Record) => { + if (isPublic.value) { + return + } + const rowId = extractPkFromRow(row.row, meta.value!.columns!) if (rowId) { @@ -234,6 +241,7 @@ watch(view, async (nextView) => { :data-testid="`nc-gallery-card-${record.row.id}`" @click="expandFormClick($event, record)" @contextmenu="showContextMenu($event, { row: rowIndex })" + :style="isPublic ? { cursor: 'default' } : { cursor: 'pointer' }" > -
+
) { }) .catch(async (error) => { await state.signOut() - // todo: handle new user - navigateTo('/signIn') + if (!route.meta.public) navigateTo('/signIn') return Promise.reject(error) }) diff --git a/packages/nc-gui/composables/useMultiSelect/convertCellData.ts b/packages/nc-gui/composables/useMultiSelect/convertCellData.ts index 47eb6e8155..a6bb90685a 100644 --- a/packages/nc-gui/composables/useMultiSelect/convertCellData.ts +++ b/packages/nc-gui/composables/useMultiSelect/convertCellData.ts @@ -7,7 +7,6 @@ import { parseProp } from '#imports' export default function convertCellData( args: { from: UITypes; to: UITypes; value: any; column: ColumnType; appInfo: AppInfo }, isMysql = false, - isXcdbBase = false, ) { const { from, to, value } = args if (from === to && ![UITypes.Attachment, UITypes.Date, UITypes.DateTime, UITypes.Time, UITypes.Year].includes(to)) { diff --git a/packages/nc-gui/composables/useMultiSelect/index.ts b/packages/nc-gui/composables/useMultiSelect/index.ts index d217b0249d..b5d5fb4226 100644 --- a/packages/nc-gui/composables/useMultiSelect/index.ts +++ b/packages/nc-gui/composables/useMultiSelect/index.ts @@ -55,7 +55,7 @@ export function useMultiSelect( const { appInfo } = useGlobal() - const { isMysql, isXcdbBase } = useProject() + const { isMysql } = useProject() let clipboardContext = $ref<{ value: any; uidt: UITypes } | null>(null) @@ -359,7 +359,6 @@ export function useMultiSelect( appInfo: unref(appInfo), }, isMysql(meta.value?.base_id), - isXcdbBase(meta.value?.base_id), ) e.preventDefault() @@ -394,7 +393,6 @@ export function useMultiSelect( appInfo: unref(appInfo), }, isMysql(meta.value?.base_id), - isXcdbBase(meta.value?.base_id), ) e.preventDefault() syncCellData?.(activeCell) diff --git a/packages/nc-gui/context/index.ts b/packages/nc-gui/context/index.ts index 0ea07a931e..1b8e84baa0 100644 --- a/packages/nc-gui/context/index.ts +++ b/packages/nc-gui/context/index.ts @@ -38,3 +38,4 @@ export const ToggleDialogInj: InjectionKey = Symbol('toggle-dialog-inj export const CellClickHookInj: InjectionKey | undefined> = Symbol('cell-click-injection') export const SaveRowInj: InjectionKey<(() => void) | undefined> = Symbol('save-row-injection') export const CurrentCellInj: InjectionKey> = Symbol('current-cell-injection') +export const IsUnderLookupInj: InjectionKey> = Symbol('is-under-lookup-injection') diff --git a/packages/nc-gui/package-lock.json b/packages/nc-gui/package-lock.json index fde8f2ee35..f833effd95 100644 --- a/packages/nc-gui/package-lock.json +++ b/packages/nc-gui/package-lock.json @@ -30,7 +30,7 @@ "leaflet.markercluster": "^1.5.3", "locale-codes": "^1.3.1", "monaco-editor": "^0.33.0", - "nocodb-sdk": "0.108.0-beta.0", + "nocodb-sdk": "file:../nocodb-sdk", "papaparse": "^5.3.2", "pinia": "^2.0.33", "qrcode": "^1.5.1", @@ -111,7 +111,6 @@ }, "../nocodb-sdk": { "version": "0.108.0-beta.0", - "extraneous": true, "license": "AGPL-3.0-or-later", "dependencies": { "axios": "^0.21.1", @@ -8776,6 +8775,7 @@ "version": "1.15.1", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", + "devOptional": true, "funding": [ { "type": "individual", @@ -12294,21 +12294,8 @@ } }, "node_modules/nocodb-sdk": { - "version": "0.108.0-beta.0", - "resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.108.0-beta.0.tgz", - "integrity": "sha512-nLbOOVGxx3KqCvEKHhPE4/ZBS47gBOeo2P6mefo2J0jTVUVq6L7b8iIh5mvvmsXp+UOPxtxfcdKlYiTF++bYtw==", - "dependencies": { - "axios": "^0.21.1", - "jsep": "^1.3.6" - } - }, - "node_modules/nocodb-sdk/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dependencies": { - "follow-redirects": "^1.14.0" - } + "resolved": "../nocodb-sdk", + "link": true }, "node_modules/node-abi": { "version": "3.23.0", @@ -24810,7 +24797,8 @@ "follow-redirects": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==" + "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", + "devOptional": true }, "form-data": { "version": "4.0.0", @@ -27360,22 +27348,22 @@ } }, "nocodb-sdk": { - "version": "0.108.0-beta.0", - "resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.108.0-beta.0.tgz", - "integrity": "sha512-nLbOOVGxx3KqCvEKHhPE4/ZBS47gBOeo2P6mefo2J0jTVUVq6L7b8iIh5mvvmsXp+UOPxtxfcdKlYiTF++bYtw==", + "version": "file:../nocodb-sdk", "requires": { + "@typescript-eslint/eslint-plugin": "^4.0.1", + "@typescript-eslint/parser": "^4.0.1", "axios": "^0.21.1", - "jsep": "^1.3.6" - }, - "dependencies": { - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "requires": { - "follow-redirects": "^1.14.0" - } - } + "cspell": "^4.1.0", + "eslint": "^7.8.0", + "eslint-config-prettier": "^6.11.0", + "eslint-plugin-eslint-comments": "^3.2.0", + "eslint-plugin-functional": "^3.0.2", + "eslint-plugin-import": "^2.22.0", + "eslint-plugin-prettier": "^4.0.0", + "jsep": "^1.3.6", + "npm-run-all": "^4.1.5", + "prettier": "^2.1.1", + "typescript": "^4.0.2" } }, "node-abi": { diff --git a/packages/nc-gui/package.json b/packages/nc-gui/package.json index a2a7b215db..847017b499 100644 --- a/packages/nc-gui/package.json +++ b/packages/nc-gui/package.json @@ -54,7 +54,7 @@ "leaflet.markercluster": "^1.5.3", "locale-codes": "^1.3.1", "monaco-editor": "^0.33.0", - "nocodb-sdk": "0.108.0-beta.0", + "nocodb-sdk": "file:../nocodb-sdk", "papaparse": "^5.3.2", "pinia": "^2.0.33", "qrcode": "^1.5.1", diff --git a/packages/nc-gui/pages/index/index/index.vue b/packages/nc-gui/pages/index/index/index.vue index 486786b72b..8aeedb8bc6 100644 --- a/packages/nc-gui/pages/index/index/index.vue +++ b/packages/nc-gui/pages/index/index/index.vue @@ -308,6 +308,7 @@ const copyProjectMeta = async () => {
{ - + { + async get(key: string, type: string): Promise { log(`RedisCacheMgr::get: getting key ${key} with type ${type}`); if (type === CacheGetType.TYPE_ARRAY) { return this.client.smembers(key); @@ -135,7 +135,7 @@ export default class RedisCacheMgr extends CacheMgr { // e.g. arr = ["nc:::", "nc:::"] const arr = (await this.get(key, CacheGetType.TYPE_ARRAY)) || []; log(`RedisCacheMgr::getList: getting list with key ${key}`); - const isNoneList = arr.length && arr[0] === 'NONE'; + const isNoneList = arr.length && arr.includes('NONE'); if (isNoneList) { return Promise.resolve({ @@ -248,7 +248,7 @@ export default class RedisCacheMgr extends CacheMgr { : `${this.prefix}:${scope}:${subListKeys.join(':')}:list`; log(`RedisCacheMgr::appendToList: append key ${key} to ${listKey}`); let list = (await this.get(listKey, CacheGetType.TYPE_ARRAY)) || []; - if (list.length && list[0] === 'NONE') { + if (list.length && list.includes('NONE')) { list = []; await this.del(listKey); } diff --git a/packages/nocodb/src/cache/RedisMockCacheMgr.ts b/packages/nocodb/src/cache/RedisMockCacheMgr.ts index c4249ae484..8866895674 100644 --- a/packages/nocodb/src/cache/RedisMockCacheMgr.ts +++ b/packages/nocodb/src/cache/RedisMockCacheMgr.ts @@ -40,7 +40,7 @@ export default class RedisMockCacheMgr extends CacheMgr { } // @ts-ignore - async get(key: string, type: string, config?: any): Promise { + async get(key: string, type: string): Promise { log(`RedisMockCacheMgr::get: getting key ${key} with type ${type}`); if (type === CacheGetType.TYPE_ARRAY) { return this.client.smembers(key); diff --git a/packages/nocodb/src/controllers/api-tokens.controller.ts b/packages/nocodb/src/controllers/api-tokens.controller.ts index 78335e809a..5460edf132 100644 --- a/packages/nocodb/src/controllers/api-tokens.controller.ts +++ b/packages/nocodb/src/controllers/api-tokens.controller.ts @@ -9,7 +9,6 @@ import { Request, UseGuards, } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; import { GlobalGuard } from '../guards/global/global.guard'; import { PagedResponseImpl } from '../helpers/PagedResponse'; import { diff --git a/packages/nocodb/src/controllers/attachments.controller.ts b/packages/nocodb/src/controllers/attachments.controller.ts index 69885be5be..92a13109f0 100644 --- a/packages/nocodb/src/controllers/attachments.controller.ts +++ b/packages/nocodb/src/controllers/attachments.controller.ts @@ -30,7 +30,6 @@ export class AttachmentsController { @UploadedFiles() files: Array, @Body() body: any, @Request() req: any, - @Query('path') path: string, ) { const attachments = await this.attachmentsService.upload({ files: files, diff --git a/packages/nocodb/src/controllers/audits.controller.ts b/packages/nocodb/src/controllers/audits.controller.ts index ce0eb18613..816fb8b04f 100644 --- a/packages/nocodb/src/controllers/audits.controller.ts +++ b/packages/nocodb/src/controllers/audits.controller.ts @@ -10,7 +10,6 @@ import { Request, UseGuards, } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; import { GlobalGuard } from '../guards/global/global.guard'; import { PagedResponseImpl } from '../helpers/PagedResponse'; import { diff --git a/packages/nocodb/src/controllers/bases.controller.ts b/packages/nocodb/src/controllers/bases.controller.ts index 28b45367a7..2363d170c0 100644 --- a/packages/nocodb/src/controllers/bases.controller.ts +++ b/packages/nocodb/src/controllers/bases.controller.ts @@ -10,7 +10,6 @@ import { UseGuards, } from '@nestjs/common'; import { BaseReqType } from 'nocodb-sdk'; -import { AuthGuard } from '@nestjs/passport'; import { GlobalGuard } from '../guards/global/global.guard'; import { PagedResponseImpl } from '../helpers/PagedResponse'; import { diff --git a/packages/nocodb/src/controllers/bulk-data-alias.controller.ts b/packages/nocodb/src/controllers/bulk-data-alias.controller.ts index e1202929c3..138941a4d7 100644 --- a/packages/nocodb/src/controllers/bulk-data-alias.controller.ts +++ b/packages/nocodb/src/controllers/bulk-data-alias.controller.ts @@ -10,7 +10,6 @@ import { Response, UseGuards, } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; import { GlobalGuard } from '../guards/global/global.guard'; import { Acl, diff --git a/packages/nocodb/src/controllers/columns.controller.ts b/packages/nocodb/src/controllers/columns.controller.ts index 764be4c4d1..eb9c4e6343 100644 --- a/packages/nocodb/src/controllers/columns.controller.ts +++ b/packages/nocodb/src/controllers/columns.controller.ts @@ -11,7 +11,6 @@ import { UseGuards, } from '@nestjs/common'; import { ColumnReqType } from 'nocodb-sdk'; -import { AuthGuard } from '@nestjs/passport'; import { GlobalGuard } from '../guards/global/global.guard'; import { Acl, diff --git a/packages/nocodb/src/controllers/data-alias-export.controller.ts b/packages/nocodb/src/controllers/data-alias-export.controller.ts index 42da30027d..7c3a4ad4fa 100644 --- a/packages/nocodb/src/controllers/data-alias-export.controller.ts +++ b/packages/nocodb/src/controllers/data-alias-export.controller.ts @@ -1,6 +1,5 @@ import { Controller, Get, Request, Response, UseGuards } from '@nestjs/common'; import * as XLSX from 'xlsx'; -import { AuthGuard } from '@nestjs/passport'; import { GlobalGuard } from '../guards/global/global.guard'; import { Acl, diff --git a/packages/nocodb/src/controllers/data-alias-nested.controller.ts b/packages/nocodb/src/controllers/data-alias-nested.controller.ts index 53c11f5f42..4edcd10a5d 100644 --- a/packages/nocodb/src/controllers/data-alias-nested.controller.ts +++ b/packages/nocodb/src/controllers/data-alias-nested.controller.ts @@ -8,7 +8,6 @@ import { Request, UseGuards, } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; import { GlobalGuard } from '../guards/global/global.guard'; import { Acl, @@ -131,7 +130,6 @@ export class DataAliasNestedController { @Param('projectName') projectName: string, @Param('tableName') tableName: string, @Param('refRowId') refRowId: string, - @Param('relationType') relationType: string, ) { await this.dataAliasNestedService.relationDataRemove({ columnName: columnName, @@ -158,7 +156,6 @@ export class DataAliasNestedController { @Param('projectName') projectName: string, @Param('tableName') tableName: string, @Param('refRowId') refRowId: string, - @Param('relationType') relationType: string, ) { await this.dataAliasNestedService.relationDataAdd({ columnName: columnName, diff --git a/packages/nocodb/src/controllers/data-alias.controller.ts b/packages/nocodb/src/controllers/data-alias.controller.ts index 296b0a12a8..b99348f07d 100644 --- a/packages/nocodb/src/controllers/data-alias.controller.ts +++ b/packages/nocodb/src/controllers/data-alias.controller.ts @@ -11,7 +11,6 @@ import { Response, UseGuards, } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; import { GlobalGuard } from '../guards/global/global.guard'; import { parseHrtimeToSeconds } from '../helpers'; import { diff --git a/packages/nocodb/src/controllers/filters.controller.ts b/packages/nocodb/src/controllers/filters.controller.ts index dc09b0c705..b842c77834 100644 --- a/packages/nocodb/src/controllers/filters.controller.ts +++ b/packages/nocodb/src/controllers/filters.controller.ts @@ -9,14 +9,12 @@ import { Post, UseGuards, } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; import { FilterReqType } from 'nocodb-sdk'; import { GlobalGuard } from '../guards/global/global.guard'; import { PagedResponseImpl } from '../helpers/PagedResponse'; import { Acl, ExtractProjectIdMiddleware, - UseAclMiddleware, } from '../middlewares/extract-project-id/extract-project-id.middleware'; import { FiltersService } from '../services/filters.service'; diff --git a/packages/nocodb/src/controllers/form-columns.controller.ts b/packages/nocodb/src/controllers/form-columns.controller.ts index fbb77e3cfa..960db32ca8 100644 --- a/packages/nocodb/src/controllers/form-columns.controller.ts +++ b/packages/nocodb/src/controllers/form-columns.controller.ts @@ -1,5 +1,4 @@ import { Body, Controller, Param, Patch, UseGuards } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; import { GlobalGuard } from '../guards/global/global.guard'; import { Acl, diff --git a/packages/nocodb/src/controllers/galleries.controller.ts b/packages/nocodb/src/controllers/galleries.controller.ts index bc95f07070..a951ed84d6 100644 --- a/packages/nocodb/src/controllers/galleries.controller.ts +++ b/packages/nocodb/src/controllers/galleries.controller.ts @@ -9,7 +9,6 @@ import { UseGuards, } from '@nestjs/common'; import { GalleryUpdateReqType, ViewCreateReqType } from 'nocodb-sdk'; -import { AuthGuard } from '@nestjs/passport'; import { GlobalGuard } from '../guards/global/global.guard'; import { Acl, diff --git a/packages/nocodb/src/controllers/grid-columns.controller.ts b/packages/nocodb/src/controllers/grid-columns.controller.ts index b799f24308..39559f407c 100644 --- a/packages/nocodb/src/controllers/grid-columns.controller.ts +++ b/packages/nocodb/src/controllers/grid-columns.controller.ts @@ -1,6 +1,5 @@ import { Body, Controller, Get, Param, Patch, UseGuards } from '@nestjs/common'; import { GridColumnReqType } from 'nocodb-sdk'; -import { AuthGuard } from '@nestjs/passport'; import { GlobalGuard } from '../guards/global/global.guard'; import { Acl, diff --git a/packages/nocodb/src/controllers/grids.controller.ts b/packages/nocodb/src/controllers/grids.controller.ts index 9026764fec..2e2da806e8 100644 --- a/packages/nocodb/src/controllers/grids.controller.ts +++ b/packages/nocodb/src/controllers/grids.controller.ts @@ -8,7 +8,6 @@ import { UseGuards, } from '@nestjs/common'; import { ViewCreateReqType } from 'nocodb-sdk'; -import { AuthGuard } from '@nestjs/passport'; import { GlobalGuard } from '../guards/global/global.guard'; import { Acl, diff --git a/packages/nocodb/src/controllers/maps.controller.ts b/packages/nocodb/src/controllers/maps.controller.ts index 422118aee1..fd5c88d18c 100644 --- a/packages/nocodb/src/controllers/maps.controller.ts +++ b/packages/nocodb/src/controllers/maps.controller.ts @@ -9,7 +9,6 @@ import { UseGuards, } from '@nestjs/common'; import { MapUpdateReqType, ViewCreateReqType } from 'nocodb-sdk'; -import { AuthGuard } from '@nestjs/passport'; import { GlobalGuard } from '../guards/global/global.guard'; import { Acl, diff --git a/packages/nocodb/src/controllers/meta-diffs.controller.ts b/packages/nocodb/src/controllers/meta-diffs.controller.ts index 6e281d7bf7..5db317e786 100644 --- a/packages/nocodb/src/controllers/meta-diffs.controller.ts +++ b/packages/nocodb/src/controllers/meta-diffs.controller.ts @@ -6,7 +6,6 @@ import { Post, UseGuards, } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; import { GlobalGuard } from '../guards/global/global.guard'; import { Acl, diff --git a/packages/nocodb/src/controllers/model-visibilities.controller.ts b/packages/nocodb/src/controllers/model-visibilities.controller.ts index dec2e45424..eaeb554110 100644 --- a/packages/nocodb/src/controllers/model-visibilities.controller.ts +++ b/packages/nocodb/src/controllers/model-visibilities.controller.ts @@ -8,7 +8,6 @@ import { Query, UseGuards, } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; import { GlobalGuard } from '../guards/global/global.guard'; import { Acl, diff --git a/packages/nocodb/src/controllers/old-datas/old-datas.controller.ts b/packages/nocodb/src/controllers/old-datas/old-datas.controller.ts index 91ef73f480..eb299fc4a3 100644 --- a/packages/nocodb/src/controllers/old-datas/old-datas.controller.ts +++ b/packages/nocodb/src/controllers/old-datas/old-datas.controller.ts @@ -11,7 +11,6 @@ import { Response, UseGuards, } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; import { GlobalGuard } from '../../guards/global/global.guard'; import { Acl, diff --git a/packages/nocodb/src/controllers/org-users.controller.ts b/packages/nocodb/src/controllers/org-users.controller.ts index 7ea86c037e..da860f7ca7 100644 --- a/packages/nocodb/src/controllers/org-users.controller.ts +++ b/packages/nocodb/src/controllers/org-users.controller.ts @@ -10,7 +10,6 @@ import { Request, UseGuards, } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; import { OrgUserRoles } from 'nocodb-sdk'; import { GlobalGuard } from '../guards/global/global.guard'; import { PagedResponseImpl } from '../helpers/PagedResponse'; diff --git a/packages/nocodb/src/controllers/plugins.controller.ts b/packages/nocodb/src/controllers/plugins.controller.ts index 59b5256cc1..4361ce2af3 100644 --- a/packages/nocodb/src/controllers/plugins.controller.ts +++ b/packages/nocodb/src/controllers/plugins.controller.ts @@ -14,11 +14,11 @@ import { Acl } from '../middlewares/extract-project-id/extract-project-id.middle import { PluginsService } from '../services/plugins.service'; // todo: move to a interceptor -const blockInCloudMw = (_req, res, next) => { - if (process.env.NC_CLOUD === 'true') { - res.status(403).send('Not allowed'); - } else next(); -}; +// const blockInCloudMw = (_req, res, next) => { +// if (process.env.NC_CLOUD === 'true') { +// res.status(403).send('Not allowed'); +// } else next(); +// }; @Controller() @UseGuards(GlobalGuard) diff --git a/packages/nocodb/src/controllers/project-users.controller.ts b/packages/nocodb/src/controllers/project-users.controller.ts index ca97e8b02c..4917f04704 100644 --- a/packages/nocodb/src/controllers/project-users.controller.ts +++ b/packages/nocodb/src/controllers/project-users.controller.ts @@ -11,7 +11,6 @@ import { UseGuards, } from '@nestjs/common'; import { ProjectUserReqType } from 'nocodb-sdk'; -import { AuthGuard } from '@nestjs/passport'; import { GlobalGuard } from '../guards/global/global.guard'; import { Acl, diff --git a/packages/nocodb/src/controllers/projects.controller.ts b/packages/nocodb/src/controllers/projects.controller.ts index 7b905cba2e..2599430f1b 100644 --- a/packages/nocodb/src/controllers/projects.controller.ts +++ b/packages/nocodb/src/controllers/projects.controller.ts @@ -11,15 +11,13 @@ import { Request, UseGuards, } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; import isDocker from 'is-docker'; import { ProjectReqType } from 'nocodb-sdk'; import { GlobalGuard } from '../guards/global/global.guard'; import { PagedResponseImpl } from '../helpers/PagedResponse'; import { + Acl, ExtractProjectIdMiddleware, - UseAclMiddleware, - UseProjectIdMiddleware, } from '../middlewares/extract-project-id/extract-project-id.middleware'; import Noco from '../Noco'; import { packageVersion } from '../utils/packageVersion'; @@ -31,9 +29,7 @@ import type { ProjectType } from 'nocodb-sdk'; export class ProjectsController { constructor(private readonly projectsService: ProjectsService) {} - @UseAclMiddleware({ - permissionName: 'projectList', - }) + @Acl('projectList') @Get('/api/v1/db/meta/projects/') async list(@Query() queryParams: Record, @Request() req) { const projects = await this.projectsService.projectList({ @@ -57,7 +53,7 @@ export class ProjectsController { PackageVersion: packageVersion, }; } - + @Acl('projectGet') @Get('/api/v1/db/meta/projects/:projectId') async projectGet(@Param('projectId') projectId: string) { const project = await this.projectsService.getProjectWithInfo({ @@ -68,7 +64,7 @@ export class ProjectsController { return project; } - + @Acl('projectUpdate') @Patch('/api/v1/db/meta/projects/:projectId') async projectUpdate( @Param('projectId') projectId: string, @@ -82,6 +78,7 @@ export class ProjectsController { return project; } + @Acl('projectDelete') @Delete('/api/v1/db/meta/projects/:projectId') async projectDelete(@Param('projectId') projectId: string) { const deleted = await this.projectsService.projectSoftDelete({ @@ -91,6 +88,7 @@ export class ProjectsController { return deleted; } + @Acl('projectCreate') @Post('/api/v1/db/meta/projects') @HttpCode(200) async projectCreate(@Body() projectBody: ProjectReqType, @Request() req) { @@ -102,66 +100,3 @@ export class ProjectsController { return project; } } - -/* -// // Project CRUD - - - -export async function projectCost(req, res) { - let cost = 0; - const project = await Project.getWithInfo(req.params.projectId); - - for (const base of project.bases) { - const sqlClient = await NcConnectionMgrv2.getSqlClient(base); - const userCount = await ProjectUser.getUsersCount(req.query); - const recordCount = (await sqlClient.totalRecords())?.data.TotalRecords; - - if (recordCount > 100000) { - // 36,000 or $79/user/month - cost = Math.max(36000, 948 * userCount); - } else if (recordCount > 50000) { - // $36,000 or $50/user/month - cost = Math.max(36000, 600 * userCount); - } else if (recordCount > 10000) { - // $240/user/yr - cost = Math.min(240 * userCount, 36000); - } else if (recordCount > 1000) { - // $120/user/yr - cost = Math.min(120 * userCount, 36000); - } - } - - T.event({ - event: 'a:project:cost', - data: { - cost, - }, - }); - - res.json({ cost }); -} - -export async function hasEmptyOrNullFilters(req, res) { - res.json(await Filter.hasEmptyOrNullFilters(req.params.projectId)); -} - -export default (router) => { - - - router.get( - '/api/v1/db/meta/projects/:projectId/cost', - metaApiMetrics, - ncMetaAclMw(projectCost, 'projectCost') - ); - - - - router.get( - '/api/v1/db/meta/projects/:projectId/has-empty-or-null-filters', - metaApiMetrics, - ncMetaAclMw(hasEmptyOrNullFilters, 'hasEmptyOrNullFilters') - ); -}; - -* */ diff --git a/packages/nocodb/src/controllers/shared-bases.controller.ts b/packages/nocodb/src/controllers/shared-bases.controller.ts index 02d55bf444..404e934e2f 100644 --- a/packages/nocodb/src/controllers/shared-bases.controller.ts +++ b/packages/nocodb/src/controllers/shared-bases.controller.ts @@ -10,7 +10,6 @@ import { Request, UseGuards, } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; import { GlobalGuard } from '../guards/global/global.guard'; import { Acl, diff --git a/packages/nocodb/src/controllers/sorts.controller.ts b/packages/nocodb/src/controllers/sorts.controller.ts index 974d9b426c..5f5829fe67 100644 --- a/packages/nocodb/src/controllers/sorts.controller.ts +++ b/packages/nocodb/src/controllers/sorts.controller.ts @@ -9,7 +9,6 @@ import { Post, UseGuards, } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; import { SortReqType } from 'nocodb-sdk'; import { GlobalGuard } from '../guards/global/global.guard'; import { PagedResponseImpl } from '../helpers/PagedResponse'; diff --git a/packages/nocodb/src/controllers/tables.controller.ts b/packages/nocodb/src/controllers/tables.controller.ts index 2a214956a1..4b2f709f35 100644 --- a/packages/nocodb/src/controllers/tables.controller.ts +++ b/packages/nocodb/src/controllers/tables.controller.ts @@ -11,7 +11,6 @@ import { Request, UseGuards, } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; import { TableReqType } from 'nocodb-sdk'; import { GlobalGuard } from '../guards/global/global.guard'; import extractRolesObj from '../utils/extractRolesObj'; diff --git a/packages/nocodb/src/controllers/users/users.controller.ts b/packages/nocodb/src/controllers/users/users.controller.ts index 8ffb6dbf6a..0c8f153c78 100644 --- a/packages/nocodb/src/controllers/users/users.controller.ts +++ b/packages/nocodb/src/controllers/users/users.controller.ts @@ -1,5 +1,3 @@ -import { promisify } from 'util'; -import { AuditOperationSubTypes, AuditOperationTypes } from 'nocodb-sdk'; import { Body, Controller, @@ -19,23 +17,17 @@ import { Acl, ExtractProjectIdMiddleware, } from '../../middlewares/extract-project-id/extract-project-id.middleware'; -import Noco from '../../Noco'; -import { GoogleStrategy } from '../../strategies/google.strategy/google.strategy'; -import extractRolesObj from '../../utils/extractRolesObj'; -import { Audit, User } from '../../models'; +import { User } from '../../models'; import { - genJwt, randomTokenString, setTokenCookie, } from '../../services/users/helpers'; import { UsersService } from '../../services/users/users.service'; +import extractRolesObj from '../../utils/extractRolesObj'; @Controller() export class UsersController { - constructor( - private readonly usersService: UsersService, - private googleStrategy: GoogleStrategy, - ) {} + constructor(private readonly usersService: UsersService) {} @Post([ '/auth/user/signup', @@ -59,56 +51,14 @@ export class UsersController { '/api/v1/auth/token/refresh', ]) @HttpCode(200) - async refreshToken(@Request() req: any, @Request() res: any): Promise { - return await this.usersService.refreshToken({ - body: req.body, - req, - res, - }); - } - - async 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 = randomTokenString(); - - if (!user.token_version) { - user.token_version = 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: AuditOperationTypes.AUTHENTICATION, - op_sub_type: AuditOperationSubTypes.SIGNIN, - user: user.email, - ip: req.clientIp, - description: auditDescription, - }); - - res.json({ - token: genJwt(user, Noco.getConfig()), - } as any); - } catch (e) { - console.log(e); - throw e; - } + async refreshToken(@Request() req: any, @Response() res: any): Promise { + res.json( + await this.usersService.refreshToken({ + body: req.body, + req, + res, + }), + ); } @Post([ @@ -118,8 +68,9 @@ export class UsersController { ]) @UseGuards(AuthGuard('local')) @HttpCode(200) - async signin(@Request() req) { - return this.usersService.login(req.user); + async signin(@Request() req, @Response() res) { + await this.setRefreshToken({ req, res }); + res.json(this.usersService.login(req.user)); } @Post('/api/v1/auth/user/signout') @@ -136,18 +87,15 @@ export class UsersController { @Post(`/auth/google/genTokenByCode`) @HttpCode(200) @UseGuards(AuthGuard('google')) - async googleSignin(@Request() req) { - return this.usersService.login(req.user); + async googleSignin(@Request() req, @Response() res) { + await this.setRefreshToken({ req, res }); + res.json(this.usersService.login(req.user)); } @Get('/auth/google') @UseGuards(AuthGuard('google')) - googleAuthenticate(@Request() req) { - // this.googleStrategy.authenticate(req, { - // scope: ['profile', 'email'], - // state: req.query.state, - // callbackURL: req.ncSiteUrl + Noco.getConfig().dashboardPath, - // }); + googleAuthenticate() { + // google strategy will take care the request } @Get(['/auth/user/me', '/api/v1/db/auth/user/me', '/api/v1/auth/user/me']) @@ -168,7 +116,7 @@ export class UsersController { @UseGuards(GlobalGuard) @Acl('passwordChange') @HttpCode(200) - async passwordChange(@Request() req: any, @Body() body: any): Promise { + async passwordChange(@Request() req: any): Promise { if (!(req as any).isAuthenticated()) { NcError.forbidden('Not allowed'); } @@ -188,7 +136,7 @@ export class UsersController { '/api/v1/auth/password/forgot', ]) @HttpCode(200) - async passwordForgot(@Request() req: any, @Body() body: any): Promise { + async passwordForgot(@Request() req: any): Promise { await this.usersService.passwordForgot({ siteUrl: (req as any).ncSiteUrl, body: req.body, @@ -269,4 +217,27 @@ export class UsersController { return res.status(400).json({ msg: e.message }); } } + + async setRefreshToken({ res, req }) { + const userId = req.user?.id; + + if (!userId) return; + + const user = await User.get(userId); + + if (!user) return; + + const refreshToken = randomTokenString(); + + if (!user.token_version) { + user.token_version = randomTokenString(); + } + + await User.update(user.id, { + refresh_token: refreshToken, + email: user.email, + token_version: user.token_version, + }); + setTokenCookie(res, refreshToken); + } } diff --git a/packages/nocodb/src/controllers/view-columns.controller.ts b/packages/nocodb/src/controllers/view-columns.controller.ts index a8b272ce40..92a757e927 100644 --- a/packages/nocodb/src/controllers/view-columns.controller.ts +++ b/packages/nocodb/src/controllers/view-columns.controller.ts @@ -8,8 +8,7 @@ import { Post, UseGuards, } from '@nestjs/common'; -import { ColumnReqType, ViewColumnReqType } from 'nocodb-sdk'; -import { AuthGuard } from '@nestjs/passport'; +import { ViewColumnReqType } from 'nocodb-sdk'; import { GlobalGuard } from '../guards/global/global.guard'; import { PagedResponseImpl } from '../helpers/PagedResponse'; import { diff --git a/packages/nocodb/src/db/BaseModelSql.ts b/packages/nocodb/src/db/BaseModelSql.ts index 5374056ec3..dc628fa321 100644 --- a/packages/nocodb/src/db/BaseModelSql.ts +++ b/packages/nocodb/src/db/BaseModelSql.ts @@ -1613,7 +1613,7 @@ class BaseModelSql extends BaseModel { } } - async nestedRead(id, { where, fields: fields1, f, ...rest }, trx = null) { + async nestedRead(id, { fields: fields1, f, ...rest }, trx = null) { rest = Object.assign({}, this.defaultNestedQueryParams, rest); const { hm: childs = '', bt: parents = '', mm: many = '' } = rest; @@ -1852,7 +1852,7 @@ class BaseModelSql extends BaseModel { return null; } // @ts-ignore - const { tn, cn, vtn, vcn, vrcn, rtn, rcn } = + const { vtn, vcn, vrcn, rtn, rcn } = this.manyToManyRelations.find(({ vtn }) => assoc === vtn) || {}; const childModel = this.dbModels[rtn]; @@ -1894,7 +1894,7 @@ class BaseModelSql extends BaseModel { return null; } // @ts-ignore - const { tn, cn, vtn, vcn, vrcn, rtn, rcn } = + const { vtn, vcn, vrcn, rtn, rcn } = this.manyToManyRelations.find(({ vtn }) => assoc === vtn) || {}; const childModel = this.dbModels[rtn]; diff --git a/packages/nocodb/src/db/BaseModelSqlv2.ts b/packages/nocodb/src/db/BaseModelSqlv2.ts index 1d8dd24a1f..86e2a96431 100644 --- a/packages/nocodb/src/db/BaseModelSqlv2.ts +++ b/packages/nocodb/src/db/BaseModelSqlv2.ts @@ -19,16 +19,7 @@ import DOMPurify from 'isomorphic-dompurify'; import { v4 as uuidv4 } from 'uuid'; import { NcError } from '../helpers/catchError'; import getAst from '../helpers/getAst'; -import { - Audit, - Base, - Column, - Filter, - Model, - Project, - Sort, - View, -} from '../models'; +import { Audit, Column, Filter, Model, Project, Sort, View } from '../models'; import { sanitize, unsanitize } from '../helpers/sqlSanitize'; import { COMPARISON_OPS, @@ -57,7 +48,7 @@ import type { SelectOption, } from '../models'; import type { Knex } from 'knex'; -import type { BoolType, SortType } from 'nocodb-sdk'; +import type { SortType } from 'nocodb-sdk'; dayjs.extend(utc); dayjs.extend(timezone); @@ -1361,12 +1352,6 @@ class BaseModelSqlv2 { const columns = await this.model.getColumns(); for (const column of columns) { switch (column.uidt) { - case UITypes.Rollup: - { - // @ts-ignore - const colOptions: RollupColumn = await column.getColOptions(); - } - break; case UITypes.Lookup: { // @ts-ignore diff --git a/packages/nocodb/src/db/CustomKnex.ts b/packages/nocodb/src/db/CustomKnex.ts index c9c38a9bc9..6217bad256 100644 --- a/packages/nocodb/src/db/CustomKnex.ts +++ b/packages/nocodb/src/db/CustomKnex.ts @@ -1,6 +1,6 @@ import { Knex, knex } from 'knex'; import { SnowflakeClient } from 'nc-help'; -import pg, { types } from 'pg'; +import { types } from 'pg'; import dayjs from 'dayjs'; import Filter from '../models/Filter'; import type { FilterType } from 'nocodb-sdk'; diff --git a/packages/nocodb/src/db/conditionV2.ts b/packages/nocodb/src/db/conditionV2.ts index 810c4ec05e..4234c91a08 100644 --- a/packages/nocodb/src/db/conditionV2.ts +++ b/packages/nocodb/src/db/conditionV2.ts @@ -1,5 +1,5 @@ import { isNumericCol, RelationTypes, UITypes } from 'nocodb-sdk'; -import dayjs, { extend } from 'dayjs'; +import dayjs from 'dayjs'; // import customParseFormat from 'dayjs/plugin/customParseFormat.js'; import Filter from '../models/Filter'; import { sanitize } from '../helpers/sqlSanitize'; diff --git a/packages/nocodb/src/db/sql-client/lib/SqlClientFactory.ts b/packages/nocodb/src/db/sql-client/lib/SqlClientFactory.ts index 7426582c1b..a15514c839 100644 --- a/packages/nocodb/src/db/sql-client/lib/SqlClientFactory.ts +++ b/packages/nocodb/src/db/sql-client/lib/SqlClientFactory.ts @@ -1,7 +1,5 @@ import fs from 'fs'; import { promisify } from 'util'; -import Noco from '../../../Noco'; -import SqlClientFactoryEE from './ee/SqlClientFactoryEE'; import MySqlClient from './mysql/MysqlClient'; import MssqlClient from './mssql/MssqlClient'; import OracleClient from './oracle/OracleClient'; diff --git a/packages/nocodb/src/interceptors/is-upload-allowed/is-upload-allowed.interceptor.ts b/packages/nocodb/src/interceptors/is-upload-allowed/is-upload-allowed.interceptor.ts index c3e8c75dcf..99c0f09e5a 100644 --- a/packages/nocodb/src/interceptors/is-upload-allowed/is-upload-allowed.interceptor.ts +++ b/packages/nocodb/src/interceptors/is-upload-allowed/is-upload-allowed.interceptor.ts @@ -1,6 +1,5 @@ import { Injectable } from '@nestjs/common'; import { OrgUserRoles, ProjectRoles } from 'nocodb-sdk'; -import { throwError } from 'rxjs'; import { NcError } from '../../helpers/catchError'; import Noco from '../../Noco'; import extractRolesObj from '../../utils/extractRolesObj'; diff --git a/packages/nocodb/src/middlewares/extract-project-id/extract-project-id.middleware.ts b/packages/nocodb/src/middlewares/extract-project-id/extract-project-id.middleware.ts index 56e3e56d50..d797e146c7 100644 --- a/packages/nocodb/src/middlewares/extract-project-id/extract-project-id.middleware.ts +++ b/packages/nocodb/src/middlewares/extract-project-id/extract-project-id.middleware.ts @@ -1,10 +1,7 @@ -import { promisify } from 'util'; import { Injectable, SetMetadata, UseInterceptors } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; -import { NextFunction, Request, Response } from 'express'; import { OrgUserRoles } from 'nocodb-sdk'; -import passport from 'passport'; -import { map, throwError } from 'rxjs'; +import { map } from 'rxjs'; import { Column, Filter, @@ -19,8 +16,7 @@ import { } from '../../models'; import extractRolesObj from '../../utils/extractRolesObj'; import projectAcl from '../../utils/projectAcl'; -import catchError, { NcError } from '../catchError'; -import extractProjectIdAndAuthenticate from '../extractProjectIdAndAuthenticate'; +import { NcError } from '../catchError'; import type { Observable } from 'rxjs'; import type { CallHandler, @@ -216,7 +212,6 @@ export class AclMiddleware implements NestInterceptor { ); const req = context.switchToHttp().getRequest(); - const res = context.switchToHttp().getResponse(); req.customProperty = 'This is a custom property'; const roles: Record = extractRolesObj(req.user?.roles); diff --git a/packages/nocodb/src/models/Model.ts b/packages/nocodb/src/models/Model.ts index d12427d846..0826fd538a 100644 --- a/packages/nocodb/src/models/Model.ts +++ b/packages/nocodb/src/models/Model.ts @@ -16,7 +16,6 @@ import { sanitize } from '../helpers/sqlSanitize'; import { extractProps } from '../helpers/extractProps'; import Audit from './Audit'; import View from './View'; -import Base from './Base'; import Column from './Column'; import type { BoolType, TableReqType, TableType } from 'nocodb-sdk'; import type { XKnex } from '../db/CustomKnex'; @@ -471,7 +470,6 @@ export default class Model implements TableType { knex, ) { const insertObj = {}; - const base = await Base.get(this.base_id); for (const col of await this.getColumns()) { if (isVirtualCol(col)) continue; let val = diff --git a/packages/nocodb/src/models/ProjectUser.ts b/packages/nocodb/src/models/ProjectUser.ts index f3d8897541..5042466fbf 100644 --- a/packages/nocodb/src/models/ProjectUser.ts +++ b/packages/nocodb/src/models/ProjectUser.ts @@ -174,11 +174,6 @@ export default class ProjectUser { } static async delete(projectId: string, userId: string, ncMeta = Noco.ncMeta) { - // await NocoCache.deepDel( - // CacheScope.PROJECT_USER, - // `${CacheScope.PROJECT_USER}:${projectId}:${userId}`, - // CacheDelDirection.CHILD_TO_PARENT - // ); const { email } = await ncMeta.metaGet2(null, null, MetaTable.USERS, { id: userId, }); @@ -194,11 +189,16 @@ export default class ProjectUser { const { isNoneList } = cachedList; if (!isNoneList && cachedProjectList?.length) { cachedProjectList = cachedProjectList.filter((p) => p.id !== projectId); - await NocoCache.setList( - CacheScope.USER_PROJECT, - [userId], - cachedProjectList, - ); + // delete the whole list first so that the old one won't be included + await NocoCache.del(`${CacheScope.USER_PROJECT}:${userId}:list`); + if (cachedProjectList.length > 0) { + // set the updated list (i.e. excluding the to-be-deleted project id) + await NocoCache.setList( + CacheScope.USER_PROJECT, + [userId], + cachedProjectList, + ); + } } await NocoCache.del(`${CacheScope.PROJECT_USER}:${projectId}:${userId}`); diff --git a/packages/nocodb/src/modules/datas/helpers.ts b/packages/nocodb/src/modules/datas/helpers.ts index 271535c9a6..4718d78dc9 100644 --- a/packages/nocodb/src/modules/datas/helpers.ts +++ b/packages/nocodb/src/modules/datas/helpers.ts @@ -12,7 +12,6 @@ import NcConnectionMgrv2 from '../../utils/common/NcConnectionMgrv2'; import type { BaseModelSqlv2 } from '../../db/BaseModelSqlv2'; import type LinkToAnotherRecordColumn from '../../models/LinkToAnotherRecordColumn'; import type LookupColumn from '../../models/LookupColumn'; -import type { Request } from 'express'; export interface PathParams { projectName: string; diff --git a/packages/nocodb/src/modules/jobs/jobs/at-import/helpers/readAndProcessData.ts b/packages/nocodb/src/modules/jobs/jobs/at-import/helpers/readAndProcessData.ts index 2bd3d627c6..659470d00c 100644 --- a/packages/nocodb/src/modules/jobs/jobs/at-import/helpers/readAndProcessData.ts +++ b/packages/nocodb/src/modules/jobs/jobs/at-import/helpers/readAndProcessData.ts @@ -21,14 +21,12 @@ async function readAllData({ fields, base, logBasic = (_str) => {}, - services, }: { table: { title?: string }; fields?; base: AirtableBase; logBasic?: (string) => void; logDetailed?: (string) => void; - services: AirtableImportContext; }): Promise { return new Promise((resolve, reject) => { let data = null; @@ -229,7 +227,6 @@ export async function importLTARData({ base, logDetailed, logBasic, - services, })); const modelMeta: any = diff --git a/packages/nocodb/src/modules/users/users.module.ts b/packages/nocodb/src/modules/users/users.module.ts index bb1da81911..7ee9dc9432 100644 --- a/packages/nocodb/src/modules/users/users.module.ts +++ b/packages/nocodb/src/modules/users/users.module.ts @@ -1,9 +1,6 @@ import { Module } from '@nestjs/common'; import { PassportModule } from '@nestjs/passport'; -import { - GoogleStrategy, - GoogleStrategyProvider, -} from '../../strategies/google.strategy/google.strategy'; +import { GoogleStrategyProvider } from '../../strategies/google.strategy/google.strategy'; import { GlobalModule } from '../global/global.module'; import { UsersService } from '../../services/users/users.service'; import { UsersController } from '../../controllers/users/users.controller'; diff --git a/packages/nocodb/src/run/docker.ts b/packages/nocodb/src/run/docker.ts index d0b513dbd6..a1b2634d57 100644 --- a/packages/nocodb/src/run/docker.ts +++ b/packages/nocodb/src/run/docker.ts @@ -1,4 +1,3 @@ -import axios from 'axios'; import cors from 'cors'; import express from 'express'; import Noco from '../Noco'; diff --git a/packages/nocodb/src/run/dockerRunPG_CyQuick.ts b/packages/nocodb/src/run/dockerRunPG_CyQuick.ts index a8429f4ffc..c8a8131280 100644 --- a/packages/nocodb/src/run/dockerRunPG_CyQuick.ts +++ b/packages/nocodb/src/run/dockerRunPG_CyQuick.ts @@ -1,7 +1,6 @@ import cors from 'cors'; import express from 'express'; import Noco from '../Noco'; -import nocobuild from '../nocobuild'; const server = express(); server.enable('trust proxy'); diff --git a/packages/nocodb/src/schema/swagger.json b/packages/nocodb/src/schema/swagger.json index b7d5a6e102..84d509f0ef 100644 --- a/packages/nocodb/src/schema/swagger.json +++ b/packages/nocodb/src/schema/swagger.json @@ -15197,38 +15197,45 @@ }, "comparison_op": { "description": "Comparison Operator", - "enum": [ - "allof", - "anyof", - "blank", - "btw", - "checked", - "empty", - "eq", - "ge", - "gt", - "gte", - "in", - "is", - "isWithin", - "isnot", - "le", - "like", - "lt", - "lte", - "nallof", - "nanyof", - "nbtw", - "neq", - "nlike", - "not", - "notblank", - "notchecked", - "notempty", - "notnull", - "null" - ], - "type": "string" + "anyOf": [ + { + "enum": [ + "allof", + "anyof", + "blank", + "btw", + "checked", + "empty", + "eq", + "ge", + "gt", + "gte", + "in", + "is", + "isWithin", + "isnot", + "le", + "like", + "lt", + "lte", + "nallof", + "nanyof", + "nbtw", + "neq", + "nlike", + "not", + "notblank", + "notchecked", + "notempty", + "notnull", + "null" + ], + "type": "string" + }, + { + "type": "null" + } + ] }, "comparison_sub_op": { "anyOf": [ @@ -15262,7 +15269,7 @@ "description": "Comparison Sub-Operator" }, "fk_column_id": { - "$ref": "#/components/schemas/Id", + "$ref": "#/components/schemas/StringOrNull", "description": "Foreign Key to Column" }, "fk_hook_id": { @@ -15518,38 +15525,45 @@ "properties": { "comparison_op": { "description": "Comparison Operator", - "enum": [ - "allof", - "anyof", - "blank", - "btw", - "checked", - "empty", - "eq", - "ge", - "gt", - "gte", - "in", - "is", - "isWithin", - "isnot", - "le", - "like", - "lt", - "lte", - "nallof", - "nanyof", - "nbtw", - "neq", - "nlike", - "not", - "notblank", - "notchecked", - "notempty", - "notnull", - "null" - ], - "type": "string" + "anyOf": [ + { + "enum": [ + "allof", + "anyof", + "blank", + "btw", + "checked", + "empty", + "eq", + "ge", + "gt", + "gte", + "in", + "is", + "isWithin", + "isnot", + "le", + "like", + "lt", + "lte", + "nallof", + "nanyof", + "nbtw", + "neq", + "nlike", + "not", + "notblank", + "notchecked", + "notempty", + "notnull", + "null" + ], + "type": "string" + }, + { + "type": "null" + } + ] }, "comparison_sub_op": { "anyOf": [ @@ -15583,7 +15597,7 @@ "description": "Comparison Sub-Operator" }, "fk_column_id": { - "$ref": "#/components/schemas/Id", + "$ref": "#/components/schemas/StringOrNull", "description": "Foreign Key to Column" }, "fk_parent_id": { @@ -20000,6 +20014,10 @@ "description": "The roles of the user", "example": "org-level-viewer", "type": "string" + }, + "token_version": { + "description": "Access token version", + "type": "string" } }, "required": ["email", "email_verified", "firstname", "id", "lastname"], diff --git a/packages/nocodb/src/services/bulk-data-alias.service.ts b/packages/nocodb/src/services/bulk-data-alias.service.ts index cc77470b23..bf65ef44a6 100644 --- a/packages/nocodb/src/services/bulk-data-alias.service.ts +++ b/packages/nocodb/src/services/bulk-data-alias.service.ts @@ -1,8 +1,5 @@ import { Injectable } from '@nestjs/common'; -import { isSystemColumn, UITypes } from 'nocodb-sdk'; -import * as XLSX from 'xlsx'; -import { NcError } from '../helpers/catchError'; -import { Base, Column, Model, Project, View } from '../models'; +import { Base, Model } from '../models'; import NcConnectionMgrv2 from '../utils/common/NcConnectionMgrv2'; import { getViewAndModelByAliasOrId } from '../modules/datas/helpers'; import type { PathParams } from '../modules/datas/helpers'; diff --git a/packages/nocodb/src/services/public-metas.service.ts b/packages/nocodb/src/services/public-metas.service.ts index 1ce6605e73..59ad1ef7e5 100644 --- a/packages/nocodb/src/services/public-metas.service.ts +++ b/packages/nocodb/src/services/public-metas.service.ts @@ -2,8 +2,7 @@ import { Injectable } from '@nestjs/common'; import { ErrorMessages, RelationTypes, UITypes } from 'nocodb-sdk'; import { NcError } from '../helpers/catchError'; import { Base, Column, Model, Project, View } from '../models'; -import type { LinkToAnotherRecordColumn } from '../models'; -import type { LinkToAnotherRecordType } from 'nocodb-sdk'; +import type { LinkToAnotherRecordColumn, LookupColumn } from '../models'; @Injectable() export class PublicMetasService { @@ -63,23 +62,88 @@ export class PublicMetasService { // load related table metas for (const col of view.model.columns) { - if (UITypes.LinkToAnotherRecord === col.uidt) { - const colOpt = await col.getColOptions(); - relatedMetas[colOpt.fk_related_model_id] = await Model.getWithInfo({ - id: colOpt.fk_related_model_id, - }); - if (colOpt.type === 'mm') { - relatedMetas[colOpt.fk_mm_model_id] = await Model.getWithInfo({ - id: colOpt.fk_mm_model_id, - }); - } - } + await this.extractRelatedMetas({ col, relatedMetas }); } view.relatedMetas = relatedMetas; return view; } + + private async extractRelatedMetas({ + col, + relatedMetas = {}, + }: { + col: Column; + relatedMetas: Record; + }) { + if (UITypes.LinkToAnotherRecord === col.uidt) { + await this.extractLTARRelatedMetas({ + ltarColOption: await col.getColOptions(), + relatedMetas, + }); + } else if (UITypes.Lookup === col.uidt) { + await this.extractLookupRelatedMetas({ + lookupColOption: await col.getColOptions(), + relatedMetas, + }); + } + } + + private async extractLTARRelatedMetas({ + ltarColOption, + relatedMetas = {}, + }: { + ltarColOption: LinkToAnotherRecordColumn; + relatedMetas: { [key: string]: Model }; + }) { + relatedMetas[ltarColOption.fk_related_model_id] = await Model.getWithInfo({ + id: ltarColOption.fk_related_model_id, + }); + if (ltarColOption.type === 'mm') { + relatedMetas[ltarColOption.fk_mm_model_id] = await Model.getWithInfo({ + id: ltarColOption.fk_mm_model_id, + }); + } + } + + private async extractLookupRelatedMetas({ + lookupColOption, + relatedMetas = {}, + }: { + lookupColOption: LookupColumn; + relatedMetas: { [key: string]: Model }; + }) { + const relationCol = await Column.get({ + colId: lookupColOption.fk_relation_column_id, + }); + const lookedUpCol = await Column.get({ + colId: lookupColOption.fk_lookup_column_id, + }); + + // extract meta for table which belongs the relation column + // if not already extracted + if (!relatedMetas[relationCol.fk_model_id]) { + relatedMetas[relationCol.fk_model_id] = await Model.getWithInfo({ + id: relationCol.fk_model_id, + }); + } + + // extract meta for table in which looked up column belongs + // if not already extracted + if (!relatedMetas[lookedUpCol.fk_model_id]) { + relatedMetas[lookedUpCol.fk_model_id] = await Model.getWithInfo({ + id: lookedUpCol.fk_model_id, + }); + } + + // extract metas related to the looked up column + await this.extractRelatedMetas({ + col: lookedUpCol, + relatedMetas, + }); + } + async publicSharedBaseGet(param: { sharedBaseUuid: string }): Promise { const project = await Project.getByUuid(param.sharedBaseUuid); diff --git a/packages/nocodb/src/services/users/users.service.ts b/packages/nocodb/src/services/users/users.service.ts index 6d60b76336..0753329060 100644 --- a/packages/nocodb/src/services/users/users.service.ts +++ b/packages/nocodb/src/services/users/users.service.ts @@ -486,9 +486,9 @@ export class UsersService { return this.login(user); } - async login(user: any) { + login(user: UserType) { return { - token: genJwt(user, Noco.getConfig()), //this.jwtService.sign(payload), + token: genJwt(user, Noco.getConfig()), }; } diff --git a/packages/nocodb/src/utils/nc-config/NcConfig.ts b/packages/nocodb/src/utils/nc-config/NcConfig.ts index b8d3654551..cd8cb0e2fe 100644 --- a/packages/nocodb/src/utils/nc-config/NcConfig.ts +++ b/packages/nocodb/src/utils/nc-config/NcConfig.ts @@ -126,6 +126,8 @@ export class NcConfig { if (dashboardPath) { ncConfig.dashboardPath = dashboardPath; + } else { + ncConfig.dashboardPath = '/dashboard'; } try { diff --git a/packages/nocodb/src/version-upgrader/v1-legacy/gql/GqlApiBuilder.ts b/packages/nocodb/src/version-upgrader/v1-legacy/gql/GqlApiBuilder.ts index 6bd3fccba6..c32598e8ed 100644 --- a/packages/nocodb/src/version-upgrader/v1-legacy/gql/GqlApiBuilder.ts +++ b/packages/nocodb/src/version-upgrader/v1-legacy/gql/GqlApiBuilder.ts @@ -1,4 +1,3 @@ -import debug from 'debug'; import { Router } from 'express'; import GqlXcSchemaFactory from '../../../db/sql-mgr/code/gql-schema/xc-ts/GqlXcSchemaFactory'; import BaseApiBuilder from '../BaseApiBuilder'; diff --git a/packages/nocodb/src/version-upgrader/v1-legacy/rest/RestApiBuilder.ts b/packages/nocodb/src/version-upgrader/v1-legacy/rest/RestApiBuilder.ts index 7d4dc726b6..918869c37b 100644 --- a/packages/nocodb/src/version-upgrader/v1-legacy/rest/RestApiBuilder.ts +++ b/packages/nocodb/src/version-upgrader/v1-legacy/rest/RestApiBuilder.ts @@ -1,17 +1,14 @@ -import debug from 'debug'; import autoBind from 'auto-bind'; import SwaggerXc from '../../../db/sql-mgr/code/routers/xc-ts/SwaggerXc'; import ExpressXcTsRoutes from '../../../db/sql-mgr/code/routes/xc-ts/ExpressXcTsRoutes'; import NcHelp from '../../../utils/NcHelp'; -import BaseApiBuilder, { XcTablesPopulateParams } from '../BaseApiBuilder'; +import BaseApiBuilder from '../BaseApiBuilder'; import type { MetaService } from '../../../meta/meta.service'; import type Noco from '../../../Noco'; import type { Router } from 'express'; import type { DbConfig, NcConfig } from '../../../interface/config'; import type NcProjectBuilder from '../NcProjectBuilder'; -const log = debug('nc:api:rest'); - export class RestApiBuilder extends BaseApiBuilder { public readonly type = 'rest'; diff --git a/tests/playwright/tests/db/timezone.spec.ts b/tests/playwright/tests/db/timezone.spec.ts index 9228dbb5f8..c789921ff2 100644 --- a/tests/playwright/tests/db/timezone.spec.ts +++ b/tests/playwright/tests/db/timezone.spec.ts @@ -147,9 +147,16 @@ test.describe('Timezone-XCDB : Japan/Tokyo', () => { await dashboard.treeView.openTable({ title: 'dateTimeTable' }); - // DateTime inserted using API without timezone is converted to UTC + // DateTime inserted using API without timezone is converted to db-timezone (server timezone in case of sqlite) // Display value is converted to Asia/Tokyo - await dashboard.grid.cell.verifyDateCell({ index: 0, columnHeader: 'DateTime', value: '2021-01-01 09:00' }); + const dateInserted = new Date(`2021-01-01 00:00:00${getBrowserTimezoneOffset()}`); + // convert dateInserted to Japan/Tokyo timezone in YYYY-MM-DD HH:mm format + const dateInsertedInJapan = new Date(dateInserted.getTime() + 9 * 60 * 60 * 1000) + .toISOString() + .slice(0, 16) + .replace('T', ' '); + + await dashboard.grid.cell.verifyDateCell({ index: 0, columnHeader: 'DateTime', value: dateInsertedInJapan }); // DateTime inserted using API with timezone is converted to UTC // Display value is converted to Asia/Tokyo @@ -173,8 +180,16 @@ test.describe('Timezone-XCDB : Japan/Tokyo', () => { test('API Insert, verify API read response', async () => { if (!isSqlite(context)) return; + const dateInserted = new Date(`2021-01-01 00:00:00${getBrowserTimezoneOffset()}`); + // translate dateInserted to UTC in YYYY-MM-DD HH:mm format + const dateInsertedInUTC = dateInserted.toISOString().replace('T', ' ').replace('Z', ''); + // UTC expected response - const dateUTC = ['2021-01-01 00:00:00+00:00', '2021-01-01 00:00:00+00:00', '2021-01-01 00:00:00+00:00']; + const dateUTC = [ + `${dateInsertedInUTC.slice(0, 19)}+00:00`, + '2021-01-01 00:00:00+00:00', + '2021-01-01 00:00:00+00:00', + ]; const readDate = records.list.map(record => record.DateTime); @@ -231,7 +246,18 @@ test.describe('Timezone-XCDB : Asia/Hong-kong', () => { // DateTime inserted using API without timezone is converted to UTC // Display value is converted to Asia/Hong_Kong - await dashboard.grid.cell.verifyDateCell({ index: 0, columnHeader: 'DateTime', value: '2021-01-01 08:00' }); + const dateInserted = new Date(`2021-01-01 00:00:00${getBrowserTimezoneOffset()}`); + // convert dateInserted to Asia/Hong-kong timezone using offset + const dateInsertedInHK = new Date(dateInserted.getTime() + 8 * 60 * 60 * 1000) + .toISOString() + .slice(0, 16) + .replace('T', ' '); + + await dashboard.grid.cell.verifyDateCell({ + index: 0, + columnHeader: 'DateTime', + value: dateInsertedInHK, + }); // DateTime inserted using API with timezone is converted to UTC // Display value is converted to Asia/Hong_Kong