Browse Source

Added swagger.yaml

pull/11/head
astria 3 months ago
parent
commit
d3b948385c
  1. 1
      backend/app/controllers/user.controller.js
  2. 39
      backend/app/routes/channel.route.js
  3. BIN
      backend/app/uploads/profiles/test.jpg
  4. 73
      backend/logs/access.log
  5. 291
      backend/package-lock.json
  6. 5
      backend/package.json
  7. 21
      backend/server.js
  8. 2317
      backend/swagger.yaml

1
backend/app/controllers/user.controller.js

@ -130,7 +130,6 @@ export async function register(req, res) {
logger?.write("failed to register user", 500); logger?.write("failed to register user", 500);
res.status(500).json({ error: "Internal server error" }); res.status(500).json({ error: "Internal server error" });
} finally { } finally {
client.release();
} }
} }

39
backend/app/routes/channel.route.js

@ -14,7 +14,44 @@ import {addLogger} from "../middlewares/logger.middleware.js";
const router = Router(); const router = Router();
// CREATE CHANNEL /**
* @swagger
* tags:
* name: Channels
* description: API for managing channels
* /:
* post:
* summary: Create a new channel
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* name:
* type: string
* description:
* type: string
* owner:
* type: string
* responses:
* 201:
* description: Channel created successfully
* content:
* application/json:
* schema:
* type: object
* properties:
* id:
* type: string
* name:
* type: string
* description:
* type: string
* owner:
* type: string
*/
router.post("/", [addLogger, isTokenValid, ChannelCreate.name, ChannelCreate.description, ChannelCreate.owner, validator, doUserExistsBody, doUserHaveChannel, isOwnerBody, doChannelNameExists], create); router.post("/", [addLogger, isTokenValid, ChannelCreate.name, ChannelCreate.description, ChannelCreate.owner, validator, doUserExistsBody, doUserHaveChannel, isOwnerBody, doChannelNameExists], create);
// GET CHANNEL BY ID // GET CHANNEL BY ID

BIN
backend/app/uploads/profiles/test.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

73
backend/logs/access.log

@ -11999,3 +11999,76 @@
[2025-09-05 10:06:26.509] [undefined] GET(/:id): Successfully get channel with id 6 with status 200 [2025-09-05 10:06:26.509] [undefined] GET(/:id): Successfully get channel with id 6 with status 200
[2025-09-05 10:06:37.217] [undefined] GET(/:id): try to get channel with id 5 [2025-09-05 10:06:37.217] [undefined] GET(/:id): try to get channel with id 5
[2025-09-05 10:06:37.227] [undefined] GET(/:id): Successfully get channel with id 5 with status 200 [2025-09-05 10:06:37.227] [undefined] GET(/:id): Successfully get channel with id 5 with status 200
[2025-09-05 16:39:37.274] [undefined] GET(/see-later): 'See Later' playlist retrieved for user with id 1 with status 200
[2025-09-05 16:41:47.205] [undefined] GET(/see-later): 'See Later' playlist retrieved for user with id 1 with status 200
[2025-09-05 17:01:58.738] [undefined] GET(/see-later): 'See Later' playlist retrieved for user with id 1 with status 200
[2025-09-05 17:04:07.324] [undefined] POST(/): try to register a user with username: test and email: test@test.com
[2025-09-05 17:04:08.497] [undefined] POST(/): successfully registered with status 200
[2025-09-05 17:04:46.774] [undefined] POST(/): try to register a user with username: teste and email: teste@test.com
[2025-09-05 17:04:47.739] [undefined] POST(/): successfully registered with status 200
[2025-09-05 17:05:50.681] [undefined] POST(/): try to register a user with username: testre and email: testre@test.com
[2025-09-05 17:05:51.611] [undefined] POST(/): successfully registered with status 200
[2025-09-05 17:06:30.976] [undefined] POST(/login): try to login with username 'test'
[2025-09-05 17:06:31.027] [undefined] POST(/login): Successfully logged in with status 200
[2025-09-05 17:10:52.763] [undefined] POST(/login): try to login with username 'test'
[2025-09-05 17:10:52.861] [undefined] POST(/login): Successfully logged in with status 200
[2025-09-05 17:11:15.670] [undefined] GET(/search): Invalid token with status 401
[2025-09-05 17:11:27.652] [undefined] POST(/login): try to login with username 'test'
[2025-09-05 17:11:27.751] [undefined] POST(/login): Successfully logged in with status 200
[2025-09-05 17:11:41.375] [undefined] GET(/search): try to search user by username test
[2025-09-05 17:11:41.432] [undefined] GET(/search): successfully found user with username test with status 200
[2025-09-05 17:11:51.707] [undefined] GET(/:id): try to retrieve user 2
[2025-09-05 17:11:51.762] [undefined] GET(/:id): successfully retrieved user 2 with status 200
[2025-09-05 17:12:15.622] [undefined] PUT(/:id): try to update user 2
[2025-09-05 17:12:15.630] [undefined] PUT(/:id): successfully updated user 2 with status 200
[2025-09-05 17:12:28.053] [undefined] DELETE(/:id): failed because he wasn't the owner of the user with status 403
[2025-09-05 17:12:38.114] [undefined] GET(/username/:username): try to retrieve user string
[2025-09-05 17:12:38.169] [undefined] GET(/username/:username): successfully retrieved user string with status 200
[2025-09-05 17:12:46.243] [undefined] GET(/:id/channel): try to retrieve channel of user 2
[2025-09-05 17:12:46.249] [undefined] GET(/:id/channel): failed to retrieve channel of user 2 because it doesn't exist with status 404
[2025-09-05 17:12:52.671] [undefined] GET(/:id/history): try to retrieve history of user 2
[2025-09-05 17:12:52.726] [undefined] GET(/:id/history): failed to retrieve history of user 2 because it doesn't exist with status 404
[2025-09-05 17:12:58.929] [undefined] GET(/:id/subscriptions): try to retrieve all subscriptions of user 2
[2025-09-05 17:12:58.936] [undefined] GET(/:id/subscriptions): no subscriptions found for user 2 with status 404
[2025-09-05 17:13:04.939] [undefined] GET(/:id/subscriptions/videos): try to retrieve all subscriptions of user 2
[2025-09-05 17:13:04.998] [undefined] GET(/:id/subscriptions/videos): no subscriptions found for user 2 with status 404
[2025-09-05 17:13:25.706] [undefined] POST(/): try to create new channel with owner 2 and name chien
[2025-09-05 17:13:25.710] [undefined] POST(/): Successfully created new channel with name chien with status 200
[2025-09-05 17:13:41.559] [undefined] GET(/): try to get all channels
[2025-09-05 17:13:41.564] [undefined] GET(/): Successfully get all channels with status 200
[2025-09-05 17:13:52.689] [undefined] GET(/:id): try to get channel with id 2
[2025-09-05 17:13:52.751] [undefined] GET(/:id): Successfully get channel with id 2 with status 200
[2025-09-05 17:14:09.069] [undefined] PUT(/:id): try to update channel with id 2
[2025-09-05 17:14:09.130] [undefined] PUT(/:id): Successfully updated channel with status 200
[2025-09-05 17:14:19.755] [undefined] DELETE(/:id): failed because user do not own the channel with status 403
[2025-09-05 17:14:29.922] [undefined] POST(/:id/subscribe): try to toggle subscription for channel with id 1
[2025-09-05 17:53:33.682] [undefined] POST(/:id/subscribe): Invalid token with status 401
[2025-09-05 17:53:46.173] [undefined] POST(/:id/subscribe): Invalid token with status 401
[2025-09-05 17:53:56.975] [undefined] POST(/:id/subscribe): try to toggle subscription for channel with id 1
[2025-09-05 17:55:37.631] [undefined] POST(/:id/subscribe): try to toggle subscription for channel with id 2
[2025-09-05 17:55:37.693] [undefined] POST(/:id/subscribe): Successfully subscribed to channel with status 200
[2025-09-05 17:55:57.145] [undefined] GET(/:id/stats): try to get stats
[2025-09-05 17:55:57.151] [undefined] GET(/:id/stats): Successfully get stats with status 200
[2025-09-05 17:56:13.319] [undefined] GET(/:id): try to get video 1
[2025-09-05 17:56:13.350] [undefined] GET(/:id): successfully get video 1 with status 200
[2025-09-05 17:56:24.622] [undefined] GET(/channel/:id): try to get video from channel 1
[2025-09-05 17:56:24.627] [undefined] GET(/channel/:id): successfully get video from channel 1 with status 200
[2025-09-05 17:56:30.445] [undefined] GET(/:id/like): try to toggle like on video 1
[2025-09-05 17:56:30.453] [undefined] GET(/:id/like): no likes found adding likes for video 1 with status 200
[2025-09-05 17:56:37.689] [undefined] GET(/:id/similar): try to get similar videos for video 1
[2025-09-05 17:56:37.696] [undefined] GET(/:id/similar): successfully get similar videos for video 1 with status 200
[2025-09-05 17:56:43.181] [undefined] GET(/:id/views): try to add views for video 1
[2025-09-05 17:56:43.230] [undefined] GET(/:id/views): successfully added views for video 1 with status 200
[2025-09-05 17:56:48.002] [undefined] GET(/:id/likes/day): try to get likes per day
[2025-09-05 17:56:48.063] [undefined] GET(/:id/likes/day): successfully retrieved likes per day with status 200
[2025-09-05 17:57:00.119] [undefined] POST(/): try to post comment
[2025-09-05 17:57:00.126] [undefined] POST(/): successfully post comment with status 200
[2025-09-05 17:57:09.337] [undefined] GET(/video/:id): try to get comment from video 1
[2025-09-05 17:57:09.343] [undefined] GET(/video/:id): successfully get comment with status 200
[2025-09-05 17:57:15.838] [undefined] GET(/:id): try to get comment 1
[2025-09-05 17:57:15.843] [undefined] GET(/:id): successfully get comment with status 200
[2025-09-05 17:57:26.069] [undefined] POST(/): Playlist created with id 5 with status 200
[2025-09-05 17:57:32.550] [undefined] GET(/see-later): 'See Later' playlist retrieved for user with id 2 with status 200
[2025-09-05 17:57:44.224] [undefined] POST(/:id): user not the owner of the playlist with id 1 with status 403
[2025-09-05 17:58:14.088] [undefined] POST(/:id): Video added to playlist with id 2 with status 200
[2025-09-05 17:58:21.531] [undefined] GET(/:id): Playlist retrieved with id 2 with status 200

291
backend/package-lock.json

@ -22,7 +22,10 @@
"nodemailer": "^7.0.5", "nodemailer": "^7.0.5",
"passport": "^0.7.0", "passport": "^0.7.0",
"passport-github2": "^0.1.12", "passport-github2": "^0.1.12",
"pg": "^8.16.3" "pg": "^8.16.3",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.1",
"yaml": "^2.8.1"
}, },
"devDependencies": { "devDependencies": {
"chai": "^5.2.0", "chai": "^5.2.0",
@ -35,6 +38,50 @@
"vitest": "^3.2.4" "vitest": "^3.2.4"
} }
}, },
"node_modules/@apidevtools/json-schema-ref-parser": {
"version": "9.1.2",
"resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.1.2.tgz",
"integrity": "sha512-r1w81DpR+KyRWd3f+rk6TNqMgedmAxZP5v5KWlXQWlgMUUtyEJch0DKEci1SorPMiSeM8XPl7MZ3miJ60JIpQg==",
"license": "MIT",
"dependencies": {
"@jsdevtools/ono": "^7.1.3",
"@types/json-schema": "^7.0.6",
"call-me-maybe": "^1.0.1",
"js-yaml": "^4.1.0"
}
},
"node_modules/@apidevtools/openapi-schemas": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz",
"integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==",
"license": "MIT",
"engines": {
"node": ">=10"
}
},
"node_modules/@apidevtools/swagger-methods": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz",
"integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==",
"license": "MIT"
},
"node_modules/@apidevtools/swagger-parser": {
"version": "10.0.3",
"resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.0.3.tgz",
"integrity": "sha512-sNiLY51vZOmSPFZA5TF35KZ2HbgYklQnTSDnkghamzLb3EkNtcQnrBQEj5AOCxHpTtXpqMCRM1CrmV2rG6nw4g==",
"license": "MIT",
"dependencies": {
"@apidevtools/json-schema-ref-parser": "^9.0.6",
"@apidevtools/openapi-schemas": "^2.0.4",
"@apidevtools/swagger-methods": "^3.0.2",
"@jsdevtools/ono": "^7.1.3",
"call-me-maybe": "^1.0.1",
"z-schema": "^5.0.1"
},
"peerDependencies": {
"openapi-types": ">=7"
}
},
"node_modules/@esbuild/aix-ppc64": { "node_modules/@esbuild/aix-ppc64": {
"version": "0.25.5", "version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz",
@ -485,6 +532,12 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@jsdevtools/ono": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz",
"integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==",
"license": "MIT"
},
"node_modules/@noble/hashes": { "node_modules/@noble/hashes": {
"version": "1.8.0", "version": "1.8.0",
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
@ -799,6 +852,13 @@
"win32" "win32"
] ]
}, },
"node_modules/@scarf/scarf": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz",
"integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==",
"hasInstallScript": true,
"license": "Apache-2.0"
},
"node_modules/@types/chai": { "node_modules/@types/chai": {
"version": "5.2.2", "version": "5.2.2",
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz",
@ -830,6 +890,12 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"license": "MIT"
},
"node_modules/@types/methods": { "node_modules/@types/methods": {
"version": "1.1.4", "version": "1.1.4",
"resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz", "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz",
@ -1038,7 +1104,6 @@
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true,
"license": "Python-2.0" "license": "Python-2.0"
}, },
"node_modules/asap": { "node_modules/asap": {
@ -1069,7 +1134,6 @@
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/base64url": { "node_modules/base64url": {
@ -1132,7 +1196,6 @@
"version": "1.1.12", "version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
@ -1230,6 +1293,12 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/call-me-maybe": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz",
"integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==",
"license": "MIT"
},
"node_modules/camelcase": { "node_modules/camelcase": {
"version": "6.3.0", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
@ -1480,6 +1549,15 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/commander": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz",
"integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==",
"license": "MIT",
"engines": {
"node": ">= 6"
}
},
"node_modules/component-emitter": { "node_modules/component-emitter": {
"version": "1.3.1", "version": "1.3.1",
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
@ -1494,7 +1572,6 @@
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/concat-stream": { "node_modules/concat-stream": {
@ -1679,6 +1756,18 @@
"node": ">=0.3.1" "node": ">=0.3.1"
} }
}, },
"node_modules/doctrine": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
"license": "Apache-2.0",
"dependencies": {
"esutils": "^2.0.2"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/dotenv": { "node_modules/dotenv": {
"version": "17.0.1", "version": "17.0.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.0.1.tgz", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.0.1.tgz",
@ -1876,6 +1965,15 @@
"@types/estree": "^1.0.0" "@types/estree": "^1.0.0"
} }
}, },
"node_modules/esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/etag": { "node_modules/etag": {
"version": "1.8.1", "version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
@ -2147,6 +2245,12 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"license": "ISC"
},
"node_modules/fsevents": { "node_modules/fsevents": {
"version": "2.3.3", "version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@ -2407,6 +2511,17 @@
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
"license": "ISC",
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"node_modules/inherits": { "node_modules/inherits": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
@ -2584,7 +2699,6 @@
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"argparse": "^2.0.1" "argparse": "^2.0.1"
@ -2658,6 +2772,13 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
"deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.",
"license": "MIT"
},
"node_modules/lodash.includes": { "node_modules/lodash.includes": {
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
@ -2670,6 +2791,13 @@
"integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
"integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==",
"deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.",
"license": "MIT"
},
"node_modules/lodash.isinteger": { "node_modules/lodash.isinteger": {
"version": "4.0.4", "version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
@ -2694,6 +2822,12 @@
"integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/lodash.mergewith": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
"integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
"license": "MIT"
},
"node_modules/lodash.once": { "node_modules/lodash.once": {
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
@ -2875,7 +3009,6 @@
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
@ -3262,6 +3395,13 @@
"wrappy": "1" "wrappy": "1"
} }
}, },
"node_modules/openapi-types": {
"version": "12.1.3",
"resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz",
"integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==",
"license": "MIT",
"peer": true
},
"node_modules/p-limit": { "node_modules/p-limit": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@ -3377,6 +3517,15 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/path-key": { "node_modules/path-key": {
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@ -4273,6 +4422,92 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/swagger-jsdoc": {
"version": "6.2.8",
"resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-6.2.8.tgz",
"integrity": "sha512-VPvil1+JRpmJ55CgAtn8DIcpBs0bL5L3q5bVQvF4tAW/k/9JYSj7dCpaYCAv5rufe0vcCbBRQXGvzpkWjvLklQ==",
"license": "MIT",
"dependencies": {
"commander": "6.2.0",
"doctrine": "3.0.0",
"glob": "7.1.6",
"lodash.mergewith": "^4.6.2",
"swagger-parser": "^10.0.3",
"yaml": "2.0.0-1"
},
"bin": {
"swagger-jsdoc": "bin/swagger-jsdoc.js"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/swagger-jsdoc/node_modules/glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/swagger-jsdoc/node_modules/yaml": {
"version": "2.0.0-1",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-1.tgz",
"integrity": "sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ==",
"license": "ISC",
"engines": {
"node": ">= 6"
}
},
"node_modules/swagger-parser": {
"version": "10.0.3",
"resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-10.0.3.tgz",
"integrity": "sha512-nF7oMeL4KypldrQhac8RyHerJeGPD1p2xDh900GPvc+Nk7nWP6jX2FcC7WmkinMoAmoO774+AFXcWsW8gMWEIg==",
"license": "MIT",
"dependencies": {
"@apidevtools/swagger-parser": "10.0.3"
},
"engines": {
"node": ">=10"
}
},
"node_modules/swagger-ui-dist": {
"version": "5.28.1",
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.28.1.tgz",
"integrity": "sha512-IvPrtNi8MvjiuDgoSmPYgg27Lvu38fnLD1OSd8Y103xXsPAqezVNnNeHnVCZ/d+CMXJblflGaIyHxAYIF3O71w==",
"license": "Apache-2.0",
"dependencies": {
"@scarf/scarf": "=1.4.0"
}
},
"node_modules/swagger-ui-express": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-5.0.1.tgz",
"integrity": "sha512-SrNU3RiBGTLLmFU8GIJdOdanJTl4TOmT27tt3bWWHppqYmAZ6IDuEuBvMU6nZq0zLEe6b/1rACXCgLZqO6ZfrA==",
"license": "MIT",
"dependencies": {
"swagger-ui-dist": ">=5.0.0"
},
"engines": {
"node": ">= v0.10.32"
},
"peerDependencies": {
"express": ">=4.0.0 || >=5.0.0-beta"
}
},
"node_modules/time-span": { "node_modules/time-span": {
"version": "5.1.0", "version": "5.1.0",
"resolved": "https://registry.npmjs.org/time-span/-/time-span-5.1.0.tgz", "resolved": "https://registry.npmjs.org/time-span/-/time-span-5.1.0.tgz",
@ -4879,6 +5114,18 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/yaml": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz",
"integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==",
"license": "ISC",
"bin": {
"yaml": "bin.mjs"
},
"engines": {
"node": ">= 14.6"
}
},
"node_modules/yargs": { "node_modules/yargs": {
"version": "17.7.2", "version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
@ -4981,6 +5228,36 @@
"funding": { "funding": {
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
},
"node_modules/z-schema": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz",
"integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==",
"license": "MIT",
"dependencies": {
"lodash.get": "^4.4.2",
"lodash.isequal": "^4.5.0",
"validator": "^13.7.0"
},
"bin": {
"z-schema": "bin/z-schema"
},
"engines": {
"node": ">=8.0.0"
},
"optionalDependencies": {
"commander": "^9.4.1"
}
},
"node_modules/z-schema/node_modules/commander": {
"version": "9.5.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
"integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
"license": "MIT",
"optional": true,
"engines": {
"node": "^12.20.0 || >=14"
}
} }
} }
} }

5
backend/package.json

@ -26,7 +26,10 @@
"nodemailer": "^7.0.5", "nodemailer": "^7.0.5",
"passport": "^0.7.0", "passport": "^0.7.0",
"passport-github2": "^0.1.12", "passport-github2": "^0.1.12",
"pg": "^8.16.3" "pg": "^8.16.3",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.1",
"yaml": "^2.8.1"
}, },
"devDependencies": { "devDependencies": {
"chai": "^5.2.0", "chai": "^5.2.0",

21
backend/server.js

@ -1,4 +1,7 @@
import express from "express"; import express from "express";
import swaggerui from "swagger-ui-express";
import fs from "fs";
import YAML from "yaml";
import dotenv from "dotenv"; import dotenv from "dotenv";
import UserRoute from "./app/routes/user.route.js"; import UserRoute from "./app/routes/user.route.js";
import ChannelRoute from "./app/routes/channel.route.js"; import ChannelRoute from "./app/routes/channel.route.js";
@ -26,7 +29,6 @@ const app = express();
// Increase body size limits for file uploads // Increase body size limits for file uploads
app.use(express.urlencoded({extended: true, limit: '500mb'})); app.use(express.urlencoded({extended: true, limit: '500mb'}));
app.use(express.json({limit: '500mb'})); app.use(express.json({limit: '500mb'}));
app.use(cors())
app.use(session({ app.use(session({
secret: "your-secret", secret: "your-secret",
@ -34,6 +36,23 @@ app.use(session({
saveUninitialized: false, saveUninitialized: false,
})); }));
// Swagger setup
const file = fs.readFileSync('./swagger.yaml', 'utf8');
const swaggerDocument = YAML.parse(file);
// Swagger UI options
const swaggerOptions = {
explorer: true,
swaggerOptions: {
requestInterceptor: (req) => {
req.headers['Content-Type'] = 'application/json';
return req;
}
}
};
app.use('/api/api-docs', swaggerui.serve, swaggerui.setup(swaggerDocument, swaggerOptions));
// --- Passport setup --- // --- Passport setup ---
app.use(passport.initialize()); app.use(passport.initialize());
app.use(passport.session()); app.use(passport.session());

2317
backend/swagger.yaml

File diff suppressed because it is too large
Loading…
Cancel
Save