mirror of
https://github.com/HackPlan/RootPanel.git
synced 2026-03-26 07:44:10 +08:00
Root
This commit is contained in:
20
.gitignore
vendored
20
.gitignore
vendored
@@ -1,14 +1,14 @@
|
||||
/node_modules
|
||||
/bower_components
|
||||
/coverage-reporter.html
|
||||
/npm-debug.log
|
||||
|
||||
/.vagrant
|
||||
/package.box
|
||||
|
||||
/.idea
|
||||
*~
|
||||
.DS_Store
|
||||
|
||||
/config.coffee
|
||||
.idea/
|
||||
.vagrant/
|
||||
node_modules/
|
||||
bower_components/
|
||||
|
||||
/package.box
|
||||
/npm-debug.log
|
||||
|
||||
/session.key
|
||||
/config.coffee
|
||||
/coverage-reporter.html
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
|
||||
server_name rp.rpvhost.net;
|
||||
|
||||
location ~ /\.git {
|
||||
deny all;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_pass http://unix:/home/rpadmin/rootpanel.sock:/;
|
||||
|
||||
157
app.coffee
157
app.coffee
@@ -1,157 +1,6 @@
|
||||
#!/usr/bin/env coffee
|
||||
|
||||
{EventEmitter} = require 'events'
|
||||
Root = require './core'
|
||||
|
||||
global.rp = global.app = module.exports = new EventEmitter()
|
||||
|
||||
app.libs =
|
||||
_: require 'underscore'
|
||||
Q: require 'q'
|
||||
fs: require 'fs'
|
||||
path: require 'path'
|
||||
jade: require 'jade'
|
||||
async: require 'async'
|
||||
crypto: require 'crypto'
|
||||
moment: require 'moment-timezone'
|
||||
request: require 'request'
|
||||
express: require 'express'
|
||||
child_process: require 'child_process'
|
||||
|
||||
cookieParser = require 'cookie-parser'
|
||||
BunyanMongo = require 'bunyan-mongo'
|
||||
bodyParser = require 'body-parser'
|
||||
nodemailer = require 'nodemailer'
|
||||
Insight = require 'insight'
|
||||
morgan = require 'morgan'
|
||||
Mabolo = require 'mabolo'
|
||||
bunyan = require 'bunyan'
|
||||
|
||||
harp = require 'harp'
|
||||
|
||||
{_, fs, path, express} = app.libs
|
||||
|
||||
if fs.existsSync "#{__dirname}/config.coffee"
|
||||
config = require './config'
|
||||
else
|
||||
config = require './sample/core.config.coffee'
|
||||
|
||||
app.package = require './package'
|
||||
utils = require './core/utils'
|
||||
|
||||
if fs.existsSync config.web.listen
|
||||
fs.unlinkSync config.web.listen
|
||||
|
||||
insight = new Insight
|
||||
# 这个代码用于向 RootPanel 开发者提交匿名的统计信息
|
||||
# This code used to send anonymous usage metrics to RootPanel developers
|
||||
# 您不必修改这里 You do not have to modify it
|
||||
trackingCode: 'UA-49193300-7'
|
||||
packageName: app.package.name
|
||||
packageVersion: app.package.version
|
||||
|
||||
insight.track 'app.coffee'
|
||||
|
||||
mailer = nodemailer.createTransport config.email.account
|
||||
|
||||
mabolo = new Mabolo utils.mongodbUri _.extend config.mongodb,
|
||||
name: config.mongodb.test
|
||||
|
||||
bunyanMongo = new BunyanMongo()
|
||||
|
||||
mabolo.connect().done (db) ->
|
||||
bunyanMongo.setDB db
|
||||
|
||||
logger = bunyan.createLogger
|
||||
name: app.package.name
|
||||
streams: [
|
||||
type: 'raw'
|
||||
level: 'info'
|
||||
stream: bunyanMongo
|
||||
,
|
||||
level: process.env.LOG_LEVEL ? 'debug'
|
||||
stream: process.stdout
|
||||
]
|
||||
|
||||
PlanManager = require './core/PlanManager'
|
||||
NodeManager = require './core/NodeManager'
|
||||
CacheManager = require './core/CacheManager'
|
||||
TranslationManager = require './core/TranslationManager'
|
||||
PluginManager = require './core/extends/PluginManager'
|
||||
HookManager = require './core/extends/HookManager'
|
||||
ComponentManager = require './core/extends/ComponentManager'
|
||||
|
||||
_.extend app,
|
||||
plans: new PlanManager config.plans
|
||||
nodes: new NodeManager config.nodes
|
||||
cache: new CacheManager()
|
||||
hooks: new HookManager()
|
||||
|
||||
components: new ComponentManager()
|
||||
translations: new TranslationManager config.i18n
|
||||
|
||||
utils: utils
|
||||
config: config
|
||||
mabolo: mabolo
|
||||
mailer: mailer
|
||||
logger: logger
|
||||
models: mabolo.models
|
||||
insight: insight
|
||||
express: express()
|
||||
|
||||
require './core/model/Account'
|
||||
require './core/model/Financials'
|
||||
require './core/model/CouponCode'
|
||||
require './core/model/Notification'
|
||||
require './core/model/SecurityLog'
|
||||
require './core/model/Ticket'
|
||||
require './core/model/Component'
|
||||
|
||||
PaymentProviderManager = require './core/extends/PaymentProviderManager'
|
||||
CouponProviderManager = require './core/extends/CouponProviderManager'
|
||||
NotificationManager = require './core/extends/NotificationManager'
|
||||
|
||||
app.extends =
|
||||
notifications: new NotificationManager()
|
||||
payments: new PaymentProviderManager()
|
||||
coupons: new CouponProviderManager()
|
||||
|
||||
app.middleware = require './core/middleware'
|
||||
|
||||
app.getHooks = app.extends.hook.getHooks
|
||||
app.applyHooks = app.extends.hook.applyHooks
|
||||
|
||||
app.express.use bodyParser.json()
|
||||
app.express.use cookieParser()
|
||||
|
||||
app.express.use app.middleware.reqHelpers
|
||||
app.express.use app.middleware.session()
|
||||
app.express.use app.middleware.logger()
|
||||
app.express.use app.middleware.csrf()
|
||||
app.express.use app.middleware.authenticate
|
||||
app.express.use app.middleware.renderHelpers
|
||||
|
||||
app.express.set 'views', path.join __dirname, 'core/view'
|
||||
app.express.set 'view engine', 'jade'
|
||||
|
||||
app.express.use '/component', require './core/router/component'
|
||||
app.express.use '/account', require './core/router/account'
|
||||
app.express.use '/ticket', require './core/router/ticket'
|
||||
app.express.use '/admin', require './core/router/admin'
|
||||
app.express.use '/panel', require './core/router/panel'
|
||||
|
||||
app.plugins = new PluginManager()
|
||||
|
||||
app.express.use '/bower_components', express.static './bower_components'
|
||||
app.express.use harp.mount './core/static'
|
||||
|
||||
app.express.get '/', (req, res) ->
|
||||
res.redirect '/panel/'
|
||||
|
||||
exports.start = _.once ->
|
||||
app.express.listen config.web.listen, ->
|
||||
app.started = true
|
||||
app.logger.info "RootPanel start at #{config.web.listen}"
|
||||
app.emit 'app.started'
|
||||
|
||||
unless module.parent
|
||||
exports.start()
|
||||
Root.findConfig(__dirname).done (config) ->
|
||||
global.root = new Root config
|
||||
|
||||
@@ -4,7 +4,11 @@ redis = require 'redis'
|
||||
_ = require 'underscore'
|
||||
Q = require 'q'
|
||||
|
||||
class CacheManager
|
||||
###
|
||||
Public: Cache utils
|
||||
You can access a global instance via `root.cache`.
|
||||
###
|
||||
class Cache
|
||||
constructor: ({host, port, password}) ->
|
||||
@redis = redis.createClient port, host,
|
||||
auth_pass: password
|
||||
1
core/index.coffee
Normal file
1
core/index.coffee
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require './root'
|
||||
@@ -63,7 +63,7 @@ exports.reqHelpers = (req, res, next) ->
|
||||
|
||||
res.createCookie = (name, value) ->
|
||||
res.cookie name, value,
|
||||
expires: new Date(Date.now() + config.account.cookie_time)
|
||||
expires: new Date(Date.now() + config.web.cookie_time)
|
||||
|
||||
res.createToken = (account = req.account) ->
|
||||
account.createToken('full_access', req.getClientInfo()).then (token) ->
|
||||
|
||||
211
core/root.coffee
Normal file
211
core/root.coffee
Normal file
@@ -0,0 +1,211 @@
|
||||
{EventEmitter} = require 'events'
|
||||
cookieParser = require 'cookie-parser'
|
||||
bodyParser = require 'body-parser'
|
||||
nodemailer = require 'nodemailer'
|
||||
Insight = require 'insight'
|
||||
express = require 'express'
|
||||
Mabolo = require 'mabolo'
|
||||
morgan = require 'morgan'
|
||||
path = require 'path'
|
||||
harp = require 'harp'
|
||||
fs = require 'q-io/fs'
|
||||
_ = require 'lodash'
|
||||
|
||||
###
|
||||
Class: Root object for control RootPanel, An instance is always available as the `root` global.
|
||||
###
|
||||
module.exports = class Root extends EventEmitter
|
||||
###
|
||||
Public: Find and load configure file.
|
||||
|
||||
* `rootPath` {String} e.g. `/home/rpadmin/RootPanel`
|
||||
|
||||
Return {String}.
|
||||
###
|
||||
@findConfig: (rootPath) ->
|
||||
configPath = path.resolve rootPath, '../config.coffee'
|
||||
defaultPath = path.resolve rootPath, '../sample/config.coffee'
|
||||
|
||||
fs.exists(configPath).then (exists) ->
|
||||
fs.read if exists then configPath else defaultPath
|
||||
|
||||
# Public: Config object
|
||||
config: null
|
||||
# Public: Node package object
|
||||
package: null
|
||||
# Public: express application
|
||||
express: null
|
||||
# Public: nodemailer instance
|
||||
mailer: null
|
||||
# Public: {Mabolo} instance
|
||||
mabolo: null
|
||||
# Public: {Insight} instance
|
||||
insight: null
|
||||
# Public: global {Cache} instance
|
||||
cache: null
|
||||
|
||||
# Public: {Account} Model
|
||||
Account: null
|
||||
# Public: {Financials} Model
|
||||
Financials: null
|
||||
# Public: {CouponCode} Model
|
||||
CouponCode: null
|
||||
# Public: {Notification} Model
|
||||
Notification: null
|
||||
# Public: {SecurityLog} Model
|
||||
SecurityLog: null
|
||||
# Public: {Ticket} Model
|
||||
Ticket: null
|
||||
# Public: {Component} Model
|
||||
Component: null
|
||||
|
||||
# Public: global {HookRegistry} instance
|
||||
hooks: null
|
||||
# Public: global {ViewRegistry} instance
|
||||
views: null
|
||||
# Public: global {WidgetRegistry} instance
|
||||
widgets: null
|
||||
# Public: global {ComponentRegistry} instance
|
||||
components: null
|
||||
# Public: global {CouponTypeRegistry} instance
|
||||
couponTypes: null
|
||||
# Public: global {PaymentProviderRegistry} instance
|
||||
paymentProviders: null
|
||||
|
||||
# Public: global {I18nManager} instance
|
||||
i18n: null
|
||||
# Public: global {PluginManager} instance
|
||||
plugins: null
|
||||
# Public: global {ServerManager} instance
|
||||
servers: null
|
||||
# Public: global {BillingManager} instance
|
||||
billing: null
|
||||
# Public: global {NotificationManager} instance
|
||||
notifications: null
|
||||
|
||||
###
|
||||
Public: Construct a RootPanel instance.
|
||||
|
||||
* `config` {Object} Configure object
|
||||
* `package` {Object} Node package object
|
||||
|
||||
###
|
||||
constructor: (@config, @package) ->
|
||||
@package ?= require '../package'
|
||||
|
||||
Cache = require './cache'
|
||||
|
||||
HookRegistry = require './registry/hook'
|
||||
ViewRegistry = require './registry/view'
|
||||
WidgetRegistry = require './registry/widget'
|
||||
ComponentRegistry = require './registry/component'
|
||||
CouponTypeRegistry = require './registry/coupon-type'
|
||||
PaymentProviderRegistry = require './registry/payment-provider'
|
||||
|
||||
I18nManager = require './i18n-manager'
|
||||
PluginManager = require './plugin-manager'
|
||||
ServerManager = require './server-manager'
|
||||
BillingManager = require './billing-manager'
|
||||
NotificationManager = require './notification-manager'
|
||||
|
||||
_.extend @,
|
||||
express: express()
|
||||
mailer: nodemailer.createTransport @config.email.account
|
||||
mabolo: new Mabolo mongodbUri @config.mongodb
|
||||
|
||||
insight: new Insight
|
||||
trackingCode: TRACKING_CODE
|
||||
pkg: @package
|
||||
|
||||
cache: new Cache()
|
||||
|
||||
Account: require './model/account'
|
||||
Financials: require './model/financials'
|
||||
CouponCode: require './model/coupon-code'
|
||||
Notification: require './model/notification'
|
||||
SecurityLog: require './model/security-log'
|
||||
Ticket: require './model/ticket'
|
||||
Component: require './model/component'
|
||||
|
||||
hooks: new HookRegistry()
|
||||
views: new ViewRegistry()
|
||||
widgets: new WidgetRegistry()
|
||||
components: new ComponentRegistry()
|
||||
couponTypes: new CouponTypeRegistry()
|
||||
paymentProviders: new PaymentProviderRegistry()
|
||||
|
||||
i18n: new I18nManager @config.i18n
|
||||
plugins: new PluginManager @config.plugins
|
||||
servers: new ServerManager @config.server
|
||||
billing: new BillingManager @config.billing
|
||||
notifications: new NotificationManager()
|
||||
|
||||
@express.use bodyParser.json()
|
||||
@express.use cookieParser()
|
||||
@express.use morgan 'combined'
|
||||
|
||||
middleware = require './middleware'
|
||||
|
||||
@express.use middleware.reqHelpers
|
||||
@express.use middleware.session()
|
||||
@express.use middleware.csrf()
|
||||
@express.use middleware.authenticate
|
||||
@express.use middleware.renderHelpers
|
||||
|
||||
@express.use '/admin', require './router/admin'
|
||||
@express.use '/panel', require './router/panel'
|
||||
@express.use '/ticket', require './router/ticket'
|
||||
@express.use '/account', require './router/account'
|
||||
@express.use '/component', require './router/component'
|
||||
|
||||
@express.use '/bower_components', express.static @resolve '../bower_components'
|
||||
@express.use harp.mount @resolve 'static'
|
||||
|
||||
@express.get '/', (req, res) ->
|
||||
res.redirect '/panel/'
|
||||
|
||||
###
|
||||
Public: Run RootPanel and start web service.
|
||||
|
||||
Return a {Promise}.
|
||||
###
|
||||
start: ->
|
||||
@trackUsage 'root.start'
|
||||
|
||||
fs.exists(@config.web.listen).then (exists) ->
|
||||
fs.unlink(@config.web.listen) if exists
|
||||
.then ->
|
||||
Q.Promise (resolve, reject) =>
|
||||
@express.listen @config.web.listen, (err) =>
|
||||
return reject err if err
|
||||
|
||||
@emit 'started'
|
||||
resolve()
|
||||
|
||||
###
|
||||
Public: Resolve path based on core directory.
|
||||
|
||||
* `arguments...` {String} paths
|
||||
|
||||
return {String}.
|
||||
###
|
||||
resolve: ->
|
||||
return path.resolve __dirname, arguments...
|
||||
|
||||
###
|
||||
Public: Send usage metrics to Google Analytics.
|
||||
|
||||
* `path` {String} e.g. `root.start`
|
||||
|
||||
###
|
||||
trackUsage: (path) ->
|
||||
@insight.track path.split('.')...
|
||||
|
||||
# Private: This code used to send anonymous usage metrics to RootPanel developers.
|
||||
TRACKING_CODE = 'UA-49193300-7'
|
||||
|
||||
mongodbUri = ({user, password, host, name}) ->
|
||||
if user and password
|
||||
return "mongodb://#{user}:#{password}@#{host}/#{name}"
|
||||
else
|
||||
return "mongodb://#{host}/#{name}"
|
||||
@@ -1,14 +1,18 @@
|
||||
validator = require 'validator'
|
||||
crypto = require 'crypto'
|
||||
_ = require 'underscore'
|
||||
_ = require 'lodash'
|
||||
|
||||
exports.rx =
|
||||
username: /^[a-z][0-9a-z_]{2,23}$/
|
||||
email: /^\w+([-+.]\w+)*@\w+([-+.]\w+)*$/
|
||||
password: /^.+$/
|
||||
domain: /^(\*\.)?[A-Za-z0-9]+(\-[A-Za-z0-9]+)*(\.[A-Za-z0-9]+(\-[A-Za-z0-9]+)*)*$/
|
||||
filename: /^[A-Za-z0-9_\-\.]+$/
|
||||
url: /^https?:\/\/[^\s;]*$/
|
||||
|
||||
validator.extend 'isUsername', (username) ->
|
||||
return /^[a-z][0-9a-z_]{2,23}$/.test username
|
||||
|
||||
validator.extend 'isPassword', (password) ->
|
||||
return /^.+$/.test password
|
||||
|
||||
exports.sha256 = (data) ->
|
||||
if data
|
||||
return crypto.createHash('sha256').update(data).digest('hex')
|
||||
@@ -48,19 +52,3 @@ exports.pickErrorName = (error) ->
|
||||
return "#{err.path}_exist"
|
||||
|
||||
return err.message
|
||||
|
||||
exports.formatBillingTrigger = (name, plugin_name) ->
|
||||
[part1, part2] = name.split '.'
|
||||
|
||||
if part2
|
||||
return name
|
||||
else
|
||||
return "#{plugin_name}.#{part1}"
|
||||
|
||||
exports.mongodbUri = (config) ->
|
||||
{user, password, host, name} = config
|
||||
|
||||
if user and password
|
||||
return "mongodb://#{user}:#{password}@#{host}/#{name}"
|
||||
else
|
||||
return "mongodb://#{host}/#{name}"
|
||||
|
||||
@@ -54,5 +54,6 @@ RootPanel 使用 Mabolo 管理数据模型。
|
||||
## 应用入口
|
||||
|
||||
* Routers `/core/router`: 路由
|
||||
* App Entry `/app`: RootPanel 主程序的入口
|
||||
* Root `/core/root` 全局对象 `root`
|
||||
* App Entry `/app`: 入口点
|
||||
* Tests `/core/test`: 自动测试
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "^0.9.0",
|
||||
"async-q": "^0.2.2",
|
||||
"body-parser": "^1.9.3",
|
||||
"bower": "^1.3.12",
|
||||
"bunyan": "^1.2.3",
|
||||
@@ -37,8 +38,8 @@
|
||||
"express-session": "^1.9.2",
|
||||
"get-parameter-names": "^0.2.0",
|
||||
"harp": "^0.14.0",
|
||||
"insight": "^0.4.3",
|
||||
"jade": "^1.7.0",
|
||||
"insight": "^0.5.3",
|
||||
"jade": "^1.9.2",
|
||||
"json-stable-stringify": "^1.0.0",
|
||||
"lodash": "^3.6.0",
|
||||
"mabolo": "^0.3.0-rc.1",
|
||||
@@ -50,11 +51,13 @@
|
||||
"negotiator": "^0.4.9",
|
||||
"nodemailer": "^1.3.0",
|
||||
"q": "^1.2.0",
|
||||
"q-io": "^1.12.0",
|
||||
"redis": "^0.12.1",
|
||||
"request": "^2.48.0",
|
||||
"semver": "^4.1.0",
|
||||
"ssh2": "^0.3.6",
|
||||
"underscore": "^1.7.0"
|
||||
"underscore": "^1.7.0",
|
||||
"validator": "^3.37.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^1.10.0",
|
||||
|
||||
Reference in New Issue
Block a user