Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .cursor/rules/communication-guidelines.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
description: Nguyên tắc phản hồi và không lặp lại câu hỏi cũ
alwaysApply: true
---

# Nguyên Tắc Phản Hồi & Giao Tiếp

1. **Tuyệt đối không nhắc lại, lặp lại các kết luận hoặc câu hỏi cũ**:
- Không lặp lại việc so sánh trạng thái cũ (ví dụ: việc Beta behind Prod hay các thông báo trạng thái cũ) khi user không yêu cầu.
- Khi user hỏi câu hỏi mới hoặc đặt câu hỏi phản biện, chỉ tập trung giải quyết trực diện vấn đề được nêu.

2. **Trả lời đúng trọng tâm kỹ thuật**:
- Phân tích đúng bản chất kiến trúc (OAuth 2.1, PKCE Bridge, Redirect URI security model).
- Giải thích ngắn gọn, súc tích, mạch lạc và đi thẳng vào giải pháp kỹ thuật.
5 changes: 3 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
DATABASE_URL="postgresql://postiz-user:postiz-password@localhost:5432/postiz-db-local?schema=public&sslmode=prefer"
# Direct PostgreSQL Connection URL (Used for Prisma migrations and direct connections)
DATABASE_DIRECT_URL="postgresql://postiz-user:postiz-password@localhost:5432/postiz-db-local?schema=public&sslmode=prefer"
# Node TLS verification (set to 0 for self-signed certificates or Supabase poolers)
NODE_TLS_REJECT_UNAUTHORIZED="0"
# Node TLS verification — NEVER set to 0 in production. If you use self-signed
# certificates or a Supabase pooler that requires it, restrict it to dev only.
# NODE_TLS_REJECT_UNAUTHORIZED="0"
# Redis Cache & Session Store URL
REDIS_URL="redis://localhost:6379"
# Cryptographic secret for signing JWT sessions (must be 32+ random characters)
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/branding-guard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ jobs:
branding-guard:
name: "Validate Brand Engine & Contracts"
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout Code
uses: actions/checkout@v4
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/build-extension.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ on:
jobs:
submit:
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- uses: actions/checkout@v4
Expand All @@ -21,7 +23,7 @@ jobs:
run: pnpm install

- name: Zip extensions
run: FRONTEND_URL=https://platform.postiz.com pnpm run build:extension
run: FRONTEND_URL=https://app.crove.com pnpm run build:extension

- name: Upload to Nextcloud
env:
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ on:
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read

strategy:
matrix:
Expand Down Expand Up @@ -42,5 +44,11 @@ jobs:
- name: Validate Beta deployment script and compose contract
run: pnpm run validate:beta-deploy

- name: Test SSO Worker (vitest)
run: pnpm run test:sso

- name: Test bootstrap / OAuth consent (jest)
run: pnpm exec jest --config tests/bootstrap.jest.cjs --ci --passWithNoTests

- name: Build applications
run: pnpm run build
7 changes: 5 additions & 2 deletions .github/workflows/deploy-sso.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ on:
jobs:
test-and-deploy:
runs-on: ubuntu-latest
permissions:
contents: read
environment: ${{ github.event.inputs.environment == 'prod' && 'production' || github.ref_name == 'main' && 'production' || 'beta' }}
steps:
- name: Checkout Code
uses: actions/checkout@v4
Expand Down Expand Up @@ -60,7 +63,7 @@ jobs:
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID || '3368ff98a4c956164b7bbdc8fb950163' }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
workingDirectory: 'apps/crove-sso'
command: 'deploy -e beta'
env:
Expand All @@ -71,7 +74,7 @@ jobs:
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID || '3368ff98a4c956164b7bbdc8fb950163' }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
workingDirectory: 'apps/crove-sso'
command: 'deploy'
env:
Expand Down
9 changes: 5 additions & 4 deletions .github/workflows/eslint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,17 @@ jobs:
pnpm add -D @microsoft/eslint-formatter-sarif@2.1.7

- name: Run ESLint
# Transitional: violations are now VISIBLE as a failed step instead of
# being swallowed. Flip continue-on-error to false (and add a typecheck
# gate) once the flat-config setup is validated — see audit C9.
continue-on-error: true
run: |
npx eslint apps/${{ matrix.service }}/ \
--config apps/${{ matrix.service }}/.eslintrc.json \
--format @microsoft/eslint-formatter-sarif \
--output-file apps/${{ matrix.service }}/eslint-results.sarif || true
continue-on-error: true
--output-file apps/${{ matrix.service }}/eslint-results.sarif

- name: Upload analysis results to GitHub
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: apps/${{ matrix.service }}/eslint-results.sarif
wait-for-processing: true
continue-on-error: true
5 changes: 4 additions & 1 deletion .github/workflows/publish-extension.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
jobs:
submit:
runs-on: ubuntu-latest
permissions:
contents: read
environment: production
steps:
- uses: actions/checkout@v4

Expand All @@ -20,7 +23,7 @@ jobs:
run: pnpm install

- name: Zip extensions
run: FRONTEND_URL=https://platform.postiz.com pnpm run build:extension
run: FRONTEND_URL=https://app.crove.com pnpm run build:extension

- name: Publish to Chrome Web Store
uses: mnao305/chrome-extension-upload@v5.0.0
Expand Down
188 changes: 0 additions & 188 deletions .github/workflows/staging-conflicts.yml

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,5 @@ scripts/*.env
.artifacts/
.codex-artifacts/
.playwright-mcp/
.cloudflared/

7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed
- **Beta Runtime: DOS-Me First-Party Bootstrap 401 & Facebook Connect `client_id=undefined`**:
- Root cause: the Beta runtime (`crove-post-beta` on `crove-server`) had no `CROVE_POST_CLIENT_ID`/`CROVE_POST_CLIENT_SECRET` configured, so `BootstrapGuard` failed closed with 401 before HMAC verification; `FACEBOOK_APP_ID`/`FACEBOOK_APP_SECRET` were also missing, producing `client_id=undefined` in the Connect Facebook URL.
- Remediated by configuring `CROVE_POST_CLIENT_ID=pca_dosclaw_beta_7ef5e5f1`, `CROVE_POST_CLIENT_SECRET` (existing OAuth client secret, no rotation) and copying `FACEBOOK_APP_ID`/`FACEBOOK_APP_SECRET` from the prod env file into the Beta env file on the VM (gitignored by design via `scripts/*.env`).
- Verified with a signed request differential: signed bootstrap → HTTP 400 (guard passed, validation rejected the test body) vs unsigned → HTTP 401 (fail-closed). No OAuth app was recreated and no token was rotated.
- Beta container recreated with the same immutable image digest; a one-off boot hang after recreate (backend blocked pre-Nest with no network sockets) was cleared by a plain `docker restart`.

### Added
- **MCP Client Icons & Onboarding Enhancements (Upstream Sync)**:
- Added Nanoclaw and other third-party MCP client icons support in Public API.
Expand Down
Loading
Loading