commit fa0344fb0cdc5d4be5653ed1e367bbee19aeb256 Author: leiyun Date: Fri May 16 15:54:14 2025 +0800 初始提交 diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..4689e9d --- /dev/null +++ b/.babelrc @@ -0,0 +1,8 @@ +{ + "presets": [ + ["es2015", {"loose": true}], + "stage-1" + ], + "plugins": ["transform-runtime"], + "sourceMaps": true +} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d107458 --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage/ + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Dependency directory +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git +node_modules/ + +# IDE config +.idea + +# output +output/ +output.tar.gz + +app/ + +runtime/ \ No newline at end of file diff --git a/.thinkjsrc b/.thinkjsrc new file mode 100644 index 0000000..4ffdfd9 --- /dev/null +++ b/.thinkjsrc @@ -0,0 +1,5 @@ +{ + "createAt": "2025-03-25 17:17:46", + "mode": "module", + "es": true +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..ee90448 --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ + +Application created by [ThinkJS](http://www.thinkjs.org) + +## Install dependencies + +``` +npm install +``` + +## Start server + +``` +npm start +``` + +## Deploy with pm2 + +Use pm2 to deploy app on production enviroment. + +``` +pm2 startOrReload pm2.json +``` \ No newline at end of file diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..d25335f --- /dev/null +++ b/nginx.conf @@ -0,0 +1,120 @@ +server { + listen 80; + server_name example.com www.example.com; + root D:\demo\ssl\ssl_manage/www; + set $node_port 8360; + + index index.js index.html index.htm; + if ( -f $request_filename/index.html ){ + rewrite (.*) $1/index.html break; + } + if ( !-f $request_filename ){ + rewrite (.*) /index.js; + } + location = /index.js { + proxy_http_version 1.1; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + proxy_set_header X-NginX-Proxy true; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_pass http://127.0.0.1:$node_port$request_uri; + proxy_redirect off; + } + + location = /development.js { + deny all; + } + + location = /testing.js { + deny all; + } + + location = /production.js { + deny all; + } + + location ~ /static/ { + etag on; + expires max; + } +} + + + + +## http/2 nginx conf + +# server { +# listen 80; +# server_name example.com www.example.com; +# rewrite ^(.*) https://example.com$1 permanent; +# } +# +# server { +# listen 443 ssl http2 fastopen=3 reuseport; +# server_name www.thinkjs.org thinkjs.org; +# set $node_port 8360; +# +# root D:\demo\ssl\ssl_manage/www; +# +# keepalive_timeout 70; +# +# ssl_certificate /path/to/certificate; +# ssl_certificate_key /path/to/certificate.key; +# ssl_protocols TLSv1 TLSv1.1 TLSv1.2; +# ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"; +# ssl_prefer_server_ciphers on; + +# # openssl dhparam -out dhparams.pem 2048 +# ssl_dhparam /path/to/dhparams.pem; +# +# ssl_session_cache shared:SSL:10m; +# ssl_session_timeout 10m; +# +# ssl_session_ticket_key /path/to/tls_session_ticket.key; +# ssl_session_tickets on; +# +# ssl_stapling on; +# ssl_stapling_verify on; +# ssl_trusted_certificate /path/to/startssl_trust_chain.crt; +# +# +# add_header x-Content-Type-Options nosniff; +# add_header X-Frame-Options deny; +# add_header Strict-Transport-Security "max-age=16070400"; +# +# index index.js index.html index.htm; +# if ( -f $request_filename/index.html ){ +# rewrite (.*) $1/index.html break; +# } +# if ( !-f $request_filename ){ +# rewrite (.*) /index.js; +# } +# location = /index.js { +# proxy_http_version 1.1; +# proxy_set_header X-Real-IP $remote_addr; +# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +# proxy_set_header Host $http_host; +# proxy_set_header X-NginX-Proxy true; +# proxy_set_header Upgrade $http_upgrade; +# proxy_set_header Connection "upgrade"; +# proxy_pass http://127.0.0.1:$node_port$request_uri; +# proxy_redirect off; +# } +# +# location = /production.js { +# deny all; +# } +# +# location = /testing.js { +# deny all; +# } +# +# location ~ /static/ { +# etag on; +# expires max; +# } +#} + diff --git a/package.json b/package.json new file mode 100644 index 0000000..b601850 --- /dev/null +++ b/package.json @@ -0,0 +1,30 @@ +{ + "name": "thinkjs-application", + "description": "application created by thinkjs", + "version": "1.0.0", + "scripts": { + "start": "node www/development.js", + "compile": "babel src/ --out-dir app/", + "watch-compile": "node -e \"console.log(' no longer need, use command direct.');console.log();\"", + "watch": "npm run watch-compile" + }, + "dependencies": { + "babel-runtime": "6.x.x", + "dayjs": "^1.11.13", + "fs-extra": "^11.3.0", + "greenlock": "^2.8.9", + "greenlock-store-fs": "^3.2.2", + "le-challenge-fs": "^2.0.9", + "source-map-support": "0.4.0", + "thinkjs": "v2" + }, + "devDependencies": { + "babel-cli": "^6.18.0", + "babel-preset-es2015": "^6.18.0", + "babel-preset-stage-1": "^6.16.0", + "babel-plugin-transform-runtime": "^6.15.0", + "babel-core": "^6.20.0" + }, + "repository": "", + "license": "MIT" +} diff --git a/pm2.json b/pm2.json new file mode 100644 index 0000000..6749098 --- /dev/null +++ b/pm2.json @@ -0,0 +1,18 @@ +{ + "apps": [ + { + "name": "ssl", + "script": "www/live.js", + "cwd": "/home/program/front/git/ssl_manage", + "exec_mode": "cluster", + "instances": 1, + "max_memory_restart": "2G", + "autorestart": true, + "node_args": [], + "args": [], + "env": {}, + "error_file": "/data/pm2/logs/ssl-err.log", + "out_file": "/data/pm2/logs/ssl-out.log" + } + ] +} diff --git a/src/common/bootstrap/global.js b/src/common/bootstrap/global.js new file mode 100644 index 0000000..ffc7bb5 --- /dev/null +++ b/src/common/bootstrap/global.js @@ -0,0 +1,12 @@ +/** + * this file will be loaded before server started + * you can define global functions used in controllers, models, templates + */ + +/** + * use global.xxx to define global functions + * + * global.fn1 = function(){ + * + * } + */ \ No newline at end of file diff --git a/src/common/bootstrap/middleware.js b/src/common/bootstrap/middleware.js new file mode 100644 index 0000000..88ab294 --- /dev/null +++ b/src/common/bootstrap/middleware.js @@ -0,0 +1,13 @@ +/** + * this file will be loaded before server started + * you can register middleware + * https://thinkjs.org/doc/middleware.html + */ + +/** + * + * think.middleware('xxx', http => { + * + * }) + * + */ diff --git a/src/common/config/config.js b/src/common/config/config.js new file mode 100644 index 0000000..6b90992 --- /dev/null +++ b/src/common/config/config.js @@ -0,0 +1,7 @@ +'use strict'; +/** + * config + */ +export default { + //key: value +}; \ No newline at end of file diff --git a/src/common/config/db.js b/src/common/config/db.js new file mode 100644 index 0000000..92243af --- /dev/null +++ b/src/common/config/db.js @@ -0,0 +1,22 @@ +'use strict'; +/** + * db config + * @type {Object} + */ +export default { + type: 'mysql', + adapter: { + mysql: { + host: '127.0.0.1', + port: '', + database: '', + user: '', + password: '', + prefix: '', + encoding: 'utf8' + }, + mongo: { + + } + } +}; \ No newline at end of file diff --git a/src/common/config/env/development.js b/src/common/config/env/development.js new file mode 100644 index 0000000..8499247 --- /dev/null +++ b/src/common/config/env/development.js @@ -0,0 +1,15 @@ +'use strict'; + +export default { + domains:[ + // "oa.live.educlouddata.com", + // "m.live.educlouddata.com", + // "yun.live.educlouddata.com", + // "yunh5.live.educlouddata.com", + // "kms.live.educlouddata.com", + // "ams.live.educlouddata.com", + // "data.live.educlouddata.com", + "live.qqsrx.top", + ], + CERT_DIR:"/usr/local/nginx/conf/cert" +}; \ No newline at end of file diff --git a/src/common/config/env/live.js b/src/common/config/env/live.js new file mode 100644 index 0000000..8499247 --- /dev/null +++ b/src/common/config/env/live.js @@ -0,0 +1,15 @@ +'use strict'; + +export default { + domains:[ + // "oa.live.educlouddata.com", + // "m.live.educlouddata.com", + // "yun.live.educlouddata.com", + // "yunh5.live.educlouddata.com", + // "kms.live.educlouddata.com", + // "ams.live.educlouddata.com", + // "data.live.educlouddata.com", + "live.qqsrx.top", + ], + CERT_DIR:"/usr/local/nginx/conf/cert" +}; \ No newline at end of file diff --git a/src/common/config/env/production.js b/src/common/config/env/production.js new file mode 100644 index 0000000..2f0c401 --- /dev/null +++ b/src/common/config/env/production.js @@ -0,0 +1,5 @@ +'use strict'; + +export default { + resource_on: false +}; \ No newline at end of file diff --git a/src/common/config/env/testing.js b/src/common/config/env/testing.js new file mode 100644 index 0000000..79370c0 --- /dev/null +++ b/src/common/config/env/testing.js @@ -0,0 +1,5 @@ +'use strict'; + +export default { + +}; \ No newline at end of file diff --git a/src/common/config/error.js b/src/common/config/error.js new file mode 100644 index 0000000..5ad3dc6 --- /dev/null +++ b/src/common/config/error.js @@ -0,0 +1,9 @@ +'use strict'; +/** + * err config + */ +export default { + //key: value + key: 'errno', //error number + msg: 'errmsg' //error message +}; \ No newline at end of file diff --git a/src/common/config/hook.js b/src/common/config/hook.js new file mode 100644 index 0000000..aad6b37 --- /dev/null +++ b/src/common/config/hook.js @@ -0,0 +1,9 @@ +'use strict'; + +/** + * hook config + * https://thinkjs.org/doc/middleware.html#toc-df6 + */ +export default { + +} \ No newline at end of file diff --git a/src/common/config/locale/en.js b/src/common/config/locale/en.js new file mode 100644 index 0000000..79370c0 --- /dev/null +++ b/src/common/config/locale/en.js @@ -0,0 +1,5 @@ +'use strict'; + +export default { + +}; \ No newline at end of file diff --git a/src/common/config/session.js b/src/common/config/session.js new file mode 100644 index 0000000..d6702e4 --- /dev/null +++ b/src/common/config/session.js @@ -0,0 +1,20 @@ +'use strict'; + +/** + * session configs + */ +export default { + name: 'thinkjs', + type: 'file', + secret: 'VH7!OBT^', + timeout: 24 * 3600, + cookie: { // cookie options + length: 32, + httponly: true + }, + adapter: { + file: { + path: think.RUNTIME_PATH + '/session', + } + } +}; \ No newline at end of file diff --git a/src/common/config/view.js b/src/common/config/view.js new file mode 100644 index 0000000..e18753b --- /dev/null +++ b/src/common/config/view.js @@ -0,0 +1,14 @@ +'use strict'; +/** + * template config + */ +export default { + type: 'ejs', + content_type: 'text/html', + file_ext: '.html', + file_depr: '_', + root_path: think.ROOT_PATH + '/view', + adapter: { + ejs: {} + } +}; \ No newline at end of file diff --git a/src/common/controller/error.js b/src/common/controller/error.js new file mode 100644 index 0000000..66ed454 --- /dev/null +++ b/src/common/controller/error.js @@ -0,0 +1,77 @@ +'use strict'; +/** + * error controller + */ +export default class extends think.controller.base { + /** + * display error page + * @param {Number} status [] + * @return {Promise} [] + */ + displayError(status){ + + //hide error message on production env + if(think.env === 'production'){ + this.http.error = null; + } + + let errorConfig = this.config('error'); + let message = this.http.error && this.http.error.message || ''; + if(this.isJsonp()){ + return this.jsonp({ + [errorConfig.key]: status, + [errorConfig.msg]: message + }) + }else if(this.isAjax()){ + return this.fail(status, message); + } + + let module = 'common'; + if(think.mode !== think.mode_module){ + module = this.config('default_module'); + } + let file = `${module}/error/${status}.html`; + let options = this.config('tpl'); + options = think.extend({}, options, {type: 'base', file_depr: '_'}); + this.fetch(file, {}, options).then(content => { + content = content.replace('ERROR_MESSAGE', message); + this.type(options.content_type); + this.end(content); + }); + } + /** + * Bad Request + * @return {Promise} [] + */ + _400Action(){ + return this.displayError(400); + } + /** + * Forbidden + * @return {Promise} [] + */ + _403Action(){ + return this.displayError(403); + } + /** + * Not Found + * @return {Promise} [] + */ + _404Action(){ + return this.displayError(404); + } + /** + * Internal Server Error + * @return {Promise} [] + */ + _500Action(){ + return this.displayError(500); + } + /** + * Service Unavailable + * @return {Promise} [] + */ + _503Action(){ + return this.displayError(503); + } +} \ No newline at end of file diff --git a/src/home/config/config.js b/src/home/config/config.js new file mode 100644 index 0000000..6b90992 --- /dev/null +++ b/src/home/config/config.js @@ -0,0 +1,7 @@ +'use strict'; +/** + * config + */ +export default { + //key: value +}; \ No newline at end of file diff --git a/src/home/controller/base.js b/src/home/controller/base.js new file mode 100644 index 0000000..1c45bd9 --- /dev/null +++ b/src/home/controller/base.js @@ -0,0 +1,7 @@ +'use strict'; + +export default class extends think.controller.base { + /** + * some base method in here + */ +} \ No newline at end of file diff --git a/src/home/controller/index.js b/src/home/controller/index.js new file mode 100644 index 0000000..9c33f22 --- /dev/null +++ b/src/home/controller/index.js @@ -0,0 +1,236 @@ +'use strict'; + +import Base from './base.js'; + +const Greenlock = require('greenlock'); +const path = require('path'); +const GreenlockStoreFs = require('greenlock-store-fs'); +const LeChallengeFs = require('le-challenge-fs'); +const fs = require('fs-extra'); +const { execSync } = require('child_process'); +const https = require('https'); +const dayjs = require('dayjs'); // 需安装dayjs库 + + +// SSL根目录 +const ROOT_PATH = path.join(think.ROOT_PATH, 'ssl'); +const PEM_PATH = path.join(ROOT_PATH, 'cert'); +// 创建存储对象 +const leStore = GreenlockStoreFs.create({ + configDir: path.join(ROOT_PATH, 'letsencrypt'), +}); +// 创建验证对象 +const leHttpChallenge = LeChallengeFs.create({ + webrootPath: path.join(ROOT_PATH, 'lechallenge'), +}); +// 是否同意协议 +function leAgree (opts, agreeCb) { + agreeCb(null, opts.tosUrl); +} + +// 证书申请对象 +const greenlock = Greenlock.create({ + version: 'draft-12', + // 测试环境 + server: 'https://acme-staging-v02.api.letsencrypt.org/directory', + // 生产环境 + // server: 'https://acme-v02.api.letsencrypt.org/directory', + store: leStore, + challenges: { + 'http-01': leHttpChallenge, + }, + challengeType: 'http-01', + agreeToTerms: leAgree, + debug: true, + renewBy: 10 * 24 * 60 * 60 * 1000,// 10倒计时开始续期 +}); + + +// 创建SSL证书申请请求 +async function CreateSSL (domain, email = '') { + const results = await greenlock.register({ + domains: [domain], + email, + agreeTos: true, + rsaKeySize: 2048, + }); + // 如果生成证书就保存一次证书 + const dir = path.join(PEM_PATH, domain); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir); + } + if (results.cert && results.chain) { + fs.writeFileSync(path.join(dir, `${domain}.crt`), results.cert + results.chain, 'utf-8'); + console.log(`证书${domain}.crt创建成功!`); + } + if (results.privkey) { + fs.writeFileSync(path.join(dir, `${domain}.key`), results.privkey, 'utf-8'); + console.log(`证书${domain}.key创建成功!`); + } + return results; +} + + +/** + * 检查证书过期时间 + * @param {*} domain + * @returns + */ +function checkCertExpiry (domain) { + return new Promise((resolve, reject) => { + const req = https.request({ + hostname: domain, + port: 443, + method: 'GET', + agent: new https.Agent({ rejectUnauthorized: false }) // 避免自签名证书报错 + }, (res) => { + const cert = res.socket.getPeerCertificate(); + if (cert.valid_to) { + resolve(cert.valid_to); + } else { + reject(new Error('证书信息缺失')); + } + }); + + req.on('error', (err) => reject(err)); + req.end(); + }); +} + +/** + * + * @param {*} domain + * @returns + */ +async function getRemainingDays (domain) { + try { + const validTo = await checkCertExpiry(domain); + const expiryDate = dayjs(validTo, 'MMM DD HH:mm:ss YYYY GMT'); // 解析时间格式 + const currentDate = dayjs(); + const daysLeft = expiryDate.diff(currentDate, 'day'); + return daysLeft; + } catch (err) { + console.error(`检测失败:${err.message}`); + return -1; // 错误时返回-1 + } +} + + + + +export default class extends Base { + /** + * index action + * @return {Promise} [] + */ + async indexAction () { + let domains = this.config().domains; + let msgs = [] + for (let domain of domains) { + try { + const daysLeft = await getRemainingDays(domain); + const msg = `证书${domain},剩余${daysLeft}天` + console.log(msg); + msgs.push(msg); + } catch (e) { + const msg = `证书${domain},证书缺失或无法访问` + console.log(e); + msgs.push(msg); + } + } + this.assign({ + msgs: msgs.join('\n') + }); + return this.display(); + } + + /** + * 检查并更新证书 + */ + async checksslAction () { + let domains = this.config().domains; + let updateList = []; //需要更新的数据 + for (let domain of domains) { + try { + const daysLeft = await getRemainingDays(domain); + const msg = `证书${domain},剩余${daysLeft}天`; + console.log(msg); + if (daysLeft < 90) { + updateList.push(domain); + } + } catch (e) { + console.log("==".repeat(20)) + console.log('检查证书失败:', e); + console.log("==".repeat(20)) + } + } + if (updateList.length) { + console.log("==".repeat(20), "开始生成证书", "==".repeat(20)); + console.log('开始时间:', dayjs().format('YYYY-MM-DD HH:mm:ss')); + for (let domain of updateList) { + try { + const results = await CreateSSL(domain); + console.log(`证书${domain},生成成功`); + } catch (error) { + console.log("==".repeat(20), "证书生成失败", "==".repeat(20)); + console.log("域名:", domain); + console.log(e); + console.log("==".repeat(20), "证书生成失败", "==".repeat(20)); + } + } + await this.deployCert(updateList); + console.log(`更新证书数量:${updateList.length}`); + console.log('结束时间:', dayjs().format('YYYY-MM-DD HH:mm:ss')); + console.log("==".repeat(20), "结束生成证书", "==".repeat(20)); + } + this.success(); + } + + async createAction () { + const domain = this.post('domain'); + const email = this.post('email'); + if (!domain || !email) { + return this.fail('参数错误'); + } + try { + const results = await CreateSSL(domain, email); + this.deployCert([domain]); + return this.success(results); + } catch (error) { + return this.fail(JSON.stringify(error)); + } + } + + /** + * 复制证书到指定文件夹,并重启nginx + * @param {*} domains + * @returns + */ + async deployCert (domains) { + if (!domains || domains.length === 0) { + return; + } + try { + const dir2 = this.config().CERT_DIR; //nginx配置文件中 + // 1. 复制证书 + for (let domain of domains) { + const dir = path.join(PEM_PATH, domain); //生成的证书地址,项目中 + let originCrt = `${dir}/${domain}.crt`; + let originKey = `${dir}/${domain}.key`; + if (fs.existsSync(originCrt) && fs.existsSync(originKey)) { + await fs.copy(`${dir}/${domain}.crt`, `${dir2}/${domain}.crt`); + await fs.copy(`${dir}/${domain}.key`, `${dir2}/${domain}.key`); + } + } + + // 2. 检查配置 + execSync('nginx -t'); + + // 3. 重载服务 + execSync('nginx -s reload'); + console.log('证书部署成功!'); + } catch (error) { + console.error('部署失败:', error.message); + } + } +} \ No newline at end of file diff --git a/src/home/logic/index.js b/src/home/logic/index.js new file mode 100644 index 0000000..f1b7c98 --- /dev/null +++ b/src/home/logic/index.js @@ -0,0 +1,15 @@ +'use strict'; +/** + * logic + * @param {} [] + * @return {} [] + */ +export default class extends think.logic.base { + /** + * index action logic + * @return {} [] + */ + indexAction(){ + + } +} \ No newline at end of file diff --git a/src/home/model/index.js b/src/home/model/index.js new file mode 100644 index 0000000..64ea068 --- /dev/null +++ b/src/home/model/index.js @@ -0,0 +1,7 @@ +'use strict'; +/** + * model + */ +export default class extends think.model.base { + +} \ No newline at end of file diff --git a/ssl/cert/.keep b/ssl/cert/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ssl/lechallenge/.keep b/ssl/lechallenge/.keep new file mode 100644 index 0000000..e69de29 diff --git a/ssl/letsencrypt/.keep b/ssl/letsencrypt/.keep new file mode 100644 index 0000000..e69de29 diff --git a/view/common/error_400.html b/view/common/error_400.html new file mode 100644 index 0000000..3e26b0c --- /dev/null +++ b/view/common/error_400.html @@ -0,0 +1,37 @@ + + + +Bad Request - ThinkJS + + + + +
+
+

Bad Request

+
ERROR_MESSAGE
+
+ + diff --git a/view/common/error_403.html b/view/common/error_403.html new file mode 100644 index 0000000..2824b21 --- /dev/null +++ b/view/common/error_403.html @@ -0,0 +1,37 @@ + + + +Forbidden - ThinkJS + + + + +
+
+

Forbidden

+
ERROR_MESSAGE
+
+ + diff --git a/view/common/error_404.html b/view/common/error_404.html new file mode 100644 index 0000000..4f3e432 --- /dev/null +++ b/view/common/error_404.html @@ -0,0 +1,37 @@ + + + +Not Found - ThinkJS + + + + +
+
+

Not Found

+
ERROR_MESSAGE
+
+ + diff --git a/view/common/error_500.html b/view/common/error_500.html new file mode 100644 index 0000000..9ea0b52 --- /dev/null +++ b/view/common/error_500.html @@ -0,0 +1,37 @@ + + + +Internal Server Error - ThinkJS + + + + +
+
+

Internal Server Error

+
ERROR_MESSAGE
+
+ + diff --git a/view/common/error_503.html b/view/common/error_503.html new file mode 100644 index 0000000..478727c --- /dev/null +++ b/view/common/error_503.html @@ -0,0 +1,37 @@ + + + +Service Unavailable - ThinkJS + + + + +
+
+

Service Unavailable

+
ERROR_MESSAGE
+
+ + diff --git a/view/home/index_index.html b/view/home/index_index.html new file mode 100644 index 0000000..7e0d2a1 --- /dev/null +++ b/view/home/index_index.html @@ -0,0 +1,72 @@ + + + + + + New ThinkJS Application + + + + +
+
+

证书自动更新系统

+
+
+
+
+ <%= msgs %> +
+
+ + + \ No newline at end of file diff --git a/www/README.md b/www/README.md new file mode 100644 index 0000000..dfa9125 --- /dev/null +++ b/www/README.md @@ -0,0 +1,55 @@ +## application + +### start server + +*development* + +```js +node www/development.js +``` + +*testing* + +```js +node www/testing.js +``` + +*production* + +```js +node www/production.js +``` + +or use pm2 to manage node: + +``` +pm2 start www/production.js +``` + +### compile es6 code + +``` +npm run compile +``` + +### how to link resource + +*in template file* + +```html + + + + + + + +``` + +*link image in css* + +```css +.a{ + background: url(../img/a.png) no-repeat; +} +``` diff --git a/www/development.js b/www/development.js new file mode 100644 index 0000000..760053d --- /dev/null +++ b/www/development.js @@ -0,0 +1,21 @@ +var thinkjs = require('thinkjs'); +var path = require('path'); + +var rootPath = path.dirname(__dirname); + +var instance = new thinkjs({ + APP_PATH: rootPath + path.sep + 'app', + RUNTIME_PATH: rootPath + path.sep + 'runtime', + ROOT_PATH: rootPath, + RESOURCE_PATH: __dirname, + env: 'development' +}); + +// Build code from src to app directory. +instance.compile({ + log: true, + presets: [], + plugins: [] +}); + +instance.run(); diff --git a/www/live.js b/www/live.js new file mode 100644 index 0000000..da02586 --- /dev/null +++ b/www/live.js @@ -0,0 +1,21 @@ +var thinkjs = require('thinkjs'); +var path = require('path'); + +var rootPath = path.dirname(__dirname); + +var instance = new thinkjs({ + APP_PATH: rootPath + path.sep + 'app', + RUNTIME_PATH: rootPath + path.sep + 'runtime', + ROOT_PATH: rootPath, + RESOURCE_PATH: __dirname, + env: 'live' +}); + +// Build code from src to app directory. +instance.compile({ + log: true, + presets: [], + plugins: [] +}); + +instance.run(); diff --git a/www/production.js b/www/production.js new file mode 100644 index 0000000..71d1703 --- /dev/null +++ b/www/production.js @@ -0,0 +1,14 @@ +var thinkjs = require('thinkjs'); +var path = require('path'); + +var rootPath = path.dirname(__dirname); + +var instance = new thinkjs({ + APP_PATH: rootPath + path.sep + 'app', + RUNTIME_PATH: rootPath + path.sep + 'runtime', + ROOT_PATH: rootPath, + RESOURCE_PATH: __dirname, + env: 'production' +}); + +instance.run(true); diff --git a/www/testing.js b/www/testing.js new file mode 100644 index 0000000..6b5cac1 --- /dev/null +++ b/www/testing.js @@ -0,0 +1,14 @@ +var thinkjs = require('thinkjs'); +var path = require('path'); + +var rootPath = path.dirname(__dirname); + +var instance = new thinkjs({ + APP_PATH: rootPath + path.sep + 'app', + RUNTIME_PATH: rootPath + path.sep + 'runtime', + ROOT_PATH: rootPath, + RESOURCE_PATH: __dirname, + env: 'testing' +}); + +instance.run(); \ No newline at end of file