|
|
@ -1,7 +1,10 @@ |
|
|
|
|
|
|
|
import { Logger } from '@nestjs/common'; |
|
|
|
import Noco from '~/Noco'; |
|
|
|
import Noco from '~/Noco'; |
|
|
|
import { MetaTable, RootScopes } from '~/utils/globals'; |
|
|
|
import { MetaTable, RootScopes } from '~/utils/globals'; |
|
|
|
import { encryptPropIfRequired } from '~/utils'; |
|
|
|
import { encryptPropIfRequired } from '~/utils'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const logger = new Logger('initDataSourceEncryption'); |
|
|
|
|
|
|
|
|
|
|
|
export default async function initDataSourceEncryption(_ncMeta = Noco.ncMeta) { |
|
|
|
export default async function initDataSourceEncryption(_ncMeta = Noco.ncMeta) { |
|
|
|
// return if env is not set
|
|
|
|
// return if env is not set
|
|
|
|
if (!process.env.NC_KEY_CREDENTIAL_ENCRYPT) { |
|
|
|
if (!process.env.NC_KEY_CREDENTIAL_ENCRYPT) { |
|
|
@ -12,6 +15,8 @@ export default async function initDataSourceEncryption(_ncMeta = Noco.ncMeta) { |
|
|
|
|
|
|
|
|
|
|
|
const ncMeta = await _ncMeta.startTransaction(); |
|
|
|
const ncMeta = await _ncMeta.startTransaction(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const successStatus: boolean[] = []; |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
// if configured, check for any non-encrypted data source by checking is_encrypted flag
|
|
|
|
// if configured, check for any non-encrypted data source by checking is_encrypted flag
|
|
|
|
const sources = await ncMeta |
|
|
|
const sources = await ncMeta |
|
|
@ -25,9 +30,24 @@ export default async function initDataSourceEncryption(_ncMeta = Noco.ncMeta) { |
|
|
|
|
|
|
|
|
|
|
|
.where((qb) => { |
|
|
|
.where((qb) => { |
|
|
|
qb.where('is_local', false).orWhereNull('is_local'); |
|
|
|
qb.where('is_local', false).orWhereNull('is_local'); |
|
|
|
}); |
|
|
|
}) |
|
|
|
|
|
|
|
.whereNotNull('config'); |
|
|
|
|
|
|
|
|
|
|
|
for (const source of sources) { |
|
|
|
for (const source of sources) { |
|
|
|
|
|
|
|
// skip if no config
|
|
|
|
|
|
|
|
if (!source.config) { |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check if valid json, if not warn and skip
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
JSON.parse(source.config); |
|
|
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
|
|
console.error('Invalid JSON in integration config', source.alias); |
|
|
|
|
|
|
|
successStatus.push(false); |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// encrypt the data source
|
|
|
|
// encrypt the data source
|
|
|
|
await ncMeta.metaUpdate( |
|
|
|
await ncMeta.metaUpdate( |
|
|
|
source.fk_workspace_id, |
|
|
|
source.fk_workspace_id, |
|
|
@ -42,15 +62,31 @@ export default async function initDataSourceEncryption(_ncMeta = Noco.ncMeta) { |
|
|
|
}, |
|
|
|
}, |
|
|
|
source.id, |
|
|
|
source.id, |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
successStatus.push(true); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const integrations = await ncMeta |
|
|
|
const integrations = await ncMeta |
|
|
|
.knex(MetaTable.INTEGRATIONS) |
|
|
|
.knex(MetaTable.INTEGRATIONS) |
|
|
|
.where((qb) => { |
|
|
|
.where((qb) => { |
|
|
|
qb.where('is_encrypted', false).orWhereNull('is_encrypted'); |
|
|
|
qb.where('is_encrypted', false).orWhereNull('is_encrypted'); |
|
|
|
}); |
|
|
|
}) |
|
|
|
|
|
|
|
.whereNotNull('config'); |
|
|
|
|
|
|
|
|
|
|
|
for (const integration of integrations) { |
|
|
|
for (const integration of integrations) { |
|
|
|
|
|
|
|
// skip if no config
|
|
|
|
|
|
|
|
if (!integrations.config) { |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check if valid json, if not warn and skip
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
JSON.parse(integrations.config); |
|
|
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
|
|
logger.warn('Invalid JSON in integration config', integration.title); |
|
|
|
|
|
|
|
successStatus.push(false); |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// encrypt the data source
|
|
|
|
// encrypt the data source
|
|
|
|
await ncMeta.metaUpdate( |
|
|
|
await ncMeta.metaUpdate( |
|
|
|
RootScopes.WORKSPACE, |
|
|
|
RootScopes.WORKSPACE, |
|
|
@ -65,7 +101,17 @@ export default async function initDataSourceEncryption(_ncMeta = Noco.ncMeta) { |
|
|
|
}, |
|
|
|
}, |
|
|
|
integration.id, |
|
|
|
integration.id, |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
successStatus.push(true); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if all failed, throw error
|
|
|
|
|
|
|
|
if (successStatus.length && successStatus.every((status) => !status)) { |
|
|
|
|
|
|
|
// if all fails then rollback and exit
|
|
|
|
|
|
|
|
throw new Error( |
|
|
|
|
|
|
|
'Failed to encrypt all data sources, please remove invalid data sources and try again.', |
|
|
|
|
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
await ncMeta.commit(); |
|
|
|
await ncMeta.commit(); |
|
|
|
} catch (e) { |
|
|
|
} catch (e) { |
|
|
|
await ncMeta.rollback(); |
|
|
|
await ncMeta.rollback(); |
|
|
|