2c54257c94
fix: CI/CD add missing VITE_OAUTH vars + pm2 reload via tetardtek-brain
...
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 29s
VITE_OAUTH_URL and VITE_OAUTH_CLIENT_ID were missing from build env,
causing empty client_id in PKCE flow. pm2 reload via su - tetardtek-brain
(same pattern as SuperOAuth post ssh-hardening).
2026-03-23 02:53:51 +01:00
e04666865d
fix: CallbackPage handles verification_pending and merge_pending states
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 38s
2026-03-23 01:14:50 +01:00
8309400466
feat(landing): repositionner plateforme vidéo — supprimer pitch B2B SaaS
...
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 44s
Landing reécrite : vidéos, playlists, créateurs.
Supprimé : pricing, white-label, mentions SuperOAuth, PricingCard component.
CTA principal → /app (explorer les vidéos).
2026-03-22 16:15:02 +01:00
d68041e2f1
feat(auth): PKCE client refinements + backend refresh token support
...
- oauth.ts: provider param, TokenResponse typing, exchangeCode returns full response
- LoginPage: fully async handleOAuth with buildAuthUrl
- CallbackPage: dual-mode PKCE (code) + legacy (token), refresh token forwarding
- LoginButton: provider prop support
- auth.routes: POST /auth/session accepts refreshToken, sets od_refresh cookie
2026-03-22 16:14:55 +01:00
7932659a73
feat(auth): PKCE flow preparation + CallbackPage dual-mode
...
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 29s
- Add oauth.ts — PKCE helpers (code verifier/challenge, token exchange)
- Add LoginButton — "Se connecter avec SuperOAuth" component
- Update CallbackPage — handles both PKCE (?code) and legacy (?token) flows
- Update .env.example — VITE_OAUTH_URL + VITE_OAUTH_CLIENT_ID
PKCE flow ready for when SuperOAuth exposes /oauth/authorize endpoint.
Legacy flow (redirect + token query param) remains active in production.
2026-03-22 12:50:07 +01:00
32b9af7b02
fix(auth): UserMenu sessionStorage → AuthContext — unification auth state
CI/CD — Build & Deploy / Build & Deploy (push) Failing after 24s
2026-03-17 07:43:48 +01:00
d25bfb7d87
feat(sprint3-step1-2): vision B2B + Tailwind tokens + LandingPage + Pricing B2B
2026-03-17 06:36:52 +01:00
e52aa1e79c
perf: requireAdmin — 2 queries → 1 (User + userRoles eager join TypeORM)
2026-03-15 18:00:48 +01:00
379a9a115b
fix(security): isActive defense-in-depth, MIME magic bytes upload, tenantId=origins OAuth
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 54s
2026-03-15 17:34:19 +01:00
ef4c23d6a2
fix: OAuth — window.location.href direct, no cross-origin fetch (CORS)
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 28s
2026-03-15 03:30:49 +01:00
94b607c4d0
fix: OAuth buttons — fetch authUrl then redirect (SuperOAuth JSON flow)
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 24s
2026-03-15 03:27:00 +01:00
40938be067
fix: OAuth login path — /api/v1/oauth/:provider (pas auth/oauth)
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 24s
2026-03-15 03:23:24 +01:00
3eb791d4a1
feat: VideoPage — ajouter à une playlist (owned + edit-permitted)
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 23s
2026-03-15 02:53:34 +01:00
8e78ce50b5
feat: profile avatar, callback setUser fix, admin description/thumbnail, pagination limit=100
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 26s
2026-03-15 02:45:50 +01:00
61d8a5257d
feat: admin/superadmin — fix response shape, ban/unban, stats tab, role restriction
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 24s
2026-03-15 02:30:11 +01:00
d69281a2e0
feat: B3 — search vidéos (filtre client-side + param ?q= backend)
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 22s
2026-03-15 02:22:04 +01:00
426cd4bbbd
feat: B2 — 401 interceptor + auto-refresh token (fix SuperOAuth path + response shape)
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 27s
2026-03-15 02:19:40 +01:00
6877db3227
fix: login — setUser après auth pour maj header immédiate
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 24s
2026-03-15 01:57:41 +01:00
2c3d9d95c6
feat(frontend): playlist B1 — edit, delete, share, invitations
...
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 36s
- PlaylistPage: bouton Éditer (formulaire inline titre/visibilité), Supprimer (confirm → DELETE → redirect), Partager (modal userId/permission → POST share), Retirer vidéo (✕ → DELETE)
- PlaylistsPage: section invitations reçues avec Accept / Refuser (PATCH share/:shareId)
- tsc --noEmit : 0 erreur, 0 console.log
2026-03-15 01:00:26 +01:00
df8e594d57
fix(frontend): Error Boundary, HomePage error state, HLS catch — quick wins pre-Bloc-B
2026-03-15 00:53:46 +01:00
f80b8cb81c
fix: instrument bare catch blocks — logger.error sur stream/admin/user
2026-03-15 00:18:37 +01:00
494206b5b3
feat: observability — Winston logging, pagination admin, N+1 playlists
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 27s
2026-03-14 23:21:42 +01:00
31edea9dd9
feat: rate limiting — login 10req/15min, admin 50req/min, trust proxy
2026-03-14 23:20:20 +01:00
9f53193c7c
feat: vitest setup + auth middleware — token invalide et absent → 401
2026-03-14 23:19:45 +01:00
01d347bce3
fix: ApiError typée + error handling pages video/playlists/admin
...
- api.ts : ApiError class (status: number) — remplace Error générique
- VideoPage/PlaylistPage : instanceof ApiError au lieu de message.includes()
- PlaylistsPage : fetchError + createError — silent catch supprimé
- AdminPage : guard roles.some() aligné Header (super_admin inclus)
2026-03-14 22:37:36 +01:00
4e8c1aa849
feat: sprint 3 — profil utilisateur, badge plan, dropdown Header
...
- AuthContext.User : plan? { slug, name, level } | null
- UserBadge : nickname + badge plan.slug (fallback free)
- Header : dropdown click (Profil / Déconnexion) + click-outside
- ProfilePage : infos compte, badge plan, edit nickname (PATCH /users/me + re-fetch /auth/me → setUser)
- App : route /profile protégée
- useAuth : réexporte depuis AuthContext, fin de la dérive
2026-03-14 22:33:47 +01:00
30ef7312b5
feat: sprint 3 — profile endpoints + avatar
...
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 32s
- GET /api/auth/me enrichi : avatar, plan actif, subscriptionDate
- GET /api/users/me/profile : profil complet (local UUID, sub, rôles)
- PATCH /api/users/me : update nickname / avatar (validation URL + longueur)
- User entity : champ avatar VARCHAR(500) nullable
- Migration 1742000000000-AddUserAvatar (appliquée VPS)
2026-03-14 22:25:22 +01:00
24ae8854ce
fix: GET /admin/users — find() x5 → variable locale
2026-03-14 19:35:04 +01:00
c25d9ad843
feat: admin page — guard isAdmin, error handling, upload local, role assignment
...
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 32s
- AuthContext: roles: string[] ajouté au type User
- Header: lien /admin masqué si !roles.includes('admin')
- AdminPage: redirect / si non-admin (Navigate)
- AdminPage: fetchError sur les 3 tabs (load silencieux → message visible)
- AdminPage: actionError sur toutes les mutations (toggle/delete/assign)
- AdminPage: loading UsersTab → skeleton list 3 cartes (aligné Videos/Plans)
- AdminPage: upload local — file input mp4/webm, multipart POST /admin/videos/upload,
storageKey auto-rempli, Créer bloqué pendant upload
- AdminPage: assignation rôle — PATCH /admin/users/:id/roles, rafraîchit la liste
2026-03-14 15:25:11 +01:00
2a74be2624
feat: GET /api/auth/me retourne roles[]
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 35s
2026-03-14 15:18:51 +01:00
27e6541425
fix: requireAdmin résout le user local par superOAuthId
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 59s
2026-03-14 15:14:03 +01:00
c7815aac2f
feat: token refresh, video upload, playlist routes complets
...
- auth: cookie od_token 7j, refresh token od_refresh 30j, POST /api/auth/refresh, GET /api/auth/me/optional
- admin: POST /api/admin/videos/upload via multer (mp4/webm, 4Go max, UUID filename)
- playlist: PATCH /:id, DELETE /:id, POST /:id/videos, DELETE /:id/videos/:videoId
- env: UPLOADS_DIR documenté dans .env.example
2026-03-14 14:32:18 +01:00
aa15dc0f54
feat: AuthContext, protected routes, admin page, fix VideoPlayer URL
2026-03-14 14:31:08 +01:00
324efcaa3d
feat: login email/password + proxy POST /api/auth/login → SuperOAuth
...
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 21s
- auth.routes : POST /api/auth/login proxie vers SuperOAuth, pose httpOnly cookie
- Factorisation upsertUser() partagé avec /session
- LoginPage : form email/password + séparateur + boutons OAuth provider
2026-03-14 10:26:25 +01:00
7e3ee29b13
fix: login page avec sélection provider → /api/v1/auth/oauth/:provider?redirectUrl
...
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 21s
SuperOAuth root page ignore ?redirectUrl, les boutons de sa UI pointent vers
ses propres URIs hardcodées. Fix : notre page /login construit les URLs API
directement avec redirectUrl=origins.tetardtek.com/callback.
Aussi : CORS_ORIGINS SuperOAuth mis à jour (origins.tetardtek.com ajouté).
2026-03-14 10:11:30 +01:00
34bab532be
fix: login → SuperOAuth root page (redirectUrl), drop LoginPage interne
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 21s
2026-03-14 10:04:20 +01:00
666cf6a435
feat: stream route, admin subscriptions, fix CORS multi-origin
...
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 21s
- index.ts : CORS supporte plusieurs origines (FRONTEND_URL séparé par virgule)
- stream.routes.ts : GET /api/stream/:key* — sert fichiers locaux avec auth
optionnelle, contrôle d'accès par level, support Range requests (seekable)
- admin.routes.ts : POST /api/admin/users/:id/subscriptions — assigne un plan,
expire l'abonnement actif précédent
- Fix .env VPS : FRONTEND_URL=origins.tetardtek.com (domaine correct)
2026-03-14 09:58:01 +01:00
4265d21c8b
feat: login provider selection, logout, playlists pages
...
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 22s
- LoginPage : sélection Discord/GitHub/Google/Twitch via SuperOAuth
- Header : bouton Connexion → /login, logout ↩ quand connecté, nav Playlists conditionnelle
- useAuth : expose setUser pour logout côté Layout
- PlaylistsPage : liste owned/shared, création inline
- PlaylistPage : détail playlist + liste vidéos ordonnées
- Fix : Video.id number → string (UUID)
- Routes : /login, /playlists, /playlists/:id
2026-03-14 09:32:45 +01:00
fcd9867670
ci: fix pipeline — vps-runner host mode, remove setup-node, add smoke test
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 23s
2026-03-14 09:16:57 +01:00
77e5990078
ci: relance pipeline après ajout secrets
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 54s
2026-03-14 09:03:32 +01:00
5031b31aeb
fix: pipeline CI/CD — vps-runner direct deploy (pm2 + rsync)
...
CI/CD — Build & Deploy / Build & Deploy (push) Has been cancelled
Remplace le flow Docker (docker compose up) par le vrai modèle :
- Job unique sur vps-runner (runner local sur le VPS)
- Build backend → rsync vers /var/www/originsdigital/backend/ → pm2 restart
- Build frontend avec VITE_API_URL/VITE_SUPEROAUTH_URL → rsync vers /var/www/originsdigital/frontend/dist/
- Suppression appleboy/ssh-action (inutile, le runner est sur le VPS)
2026-03-14 08:59:10 +01:00
df3fe8ebe0
fix(auth): correct SuperOAuth endpoint path — /api/v1/auth not /api/auth
CI/CD — Build & Deploy / Build (push) Failing after 43s
CI/CD — Build & Deploy / Deploy to VPS (push) Has been skipped
2026-03-14 08:40:32 +01:00
9598cd8715
perf(frontend): drop react-player — YouTube iframe natif, HLS.js lazy seulement si .m3u8
CI/CD — Build & Deploy / Build (push) Failing after 35s
CI/CD — Build & Deploy / Deploy to VPS (push) Has been skipped
2026-03-14 08:39:01 +01:00
5eb0a43d7f
feat: lazy ReactPlayer, seed 11 vidéos YouTube (niveaux 0/1/2)
CI/CD — Build & Deploy / Build (push) Failing after 41s
CI/CD — Build & Deploy / Deploy to VPS (push) Has been skipped
2026-03-14 08:25:41 +01:00
11d9432218
fix(routes): resolve superOAuthId → DB userId — critical auth bug
...
CI/CD — Build & Deploy / Build (push) Failing after 35s
CI/CD — Build & Deploy / Deploy to VPS (push) Has been skipped
req.user.id = SuperOAuth UUID, pas l'UUID TypeORM en DB.
Sans ce fix : getUserPlanLevel retourne toujours 0, ownerId ne matche jamais.
- video.routes: resolveDbUserId avant getUserPlanLevel
- playlist.routes: resolveDbUserId sur toutes les opérations owner/member
2026-03-14 08:12:11 +01:00
87d076313c
feat(frontend): VideoPage react-player v3, fix data.videos, route /video/:id
CI/CD — Build & Deploy / Build (push) Has been cancelled
CI/CD — Build & Deploy / Deploy to VPS (push) Has been cancelled
2026-03-14 08:12:08 +01:00
5d4bab7d99
chore: add assign-first-admin.sql — run once after first login
CI/CD — Build & Deploy / Build (push) Failing after 39s
CI/CD — Build & Deploy / Deploy to VPS (push) Has been skipped
2026-03-14 08:10:16 +01:00
253af8f402
fix(auth): upsert user in DB on session creation — first login creates user record
2026-03-14 08:07:42 +01:00
0591cd4528
feat(frontend): useAuth /auth/me, videos list + locked flag, VITE_API_URL
CI/CD — Build & Deploy / Build (push) Failing after 40s
CI/CD — Build & Deploy / Deploy to VPS (push) Has been skipped
2026-03-14 08:06:51 +01:00
5afcad487e
docs(backend): add .env.example
CI/CD — Build & Deploy / Build (push) Failing after 44s
CI/CD — Build & Deploy / Deploy to VPS (push) Has been skipped
2026-03-14 08:01:01 +01:00