nodemailer / wildduck Goto Github PK
View Code? Open in Web Editor NEWOpinionated email server
Home Page: https://wildduck.email/
License: European Union Public License 1.2
Opinionated email server
Home Page: https://wildduck.email/
License: European Union Public License 1.2
Not sure if it is valid or not, have to check from rfc3501 but other servers seem to handle it this way.
gmail
C: X FETCH * UID
S: * 123 FETCH (UID 123)
wildduck
C: X FETCH * UID
S: X BAD
After a clean install using the Wild Duck Installer there doesn't seem to be any pop3 server listening on port 995.
Actions that need rate limiting would be:
I apologize if this isn't the place to put this, and if I'm just not understanding exactly what this does, but is there anything in the API that can be used to send a new email from a user?
Like, if I had an application with a dashboard where I wanted to be able to send emails directly from the application, without having to use wildduck's webmail (if there even is one), or if I wanted to use a custom webmail.
Again, sorry if this isn't the right place for my question. I've looked through the API documentation as well as some of the source code and was unable to find anything.
The great remind me later feature.
When applied the message would be removed from mailbox and put into snoozing collection. Once snooze time is reached the message is returned to mailbox as unseen message.
Fetching attachment subparts is currently broken. Seems that on some occasions the attachment name is not converted to the attachment id
C: 19.172 UID FETCH 1 BODY.PEEK[2]
/opt/wildduck/node_modules/mongodb/lib/utils.js:123
process.nextTick(function() { throw err; });
^
Error: FileNotFound: file ATT00001 was not found
at /opt/wildduck/node_modules/mongodb/lib/gridfs-stream/download.js:281:17
at handleCallback (/opt/wildduck/node_modules/mongodb/lib/utils.js:120:56)
at /opt/wildduck/node_modules/mongodb/lib/collection.js:1417:5
at handleCallback (/opt/wildduck/node_modules/mongodb/lib/utils.js:120:56)
at /opt/wildduck/node_modules/mongodb/lib/cursor.js:682:5
at handleCallback (/opt/wildduck/node_modules/mongodb-core/lib/cursor.js:171:5)
at setCursorNotified (/opt/wildduck/node_modules/mongodb-core/lib/cursor.js:515:3)
at /opt/wildduck/node_modules/mongodb-core/lib/cursor.js:590:16
at queryCallback (/opt/wildduck/node_modules/mongodb-core/lib/cursor.js:253:5)
at /opt/wildduck/node_modules/mongodb-core/lib/connection/pool.js:469:18
when trying to send email from the same email address, an error will be thrown:
TypeError: Cannot read property 'on' of undefined
at StreamCollect.Readable.pipe (_stream_readable.js:501:7)
at messageHandler.counters.ttlcounter (/root/data/www/wildduck/lib/api/submit.js:395:60)
at redis.ttlcounter (/root/data/www/wildduck/lib/counters.js:39:24)
at tryCatcher (/root/data/www/wildduck/node_modules/bluebird/js/release/util.js:16:23)
at Promise.successAdapter [as _fulfillmentHandler0] (/root/data/www/wildduck/node_modules/bluebird/js/release/nodeify.js:23:30)
at Promise._settlePromise (/root/data/www/wildduck/node_modules/bluebird/js/release/promise.js:566:21)
at Promise._settlePromise0 (/root/data/www/wildduck/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/root/data/www/wildduck/node_modules/bluebird/js/release/promise.js:693:18)
at Async._drainQueue (/root/data/www/wildduck/node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (/root/data/www/wildduck/node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues (/root/data/www/wildduck/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:672:20)
at tryOnImmediate (timers.js:645:5)
at processImmediate [as _immediateCallback] (timers.js:617:5)
I understand that wildduck is "opinionated". However, is there any chance you'll be supporting pluggable storage in the future?
I notice that other projects (based on your work) have sprung up specifically to address this concern: imapper
We're keen to use wildduck. But pluggable authentication and pluggable storage are requirements I don't think we'd be able to work around.
Hi,
Can we use SpamAssassin & ClamAV with Wild Duck?
If the answer is no, is there any alternatives?
Kind Regards,
Mohammed
Could be added in the future. Looked though the spec and found nothing that would not be doable.
http://interoperability.blob.core.windows.net/files/MS-ASHTTP/%5BMS-ASHTTP%5D.pdf
Hello.
Thanks for your cool software!
Ran into two problems. First letsencrypt cert is not created. Error message:
[Sat Jan 27 11:10:25 CET 2018] Install success!
./install.sh: line 565: /root/.acme.sh/acme.sh: No such file or directory
Warning: Failed to generate certificates, using self-signed certs
Second problem: /webmail/send gives me currently 502. Error message:
2018/01/27 11:12:32 [error] 19000#19000: *231 upstream prematurely closed connection while reading response header from upstream, client: myip, server: mydomainname, request: "GET /webmail/send HTTP/2.0", upstream: "http://127.0.0.1:3000/webmail/send", host: "mydomainname"
Any ideas where i should start to debug? It's a clean ubuntu 16.04 machine.
thanks and cheers
To avoid situations where a rogue script infinitely downloads mailbox contents daily bandwidth should be limited.
When rebuilding rfc822 messages from serialized message data then the output is not always 100% exact copy of the original. Message builder moves all empty lines between multipart boundaries (end of one subtree and continuation of next) to the beginning of the body. For most messages it's not an issue because email clients usually do not put extra empty lines between the boundary lines but sometimes it happens
Status low. This is probably related to #8 and these should be resolved together with a better message parser.
wildduck/lib/message-splitter.js
Line 67 in cca4a9a
why not use or
in if
, and the if (pr1 === 0x0a)
is for what ? thx for reply.
I see that wildduck supports domain aliases but does it support multiple domains? If it doesn't out of the box is it possible to have multiple instances of wildduck use the same redis and mongodb?
btw, awesome work!
Error in imap-core/lib/imap-server.js:212
Socket closed while initiating TLS
imap-core/lib/imap-server.js:212 - onError
Created by Andris Reinman via Bugsnag
The most sane way for threading would probably be to add a separate reference collection that matches known threads to message-ids.
{
_id: threadId,
user: userId,
ids: [list of message-ids],
subject: 'normalized subject',
updated: date
}
updated
fields would have an index for "expireAfterSeconds": 31104000
so old untouched references would be removed from the database after a year or so.
Checking thread value would look something like this:
// most messages are not threaded, so an upsert call should be ok to make
threads.findOneAndUpdate({
user: userId,
ids: {$in: ['message-id', 'references', 'in-reply-to']},
subject: 'normalized subject'
}, {
$addToSet: {
ids: 'message-id' // maybe push all references etc as well?
},
$set: {
user: userId,
subject: 'normalized subject', // for the upster to work
updated: new Date()
}
}, {
upsert: true,
returnOriginal: false
})
I cannot figure out how to handle multiple domains. It seems that WildDuck assumes that all users and hosted email addresses will be using the same domain suffix (@mydomain.com
).
I also want to be handling mail for myotherdomain.com
.
Do I need to do another installation of wildduck?
Hi ,
Can anybody tell me how to install wild duck in centos..????
After download and run install scripts this error is
./install.sh: line 66: apt-key: command not found.
please solve this .
Natural sharding key for the messages would be "mailbox" but MOVE modifies this value which is not allowed when sharding is used
Currently attachments stored in GridStore can not be shared between different messages because these contain message specific metadata. The only metadata that should remain should be:
When storing new attachments the server should try to find an existing attachment first
database.collection('attachments.files').findOneAndUpdate({
md5: attachmentMd5,
length: attachmentLength
}, {
$addToSet: {
messages: messageId
}
}, (err, res)=>{
// if a document was updated (res.value exists) then thats it
// otherwise create a new attachment instance
});
This would assume a compound index on md5+length
wildduck/lib/message-handler.js
Line 466 in f984430
because of queryOpts, messageData.mailbox is always Undefined, so i think mailbox: mailboxData._id
will be better. as _id: messageData._id
is Unique, so this line also can delete.
Hi
i used install.sh
then it failed at redis server
Job for redis-server.service failed because a configured resource limit was exceeded. See "systemctl status redis-server.service" and "journalctl -xe" for details.
invoke-rc.d: initscript redis-server, action "start" failed.
● redis-server.service - Advanced key-value store
Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; vendor preset: enabled)
Active: activating (auto-restart) (Result: resources) since Wed 2018-01-31 06:15:16 EST; 4ms ago
Docs: http://redis.io/documentation,
man:redis-server(1)
Process: 4693 ExecStopPost=/bin/run-parts --verbose /etc/redis/redis-server.post-down.d (code=exited, status=0/SUCCESS)
Process: 4689 ExecStop=/bin/kill -s TERM $MAINPID (code=exited, status=0/SUCCESS)
Process: 4683 ExecStop=/bin/run-parts --verbose /etc/redis/redis-server.pre-down.d (code=exited, status=0/SUCCESS)
Process: 4679 ExecStartPost=/bin/run-parts --verbose /etc/redis/redis-server.post-up.d (code=exited, status=0/SUCCESS)
Process: 4675 ExecStart=/usr/bin/redis-server /etc/redis/redis.conf (code=exited, status=0/SUCCESS)
Process: 4669 ExecStartPre=/bin/run-parts --verbose /etc/redis/redis-server.pre-up.d (code=exited, status=0/SUCCESS)
Jan 31 06:15:16 vps166879 systemd[1]: Failed to start Advanced key-value store.
Jan 31 06:15:16 vps166879 systemd[1]: redis-server.service: Unit entered failed state.
Jan 31 06:15:16 vps166879 systemd[1]: redis-server.service: Failed with result 'r...'.
Hint: Some lines were ellipsized, use -l to show in full.
dpkg: error processing package redis-server (--configure):
subprocess installed post-installation script returned error exit status 1
Errors were encountered while processing:
redis-server
please help me
Line 106 in 571dbc0
if user A
forward is Null,
this line will forward to A self, is this will gets dead cycle?
As autoreply has Auto-Submitted
(and so on) headers to break dead cycle.
what about forward logic ? thx
Line 146 in 604e923
rfc2033 desc :
Even if there were multiple successful RCPT commands giving the same forward-path, there must be one reply for each successful RCPT command.
this code block is for this ? think you for your answer.
Currently there is no limit for concurrent connections per user. Gmail allows 15 conections for IMAP and fails with NO once connection limit is exceeded
a login <username> <password>
a NO [ALERT] Too many simultaneous connections. (Failure)
Hello, i'm trying to receive a message form my outlook account and the server actually receives it; but when i try to access the mail via HTTP API i get this error:
/root/wildduck/node_modules/mongodb/lib/utils.js:123
process.nextTick(function() { throw err; });
^
Error: Route <attachment> is missing parameter <attachment>
at pathItem (/root/wildduck/node_modules/restify/lib/router.js:229:19)
at String.replace (<anonymous>)
at Router.render (/root/wildduck/node_modules/restify/lib/router.js:247:22)
at db.users.collection.findOne (/root/wildduck/lib/api/messages.js:498:36)
at handleCallback (/root/wildduck/node_modules/mongodb/lib/utils.js:120:56)
at /root/wildduck/node_modules/mongodb/lib/collection.js:1417:5
at handleCallback (/root/wildduck/node_modules/mongodb/lib/utils.js:120:56)
at /root/wildduck/node_modules/mongodb/lib/cursor.js:682:5
at handleCallback (/root/wildduck/node_modules/mongodb-core/lib/cursor.js:171:5)
at nextFunction (/root/wildduck/node_modules/mongodb-core/lib/cursor.js:682:5)
this is the JSON data i can get if look for all the emails
{
"id": 4,
"mailbox": "5980ad36f936e433e509ea39",
"thread": "598167d53342b5742b6a4943",
"from": {
"address": "[email protected]",
"name": "Gerardo Pérez Pérez"
},
"subject": "Mail de Prueba",
"date": "2017-08-02T05:49:07.000Z",
"intro": "Hola Mundo",
"attachments": false,
"seen": false,
"deleted": false,
"flagged": false,
"draft": false,
"url": "/users/5980ad36f936e433e509ea38/mailboxes/5980ad36f936e433e509ea39/messages/4"
}
I'm using default configuration, and as suggested I'm using haraka, (also with default configuration), with queue set to queue/lmtp.
I hope, yoy can give a hint to find a solution. Thanks!
hi sir,
I want to use your code in my own private project, how can i get the right license?
Can we have a talk? I just send a chat invitation to you on google+.
Hey, is their any PPA for Ubuntu Installation? any wiki or usefull link thus i can setup this DigitalOcean? This is possible for Mass mailing with 100% inbox using this wildduck
Hi,
could this be used to implement a kind of mail filtering proxy which reject hosts by a blacklist so that the spammer get a message that the host no longer exists or even a reject message
and forward all other mails just to another mail server ?
Thats could be the solution to many spam issues :)
Cheers Marc
Hi,
I am sending and receiving messages with api as mentioned
curl -i -XPOST "http://localhost:8080/users/59fc66a03e54454869460e45/submit"
-H 'Content-type: application/json'
-d '{
"to": [{
"address": "[email protected]"
}],
"subject": "Hello world!",
"text": "Test message"
}'
But I need to send reply so that recepient can see my reply in his Inbox
{
"reference": {
"mailbox": "59fc66a03e54454869460e47",
"id": 15,
"action": "replyAll"
},
"text": "Yeah, sure"
}
is not working , what should be complete payload for it ?
please help
While Submitting the message using ReplyAll snippet in message payload, getting Socket Hung up error and message is not delivered.
Please let us know what is the issue.
The most obvious shard key for attachment.files would be the unique sha256 hash as this is the value mostly searched for. This would require knowing the hash when fetching attachments by id. As the attachments ids in the message object are already stored as references in a map then the reference value could just as well include both the id and hash, not just the id
wildduck/lib/message-handler.js
Line 538 in f984430
is messageOpts.modseq = newModseq;
for update messageOpts's modseq,
instead of messageData.modseq = newModseq;
for update messageData's modse ?
Currently Wild Duck calculates quota usage per user and per mailbox. The latter is needed for DELETE. Quota counting can get out of sync as it is not atomic, so a reindexing might be needed from time to time. Keeping mailbox specific counters also makes adding MOVE support more difficult. So it would be best to just drop the mailbox specific counters and keep the user level counters. For DELETE and reindexing use MongoDB aggregated $sum(message.size) queries.
Hi,
Is Wild Duck have a pipe filter? I cant find such thing in the documentation.
If the answer is no then is it possible to extend the filter feature to use pipes to other scripts/applications/services using plugins for example?
Kind Regards,
Mohammed
2FA TOTP seed token is stored as plaintext in db, which probably shouldn't be like that. Some services use user password to encrypt the 2FA seed. I'm not sure if would be the best way to go as 2FA is meant for exactly to these situations where user password is known. Maybe use a global secret configured in application settings instead.
If a message contains invalid punycode address then Wild Duck might throw an exception.
To: [email protected]\t\t\t\t\t-
Hi,
Thank you so much for creating this amazing project, I hope I'll be able to help in the future.
After running node server.js
I got unlimited number of errors like the following:
{"name":"Wild Duck API","hostname":"Mohammed-Notebook","pid":31868,"level":40,"req":{"method":"GET","url":"/__webpack_hmr","headers":{"host":"localhost:8080","connection":"keep-alive","accept":"text/event-stream","cache-control":"no-cache","user-agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36","referer":"http://localhost:8080/","accept-encoding":"gzip, deflate, br","accept-language":"en-US,en;q=0.8"},"remoteAddress":"127.0.0.1","remotePort":40726},"err":{"message":"could not find suitable formatter","name":"NotAcceptableError","stack":"NotAcceptableError: could not find suitable formatter\n at ServerResponse.__send (/path/wildduck/node_modules/restify/lib/response.js:400:32)\n at ServerResponse.send (/path/wildduck/node_modules/restify/lib/response.js:221:24)\n at /path/wildduck/node_modules/restify/lib/server.js:788:17\n at /path/wildduck/node_modules/restify/lib/server.js:1145:16\n at Immediate.<anonymous> (/path/wildduck/node_modules/vasync/lib/vasync.js:175:30)\n at runCallback (timers.js:785:20)\n at tryOnImmediate (timers.js:747:5)\n at processImmediate [as _immediateCallback] (timers.js:718:5)","code":"NotAcceptable"},"msg":"error retrieving formatter","time":"2017-10-12T13:09:07.255Z","v":0}
They appear one after one on the terminal.
My operating system is Linux Mint 18.02 which is built on top of Ubuntu 16.04
How can I fix this issue please?
All the best,
Mohammed
Hello, with the standard configuration + Haraka. You can send false emails, for example:
telnet wild.duck 25
MAIL FROM: [email protected]
RCPT TO: [email protected]
or
MAIL FROM: [email protected]
RCPT TO: [email protected]
Thanks
Thanks for working on such an excellent project.
This may be a question more regarging ZoneMTA as it covers both delivery and storage.
How would one configure wildduck for multi domain usage, is this something I can try and help with? If so, I'd appreciate being pointed in the right direction. I'm guessing this won't work 'out the box'.
Would if be a case of setting senderDomains somewhere in Wildduck config? Or in /opt/zone-mta/config/domains.toml
?
On a traditional postfix install we have multiple virtual_mailbox_domains
set, and then use opendkim for DKIM signing. Finally Docecot used to store in a /data/%d /%n (%d = domain) (%u = user) type fashion.
Hey there,
I've been trying out wildduck locally - and so far this seems like exactly what I need: a modern email server that can be extended and customized.
However, regarding security: Is there a way to integrate let's encrypt auto signing for domains with wildduck?
If not, where would I start in the codebase and what would be the necessary steps to do this?
Thanks in advice.
FETCH response with partial octets should only return the origin octet not the full range query
Spec: https://tools.ietf.org/html/rfc3501#page-74
Request:
C: A10 FETCH 1 (BODY[TEXT]<0.28>)
Current response
S: * 1 FETCH (BODY[TEXT]<0.28> {28}...
Should be
S: * 1 FETCH (BODY[TEXT]<0> {28}...
parseMimeTree
function expects the entire message as input and parses this synchronously. Instead it should be more like a writable stream that parses message in parts. This would be similar how a message is parsed by ZoneMTA before storing to db.
Prioriy status: low
wildduck/lib/filter-handler.js
Line 268 in 029aeec
the action ( that key === 'forward' or key === 'targetUrl') of the first filter in forEach , will not be processed in the following logic , why ?
I ran Wild Duck Installer on a new digitalocean droplet.
Wild Duck keeps restarting and it seems that it's because both ZoneMTA and API server are trying to use port 8080.
root@test-mail-server:/var/log# lsof -i :8080
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
zone-mta: 15214 wildduck 12u IPv4 41478 0t0 TCP localhost:http-alt (LISTEN)
Dec 22 05:57:54 test-mail-server systemd[1]: Started Wild Duck Mail Server.
Dec 22 05:57:54 test-mail-server node[18464]: info App -----------------------------------------------------------------
Dec 22 05:57:54 test-mail-server node[18464]: info App
Dec 22 05:57:54 test-mail-server node[18464]: info App █ █░ ██▓ ██▓ ▓█████▄ ▓█████▄ █ ██ ▄████▄ ██ ▄█▀
Dec 22 05:57:54 test-mail-server node[18464]: info App ▓█░ █ ░█░▓██▒▓██▒ ▒██▀ ██▌ ▒██▀ ██▌ ██ ▓██▒▒██▀ ▀█ ██▄█▒
Dec 22 05:57:54 test-mail-server node[18464]: info App ▒█░ █ ░█ ▒██▒▒██░ ░██ █▌ ░██ █▌▓██ ▒██░▒▓█ ▄ ▓███▄░
Dec 22 05:57:54 test-mail-server node[18464]: info App ░█░ █ ░█ ░██░▒██░ ░▓█▄ ▌ ░▓█▄ ▌▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄
Dec 22 05:57:54 test-mail-server node[18464]: info App ░░██▒██▓ ░██░░██████▒░▒████▓ ░▒████▓ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄
Dec 22 05:57:54 test-mail-server node[18464]: info App ░ ▓░▒ ▒ ░▓ ░ ▒░▓ ░ ▒▒▓ ▒ ▒▒▓ ▒ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒
Dec 22 05:57:54 test-mail-server node[18464]: info App ▒ ░ ░ ▒ ░░ ░ ▒ ░ ░ ▒ ▒ ░ ▒ ▒ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
Dec 22 05:57:54 test-mail-server node[18464]: info App ░ ░ ▒ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
Dec 22 05:57:54 test-mail-server node[18464]: info App ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
Dec 22 05:57:54 test-mail-server node[18464]: info App ░ ░ ░
Dec 22 05:57:54 test-mail-server node[18464]: info App
Dec 22 05:57:54 test-mail-server node[18464]: info App ------------------------ [email protected] ------------------------
Dec 22 05:57:54 test-mail-server node[18464]: info App
Dec 22 05:57:55 test-mail-server node[18464]: info IMAP Secure IMAP Server listening on 0.0.0.0:993
Dec 22 05:57:55 test-mail-server node[18464]: info POP3 POP3 Server listening on 0.0.0.0:9110
Dec 22 05:57:55 test-mail-server node[18464]: info LMTP LMTP Server listening on 127.0.0.1:24
Dec 22 05:57:55 test-mail-server node[18464]: ERR! App Failed to start API server
Dec 22 05:57:55 test-mail-server node[18464]: { Error: listen EADDRINUSE 127.0.0.1:8080
Dec 22 05:57:55 test-mail-server node[18464]: at Object._errnoException (util.js:1024:11)
Dec 22 05:57:55 test-mail-server node[18464]: at _exceptionWithHostPort (util.js:1046:20)
Dec 22 05:57:55 test-mail-server node[18464]: at Server.setupListenHandle [as _listen2] (net.js:1351:14)
Dec 22 05:57:55 test-mail-server node[18464]: at listenInCluster (net.js:1392:12)
Dec 22 05:57:55 test-mail-server node[18464]: at doListen (net.js:1501:7)
Dec 22 05:57:55 test-mail-server node[18464]: at _combinedTickCallback (internal/process/next_tick.js:141:11)
Dec 22 05:57:55 test-mail-server node[18464]: at process._tickDomainCallback (internal/process/next_tick.js:218:9)
Dec 22 05:57:55 test-mail-server node[18464]: code: 'EADDRINUSE',
Dec 22 05:57:55 test-mail-server node[18464]: errno: 'EADDRINUSE',
Dec 22 05:57:55 test-mail-server node[18464]: syscall: 'listen',
Dec 22 05:57:55 test-mail-server node[18464]: address: '127.0.0.1',
Dec 22 05:57:55 test-mail-server node[18464]: port: 8080 }
I don't have time to work on this right now but JMAP is something that probably should be considered. IMAP is not so great for web clients.
Hello
I have done the SMTP server with haraka and save mail data in mysql. But can not able send data to other IMAP mail clients. So can I do it using wildduck ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.