diff --git a/src/generators/app/index.js b/src/generators/app/index.js
index a28f5336c..4bc786152 100644
--- a/src/generators/app/index.js
+++ b/src/generators/app/index.js
@@ -262,6 +262,10 @@ export class Generator extends Base {
message: 'Would you like to include additional oAuth strategies?',
when: answers => answers.auth,
choices: [{
+ value: 'githubAuth',
+ name: 'GitHub',
+ checked: false
+ }, {
value: 'googleAuth',
name: 'Google',
checked: false
@@ -317,6 +321,7 @@ export class Generator extends Base {
});
}
insight.track('oauth', !!this.filters.oauth);
+ insight.track('github-oauth', !!this.filters['githubeAuth']);
insight.track('google-oauth', !!this.filters['googleAuth']);
insight.track('facebook-oauth', !!this.filters['facebookAuth']);
insight.track('twitter-oauth', !!this.filters['twitterAuth']);
diff --git a/src/test/main.test.js b/src/test/main.test.js
index 79dbfff5d..454c67c11 100644
--- a/src/test/main.test.js
+++ b/src/test/main.test.js
@@ -197,7 +197,7 @@ describe('angular-fullstack:app', function() {
testing: 'jasmine',
odms: ['mongoose'],
auth: true,
- oauth: ['twitterAuth', 'facebookAuth', 'googleAuth'],
+ oauth: ['twitterAuth', 'facebookAuth', 'googleAuth', 'githubAuth'],
socketio: true,
bootstrap: true,
uibootstrap: true
diff --git a/templates/app/_package.json b/templates/app/_package.json
index 7d119f9c0..a1ddc5f0c 100644
--- a/templates/app/_package.json
+++ b/templates/app/_package.json
@@ -33,14 +33,21 @@
"connect-mongo": "^1.2.1",<% } %><% if(filters.sequelize) { %>
"sequelize": "^3.23.6",
"sqlite3": "~3.1.1",
- "express-sequelize-session": "0.4.0",<% } %><% if(filters.auth) { %>
+ "express-sequelize-session": "0.4.0",<% } %>
+ <%_ if(filters.auth) { -%>
"jsonwebtoken": "^7.0.0",
"express-jwt": "^5.0.0",
"passport": "~0.3.0",
- "passport-local": "^1.0.0",<% } %><% if(filters.facebookAuth) { %>
- "passport-facebook": "^2.0.0",<% } %><% if(filters.twitterAuth) { %>
- "passport-twitter": "^1.0.3",<% } %><% if(filters.googleAuth) { %>
- "passport-google-oauth20": "^1.0.0",<% } %><% if(filters.socketio) { %>
+ "passport-local": "^1.0.0",<% } %>
+ <%_ if(filters.facebookAuth) { -%>
+ "passport-facebook": "^2.0.0",<% } %>
+ <%_ if(filters.twitterAuth) { -%>
+ "passport-twitter": "^1.0.3",<% } %>
+ <%_ if(filters.googleAuth) { -%>
+ "passport-google-oauth20": "^1.0.0",<% } %>
+ <%_ if(filters.githubAuth) { -%>
+ "passport-github": "^1.1.0",<% } %>
+ <%_ if(filters.socketio) { -%>
"socket.io": "^1.3.5",
"socket.io-client": "^1.3.5",
"socketio-jwt": "^4.2.0",<% } %>
diff --git a/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(css).css b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(css).css
index be33316e0..60e5b2fff 100644
--- a/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(css).css
+++ b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(css).css
@@ -1,20 +1,25 @@
-<% if (!filters.bootstrap) { if (filters.facebookAuth) { %>.btn-facebook {
+<%_ if(!filters.bootstrap) { -%>
+ <%_ if(filters.facebookAuth) { -%>
+.btn-facebook {
color: #fff;
background-color: #3B5998;
border-color: #133783;
-}
-<% } if (filters.googleAuth) { %>.btn-google {
+}<% } %>
+ <%_ if(filters.googleAuth) { -%>
+.btn-google {
color: #fff;
background-color: #dd4b39;
border-color: #c53727;
-}
-<% } if (filters.twitterAuth) { %>.btn-twitter {
+}<% } %>
+ <%_ if(filters.twitterAuth) { -%>
+.btn-twitter {
color: #fff;
background-color: #2daddc;
border-color: #0271bf;
-}
-<% } %>.btn-github {
+}<% } %>
+ <%_ if(filters.githubAuth) { -%>
+.btn-github {
color: #fff;
- background-color: #fafafa;
- border-color: #ccc;
+ background-color: #444444;
}<% } %>
+<% } %>
\ No newline at end of file
diff --git a/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(html).html b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(html).html
index 7b9b0623a..b14eec94a 100644
--- a/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(html).html
+++ b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(html).html
@@ -1,12 +1,20 @@
-<% if(filters.facebookAuth) { %>
+<%_ if(filters.facebookAuth) { -%>
+
Connect with Facebook
-
-<% } if (filters.googleAuth) { %>
+<% } %>
+<%_ if(filters.googleAuth) { -%>
+
Connect with Google+
-
-<% } if (filters.twitterAuth) { %>
+<% } %>
+<%_ if(filters.twitterAuth) { -%>
+
Connect with Twitter
<% } %>
+<%_ if(filters.githubAuth) { -%>
+
+
+ Connect with GitHub
+<% } %>
diff --git a/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(less).less b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(less).less
index be33316e0..60e5b2fff 100644
--- a/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(less).less
+++ b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(less).less
@@ -1,20 +1,25 @@
-<% if (!filters.bootstrap) { if (filters.facebookAuth) { %>.btn-facebook {
+<%_ if(!filters.bootstrap) { -%>
+ <%_ if(filters.facebookAuth) { -%>
+.btn-facebook {
color: #fff;
background-color: #3B5998;
border-color: #133783;
-}
-<% } if (filters.googleAuth) { %>.btn-google {
+}<% } %>
+ <%_ if(filters.googleAuth) { -%>
+.btn-google {
color: #fff;
background-color: #dd4b39;
border-color: #c53727;
-}
-<% } if (filters.twitterAuth) { %>.btn-twitter {
+}<% } %>
+ <%_ if(filters.twitterAuth) { -%>
+.btn-twitter {
color: #fff;
background-color: #2daddc;
border-color: #0271bf;
-}
-<% } %>.btn-github {
+}<% } %>
+ <%_ if(filters.githubAuth) { -%>
+.btn-github {
color: #fff;
- background-color: #fafafa;
- border-color: #ccc;
+ background-color: #444444;
}<% } %>
+<% } %>
\ No newline at end of file
diff --git a/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(sass).scss b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(sass).scss
index be33316e0..60e5b2fff 100644
--- a/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(sass).scss
+++ b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(sass).scss
@@ -1,20 +1,25 @@
-<% if (!filters.bootstrap) { if (filters.facebookAuth) { %>.btn-facebook {
+<%_ if(!filters.bootstrap) { -%>
+ <%_ if(filters.facebookAuth) { -%>
+.btn-facebook {
color: #fff;
background-color: #3B5998;
border-color: #133783;
-}
-<% } if (filters.googleAuth) { %>.btn-google {
+}<% } %>
+ <%_ if(filters.googleAuth) { -%>
+.btn-google {
color: #fff;
background-color: #dd4b39;
border-color: #c53727;
-}
-<% } if (filters.twitterAuth) { %>.btn-twitter {
+}<% } %>
+ <%_ if(filters.twitterAuth) { -%>
+.btn-twitter {
color: #fff;
background-color: #2daddc;
border-color: #0271bf;
-}
-<% } %>.btn-github {
+}<% } %>
+ <%_ if(filters.githubAuth) { -%>
+.btn-github {
color: #fff;
- background-color: #fafafa;
- border-color: #ccc;
+ background-color: #444444;
}<% } %>
+<% } %>
\ No newline at end of file
diff --git a/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(stylus).styl b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(stylus).styl
index 995d4c766..ace003c55 100644
--- a/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(stylus).styl
+++ b/templates/app/client/components/oauth-buttons(oauth)/oauth-buttons(stylus).styl
@@ -1,16 +1,21 @@
-<% if (!filters.bootstrap) { if (filters.facebookAuth) { %>.btn-facebook
+<%_ if(!filters.bootstrap) { -%>
+ <%_ if(filters.facebookAuth) { -%>
+.btn-facebook
color #fff
background-color #3B5998
- border-color #133783
-<% } if (filters.googleAuth) { %>.btn-google
+ border-color #133783<% } %>
+ <%_ if(filters.googleAuth) { -%>
+.btn-google
color #fff
background-color #dd4b39
- border-color #c53727
-<% } if (filters.twitterAuth) { %>.btn-twitter
+ border-color #c53727<% } %>
+ <%_ if(filters.twitterAuth) { -%>
+.btn-twitter
color #fff
background-color #2daddc
- border-color #0271bf
-<% } %>.btn-github
+ border-color #0271bf<% } %>
+ <%_ if(filters.githubAuth) { -%>
+.btn-github
color #fff
- background-color #fafafa
- border-color #ccc<% } %>
+ background-color #444444<% } %>
+<% } %>
\ No newline at end of file
diff --git a/templates/app/e2e/account(auth)/login/login.spec(jasmine).js b/templates/app/e2e/account(auth)/login/login.spec(jasmine).js
index 780ed57d0..51a6ba158 100644
--- a/templates/app/e2e/account(auth)/login/login.spec(jasmine).js
+++ b/templates/app/e2e/account(auth)/login/login.spec(jasmine).js
@@ -51,6 +51,9 @@ describe('Login View', function() {
expect(page.form.oauthButtons.google.getAttribute('class')).toMatch('btn-block');<% } if (filters.twitterAuth) { %>
expect(page.form.oauthButtons.twitter.getText()).toBe('Connect with Twitter');
expect(page.form.oauthButtons.twitter.getAttribute('class')).toMatch('btn-block');<% } %>
+ <%_ if (filters.githubAuth) { -%>
+ expect(page.form.oauthButtons.github.getText()).toBe('Connect with GitHub');
+ expect(page.form.oauthButtons.github.getAttribute('class')).toMatch('btn-block');<% } %>
});<% } %>
describe('with local auth', function() {
diff --git a/templates/app/e2e/account(auth)/login/login.spec(mocha).js b/templates/app/e2e/account(auth)/login/login.spec(mocha).js
index fd11f4131..cf927aef6 100644
--- a/templates/app/e2e/account(auth)/login/login.spec(mocha).js
+++ b/templates/app/e2e/account(auth)/login/login.spec(mocha).js
@@ -51,6 +51,9 @@ describe('Login View', function() {
<%= expect() %>page.form.oauthButtons.google.getAttribute('class')<%= to() %>.eventually.contain('btn-block');<% } if (filters.twitterAuth) { %>
<%= expect() %>page.form.oauthButtons.twitter.getText()<%= to() %>.eventually.equal('Connect with Twitter');
<%= expect() %>page.form.oauthButtons.twitter.getAttribute('class')<%= to() %>.eventually.contain('btn-block');<% } %>
+ <%_ if (filters.githubAuth) { -%>
+ <%= expect() %>page.form.oauthButtons.github.getText()<%= to() %>.eventually.equal('Connect with GitHub');
+ <%= expect() %>page.form.oauthButtons.github.getAttribute('class')<%= to() %>.eventually.contain('btn-block');<% } %>
});<% } %>
describe('with local auth', function() {
diff --git a/templates/app/e2e/account(auth)/signup/signup.spec(jasmine).js b/templates/app/e2e/account(auth)/signup/signup.spec(jasmine).js
index a70f76f19..4da100cca 100644
--- a/templates/app/e2e/account(auth)/signup/signup.spec(jasmine).js
+++ b/templates/app/e2e/account(auth)/signup/signup.spec(jasmine).js
@@ -1,7 +1,7 @@
'use strict';
-var config = browser.params;<% if (filters.mongooseModels) { %>
-var UserModel = require(config.serverConfig.root + '/server/api/user/user.model').default;<% } %><% if (filters.sequelizeModels) { %>
+var config = browser.params;<% if(filters.mongooseModels) { %>
+var UserModel = require(config.serverConfig.root + '/server/api/user/user.model').default;<% } %><% if(filters.sequelizeModels) { %>
var UserModel = require(config.serverConfig.root + '/server/sqldb').User;<% } %>
describe('Signup View', function() {
@@ -38,22 +38,25 @@ describe('Signup View', function() {
expect(page.form.confirmPassword.getAttribute('name')).toBe('confirmPassword');
expect(page.form.submit.getAttribute('type')).toBe('submit');
expect(page.form.submit.getText()).toBe('Sign up');
- });<% if (filters.oauth) { %>
+ });<% if(filters.oauth) { %>
- it('should include oauth buttons with correct classes applied', function() {<% if (filters.facebookAuth) { %>
+ it('should include oauth buttons with correct classes applied', function() {<% if(filters.facebookAuth) { %>
expect(page.form.oauthButtons.facebook.getText()).toBe('Connect with Facebook');
- expect(page.form.oauthButtons.facebook.getAttribute('class')).toMatch('btn-block');<% } if (filters.googleAuth) { %>
+ expect(page.form.oauthButtons.facebook.getAttribute('class')).toMatch('btn-block');<% } if(filters.googleAuth) { %>
expect(page.form.oauthButtons.google.getText()).toBe('Connect with Google+');
- expect(page.form.oauthButtons.google.getAttribute('class')).toMatch('btn-block');<% } if (filters.twitterAuth) { %>
+ expect(page.form.oauthButtons.google.getAttribute('class')).toMatch('btn-block');<% } if(filters.twitterAuth) { %>
expect(page.form.oauthButtons.twitter.getText()).toBe('Connect with Twitter');
expect(page.form.oauthButtons.twitter.getAttribute('class')).toMatch('btn-block');<% } %>
+ <%_ if(filters.githubAuth) { -%>
+ expect(page.form.oauthButtons.github.getText()).toBe('Connect with GitHub');
+ expect(page.form.oauthButtons.github.getAttribute('class')).toMatch('btn-block');<% } %>
});<% } %>
describe('with local auth', function() {
beforeAll(function(done) {
- <% if (filters.mongooseModels) { %>UserModel.remove().then(done);<% }
- if (filters.sequelizeModels) { %>UserModel.destroy({ where: {} }).then(done);<% } %>
+ <% if(filters.mongooseModels) { %>UserModel.remove().then(done);<% }
+ if(filters.sequelizeModels) { %>UserModel.destroy({ where: {} }).then(done);<% } %>
});
it('should signup a new user, log them in, and redirecting to "/"', function() {
diff --git a/templates/app/e2e/account(auth)/signup/signup.spec(mocha).js b/templates/app/e2e/account(auth)/signup/signup.spec(mocha).js
index f7debbe47..9390dbe52 100644
--- a/templates/app/e2e/account(auth)/signup/signup.spec(mocha).js
+++ b/templates/app/e2e/account(auth)/signup/signup.spec(mocha).js
@@ -1,7 +1,7 @@
'use strict';
-var config = browser.params;<% if (filters.mongooseModels) { %>
-var UserModel = require(config.serverConfig.root + '/server/api/user/user.model').default;<% } %><% if (filters.sequelizeModels) { %>
+var config = browser.params;<% if(filters.mongooseModels) { %>
+var UserModel = require(config.serverConfig.root + '/server/api/user/user.model').default;<% } %><% if(filters.sequelizeModels) { %>
var UserModel = require(config.serverConfig.root + '/server/sqldb').User;<% } %>
describe('Signup View', function() {
@@ -26,8 +26,8 @@ describe('Signup View', function() {
});
after(function() {
- <% if (filters.mongooseModels) { %>return UserModel.remove();<% }
- if (filters.sequelizeModels) { %>return UserModel.destroy({ where: {} });<% } %>
+ <% if(filters.mongooseModels) { %>return UserModel.remove();<% }
+ if(filters.sequelizeModels) { %>return UserModel.destroy({ where: {} });<% } %>
});
it('should include signup form with correct inputs and submit button', function() {
@@ -41,22 +41,25 @@ describe('Signup View', function() {
<%= expect() %>page.form.confirmPassword.getAttribute('name')<%= to() %>.eventually.equal('confirmPassword');
<%= expect() %>page.form.submit.getAttribute('type')<%= to() %>.eventually.equal('submit');
<%= expect() %>page.form.submit.getText()<%= to() %>.eventually.equal('Sign up');
- });<% if (filters.oauth) { %>
+ });<% if(filters.oauth) { %>
- it('should include oauth buttons with correct classes applied', function() {<% if (filters.facebookAuth) { %>
+ it('should include oauth buttons with correct classes applied', function() {<% if(filters.facebookAuth) { %>
<%= expect() %>page.form.oauthButtons.facebook.getText()<%= to() %>.eventually.equal('Connect with Facebook');
- <%= expect() %>page.form.oauthButtons.facebook.getAttribute('class')<%= to() %>.eventually.contain('btn-block');<% } if (filters.googleAuth) { %>
+ <%= expect() %>page.form.oauthButtons.facebook.getAttribute('class')<%= to() %>.eventually.contain('btn-block');<% } if(filters.googleAuth) { %>
<%= expect() %>page.form.oauthButtons.google.getText()<%= to() %>.eventually.equal('Connect with Google+');
- <%= expect() %>page.form.oauthButtons.google.getAttribute('class')<%= to() %>.eventually.contain('btn-block');<% } if (filters.twitterAuth) { %>
+ <%= expect() %>page.form.oauthButtons.google.getAttribute('class')<%= to() %>.eventually.contain('btn-block');<% } if(filters.twitterAuth) { %>
<%= expect() %>page.form.oauthButtons.twitter.getText()<%= to() %>.eventually.equal('Connect with Twitter');
<%= expect() %>page.form.oauthButtons.twitter.getAttribute('class')<%= to() %>.eventually.contain('btn-block');<% } %>
+ <%_ if(filters.githubAuth) { -%>
+ <%= expect() %>page.form.oauthButtons.github.getText()<%= to() %>.eventually.equal('Connect with GitHub');
+ <%= expect() %>page.form.oauthButtons.github.getAttribute('class')<%= to() %>.eventually.contain('btn-block');<% } %>
});<% } %>
describe('with local auth', function() {
before(function() {
- <% if (filters.mongooseModels) { %>return UserModel.remove();<% }
- if (filters.sequelizeModels) { %>return UserModel.destroy({ where: {} });<% } %>
+ <% if(filters.mongooseModels) { %>return UserModel.remove();<% }
+ if(filters.sequelizeModels) { %>return UserModel.destroy({ where: {} });<% } %>
})
it('should signup a new user, log them in, and redirecting to "/"', function() {
diff --git a/templates/app/e2e/components/oauth-buttons(oauth)/oauth-buttons.po.js b/templates/app/e2e/components/oauth-buttons(oauth)/oauth-buttons.po.js
index c25d2b994..009d964e6 100644
--- a/templates/app/e2e/components/oauth-buttons(oauth)/oauth-buttons.po.js
+++ b/templates/app/e2e/components/oauth-buttons(oauth)/oauth-buttons.po.js
@@ -3,13 +3,16 @@
* https://docs.google.com/presentation/d/1B6manhG0zEXkC-H-tPo2vwU06JhL8w9-XCF9oehXzAQ
*/
-'use strict';
-
var OauthButtons = function() {
- var oauthButtons = this.oauthButtons = element(by.css('oauth-buttons'));<% if (filters.facebookAuth) { %>
- oauthButtons.facebook = oauthButtons.element(by.css('.btn<% if (filters.bootstrap) { %>.btn-social<% } %>.btn-facebook'));<% } if (filters.googleAuth) { %>
- oauthButtons.google = oauthButtons.element(by.css('.btn<% if (filters.bootstrap) { %>.btn-social<% } %>.btn-google'));<% } if (filters.twitterAuth) { %>
- oauthButtons.twitter = oauthButtons.element(by.css('.btn<% if (filters.bootstrap) { %>.btn-social<% } %>.btn-twitter'));<% } %>
+ var oauthButtons = this.oauthButtons = element(by.css('oauth-buttons'));
+ <%_ if(filters.facebookAuth) { -%>
+ oauthButtons.facebook = oauthButtons.element(by.css('.btn<% if(filters.bootstrap) { %>.btn-social<% } %>.btn-facebook'));<% } %>
+ <%_ if(filters.googleAuth) { -%>
+ oauthButtons.google = oauthButtons.element(by.css('.btn<% if(filters.bootstrap) { %>.btn-social<% } %>.btn-google'));<% } %>
+ <%_ if(filters.twitterAuth) { -%>
+ oauthButtons.twitter = oauthButtons.element(by.css('.btn<% if(filters.bootstrap) { %>.btn-social<% } %>.btn-twitter'));<% } %>
+ <%_ if(filters.githubAuth) { -%>
+ oauthButtons.github = oauthButtons.element(by.css('.btn<% if(filters.bootstrap) { %>.btn-social<% } %>.btn-github'));<% } %>
};
module.exports = new OauthButtons();
diff --git a/templates/app/server/api/user(auth)/user.model(mongooseModels).js b/templates/app/server/api/user(auth)/user.model(mongooseModels).js
index f23208f12..cb437f9cb 100644
--- a/templates/app/server/api/user(auth)/user.model(mongooseModels).js
+++ b/templates/app/server/api/user(auth)/user.model(mongooseModels).js
@@ -38,11 +38,17 @@ var UserSchema = new Schema({
}<% } else { %>true<% } %>
},
provider: String,
- salt: String<% if(filters.oauth) { %>,<% if(filters.facebookAuth) { %>
- facebook: {},<% } %><% if(filters.twitterAuth) { %>
- twitter: {},<% } %><% if(filters.googleAuth) { %>
+ salt: String,
+<%_ if(filters.oauth) { -%>
+ <%_ if(filters.facebookAuth) { -%>
+ facebook: {},<% } %>
+ <%_ if(filters.twitterAuth) { -%>
+ twitter: {},<% } %>
+ <%_ if(filters.googleAuth) { -%>
google: {},<% } %>
- github: {}<% } %>
+ <%_ if(filters.githubAuth) { -%>
+ github: {},
+<% } %>
});
/**
diff --git a/templates/app/server/api/user(auth)/user.model(sequelizeModels).js b/templates/app/server/api/user(auth)/user.model(sequelizeModels).js
index 58e8f5ae2..721f80442 100644
--- a/templates/app/server/api/user(auth)/user.model(sequelizeModels).js
+++ b/templates/app/server/api/user(auth)/user.model(sequelizeModels).js
@@ -1,7 +1,7 @@
'use strict';
import crypto from 'crypto';<% if(filters.oauth) { %>
-var authTypes = ['github', 'twitter', 'facebook', 'google'];<% } %>
+const authTypes = ['github', 'twitter', 'facebook', 'google'];<% } %>
var validatePresenceOf = function(value) {
return value && value.length;
@@ -37,11 +37,17 @@ export default function(sequelize, DataTypes) {
}
},
provider: DataTypes.STRING,
- salt: DataTypes.STRING<% if(filters.oauth) { %>,<% if(filters.facebookAuth) { %>
- facebook: DataTypes.JSON,<% } %><% if(filters.twitterAuth) { %>
- twitter: DataTypes.JSON,<% } %><% if(filters.googleAuth) { %>
+ salt: DataTypes.STRING,
+ <% if(filters.oauth) { %>
+ <%_ if(filters.facebookAuth) { -%>
+ facebook: DataTypes.JSON,<% } %>
+ <%_ if(filters.twitterAuth) { -%>
+ twitter: DataTypes.JSON,<% } %>
+ <%_ if(filters.githubAuth) { -%>
+ github: DataTypes.JSON,<% } %>
+ <%_ if(filters.googleAuth) { -%>
google: DataTypes.JSON,<% } %>
- github: DataTypes.JSON<% } %>
+ <% } %>
}, {
diff --git a/templates/app/server/api/user(auth)/user.model.spec(mongooseModels).js b/templates/app/server/api/user(auth)/user.model.spec(mongooseModels).js
index 5fe8de3c5..aaaa766b0 100644
--- a/templates/app/server/api/user(auth)/user.model.spec(mongooseModels).js
+++ b/templates/app/server/api/user(auth)/user.model.spec(mongooseModels).js
@@ -54,7 +54,20 @@ describe('User Model', function() {
it('should fail when saving without an email', function() {
user.email = undefined;
return <%= expect() %>user.save()<%= to() %>.be.rejected;
- });<% if (filters.oauth && filters.googleAuth) { %>
+ });
+ <%_ if(filters.githubAuth) { -%>
+
+ describe('given user provider is github', function() {
+ beforeEach(function() {
+ user.provider = 'github';
+ });
+
+ it('should succeed when saving without an email', function() {
+ user.email = null;
+ return <%= expect() %>user.save()<%= to() %>.be.fulfilled;
+ });
+ });<% } %>
+ <%_ if(filters.oauth && filters.googleAuth) { -%>
describe('given user provider is google', function() {
beforeEach(function() {
@@ -65,7 +78,7 @@ describe('User Model', function() {
user.email = null;
return <%= expect() %>user.save()<%= to() %>.be.fulfilled;
});
- });<% } %><% if (filters.oauth && filters.facebookAuth) { %>
+ });<% } %><% if(filters.oauth && filters.facebookAuth) { %>
describe('given user provider is facebook', function() {
beforeEach(function() {
@@ -76,7 +89,7 @@ describe('User Model', function() {
user.email = null;
return <%= expect() %>user.save()<%= to() %>.be.fulfilled;
});
- });<% } %><% if (filters.oauth && filters.twitterAuth) { %>
+ });<% } %><% if(filters.oauth && filters.twitterAuth) { %>
describe('given user provider is twitter', function() {
beforeEach(function() {
@@ -87,7 +100,7 @@ describe('User Model', function() {
user.email = null;
return <%= expect() %>user.save()<%= to() %>.be.fulfilled;
});
- });<% } %><% if (filters.oauth) { %>
+ });<% } %><% if(filters.oauth) { %>
describe('given user provider is github', function() {
beforeEach(function() {
@@ -137,7 +150,20 @@ describe('User Model', function() {
return u.authenticate('password');
})<%= to() %>.eventually.be.true;
});
- });<% if (filters.oauth && filters.googleAuth) { %>
+ });
+ <%_ if(filters.oauth && filters.githubAuth) { -%>
+
+ describe('given user provider is github', function() {
+ beforeEach(function() {
+ user.provider = 'github';
+ });
+
+ it('should succeed when saving without a password', function() {
+ user.password = null;
+ return <%= expect() %>user.save()<%= to() %>.be.fulfilled;
+ });
+ });<% } %>
+ <%_ if(filters.oauth && filters.googleAuth) { -%>
describe('given user provider is google', function() {
beforeEach(function() {
@@ -148,7 +174,7 @@ describe('User Model', function() {
user.password = null;
return <%= expect() %>user.save()<%= to() %>.be.fulfilled;
});
- });<% } %><% if (filters.oauth && filters.facebookAuth) { %>
+ });<% } %><% if(filters.oauth && filters.facebookAuth) { %>
describe('given user provider is facebook', function() {
beforeEach(function() {
@@ -159,7 +185,7 @@ describe('User Model', function() {
user.password = null;
return <%= expect() %>user.save()<%= to() %>.be.fulfilled;
});
- });<% } %><% if (filters.oauth && filters.twitterAuth) { %>
+ });<% } %><% if(filters.oauth && filters.twitterAuth) { %>
describe('given user provider is twitter', function() {
beforeEach(function() {
@@ -170,7 +196,7 @@ describe('User Model', function() {
user.password = null;
return <%= expect() %>user.save()<%= to() %>.be.fulfilled;
});
- });<% } %><% if (filters.oauth) { %>
+ });<% } %><% if(filters.oauth) { %>
describe('given user provider is github', function() {
beforeEach(function() {
diff --git a/templates/app/server/auth(auth)/github(githubAuth)/index.js b/templates/app/server/auth(auth)/github(githubAuth)/index.js
new file mode 100644
index 000000000..85b4c4b87
--- /dev/null
+++ b/templates/app/server/auth(auth)/github(githubAuth)/index.js
@@ -0,0 +1,20 @@
+import { Router } from 'express';
+import passport from 'passport';
+import { setTokenCookie } from '../auth.service';
+
+let router = new Router();
+
+router
+ .get('/', passport.authenticate('github', {
+ failureRedirect: '/signup',
+ scope: [
+ 'user:email',
+ ],
+ session: false
+ }))
+ .get('/callback', passport.authenticate('github', {
+ failureRedirect: '/signup',
+ session: false
+ }), setTokenCookie);
+
+export default router;
diff --git a/templates/app/server/auth(auth)/github(githubAuth)/passport.js b/templates/app/server/auth(auth)/github(githubAuth)/passport.js
new file mode 100644
index 000000000..3ea90f66f
--- /dev/null
+++ b/templates/app/server/auth(auth)/github(githubAuth)/passport.js
@@ -0,0 +1,38 @@
+import passport from 'passport';
+import { Strategy as GitHubStrategy } from 'passport-github';
+
+export function setup(User, config) {
+ passport.use(new GitHubStrategy({
+ clientID: config.gitHub.clientID,
+ clientSecret: config.gitHub.clientSecret,
+ callbackURL: config.gitHub.callbackURL,
+ passReqToCallback: true
+ },
+ function(accessToken, refreshToken, profile, done) {
+ <%_ if(filters.mongooseModels) { -%>
+ User.findOne({'github.id': profile.id}).exec()<% } %>
+ <%_ if(filters.sequelizeModels) { -%>
+ User.find({where:{'github.id': profile.id}})<% } %>
+ .then(user => {
+ if(user) {
+ return done(null, user);
+ }
+
+ <%_ if(filters.mongooseModels) { -%>
+ user = new User({<% } %>
+ <%_ if(filters.sequelizeModels) { -%>
+ user = User.build({<% } %>
+ name: profile.displayName,
+ email: profile.emails[0].value,
+ role: 'user',
+ provider: 'github',
+ github: profile._json
+ });
+
+ return user.save()
+ .then(savedUser => done(null, savedUser))
+ .catch(err => done(err));
+ })
+ .catch(err => done(err));
+ }));
+}
diff --git a/templates/app/server/auth(auth)/index.js b/templates/app/server/auth(auth)/index.js
index 3f9983fb3..658d6ca77 100644
--- a/templates/app/server/auth(auth)/index.js
+++ b/templates/app/server/auth(auth)/index.js
@@ -9,12 +9,16 @@ require('./local/passport').setup(User, config);<% if (filters.facebookAuth) { %
require('./facebook/passport').setup(User, config);<% } %><% if (filters.googleAuth) { %>
require('./google/passport').setup(User, config);<% } %><% if (filters.twitterAuth) { %>
require('./twitter/passport').setup(User, config);<% } %>
+<%_ if (filters.githubAuth) { -%>
+require('./github/passport').setup(User, config);<% } %>
var router = express.Router();
router.use('/local', require('./local').default);<% if (filters.facebookAuth) { %>
-router.use('/facebook', require('./facebook').default);<% } %><% if (filters.twitterAuth) { %>
-router.use('/twitter', require('./twitter').default);<% } %><% if (filters.googleAuth) { %>
-router.use('/google', require('./google').default);<% } %>
+router.use('/facebook', require('./facebook').default);<% } %><% if (filters.googleAuth) { %>
+router.use('/google', require('./google').default);<% } %><% if (filters.twitterAuth) { %>
+router.use('/twitter', require('./twitter').default);<% } %>
+<%_ if (filters.githubAuth) { -%>
+router.use('/github', require('./github').default);<% } %>
export default router;
diff --git a/templates/app/server/config/_local.env.js b/templates/app/server/config/_local.env.js
index 02a5a084b..0084964b0 100644
--- a/templates/app/server/config/_local.env.js
+++ b/templates/app/server/config/_local.env.js
@@ -1,23 +1,28 @@
-'use strict';
-
// Use local.env.js for environment variables that will be set when the server starts locally.
// Use for your api keys, secrets, etc. This file should not be tracked by git.
//
// You will need to set these on the server you deploy to.
module.exports = {
- DOMAIN: 'http://localhost:<%= devPort %>',
- SESSION_SECRET: '<%= lodash.slugify(appname) + "-secret" %>',<% if (filters.facebookAuth) { %>
+ DOMAIN: 'http://localhost:<%= devPort %>',
+ SESSION_SECRET: '<%= lodash.slugify(appname) + "-secret" %>',
+ <%_ if (filters.facebookAuth) { -%>
+
+ FACEBOOK_ID: 'app-id',
+ FACEBOOK_SECRET: 'secret',<% } %>
+ <%_ if (filters.twitterAuth) { -%>
+
+ TWITTER_ID: 'app-id',
+ TWITTER_SECRET: 'secret',<% } %>
+ <%_ if (filters.githubAuth) { -%>
- FACEBOOK_ID: 'app-id',
- FACEBOOK_SECRET: 'secret',<% } if (filters.twitterAuth) { %>
+ GITHUB_ID: 'app-id',
+ GITHUB_SECRET: 'secret',<% } %>
+ <%_ if (filters.googleAuth) { -%>
- TWITTER_ID: 'app-id',
- TWITTER_SECRET: 'secret',<% } if (filters.googleAuth) { %>
+ GOOGLE_ID: 'app-id',
+ GOOGLE_SECRET: 'secret',<% } %>
- GOOGLE_ID: 'app-id',
- GOOGLE_SECRET: 'secret',
-<% } %>
// Control debug level for modules using visionmedia/debug
DEBUG: ''
};
diff --git a/templates/app/server/config/_local.env.sample.js b/templates/app/server/config/_local.env.sample.js
index 79dce5854..0084964b0 100644
--- a/templates/app/server/config/_local.env.sample.js
+++ b/templates/app/server/config/_local.env.sample.js
@@ -1,5 +1,3 @@
-'use strict';
-
// Use local.env.js for environment variables that will be set when the server starts locally.
// Use for your api keys, secrets, etc. This file should not be tracked by git.
//
@@ -7,13 +5,20 @@
module.exports = {
DOMAIN: 'http://localhost:<%= devPort %>',
- SESSION_SECRET: '<%= lodash.slugify(appname) + "-secret" %>',<% if (filters.facebookAuth) { %>
+ SESSION_SECRET: '<%= lodash.slugify(appname) + "-secret" %>',
+ <%_ if (filters.facebookAuth) { -%>
FACEBOOK_ID: 'app-id',
- FACEBOOK_SECRET: 'secret',<% } if (filters.twitterAuth) { %>
+ FACEBOOK_SECRET: 'secret',<% } %>
+ <%_ if (filters.twitterAuth) { -%>
TWITTER_ID: 'app-id',
- TWITTER_SECRET: 'secret',<% } if (filters.googleAuth) { %>
+ TWITTER_SECRET: 'secret',<% } %>
+ <%_ if (filters.githubAuth) { -%>
+
+ GITHUB_ID: 'app-id',
+ GITHUB_SECRET: 'secret',<% } %>
+ <%_ if (filters.googleAuth) { -%>
GOOGLE_ID: 'app-id',
GOOGLE_SECRET: 'secret',<% } %>
diff --git a/templates/app/server/config/environment/index.js b/templates/app/server/config/environment/index.js
index b82e4ae4f..49ece374e 100644
--- a/templates/app/server/config/environment/index.js
+++ b/templates/app/server/config/environment/index.js
@@ -43,25 +43,35 @@ var all = {
safe: true
}
}
- }<% if(filters.facebookAuth) { %>,
+ },
+ <%_ if(filters.facebookAuth) { -%>
facebook: {
clientID: process.env.FACEBOOK_ID || 'id',
clientSecret: process.env.FACEBOOK_SECRET || 'secret',
callbackURL: `${process.env.DOMAIN || ''}/auth/facebook/callback`
- }<% } %><% if(filters.twitterAuth) { %>,
+ },<% } %>
+ <%_ if(filters.twitterAuth) { -%>
twitter: {
- clientID: process.env.TWITTER_ID || 'id',
+ clientID: process.env.TWITTER_ID || 'id'
clientSecret: process.env.TWITTER_SECRET || 'secret',
callbackURL: `${process.env.DOMAIN || ''}/auth/twitter/callback`
- }<% } %><% if(filters.googleAuth) { %>,
+ },<% } %>
+ <%_ if(filters.githubAuth) { -%>
+
+ github: {
+ clientID: process.env.GITHUB_ID || 'id',
+ clientSecret: process.env.GITHUB_SECRET || 'secret',
+ callbackURL: `${process.env.DOMAIN || ''}/auth/github/callback`
+ },<% } %>
+ <%_ if(filters.googleAuth) { -%>
google: {
clientID: process.env.GOOGLE_ID || 'id',
clientSecret: process.env.GOOGLE_SECRET || 'secret',
callbackURL: `${process.env.DOMAIN || ''}/auth/google/callback`
- }<% } %>
+ },<% } %>
};
// Export the config object based on the NODE_ENV