Git Product home page Git Product logo

neutron's Introduction

neutron

Build Status GoDoc

Self-hosted server for Protonmail client.

This project is not affiliated or supported by ProtonMail.

What is it?

Neutron is a server that will allow the ProtonMail client to be used with backends. Several backends are available right now:

  • IMAP: this will read and store messages on your IMAP server. Received messages will stay as is (that is, unencrypted) but messages saved from the web client will be encrypted. You will login to the web client with your IMAP username and password.
  • SMTP: this will send messages using your SMTP server. Messages are sent encrypted to the server. If a recipient's public key is not found, the server will decrypt the message before sending it to this recipient.
  • Filesystem: settings, contacts, keys are stored on disk. Keys are always stored encrypted.
  • Memory: all is stored in memory and will be destroyed when the server is stopped.

Neutron is modular so it's easy to create new backends and handle more scenarios.

Keep in mind that Neutron is less secure than ProtonMail: most servers don't use full-disk encryption and aren't under 1,000 meters of granite rock in Switzerland. Also, SRP is not yet supported (#35). If you use Neutron, make sure to donate to ProtonMail!

Install

Configuration

See config.json. You'll have to change IMAP and SMTP settings to match your mail server config.

{
	"Memory": {
		"Enabled": true,
		"Populate": false, // Populate server with default neutron user
		"Domains": ["emersion.fr"] // Available e-mail domains
	},
	"Imap": { // IMAP server config
		"Enabled": true,
		"Hostname": "mail.gandi.net",
		"Tls": true,
		"Suffix": "@emersion.fr" // Will be appended to username when authenticating
	},
	"Smtp": { // SMTP server config
		"Enabled": true,
		"Hostname": "mail.gandi.net",
		"Port": 587,
		"Suffix": "@emersion.fr" // Will be appended to username when authenticating
	},
	"Disk": { // Store keys, contacts and settings on disk
		"Enabled": true,
		"Keys": { "Directory": "db/keys" }, // PGP keys location
		"Contacts": { "Directory": "db/contacts" },
		"UsersSettings": { "Directory": "db/settings" },
		"Addresses": { "Directory": "db/addresses" }
	}
}

Usage

To generate keys for a new user the first time, just click Sign up on the login page and enter your IMAP credentials.

Options

  • -config: specify a custom config file
  • -help: show help

Build

Requirements:

  • Go (to build the server)
  • Node, NPM (to build the client)
# Get the code
go get -u github.com/emersion/neutron
cd $GOPATH/src/github.com/emersion/neutron

# Build the client
git submodule init
git submodule update
make build-client

# Start the server
make start

Docker

make build-docker
docker build -t neutron .
docker create -p 4000:4000 -v $PWD/config.json:/config.json -v $PWD/db:/db neutron

Backends

All backends must implement the backend interface. The main backend interface is split into multiple other backend interfaces for different roles: ContactsBackend, LabelsBackend and so on. This allows to build modular backends, e.g. a MessagesBackend which stores messages on an IMAP server with a ContactsBackend which stores contacts on a LDAP server and a SendBackend which sends outgoing messages to a SMTP server.

Writing a backend is just a matter of implementing the necessary functions. You can read the memory backend to understand how to do that. Docs for the backend are available here: https://godoc.org/github.com/emersion/neutron/backend#Backend

License

MIT

neutron's People

Contributors

emersion avatar galaxor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

neutron's Issues

How to configure Apache with HTTPS to proxy requests to Neutron?

I've built neutron using go. I've setup my SSL cert using Letsencrypt.
I can see the Protonmail server at port 4000, and I can see the CentOS test page at port 443.

Running "make start" to get Macaron to listen on port 4000. But, I cannot figure out how to get the server to use SSL for neutron. Any help would be greatly appreciated!

Thank!

Make Start (and make build-docker) fail

I am running CentOS 7. I've successfully built Neutron as instructed. However, when I run make start or make build-docker I get the same error:

make start
go run neutron.go

github.com/emersion/neutron/backend/imap

backend/imap/attachments.go:40: undefined: imap.NewSeqSet
backend/imap/events.go:40: undefined: imap.NewSeqSet
backend/imap/messages.go:44: undefined: imap.NewSeqSet
backend/imap/messages.go:159: undefined: imap.NewSeqSet
backend/imap/messages.go:389: undefined: imap.NewSeqSet
backend/imap/messages.go:532: undefined: imap.NewSeqSet
make: *** [start] Error 2

Thanks for any assistance!

problem with go imap compilation

Hi,

firstly, when I try:
$ go get -u github.com/emersion/neutron

I get:

# github.com/emersion/go-imap-idle
../go/src/github.com/emersion/go-imap-idle/client.go:28: cannot use res (type *Response) as type responses.Handler in argument to c.c.Execute:
	*Response does not implement responses.Handler (missing Handle method)
../go/src/github.com/emersion/go-imap-idle/response.go:13: undefined: imap.RespHandler
../go/src/github.com/emersion/go-imap-idle/response.go:27: select case must be receive, send or assign recv
../go/src/github.com/emersion/go-imap-idle/server.go:17: undefined: imap.ContinuationResp
# github.com/emersion/go-imap-quota
../go/src/github.com/emersion/go-imap-quota/client.go:28: invalid operation: c.c.State & imap.AuthenticatedState (mismatched types func() imap.ConnState and int)
../go/src/github.com/emersion/go-imap-quota/client.go:46: invalid operation: c.c.State & imap.AuthenticatedState (mismatched types func() imap.ConnState and int)
../go/src/github.com/emersion/go-imap-quota/client.go:56: cannot use res (type *Response) as type responses.Handler in argument to c.c.Execute:
	*Response does not implement responses.Handler (missing Handle method)
../go/src/github.com/emersion/go-imap-quota/client.go:72: invalid operation: c.c.State & imap.AuthenticatedState (mismatched types func() imap.ConnState and int)
../go/src/github.com/emersion/go-imap-quota/client.go:82: cannot use res (type *Response) as type responses.Handler in argument to c.c.Execute:
	*Response does not implement responses.Handler (missing Handle method)
../go/src/github.com/emersion/go-imap-quota/commands.go:100: undefined: utf7.Encoder in utf7.Encoder.String
../go/src/github.com/emersion/go-imap-quota/commands.go:119: undefined: utf7.Decoder in utf7.Decoder.String
../go/src/github.com/emersion/go-imap-quota/responses.go:78: undefined: imap.RespHandler
../go/src/github.com/emersion/go-imap-quota/responses.go:127: undefined: utf7.Decoder
../go/src/github.com/emersion/go-imap-quota/responses.go:155: undefined: imap.RespHandler
../go/src/github.com/emersion/go-imap-quota/responses.go:127: too many errors

My environment:

Ubuntu 17.10 64bit
go version go1.8.3 linux/amd64
nodejs --version v6.11.4
npm --version 3.5.2

secondly, when I try:
cd $GOPATH/src/github.com/emersion/neutron

I get:
bash: cd: /src/github.com/emersion/neutron: No such file or directory

Are you human?

I've setup an instance of neutron. After a bit of effort in the setup I've gotten to the point of creating an account.

I setup the account, it starts to generate keys, and then asks: Are you human? To fight spam, please verify you are human.

However, no Captcha loads. Any assistance is appreciated! Thank you.

HTML modifications

I am attempting to clean up a little bit of the HTML that references protonmail.com.

Making changes to /home/MYHOME/go/src/github.com/emersion/neutron/public/src/app/templates/partials

does not result in any changes. Specifically, I have tried to change the < Back to Protonmail link. To do so I opened header-no-auth.tpl.html and modified it.... but after saving it and restarting neutron I see no change.

I also attempted to modify app.html with no obvious changes. (For instance, changing Protonmail to Neutron as seen in https://gitlab.com/vpapadopou/neutronium/commit/69f31a93435d8c6fb1b6a707093d8456b7f84560)

Can anyone chime in as to what I'm missing here? Thank you!

IMAP support

Create backends to support IMAP servers.

  • Backend
    • Basic auth
  • MessagesBackend
    • Listing messages
    • Getting messages
    • Modifying messages flags/folders
    • Inserting messages
    • Updating messages content
    • Deleting messages
    • MIME support
  • AttachmentsBackend (saves temporary attachments to memory)
    • Reading attachments
    • Writing attachments
  • LabelsBackend (labels are IMAP folders)

encrypting incoming emails

This is just an enhancement idea, me thinking out loud. Unfortunately I don't know the internals of the Protonmail web client and I cannot contribute any usable code to neutron.

How could incomming emails be encrypted? Maybe by an LMTP server that sits between Postfix and Dovecot?

World --smtp--> Postfix --lmtp--> Neutron encryption --lmtp--> Dovecot local delivery

Does this make any sense? Could it work?

SRP support

The latest frontend uses SRP. Backends require a username and a password. How to make this work?

build error

I'm not sure if this is a neutron specific error, a bug in node-sass or something else. Any idea?

~/go/src/github.com/emersion/neutron # make build-client
cd public && \
npm install && \
node_modules/.bin/grunt ngconstant:dev build
npm WARN deprecated [email protected]: ..psst! While Bower is maintained, we recommend Yarn and Webpack for *new* front-end projects! Yarn's advantage is security and reliability, and Webpack's is support for both CommonJS and AMD projects. Currently there's no migration path, but please help to create it: https://github.com/bower/bower/issues/2467
npm WARN deprecated [email protected]: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
npm WARN deprecated [email protected]: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
npm WARN deprecated [email protected]: graceful-fs v3.0.0 and before will fail on node releases >= v7.0. Please update to graceful-fs@^4.0.0 as soon as possible. Use 'npm ls graceful-fs' to find it in the tree.
npm WARN deprecated [email protected]: Use uuid module instead
npm WARN deprecated [email protected]: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
npm WARN deprecated [email protected]: Jade has been renamed to pug, please install the latest version of pug instead of jade
npm WARN deprecated [email protected]: Deprecated, use jstransformer
npm WARN prefer global [email protected] should be installed with -g
npm WARN prefer global [email protected] should be installed with -g

> [email protected] install /root/go/src/github.com/emersion/neutron/public/node_modules/node-sass
> node scripts/install.js

Downloading binary from https://github.com/sass/node-sass/releases/download/v3.13.1/linux-x64-48_binding.node
Download complete  ] - :
Binary saved to /root/go/src/github.com/emersion/neutron/public/node_modules/node-sass/vendor/linux-x64-48/binding.node
Caching binary to /root/.npm/node-sass/3.13.1/linux-x64-48_binding.node

> [email protected] install /root/go/src/github.com/emersion/neutron/public/node_modules/phantomjs-prebuilt
> node install.js

PhantomJS not found on PATH
Downloading https://github.com/Medium/phantomjs/releases/download/v2.1.1/phantomjs-2.1.1-linux-x86_64.tar.bz2
Saving to /tmp/phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2
Receiving...
  [===================================-----] 89%
Received 22866K total.
Extracting tar contents (via spawned process)
Removing /root/go/src/github.com/emersion/neutron/public/node_modules/phantomjs-prebuilt/lib/phantom
Copying extracted folder /tmp/phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2-extract-1499588103438/phantomjs-2.1.1-linux-x86_64 -> /root/go/src/github.com/emersion/neutron/public/node_modules/phantomjs-prebuilt/lib/phantom
Writing location.js file
Done. Phantomjs binary available at /root/go/src/github.com/emersion/neutron/public/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs

> [email protected] postinstall /root/go/src/github.com/emersion/neutron/public/node_modules/node-sass
> node scripts/build.js



make: *** [Makefile:7: build-client] Error 1

Get 404 /auth/modulus when trying to create a user

Trying to create a user but is unable to do so from the /create/new path. Then I press the button on the capcha step it fails 404 because it tries to get /auth/modulus and this path does not exist.

@emersion:
Is there any other way to create a user, for example create the user directly in the database?

Seems like a great project if I could just get it up and running!

Thanks!

how to use it with other rest client?

we want to build a webmail with angular2, so we need to create an imap-to-http api server,
how can i use this project to build this server or how to disable proton-webmail related encryption features?

Unsure on config for "sub-slug-URI"

I've installed from deb, and I've reverse-proxied from nginx on mysite.tld/mailn - but when visiting the page, it tries to load js from mysite.tld/src/... (apparantly developer-mode?) instead of mysite.tld/mailn/src/....
I didn't figure out where to tell neutronmail that it's on a sub-slug (/mailn/), since it doesn't seem to investigate its path it self.

Also, the packager page (https://packager.io/gh/emersion/neutron) shows all builds as failed since 4 months back, so I don't know if I'm running the latest version (couldn't figure out how to get the neutronmail binary to tell me the version either)

Fedora 28 - "conn.go:173:12: error: incompatible types in assignment"

Hi guys, at first command get a problem, this is what I've got

`$

go get -u github.com/emersion/neutron

github.com/emersion/neutron/backend/imap

go/src/github.com/emersion/neutron/backend/imap/conn.go:173:12: error: incompatible types in assignment
c.Updates = updates
^
`
I was looking for similar issues but with no luck.
Greetings

Invalid POST /api/contacts response

When creating contacts, a BatchResp is returned. Not the excepted behaviour.

{
    "Code": 1001,
    "Responses": [
        {
            "Name": "Sauce",
            "Email": "[email protected]",
            "Response": {
                "Contact": {
                    "ID": "93pX_VKTJLQmTF5kGEiswkepD3y_RXb701pI5OVDdj4qMYMuWwYX7dV1HjjUKI0wFNYUK3mDNVvy8XcDunGMSg==",
                    "Name": "Sauce",
                    "Email": "[email protected]"
                },
                "Code": 1000
            }
        }
    ]
}

Creating Account -> Creating New Account

I've installed the code, but when I go to create a new account I get to:

Creating account

Generating keys
Creating new account
Logging in to new account
Setting up new account
Done
Redirecting

It crashes at Creating new account. There's a checkmark next to Generating Keys and Creating New account.... but then a crash (server side). Any insight? Thank you!

Sign up on the login page and enter your IMAP credentials?

The readme states that the following action needs to be performed in order to generate keys:

To generate keys for a new user the first time, just click Sign up on the login page and enter your IMAP credentials.

However, there is no such "Sign up" link on the login page. The only Sign up button is the one redirecting to protonmail.com/signup. Also directly accessing the "/signup" page doesn't work and redirect the user to "/login".

Login 404s

So, I got a backend (neutron) running and I got a frontend (the forked WebClient) running. But any attempt to authenticate results in a 404 from the backend.

[Macaron] 2018-01-07 21:26:47: Started OPTIONS /api/auth/info for 172.17.0.1
[Macaron] 2018-01-07 21:26:47: Completed OPTIONS /api/auth/info 404 Not Found in 127.443µs
[Macaron] 2018-01-07 21:26:47: Started OPTIONS /api/bugs/crash for 172.17.0.1
[Macaron] 2018-01-07 21:26:47: Completed OPTIONS /api/bugs/crash 404 Not Found in 112.76µs

That's using a username and password that authenticate just fine in my IMAP client.

Also, I created a gpg public/private keypair neutron/db/keys/<my-domain>.org/<my-username>.{pub,priv}.gpg

Is there something else I have to do to make neutron able to authenticate me?

receiving emails (how does it work? documentation)

I don't understand how a full setup for receiving and sending emails works.

For sending emails, neutron uses an external smtp server. (?)

How does it receive emails? What is stored on the IMAP server? encrypted or unencrypted emails?

Is the stored data (emails) fully encrypted?

Basic REST endpoints

See https://github.com/ProtonMail/WebClient/blob/v3/postman.json

attachments

  • GET /api/attachments/:id
  • POST /api/attachments/upload
  • PUT /api/attachments/remove

bugs

  • POST /api/bugs/crash

contacts

  • GET /api/contacts
  • POST /api/contacts
  • PUT /api/contacts/:id
  • PUT /api/contacts/delete
  • DELETE /api/contacts

conversations

  • GET /api/conversations
  • GET /api/conversations/count
  • GET /api/conversations/:id
  • PUT /api/conversations/read, /api/conversations/unread
  • PUT /api/conversations/star, /api/conversations/unstar
  • PUT /api/conversations/trash, /api/conversations/inbox, /api/conversations/spam, /api/conversations/archive
  • PUT /api/conversations/delete
  • PUT /api/conversations/label

domains

  • GET /api/domains/available

events

  • GET /api/events/:id
  • GET /api/events/latest

keys

  • PUT /api/keys/private

labels

  • GET /api/labels
  • POST /api/labels/apply/:id
  • PUT /api/labels/remove/:id
  • PUT /api/labels/order
  • POST /api/labels
  • PUT /api/labels/:id
  • DELETE /api/labels/:id

messages

  • GET /api/messages
  • GET /api/messages/count
  • GET /api/messages/total
  • GET /api/messages/:id
  • POST /api/messages/send/:id
  • PUT /api/messages/read, /api/messages/unread
  • PUT /api/messages/star, /api/messages/unstar
  • POST /api/messages/draft
  • PUT /api/messages/draft/:id
  • PUT /api/messages/trash, /api/messages/inbox, /api/messages/spam, /api/messages/archive
  • PUT /api/messages/delete
  • PUT /api/messages/label
  • DELETE /api/messages/draft
  • DELETE /api/messages/spam
  • DELETE /api/messages/trash

settings

  • PUT /api/settings/password
  • PUT /api/settings/signature
  • PUT /api/settings/display
  • PUT /api/settings/addressorder
  • PUT /api/settings/theme
  • PUT /api/settings/autosave
  • PUT /api/settings/composermode
  • PUT /api/settings/messagebuttons
  • PUT /api/settings/showimages
  • PUT /api/settings/viewlayout
  • PUT /api/settings/viewmode ?

users

  • GET /api/users
  • GET /api/users/:id
  • GET /api/users/pubkeys/:email (email is base64-encoded)
  • GET /api/users/direct
  • GET /api/users/available/:username

auth

  • POST /api/auth
  • POST /api/auth/cookies
  • DELETE /api/auth

Changes to go-imap API

It looks like the go-imap API has changed, and so "go get -u github.com/emersion/neutron" doesn't work anymore.

I started to try to fix it, but it looks like you (emersion) are the maintainer of go-imap, so you might be able to do it faster or more correctly than I am.

root@fb04f9e472e0:/go# go get -u github.com/emersion/neutron
# github.com/emersion/neutron/backend/imap
src/github.com/emersion/neutron/backend/imap/attachments.go:46:21: cannot use items (type []string) as type []imap.FetchItem in argument to c.Client.UidFetch
src/github.com/emersion/neutron/backend/imap/attachments.go:56:55: cannot use "BODY[" + partId + "]" (type string) as type *imap.BodySectionName in argument to data.GetBody
src/github.com/emersion/neutron/backend/imap/conn.go:105:13: invalid operation: c.Client.State & imap.ConnectedState (mismatched types func() imap.ConnState and imap.ConnState)
src/github.com/emersion/neutron/backend/imap/conn.go:154:34: c.Client.Mailbox.Name undefined (type func() *imap.MailboxStatus has no field or method Name)
src/github.com/emersion/neutron/backend/imap/conn.go:174:21: c.MailboxUpdates undefined (type *conn has no field or method MailboxUpdates)
src/github.com/emersion/neutron/backend/imap/conn.go:185:21: c.Expunges undefined (type *conn has no field or method Expunges)
src/github.com/emersion/neutron/backend/imap/conn.go:286:34: c.Client.Mailbox.Name undefined (type func() *imap.MailboxStatus has no field or method Name)
src/github.com/emersion/neutron/backend/imap/events.go:39:22: c.Client.Mailbox.Name undefined (type func() *imap.MailboxStatus has no field or method Name)
src/github.com/emersion/neutron/backend/imap/events.go:44:32: cannot use []string literal (type []string) as type []imap.FetchItem in argument to c.Client.Fetch
src/github.com/emersion/neutron/backend/imap/events.go:44:33: undefined: imap.UidMsgAttr
src/github.com/emersion/neutron/backend/imap/events.go:44:32: too many errors

SMTP support

  • Basic support
  • MIME support
  • Attachments support

Cannot use update (type chan interface {})

Hi. On Ubuntu 18.04, I get:

$ go version
go version go1.10.4 linux/amd64
$ nodejs --version
v8.10.0
$ npm --version
6.10.0
$ go get -u github.com/emersion/neutron
# github.com/emersion/neutron/backend/imap
../../go/src/github.com/emersion/neutron/backend/imap/conn.go:173:12: cannot use updates (type chan interface {}) as type chan<- client.Update in assignment

Advanced REST API endpoints

addresses

  • POST /api/addresses
  • PUT /api/addresses/:id
  • PUT /api/addresses/:id/enable, /addresses/:id/disable
  • DELETE /api/addresses/:id

domains

  • GET /api/domains
  • POST /api/domains
  • GET /api/domains/:id
  • DELETE /api/domains/:id

eo

  • GET /api/eo/token/:id
  • GET /api/eo/message (headers x-eo-uid and authorization)
  • GET /api/eo/attachment/:id (headers x-eo-uid and authorization)
  • POST /api/eo/reply (headers x-eo-uid and authorization)

keys

  • POST /api/keys
  • POST /api/keys/reset
  • POST /api/keys/order
  • PUT /api/keys/:id
  • DELETE /api/keys/:id

logs

  • GET /api/logs/auth
  • DELETE /api/logs/auth

settings

  • PUT /api/settings/noticeemail
  • PUT /api/settings/notify
  • PUT /api/settings/language
  • PUT /api/settings/logauth

members

  • GET /api/members
  • POST /api/members
  • GET /api/members/:id
  • DELETE /api/members/:id
  • PUT /api/members/:id/nickname
  • PUT /api/members/:id/quota
  • PUT /api/members/:id/role
  • PUT /api/members/:id/password
  • PUT /api/members/:id/private
  • POST /api/members/auth
  • DELETE /api/members/auth

memberkeys

organizations

  • GET /api/organizations
  • POST /api/organizations
  • GET /api/organizations/keys
  • PUT /api/organizations
  • PUT /api/organizations/keys/private
  • PUT /api/organizations/payment
  • DELETE /api/organizations

payments

  • GET /api/payments/plans
  • GET /api/payments/subscription
  • GET /api/payments/methods

users

  • PUT /api/users/keys
  • POST /api/users/:token
  • POST /api/users/code
  • PUT /api/users/lock ?
  • PUT /api/users/unlock ?

auth

  • POST /api/auth/refresh

reset

  • POST /api/reset
  • POST /api/reset/:token
  • POST /api/reset/mailbox
  • POST /api/reset/mailbox/:token
  • GET /api/reset/:username/:token

misc

  • PUT /api/tests/error

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.