diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 15c9195..60282b4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,8 +1,9 @@ name: Release Obsidian Plugin -on: - release: - types: [created, published] # 当在 GitHub 上创建或发布 Release 时触发 +on: + push: + tags: + - 'v*' # 推送版本标签时自动创建 Release 并上传插件文件 workflow_dispatch: # 支持手动触发测试 jobs: @@ -34,13 +35,11 @@ jobs: uses: actions/upload-artifact@v4 with: name: obsidian-github-stars-manager-build - path: | - main.js - manifest.json - styles.css - themes.css - versions.json - retention-days: 30 + path: | + main.js + manifest.json + styles.css + retention-days: 30 test: runs-on: ubuntu-latest @@ -58,12 +57,10 @@ jobs: - name: Verify build files exist run: | echo "🔍 Verifying build files..." - test -f main.js && echo "✅ main.js exists" || (echo "❌ main.js missing" && exit 1) - test -f manifest.json && echo "✅ manifest.json exists" || (echo "❌ manifest.json missing" && exit 1) - test -f styles.css && echo "✅ styles.css exists" || (echo "❌ styles.css missing" && exit 1) - test -f themes.css && echo "✅ themes.css exists" || (echo "❌ themes.css missing" && exit 1) - test -f versions.json && echo "✅ versions.json exists" || (echo "❌ versions.json missing" && exit 1) - echo "🎉 All required files are present!" + test -f main.js && echo "✅ main.js exists" || (echo "❌ main.js missing" && exit 1) + test -f manifest.json && echo "✅ manifest.json exists" || (echo "❌ manifest.json missing" && exit 1) + test -f styles.css && echo "✅ styles.css exists" || (echo "❌ styles.css missing" && exit 1) + echo "🎉 All required files are present!" validate: runs-on: ubuntu-latest @@ -145,37 +142,38 @@ jobs: release: runs-on: ubuntu-latest needs: [build, test, validate] - if: github.event_name == 'release' - permissions: - contents: write + if: startsWith(github.ref, 'refs/tags/v') + permissions: + contents: write + id-token: write + attestations: write steps: - name: Checkout code uses: actions/checkout@v4 - - name: Download build artifacts - uses: actions/download-artifact@v4 - with: - name: obsidian-github-stars-manager-build - - - name: Create release archive - run: | - echo "📦 Creating release archive..." - zip -r obsidian-github-stars-manager.zip main.js manifest.json styles.css themes.css versions.json - ls -lh obsidian-github-stars-manager.zip - - - name: Upload release assets - uses: softprops/action-gh-release@v2 - with: - files: | - main.js - manifest.json - styles.css - themes.css - versions.json - obsidian-github-stars-manager.zip - draft: false - prerelease: false + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: obsidian-github-stars-manager-build + + - name: Attest release assets + uses: actions/attest-build-provenance@v2 + with: + subject-path: | + main.js + manifest.json + styles.css + + - name: Upload release assets + uses: softprops/action-gh-release@v2 + with: + files: | + main.js + manifest.json + styles.css + draft: false + prerelease: false generate_release_notes: true fail_on_unmatched_files: true env: @@ -184,12 +182,9 @@ jobs: - name: Release summary run: | echo "🎉 Release completed successfully!" - echo "📦 Files uploaded:" - echo " - main.js" - echo " - manifest.json" - echo " - styles.css" - echo " - themes.css" - echo " - versions.json" - echo " - obsidian-github-stars-manager.zip" - echo "" - echo "✨ Release Notes automatically generated from commit history" + echo "📦 Files uploaded:" + echo " - main.js" + echo " - manifest.json" + echo " - styles.css" + echo "" + echo "✨ Release Notes automatically generated from commit history" diff --git a/README.md b/README.md index e595cae..2461323 100644 --- a/README.md +++ b/README.md @@ -35,15 +35,35 @@ - 📱 响应式瀑布流布局:类似 Pinterest 的卡片展示方式 - ✨ 平滑动画和悬停效果 -### 🔒 安全与隐私 -- 🔐 使用 GitHub Personal Access Token 进行安全认证 -- 💾 所有数据本地存储,不上传到任何第三方服务器 -- 🛡️ 符合 Obsidian 插件商店安全标准 -- ✅ 通过 eslint-plugin-obsidianmd 全部规则验证 - -## 配置 - -要使用此插件,您需要提供一个具有必要权限的 GitHub 个人访问令牌 (PAT),以便读取您已加星标的仓库。 +### 🔒 安全与隐私 +- 🔐 使用 GitHub Personal Access Token 进行安全认证 +- 💾 GitHub 令牌、仓库缓存、标签和笔记均保存在本地插件数据中 +- 🌐 仅在同步或校验令牌时访问 GitHub 官方服务 +- ✅ 通过 eslint-plugin-obsidianmd 全部规则验证 + +## 安全与隐私 + +GitHub Stars Manager 是本地优先的 GitHub 集成插件。插件只会在用户配置账号、校验令牌、手动同步或触发相关操作时访问 GitHub 服务。 + +运行时可能访问的外部服务: + +- `api.github.com`:校验 GitHub 令牌、读取当前用户信息、获取已加星标仓库和仓库详情 +- `github.com`:用户点击仓库链接时在浏览器中打开 GitHub 页面 +- `avatars.githubusercontent.com` 或其他 GitHub 头像域名:显示 GitHub 用户和仓库所有者头像 + +插件不会: + +- 上传保险库内容或笔记正文 +- 收集分析数据或遥测数据 +- 跟踪用户行为 +- 下载或执行远程代码 +- 将 GitHub 令牌发送到 GitHub 以外的服务 + +GitHub 个人访问令牌会保存在 Obsidian 插件设置数据中。该数据位于本地保险库配置内,不会由插件主动上传;但它不是加密密码库。建议为令牌设置过期时间,并尽量使用满足需求的最小权限。 + +## 配置 + +要使用此插件,您需要提供一个具有必要权限的 GitHub 个人访问令牌 (PAT),以便读取您已加星标的仓库。 **如何获取 GitHub 个人访问令牌 (PAT):** @@ -54,7 +74,7 @@ 5. **生成新令牌:** 点击 "Generate new token" 按钮,然后选择 "Generate new token (classic)"。 6. **令牌描述:** 在 "Note" 字段中,为您的令牌添加一个描述性的名称,例如 "Obsidian Stars Manager"。 7. **设置过期时间:** 选择一个合适的过期时间 (Expiration)。为了安全起见,建议不要选择 "No expiration"。 -8. **选择范围 (Scopes):** 这是最关键的一步。您需要授予此令牌访问您的仓库的权限。勾选 `repo` 这个顶级复选框。这将自动选中其下的所有子权限,这是插件读取您的星标仓库所必需的。 +8. **选择范围 (Scopes):** 建议优先使用最小权限。读取公开星标仓库通常使用 `read:user` 和 `public_repo` 即可;只有在确实需要访问私有仓库相关数据时,才考虑使用更宽泛的 `repo` 权限。 9. **生成令牌:** 点击页面底部的 "Generate token" 按钮。 10. **复制令牌:** **重要!** GitHub 只会显示一次完整的令牌。请立即点击复制按钮将其复制下来,并妥善保管。**离开此页面后将无法再次看到完整的令牌。** 11. **在插件中使用:** 将复制的令牌粘贴到 Obsidian 中 "GitHub Stars Manager" 插件设置选项卡里的 "GitHub 个人访问令牌 (PAT)" 字段中。 @@ -96,7 +116,7 @@ ### 手动安装 1. 下载最新版本的 `main.js`、`manifest.json` 和 `styles.css` -2. 将这些文件复制到您的保险库文件夹:`VaultFolder/.obsidian/plugins/obsidian-github-stars-manager/` +2. 将这些文件复制到您的保险库文件夹:`VaultFolder/.obsidian/plugins/github-stars-manager/` 3. 重启 Obsidian 4. 在设置中启用插件 @@ -160,13 +180,20 @@ npm run version ## 更新日志 -### v0.1.1 (当前版本) -- 🏷️ 新增 Tag Chips 输入组件,支持快速选择标签 -- ⭐ 添加星标总数显示功能 -- 🎨 增强笔记卡片可见性和 UI 样式 +### v0.1.2 (当前版本) +- 🛡️ 将最低 Obsidian 版本声明更新为 1.7.2,匹配当前使用的官方 API 要求 +- 🔒 补充安全与隐私说明,明确运行时访问的 GitHub 服务和本地数据存储方式 +- 🔑 将 GitHub 令牌说明调整为最小权限优先,推荐 `read:user` 和 `public_repo` +- 📦 优化 Release 工作流,仅发布 Obsidian 支持的插件文件并生成构建来源证明 +- 🔧 移除构建脚本中的 `builtin-modules` 和 `dotenv` 依赖,降低审核警告 + +### v0.1.1 +- 🏷️ 新增 Tag Chips 输入组件,支持快速选择标签 +- ⭐ 添加星标总数显示功能 +- 🎨 增强笔记卡片可见性和 UI 样式 - 🔧 启用全部 25 个 eslint-plugin-obsidianmd 规则 - 🐛 修复 token 错误处理和提示信息 -- 🛡️ 通过 Obsidian 插件商店安全审核 +- 🛡️ 补充安全与隐私说明,便于 Obsidian Community 审核识别网络与数据行为 - 🤖 配置 pre-commit hook 和 GitHub Actions CI/CD ### v0.1.0 @@ -204,4 +231,4 @@ MIT License - 详见 [LICENSE](LICENSE) 文件 - [Obsidian 官网](https://obsidian.md) - [GitHub API 文档](https://docs.github.com/en/rest) -- [插件开发文档](https://docs.obsidian.md/Plugins/Getting+started/Build+a+plugin) \ No newline at end of file +- [插件开发文档](https://docs.obsidian.md/Plugins/Getting+started/Build+a+plugin) diff --git a/README_en.md b/README_en.md index 5cff76b..e643c5b 100644 --- a/README_en.md +++ b/README_en.md @@ -35,13 +35,33 @@ A powerful Obsidian plugin that allows you to manage and view your GitHub starre - 📱 Responsive waterfall layout: Pinterest-style card display - ✨ Smooth animations and hover effects -### 🔒 Security & Privacy -- 🔐 Secure authentication using GitHub Personal Access Token -- 💾 All data stored locally, no upload to any third-party servers -- 🛡️ Compliant with Obsidian plugin store security standards -- ✅ Passed all eslint-plugin-obsidianmd rule validations - -## Configuration +### 🔒 Security & Privacy +- 🔐 Secure authentication using GitHub Personal Access Token +- 💾 GitHub tokens, repository cache, tags, and notes are stored in local plugin data +- 🌐 Only connects to official GitHub services when syncing or validating tokens +- ✅ Passed all eslint-plugin-obsidianmd rule validations + +## Security & Privacy + +GitHub Stars Manager is a local-first GitHub integration. It only connects to GitHub services when you configure an account, validate a token, sync repositories, or open GitHub-related links. + +Runtime external services: + +- `api.github.com`: validates GitHub tokens, reads the current user, fetches starred repositories, and fetches repository details +- `github.com`: opens repository pages when you click repository links +- `avatars.githubusercontent.com` or other GitHub avatar hosts: displays GitHub user and repository owner avatars + +This plugin does not: + +- upload vault content or note bodies +- collect analytics or telemetry +- track users +- download or execute remote code +- send your GitHub token to any service other than GitHub + +GitHub Personal Access Tokens are stored in local Obsidian plugin settings data inside your vault configuration. The plugin does not upload this data, but it is not an encrypted password vault. Use token expiration and the minimum scopes needed for your use case. + +## Configuration To use this plugin, you need to provide a GitHub Personal Access Token (PAT) with the necessary permissions to read your starred repositories. @@ -54,7 +74,7 @@ To use this plugin, you need to provide a GitHub Personal Access Token (PAT) wit 5. **Generate New Token:** Click the "Generate new token" button, then select "Generate new token (classic)". 6. **Token Description:** In the "Note" field, give your token a descriptive name, e.g., "Obsidian Stars Manager". 7. **Set Expiration:** Choose an appropriate expiration duration. For security, "No expiration" is not recommended. -8. **Select Scopes:** This is crucial. You need to grant permission to access your repositories. Check the top-level `repo` scope checkbox. This automatically selects all necessary sub-permissions for the plugin to read your starred repositories. +8. **Select Scopes:** Prefer the minimum required scopes. Reading public starred repositories usually only requires `read:user` and `public_repo`. Only use the broader `repo` scope if you specifically need access to private repository-related data. 9. **Generate Token:** Click the "Generate token" button at the bottom of the page. 10. **Copy Token:** **Important!** GitHub will only show the full token once. Click the copy icon immediately to copy it and store it securely. **You won't be able to see the full token again after leaving this page.** 11. **Use in Plugin:** Paste the copied token into the "GitHub Personal Access Token (PAT)" field in the "GitHub Stars Manager" settings tab within Obsidian. @@ -96,7 +116,7 @@ You can quickly switch themes using the theme button at the top of the plugin in ### Manual Installation 1. Download the latest `main.js`, `manifest.json`, and `styles.css` -2. Copy these files to your vault: `VaultFolder/.obsidian/plugins/obsidian-github-stars-manager/` +2. Copy these files to your vault: `VaultFolder/.obsidian/plugins/github-stars-manager/` 3. Restart Obsidian 4. Enable the plugin in settings @@ -149,13 +169,20 @@ npm run version ## Changelog -### v0.1.1 (Current Version) -- 🏷️ Added Tag Chips input component with quick tag selection -- ⭐ Added total stars count display feature -- 🎨 Enhanced note card visibility and UI styling +### v0.1.2 (Current Version) +- 🛡️ Updated the minimum Obsidian version to 1.7.2 to match the official API requirements used by the plugin +- 🔒 Added clearer security and privacy disclosures for GitHub services and local data storage +- 🔑 Changed GitHub token guidance to prefer the minimum `read:user` and `public_repo` scopes +- 📦 Improved the Release workflow to publish only Obsidian-supported plugin files and generate build provenance attestations +- 🔧 Removed `builtin-modules` and `dotenv` from the build script to reduce review warnings + +### v0.1.1 +- 🏷️ Added Tag Chips input component with quick tag selection +- ⭐ Added total stars count display feature +- 🎨 Enhanced note card visibility and UI styling - 🔧 Enabled all 25 eslint-plugin-obsidianmd rules - 🐛 Fixed token error handling and error messages -- 🛡️ Passed Obsidian plugin store security review +- 🛡️ Added clearer security and privacy disclosures for Obsidian Community review - 🤖 Configured pre-commit hooks and GitHub Actions CI/CD ### v0.1.0 diff --git a/esbuild.config.mjs b/esbuild.config.mjs index b65e16a..75f6977 100644 --- a/esbuild.config.mjs +++ b/esbuild.config.mjs @@ -1,13 +1,34 @@ -import esbuild from "esbuild"; -import process from "process"; -import builtins from "builtin-modules"; -import fs from "fs"; // Added for file system operations -import path from "path"; // Added for path manipulation -import { fileURLToPath } from 'url'; -import dotenv from 'dotenv'; - -// Load environment variables from .env file -dotenv.config(); +import esbuild from "esbuild"; +import process from "process"; +import fs from "fs"; // Added for file system operations +import path from "path"; // Added for path manipulation +import { builtinModules } from "node:module"; + +function loadLocalEnvFile(envPath = ".env") { + if (!fs.existsSync(envPath)) return; + + const envContent = fs.readFileSync(envPath, "utf8"); + for (const line of envContent.split(/\r?\n/)) { + const trimmedLine = line.trim(); + if (!trimmedLine || trimmedLine.startsWith("#")) continue; + + const separatorIndex = trimmedLine.indexOf("="); + if (separatorIndex === -1) continue; + + const key = trimmedLine.slice(0, separatorIndex).trim(); + let value = trimmedLine.slice(separatorIndex + 1).trim(); + + if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) { + value = value.slice(1, -1); + } + + if (key && process.env[key] === undefined) { + process.env[key] = value; + } + } +} + +loadLocalEnvFile(); // 设置正确的字符编码处理 process.stdout.setEncoding('utf8'); @@ -62,7 +83,10 @@ if you want to view the source, please visit the github repository of this plugi */ `; -const prod = (process.argv[2] === "production"); +const prod = (process.argv[2] === "production"); +const nodeBuiltins = Array.from(new Set(builtinModules.flatMap(moduleName => { + return moduleName.startsWith("node:") ? [moduleName, moduleName.slice(5)] : [moduleName, `node:${moduleName}`]; +}))); // esbuild plugin to handle copying files after build with backup const copyPlugin = { @@ -163,7 +187,7 @@ const context = await esbuild.context({ "@lezer/common", "@lezer/highlight", "@lezer/lr", - ...builtins], + ...nodeBuiltins], format: "cjs", target: "es2018", logLevel: "info", diff --git a/manifest.json b/manifest.json index 7110bf5..3af06f0 100644 --- a/manifest.json +++ b/manifest.json @@ -1,8 +1,8 @@ { "id": "github-stars-manager", "name": "GitHub Stars Manager", - "version": "0.1.1", - "minAppVersion": "1.0.0", + "version": "0.1.2", + "minAppVersion": "1.7.2", "description": "Manage your GitHub starred repositories.", "author": "EmberSparks", "authorUrl": "https://github.com/EmberSparks", diff --git a/package-lock.json b/package-lock.json index 606e54d..edcfbbe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "github-stars-manager", - "version": "0.1.1", + "version": "0.1.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "github-stars-manager", - "version": "0.1.1", + "version": "0.1.2", "license": "MIT", "dependencies": { "@octokit/rest": "^22.0.0", @@ -17,8 +17,6 @@ "@types/node": "^18.19.0", "@typescript-eslint/eslint-plugin": "^8.0.0", "@typescript-eslint/parser": "^8.0.0", - "builtin-modules": "^3.3.0", - "dotenv": "^16.3.1", "esbuild": "^0.19.0", "eslint": "^9.39.1", "eslint-plugin-import": "^2.32.0", @@ -1456,18 +1454,6 @@ "node": ">=8" } }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmmirror.com/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -1771,18 +1757,6 @@ "node": ">=0.10.0" } }, - "node_modules/dotenv": { - "version": "16.6.1", - "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.6.1.tgz", - "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", diff --git a/package.json b/package.json index 892655f..b0e472d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "github-stars-manager", - "version": "0.1.1", + "version": "0.1.2", "description": "Obsidian plugin for managing and viewing your GitHub starred repositories with multi-account support and custom themes", "main": "main.js", "scripts": { @@ -25,8 +25,6 @@ "@types/node": "^18.19.0", "@typescript-eslint/eslint-plugin": "^8.0.0", "@typescript-eslint/parser": "^8.0.0", - "builtin-modules": "^3.3.0", - "dotenv": "^16.3.1", "esbuild": "^0.19.0", "eslint": "^9.39.1", "eslint-plugin-import": "^2.32.0", diff --git a/src/i18n/en.ts b/src/i18n/en.ts index e052ce1..a956991 100644 --- a/src/i18n/en.ts +++ b/src/i18n/en.ts @@ -291,8 +291,8 @@ export const en = { autoFetch: 'Auto fetch', tokenLabel: 'Personal access token', tokenPlaceholder: 'Ghp_xxxxxxxxxxxx', - tokenDesc: 'GitHub personal access token with read:user and public_repo scopes', - tokenDescShort: 'GitHub personal access token with repo scope permission required', + tokenDesc: 'GitHub personal access token. Prefer the minimum read:user and public_repo scopes.', + tokenDescShort: 'Prefer read:user and public_repo scopes; use repo only if private repository data is needed.', tokenInputPlaceholder: 'Enter your GitHub personal access token', howToGetToken: 'How to get a token?', validateAndSave: 'Validate and save', @@ -308,7 +308,7 @@ export const en = { // Single token (legacy) githubToken: 'GitHub personal access token', - githubTokenDesc: 'Token for accessing your GitHub starred repositories. Requires repo scope permission. It is recommended to use the multi-account management feature above.', + githubTokenDesc: 'Token for accessing your GitHub starred repositories. Prefer the minimum read:user and public_repo scopes; use repo only if private repository data is needed. It is recommended to use the multi-account management feature above.', githubTokenPlaceholder: 'Enter your GitHub personal access token', // Sync settings diff --git a/src/i18n/zh.ts b/src/i18n/zh.ts index 82e0ac2..a9712c7 100644 --- a/src/i18n/zh.ts +++ b/src/i18n/zh.ts @@ -293,8 +293,8 @@ export const zh: TranslationKeys = { autoFetch: '自动获取', tokenLabel: '个人访问令牌', tokenPlaceholder: 'ghp_xxxxxxxxxxxx', - tokenDesc: '需要read:user和public_repo权限的GitHub个人访问令牌', - tokenDescShort: '需要repo权限的GitHub个人访问令牌', + tokenDesc: 'GitHub 个人访问令牌,建议使用 read:user 和 public_repo 最小权限', + tokenDescShort: '建议使用 read:user 和 public_repo 权限;仅需私有仓库数据时才使用 repo 权限', tokenInputPlaceholder: '输入您的GitHub个人访问令牌', howToGetToken: '如何获取令牌?', validateAndSave: '验证并保存', @@ -310,7 +310,7 @@ export const zh: TranslationKeys = { // 单一令牌(向后兼容) githubToken: 'GitHub个人访问令牌', - githubTokenDesc: '用于访问您的GitHub星标仓库的令牌。需要repo权限。建议使用上方的多账号管理功能。', + githubTokenDesc: '用于访问您的 GitHub 星标仓库的令牌。建议使用 read:user 和 public_repo 最小权限;仅需私有仓库数据时才使用 repo 权限。建议使用上方的多账号管理功能。', githubTokenPlaceholder: '输入您的GitHub个人访问令牌', // 同步设置 diff --git a/versions.json b/versions.json index 9f3abf3..2240668 100644 --- a/versions.json +++ b/versions.json @@ -1,4 +1,5 @@ { "0.1.0": "1.0.0", - "0.1.1": "1.0.0" + "0.1.1": "1.7.2", + "0.1.2": "1.7.2" } \ No newline at end of file