@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
package/License ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2016 Andrey Sidorov (sidorares@yandex.ru) and contributors
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,114 @@
1
+ [npm-image]: https://img.shields.io/npm/v/mysql2.svg
2
+ [npm-url]: https://npmjs.com/package/mysql2
3
+ [node-version-image]: https://img.shields.io/node/v/mysql2.svg
4
+ [node-version-url]: https://nodejs.org/en/download
5
+ [downloads-image]: https://img.shields.io/npm/dm/mysql2.svg
6
+ [downloads-url]: https://npmjs.com/package/mysql2
7
+ [license-url]: https://github.com/sidorares/node-mysql2/blob/master/License
8
+ [license-image]: https://img.shields.io/npm/l/mysql2.svg?maxAge=2592000
9
+ [node-mysql]: https://github.com/mysqljs/mysql
10
+ [mysqljs]: https://github.com/mysqljs
11
+ [mysql-native]: https://github.com/sidorares/nodejs-mysql-native
12
+ [sidorares]: https://github.com/sidorares
13
+ [TooTallNate]: https://gist.github.com/TooTallNate
14
+ [starttls.js]: https://gist.github.com/TooTallNate/848444
15
+ [node-mariasql]: https://github.com/mscdex/node-mariasql
16
+ [contributors]: https://github.com/sidorares/node-mysql2/graphs/contributors
17
+ [contributing]: https://github.com/sidorares/node-mysql2/blob/master/Contributing.md
18
+ [docs-base]: https://sidorares.github.io/node-mysql2/docs
19
+ [docs-base-zh-CN]: https://sidorares.github.io/node-mysql2/zh-CN/docs
20
+ [docs-base-pt-BR]: https://sidorares.github.io/node-mysql2/pt-BR/docs
21
+ [docs-prepared-statements]: https://sidorares.github.io/node-mysql2/docs/documentation/prepared-statements
22
+ [docs-mysql-server]: https://sidorares.github.io/node-mysql2/docs/documentation/mysql-server
23
+ [docs-promise-wrapper]: https://sidorares.github.io/node-mysql2/docs/documentation/promise-wrapper
24
+ [docs-authentication-switch]: https://sidorares.github.io/node-mysql2/docs/documentation/authentication-switch
25
+ [docs-streams]: https://sidorares.github.io/node-mysql2/docs/documentation/extras
26
+ [docs-typescript-docs]: https://sidorares.github.io/node-mysql2/docs/documentation/typescript-examples
27
+ [docs-qs-pooling]: https://sidorares.github.io/node-mysql2/docs#using-connection-pools
28
+ [docs-qs-first-query]: https://sidorares.github.io/node-mysql2/docs#first-query
29
+ [docs-qs-using-prepared-statements]: https://sidorares.github.io/node-mysql2/docs#using-prepared-statements
30
+ [docs-examples]: https://sidorares.github.io/node-mysql2/docs/examples
31
+ [docs-faq]: https://sidorares.github.io/node-mysql2/docs/faq
32
+ [docs-documentation]: https://sidorares.github.io/node-mysql2/docs/documentation
33
+ [docs-contributing]: https://sidorares.github.io/node-mysql2/docs/contributing/website
34
+ [coverage]: https://img.shields.io/codecov/c/github/sidorares/node-mysql2
35
+ [coverage-url]: https://app.codecov.io/github/sidorares/node-mysql2
36
+ [ci-url]: https://github.com/sidorares/node-mysql2/actions/workflows/ci-coverage.yml?query=branch%3Amaster
37
+ [ci-image]: https://img.shields.io/github/actions/workflow/status/sidorares/node-mysql2/ci-coverage.yml?event=push&style=flat&label=CI&branch=master
38
+
39
+ # MySQL2
40
+
41
+ [![NPM Version][npm-image]][npm-url]
42
+ [![NPM Downloads][downloads-image]][downloads-url]
43
+ [![Node.js Version][node-version-image]][node-version-url]
44
+ [![GitHub Workflow Status (with event)][ci-image]][ci-url]
45
+ [![Codecov][coverage]][coverage-url]
46
+ [![License][license-image]][license-url]
47
+
48
+ [English][docs-base] | [简体中文][docs-base-zh-CN] | [Português (BR)][docs-base-pt-BR]
49
+
50
+ > MySQL client for Node.js with focus on performance. Supports prepared statements, non-utf8 encodings, binary log protocol, compression, ssl [much more][docs-documentation].
51
+
52
+ **Table of Contents**
53
+
54
+ - [History and Why MySQL2](#history-and-why-mysql2)
55
+ - [Installation](#installation)
56
+ - [Documentation](#documentation)
57
+ - [Acknowledgements](#acknowledgements)
58
+ - [Contributing](#contributing)
59
+
60
+ ## History and Why MySQL2
61
+
62
+ MySQL2 project is a continuation of [MySQL-Native][mysql-native]. Protocol parser code was rewritten from scratch and api changed to match popular [Node MySQL][node-mysql]. MySQL2 team is working together with [Node MySQL][node-mysql] team to factor out shared code and move it under [mysqljs][mysqljs] organization.
63
+
64
+ MySQL2 is mostly API compatible with [Node MySQL][node-mysql] and supports majority of features. MySQL2 also offers these additional features:
65
+
66
+ - Faster / Better Performance
67
+ - [Prepared Statements][docs-prepared-statements]
68
+ - MySQL Binary Log Protocol
69
+ - [MySQL Server][docs-mysql-server]
70
+ - Extended support for Encoding and Collation
71
+ - [Promise Wrapper][docs-promise-wrapper]
72
+ - Compression
73
+ - SSL and [Authentication Switch][docs-authentication-switch]
74
+ - [Custom Streams][docs-streams]
75
+ - [Pooling][docs-qs-pooling]
76
+
77
+ ## Installation
78
+
79
+ MySQL2 is free from native bindings and can be installed on Linux, Mac OS or Windows without any issues.
80
+
81
+ ```bash
82
+ npm install --save mysql2
83
+ ```
84
+
85
+ If you are using TypeScript, you will need to install `@types/node`.
86
+
87
+ ```bash
88
+ npm install --save-dev @types/node
89
+ ```
90
+
91
+ > For TypeScript documentation and examples, see [here][docs-typescript-docs].
92
+
93
+ ## Documentation
94
+
95
+ - [Quickstart][docs-base]
96
+ - [First Query][docs-qs-first-query], [Using Prepared Statements][docs-qs-using-prepared-statements], [Using Connection Pools][docs-qs-pooling] and more.
97
+ - [Documentation][docs-documentation]
98
+ - [Examples][docs-examples]
99
+ - [FAQ][docs-faq]
100
+
101
+ ## Acknowledgements
102
+
103
+ - Internal protocol is written by [@sidorares][sidorares] [MySQL-Native][mysql-native].
104
+ - Constants, SQL parameters interpolation, Pooling, `ConnectionConfig` class taken from [Node MySQL][node-mysql].
105
+ - SSL upgrade code based on [@TooTallNate][TooTallNate] [code][starttls.js].
106
+ - Secure connection / compressed connection api flags compatible to [MariaSQL][node-mariasql] client.
107
+ - [Contributors][contributors].
108
+
109
+ ## Contributing
110
+
111
+ Want to improve something in **MySQL2**?
112
+ Please check [Contributing.md][contributing] for detailed instruction on how to get started.
113
+
114
+ To contribute in **MySQL2 Documentation**, please visit the [Website Contributing Guidelines][docs-contributing] for detailed instruction on how to get started.
package/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './typings/mysql/index.js';
package/index.js ADDED
@@ -0,0 +1,77 @@
1
+ 'use strict';
2
+
3
+ const SqlString = require('sql-escaper');
4
+
5
+ const ConnectionConfig = require('./lib/connection_config.js');
6
+ const parserCache = require('./lib/parsers/parser_cache.js');
7
+
8
+ const Connection = require('./lib/connection.js');
9
+
10
+ exports.createConnection = require('./lib/create_connection.js');
11
+ exports.connect = exports.createConnection;
12
+ exports.Connection = Connection;
13
+ exports.ConnectionConfig = ConnectionConfig;
14
+
15
+ const Pool = require('./lib/pool.js');
16
+ const PoolCluster = require('./lib/pool_cluster.js');
17
+ const createPool = require('./lib/create_pool.js');
18
+ const createPoolCluster = require('./lib/create_pool_cluster.js');
19
+
20
+ exports.createPool = createPool;
21
+
22
+ exports.createPoolCluster = createPoolCluster;
23
+
24
+ exports.createQuery = Connection.createQuery;
25
+
26
+ exports.Pool = Pool;
27
+
28
+ exports.PoolCluster = PoolCluster;
29
+
30
+ exports.createServer = function (handler) {
31
+ const Server = require('./lib/server.js');
32
+ const s = new Server();
33
+ if (handler) {
34
+ s.on('connection', handler);
35
+ }
36
+ return s;
37
+ };
38
+
39
+ exports.PoolConnection = require('./lib/pool_connection.js');
40
+ exports.authPlugins = require('./lib/auth_plugins');
41
+ exports.escape = SqlString.escape;
42
+ exports.escapeId = SqlString.escapeId;
43
+ exports.format = SqlString.format;
44
+ exports.raw = SqlString.raw;
45
+
46
+ exports.__defineGetter__(
47
+ 'createConnectionPromise',
48
+ () => require('./promise.js').createConnection
49
+ );
50
+
51
+ exports.__defineGetter__(
52
+ 'createPoolPromise',
53
+ () => require('./promise.js').createPool
54
+ );
55
+
56
+ exports.__defineGetter__(
57
+ 'createPoolClusterPromise',
58
+ () => require('./promise.js').createPoolCluster
59
+ );
60
+
61
+ exports.__defineGetter__('Types', () => require('./lib/constants/types.js'));
62
+
63
+ exports.__defineGetter__('Charsets', () =>
64
+ require('./lib/constants/charsets.js')
65
+ );
66
+
67
+ exports.__defineGetter__('CharsetToEncoding', () =>
68
+ require('./lib/constants/charset_encodings.js')
69
+ );
70
+
71
+ exports.setMaxParserCache = function (max) {
72
+ parserCache.setMaxCache(max);
73
+ };
74
+
75
+ exports.clearParserCache = function () {
76
+ parserCache.clearCache();
77
+ };
package/lib/auth_41.js ADDED
@@ -0,0 +1,95 @@
1
+ 'use strict';
2
+
3
+ /*
4
+ 4.1 authentication: (http://bazaar.launchpad.net/~mysql/mysql-server/5.5/view/head:/sql/password.c)
5
+
6
+ SERVER: public_seed=create_random_string()
7
+ send(public_seed)
8
+
9
+ CLIENT: recv(public_seed)
10
+ hash_stage1=sha1("password")
11
+ hash_stage2=sha1(hash_stage1)
12
+ reply=xor(hash_stage1, sha1(public_seed,hash_stage2)
13
+
14
+ // this three steps are done in scramble()
15
+
16
+ send(reply)
17
+
18
+
19
+ SERVER: recv(reply)
20
+ hash_stage1=xor(reply, sha1(public_seed,hash_stage2))
21
+ candidate_hash2=sha1(hash_stage1)
22
+ check(candidate_hash2==hash_stage2)
23
+
24
+ server stores sha1(sha1(password)) ( hash_stag2)
25
+ */
26
+
27
+ const crypto = require('crypto');
28
+
29
+ function sha1(msg, msg1, msg2) {
30
+ const hash = crypto.createHash('sha1');
31
+ hash.update(msg);
32
+ if (msg1) {
33
+ hash.update(msg1);
34
+ }
35
+
36
+ if (msg2) {
37
+ hash.update(msg2);
38
+ }
39
+
40
+ return hash.digest();
41
+ }
42
+
43
+ function xor(a, b) {
44
+ const result = Buffer.allocUnsafe(a.length);
45
+ for (let i = 0; i < a.length; i++) {
46
+ result[i] = a[i] ^ b[i];
47
+ }
48
+ return result;
49
+ }
50
+
51
+ exports.xor = xor;
52
+
53
+ function token(password, scramble1, scramble2) {
54
+ if (!password) {
55
+ return Buffer.alloc(0);
56
+ }
57
+ const stage1 = sha1(password);
58
+ return exports.calculateTokenFromPasswordSha(stage1, scramble1, scramble2);
59
+ }
60
+
61
+ exports.calculateTokenFromPasswordSha = function (
62
+ passwordSha,
63
+ scramble1,
64
+ scramble2
65
+ ) {
66
+ // we use AUTH 41 here, and we need only the bytes we just need.
67
+ const authPluginData1 = scramble1.slice(0, 8);
68
+ const authPluginData2 = scramble2.slice(0, 12);
69
+ const stage2 = sha1(passwordSha);
70
+ const stage3 = sha1(authPluginData1, authPluginData2, stage2);
71
+ return xor(stage3, passwordSha);
72
+ };
73
+
74
+ exports.calculateToken = token;
75
+
76
+ exports.verifyToken = function (publicSeed1, publicSeed2, token, doubleSha) {
77
+ const hashStage1 = xor(token, sha1(publicSeed1, publicSeed2, doubleSha));
78
+ const candidateHash2 = sha1(hashStage1);
79
+ return candidateHash2.compare(doubleSha) === 0;
80
+ };
81
+
82
+ exports.doubleSha1 = function (password) {
83
+ return sha1(sha1(password));
84
+ };
85
+
86
+ function xorRotating(a, seed) {
87
+ const result = Buffer.allocUnsafe(a.length);
88
+ const seedLen = seed.length;
89
+
90
+ for (let i = 0; i < a.length; i++) {
91
+ result[i] = a[i] ^ seed[i % seedLen];
92
+ }
93
+ return result;
94
+ }
95
+ exports.xorRotating = xorRotating;
@@ -0,0 +1,114 @@
1
+ 'use strict';
2
+
3
+ // https://mysqlserverteam.com/mysql-8-0-4-new-default-authentication-plugin-caching_sha2_password/
4
+
5
+ const PLUGIN_NAME = 'caching_sha2_password';
6
+ const crypto = require('crypto');
7
+ const { xor, xorRotating } = require('../auth_41');
8
+
9
+ const REQUEST_SERVER_KEY_PACKET = Buffer.from([2]);
10
+ const FAST_AUTH_SUCCESS_PACKET = Buffer.from([3]);
11
+ const PERFORM_FULL_AUTHENTICATION_PACKET = Buffer.from([4]);
12
+
13
+ const STATE_INITIAL = 0;
14
+ const STATE_TOKEN_SENT = 1;
15
+ const STATE_WAIT_SERVER_KEY = 2;
16
+ const STATE_FINAL = -1;
17
+
18
+ function sha256(msg) {
19
+ const hash = crypto.createHash('sha256');
20
+ hash.update(msg);
21
+ return hash.digest();
22
+ }
23
+
24
+ function calculateToken(password, scramble) {
25
+ if (!password) {
26
+ return Buffer.alloc(0);
27
+ }
28
+ const stage1 = sha256(Buffer.from(password));
29
+ const stage2 = sha256(stage1);
30
+ const stage3 = sha256(Buffer.concat([stage2, scramble]));
31
+ return xor(stage1, stage3);
32
+ }
33
+
34
+ function encrypt(password, scramble, key) {
35
+ const stage1 = xorRotating(Buffer.from(`${password}\0`, 'utf8'), scramble);
36
+ return crypto.publicEncrypt(
37
+ {
38
+ key,
39
+ padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
40
+ },
41
+ stage1
42
+ );
43
+ }
44
+
45
+ const pluginFactory =
46
+ (pluginOptions = {}) =>
47
+ ({ connection }) => {
48
+ let state = 0;
49
+ let scramble = null;
50
+
51
+ const password = connection.config.password;
52
+
53
+ const authWithKey = (serverKey) => {
54
+ const _password = encrypt(password, scramble, serverKey);
55
+ state = STATE_FINAL;
56
+ return _password;
57
+ };
58
+
59
+ return (data) => {
60
+ switch (state) {
61
+ case STATE_INITIAL:
62
+ scramble = data.slice(0, 20);
63
+ state = STATE_TOKEN_SENT;
64
+ return calculateToken(password, scramble);
65
+
66
+ case STATE_TOKEN_SENT:
67
+ if (FAST_AUTH_SUCCESS_PACKET.equals(data)) {
68
+ state = STATE_FINAL;
69
+ return null;
70
+ }
71
+
72
+ if (PERFORM_FULL_AUTHENTICATION_PACKET.equals(data)) {
73
+ const isSecureConnection =
74
+ typeof pluginOptions.overrideIsSecure === 'undefined'
75
+ ? connection.config.ssl || connection.config.socketPath
76
+ : pluginOptions.overrideIsSecure;
77
+ if (isSecureConnection) {
78
+ state = STATE_FINAL;
79
+ return Buffer.from(`${password}\0`, 'utf8');
80
+ }
81
+
82
+ // if client provides key we can save one extra roundrip on first connection
83
+ if (pluginOptions.serverPublicKey) {
84
+ return authWithKey(pluginOptions.serverPublicKey);
85
+ }
86
+
87
+ state = STATE_WAIT_SERVER_KEY;
88
+ return REQUEST_SERVER_KEY_PACKET;
89
+ }
90
+ throw new Error(
91
+ `Invalid AuthMoreData packet received by ${PLUGIN_NAME} plugin in STATE_TOKEN_SENT state.`
92
+ );
93
+ case STATE_WAIT_SERVER_KEY:
94
+ if (pluginOptions.onServerPublicKey) {
95
+ pluginOptions.onServerPublicKey(data);
96
+ }
97
+ return authWithKey(data);
98
+ case STATE_FINAL:
99
+ throw new Error(
100
+ `Unexpected data in AuthMoreData packet received by ${PLUGIN_NAME} plugin in STATE_FINAL state.`
101
+ );
102
+ }
103
+
104
+ throw new Error(
105
+ `Unexpected data in AuthMoreData packet received by ${PLUGIN_NAME} plugin in state ${state}`
106
+ );
107
+ };
108
+ };
109
+
110
+ // Export the plugin factory as default
111
+ module.exports = pluginFactory;
112
+
113
+ // Export calculateToken for reuse in initial handshake optimization
114
+ module.exports.calculateToken = calculateToken;
@@ -0,0 +1,18 @@
1
+ ##
2
+
3
+ https://dev.mysql.com/doc/refman/8.0/en/caching-sha2-pluggable-authentication.html
4
+
5
+ ```js
6
+ const mysql = require('mysql');
7
+ mysql.createConnection({
8
+ authPlugins: {
9
+ caching_sha2_password: mysql.authPlugins.caching_sha2_password({
10
+ onServerPublikKey: function (key) {
11
+ console.log(key);
12
+ },
13
+ serverPublicKey: 'xxxyyy',
14
+ overrideIsSecure: true, //
15
+ }),
16
+ },
17
+ });
18
+ ```
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+
3
+ module.exports = {
4
+ caching_sha2_password: require('./caching_sha2_password'),
5
+ mysql_clear_password: require('./mysql_clear_password'),
6
+ mysql_native_password: require('./mysql_native_password'),
7
+ sha256_password: require('./sha256_password'),
8
+ };
@@ -0,0 +1,17 @@
1
+ 'use strict';
2
+
3
+ function bufferFromStr(str) {
4
+ return Buffer.from(`${str}\0`);
5
+ }
6
+
7
+ const create_mysql_clear_password_plugin = (pluginOptions) =>
8
+ function mysql_clear_password_plugin({ connection, command }) {
9
+ const password =
10
+ command.password || pluginOptions.password || connection.config.password;
11
+
12
+ return function (/* pluginData */) {
13
+ return bufferFromStr(password);
14
+ };
15
+ };
16
+
17
+ module.exports = create_mysql_clear_password_plugin;
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ //const PLUGIN_NAME = 'mysql_native_password';
4
+ const auth41 = require('../auth_41.js');
5
+
6
+ module.exports =
7
+ (pluginOptions) =>
8
+ ({ connection, command }) => {
9
+ const password =
10
+ command.password || pluginOptions.password || connection.config.password;
11
+ const passwordSha1 =
12
+ command.passwordSha1 ||
13
+ pluginOptions.passwordSha1 ||
14
+ connection.config.passwordSha1;
15
+ return (data) => {
16
+ const authPluginData1 = data.slice(0, 8);
17
+ const authPluginData2 = data.slice(8, 20);
18
+ let authToken;
19
+ if (passwordSha1) {
20
+ authToken = auth41.calculateTokenFromPasswordSha(
21
+ passwordSha1,
22
+ authPluginData1,
23
+ authPluginData2
24
+ );
25
+ } else {
26
+ authToken = auth41.calculateToken(
27
+ password,
28
+ authPluginData1,
29
+ authPluginData2
30
+ );
31
+ }
32
+ return authToken;
33
+ };
34
+ };
@@ -0,0 +1,68 @@
1
+ 'use strict';
2
+
3
+ const PLUGIN_NAME = 'sha256_password';
4
+ const crypto = require('crypto');
5
+ const { xorRotating } = require('../auth_41');
6
+ const Tls = require('tls');
7
+
8
+ const REQUEST_SERVER_KEY_PACKET = Buffer.from([1]);
9
+
10
+ const STATE_INITIAL = 0;
11
+ const STATE_WAIT_SERVER_KEY = 1;
12
+ const STATE_FINAL = -1;
13
+
14
+ function encrypt(password, scramble, key) {
15
+ const stage1 = xorRotating(Buffer.from(`${password}\0`, 'utf8'), scramble);
16
+ return crypto.publicEncrypt(key, stage1);
17
+ }
18
+
19
+ module.exports =
20
+ (pluginOptions = {}) =>
21
+ ({ connection }) => {
22
+ let state = 0;
23
+ let scramble = null;
24
+
25
+ const password = connection.config.password;
26
+
27
+ const authWithKey = (serverKey) => {
28
+ const _password = encrypt(password, scramble, serverKey);
29
+ state = STATE_FINAL;
30
+ return _password;
31
+ };
32
+
33
+ return (data) => {
34
+ switch (state) {
35
+ case STATE_INITIAL:
36
+ if (
37
+ connection.stream instanceof Tls.TLSSocket &&
38
+ connection.stream.encrypted === true
39
+ ) {
40
+ // We don't need to encrypt passwords over TLS connection
41
+ return Buffer.from(`${password}\0`, 'utf8');
42
+ }
43
+
44
+ scramble = data.slice(0, 20);
45
+ // if client provides key we can save one extra roundrip on first connection
46
+ if (pluginOptions.serverPublicKey) {
47
+ return authWithKey(pluginOptions.serverPublicKey);
48
+ }
49
+
50
+ state = STATE_WAIT_SERVER_KEY;
51
+ return REQUEST_SERVER_KEY_PACKET;
52
+
53
+ case STATE_WAIT_SERVER_KEY:
54
+ if (pluginOptions.onServerPublicKey) {
55
+ pluginOptions.onServerPublicKey(data);
56
+ }
57
+ return authWithKey(data);
58
+ case STATE_FINAL:
59
+ throw new Error(
60
+ `Unexpected data in AuthMoreData packet received by ${PLUGIN_NAME} plugin in STATE_FINAL state.`
61
+ );
62
+ }
63
+
64
+ throw new Error(
65
+ `Unexpected data in AuthMoreData packet received by ${PLUGIN_NAME} plugin in state ${state}`
66
+ );
67
+ };
68
+ };