@platformatic/kafka 1.22.0-alpha.2 → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -121,6 +121,21 @@ export declare const baseOptionsSchema: {
121
121
  type?: undefined;
122
122
  })[];
123
123
  };
124
+ oauthBearerExtensions: {
125
+ oneOf: ({
126
+ type: string;
127
+ patternProperties: {
128
+ '.+': {
129
+ type: string;
130
+ };
131
+ };
132
+ function?: undefined;
133
+ } | {
134
+ function: boolean;
135
+ type?: undefined;
136
+ patternProperties?: undefined;
137
+ })[];
138
+ };
124
139
  authBytesValidator: {
125
140
  function: boolean;
126
141
  };
@@ -41,6 +41,9 @@ export const baseOptionsSchema = {
41
41
  username: { oneOf: [{ type: 'string' }, { function: true }] },
42
42
  password: { oneOf: [{ type: 'string' }, { function: true }] },
43
43
  token: { oneOf: [{ type: 'string' }, { function: true }] },
44
+ oauthBearerExtensions: {
45
+ oneOf: [{ type: 'object', patternProperties: { '.+': { type: 'string' } } }, { function: true }]
46
+ },
44
47
  authBytesValidator: { function: true },
45
48
  authenticate: { function: true }
46
49
  },
@@ -6,7 +6,7 @@ import { type Callback, type ResponseParser } from '../apis/definitions.ts';
6
6
  import { type SASLMechanismValue } from '../apis/enumerations.ts';
7
7
  import { type SaslAuthenticateResponse, type SASLAuthenticationAPI } from '../apis/security/sasl-authenticate-v2.ts';
8
8
  import { Writer } from '../protocol/writer.ts';
9
- export type SASLCredentialProvider = () => string | Promise<string>;
9
+ export type SASLCredentialProvider<T = string> = () => T | Promise<T>;
10
10
  export interface Broker {
11
11
  host: string;
12
12
  port: number;
@@ -17,8 +17,9 @@ export interface SASLOptions {
17
17
  username?: string | SASLCredentialProvider;
18
18
  password?: string | SASLCredentialProvider;
19
19
  token?: string | SASLCredentialProvider;
20
- authBytesValidator?: (authBytes: Buffer, callback: CallbackWithPromise<Buffer>) => void;
20
+ oauthBearerExtensions?: Record<string, string> | SASLCredentialProvider<Record<string, string>>;
21
21
  authenticate?: SASLCustomAuthenticator;
22
+ authBytesValidator?: (authBytes: Buffer, callback: CallbackWithPromise<Buffer>) => void;
22
23
  }
23
24
  export interface ConnectionOptions {
24
25
  connectTimeout?: number;
@@ -68,9 +68,11 @@ export class Connection extends EventEmitter {
68
68
  this.#socketMustBeDrained = false;
69
69
  notifyCreation('connection', this);
70
70
  }
71
+ /* c8 ignore next 3 - Simple getter */
71
72
  get host() {
72
73
  return this.#status === ConnectionStatuses.CONNECTING || ConnectionStatuses.CONNECTED ? this.#host : undefined;
73
74
  }
75
+ /* c8 ignore next 3 - Simple getter */
74
76
  get port() {
75
77
  return this.#status === ConnectionStatuses.CONNECTING || ConnectionStatuses.CONNECTED ? this.#port : undefined;
76
78
  }
@@ -257,7 +259,7 @@ export class Connection extends EventEmitter {
257
259
  if (this.#status === ConnectionStatuses.CONNECTING) {
258
260
  this.#status = ConnectionStatuses.AUTHENTICATING;
259
261
  }
260
- const { mechanism, username, password, token, authenticate } = this.#options.sasl;
262
+ const { mechanism, username, password, token, oauthBearerExtensions, authenticate } = this.#options.sasl;
261
263
  if (!allowedSASLMechanisms.includes(mechanism)) {
262
264
  this.#onConnectionError(host, port, diagnosticContext, new UserError(`SASL mechanism ${mechanism} not supported.`));
263
265
  return;
@@ -276,7 +278,7 @@ export class Connection extends EventEmitter {
276
278
  saslPlain.authenticate(saslAuthenticateV2.api, this, username, password, callback);
277
279
  }
278
280
  else if (mechanism === SASLMechanisms.OAUTHBEARER) {
279
- saslOAuthBearer.authenticate(saslAuthenticateV2.api, this, token, callback);
281
+ saslOAuthBearer.authenticate(saslAuthenticateV2.api, this, token, oauthBearerExtensions, callback);
280
282
  }
281
283
  else if (mechanism === SASLMechanisms.GSSAPI) {
282
284
  callback(new UserError('No custom SASL/GSSAPI authenticator provided.'), undefined);
@@ -2,5 +2,5 @@ import { type CallbackWithPromise } from '../../apis/callbacks.ts';
2
2
  import { type SASLAuthenticationAPI, type SaslAuthenticateResponse } from '../../apis/security/sasl-authenticate-v2.ts';
3
3
  import { type Connection, type SASLCredentialProvider } from '../../network/connection.ts';
4
4
  export declare function jwtValidateAuthenticationBytes(authBytes: Buffer, callback: CallbackWithPromise<Buffer>): void;
5
- export declare function authenticate(authenticateAPI: SASLAuthenticationAPI, connection: Connection, tokenOrProvider: string | SASLCredentialProvider, callback: CallbackWithPromise<SaslAuthenticateResponse>): void;
6
- export declare function authenticate(authenticateAPI: SASLAuthenticationAPI, connection: Connection, tokenOrProvider: string | SASLCredentialProvider): Promise<SaslAuthenticateResponse>;
5
+ export declare function authenticate(authenticateAPI: SASLAuthenticationAPI, connection: Connection, tokenOrProvider: string | SASLCredentialProvider, extensions: Record<string, string> | SASLCredentialProvider<Record<string, string>>, callback: CallbackWithPromise<SaslAuthenticateResponse>): void;
6
+ export declare function authenticate(authenticateAPI: SASLAuthenticationAPI, connection: Connection, tokenOrProvider: string | SASLCredentialProvider, extensions: Record<string, string> | SASLCredentialProvider<Record<string, string>>): Promise<SaslAuthenticateResponse>;
@@ -18,7 +18,7 @@ export function jwtValidateAuthenticationBytes(authBytes, callback) {
18
18
  }
19
19
  callback(null, authBytes);
20
20
  }
21
- export function authenticate(authenticateAPI, connection, tokenOrProvider, callback) {
21
+ export function authenticate(authenticateAPI, connection, tokenOrProvider, extensionsOrProvider, callback) {
22
22
  if (!callback) {
23
23
  callback = createPromisifiedCallback();
24
24
  }
@@ -27,7 +27,18 @@ export function authenticate(authenticateAPI, connection, tokenOrProvider, callb
27
27
  callback(error, undefined);
28
28
  return;
29
29
  }
30
- authenticateAPI(connection, Buffer.from(`n,,\x01auth=Bearer ${token}\x01\x01`), callback);
30
+ getCredential('SASL/OAUTHBEARER extensions', extensionsOrProvider ?? {}, (error, extensionsMap) => {
31
+ if (error) {
32
+ return callback(error, undefined);
33
+ }
34
+ let extensions = '';
35
+ if (extensionsMap) {
36
+ for (const [key, value] of Object.entries(extensionsMap)) {
37
+ extensions += `\x01${key}=${value}`;
38
+ }
39
+ }
40
+ authenticateAPI(connection, Buffer.from(`n,,\x01auth=Bearer ${token}${extensions}\x01\x01`), callback);
41
+ });
31
42
  });
32
43
  return callback[kCallbackPromise];
33
44
  }
@@ -1,4 +1,4 @@
1
1
  import { type CallbackWithPromise } from '../../apis/index.ts';
2
2
  import { type SASLCredentialProvider } from '../../network/connection.ts';
3
- export declare function getCredential(label: string, credentialOrProvider: string | SASLCredentialProvider, callback: CallbackWithPromise<string>): void;
4
- export declare function getCredential(label: string, credentialOrProvider: string | SASLCredentialProvider): Promise<string>;
3
+ export declare function getCredential<T>(label: string, credentialOrProvider: T | SASLCredentialProvider<T>, callback: CallbackWithPromise<T>): void;
4
+ export declare function getCredential<T>(label: string, credentialOrProvider: T | SASLCredentialProvider<T>): Promise<T>;
@@ -4,33 +4,34 @@ export function getCredential(label, credentialOrProvider, callback) {
4
4
  if (!callback) {
5
5
  callback = createPromisifiedCallback();
6
6
  }
7
- if (typeof credentialOrProvider === 'string') {
8
- callback(null, credentialOrProvider);
7
+ if (typeof credentialOrProvider === 'undefined') {
8
+ callback(new AuthenticationError(`The ${label} should be a value or a function.`), undefined);
9
9
  return callback[kCallbackPromise];
10
10
  }
11
11
  else if (typeof credentialOrProvider !== 'function') {
12
- callback(new AuthenticationError(`The ${label} should be a string or a function.`), undefined);
12
+ callback(null, credentialOrProvider);
13
13
  return callback[kCallbackPromise];
14
14
  }
15
15
  try {
16
16
  const credential = credentialOrProvider();
17
- if (typeof credential === 'string') {
18
- callback(null, credential);
17
+ if (credential == null) {
18
+ callback(new AuthenticationError(`The ${label} provider should return a string or a promise that resolves to a value.`), undefined);
19
19
  return callback[kCallbackPromise];
20
20
  }
21
21
  else if (typeof credential?.then !== 'function') {
22
- callback(new AuthenticationError(`The ${label} provider should return a string or a promise that resolves to a string.`), undefined);
22
+ callback(null, credential);
23
23
  return callback[kCallbackPromise];
24
24
  }
25
+ ;
25
26
  credential
26
- .then(token => {
27
- if (typeof token !== 'string') {
28
- process.nextTick(callback, new AuthenticationError(`The ${label} provider should resolve to a string.`), undefined);
29
- return callback[kCallbackPromise];
27
+ .then((result) => {
28
+ if (result == null) {
29
+ process.nextTick(callback, new AuthenticationError(`The ${label} provider should resolve to a value.`), undefined);
30
+ return;
30
31
  }
31
- process.nextTick(callback, null, token);
32
+ process.nextTick(callback, null, result);
32
33
  })
33
- .catch(error => {
34
+ .catch((error) => {
34
35
  process.nextTick(callback, new AuthenticationError(`The ${label} provider threw an error.`, { cause: error }));
35
36
  });
36
37
  }
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  export const name = "@platformatic/kafka";
2
- export const version = "1.22.0-alpha.2";
2
+ export const version = "1.22.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/kafka",
3
- "version": "1.22.0-alpha.2",
3
+ "version": "1.22.0",
4
4
  "description": "Modern and performant client for Apache Kafka",
5
5
  "homepage": "https://github.com/platformatic/kafka",
6
6
  "author": "Platformatic Inc. <oss@platformatic.dev> (https://platformatic.dev)",