summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bucky/app/index.js10
-rw-r--r--bucky/app/router.js11
-rw-r--r--bucky/util/auth.js84
-rw-r--r--public/assets/css/bucky.css23
-rw-r--r--public/assets/js/index.js6
-rw-r--r--public/assets/js/lib/router.js1
-rw-r--r--public/assets/js/lib/sdk/_sdk.js34
-rw-r--r--public/assets/js/lib/sdk/auth.js75
-rw-r--r--public/assets/js/lib/views/details/comments.js1
-rw-r--r--public/assets/js/lib/views/login/login.js18
-rw-r--r--public/assets/js/vendor/view/formview.js33
-rw-r--r--views/pages/login.ejs13
-rw-r--r--views/partials/scripts.ejs3
13 files changed, 249 insertions, 63 deletions
diff --git a/bucky/app/index.js b/bucky/app/index.js
index e2fcd48..0da18c7 100644
--- a/bucky/app/index.js
+++ b/bucky/app/index.js
@@ -21,13 +21,8 @@ var site = module.exports = {}
site.init = function(){
app = express()
app.set('port', 5000)
- app.set('view engine', 'ejs')
- app.set('views', path.join(__dirname, '../../views'))
- app.use(express.static(path.join(__dirname, '../../public')))
-
app.use(favicon(__dirname + '../../../public/favicon.ico'))
app.use(bodyParser.json())
- app.use(bodyParser.urlencoded({ extended: false }))
app.use(session({
key: 'bucky.sid',
@@ -45,6 +40,7 @@ site.init = function(){
saveUninitialized: false,
}))
app.use(csurf({ cookie: false }))
+ app.disable('x-powered-by')
app.use(express.query())
app.use(passport.initialize())
@@ -61,6 +57,10 @@ site.init = function(){
})
site.route(app)
+
+ app.set('view engine', 'ejs')
+ app.set('views', path.join(__dirname, '../../views'))
+ app.use(express.static(path.join(__dirname, '../../public')))
}
site.route = require('./router')
diff --git a/bucky/app/router.js b/bucky/app/router.js
index 007ff6b..eada09b 100644
--- a/bucky/app/router.js
+++ b/bucky/app/router.js
@@ -15,11 +15,6 @@ module.exports = function(app){
app.get("/", middleware.ensureAuthenticated, function(req, res){
res.redirect('/index')
})
- app.get("/login", function(req, res){
- res.render("pages/login", {
- title: "login"
- })
- })
app.get("/index", middleware.ensureAuthenticated, function(req, res){
res.render("pages/index", {
title: fortune("titles"),
@@ -49,7 +44,6 @@ module.exports = function(app){
}
)
- app.post("/api/login", auth.loggedInLocal)
app.get("/api/index",
bucky.ensureLastlog,
middleware.ensureAuthenticated,
@@ -66,10 +60,10 @@ module.exports = function(app){
})
}
)
+
app.get("/api/keyword/:keyword",
bucky.ensureLastlog,
middleware.ensureAuthenticated,
- bucky.keyword,
bucky.ensureThreadsForKeyword,
bucky.ensureCommentCountsForThreads,
bucky.ensureFileCountsForThreads,
@@ -223,5 +217,6 @@ module.exports = function(app){
// send new mail
}
)
-
+
+ auth.route(app)
}
diff --git a/bucky/util/auth.js b/bucky/util/auth.js
index 436d5e6..6fdd5bd 100644
--- a/bucky/util/auth.js
+++ b/bucky/util/auth.js
@@ -1,17 +1,53 @@
-var passport = require('passport'),
- LocalStrategy = require('passport-local').Strategy,
- crypto = require('crypto'),
- db = require('../db');
+var passport = require('passport');
+var LocalStrategy = require('passport-local').Strategy;
+var crypto = require('crypto');
+var db = require('../db');
+var middleware = require('./middleware')
var auth = module.exports = {
init: function(){
passport.serializeUser(auth.serializeUser)
passport.deserializeUser(auth.deserializeUser)
-
passport.use(new LocalStrategy(auth.verifyLocalUser))
+ },
+
+ route: function(app){
+ app.get("/login",
+ function(req, res){
+ res.render("pages/login", {
+ title: "login"
+ })
+ })
+ app.get("/signup", function(req, res){
+ res.render("pages/signup", {
+ title: "signup"
+ })
+ })
+ app.get("/logout", auth.logout)
+ app.put("/api/login",
+ passport.authenticate("local"),
+ function (req, res) {
+ if (req.isAuthenticated()) {
+ var returnTo = req.session.returnTo
+ delete req.session.returnTo
+ console.log("LOGGED IN", req.user.username)
+ return res.json({
+ status: "OK",
+ user: auth.sanitizeUser(req.user),
+ returnTo: returnTo || "/index",
+ })
+ }
+ res.json({
+ error: 'bad credentials',
+ })
+ })
+ app.put("/api/checkin",
+ middleware.ensureAuthenticated,
+ auth.checkin
+ )
},
serializeUser: function (user, done) {
@@ -39,35 +75,23 @@ var auth = module.exports = {
return done(null, user)
- if (! user) {
- return done(null, false, { error: { errors: { username: { message: 'No such username.' } }}})
- }
- if (! auth.validPassword(user, password)) {
- return done(null, false, { error: { errors: { password: { message: 'Incorrect password.' } }}})
+ if (! user || ! auth.validPassword(user, password)) {
+ return done(null, false, { error: { message: 'Bad username/password.' } })
}
return done(null, user);
})
},
- loggedInLocal: function (req, res, next) {
- passport.authenticate("local", function(err, user, info){
- if (err) {
- return res.json({ error: err });
- }
- if (! user) {
- return info ? res.json(info) : res.redirect("/login");
- }
-
- // user.last_seen = new Date ()
- // user.save(function(err, data){ if (err) console.err('error setting ip for user') })
-
- req.logIn(user, function(err) {
- if (err) { return next(err); }
- var returnTo = req.session.returnTo
- delete req.session.returnTo
- return res.json({ status: "OK", returnTo: returnTo || "/index" })
- });
- })(req, res, next)
+ sanitizeUser: function (req_user) {
+ // sanitize user object
+ var user = JSON.parse(JSON.stringify(req_user))
+ delete user.password
+ return user
+ },
+
+ checkin: function (req, res) {
+ var user = auth.sanitizeUser(req.user)
+ res.json(user)
},
logout: function (req, res) {
@@ -75,4 +99,4 @@ var auth = module.exports = {
res.redirect('/');
},
-} \ No newline at end of file
+}
diff --git a/public/assets/css/bucky.css b/public/assets/css/bucky.css
index 8874311..e96c0aa 100644
--- a/public/assets/css/bucky.css
+++ b/public/assets/css/bucky.css
@@ -83,6 +83,13 @@ a:hover { color: #2040f0; text-decoration: underline; }
hr {
border-color: #000;
}
+input[type=text],
+input[type=password] {
+ font-family: 'Trebuchet MS', sans-serif;
+ font-size: 10px;
+ border: 1px solid #888;
+ padding: 3px;
+}
#menu {
margin: 7px 0 14px;
}
@@ -344,7 +351,8 @@ tr:nth-child(even) td.black { background-color: #eee; border-bottom-color:
margin: 0;
padding: 0 3px 3px 0;
text-align: center;
- font-size: 11px;
+ font-size: 10px;
+ opacity: 0.8;
vertical-align: top;
}
#comments .avatar {
@@ -416,8 +424,6 @@ pre br {
width: 100%;
padding: 5px;
font-size: 15px;
- font-family: 'Trebuchet MS', sans-serif;
- border: 1px solid #888;
margin-top: 10px;
}
#thread_form textarea {
@@ -676,6 +682,17 @@ pre br {
header .search_form {
display: none;
}
+
+/* LOGIN */
+
+#login div,
+#signup div {
+ margin: 2px;
+}
+#login .errors {
+ display: inline-block;
+}
+
@media (max-width: 700px) {
body {
padding: 10px 10px;
diff --git a/public/assets/js/index.js b/public/assets/js/index.js
index 8f1a059..4576fd4 100644
--- a/public/assets/js/index.js
+++ b/public/assets/js/index.js
@@ -7,6 +7,12 @@ var app = (function(){
$(window).on("focus", app.focus)
$(window).on("blur", app.blur)
+
+ auth.init(app.ready)
+ }
+
+ app.ready = function(){
+ app.router.route()
}
app.focused = true
diff --git a/public/assets/js/lib/router.js b/public/assets/js/lib/router.js
index 8146906..6802a86 100644
--- a/public/assets/js/lib/router.js
+++ b/public/assets/js/lib/router.js
@@ -18,7 +18,6 @@ var SiteRouter = Router.extend({
},
initialize: function(){
- this.route()
},
index: function(keyword){
diff --git a/public/assets/js/lib/sdk/_sdk.js b/public/assets/js/lib/sdk/_sdk.js
new file mode 100644
index 0000000..320113e
--- /dev/null
+++ b/public/assets/js/lib/sdk/_sdk.js
@@ -0,0 +1,34 @@
+var sdk = (function(){
+ var sdk = {}
+
+ sdk.env = "development"
+
+ var endpoint = window.location.origin
+
+ sdk.init = function(opt){
+ switch (sdk.env = opt.env || "development") {
+ case 'test':
+ break
+ default:
+ case 'development':
+ break
+ case 'production':
+ break
+ }
+ }
+
+ sdk.path = function(api){
+ return endpoint + api
+ }
+
+ sdk.image = function(file, size){
+ return "https://i.asdf.us/bucky/data/" + file.thread + "/" + file.id
+ }
+
+// $.ajaxSetup({
+// // possibly: application/json; charset=utf-8"
+// contentType: "application/json",
+// })
+
+ return sdk
+})() \ No newline at end of file
diff --git a/public/assets/js/lib/sdk/auth.js b/public/assets/js/lib/sdk/auth.js
new file mode 100644
index 0000000..a5a735a
--- /dev/null
+++ b/public/assets/js/lib/sdk/auth.js
@@ -0,0 +1,75 @@
+var auth = (function(){
+ var auth = {}
+
+ auth.appname = is_iphone ? "bucky-web/3.0.0" : "bucky-web/3.0.0"
+ auth.apikey = "influssiblefraubuzzardsunsetideogrammatton"
+ auth.device = "browser"
+
+ auth.user = {id:-1}
+
+ auth.next_view = null
+
+ auth.init = function(fn){
+ console.log("auth init")
+ // if we're on an authentication page, ignore the current user
+ if (window.location.pathname !== '/login' || window.location.pathname !== '/signup') {
+ fn && fn( false )
+ return
+ }
+ auth.load_user(function(user){
+ var logged_in = auth.logged_in()
+ if (logged_in) {
+ fn && fn()
+ return
+ }
+ auth.checkin({
+ success: function(user){
+ if (user) {
+ auth.set_user(user, fn)
+ }
+ },
+ error: function(){
+ window.location.href = "/login"
+ }
+ })
+ })
+ }
+ auth.get_user = function(cb){
+ cb && cb(auth.user)
+ }
+ auth.set_user = function(user, cb){
+ auth.user = user
+ localStorage.setItem("bucky.user", JSON.stringify(user))
+ cb && cb()
+ }
+ auth.load_user = function(cb){
+ var user
+ var user_str = localStorage.getItem("bucky.user")
+ if (user_str && user_str.length) {
+ try {
+ user = JSON.parse(user_str)
+ if (! user.id) user = {id:-1}
+ } catch(e) {
+ user = {id:-1}
+ }
+ }
+ auth.user = user
+ cb && cb(user)
+ }
+ auth.clear_user = function(cb){
+ auth.user = {id:-1}
+ localStorage.removeItem("bucky.user")
+ cb && cb()
+ }
+ auth.log_out = function(){
+ auth.clear_user()
+ }
+ auth.logged_in = function(){
+ return (auth.user.id && auth.user.id !== -1 && auth.user.id !== "undefined")
+ }
+ auth.checkin = function(){
+
+ }
+
+ return auth
+})() \ No newline at end of file
diff --git a/public/assets/js/lib/views/details/comments.js b/public/assets/js/lib/views/details/comments.js
index 65473c6..5d99138 100644
--- a/public/assets/js/lib/views/details/comments.js
+++ b/public/assets/js/lib/views/details/comments.js
@@ -26,7 +26,6 @@ var CommentsView = FormView.extend({
.replace(/{{comment}}/g, tidy_urls(comment.comment))
.replace(/{{date}}/g, datetime[0])
.replace(/{{time}}/g, datetime[1])
- console.log(t)
var $t = $(t)
return $t
},
diff --git a/public/assets/js/lib/views/login/login.js b/public/assets/js/lib/views/login/login.js
index 90c1b67..48676e9 100644
--- a/public/assets/js/lib/views/login/login.js
+++ b/public/assets/js/lib/views/login/login.js
@@ -2,20 +2,30 @@ var LoginView = FormView.extend({
el: "#login",
action: "/api/login",
- method: "POST",
+ method: "put",
initialize: function(opt){
this.__super__.initialize.call(this)
+ $("body").removeClass("loading")
this.$("[name=username]").focus()
},
- showErrors: function(errors){
- console.log(errors)
+ showErrors: function(err){
+ $(".errors").show().css({ opacity: 1 }).html("Bad username/password combo")
},
success: function(data){
+ console.log("LOGGED IN?", data)
+ if (data.user) {
+ auth.set_user(data.user)
+ }
+ else {
+ this.showErrors()
+ return
+ }
if (data.returnTo) {
- window.location.href = "/index"
+ console.log(data.returnTo)
+ window.location.href = data.returnTo
}
else {
window.location.href = "/index"
diff --git a/public/assets/js/vendor/view/formview.js b/public/assets/js/vendor/view/formview.js
index f71c550..b2825a2 100644
--- a/public/assets/js/vendor/view/formview.js
+++ b/public/assets/js/vendor/view/formview.js
@@ -33,30 +33,40 @@ var FormView = View.extend({
},
serialize: function(){
- var fd = new FormData(), hasCSRF = false
+ var fd, fh, hasCSRF = false
+ var file_els = this.$("input[name][type='file']")
+ if (file_els.length) {
+ fd = new FormData()
+ }
+ else {
+ fh = {}
+ }
this.$("input[name], select[name], textarea[name]").each( function(){
if (this.type == "file") {
for (var i = 0; i < this.files.length; i++) {
fd.append(this.name, this.files[i]);
}
}
- else if (this.type == "password") {
- if (this.value.length > 0) {
- fd.append(this.name, SHA1.hex('bucky$' + this.value + '$bucky'))
- }
- }
else {
- fd.append(this.name, this.value);
+ if (fd) {
+ fd.append(this.name, this.value)
+ } else {
+ fh[this.name] = this.value
+ }
hasCSRF = hasCSRF || this.name == "_csrf"
}
});
if (! hasCSRF) {
- fd.append("_csrf", $("[name=_csrf]").attr("value"))
+ if (fd) {
+ fd.append("_csrf", $("[name=_csrf]").attr("value"))
+ } else {
+ fh["_csrf"] = $("[name=_csrf]").attr("value")
+ }
}
- return fd
+ return fd || JSON.stringify(fh)
},
save: function(e, successCallback, errorCallback){
@@ -80,14 +90,15 @@ var FormView = View.extend({
var action = typeof this.action == "function" ? this.action() : this.action
if (! action) return
+ var data = this.serialize()
var request = $.ajax({
url: action,
type: this.method,
- data: this.serialize(),
+ data: data,
headers: { "csrf-token": $("[name=_csrf]").attr("value") },
+ contentType: data instanceof FormData ? false : "application/json",
dataType: "json",
processData: false,
- contentType: false,
success: function(response){
console.log(response)
if (response.error) {
diff --git a/views/pages/login.ejs b/views/pages/login.ejs
index 7c56c2f..074be1a 100644
--- a/views/pages/login.ejs
+++ b/views/pages/login.ejs
@@ -16,6 +16,19 @@
<label for="login-submit"></label>
<button id="login-submit">LOGIN</button>
</div>
+
+ <br>
+ <div>
+ <label></label>
+ <span class="errors">&nbsp;</span>
+ </div>
+ <br>
+
+ <div>
+ <label></label>
+ <a href="/signup">Signup</a>
+ </div>
+
</form>
</div>
diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs
index 5bb7049..79ef89e 100644
--- a/views/partials/scripts.ejs
+++ b/views/partials/scripts.ejs
@@ -8,6 +8,9 @@
<script src="/assets/js/vendor/view/formview.js"></script>
<script src="/assets/js/vendor/view/router.js"></script>
+<script src="/assets/js/lib/sdk/_sdk.js"></script>
+<script src="/assets/js/lib/sdk/auth.js"></script>
+
<script src="/assets/js/lib/router.js"></script>
<script src="/assets/js/util/format.js"></script>