Skip to content

Commit ecb7478

Browse files
Merge pull request #174 from DevLoversTeam/develop
Release v0.4.0
2 parents bfa059e + a8d6986 commit ecb7478

437 files changed

Lines changed: 99331 additions & 21258 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: Shop janitor - restock stale orders
2+
3+
on:
4+
schedule:
5+
- cron: "*/5 * * * *" # every 5 minutes (UTC)
6+
workflow_dispatch: {}
7+
8+
concurrency:
9+
group: shop-janitor-restock-stale
10+
cancel-in-progress: false
11+
12+
permissions:
13+
contents: read
14+
15+
jobs:
16+
run:
17+
runs-on: ubuntu-latest
18+
timeout-minutes: 3
19+
20+
defaults:
21+
run:
22+
working-directory: frontend
23+
24+
steps:
25+
- name: Checkout
26+
uses: actions/checkout@v4
27+
28+
- name: Setup Node
29+
uses: actions/setup-node@v4
30+
with:
31+
node-version: "20"
32+
33+
# Step-level guard: тут secrets дозволені
34+
- name: Guard config (skip if secrets missing)
35+
id: guard
36+
run: |
37+
if [ -z "$JANITOR_URL" ] || [ -z "$INTERNAL_JANITOR_SECRET" ]; then
38+
echo "::warning::JANITOR_URL or INTERNAL_JANITOR_SECRET is empty; skipping janitor run."
39+
echo "should_run=false" >> "$GITHUB_OUTPUT"
40+
exit 0
41+
fi
42+
echo "should_run=true" >> "$GITHUB_OUTPUT"
43+
env:
44+
JANITOR_URL: ${{ secrets.JANITOR_URL }}
45+
INTERNAL_JANITOR_SECRET: ${{ secrets.INTERNAL_JANITOR_SECRET }}
46+
47+
- name: Run janitor
48+
if: steps.guard.outputs.should_run == 'true'
49+
run: node scripts/shop-janitor-restock-stale.mjs
50+
env:
51+
JANITOR_URL: ${{ secrets.JANITOR_URL }}
52+
INTERNAL_JANITOR_SECRET: ${{ secrets.INTERNAL_JANITOR_SECRET }}
53+
JANITOR_TIMEOUT_MS: "25000"

.gitignore

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,12 @@ next-env.d.ts
6464
# Documentation (development only)
6565
.claude/
6666
CLAUDE.md
67-
frontend/docs/
67+
frontend/docs/
68+
frontend/.env.bak
69+
70+
71+
# local env backups
72+
frontend/.env*.bak
73+
frontend/.env.bak
74+
75+
tmpclaude-*

.hintrc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@
88
{
99
"aria-valid-attr-value": "off"
1010
}
11-
]
11+
],
12+
"axe/structure": [
13+
"default",
14+
{
15+
"list": "off"
16+
}
17+
],
18+
"no-inline-styles": "off"
1219
}
1320
}

CHANGELOG.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,61 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
101101
- Prevented import breakages caused by outdated shop/platform shells
102102
- Improved robustness of quiz duration calculation with reliable fallbacks
103103
- Cleaned up redundant files, comments, and unused utilities
104+
105+
## [0.4.0] - 2026-01-21
106+
107+
### Added
108+
109+
- Complete authentication lifecycle:
110+
- Google & GitHub OAuth
111+
- Email verification
112+
- Password reset and recovery flows
113+
- Full internationalization (uk / en / pl) across:
114+
- Authentication pages
115+
- Dashboard
116+
- Contacts
117+
- About page
118+
- Blog, Q&A, Quiz
119+
- Privacy Policy and Terms & Conditions
120+
- New quiz content:
121+
- Angular, Vue.js, Node.js quizzes
122+
- HTML and React question bases
123+
- Advanced quiz experience:
124+
- Countdown timer with persistence and auto-submit
125+
- Encrypted/hashed answers to prevent client-side cheating
126+
- Session persistence with quit confirmation
127+
- Guest quiz results synced after authentication
128+
- Real-time online users counter with animated UI
129+
- GDPR-compliant cookie consent banner with i18n support
130+
- Unified platform & shop header system
131+
- System theme–based favicon switching (light / dark)
132+
- Initial SVG icon set for UI usage
133+
134+
### Changed
135+
136+
- Quiz UI redesigned:
137+
- Category-based tabs
138+
- Consistent QuizCard layout
139+
- Progress indicators and status badges
140+
- Q&A UI refreshed:
141+
- Unified layout with shared background
142+
- Improved pagination and accordion readability
143+
- Authentication pages refactored into reusable components
144+
- Blog experience improved:
145+
- Redesigned blog page and cards
146+
- Category pages and header search
147+
- Recommended posts section
148+
- Shop UI and layout unified across platform and admin views
149+
- Tailwind theme tokens centralized for theme-aware styling
150+
- Database migration history reset to a clean, linear baseline
151+
152+
### Fixed
153+
154+
- Fixed GitHub OAuth redirect and CSRF state handling
155+
- Fixed quiz timer issues when switching languages
156+
- Fixed Q&A API caching to always return fresh data
157+
- Resolved multiple accessibility issues (WCAG, W3C, Lighthouse 100%)
158+
- Hardened authentication redirects to prevent open-redirect vulnerabilities
159+
- Stabilized shop checkout, refund, inventory, and webhook flows
160+
- Improved Neon performance and reduced CU-hours usage
161+
- Cleaned up redundant files, comments, and legacy code

frontend/.env.example

Lines changed: 73 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,92 @@
1+
# --- Core / Environment
2+
APP_ENV=
3+
APP_URL=
4+
NEXT_PUBLIC_SITE_URL=
5+
6+
# --- Database
17
DATABASE_URL=
8+
9+
# --- Auth (app)
210
AUTH_SECRET=
311

4-
CLOUDINARY_CLOUD_NAME=
12+
# --- OAuth: Google
13+
GOOGLE_CLIENT_ID_DEVELOP=
14+
GOOGLE_CLIENT_ID_LOCAL=
15+
GOOGLE_CLIENT_ID_PROD=
16+
GOOGLE_CLIENT_REDIRECT_URI_DEVELOP=
17+
GOOGLE_CLIENT_REDIRECT_URI_LOCAL=
18+
GOOGLE_CLIENT_REDIRECT_URI_PROD=
19+
GOOGLE_CLIENT_SECRET_DEVELOP=
20+
GOOGLE_CLIENT_SECRET_LOCAL=
21+
GOOGLE_CLIENT_SECRET_PROD=
22+
23+
# --- OAuth: GitHub
24+
GITHUB_CLIENT_ID_DEVELOP=
25+
GITHUB_CLIENT_ID_LOCAL=
26+
GITHUB_CLIENT_ID_PROD=
27+
GITHUB_CLIENT_REDIRECT_URI_DEVELOP=
28+
GITHUB_CLIENT_REDIRECT_URI_LOCAL=
29+
GITHUB_CLIENT_REDIRECT_URI_PROD=
30+
GITHUB_CLIENT_SECRET_DEVELOP=
31+
GITHUB_CLIENT_SECRET_LOCAL=
32+
GITHUB_CLIENT_SECRET_PROD=
33+
34+
# --- Cloudinary
535
CLOUDINARY_API_KEY=
636
CLOUDINARY_API_SECRET=
37+
CLOUDINARY_CLOUD_NAME=
738
CLOUDINARY_UPLOAD_FOLDER=
8-
939
CLOUDINARY_URL=
10-
ENABLE_ADMIN_API=
1140

41+
# --- Payments (Stripe)
42+
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
1243
PAYMENTS_ENABLED=
13-
NEXT_PUBLIC_PAYMENTS_ENABLED=
44+
# Options: test, live (defaults to test in development, live in production)
45+
STRIPE_MODE=
1446
STRIPE_SECRET_KEY=
1547
STRIPE_WEBHOOK_SECRET=
1648

17-
STRIPE_MODE=
18-
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
49+
# --- Admin / Internal ops
50+
ENABLE_ADMIN_API=
51+
INTERNAL_JANITOR_MIN_INTERVAL_SECONDS=
52+
INTERNAL_JANITOR_SECRET=
53+
JANITOR_URL=
1954

20-
NEXT_PUBLIC_SITE_URL=
21-
NEXT_PUBLIC_SITE_URL=
55+
# --- Quiz
56+
QUIZ_ENCRYPTION_KEY=
2257

58+
# --- Telegram
2359
TELEGRAM_BOT_TOKEN=
2460
TELEGRAM_CHAT_ID=
2561

26-
GOOGLE_CLIENT_ID=
27-
GOOGLE_CLIENT_SECRET=
28-
GOOGLE_CLIENT_REDIRECT_URI_LOCAL=
29-
GOOGLE_CLIENT_REDIRECT_URI_DEVELOP=
30-
GOOGLE_CLIENT_REDIRECT_URI_PROD=
62+
# --- Email (Gmail SMTP)
63+
EMAIL_FROM=
64+
GMAIL_APP_PASSWORD=
65+
GMAIL_USER=
3166

32-
GITHUB_CLIENT_ID_DEVELOP=
33-
GITHUB_CLIENT_SECRET_DEVELOP=
34-
GITHUB_CLIENT_REDIRECT_URI_DEVELOP=
67+
# --- Security
68+
CSRF_SECRET=
69+
70+
CHECKOUT_RATE_LIMIT_MAX=10
71+
CHECKOUT_RATE_LIMIT_WINDOW_SECONDS=300
72+
73+
# Stripe webhook rate limit envs (applied per reason; reason-specific overrides generic).
74+
# Missing signature has its own envs with fallback to generic, then legacy invalid_sig.
75+
STRIPE_WEBHOOK_MISSING_SIG_RL_MAX=30
76+
STRIPE_WEBHOOK_MISSING_SIG_RL_WINDOW_SECONDS=60
77+
78+
# Generic Stripe webhook rate limit fallback (applies to missing_sig and invalid_sig).
79+
STRIPE_WEBHOOK_RL_MAX=30
80+
STRIPE_WEBHOOK_RL_WINDOW_SECONDS=60
81+
82+
# Invalid signature envs (canonical for invalid_sig, legacy fallback for missing_sig).
83+
STRIPE_WEBHOOK_INVALID_SIG_RL_MAX=30
84+
STRIPE_WEBHOOK_INVALID_SIG_RL_WINDOW_SECONDS=60
85+
86+
# SECURITY: If true, trust x-real-ip / x-forwarded-for headers for rate limiting.
87+
# Enable ONLY behind Cloudflare or a trusted reverse proxy that overwrites these headers.
88+
# Default: false (empty/0/false).
89+
TRUST_FORWARDED_HEADERS=0
3590

36-
APP_ENV=
91+
# emergency switch
92+
RATE_LIMIT_DISABLED=0

0 commit comments

Comments
 (0)