1 | "use strict";
|
2 |
|
3 | var url = require('url')
|
4 | var cheerio = require('cheerio')
|
5 | var program = require('commander')
|
6 | var path = require('path')
|
7 | var fs = require('fs')
|
8 | var Q = require('q')
|
9 | var CookieAccess = require('cookiejar').CookieAccessInfo
|
10 |
|
11 |
|
12 | var settings = {
|
13 | daemon: 'brix.alibaba-inc.com',
|
14 |
|
15 | port: '5000'
|
16 | }
|
17 |
|
18 | var mosaic = exports
|
19 |
|
20 |
|
21 | mosaic.config = function(p, v) {
|
22 | if (typeof v !== 'undefined') {
|
23 | settings[p] = v
|
24 | }
|
25 | else {
|
26 | return settings[p]
|
27 | }
|
28 | }
|
29 |
|
30 | mosaic.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 |
|
51 | mosaic.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 |
|
61 | mosaic.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 |
|
104 | mosaic.doLogin = function(remote, data) {
|
105 | var d = Q.defer()
|
106 | var req = mosaic.agent().post(remote)
|
107 |
|
108 | data.login_maintain = 'on'
|
109 |
|
110 |
|
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 |
|
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 |
|
131 | mosaic.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 |
|
141 | mosaic.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 |
|
152 | mosaic.attachCookies = function() {}
|
153 |
|
154 |
|
155 |
|
156 |
|
157 | var utils = require('./utils')
|
158 |
|
159 | for (var p in utils) {
|
160 | if (utils.hasOwnProperty(p)) {
|
161 | mosaic[p] = utils[p]
|
162 | }
|
163 | }
|
164 |
|
165 | mosaic.config('home', mosaic.home())
|