Commit Graph

43 Commits

Author SHA1 Message Date
julien a27b8018b1 fix(users): restrict role updates to Admin users only
Any authenticated user could previously call PUT /update/role and
escalate their own role to Admin. The endpoint now returns 403 if
the requesting user is not already an Admin.
2026-04-26 20:32:37 +02:00
julien ece5506904 fix(comments): use authenticated user id as authorId instead of req.body
Accepting authorId from the request body allowed any authenticated user
to create comments impersonating another user. The author is now always
the authenticated user from req.payload.
2026-04-26 20:31:37 +02:00
julien 6245d1eabd fix(auth): replace fixed-salt bcrypt with HMAC-SHA256 for API key hashing
bcrypt with a fixed salt is deterministic but defeats the purpose of
bcrypt salting. API keys are high-entropy UUIDs (128 bits), making
brute-force resistance unnecessary — HMAC-SHA256 with the app secret
is the correct primitive for deterministic, secure key hashing.

Also fixes application.author.id → application.authorId in the API key
auth path, which was silently setting req.payload.id to undefined.
2026-04-26 20:31:06 +02:00
julien b3a31e4725 feat(auth): migrate Application model from MongoDB to MySQL
- Add Sequelize migration creating the 'application' table
- Add Application Sequelize model with slugify, toJSONFor, toAuthJSON
- Rewrite passport-headerapikey strategy to use DB.Application
- Rewrite applications.routes.js to use Sequelize (findAll, count,
  build/save, destroy) instead of Mongoose
- Fix pre-existing bug: passport was querying { encryptedKey } but the
  stored field is named 'apikey'
- Add Application to MySQL models index and relationships
- Remove Application from Mongoose models index and delete the schema
2026-04-26 18:26:58 +02:00
julien 66821427be fix(skydive): migrate author field from ObjectId to UUID string
- Register SkydiverProfile model in mysql.js (fixes startup crash on association)
- Replace $toObjectId with direct string match in all 12 aggregation queries
- Guard toJSONFor on all Mongo models to fall back to MySQL user.toProfileJSONFor()
  when author is a UUID string (restores username/image in API responses)
- Pass user to toJSONFor() everywhere instead of null
- Remove dead .populate('author') calls (author: String has no ref)
- Fix ownership check in /last route: compare author string to req.payload.id
  instead of the now-absent author.username property
2026-04-26 04:27:47 +02:00
julien da1f9437ab feat(tests): add Jest+Supertest infrastructure with jump route suite (14 tests)
- Extract Express app creation into src/createApp.js to enable testing without starting the server
- Add Jest, Supertest, test helpers (createTestApp, auth token generator)
- Write 14 integration tests for skydive/jumps: auth protection, CRUD, ownership checks

Bugs caught and fixed by the test suite:
- MongoDB models: author field typed as Schema.Types.UUID (Mongoose 6 rejects string UUIDs) → changed to String
- Jump.toJSONFor: called toProfileJSONFor on a UUID string → guarded with typeof check
- exceptions.handler: used err.statusCode but express-jwt throws err.status → returns 500 on 401 errors
- Jump.count(query): deprecated Mongoose method was ignoring the filter → replaced with countDocuments
- jumps.routes GET /: $or query included non-schema field "title" stripped by strictQuery, leaving {} (match-all) → replaced with slug/lieu search
- $regex: was passing a JS RegExp object which serializes to {} in MongoDB → now passes raw string
2026-04-26 01:23:01 +02:00
julien 4c765945b3 refactor(naming): harmonize controller and route file names
- Delete product.controller.js, merge unique functions into products.controller.js
- Rename user.controller.js → users.controller.js, user.routes.js → users.routes.js
- Remove dead herowars/herowars.routes.js reference from herowars index
- Update all import paths accordingly
2026-04-26 00:39:29 +02:00
julien 30104cda05 chore(skydive): remove jumps /feed route
Following is a CMS concept (article feed by followed authors).
Applying it to jumps was a design error — no component ever called
this endpoint. Removed route and associated UserService.getUserFollowed
dependency from skydive.
2026-04-26 00:16:16 +02:00
julien c6d327fb4f chore(models): remove mongo/User from index
MongoDB User model deleted — all user lookups now go through MySQL.
2026-04-26 00:06:06 +02:00
julien 5bcecd01f9 refactor(skydive): replace MongoDB User with MySQL UserService
All skydive routes now fetch users via UserService (MySQL) instead of
mongoose.model('User'). Key changes:
- user._id.toString() → user.id (same UUID, different source)
- User.findOne({ username }) → UserService.getUserByUsername()
- /feed route migrated to async/await using UserService.getUserFollowed()
  to resolve the following list from the MySQL Follower table
- jump/file/application author set as user.id (UUID string) instead of
  the full Mongoose document
- jump.toJSONFor(null) — following field in responses is now always false
  until Jump model is migrated away from MongoDB User dependency
- user.controller: licence/poids/bg_image routed to SkydiverProfileService
  fixing the silent Sequelize save bug for those fields
2026-04-26 00:05:57 +02:00
julien ad7fc4384a feat(skydiver-profile): add SkydiverProfile MySQL model and service
Introduces the skydiver_profile table as an optional 1-to-1 extension
of the user table, holding skydive-specific fields (licence, poids,
bg_image). Wired up with Sequelize associations and a service with
upsert support. Migration, model, relationships, and service layer
all included.
2026-04-25 22:32:30 +02:00
julien 07de469acb chore(models): remove dead MongoDB Article, Comment, Tag models
Migration to MySQL is complete for these three entities — ArticleService,
CommentService, and TagService all use Sequelize exclusively. No remaining
references to the Mongoose versions anywhere in the codebase.
2026-04-25 21:49:03 +02:00
julien 65f70abf30 refactor(skydive): rename route files to *.routes.js convention
Aligns skydive domain with the naming used in cms, ecommerce, and herowars.
Pure rename — no logic changes.
2026-04-25 21:15:15 +02:00
julien e368e61c92 chore(skydive): remove duplicate profiles route
Dead code — identical logic already lives in cms/profiles.routes.js
(refactored with controllers). Frontend exclusively uses /cms/profiles/*.
2026-04-25 21:09:06 +02:00
julien 9a8f33d9bd chore(routes): remove legacy v1/v2/v3 backup folders
These directories were dead code — commented out in routes/index.js
and superseded by the domain-based structure (skydive/cms/ecommerce/herowars).
Also removes the now-pointless commented-out require lines.
2026-04-25 18:01:30 +02:00
julien 7dd2a077e5 chore(models): remove unused Product-tmp.js
Leftover scratch file, not registered in src/database/mysql.js and
not referenced anywhere in src/ or scripts/.
2026-04-25 17:22:08 +02:00
julien c09b60131a refactor(routes): move product/products from cms to ecommerce domain
Product and products routes were sitting under /api/cms but conceptually
belong to a separate e-commerce domain. Split them out into a dedicated
ecommerce subrouter mounted at /api/ecommerce.
2026-04-25 17:20:36 +02:00
julien 74df96c298 docs: add migration documentation, finalization scripts, and update Swagger paths 2026-04-24 00:50:34 +02:00
julien 9f73ed07ba refactor: restructure API routes from v1/v2/v3 to domain-based (skydive/cms/herowars) 2026-04-24 00:47:58 +02:00
julien b99842f458 API Routes update 2026-03-29 23:57:09 +02:00
julien fe1bcc0ff7 Adding Swagger 2026-03-29 23:56:11 +02:00
julien 3c7d65a443 Routes update 2026-03-21 02:33:04 +01:00
julien d8195dbf31 Controller and Model updates 2026-03-21 02:30:46 +01:00
julien ace057d379 Creating a config folder and moving the ‘env’ files 2026-03-21 02:23:36 +01:00
julien 571276253c Suppression de fichiers inutilisés 2025-12-08 15:45:07 +01:00
julien b710b34569 fix(user): persist updateUser correctly; add setup:api script and README update; seeders tweaks 2025-12-05 01:33:38 +01:00
julien 9355431730 Mise à jour et ajout de controllers, routes, services et utilities 2025-11-30 17:54:01 +01:00
julien ba2899f683 Mise à jour de middlewares 2025-11-30 17:49:32 +01:00
julien b861dcbb46 Ajout d'un seeder pour la creation d'article de demonstration 2025-11-30 17:48:57 +01:00
julien 0b704dc8d5 Ajout d'une migration initiale 2025-11-30 17:47:51 +01:00
julien 394b583d4b Mise à jours des informations de base de données MySQL 2025-11-30 17:46:39 +01:00
julien 60feffd929 Refactoring et ajout de routes Hero Wars 2025-11-27 10:50:17 +01:00
Rampeur 6510c55458 Ajout et mise à jour de models mysql 2025-08-29 16:08:53 +02:00
Rampeur b1513dccdd Mise à jour de controleurs, models et routes 2025-08-19 05:13:24 +02:00
Rampeur 10013e1de8 Mise à jour des .env 2025-08-15 23:24:41 +02:00
Rampeur f211bc4b5b Refactoring 2025-08-15 20:32:33 +02:00
Rampeur 25a09aa0fe Refactoring 2025-08-15 20:21:03 +02:00
Rampeur 5d361da628 Réorganisation des sources 2025-08-15 19:39:35 +02:00
Rampeur e17fecc554 Réorganisation des sources 2025-08-15 17:30:39 +02:00
Rampeur ea2d177c4c Réorganisation des sources 2025-08-15 17:29:23 +02:00
Rampeur bd3d1ade49 Mise à jour des models mysql 2025-08-15 15:54:13 +02:00
Rampeur 8a011af73a Utilisation simultanée de mongodb et mysql 2025-08-14 18:22:05 +02:00
Rampeur 49b1a3f6b3 Ajout de la base de données MySQL 2025-08-13 21:51:07 +02:00