17
README.md
17
README.md
@ -177,6 +177,23 @@ app.get('/auth/facebook/callback', passport.authenticate('facebook', { successRe
|
|||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
|
<img src="http://www.danpontefract.com/wp-content/uploads/2014/02/logo-linkedin.png" width="200">
|
||||||
|
- Sign in at [LinkedIn Developer Network](http://developer.linkedin.com/)
|
||||||
|
- From the account name dropdown menu select **API Keys**
|
||||||
|
- *It may ask you to sign in once again*
|
||||||
|
- Click **+ Add New Application** button
|
||||||
|
- Fill out all *required* fields
|
||||||
|
- For **Default Scope** make sure *at least* the following is checked:
|
||||||
|
- `r_fullprofile`
|
||||||
|
- `r_emailaddress`
|
||||||
|
- `r_network`
|
||||||
|
- Finish by clicking **Add Application** button
|
||||||
|
- Copy and paste *API Key* and *Secret Key* keys into `config/secrets.js`
|
||||||
|
- *API Key* is your **clientID**
|
||||||
|
- *Secret Key* is your **clientSecret**
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
<img src="https://s3.amazonaws.com/venmo/venmo_logo_blue.png" width="200">
|
<img src="https://s3.amazonaws.com/venmo/venmo_logo_blue.png" width="200">
|
||||||
- Visit the **Account** section of your Venmo profile after logging in
|
- Visit the **Account** section of your Venmo profile after logging in
|
||||||
- Click on the **Developers** tab
|
- Click on the **Developers** tab
|
||||||
|
3
app.js
3
app.js
@ -132,6 +132,7 @@ app.get('/api/github', passportConf.isAuthenticated, passportConf.isAuthorized,
|
|||||||
app.get('/api/twitter', passportConf.isAuthenticated, passportConf.isAuthorized, apiController.getTwitter);
|
app.get('/api/twitter', passportConf.isAuthenticated, passportConf.isAuthorized, apiController.getTwitter);
|
||||||
app.get('/api/venmo', passportConf.isAuthenticated, passportConf.isAuthorized, apiController.getVenmo);
|
app.get('/api/venmo', passportConf.isAuthenticated, passportConf.isAuthorized, apiController.getVenmo);
|
||||||
app.post('/api/venmo', passportConf.isAuthenticated, passportConf.isAuthorized, apiController.postVenmo);
|
app.post('/api/venmo', passportConf.isAuthenticated, passportConf.isAuthorized, apiController.postVenmo);
|
||||||
|
app.get('/api/linkedin', apiController.getLinkedin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OAuth routes for sign-in.
|
* OAuth routes for sign-in.
|
||||||
@ -145,6 +146,8 @@ app.get('/auth/google', passport.authenticate('google', { scope: 'profile email'
|
|||||||
app.get('/auth/google/callback', passport.authenticate('google', { successRedirect: '/', failureRedirect: '/login' }));
|
app.get('/auth/google/callback', passport.authenticate('google', { successRedirect: '/', failureRedirect: '/login' }));
|
||||||
app.get('/auth/twitter', passport.authenticate('twitter'));
|
app.get('/auth/twitter', passport.authenticate('twitter'));
|
||||||
app.get('/auth/twitter/callback', passport.authenticate('twitter', { successRedirect: '/', failureRedirect: '/login' }));
|
app.get('/auth/twitter/callback', passport.authenticate('twitter', { successRedirect: '/', failureRedirect: '/login' }));
|
||||||
|
app.get('/auth/linkedin', passport.authenticate('linkedin', { state: 'SOME STATE' }));
|
||||||
|
app.get('/auth/linkedin/callback', passport.authenticate('linkedin', { successRedirect: '/', failureRedirect: '/login' }));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OAuth routes for API examples that require authorization.
|
* OAuth routes for API examples that require authorization.
|
||||||
|
@ -5,6 +5,7 @@ var FacebookStrategy = require('passport-facebook').Strategy;
|
|||||||
var TwitterStrategy = require('passport-twitter').Strategy;
|
var TwitterStrategy = require('passport-twitter').Strategy;
|
||||||
var GitHubStrategy = require('passport-github').Strategy;
|
var GitHubStrategy = require('passport-github').Strategy;
|
||||||
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
|
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
|
||||||
|
var LinkedInStrategy = require('passport-linkedin-oauth2').Strategy;
|
||||||
var OAuthStrategy = require('passport-oauth').OAuthStrategy; // Tumblr
|
var OAuthStrategy = require('passport-oauth').OAuthStrategy; // Tumblr
|
||||||
var OAuth2Strategy = require('passport-oauth').OAuth2Strategy; // Venmo, Foursquare
|
var OAuth2Strategy = require('passport-oauth').OAuth2Strategy; // Venmo, Foursquare
|
||||||
var User = require('../models/User');
|
var User = require('../models/User');
|
||||||
@ -229,6 +230,59 @@ passport.use(new GoogleStrategy(secrets.google, function(req, accessToken, refre
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign in with LinkedIn.
|
||||||
|
*/
|
||||||
|
|
||||||
|
passport.use(new LinkedInStrategy(secrets.linkedin, function(req, accessToken, refreshToken, profile, done) {
|
||||||
|
if (req.user) {
|
||||||
|
User.findOne({ $or: [
|
||||||
|
{ linkedin: profile.id },
|
||||||
|
{ email: profile._json.emailAddress }
|
||||||
|
] }, function(err, existingUser) {
|
||||||
|
if (existingUser) {
|
||||||
|
req.flash('errors', { msg: 'There is already a LinkedIn account that belongs to you. Sign in with that account or delete it, then link it with your current account.' });
|
||||||
|
done(err);
|
||||||
|
} else {
|
||||||
|
User.findById(req.user.id, function(err, user) {
|
||||||
|
user.linkedin = profile.id;
|
||||||
|
user.tokens.push({ kind: 'linkedin', accessToken: accessToken });
|
||||||
|
user.profile.name = user.profile.name || profile.displayName;
|
||||||
|
user.profile.location = user.profile.location || profile._json.location.name;
|
||||||
|
user.profile.picture = user.profile.picture || profile._json.pictureUrl;
|
||||||
|
user.profile.website = user.profile.website || profile._json.publicProfileUrl;
|
||||||
|
user.save(function(err) {
|
||||||
|
req.flash('info', { msg: 'LinkedIn account has been linked.' });
|
||||||
|
done(err, user);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
User.findOne({ linkedin: profile.id }, function(err, existingUser) {
|
||||||
|
if (existingUser) return done(null, existingUser);
|
||||||
|
User.findOne({ email: profile._json.emailAddress }, function(err, existingEmailUser) {
|
||||||
|
if (existingEmailUser) {
|
||||||
|
req.flash('errors', { msg: 'There is already an account using this email address. Sign in to that account and link it with Google manually from Account Settings.' });
|
||||||
|
done(err);
|
||||||
|
} else {
|
||||||
|
var user = new User();
|
||||||
|
user.linkedin = profile.id;
|
||||||
|
user.tokens.push({ kind: 'linkedin', accessToken: accessToken });
|
||||||
|
user.email = profile._json.emailAddress;
|
||||||
|
user.profile.name = profile.displayName;
|
||||||
|
user.profile.location = profile._json.location.name;
|
||||||
|
user.profile.picture = profile._json.pictureUrl;
|
||||||
|
user.profile.website = profile._json.publicProfileUrl;
|
||||||
|
user.save(function(err) {
|
||||||
|
done(err, user);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tumblr API
|
* Tumblr API
|
||||||
* Uses OAuth 1.0a Strategy.
|
* Uses OAuth 1.0a Strategy.
|
||||||
|
@ -14,6 +14,7 @@ var Github = require('github-api');
|
|||||||
var Twit = require('twit');
|
var Twit = require('twit');
|
||||||
var paypal = require('paypal-rest-sdk');
|
var paypal = require('paypal-rest-sdk');
|
||||||
var twilio = require('twilio')(secrets.twilio.sid, secrets.twilio.token);
|
var twilio = require('twilio')(secrets.twilio.sid, secrets.twilio.token);
|
||||||
|
var Linkedin = require('node-linkedin')(secrets.linkedin.clientID, secrets.linkedin.clientSecret, secrets.linkedin.callbackURL);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /api
|
* GET /api
|
||||||
@ -482,3 +483,17 @@ exports.postVenmo = function(req, res, next) {
|
|||||||
res.redirect('/api/venmo');
|
res.redirect('/api/venmo');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.getLinkedin = function(req, res, next) {
|
||||||
|
var token = _.findWhere(req.user.tokens, { kind: 'linkedin' });
|
||||||
|
var linkedin = Linkedin.init(token.accessToken);
|
||||||
|
|
||||||
|
linkedin.people.me(function(err, $in) {
|
||||||
|
if (err) return next(err);
|
||||||
|
console.log($in.positions.values);
|
||||||
|
res.render('api/linkedin', {
|
||||||
|
title: 'LinkedIn API',
|
||||||
|
profile: $in
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
@ -10,6 +10,7 @@ var userSchema = new mongoose.Schema({
|
|||||||
twitter: { type: String, unique: true, sparse: true },
|
twitter: { type: String, unique: true, sparse: true },
|
||||||
google: { type: String, unique: true, sparse: true },
|
google: { type: String, unique: true, sparse: true },
|
||||||
github: { type: String, unique: true, sparse: true },
|
github: { type: String, unique: true, sparse: true },
|
||||||
|
linkedin: { type: String, unique: true, sparse: true },
|
||||||
tokens: Array,
|
tokens: Array,
|
||||||
|
|
||||||
profile: {
|
profile: {
|
||||||
|
18
package.json
18
package.json
@ -2,8 +2,8 @@
|
|||||||
"name": "hackathon-starter",
|
"name": "hackathon-starter",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type" : "git",
|
"type": "git",
|
||||||
"url" : "https://github.com/sahat/hackathon-starter.git"
|
"url": "https://github.com/sahat/hackathon-starter.git"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node app.js",
|
"start": "node app.js",
|
||||||
@ -14,6 +14,8 @@
|
|||||||
"bcrypt-nodejs": "~0.0.3",
|
"bcrypt-nodejs": "~0.0.3",
|
||||||
"cheerio": "~0.13.1",
|
"cheerio": "~0.13.1",
|
||||||
"connect-assets": "~3.0.0-beta1",
|
"connect-assets": "~3.0.0-beta1",
|
||||||
|
"connect-mongo": "~0.4.0",
|
||||||
|
"csso": "~1.3.11",
|
||||||
"express": "~3.4.8",
|
"express": "~3.4.8",
|
||||||
"express-flash": "~0.0.2",
|
"express-flash": "~0.0.2",
|
||||||
"express-validator": "~1.0.1",
|
"express-validator": "~1.0.1",
|
||||||
@ -24,24 +26,24 @@
|
|||||||
"less": "~1.6.3",
|
"less": "~1.6.3",
|
||||||
"mongoose": "~3.8.7",
|
"mongoose": "~3.8.7",
|
||||||
"node-foursquare": "~0.2.0",
|
"node-foursquare": "~0.2.0",
|
||||||
|
"node-linkedin": "~0.1.4",
|
||||||
"nodemailer": "~0.6.0",
|
"nodemailer": "~0.6.0",
|
||||||
"passport": "~0.2.0",
|
"passport": "~0.2.0",
|
||||||
"passport-facebook": "~1.0.2",
|
"passport-facebook": "~1.0.2",
|
||||||
"passport-github": "~0.1.5",
|
"passport-github": "~0.1.5",
|
||||||
"passport-google-oauth": "~0.1.5",
|
"passport-google-oauth": "~0.1.5",
|
||||||
|
"passport-linkedin-oauth2": "~1.1.1",
|
||||||
"passport-local": "~0.1.6",
|
"passport-local": "~0.1.6",
|
||||||
"passport-oauth": "~1.0.0",
|
"passport-oauth": "~1.0.0",
|
||||||
"passport-twitter": "~1.0.2",
|
"passport-twitter": "~1.0.2",
|
||||||
|
"paypal-rest-sdk": "~0.6.4",
|
||||||
"request": "~2.34.0",
|
"request": "~2.34.0",
|
||||||
"tumblr.js": "~0.0.4",
|
"tumblr.js": "~0.0.4",
|
||||||
|
"twilio": "~1.5.0",
|
||||||
"twit": "~1.1.12",
|
"twit": "~1.1.12",
|
||||||
"underscore": "~1.6.0",
|
"underscore": "~1.6.0",
|
||||||
"paypal-rest-sdk": "~0.6.4",
|
"uglify-js": "~2.4.12",
|
||||||
"connect-mongo": "~0.4.0",
|
"validator": "~3.3.0"
|
||||||
"twilio": "~1.5.0",
|
|
||||||
"validator": "~3.3.0",
|
|
||||||
"csso": "~1.3.11",
|
|
||||||
"uglify-js": "~2.4.12"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"chai": "~1.9.0",
|
"chai": "~1.9.0",
|
||||||
|
140
public/css/lib/bootstrap-social.less
vendored
Executable file
140
public/css/lib/bootstrap-social.less
vendored
Executable file
@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* Social Buttons for Bootstrap
|
||||||
|
*
|
||||||
|
* Copyright 2013-2014 Panayiotis Lipiridis
|
||||||
|
* Licensed under the MIT License
|
||||||
|
*
|
||||||
|
* https://github.com/lipis/bootstrap-social
|
||||||
|
*/
|
||||||
|
|
||||||
|
.btn-social {
|
||||||
|
@bs-height-base: (@line-height-computed + @padding-base-vertical * 2);
|
||||||
|
@bs-height-lg: (floor(@font-size-large * @line-height-base) + @padding-large-vertical * 2);
|
||||||
|
@bs-height-sm: (floor(@font-size-small * 1.5) + @padding-small-vertical * 2);
|
||||||
|
@bs-height-xs: (floor(@font-size-small * 1.2) + @padding-small-vertical + 1);
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
padding-left: @bs-height-base + @padding-base-horizontal;
|
||||||
|
text-align: left;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
:first-child {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: @bs-height-base;
|
||||||
|
line-height: (@bs-height-base + 2);
|
||||||
|
font-size: 1.6em;
|
||||||
|
text-align: center;
|
||||||
|
border-right: 1px solid rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
&.btn-lg {
|
||||||
|
padding-left: @bs-height-lg + @padding-large-horizontal;
|
||||||
|
:first-child {
|
||||||
|
line-height: @bs-height-lg;
|
||||||
|
width: @bs-height-lg;
|
||||||
|
font-size: 1.8em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.btn-sm {
|
||||||
|
padding-left: @bs-height-sm + @padding-small-horizontal;
|
||||||
|
:first-child {
|
||||||
|
line-height: @bs-height-sm;
|
||||||
|
width: @bs-height-sm;
|
||||||
|
font-size: 1.4em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.btn-xs {
|
||||||
|
padding-left: @bs-height-xs + @padding-small-horizontal;
|
||||||
|
:first-child {
|
||||||
|
line-height: @bs-height-xs;
|
||||||
|
width: @bs-height-xs;
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-social-icon {
|
||||||
|
.btn-social;
|
||||||
|
height: (@bs-height-base + 2);
|
||||||
|
width: (@bs-height-base + 2);
|
||||||
|
padding: 0;
|
||||||
|
:first-child {
|
||||||
|
border: none;
|
||||||
|
text-align: center;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
&.btn-lg {
|
||||||
|
height: @bs-height-lg;
|
||||||
|
width: @bs-height-lg;
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
&.btn-sm {
|
||||||
|
height: (@bs-height-sm + 2);
|
||||||
|
width: (@bs-height-sm + 2);
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
&.btn-xs {
|
||||||
|
height: (@bs-height-xs + 2);
|
||||||
|
width: (@bs-height-xs + 2);
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-social(@color-bg, @color: white) {
|
||||||
|
background-color: @color-bg;
|
||||||
|
.button-variant(@color, @color-bg, rgba(0, 0, 0, 0.2));
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-bitbucket {
|
||||||
|
.btn-social(#205081);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-dropbox {
|
||||||
|
.btn-social(#1087dd);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-facebook {
|
||||||
|
.btn-social(#3b5998);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-flickr {
|
||||||
|
.btn-social(#ff0084);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-foursquare {
|
||||||
|
.btn-social(#0072b1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-github {
|
||||||
|
.btn-social(#444444);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-google-plus {
|
||||||
|
.btn-social(#dd4b39);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-instagram {
|
||||||
|
.btn-social(#3f729b);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-linkedin {
|
||||||
|
.btn-social(#007bb6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-tumblr {
|
||||||
|
.btn-social(#2c4762);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-twitter {
|
||||||
|
.btn-social(#55acee);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-vk {
|
||||||
|
.btn-social(#587ea3);
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
@import (less) "lib/animate.css";
|
@import (less) "lib/animate.css";
|
||||||
@import (less) "lib/font-awesome.min.css";
|
@import (less) "lib/font-awesome.min.css";
|
||||||
@import "lib/bootstrap/bootstrap";
|
@import "lib/bootstrap/bootstrap";
|
||||||
|
@import "lib/bootstrap-social";
|
||||||
@import "themes/default";
|
@import "themes/default";
|
||||||
|
|
||||||
// Scaffolding
|
// Scaffolding
|
||||||
@ -50,49 +51,6 @@ body {
|
|||||||
height: 45px;
|
height: 45px;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Social Buttons
|
|
||||||
// -------------------------
|
|
||||||
|
|
||||||
.btn-facebook {
|
|
||||||
color: #fff;
|
|
||||||
background: #3b5998;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.07);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-twitter {
|
|
||||||
color: #fff;
|
|
||||||
background: #00aced;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.07);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-google-plus {
|
|
||||||
color: #fff;
|
|
||||||
background: #dd4b39;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.07);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-github {
|
|
||||||
color: #fff;
|
|
||||||
background: #333;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.07);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extra space between font-awesome icons and text
|
// Extra space between font-awesome icons and text
|
||||||
[class^="fa-"],
|
[class^="fa-"],
|
||||||
[class*="fa-"] {
|
[class*="fa-"] {
|
||||||
@ -119,7 +77,7 @@ body {
|
|||||||
|
|
||||||
.facebook-caption {
|
.facebook-caption {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background-color: rgba(0,0,0,0.5);
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
|
@ -1,29 +1,33 @@
|
|||||||
extends ../layout
|
extends ../layout
|
||||||
|
|
||||||
block content
|
block content
|
||||||
.col-sm-8.col-sm-offset-2
|
|
||||||
form(method='POST')
|
form(method='POST')
|
||||||
legend Sign In
|
legend Sign In
|
||||||
input(type='hidden', name='_csrf', value=token)
|
input(type='hidden', name='_csrf', value=token)
|
||||||
.form-group
|
.row
|
||||||
.btn-group.btn-group-justified
|
.col-sm-4
|
||||||
if secrets.facebookAuth
|
if secrets.facebookAuth
|
||||||
a.btn.btn-facebook(href='/auth/facebook')
|
a.btn.btn-block.btn-facebook.btn-social(href='/auth/facebook')
|
||||||
i.fa.fa-facebook
|
i.fa.fa-facebook
|
||||||
| Facebook
|
| Sign in with Facebook
|
||||||
if secrets.twitterAuth
|
if secrets.twitterAuth
|
||||||
a.btn.btn-twitter(href='/auth/twitter')
|
a.btn.btn-block.btn-twitter.btn-social(href='/auth/twitter')
|
||||||
i.fa.fa-twitter
|
i.fa.fa-twitter
|
||||||
| Twitter
|
| Sign in with Twitter
|
||||||
if secrets.githubAuth
|
|
||||||
a.btn.btn-github(href='/auth/github')
|
|
||||||
i.fa.fa-github
|
|
||||||
| GitHub
|
|
||||||
if secrets.googleAuth
|
if secrets.googleAuth
|
||||||
a.btn.btn-google-plus(href='/auth/google')
|
a.btn.btn-block.btn-google-plus.btn-social(href='/auth/google')
|
||||||
i.fa.fa-google-plus
|
i.fa.fa-google-plus
|
||||||
| Google
|
| Sign in with Google
|
||||||
|
if secrets.githubAuth
|
||||||
|
a.btn.btn-block.btn-github.btn-social(href='/auth/github')
|
||||||
|
i.fa.fa-github
|
||||||
|
| Sign in with GitHub
|
||||||
|
if secrets.linkedinAuth
|
||||||
|
a.btn.btn-block.btn-linkedin.btn-social(href='/auth/linkedin')
|
||||||
|
i.fa.fa-linkedin
|
||||||
|
| Sign in with LinkedIn
|
||||||
if secrets.localAuth
|
if secrets.localAuth
|
||||||
|
.col-sm-8
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(for='email') Email
|
label.control-label(for='email') Email
|
||||||
input.form-control(type='text', name='email', id='email', placeholder='Email', autofocus=true)
|
input.form-control(type='text', name='email', id='email', placeholder='Email', autofocus=true)
|
||||||
|
@ -98,3 +98,9 @@ block content
|
|||||||
p: a.text-danger(href='/account/unlink/github') Unlink your GitHub account
|
p: a.text-danger(href='/account/unlink/github') Unlink your GitHub account
|
||||||
else
|
else
|
||||||
p: a(href='/auth/github') Link your GitHub account
|
p: a(href='/auth/github') Link your GitHub account
|
||||||
|
|
||||||
|
if secrets.linkedinAuth
|
||||||
|
if user.linkedin
|
||||||
|
p: a.text-danger(href='/account/unlink/linkedin') Unlink your LinkedIn account
|
||||||
|
else
|
||||||
|
p: a(href='/auth/linkedin') Link your LinkedIn account
|
||||||
|
@ -17,6 +17,9 @@ block content
|
|||||||
small ⇢ Login Required
|
small ⇢ Login Required
|
||||||
li
|
li
|
||||||
a(href='/api/lastfm') Last.fm
|
a(href='/api/lastfm') Last.fm
|
||||||
|
li
|
||||||
|
a(href='/api/linkedin') LinkedIn
|
||||||
|
small ⇢ Login Required
|
||||||
li
|
li
|
||||||
a(href='/api/nyt') New York Times
|
a(href='/api/nyt') New York Times
|
||||||
li
|
li
|
||||||
|
71
views/api/linkedin.jade
Normal file
71
views/api/linkedin.jade
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
extends ../layout
|
||||||
|
|
||||||
|
block content
|
||||||
|
.page-header
|
||||||
|
h2
|
||||||
|
i.fa.fa-linkedin-square
|
||||||
|
| LinkedIn API
|
||||||
|
|
||||||
|
.btn-group.btn-group-justified
|
||||||
|
a.btn.btn-primary(href='https://github.com/Kuew/node-linkedin', target='_blank')
|
||||||
|
i.fa.fa-book
|
||||||
|
| Node LinkedIn Docs
|
||||||
|
a.btn.btn-primary(href='http://developer.linkedin.com/documents/authentication', target='_blank')
|
||||||
|
i.fa.fa-check-square-o
|
||||||
|
| Getting Started
|
||||||
|
a.btn.btn-primary(href='http://developer.linkedin.com/apis', target='_blank')
|
||||||
|
i.fa.fa-code-fork
|
||||||
|
| API Endpoints
|
||||||
|
|
||||||
|
h3.text-primary My LinkedIn Profile
|
||||||
|
.well.well-sm
|
||||||
|
.row
|
||||||
|
.col-sm-12
|
||||||
|
.col-sm-2
|
||||||
|
br
|
||||||
|
img.thumbnail(src='#{profile.pictureUrl}')
|
||||||
|
.col-sm-10
|
||||||
|
h3= profile.formattedName
|
||||||
|
h4= profile.headline
|
||||||
|
span.text-muted #{profile.location.name} | #{profile.industry}
|
||||||
|
br
|
||||||
|
.row
|
||||||
|
.col-sm-12
|
||||||
|
dl.dl-horizontal
|
||||||
|
dt.text-muted Current
|
||||||
|
for company in profile.positions.values
|
||||||
|
if company.isCurrent
|
||||||
|
dd
|
||||||
|
strong= company.title
|
||||||
|
| at
|
||||||
|
strong #{company.company.name}
|
||||||
|
dt.text-muted Previous
|
||||||
|
for company in profile.positions.values
|
||||||
|
if !company.isCurrent
|
||||||
|
dd
|
||||||
|
| #{company.title}
|
||||||
|
| at
|
||||||
|
| #{company.company.name}
|
||||||
|
dt.text-muted Education
|
||||||
|
for education in profile.educations.values
|
||||||
|
dd= education.schoolName
|
||||||
|
dt.text-muted Recommendations
|
||||||
|
dd
|
||||||
|
strong #{profile.numRecommenders}
|
||||||
|
| recommendation(s) received
|
||||||
|
dt.text-muted Connections
|
||||||
|
dd
|
||||||
|
strong #{profile.numConnections}
|
||||||
|
| connections
|
||||||
|
.text-center
|
||||||
|
small.text-muted= profile.publicProfileUrl
|
||||||
|
|
||||||
|
h3.text-primary LinkedIn Connections
|
||||||
|
table.table.table-hover.table-striped.table-bordered
|
||||||
|
tbody
|
||||||
|
for connection in profile.connections.values
|
||||||
|
if connection.id != 'private'
|
||||||
|
tr
|
||||||
|
td
|
||||||
|
strong #{connection.firstName} #{connection.lastName}
|
||||||
|
.text-muted #{connection.headline}
|
Reference in New Issue
Block a user