Skip to content

Commit f0f074e

Browse files
authored
feat: Build pinecone quick connect integration flow (#25854)
1 parent 4fb5ae6 commit f0f074e

10 files changed

Lines changed: 389 additions & 20 deletions

File tree

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
1-
export type QuickConnectOption = {
1+
type QuickConnectGenericOption = {
22
packageName: string;
33
credentialType: string;
44
text: string;
55
quickConnectType: string;
66
serviceName: string;
77
consentText?: string;
8+
config?: never;
89
};
10+
11+
export type QuickConnectPineconeOption = Omit<QuickConnectGenericOption, 'config'> & {
12+
quickConnectType: 'pinecone';
13+
config: {
14+
integrationId: string;
15+
};
16+
};
17+
18+
export type QuickConnectOption = QuickConnectGenericOption | QuickConnectPineconeOption;

packages/@n8n/config/src/configs/security.config.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
import z from 'zod';
2+
13
import { Config, Env } from '../decorators';
24

5+
const crossOriginOpenerPolicySchema = z.enum(['same-origin', 'same-origin-allow-popups']);
6+
37
@Config
48
export class SecurityConfig {
59
/**
@@ -48,6 +52,12 @@ export class SecurityConfig {
4852
@Env('N8N_CONTENT_SECURITY_POLICY_REPORT_ONLY')
4953
contentSecurityPolicyReportOnly: boolean = false;
5054

55+
/**
56+
* Configuration for the `Cross-Origin-Opener-Policy` header.
57+
*/
58+
@Env('N8N_CROSS_ORIGIN_OPENER_POLICY', crossOriginOpenerPolicySchema)
59+
crossOriginOpenerPolicy: z.infer<typeof crossOriginOpenerPolicySchema> = 'same-origin';
60+
5161
/**
5262
* Whether to disable HTML sandboxing for webhooks. The sandboxing mechanism uses CSP headers now,
5363
* but the name is kept for backwards compatibility.

packages/@n8n/config/test/config.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ describe('GlobalConfig', () => {
332332
daysAbandonedWorkflow: 90,
333333
contentSecurityPolicy: '{}',
334334
contentSecurityPolicyReportOnly: false,
335+
crossOriginOpenerPolicy: 'same-origin',
335336
disableWebhookHtmlSandboxing: false,
336337
disableBareRepos: true,
337338
awsSystemCredentialsAccess: false,
@@ -568,6 +569,24 @@ describe('GlobalConfig', () => {
568569
expect(globalConfig.taskRunners.enabled).toEqual(true);
569570
expect(globalConfig.database.type).toEqual('postgresdb');
570571
});
572+
573+
it('should validate crossOriginOpenerPolicy enum values', () => {
574+
process.env = {
575+
N8N_CROSS_ORIGIN_OPENER_POLICY: 'same-origin-allow-popups',
576+
};
577+
578+
const globalConfig = Container.get(GlobalConfig);
579+
expect(globalConfig.security.crossOriginOpenerPolicy).toEqual('same-origin-allow-popups');
580+
});
581+
582+
it('should warn and fall back to default for invalid crossOriginOpenerPolicy', () => {
583+
process.env = {
584+
N8N_CROSS_ORIGIN_OPENER_POLICY: 'invalid-policy',
585+
};
586+
587+
const globalConfig = Container.get(GlobalConfig);
588+
expect(globalConfig.security.crossOriginOpenerPolicy).toEqual('same-origin');
589+
});
571590
});
572591

573592
describe('health endpoint transformation', () => {

packages/cli/src/modules/quick-connect/__tests__/quick-connect.service.test.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,20 @@ describe('QuickConnectService', () => {
4141
type: 'testCredentialType',
4242
};
4343

44-
const createMockOption = (overrides: Partial<QuickConnectOption> = {}): QuickConnectOption => ({
45-
packageName: '@n8n/test-package',
46-
credentialType: 'testCredentialType',
47-
text: 'Test Quick connect',
48-
quickConnectType: 'backend',
49-
serviceName: 'Test Service',
50-
consentText: 'Allow access?',
51-
backendFlowConfig: {
52-
secret: 'test-secret',
53-
},
54-
...overrides,
55-
});
44+
const createMockOption = (overrides: Partial<QuickConnectOption> = {}): QuickConnectOption =>
45+
// @ts-expect-error default values overrides for test scenario produce TS error
46+
({
47+
packageName: '@n8n/test-package',
48+
credentialType: 'testCredentialType',
49+
text: 'Test Quick connect',
50+
quickConnectType: 'backend',
51+
serviceName: 'Test Service',
52+
consentText: 'Allow access?',
53+
backendFlowConfig: {
54+
secret: 'test-secret',
55+
},
56+
...overrides,
57+
});
5658

5759
const createMockHandler = (
5860
credentialType: string,

packages/cli/src/modules/quick-connect/quick-connect.config.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,32 @@ const backendFlowConfigSchema = z.object({
77

88
export type BackendFlowConfig = z.infer<typeof backendFlowConfigSchema>;
99

10-
const quickConnectOptionSchema = z.object({
10+
const baseQuickConnectOptionSchema = z.object({
1111
packageName: z.string(),
1212
credentialType: z.string(),
1313
text: z.string(),
1414
quickConnectType: z.string(),
1515
serviceName: z.string(),
1616
consentText: z.string().optional(),
17+
config: z.never().optional(),
1718
backendFlowConfig: backendFlowConfigSchema.optional(),
1819
});
1920

21+
const pineconeQuickConnectOptionSchema = baseQuickConnectOptionSchema.extend({
22+
quickConnectType: z.literal('pinecone'),
23+
config: z.object({
24+
integrationId: z.string(),
25+
}),
26+
});
27+
28+
const quickConnectOptionSchema = z.union([
29+
pineconeQuickConnectOptionSchema,
30+
baseQuickConnectOptionSchema,
31+
]);
32+
2033
export type QuickConnectOption = z.infer<typeof quickConnectOptionSchema>;
2134

22-
const quickConnectBackendOptionSchema = quickConnectOptionSchema.required({
35+
const quickConnectBackendOptionSchema = baseQuickConnectOptionSchema.required({
2336
backendFlowConfig: true,
2437
});
2538

packages/cli/src/server.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ export class Server extends AbstractServer {
366366
errorMessage: 'The contentSecurityPolicy is not valid JSON.',
367367
},
368368
);
369+
const crossOriginOpenerPolicy = Container.get(SecurityConfig).crossOriginOpenerPolicy;
369370
const cspReportOnly = Container.get(SecurityConfig).contentSecurityPolicyReportOnly;
370371
const securityHeadersMiddleware = helmet({
371372
contentSecurityPolicy: isEmpty(cspDirectives)
@@ -393,6 +394,9 @@ export class Server extends AbstractServer {
393394
preload: false,
394395
}
395396
: false,
397+
crossOriginOpenerPolicy: {
398+
policy: crossOriginOpenerPolicy,
399+
},
396400
});
397401

398402
// Route all UI urls to index.html to support history-api

packages/frontend/editor-ui/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"@n8n/rest-api-client": "workspace:*",
5050
"@n8n/stores": "workspace:*",
5151
"@n8n/utils": "workspace:*",
52+
"@pinecone-database/connect": "0.0.4",
5253
"@replit/codemirror-indentation-markers": "^6.5.3",
5354
"@sentry/vue": "catalog:frontend",
5455
"@types/semver": "^7.7.0",

0 commit comments

Comments
 (0)