fnakstad / angular-client-side-auth Goto Github PK
View Code? Open in Web Editor NEWOne way to implement authentication/authorization in Angular applications
Home Page: http://angular-client-side-auth.herokuapp.com/
License: MIT License
One way to implement authentication/authorization in Angular applications
Home Page: http://angular-client-side-auth.herokuapp.com/
License: MIT License
The Active Tab 'Private' is not displayed when selecting /private/nested/ or /private/admin/ on top of the page.
It should be possible to filter the users listed on the admin page by user role.
I'm working on a project where we want to use the stable angular version 1.0.7. I tried running this project as is locally and it works. But when I downgrade the angular version in index.jade to 1.0.7 the nav bar components do not display. It seems that the directive is always returning display:none.
I debugged into Auth.authorize in services.js:
authorize: function(accessLevel, role) {
Both accessLevel and role are always undefined.
How to make it work with angular 1.0.7?
Since bitmasks of user roles and access levels are generated on the fly, they can differ if items in their respective arrays are moved around. This can become a huge problem if a user's role (the Number value) is persisted to the database, then the array items are moved around, leading to each role getting a different bitmask from what has previously been stored in the database. This can be rectified by storing the String value of the role (or some other kind of unique identifier) instead of the Number value.
Hello,
I love this piece of code you wrote and really like that you make it better everytime.
I got one question.. i am not a fan of jade, i prefer pure html. I'm not having any success modifying the code to just load html rather than jade.
Any tips from you please? would be really appreciated.
What's wrong running this under IE9? :
TypeError: Unable to get property 'bitMask' of undefined or null referenceundefined
Hello Frederik,
how are you doing? I see your app is already ready to use in a production software :-) . Good job!
Anyway, I played with the application a bit and I am here to give you some points or questions: as you already implemented "Remember me" functionality for "local strategy" logins, did you consider also this with other strategies like "Facebook", "Twitter" etc.?
It seems, it does not work now when I checked "Remember Me" while logging via Facebook, I do not know if this is possible to get "Remeber Me" directly from those providers via callbacks. If not, it would be nice some hints how to do it locally within the application. Thank you.
Regards
Kahramon.
Hey, first of all gotta say I love your method of authentication. I integrated your code, and made a cookie similar to yours
user=%7B%22username%22%3A%[email protected]%22%2C%22role%22%3A%7B%22bitMask%22%3A4%2C%22title%22%3A%22admin%22%7D%7D; connect.sess=s%3Aj%3A%7B%22passport%22%3A%7B%7D%7D.Y%2FN8%2F6JZIdX2TJ%2BTKGLvw0Fxbthv7AppwHR0GLB0EpI
But when I try to login in, it breaks at
return accessLevel.bitMask & role.bitMask;
in the service 'Auth' and in the app.js file on the run function
if (!Auth.authorize(next.access)) {
if(Auth.isLoggedIn()) $location.path('/');
else $location.path('/login');
}
any help would be much appreciated.
-Aman
In https://github.com/fnakstad/angular-client-side-auth/blob/master/client/js/controllers.js:
You reference $rootScope but you do not inject it.
Secondly you directive just works in Navigation Controller, because userRoles and accessLevels are only defined in the scope of the Navication Controller.
I solved both issues by injecting rootScope and assigning userRoles and accessLevels there.
Maybe it would be a good idea ad the user to the rootScope.
BR, Rene
Hi, Your application is using Jade engine which is working fine.
I was looking for a solution to use same app work with angularjs templating and routing. Made all the necessary changes except boiled down to one problem in routes.js which handles routing path: '/*' & path: '/partials'. I explain that in 2 parts.
Part 1 :
In below code http://localhost:3000/ trigger path: '/*' route and do the proper cookie setting which is fine after that need to redirect like res.redirect('/') which result redirected to /login. Now read Part 2 below.
{
path: '/*',
httpMethod: 'GET',
middleware: [function(req, res) {
res.redirect('/');
}],
accessLevel: accessLevels.public
}
Part 2:
After Part 1, first time path: '/' route is triggered. After that path: '/partials' is called for every link on the tab to render pages. path: '/partials' is MUST route to stop triggering path: '/' route.
Question : What should be in response in the below route because I can not use res.render(requestedView) as my pages are .html and if I use redirect(req.url) that creates loop?
Question: I even unable to hit path: '/partials' and always trigger path: '/*'. So what to do.?
{
path: '/partials',
httpMethod: 'GET',
middleware: [function (req, res) {
var requestedView = path.join('./', req.url);
res.render(requestedView);
}],
accessLevel: accessLevels.public
}
I will be grateful if you help.
In client/views/index.jade
the initial !!! 5
in the very first line causes an error when the server is started. It should be replaced by a doctype
declaration.
Hi,
Thanks for this great repo, you've solved a piece of the puzzle that's been a bit difficult for me to resolve. To that end I've included credits in my repo which uses another repo plus my dependency on a Firebird Sql database.
John
https://github.com/johntom/Angular-Passport-Auth-SIO
Hello,
just noticed that if i enter a wrong username/password i get the following error on server console:
Error: failed to serialize user into session
at pass (/home/sites/angular-client-side-auth/node_modules/passport/lib/passport/index.js:267:19)
at /home/sites/angular-client-side-auth/node_modules/passport/lib/passport/index.js:271:36
at serializeUser (/home/sites/angular-client-side-auth/models/User.js:66:5)
at pass (/home/sites/angular-client-side-auth/node_modules/passport/lib/passport/index.js:271:7)
at Passport.serializeUser (/home/sites/angular-client-side-auth/node_modules/passport/lib/passport/index.js:275:5)
at IncomingMessage.req.login.req.logIn (/home/sites/angular-client-side-auth/node_modules/passport/lib/passport/http/request.js:43:29)
at /home/sites/angular-client-side-auth/routes.js:21:21
at allFailed (/home/sites/angular-client-side-auth/node_modules/passport/lib/passport/middleware/authenticate.js:87:18)
at attempt (/home/sites/angular-client-side-auth/node_modules/passport/lib/passport/middleware/authenticate.js:231:28)
at Context.delegate.fail (/home/sites/angular-client-side-auth/node_modules/passport/lib/passport/middleware/authenticate.js:226:9)
And if i press the LOGIN multiple times forever seems to stop the script.
Any idea please?
First off - thanks so much for this project - it is greatly appreciated!
Not sure of this is an issue or not, but when listing accessLevels, I notice that the title seems to be the last role declared in the array, e.g.
Config:
accessLevels: {
'public': '*',
'anon': ['public'],
'user': ['user', 'userpro', 'admin'],
'userpro': ['userpro', 'admin'],
'admin': ['admin']
}
Resulting accessLevels:
{ public: { bitMask: 15, title: '*' },
anon: { bitMask: 1, title: 'public' },
user: { bitMask: 14, title: 'admin' },
userpro: { bitMask: 12, title: 'admin' },
admin: { bitMask: 8, title: 'admin' } }
As you can see, admin is the tile for the last three access levels. I was wondering if thIs was deliberate or whether it was a bug?
Thanks, Rob
I just modified the local strategy to support database backing, Users.find gets the user and the inside the callback, I moved the corresponding code. After I moved this, When i login, the home screen does not come. If i refresh the screen, then it home screen appears. I am not sure if it is a client side or server side issue. I am new to node and any suggestions on how to debug will also be very helpful.
The Users objects is sequelize orm mapping for the table that stores user info.
localStrategy: new LocalStrategy(
function(username, password, done) {
Users.find({ where: {username: username} }).success(function(user){
console.log('super')
if(!user) {
done(null, false, { message: 'Incorrect username.' });
}
else if(user.password != password) {
done(null, false, { message: 'Incorrect username.' });
}
return done(null, user);
}).error(function(err){
console.log('error in LocalStrategy',err);
});
}
)
how to solve the below issue
root@ahker:~/www/angular-client-side-auth-master# npm start
[email protected] start /home/vinoth/www/angular-client-side-auth
-master
node server.js
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: Cannot find module 'express'
at Function._resolveFilename (module.js:332:11)
at Function._load (module.js:279:25)
at Module.require (module.js:354:17)
at require (module.js:370:17)
at Object. (/home/vinoth/www/angular-client-side-auth-master/serv
er.js:1:83)
at Module._compile (module.js:441:26)
at Object..js (module.js:459:10)
at Module.load (module.js:348:32)
at Function._load (module.js:308:12)
at Array.0 (module.js:479:10)
npm ERR! [email protected] start: node server.js
npm ERR! sh "-c" "node server.js"
failed with 1
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is most likely a problem with the angular-client-side-auth package
,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node server.js
npm ERR! You can get their info via:
npm ERR! npm owner ls angular-client-side-auth
npm ERR! There is likely additional logging output above.
npm ERR!
npm ERR! System Linux 3.2.0-55-generic
npm ERR! command "node" "/usr/bin/npm" "start"
npm ERR! cwd /home/vinoth/www/angular-client-side-auth-master
npm ERR! node -v v0.6.12
npm ERR! npm -v 1.1.4
npm ERR! code ELIFECYCLE
npm ERR! message [email protected] start: node server.js
npm ERR! message sh "-c" "node server.js"
failed with 1
npm ERR! errno {}
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /home/vinoth/www/angular-client-side-auth-master/npm-debug.log
npm not ok
root@ahker:~/www/angular-client-side-auth-master# npm install express
npm http GET https://registry.npmjs.org/express
npm http 304 https://registry.npmjs.org/express
npm http GET https://registry.npmjs.org/connect/2.9.1
npm http GET https://registry.npmjs.org/commander/2.0.0
npm http GET https://registry.npmjs.org/range-parser/0.0.4
npm http GET https://registry.npmjs.org/cookie/0.1.0
npm http GET https://registry.npmjs.org/buffer-crc32/0.2.1
npm http GET https://registry.npmjs.org/mkdirp/0.3.5
npm http GET https://registry.npmjs.org/fresh/0.2.0
npm http GET https://registry.npmjs.org/methods/0.0.1
npm http GET https://registry.npmjs.org/send/0.1.4
npm http GET https://registry.npmjs.org/cookie-signature/1.0.1
npm http GET https://registry.npmjs.org/debug
npm http 304 https://registry.npmjs.org/range-parser/0.0.4
npm http 304 https://registry.npmjs.org/cookie/0.1.0
npm http 304 https://registry.npmjs.org/commander/2.0.0
npm http 304 https://registry.npmjs.org/connect/2.9.1
npm http 304 https://registry.npmjs.org/buffer-crc32/0.2.1
npm http 304 https://registry.npmjs.org/mkdirp/0.3.5
npm http 304 https://registry.npmjs.org/fresh/0.2.0
npm http 304 https://registry.npmjs.org/methods/0.0.1
npm http 304 https://registry.npmjs.org/send/0.1.4
npm http 304 https://registry.npmjs.org/cookie-signature/1.0.1
npm http 304 https://registry.npmjs.org/debug
npm ERR! error installing [email protected]
npm ERR! error rolling back [email protected] Error: UNKNOWN, unknown error '/home/v
inoth/www/angular-client-side-auth-master/node_modules/express'
npm ERR! Unsupported
npm ERR! Not compatible with your version of node/npm: [email protected]
npm ERR! Required: {"node":">= 0.8.0"}
npm ERR! Actual: {"npm":"1.1.4","node":"0.6.12"}
npm ERR!
npm ERR! System Linux 3.2.0-55-generic
npm ERR! command "node" "/usr/bin/npm" "install" "express"
npm ERR! cwd /home/vinoth/www/angular-client-side-auth-master
npm ERR! node -v v0.6.12
npm ERR! npm -v 1.1.4
npm ERR! code ENOTSUP
npm ERR! message Unsupported
npm ERR! errno {}
npm http GET https://registry.npmjs.org/mime
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /home/vinoth/www/angular-client-side-auth-master/npm-debug.log
npm not ok
root@ahker:~/www/angular-client-side-auth-master#
I'm trying to adapt your code to store users in a MongoDB database using Mongoose.
What I'm having trouble with is req.user on the server side code. It ends up as
{ options: {},
safe: undefined,
_conditions: { _id: 53395f1e44908fd4cb9f0fbe },
_updateArg: {},
_fields: undefined,
_geoComparison: undefined,
op: 'findOne',
model:
{ [Function: model]
base: [Object],
modelName: 'User',
model: [Function: model],
db: [Object],
findByUsername: [Function],
schema: [Object],
options: undefined,
collection: [Object] } }
rather than something like
{ id: 1,
username: 'user',
password: '123',
role: { bitMask: 2, title: 'user' } }
as it is when I run your code.
My inference is that it is being set as a Mongoose object, but I can't figure out where it is being set in order to ensure that it is set properly. Can you perhaps point me in the right direction?
Any insight would be appreciated. When I get it working, I'll put the code up on github as a fork of your code.
Sorry for writing an issue here but don't know how to ask a question. I'm trying to implement ui-router insteed of default angualr's $routeProvider. It is possible to switch them? Because I have a serious problem to force it to work.
Hi i really like your auth code and I am using it as a template for my project.
I was wondering what would be the best way to keep the username accessible through my custom Controllers.
I saw that I can use $rootScope.userRole to get the userRole in my controllers but what would be an efficient way to keep username?
i tried a UserDetails factory that keeps the username. it worked until i do a refresh of the page (F5) then i loose the username value.
any idea please?
Hello! What a wonderful repo, thank you for making this available.
One thing I am curious about:
is there a particular reason you are using _.extend
in the Auth
factory?
https://github.com/fnakstad/angular-client-side-auth/blob/master/client/js/services.js#L13
My own personal preference is to use angular.extend
simply to reduce external dependencies wherever I can. But I was wondering if there are any arguments for using the underscore extend instead? Am I missing out on anything by using 'angular.extend'? Looking at the source for both, they seem functionally equivalent.
All things equal, angular.extend is technically faster.
http://jsperf.com/angular-extend-vs-underscore-extend/
http://jsperf.com/angular-extend-vs-underscore-extend/5
Thank you!
Hello,
I'm building an application where i would have API calls like this:
/api/1/messages
/api/1/message/1
/api/1/projects
but when i issue those calls in AngularJS using the $http.get command... seems like AngularJS is taking the request and showing me a 404 page and not passing the request to the server side.
what would be the best way to tackle that?
Hello Frederik,
a) I noted that if we want register already registered user, for example "admin" as a normal user, it behaves like we registered -> may be it can be fixed something like we get alert "you cannot register already registered user".
b) I would one suggestion to your app here: you can implement also "Remember me" functionality to do your app more usable. However, this is not so important and your app is still simple clever and thank you!
Kahramon
Add Twitter and Facebook login options.
I was studying your app for learning. I was trying to remove accessLevel and keep role based authentication. But app is not displaying proper menu items for logged in user. I was wondering if you could help.
Is there any use of binary numbers in the app?
any specific changes to make only roles work and remove access level which is confusing. I did most of the changes and app working fine but menu is no working properly?
exports.userRoles = {
public: 1, // 001
user: 2, // 010
admin: 4 // 100
};
exports.accessLevels = {
public: 7, // 111
anon: 1, // 001
user: 6, // 110
admin: 4 // 100
};
I'm in the middle of migrating from ngroute to ui-router, and am trying to figure out the best way to handle things when it comes to nested views and other ui-router features. Since a lot of people following this repo have requested this feature and are using ui-router in various projects, I'm hoping you all can help me with some comments and ideas on how you want this to work. Clone the new branch, ui-router-migration, to test it out. This is how my proposed solution works as of now:
The access
property must now be set as a child of the data property. An excellent side-effect of this is that child views inherit access properties from their parents while still offering to set them explicitly. This means you can now organise your application into “areas” which define the access restrictions for all nested views by making said states abstract and adding a basic template where you just insert a ui-view
tag. Here’s an example of how it looks like:
// Regular user routes
$stateProvider
.state('user', {
abstract: true,
template: "<ui-view/>",
data: {
access: access.user
}
})
.state('user.home', {
url: '/',
templateUrl: 'home'
})
.state('user.private', {
abstract: true,
url: '/private/',
templateUrl: 'private/layout'
})
.state('user.private.home', {
url: '',
templateUrl: 'private/home'
})
.state('user.private.nested', {
url: 'nested/',
templateUrl: 'private/nested'
})
.state('user.private.admin', {
url: 'admin/',
templateUrl: 'private/nestedAdmin',
data: {
access: access.admin
}
});
Another change is in the $stateChangeStart handler which has been updated to handle unauthorized accesses in a slightly different manner:
$rootScope.$on("$stateChangeStart", function (event, toState, toParams, fromState, fromParams) {
if (!Auth.authorize(toState.data.access)) {
event.preventDefault();
if(fromState.url === '^') {
if(Auth.isLoggedIn()) $state.go('user.home');
else $state.go('anon.login');
}
$rootScope.error = "Seems like you tried accessing a route you don't have access to...";
}
});
Instead of simply redirecting you, it now prevents the state change and pops up an error message. If the navigation is the result of a full page reload however, it will additionally redirect you to an appropriate state depending on login status.
Please give me input on what you think about this approach, and come with any other suggestions about things that should be included before merging this into master. Many of you have worked with UI-Router much longer than I, so I’d be very interested to hear more about the different ways it is used :)
Hello Frederik,
I am back here to give you some other suggestions to your app to do it more better and realistic:-)
I think, these points are very easy to you to realize:
a) while registering there could be additional input "Confirm password".
b) more importantly I would welcome some extentions on the $http methods($http.get, $http.put, $http.delete..).
I give your this scenario: when admin logges in, he can see the "Users" tab in the navigation panel, there he can get all registered users($http.get(/users)), when click on a user name he get the details of the user or delete the user via "Delete" button. This is all and we will have complete $http methods.
Thank You!
Kahramon.
Inexistent urls raises exception in authorize method of https://github.com/fnakstad/angular-client-side-auth/blob/master/client/js/services.js#L17 caused by an empty accessLevel parameter.
Try to load any 404 url to see this error in console, for example:
http://angular-client-side-auth.herokuapp.com/asdasd
As of today the menu items as well as the upper right user info section is shown based on the current user role. However, it would be easier if this could be defined by an attribute directive. This would also prove useful for people thinking of adapting the solution to their own projects. Here's an example of how it could work in the views:
<div id="secretItem" data-access-level="accessLevels.admin"></div>
.
This is a very simple mistake that I made, but it could potentially come up in production and its a browser crashing one.
I overlooked the fact that Angular's templateUrls for its routes.js are defined at the bottom of index.jade. When I tried creating a new view and simply using "new_page" for the templateUrl in routes.js (thinking Express was working some file type independent magic), Angular would route to "new_page", which would cause the server to respond with its "catch-all" which is "index". This loads Angular again, and the cycle continues until the browser crashes or stops the script.
Obviously in this case it was just a stupid mistake, but I feel like it should have defaulted to a 404, or something more graceful. I feel like this has the potential of happening in production... Any thoughts on how to catch this loop if it happens?
To reproduce the problem, first you log on with admin/123, then click Log out from the nav. Now, click on the Twitter login button but DO NOT login, simply click the Back button on IE, you will see the user is still logged in.
The problem is IE writes the existing cookie when you go back to previous page.
Hi,
I went through your code (great work!) and I do not see any code that redirects to login page on page load.
You have the
$rootScope.$on("$routeChangeStart", function (event, next, current)
but this is only relevant when route changes, right? Where is the code that checks if there is a logged in user on initial page load?
regards
Using your authorization system, I am asked to save my username/pwd on FF. However, on Chrome, this is not the case.
Popular solutions to this problem for ajax-based logins utilize a hidden iframe (e.g., https://gist.github.com/kostiklv/968927) but that does not prevent the page from being reloaded, which defeats the whole purpose of an SPA.
I would be very interested to hear your thoughts on how to address this issue - it seems very odd to me that Chrome, developed by the same company that made AngularJS, doesn't play well with SPAs in this regard.
When I clicked on the Twitter button to direct to Twitter's login page, It threw the error "failed to obtain request token" instead. I had added the Twitter consumer key and secret yet (The one created in https://dev.twitter.com/apps). The Google works fine. I haven't checked Facebook and Linkedin yet.
I googled the error and they tell me to change the server's clock, but I'm using windows localhost and my clock still be accurate.
Any help would be appreciated.
Per comment from Matthew:
Thanks for taking the time to post your solution online! I implemented it this afternoon and it works nicely. I modified register.jade so that it does not show validation errors when you first click on it. Once you start to type in the fields it performs the validation and if invalid, the messages show. I like suppressing validation messages until the user starts to type. Here is what I changed (I added registerForm.$dirty &&):
.alert.alert-error(ng-show="registerForm.$dirty && registerForm.$invalid")
Your code is simple and very clear but it really needs a reference tag to identify your major releases.
I'm considering switching to ui-router branch and it was hard to figure what was your improvement.
By the way : thank you very much for this great work
Page /login should be restrict for authorized users.
ok, and if i open something like /auth/twitter this will authorize me again.
users-Mac:angular-client-side-auth-master user$ npm start
[email protected] start /Users/user/Documents/Proyects/angular-client-side-auth-master
grunt dev
sh: grunt: command not found
npm ERR! [email protected] start: grunt dev
npm ERR! Exit status 127
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is most likely a problem with the angular-client-side-auth package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! grunt dev
npm ERR! You can get their info via:
npm ERR! npm owner ls angular-client-side-auth
npm ERR! There is likely additional logging output above.
npm ERR! System Darwin 13.0.0
npm ERR! command "/usr/local/Cellar/node/0.10.25/bin/node" "/usr/local/bin/npm" "start"
npm ERR! cwd /Users/user/Documents/Proyects/angular-client-side-auth-master
npm ERR! node -v v0.10.25
npm ERR! npm -v 1.3.24
npm ERR! code ELIFECYCLE
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /Users/user/Documents/Proyects/angular-client-side-auth-master/npm-debug.log
npm ERR! not ok code 0
users-Mac:angular-client-side-auth-master user$
The way the routingConfig
is utilized today smells a little bit... Maybe use .constant()
to set userRoles
and accessLevels
?
Let me thank you first for this implementation, but I am getting SyntaxError: Unexpected token '<' in the browser console while trying to run locally. Tried both in bot mac and windows. Am I missing something?
Some simple validation should be added on both the server and client side to regulate username/password length, and make sure that a valid role has been selected. On the server side this can be aided by chriso/node-validator
.
Hello,
I was trying to do something like:
$routeProvider.when('/private/:destination',
but angular seems to crash and i cant get the value of $routeParams.destination. The code for this routing is quite simple but i can't seem to find where its going wrong. any ideas please?
hi fred,
wondering if you have considered accounting for xsrf at all in this scheme?
regards,
tony.
Hello,
I'm implementing something based in your code, thanks :)
I was thinking, maybe it would be a good idea to pass the rootScope manipulation logic for inside the Auth service ? Whenever a login or a logout is made, we always need to set these variables.
What do you think ?
I think a great enhancement would be to include a Rights profile per role along with the ability to dynamically create new Roles / Rights. For instance you can create a duplicate User Role {User2} that has rights to login but maybe cannot view the nested menu.
The admin could duplicate Roles / Rights and then modify the access rights.
Hello,
I'm trying to build a small web app based on this project. Is it possible you could provide a example of how to test 'when a user logs in and then goes to /private'?
((To be more clear... Test one would be 'log user in'. Test two is 'user goes to /private')))
Basically, i'm able able to log in, but after that i'm having trouble mocking authenticated passport.js users in my tests.
I've been trying to use this module. https://github.com/steventux/passport-stub
Thank you ahead of time!
Edit: End goal is to have the function 'ensureAuthorized' to have valid data in 'req.user' so I can test a route that has a accessLevel higher then public. (Like an admin only POST request)
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.