@tachybase/module-multi-app 0.23.8
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.
- package/.turbo/turbo-build.log +14 -0
- package/README.md +34 -0
- package/README.zh-CN.md +34 -0
- package/client.d.ts +1 -0
- package/client.js +1 -0
- package/dist/client/AppManager.d.ts +2 -0
- package/dist/client/AppNameInput.d.ts +2 -0
- package/dist/client/MultiAppBlockInitializer.d.ts +2 -0
- package/dist/client/MultiAppManagerProvider.d.ts +2 -0
- package/dist/client/MultiAppManagerProvider.style.d.ts +5 -0
- package/dist/client/Settings.d.ts +2 -0
- package/dist/client/index.d.ts +6 -0
- package/dist/client/index.js +1 -0
- package/dist/client/settings/schemas/applications.d.ts +13 -0
- package/dist/client/utils.d.ts +4 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +27 -0
- package/dist/externalVersion.js +16 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +39 -0
- package/dist/locale/en-US.json +27 -0
- package/dist/locale/es-ES.json +9 -0
- package/dist/locale/ko_KR.json +11 -0
- package/dist/locale/pt-BR.json +9 -0
- package/dist/locale/zh-CN.json +27 -0
- package/dist/node_modules/mariadb/LICENSE +502 -0
- package/dist/node_modules/mariadb/callback.js +41 -0
- package/dist/node_modules/mariadb/lib/cmd/batch-bulk.js +278 -0
- package/dist/node_modules/mariadb/lib/cmd/batch-rewrite.js +372 -0
- package/dist/node_modules/mariadb/lib/cmd/change-user.js +149 -0
- package/dist/node_modules/mariadb/lib/cmd/class/ok-packet.js +17 -0
- package/dist/node_modules/mariadb/lib/cmd/column-definition.js +102 -0
- package/dist/node_modules/mariadb/lib/cmd/command.js +168 -0
- package/dist/node_modules/mariadb/lib/cmd/common-binary-cmd.js +327 -0
- package/dist/node_modules/mariadb/lib/cmd/common-text-cmd.js +427 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/caching-sha2-password-auth.js +168 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/clear-password-auth.js +23 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/ed25519-password-auth.js +761 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/native-password-auth.js +55 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/pam-password-auth.js +58 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/plugin-auth.js +19 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/sha256-password-auth.js +142 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/client-capabilities.js +74 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/client-handshake-response.js +126 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/handshake.js +292 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/initial-handshake.js +74 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/ssl-request.js +29 -0
- package/dist/node_modules/mariadb/lib/cmd/ping.js +52 -0
- package/dist/node_modules/mariadb/lib/cmd/query.js +255 -0
- package/dist/node_modules/mariadb/lib/cmd/quit.js +28 -0
- package/dist/node_modules/mariadb/lib/cmd/reset.js +54 -0
- package/dist/node_modules/mariadb/lib/cmd/resultset.js +607 -0
- package/dist/node_modules/mariadb/lib/cmd/stream.js +45 -0
- package/dist/node_modules/mariadb/lib/config/connection-options.js +258 -0
- package/dist/node_modules/mariadb/lib/config/pool-cluster-options.js +19 -0
- package/dist/node_modules/mariadb/lib/config/pool-options.js +47 -0
- package/dist/node_modules/mariadb/lib/connection-callback.js +160 -0
- package/dist/node_modules/mariadb/lib/connection.js +1460 -0
- package/dist/node_modules/mariadb/lib/const/capabilities.js +64 -0
- package/dist/node_modules/mariadb/lib/const/collations.js +473 -0
- package/dist/node_modules/mariadb/lib/const/connection_status.js +13 -0
- package/dist/node_modules/mariadb/lib/const/error-code.js +1282 -0
- package/dist/node_modules/mariadb/lib/const/field-detail.js +35 -0
- package/dist/node_modules/mariadb/lib/const/field-type.js +71 -0
- package/dist/node_modules/mariadb/lib/const/server-status.js +30 -0
- package/dist/node_modules/mariadb/lib/const/state-change.js +12 -0
- package/dist/node_modules/mariadb/lib/filtered-pool-cluster.js +81 -0
- package/dist/node_modules/mariadb/lib/io/bulk-packet.js +590 -0
- package/dist/node_modules/mariadb/lib/io/compression-input-stream.js +141 -0
- package/dist/node_modules/mariadb/lib/io/compression-output-stream.js +171 -0
- package/dist/node_modules/mariadb/lib/io/packet-input-stream.js +193 -0
- package/dist/node_modules/mariadb/lib/io/packet-node-encoded.js +36 -0
- package/dist/node_modules/mariadb/lib/io/packet-node-iconv.js +37 -0
- package/dist/node_modules/mariadb/lib/io/packet-output-stream.js +502 -0
- package/dist/node_modules/mariadb/lib/io/packet.js +515 -0
- package/dist/node_modules/mariadb/lib/io/rewrite-packet.js +481 -0
- package/dist/node_modules/mariadb/lib/misc/connection-information.js +96 -0
- package/dist/node_modules/mariadb/lib/misc/errors.js +123 -0
- package/dist/node_modules/mariadb/lib/misc/parse.js +1033 -0
- package/dist/node_modules/mariadb/lib/misc/utils.js +298 -0
- package/dist/node_modules/mariadb/lib/pool-base.js +611 -0
- package/dist/node_modules/mariadb/lib/pool-callback.js +202 -0
- package/dist/node_modules/mariadb/lib/pool-cluster-callback.js +66 -0
- package/dist/node_modules/mariadb/lib/pool-cluster.js +407 -0
- package/dist/node_modules/mariadb/lib/pool-promise.js +108 -0
- package/dist/node_modules/mariadb/package.json +1 -0
- package/dist/node_modules/mariadb/promise.js +34 -0
- package/dist/node_modules/mariadb/types/index.d.ts +870 -0
- package/dist/server/actions/apps.d.ts +5 -0
- package/dist/server/actions/apps.js +117 -0
- package/dist/server/app-lifecycle.d.ts +8 -0
- package/dist/server/app-lifecycle.js +99 -0
- package/dist/server/app-start-env.d.ts +2 -0
- package/dist/server/app-start-env.js +105 -0
- package/dist/server/collections/applications.d.ts +2 -0
- package/dist/server/collections/applications.js +82 -0
- package/dist/server/index.d.ts +4 -0
- package/dist/server/index.js +29 -0
- package/dist/server/middlewares/app-selector.d.ts +1 -0
- package/dist/server/middlewares/app-selector.js +47 -0
- package/dist/server/middlewares/index.d.ts +2 -0
- package/dist/server/middlewares/index.js +23 -0
- package/dist/server/middlewares/inject-app-list.d.ts +1 -0
- package/dist/server/middlewares/inject-app-list.js +48 -0
- package/dist/server/migrations/20240820153000-add-apps-tmpl.d.ts +6 -0
- package/dist/server/migrations/20240820153000-add-apps-tmpl.js +47 -0
- package/dist/server/migrations/20241126124904-add-createdBy.d.ts +6 -0
- package/dist/server/migrations/20241126124904-add-createdBy.js +41 -0
- package/dist/server/models/application.d.ts +10 -0
- package/dist/server/models/application.js +57 -0
- package/dist/server/server.d.ts +19 -0
- package/dist/server/server.js +246 -0
- package/dist/swagger/index.d.ts +197 -0
- package/dist/swagger/index.js +227 -0
- package/package.json +38 -0
- package/server.d.ts +2 -0
- package/server.js +1 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const PluginAuth = require('./plugin-auth');
|
|
4
|
+
const Crypto = require('crypto');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Standard authentication plugin
|
|
8
|
+
*/
|
|
9
|
+
class NativePasswordAuth extends PluginAuth {
|
|
10
|
+
constructor(packSeq, compressPackSeq, pluginData, resolve, reject, multiAuthResolver) {
|
|
11
|
+
super(resolve, reject, multiAuthResolver);
|
|
12
|
+
this.pluginData = pluginData;
|
|
13
|
+
this.sequenceNo = packSeq;
|
|
14
|
+
this.compressSequenceNo = compressPackSeq;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
start(out, opts, info) {
|
|
18
|
+
//seed is ended with a null byte value.
|
|
19
|
+
const data = this.pluginData.slice(0, 20);
|
|
20
|
+
let authToken = NativePasswordAuth.encryptPassword(opts.password, data, 'sha1');
|
|
21
|
+
|
|
22
|
+
out.startPacket(this);
|
|
23
|
+
if (authToken.length > 0) {
|
|
24
|
+
out.writeBuffer(authToken, 0, authToken.length);
|
|
25
|
+
out.flushBuffer(true);
|
|
26
|
+
} else {
|
|
27
|
+
out.writeEmptyPacket(true);
|
|
28
|
+
}
|
|
29
|
+
this.emit('send_end');
|
|
30
|
+
this.onPacketReceive = this.successSend;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static encryptPassword(password, seed, algorithm) {
|
|
34
|
+
if (!password) return Buffer.alloc(0);
|
|
35
|
+
|
|
36
|
+
let hash = Crypto.createHash(algorithm);
|
|
37
|
+
let stage1 = hash.update(password, 'utf8').digest();
|
|
38
|
+
hash = Crypto.createHash(algorithm);
|
|
39
|
+
|
|
40
|
+
let stage2 = hash.update(stage1).digest();
|
|
41
|
+
hash = Crypto.createHash(algorithm);
|
|
42
|
+
|
|
43
|
+
hash.update(seed);
|
|
44
|
+
hash.update(stage2);
|
|
45
|
+
|
|
46
|
+
let digest = hash.digest();
|
|
47
|
+
let returnBytes = Buffer.allocUnsafe(digest.length);
|
|
48
|
+
for (let i = 0; i < digest.length; i++) {
|
|
49
|
+
returnBytes[i] = stage1[i] ^ digest[i];
|
|
50
|
+
}
|
|
51
|
+
return returnBytes;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
module.exports = NativePasswordAuth;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const PluginAuth = require('./plugin-auth');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Use PAM authentication
|
|
5
|
+
*/
|
|
6
|
+
class PamPasswordAuth extends PluginAuth {
|
|
7
|
+
constructor(packSeq, compressPackSeq, pluginData, resolve, reject, multiAuthResolver) {
|
|
8
|
+
super(resolve, reject, multiAuthResolver);
|
|
9
|
+
this.pluginData = pluginData;
|
|
10
|
+
this.sequenceNo = packSeq;
|
|
11
|
+
this.counter = 0;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
start(out, opts, info) {
|
|
15
|
+
this.exchange(this.pluginData, out, opts, info);
|
|
16
|
+
this.onPacketReceive = this.response;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
exchange(buffer, out, opts, info) {
|
|
20
|
+
//conversation is :
|
|
21
|
+
// - first byte is information tell if question is a password (4) or clear text (2).
|
|
22
|
+
// - other bytes are the question to user
|
|
23
|
+
|
|
24
|
+
out.startPacket(this);
|
|
25
|
+
|
|
26
|
+
let pwd;
|
|
27
|
+
if (Array.isArray(opts.password)) {
|
|
28
|
+
pwd = opts.password[this.counter];
|
|
29
|
+
this.counter++;
|
|
30
|
+
} else {
|
|
31
|
+
pwd = opts.password;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (pwd) out.writeString(pwd);
|
|
35
|
+
out.writeInt8(0);
|
|
36
|
+
out.flushBuffer(true);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
response(packet, out, opts, info) {
|
|
40
|
+
const marker = packet.peek();
|
|
41
|
+
switch (marker) {
|
|
42
|
+
//*********************************************************************************************************
|
|
43
|
+
//* OK_Packet and Err_Packet ending packet
|
|
44
|
+
//*********************************************************************************************************
|
|
45
|
+
case 0x00:
|
|
46
|
+
case 0xff:
|
|
47
|
+
this.emit('send_end');
|
|
48
|
+
return this.successSend(packet, out, opts, info);
|
|
49
|
+
|
|
50
|
+
default:
|
|
51
|
+
let promptData = packet.readBuffer();
|
|
52
|
+
this.exchange(promptData, out, opts, info);
|
|
53
|
+
this.onPacketReceive = this.response;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
module.exports = PamPasswordAuth;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Command = require('../../command');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Base authentication plugin
|
|
7
|
+
*/
|
|
8
|
+
class PluginAuth extends Command {
|
|
9
|
+
constructor(resolve, reject, multiAuthResolver) {
|
|
10
|
+
super(resolve, reject);
|
|
11
|
+
this.multiAuthResolver = multiAuthResolver;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
successSend(packet, out, opts, info) {
|
|
15
|
+
this.multiAuthResolver(packet, out, opts, info);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = PluginAuth;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
const PluginAuth = require('./plugin-auth');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const crypto = require('crypto');
|
|
4
|
+
const Errors = require('../../../misc/errors');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Use Sha256 authentication
|
|
8
|
+
*/
|
|
9
|
+
class Sha256PasswordAuth extends PluginAuth {
|
|
10
|
+
constructor(packSeq, compressPackSeq, pluginData, resolve, reject, multiAuthResolver) {
|
|
11
|
+
super(resolve, reject, multiAuthResolver);
|
|
12
|
+
this.pluginData = pluginData;
|
|
13
|
+
this.sequenceNo = packSeq;
|
|
14
|
+
this.counter = 0;
|
|
15
|
+
this.initialState = true;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
start(out, opts, info) {
|
|
19
|
+
this.exchange(this.pluginData, out, opts, info);
|
|
20
|
+
this.onPacketReceive = this.response;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
exchange(buffer, out, opts, info) {
|
|
24
|
+
if (this.initialState) {
|
|
25
|
+
if (!opts.password) {
|
|
26
|
+
out.startPacket(this);
|
|
27
|
+
out.writeEmptyPacket(true);
|
|
28
|
+
return;
|
|
29
|
+
} else if (opts.ssl) {
|
|
30
|
+
// using SSL, so sending password in clear
|
|
31
|
+
out.startPacket(this);
|
|
32
|
+
if (opts.password) {
|
|
33
|
+
out.writeString(opts.password);
|
|
34
|
+
}
|
|
35
|
+
out.writeInt8(0);
|
|
36
|
+
out.flushBuffer(true);
|
|
37
|
+
return;
|
|
38
|
+
} else {
|
|
39
|
+
// retrieve public key from configuration or from server
|
|
40
|
+
if (opts.rsaPublicKey) {
|
|
41
|
+
try {
|
|
42
|
+
let key = opts.rsaPublicKey;
|
|
43
|
+
if (!key.includes('-----BEGIN')) {
|
|
44
|
+
// rsaPublicKey contain path
|
|
45
|
+
key = fs.readFileSync(key, 'utf8');
|
|
46
|
+
}
|
|
47
|
+
this.publicKey = Sha256PasswordAuth.retreivePublicKey(key);
|
|
48
|
+
} catch (err) {
|
|
49
|
+
return this.throwError(err, info);
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
if (!opts.allowPublicKeyRetrieval) {
|
|
53
|
+
return this.throwError(
|
|
54
|
+
Errors.createError(
|
|
55
|
+
'RSA public key is not available client side. Either set option `rsaPublicKey` to indicate' +
|
|
56
|
+
' public key path, or allow public key retrieval with option `allowPublicKeyRetrieval`',
|
|
57
|
+
null,
|
|
58
|
+
true,
|
|
59
|
+
info,
|
|
60
|
+
'08S01',
|
|
61
|
+
Errors.ER_CANNOT_RETRIEVE_RSA_KEY
|
|
62
|
+
),
|
|
63
|
+
info
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
this.initialState = false;
|
|
67
|
+
|
|
68
|
+
// ask public Key Retrieval
|
|
69
|
+
out.startPacket(this);
|
|
70
|
+
out.writeInt8(0x01);
|
|
71
|
+
out.flushBuffer(true);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// send Sha256Password Packet
|
|
77
|
+
Sha256PasswordAuth.sendSha256PwdPacket(
|
|
78
|
+
this,
|
|
79
|
+
this.pluginData,
|
|
80
|
+
this.publicKey,
|
|
81
|
+
opts.password,
|
|
82
|
+
out
|
|
83
|
+
);
|
|
84
|
+
} else {
|
|
85
|
+
// has request public key
|
|
86
|
+
this.publicKey = Sha256PasswordAuth.retreivePublicKey(buffer.toString('utf8', 1));
|
|
87
|
+
Sha256PasswordAuth.sendSha256PwdPacket(
|
|
88
|
+
this,
|
|
89
|
+
this.pluginData,
|
|
90
|
+
this.publicKey,
|
|
91
|
+
opts.password,
|
|
92
|
+
out
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
static retreivePublicKey(key) {
|
|
98
|
+
return key.replace('(-+BEGIN PUBLIC KEY-+\\r?\\n|\\n?-+END PUBLIC KEY-+\\r?\\n?)', '');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
static sendSha256PwdPacket(cmd, pluginData, publicKey, password, out) {
|
|
102
|
+
const truncatedSeed = pluginData.slice(0, pluginData.length - 1);
|
|
103
|
+
out.startPacket(cmd);
|
|
104
|
+
const enc = Sha256PasswordAuth.encrypt(truncatedSeed, password, publicKey);
|
|
105
|
+
out.writeBuffer(enc, 0, enc.length);
|
|
106
|
+
out.flushBuffer(cmd);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// encrypt password with public key
|
|
110
|
+
static encrypt(seed, password, publicKey) {
|
|
111
|
+
const nullFinishedPwd = Buffer.from(password + '\0');
|
|
112
|
+
const xorBytes = Buffer.allocUnsafe(nullFinishedPwd.length);
|
|
113
|
+
const seedLength = seed.length;
|
|
114
|
+
for (let i = 0; i < xorBytes.length; i++) {
|
|
115
|
+
xorBytes[i] = nullFinishedPwd[i] ^ seed[i % seedLength];
|
|
116
|
+
}
|
|
117
|
+
return crypto.publicEncrypt(
|
|
118
|
+
{ key: publicKey, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING },
|
|
119
|
+
xorBytes
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
response(packet, out, opts, info) {
|
|
124
|
+
const marker = packet.peek();
|
|
125
|
+
switch (marker) {
|
|
126
|
+
//*********************************************************************************************************
|
|
127
|
+
//* OK_Packet and Err_Packet ending packet
|
|
128
|
+
//*********************************************************************************************************
|
|
129
|
+
case 0x00:
|
|
130
|
+
case 0xff:
|
|
131
|
+
this.emit('send_end');
|
|
132
|
+
return this.successSend(packet, out, opts, info);
|
|
133
|
+
|
|
134
|
+
default:
|
|
135
|
+
let promptData = packet.readBufferRemaining();
|
|
136
|
+
this.exchange(promptData, out, opts, info);
|
|
137
|
+
this.onPacketReceive = this.response;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
module.exports = Sha256PasswordAuth;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Capabilities = require('../../const/capabilities');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Initialize client capabilities according to options and server capabilities
|
|
7
|
+
*
|
|
8
|
+
* @param opts options
|
|
9
|
+
* @param info information
|
|
10
|
+
*/
|
|
11
|
+
module.exports.init = function (opts, info) {
|
|
12
|
+
let capabilities =
|
|
13
|
+
Capabilities.IGNORE_SPACE |
|
|
14
|
+
Capabilities.PROTOCOL_41 |
|
|
15
|
+
Capabilities.TRANSACTIONS |
|
|
16
|
+
Capabilities.SECURE_CONNECTION |
|
|
17
|
+
Capabilities.MULTI_RESULTS |
|
|
18
|
+
Capabilities.PS_MULTI_RESULTS |
|
|
19
|
+
Capabilities.SESSION_TRACK |
|
|
20
|
+
Capabilities.PLUGIN_AUTH_LENENC_CLIENT_DATA;
|
|
21
|
+
|
|
22
|
+
if ((info.serverCapabilities & Capabilities.MYSQL) === BigInt(0)) {
|
|
23
|
+
capabilities |= Capabilities.MARIADB_CLIENT_EXTENDED_TYPE_INFO;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (info.serverCapabilities & Capabilities.PLUGIN_AUTH) {
|
|
27
|
+
capabilities |= Capabilities.PLUGIN_AUTH;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (opts.connectAttributes && info.serverCapabilities & Capabilities.CONNECT_ATTRS) {
|
|
31
|
+
capabilities |= Capabilities.CONNECT_ATTRS;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (opts.foundRows) {
|
|
35
|
+
capabilities |= Capabilities.FOUND_ROWS;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (opts.permitLocalInfile) {
|
|
39
|
+
capabilities |= Capabilities.LOCAL_FILES;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (opts.multipleStatements) {
|
|
43
|
+
capabilities |= Capabilities.MULTI_STATEMENTS;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
info.eofDeprecated = (info.serverCapabilities & Capabilities.DEPRECATE_EOF) > 0;
|
|
47
|
+
if (info.eofDeprecated) {
|
|
48
|
+
capabilities |= Capabilities.DEPRECATE_EOF;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (opts.database && info.serverCapabilities & Capabilities.CONNECT_WITH_DB) {
|
|
52
|
+
capabilities |= Capabilities.CONNECT_WITH_DB;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// use compression only if requested by client and supported by server
|
|
56
|
+
if (opts.compress) {
|
|
57
|
+
if (info.serverCapabilities & Capabilities.COMPRESS) {
|
|
58
|
+
capabilities |= Capabilities.COMPRESS;
|
|
59
|
+
} else {
|
|
60
|
+
opts.compress = false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (opts.bulk) {
|
|
65
|
+
if (info.serverCapabilities & Capabilities.MARIADB_CLIENT_STMT_BULK_OPERATIONS) {
|
|
66
|
+
capabilities |= Capabilities.MARIADB_CLIENT_STMT_BULK_OPERATIONS;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (opts.permitConnectionWhenExpired) {
|
|
71
|
+
capabilities |= Capabilities.CAN_HANDLE_EXPIRED_PASSWORDS;
|
|
72
|
+
}
|
|
73
|
+
info.clientCapabilities = capabilities;
|
|
74
|
+
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Capabilities = require('../../const/capabilities');
|
|
4
|
+
const Iconv = require('iconv-lite');
|
|
5
|
+
const NativePasswordAuth = require('./auth/native-password-auth');
|
|
6
|
+
const Ed25519PasswordAuth = require('./auth/ed25519-password-auth');
|
|
7
|
+
const driverVersion = require('../../../package.json').version;
|
|
8
|
+
const os = require('os');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Send Handshake response packet
|
|
12
|
+
* see https://mariadb.com/kb/en/library/1-connecting-connecting/#handshake-response-packet
|
|
13
|
+
*
|
|
14
|
+
* @param cmd current handshake command
|
|
15
|
+
* @param out output writer
|
|
16
|
+
* @param opts connection options
|
|
17
|
+
* @param pluginName plugin name
|
|
18
|
+
* @param info connection information
|
|
19
|
+
*/
|
|
20
|
+
module.exports.send = function send(cmd, out, opts, pluginName, info) {
|
|
21
|
+
out.startPacket(cmd);
|
|
22
|
+
info.defaultPluginName = pluginName;
|
|
23
|
+
const pwd = Array.isArray(opts.password) ? opts.password[0] : opts.password;
|
|
24
|
+
let authToken;
|
|
25
|
+
let authPlugin;
|
|
26
|
+
switch (pluginName) {
|
|
27
|
+
case 'client_ed25519':
|
|
28
|
+
authToken = Ed25519PasswordAuth.encryptPassword(pwd, info.seed);
|
|
29
|
+
authPlugin = 'client_ed25519';
|
|
30
|
+
break;
|
|
31
|
+
|
|
32
|
+
case 'mysql_clear_password':
|
|
33
|
+
authToken = Buffer.from(pwd);
|
|
34
|
+
authPlugin = 'mysql_clear_password';
|
|
35
|
+
break;
|
|
36
|
+
|
|
37
|
+
default:
|
|
38
|
+
authToken = NativePasswordAuth.encryptPassword(pwd, info.seed, 'sha1');
|
|
39
|
+
authPlugin = 'mysql_native_password';
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
out.writeInt32(Number(info.clientCapabilities & BigInt(0xffffffff)));
|
|
43
|
+
out.writeInt32(1024 * 1024 * 1024); // max packet size
|
|
44
|
+
out.writeInt8(opts.collation.index);
|
|
45
|
+
for (let i = 0; i < 19; i++) {
|
|
46
|
+
out.writeInt8(0);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
out.writeInt32(Number(info.clientCapabilities >> BigInt(32)));
|
|
50
|
+
|
|
51
|
+
//null encoded user
|
|
52
|
+
out.writeString(opts.user || '');
|
|
53
|
+
out.writeInt8(0);
|
|
54
|
+
|
|
55
|
+
if (info.serverCapabilities & Capabilities.PLUGIN_AUTH_LENENC_CLIENT_DATA) {
|
|
56
|
+
out.writeLengthCoded(authToken.length);
|
|
57
|
+
out.writeBuffer(authToken, 0, authToken.length);
|
|
58
|
+
} else if (info.serverCapabilities & Capabilities.SECURE_CONNECTION) {
|
|
59
|
+
out.writeInt8(authToken.length);
|
|
60
|
+
out.writeBuffer(authToken, 0, authToken.length);
|
|
61
|
+
} else {
|
|
62
|
+
out.writeBuffer(authToken, 0, authToken.length);
|
|
63
|
+
out.writeInt8(0);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (info.clientCapabilities & Capabilities.CONNECT_WITH_DB) {
|
|
67
|
+
out.writeString(opts.database);
|
|
68
|
+
out.writeInt8(0);
|
|
69
|
+
info.database = opts.database;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (info.clientCapabilities & Capabilities.PLUGIN_AUTH) {
|
|
73
|
+
out.writeString(authPlugin);
|
|
74
|
+
out.writeInt8(0);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (info.clientCapabilities & Capabilities.CONNECT_ATTRS) {
|
|
78
|
+
out.writeInt8(0xfc);
|
|
79
|
+
let initPos = out.pos; //save position, assuming connection attributes length will be less than 2 bytes length
|
|
80
|
+
out.writeInt16(0);
|
|
81
|
+
|
|
82
|
+
const encoding = opts.collation.charset;
|
|
83
|
+
|
|
84
|
+
writeParam(out, '_client_name', encoding);
|
|
85
|
+
writeParam(out, 'MariaDB connector/Node', encoding);
|
|
86
|
+
|
|
87
|
+
writeParam(out, '_client_version', encoding);
|
|
88
|
+
writeParam(out, driverVersion, encoding);
|
|
89
|
+
|
|
90
|
+
const address = cmd.getSocket().address().address;
|
|
91
|
+
if (address) {
|
|
92
|
+
writeParam(out, '_server_host', encoding);
|
|
93
|
+
writeParam(out, address, encoding);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
writeParam(out, '_os', encoding);
|
|
97
|
+
writeParam(out, process.platform, encoding);
|
|
98
|
+
|
|
99
|
+
writeParam(out, '_client_host', encoding);
|
|
100
|
+
writeParam(out, os.hostname(), encoding);
|
|
101
|
+
|
|
102
|
+
writeParam(out, '_node_version', encoding);
|
|
103
|
+
writeParam(out, process.versions.node, encoding);
|
|
104
|
+
|
|
105
|
+
if (opts.connectAttributes !== true) {
|
|
106
|
+
let attrNames = Object.keys(opts.connectAttributes);
|
|
107
|
+
for (let k = 0; k < attrNames.length; ++k) {
|
|
108
|
+
writeParam(out, attrNames[k], encoding);
|
|
109
|
+
writeParam(out, opts.connectAttributes[attrNames[k]], encoding);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
//write end size
|
|
114
|
+
out.writeInt16AtPos(initPos);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
out.flushBuffer(true);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
function writeParam(out, val, encoding) {
|
|
121
|
+
let param = Buffer.isEncoding(encoding)
|
|
122
|
+
? Buffer.from(val, encoding)
|
|
123
|
+
: Iconv.encode(val, encoding);
|
|
124
|
+
out.writeLengthCoded(param.length);
|
|
125
|
+
out.writeBuffer(param, 0, param.length);
|
|
126
|
+
}
|