library.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
CIVITAS - NodeBB 连接系统 | |
Proudly powered by oott123 | |
*/ | |
(function (module) { | |
"use strict"; | |
var User = module.parent.require('./user'), | |
Topics = module.parent.require('./topics'), | |
winston = module.parent.require('winston'), | |
_ = module.parent.require('underscore'), | |
crypto = require('crypto'), | |
async = module.parent.require('async'); | |
var config = { | |
id: '', | |
secret: '', | |
host: 'api.soobb.com' | |
}; | |
/* | |
* 拒绝访客页面中间件 | |
*/ | |
var rejectGuest = function (req, res, next) { | |
if (req.user) { | |
return next(); | |
} | |
return res.redirect('/login'); | |
}; | |
/* | |
* 登出 hook | |
*/ | |
var logoutMid = function (req, res, next) { | |
res.clearCookie('CIVITAS-Authentication', { | |
domain: '.soobb.com' | |
}); | |
next(); | |
}; | |
/** | |
* 对 civitas api 做请求签名 | |
* @param url string 要请求的路径 | |
* @param query object 要请求的请求体 | |
* @return string 返回签名值(base64(sha1(sort(query)+secret+timestamp))) | |
*/ | |
var signRequest = function (url, query) { | |
var sortedKeys = _.keys(query).sort(); | |
var sortedQueryString = []; | |
for (var i = 0; i < sortedKeys.length; i++) { | |
sortedQueryString.push(sortedKeys[i] + '=' + query[sortedKeys[i]]); | |
} | |
var queryString = url + '?' + sortedQueryString.join('&'); | |
var signStr = queryString + ',' + | |
config.secret + ',' + | |
query.Timestamp; | |
return crypto.createHash('sha1').update(signStr).digest('base64'); | |
}; | |
/** | |
* 进行 civitas api 请求 | |
* @param url string 要请求的路径 | |
* @param query object 要请求的内容 | |
* @return string 回调返回请求结果 | |
*/ | |
var apiRequest = function (url, query, callback) { | |
query.Timestamp = parseInt((new Date()).getTime() / 1000); | |
query.Signature = signRequest(url, query); | |
query.Identifier = config.id; | |
var requestLib = require('request'); | |
requestLib.post('http://' + config.host + '/' + url, { | |
form: query, | |
timeout: 3000 | |
}, function (error, response, body) { | |
if (error || response.statusCode != 200) return callback(error || response.statusCode); | |
callback(null, body); | |
}); | |
}; | |
var CIVPass = {}; | |
CIVPass.init = function (app, middleware, controllers) { | |
app.get(/(\/|\/api\/)login/, function (req, res) { | |
//res.redirect('http://civitas.soobb.com/'); | |
res.write('<script>window.top.location="http://civitas.soobb.com/"</script>'); | |
return res.end(); | |
}); | |
app.all('*', function (req, res, next) { | |
var authCookie = req.cookies['CIVITAS-Authentication']; | |
if (!authCookie) { | |
req.user = null; | |
return req.session.destroy(function (err) { | |
next(); | |
}); | |
} | |
if (req.user) { | |
return next(); | |
} | |
async.waterfall([ | |
function (done) { | |
apiRequest('Accounts/GetProfile', { | |
Token: authCookie | |
}, done); | |
}, | |
function (apiData, done) { | |
var arr = false; | |
try { | |
arr = JSON.parse(apiData); | |
} catch (e) { | |
return done(e); | |
} | |
var extraIDs = null; | |
if (arr.CIVITASIDs instanceof Array) { | |
extraIDs = arr.CIVITASIDs.join(':'); | |
} | |
var userData = { | |
username: arr.Nickname, | |
email: arr.Email, | |
picture: arr.Avatar, | |
uploadedpicture: arr.Avatar, | |
civitasID: arr.CIVITASID, | |
extraIDs: extraIDs | |
}; | |
User.getUidByEmail(userData.email, function (err, uid) { | |
if (err) return done(err); | |
done(null, { | |
uid: uid, | |
userData: userData | |
}); | |
}); | |
}, | |
function (thatData, done) { | |
if (thatData.uid) { | |
//=== 用户已存在 case === | |
//更新用户资料的同时返回…… | |
User.setUserFields(thatData.uid, thatData.userData); | |
return done(null, thatData.uid); | |
} else { | |
//=== 用户不存在 case === | |
User.create(thatData.userData, done); | |
} | |
}, | |
function (uid, done) { | |
req.login({ | |
uid: uid | |
}, done); | |
} | |
], function (err, data) { | |
if (err) { | |
return res.end; | |
} | |
next(); | |
}); | |
}); | |
app.get('/civitas/back/', function (req, res) { | |
return res.redirect('http://civitas.soobb.com/#BackFromBB'); | |
}) | |
app.get('/civitas/resent/', function (req, res) { | |
Topics.getLatestTopics(1, 0, 10, 'day', function (err, topics) { | |
if (err) res.end(); | |
var returnArr = [], | |
topics = topics.topics; | |
for (var i = 0; i < topics.length; i++) { | |
var top = topics[i]; | |
returnArr.push({ | |
slug: top.slug, | |
timestamp: top.timestamp, | |
title: top.title, | |
category: { | |
name: top.category.name, | |
slug: top.category.slug | |
}, | |
username: top.user.username, | |
avatar: top.user.picture | |
}); | |
} | |
res.write('civitas_resent_callback('); | |
res.write(JSON.stringify(returnArr)); | |
res.write(')'); | |
res.end(); | |
}); | |
}); | |
app.post('/logout', logoutMid); | |
}; | |
/* | |
* 帖子资料栏增加条目 | |
*/ | |
CIVPass.connectCivtas = function (profileInfo, callback) { | |
User.getUserField(profileInfo.uid, 'civitasID', function (err, data) { | |
//加入 civitasID | |
if (data) { | |
profileInfo.profile.push({ | |
content: '<a href="http://civitas.soobb.com/People/' + data + '/">拜访居民</a>' | |
}); | |
} | |
//……和论坛 ID | |
profileInfo.profile.push({ | |
content: '#' + profileInfo.uid | |
}); | |
callback(err, profileInfo); | |
}); | |
}; | |
/* | |
* 导航栏增加条目 | |
*/ | |
CIVPass.headerNav = function (header, callback) { | |
header.navigation.push({ | |
'route': '/civitas/back/', | |
'title': '返回 CIVITAS', | |
'iconClass': 'fa-reply', | |
'textClass': 'visible-xs-inline', | |
'text': '返回 CIVITAS' | |
}); | |
return callback(null, header); | |
}; | |
module.exports = CIVPass; | |
}(module)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment