@depup/mysql2 3.19.0-depup.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.
Files changed (124) hide show
  1. package/License +19 -0
  2. package/README.md +114 -0
  3. package/index.d.ts +1 -0
  4. package/index.js +77 -0
  5. package/lib/auth_41.js +95 -0
  6. package/lib/auth_plugins/caching_sha2_password.js +114 -0
  7. package/lib/auth_plugins/caching_sha2_password.md +18 -0
  8. package/lib/auth_plugins/index.js +8 -0
  9. package/lib/auth_plugins/mysql_clear_password.js +17 -0
  10. package/lib/auth_plugins/mysql_native_password.js +34 -0
  11. package/lib/auth_plugins/sha256_password.js +68 -0
  12. package/lib/base/connection.js +988 -0
  13. package/lib/base/pool.js +282 -0
  14. package/lib/base/pool_connection.js +77 -0
  15. package/lib/commands/auth_switch.js +129 -0
  16. package/lib/commands/binlog_dump.js +109 -0
  17. package/lib/commands/change_user.js +68 -0
  18. package/lib/commands/client_handshake.js +383 -0
  19. package/lib/commands/close_statement.js +18 -0
  20. package/lib/commands/command.js +54 -0
  21. package/lib/commands/execute.js +112 -0
  22. package/lib/commands/index.js +27 -0
  23. package/lib/commands/ping.js +36 -0
  24. package/lib/commands/prepare.js +143 -0
  25. package/lib/commands/query.js +361 -0
  26. package/lib/commands/quit.js +29 -0
  27. package/lib/commands/register_slave.js +27 -0
  28. package/lib/commands/server_handshake.js +202 -0
  29. package/lib/compressed_protocol.js +153 -0
  30. package/lib/connection.js +12 -0
  31. package/lib/connection_config.js +293 -0
  32. package/lib/constants/charset_encodings.js +317 -0
  33. package/lib/constants/charsets.js +317 -0
  34. package/lib/constants/client.js +38 -0
  35. package/lib/constants/commands.js +36 -0
  36. package/lib/constants/cursor.js +8 -0
  37. package/lib/constants/encoding_charset.js +50 -0
  38. package/lib/constants/errors.js +3973 -0
  39. package/lib/constants/field_flags.js +20 -0
  40. package/lib/constants/server_status.js +44 -0
  41. package/lib/constants/session_track.js +11 -0
  42. package/lib/constants/ssl_profiles.js +11 -0
  43. package/lib/constants/types.js +64 -0
  44. package/lib/create_connection.js +10 -0
  45. package/lib/create_pool.js +10 -0
  46. package/lib/create_pool_cluster.js +9 -0
  47. package/lib/helpers.js +83 -0
  48. package/lib/packet_parser.js +195 -0
  49. package/lib/packets/auth_next_factor.js +35 -0
  50. package/lib/packets/auth_switch_request.js +38 -0
  51. package/lib/packets/auth_switch_request_more_data.js +33 -0
  52. package/lib/packets/auth_switch_response.js +30 -0
  53. package/lib/packets/binary_row.js +95 -0
  54. package/lib/packets/binlog_dump.js +33 -0
  55. package/lib/packets/binlog_query_statusvars.js +115 -0
  56. package/lib/packets/change_user.js +97 -0
  57. package/lib/packets/close_statement.js +21 -0
  58. package/lib/packets/column_definition.js +291 -0
  59. package/lib/packets/execute.js +214 -0
  60. package/lib/packets/handshake.js +112 -0
  61. package/lib/packets/handshake_response.js +173 -0
  62. package/lib/packets/index.js +152 -0
  63. package/lib/packets/packet.js +946 -0
  64. package/lib/packets/prepare_statement.js +27 -0
  65. package/lib/packets/prepared_statement_header.js +16 -0
  66. package/lib/packets/query.js +27 -0
  67. package/lib/packets/register_slave.js +46 -0
  68. package/lib/packets/resultset_header.js +124 -0
  69. package/lib/packets/ssl_request.js +25 -0
  70. package/lib/packets/text_row.js +47 -0
  71. package/lib/parsers/binary_parser.js +235 -0
  72. package/lib/parsers/parser_cache.js +68 -0
  73. package/lib/parsers/static_binary_parser.js +213 -0
  74. package/lib/parsers/static_text_parser.js +152 -0
  75. package/lib/parsers/string.js +50 -0
  76. package/lib/parsers/text_parser.js +214 -0
  77. package/lib/pool.js +12 -0
  78. package/lib/pool_cluster.js +375 -0
  79. package/lib/pool_config.js +30 -0
  80. package/lib/pool_connection.js +12 -0
  81. package/lib/promise/connection.js +228 -0
  82. package/lib/promise/inherit_events.js +27 -0
  83. package/lib/promise/make_done_cb.js +19 -0
  84. package/lib/promise/pool.js +118 -0
  85. package/lib/promise/pool_cluster.js +54 -0
  86. package/lib/promise/pool_connection.js +23 -0
  87. package/lib/promise/prepared_statement_info.js +32 -0
  88. package/lib/results_stream.js +38 -0
  89. package/lib/server.js +37 -0
  90. package/package.json +96 -0
  91. package/promise.d.ts +139 -0
  92. package/promise.js +208 -0
  93. package/typings/mysql/LICENSE.txt +15 -0
  94. package/typings/mysql/index.d.ts +84 -0
  95. package/typings/mysql/info.txt +1 -0
  96. package/typings/mysql/lib/Auth.d.ts +30 -0
  97. package/typings/mysql/lib/Connection.d.ts +442 -0
  98. package/typings/mysql/lib/Pool.d.ts +71 -0
  99. package/typings/mysql/lib/PoolCluster.d.ts +92 -0
  100. package/typings/mysql/lib/PoolConnection.d.ts +11 -0
  101. package/typings/mysql/lib/Server.d.ts +11 -0
  102. package/typings/mysql/lib/constants/CharsetToEncoding.d.ts +8 -0
  103. package/typings/mysql/lib/constants/Charsets.d.ts +326 -0
  104. package/typings/mysql/lib/constants/Types.d.ts +70 -0
  105. package/typings/mysql/lib/constants/index.d.ts +5 -0
  106. package/typings/mysql/lib/parsers/ParserCache.d.ts +4 -0
  107. package/typings/mysql/lib/parsers/index.d.ts +18 -0
  108. package/typings/mysql/lib/parsers/typeCast.d.ts +54 -0
  109. package/typings/mysql/lib/protocol/packets/Field.d.ts +10 -0
  110. package/typings/mysql/lib/protocol/packets/FieldPacket.d.ts +27 -0
  111. package/typings/mysql/lib/protocol/packets/OkPacket.d.ts +23 -0
  112. package/typings/mysql/lib/protocol/packets/ProcedurePacket.d.ts +13 -0
  113. package/typings/mysql/lib/protocol/packets/ResultSetHeader.d.ts +18 -0
  114. package/typings/mysql/lib/protocol/packets/RowDataPacket.d.ts +9 -0
  115. package/typings/mysql/lib/protocol/packets/index.d.ts +28 -0
  116. package/typings/mysql/lib/protocol/packets/params/ErrorPacketParams.d.ts +6 -0
  117. package/typings/mysql/lib/protocol/packets/params/OkPacketParams.d.ts +9 -0
  118. package/typings/mysql/lib/protocol/sequences/ExecutableBase.d.ts +41 -0
  119. package/typings/mysql/lib/protocol/sequences/Prepare.d.ts +65 -0
  120. package/typings/mysql/lib/protocol/sequences/Query.d.ts +228 -0
  121. package/typings/mysql/lib/protocol/sequences/QueryableBase.d.ts +41 -0
  122. package/typings/mysql/lib/protocol/sequences/Sequence.d.ts +5 -0
  123. package/typings/mysql/lib/protocol/sequences/promise/ExecutableBase.d.ts +17 -0
  124. package/typings/mysql/lib/protocol/sequences/promise/QueryableBase.d.ts +18 -0
@@ -0,0 +1,282 @@
1
+ 'use strict';
2
+
3
+ const process = require('process');
4
+ const SqlString = require('sql-escaper');
5
+ const EventEmitter = require('events').EventEmitter;
6
+ const PoolConnection = require('../pool_connection.js');
7
+ const Queue = require('denque');
8
+ const BaseConnection = require('./connection.js');
9
+ const Errors = require('../constants/errors.js');
10
+
11
+ // Source: https://github.com/go-sql-driver/mysql/blob/76c00e35a8d48f8f70f0e7dffe584692bd3fa612/packets.go#L598-L613
12
+ function isReadOnlyError(err) {
13
+ if (!err || !err.errno) {
14
+ return false;
15
+ }
16
+ // 1792: ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION
17
+ // 1290: ER_OPTION_PREVENTS_STATEMENT (returned by Aurora during failover)
18
+ // 1836: ER_READ_ONLY_MODE
19
+ return (
20
+ err.errno === Errors.ER_OPTION_PREVENTS_STATEMENT ||
21
+ err.errno === Errors.ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION ||
22
+ err.errno === Errors.ER_READ_ONLY_MODE
23
+ );
24
+ }
25
+
26
+ function spliceConnection(queue, connection) {
27
+ const len = queue.length;
28
+ for (let i = 0; i < len; i++) {
29
+ if (queue.get(i) === connection) {
30
+ queue.removeOne(i);
31
+ break;
32
+ }
33
+ }
34
+ }
35
+
36
+ class BasePool extends EventEmitter {
37
+ constructor(options) {
38
+ super();
39
+ this.config = options.config;
40
+ this.config.connectionConfig.pool = this;
41
+ this._allConnections = new Queue();
42
+ this._freeConnections = new Queue();
43
+ this._connectionQueue = new Queue();
44
+ this._closed = false;
45
+ if (this.config.maxIdle < this.config.connectionLimit) {
46
+ // create idle connection timeout automatically release job
47
+ this._removeIdleTimeoutConnections();
48
+ }
49
+ }
50
+
51
+ getConnection(cb) {
52
+ if (this._closed) {
53
+ return process.nextTick(() => cb(new Error('Pool is closed.')));
54
+ }
55
+ let connection;
56
+ if (this._freeConnections.length > 0) {
57
+ connection = this._freeConnections.pop();
58
+ this.emit('acquire', connection);
59
+ return process.nextTick(() => cb(null, connection));
60
+ }
61
+ if (
62
+ this.config.connectionLimit === 0 ||
63
+ this._allConnections.length < this.config.connectionLimit
64
+ ) {
65
+ connection = new PoolConnection(this, {
66
+ config: this.config.connectionConfig,
67
+ });
68
+ this._allConnections.push(connection);
69
+ return connection.connect((err) => {
70
+ if (this._closed) {
71
+ return cb(new Error('Pool is closed.'));
72
+ }
73
+ if (err) {
74
+ return cb(err);
75
+ }
76
+ this.emit('connection', connection);
77
+ this.emit('acquire', connection);
78
+ return cb(null, connection);
79
+ });
80
+ }
81
+ if (!this.config.waitForConnections) {
82
+ return process.nextTick(() => cb(new Error('No connections available.')));
83
+ }
84
+ if (
85
+ this.config.queueLimit &&
86
+ this._connectionQueue.length >= this.config.queueLimit
87
+ ) {
88
+ return cb(new Error('Queue limit reached.'));
89
+ }
90
+ this.emit('enqueue');
91
+ return this._connectionQueue.push(cb);
92
+ }
93
+
94
+ releaseConnection(connection) {
95
+ let cb;
96
+ if (!connection._pool) {
97
+ // The connection has been removed from the pool and is no longer good.
98
+ if (this._connectionQueue.length) {
99
+ cb = this._connectionQueue.shift();
100
+ process.nextTick(this.getConnection.bind(this, cb));
101
+ }
102
+ } else if (this._connectionQueue.length) {
103
+ cb = this._connectionQueue.shift();
104
+ process.nextTick(cb.bind(null, null, connection));
105
+ } else {
106
+ this._freeConnections.push(connection);
107
+ this.emit('release', connection);
108
+ }
109
+ }
110
+
111
+ [Symbol.dispose]() {
112
+ if (!this._closed) {
113
+ this.end();
114
+ }
115
+ }
116
+
117
+ end(cb) {
118
+ this._closed = true;
119
+ clearTimeout(this._removeIdleTimeoutConnectionsTimer);
120
+ if (typeof cb !== 'function') {
121
+ cb = function (err) {
122
+ if (err) {
123
+ throw err;
124
+ }
125
+ };
126
+ }
127
+ let calledBack = false;
128
+ let closedConnections = 0;
129
+ let connection;
130
+ const endCB = function (err) {
131
+ if (calledBack) {
132
+ return;
133
+ }
134
+ if (err || ++closedConnections >= this._allConnections.length) {
135
+ calledBack = true;
136
+ cb(err);
137
+ return;
138
+ }
139
+ }.bind(this);
140
+ if (this._allConnections.length === 0) {
141
+ endCB();
142
+ return;
143
+ }
144
+ for (let i = 0; i < this._allConnections.length; i++) {
145
+ connection = this._allConnections.get(i);
146
+ connection._realEnd(endCB);
147
+ }
148
+ }
149
+
150
+ query(sql, values, cb) {
151
+ const cmdQuery = BaseConnection.createQuery(
152
+ sql,
153
+ values,
154
+ cb,
155
+ this.config.connectionConfig
156
+ );
157
+ if (typeof cmdQuery.namedPlaceholders === 'undefined') {
158
+ cmdQuery.namedPlaceholders =
159
+ this.config.connectionConfig.namedPlaceholders;
160
+ }
161
+ this.getConnection((err, conn) => {
162
+ if (err) {
163
+ if (typeof cmdQuery.onResult === 'function') {
164
+ cmdQuery.onResult(err);
165
+ } else {
166
+ cmdQuery.emit('error', err);
167
+ }
168
+ return;
169
+ }
170
+ try {
171
+ let queryError = null;
172
+ const origOnResult = cmdQuery.onResult;
173
+ if (origOnResult) {
174
+ cmdQuery.onResult = function (err, rows, fields) {
175
+ queryError = err || null;
176
+ origOnResult(err, rows, fields);
177
+ };
178
+ } else {
179
+ cmdQuery.once('error', (err) => {
180
+ queryError = err;
181
+ });
182
+ }
183
+ conn.query(cmdQuery).once('end', () => {
184
+ if (isReadOnlyError(queryError)) {
185
+ conn.destroy();
186
+ } else {
187
+ conn.release();
188
+ }
189
+ });
190
+ } catch (e) {
191
+ conn.release();
192
+ throw e;
193
+ }
194
+ });
195
+ return cmdQuery;
196
+ }
197
+
198
+ execute(sql, values, cb) {
199
+ // TODO construct execute command first here and pass it to connection.execute
200
+ // so that polymorphic arguments logic is there in one place
201
+ if (typeof values === 'function') {
202
+ cb = values;
203
+ values = [];
204
+ }
205
+ this.getConnection((err, conn) => {
206
+ if (err) {
207
+ return cb(err);
208
+ }
209
+ try {
210
+ conn
211
+ .execute(sql, values, (err, rows, fields) => {
212
+ if (isReadOnlyError(err)) {
213
+ conn.destroy();
214
+ }
215
+ cb(err, rows, fields);
216
+ })
217
+ .once('end', () => {
218
+ conn.release();
219
+ });
220
+ } catch (e) {
221
+ conn.release();
222
+ return cb(e);
223
+ }
224
+ });
225
+ }
226
+
227
+ _removeConnection(connection) {
228
+ // Remove connection from all connections
229
+ spliceConnection(this._allConnections, connection);
230
+ // Remove connection from free connections
231
+ spliceConnection(this._freeConnections, connection);
232
+ this.releaseConnection(connection);
233
+ }
234
+
235
+ _removeIdleTimeoutConnections() {
236
+ if (this._removeIdleTimeoutConnectionsTimer) {
237
+ clearTimeout(this._removeIdleTimeoutConnectionsTimer);
238
+ }
239
+
240
+ this._removeIdleTimeoutConnectionsTimer = setTimeout(() => {
241
+ try {
242
+ while (
243
+ this._freeConnections.length > this.config.maxIdle ||
244
+ (this._freeConnections.length > 0 &&
245
+ Date.now() - this._freeConnections.get(0).lastActiveTime >
246
+ this.config.idleTimeout)
247
+ ) {
248
+ if (this.config.connectionConfig.gracefulEnd) {
249
+ this._freeConnections.get(0).end();
250
+ } else {
251
+ this._freeConnections.get(0).destroy();
252
+ }
253
+ }
254
+ } finally {
255
+ this._removeIdleTimeoutConnections();
256
+ }
257
+ }, 1000);
258
+ }
259
+
260
+ format(sql, values) {
261
+ return SqlString.format(
262
+ sql,
263
+ values,
264
+ this.config.connectionConfig.stringifyObjects,
265
+ this.config.connectionConfig.timezone
266
+ );
267
+ }
268
+
269
+ escape(value) {
270
+ return SqlString.escape(
271
+ value,
272
+ this.config.connectionConfig.stringifyObjects,
273
+ this.config.connectionConfig.timezone
274
+ );
275
+ }
276
+
277
+ escapeId(value) {
278
+ return SqlString.escapeId(value, false);
279
+ }
280
+ }
281
+
282
+ module.exports = BasePool;
@@ -0,0 +1,77 @@
1
+ 'use strict';
2
+
3
+ const BaseConnection = require('./connection.js');
4
+
5
+ class BasePoolConnection extends BaseConnection {
6
+ constructor(pool, options) {
7
+ super(options);
8
+ this._pool = pool;
9
+ // The last active time of this connection
10
+ this.lastActiveTime = Date.now();
11
+ // When a fatal error occurs the connection's protocol ends, which will cause
12
+ // the connection to end as well, thus we only need to watch for the end event
13
+ // and we will be notified of disconnects.
14
+ // REVIEW: Moved to `once`
15
+ this.once('end', () => {
16
+ this._removeFromPool();
17
+ });
18
+ this.once('error', () => {
19
+ this._removeFromPool();
20
+ });
21
+ }
22
+
23
+ release() {
24
+ if (!this._pool || this._pool._closed) {
25
+ return;
26
+ }
27
+ // update last active time
28
+ this.lastActiveTime = Date.now();
29
+ this._pool.releaseConnection(this);
30
+ }
31
+
32
+ [Symbol.dispose]() {
33
+ this.release();
34
+ }
35
+
36
+ end(callback) {
37
+ if (this.config.gracefulEnd) {
38
+ this._removeFromPool();
39
+ super.end(callback);
40
+
41
+ return;
42
+ }
43
+
44
+ const err = new Error(
45
+ 'Calling conn.end() to release a pooled connection is ' +
46
+ 'deprecated. In next version calling conn.end() will be ' +
47
+ 'restored to default conn.end() behavior. Use ' +
48
+ 'conn.release() instead.'
49
+ );
50
+ this.emit('warn', err);
51
+ console.warn(err.message);
52
+ this.release();
53
+ if (typeof callback === 'function') {
54
+ callback();
55
+ }
56
+ }
57
+
58
+ destroy() {
59
+ this._removeFromPool();
60
+ super.destroy();
61
+ }
62
+
63
+ _removeFromPool() {
64
+ if (!this._pool || this._pool._closed) {
65
+ return;
66
+ }
67
+ const pool = this._pool;
68
+ this._pool = null;
69
+ pool._removeConnection(this);
70
+ }
71
+ }
72
+
73
+ BasePoolConnection.statementKey = BaseConnection.statementKey;
74
+ module.exports = BasePoolConnection;
75
+
76
+ // TODO: Remove this when we are removing PoolConnection#end
77
+ BasePoolConnection.prototype._realEnd = BaseConnection.prototype.end;
@@ -0,0 +1,129 @@
1
+ // This file was modified by Oracle on July 5, 2021.
2
+ // Errors generated by asynchronous authentication plugins are now being
3
+ // handled and subsequently emitted at the command level.
4
+ // Modifications copyright (c) 2021, Oracle and/or its affiliates.
5
+
6
+ 'use strict';
7
+
8
+ const Packets = require('../packets/index.js');
9
+ const sha256_password = require('../auth_plugins/sha256_password');
10
+ const caching_sha2_password = require('../auth_plugins/caching_sha2_password.js');
11
+ const mysql_native_password = require('../auth_plugins/mysql_native_password.js');
12
+ const mysql_clear_password = require('../auth_plugins/mysql_clear_password.js');
13
+
14
+ // Use Object.create(null) to avoid prototype pollution
15
+ // This prevents server-controlled pluginName values like "toString" or "__proto__"
16
+ // from resolving to prototype properties
17
+ const standardAuthPlugins = Object.assign(Object.create(null), {
18
+ sha256_password: sha256_password({}),
19
+ caching_sha2_password: caching_sha2_password({}),
20
+ mysql_native_password: mysql_native_password({}),
21
+ mysql_clear_password: mysql_clear_password({}),
22
+ });
23
+
24
+ // Helper function to get auth plugin (custom or standard)
25
+ function getAuthPlugin(pluginName, connection) {
26
+ const customPlugins = connection.config.authPlugins;
27
+
28
+ // Check custom plugins with hasOwnProperty for safety
29
+ if (
30
+ customPlugins &&
31
+ Object.prototype.hasOwnProperty.call(customPlugins, pluginName)
32
+ ) {
33
+ return customPlugins[pluginName];
34
+ }
35
+
36
+ // Safe to access standardAuthPlugins directly since it has no prototype
37
+ return standardAuthPlugins[pluginName];
38
+ }
39
+
40
+ function warnLegacyAuthSwitch() {
41
+ console.warn(
42
+ 'WARNING! authSwitchHandler api is deprecated, please use new authPlugins api'
43
+ );
44
+ }
45
+
46
+ function authSwitchPluginError(error, command) {
47
+ // Authentication errors are fatal
48
+ error.code = 'AUTH_SWITCH_PLUGIN_ERROR';
49
+ error.fatal = true;
50
+
51
+ command.emit('error', error);
52
+ }
53
+
54
+ function authSwitchRequest(packet, connection, command) {
55
+ const { pluginName, pluginData } =
56
+ Packets.AuthSwitchRequest.fromPacket(packet);
57
+
58
+ // legacy plugin api don't allow to override mysql_native_password
59
+ // if pluginName is mysql_native_password it's using standard auth4.1 auth
60
+ if (
61
+ connection.config.authSwitchHandler &&
62
+ pluginName !== 'mysql_native_password'
63
+ ) {
64
+ const legacySwitchHandler = connection.config.authSwitchHandler;
65
+ warnLegacyAuthSwitch();
66
+ legacySwitchHandler({ pluginName, pluginData }, (err, data) => {
67
+ if (err) {
68
+ return authSwitchPluginError(err, command);
69
+ }
70
+ connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket());
71
+ });
72
+ return;
73
+ }
74
+
75
+ const authPlugin = getAuthPlugin(pluginName, connection);
76
+ if (!authPlugin) {
77
+ throw new Error(
78
+ `Server requests authentication using unknown plugin ${pluginName}. See ${'TODO: add plugins doco here'} on how to configure or author authentication plugins.`
79
+ );
80
+ }
81
+ connection._authPlugin = authPlugin({ connection, command });
82
+ Promise.resolve(connection._authPlugin(pluginData))
83
+ .then((data) => {
84
+ if (data) {
85
+ connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket());
86
+ }
87
+ })
88
+ .catch((err) => {
89
+ authSwitchPluginError(err, command);
90
+ });
91
+ }
92
+
93
+ function authSwitchRequestMoreData(packet, connection, command) {
94
+ const { data } = Packets.AuthSwitchRequestMoreData.fromPacket(packet);
95
+
96
+ if (connection.config.authSwitchHandler) {
97
+ const legacySwitchHandler = connection.config.authSwitchHandler;
98
+ warnLegacyAuthSwitch();
99
+ legacySwitchHandler({ pluginData: data }, (err, data) => {
100
+ if (err) {
101
+ return authSwitchPluginError(err, command);
102
+ }
103
+ connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket());
104
+ });
105
+ return;
106
+ }
107
+
108
+ if (!connection._authPlugin) {
109
+ throw new Error(
110
+ 'AuthPluginMoreData received but no auth plugin instance found'
111
+ );
112
+ }
113
+ Promise.resolve(connection._authPlugin(data))
114
+ .then((data) => {
115
+ if (data) {
116
+ connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket());
117
+ }
118
+ })
119
+ .catch((err) => {
120
+ authSwitchPluginError(err, command);
121
+ });
122
+ }
123
+
124
+ module.exports = {
125
+ authSwitchRequest,
126
+ authSwitchRequestMoreData,
127
+ getAuthPlugin,
128
+ standardAuthPlugins,
129
+ };
@@ -0,0 +1,109 @@
1
+ 'use strict';
2
+
3
+ const Command = require('./command');
4
+ const Packets = require('../packets');
5
+
6
+ const eventParsers = [];
7
+
8
+ class BinlogEventHeader {
9
+ constructor(packet) {
10
+ this.timestamp = packet.readInt32();
11
+ this.eventType = packet.readInt8();
12
+ this.serverId = packet.readInt32();
13
+ this.eventSize = packet.readInt32();
14
+ this.logPos = packet.readInt32();
15
+ this.flags = packet.readInt16();
16
+ }
17
+ }
18
+
19
+ class BinlogDump extends Command {
20
+ constructor(opts) {
21
+ super();
22
+ // this.onResult = callback;
23
+ this.opts = opts;
24
+ }
25
+
26
+ start(packet, connection) {
27
+ const newPacket = new Packets.BinlogDump(this.opts);
28
+ connection.writePacket(newPacket.toPacket(1));
29
+ return BinlogDump.prototype.binlogData;
30
+ }
31
+
32
+ binlogData(packet) {
33
+ // ok - continue consuming events
34
+ // error - error
35
+ // eof - end of binlog
36
+ if (packet.isEOF()) {
37
+ this.emit('eof');
38
+ return null;
39
+ }
40
+ // binlog event header
41
+ packet.readInt8();
42
+ const header = new BinlogEventHeader(packet);
43
+ const EventParser = eventParsers[header.eventType];
44
+ let event;
45
+ if (EventParser) {
46
+ event = new EventParser(packet);
47
+ } else {
48
+ event = {
49
+ name: 'UNKNOWN',
50
+ };
51
+ }
52
+ event.header = header;
53
+ this.emit('event', event);
54
+ return BinlogDump.prototype.binlogData;
55
+ }
56
+ }
57
+
58
+ class RotateEvent {
59
+ constructor(packet) {
60
+ this.pposition = packet.readInt32();
61
+ // TODO: read uint64 here
62
+ packet.readInt32(); // positionDword2
63
+ this.nextBinlog = packet.readString();
64
+ this.name = 'RotateEvent';
65
+ }
66
+ }
67
+
68
+ class FormatDescriptionEvent {
69
+ constructor(packet) {
70
+ this.binlogVersion = packet.readInt16();
71
+ this.serverVersion = packet.readString(50).replace(/\u0000.*/, ''); // eslint-disable-line no-control-regex
72
+ this.createTimestamp = packet.readInt32();
73
+ this.eventHeaderLength = packet.readInt8(); // should be 19
74
+ this.eventsLength = packet.readBuffer();
75
+ this.name = 'FormatDescriptionEvent';
76
+ }
77
+ }
78
+
79
+ class QueryEvent {
80
+ constructor(packet) {
81
+ const parseStatusVars = require('../packets/binlog_query_statusvars.js');
82
+ this.slaveProxyId = packet.readInt32();
83
+ this.executionTime = packet.readInt32();
84
+ const schemaLength = packet.readInt8();
85
+ this.errorCode = packet.readInt16();
86
+ const statusVarsLength = packet.readInt16();
87
+ const statusVars = packet.readBuffer(statusVarsLength);
88
+ this.schema = packet.readString(schemaLength);
89
+ packet.readInt8(); // should be zero
90
+ this.statusVars = parseStatusVars(statusVars);
91
+ this.query = packet.readString();
92
+ this.name = 'QueryEvent';
93
+ }
94
+ }
95
+
96
+ class XidEvent {
97
+ constructor(packet) {
98
+ this.binlogVersion = packet.readInt16();
99
+ this.xid = packet.readInt64();
100
+ this.name = 'XidEvent';
101
+ }
102
+ }
103
+
104
+ eventParsers[2] = QueryEvent;
105
+ eventParsers[4] = RotateEvent;
106
+ eventParsers[15] = FormatDescriptionEvent;
107
+ eventParsers[16] = XidEvent;
108
+
109
+ module.exports = BinlogDump;
@@ -0,0 +1,68 @@
1
+ // This file was modified by Oracle on September 21, 2021.
2
+ // The changes involve saving additional authentication factor passwords
3
+ // in the command scope and enabling multi-factor authentication in the
4
+ // client-side when the server supports it.
5
+ // Modifications copyright (c) 2021, Oracle and/or its affiliates.
6
+
7
+ 'use strict';
8
+
9
+ const Command = require('./command.js');
10
+ const Packets = require('../packets/index.js');
11
+ const ClientConstants = require('../constants/client');
12
+ const ClientHandshake = require('./client_handshake.js');
13
+ const CharsetToEncoding = require('../constants/charset_encodings.js');
14
+
15
+ class ChangeUser extends Command {
16
+ constructor(options, callback) {
17
+ super();
18
+ this.onResult = callback;
19
+ this.user = options.user;
20
+ this.password = options.password;
21
+ // "password1" is an alias of "password"
22
+ this.password1 = options.password;
23
+ this.password2 = options.password2;
24
+ this.password3 = options.password3;
25
+ this.database = options.database;
26
+ this.passwordSha1 = options.passwordSha1;
27
+ this.charsetNumber = options.charsetNumber;
28
+ this.currentConfig = options.currentConfig;
29
+ this.authenticationFactor = 0;
30
+ }
31
+ start(packet, connection) {
32
+ const newPacket = new Packets.ChangeUser({
33
+ flags: connection.config.clientFlags,
34
+ user: this.user,
35
+ database: this.database,
36
+ charsetNumber: this.charsetNumber,
37
+ password: this.password,
38
+ passwordSha1: this.passwordSha1,
39
+ authPluginData1: connection._handshakePacket.authPluginData1,
40
+ authPluginData2: connection._handshakePacket.authPluginData2,
41
+ });
42
+ this.currentConfig.user = this.user;
43
+ this.currentConfig.password = this.password;
44
+ this.currentConfig.database = this.database;
45
+ this.currentConfig.charsetNumber = this.charsetNumber;
46
+ connection.clientEncoding = CharsetToEncoding[this.charsetNumber];
47
+ // clear prepared statements cache as all statements become invalid after changeUser
48
+ connection._statements.clear();
49
+ connection.writePacket(newPacket.toPacket());
50
+ // check if the server supports multi-factor authentication
51
+ const multiFactorAuthentication =
52
+ connection.serverCapabilityFlags &
53
+ ClientConstants.MULTI_FACTOR_AUTHENTICATION;
54
+ if (multiFactorAuthentication) {
55
+ // if the server supports multi-factor authentication, we enable it in
56
+ // the client
57
+ this.authenticationFactor = 1;
58
+ }
59
+ return ChangeUser.prototype.handshakeResult;
60
+ }
61
+ }
62
+
63
+ ChangeUser.prototype.handshakeResult =
64
+ ClientHandshake.prototype.handshakeResult;
65
+ ChangeUser.prototype.calculateNativePasswordAuthToken =
66
+ ClientHandshake.prototype.calculateNativePasswordAuthToken;
67
+
68
+ module.exports = ChangeUser;