// Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy of // the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations under // the License. // $$ inspired by @wycats: http://yehudakatz.com/2009/04/20/evented-programming-with-jquery/ function $$(node) { var data = $(node).data("$$"); if (data) { return data; } else { data = {}; $(node).data("$$", data); return data; } }; (function($) { function Session() { function doLogin(name, password, callback) { $.couch.login({ name : name, password : password, success : function() { $.futon.session.sidebar(); callback(); }, error : function(code, error, reason) { $.futon.session.sidebar(); callback({name : "Error logging in: "+reason}); } }); }; function doSignup(name, password, callback, runLogin) { $.couch.signup({ name : name }, password, { success : function() { if (runLogin) { doLogin(name, password, callback); } else { callback(); } }, error : function(status, error, reason) { $.futon.session.sidebar(); if (error == "conflict") { callback({name : "Name '"+name+"' is taken"}); } else { callback({name : "Signup error: "+reason}); } } }); }; function validateUsernameAndPassword(data, callback) { if (!data.name || data.name.length == 0) { callback({name: "Please enter a name."}); return false; }; return validatePassword(data, callback); }; function validatePassword(data, callback) { if (!data.password || data.password.length == 0) { callback({password: "Please enter a password."}); return false; }; return true; }; function createAdmin() { $.showDialog("dialog/_create_admin.html", { submit: function(data, callback) { if (!validateUsernameAndPassword(data, callback)) return; $.couch.config({ success : function() { doLogin(data.name, data.password, function(errors) { if(!$.isEmptyObject(errors)) { callback(errors); return; } doSignup(data.name, null, function(errors) { if (errors && errors.name && errors.name.indexOf && errors.name.indexOf("taken") == -1) { callback(errors); } else { callback(); } }, false); }); } }, "admins", data.name, data.password); } }); return false; }; function login() { $.showDialog("dialog/_login.html", { submit: function(data, callback) { if (!validateUsernameAndPassword(data, callback)) return; doLogin(data.name, data.password, callback); } }); return false; }; function logout() { $.couch.logout({ success : function(resp) { $.futon.session.sidebar(); } }) }; function signup() { $.showDialog("dialog/_signup.html", { submit: function(data, callback) { if (!validateUsernameAndPassword(data, callback)) return; doSignup(data.name, data.password, callback, true); } }); return false; }; function changePassword () { $.showDialog("dialog/_change_password.html", { submit: function(data, callback) { if (validatePassword(data, callback)) { if (data.password != data.verify_password) { callback({verify_password: "Passwords don't match."}); return false; } } else { return false; } $.couch.session({success: function (resp) { if (resp.userCtx.roles.indexOf("_admin") > -1) { $.couch.config({ success : function () { doLogin(resp.userCtx.name, data.password, function(errors) { if(!$.isEmptyObject(errors)) { callback(errors); return; } else { location.reload(); } }); } }, "admins", resp.userCtx.name, data.password); } else { $.couch.db(resp.info.authentication_db).openDoc("org.couchdb.user:"+resp.userCtx.name, { success: function (user) { $.couch.db(resp.info.authentication_db).saveDoc($.couch.prepareUserDoc(user, data.password), { success: function() { doLogin(user.name, data.password, function(errors) { if(!$.isEmptyObject(errors)) { callback(errors); return; } else { location.reload(); } }); } }); } }); } }}); } }); return false; }; this.setupSidebar = function() { $("#userCtx .login").click(login); $("#userCtx .logout").click(logout); $("#userCtx .signup").click(signup); $("#userCtx .createadmin").click(createAdmin); $("#userCtx .changepass").click(changePassword); }; this.sidebar = function() { // get users db info? $("#userCtx span").hide(); $.couch.session({ success : function(r) { var userCtx = r.userCtx; $$("#userCtx").userCtx = userCtx; if (userCtx.name) { $("#userCtx .name").text(userCtx.name).attr({href : $.couch.urlPrefix + "/_utils/document.html?"+encodeURIComponent(r.info.authentication_db)+"/org.couchdb.user%3A"+encodeURIComponent(userCtx.name)}); if (userCtx.roles.indexOf("_admin") != -1) { $("#userCtx .loggedin").show(); $("#userCtx .loggedinadmin").show(); } else { $("#userCtx .loggedin").show(); } } else if (userCtx.roles.indexOf("_admin") != -1) { $("#userCtx .adminparty").show(); } else { $("#userCtx .loggedout").show(); }; } }) }; }; function Navigation() { var nav = this; this.loaded = false; this.eventHandlers = { load: [] }; this.ready = function(callback) { if (callback) { if (this.loaded) { callback.apply(this); } this.eventHandlers["load"].push(callback); } else { this.loaded = true; callbacks = this.eventHandlers["load"]; for (var i = 0; i < callbacks.length; i++) { callbacks[i].apply(this); } } } this.addDatabase = function(name) { var current = $.futon.storage.get("recent", ""); var recentDbs = current ? current.split(",") : []; if ($.inArray(name, recentDbs) == -1) { recentDbs.unshift(name); if (recentDbs.length > 10) recentDbs.length = 10; $.futon.storage.set("recent", recentDbs.join(",")); this.updateDatabases(); } } this.removeDatabase = function(name) { // remove database from recent databases list var current = $.futon.storage.get("recent", ""); var recentDbs = current ? current.split(",") : []; var recentIdx = $.inArray(name, recentDbs); if (recentIdx >= 0) { recentDbs.splice(recentIdx, 1); $.futon.storage.set("recent", recentDbs.join(",")); this.updateDatabases(); } } this.updateDatabases = function() { var selection = null; $("#dbs .selected a").each(function() { selection = [this.pathname, this.search]; }); $("#dbs").empty(); var recentDbs = $.futon.storage.get("recent").split(","); recentDbs.sort(); $.each(recentDbs, function(idx, name) { if (name) { name = encodeURIComponent(name); $("#dbs").append("