diff options
| -rw-r--r-- | bucky/app/index.js | 10 | ||||
| -rw-r--r-- | bucky/app/router.js | 11 | ||||
| -rw-r--r-- | bucky/util/auth.js | 84 | ||||
| -rw-r--r-- | public/assets/css/bucky.css | 23 | ||||
| -rw-r--r-- | public/assets/js/index.js | 6 | ||||
| -rw-r--r-- | public/assets/js/lib/router.js | 1 | ||||
| -rw-r--r-- | public/assets/js/lib/sdk/_sdk.js | 34 | ||||
| -rw-r--r-- | public/assets/js/lib/sdk/auth.js | 75 | ||||
| -rw-r--r-- | public/assets/js/lib/views/details/comments.js | 1 | ||||
| -rw-r--r-- | public/assets/js/lib/views/login/login.js | 18 | ||||
| -rw-r--r-- | public/assets/js/vendor/view/formview.js | 33 | ||||
| -rw-r--r-- | views/pages/login.ejs | 13 | ||||
| -rw-r--r-- | views/partials/scripts.ejs | 3 |
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"> </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> |
