diff --git a/INSTALL.md b/INSTALL.md index 9c2351f..37ef70f 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -68,6 +68,10 @@ rpadmin ALL=(ALL) NOPASSWD: ALL + vi /etc/rc.local + + iptables-restore < /etc/iptables.rules + reboot su rpadmin diff --git a/WIKI/README.md b/WIKI/README.md index 78f33f9..fc0e99e 100644 --- a/WIKI/README.md +++ b/WIKI/README.md @@ -13,10 +13,6 @@ * [文件系统](Linux/Filesystem.md) * [SSH](Linux/SSH.md) -### Service - -* [ShadowSocks](Service/ShadowSocks.md) - ### Nginx * [JSON 配置文件](Nginx/JSON-Configure.md) diff --git a/app.coffee b/app.coffee index eb7f363..7d9887a 100644 --- a/app.coffee +++ b/app.coffee @@ -26,11 +26,13 @@ fs.chmodSync path.join(__dirname, 'config.coffee'), 0o750 bindRouters = -> app.use require 'middleware-injector' - for module_name in ['account', 'admin', 'panel', 'plan', 'ticket', 'wiki', 'bitcoin'] + for module_name in ['account', 'admin', 'panel', 'plan', 'ticket', 'bitcoin'] app.use "/#{module_name}", require './core/router/' + module_name plugin.loadPlugins() + app.use '/wiki', require './core/router/wiki' + app.get '/', (req, res) -> res.redirect '/panel/' diff --git a/config.coffee b/config.coffee index 74014b0..f803a30 100644 --- a/config.coffee +++ b/config.coffee @@ -1,5 +1,6 @@ module.exports = web: + name: 'GreenShadow' url: 'http://ss.rpvhost.net' listen: '/home/rpadmin/rootpanel.sock' google_analytics_id: 'UA-49193300-2' @@ -16,6 +17,8 @@ module.exports = available_services: ['shadowsocks'] billing: + taobao_item_id: '38370649858' + force_unsubscribe: when_balance_below: 0 when_arrears_above: 0 @@ -31,22 +34,6 @@ module.exports = services: ['shadowsocks'] resources: {} - nodes: - us1: - domain: 'us1.rpvhost.net' - location: 'Linode Fremont, CA, USA' - readme: '' - - jp1: - domain: 'jp1.rpvhost.net' - location: 'Linode Tokyo, JP' - readme: '' - - ss: - domain: 'ss.rpvhost.net' - location: 'Linode Fremont, CA, USA' - readme: 'ShadowSocks Only' - mongodb: user: 'rpadmin' password: 'password' diff --git a/core/router/panel.coffee b/core/router/panel.coffee index a026cff..ce74c35 100644 --- a/core/router/panel.coffee +++ b/core/router/panel.coffee @@ -30,7 +30,8 @@ exports.get '/pay', requireAuthenticate, renderAccount, (req, res) -> billing_log: (callback) -> mBalance.find account_id: req.account._id - type: 'billing' + type: + $in: ['billing', 'service_billing'] , sort: created_at: -1 diff --git a/core/router/wiki.coffee b/core/router/wiki.coffee index 85b720d..7a669d8 100644 --- a/core/router/wiki.coffee +++ b/core/router/wiki.coffee @@ -2,9 +2,10 @@ markdown = require('markdown').markdown path = require 'path' fs = require 'fs' -app.view_hook.menu_bar.push - href: '/wiki/' - html: '用户手册' +unless _.find(app.view_hook.menu_bar, (i) -> i.href == '/wiki/') + app.view_hook.menu_bar.push + href: '/wiki/' + html: '用户手册' {renderAccount} = require './middleware' diff --git a/core/view/layout.jade b/core/view/layout.jade index 8c6c4b2..4671a4b 100644 --- a/core/view/layout.jade +++ b/core/view/layout.jade @@ -18,7 +18,7 @@ html span.icon-bar span.icon-bar span.icon-bar - a.navbar-brand(href='/')= t('app.name') + a.navbar-brand(href='/')= config.web.name #navbar-collapse.collapse.navbar-collapse ul.nav.navbar-nav for item in app.view_hook.menu_bar diff --git a/core/view/panel/pay.jade b/core/view/panel/pay.jade index fa65d71..5343f1f 100644 --- a/core/view/panel/pay.jade +++ b/core/view/panel/pay.jade @@ -15,24 +15,8 @@ block main div h2 淘宝 - p 拍下对应宝贝后付款即可,购买时注意选择服务器节点选项,备注填写你在 RP 主机的用户名。 - a.btn.btn-success(href='http://item.taobao.com/item.htm?id=38370649858') 淘宝购买 - - .row - header 机房列表 - table.table.table-hover - thead - tr - th 域名 - th 位置 - th 说明 - tbody - for node in nodes - tr - td - a(href='//#{node.domain}')= node.domain - td= node.location - td= node.readme + p 拍下对应宝贝后付款即可,购买时注意选择服务器节点选项,备注填写你的用户名。 + a.btn.btn-success(href='http://item.taobao.com/item.htm?id=#{config.billing.taobao_item_id}') 淘宝购买 .row header 充值记录 @@ -69,4 +53,7 @@ block main tr td= moment(item.created_at).format('YYYY-MM-DD HH:mm:ss') td #{item.amount.toFixed(2)} CNY - td #{item.attribute.plans.join(', ')} | #{item.attribute.billing_time} hours #{item.attribute.is_force ? '| force' : ''} + if item.type == 'billing' + td #{item.attribute.plans.join(', ')} | #{item.attribute.billing_time} hours #{item.attribute.is_force ? '| force' : ''} + else if item.type == 'service_billing' && item.attribute.service == 'shadowsocks' + td ShadowSocks #{item.attribute.traffic_mb} MB #{item.attribute.is_force ? '| force' : ''} diff --git a/WIKI/Service/ShadowSocks.md b/plugin/shadowsocks/WIKI/README.md similarity index 100% rename from WIKI/Service/ShadowSocks.md rename to plugin/shadowsocks/WIKI/README.md diff --git a/plugin/shadowsocks/action.coffee b/plugin/shadowsocks/action.coffee index c9548f1..8d782f4 100644 --- a/plugin/shadowsocks/action.coffee +++ b/plugin/shadowsocks/action.coffee @@ -1,5 +1,9 @@ +markdown = require('markdown').markdown +fs = require 'fs' +path = require 'path' + service = require './service' -{requireInService} = require '../../core/router/middleware' +{renderAccount, requireInService} = require '../../core/router/middleware' mAccount = require '../../core/model/account' @@ -18,3 +22,32 @@ exports.post '/reset_password', (req, res) -> service.restart req.account, -> res.json {} + +wiki_router = express.Router() + +wiki_router.use (req, res) -> + req.inject [renderAccount], -> + url = req.url.substr 1 + + unless url + url = 'README.md' + + filename = path.resolve path.join __dirname, 'WIKI', url + baseDir = path.resolve path.join __dirname, 'WIKI' + + unless filename[0 .. baseDir.length-1] == baseDir + return res.json 404 + + fs.readFile filename, (err, data) -> + if err + return res.status(404).send err.toString() + + res.render 'wiki', + title: url + content: markdown.toHTML data.toString() + +app.view_hook.menu_bar.push + href: '/wiki/' + html: '用户手册' + +app.use '/wiki', wiki_router diff --git a/plugin/shadowsocks/service.coffee b/plugin/shadowsocks/service.coffee index e3b63d6..55fff72 100644 --- a/plugin/shadowsocks/service.coffee +++ b/plugin/shadowsocks/service.coffee @@ -63,8 +63,9 @@ module.exports = last_traffic_value: 0 , new: true, (err, account) -> child_process.exec "sudo iptables -I OUTPUT -p tcp --sport #{port}", -> - module.exports.restart account, -> - callback() + child_process.exec 'sudo iptables-save | sudo tee /etc/iptables.rules', -> + module.exports.restart account, -> + callback() delete: (account, callback) -> queryIptablesInfo (iptables_info) -> @@ -86,6 +87,9 @@ module.exports = (callback) -> child_process.exec "sudo iptables -D OUTPUT #{iptables_info[port].num}", callback + (callback) -> + child_process.exec 'sudo iptables-save | sudo tee /etc/iptables.rules', callback + (callback) -> child_process.exec "sudo rm /etc/supervisor/conf.d/#{account.username}.conf", callback diff --git a/sample/shadowsocks.config.coffee b/sample/shadowsocks.config.coffee index ef48285..f6cc03d 100644 --- a/sample/shadowsocks.config.coffee +++ b/sample/shadowsocks.config.coffee @@ -1,8 +1,9 @@ module.exports = web: - url: 'http://ss.rpvhost.net' + name: 'GreenShadow' + url: 'http://greenshadow.net' listen: '/home/rpadmin/rootpanel.sock' - google_analytics_id: 'UA-49193300-2' + google_analytics_id: 'UA-49193300-3' account: cookie_time: 30 * 24 * 3600 * 1000 @@ -16,6 +17,8 @@ module.exports = available_services: ['shadowsocks'] billing: + taobao_item_id: '38370649858' + force_unsubscribe: when_balance_below: 0 when_arrears_above: 0 @@ -31,12 +34,6 @@ module.exports = services: ['shadowsocks'] resources: {} - nodes: - ss: - domain: 'ss.rpvhost.net' - location: 'Linode Fremont, CA, USA' - readme: 'ShadowSocks Only' - mongodb: user: 'rpadmin' password: 'password'