All notable changes to this project will be documented in this file.
- [Article] Added
unlistedfield (default:false) to the Article model. Unlisted articles remain publicly accessible via direct URL but are excluded from all list and context queries (pagination,GET /articles/all, prev/next navigation, and related article recommendations). This is useful for content such as translated versions of existing articles that should not appear in the main article feed. - [Article] Introduced
ARTICLE_LISTED_PUBLIC_FILTERconstant to complement the existingARTICLE_PUBLIC_FILTER, providing a dedicated filter for list-scoped public queries while preserving direct access semantics.
- Architecture / Config: Migrated the entire application configuration system from command-line arguments (CLI) to environment variables (
process.env). This aligns NodePress with modern cloud-native deployment standards (Twelve-Factor App methodology). - Environment Utility: Replaced the
parseArgvutility with a robustcreateEnvGetterutility. It features strict type-safe transformations, smart environment fallbacks (devFallback), and namespace isolation (all application variables are now strictly prefixed withNP_, e.g.,NP_ADMIN_EMAIL). - DX (Developer Experience): Retained the non-blocking validation mechanism for the configuration flow. Missing required environment variables will explicitly log descriptive errors/warnings to the output stream, guiding developers on what is critically missing without forcefully crashing the application during local startup.
- Search Endpoints: Fixed a Regular Expression Denial of Service (ReDoS) vulnerability in public search endpoints. User-supplied keywords are now strictly sanitized using
lodash/escapeRegExpat the global DTO validation layer to prevent malicious backtracking in MongoDB's regex engine. (#128) - Defense-in-Depth: Added strict length limits (
@MaxLength(50)) and space-collapsing to search keywords to prevent memory/resource exhaustion and space-padding bypasses.
- Database: Removed legacy and inefficient MongoDB
$textindices from theArticlemodel. Search operations now exclusively use native$regexoperators for consistent and predictable substring matching across all languages (including CJK).
- Standard OAuth 2.0 Support: Implemented a complete Access Token + Refresh Token flow for both Admin and Account modules.
- Refresh Token Rotation: Added
AuthRefreshTokenServiceutilizing Redis for secure, high-performance token management. - Enhanced Security:
- Integrated
@nestjs/throttlerfor granular rate limiting on sensitive auth endpoints. - Implemented token revocation (blacklist) for both short-lived and long-lived tokens.
- Unified
AuthPayloadinterface to ensure strict type safety across the auth lifecycle.
- Integrated
- Defensive Programming: Added optional
refresh_tokensupport during logout to prevent client-side deadlocks.
- API Response Structure: Standardized token responses to use
access_token,refresh_token,expires_in, andtoken_type(Bearer). - Service Refactoring: Decoupled authentication logic from Controllers into dedicated
AdminAuthServiceandUserAuthTokenService. - Route Renaming: Renamed
/admin/check-tokento/admin/verify-tokento better reflect its functional purpose.
- Race Condition Prevention: Optimized token refresh logic to minimize potential concurrency issues in single-admin scenarios.
This update brings a foundational architectural shift to the backend, strictly adhering to Domain-Driven Design (DDD) principles and Event-Driven Architecture (EDA). It resolves legacy circular dependencies and dramatically improves system maintainability.
- [BREAKING] Completely removed the backend
ArchiveModuleand the/archiveendpoint. - Why: The backend is no longer responsible for assembling massive, global JSON payloads. The frontend (SSR) will now utilize
Promise.allto concurrently fetch/tags,/categories, and/articles, assuming the BFF (Backend For Frontend) role. This significantly reduces backend memory overhead and unnecessary serialization.
- Integrated
@nestjs/event-emitteras the central Event Bus, replacing direct cross-module method invocations. - Decoupled Side-Effects: When a
TagorCategoryis deleted, its respective module only handles its own database/cache cleanup and then broadcasts events (TagDeleted,CategoryDeleted). - Silent Cascading Updates: The
Articlemodule now utilizesArticleListenerto asynchronously react to these events, safely executing$pulloperations to erase orphaned foreign keys without creating tight bidirectional coupling.
The previously monolithic ArticleService has been surgically divided into specialized sub-services:
ArticleStatsService: Dedicated to complex MongoDB aggregations (providing article counts for Tags/Categories, global reading statistics, and calendar data).ArticleSyncService: Dedicated to silent data synchronization and cleanup (e.g., atomic$pullof deleted taxonomies).ArticleContextService: Dedicated to contextual queries (previous/next and related articles).
- Cache Race-Condition Prevention: Refactored event listener execution order to guarantee that database
$pulloperations complete strictly before Redis caches are flushed and rebuilt, preventing stale data write-backs under high concurrency.
-
ID System Migration: Completely transitioned from MongoDB ObjectId to Number ID across all API layers and identifiers.
-
Identity Logic: Replaced legacy
Admin|Guestlogic with a unified and scalable Identity model. -
Schema Standardization:
-
Enforced strict responsibility separation: DTOs for input validation vs. Models for schema definition (indexes, defaults).
-
Standardized
nullas the database default value to eliminateundefinedinconsistencies. -
Added explicit storage type definitions for all Model fields.
-
Ensured all fields with default values are marked as
IsOptional. -
Implemented automatic string trimming via
@Transform(({ value }) => value?.trim()). -
Type Safety: Enhanced developer experience by providing comprehensive return types for all controller actions.
- User Module: Introduced a dedicated User module to handle core user entities.
- Disqus Module: Formally deprecated and removed the Disqus integration module.
- Service Decoupling: Refactored
ArticleServiceinto multiple sub-services based on specific responsibilities (e.g., Stats, Context). - Algorithm Optimization: Deeply optimized the
getRelatedArticlesrecommendation algorithm using a weighted similarity and Top-K sampling strategy. - Logic Refactoring: Overhauled internal service logic for better maintainability and performance.
-
Schema Flattening: Simplified the
authorstructure by flattening fields: -
author.name>author_name -
author.email>author_email -
author.website>author_website -
Removed the legacy
authorobject. -
Field Migration:
-
pid>parent_id(migrated0tonullfor better relational representation). -
post_id>target_id. -
Added
target_type('article' | 'page') to support polymorphic commenting. -
agent>user_agent. -
Functionality Updates:
-
Added a
userfield for registered user associations. -
Removed legacy IP repair functionality.
-
Removed the
agentfield from the creation payload.
- Performance Optimization: Significantly enhanced
aggregateArticleCountperformance through optimized aggregation pipelines. - Interface Cleanup: Removed redundant and over-engineered API endpoints.
- Hierarchy Refactoring: Renamed
pidtoparent_idand migrated its type fromObjectIdtoNumber.
- Singleton Pattern: Enforced a strict singleton constraint for both modules (requires
singleton: truein the database). - Security Update: Mandatory password setup is now required upon the first administrative profile update.
- Field Update: Renamed
option.blocklist.mailstooption.blocklist.emailsfor semantic clarity.
- Vote Schema: Flattened author fields to
author_nameandauthor_email; removed legacyauthor_typeandauthorobject. - Feedback Schema: Flattened user fields to
author_nameandauthor_email; removed the legacytidfield.
- Route Update: Refactored the manual refresh logic from
PATCH /archivetoPOST /archive/refresh.
- Added
CLOUDFLARE_AI_GATEWAYfor Cloudflare AI integration. - Updated
AKISMETconfiguration for enhanced spam protection.
- Critical Bug Fix: Resolved an issue where empty request bodies caused the
ValidationPipeto crash withCannot read properties of undefined (reading 'constructor'). - Logger Optimization: Enhanced global logging options to support system-level logs:
['fatal', 'error', 'warn']. - Model Efficiency: Replaced
getExtraObjectwithgetExtrasMapacross all models to optimizeextrasfield processing performance. - Compiler Options: Optimized
tsconfig.jsonconfigurations for better build performance and type safety.
- New Feature: Introduced a comprehensive
AIModuleto power intelligent content operations. - Capabilities:
generate-article-summary: Generate concise summaries for articles.generate-article-review: Generate high quality review for articles.generate-comment-reply: Automatically generate repliy user comments.
- Spam Management: Updated the anti-spam logic to trigger an administrative email notification even when a comment is identified and blocked as spam.
- Dependency Management: Upgraded all project dependencies to their latest stable versions.
- Lifecycle Management: Refactored module initialization logic to strictly distinguish between
constructorandonModuleInitexecution phases. - Task Scheduling: Migrated periodic background tasks from
node-scheduleto the native@nestjs/schedulemodule. - Event-Driven Architecture: Decoupled serial business logic in controllers by implementing a pub/sub pattern via
@nestjs/event-emitter.
- New Feature: Implemented a centralized
WebhookModuleto support external system integrations. - Event Listeners: Added
WebhookListenerto asynchronously dispatch notifications forOptionsandArticleevents.
- Renamed all
extendsfields toextrasacross all database tables. - Renamed the
nameproperty tokeywithin theKeyValueModel.
- Renamed the module from
optiontooptions. - Refactored
options.friend_linksstructure to[{ name: string, url: string }]. - Removed the
options.metafield.
- Renamed
article.descriptiontoarticle.summary. - Renamed
article.metatoarticle.stats. - Renamed
article.statetoarticle.status. - Added a new status value
Privatetoarticle.status. - Updated
ArticleLanguage.Mixedvalue frommixtomul. - Removed the
article.publicfield and its associated states. - Removed the
article.passwordfield and its associated states.
- Renamed
comment.statetocomment.status. - Removed the legacy
comment.is_topfield.
- Renamed
announcement.statetoannouncement.status.
- Renamed the module from
extensiontosystem. - API Endpoints: Updated
/system/statisticto/system/statistics.
- API Endpoints: Updated
/vote/postto/vote/article. - DTOs: Renamed
ArticleVoteDTO.post_idtoArticleVoteDTO.article_id.
- Refactor AWS service into a generic S3 service, decoupling from AWS S3.
- Added new API endpoint:
/article/all. - Renamed
optionfieldad_configtoapp_configfor broader client configuration usage.
Feature
- Update all dependencies to their latest versions.
- Upgrade
mongooseto v9. - Redesign the paginate utility to provide stricter type constraints.
- Use the correct schema option
{ id: false }to reduce ambiguity. - Improve query performance by leveraging the
leanoption.
Feature
- Improved password hash algorithm, using a more secure
bcrypt
Feature
- Replaced Express with Fastify as the HTTP server
- Renamed
AuthModuletoAdminModule - Refactored the global JWT authentication mechanism
- Refactored decorators
- Removed all legacy middleware (CORS)
- Removed the unused Cache decorator
- Removed unnecessary global constants
Feature
- Upgrade
expressto v5 - Upgrade
nestjsto v11 - Upgrade
Redissupports to v8 - Replaced
Rediswith@redis/client - Replaced
yargswithyargs-parser - Refactored
app.config.tsfile
Feature
- Upgrade dependencies
- Use
picocolorsinstead ofchalk
Feature
- Upgrade actions dependencies
- Upgrade dependencies
- Upgrade Eslint to v9
Refactor
- [Google] upgrade Google Analytics to v4
- [Article] optimize
getRelatedArticlesAPI - [Expansion] rename module name from
expansiontoextension
Feature
- [Auth] rename DB collection name from
AuthtoAdmin
Feature
- [Category] Add
/allAPI - Upgrade dependencies
Feature
- Improve global throttler
- Improve global log interceptor format
- Upgrade dependencies
Breaking Change
- Remove
/article/hottestAPI
Feature
- [Article] Add
featuredfield - Upgrade dependencies
Feature
- [Article] Add
mixedlanguage option - [Comment] Add
/calendarAPI - [Expansion] Add daily statistics
- Upgrade dependencies
Feature
- Add config
REDIS.namespace - Improve Redis Store
Feature
- Rename field
tag.articles_counttotag.article_count - Rename field
category.articles_counttocategory.article_count
Fix
- Fix
ArticleContextdata type - Fix
DBBackupServiceerror
Feature
- Upgrade nestjs v9 to v10
- Update various dependencies
- Use
pnpminstead ofyarnas a package management tool - Use
dayjsinstead ofmoment - Refactor and improve cache system
- Remove field
__vfrom all models - Rename field
create_attocreated_atandupdate_attoupdated_at - Rename field
article.thumbtoarticle.thumbnail - Rename field
article.tagtoarticle.tags - Rename field
article.categorytoarticle.categories - Rename field
article.disabled_commenttoarticle.disabled_comments - Add
Bingsupport toSeoService
Fix
- Fix googleAPI
Credentialstype - Fix
Statisticservice error
Feature
- Update various dependencies
Feature
- Fix
mongodumpcommand args
Feature
/vote/siteand/vote/articlemerged into/vote/post
Feature
- Add vote model
- Improve feedback service
Feature
- Anonymous user vote email.
- Add to
agentvote notification email.
Chore
- Upgrade deps
Feature
- Remove classified dir.
- Improve DB backup mail context
Feature
- AliYun OSS to AWS S3
- Remove STSToken API for cloud storage
Feature
- [Helper] improve
nodemailerconfig - [Helper] improve
akismettypes
Chore
- Upgrade deps
Feature
- [Option] add
statementfriend_linksfield - Add
feedbackmodule
Feature
- [Article] add
langfield
Feature
- New API
/article/calendar - Refactoring API
/article/related/:idto/article/:id/context - Rename API
/article/hotto/article/hottest - Improve
Articlemodule
BugFix
- fix
{ timestamps: false }forarticle.meta.viewsarticle.meta.likesarticle.meta.commentscomment.voteoption.meta.likes
Feature
- improve
guards - improve
QueryParamsdecorator - improve
Mongoosetypes - improve
Model>DTOs - improve
Optionmodule service - improve
Expansionstatistic service - Remove query
cachefield - Rename
tag.countcategory.countto<target>.articles_count - Add API
/article/hot/article/related/tag/all - Add
PermissionPipeExposePipepipes - Rename
HttpProcessortoResponsor - Generate documentation by
compodoc
Feature
- [MongoDB] improve MongoDB config & backup
Feature
express-rate-limit>@nestjs/throttler- [Vote] add throttler
- [Disqus] add throttler
- [Comment] add throttler
Feature
- [Disqus] cache for userinfo & thread
Feature
- [Article] random related articles
- [Comment] improve email content
- [Vote] send email to admin when new vote
Feature
- [Comment] add
reviseIPLocationservice
Chore
- email text
Feature
- [Like] rename
Likemodule toVote - [Disqus] add Disqus comment module
- [Auth] rename
gravatartoavatar - [Article] add
disabled_commentfield - [Article] remove
t_contentfield - [Option] remove
icpfield - [Option] rename
blacklisttoblocklist - [Comment] remove
is_topfield - [Comment] add
dislikesfield - [Comment] hidden
ip,emailfields - [Comment] add
email_hashvirtual field - [Helper] IP location services to
ip-api.com&ipapi.co
Chore
- Upgrade deps
- Remove
geoip-litedep
Chore
- Improve deploy logic
Feature
- Fix archive article query options
Feature
- Remove
mongoose-paginate - Remove
APP.LIMITconfig - Improve
AutoIncrementID.Config - Improve global paginate config
Feature
- Remove
syndicationmodule - Remove
cache-manager-redis-store - Add
archvemodule - Add global logger
Chore
- Upgrade deps
Redis> v4nest> v8mongoose> v6
Chore
- Upgrade deps
- Update CI scripts
- Update ESLint config & format
Feature
- DB backup shell & path
- Support patch API to backup DB & recover DB
Chore
- Upgrade all deps
- Remove unused deps
- Update API Document
- Fix typos
- Add
cspell.json
Breaking Change
- Remove
VlogMusicGitHubmodules to BFF server
Chore
- Upgrade all deps
Breaking Change
- comment content HTML -> markdown text
- remove marked module
Chore
- Upgrade all deps
Feature
- support redis
passwordconfig
Breaking Change
- add fe public path
- remove legacy folder file path for syndication
- Upgrade deps
- Fix bilibili video API url
- Add AD config field (options)
Promisetoasync awaitmongoose-auto-incrementtoauto-incrementmongoose-paginatetomongoose-paginate-v2- Add documents id field to unique index
- Improve sub documents
_id: falseoption - Improve documents
enumoption
- Wallpaper module support
en - Enable
esModuleInteropfortsconfig
- Fix article/hotList
query.state - Upgrade TypeScript deep
- Update
Optional Chaining
- Rename Sitemap module to Syndication module
- Add RSS service with Syndication module
- Add renewal API with Auth module
- Improve akismet module
- Remove geo-ip service
- Upgrade Nest
- Upgrade Mongoose (remove MongoDB's autoConnect)
- Upgrade RedisStore (workaround
is_cacheable_valueoption) - Upgrade typegoose (Remove
getModelForSchema) - Upgrade all dependencies
- Replace ESLint with TSLint
- Upgrade mongoose
- Update README.md
- Update FUNDING.yml
- Replace QINIU to Aliyun OSS
- Update uptoken and dbbackup module
- Remove project page with sitemap
- Add datebase backup service
- Add actions
- Update global console method
- 更新 所有依赖
- 更新 sitemap 模块及进行优化
- 更新 缓存及数据库模块、在核心节点增加告警服务
- 更新 SEO ping 服务
- 增加 API 文档
- 增加 logo 资源
- 增加 模型构造器、Provider 构造器、模型注入器
- 增加 Google 证书服务
增加 compodoc 文档构建器,但不实用- 优化 各模型搜索业务完善为大小写通配,并 trim 处理
- 优化 验证模型
- 优化 鉴权业务
- 优化 helper 模块
- 优化 设置表
- 去除 对 nestjs-typegoose 模块的依赖
- 废弃 枚举常量接口
- Update nestjs to v6.0
- 修正邮件服务文案错误
- 修复更新密码覆盖问题
- 修正缓存请求服务的问题
- 修正配置读取类型错误问题
- 升级 Wallpaper 业务
- 使用 Nest 进行重构
- 增加 Bilibili Vlog 业务模块
- opeitime logic
- add constants api
- 增加统计数据接口
- 优化密码更新机制
- 升级完善全站缓存机制
- 增加时间定点任务库
- 优化编码风格
- 完善项目信息
- 完善 Js Doc 信息
- Music 控制器增加 limit 参数
- Github 控制器优化数据
- 增加 bing-wallpaper API 服务
- 使用更友好的 consola 日志模块
- 为控制器和 Model 抽象出单独的状态常量
- 文章增加原创、转载字段
- 优化评论系统的业务
- submitSpam 与移至黑名单功能映射
- 移黑功能,会自动将 SPAM 信息提交至 akismet,同时添加至系统黑名单
- 升级 akismet-api 库,增加两项功能
- 升级 geoip-lite 库
- 升级 helmet 库
- 升级 jsonwebtoken 库,根据版本调整逻辑
- 升级 marked
- 升级 mongoose 库
- 升级 nodemailer 库,更新逻辑,去除 nodemailer-smtp-transport 库
- 升级 redis 库
- 升级 request 库
- 升级 sitemap 库,优化部分逻辑
- 升级 yargs 库
- fork mongoose-paginate 修复旧方法警告问题
- 更新密码加密机制
- 增加检查 Token 有效性接口
- 重构了播放器 API
- 修复了评论数 bug
- 驱动搜索引擎 ping 接口 文章发布后自动 ping 给搜索引擎 xml
- 增加评论功能+黑名单,评论可自动校验 spam,及黑名单 (ip、邮箱、关键字的校验)
- 使用 helmet + 手动优化,优化程序安全性
- 优化 mongoose 实例
- 优化数据表结构
- 更新数据时时间更新
- 修复时间检索失效
- 增加 idle-gc 内存回收
- 增加百度搜索引擎的实时提交
- 更新模块化别名
- 更新 README.md
- 加入网站地图接口
- 网站地图由于缓存或者 primise 不能及时更新
- 网站地图的数据构成中文章需要筛选公开一发布的文章
- 对接百度统计开放平台 api
- 密码存储需要使用 md5 加密机制
- token... 等 config 信息使用 node 命令参数在 shell 中配置覆盖
- lean 和 翻页插件一起使用,返回的 id 字段是 _id bug
- 整理统一 result 的返回结构
- 围观后计数功能
- 多说转发热门文章接口
- 相关文章接口
- 使用 Redis 缓存标签、播放器、Github 数据