mirror of
https://github.com/ever-co/ever-gauzy.git
synced 2026-10-31 07:53:14 +08:00
Merge pull request #10795 from ever-co/feat/gw-export-redact-ever-works
fix(integration-ever-works): redact the connection secrets in export archives
This commit is contained in:
@@ -404,6 +404,23 @@ describe('export redaction of the real entity graph', () => {
|
||||
expect(redactForExport(address, custom).address).toBe('docs@acme.com');
|
||||
});
|
||||
|
||||
it('masks the Ever Works connection secrets without breaking the NOT NULL key column', () => {
|
||||
const connection = pluginEntities.find((entity) => entity.name === 'EverWorksConnection');
|
||||
expect(connection).toBeDefined();
|
||||
|
||||
const row = Object.assign(new (connection as any)(), {
|
||||
apiBaseUrl: 'https://api.example.com/api',
|
||||
apiKeyEncrypted: 'v1:k:' + 'a'.repeat(24) + ':' + 'b'.repeat(32) + ':' + 'c'.repeat(64),
|
||||
webhookSecretEncrypted: 'v1:k:' + 'd'.repeat(24) + ':' + 'e'.repeat(32) + ':' + 'f'.repeat(64)
|
||||
});
|
||||
const redacted = redactForExport(connection, row);
|
||||
|
||||
// `apiKeyEncrypted` is NOT NULL: a fixed mask imports, an empty cell would not.
|
||||
expect(redacted.apiKeyEncrypted).toBe(OPAQUE_EXPORT_MASK);
|
||||
expect(redacted.webhookSecretEncrypted).toBe('');
|
||||
expect(redacted.apiBaseUrl).toBe('https://api.example.com/api');
|
||||
});
|
||||
|
||||
it('still covers the two key/value columns the name pattern cannot see', () => {
|
||||
// `settingsValue` and `value` look like nothing; they hold every integration token and
|
||||
// every object-storage secret key in the product.
|
||||
|
||||
+9
-2
@@ -1,5 +1,5 @@
|
||||
import { ID } from '@gauzy/contracts';
|
||||
import { ColumnIndex, MultiORMColumn, MultiORMEntity, TenantOrganizationBaseEntity } from '@gauzy/core';
|
||||
import { ColumnIndex, ExportRedacted, MultiORMColumn, MultiORMEntity, TenantOrganizationBaseEntity } from '@gauzy/core';
|
||||
import { MikroOrmEverWorksConnectionRepository } from './repository/mikro-orm-ever-works-connection.repository';
|
||||
|
||||
/** How the connection authenticates to Ever Works: an integration key now, an Ever ID token later (plan 02 §5). */
|
||||
@@ -63,7 +63,13 @@ export class EverWorksConnection extends TenantOrganizationBaseEntity {
|
||||
@MultiORMColumn({ type: 'varchar', length: 32, nullable: true })
|
||||
keyPrefix?: string | null;
|
||||
|
||||
/** The integration key, encrypted. */
|
||||
/**
|
||||
* The integration key, encrypted. An export archive carries a fixed mask instead (`opaque`, not
|
||||
* `blank`: the column is NOT NULL, and an empty cell would make the import refuse the row). The
|
||||
* ciphertext is bound to this row's id and the instance's key, so it could not be read after an
|
||||
* import anyway: an imported connection fails its health check and asks for a new key.
|
||||
*/
|
||||
@ExportRedacted({ opaque: true })
|
||||
@MultiORMColumn({ type: 'text' })
|
||||
apiKeyEncrypted!: string;
|
||||
|
||||
@@ -82,6 +88,7 @@ export class EverWorksConnection extends TenantOrganizationBaseEntity {
|
||||
@MultiORMColumn({ type: 'varchar', length: 64, nullable: true })
|
||||
webhookSubscriptionId?: string | null;
|
||||
|
||||
@ExportRedacted({ blank: true })
|
||||
@MultiORMColumn({ type: 'text', nullable: true })
|
||||
webhookSecretEncrypted?: string | null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user