diff --git a/OWNERS b/OWNERS index a7dbbdfc339..b33dcc056b6 100644 --- a/OWNERS +++ b/OWNERS @@ -30,6 +30,7 @@ packages/@n8n/backend-network/ @n8n-io/catalysts packages/@n8n/backend-services/ @n8n-io/catalysts packages/@n8n/backend-services/src/services/role.service.ts @n8n-io/iam packages/@n8n/backend-services/src/services/role-cache.service.ts @n8n-io/iam +packages/@n8n/backend-services/src/services/jwt.service.ts @n8n-io/iam packages/@n8n/backend-test-utils/ @n8n-io/catalysts packages/@n8n/di/ @n8n-io/catalysts packages/@n8n/errors/ @n8n-io/catalysts @@ -154,7 +155,6 @@ packages/cli/src/controllers/dynamic-node-parameters.controller.ts @n8n-io/node packages/cli/src/controllers/e2e.controller.ts @n8n-io/qa-dx # CLI services -packages/cli/src/services/jwt.service.ts @n8n-io/iam packages/cli/src/services/user.service.ts @n8n-io/iam packages/cli/src/services/password.utility.ts @n8n-io/iam packages/cli/src/services/public-api-key.service.ts @n8n-io/iam diff --git a/packages/@n8n/backend-services/eslint.config.mjs b/packages/@n8n/backend-services/eslint.config.mjs index 65fb1ff69aa..b3b56291d5f 100644 --- a/packages/@n8n/backend-services/eslint.config.mjs +++ b/packages/@n8n/backend-services/eslint.config.mjs @@ -5,6 +5,26 @@ import { backendConfig } from '@n8n/eslint-config/backend'; export default defineConfig( globalIgnores(['coverage/**', 'vitest.config.ts']), backendConfig, + { + files: ['./src/**/*.ts'], + ignores: ['./src/services/jwt.service.ts', './src/**/__tests__/**'], + rules: { + '@typescript-eslint/no-restricted-imports': [ + 'error', + { + paths: [ + { + name: 'jsonwebtoken', + allowImportNames: ['JsonWebTokenError', 'TokenExpiredError', 'NotBeforeError'], + allowTypeImports: true, + message: 'Sign and verify through JwtService.', + }, + ], + patterns: [{ group: ['jsonwebtoken/*'], message: 'Sign and verify through JwtService.' }], + }, + ], + }, + }, { rules: { 'n8n-local-rules/no-guardrail-disable': [ diff --git a/packages/@n8n/backend-services/oxlint.config.mts b/packages/@n8n/backend-services/oxlint.config.mts index a02ff6e1161..0f4d0563337 100644 --- a/packages/@n8n/backend-services/oxlint.config.mts +++ b/packages/@n8n/backend-services/oxlint.config.mts @@ -6,6 +6,30 @@ export default defineConfig({ extends: [backendConfig], options: { typeAware: true }, ignorePatterns: ['coverage/**'], + overrides: [ + { + files: ['./src/**/*.ts'], + excludeFiles: ['./src/services/jwt.service.ts', './src/**/__tests__/**'], + rules: { + 'no-restricted-imports': [ + 'error', + { + paths: [ + { + name: 'jsonwebtoken', + allowImportNames: ['JsonWebTokenError', 'TokenExpiredError', 'NotBeforeError'], + allowTypeImports: true, + message: 'Sign and verify through JwtService.', + }, + ], + patterns: [ + { group: ['jsonwebtoken/*'], message: 'Sign and verify through JwtService.' }, + ], + }, + ], + }, + }, + ], rules: { 'n8n-local-rules/no-guardrail-disable': [ 'error', diff --git a/packages/@n8n/backend-services/package.json b/packages/@n8n/backend-services/package.json index 54adc104fac..1437ab8ef3f 100644 --- a/packages/@n8n/backend-services/package.json +++ b/packages/@n8n/backend-services/package.json @@ -28,14 +28,16 @@ "@n8n/backend-network": "workspace:*", "@n8n/config": "workspace:*", "@n8n/constants": "workspace:*", - "@n8n/decorators": "workspace:*", "@n8n/db": "workspace:*", + "@n8n/decorators": "workspace:*", "@n8n/di": "workspace:*", "@n8n/errors": "workspace:*", "@n8n/permissions": "workspace:*", "@n8n/utils": "workspace:*", "cache-manager": "catalog:", "ioredis": "5.3.2", + "jsonwebtoken": "catalog:", + "n8n-core": "workspace:*", "n8n-workflow": "workspace:*" }, "peerDependencies": { @@ -47,6 +49,7 @@ "@n8n/oxlint-config": "workspace:*", "@n8n/typescript-config": "workspace:*", "@n8n/vitest-config": "workspace:*", + "@types/jsonwebtoken": "catalog:", "@types/lodash": "catalog:", "@vitest/coverage-v8": "catalog:", "eslint": "catalog:", diff --git a/packages/@n8n/backend-services/src/index.ts b/packages/@n8n/backend-services/src/index.ts index 78f6934c5da..da7a3534510 100644 --- a/packages/@n8n/backend-services/src/index.ts +++ b/packages/@n8n/backend-services/src/index.ts @@ -55,3 +55,16 @@ export { type Jwk, type SkippedJwk, } from './services/oauth-discovery-client'; + +export { + type PurposedSignOptions, + type PurposedVerifyOptions, + JwtService, + type JwtPayload, +} from './services/jwt.service'; +export { + TOKEN_PURPOSES, + type TokenPurpose, + API_KEY_PURPOSES, + LEGACY_UNBOUND_PURPOSES, +} from './services/token-purposes'; diff --git a/packages/cli/src/services/__tests__/jwt.service.test.ts b/packages/@n8n/backend-services/src/services/__tests__/jwt.service.test.ts similarity index 99% rename from packages/cli/src/services/__tests__/jwt.service.test.ts rename to packages/@n8n/backend-services/src/services/__tests__/jwt.service.test.ts index cfb1cd059e6..b2c031fcffe 100644 --- a/packages/cli/src/services/__tests__/jwt.service.test.ts +++ b/packages/@n8n/backend-services/src/services/__tests__/jwt.service.test.ts @@ -5,7 +5,7 @@ import type { InstanceSettings } from 'n8n-core'; import { generateKeyPairSync } from 'node:crypto'; import { mock } from 'vitest-mock-extended'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '../jwt.service'; const getJwtSecret = (svc: JwtService) => (svc as unknown as { jwtSecret: string }).jwtSecret; diff --git a/packages/cli/src/services/jwt.service.ts b/packages/@n8n/backend-services/src/services/jwt.service.ts similarity index 98% rename from packages/cli/src/services/jwt.service.ts rename to packages/@n8n/backend-services/src/services/jwt.service.ts index 9f6b0221bab..fbc5b9bc37b 100644 --- a/packages/cli/src/services/jwt.service.ts +++ b/packages/@n8n/backend-services/src/services/jwt.service.ts @@ -6,11 +6,7 @@ import { createHash, type KeyObject } from 'crypto'; import jwt from 'jsonwebtoken'; import { InstanceSettings, type DeploymentStateRepo } from 'n8n-core'; -import { - LEGACY_UNBOUND_PURPOSES, - TOKEN_PURPOSES, - type TokenPurpose, -} from '@/services/token-purposes'; +import { LEGACY_UNBOUND_PURPOSES, TOKEN_PURPOSES, type TokenPurpose } from './token-purposes'; /** * `audience` is omitted on purpose: it is derived from the token's purpose, so diff --git a/packages/cli/src/services/token-purposes.ts b/packages/@n8n/backend-services/src/services/token-purposes.ts similarity index 100% rename from packages/cli/src/services/token-purposes.ts rename to packages/@n8n/backend-services/src/services/token-purposes.ts diff --git a/packages/@n8n/backend-services/test/setup-test-folder.ts b/packages/@n8n/backend-services/test/setup-test-folder.ts new file mode 100644 index 00000000000..617161fc9b6 --- /dev/null +++ b/packages/@n8n/backend-services/test/setup-test-folder.ts @@ -0,0 +1,12 @@ +import { mkdtempSync, rmSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; + +const testFolder = mkdtempSync(join(tmpdir(), 'n8n-backend-services-')); + +process.env.N8N_USER_FOLDER = testFolder; +process.env.N8N_ENCRYPTION_KEY = 'test-key'; + +afterAll(() => { + rmSync(testFolder, { recursive: true, force: true }); +}); diff --git a/packages/@n8n/backend-services/vitest.config.ts b/packages/@n8n/backend-services/vitest.config.ts index aa666866549..3fda3b9533f 100644 --- a/packages/@n8n/backend-services/vitest.config.ts +++ b/packages/@n8n/backend-services/vitest.config.ts @@ -3,6 +3,7 @@ import { configDefaults, mergeConfig } from 'vitest/config'; export default mergeConfig(createVitestConfigWithDecorators(), { test: { + setupFiles: ['./test/setup-test-folder.ts'], // One fork per file: tests register mocks in the shared `@n8n/di` Container. pool: 'forks', // Vitest's default exclude does not cover dist; stale compiled tests there fail as CJS. diff --git a/packages/cli/eslint.config.mjs b/packages/cli/eslint.config.mjs index 740022b6cbd..9694876946d 100644 --- a/packages/cli/eslint.config.mjs +++ b/packages/cli/eslint.config.mjs @@ -208,8 +208,6 @@ export default defineConfig( // JwtService itself: verifying tokens signed by a foreign key, which JwtService cannot // verify. Do NOT add a file for any other reason. files: [ - // Owns the signing key and derives every audience from a purpose. - './src/services/jwt.service.ts', // Verifies subject tokens with a foreign key from the trusted-key store, // against the audience that key is registered for. './src/modules/token-exchange/services/token-exchange.service.ts', diff --git a/packages/cli/oxlint.config.mts b/packages/cli/oxlint.config.mts index f3767cd3763..ee6775d55fc 100644 --- a/packages/cli/oxlint.config.mts +++ b/packages/cli/oxlint.config.mts @@ -210,8 +210,6 @@ export default defineConfig({ // JwtService itself: verifying tokens signed by a foreign key, which JwtService cannot // verify. Do NOT add a file for any other reason. files: [ - // Owns the signing key and derives every audience from a purpose. - './src/services/jwt.service.ts', // Verifies subject tokens with a foreign key from the trusted-key store, // against the audience that key is registered for. './src/modules/token-exchange/services/token-exchange.service.ts', diff --git a/packages/cli/src/auth/__tests__/auth-service-browser-id-whitelist.test.ts b/packages/cli/src/auth/__tests__/auth-service-browser-id-whitelist.test.ts index b142f139a5a..853c1f360a8 100644 --- a/packages/cli/src/auth/__tests__/auth-service-browser-id-whitelist.test.ts +++ b/packages/cli/src/auth/__tests__/auth-service-browser-id-whitelist.test.ts @@ -4,8 +4,7 @@ import { mock } from 'vitest-mock-extended'; import { AuthService } from '@/auth/auth.service'; import type { MfaService } from '@/mfa/mfa.service'; -import type { JwtService } from '@/services/jwt.service'; -import type { UrlService } from '@n8n/backend-services'; +import type { JwtService, UrlService } from '@n8n/backend-services'; describe('AuthService Browser ID Whitelist', () => { let authService: AuthService; diff --git a/packages/cli/src/auth/__tests__/auth.service.test.ts b/packages/cli/src/auth/__tests__/auth.service.test.ts index b33bd2a62b1..10d55385ef7 100644 --- a/packages/cli/src/auth/__tests__/auth.service.test.ts +++ b/packages/cli/src/auth/__tests__/auth.service.test.ts @@ -16,8 +16,7 @@ import { AuthService } from '@/auth/auth.service'; import { AUTH_COOKIE_NAME } from '@/constants'; import type { License } from '@/license'; import type { MfaService } from '@/mfa/mfa.service'; -import { JwtService } from '@/services/jwt.service'; -import type { UrlService } from '@n8n/backend-services'; +import { JwtService, type UrlService } from '@n8n/backend-services'; describe('AuthService', () => { const browserId = 'test-browser-id'; diff --git a/packages/cli/src/auth/auth.service.ts b/packages/cli/src/auth/auth.service.ts index 0676855c56d..cddbb094dea 100644 --- a/packages/cli/src/auth/auth.service.ts +++ b/packages/cli/src/auth/auth.service.ts @@ -15,8 +15,7 @@ import { AUTH_COOKIE_NAME, RESPONSE_ERROR_MESSAGES } from '@/constants'; import { AuthError, ForbiddenError } from '@n8n/errors'; import { License } from '@/license'; import { MfaService } from '@/mfa/mfa.service'; -import { JwtService } from '@/services/jwt.service'; -import { UrlService } from '@n8n/backend-services'; +import { JwtService, UrlService } from '@n8n/backend-services'; interface AuthJwtPayload { /** User Id */ diff --git a/packages/cli/src/commands/__tests__/start.test.ts b/packages/cli/src/commands/__tests__/start.test.ts index 22772f18b2a..e82b82ade84 100644 --- a/packages/cli/src/commands/__tests__/start.test.ts +++ b/packages/cli/src/commands/__tests__/start.test.ts @@ -32,8 +32,7 @@ import { OtelService } from '@/modules/otel/otel.service'; import { NodeTypes } from '@/node-types'; import { PostHogClient } from '@/posthog'; import { PollJobProvider } from '@/scheduling/poll-trigger-node/poll-job-provider'; -import { JwtService } from '@/services/jwt.service'; -import { RoleCacheService } from '@n8n/backend-services'; +import { JwtService, RoleCacheService } from '@n8n/backend-services'; import { ShutdownService } from '@/shutdown/shutdown.service'; import { TaskRunnerModule } from '@/task-runners/task-runner-module'; diff --git a/packages/cli/src/commands/__tests__/webhook.test.ts b/packages/cli/src/commands/__tests__/webhook.test.ts index 35443822c79..6f09b2d9b54 100644 --- a/packages/cli/src/commands/__tests__/webhook.test.ts +++ b/packages/cli/src/commands/__tests__/webhook.test.ts @@ -11,8 +11,7 @@ import { LoadNodesAndCredentials } from '@/load-nodes-and-credentials'; import { PubSubRegistry } from '@/scaling/pubsub/pubsub.registry'; import { Subscriber } from '@/scaling/pubsub/subscriber.service'; import { SystemTaskRunner } from '@/scheduling/system-tasks/system-task-runner'; -import { JwtService } from '@/services/jwt.service'; -import { RedisClientService } from '@n8n/backend-services'; +import { JwtService, RedisClientService } from '@n8n/backend-services'; import { WebhookServer } from '@/webhooks/webhook-server'; import { BaseCommand } from '../base-command'; diff --git a/packages/cli/src/commands/__tests__/worker.test.ts b/packages/cli/src/commands/__tests__/worker.test.ts index 671d3caeb7a..58a0c344aba 100644 --- a/packages/cli/src/commands/__tests__/worker.test.ts +++ b/packages/cli/src/commands/__tests__/worker.test.ts @@ -1,6 +1,6 @@ import type { Logger } from '@n8n/backend-common'; import { uninstallGlobalProxyAgent } from '@n8n/backend-network/testing'; -import type { EventService } from '@n8n/backend-services'; +import { type EventService, JwtService, RedisClientService } from '@n8n/backend-services'; import { mockInstance } from '@n8n/backend-test-utils'; import type { ExecutionsConfig } from '@n8n/config'; import { GlobalConfig } from '@n8n/config'; @@ -33,8 +33,6 @@ import { Subscriber } from '@/scaling/pubsub/subscriber.service'; import { WorkerServer } from '@/scaling/worker-server'; import { WorkerStatusService } from '@/scaling/worker-status.service.ee'; import { SystemTaskRunner } from '@/scheduling/system-tasks/system-task-runner'; -import { JwtService } from '@/services/jwt.service'; -import { RedisClientService } from '@n8n/backend-services'; import { ShutdownService } from '@/shutdown/shutdown.service'; import { TaskRunnerModule } from '@/task-runners/task-runner-module'; diff --git a/packages/cli/src/commands/start.ts b/packages/cli/src/commands/start.ts index 2c137dab3cf..e0ed8533157 100644 --- a/packages/cli/src/commands/start.ts +++ b/packages/cli/src/commands/start.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-unsafe-call */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import { EventService, UrlService, RoleCacheService } from '@n8n/backend-services'; +import { EventService, UrlService, RoleCacheService, JwtService } from '@n8n/backend-services'; import { HTML_NONCE_PLACEHOLDER, LICENSE_FEATURES } from '@n8n/constants'; import { AuthRolesService, @@ -39,7 +39,6 @@ import { DurableScheduler } from '@/scheduling/durable-scheduler'; import { PollJobProvider } from '@/scheduling/poll-trigger-node/poll-job-provider'; import { mainSystemTasks } from '@/scheduling/system-tasks/main-system-tasks'; import { Server } from '@/server'; -import { JwtService } from '@/services/jwt.service'; import { WaitTracker } from '@/wait-tracker'; diff --git a/packages/cli/src/commands/webhook.ts b/packages/cli/src/commands/webhook.ts index 52d6ab3519f..e03d020887b 100644 --- a/packages/cli/src/commands/webhook.ts +++ b/packages/cli/src/commands/webhook.ts @@ -11,7 +11,7 @@ import { LoadNodesAndCredentials } from '@/load-nodes-and-credentials'; import { Publisher } from '@/scaling/pubsub/publisher.service'; import { PubSubRegistry } from '@/scaling/pubsub/pubsub.registry'; import { Subscriber } from '@/scaling/pubsub/subscriber.service'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; import { WebhookServer } from '@/webhooks/webhook-server'; import { BaseCommand } from './base-command'; diff --git a/packages/cli/src/commands/worker.ts b/packages/cli/src/commands/worker.ts index d98ec8fc47c..c03fbbcba4d 100644 --- a/packages/cli/src/commands/worker.ts +++ b/packages/cli/src/commands/worker.ts @@ -21,7 +21,7 @@ import { resolveQueueName, resolveWorkerPoolName } from '@/scaling/queue-name'; import type { ScalingService } from '@/scaling/scaling.service'; import type { WorkerServer, WorkerServerEndpointsConfig } from '@/scaling/worker-server'; import { WorkerStatusService } from '@/scaling/worker-status.service.ee'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; import { BaseCommand } from './base-command'; diff --git a/packages/cli/src/controllers/__tests__/users.controller.test.ts b/packages/cli/src/controllers/__tests__/users.controller.test.ts index 94ae053bd01..06fbc3eb282 100644 --- a/packages/cli/src/controllers/__tests__/users.controller.test.ts +++ b/packages/cli/src/controllers/__tests__/users.controller.test.ts @@ -4,8 +4,7 @@ import { mock } from 'vitest-mock-extended'; import { NotFoundError } from '@n8n/errors'; import type { UserRequest } from '@/requests'; -import type { JwtService } from '@/services/jwt.service'; -import type { UrlService } from '@n8n/backend-services'; +import type { JwtService, UrlService } from '@n8n/backend-services'; import type { UserService } from '@/services/user.service'; import { UsersController } from '../users.controller'; diff --git a/packages/cli/src/controllers/users.controller.ts b/packages/cli/src/controllers/users.controller.ts index 3b4a3aab687..af530ad9dd4 100644 --- a/packages/cli/src/controllers/users.controller.ts +++ b/packages/cli/src/controllers/users.controller.ts @@ -32,8 +32,7 @@ import { Response } from 'express'; import { AuthService } from '@/auth/auth.service'; import { ForbiddenError, NotFoundError } from '@n8n/errors'; import { UserRequest } from '@/requests'; -import { JwtService } from '@/services/jwt.service'; -import { UrlService } from '@n8n/backend-services'; +import { JwtService, UrlService } from '@n8n/backend-services'; import { UserService } from '@/services/user.service'; @RestController('/users') diff --git a/packages/cli/src/modules/agents/integrations/platforms/teams/__tests__/teams-arm-template.service.test.ts b/packages/cli/src/modules/agents/integrations/platforms/teams/__tests__/teams-arm-template.service.test.ts index c2743738739..26582dacca9 100644 --- a/packages/cli/src/modules/agents/integrations/platforms/teams/__tests__/teams-arm-template.service.test.ts +++ b/packages/cli/src/modules/agents/integrations/platforms/teams/__tests__/teams-arm-template.service.test.ts @@ -2,8 +2,7 @@ import { mock } from 'vitest-mock-extended'; import type { GlobalConfig } from '@n8n/config'; import type { InstanceSettings } from 'n8n-core'; -import { JwtService } from '@/services/jwt.service'; -import type { UrlService } from '@n8n/backend-services'; +import { JwtService, type UrlService } from '@n8n/backend-services'; import { TeamsArmTemplateService } from '../teams-arm-template.service'; diff --git a/packages/cli/src/modules/agents/integrations/platforms/teams/__tests__/teams-setup.service.test.ts b/packages/cli/src/modules/agents/integrations/platforms/teams/__tests__/teams-setup.service.test.ts index 32417d00a4c..14edf81b85c 100644 --- a/packages/cli/src/modules/agents/integrations/platforms/teams/__tests__/teams-setup.service.test.ts +++ b/packages/cli/src/modules/agents/integrations/platforms/teams/__tests__/teams-setup.service.test.ts @@ -4,10 +4,9 @@ import type { GlobalConfig } from '@n8n/config'; import type { User } from '@n8n/db'; import type { InstanceSettings } from 'n8n-core'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService, type UrlService } from '@n8n/backend-services'; import type { CredentialsService } from '@/credentials/credentials.service'; -import type { UrlService } from '@n8n/backend-services'; import type { Agent } from '../../../../entities/agent.entity'; import { AgentCredentialLookupService } from '../../../agent-credential-lookup.service'; diff --git a/packages/cli/src/modules/agents/integrations/platforms/teams/teams-arm-template.service.ts b/packages/cli/src/modules/agents/integrations/platforms/teams/teams-arm-template.service.ts index f7d97f18e20..bfe60047d50 100644 --- a/packages/cli/src/modules/agents/integrations/platforms/teams/teams-arm-template.service.ts +++ b/packages/cli/src/modules/agents/integrations/platforms/teams/teams-arm-template.service.ts @@ -2,8 +2,7 @@ import { Service } from '@n8n/di'; import { UserError } from 'n8n-workflow'; import { createHmac } from 'node:crypto'; -import { JwtService } from '@/services/jwt.service'; -import { UrlService } from '@n8n/backend-services'; +import { JwtService, UrlService } from '@n8n/backend-services'; import { sanitiseAppName } from '../../integration-helpers'; diff --git a/packages/cli/src/modules/mcp/__tests__/mcp-api-key.service.integration.test.ts b/packages/cli/src/modules/mcp/__tests__/mcp-api-key.service.integration.test.ts index 6f9aeff4fb3..9ffae754d33 100644 --- a/packages/cli/src/modules/mcp/__tests__/mcp-api-key.service.integration.test.ts +++ b/packages/cli/src/modules/mcp/__tests__/mcp-api-key.service.integration.test.ts @@ -9,7 +9,7 @@ import { ScopedJwtStrategy } from '@/modules/token-exchange/services/scoped-jwt. import { TOKEN_EXCHANGE_ISSUER } from '@/modules/token-exchange/token-exchange.types'; import { ApiKeyAuthStrategy } from '@/services/api-key-auth.strategy'; import { AuthStrategyRegistry } from '@/services/auth-strategy.registry'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; import { SessionCookieAuthStrategy } from '@/services/session-cookie-auth.strategy'; import { createMember, createOwner, createOwnerWithApiKey } from '@test-integration/db/users'; diff --git a/packages/cli/src/modules/mcp/__tests__/mcp-api-key.service.test.ts b/packages/cli/src/modules/mcp/__tests__/mcp-api-key.service.test.ts index 1402725fc26..0c98cab573e 100644 --- a/packages/cli/src/modules/mcp/__tests__/mcp-api-key.service.test.ts +++ b/packages/cli/src/modules/mcp/__tests__/mcp-api-key.service.test.ts @@ -3,7 +3,7 @@ import type { ApiKeyRepository, User, TokenGrant } from '@n8n/db'; import { mock } from 'vitest-mock-extended'; import type { AuthStrategyRegistry } from '@/services/auth-strategy.registry'; -import type { JwtService } from '@/services/jwt.service'; +import type { JwtService } from '@n8n/backend-services'; import { McpServerApiKeyService } from '../mcp-api-key.service'; diff --git a/packages/cli/src/modules/mcp/__tests__/mcp-server-middleware.service.test.ts b/packages/cli/src/modules/mcp/__tests__/mcp-server-middleware.service.test.ts index e3e4611db33..875c5f903f5 100644 --- a/packages/cli/src/modules/mcp/__tests__/mcp-server-middleware.service.test.ts +++ b/packages/cli/src/modules/mcp/__tests__/mcp-server-middleware.service.test.ts @@ -7,7 +7,7 @@ import { generateKeyPairSync } from 'node:crypto'; import { mock, mockDeep } from 'vitest-mock-extended'; import type { InstanceSettings } from 'n8n-core'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; import type { McpCallerAuth } from '@/services/oauth-token-verifier-proxy.service'; import { OAuthTokenVerifierProxy } from '@/services/oauth-token-verifier-proxy.service'; import { Telemetry } from '@/telemetry'; diff --git a/packages/cli/src/modules/mcp/mcp-api-key.service.ts b/packages/cli/src/modules/mcp/mcp-api-key.service.ts index b61c208de4f..5ad5327e95e 100644 --- a/packages/cli/src/modules/mcp/mcp-api-key.service.ts +++ b/packages/cli/src/modules/mcp/mcp-api-key.service.ts @@ -6,7 +6,7 @@ import { ensureError } from '@n8n/utils/errors/ensure-error'; import { ApiKeyAudience } from 'n8n-workflow'; import { AuthStrategyRegistry } from '@/services/auth-strategy.registry'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; import { UserWithContext } from '@/services/oauth-token-verifier-proxy.service'; const API_KEY_AUDIENCE: ApiKeyAudience = 'mcp-server-api'; diff --git a/packages/cli/src/modules/mcp/mcp-server-middleware.service.ts b/packages/cli/src/modules/mcp/mcp-server-middleware.service.ts index 93998ce2b3a..096614c7d07 100644 --- a/packages/cli/src/modules/mcp/mcp-server-middleware.service.ts +++ b/packages/cli/src/modules/mcp/mcp-server-middleware.service.ts @@ -4,7 +4,7 @@ import { NextFunction, Response, Request } from 'express'; import { ensureError } from '@n8n/utils/errors/ensure-error'; import { AuthError } from '@n8n/errors'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; import { OAuthTokenVerifierProxy, type TelemetryAuthContext, diff --git a/packages/cli/src/modules/oauth-server/__tests__/oauth-consent.controller.api.test.ts b/packages/cli/src/modules/oauth-server/__tests__/oauth-consent.controller.api.test.ts index fafd8b4b241..c28cd59218a 100644 --- a/packages/cli/src/modules/oauth-server/__tests__/oauth-consent.controller.api.test.ts +++ b/packages/cli/src/modules/oauth-server/__tests__/oauth-consent.controller.api.test.ts @@ -3,9 +3,8 @@ import type { User } from '@n8n/db'; import { Container } from '@n8n/di'; import { McpSettingsService } from '@/modules/mcp/mcp.settings.service'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService, UrlService } from '@n8n/backend-services'; import { ProtectedResourceRegistry } from '@/services/protected-resource.registry'; -import { UrlService } from '@n8n/backend-services'; import { createOwner, createMember } from '@test-integration/db/users'; import { setupTestServer } from '@test-integration/utils'; diff --git a/packages/cli/src/modules/oauth-server/__tests__/oauth-session.service.test.ts b/packages/cli/src/modules/oauth-server/__tests__/oauth-session.service.test.ts index 60ea7162865..ec38e2269c4 100644 --- a/packages/cli/src/modules/oauth-server/__tests__/oauth-session.service.test.ts +++ b/packages/cli/src/modules/oauth-server/__tests__/oauth-session.service.test.ts @@ -3,7 +3,7 @@ import { JsonWebTokenError, TokenExpiredError } from 'jsonwebtoken'; import { mock } from 'vitest-mock-extended'; import { ZodError } from 'zod'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; import { OAuthSessionService, type OAuthSessionPayload } from '../oauth-session.service'; diff --git a/packages/cli/src/modules/oauth-server/__tests__/oauth-signing-key.service.integration.test.ts b/packages/cli/src/modules/oauth-server/__tests__/oauth-signing-key.service.integration.test.ts index 65bf8ef8109..34d32f4ff33 100644 --- a/packages/cli/src/modules/oauth-server/__tests__/oauth-signing-key.service.integration.test.ts +++ b/packages/cli/src/modules/oauth-server/__tests__/oauth-signing-key.service.integration.test.ts @@ -7,7 +7,7 @@ import { createLocalJWKSet, jwtVerify } from 'jose'; import { Cipher, InstanceSettings } from 'n8n-core'; import { generateKeyPairSync } from 'node:crypto'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; import { OAUTH_SIGNING_ALGORITHM, diff --git a/packages/cli/src/modules/oauth-server/__tests__/oauth-token.service.test.ts b/packages/cli/src/modules/oauth-server/__tests__/oauth-token.service.test.ts index 530b9f1c809..f6c041a93a9 100644 --- a/packages/cli/src/modules/oauth-server/__tests__/oauth-token.service.test.ts +++ b/packages/cli/src/modules/oauth-server/__tests__/oauth-token.service.test.ts @@ -11,7 +11,7 @@ import type { InstanceSettings } from 'n8n-core'; import type { KeyObject } from 'node:crypto'; import { createHmac, createPublicKey, generateKeyPairSync } from 'node:crypto'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService, type UrlService } from '@n8n/backend-services'; import type { AccessToken } from '../database/entities/oauth-access-token.entity'; import type { RefreshToken } from '../database/entities/oauth-refresh-token.entity'; @@ -31,7 +31,6 @@ import { McpProtectedResource } from '@/modules/mcp/mcp-protected-resource'; import type { McpConfig } from '@/modules/mcp/mcp.config'; import type { McpSettingsService } from '@/modules/mcp/mcp.settings.service'; import { ProtectedResourceRegistry } from '@/services/protected-resource.registry'; -import type { UrlService } from '@n8n/backend-services'; import type { WorkflowFinderService } from '@/workflows/workflow-finder.service'; const LEGACY_HMAC_SECRET = 'legacy-hmac-secret'; diff --git a/packages/cli/src/modules/oauth-server/__tests__/signing-key-fixtures.ts b/packages/cli/src/modules/oauth-server/__tests__/signing-key-fixtures.ts index a9672ff47bc..136e92e40db 100644 --- a/packages/cli/src/modules/oauth-server/__tests__/signing-key-fixtures.ts +++ b/packages/cli/src/modules/oauth-server/__tests__/signing-key-fixtures.ts @@ -5,7 +5,7 @@ import type { JsonWebKey, KeyObject } from 'node:crypto'; import { createPrivateKey, sign as cryptoSign } from 'node:crypto'; import { mock } from 'vitest-mock-extended'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; import { OAUTH_SIGNING_KEY_TYPE } from '../oauth-signing-key.constants'; import { OAuthSigningKeyService } from '../oauth-signing-key.service'; diff --git a/packages/cli/src/modules/oauth-server/__tests__/workflow-mcp-trigger-authorization.api.test.ts b/packages/cli/src/modules/oauth-server/__tests__/workflow-mcp-trigger-authorization.api.test.ts index 61ce1261da7..e2c9fa0a24d 100644 --- a/packages/cli/src/modules/oauth-server/__tests__/workflow-mcp-trigger-authorization.api.test.ts +++ b/packages/cli/src/modules/oauth-server/__tests__/workflow-mcp-trigger-authorization.api.test.ts @@ -16,9 +16,7 @@ import { setupTestServer } from '@test-integration/utils'; import { MCP_TRIGGER_NODE_TYPE } from '@/constants'; import { OAuthTokenService } from '@/modules/oauth-server/oauth-token.service'; -import { CacheService } from '@n8n/backend-services'; -import { UrlService } from '@n8n/backend-services'; -import { JwtService } from '@/services/jwt.service'; +import { CacheService, UrlService, JwtService } from '@n8n/backend-services'; import { OAuthClientRepository } from '../database/repositories/oauth-client.repository'; import type { OAuthSessionPayload } from '../oauth-session.service'; diff --git a/packages/cli/src/modules/oauth-server/oauth-session.service.ts b/packages/cli/src/modules/oauth-server/oauth-session.service.ts index 50a30fcf05a..30d5b4c5bcb 100644 --- a/packages/cli/src/modules/oauth-server/oauth-session.service.ts +++ b/packages/cli/src/modules/oauth-server/oauth-session.service.ts @@ -3,7 +3,7 @@ import { Service } from '@n8n/di'; import { Response } from 'express'; import { z } from 'zod'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; const oauthSessionPayloadSchema = z.object({ clientId: z.string(), diff --git a/packages/cli/src/modules/oauth-server/oauth-signing-key.service.ts b/packages/cli/src/modules/oauth-server/oauth-signing-key.service.ts index db2a540ac2f..23bc5a3ef01 100644 --- a/packages/cli/src/modules/oauth-server/oauth-signing-key.service.ts +++ b/packages/cli/src/modules/oauth-server/oauth-signing-key.service.ts @@ -12,7 +12,7 @@ import type { JsonWebKey, KeyObject } from 'node:crypto'; import { createPrivateKey, createPublicKey, generateKeyPair } from 'node:crypto'; import { promisify } from 'node:util'; -import { JwtService, type JwtPayload } from '@/services/jwt.service'; +import { JwtService, type JwtPayload } from '@n8n/backend-services'; import { ACCESS_TOKEN_TYPES, diff --git a/packages/cli/src/modules/oauth-server/oauth-token.service.ts b/packages/cli/src/modules/oauth-server/oauth-token.service.ts index f566d146c02..434ff1ecb60 100644 --- a/packages/cli/src/modules/oauth-server/oauth-token.service.ts +++ b/packages/cli/src/modules/oauth-server/oauth-token.service.ts @@ -15,14 +15,13 @@ import { UnexpectedError } from 'n8n-workflow'; import { randomBytes, randomUUID } from 'node:crypto'; import { authorizeAgainstGrant } from '@/modules/inbound-auth-core/grant-authorization'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService, UrlService } from '@n8n/backend-services'; import type { OAuthTokenVerifier, UserWithContext, } from '@/services/oauth-token-verifier-proxy.service'; import type { ProtectedResource } from '@/services/protected-resource.registry'; import { ProtectedResourceRegistry } from '@/services/protected-resource.registry'; -import { UrlService } from '@n8n/backend-services'; import { WorkflowFinderService } from '@/workflows/workflow-finder.service'; import { AccessTokenRepository } from './database/repositories/oauth-access-token.repository'; diff --git a/packages/cli/src/modules/scim/__tests__/scim-token.service.test.ts b/packages/cli/src/modules/scim/__tests__/scim-token.service.test.ts index 5d1d7741172..ccd9a19afef 100644 --- a/packages/cli/src/modules/scim/__tests__/scim-token.service.test.ts +++ b/packages/cli/src/modules/scim/__tests__/scim-token.service.test.ts @@ -2,8 +2,7 @@ import type { ApiKey, User } from '@n8n/db'; import type { Mocked } from 'vitest'; import { mock } from 'vitest-mock-extended'; -import type { JwtService } from '@/services/jwt.service'; -import type { UrlService } from '@n8n/backend-services'; +import type { JwtService, UrlService } from '@n8n/backend-services'; import type { ScimApiKeyRepository } from '../database/scim-api-key.repository'; import { ScimTokenService } from '../scim-token.service'; diff --git a/packages/cli/src/modules/scim/database/scim-api-key.repository.ts b/packages/cli/src/modules/scim/database/scim-api-key.repository.ts index 39f75ecafea..9cfdc1d3000 100644 --- a/packages/cli/src/modules/scim/database/scim-api-key.repository.ts +++ b/packages/cli/src/modules/scim/database/scim-api-key.repository.ts @@ -2,7 +2,7 @@ import { ApiKey, BaseRepository, TransactionRunner, type OperationContext } from import { Service } from '@n8n/di'; import { DataSource } from '@n8n/typeorm'; -import { TOKEN_PURPOSES } from '@/services/token-purposes'; +import { TOKEN_PURPOSES } from '@n8n/backend-services'; /** * SCIM provisioning keys are ordinary API keys reserved by their audience. diff --git a/packages/cli/src/modules/scim/scim-token.service.ts b/packages/cli/src/modules/scim/scim-token.service.ts index 01a1884183f..c91169849e1 100644 --- a/packages/cli/src/modules/scim/scim-token.service.ts +++ b/packages/cli/src/modules/scim/scim-token.service.ts @@ -2,8 +2,7 @@ import { type OperationContext, type User } from '@n8n/db'; import { Service } from '@n8n/di'; import { randomUUID } from 'crypto'; -import { JwtService } from '@/services/jwt.service'; -import { UrlService } from '@n8n/backend-services'; +import { JwtService, UrlService } from '@n8n/backend-services'; import { ScimApiKeyRepository } from './database/scim-api-key.repository'; diff --git a/packages/cli/src/modules/sso-oidc/__tests__/oidc.service.ee.test.ts b/packages/cli/src/modules/sso-oidc/__tests__/oidc.service.ee.test.ts index 11a93fa39a3..011ea7b2d22 100644 --- a/packages/cli/src/modules/sso-oidc/__tests__/oidc.service.ee.test.ts +++ b/packages/cli/src/modules/sso-oidc/__tests__/oidc.service.ee.test.ts @@ -31,8 +31,7 @@ vi.mock('openid-client', async (importOriginal) => { import { BadRequestError, ForbiddenError } from '@n8n/errors'; import { type ProvisioningService } from '@/modules/provisioning.ee/provisioning.service.ee'; import { Publisher } from '@/scaling/pubsub/publisher.service'; -import type { JwtService } from '@/services/jwt.service'; -import type { UrlService } from '@n8n/backend-services'; +import type { JwtService, UrlService } from '@n8n/backend-services'; import * as ssoHelpers from '@/sso.ee/sso-helpers'; import { OIDC_PREFERENCES_DB_KEY } from '../constants'; diff --git a/packages/cli/src/modules/sso-oidc/oidc.service.ee.ts b/packages/cli/src/modules/sso-oidc/oidc.service.ee.ts index 7775c46b39c..99174eb2bbd 100644 --- a/packages/cli/src/modules/sso-oidc/oidc.service.ee.ts +++ b/packages/cli/src/modules/sso-oidc/oidc.service.ee.ts @@ -22,8 +22,7 @@ import { inspect } from 'util'; import { BadRequestError, ForbiddenError } from '@n8n/errors'; import { buildOidcClaimsContext } from '@/modules/provisioning.ee/claims-context.builder'; import { ProvisioningService } from '@/modules/provisioning.ee/provisioning.service.ee'; -import { JwtService } from '@/services/jwt.service'; -import { UrlService } from '@n8n/backend-services'; +import { JwtService, UrlService } from '@n8n/backend-services'; import { assertAuthenticationMethodCanBeEnabled, getCurrentAuthenticationMethod, diff --git a/packages/cli/src/modules/token-exchange/services/__tests__/scoped-jwt.strategy.integration.test.ts b/packages/cli/src/modules/token-exchange/services/__tests__/scoped-jwt.strategy.integration.test.ts index fb359e4544c..98556894165 100644 --- a/packages/cli/src/modules/token-exchange/services/__tests__/scoped-jwt.strategy.integration.test.ts +++ b/packages/cli/src/modules/token-exchange/services/__tests__/scoped-jwt.strategy.integration.test.ts @@ -5,7 +5,7 @@ import { Container } from '@n8n/di'; import type { InstanceSettings } from 'n8n-core'; import { mock } from 'vitest-mock-extended'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; import { createMember, createOwner } from '@test-integration/db/users'; import { TOKEN_EXCHANGE_ISSUER } from '../../token-exchange.types'; diff --git a/packages/cli/src/modules/token-exchange/services/__tests__/scoped-jwt.strategy.test.ts b/packages/cli/src/modules/token-exchange/services/__tests__/scoped-jwt.strategy.test.ts index 3cb0a509d7c..3b97b37163a 100644 --- a/packages/cli/src/modules/token-exchange/services/__tests__/scoped-jwt.strategy.test.ts +++ b/packages/cli/src/modules/token-exchange/services/__tests__/scoped-jwt.strategy.test.ts @@ -4,7 +4,7 @@ import type { InstanceSettings } from 'n8n-core'; import type { Mocked } from 'vitest'; import { mock } from 'vitest-mock-extended'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; import { TOKEN_EXCHANGE_ISSUER, type IssuedJwtPayload } from '../../token-exchange.types'; import { ScopedJwtStrategy } from '../scoped-jwt.strategy'; diff --git a/packages/cli/src/modules/token-exchange/services/__tests__/token-exchange.service.test.ts b/packages/cli/src/modules/token-exchange/services/__tests__/token-exchange.service.test.ts index 3431ca7fed1..54ed9d31cc5 100644 --- a/packages/cli/src/modules/token-exchange/services/__tests__/token-exchange.service.test.ts +++ b/packages/cli/src/modules/token-exchange/services/__tests__/token-exchange.service.test.ts @@ -4,7 +4,7 @@ import jwt from 'jsonwebtoken'; import { mock } from 'vitest-mock-extended'; import { AuthError, BadRequestError } from '@n8n/errors'; -import type { JwtService } from '@/services/jwt.service'; +import type { JwtService } from '@n8n/backend-services'; import type { TokenExchangeConfig } from '../../token-exchange.config'; import type { ResolvedTrustedKey } from '../../token-exchange.schemas'; diff --git a/packages/cli/src/modules/token-exchange/services/scoped-jwt.strategy.ts b/packages/cli/src/modules/token-exchange/services/scoped-jwt.strategy.ts index 148b007b0c8..d8f9cd95d8f 100644 --- a/packages/cli/src/modules/token-exchange/services/scoped-jwt.strategy.ts +++ b/packages/cli/src/modules/token-exchange/services/scoped-jwt.strategy.ts @@ -5,7 +5,7 @@ import { getApiKeyScopesForRole } from '@n8n/permissions'; import { JsonWebTokenError, TokenExpiredError } from 'jsonwebtoken'; import type { AuthStrategy, AuthStrategyOptions } from '@/services/auth-strategy.types'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; import { TOKEN_EXCHANGE_ISSUER, type IssuedJwtPayload } from '../token-exchange.types'; diff --git a/packages/cli/src/modules/token-exchange/services/token-exchange.service.ts b/packages/cli/src/modules/token-exchange/services/token-exchange.service.ts index 3489e7187ae..96a56a6fa0f 100644 --- a/packages/cli/src/modules/token-exchange/services/token-exchange.service.ts +++ b/packages/cli/src/modules/token-exchange/services/token-exchange.service.ts @@ -4,7 +4,7 @@ import { Service } from '@n8n/di'; import { randomUUID } from 'crypto'; import jwt from 'jsonwebtoken'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; import { TokenExchangeConfig } from '../token-exchange.config'; import { TokenExchangeAuthError, TokenExchangeRequestError } from '../token-exchange.errors'; diff --git a/packages/cli/src/services/__tests__/api-key-auth.strategy.integration.test.ts b/packages/cli/src/services/__tests__/api-key-auth.strategy.integration.test.ts index df86e0c7eb5..615889fceca 100644 --- a/packages/cli/src/services/__tests__/api-key-auth.strategy.integration.test.ts +++ b/packages/cli/src/services/__tests__/api-key-auth.strategy.integration.test.ts @@ -14,7 +14,7 @@ import { createOwnerWithApiKey } from '@test-integration/db/users'; import { retryUntil } from '@test-integration/retry-until'; import { ApiKeyAuthStrategy } from '../api-key-auth.strategy'; -import { JwtService } from '../jwt.service'; +import { JwtService } from '@n8n/backend-services'; import { API_KEY_ISSUER } from '../public-api-key.service'; const mockReqWith = (apiKey: string): AuthenticatedRequest => diff --git a/packages/cli/src/services/__tests__/deployment-signing-secrets.integration.test.ts b/packages/cli/src/services/__tests__/deployment-signing-secrets.integration.test.ts index b4060c7e745..631fd22438f 100644 --- a/packages/cli/src/services/__tests__/deployment-signing-secrets.integration.test.ts +++ b/packages/cli/src/services/__tests__/deployment-signing-secrets.integration.test.ts @@ -7,7 +7,7 @@ import jsonwebtoken from 'jsonwebtoken'; import { Cipher, InstanceSettings } from 'n8n-core'; import { mock } from 'vitest-mock-extended'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; const INSTANCE_ENCRYPTION_KEY = 'signing-secrets-instance-key'; diff --git a/packages/cli/src/services/__tests__/public-api-key.service.integration.test.ts b/packages/cli/src/services/__tests__/public-api-key.service.integration.test.ts index c45943ca125..aa4bb565990 100644 --- a/packages/cli/src/services/__tests__/public-api-key.service.integration.test.ts +++ b/packages/cli/src/services/__tests__/public-api-key.service.integration.test.ts @@ -11,7 +11,7 @@ import { mock } from 'vitest-mock-extended'; import { createAdminWithApiKey, createOwnerWithApiKey } from '@test-integration/db/users'; -import { JwtService } from '../jwt.service'; +import { JwtService } from '@n8n/backend-services'; import { PublicApiKeyService } from '../public-api-key.service'; const instanceSettings = mock({ encryptionKey: 'test-key' }); diff --git a/packages/cli/src/services/__tests__/public-api-key.service.test.ts b/packages/cli/src/services/__tests__/public-api-key.service.test.ts index 29aab9fb506..bacd15732cd 100644 --- a/packages/cli/src/services/__tests__/public-api-key.service.test.ts +++ b/packages/cli/src/services/__tests__/public-api-key.service.test.ts @@ -6,7 +6,7 @@ import { mock } from 'vitest-mock-extended'; import { BadRequestError, NotFoundError } from '@n8n/errors'; import type { UserManagementMailer } from '@/user-management/email'; -import type { JwtService } from '../jwt.service'; +import type { JwtService } from '@n8n/backend-services'; import { PublicApiKeyService } from '../public-api-key.service'; vi.mock('@n8n/permissions', async () => ({ diff --git a/packages/cli/src/services/__tests__/user.service.test.ts b/packages/cli/src/services/__tests__/user.service.test.ts index 959f6ff01cc..024d685f0a9 100644 --- a/packages/cli/src/services/__tests__/user.service.test.ts +++ b/packages/cli/src/services/__tests__/user.service.test.ts @@ -1,5 +1,5 @@ import { InviteUsersRequestDto } from '@n8n/api-types'; -import { type EventService, UrlService, type RoleService } from '@n8n/backend-services'; +import { type EventService, UrlService, type RoleService, JwtService } from '@n8n/backend-services'; import { mockInstance } from '@n8n/backend-test-utils'; import { GlobalConfig } from '@n8n/config'; import { @@ -30,7 +30,6 @@ import { UserService } from '@/services/user.service'; import * as ssoHelpers from '@/sso.ee/sso-helpers'; import type { UserManagementMailer } from '@/user-management/email'; -import { JwtService } from '../jwt.service'; import type { OwnershipTransferService } from '../ownership-transfer/ownership-transfer.service'; import type { OwnershipService } from '../ownership.service'; import type { ProjectService } from '../project.service.ee'; diff --git a/packages/cli/src/services/api-key-auth.strategy.ts b/packages/cli/src/services/api-key-auth.strategy.ts index 1e3db7fec26..df7d713e173 100644 --- a/packages/cli/src/services/api-key-auth.strategy.ts +++ b/packages/cli/src/services/api-key-auth.strategy.ts @@ -8,8 +8,7 @@ import { TokenExpiredError } from 'jsonwebtoken'; import { isApiKeyAuthEnabled } from '@/public-api'; import type { AuthStrategy, AuthStrategyOptions } from './auth-strategy.types'; -import { JwtService } from './jwt.service'; -import { API_KEY_PURPOSES } from './token-purposes'; +import { JwtService, API_KEY_PURPOSES } from '@n8n/backend-services'; import { API_KEY_AUDIENCE, API_KEY_ISSUER, PREFIX_LEGACY_API_KEY } from './public-api-key.service'; const API_KEY_HEADER = 'x-n8n-api-key'; diff --git a/packages/cli/src/services/public-api-key.service.ts b/packages/cli/src/services/public-api-key.service.ts index d98dcc5764f..a50b49dd758 100644 --- a/packages/cli/src/services/public-api-key.service.ts +++ b/packages/cli/src/services/public-api-key.service.ts @@ -24,7 +24,7 @@ import { randomUUID } from 'crypto'; import { BadRequestError, NotFoundError } from '@n8n/errors'; import { UserManagementMailer } from '@/user-management/email'; -import { JwtService } from './jwt.service'; +import { JwtService } from '@n8n/backend-services'; export const API_KEY_AUDIENCE: ApiKeyAudience = 'public-api'; export const API_KEY_ISSUER = 'n8n'; diff --git a/packages/cli/src/services/user.service.ts b/packages/cli/src/services/user.service.ts index 5093bdd90e5..9ebaf94cd83 100644 --- a/packages/cli/src/services/user.service.ts +++ b/packages/cli/src/services/user.service.ts @@ -1,6 +1,6 @@ import type { RoleChangeRequestDto } from '@n8n/api-types'; import { Logger } from '@n8n/backend-common'; -import { EventService, UrlService, RoleService } from '@n8n/backend-services'; +import { EventService, UrlService, RoleService, JwtService } from '@n8n/backend-services'; import { GlobalConfig } from '@n8n/config'; import type { PublicUser } from '@n8n/db'; import { @@ -30,7 +30,6 @@ import type { IUserSettings } from 'n8n-workflow'; import { UserError } from 'n8n-workflow'; import { validate as uuidValidate } from 'uuid'; -import { JwtService } from './jwt.service'; import { OwnershipService } from './ownership.service'; import { ProjectService } from './project.service.ee'; import { PublicApiKeyService } from './public-api-key.service'; diff --git a/packages/cli/test/integration/auth.api.test.ts b/packages/cli/test/integration/auth.api.test.ts index 1ba6653b330..7232beddf37 100644 --- a/packages/cli/test/integration/auth.api.test.ts +++ b/packages/cli/test/integration/auth.api.test.ts @@ -1,4 +1,4 @@ -import { EventService } from '@n8n/backend-services'; +import { EventService, JwtService } from '@n8n/backend-services'; import { randomValidPassword, testDb } from '@n8n/backend-test-utils'; import type { User } from '@n8n/db'; import { GLOBAL_MEMBER_ROLE, GLOBAL_OWNER_ROLE, UserRepository } from '@n8n/db'; @@ -9,7 +9,6 @@ import config from '@/config'; import { AUTH_COOKIE_NAME } from '@/constants'; import type { RelayEventMap } from '@/events/maps/relay.event-map'; import { MfaService } from '@/mfa/mfa.service'; -import { JwtService } from '@/services/jwt.service'; import { LOGGED_OUT_RESPONSE_BODY } from './shared/constants'; import { createUser, createUserShell } from './shared/db/users'; diff --git a/packages/cli/test/integration/controllers/invitation/invitation.controller.integration.test.ts b/packages/cli/test/integration/controllers/invitation/invitation.controller.integration.test.ts index fb9d10fbcdc..132fb45c3f9 100644 --- a/packages/cli/test/integration/controllers/invitation/invitation.controller.integration.test.ts +++ b/packages/cli/test/integration/controllers/invitation/invitation.controller.integration.test.ts @@ -1,4 +1,4 @@ -import { EventService } from '@n8n/backend-services'; +import { EventService, JwtService } from '@n8n/backend-services'; import { mockInstance, randomEmail, @@ -18,7 +18,6 @@ import { PROJECT_OWNER_ROLE_SLUG } from '@n8n/permissions'; import { Not } from '@n8n/typeorm'; import { ExternalHooks } from '@/external-hooks'; -import { JwtService } from '@/services/jwt.service'; import { PasswordUtility } from '@/services/password.utility'; import { UserManagementMailer } from '@/user-management/email'; diff --git a/packages/cli/test/integration/oidc/oidc.service.ee.test.ts b/packages/cli/test/integration/oidc/oidc.service.ee.test.ts index 3002b9d060b..7de28979dfa 100644 --- a/packages/cli/test/integration/oidc/oidc.service.ee.test.ts +++ b/packages/cli/test/integration/oidc/oidc.service.ee.test.ts @@ -28,7 +28,7 @@ import { License } from '@/license'; import { ProvisioningService } from '@/modules/provisioning.ee/provisioning.service.ee'; import { OIDC_CLIENT_SECRET_REDACTED_VALUE } from '@/modules/sso-oidc/constants'; import { OidcService } from '@/modules/sso-oidc/oidc.service.ee'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; import { createCustomRoleWithScopes, createScope } from '@test-integration/db/roles'; import { createUser } from '@test-integration/db/users'; diff --git a/packages/cli/test/integration/password-reset.api.test.ts b/packages/cli/test/integration/password-reset.api.test.ts index 1788398513e..1afb0bb0e81 100644 --- a/packages/cli/test/integration/password-reset.api.test.ts +++ b/packages/cli/test/integration/password-reset.api.test.ts @@ -18,7 +18,7 @@ import { AuthService } from '@/auth/auth.service'; import config from '@/config'; import { ExternalHooks } from '@/external-hooks'; import { License } from '@/license'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; import { PasswordUtility } from '@/services/password.utility'; import { setCurrentAuthenticationMethod } from '@/sso.ee/sso-helpers'; import { UserManagementMailer } from '@/user-management/email'; diff --git a/packages/cli/test/integration/public-api/endpoints-with-scopes-enabled.test.ts b/packages/cli/test/integration/public-api/endpoints-with-scopes-enabled.test.ts index 81b6c8b5d9d..5787f55a2aa 100644 --- a/packages/cli/test/integration/public-api/endpoints-with-scopes-enabled.test.ts +++ b/packages/cli/test/integration/public-api/endpoints-with-scopes-enabled.test.ts @@ -23,7 +23,7 @@ import { mock } from 'vitest-mock-extended'; import { TOKEN_EXCHANGE_ISSUER } from '@/modules/token-exchange/token-exchange.types'; import { CredentialsTester } from '@/services/credentials-tester.service'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; import { affixRoleToSaveCredential, createCredentials } from '@test-integration/db/credentials'; import { createAnnotationTags, diff --git a/packages/cli/test/integration/token-exchange/token-exchange.controller.test.ts b/packages/cli/test/integration/token-exchange/token-exchange.controller.test.ts index 23aaaa9a3ca..07480fd3608 100644 --- a/packages/cli/test/integration/token-exchange/token-exchange.controller.test.ts +++ b/packages/cli/test/integration/token-exchange/token-exchange.controller.test.ts @@ -14,7 +14,7 @@ import { type IssuedJwtPayload, type TokenExchangeSuccessResponse, } from '@/modules/token-exchange/token-exchange.types'; -import { JwtService } from '@/services/jwt.service'; +import { JwtService } from '@n8n/backend-services'; import { createUser } from '../shared/db/users'; import * as utils from '../shared/utils'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cea17fbc238..ceade73ac1a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1883,6 +1883,12 @@ importers: ioredis: specifier: 5.3.2 version: 5.3.2(supports-color@8.1.1) + jsonwebtoken: + specifier: 'catalog:' + version: 9.0.3 + n8n-core: + specifier: workspace:* + version: link:../../core n8n-workflow: specifier: workspace:* version: link:../../workflow @@ -1902,6 +1908,9 @@ importers: '@n8n/vitest-config': specifier: workspace:* version: link:../vitest-config + '@types/jsonwebtoken': + specifier: 'catalog:' + version: 9.0.10 '@types/lodash': specifier: 'catalog:' version: 4.17.17