mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-17 05:29:44 +02:00
refactor(core): Move JWT support into backend services (#41089)
This commit is contained in:
parent
7920e6cf6b
commit
b6d39e2d30
2
OWNERS
2
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
|
||||
|
|
|
|||
|
|
@ -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': [
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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:",
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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
|
||||
12
packages/@n8n/backend-services/test/setup-test-folder.ts
Normal file
12
packages/@n8n/backend-services/test/setup-test-folder.ts
Normal file
|
|
@ -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 });
|
||||
});
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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 =>
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
|
|
@ -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<InstanceSettings>({ encryptionKey: 'test-key' });
|
||||
|
|
|
|||
|
|
@ -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 () => ({
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user