UNPKG

3.5 kBJavaScriptView Raw
1"use strict";
2
3var url = require('url')
4var cheerio = require('cheerio')
5var program = require('commander')
6var path = require('path')
7var fs = require('fs')
8var Q = require('q')
9var CookieAccess = require('cookiejar').CookieAccessInfo
10
11
12var settings = {
13 daemon: 'brix.alibaba-inc.com',
14 // daemon: '127.0.0.1:7000',
15 port: '5000'
16}
17
18var mosaic = exports
19
20
21mosaic.config = function(p, v) {
22 if (typeof v !== 'undefined') {
23 settings[p] = v
24 }
25 else {
26 return settings[p]
27 }
28}
29
30mosaic.home = function() {
31 var homedir = process.env.HOME;
32
33 if (!homedir) {
34 homedir = process.env.HOMEDRIVE + process.env.HOMEPATH;
35 }
36
37 var mohome = path.join(homedir, '.mosaic')
38
39 if (fs.existsSync(mohome)) {
40 if (fs.statSync(mohome).isFile()) {
41 mosaic.fatal('配置目录创建失败,已存在 ~/.mosaic 文件')
42 }
43 }
44 else {
45 fs.mkdirSync(mohome)
46 }
47
48 return mohome
49}
50
51mosaic.remote = function(path) {
52 path = path || ''
53
54 return url.format({
55 protocol: 'http',
56 host: mosaic.config('daemon'),
57 pathname: path.charAt(0) === '/' ? path : 'api/' + path
58 })
59}
60
61mosaic.login = function(res) {
62
63 return Q
64 .fcall(function() {
65 var $ = cheerio.load(res.text)
66 var props = '_csrf_token action return login_maintain event_submit_do_sso_login'.split(' ')
67 var data = {}
68
69 props.forEach(function(p) {
70 data[p] = $('[name="' + p + '"]').val()
71 })
72 data.login_maintain = true
73
74 return data
75 })
76 .then(function(data) {
77 var d = Q.defer()
78
79 program.prompt('Username: ', function(name) {
80 data['_fm.l._0.a'] = name
81 d.resolve(data)
82 })
83
84 return d.promise
85 })
86 .then(function(data) {
87 var d = Q.defer()
88
89 program.password('Password: ', function(password) {
90 data['_fm.l._0.p'] = password
91 d.resolve(data)
92 })
93
94 return d.promise
95 })
96 .then(function(data) {
97 return mosaic.doLogin(res.req.url, data)
98 })
99 .fail(function(err) {
100 throw err
101 })
102}
103
104mosaic.doLogin = function(remote, data) {
105 var d = Q.defer()
106 var req = mosaic.agent().post(remote)
107
108 data.login_maintain = 'on'
109 // superagent defaults Content-Type to application/json
110 // don't ask me how I find this out.
111 req.type('form').send(data).end(function(err, res) {
112 if (err) return d.reject(err)
113
114 var $ = cheerio.load(res.text)
115 var errNode = $('.hint .error')
116
117 if (errNode.length > 0) {
118 mosaic.error(errNode.text())
119 // Login error occured. Let's resolve the login promise again.
120 d.resolve(mosaic.login(res))
121 }
122 else {
123 mosaic.saveCookies()
124 d.resolve(res)
125 }
126 })
127
128 return d.promise
129}
130
131mosaic.agent = function() {
132 var agent = mosaic._agent
133 var fpath = path.join(mosaic.home(), 'cookies.txt')
134
135 if (!agent) agent = mosaic._agent = require('superagent').agent()
136 if (fs.existsSync(fpath)) agent.jar.setCookies(fs.readFileSync(fpath, 'utf-8'))
137
138 return agent
139}
140
141mosaic.saveCookies = function() {
142 var url = require('url').parse(mosaic.remote())
143 var access = CookieAccess(url.host, url.pathname, 'https:' === url.protocol)
144
145 fs.writeFileSync(
146 path.join(mosaic.home(), 'cookies.txt'),
147 mosaic.agent().jar.getCookies(access).toValueString(),
148 'utf-8'
149 )
150}
151
152mosaic.attachCookies = function() {}
153
154/*
155 * mix utils into module.exports
156 */
157var utils = require('./utils')
158
159for (var p in utils) {
160 if (utils.hasOwnProperty(p)) {
161 mosaic[p] = utils[p]
162 }
163}
164
165mosaic.config('home', mosaic.home())