Browse Source

Merge branch 'develop' into refactor/timezone-locale

pull/5689/head
Wing-Kam Wong 1 year ago
parent
commit
6b1a853a56
  1. 14
      packages/nc-gui/package-lock.json
  2. 2
      packages/nc-lib-gui/package.json
  3. 10
      packages/noco-docs/content/en/engineering/development-setup.md
  4. 4
      packages/nocodb-sdk/package-lock.json
  5. 2
      packages/nocodb-sdk/package.json
  6. 4
      packages/nocodb/Dockerfile
  7. 4
      packages/nocodb/Dockerfile.local
  8. 32
      packages/nocodb/package-lock.json
  9. 4
      packages/nocodb/package.json
  10. 2
      packages/nocodb/src/Noco.ts
  11. 3
      packages/nocodb/src/app.module.ts
  12. 281
      packages/nocodb/src/helpers/initAdminFromEnv.ts
  13. 7
      packages/nocodb/src/middlewares/public/public.middleware.spec.ts
  14. 23
      packages/nocodb/src/middlewares/public/public.middleware.ts
  15. 2
      packages/nocodb/src/models/Base.ts
  16. 34
      packages/nocodb/src/models/Model.ts
  17. 0
      packages/nocodb/src/public/css/fonts.montserrat.css
  18. 0
      packages/nocodb/src/public/css/fonts.roboto.css
  19. 0
      packages/nocodb/src/public/css/materialdesignicons.5.x.min.css
  20. 0
      packages/nocodb/src/public/css/swagger-ui-bundle.4.5.2.min.css
  21. 0
      packages/nocodb/src/public/css/vuetify.2.x.min.css
  22. 0
      packages/nocodb/src/public/favicon.ico
  23. 0
      packages/nocodb/src/public/icon.png
  24. 0
      packages/nocodb/src/public/js/axios.0.19.2.min.js
  25. 0
      packages/nocodb/src/public/js/redoc.standalone.min.js
  26. 0
      packages/nocodb/src/public/js/swagger-ui-bundle.4.5.2.min.js
  27. 0
      packages/nocodb/src/public/js/vue.2.6.14.min.js
  28. 0
      packages/nocodb/src/public/js/vue.global.js
  29. 0
      packages/nocodb/src/public/js/vuetify.2.x.min.js
  30. 15
      packages/nocodb/src/services/app-init.service.ts
  31. 5
      packages/nocodb/src/strategies/authtoken.strategy/authtoken.strategy.ts
  32. 2
      packages/nocodb/src/version-upgrader/NcUpgrader.ts
  33. 48
      packages/nocodb/src/version-upgrader/ncProjectConfigUpgrader.ts
  34. 2
      packages/nocodb/webpack.config.js

14
packages/nc-gui/package-lock.json generated

@ -110,7 +110,7 @@
}
},
"../nocodb-sdk": {
"version": "0.107.3",
"version": "0.107.4",
"license": "AGPL-3.0-or-later",
"dependencies": {
"axios": "^0.21.1",
@ -15245,9 +15245,9 @@
}
},
"node_modules/socket.io-parser": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz",
"integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==",
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.3.tgz",
"integrity": "sha512-JMafRntWVO2DCJimKsRTh/wnqVvO4hrfwOqtO7f+uzwsQMuxO6VwImtYxaQ+ieoyshWOTJyV0fA21lccEXRPpQ==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
@ -29548,9 +29548,9 @@
}
},
"socket.io-parser": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz",
"integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==",
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.3.tgz",
"integrity": "sha512-JMafRntWVO2DCJimKsRTh/wnqVvO4hrfwOqtO7f+uzwsQMuxO6VwImtYxaQ+ieoyshWOTJyV0fA21lccEXRPpQ==",
"requires": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"

2
packages/nc-lib-gui/package.json

@ -1,6 +1,6 @@
{
"name": "nc-lib-gui",
"version": "0.107.3",
"version": "0.107.4",
"description": "NocoDB GUI",
"author": {
"name": "NocoDB",

10
packages/noco-docs/content/en/engineering/development-setup.md

@ -51,4 +51,14 @@ For Playwright tests, screenshots are captured on the tests. These will provide
![Screenshot 2022-09-29 at 12 43 37 PM](https://user-images.githubusercontent.com/86527202/192965070-dc04b952-70fb-4197-b4bd-ca7eda066e60.png)
## Accessing 'Easter egg' menu
Double click twice on empty space between `View list` & `Share` button to the left top of Grid view; following options become accessible
1. Export Cache
2. Delete Cache
3. Debug Meta
4. Toggle Beta Features
![Screenshot 2023-05-23 at 8 35 14 PM](https://github.com/nocodb/nocodb/assets/86527202/fe2765fa-5796-4d26-8c12-e71b8226872e)

4
packages/nocodb-sdk/package-lock.json generated

@ -1,12 +1,12 @@
{
"name": "nocodb-sdk",
"version": "0.107.3",
"version": "0.107.4",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "nocodb-sdk",
"version": "0.107.3",
"version": "0.107.4",
"license": "AGPL-3.0-or-later",
"dependencies": {
"axios": "^0.21.1",

2
packages/nocodb-sdk/package.json

@ -1,6 +1,6 @@
{
"name": "nocodb-sdk",
"version": "0.107.3",
"version": "0.107.4",
"description": "NocoDB SDK",
"main": "build/main/index.js",
"typings": "build/main/index.d.ts",

4
packages/nocodb/Dockerfile

@ -31,9 +31,7 @@ COPY ./package*.json ./
COPY ./docker/main.js ./docker/main.js
#COPY ./docker/start.sh /usr/src/appEntry/start.sh
COPY ./docker/start-litestream.sh /usr/src/appEntry/start.sh
COPY ./public/css/*.css ./docker/public/css/
COPY ./public/js/*.js ./docker/public/js/
COPY ./public/favicon.ico ./docker/public/
COPY src/public/ ./docker/public/
# install production dependencies,
# reduce node_module size with modclean & removing sqlite deps,

4
packages/nocodb/Dockerfile.local

@ -14,9 +14,7 @@ COPY ./package*.json ./
COPY ./docker/nc-gui/ ./docker/nc-gui/
COPY ./docker/main.js ./docker/index.js
COPY ./docker/start-local.sh /usr/src/appEntry/start.sh
COPY ./public/css/*.css ./docker/public/css/
COPY ./public/js/*.js ./docker/public/js/
COPY ./public/favicon.ico ./docker/public/
COPY src/public/ ./docker/public/
# install production dependencies,
# reduce node_module size with modclean & removing sqlite deps,

32
packages/nocodb/package-lock.json generated

@ -1,12 +1,12 @@
{
"name": "nocodb",
"version": "0.107.3",
"version": "0.107.4",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "nocodb",
"version": "0.107.3",
"version": "0.107.4",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@google-cloud/storage": "^5.7.2",
@ -80,7 +80,7 @@
"mysql2": "^3.2.0",
"nanoid": "^3.1.20",
"nc-help": "^0.2.87",
"nc-lib-gui": "0.107.3",
"nc-lib-gui": "0.107.4",
"nc-plugin": "^0.1.3",
"ncp": "^2.0.0",
"nocodb-sdk": "file:../nocodb-sdk",
@ -190,7 +190,7 @@
}
},
"../nocodb-sdk": {
"version": "0.107.3",
"version": "0.107.4",
"license": "AGPL-3.0-or-later",
"dependencies": {
"axios": "^0.21.1",
@ -13157,9 +13157,9 @@
}
},
"node_modules/nc-lib-gui": {
"version": "0.107.3",
"resolved": "https://registry.npmjs.org/nc-lib-gui/-/nc-lib-gui-0.107.3.tgz",
"integrity": "sha512-U/GEGt4AFIIA0W1uD5nzG9drWrwdZjj1V1AFTNXdXECqpW3tshev6IFJhBOPXNl7QbXR3POAfZLW3x/IUjQZ7Q==",
"version": "0.107.4",
"resolved": "https://registry.npmjs.org/nc-lib-gui/-/nc-lib-gui-0.107.4.tgz",
"integrity": "sha512-+e0jjJgrBfgLGTTShkcu1QQ2I0QxE/NUCCJ5L8KeZibm71pvgxL/P2hfatSz8PvzSDU/YwXnyXZQkeaSDBzNyA==",
"dependencies": {
"express": "^4.17.1"
}
@ -15797,9 +15797,9 @@
}
},
"node_modules/socket.io-parser": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.2.tgz",
"integrity": "sha512-DJtziuKypFkMMHCm2uIshOYC7QaylbtzQwiMYDuCKy3OPkjLzu4B2vAhTlqipRHHzrI0NJeBAizTK7X+6m1jVw==",
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.3.tgz",
"integrity": "sha512-JMafRntWVO2DCJimKsRTh/wnqVvO4hrfwOqtO7f+uzwsQMuxO6VwImtYxaQ+ieoyshWOTJyV0fA21lccEXRPpQ==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
@ -28442,9 +28442,9 @@
}
},
"nc-lib-gui": {
"version": "0.107.3",
"resolved": "https://registry.npmjs.org/nc-lib-gui/-/nc-lib-gui-0.107.3.tgz",
"integrity": "sha512-U/GEGt4AFIIA0W1uD5nzG9drWrwdZjj1V1AFTNXdXECqpW3tshev6IFJhBOPXNl7QbXR3POAfZLW3x/IUjQZ7Q==",
"version": "0.107.4",
"resolved": "https://registry.npmjs.org/nc-lib-gui/-/nc-lib-gui-0.107.4.tgz",
"integrity": "sha512-+e0jjJgrBfgLGTTShkcu1QQ2I0QxE/NUCCJ5L8KeZibm71pvgxL/P2hfatSz8PvzSDU/YwXnyXZQkeaSDBzNyA==",
"requires": {
"express": "^4.17.1"
}
@ -30444,9 +30444,9 @@
}
},
"socket.io-parser": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.2.tgz",
"integrity": "sha512-DJtziuKypFkMMHCm2uIshOYC7QaylbtzQwiMYDuCKy3OPkjLzu4B2vAhTlqipRHHzrI0NJeBAizTK7X+6m1jVw==",
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.3.tgz",
"integrity": "sha512-JMafRntWVO2DCJimKsRTh/wnqVvO4hrfwOqtO7f+uzwsQMuxO6VwImtYxaQ+ieoyshWOTJyV0fA21lccEXRPpQ==",
"requires": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"

4
packages/nocodb/package.json

@ -1,6 +1,6 @@
{
"name": "nocodb",
"version": "0.107.3",
"version": "0.107.4",
"description": "NocoDB Backend",
"main": "dist/bundle.js",
"author": {
@ -113,7 +113,7 @@
"mysql2": "^3.2.0",
"nanoid": "^3.1.20",
"nc-help": "^0.2.87",
"nc-lib-gui": "0.107.3",
"nc-lib-gui": "0.107.4",
"nc-plugin": "^0.1.3",
"ncp": "^2.0.0",
"nocodb-sdk": "file:../nocodb-sdk",

2
packages/nocodb/src/Noco.ts

@ -1,5 +1,6 @@
import Sentry, { Handlers } from '@sentry/node';
import { Logger } from '@nestjs/common';
import path from 'path';
import { NestFactory } from '@nestjs/core';
import clear from 'clear';
import * as express from 'express';
@ -122,6 +123,7 @@ export default class Noco {
const dashboardPath = process.env.NC_DASHBOARD_URL || '/dashboard';
server.use(NcToolGui.expressMiddleware(dashboardPath));
server.use(express.static(path.join(__dirname, 'public')));
server.get('/', (_req, res) => res.redirect(dashboardPath));
this.initSentryErrorHandler(server);

3
packages/nocodb/src/app.module.ts

@ -5,7 +5,6 @@ import { EventEmitterModule as NestJsEventEmitter } from '@nestjs/event-emitter'
import { GlobalExceptionFilter } from './filters/global-exception/global-exception.filter';
import { GlobalMiddleware } from './middlewares/global/global.middleware';
import { GuiMiddleware } from './middlewares/gui/gui.middleware';
import { PublicMiddleware } from './middlewares/public/public.middleware';
import { DatasModule } from './modules/datas/datas.module';
import { EventEmitterModule } from './modules/event-emitter/event-emitter.module';
import { AuthService } from './services/auth.service';
@ -59,8 +58,6 @@ export class AppModule {
consumer
.apply(GuiMiddleware)
.forRoutes({ path: '*', method: RequestMethod.GET })
.apply(PublicMiddleware)
.forRoutes({ path: '*', method: RequestMethod.GET })
.apply(GlobalMiddleware)
.forRoutes({ path: '*', method: RequestMethod.ALL });
}

281
packages/nocodb/src/helpers/initAdminFromEnv.ts

@ -0,0 +1,281 @@
import { promisify } from 'util';
import { v4 as uuidv4 } from 'uuid';
import bcrypt from 'bcryptjs';
import { validatePassword } from 'nocodb-sdk';
import boxen from 'boxen';
import { T } from 'nc-help';
import { isEmail } from 'validator';
import NocoCache from '../cache/NocoCache';
import { ProjectUser, User } from '../models';
import Noco from '../Noco';
import { CacheScope, MetaTable } from '../utils/globals';
const rolesLevel = { owner: 0, creator: 1, editor: 2, commenter: 3, viewer: 4 };
export default async function initAdminFromEnv(_ncMeta = Noco.ncMeta) {
if (process.env.NC_ADMIN_EMAIL && process.env.NC_ADMIN_PASSWORD) {
if (!isEmail(process.env.NC_ADMIN_EMAIL?.trim())) {
console.log(
'\n',
boxen(
`Provided admin email '${process.env.NC_ADMIN_EMAIL}' is not valid`,
{
title: 'Invalid admin email',
padding: 1,
borderStyle: 'double',
titleAlignment: 'center',
borderColor: 'red',
},
),
'\n',
);
process.exit(1);
}
const { valid, error, hint } = validatePassword(
process.env.NC_ADMIN_PASSWORD,
);
if (!valid) {
console.log(
'\n',
boxen(`${error}${hint ? `\n\n${hint}` : ''}`, {
title: 'Invalid admin password',
padding: 1,
borderStyle: 'double',
titleAlignment: 'center',
borderColor: 'red',
}),
'\n',
);
process.exit(1);
}
let ncMeta;
try {
ncMeta = await _ncMeta.startTransaction();
const email = process.env.NC_ADMIN_EMAIL.toLowerCase().trim();
const salt = await promisify(bcrypt.genSalt)(10);
const password = await promisify(bcrypt.hash)(
process.env.NC_ADMIN_PASSWORD,
salt,
);
const email_verification_token = uuidv4();
const roles = 'user,super';
// if super admin not present
if (await User.isFirst(ncMeta)) {
// roles = 'owner,creator,editor'
T.emit('evt', {
evt_type: 'project:invite',
count: 1,
});
await User.insert(
{
firstname: '',
lastname: '',
email,
salt,
password,
email_verification_token,
roles,
},
ncMeta,
);
} else {
const salt = await promisify(bcrypt.genSalt)(10);
const password = await promisify(bcrypt.hash)(
process.env.NC_ADMIN_PASSWORD,
salt,
);
const email_verification_token = uuidv4();
const superUser = await ncMeta.metaGet2(null, null, MetaTable.USERS, {
roles: 'user,super',
});
if (!superUser?.id) {
const existingUserWithNewEmail = await User.getByEmail(email, ncMeta);
if (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(
existingUserWithNewEmail.id,
{
salt,
email,
password,
email_verification_token,
token_version: null,
refresh_token: null,
roles,
},
ncMeta,
);
} else {
T.emit('evt', {
evt_type: 'project:invite',
count: 1,
});
await User.insert(
{
firstname: '',
lastname: '',
email,
salt,
password,
email_verification_token,
roles,
},
ncMeta,
);
}
} else if (email !== superUser.email) {
// update admin email and password and migrate projects
// if user already present and associated with some project
// check user account already present with the new admin email
const existingUserWithNewEmail = await User.getByEmail(email, ncMeta);
if (existingUserWithNewEmail?.id) {
// get all project access belongs to the existing account
// and migrate to the admin account
const existingUserProjects = await ncMeta.metaList2(
null,
null,
MetaTable.PROJECT_USERS,
{
condition: { fk_user_id: existingUserWithNewEmail.id },
},
);
for (const existingUserProject of existingUserProjects) {
const userProject = await ProjectUser.get(
existingUserProject.project_id,
superUser.id,
ncMeta,
);
// if admin user already have access to the project
// then update role based on the highest access level
if (userProject) {
if (
rolesLevel[userProject.roles] >
rolesLevel[existingUserProject.roles]
) {
await ProjectUser.update(
userProject.project_id,
superUser.id,
existingUserProject.roles,
ncMeta,
);
}
} else {
// if super doesn't have access then add the access
await ProjectUser.insert(
{
...existingUserProject,
fk_user_id: superUser.id,
},
ncMeta,
);
}
// delete the old project access entry from DB
await ProjectUser.delete(
existingUserProject.project_id,
existingUserProject.fk_user_id,
ncMeta,
);
}
// delete existing user
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,
{
salt,
email,
password,
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,
email,
password,
email_verification_token,
token_version: null,
refresh_token: null,
},
ncMeta,
);
}
} else {
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();
} catch (e) {
console.log('Error occurred while updating/creating admin user');
console.log(e);
await ncMeta.rollback(e);
}
}
}

7
packages/nocodb/src/middlewares/public/public.middleware.spec.ts

@ -1,7 +0,0 @@
import { PublicMiddleware } from './public.middleware';
describe('PublicMiddleware', () => {
it('should be defined', () => {
expect(new PublicMiddleware()).toBeDefined();
});
});

23
packages/nocodb/src/middlewares/public/public.middleware.ts

@ -1,23 +0,0 @@
import path, { join } from 'path';
import { Injectable } from '@nestjs/common';
import express from 'express';
import isDocker from 'is-docker';
import type { NestMiddleware } from '@nestjs/common';
@Injectable()
export class PublicMiddleware implements NestMiddleware {
use(req: any, res: any, next: () => void) {
// redirect root to dashboard
if (req.path === '/') {
const dashboardPath = process.env.NC_DASHBOARD_URL || '/dashboard';
return res.redirect(dashboardPath);
}
// serve static files from public folder
if (isDocker()) {
express.static(join(process.cwd(), 'docker', 'public'))(req, res, next);
} else {
express.static(join(process.cwd(), 'public'))(req, res, next);
}
}
}

2
packages/nocodb/src/models/Base.ts

@ -91,6 +91,7 @@ export default class Base implements BaseType {
base: BaseType & {
id: string;
projectId: string;
skipReorder?: boolean;
},
ncMeta = Noco.ncMeta,
) {
@ -144,6 +145,7 @@ export default class Base implements BaseType {
// call before reorder to update cache
const returnBase = await this.get(oldBase.id, ncMeta);
if (!base.skipReorder)
await this.reorderBases(base.projectId, returnBase.id, ncMeta);
return returnBase;

34
packages/nocodb/src/models/Model.ts

@ -137,7 +137,15 @@ export default class Model implements TableType {
MetaTable.MODELS,
insertObj,
);
if (baseId) {
await NocoCache.appendToList(
CacheScope.MODEL,
[projectId, baseId],
`${CacheScope.MODEL}:${id}`,
);
}
// cater cases where baseId is not required
// e.g. xcVisibilityMetaGet
await NocoCache.appendToList(
CacheScope.MODEL,
[projectId],
@ -171,7 +179,10 @@ export default class Model implements TableType {
},
ncMeta = Noco.ncMeta,
): Promise<Model[]> {
const cachedList = await NocoCache.getList(CacheScope.MODEL, [project_id]);
const cachedList = await NocoCache.getList(CacheScope.MODEL, [
project_id,
base_id,
]);
let { list: modelList } = cachedList;
const { isNoneList } = cachedList;
if (!isNoneList && !modelList.length) {
@ -191,7 +202,11 @@ export default class Model implements TableType {
model.meta = parseMetaProp(model);
}
await NocoCache.setList(CacheScope.MODEL, [project_id], modelList);
await NocoCache.setList(
CacheScope.MODEL,
[project_id, base_id],
modelList,
);
}
modelList.sort(
(a, b) =>
@ -746,13 +761,13 @@ export default class Model implements TableType {
},
ncMeta = Noco.ncMeta,
) {
const cacheKey = base_id
? `${CacheScope.MODEL}:${project_id}:${base_id}:${aliasOrId}`
: `${CacheScope.MODEL}:${project_id}:${aliasOrId}`;
const modelId =
project_id &&
aliasOrId &&
(await NocoCache.get(
`${CacheScope.MODEL}:${project_id}:${aliasOrId}`,
CacheGetType.TYPE_OBJECT,
));
(await NocoCache.get(cacheKey, CacheGetType.TYPE_OBJECT));
if (!modelId) {
const model = base_id
? await ncMeta.metaGet2(
@ -798,10 +813,7 @@ export default class Model implements TableType {
},
);
if (model) {
await NocoCache.set(
`${CacheScope.MODEL}:${project_id}:${aliasOrId}`,
model.id,
);
await NocoCache.set(cacheKey, model.id);
await NocoCache.set(`${CacheScope.MODEL}:${model.id}`, model);
}
return model && new Model(model);

0
packages/nocodb/public/css/fonts.montserrat.css → packages/nocodb/src/public/css/fonts.montserrat.css

0
packages/nocodb/public/css/fonts.roboto.css → packages/nocodb/src/public/css/fonts.roboto.css

0
packages/nocodb/public/css/materialdesignicons.5.x.min.css → packages/nocodb/src/public/css/materialdesignicons.5.x.min.css vendored

0
packages/nocodb/public/css/swagger-ui-bundle.4.5.2.min.css → packages/nocodb/src/public/css/swagger-ui-bundle.4.5.2.min.css vendored

0
packages/nocodb/public/css/vuetify.2.x.min.css → packages/nocodb/src/public/css/vuetify.2.x.min.css vendored

0
packages/nocodb/public/favicon.ico → packages/nocodb/src/public/favicon.ico

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

0
packages/nocodb/public/icon.png → packages/nocodb/src/public/icon.png

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

0
packages/nocodb/public/js/axios.0.19.2.min.js → packages/nocodb/src/public/js/axios.0.19.2.min.js vendored

0
packages/nocodb/public/js/redoc.standalone.min.js → packages/nocodb/src/public/js/redoc.standalone.min.js vendored

0
packages/nocodb/public/js/swagger-ui-bundle.4.5.2.min.js → packages/nocodb/src/public/js/swagger-ui-bundle.4.5.2.min.js vendored

0
packages/nocodb/public/js/vue.2.6.14.min.js → packages/nocodb/src/public/js/vue.2.6.14.min.js vendored

0
packages/nocodb/public/js/vue.global.js → packages/nocodb/src/public/js/vue.global.js

0
packages/nocodb/public/js/vuetify.2.x.min.js → packages/nocodb/src/public/js/vuetify.2.x.min.js vendored

15
packages/nocodb/src/services/app-init.service.ts

@ -1,9 +1,12 @@
import { Inject, Injectable } from '@nestjs/common';
import { T } from 'nc-help';
import NocoCache from '../cache/NocoCache';
import { Connection } from '../connection/connection';
import initAdminFromEnv from '../helpers/initAdminFromEnv';
import NcPluginMgrv2 from '../helpers/NcPluginMgrv2';
import { MetaService } from '../meta/meta.service';
import { User } from '../models'
import Noco from '../Noco';
import getInstance from '../utils/getInstance';
import NcConfigFactory from '../utils/NcConfigFactory';
import NcUpgrader from '../version-upgrader/NcUpgrader';
import type { IEventEmitter } from '../modules/event-emitter/event-emitter.interface';
@ -35,7 +38,7 @@ export const appInitServiceProvider: Provider = {
metaService: MetaService,
eventEmitter: IEventEmitter,
) => {
process.env.NC_VERSION = '0105004';
process.env.NC_VERSION = '0107004';
await NocoCache.init();
@ -54,6 +57,9 @@ export const appInitServiceProvider: Provider = {
// init jwt secret
await Noco.initJwt();
// load super admin user from env if env is set
await initAdminFromEnv(metaService);
// init plugin manager
await NcPluginMgrv2.init(Noco.ncMeta);
await Noco.loadEEState();
@ -61,6 +67,11 @@ export const appInitServiceProvider: Provider = {
// run upgrader
await NcUpgrader.upgrade({ ncMeta: Noco._ncMeta });
T.init({
instance: getInstance,
});
T.emit('evt_app_started', await User.count());
// todo: move app config to app-init service
return new AppInitService(connection.config);
},

5
packages/nocodb/src/strategies/authtoken.strategy/authtoken.strategy.ts

@ -26,6 +26,11 @@ export class AuthTokenStrategy extends PassportStrategy(Strategy, 'authtoken') {
return callback({ msg: 'User not found' });
}
Object.assign(user, {
id: dbUser.id,
roles: dbUser.roles,
});
dbUser.is_api_token = true;
if (req['ncProjectId']) {
const projectUser = await ProjectUser.get(

2
packages/nocodb/src/version-upgrader/NcUpgrader.ts

@ -13,6 +13,7 @@ import ncProjectUpgraderV2_0090000 from './ncProjectUpgraderV2_0090000';
import ncProjectEnvUpgrader0011045 from './ncProjectEnvUpgrader0011045';
import ncProjectEnvUpgrader from './ncProjectEnvUpgrader';
import ncHookUpgrader from './ncHookUpgrader';
import ncProjectConfigUpgrader from './ncProjectConfigUpgrader';
import type { MetaService } from '../meta/meta.service';
import type { NcConfig } from '../interface/config';
@ -48,6 +49,7 @@ export default class NcUpgrader {
{ name: '0105002', handler: ncStickyColumnUpgrader },
{ name: '0105003', handler: ncFilterUpgrader_0105003 },
{ name: '0105004', handler: ncHookUpgrader },
{ name: '0107004', handler: ncProjectConfigUpgrader },
];
if (!(await ctx.ncMeta.knexConnection?.schema?.hasTable?.('nc_store'))) {
return;

48
packages/nocodb/src/version-upgrader/ncProjectConfigUpgrader.ts

@ -0,0 +1,48 @@
import CryptoJS from 'crypto-js';
import { Base } from '../models';
import { MetaTable } from '../utils/globals';
import type { NcUpgraderCtx } from './NcUpgrader';
const TEMP_KEY = 'temporary-key';
// In version 0.107.0 we were used a temporary fallback secret key for JWT token encryption and project base config encryption.
// So any project created in version 0.107.0 won't be able to decrypt the project base config.
// So we need to update the project base config with the new secret key.
// Get all the project bases and update the project config with the new secret key.
export default async function ({ ncMeta }: NcUpgraderCtx) {
const actions = [];
// Get all the project bases
const bases = await ncMeta.metaList2(null, null, MetaTable.BASES);
// Update the base config with the new secret key if we could decrypt the base config with the fallback secret key
for (const base of bases) {
let config;
// Try to decrypt the base config with the fallback secret key
// if we could decrypt the base config with the fallback secret key then we will update the base config with the new secret key
// otherwise we will skip the base config update since it is already encrypted with the new secret key
try {
config = JSON.parse(
CryptoJS.AES.decrypt(base.config, TEMP_KEY).toString(CryptoJS.enc.Utf8),
);
// Update the base config with the new secret key
actions.push(
Base.updateBase(
base.id,
{
id: base.id,
projectId: base.project_id,
config,
skipReorder: true,
},
ncMeta,
),
);
} catch (e) {
// ignore the error
}
}
await Promise.all(actions);
}

2
packages/nocodb/webpack.config.js

@ -44,7 +44,7 @@ module.exports = {
plugins: [
new webpack.EnvironmentPlugin(['EE']),
new CopyPlugin({
patterns: [{ from: 'public', to: 'public' }],
patterns: [{ from: 'src/public', to: 'public' }],
}),
],

Loading…
Cancel
Save