diff --git a/packages/core/src/driver.ts b/packages/core/src/driver.ts index 96d1fdeec..d2476810e 100644 --- a/packages/core/src/driver.ts +++ b/packages/core/src/driver.ts @@ -198,12 +198,12 @@ class SessionConfig { /** * The {@link AuthToken} which will be used for the duration of the session. * - * By default, the session will use connections authenticated with {@link AuthToken} configured in the - * driver creation. This configuration allows switch user and/or authorization information for the + * By default, the session will use connections authenticated with the {@link AuthToken} configured on + * driver creation. This configuration allows switching user and/or authorization information for the * session lifetime. * - * **Warning**: This option is only enable when the driver is connected with Neo4j Database servers - * which supports Bolt 5.1 and onwards. + * **Warning**: This option is only available when the driver is connected to Neo4j Database servers + * which supports Bolt 5.1 or newer. * * @type {AuthToken|undefined} * @see {@link driver} @@ -357,6 +357,7 @@ class QueryConfig { bookmarkManager?: BookmarkManager | null resultTransformer?: ResultTransformer transactionConfig?: TransactionConfig + auth?: AuthToken /** * @constructor @@ -413,6 +414,21 @@ class QueryConfig { * */ this.transactionConfig = undefined + + /** + * The {@link AuthToken} which will be used for executing the query. + * + * By default, the query executor will use connections authenticated with the {@link AuthToken} configured on + * driver creation. This configuration allows switching user and/or authorization information for the + * underlying transaction's lifetime. + * + * **Warning**: This option is only available when the driver is connected to Neo4j Database servers + * which support Bolt 5.1 or newer. + * + * @type {AuthToken|undefined} + * @see {@link driver} + */ + this.auth = undefined } } @@ -578,7 +594,8 @@ class Driver { routing: routingConfig, database: config.database, impersonatedUser: config.impersonatedUser, - transactionConfig: config.transactionConfig + transactionConfig: config.transactionConfig, + auth: config.auth }, query, parameters) } diff --git a/packages/core/src/internal/query-executor.ts b/packages/core/src/internal/query-executor.ts index 90dcc4fb1..aaf7f459a 100644 --- a/packages/core/src/internal/query-executor.ts +++ b/packages/core/src/internal/query-executor.ts @@ -19,10 +19,10 @@ import BookmarkManager from '../bookmark-manager' import Session, { TransactionConfig } from '../session' import Result from '../result' import ManagedTransaction from '../transaction-managed' -import { Query } from '../types' +import { AuthToken, Query } from '../types' import { TELEMETRY_APIS } from './constants' -type SessionFactory = (config: { database?: string, bookmarkManager?: BookmarkManager, impersonatedUser?: string }) => Session +type SessionFactory = (config: { database?: string, bookmarkManager?: BookmarkManager, impersonatedUser?: string, auth?: AuthToken }) => Session type TransactionFunction = (transactionWork: (tx: ManagedTransaction) => Promise, transactionConfig?: TransactionConfig) => Promise @@ -32,6 +32,7 @@ interface ExecutionConfig { impersonatedUser?: string bookmarkManager?: BookmarkManager transactionConfig?: TransactionConfig + auth?: AuthToken resultTransformer: (result: Result) => Promise } @@ -44,7 +45,8 @@ export default class QueryExecutor { const session = this._createSession({ database: config.database, bookmarkManager: config.bookmarkManager, - impersonatedUser: config.impersonatedUser + impersonatedUser: config.impersonatedUser, + auth: config.auth }) // @ts-expect-error The method is private for external users diff --git a/packages/core/test/driver.test.ts b/packages/core/test/driver.test.ts index 48b872703..f4e810efb 100644 --- a/packages/core/test/driver.test.ts +++ b/packages/core/test/driver.test.ts @@ -484,6 +484,7 @@ describe('Driver', () => { ['config.routing=READ', 'create num $d', { d: 1 }, { routing: routing.READ }, extendsDefaultWith({ routing: routing.READ })], ['config.database="dbname"', 'q', {}, { database: 'dbname' }, extendsDefaultWith({ database: 'dbname' })], ['config.impersonatedUser="the_user"', 'q', {}, { impersonatedUser: 'the_user' }, extendsDefaultWith({ impersonatedUser: 'the_user' })], + ['config.auth={ scheme: "none", credentials: "" }', 'q', {}, { auth: { scheme: 'none', credentials: '' } }, extendsDefaultWith({ auth: { scheme: 'none', credentials: '' } })], ['config.bookmarkManager=null', 'q', {}, { bookmarkManager: null }, extendsDefaultWith({ bookmarkManager: undefined })], ['config.bookmarkManager set to non-null/empty', 'q', {}, { bookmarkManager: theBookmarkManager }, extendsDefaultWith({ bookmarkManager: theBookmarkManager })], ['config.resultTransformer set', 'q', {}, { resultTransformer: aTransformer }, extendsDefaultWith({ resultTransformer: aTransformer })], diff --git a/packages/core/test/internal/query-executor.test.ts b/packages/core/test/internal/query-executor.test.ts index f07416516..4bf67cb89 100644 --- a/packages/core/test/internal/query-executor.test.ts +++ b/packages/core/test/internal/query-executor.test.ts @@ -39,7 +39,9 @@ describe('QueryExecutor', () => { ['database set', { database: 'adb' }, { database: 'adb' }], ['database undefined', { database: undefined }, { database: undefined }], ['impersonatedUser set', { impersonatedUser: 'anUser' }, { impersonatedUser: 'anUser' }], - ['impersonatedUser undefined', { impersonatedUser: undefined }, { impersonatedUser: undefined }] + ['impersonatedUser undefined', { impersonatedUser: undefined }, { impersonatedUser: undefined }], + ['auth set', { auth: { scheme: 'none', credentials: '' } }, { auth: { scheme: 'none', credentials: '' } }], + ['auth undefined', { auth: undefined }, { auth: undefined }] ])('should redirect % to the session creation', async (_, executorConfig, expectConfig) => { const { queryExecutor, createSession } = createExecutor() diff --git a/packages/neo4j-driver-deno/lib/core/driver.ts b/packages/neo4j-driver-deno/lib/core/driver.ts index a6e61c49b..9ba6e07cf 100644 --- a/packages/neo4j-driver-deno/lib/core/driver.ts +++ b/packages/neo4j-driver-deno/lib/core/driver.ts @@ -198,12 +198,12 @@ class SessionConfig { /** * The {@link AuthToken} which will be used for the duration of the session. * - * By default, the session will use connections authenticated with {@link AuthToken} configured in the - * driver creation. This configuration allows switch user and/or authorization information for the + * By default, the session will use connections authenticated with the {@link AuthToken} configured on + * driver creation. This configuration allows switching user and/or authorization information for the * session lifetime. * - * **Warning**: This option is only enable when the driver is connected with Neo4j Database servers - * which supports Bolt 5.1 and onwards. + * **Warning**: This option is only available when the driver is connected to Neo4j Database servers + * which supports Bolt 5.1 or newer. * * @type {AuthToken|undefined} * @see {@link driver} @@ -357,6 +357,7 @@ class QueryConfig { bookmarkManager?: BookmarkManager | null resultTransformer?: ResultTransformer transactionConfig?: TransactionConfig + auth?: AuthToken /** * @constructor @@ -413,6 +414,21 @@ class QueryConfig { * */ this.transactionConfig = undefined + + /** + * The {@link AuthToken} which will be used for executing the query. + * + * By default, the query executor will use connections authenticated with the {@link AuthToken} configured on + * driver creation. This configuration allows switching user and/or authorization information for the + * underlying transaction's lifetime. + * + * **Warning**: This option is only available when the driver is connected to Neo4j Database servers + * which support Bolt 5.1 or newer. + * + * @type {AuthToken|undefined} + * @see {@link driver} + */ + this.auth = undefined } } @@ -578,7 +594,8 @@ class Driver { routing: routingConfig, database: config.database, impersonatedUser: config.impersonatedUser, - transactionConfig: config.transactionConfig + transactionConfig: config.transactionConfig, + auth: config.auth }, query, parameters) } diff --git a/packages/neo4j-driver-deno/lib/core/internal/query-executor.ts b/packages/neo4j-driver-deno/lib/core/internal/query-executor.ts index 56ac2b1b4..3ee641673 100644 --- a/packages/neo4j-driver-deno/lib/core/internal/query-executor.ts +++ b/packages/neo4j-driver-deno/lib/core/internal/query-executor.ts @@ -19,10 +19,10 @@ import BookmarkManager from '../bookmark-manager.ts' import Session, { TransactionConfig } from '../session.ts' import Result from '../result.ts' import ManagedTransaction from '../transaction-managed.ts' -import { Query } from '../types.ts' +import { AuthToken, Query } from '../types.ts' import { TELEMETRY_APIS } from './constants.ts' -type SessionFactory = (config: { database?: string, bookmarkManager?: BookmarkManager, impersonatedUser?: string }) => Session +type SessionFactory = (config: { database?: string, bookmarkManager?: BookmarkManager, impersonatedUser?: string, auth?: AuthToken }) => Session type TransactionFunction = (transactionWork: (tx: ManagedTransaction) => Promise, transactionConfig?: TransactionConfig) => Promise @@ -32,6 +32,7 @@ interface ExecutionConfig { impersonatedUser?: string bookmarkManager?: BookmarkManager transactionConfig?: TransactionConfig + auth?: AuthToken resultTransformer: (result: Result) => Promise } @@ -44,7 +45,8 @@ export default class QueryExecutor { const session = this._createSession({ database: config.database, bookmarkManager: config.bookmarkManager, - impersonatedUser: config.impersonatedUser + impersonatedUser: config.impersonatedUser, + auth: config.auth }) // @ts-expect-error The method is private for external users diff --git a/packages/testkit-backend/src/feature/common.js b/packages/testkit-backend/src/feature/common.js index 69d881f76..1e420e447 100644 --- a/packages/testkit-backend/src/feature/common.js +++ b/packages/testkit-backend/src/feature/common.js @@ -26,6 +26,7 @@ const features = [ 'Feature:Bolt:Patch:UTC', 'Feature:API:ConnectionAcquisitionTimeout', 'Feature:API:Driver.ExecuteQuery', + 'Feature:API:Driver.ExecuteQuery:WithAuth', 'Feature:API:Driver:NotificationsConfig', 'Feature:API:Driver:GetServerInfo', 'Feature:API:Driver.SupportsSessionAuth', diff --git a/packages/testkit-backend/src/request-handlers.js b/packages/testkit-backend/src/request-handlers.js index b1f17dd55..c7198c506 100644 --- a/packages/testkit-backend/src/request-handlers.js +++ b/packages/testkit-backend/src/request-handlers.js @@ -707,6 +707,10 @@ export function ExecuteQuery ({ neo4j }, context, { driverId, cypher, params, co timeout: config.timeout } } + + if (config.authorizationToken != null) { + configuration.auth = context.binder.parseAuthToken(config.authorizationToken.data) + } } driver.executeQuery(cypher, params, configuration)