| 1 | // PLUGIN_INFO//{{{ |
|---|
| 2 | var PLUGIN_INFO = |
|---|
| 3 | <VimperatorPlugin> |
|---|
| 4 | <name>{NAME}</name> |
|---|
| 5 | <description>login manager</description> |
|---|
| 6 | <author mail="konbu.komuro@gmail.com" homepage="http://d.hatena.ne.jp/hogelog/">hogelog</author> |
|---|
| 7 | <version>0.0.1</version> |
|---|
| 8 | <minVersion>2.0pre</minVersion> |
|---|
| 9 | <maxVersion>2.0pre</maxVersion> |
|---|
| 10 | <updateURL>http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk/loginManger.js</updateURL> |
|---|
| 11 | <license>public domain</license> |
|---|
| 12 | <detail><![CDATA[ |
|---|
| 13 | This plugin use Tombloo library, |
|---|
| 14 | so require install Tombloo Addon. |
|---|
| 15 | http://wiki.github.com/to/tombloo |
|---|
| 16 | |
|---|
| 17 | === TODO === |
|---|
| 18 | - solve depends Tombloo |
|---|
| 19 | - all |
|---|
| 20 | |
|---|
| 21 | ]]></detail> |
|---|
| 22 | </VimperatorPlugin>; |
|---|
| 23 | //}}} |
|---|
| 24 | |
|---|
| 25 | (function(){ |
|---|
| 26 | |
|---|
| 27 | var loginManager = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager); |
|---|
| 28 | var Tombloo = Cc["@brasil.to/tombloo-service;1"].getService().wrappedJSObject; |
|---|
| 29 | |
|---|
| 30 | var services = { |
|---|
| 31 | pixiv: { |
|---|
| 32 | HOST: "http://www.pixiv.net", |
|---|
| 33 | LOGIN: "/index.php", |
|---|
| 34 | LOGOUT: "/logout.php", |
|---|
| 35 | usernameField: "pixiv_id", |
|---|
| 36 | passwordField: "pass", |
|---|
| 37 | extraField: { |
|---|
| 38 | mode: function() "login", |
|---|
| 39 | skip: function() "1", |
|---|
| 40 | }, |
|---|
| 41 | }, |
|---|
| 42 | mixi: { |
|---|
| 43 | HOST: "https://mixi.jp", |
|---|
| 44 | LOGIN: "/login.pl", |
|---|
| 45 | LOGOUT: "/logout.pl", |
|---|
| 46 | usernameField: "email", |
|---|
| 47 | passwordField: "password", |
|---|
| 48 | extraField: { |
|---|
| 49 | next_url: function() "/home.pl", |
|---|
| 50 | }, |
|---|
| 51 | }, |
|---|
| 52 | hatena: { |
|---|
| 53 | HOST: "https://www.hatena.ne.jp", |
|---|
| 54 | LOGIN: "/login", |
|---|
| 55 | LOGOUT: "/logout", |
|---|
| 56 | usernameField: "name", |
|---|
| 57 | passwordField: "password", |
|---|
| 58 | }, |
|---|
| 59 | hatelabo: { |
|---|
| 60 | HOST: "https://www.hatelabo.jp", |
|---|
| 61 | LOGIN: "/login", |
|---|
| 62 | LOGOUT: "/logout", |
|---|
| 63 | usernameField: "name", |
|---|
| 64 | passwordField: "password", |
|---|
| 65 | }, |
|---|
| 66 | tumblr: { |
|---|
| 67 | HOST: "http://www.tumblr.com", |
|---|
| 68 | LOGIN: "/login", |
|---|
| 69 | LOGOUT: "/logout", |
|---|
| 70 | usernameField: "email", |
|---|
| 71 | passwordField: "password", |
|---|
| 72 | }, |
|---|
| 73 | twitter: { |
|---|
| 74 | HOST: "https://twitter.com", |
|---|
| 75 | LOGIN: "/sessions", |
|---|
| 76 | LOGOUT: "/sessions/destroy", |
|---|
| 77 | usernameField: "session[username_or_email]", |
|---|
| 78 | passwordField: "session[password]", |
|---|
| 79 | extraField: { |
|---|
| 80 | authenticity_token: tokenGetter(/authenticity_token.+value="(.+?)"/), |
|---|
| 81 | }, |
|---|
| 82 | }, |
|---|
| 83 | "wassr.com": { |
|---|
| 84 | HOST: "https://wassr.com", |
|---|
| 85 | LOGIN: "/account/login", |
|---|
| 86 | LOGOUT: "/account/logout", |
|---|
| 87 | usernameField: "login_id", |
|---|
| 88 | passwordField: "login_pw", |
|---|
| 89 | extraField: { |
|---|
| 90 | CSRFPROTECT: tokenGetter(/CSRFPROTECT.+value="(.+?)"/), |
|---|
| 91 | }, |
|---|
| 92 | }, |
|---|
| 93 | "wassr.jp": { |
|---|
| 94 | HOST: "https://wassr.jp", |
|---|
| 95 | LOGIN: "/account/login", |
|---|
| 96 | LOGOUT: "/account/logout", |
|---|
| 97 | usernameField: "login_id", |
|---|
| 98 | passwordField: "login_pw", |
|---|
| 99 | extraField: { |
|---|
| 100 | CSRFPROTECT: tokenGetter(/CSRFPROTECT.+value="(.+?)"/), |
|---|
| 101 | }, |
|---|
| 102 | }, |
|---|
| 103 | }; |
|---|
| 104 | for (name in services){ |
|---|
| 105 | services[name] = new Service(services[name]); |
|---|
| 106 | } |
|---|
| 107 | |
|---|
| 108 | commands.addUserCommand(["login"], "Login", |
|---|
| 109 | function(args){ |
|---|
| 110 | let [servicename, username] = args; |
|---|
| 111 | let service = services[servicename]; |
|---|
| 112 | if (!service) return false; |
|---|
| 113 | service.login(username); |
|---|
| 114 | }, { |
|---|
| 115 | completer: function(context, args){ |
|---|
| 116 | if (args.completeArg == 0){ |
|---|
| 117 | context.title = ["service"]; |
|---|
| 118 | context.completions = [[s,""] for(s in services)]; |
|---|
| 119 | } else if (args.completeArg == 1){ |
|---|
| 120 | let service = services[args[0]]; |
|---|
| 121 | if (!service) return false; |
|---|
| 122 | context.title = ["username"]; |
|---|
| 123 | context.completions = [[u,""] for each(u in service.usernames())]; |
|---|
| 124 | } |
|---|
| 125 | }, |
|---|
| 126 | literal: 1, |
|---|
| 127 | }); |
|---|
| 128 | commands.addUserCommand(["logout"], "Logout", |
|---|
| 129 | function(args){ |
|---|
| 130 | let [servicename, username] = args; |
|---|
| 131 | let service = services[servicename]; |
|---|
| 132 | if (!service) return false; |
|---|
| 133 | service.logout(username); |
|---|
| 134 | }, { |
|---|
| 135 | completer: function(context, args){ |
|---|
| 136 | context.title = ["service"]; |
|---|
| 137 | context.completions = [[s,""] for(s in services)]; |
|---|
| 138 | }, |
|---|
| 139 | }); |
|---|
| 140 | |
|---|
| 141 | function Service(service) |
|---|
| 142 | { |
|---|
| 143 | let self = this; |
|---|
| 144 | self.login = function(username){ |
|---|
| 145 | let logins = loginManager.findLogins({}, service.HOST, service.HOST, null) |
|---|
| 146 | .filter(function(x) x.username==username); |
|---|
| 147 | if(logins.length==0) return; |
|---|
| 148 | let password = logins[0].password; |
|---|
| 149 | let page = service.HOST+service.LOGIN; |
|---|
| 150 | let content = {}; |
|---|
| 151 | content[service.usernameField] = username; |
|---|
| 152 | content[service.passwordField] = password; |
|---|
| 153 | if (service.extraField){ |
|---|
| 154 | for (field in service.extraField){ |
|---|
| 155 | content[field] = service.extraField[field](service); |
|---|
| 156 | if (!content[field]){ |
|---|
| 157 | liberator.echoerr("failed get "+field); |
|---|
| 158 | } |
|---|
| 159 | } |
|---|
| 160 | } |
|---|
| 161 | return Tombloo |
|---|
| 162 | .request(page, {sendContent: content}) |
|---|
| 163 | .addCallback(function() |
|---|
| 164 | liberator.echo('login "'+service.HOST+'" as '+username)); |
|---|
| 165 | }; |
|---|
| 166 | self.logout = function(){ |
|---|
| 167 | let content = {}; |
|---|
| 168 | if (service.extraField){ |
|---|
| 169 | for (field in service.extraField){ |
|---|
| 170 | content[field] = service.extraField[field](service); |
|---|
| 171 | } |
|---|
| 172 | } |
|---|
| 173 | return Tombloo |
|---|
| 174 | .request(service.HOST+service.LOGOUT, {sendContent: content}) |
|---|
| 175 | .addCallback(function() |
|---|
| 176 | liberator.echo('logout "'+service.HOST+'"')); |
|---|
| 177 | }; |
|---|
| 178 | self.usernames = function(){ |
|---|
| 179 | let logins = loginManager.findLogins({}, service.HOST, service.HOST, null); |
|---|
| 180 | return [x.username for each(x in logins) if(x.username)]; |
|---|
| 181 | }; |
|---|
| 182 | for (prop in service){ |
|---|
| 183 | if (self[prop]) self["_"+prop] = self[prop]; |
|---|
| 184 | self[prop] = service[prop]; |
|---|
| 185 | } |
|---|
| 186 | } |
|---|
| 187 | function tokenGetter(pattern) |
|---|
| 188 | { |
|---|
| 189 | return function(service){ |
|---|
| 190 | let res = util.httpGet(service.HOST); |
|---|
| 191 | if (pattern.test(res.responseText)){ |
|---|
| 192 | return RegExp.$1; |
|---|
| 193 | } |
|---|
| 194 | }; |
|---|
| 195 | } |
|---|
| 196 | |
|---|
| 197 | })(); |
|---|
| 198 | // vim: fdm=marker sw=4 ts=4 et: |
|---|