|
diff --git a/Dockerfile b/Dockerfile |
|
index 7eb74fd7..c35d6945 100644 |
|
--- a/Dockerfile |
|
+++ b/Dockerfile |
|
@@ -6,9 +6,13 @@ WORKDIR /app |
|
ENV NPM_CONFIG_PREFIX=/home/node/.npm-global \ |
|
PATH=$PATH:/home/node/.npm-global/bin |
|
|
|
+# 安装国内镜像 |
|
+RUN npm install -g mirror-config-china --registry=https://registry.npmmirror.com |
|
+# 安装 CSP hash 计算工具 |
|
+RUN npm install -g github:apaatsio/csp-hash-from-html |
|
+ |
|
COPY package*.json ./ |
|
-RUN npm install -g mirror-config-china --registry=https://registry.npmmirror.com && \ |
|
- npm install |
|
+RUN npm install |
|
|
|
COPY . . |
|
RUN npm run build:prod |
|
diff --git a/package.json b/package.json |
|
index e42a38f5..5e22d477 100644 |
|
--- a/package.json |
|
+++ b/package.json |
|
@@ -4,7 +4,7 @@ |
|
"private": true, |
|
"scripts": { |
|
"dev": "vue-cli-service serve", |
|
- "build:prod": "vue-cli-service build", |
|
+ "build:prod": "vue-cli-service build && node update_csp.js", |
|
"build:stage": "vue-cli-service build --mode staging", |
|
"preview": "node build/index.js --preview", |
|
"lint": "eslint --fix --ext .js,.vue src", |
|
diff --git a/public/index.html b/public/index.html |
|
index 97cb494b..a5276766 100644 |
|
--- a/public/index.html |
|
+++ b/public/index.html |
|
@@ -9,6 +9,13 @@ |
|
<link rel="stylesheet" href="https://at.alicdn.com/t/font_2776755_qgop6g08bnq.css"> |
|
<link rel="stylesheet" href="https://at.alicdn.com/t/font_2950190_s1zn60qmw4r.css"> |
|
<meta property="og:image" content="https://greatmessage.688023.cn/logo.png"> |
|
+ <% if (htmlWebpackPlugin.options.isProduction) { %> |
|
+ <!-- 在这里放置只在生产环境下生成的标签 --> |
|
+ <meta |
|
+ http-equiv="Content-Security-Policy" |
|
+ content="script-src 'self' bootstrapcdn.com *.bootstrapcdn.com *.jsdelivr.net googleapis.com *.googleapis.com *.dingtalk.com {{CSP_SCRIPT_SRC_SHAS}};" |
|
+ /> |
|
+ <% } %> |
|
<meta |
|
name="description" |
|
content="专业的安全信息情报平台" |
|
diff --git a/update_csp.js b/update_csp.js |
|
index e69de29b..d7c4f0ad 100644 |
|
--- a/update_csp.js |
|
+++ b/update_csp.js |
|
@@ -0,0 +1,44 @@ |
|
+/** |
|
+ * 更新csp script-src sha的脚本 |
|
+ */ |
|
+const glob = require("glob"); |
|
+const fs = require("fs"); |
|
+const path = require("path"); |
|
+const { execSync } = require("child_process"); |
|
+ |
|
+const distDir = "./dist"; |
|
+ |
|
+const globPattern = path.join(distDir, "**/*.html"); |
|
+ |
|
+function trimString(str, trimStr) { |
|
+ let result = str; |
|
+ |
|
+ // 去除开头的指定字符串 |
|
+ while (result.startsWith(trimStr)) { |
|
+ result = result.substring(trimStr.length); |
|
+ } |
|
+ |
|
+ // 去除结尾的指定字符串 |
|
+ while (result.endsWith(trimStr)) { |
|
+ result = result.substring(0, result.length - trimStr.length); |
|
+ } |
|
+ |
|
+ return result; |
|
+} |
|
+ |
|
+// 计算 csp hash |
|
+const hashResult = execSync(`npx csp-hash -d script-src ${globPattern}`) |
|
+ .toString() |
|
+ .trim(); |
|
+const firstSpaceIndex = hashResult.indexOf(" "); |
|
+const shaText = hashResult.substring(firstSpaceIndex + 1); |
|
+ |
|
+// 补全 html 中的 csp 策略 |
|
+glob.sync(globPattern).map(function(filePath) { |
|
+ const content = fs.readFileSync(filePath, "utf-8"); |
|
+ const modifiedContent = content.replace( |
|
+ /\{\{\s*CSP_SCRIPT_SRC_SHAS\s*\}\}/g, |
|
+ trimString(shaText, ";") |
|
+ ); |
|
+ fs.writeFileSync(filePath, modifiedContent, "utf-8"); |
|
+}); |
|
diff --git a/vue.config.js b/vue.config.js |
|
index 2e3ca4a5..46bc6522 100644 |
|
--- a/vue.config.js |
|
+++ b/vue.config.js |
|
@@ -68,6 +68,7 @@ module.exports = { |
|
config.plugin('html') |
|
.tap(args => { |
|
args[0].title = '天禹漏洞情报平台' |
|
+ args[0].isProduction = process.env.NODE_ENV === 'production' |
|
return args |
|
}) |
|
|