mirror of
https://github.com/nodemailer/wildduck.git
synced 2025-10-09 21:37:13 +08:00
Updated nick handling
This commit is contained in:
parent
c0351a91cf
commit
6db8e096bc
5 changed files with 159 additions and 13 deletions
|
@ -10,7 +10,10 @@ secure=false
|
||||||
[motd]
|
[motd]
|
||||||
source="message" # "message" or "file"
|
source="message" # "message" or "file"
|
||||||
#file="/path/to/motd"
|
#file="/path/to/motd"
|
||||||
message="Set MOTD message with the server config option \u0002irc.motd\u0002"
|
message="""
|
||||||
|
Set MOTD message with the server config option \u0002irc.motd\u0002.
|
||||||
|
Once you have set or changed the message then reload the server by
|
||||||
|
running \u0002systemctl reload wildduck\u0002 or send a SIGHUP message to it"""
|
||||||
|
|
||||||
[tls]
|
[tls]
|
||||||
# If certificate path is not defined, use global or built-in self-signed certs
|
# If certificate path is not defined, use global or built-in self-signed certs
|
||||||
|
|
11
indexes.yaml
11
indexes.yaml
|
@ -335,3 +335,14 @@ indexes:
|
||||||
expireAfterSeconds: 15552000
|
expireAfterSeconds: 15552000
|
||||||
key:
|
key:
|
||||||
updated: 1
|
updated: 1
|
||||||
|
|
||||||
|
# Indexes for IRC
|
||||||
|
|
||||||
|
- collection: nicks
|
||||||
|
index:
|
||||||
|
name: irc_nicks
|
||||||
|
unique: true
|
||||||
|
key:
|
||||||
|
ns: 1
|
||||||
|
unickview: 1
|
||||||
|
user: 1
|
||||||
|
|
|
@ -51,7 +51,7 @@ class GridstoreStorage {
|
||||||
transferEncoding: attachment.transferEncoding
|
transferEncoding: attachment.transferEncoding
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!isNaN(metadata.m)) {
|
if (isNaN(metadata.m) || typeof metadata.m !== 'number') {
|
||||||
errors.notify(new Error('Invalid magic "' + metadata.m + '" for ' + id));
|
errors.notify(new Error('Invalid magic "' + metadata.m + '" for ' + id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ class GridstoreStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(id, magic, callback) {
|
delete(id, magic, callback) {
|
||||||
if (!isNaN(magic)) {
|
if (isNaN(magic) || typeof magic !== 'number') {
|
||||||
errors.notify(new Error('Invalid magic "' + magic + '" for ' + id));
|
errors.notify(new Error('Invalid magic "' + magic + '" for ' + id));
|
||||||
}
|
}
|
||||||
this.gridfs.collection(this.bucketName + '.files').findOneAndUpdate({
|
this.gridfs.collection(this.bucketName + '.files').findOneAndUpdate({
|
||||||
|
@ -239,7 +239,7 @@ class GridstoreStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
update(ids, count, magic, callback) {
|
update(ids, count, magic, callback) {
|
||||||
if (!isNaN(magic)) {
|
if (isNaN(magic) || typeof magic !== 'number') {
|
||||||
errors.notify(new Error('Invalid magic "' + magic + '" for ' + ids));
|
errors.notify(new Error('Invalid magic "' + magic + '" for ' + ids));
|
||||||
}
|
}
|
||||||
// update attachments
|
// update attachments
|
||||||
|
|
|
@ -5,6 +5,7 @@ const crypto = require('crypto');
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
const os = require('os');
|
const os = require('os');
|
||||||
const codes = require('./codes');
|
const codes = require('./codes');
|
||||||
|
const db = require('../db');
|
||||||
|
|
||||||
const PING_TIMEOUT = 120 * 1000;
|
const PING_TIMEOUT = 120 * 1000;
|
||||||
const SOCKET_TIMEOUT = 5 * 60 * 1000;
|
const SOCKET_TIMEOUT = 5 * 60 * 1000;
|
||||||
|
@ -412,16 +413,128 @@ class IRCConnection extends EventEmitter {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//this.session.clientHostname = 'example.com';
|
||||||
this.session.user = result.username;
|
this.session.user = result.username;
|
||||||
|
|
||||||
|
db.users.collection('users').findOne({ _id: result.user }, {
|
||||||
|
fields: {
|
||||||
|
_id: true,
|
||||||
|
username: true,
|
||||||
|
address: true,
|
||||||
|
name: true,
|
||||||
|
ns: true
|
||||||
|
}
|
||||||
|
}, (err, userData) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
let ns = userData.ns;
|
||||||
|
|
||||||
|
if (userData.address) {
|
||||||
|
let parts = userData.address.split('@');
|
||||||
|
this.session.user = parts.shift();
|
||||||
|
this.session.clientHostname = parts.join('@');
|
||||||
|
if (!ns) {
|
||||||
|
ns = this.session.clientHostname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.session.ns = ns || 'root';
|
||||||
|
|
||||||
next(null, {
|
next(null, {
|
||||||
id: result.user,
|
id: userData._id,
|
||||||
username: result.username
|
username: userData.username
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getNick(nick, next) {
|
||||||
|
let ns = this.session.ns;
|
||||||
|
let unickview = nick.toLowerCase().replace(/\./g, '');
|
||||||
|
let user = this.session.auth.id;
|
||||||
|
|
||||||
|
let verifyUser = done => {
|
||||||
|
if (unickview === this.session.auth.username.replace(/\./g, '')) {
|
||||||
|
return done();
|
||||||
|
}
|
||||||
|
db.users.collection('users').findOne({ unameview: unickview }, {
|
||||||
|
fields: {
|
||||||
|
_id: true,
|
||||||
|
username: true
|
||||||
|
}
|
||||||
|
}, (err, userData) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
if (userData && userData._id.toString() !== this.session.auth.id.toString()) {
|
||||||
|
return next(new Error('Can not acquire reserved nick'));
|
||||||
|
}
|
||||||
|
return done();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
verifyUser(() => {
|
||||||
|
db.database.collection('nicks').insertOne({
|
||||||
|
ns,
|
||||||
|
unickview,
|
||||||
|
nick,
|
||||||
|
user
|
||||||
|
}, (err, r) => {
|
||||||
|
if (err) {
|
||||||
|
if (err.code === 11000) {
|
||||||
|
return db.database.collection('nicks').findOne({
|
||||||
|
ns,
|
||||||
|
unickview
|
||||||
|
}, (err, nickData) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
if (!nickData) {
|
||||||
|
return next(new Error('Race condition in acquireing nick'));
|
||||||
|
}
|
||||||
|
if (nickData.user.toString() === user.toString()) {
|
||||||
|
return next(null, nickData._id);
|
||||||
|
}
|
||||||
|
return next(new Error('Requested nick is already in use'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
let insertId = r && r.insertedId;
|
||||||
|
if (!insertId) {
|
||||||
|
return next(new Error('Failed to set up nick'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to remove old nicks
|
||||||
|
db.database.collection('nicks').deleteOne({
|
||||||
|
ns,
|
||||||
|
unickview: { $ne: unickview },
|
||||||
|
user
|
||||||
|
}, () => next(null, insertId));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
verifyNickChange(currentSource, next) {
|
||||||
|
this.getNick(this.session.nick, err => {
|
||||||
|
if (err) {
|
||||||
|
currentSource = currentSource || this.getFormattedName();
|
||||||
|
this.send({ verb: 'ERR_UNAVAILRESOURCE', params: err.message });
|
||||||
|
this.session.nick = this.session.user;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentSource) {
|
||||||
|
this.send({ source: currentSource, verb: 'NICK', target: false, params: this.session.nick });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.server.nick(this);
|
||||||
|
return next();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
checkAuth() {
|
checkAuth() {
|
||||||
if (!this.session.auth) {
|
if (!this.session.auth) {
|
||||||
this.send({ verb: 'ERR_NOTREGISTERED', params: 'PRIVMSG', message: 'Authentication required to chat in this server' });
|
this.send({ verb: 'ERR_NOTREGISTERED', params: 'PRIVMSG', message: 'Authentication required to chat in this server' });
|
||||||
|
@ -475,18 +588,28 @@ class IRCConnection extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
command_NICK(params, next) {
|
command_NICK(params, next) {
|
||||||
|
let currentSource = this.getFormattedName();
|
||||||
|
|
||||||
if (params.length > 1) {
|
if (params.length > 1) {
|
||||||
this.send({ verb: 'ERR_ERRONEUSNICKNAME', params, message: 'Erroneous Nickname' });
|
this.send({ verb: 'ERR_ERRONEUSNICKNAME', params, message: 'Erroneous Nickname' });
|
||||||
|
return next();
|
||||||
} else if (!params.length) {
|
} else if (!params.length) {
|
||||||
this.send({ verb: 'ERR_NEEDMOREPARAMS', params, message: 'Not enough parameters' });
|
this.send({ verb: 'ERR_NEEDMOREPARAMS', params, message: 'Not enough parameters' });
|
||||||
|
return next();
|
||||||
} else if (this.server.disabledNicks.includes(params[0].trim().toLowerCase())) {
|
} else if (this.server.disabledNicks.includes(params[0].trim().toLowerCase())) {
|
||||||
this.send({ verb: 'ERR_ERRONEUSNICKNAME', params, message: 'Erroneous Nickname' });
|
this.send({ verb: 'ERR_ERRONEUSNICKNAME', params, message: 'Erroneous Nickname' });
|
||||||
|
return next();
|
||||||
} else {
|
} else {
|
||||||
this.session.nick = params[0];
|
this.session.nick = params[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
this.checkSessionStart();
|
this.checkSessionStart();
|
||||||
this.server.nick(this);
|
|
||||||
return next();
|
if (this.session.auth) {
|
||||||
|
this.verifyNickChange(currentSource, next);
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
command_PASS(params, next) {
|
command_PASS(params, next) {
|
||||||
|
@ -526,6 +649,7 @@ class IRCConnection extends EventEmitter {
|
||||||
if (auth) {
|
if (auth) {
|
||||||
this.session.auth = auth;
|
this.session.auth = auth;
|
||||||
this.checkSessionStart();
|
this.checkSessionStart();
|
||||||
|
return this.verifyNickChange(false, next);
|
||||||
}
|
}
|
||||||
return next();
|
return next();
|
||||||
});
|
});
|
||||||
|
@ -731,6 +855,7 @@ class IRCConnection extends EventEmitter {
|
||||||
target: this.session.nick,
|
target: this.session.nick,
|
||||||
message: 'You are now identified for ' + this.session.user
|
message: 'You are now identified for ' + this.session.user
|
||||||
});
|
});
|
||||||
|
return this.verifyNickChange(false, next);
|
||||||
} else {
|
} else {
|
||||||
this.send({
|
this.send({
|
||||||
source: ':NickServ!NickServ@services.',
|
source: ':NickServ!NickServ@services.',
|
||||||
|
@ -806,6 +931,7 @@ class IRCConnection extends EventEmitter {
|
||||||
message: 'You are now logged in as ' + this.session.user
|
message: 'You are now logged in as ' + this.session.user
|
||||||
});
|
});
|
||||||
this.send({ verb: 'RPL_SASLSUCCESS', target: this.session.nick || '*', message: 'SASL authentication successful' });
|
this.send({ verb: 'RPL_SASLSUCCESS', target: this.session.nick || '*', message: 'SASL authentication successful' });
|
||||||
|
return this.verifyNickChange(false, next);
|
||||||
} else {
|
} else {
|
||||||
this.send({ verb: 'ERR_SASLFAIL', target: this.session.nick || '*', message: 'SASL authentication failed' });
|
this.send({ verb: 'ERR_SASLFAIL', target: this.session.nick || '*', message: 'SASL authentication failed' });
|
||||||
}
|
}
|
||||||
|
@ -816,6 +942,12 @@ class IRCConnection extends EventEmitter {
|
||||||
|
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
command_NN(params, next) {
|
||||||
|
this.session.nick = params[0];
|
||||||
|
this.server.nick(this);
|
||||||
|
next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = IRCConnection;
|
module.exports = IRCConnection;
|
||||||
|
|
|
@ -25,14 +25,14 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"addressparser": "1.0.1",
|
"addressparser": "1.0.1",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"bugsnag": "1.12.1",
|
"bugsnag": "1.12.2",
|
||||||
"generate-password": "1.3.0",
|
"generate-password": "1.3.0",
|
||||||
"he": "1.1.1",
|
"he": "1.1.1",
|
||||||
"html-to-text": "3.3.0",
|
"html-to-text": "3.3.0",
|
||||||
"humanname": "0.2.2",
|
"humanname": "0.2.2",
|
||||||
"humanparser": "1.5.0",
|
"humanparser": "1.5.0",
|
||||||
"iconv-lite": "0.4.19",
|
"iconv-lite": "0.4.19",
|
||||||
"joi": "10.6.0",
|
"joi": "11.0.1",
|
||||||
"js-yaml": "3.10.0",
|
"js-yaml": "3.10.0",
|
||||||
"libbase64": "0.2.0",
|
"libbase64": "0.2.0",
|
||||||
"libmime": "3.1.0",
|
"libmime": "3.1.0",
|
||||||
|
@ -49,14 +49,14 @@
|
||||||
"qrcode": "0.9.0",
|
"qrcode": "0.9.0",
|
||||||
"redfour": "1.0.2",
|
"redfour": "1.0.2",
|
||||||
"redis": "2.8.0",
|
"redis": "2.8.0",
|
||||||
"restify": "5.2.0",
|
"restify": "6.0.0",
|
||||||
"seq-index": "1.1.0",
|
"seq-index": "1.1.0",
|
||||||
"smtp-server": "3.1.0",
|
"smtp-server": "3.1.0",
|
||||||
"speakeasy": "2.0.0",
|
"speakeasy": "2.0.0",
|
||||||
"tlds": "1.196.0",
|
"tlds": "1.196.0",
|
||||||
"utf7": "1.0.2",
|
"utf7": "1.0.2",
|
||||||
"uuid": "3.1.0",
|
"uuid": "3.1.0",
|
||||||
"wild-config": "1.3.2"
|
"wild-config": "1.3.5"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
Loading…
Add table
Reference in a new issue