Commit graph

524 commits

Author SHA1 Message Date
XiaoSeS
ac42c2346c
Merge pull request #786 from iflytek/fix/issue-613-oauth-concurrency-20260831
fix(auth): converge concurrent identity binding
2026-08-31 18:49:41 +08:00
XiaoSeS
bdb42b1be9
Merge pull request #787 from iflytek/fix/issue-615-audit-atomicity-20260831
fix(governance): make mutations and audit atomic
2026-08-31 18:48:30 +08:00
XiaoSeS
a73997c672
Merge pull request #784 from iflytek/fix/concurrent-publish-coordinate-race
fix(publish): return deterministic conflict on concurrent coordinate race
2026-08-31 18:47:19 +08:00
XiaoSeS
3a29f6d750 fix(auth): converge concurrent identity binding
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-31 16:30:33 +08:00
XiaoSeS
b22b92fcbc fix(governance): make mutations and audit atomic
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-31 16:30:33 +08:00
XiaoSeS
182f7bacef fix(publish): flush concurrent coordinate writes
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-31 16:30:33 +08:00
XiaoSeS
13510609a0
Merge pull request #783 from iflytek/fix/auth-stale-session-public-routes
fix(auth): allow public routes after session expiry
2026-08-31 15:25:01 +08:00
XiaoSeS
d1cd3d2afe
Merge pull request #782 from FenjuFu/fix/audit-detail-json
fix(audit): render audit detail JSON with Jackson instead of string concatenation
2026-08-31 15:24:06 +08:00
XiaoSeS
49ef09d989
Merge pull request #773 from FenjuFu/fix/publish-case-insensitive-whitelist
fix(publish): match allowed filenames case-insensitively
2026-08-31 15:19:52 +08:00
FenjuFu
d224c5a8ba fix(publish): return deterministic conflict on concurrent coordinate race
Concurrent publishes for the same (namespace_id, slug, owner_id) or
(skill_id, version) coordinate both pass the check-then-create reads and
race on the database unique constraints. The losing request surfaced an
unhandled DataIntegrityViolationException as HTTP 500.

Translate the constraint violation at both insert points into a
deterministic DomainBadRequestException (error.skill.publish.concurrentConflict),
matching the existing idiom in LabelDefinitionService/ReviewService/
PromotionService. No same-transaction re-read is attempted, so the losing
publish rolls back cleanly and returns a retryable conflict instead of a 500.

Add the i18n key (en/zh) and two unit tests covering the skill-insert and
version-insert races.

Closes #617

Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>
2026-08-31 14:27:45 +08:00
XiaoSeS
346acbcfa3 fix(auth): preserve protected invalid-session handling
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-31 14:00:45 +08:00
XiaoSeS
9f3b10d27a test(publish): cover case-insensitive whitelist variants
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-31 14:00:45 +08:00
XiaoSeS
98a0e1d2f9 fix(auth): allow public routes after session expiry
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-31 14:00:45 +08:00
FenjuFu
215ab11b09 fix(audit): render audit detail JSON with Jackson instead of concatenation
audit_log.detail_json is a JSONB column, so the value has to be valid
JSON or the insert fails. It was built by string concatenation at every
call site, with three inconsistent levels of escaping: none at all in
ClawHubCompatAppService, DeviceAuthWebController, LabelAdminAppService
and SkillLabelAppService; quotes only in ReviewPortalAppService,
SkillLifecycleAppService, NamespaceGovernanceService and
SkillGovernanceService; quotes and backslashes in
PromotionPortalAppService.escapeJson.

None of the three escapes control characters, which JSON forbids raw
inside a string. A reviewer pressing Enter in a review comment therefore
produced a payload PostgreSQL rejects, and because the audit write
happens after the domain mutation, the review was already approved when
the request returned 500.

Add AuditDetail, which renders the payload through Jackson, and route
all 29 construction sites through it. 17 of those interpolate a string
value and are the actual defect surface; the numeric and constant ones
are converted too so there is one way to build audit detail and no
hand-rolled example left to copy.

SkillHardDeleteService.toAuditPayload already did this correctly with a
LinkedHashMap and an ObjectMapper; AuditDetail is that shape extracted.
The service itself is left alone rather than changing its constructor
signature for no behavior gain.

Output is byte-identical for values that were already escaped correctly,
so the existing exact-string assertions in AdminSearchControllerTest and
PromotionPortalAppServiceTest are unchanged. null still means "no
detail": the builder returns null rather than {} when no field is set.

Addresses the JSON half of #615. The transaction half -- the domain
mutation and the audit write not sharing one transaction -- is a
separate design decision about whether an audit failure should roll back
a review, and is not bundled here.

Signed-off-by: FenjuFu <fufenjupku@gmail.com>
2026-08-30 18:39:48 +08:00
XiaoSeS
aa4ea17c4a fix(deploy): preserve storage volume ownership
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-29 15:58:55 +08:00
XiaoSeS
60fed4d94f fix(auth): support bearer tokens behind sub-path proxies
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-29 15:05:09 +08:00
XiaoSeS
2babc0935b fix(cli): add namespace sync manifest endpoint
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-29 14:06:34 +08:00
FenjuFu
e9ac6c162a fix(publish): match allowed filenames case-insensitively
Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>
2026-08-28 17:57:01 +08:00
XiaoSeS
f993ad6533
Merge pull request #712 from Vast-Stars/feat/personal-namespace-provisioning
feat(namespace): auto-provision a personal namespace on registration
2026-08-28 17:04:21 +08:00
XiaoSeS
37e3c63236
Merge pull request #688 from iflytek/fix/auth-email-assurance-guard-main
fix(auth): enforce trusted OAuth identity attributes
2026-08-28 17:04:15 +08:00
XiaoSeS
eeb63613f2 fix(namespace): enable personal provisioning by default 2026-08-28 16:42:26 +08:00
XiaoSeS
ee0f0763db refactor(namespace): keep personal provisioning configuration-only 2026-08-28 15:55:29 +08:00
XiaoSeS
7beb1be356 fix(namespace): skip system accounts during provisioning 2026-08-28 15:27:39 +08:00
XiaoSeS
04bb414b37 fix(namespace): use stable random personal namespace slugs 2026-08-28 15:19:56 +08:00
XiaoSeS
dc31bb97f4 Revert "feat(namespace): backfill personal namespaces for existing accounts"
This reverts commit 2d50437e4f.
2026-08-28 15:19:56 +08:00
XiaoSeS
fbf6887e9d Revert "fix(namespace): stop the backfill from querying with a null keyword"
This reverts commit 639e081ca7.
2026-08-28 15:19:56 +08:00
XiaoSeS
eba2762b5b Revert "feat(namespace): let operators choose which namespaces new accounts join"
This reverts commit a9e7f43e5a.
2026-08-28 15:19:56 +08:00
XiaoSeS
c91c2ca408 fix(auth): make GitHub email assurance resilient 2026-08-28 15:08:07 +08:00
XiaoSeS
c32bced109
Merge pull request #748 from myml/fix/security-csp-policy
fix(security): harden CSP policy and hide nginx server tokens
2026-08-28 10:22:14 +08:00
XiaoSeS
c825d896a4
Merge pull request #762 from FenjuFu/fix/code-scanning-alerts-2026-08
fix(security): resolve CodeQL findings
2026-08-28 10:22:04 +08:00
XiaoSeS
2e78f79e83
Merge pull request #765 from iflytek/fix/pr735-subscription-authorization-20260827
Some checks are pending
Security / Dependency Review (push) Waiting to run
Security / CodeQL (java-kotlin) (push) Waiting to run
Security / CodeQL (javascript-typescript) (push) Waiting to run
Security / CodeQL (python) (push) Waiting to run
fix(subscription): enforce current visibility for subscribers
2026-08-27 17:48:08 +08:00
XiaoSeS
1544ae4775 fix(skill-card): add owner summary compatibility overload
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-27 17:30:15 +08:00
XiaoSeS
ec9689dbc8 fix(skill-card): preserve owner fields when adding labels
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-27 17:28:09 +08:00
XiaoSeS
41a389432d fix(skill-card): keep legacy summary constructor compatible
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-27 17:26:30 +08:00
XiaoSeS
b0c4a154fd fix(skill-card): resolve author display names in summaries
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-27 17:21:15 +08:00
wurongjie
f43c047a6b feat(skill-card): show author and update time in skill card
Add ownerId and ownerDisplayName fields to SkillSummaryResponse,
and render author and last update time at the bottom of each skill card.

在技能卡片底部新增作者和最近更新时间显示,搜索结果接口新增
ownerId 和 ownerDisplayName 字段。

Log: 技能卡片新增作者和更新时间
Influence: 搜索结果页技能卡片底部显示作者和更新时间信息,接口新增 ownerId/ownerDisplayName 字段。
Signed-off-by: wurongjie <wurongjie@uniontech.com>
2026-08-27 17:21:15 +08:00
XiaoSeS
a3d1b4c9c5 test(subscription): remove unrelated confirm-publish assertions
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-27 16:56:01 +08:00
XiaoSeS
126f01d75e fix(subscription): retain yank visibility context
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-27 16:50:37 +08:00
XiaoSeS
1331667496 fix(subscription): reuse visibility policy and localize denial
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-27 16:45:55 +08:00
千乘妍 (Xiaoyaner)
bacfd58aa0 fix: emit confirm-publish events with permission-aware subscriber fanout
Signed-off-by: 千乘妍 (Xiaoyaner) <258399167+xiaoyaner0201@users.noreply.github.com>
2026-08-27 16:43:32 +08:00
FenjuFu
36967794d1 fix(security): resolve CodeQL findings
Use a bounded safe YAML constructor, remove the polynomial placeholder regex, keep public label access GET-only with CSRF protection, validate CLI callbacks as loopback URL objects, and use cryptographic UUIDs for E2E identities.

Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>
2026-08-27 15:16:54 +08:00
FenjuFu
7fc1df5043
feat(ratelimit): make thresholds runtime-configurable
Validated locally and in CI, including runtime configuration documentation.
2026-08-27 15:07:31 +08:00
Michael
16306dd4f4
feat(i18n): add Russian locale for web UI and server messages (#700)
Signed-off-by: Mikhail Neradkov <michael.neradkov@gmail.com>
2026-08-26 19:43:07 +08:00
bbdu3
95e630c096
fix(scan): prevent scan tasks from being lost after transaction commit
Some checks are pending
Security / Dependency Review (push) Waiting to run
Security / CodeQL (java-kotlin) (push) Waiting to run
Security / CodeQL (javascript-typescript) (push) Waiting to run
Security / CodeQL (python) (push) Waiting to run
Preserve scan delivery on lock contention through the retry path and add reclaim regression coverage.
2026-08-26 17:46:16 +08:00
XiaoSeS
3522bad295
Merge pull request #623 from gale-popai/fix/oauth-return-to
fix(auth): keep the OAuth return target through the provider callback
2026-08-26 15:29:48 +08:00
wrj97
5a95278528
fix(compat): prioritize PUBLIC/GLOBAL skills in legacy slug lookup (#750)
Some checks are pending
Security / Dependency Review (push) Waiting to run
Security / CodeQL (java-kotlin) (push) Waiting to run
Security / CodeQL (javascript-typescript) (push) Waiting to run
Security / CodeQL (python) (push) Waiting to run
* fix(compat): prioritize PUBLIC/GLOBAL skills in legacy slug lookup

When multiple skills share the same slug across namespaces,
findByLegacySlug now prefers PUBLIC visibility and GLOBAL
namespace over NAMESPACE_ONLY/PRIVATE ones, so plain slug
lookups resolve to the most accessible skill. Namespaces are
batch-fetched via findByIdIn to avoid N+1 database queries.

Signed-off-by: wurongjie <wurongjie@uniontech.com>

* fix(compat): prefer published legacy slug candidates

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

---------

Signed-off-by: wurongjie <wurongjie@uniontech.com>
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
Co-authored-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-25 16:58:17 +08:00
FenjuFu
91d0ae1504
feat(api): return skill labels from the skill listing endpoints on request (#730)
* feat(api): return skill labels from the skill listing endpoints on request

Skill labels were reachable only one skill at a time, through
/api/{v1,web}/skills/{namespace}/{slug}/labels, so a client rendering a list had
to issue a follow-up request per row.

Add includeLabels=true to GET /api/v1/skills and GET /api/web/skills. The labels
array is populated only when the parameter is set and left out of the payload
otherwise, so existing responses are byte-identical.

Labels for the whole page are resolved by SkillLabelProjectionService in three
queries — assignments, definitions, translations — rather than three per skill.

Closes #710

Signed-off-by: FenjuFu <fufenjupku@gmail.com>

* fix(api): use include parameter for skill labels

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* test(api): reject unsupported include before search

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

---------

Signed-off-by: FenjuFu <fufenjupku@gmail.com>
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
Co-authored-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-08-25 13:49:24 +08:00
FenjuFu
954dfce7a4
fix(publish): accept Windows zip directory entries (#742)
* fix(publish): accept Windows zip directory entries

Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>

* chore: restore repository line endings

Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>

---------

Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>
2026-08-24 19:58:18 +08:00
FenjuFu
d5c6411ce6
fix(i18n): disable host locale fallback (#741)
Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>
2026-08-24 19:54:05 +08:00
wurongjie
b807fb3ee1 fix(security): harden CSP policy and hide nginx server tokens
- Remove 'unsafe-inline' and 'unsafe-eval' from script-src directive
- Restrict connect-src to 'self' only
- Disable nginx server_tokens to hide version information

Signed-off-by: wurongjie <wurongjie@uniontech.com>
2026-08-24 17:02:42 +08:00