added api server and changed docker files
This commit is contained in:
35
login-auth_backend/node_modules/mysql2/lib/packets/auth_next_factor.js
generated
vendored
Normal file
35
login-auth_backend/node_modules/mysql2/lib/packets/auth_next_factor.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2021, Oracle and/or its affiliates.
|
||||
|
||||
'use strict';
|
||||
|
||||
const Packet = require('../packets/packet');
|
||||
|
||||
class AuthNextFactor {
|
||||
constructor(opts) {
|
||||
this.pluginName = opts.pluginName;
|
||||
this.pluginData = opts.pluginData;
|
||||
}
|
||||
|
||||
toPacket(encoding) {
|
||||
const length = 6 + this.pluginName.length + this.pluginData.length;
|
||||
const buffer = Buffer.allocUnsafe(length);
|
||||
const packet = new Packet(0, buffer, 0, length);
|
||||
packet.offset = 4;
|
||||
packet.writeInt8(0x02);
|
||||
packet.writeNullTerminatedString(this.pluginName, encoding);
|
||||
packet.writeBuffer(this.pluginData);
|
||||
return packet;
|
||||
}
|
||||
|
||||
static fromPacket(packet, encoding) {
|
||||
packet.readInt8(); // marker
|
||||
const name = packet.readNullTerminatedString(encoding);
|
||||
const data = packet.readBuffer();
|
||||
return new AuthNextFactor({
|
||||
pluginName: name,
|
||||
pluginData: data,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AuthNextFactor;
|
38
login-auth_backend/node_modules/mysql2/lib/packets/auth_switch_request.js
generated
vendored
Normal file
38
login-auth_backend/node_modules/mysql2/lib/packets/auth_switch_request.js
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
'use strict';
|
||||
|
||||
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchRequest
|
||||
|
||||
const Packet = require('../packets/packet');
|
||||
|
||||
class AuthSwitchRequest {
|
||||
constructor(opts) {
|
||||
this.pluginName = opts.pluginName;
|
||||
this.pluginData = opts.pluginData;
|
||||
}
|
||||
|
||||
toPacket() {
|
||||
const length = 6 + this.pluginName.length + this.pluginData.length;
|
||||
const buffer = Buffer.allocUnsafe(length);
|
||||
const packet = new Packet(0, buffer, 0, length);
|
||||
packet.offset = 4;
|
||||
packet.writeInt8(0xfe);
|
||||
// TODO: use server encoding
|
||||
packet.writeNullTerminatedString(this.pluginName, 'cesu8');
|
||||
packet.writeBuffer(this.pluginData);
|
||||
return packet;
|
||||
}
|
||||
|
||||
static fromPacket(packet) {
|
||||
packet.readInt8(); // marker
|
||||
// assert marker == 0xfe?
|
||||
// TODO: use server encoding
|
||||
const name = packet.readNullTerminatedString('cesu8');
|
||||
const data = packet.readBuffer();
|
||||
return new AuthSwitchRequest({
|
||||
pluginName: name,
|
||||
pluginData: data,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AuthSwitchRequest;
|
33
login-auth_backend/node_modules/mysql2/lib/packets/auth_switch_request_more_data.js
generated
vendored
Normal file
33
login-auth_backend/node_modules/mysql2/lib/packets/auth_switch_request_more_data.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchRequest
|
||||
|
||||
const Packet = require('../packets/packet');
|
||||
|
||||
class AuthSwitchRequestMoreData {
|
||||
constructor(data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
toPacket() {
|
||||
const length = 5 + this.data.length;
|
||||
const buffer = Buffer.allocUnsafe(length);
|
||||
const packet = new Packet(0, buffer, 0, length);
|
||||
packet.offset = 4;
|
||||
packet.writeInt8(0x01);
|
||||
packet.writeBuffer(this.data);
|
||||
return packet;
|
||||
}
|
||||
|
||||
static fromPacket(packet) {
|
||||
packet.readInt8(); // marker
|
||||
const data = packet.readBuffer();
|
||||
return new AuthSwitchRequestMoreData(data);
|
||||
}
|
||||
|
||||
static verifyMarker(packet) {
|
||||
return packet.peekByte() === 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AuthSwitchRequestMoreData;
|
30
login-auth_backend/node_modules/mysql2/lib/packets/auth_switch_response.js
generated
vendored
Normal file
30
login-auth_backend/node_modules/mysql2/lib/packets/auth_switch_response.js
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
'use strict';
|
||||
|
||||
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchRequest
|
||||
|
||||
const Packet = require('../packets/packet');
|
||||
|
||||
class AuthSwitchResponse {
|
||||
constructor(data) {
|
||||
if (!Buffer.isBuffer(data)) {
|
||||
data = Buffer.from(data);
|
||||
}
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
toPacket() {
|
||||
const length = 4 + this.data.length;
|
||||
const buffer = Buffer.allocUnsafe(length);
|
||||
const packet = new Packet(0, buffer, 0, length);
|
||||
packet.offset = 4;
|
||||
packet.writeBuffer(this.data);
|
||||
return packet;
|
||||
}
|
||||
|
||||
static fromPacket(packet) {
|
||||
const data = packet.readBuffer();
|
||||
return new AuthSwitchResponse(data);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AuthSwitchResponse;
|
95
login-auth_backend/node_modules/mysql2/lib/packets/binary_row.js
generated
vendored
Normal file
95
login-auth_backend/node_modules/mysql2/lib/packets/binary_row.js
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
'use strict';
|
||||
|
||||
const Types = require('../constants/types');
|
||||
const Packet = require('../packets/packet');
|
||||
|
||||
const binaryReader = new Array(256);
|
||||
|
||||
class BinaryRow {
|
||||
constructor(columns) {
|
||||
this.columns = columns || [];
|
||||
}
|
||||
|
||||
static toPacket(columns, encoding) {
|
||||
// throw new Error('Not implemented');
|
||||
const sequenceId = 0; // TODO remove, this is calculated now in connecton
|
||||
let length = 0;
|
||||
columns.forEach((val) => {
|
||||
if (val === null || typeof val === 'undefined') {
|
||||
++length;
|
||||
return;
|
||||
}
|
||||
length += Packet.lengthCodedStringLength(val.toString(10), encoding);
|
||||
});
|
||||
|
||||
length = length + 2;
|
||||
|
||||
const buffer = Buffer.allocUnsafe(length + 4);
|
||||
const packet = new Packet(sequenceId, buffer, 0, length + 4);
|
||||
packet.offset = 4;
|
||||
|
||||
packet.writeInt8(0);
|
||||
|
||||
let bitmap = 0;
|
||||
let bitValue = 1;
|
||||
columns.forEach((parameter) => {
|
||||
if (parameter.type === Types.NULL) {
|
||||
bitmap += bitValue;
|
||||
}
|
||||
bitValue *= 2;
|
||||
if (bitValue === 256) {
|
||||
packet.writeInt8(bitmap);
|
||||
bitmap = 0;
|
||||
bitValue = 1;
|
||||
}
|
||||
});
|
||||
if (bitValue !== 1) {
|
||||
packet.writeInt8(bitmap);
|
||||
}
|
||||
|
||||
columns.forEach((val) => {
|
||||
if (val === null) {
|
||||
packet.writeNull();
|
||||
return;
|
||||
}
|
||||
if (typeof val === 'undefined') {
|
||||
packet.writeInt8(0);
|
||||
return;
|
||||
}
|
||||
packet.writeLengthCodedString(val.toString(10), encoding);
|
||||
});
|
||||
return packet;
|
||||
}
|
||||
|
||||
// TODO: complete list of types...
|
||||
static fromPacket(fields, packet) {
|
||||
const columns = new Array(fields.length);
|
||||
packet.readInt8(); // TODO check it's 0
|
||||
const nullBitmapLength = Math.floor((fields.length + 7 + 2) / 8);
|
||||
// TODO: read and interpret null bitmap
|
||||
packet.skip(nullBitmapLength);
|
||||
for (let i = 0; i < columns.length; ++i) {
|
||||
columns[i] = binaryReader[fields[i].columnType].apply(packet);
|
||||
}
|
||||
return new BinaryRow(columns);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: replace with constants.MYSQL_TYPE_*
|
||||
binaryReader[Types.DECIMAL] = Packet.prototype.readLengthCodedString;
|
||||
binaryReader[1] = Packet.prototype.readInt8; // tiny
|
||||
binaryReader[2] = Packet.prototype.readInt16; // short
|
||||
binaryReader[3] = Packet.prototype.readInt32; // long
|
||||
binaryReader[4] = Packet.prototype.readFloat; // float
|
||||
binaryReader[5] = Packet.prototype.readDouble; // double
|
||||
binaryReader[6] = Packet.prototype.assertInvalid; // null, should be skipped vie null bitmap
|
||||
binaryReader[7] = Packet.prototype.readTimestamp; // timestamp, http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::MYSQL_TYPE_TIMESTAMP
|
||||
binaryReader[8] = Packet.prototype.readInt64; // long long
|
||||
binaryReader[9] = Packet.prototype.readInt32; // int24
|
||||
binaryReader[10] = Packet.prototype.readTimestamp; // date
|
||||
binaryReader[11] = Packet.prototype.readTime; // time, http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::MYSQL_TYPE_TIME
|
||||
binaryReader[12] = Packet.prototype.readDateTime; // datetime, http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::MYSQL_TYPE_DATETIME
|
||||
binaryReader[13] = Packet.prototype.readInt16; // year
|
||||
binaryReader[Types.VAR_STRING] = Packet.prototype.readLengthCodedString; // var string
|
||||
|
||||
module.exports = BinaryRow;
|
33
login-auth_backend/node_modules/mysql2/lib/packets/binlog_dump.js
generated
vendored
Normal file
33
login-auth_backend/node_modules/mysql2/lib/packets/binlog_dump.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
// http://dev.mysql.com/doc/internals/en/com-binlog-dump.html#packet-COM_BINLOG_DUMP
|
||||
|
||||
const Packet = require('../packets/packet');
|
||||
const CommandCodes = require('../constants/commands');
|
||||
|
||||
// TODO: add flag to constants
|
||||
// 0x01 - BINLOG_DUMP_NON_BLOCK
|
||||
// send EOF instead of blocking
|
||||
class BinlogDump {
|
||||
constructor(opts) {
|
||||
this.binlogPos = opts.binlogPos || 0;
|
||||
this.serverId = opts.serverId || 0;
|
||||
this.flags = opts.flags || 0;
|
||||
this.filename = opts.filename || '';
|
||||
}
|
||||
|
||||
toPacket() {
|
||||
const length = 15 + Buffer.byteLength(this.filename, 'utf8'); // TODO: should be ascii?
|
||||
const buffer = Buffer.allocUnsafe(length);
|
||||
const packet = new Packet(0, buffer, 0, length);
|
||||
packet.offset = 4;
|
||||
packet.writeInt8(CommandCodes.BINLOG_DUMP);
|
||||
packet.writeInt32(this.binlogPos);
|
||||
packet.writeInt16(this.flags);
|
||||
packet.writeInt32(this.serverId);
|
||||
packet.writeString(this.filename);
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BinlogDump;
|
115
login-auth_backend/node_modules/mysql2/lib/packets/binlog_query_statusvars.js
generated
vendored
Normal file
115
login-auth_backend/node_modules/mysql2/lib/packets/binlog_query_statusvars.js
generated
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
'use strict';
|
||||
|
||||
// http://dev.mysql.com/doc/internals/en/query-event.html
|
||||
|
||||
const keys = {
|
||||
FLAGS2: 0,
|
||||
SQL_MODE: 1,
|
||||
CATALOG: 2,
|
||||
AUTO_INCREMENT: 3,
|
||||
CHARSET: 4,
|
||||
TIME_ZONE: 5,
|
||||
CATALOG_NZ: 6,
|
||||
LC_TIME_NAMES: 7,
|
||||
CHARSET_DATABASE: 8,
|
||||
TABLE_MAP_FOR_UPDATE: 9,
|
||||
MASTER_DATA_WRITTEN: 10,
|
||||
INVOKERS: 11,
|
||||
UPDATED_DB_NAMES: 12,
|
||||
MICROSECONDS: 3,
|
||||
};
|
||||
|
||||
module.exports = function parseStatusVars(buffer) {
|
||||
const result = {};
|
||||
let offset = 0;
|
||||
let key, length, prevOffset;
|
||||
while (offset < buffer.length) {
|
||||
key = buffer[offset++];
|
||||
switch (key) {
|
||||
case keys.FLAGS2:
|
||||
result.flags = buffer.readUInt32LE(offset);
|
||||
offset += 4;
|
||||
break;
|
||||
case keys.SQL_MODE:
|
||||
// value is 8 bytes, but all dcumented flags are in first 4 bytes
|
||||
result.sqlMode = buffer.readUInt32LE(offset);
|
||||
offset += 8;
|
||||
break;
|
||||
case keys.CATALOG:
|
||||
length = buffer[offset++];
|
||||
result.catalog = buffer.toString('utf8', offset, offset + length);
|
||||
offset += length + 1; // null byte after string
|
||||
break;
|
||||
case keys.CHARSET:
|
||||
result.clientCharset = buffer.readUInt16LE(offset);
|
||||
result.connectionCollation = buffer.readUInt16LE(offset + 2);
|
||||
result.serverCharset = buffer.readUInt16LE(offset + 4);
|
||||
offset += 6;
|
||||
break;
|
||||
case keys.TIME_ZONE:
|
||||
length = buffer[offset++];
|
||||
result.timeZone = buffer.toString('utf8', offset, offset + length);
|
||||
offset += length; // no null byte
|
||||
break;
|
||||
case keys.CATALOG_NZ:
|
||||
length = buffer[offset++];
|
||||
result.catalogNz = buffer.toString('utf8', offset, offset + length);
|
||||
offset += length; // no null byte
|
||||
break;
|
||||
case keys.LC_TIME_NAMES:
|
||||
result.lcTimeNames = buffer.readUInt16LE(offset);
|
||||
offset += 2;
|
||||
break;
|
||||
case keys.CHARSET_DATABASE:
|
||||
result.schemaCharset = buffer.readUInt16LE(offset);
|
||||
offset += 2;
|
||||
break;
|
||||
case keys.TABLE_MAP_FOR_UPDATE:
|
||||
result.mapForUpdate1 = buffer.readUInt32LE(offset);
|
||||
result.mapForUpdate2 = buffer.readUInt32LE(offset + 4);
|
||||
offset += 8;
|
||||
break;
|
||||
case keys.MASTER_DATA_WRITTEN:
|
||||
result.masterDataWritten = buffer.readUInt32LE(offset);
|
||||
offset += 4;
|
||||
break;
|
||||
case keys.INVOKERS:
|
||||
length = buffer[offset++];
|
||||
result.invokerUsername = buffer.toString(
|
||||
'utf8',
|
||||
offset,
|
||||
offset + length
|
||||
);
|
||||
offset += length;
|
||||
length = buffer[offset++];
|
||||
result.invokerHostname = buffer.toString(
|
||||
'utf8',
|
||||
offset,
|
||||
offset + length
|
||||
);
|
||||
offset += length;
|
||||
break;
|
||||
case keys.UPDATED_DB_NAMES:
|
||||
length = buffer[offset++];
|
||||
// length - number of null-terminated strings
|
||||
result.updatedDBs = []; // we'll store them as array here
|
||||
for (; length; --length) {
|
||||
prevOffset = offset;
|
||||
// fast forward to null terminating byte
|
||||
while (buffer[offset++] && offset < buffer.length) {
|
||||
// empty body, everything inside while condition
|
||||
}
|
||||
result.updatedDBs.push(
|
||||
buffer.toString('utf8', prevOffset, offset - 1)
|
||||
);
|
||||
}
|
||||
break;
|
||||
case keys.MICROSECONDS:
|
||||
result.microseconds =
|
||||
// REVIEW: INVALID UNKNOWN VARIABLE!
|
||||
buffer.readInt16LE(offset) + (buffer[offset + 2] << 16);
|
||||
offset += 3;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
97
login-auth_backend/node_modules/mysql2/lib/packets/change_user.js
generated
vendored
Normal file
97
login-auth_backend/node_modules/mysql2/lib/packets/change_user.js
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
'use strict';
|
||||
|
||||
const CommandCode = require('../constants/commands.js');
|
||||
const ClientConstants = require('../constants/client.js');
|
||||
const Packet = require('../packets/packet.js');
|
||||
const auth41 = require('../auth_41.js');
|
||||
const CharsetToEncoding = require('../constants/charset_encodings.js');
|
||||
|
||||
// https://dev.mysql.com/doc/internals/en/com-change-user.html#packet-COM_CHANGE_USER
|
||||
class ChangeUser {
|
||||
constructor(opts) {
|
||||
this.flags = opts.flags;
|
||||
this.user = opts.user || '';
|
||||
this.database = opts.database || '';
|
||||
this.password = opts.password || '';
|
||||
this.passwordSha1 = opts.passwordSha1;
|
||||
this.authPluginData1 = opts.authPluginData1;
|
||||
this.authPluginData2 = opts.authPluginData2;
|
||||
this.connectAttributes = opts.connectAttrinutes || {};
|
||||
let authToken;
|
||||
if (this.passwordSha1) {
|
||||
authToken = auth41.calculateTokenFromPasswordSha(
|
||||
this.passwordSha1,
|
||||
this.authPluginData1,
|
||||
this.authPluginData2
|
||||
);
|
||||
} else {
|
||||
authToken = auth41.calculateToken(
|
||||
this.password,
|
||||
this.authPluginData1,
|
||||
this.authPluginData2
|
||||
);
|
||||
}
|
||||
this.authToken = authToken;
|
||||
this.charsetNumber = opts.charsetNumber;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// ChangeUser.fromPacket = function(packet)
|
||||
// };
|
||||
serializeToBuffer(buffer) {
|
||||
const isSet = (flag) => this.flags & ClientConstants[flag];
|
||||
const packet = new Packet(0, buffer, 0, buffer.length);
|
||||
packet.offset = 4;
|
||||
const encoding = CharsetToEncoding[this.charsetNumber];
|
||||
packet.writeInt8(CommandCode.CHANGE_USER);
|
||||
packet.writeNullTerminatedString(this.user, encoding);
|
||||
if (isSet('SECURE_CONNECTION')) {
|
||||
packet.writeInt8(this.authToken.length);
|
||||
packet.writeBuffer(this.authToken);
|
||||
} else {
|
||||
packet.writeBuffer(this.authToken);
|
||||
packet.writeInt8(0);
|
||||
}
|
||||
packet.writeNullTerminatedString(this.database, encoding);
|
||||
packet.writeInt16(this.charsetNumber);
|
||||
if (isSet('PLUGIN_AUTH')) {
|
||||
// TODO: read this from parameters
|
||||
packet.writeNullTerminatedString('mysql_native_password', 'latin1');
|
||||
}
|
||||
if (isSet('CONNECT_ATTRS')) {
|
||||
const connectAttributes = this.connectAttributes;
|
||||
const attrNames = Object.keys(connectAttributes);
|
||||
let keysLength = 0;
|
||||
for (let k = 0; k < attrNames.length; ++k) {
|
||||
keysLength += Packet.lengthCodedStringLength(attrNames[k], encoding);
|
||||
keysLength += Packet.lengthCodedStringLength(
|
||||
connectAttributes[attrNames[k]],
|
||||
encoding
|
||||
);
|
||||
}
|
||||
packet.writeLengthCodedNumber(keysLength);
|
||||
for (let k = 0; k < attrNames.length; ++k) {
|
||||
packet.writeLengthCodedString(attrNames[k], encoding);
|
||||
packet.writeLengthCodedString(
|
||||
connectAttributes[attrNames[k]],
|
||||
encoding
|
||||
);
|
||||
}
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
toPacket() {
|
||||
if (typeof this.user !== 'string') {
|
||||
throw new Error('"user" connection config property must be a string');
|
||||
}
|
||||
if (typeof this.database !== 'string') {
|
||||
throw new Error('"database" connection config property must be a string');
|
||||
}
|
||||
// dry run: calculate resulting packet length
|
||||
const p = this.serializeToBuffer(Packet.MockBuffer());
|
||||
return this.serializeToBuffer(Buffer.allocUnsafe(p.offset));
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ChangeUser;
|
21
login-auth_backend/node_modules/mysql2/lib/packets/close_statement.js
generated
vendored
Normal file
21
login-auth_backend/node_modules/mysql2/lib/packets/close_statement.js
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
const Packet = require('../packets/packet');
|
||||
const CommandCodes = require('../constants/commands');
|
||||
|
||||
class CloseStatement {
|
||||
constructor(id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
// note: no response sent back
|
||||
toPacket() {
|
||||
const packet = new Packet(0, Buffer.allocUnsafe(9), 0, 9);
|
||||
packet.offset = 4;
|
||||
packet.writeInt8(CommandCodes.STMT_CLOSE);
|
||||
packet.writeInt32(this.id);
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CloseStatement;
|
291
login-auth_backend/node_modules/mysql2/lib/packets/column_definition.js
generated
vendored
Normal file
291
login-auth_backend/node_modules/mysql2/lib/packets/column_definition.js
generated
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
'use strict';
|
||||
|
||||
const Packet = require('../packets/packet');
|
||||
const StringParser = require('../parsers/string');
|
||||
const CharsetToEncoding = require('../constants/charset_encodings.js');
|
||||
|
||||
const fields = ['catalog', 'schema', 'table', 'orgTable', 'name', 'orgName'];
|
||||
|
||||
// creating JS string is relatively expensive (compared to
|
||||
// reading few bytes from buffer) because all string properties
|
||||
// except for name are unlikely to be used we postpone
|
||||
// string conversion until property access
|
||||
//
|
||||
// TODO: watch for integration benchmarks (one with real network buffer)
|
||||
// there could be bad side effect as keeping reference to a buffer makes it
|
||||
// sit in the memory longer (usually until final .query() callback)
|
||||
// Latest v8 perform much better in regard to bufferer -> string conversion,
|
||||
// at some point of time this optimisation might become unnecessary
|
||||
// see https://github.com/sidorares/node-mysql2/pull/137
|
||||
//
|
||||
class ColumnDefinition {
|
||||
constructor(packet, clientEncoding) {
|
||||
this._buf = packet.buffer;
|
||||
this._clientEncoding = clientEncoding;
|
||||
this._catalogLength = packet.readLengthCodedNumber();
|
||||
this._catalogStart = packet.offset;
|
||||
packet.offset += this._catalogLength;
|
||||
this._schemaLength = packet.readLengthCodedNumber();
|
||||
this._schemaStart = packet.offset;
|
||||
packet.offset += this._schemaLength;
|
||||
this._tableLength = packet.readLengthCodedNumber();
|
||||
this._tableStart = packet.offset;
|
||||
packet.offset += this._tableLength;
|
||||
this._orgTableLength = packet.readLengthCodedNumber();
|
||||
this._orgTableStart = packet.offset;
|
||||
packet.offset += this._orgTableLength;
|
||||
// name is always used, don't make it lazy
|
||||
const _nameLength = packet.readLengthCodedNumber();
|
||||
const _nameStart = packet.offset;
|
||||
packet.offset += _nameLength;
|
||||
this._orgNameLength = packet.readLengthCodedNumber();
|
||||
this._orgNameStart = packet.offset;
|
||||
packet.offset += this._orgNameLength;
|
||||
packet.skip(1); // length of the following fields (always 0x0c)
|
||||
this.characterSet = packet.readInt16();
|
||||
this.encoding = CharsetToEncoding[this.characterSet];
|
||||
this.name = StringParser.decode(
|
||||
this._buf,
|
||||
this.encoding === 'binary' ? this._clientEncoding : this.encoding,
|
||||
_nameStart,
|
||||
_nameStart + _nameLength
|
||||
);
|
||||
this.columnLength = packet.readInt32();
|
||||
this.columnType = packet.readInt8();
|
||||
this.type = this.columnType;
|
||||
this.flags = packet.readInt16();
|
||||
this.decimals = packet.readInt8();
|
||||
}
|
||||
|
||||
inspect() {
|
||||
return {
|
||||
catalog: this.catalog,
|
||||
schema: this.schema,
|
||||
name: this.name,
|
||||
orgName: this.orgName,
|
||||
table: this.table,
|
||||
orgTable: this.orgTable,
|
||||
characterSet: this.characterSet,
|
||||
encoding: this.encoding,
|
||||
columnLength: this.columnLength,
|
||||
type: this.columnType,
|
||||
flags: this.flags,
|
||||
decimals: this.decimals,
|
||||
};
|
||||
}
|
||||
|
||||
[Symbol.for('nodejs.util.inspect.custom')](depth, inspectOptions, inspect) {
|
||||
const Types = require('../constants/types.js');
|
||||
const typeNames = [];
|
||||
for (const t in Types) {
|
||||
typeNames[Types[t]] = t;
|
||||
}
|
||||
const fiedFlags = require('../constants/field_flags.js');
|
||||
const flagNames = [];
|
||||
// TODO: respect inspectOptions.showHidden
|
||||
//const inspectFlags = inspectOptions.showHidden ? this.flags : this.flags & ~fiedFlags.PRI_KEY;
|
||||
const inspectFlags = this.flags;
|
||||
for (const f in fiedFlags) {
|
||||
if (inspectFlags & fiedFlags[f]) {
|
||||
if (f === 'PRI_KEY') {
|
||||
flagNames.push('PRIMARY KEY');
|
||||
} else if (f === 'NOT_NULL') {
|
||||
flagNames.push('NOT NULL');
|
||||
} else if (f === 'BINARY') {
|
||||
// ignore flag for now
|
||||
} else if (f === 'MULTIPLE_KEY') {
|
||||
// not sure if that should be part of inspection.
|
||||
// in the schema usually this is part of index definition
|
||||
// example: UNIQUE KEY `my_uniq_id` (`id_box_elements`,`id_router`)
|
||||
// note that only first column has MULTIPLE_KEY flag set in this case
|
||||
// so there is no good way of knowing that this is part of index just
|
||||
// by looking at indifidual field flags
|
||||
} else if (f === 'NO_DEFAULT_VALUE') {
|
||||
// almost the same as NOT_NULL?
|
||||
} else if (f === 'BLOB') {
|
||||
// included in the type
|
||||
} else if (f === 'UNSIGNED') {
|
||||
// this should be first after type
|
||||
} else if (f === 'TIMESTAMP') {
|
||||
// timestamp flag is redundant for inspection - already included in type
|
||||
} else if (f === 'ON_UPDATE_NOW') {
|
||||
flagNames.push('ON UPDATE CURRENT_TIMESTAMP');
|
||||
} else {
|
||||
flagNames.push(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (depth > 1) {
|
||||
return inspect({
|
||||
...this.inspect(),
|
||||
typeName: typeNames[this.columnType],
|
||||
flags: flagNames,
|
||||
});
|
||||
}
|
||||
|
||||
const isUnsigned = this.flags & fiedFlags.UNSIGNED;
|
||||
|
||||
let typeName = typeNames[this.columnType];
|
||||
if (typeName === 'BLOB') {
|
||||
// TODO: check for non-utf8mb4 encoding
|
||||
if (this.columnLength === 4294967295) {
|
||||
typeName = 'LONGTEXT';
|
||||
} else if (this.columnLength === 67108860) {
|
||||
typeName = 'MEDIUMTEXT';
|
||||
} else if (this.columnLength === 262140) {
|
||||
typeName = 'TEXT';
|
||||
} else if (this.columnLength === 1020) {
|
||||
// 255*4
|
||||
typeName = 'TINYTEXT';
|
||||
} else {
|
||||
typeName = `BLOB(${this.columnLength})`;
|
||||
}
|
||||
} else if (typeName === 'VAR_STRING') {
|
||||
// TODO: check for non-utf8mb4 encoding
|
||||
typeName = `VARCHAR(${Math.ceil(this.columnLength / 4)})`;
|
||||
} else if (typeName === 'TINY') {
|
||||
if (
|
||||
(this.columnLength === 3 && isUnsigned) ||
|
||||
(this.columnLength === 4 && !isUnsigned)
|
||||
) {
|
||||
typeName = 'TINYINT';
|
||||
} else {
|
||||
typeName = `TINYINT(${this.columnLength})`;
|
||||
}
|
||||
} else if (typeName === 'LONGLONG') {
|
||||
if (this.columnLength === 20) {
|
||||
typeName = 'BIGINT';
|
||||
} else {
|
||||
typeName = `BIGINT(${this.columnLength})`;
|
||||
}
|
||||
} else if (typeName === 'SHORT') {
|
||||
if (isUnsigned && this.columnLength === 5) {
|
||||
typeName = 'SMALLINT';
|
||||
} else if (!isUnsigned && this.columnLength === 6) {
|
||||
typeName = 'SMALLINT';
|
||||
} else {
|
||||
typeName = `SMALLINT(${this.columnLength})`;
|
||||
}
|
||||
} else if (typeName === 'LONG') {
|
||||
if (isUnsigned && this.columnLength === 10) {
|
||||
typeName = 'INT';
|
||||
} else if (!isUnsigned && this.columnLength === 11) {
|
||||
typeName = 'INT';
|
||||
} else {
|
||||
typeName = `INT(${this.columnLength})`;
|
||||
}
|
||||
} else if (typeName === 'INT24') {
|
||||
if (isUnsigned && this.columnLength === 8) {
|
||||
typeName = 'MEDIUMINT';
|
||||
} else if (!isUnsigned && this.columnLength === 9) {
|
||||
typeName = 'MEDIUMINT';
|
||||
} else {
|
||||
typeName = `MEDIUMINT(${this.columnLength})`;
|
||||
}
|
||||
} else if (typeName === 'DOUBLE') {
|
||||
// DOUBLE without modifiers is reported as DOUBLE(22, 31)
|
||||
if (this.columnLength === 22 && this.decimals === 31) {
|
||||
typeName = 'DOUBLE';
|
||||
} else {
|
||||
typeName = `DOUBLE(${this.columnLength},${this.decimals})`;
|
||||
}
|
||||
} else if (typeName === 'FLOAT') {
|
||||
// FLOAT without modifiers is reported as FLOAT(12, 31)
|
||||
if (this.columnLength === 12 && this.decimals === 31) {
|
||||
typeName = 'FLOAT';
|
||||
} else {
|
||||
typeName = `FLOAT(${this.columnLength},${this.decimals})`;
|
||||
}
|
||||
} else if (typeName === 'NEWDECIMAL') {
|
||||
if (this.columnLength === 11 && this.decimals === 0) {
|
||||
typeName = 'DECIMAL';
|
||||
} else if (this.decimals === 0) {
|
||||
// not sure why, but DECIMAL(13) is reported as DECIMAL(14, 0)
|
||||
// and DECIMAL(13, 9) is reported as NEWDECIMAL(15, 9)
|
||||
if (isUnsigned) {
|
||||
typeName = `DECIMAL(${this.columnLength})`;
|
||||
} else {
|
||||
typeName = `DECIMAL(${this.columnLength - 1})`;
|
||||
}
|
||||
} else {
|
||||
typeName = `DECIMAL(${this.columnLength - 2},${this.decimals})`;
|
||||
}
|
||||
} else {
|
||||
typeName = `${typeNames[this.columnType]}(${this.columnLength})`;
|
||||
}
|
||||
|
||||
if (isUnsigned) {
|
||||
typeName += ' UNSIGNED';
|
||||
}
|
||||
|
||||
// TODO respect colors option
|
||||
return `\`${this.name}\` ${[typeName, ...flagNames].join(' ')}`;
|
||||
}
|
||||
|
||||
static toPacket(column, sequenceId) {
|
||||
let length = 17; // = 4 padding + 1 + 12 for the rest
|
||||
fields.forEach((field) => {
|
||||
length += Packet.lengthCodedStringLength(
|
||||
column[field],
|
||||
CharsetToEncoding[column.characterSet]
|
||||
);
|
||||
});
|
||||
const buffer = Buffer.allocUnsafe(length);
|
||||
|
||||
const packet = new Packet(sequenceId, buffer, 0, length);
|
||||
function writeField(name) {
|
||||
packet.writeLengthCodedString(
|
||||
column[name],
|
||||
CharsetToEncoding[column.characterSet]
|
||||
);
|
||||
}
|
||||
packet.offset = 4;
|
||||
fields.forEach(writeField);
|
||||
packet.writeInt8(0x0c);
|
||||
packet.writeInt16(column.characterSet);
|
||||
packet.writeInt32(column.columnLength);
|
||||
packet.writeInt8(column.columnType);
|
||||
packet.writeInt16(column.flags);
|
||||
packet.writeInt8(column.decimals);
|
||||
packet.writeInt16(0); // filler
|
||||
return packet;
|
||||
}
|
||||
|
||||
// node-mysql compatibility: alias "db" to "schema"
|
||||
get db() {
|
||||
return this.schema;
|
||||
}
|
||||
}
|
||||
|
||||
const addString = function (name) {
|
||||
Object.defineProperty(ColumnDefinition.prototype, name, {
|
||||
get: function () {
|
||||
const start = this[`_${name}Start`];
|
||||
const end = start + this[`_${name}Length`];
|
||||
const val = StringParser.decode(
|
||||
this._buf,
|
||||
this.encoding === 'binary' ? this._clientEncoding : this.encoding,
|
||||
start,
|
||||
end
|
||||
);
|
||||
|
||||
Object.defineProperty(this, name, {
|
||||
value: val,
|
||||
writable: false,
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
});
|
||||
|
||||
return val;
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
addString('catalog');
|
||||
addString('schema');
|
||||
addString('table');
|
||||
addString('orgTable');
|
||||
addString('orgName');
|
||||
|
||||
module.exports = ColumnDefinition;
|
214
login-auth_backend/node_modules/mysql2/lib/packets/execute.js
generated
vendored
Normal file
214
login-auth_backend/node_modules/mysql2/lib/packets/execute.js
generated
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
'use strict';
|
||||
|
||||
const CursorType = require('../constants/cursor');
|
||||
const CommandCodes = require('../constants/commands');
|
||||
const Types = require('../constants/types');
|
||||
const Packet = require('../packets/packet');
|
||||
const CharsetToEncoding = require('../constants/charset_encodings.js');
|
||||
|
||||
function isJSON(value) {
|
||||
return (
|
||||
Array.isArray(value) ||
|
||||
value.constructor === Object ||
|
||||
(typeof value.toJSON === 'function' && !Buffer.isBuffer(value))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a value to an object describing type, String/Buffer representation and length
|
||||
* @param {*} value
|
||||
*/
|
||||
function toParameter(value, encoding, timezone) {
|
||||
let type = Types.VAR_STRING;
|
||||
let length;
|
||||
let writer = function (value) {
|
||||
// eslint-disable-next-line no-invalid-this
|
||||
return Packet.prototype.writeLengthCodedString.call(this, value, encoding);
|
||||
};
|
||||
if (value !== null) {
|
||||
switch (typeof value) {
|
||||
case 'undefined':
|
||||
throw new TypeError('Bind parameters must not contain undefined');
|
||||
|
||||
case 'number':
|
||||
type = Types.DOUBLE;
|
||||
length = 8;
|
||||
writer = Packet.prototype.writeDouble;
|
||||
break;
|
||||
|
||||
case 'boolean':
|
||||
value = value | 0;
|
||||
type = Types.TINY;
|
||||
length = 1;
|
||||
writer = Packet.prototype.writeInt8;
|
||||
break;
|
||||
|
||||
case 'object':
|
||||
if (Object.prototype.toString.call(value) === '[object Date]') {
|
||||
type = Types.DATETIME;
|
||||
length = 12;
|
||||
writer = function (value) {
|
||||
// eslint-disable-next-line no-invalid-this
|
||||
return Packet.prototype.writeDate.call(this, value, timezone);
|
||||
};
|
||||
} else if (isJSON(value)) {
|
||||
value = JSON.stringify(value);
|
||||
type = Types.JSON;
|
||||
} else if (Buffer.isBuffer(value)) {
|
||||
length = Packet.lengthCodedNumberLength(value.length) + value.length;
|
||||
writer = Packet.prototype.writeLengthCodedBuffer;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
value = value.toString();
|
||||
}
|
||||
} else {
|
||||
value = '';
|
||||
type = Types.NULL;
|
||||
}
|
||||
if (!length) {
|
||||
length = Packet.lengthCodedStringLength(value, encoding);
|
||||
}
|
||||
return { value, type, length, writer };
|
||||
}
|
||||
|
||||
class Execute {
|
||||
constructor(id, parameters, charsetNumber, timezone) {
|
||||
this.id = id;
|
||||
this.parameters = parameters;
|
||||
this.encoding = CharsetToEncoding[charsetNumber];
|
||||
this.timezone = timezone;
|
||||
}
|
||||
|
||||
static fromPacket(packet, encoding) {
|
||||
const stmtId = packet.readInt32();
|
||||
const flags = packet.readInt8();
|
||||
const iterationCount = packet.readInt32();
|
||||
|
||||
let i = packet.offset;
|
||||
while (i < packet.end - 1) {
|
||||
if (
|
||||
(packet.buffer[i + 1] === Types.VAR_STRING ||
|
||||
packet.buffer[i + 1] === Types.NULL ||
|
||||
packet.buffer[i + 1] === Types.DOUBLE ||
|
||||
packet.buffer[i + 1] === Types.TINY ||
|
||||
packet.buffer[i + 1] === Types.DATETIME ||
|
||||
packet.buffer[i + 1] === Types.JSON) &&
|
||||
packet.buffer[i] === 1 &&
|
||||
packet.buffer[i + 2] === 0
|
||||
) {
|
||||
break;
|
||||
} else {
|
||||
packet.readInt8();
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
const types = [];
|
||||
|
||||
for (let i = packet.offset + 1; i < packet.end - 1; i++) {
|
||||
if (
|
||||
(packet.buffer[i] === Types.VAR_STRING ||
|
||||
packet.buffer[i] === Types.NULL ||
|
||||
packet.buffer[i] === Types.DOUBLE ||
|
||||
packet.buffer[i] === Types.TINY ||
|
||||
packet.buffer[i] === Types.DATETIME ||
|
||||
packet.buffer[i] === Types.JSON) &&
|
||||
packet.buffer[i + 1] === 0
|
||||
) {
|
||||
types.push(packet.buffer[i]);
|
||||
packet.skip(2);
|
||||
}
|
||||
}
|
||||
|
||||
packet.skip(1);
|
||||
|
||||
const values = [];
|
||||
for (let i = 0; i < types.length; i++) {
|
||||
if (types[i] === Types.VAR_STRING) {
|
||||
values.push(packet.readLengthCodedString(encoding));
|
||||
} else if (types[i] === Types.DOUBLE) {
|
||||
values.push(packet.readDouble());
|
||||
} else if (types[i] === Types.TINY) {
|
||||
values.push(packet.readInt8());
|
||||
} else if (types[i] === Types.DATETIME) {
|
||||
values.push(packet.readDateTime());
|
||||
} else if (types[i] === Types.JSON) {
|
||||
values.push(JSON.parse(packet.readLengthCodedString(encoding)));
|
||||
}
|
||||
if (types[i] === Types.NULL) {
|
||||
values.push(null);
|
||||
}
|
||||
}
|
||||
|
||||
return { stmtId, flags, iterationCount, values };
|
||||
}
|
||||
|
||||
toPacket() {
|
||||
// TODO: don't try to calculate packet length in advance, allocate some big buffer in advance (header + 256 bytes?)
|
||||
// and copy + reallocate if not enough
|
||||
// 0 + 4 - length, seqId
|
||||
// 4 + 1 - COM_EXECUTE
|
||||
// 5 + 4 - stmtId
|
||||
// 9 + 1 - flags
|
||||
// 10 + 4 - iteration-count (always 1)
|
||||
let length = 14;
|
||||
let parameters;
|
||||
if (this.parameters && this.parameters.length > 0) {
|
||||
length += Math.floor((this.parameters.length + 7) / 8);
|
||||
length += 1; // new-params-bound-flag
|
||||
length += 2 * this.parameters.length; // type byte for each parameter if new-params-bound-flag is set
|
||||
parameters = this.parameters.map((value) =>
|
||||
toParameter(value, this.encoding, this.timezone)
|
||||
);
|
||||
length += parameters.reduce(
|
||||
(accumulator, parameter) => accumulator + parameter.length,
|
||||
0
|
||||
);
|
||||
}
|
||||
const buffer = Buffer.allocUnsafe(length);
|
||||
const packet = new Packet(0, buffer, 0, length);
|
||||
packet.offset = 4;
|
||||
packet.writeInt8(CommandCodes.STMT_EXECUTE);
|
||||
packet.writeInt32(this.id);
|
||||
packet.writeInt8(CursorType.NO_CURSOR); // flags
|
||||
packet.writeInt32(1); // iteration-count, always 1
|
||||
if (parameters) {
|
||||
let bitmap = 0;
|
||||
let bitValue = 1;
|
||||
parameters.forEach((parameter) => {
|
||||
if (parameter.type === Types.NULL) {
|
||||
bitmap += bitValue;
|
||||
}
|
||||
bitValue *= 2;
|
||||
if (bitValue === 256) {
|
||||
packet.writeInt8(bitmap);
|
||||
bitmap = 0;
|
||||
bitValue = 1;
|
||||
}
|
||||
});
|
||||
if (bitValue !== 1) {
|
||||
packet.writeInt8(bitmap);
|
||||
}
|
||||
// TODO: explain meaning of the flag
|
||||
// afaik, if set n*2 bytes with type of parameter are sent before parameters
|
||||
// if not, previous execution types are used (TODO prooflink)
|
||||
packet.writeInt8(1); // new-params-bound-flag
|
||||
// Write parameter types
|
||||
parameters.forEach((parameter) => {
|
||||
packet.writeInt8(parameter.type); // field type
|
||||
packet.writeInt8(0); // parameter flag
|
||||
});
|
||||
// Write parameter values
|
||||
parameters.forEach((parameter) => {
|
||||
if (parameter.type !== Types.NULL) {
|
||||
parameter.writer.call(packet, parameter.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Execute;
|
112
login-auth_backend/node_modules/mysql2/lib/packets/handshake.js
generated
vendored
Normal file
112
login-auth_backend/node_modules/mysql2/lib/packets/handshake.js
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
'use strict';
|
||||
|
||||
const Packet = require('../packets/packet');
|
||||
const ClientConstants = require('../constants/client.js');
|
||||
|
||||
// https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake
|
||||
|
||||
class Handshake {
|
||||
constructor(args) {
|
||||
this.protocolVersion = args.protocolVersion;
|
||||
this.serverVersion = args.serverVersion;
|
||||
this.capabilityFlags = args.capabilityFlags;
|
||||
this.connectionId = args.connectionId;
|
||||
this.authPluginData1 = args.authPluginData1;
|
||||
this.authPluginData2 = args.authPluginData2;
|
||||
this.characterSet = args.characterSet;
|
||||
this.statusFlags = args.statusFlags;
|
||||
this.authPluginName = args.authPluginName;
|
||||
}
|
||||
|
||||
setScrambleData(cb) {
|
||||
require('crypto').randomBytes(20, (err, data) => {
|
||||
if (err) {
|
||||
cb(err);
|
||||
return;
|
||||
}
|
||||
this.authPluginData1 = data.slice(0, 8);
|
||||
this.authPluginData2 = data.slice(8, 20);
|
||||
cb();
|
||||
});
|
||||
}
|
||||
|
||||
toPacket(sequenceId) {
|
||||
const length = 68 + Buffer.byteLength(this.serverVersion, 'utf8');
|
||||
const buffer = Buffer.alloc(length + 4, 0); // zero fill, 10 bytes filler later needs to contain zeros
|
||||
const packet = new Packet(sequenceId, buffer, 0, length + 4);
|
||||
packet.offset = 4;
|
||||
packet.writeInt8(this.protocolVersion);
|
||||
packet.writeString(this.serverVersion, 'cesu8');
|
||||
packet.writeInt8(0);
|
||||
packet.writeInt32(this.connectionId);
|
||||
packet.writeBuffer(this.authPluginData1);
|
||||
packet.writeInt8(0);
|
||||
const capabilityFlagsBuffer = Buffer.allocUnsafe(4);
|
||||
capabilityFlagsBuffer.writeUInt32LE(this.capabilityFlags, 0);
|
||||
packet.writeBuffer(capabilityFlagsBuffer.slice(0, 2));
|
||||
packet.writeInt8(this.characterSet);
|
||||
packet.writeInt16(this.statusFlags);
|
||||
packet.writeBuffer(capabilityFlagsBuffer.slice(2, 4));
|
||||
packet.writeInt8(21); // authPluginDataLength
|
||||
packet.skip(10);
|
||||
packet.writeBuffer(this.authPluginData2);
|
||||
packet.writeInt8(0);
|
||||
packet.writeString('mysql_native_password', 'latin1');
|
||||
packet.writeInt8(0);
|
||||
return packet;
|
||||
}
|
||||
|
||||
static fromPacket(packet) {
|
||||
const args = {};
|
||||
args.protocolVersion = packet.readInt8();
|
||||
args.serverVersion = packet.readNullTerminatedString('cesu8');
|
||||
args.connectionId = packet.readInt32();
|
||||
args.authPluginData1 = packet.readBuffer(8);
|
||||
packet.skip(1);
|
||||
const capabilityFlagsBuffer = Buffer.allocUnsafe(4);
|
||||
capabilityFlagsBuffer[0] = packet.readInt8();
|
||||
capabilityFlagsBuffer[1] = packet.readInt8();
|
||||
if (packet.haveMoreData()) {
|
||||
args.characterSet = packet.readInt8();
|
||||
args.statusFlags = packet.readInt16();
|
||||
// upper 2 bytes
|
||||
capabilityFlagsBuffer[2] = packet.readInt8();
|
||||
capabilityFlagsBuffer[3] = packet.readInt8();
|
||||
args.capabilityFlags = capabilityFlagsBuffer.readUInt32LE(0);
|
||||
if (args.capabilityFlags & ClientConstants.PLUGIN_AUTH) {
|
||||
args.authPluginDataLength = packet.readInt8();
|
||||
} else {
|
||||
args.authPluginDataLength = 0;
|
||||
packet.skip(1);
|
||||
}
|
||||
packet.skip(10);
|
||||
} else {
|
||||
args.capabilityFlags = capabilityFlagsBuffer.readUInt16LE(0);
|
||||
}
|
||||
|
||||
const isSecureConnection =
|
||||
args.capabilityFlags & ClientConstants.SECURE_CONNECTION;
|
||||
if (isSecureConnection) {
|
||||
const authPluginDataLength = args.authPluginDataLength;
|
||||
if (authPluginDataLength === 0) {
|
||||
// for Secure Password Authentication
|
||||
args.authPluginDataLength = 20;
|
||||
args.authPluginData2 = packet.readBuffer(12);
|
||||
packet.skip(1);
|
||||
} else {
|
||||
// length > 0
|
||||
// for Custom Auth Plugin (PLUGIN_AUTH)
|
||||
const len = Math.max(13, authPluginDataLength - 8);
|
||||
args.authPluginData2 = packet.readBuffer(len);
|
||||
}
|
||||
}
|
||||
|
||||
if (args.capabilityFlags & ClientConstants.PLUGIN_AUTH) {
|
||||
args.authPluginName = packet.readNullTerminatedString('ascii');
|
||||
}
|
||||
|
||||
return new Handshake(args);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Handshake;
|
144
login-auth_backend/node_modules/mysql2/lib/packets/handshake_response.js
generated
vendored
Normal file
144
login-auth_backend/node_modules/mysql2/lib/packets/handshake_response.js
generated
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
'use strict';
|
||||
|
||||
const ClientConstants = require('../constants/client.js');
|
||||
const CharsetToEncoding = require('../constants/charset_encodings.js');
|
||||
const Packet = require('../packets/packet.js');
|
||||
|
||||
const auth41 = require('../auth_41.js');
|
||||
|
||||
class HandshakeResponse {
|
||||
constructor(handshake) {
|
||||
this.user = handshake.user || '';
|
||||
this.database = handshake.database || '';
|
||||
this.password = handshake.password || '';
|
||||
this.passwordSha1 = handshake.passwordSha1;
|
||||
this.authPluginData1 = handshake.authPluginData1;
|
||||
this.authPluginData2 = handshake.authPluginData2;
|
||||
this.compress = handshake.compress;
|
||||
this.clientFlags = handshake.flags;
|
||||
// TODO: pre-4.1 auth support
|
||||
let authToken;
|
||||
if (this.passwordSha1) {
|
||||
authToken = auth41.calculateTokenFromPasswordSha(
|
||||
this.passwordSha1,
|
||||
this.authPluginData1,
|
||||
this.authPluginData2
|
||||
);
|
||||
} else {
|
||||
authToken = auth41.calculateToken(
|
||||
this.password,
|
||||
this.authPluginData1,
|
||||
this.authPluginData2
|
||||
);
|
||||
}
|
||||
this.authToken = authToken;
|
||||
this.charsetNumber = handshake.charsetNumber;
|
||||
this.encoding = CharsetToEncoding[handshake.charsetNumber];
|
||||
this.connectAttributes = handshake.connectAttributes;
|
||||
}
|
||||
|
||||
serializeResponse(buffer) {
|
||||
const isSet = (flag) => this.clientFlags & ClientConstants[flag];
|
||||
const packet = new Packet(0, buffer, 0, buffer.length);
|
||||
packet.offset = 4;
|
||||
packet.writeInt32(this.clientFlags);
|
||||
packet.writeInt32(0); // max packet size. todo: move to config
|
||||
packet.writeInt8(this.charsetNumber);
|
||||
packet.skip(23);
|
||||
const encoding = this.encoding;
|
||||
packet.writeNullTerminatedString(this.user, encoding);
|
||||
let k;
|
||||
if (isSet('PLUGIN_AUTH_LENENC_CLIENT_DATA')) {
|
||||
packet.writeLengthCodedNumber(this.authToken.length);
|
||||
packet.writeBuffer(this.authToken);
|
||||
} else if (isSet('SECURE_CONNECTION')) {
|
||||
packet.writeInt8(this.authToken.length);
|
||||
packet.writeBuffer(this.authToken);
|
||||
} else {
|
||||
packet.writeBuffer(this.authToken);
|
||||
packet.writeInt8(0);
|
||||
}
|
||||
if (isSet('CONNECT_WITH_DB')) {
|
||||
packet.writeNullTerminatedString(this.database, encoding);
|
||||
}
|
||||
if (isSet('PLUGIN_AUTH')) {
|
||||
// TODO: pass from config
|
||||
packet.writeNullTerminatedString('mysql_native_password', 'latin1');
|
||||
}
|
||||
if (isSet('CONNECT_ATTRS')) {
|
||||
const connectAttributes = this.connectAttributes || {};
|
||||
const attrNames = Object.keys(connectAttributes);
|
||||
let keysLength = 0;
|
||||
for (k = 0; k < attrNames.length; ++k) {
|
||||
keysLength += Packet.lengthCodedStringLength(attrNames[k], encoding);
|
||||
keysLength += Packet.lengthCodedStringLength(
|
||||
connectAttributes[attrNames[k]],
|
||||
encoding
|
||||
);
|
||||
}
|
||||
packet.writeLengthCodedNumber(keysLength);
|
||||
for (k = 0; k < attrNames.length; ++k) {
|
||||
packet.writeLengthCodedString(attrNames[k], encoding);
|
||||
packet.writeLengthCodedString(
|
||||
connectAttributes[attrNames[k]],
|
||||
encoding
|
||||
);
|
||||
}
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
toPacket() {
|
||||
if (typeof this.user !== 'string') {
|
||||
throw new Error('"user" connection config property must be a string');
|
||||
}
|
||||
if (typeof this.database !== 'string') {
|
||||
throw new Error('"database" connection config property must be a string');
|
||||
}
|
||||
// dry run: calculate resulting packet length
|
||||
const p = this.serializeResponse(Packet.MockBuffer());
|
||||
return this.serializeResponse(Buffer.alloc(p.offset));
|
||||
}
|
||||
static fromPacket(packet) {
|
||||
const args = {};
|
||||
args.clientFlags = packet.readInt32();
|
||||
function isSet(flag) {
|
||||
return args.clientFlags & ClientConstants[flag];
|
||||
}
|
||||
args.maxPacketSize = packet.readInt32();
|
||||
args.charsetNumber = packet.readInt8();
|
||||
const encoding = CharsetToEncoding[args.charsetNumber];
|
||||
args.encoding = encoding;
|
||||
packet.skip(23);
|
||||
args.user = packet.readNullTerminatedString(encoding);
|
||||
let authTokenLength;
|
||||
if (isSet('PLUGIN_AUTH_LENENC_CLIENT_DATA')) {
|
||||
authTokenLength = packet.readLengthCodedNumber(encoding);
|
||||
args.authToken = packet.readBuffer(authTokenLength);
|
||||
} else if (isSet('SECURE_CONNECTION')) {
|
||||
authTokenLength = packet.readInt8();
|
||||
args.authToken = packet.readBuffer(authTokenLength);
|
||||
} else {
|
||||
args.authToken = packet.readNullTerminatedString(encoding);
|
||||
}
|
||||
if (isSet('CONNECT_WITH_DB')) {
|
||||
args.database = packet.readNullTerminatedString(encoding);
|
||||
}
|
||||
if (isSet('PLUGIN_AUTH')) {
|
||||
args.authPluginName = packet.readNullTerminatedString(encoding);
|
||||
}
|
||||
if (isSet('CONNECT_ATTRS')) {
|
||||
const keysLength = packet.readLengthCodedNumber(encoding);
|
||||
const keysEnd = packet.offset + keysLength;
|
||||
const attrs = {};
|
||||
while (packet.offset < keysEnd) {
|
||||
attrs[packet.readLengthCodedString(encoding)] =
|
||||
packet.readLengthCodedString(encoding);
|
||||
}
|
||||
args.connectAttributes = attrs;
|
||||
}
|
||||
return args;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = HandshakeResponse;
|
152
login-auth_backend/node_modules/mysql2/lib/packets/index.js
generated
vendored
Normal file
152
login-auth_backend/node_modules/mysql2/lib/packets/index.js
generated
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
// This file was modified by Oracle on June 1, 2021.
|
||||
// A utility method was introduced to generate an Error instance from a
|
||||
// binary server packet.
|
||||
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
|
||||
|
||||
// This file was modified by Oracle on September 21, 2021.
|
||||
// The new AuthNextFactor packet is now available.
|
||||
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
|
||||
|
||||
'use strict';
|
||||
|
||||
const process = require('process');
|
||||
|
||||
const AuthNextFactor = require('./auth_next_factor');
|
||||
const AuthSwitchRequest = require('./auth_switch_request');
|
||||
const AuthSwitchRequestMoreData = require('./auth_switch_request_more_data');
|
||||
const AuthSwitchResponse = require('./auth_switch_response');
|
||||
const BinaryRow = require('./binary_row');
|
||||
const BinlogDump = require('./binlog_dump');
|
||||
const ChangeUser = require('./change_user');
|
||||
const CloseStatement = require('./close_statement');
|
||||
const ColumnDefinition = require('./column_definition');
|
||||
const Execute = require('./execute');
|
||||
const Handshake = require('./handshake');
|
||||
const HandshakeResponse = require('./handshake_response');
|
||||
const PrepareStatement = require('./prepare_statement');
|
||||
const PreparedStatementHeader = require('./prepared_statement_header');
|
||||
const Query = require('./query');
|
||||
const RegisterSlave = require('./register_slave');
|
||||
const ResultSetHeader = require('./resultset_header');
|
||||
const SSLRequest = require('./ssl_request');
|
||||
const TextRow = require('./text_row');
|
||||
|
||||
const ctorMap = {
|
||||
AuthNextFactor,
|
||||
AuthSwitchRequest,
|
||||
AuthSwitchRequestMoreData,
|
||||
AuthSwitchResponse,
|
||||
BinaryRow,
|
||||
BinlogDump,
|
||||
ChangeUser,
|
||||
CloseStatement,
|
||||
ColumnDefinition,
|
||||
Execute,
|
||||
Handshake,
|
||||
HandshakeResponse,
|
||||
PrepareStatement,
|
||||
PreparedStatementHeader,
|
||||
Query,
|
||||
RegisterSlave,
|
||||
ResultSetHeader,
|
||||
SSLRequest,
|
||||
TextRow,
|
||||
};
|
||||
Object.entries(ctorMap).forEach(([name, ctor]) => {
|
||||
module.exports[name] = ctor;
|
||||
// monkey-patch it to include name if debug is on
|
||||
if (process.env.NODE_DEBUG) {
|
||||
if (ctor.prototype.toPacket) {
|
||||
const old = ctor.prototype.toPacket;
|
||||
ctor.prototype.toPacket = function () {
|
||||
const p = old.call(this);
|
||||
p._name = name;
|
||||
return p;
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// simple packets:
|
||||
const Packet = require('./packet');
|
||||
exports.Packet = Packet;
|
||||
|
||||
class OK {
|
||||
static toPacket(args, encoding) {
|
||||
args = args || {};
|
||||
const affectedRows = args.affectedRows || 0;
|
||||
const insertId = args.insertId || 0;
|
||||
const serverStatus = args.serverStatus || 0;
|
||||
const warningCount = args.warningCount || 0;
|
||||
const message = args.message || '';
|
||||
|
||||
let length = 9 + Packet.lengthCodedNumberLength(affectedRows);
|
||||
length += Packet.lengthCodedNumberLength(insertId);
|
||||
|
||||
const buffer = Buffer.allocUnsafe(length);
|
||||
const packet = new Packet(0, buffer, 0, length);
|
||||
packet.offset = 4;
|
||||
packet.writeInt8(0);
|
||||
packet.writeLengthCodedNumber(affectedRows);
|
||||
packet.writeLengthCodedNumber(insertId);
|
||||
packet.writeInt16(serverStatus);
|
||||
packet.writeInt16(warningCount);
|
||||
packet.writeString(message, encoding);
|
||||
packet._name = 'OK';
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
exports.OK = OK;
|
||||
|
||||
// warnings, statusFlags
|
||||
class EOF {
|
||||
static toPacket(warnings, statusFlags) {
|
||||
if (typeof warnings === 'undefined') {
|
||||
warnings = 0;
|
||||
}
|
||||
if (typeof statusFlags === 'undefined') {
|
||||
statusFlags = 0;
|
||||
}
|
||||
const packet = new Packet(0, Buffer.allocUnsafe(9), 0, 9);
|
||||
packet.offset = 4;
|
||||
packet.writeInt8(0xfe);
|
||||
packet.writeInt16(warnings);
|
||||
packet.writeInt16(statusFlags);
|
||||
packet._name = 'EOF';
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
exports.EOF = EOF;
|
||||
|
||||
class Error {
|
||||
static toPacket(args, encoding) {
|
||||
const length = 13 + Buffer.byteLength(args.message, 'utf8');
|
||||
const packet = new Packet(0, Buffer.allocUnsafe(length), 0, length);
|
||||
packet.offset = 4;
|
||||
packet.writeInt8(0xff);
|
||||
packet.writeInt16(args.code);
|
||||
// TODO: sql state parameter
|
||||
packet.writeString('#_____', encoding);
|
||||
packet.writeString(args.message, encoding);
|
||||
packet._name = 'Error';
|
||||
return packet;
|
||||
}
|
||||
|
||||
static fromPacket(packet) {
|
||||
packet.readInt8(); // marker
|
||||
const code = packet.readInt16();
|
||||
packet.readString(1, 'ascii'); // sql state marker
|
||||
// The SQL state of the ERR_Packet which is always 5 bytes long.
|
||||
// https://dev.mysql.com/doc/dev/mysql-server/8.0.11/page_protocol_basic_dt_strings.html#sect_protocol_basic_dt_string_fix
|
||||
packet.readString(5, 'ascii'); // sql state (ignore for now)
|
||||
const message = packet.readNullTerminatedString('utf8');
|
||||
const error = new Error();
|
||||
error.message = message;
|
||||
error.code = code;
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
exports.Error = Error;
|
931
login-auth_backend/node_modules/mysql2/lib/packets/packet.js
generated
vendored
Normal file
931
login-auth_backend/node_modules/mysql2/lib/packets/packet.js
generated
vendored
Normal file
@@ -0,0 +1,931 @@
|
||||
// This file was modified by Oracle on June 1, 2021.
|
||||
// A comment describing some changes in the strict default SQL mode regarding
|
||||
// non-standard dates was introduced.
|
||||
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
|
||||
|
||||
'use strict';
|
||||
|
||||
const ErrorCodeToName = require('../constants/errors.js');
|
||||
const NativeBuffer = require('buffer').Buffer;
|
||||
const Long = require('long');
|
||||
const StringParser = require('../parsers/string.js');
|
||||
const Types = require('../constants/types.js');
|
||||
const INVALID_DATE = new Date(NaN);
|
||||
|
||||
// this is nearly duplicate of previous function so generated code is not slower
|
||||
// due to "if (dateStrings)" branching
|
||||
const pad = '000000000000';
|
||||
function leftPad(num, value) {
|
||||
const s = value.toString();
|
||||
// if we don't need to pad
|
||||
if (s.length >= num) {
|
||||
return s;
|
||||
}
|
||||
return (pad + s).slice(-num);
|
||||
}
|
||||
|
||||
// The whole reason parse* function below exist
|
||||
// is because String creation is relatively expensive (at least with V8), and if we have
|
||||
// a buffer with "12345" content ideally we would like to bypass intermediate
|
||||
// "12345" string creation and directly build 12345 number out of
|
||||
// <Buffer 31 32 33 34 35> data.
|
||||
// In my benchmarks the difference is ~25M 8-digit numbers per second vs
|
||||
// 4.5 M using Number(packet.readLengthCodedString())
|
||||
// not used when size is close to max precision as series of *10 accumulate error
|
||||
// and approximate result mihgt be diffreent from (approximate as well) Number(bigNumStringValue))
|
||||
// In the futire node version if speed difference is smaller parse* functions might be removed
|
||||
// don't consider them as Packet public API
|
||||
|
||||
const minus = '-'.charCodeAt(0);
|
||||
const plus = '+'.charCodeAt(0);
|
||||
|
||||
// TODO: handle E notation
|
||||
const dot = '.'.charCodeAt(0);
|
||||
const exponent = 'e'.charCodeAt(0);
|
||||
const exponentCapital = 'E'.charCodeAt(0);
|
||||
|
||||
class Packet {
|
||||
constructor(id, buffer, start, end) {
|
||||
// hot path, enable checks when testing only
|
||||
// if (!Buffer.isBuffer(buffer) || typeof start == 'undefined' || typeof end == 'undefined')
|
||||
// throw new Error('invalid packet');
|
||||
this.sequenceId = id;
|
||||
this.numPackets = 1;
|
||||
this.buffer = buffer;
|
||||
this.start = start;
|
||||
this.offset = start + 4;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
// ==============================
|
||||
// readers
|
||||
// ==============================
|
||||
reset() {
|
||||
this.offset = this.start + 4;
|
||||
}
|
||||
|
||||
length() {
|
||||
return this.end - this.start;
|
||||
}
|
||||
|
||||
slice() {
|
||||
return this.buffer.slice(this.start, this.end);
|
||||
}
|
||||
|
||||
dump() {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(
|
||||
[this.buffer.asciiSlice(this.start, this.end)],
|
||||
this.buffer.slice(this.start, this.end),
|
||||
this.length(),
|
||||
this.sequenceId
|
||||
);
|
||||
}
|
||||
|
||||
haveMoreData() {
|
||||
return this.end > this.offset;
|
||||
}
|
||||
|
||||
skip(num) {
|
||||
this.offset += num;
|
||||
}
|
||||
|
||||
readInt8() {
|
||||
return this.buffer[this.offset++];
|
||||
}
|
||||
|
||||
readInt16() {
|
||||
this.offset += 2;
|
||||
return this.buffer.readUInt16LE(this.offset - 2);
|
||||
}
|
||||
|
||||
readInt24() {
|
||||
return this.readInt16() + (this.readInt8() << 16);
|
||||
}
|
||||
|
||||
readInt32() {
|
||||
this.offset += 4;
|
||||
return this.buffer.readUInt32LE(this.offset - 4);
|
||||
}
|
||||
|
||||
readSInt8() {
|
||||
return this.buffer.readInt8(this.offset++);
|
||||
}
|
||||
|
||||
readSInt16() {
|
||||
this.offset += 2;
|
||||
return this.buffer.readInt16LE(this.offset - 2);
|
||||
}
|
||||
|
||||
readSInt32() {
|
||||
this.offset += 4;
|
||||
return this.buffer.readInt32LE(this.offset - 4);
|
||||
}
|
||||
|
||||
readInt64JSNumber() {
|
||||
const word0 = this.readInt32();
|
||||
const word1 = this.readInt32();
|
||||
const l = new Long(word0, word1, true);
|
||||
return l.toNumber();
|
||||
}
|
||||
|
||||
readSInt64JSNumber() {
|
||||
const word0 = this.readInt32();
|
||||
const word1 = this.readInt32();
|
||||
if (!(word1 & 0x80000000)) {
|
||||
return word0 + 0x100000000 * word1;
|
||||
}
|
||||
const l = new Long(word0, word1, false);
|
||||
return l.toNumber();
|
||||
}
|
||||
|
||||
readInt64String() {
|
||||
const word0 = this.readInt32();
|
||||
const word1 = this.readInt32();
|
||||
const res = new Long(word0, word1, true);
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
readSInt64String() {
|
||||
const word0 = this.readInt32();
|
||||
const word1 = this.readInt32();
|
||||
const res = new Long(word0, word1, false);
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
readInt64() {
|
||||
const word0 = this.readInt32();
|
||||
const word1 = this.readInt32();
|
||||
let res = new Long(word0, word1, true);
|
||||
const resNumber = res.toNumber();
|
||||
const resString = res.toString();
|
||||
res = resNumber.toString() === resString ? resNumber : resString;
|
||||
return res;
|
||||
}
|
||||
|
||||
readSInt64() {
|
||||
const word0 = this.readInt32();
|
||||
const word1 = this.readInt32();
|
||||
let res = new Long(word0, word1, false);
|
||||
const resNumber = res.toNumber();
|
||||
const resString = res.toString();
|
||||
res = resNumber.toString() === resString ? resNumber : resString;
|
||||
return res;
|
||||
}
|
||||
|
||||
isEOF() {
|
||||
return this.buffer[this.offset] === 0xfe && this.length() < 13;
|
||||
}
|
||||
|
||||
eofStatusFlags() {
|
||||
return this.buffer.readInt16LE(this.offset + 3);
|
||||
}
|
||||
|
||||
eofWarningCount() {
|
||||
return this.buffer.readInt16LE(this.offset + 1);
|
||||
}
|
||||
|
||||
readLengthCodedNumber(bigNumberStrings, signed) {
|
||||
const byte1 = this.buffer[this.offset++];
|
||||
if (byte1 < 251) {
|
||||
return byte1;
|
||||
}
|
||||
return this.readLengthCodedNumberExt(byte1, bigNumberStrings, signed);
|
||||
}
|
||||
|
||||
readLengthCodedNumberSigned(bigNumberStrings) {
|
||||
return this.readLengthCodedNumber(bigNumberStrings, true);
|
||||
}
|
||||
|
||||
readLengthCodedNumberExt(tag, bigNumberStrings, signed) {
|
||||
let word0, word1;
|
||||
let res;
|
||||
if (tag === 0xfb) {
|
||||
return null;
|
||||
}
|
||||
if (tag === 0xfc) {
|
||||
return this.readInt8() + (this.readInt8() << 8);
|
||||
}
|
||||
if (tag === 0xfd) {
|
||||
return this.readInt8() + (this.readInt8() << 8) + (this.readInt8() << 16);
|
||||
}
|
||||
if (tag === 0xfe) {
|
||||
// TODO: check version
|
||||
// Up to MySQL 3.22, 0xfe was followed by a 4-byte integer.
|
||||
word0 = this.readInt32();
|
||||
word1 = this.readInt32();
|
||||
if (word1 === 0) {
|
||||
return word0; // don't convert to float if possible
|
||||
}
|
||||
if (word1 < 2097152) {
|
||||
// max exact float point int, 2^52 / 2^32
|
||||
return word1 * 0x100000000 + word0;
|
||||
}
|
||||
res = new Long(word0, word1, !signed); // Long need unsigned
|
||||
const resNumber = res.toNumber();
|
||||
const resString = res.toString();
|
||||
res = resNumber.toString() === resString ? resNumber : resString;
|
||||
return bigNumberStrings ? resString : res;
|
||||
}
|
||||
// eslint-disable-next-line no-console
|
||||
console.trace();
|
||||
throw new Error(`Should not reach here: ${tag}`);
|
||||
}
|
||||
|
||||
readFloat() {
|
||||
const res = this.buffer.readFloatLE(this.offset);
|
||||
this.offset += 4;
|
||||
return res;
|
||||
}
|
||||
|
||||
readDouble() {
|
||||
const res = this.buffer.readDoubleLE(this.offset);
|
||||
this.offset += 8;
|
||||
return res;
|
||||
}
|
||||
|
||||
readBuffer(len) {
|
||||
if (typeof len === 'undefined') {
|
||||
len = this.end - this.offset;
|
||||
}
|
||||
this.offset += len;
|
||||
return this.buffer.slice(this.offset - len, this.offset);
|
||||
}
|
||||
|
||||
// DATE, DATETIME and TIMESTAMP
|
||||
readDateTime(timezone) {
|
||||
if (!timezone || timezone === 'Z' || timezone === 'local') {
|
||||
const length = this.readInt8();
|
||||
if (length === 0xfb) {
|
||||
return null;
|
||||
}
|
||||
let y = 0;
|
||||
let m = 0;
|
||||
let d = 0;
|
||||
let H = 0;
|
||||
let M = 0;
|
||||
let S = 0;
|
||||
let ms = 0;
|
||||
if (length > 3) {
|
||||
y = this.readInt16();
|
||||
m = this.readInt8();
|
||||
d = this.readInt8();
|
||||
}
|
||||
if (length > 6) {
|
||||
H = this.readInt8();
|
||||
M = this.readInt8();
|
||||
S = this.readInt8();
|
||||
}
|
||||
if (length > 10) {
|
||||
ms = this.readInt32() / 1000;
|
||||
}
|
||||
// NO_ZERO_DATE mode and NO_ZERO_IN_DATE mode are part of the strict
|
||||
// default SQL mode used by MySQL 8.0. This means that non-standard
|
||||
// dates like '0000-00-00' become NULL. For older versions and other
|
||||
// possible MySQL flavours we still need to account for the
|
||||
// non-standard behaviour.
|
||||
if (y + m + d + H + M + S + ms === 0) {
|
||||
return INVALID_DATE;
|
||||
}
|
||||
if (timezone === 'Z') {
|
||||
return new Date(Date.UTC(y, m - 1, d, H, M, S, ms));
|
||||
}
|
||||
return new Date(y, m - 1, d, H, M, S, ms);
|
||||
}
|
||||
let str = this.readDateTimeString(6, 'T', null);
|
||||
if (str.length === 10) {
|
||||
str += 'T00:00:00';
|
||||
}
|
||||
return new Date(str + timezone);
|
||||
}
|
||||
|
||||
readDateTimeString(decimals, timeSep, columnType) {
|
||||
const length = this.readInt8();
|
||||
let y = 0;
|
||||
let m = 0;
|
||||
let d = 0;
|
||||
let H = 0;
|
||||
let M = 0;
|
||||
let S = 0;
|
||||
let ms = 0;
|
||||
let str;
|
||||
if (length > 3) {
|
||||
y = this.readInt16();
|
||||
m = this.readInt8();
|
||||
d = this.readInt8();
|
||||
str = [leftPad(4, y), leftPad(2, m), leftPad(2, d)].join('-');
|
||||
}
|
||||
if (length > 6) {
|
||||
H = this.readInt8();
|
||||
M = this.readInt8();
|
||||
S = this.readInt8();
|
||||
str += `${timeSep || ' '}${[
|
||||
leftPad(2, H),
|
||||
leftPad(2, M),
|
||||
leftPad(2, S),
|
||||
].join(':')}`;
|
||||
} else if (columnType === Types.DATETIME) {
|
||||
str += ' 00:00:00';
|
||||
}
|
||||
if (length > 10) {
|
||||
ms = this.readInt32();
|
||||
str += '.';
|
||||
if (decimals) {
|
||||
ms = leftPad(6, ms);
|
||||
if (ms.length > decimals) {
|
||||
ms = ms.substring(0, decimals); // rounding is done at the MySQL side, only 0 are here
|
||||
}
|
||||
}
|
||||
str += ms;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
// TIME - value as a string, Can be negative
|
||||
readTimeString(convertTtoMs) {
|
||||
const length = this.readInt8();
|
||||
if (length === 0) {
|
||||
return '00:00:00';
|
||||
}
|
||||
const sign = this.readInt8() ? -1 : 1; // 'isNegative' flag byte
|
||||
let d = 0;
|
||||
let H = 0;
|
||||
let M = 0;
|
||||
let S = 0;
|
||||
let ms = 0;
|
||||
if (length > 6) {
|
||||
d = this.readInt32();
|
||||
H = this.readInt8();
|
||||
M = this.readInt8();
|
||||
S = this.readInt8();
|
||||
}
|
||||
if (length > 10) {
|
||||
ms = this.readInt32();
|
||||
}
|
||||
if (convertTtoMs) {
|
||||
H += d * 24;
|
||||
M += H * 60;
|
||||
S += M * 60;
|
||||
ms += S * 1000;
|
||||
ms *= sign;
|
||||
return ms;
|
||||
}
|
||||
// Format follows mySQL TIME format ([-][h]hh:mm:ss[.u[u[u[u[u[u]]]]]])
|
||||
// For positive times below 24 hours, this makes it equal to ISO 8601 times
|
||||
return (
|
||||
(sign === -1 ? '-' : '') +
|
||||
[leftPad(2, d * 24 + H), leftPad(2, M), leftPad(2, S)].join(':') +
|
||||
(ms ? `.${ms}`.replace(/0+$/, '') : '')
|
||||
);
|
||||
}
|
||||
|
||||
readLengthCodedString(encoding) {
|
||||
const len = this.readLengthCodedNumber();
|
||||
// TODO: check manually first byte here to avoid polymorphic return type?
|
||||
if (len === null) {
|
||||
return null;
|
||||
}
|
||||
this.offset += len;
|
||||
// TODO: Use characterSetCode to get proper encoding
|
||||
// https://github.com/sidorares/node-mysql2/pull/374
|
||||
return StringParser.decode(
|
||||
this.buffer,
|
||||
encoding,
|
||||
this.offset - len,
|
||||
this.offset
|
||||
);
|
||||
}
|
||||
|
||||
readLengthCodedBuffer() {
|
||||
const len = this.readLengthCodedNumber();
|
||||
if (len === null) {
|
||||
return null;
|
||||
}
|
||||
return this.readBuffer(len);
|
||||
}
|
||||
|
||||
readNullTerminatedString(encoding) {
|
||||
const start = this.offset;
|
||||
let end = this.offset;
|
||||
while (this.buffer[end]) {
|
||||
end = end + 1; // TODO: handle OOB check
|
||||
}
|
||||
this.offset = end + 1;
|
||||
return StringParser.decode(this.buffer, encoding, start, end);
|
||||
}
|
||||
|
||||
// TODO reuse?
|
||||
readString(len, encoding) {
|
||||
if (typeof len === 'string' && typeof encoding === 'undefined') {
|
||||
encoding = len;
|
||||
len = undefined;
|
||||
}
|
||||
if (typeof len === 'undefined') {
|
||||
len = this.end - this.offset;
|
||||
}
|
||||
this.offset += len;
|
||||
return StringParser.decode(
|
||||
this.buffer,
|
||||
encoding,
|
||||
this.offset - len,
|
||||
this.offset
|
||||
);
|
||||
}
|
||||
|
||||
parseInt(len, supportBigNumbers) {
|
||||
if (len === null) {
|
||||
return null;
|
||||
}
|
||||
if (len >= 14 && !supportBigNumbers) {
|
||||
const s = this.buffer.toString('ascii', this.offset, this.offset + len);
|
||||
this.offset += len;
|
||||
return Number(s);
|
||||
}
|
||||
let result = 0;
|
||||
const start = this.offset;
|
||||
const end = this.offset + len;
|
||||
let sign = 1;
|
||||
if (len === 0) {
|
||||
return 0; // TODO: assert? exception?
|
||||
}
|
||||
if (this.buffer[this.offset] === minus) {
|
||||
this.offset++;
|
||||
sign = -1;
|
||||
}
|
||||
// max precise int is 9007199254740992
|
||||
let str;
|
||||
const numDigits = end - this.offset;
|
||||
if (supportBigNumbers) {
|
||||
if (numDigits >= 15) {
|
||||
str = this.readString(end - this.offset, 'binary');
|
||||
result = parseInt(str, 10);
|
||||
if (result.toString() === str) {
|
||||
return sign * result;
|
||||
}
|
||||
return sign === -1 ? `-${str}` : str;
|
||||
}
|
||||
if (numDigits > 16) {
|
||||
str = this.readString(end - this.offset);
|
||||
return sign === -1 ? `-${str}` : str;
|
||||
}
|
||||
}
|
||||
if (this.buffer[this.offset] === plus) {
|
||||
this.offset++; // just ignore
|
||||
}
|
||||
while (this.offset < end) {
|
||||
result *= 10;
|
||||
result += this.buffer[this.offset] - 48;
|
||||
this.offset++;
|
||||
}
|
||||
const num = result * sign;
|
||||
if (!supportBigNumbers) {
|
||||
return num;
|
||||
}
|
||||
str = this.buffer.toString('ascii', start, end);
|
||||
if (num.toString() === str) {
|
||||
return num;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
// note that if value of inputNumberAsString is bigger than MAX_SAFE_INTEGER
|
||||
// ( or smaller than MIN_SAFE_INTEGER ) the parseIntNoBigCheck result might be
|
||||
// different from what you would get from Number(inputNumberAsString)
|
||||
// String(parseIntNoBigCheck) <> String(Number(inputNumberAsString)) <> inputNumberAsString
|
||||
parseIntNoBigCheck(len) {
|
||||
if (len === null) {
|
||||
return null;
|
||||
}
|
||||
let result = 0;
|
||||
const end = this.offset + len;
|
||||
let sign = 1;
|
||||
if (len === 0) {
|
||||
return 0; // TODO: assert? exception?
|
||||
}
|
||||
if (this.buffer[this.offset] === minus) {
|
||||
this.offset++;
|
||||
sign = -1;
|
||||
}
|
||||
if (this.buffer[this.offset] === plus) {
|
||||
this.offset++; // just ignore
|
||||
}
|
||||
while (this.offset < end) {
|
||||
result *= 10;
|
||||
result += this.buffer[this.offset] - 48;
|
||||
this.offset++;
|
||||
}
|
||||
return result * sign;
|
||||
}
|
||||
|
||||
// copy-paste from https://github.com/mysqljs/mysql/blob/master/lib/protocol/Parser.js
|
||||
parseGeometryValue() {
|
||||
const buffer = this.readLengthCodedBuffer();
|
||||
let offset = 4;
|
||||
if (buffer === null || !buffer.length) {
|
||||
return null;
|
||||
}
|
||||
function parseGeometry() {
|
||||
let x, y, i, j, numPoints, line;
|
||||
let result = null;
|
||||
const byteOrder = buffer.readUInt8(offset);
|
||||
offset += 1;
|
||||
const wkbType = byteOrder
|
||||
? buffer.readUInt32LE(offset)
|
||||
: buffer.readUInt32BE(offset);
|
||||
offset += 4;
|
||||
switch (wkbType) {
|
||||
case 1: // WKBPoint
|
||||
x = byteOrder
|
||||
? buffer.readDoubleLE(offset)
|
||||
: buffer.readDoubleBE(offset);
|
||||
offset += 8;
|
||||
y = byteOrder
|
||||
? buffer.readDoubleLE(offset)
|
||||
: buffer.readDoubleBE(offset);
|
||||
offset += 8;
|
||||
result = { x: x, y: y };
|
||||
break;
|
||||
case 2: // WKBLineString
|
||||
numPoints = byteOrder
|
||||
? buffer.readUInt32LE(offset)
|
||||
: buffer.readUInt32BE(offset);
|
||||
offset += 4;
|
||||
result = [];
|
||||
for (i = numPoints; i > 0; i--) {
|
||||
x = byteOrder
|
||||
? buffer.readDoubleLE(offset)
|
||||
: buffer.readDoubleBE(offset);
|
||||
offset += 8;
|
||||
y = byteOrder
|
||||
? buffer.readDoubleLE(offset)
|
||||
: buffer.readDoubleBE(offset);
|
||||
offset += 8;
|
||||
result.push({ x: x, y: y });
|
||||
}
|
||||
break;
|
||||
case 3: // WKBPolygon
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
const numRings = byteOrder
|
||||
? buffer.readUInt32LE(offset)
|
||||
: buffer.readUInt32BE(offset);
|
||||
offset += 4;
|
||||
result = [];
|
||||
for (i = numRings; i > 0; i--) {
|
||||
numPoints = byteOrder
|
||||
? buffer.readUInt32LE(offset)
|
||||
: buffer.readUInt32BE(offset);
|
||||
offset += 4;
|
||||
line = [];
|
||||
for (j = numPoints; j > 0; j--) {
|
||||
x = byteOrder
|
||||
? buffer.readDoubleLE(offset)
|
||||
: buffer.readDoubleBE(offset);
|
||||
offset += 8;
|
||||
y = byteOrder
|
||||
? buffer.readDoubleLE(offset)
|
||||
: buffer.readDoubleBE(offset);
|
||||
offset += 8;
|
||||
line.push({ x: x, y: y });
|
||||
}
|
||||
result.push(line);
|
||||
}
|
||||
break;
|
||||
case 4: // WKBMultiPoint
|
||||
case 5: // WKBMultiLineString
|
||||
case 6: // WKBMultiPolygon
|
||||
case 7: // WKBGeometryCollection
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
const num = byteOrder
|
||||
? buffer.readUInt32LE(offset)
|
||||
: buffer.readUInt32BE(offset);
|
||||
offset += 4;
|
||||
result = [];
|
||||
for (i = num; i > 0; i--) {
|
||||
result.push(parseGeometry());
|
||||
}
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return parseGeometry();
|
||||
}
|
||||
|
||||
parseVector() {
|
||||
const bufLen = this.readLengthCodedNumber();
|
||||
const vectorEnd = this.offset + bufLen;
|
||||
const result = [];
|
||||
while (this.offset < vectorEnd && this.offset < this.end) {
|
||||
result.push(this.readFloat());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
parseDate(timezone) {
|
||||
const strLen = this.readLengthCodedNumber();
|
||||
if (strLen === null) {
|
||||
return null;
|
||||
}
|
||||
if (strLen !== 10) {
|
||||
// we expect only YYYY-MM-DD here.
|
||||
// if for some reason it's not the case return invalid date
|
||||
return new Date(NaN);
|
||||
}
|
||||
const y = this.parseInt(4);
|
||||
this.offset++; // -
|
||||
const m = this.parseInt(2);
|
||||
this.offset++; // -
|
||||
const d = this.parseInt(2);
|
||||
if (!timezone || timezone === 'local') {
|
||||
return new Date(y, m - 1, d);
|
||||
}
|
||||
if (timezone === 'Z') {
|
||||
return new Date(Date.UTC(y, m - 1, d));
|
||||
}
|
||||
return new Date(
|
||||
`${leftPad(4, y)}-${leftPad(2, m)}-${leftPad(2, d)}T00:00:00${timezone}`
|
||||
);
|
||||
}
|
||||
|
||||
parseDateTime(timezone) {
|
||||
const str = this.readLengthCodedString('binary');
|
||||
if (str === null) {
|
||||
return null;
|
||||
}
|
||||
if (!timezone || timezone === 'local') {
|
||||
return new Date(str);
|
||||
}
|
||||
return new Date(`${str}${timezone}`);
|
||||
}
|
||||
|
||||
parseFloat(len) {
|
||||
if (len === null) {
|
||||
return null;
|
||||
}
|
||||
let result = 0;
|
||||
const end = this.offset + len;
|
||||
let factor = 1;
|
||||
let pastDot = false;
|
||||
let charCode = 0;
|
||||
if (len === 0) {
|
||||
return 0; // TODO: assert? exception?
|
||||
}
|
||||
if (this.buffer[this.offset] === minus) {
|
||||
this.offset++;
|
||||
factor = -1;
|
||||
}
|
||||
if (this.buffer[this.offset] === plus) {
|
||||
this.offset++; // just ignore
|
||||
}
|
||||
while (this.offset < end) {
|
||||
charCode = this.buffer[this.offset];
|
||||
if (charCode === dot) {
|
||||
pastDot = true;
|
||||
this.offset++;
|
||||
} else if (charCode === exponent || charCode === exponentCapital) {
|
||||
this.offset++;
|
||||
const exponentValue = this.parseInt(end - this.offset);
|
||||
return (result / factor) * Math.pow(10, exponentValue);
|
||||
} else {
|
||||
result *= 10;
|
||||
result += this.buffer[this.offset] - 48;
|
||||
this.offset++;
|
||||
if (pastDot) {
|
||||
factor = factor * 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result / factor;
|
||||
}
|
||||
|
||||
parseLengthCodedIntNoBigCheck() {
|
||||
return this.parseIntNoBigCheck(this.readLengthCodedNumber());
|
||||
}
|
||||
|
||||
parseLengthCodedInt(supportBigNumbers) {
|
||||
return this.parseInt(this.readLengthCodedNumber(), supportBigNumbers);
|
||||
}
|
||||
|
||||
parseLengthCodedIntString() {
|
||||
return this.readLengthCodedString('binary');
|
||||
}
|
||||
|
||||
parseLengthCodedFloat() {
|
||||
return this.parseFloat(this.readLengthCodedNumber());
|
||||
}
|
||||
|
||||
peekByte() {
|
||||
return this.buffer[this.offset];
|
||||
}
|
||||
|
||||
// OxFE is often used as "Alt" flag - not ok, not error.
|
||||
// For example, it's first byte of AuthSwitchRequest
|
||||
isAlt() {
|
||||
return this.peekByte() === 0xfe;
|
||||
}
|
||||
|
||||
isError() {
|
||||
return this.peekByte() === 0xff;
|
||||
}
|
||||
|
||||
asError(encoding) {
|
||||
this.reset();
|
||||
this.readInt8(); // fieldCount
|
||||
const errorCode = this.readInt16();
|
||||
let sqlState = '';
|
||||
if (this.buffer[this.offset] === 0x23) {
|
||||
this.skip(1);
|
||||
sqlState = this.readBuffer(5).toString();
|
||||
}
|
||||
const message = this.readString(undefined, encoding);
|
||||
const err = new Error(message);
|
||||
err.code = ErrorCodeToName[errorCode];
|
||||
err.errno = errorCode;
|
||||
err.sqlState = sqlState;
|
||||
err.sqlMessage = message;
|
||||
return err;
|
||||
}
|
||||
|
||||
writeInt32(n) {
|
||||
this.buffer.writeUInt32LE(n, this.offset);
|
||||
this.offset += 4;
|
||||
}
|
||||
|
||||
writeInt24(n) {
|
||||
this.writeInt8(n & 0xff);
|
||||
this.writeInt16(n >> 8);
|
||||
}
|
||||
|
||||
writeInt16(n) {
|
||||
this.buffer.writeUInt16LE(n, this.offset);
|
||||
this.offset += 2;
|
||||
}
|
||||
|
||||
writeInt8(n) {
|
||||
this.buffer.writeUInt8(n, this.offset);
|
||||
this.offset++;
|
||||
}
|
||||
|
||||
writeDouble(n) {
|
||||
this.buffer.writeDoubleLE(n, this.offset);
|
||||
this.offset += 8;
|
||||
}
|
||||
|
||||
writeBuffer(b) {
|
||||
b.copy(this.buffer, this.offset);
|
||||
this.offset += b.length;
|
||||
}
|
||||
|
||||
writeNull() {
|
||||
this.buffer[this.offset] = 0xfb;
|
||||
this.offset++;
|
||||
}
|
||||
|
||||
// TODO: refactor following three?
|
||||
writeNullTerminatedString(s, encoding) {
|
||||
const buf = StringParser.encode(s, encoding);
|
||||
this.buffer.length && buf.copy(this.buffer, this.offset);
|
||||
this.offset += buf.length;
|
||||
this.writeInt8(0);
|
||||
}
|
||||
|
||||
writeString(s, encoding) {
|
||||
if (s === null) {
|
||||
this.writeInt8(0xfb);
|
||||
return;
|
||||
}
|
||||
if (s.length === 0) {
|
||||
return;
|
||||
}
|
||||
// const bytes = Buffer.byteLength(s, 'utf8');
|
||||
// this.buffer.write(s, this.offset, bytes, 'utf8');
|
||||
// this.offset += bytes;
|
||||
const buf = StringParser.encode(s, encoding);
|
||||
this.buffer.length && buf.copy(this.buffer, this.offset);
|
||||
this.offset += buf.length;
|
||||
}
|
||||
|
||||
writeLengthCodedString(s, encoding) {
|
||||
const buf = StringParser.encode(s, encoding);
|
||||
this.writeLengthCodedNumber(buf.length);
|
||||
this.buffer.length && buf.copy(this.buffer, this.offset);
|
||||
this.offset += buf.length;
|
||||
}
|
||||
|
||||
writeLengthCodedBuffer(b) {
|
||||
this.writeLengthCodedNumber(b.length);
|
||||
b.copy(this.buffer, this.offset);
|
||||
this.offset += b.length;
|
||||
}
|
||||
|
||||
writeLengthCodedNumber(n) {
|
||||
if (n < 0xfb) {
|
||||
return this.writeInt8(n);
|
||||
}
|
||||
if (n < 0xffff) {
|
||||
this.writeInt8(0xfc);
|
||||
return this.writeInt16(n);
|
||||
}
|
||||
if (n < 0xffffff) {
|
||||
this.writeInt8(0xfd);
|
||||
return this.writeInt24(n);
|
||||
}
|
||||
if (n === null) {
|
||||
return this.writeInt8(0xfb);
|
||||
}
|
||||
// TODO: check that n is out of int precision
|
||||
this.writeInt8(0xfe);
|
||||
this.buffer.writeUInt32LE(n, this.offset);
|
||||
this.offset += 4;
|
||||
this.buffer.writeUInt32LE(n >> 32, this.offset);
|
||||
this.offset += 4;
|
||||
return this.offset;
|
||||
}
|
||||
|
||||
writeDate(d, timezone) {
|
||||
this.buffer.writeUInt8(11, this.offset);
|
||||
if (!timezone || timezone === 'local') {
|
||||
this.buffer.writeUInt16LE(d.getFullYear(), this.offset + 1);
|
||||
this.buffer.writeUInt8(d.getMonth() + 1, this.offset + 3);
|
||||
this.buffer.writeUInt8(d.getDate(), this.offset + 4);
|
||||
this.buffer.writeUInt8(d.getHours(), this.offset + 5);
|
||||
this.buffer.writeUInt8(d.getMinutes(), this.offset + 6);
|
||||
this.buffer.writeUInt8(d.getSeconds(), this.offset + 7);
|
||||
this.buffer.writeUInt32LE(d.getMilliseconds() * 1000, this.offset + 8);
|
||||
} else {
|
||||
if (timezone !== 'Z') {
|
||||
const offset =
|
||||
(timezone[0] === '-' ? -1 : 1) *
|
||||
(parseInt(timezone.substring(1, 3), 10) * 60 +
|
||||
parseInt(timezone.substring(4), 10));
|
||||
if (offset !== 0) {
|
||||
d = new Date(d.getTime() + 60000 * offset);
|
||||
}
|
||||
}
|
||||
this.buffer.writeUInt16LE(d.getUTCFullYear(), this.offset + 1);
|
||||
this.buffer.writeUInt8(d.getUTCMonth() + 1, this.offset + 3);
|
||||
this.buffer.writeUInt8(d.getUTCDate(), this.offset + 4);
|
||||
this.buffer.writeUInt8(d.getUTCHours(), this.offset + 5);
|
||||
this.buffer.writeUInt8(d.getUTCMinutes(), this.offset + 6);
|
||||
this.buffer.writeUInt8(d.getUTCSeconds(), this.offset + 7);
|
||||
this.buffer.writeUInt32LE(d.getUTCMilliseconds() * 1000, this.offset + 8);
|
||||
}
|
||||
this.offset += 12;
|
||||
}
|
||||
|
||||
writeHeader(sequenceId) {
|
||||
const offset = this.offset;
|
||||
this.offset = 0;
|
||||
this.writeInt24(this.buffer.length - 4);
|
||||
this.writeInt8(sequenceId);
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new Packet(this.sequenceId, this.buffer, this.start, this.end);
|
||||
}
|
||||
|
||||
type() {
|
||||
if (this.isEOF()) {
|
||||
return 'EOF';
|
||||
}
|
||||
if (this.isError()) {
|
||||
return 'Error';
|
||||
}
|
||||
if (this.buffer[this.offset] === 0) {
|
||||
return 'maybeOK'; // could be other packet types as well
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
static lengthCodedNumberLength(n) {
|
||||
if (n < 0xfb) {
|
||||
return 1;
|
||||
}
|
||||
if (n < 0xffff) {
|
||||
return 3;
|
||||
}
|
||||
if (n < 0xffffff) {
|
||||
return 5;
|
||||
}
|
||||
return 9;
|
||||
}
|
||||
|
||||
static lengthCodedStringLength(str, encoding) {
|
||||
const buf = StringParser.encode(str, encoding);
|
||||
const slen = buf.length;
|
||||
return Packet.lengthCodedNumberLength(slen) + slen;
|
||||
}
|
||||
|
||||
static MockBuffer() {
|
||||
const noop = function () {};
|
||||
const res = Buffer.alloc(0);
|
||||
for (const op in NativeBuffer.prototype) {
|
||||
if (typeof res[op] === 'function') {
|
||||
res[op] = noop;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Packet;
|
27
login-auth_backend/node_modules/mysql2/lib/packets/prepare_statement.js
generated
vendored
Normal file
27
login-auth_backend/node_modules/mysql2/lib/packets/prepare_statement.js
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
'use strict';
|
||||
|
||||
const Packet = require('../packets/packet');
|
||||
const CommandCodes = require('../constants/commands');
|
||||
const StringParser = require('../parsers/string.js');
|
||||
const CharsetToEncoding = require('../constants/charset_encodings.js');
|
||||
|
||||
class PrepareStatement {
|
||||
constructor(sql, charsetNumber) {
|
||||
this.query = sql;
|
||||
this.charsetNumber = charsetNumber;
|
||||
this.encoding = CharsetToEncoding[charsetNumber];
|
||||
}
|
||||
|
||||
toPacket() {
|
||||
const buf = StringParser.encode(this.query, this.encoding);
|
||||
const length = 5 + buf.length;
|
||||
const buffer = Buffer.allocUnsafe(length);
|
||||
const packet = new Packet(0, buffer, 0, length);
|
||||
packet.offset = 4;
|
||||
packet.writeInt8(CommandCodes.STMT_PREPARE);
|
||||
packet.writeBuffer(buf);
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PrepareStatement;
|
16
login-auth_backend/node_modules/mysql2/lib/packets/prepared_statement_header.js
generated
vendored
Normal file
16
login-auth_backend/node_modules/mysql2/lib/packets/prepared_statement_header.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
class PreparedStatementHeader {
|
||||
constructor(packet) {
|
||||
packet.skip(1); // should be 0
|
||||
this.id = packet.readInt32();
|
||||
this.fieldCount = packet.readInt16();
|
||||
this.parameterCount = packet.readInt16();
|
||||
packet.skip(1); // should be 0
|
||||
this.warningCount = packet.readInt16();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: toPacket
|
||||
|
||||
module.exports = PreparedStatementHeader;
|
27
login-auth_backend/node_modules/mysql2/lib/packets/query.js
generated
vendored
Normal file
27
login-auth_backend/node_modules/mysql2/lib/packets/query.js
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
'use strict';
|
||||
|
||||
const Packet = require('../packets/packet.js');
|
||||
const CommandCode = require('../constants/commands.js');
|
||||
const StringParser = require('../parsers/string.js');
|
||||
const CharsetToEncoding = require('../constants/charset_encodings.js');
|
||||
|
||||
class Query {
|
||||
constructor(sql, charsetNumber) {
|
||||
this.query = sql;
|
||||
this.charsetNumber = charsetNumber;
|
||||
this.encoding = CharsetToEncoding[charsetNumber];
|
||||
}
|
||||
|
||||
toPacket() {
|
||||
const buf = StringParser.encode(this.query, this.encoding);
|
||||
const length = 5 + buf.length;
|
||||
const buffer = Buffer.allocUnsafe(length);
|
||||
const packet = new Packet(0, buffer, 0, length);
|
||||
packet.offset = 4;
|
||||
packet.writeInt8(CommandCode.QUERY);
|
||||
packet.writeBuffer(buf);
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Query;
|
46
login-auth_backend/node_modules/mysql2/lib/packets/register_slave.js
generated
vendored
Normal file
46
login-auth_backend/node_modules/mysql2/lib/packets/register_slave.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
'use strict';
|
||||
|
||||
// http://dev.mysql.com/doc/internals/en/com-register-slave.html
|
||||
// note that documentation is incorrect, for example command code is actually 0x15 but documented as 0x14
|
||||
|
||||
const Packet = require('../packets/packet');
|
||||
const CommandCodes = require('../constants/commands');
|
||||
|
||||
class RegisterSlave {
|
||||
constructor(opts) {
|
||||
this.serverId = opts.serverId || 0;
|
||||
this.slaveHostname = opts.slaveHostname || '';
|
||||
this.slaveUser = opts.slaveUser || '';
|
||||
this.slavePassword = opts.slavePassword || '';
|
||||
this.slavePort = opts.slavePort || 0;
|
||||
this.replicationRank = opts.replicationRank || 0;
|
||||
this.masterId = opts.masterId || 0;
|
||||
}
|
||||
|
||||
toPacket() {
|
||||
const length =
|
||||
15 + // TODO: should be ascii?
|
||||
Buffer.byteLength(this.slaveHostname, 'utf8') +
|
||||
Buffer.byteLength(this.slaveUser, 'utf8') +
|
||||
Buffer.byteLength(this.slavePassword, 'utf8') +
|
||||
3 +
|
||||
4;
|
||||
const buffer = Buffer.allocUnsafe(length);
|
||||
const packet = new Packet(0, buffer, 0, length);
|
||||
packet.offset = 4;
|
||||
packet.writeInt8(CommandCodes.REGISTER_SLAVE);
|
||||
packet.writeInt32(this.serverId);
|
||||
packet.writeInt8(Buffer.byteLength(this.slaveHostname, 'utf8'));
|
||||
packet.writeString(this.slaveHostname);
|
||||
packet.writeInt8(Buffer.byteLength(this.slaveUser, 'utf8'));
|
||||
packet.writeString(this.slaveUser);
|
||||
packet.writeInt8(Buffer.byteLength(this.slavePassword, 'utf8'));
|
||||
packet.writeString(this.slavePassword);
|
||||
packet.writeInt16(this.slavePort);
|
||||
packet.writeInt32(this.replicationRank);
|
||||
packet.writeInt32(this.masterId);
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RegisterSlave;
|
124
login-auth_backend/node_modules/mysql2/lib/packets/resultset_header.js
generated
vendored
Normal file
124
login-auth_backend/node_modules/mysql2/lib/packets/resultset_header.js
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
'use strict';
|
||||
|
||||
// TODO: rename to OK packet
|
||||
// https://dev.mysql.com/doc/internals/en/packet-OK_Packet.html
|
||||
|
||||
const Packet = require('./packet.js');
|
||||
const ClientConstants = require('../constants/client.js');
|
||||
const ServerSatusFlags = require('../constants/server_status.js');
|
||||
|
||||
const EncodingToCharset = require('../constants/encoding_charset.js');
|
||||
const sessionInfoTypes = require('../constants/session_track.js');
|
||||
|
||||
class ResultSetHeader {
|
||||
constructor(packet, connection) {
|
||||
const bigNumberStrings = connection.config.bigNumberStrings;
|
||||
const encoding = connection.serverEncoding;
|
||||
const flags = connection._handshakePacket.capabilityFlags;
|
||||
const isSet = function (flag) {
|
||||
return flags & ClientConstants[flag];
|
||||
};
|
||||
if (packet.buffer[packet.offset] !== 0) {
|
||||
this.fieldCount = packet.readLengthCodedNumber();
|
||||
if (this.fieldCount === null) {
|
||||
this.infileName = packet.readString(undefined, encoding);
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.fieldCount = packet.readInt8(); // skip OK byte
|
||||
this.affectedRows = packet.readLengthCodedNumber(bigNumberStrings);
|
||||
this.insertId = packet.readLengthCodedNumberSigned(bigNumberStrings);
|
||||
this.info = '';
|
||||
if (isSet('PROTOCOL_41')) {
|
||||
this.serverStatus = packet.readInt16();
|
||||
this.warningStatus = packet.readInt16();
|
||||
} else if (isSet('TRANSACTIONS')) {
|
||||
this.serverStatus = packet.readInt16();
|
||||
}
|
||||
let stateChanges = null;
|
||||
if (isSet('SESSION_TRACK') && packet.offset < packet.end) {
|
||||
this.info = packet.readLengthCodedString(encoding);
|
||||
|
||||
if (this.serverStatus && ServerSatusFlags.SERVER_SESSION_STATE_CHANGED) {
|
||||
// session change info record - see
|
||||
// https://dev.mysql.com/doc/internals/en/packet-OK_Packet.html#cs-sect-packet-ok-sessioninfo
|
||||
let len =
|
||||
packet.offset < packet.end ? packet.readLengthCodedNumber() : 0;
|
||||
const end = packet.offset + len;
|
||||
let type, key, stateEnd;
|
||||
if (len > 0) {
|
||||
stateChanges = {
|
||||
systemVariables: {},
|
||||
schema: null,
|
||||
gtids: [],
|
||||
trackStateChange: null,
|
||||
};
|
||||
}
|
||||
while (packet.offset < end) {
|
||||
type = packet.readInt8();
|
||||
len = packet.readLengthCodedNumber();
|
||||
stateEnd = packet.offset + len;
|
||||
if (type === sessionInfoTypes.SYSTEM_VARIABLES) {
|
||||
key = packet.readLengthCodedString(encoding);
|
||||
const val = packet.readLengthCodedString(encoding);
|
||||
stateChanges.systemVariables[key] = val;
|
||||
if (key === 'character_set_client') {
|
||||
const charsetNumber = EncodingToCharset[val];
|
||||
// TODO - better api for driver users to handle unknown encodings?
|
||||
// maybe custom coverter in the config?
|
||||
// For now just ignore character_set_client command if there is
|
||||
// no known mapping from reported encoding to a charset code
|
||||
if (typeof charsetNumber !== 'undefined') {
|
||||
connection.config.charsetNumber = charsetNumber;
|
||||
}
|
||||
}
|
||||
} else if (type === sessionInfoTypes.SCHEMA) {
|
||||
key = packet.readLengthCodedString(encoding);
|
||||
stateChanges.schema = key;
|
||||
} else if (type === sessionInfoTypes.STATE_CHANGE) {
|
||||
stateChanges.trackStateChange =
|
||||
packet.readLengthCodedString(encoding);
|
||||
} else if (type === sessionInfoTypes.STATE_GTIDS) {
|
||||
// TODO: find if the first length coded string means anything. Usually comes as empty
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const _unknownString = packet.readLengthCodedString(encoding);
|
||||
const gtid = packet.readLengthCodedString(encoding);
|
||||
stateChanges.gtids = gtid.split(',');
|
||||
} else {
|
||||
// unsupported session track type. For now just ignore
|
||||
}
|
||||
packet.offset = stateEnd;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.info = packet.readString(undefined, encoding);
|
||||
}
|
||||
if (stateChanges) {
|
||||
this.stateChanges = stateChanges;
|
||||
}
|
||||
const m = this.info.match(/\schanged:\s*(\d+)/i);
|
||||
if (m !== null) {
|
||||
this.changedRows = parseInt(m[1], 10);
|
||||
} else {
|
||||
this.changedRows = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: should be consistent instance member, but it's just easier here to have just function
|
||||
static toPacket(fieldCount, insertId) {
|
||||
let length = 4 + Packet.lengthCodedNumberLength(fieldCount);
|
||||
if (typeof insertId !== 'undefined') {
|
||||
length += Packet.lengthCodedNumberLength(insertId);
|
||||
}
|
||||
const buffer = Buffer.allocUnsafe(length);
|
||||
const packet = new Packet(0, buffer, 0, length);
|
||||
packet.offset = 4;
|
||||
packet.writeLengthCodedNumber(fieldCount);
|
||||
if (typeof insertId !== 'undefined') {
|
||||
packet.writeLengthCodedNumber(insertId);
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ResultSetHeader;
|
25
login-auth_backend/node_modules/mysql2/lib/packets/ssl_request.js
generated
vendored
Normal file
25
login-auth_backend/node_modules/mysql2/lib/packets/ssl_request.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
const ClientConstants = require('../constants/client');
|
||||
const Packet = require('../packets/packet');
|
||||
|
||||
class SSLRequest {
|
||||
constructor(flags, charset) {
|
||||
this.clientFlags = flags | ClientConstants.SSL;
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
toPacket() {
|
||||
const length = 36;
|
||||
const buffer = Buffer.allocUnsafe(length);
|
||||
const packet = new Packet(0, buffer, 0, length);
|
||||
buffer.fill(0);
|
||||
packet.offset = 4;
|
||||
packet.writeInt32(this.clientFlags);
|
||||
packet.writeInt32(0); // max packet size. todo: move to config
|
||||
packet.writeInt8(this.charset);
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SSLRequest;
|
47
login-auth_backend/node_modules/mysql2/lib/packets/text_row.js
generated
vendored
Normal file
47
login-auth_backend/node_modules/mysql2/lib/packets/text_row.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
'use strict';
|
||||
|
||||
const Packet = require('../packets/packet');
|
||||
|
||||
class TextRow {
|
||||
constructor(columns) {
|
||||
this.columns = columns || [];
|
||||
}
|
||||
|
||||
static fromPacket(packet) {
|
||||
// packet.reset(); // set offset to starting point?
|
||||
const columns = [];
|
||||
while (packet.haveMoreData()) {
|
||||
columns.push(packet.readLengthCodedString());
|
||||
}
|
||||
return new TextRow(columns);
|
||||
}
|
||||
|
||||
static toPacket(columns, encoding) {
|
||||
const sequenceId = 0; // TODO remove, this is calculated now in connecton
|
||||
let length = 0;
|
||||
columns.forEach((val) => {
|
||||
if (val === null || typeof val === 'undefined') {
|
||||
++length;
|
||||
return;
|
||||
}
|
||||
length += Packet.lengthCodedStringLength(val.toString(10), encoding);
|
||||
});
|
||||
const buffer = Buffer.allocUnsafe(length + 4);
|
||||
const packet = new Packet(sequenceId, buffer, 0, length + 4);
|
||||
packet.offset = 4;
|
||||
columns.forEach((val) => {
|
||||
if (val === null) {
|
||||
packet.writeNull();
|
||||
return;
|
||||
}
|
||||
if (typeof val === 'undefined') {
|
||||
packet.writeInt8(0);
|
||||
return;
|
||||
}
|
||||
packet.writeLengthCodedString(val.toString(10), encoding);
|
||||
});
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TextRow;
|
Reference in New Issue
Block a user